[Live-devel] JPEG file over RTP

Andy Bell andy at j2kvideo.com
Tue Jun 29 03:37:11 PDT 2010


On Tue, Jun 29, 2010 at 7:28 AM, Ross Finlayson <finlayson at live555.com>wrote:

> The problem is that when I come to decode the stream in VLC the image is
>> far blockier than the original.  Why is this?  What am I doing wrong?
>>
>
> I don't know, in part because you're missing some details about your
> implementation.  In particular, you didn't say anything about your
> implementation of the following pure virtual functions defined for
> "JPEGVideoSource":
>        virtual u_int8_t type() = 0;
>        virtual u_int8_t qFactor() = 0;
>        virtual u_int8_t width() = 0; // # pixels/8 (or 0 for 2048 pixels)
>        virtual u_int8_t height() = 0; // # pixels/8 (or 0 for 2048 pixels)
>
> In any case, though, I suggest that - if possible - you test your system
> first by receiving data into a file (by connecting a "JPEGVideoRTPSource" to
> a "FileSink"), and looking at the resulting data using a JPEG image viewer
> (rather than a media player like VLC). If your server implements RTSP, then
> this is easy: Just run "openRTSP" with the "-m" option.
>

Hi Ross,

TestJPEGVideoSource* TestJPEGVideoSource::createNew(UsageEnvironment& env,
const char * fileName, unsigned int timePerFrame)

{

FILE * fid = fopen( fileName, "r" );

 if ( fid == NULL )

{

env.setResultErrMsg( "Failed to open input device file" );

return NULL;

}

 return new TestJPEGVideoSource( env, fid, timePerFrame );

}


TestJPEGVideoSource::TestJPEGVideoSource(UsageEnvironment& env, FILE* fid,
unsigned int timePerFrame)

: JPEGVideoSource(env), fFid(fid), fTimePerFrame(timePerFrame),
fNeedAFrame(False)

{

this->buffer = NULL;

fseek( fid, 0L, SEEK_END );

size_t sz = ftell( fFid );

fseek( fid, 0L, SEEK_SET );

 buffer = new unsigned char[ sz ];

fread( buffer, 1, sz, fid );

bool sof0 = false;

bool sos = false;

this->sosIndex = 0;

this->sosSize = 0;

 for ( int i = 0; i < (int)(sz - 8); ++i )

{

if ( buffer[i] == 0xFF && buffer[i+1] == 0xC0)

{

fLastHeight = (buffer[i+5]<<5)|(buffer[i+6]>>3);

fLastWidth = (buffer[i+7]<<5)|(buffer[i+8]>>3);

if ( sos && sof0 ) break;

}

else if ( buffer[i] == 0xFF && buffer[i+1] == 0xDA )

{

sosIndex = i + 2;

if ( sos && sof0 ) break;

}

 }

 if ( this->sosIndex > 0 )

this->sosSize = sz - this->sosIndex;

 printf( "Streaming image w=%d h=%d total_size=%d sos_size=%d\n", fLastWidth
* 8, fLastHeight * 8, (int)sz, this->sosSize );

fclose(fFid);

}


TestJPEGVideoSource::~TestJPEGVideoSource()

{

if ( this->buffer ) delete [] buffer;

}


void TestJPEGVideoSource::doGetNextFrame()

{

fFrameSize = this->sosSize;

 if ( fFrameSize > fMaxSize )

{

printf( "Truncating frame!!\n" );

fNumTruncatedBytes = fFrameSize - fMaxSize;

fFrameSize = fMaxSize;

}

 memcpy( fTo, this->buffer + this->sosIndex, fFrameSize );

 if ( fPresentationTime.tv_sec == 0 && fPresentationTime.tv_usec == 0 )

{

gettimeofday( &fPresentationTime, NULL );

}

else

{

unsigned uSeconds = fPresentationTime.tv_usec + ( fTimePerFrame * 1000 );

fPresentationTime.tv_sec += uSeconds / 1000000;

fPresentationTime.tv_usec = uSeconds % 1000000;

}


 fDurationInMicroseconds = fTimePerFrame * 1000;

 nextTask() = envir().taskScheduler().scheduleDelayedTask( 0,
(TaskFunc*)FramedSource::afterGetting, this );

}

u_int8_t TestJPEGVideoSource::type()

{

return 1;

}

u_int8_t TestJPEGVideoSource::qFactor()

{

return 65;

}

u_int8_t TestJPEGVideoSource::width()

{

return fLastWidth;

}

u_int8_t TestJPEGVideoSource::height()

{

return fLastHeight;

}

That's pretty much it.  I have downloaded an image from an RTSP source using
openRTSP saving each frame as a JPG file.  I am the using one these JPG
files to be used as a source for the above code.  I have then connected
using openRTSP to my server streaming back the above source.  I have
attached the 'input' image and the 'output' image of the process.

Thanks, Andy.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.live555.com/pipermail/live-devel/attachments/20100629/efd28719/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: input.jpg
Type: image/jpeg
Size: 15701 bytes
Desc: not available
URL: <http://lists.live555.com/pipermail/live-devel/attachments/20100629/efd28719/attachment-0002.jpg>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: output.jpg
Type: image/jpeg
Size: 15713 bytes
Desc: not available
URL: <http://lists.live555.com/pipermail/live-devel/attachments/20100629/efd28719/attachment-0003.jpg>


More information about the live-devel mailing list