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>
bell...@imavis.com <mailto://bell...@imavis.com>
_______________________________________________
live-devel mailing list
live-devel@lists.live555.com
http://lists.live555.com/mailman/listinfo/live-devel