⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jpegvideortpsource.cpp

📁 流媒体传输协议的实现代码,非常有用.可以支持rtsp mms等流媒体传输协议
💻 CPP
📖 第 1 页 / 共 2 页
字号:
  *ptr++ = (BYTE)(h); // number of lines (must be a multiple of 8)  *ptr++ = (BYTE)(w >> 8);  *ptr++ = (BYTE)(w); // number of columns (must be a multiple of 8)  *ptr++ = 0x03; // number of components  *ptr++ = 0x01; // id of component  *ptr++ = type ? 0x22 : 0x21; // sampling ratio (h,v)  *ptr++ = 0x00; // quant table id  *ptr++ = 0x02; // id of component  *ptr++ = 0x11; // sampling ratio (h,v)  *ptr++ = numQtables == 1 ? 0x00 : 0x01; // quant table id  *ptr++ = 0x03; // id of component  *ptr++ = 0x11; // sampling ratio (h,v)  *ptr++ = 0x01; // quant table id    createHuffmanHeader(ptr, lum_dc_codelens, sizeof lum_dc_codelens,		      lum_dc_symbols, sizeof lum_dc_symbols, 0, 0);  createHuffmanHeader(ptr, lum_ac_codelens, sizeof lum_ac_codelens,		      lum_ac_symbols, sizeof lum_ac_symbols, 0, 1);  createHuffmanHeader(ptr, chm_dc_codelens, sizeof chm_dc_codelens,		      chm_dc_symbols, sizeof chm_dc_symbols, 1, 0);  createHuffmanHeader(ptr, chm_ac_codelens, sizeof chm_ac_codelens,		      chm_ac_symbols, sizeof chm_ac_symbols, 1, 1);  // MARKER_SOS:  *ptr++ = 0xFF;  *ptr++ = MARKER_SOS;  *ptr++ = 0x00; *ptr++ = 0x0C; // size of chunk  *ptr++ = 0x03; // number of components  *ptr++ = 0x01; // id of component  *ptr++ = 0x00; // huffman table id (DC, AC)  *ptr++ = 0x02; // id of component  *ptr++ = 0x11; // huffman table id (DC, AC)  *ptr++ = 0x03; // id of component  *ptr++ = 0x11; // huffman table id (DC, AC)  *ptr++ = 0x00; // start of spectral  *ptr++ = 0x3F; // end of spectral  *ptr++ = 0x00; // successive approximation bit position (high, low)}// The default 'luma' and 'chroma' quantizer tables, in zigzag order:static unsigned char const defaultQuantizers[128] = {  // luma table:  16, 11, 12, 14, 12, 10, 16, 14,  13, 14, 18, 17, 16, 19, 24, 40,  26, 24, 22, 22, 24, 49, 35, 37,  29, 40, 58, 51, 61, 60, 57, 51,  56, 55, 64, 72, 92, 78, 64, 68,  87, 69, 55, 56, 80, 109, 81, 87,  95, 98, 103, 104, 103, 62, 77, 113,  121, 112, 100, 120, 92, 101, 103, 99,  // chroma table:  17, 18, 18, 24, 21, 24, 47, 26,  26, 47, 99, 66, 56, 66, 99, 99,  99, 99, 99, 99, 99, 99, 99, 99,  99, 99, 99, 99, 99, 99, 99, 99,  99, 99, 99, 99, 99, 99, 99, 99,  99, 99, 99, 99, 99, 99, 99, 99,  99, 99, 99, 99, 99, 99, 99, 99,  99, 99, 99, 99, 99, 99, 99, 99};static void makeDefaultQtables(unsigned char* resultTables, unsigned Q) {  int factor = Q;  int q;  if (Q < 1) factor = 1;  else if (Q > 99) factor = 99;  if (Q < 50) {    q = 5000 / factor;  } else {    q = 200 - factor*2;  }  for (int i = 0; i < 128; ++i) {    int newVal = (defaultQuantizers[i]*q + 50)/100;    if (newVal < 1) newVal = 1;    else if (newVal > 255) newVal = 255;    resultTables[i] = newVal;  }}Boolean JPEGVideoRTPSource::processSpecialHeader(BufferedPacket* packet,		       unsigned& resultSpecialHeaderSize) {  unsigned char* headerStart = packet->data();  unsigned packetSize = packet->dataSize();  unsigned char* qtables = NULL;  unsigned qtlen = 0;  unsigned dri = 0;  // There's at least 8-byte video-specific header  /*0                   1                   2                   30 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| Type-specific |              Fragment Offset                  |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|      Type     |       Q       |     Width     |     Height    |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  */  if (packetSize < 8) return False;  resultSpecialHeaderSize = 8;  unsigned Offset = (unsigned)((DWORD)headerStart[1] << 16 | (DWORD)headerStart[2] << 8 | (DWORD)headerStart[3]);  unsigned Type = (unsigned)headerStart[4];  unsigned type = Type & 1;  unsigned Q = (unsigned)headerStart[5];  unsigned width = (unsigned)headerStart[6] * 8;  if (width == 0) width = 256*8; // special case  unsigned height = (unsigned)headerStart[7] * 8;  if (height == 0) height = 256*8; // special case  if (Type > 63) {    // Restart Marker header present    /*0                   1                   2                   30 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|       Restart Interval        |F|L|       Restart Count       |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+    */    if (packetSize < resultSpecialHeaderSize + 4) return False;    unsigned RestartInterval = (unsigned)((WORD)headerStart[resultSpecialHeaderSize] << 8 | (WORD)headerStart[resultSpecialHeaderSize + 1]);    dri = RestartInterval;    resultSpecialHeaderSize += 4;  }  if (Offset == 0) {    if (Q > 127) {      // Quantization Table header present/*0                   1                   2                   30 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|      MBZ      |   Precision   |             Length            |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                    Quantization Table Data                    ||                              ...                              |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+*/      if (packetSize < resultSpecialHeaderSize + 4) return False;      unsigned MBZ = (unsigned)headerStart[resultSpecialHeaderSize];      if (MBZ == 0) {	// unsigned Precision = (unsigned)headerStart[resultSpecialHeaderSize + 1];	unsigned Length = (unsigned)((WORD)headerStart[resultSpecialHeaderSize + 2] << 8 | (WORD)headerStart[resultSpecialHeaderSize + 3]);	//ASSERT(Length == 128);	resultSpecialHeaderSize += 4;	if (packetSize < resultSpecialHeaderSize + Length) return False;	if (qtables) delete [] qtables;	qtlen = Length;	qtables = &headerStart[resultSpecialHeaderSize];		resultSpecialHeaderSize += Length;      }    }  }  // If this is the first (or only) fragment of a JPEG frame, then we need  // to synthesize a JPEG header, and prepend it to the incoming data.  // Hack: We can do this because we allowed space for it in  // our special "JPEGBufferedPacket" subclass.  We also adjust  // "resultSpecialHeaderSize" to compensate for this, by subtracting  // the size of the synthesized header.  Note that this will cause  // "resultSpecialHeaderSize" to become negative, but the code that called  // us (in "MultiFramedRTPSource") will handle this properly.  if (Offset == 0) {    unsigned char newQtables[128];    if (qtlen == 0) {      // A quantization table was not present in the RTP JPEG header,      // so use the default tables, scaled according to the "Q" factor:      makeDefaultQtables(newQtables, Q);      qtables = newQtables;      qtlen = sizeof newQtables;    }    unsigned hdrlen = computeJPEGHeaderSize(qtlen, dri);    resultSpecialHeaderSize -= hdrlen; // goes negative    headerStart += (int)resultSpecialHeaderSize; // goes backward    createJPEGHeader(headerStart, type, width, height, qtables, qtlen, dri);  }  fCurrentPacketBeginsFrame = (Offset == 0);  // The RTP "M" (marker) bit indicates the last fragment of a frame:  ((JPEGBufferedPacket*)packet)->completesFrame   = fCurrentPacketCompletesFrame = packet->rtpMarkerBit();  return True;}    char const* JPEGVideoRTPSource::MIMEtype() const {  return "video/JPEG";}////////// JPEGBufferedPacket and JPEGBufferedPacketFactory implementationvoid JPEGBufferedPacket::reset() {  BufferedPacket::reset();  // Move our "fHead" and "fTail" forward, to allow space for a synthesized  // JPEG header to precede the RTP data that comes in over the network.  unsigned offset = MAX_JPEG_HEADER_SIZE;  if (offset > fPacketSize) offset = fPacketSize; // shouldn't happen  fHead = fTail = offset;}unsigned JPEGBufferedPacket::nextEnclosedFrameSize(unsigned char*& framePtr, unsigned dataSize) {  // Normally, the enclosed frame size is just "dataSize".  If, however,  // the frame does not end with the "EOI" marker, then add this now:  if (completesFrame && dataSize >= 2 &&      !(framePtr[dataSize-2] == 0xFF && framePtr[dataSize-1] == MARKER_EOI)) {    framePtr[dataSize++] = 0xFF;    framePtr[dataSize++] = MARKER_EOI;  }  return dataSize;}BufferedPacket* JPEGBufferedPacketFactory::createNewPacket(MultiFramedRTPSource* /*ourSource*/) {  return new JPEGBufferedPacket;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -