I'm dealing with Onvif too and I need to extend JPEGVideoSource, call it 
JPEGVideoSourceEx. How to make the MediaSubsession create a JPEGVideoSourceEx 
class instead of a JPEGVideoSource.

Thank you,

    Renato MAURO

  ----- Original Message ----- 
  From: Cristiano Belloni 
  To: LIVE555 Streaming Media - development & use 
  Sent: Wednesday, October 27, 2010 9:51 AM
  Subject: Re: [Live-devel] JPEGVideoRTPSink and Restart markers


  Il 27/10/2010 02:39, Ross Finlayson ha scritto: 
      I'm trying to create a rtsp server to stream MJPEG images. 


    Ugh.  JPEG is a *terrible* codec for video streaming. 


  I agree, but *everyone* requests JPEG as an entry point. Onvif, for example, 
requests MJPEG/RTP streaming as a MUST IMPLEMENT.





       I have implemented a new TestJPEGFileServerMediaSubsession that creates 
a TestJPEGVideoRTPSink. 

      In TestJPEGVideoRTPSink::doSpecialFrameHandling I'm adding the 
quantization tables of the image into the header using setSpecialHeaderBytes 


    Note that the existing "JPEGVideoRTPSink" code already does this. You 
should not have to reinvent the wheel here. 



      This is working fine using some JPEG images, but fails with others. 

      I'm testing one image that has the marker 0xFF, 0xDD ( Define Restart 
Interval) and I think I have to do something else seeing this comment in the 
code 

      // Note: We assume that there are no 'restart markers' 

      So, what should I do with images containing restart markers and 
macroblocks? 


    The JPEG transmitting code ("JPEGVideoSource" and "JPEGVideoRTPSink") 
currently don't support "Restart Marker Headers" (see RFC 2435, section 3.1.7). 
 You will need to update the (definition and implementation) of these two 
classes to support them. 

  I did something similar, Francisco. In a nutshell, you've got to extend 
JPEGVideoSource and look for DRI markers like this:

   //Look for the DRI marker
      for (unsigned i = 0; i < JPEGHeaderSize; ++i) {
          if (fBuffer[i] == 0xFF) {
              if (fBuffer[i+1] == 0xDD) { // DRI
                  if ((fBuffer[i+2] != 0) || (fBuffer[i+3] != 4)) {
                      envir() << "Wrong DRI marker!\n";
                      continue;
                  }
                  else {
                      fRestartInterval = (fBuffer[i+4] << 8) + fBuffer[i+5];
                      printf ("DRI restart Interval found @ %d is %d\n", i, 
fRestartInterval);
                      break;
                  }
              }
          }
      }

  Then, extend JPEGVideoRTPSink to take care about the restart markers in 
doSpecialFrameHandling():
  (In reality, here I extended VideoRTPSink because I needed to, feel free to 
do your adaptations)

  u_int8_t RestartMarkerHeader[4]; // the special header
  u_int16_t restartInterval = source->restartInterval();

  RestartMarkerHeader[0] = restartInterval >> 8;
  RestartMarkerHeader[1] = restartInterval;
  RestartMarkerHeader[2] = 0xFF;
  RestartMarkerHeader[3] = 0xFF;

  setSpecialHeaderBytes(RestartMarkerHeader, sizeof RestartMarkerHeader, sizeof 
mainJPEGHeader /* start position */);

  Finally, reflect the size change in the headers in specialHeaderSize():

  // We assume that there are 'restart markers'
  headerSize += 4;


  -- 
  Belloni Cristiano
  Imavis Srl.
  www.imavis.com
  bell...@imavis.com



------------------------------------------------------------------------------


  _______________________________________________
  live-devel mailing list
  live-devel@lists.live555.com
  http://lists.live555.com/mailman/listinfo/live-devel
_______________________________________________
live-devel mailing list
live-devel@lists.live555.com
http://lists.live555.com/mailman/listinfo/live-devel

Reply via email to