[Live-devel] JPEGVideoRTPSink and Restart markers

Cristiano Belloni belloni at imavis.com
Wed Oct 27 00:51:35 PDT 2010


  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 <http://www.imavis.com>
belloni at imavis.com <mailto://belloni@imavis.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.live555.com/pipermail/live-devel/attachments/20101027/dd3c023d/attachment-0001.html>


More information about the live-devel mailing list