00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "JPEGVideoRTPSink.hh"
00022 #include "JPEGVideoSource.hh"
00023
00024 JPEGVideoRTPSink
00025 ::JPEGVideoRTPSink(UsageEnvironment& env, Groupsock* RTPgs)
00026 : VideoRTPSink(env, RTPgs, 26, 90000, "JPEG") {
00027 }
00028
00029 JPEGVideoRTPSink::~JPEGVideoRTPSink() {
00030 }
00031
00032 JPEGVideoRTPSink*
00033 JPEGVideoRTPSink::createNew(UsageEnvironment& env, Groupsock* RTPgs) {
00034 return new JPEGVideoRTPSink(env, RTPgs);
00035 }
00036
00037 Boolean JPEGVideoRTPSink::sourceIsCompatibleWithUs(MediaSource& source) {
00038 return source.isJPEGVideoSource();
00039 }
00040
00041 Boolean JPEGVideoRTPSink
00042 ::frameCanAppearAfterPacketStart(unsigned char const* ,
00043 unsigned ) const {
00044
00045 return False;
00046 }
00047
00048 void JPEGVideoRTPSink
00049 ::doSpecialFrameHandling(unsigned fragmentationOffset,
00050 unsigned char* ,
00051 unsigned ,
00052 struct timeval framePresentationTime,
00053 unsigned numRemainingBytes) {
00054
00055 JPEGVideoSource* source = (JPEGVideoSource*)fSource;
00056 if (source == NULL) return;
00057
00058 u_int8_t mainJPEGHeader[8];
00059 u_int8_t const type = source->type();
00060
00061 mainJPEGHeader[0] = 0;
00062 mainJPEGHeader[1] = fragmentationOffset >> 16;
00063 mainJPEGHeader[2] = fragmentationOffset >> 8;
00064 mainJPEGHeader[3] = fragmentationOffset;
00065 mainJPEGHeader[4] = type;
00066 mainJPEGHeader[5] = source->qFactor();
00067 mainJPEGHeader[6] = source->width();
00068 mainJPEGHeader[7] = source->height();
00069 setSpecialHeaderBytes(mainJPEGHeader, sizeof mainJPEGHeader);
00070
00071 unsigned restartMarkerHeaderSize = 0;
00072 if (type >= 64 && type <= 127) {
00073
00074 restartMarkerHeaderSize = 4;
00075 u_int16_t const restartInterval = source->restartInterval();
00076
00077 u_int8_t restartMarkerHeader[4];
00078 restartMarkerHeader[0] = restartInterval>>8;
00079 restartMarkerHeader[1] = restartInterval&0xFF;
00080 restartMarkerHeader[2] = restartMarkerHeader[3] = 0xFF;
00081
00082 setSpecialHeaderBytes(restartMarkerHeader, restartMarkerHeaderSize,
00083 sizeof mainJPEGHeader);
00084 }
00085
00086 if (fragmentationOffset == 0 && source->qFactor() >= 128) {
00087
00088 u_int8_t precision;
00089 u_int16_t length;
00090 u_int8_t const* quantizationTables
00091 = source->quantizationTables(precision, length);
00092
00093 unsigned const quantizationHeaderSize = 4 + length;
00094 u_int8_t* quantizationHeader = new u_int8_t[quantizationHeaderSize];
00095
00096 quantizationHeader[0] = 0;
00097 quantizationHeader[1] = precision;
00098 quantizationHeader[2] = length >> 8;
00099 quantizationHeader[3] = length&0xFF;
00100 if (quantizationTables != NULL) {
00101 for (u_int16_t i = 0; i < length; ++i) {
00102 quantizationHeader[4+i] = quantizationTables[i];
00103 }
00104 }
00105
00106 setSpecialHeaderBytes(quantizationHeader, quantizationHeaderSize,
00107 sizeof mainJPEGHeader + restartMarkerHeaderSize);
00108 delete[] quantizationHeader;
00109 }
00110
00111 if (numRemainingBytes == 0) {
00112
00113
00114 setMarkerBit();
00115 }
00116
00117
00118 setTimestamp(framePresentationTime);
00119 }
00120
00121
00122 unsigned JPEGVideoRTPSink::specialHeaderSize() const {
00123
00124 JPEGVideoSource* source = (JPEGVideoSource*)fSource;
00125 if (source == NULL) return 0;
00126
00127 unsigned headerSize = 8;
00128
00129 u_int8_t const type = source->type();
00130 if (type >= 64 && type <= 127) {
00131
00132 headerSize += 4;
00133 }
00134
00135 if (curFragmentationOffset() == 0 && source->qFactor() >= 128) {
00136
00137 u_int8_t dummy;
00138 u_int16_t quantizationTablesSize;
00139 (void)(source->quantizationTables(dummy, quantizationTablesSize));
00140
00141 headerSize += 4 + quantizationTablesSize;
00142 }
00143
00144 return headerSize;
00145 }