<P>Howdy List !!!</P>
<P>&nbsp;</P>
<P>I'm a student and&nbsp; doing my degree thesis.<BR>I have a little problem on
streaming live video. I'm using the last version of LiveMedia. And currently I
can stream live video and recieve&nbsp; &amp; play with VLC. But only for a few
seconds. After recieving and playing on VLC for a few seconds VLC stops
playback, and in statistic of VLC I can see that VLC start to lost frames. At
least VLC staying online.</P>
<P>As a model I used testMPEG4VideoStreamer. My OS is Win2000 SP4, Devstud is
VC++2005. LiveMedia libs are also built under VC++2005 succesfully, after some
tricks. I have a GUI, so livemedia loop has a own thread, and&nbsp;I can stop
it using watchVarible in any time user want.</P>
<P>So in debugging I see that in first call of doGetNextFrame the
fMaxSize=150000. But in second call the fMaxSize less then 150000. In third
call fMaxSize less then it was in second call. And so on.., As I figured out,
always (curent)fMaxSize=(prev)fMaxSize - (prev)fFrameSize.<BR>For video of
320x280 resolution size of raw frame is 320*280*4=358400 bytes. But encoded
frame size is between 7000 and 15000 bytes. So in each call of doGetNextFrame I
check usb Webcam for a responce and grab current frame. Then call deliverFrame
where grabed frame encoded by encoder, and delivered to fTO,&nbsp; set
fFrameSize to encoded frame size. In each calls fMaxSize becomes less then in
prev call. So, in the end after delivering 13~16 frames fMaxSize becomes less
than encoded frame size. And deliverFrame starts to trancate encoded frame, and
sets fNumTrancatedBytes. It's happen once. And in next call fMaxSize again
becomes equal around of 150000, not bigger. And loop starts again... But for a
while. And programm crashes, more precisly for some reason afterPlaying func is
called...</P>
<P>Here doGetNextFrame and dilverFrame codes. Your suggestions are greatly
appreciated. Thank you.</P>
<P>&nbsp;</P>
<P>void WebCamDeviceSource::doGetNextFrame() {</P>
<P>&nbsp; // Arrange here for our "deliverFrame" member function to be
called<BR>&nbsp; // when the next frame of data becomes available from the
device.<BR>&nbsp; // This must be done in a non-blocking fashion - i.e., so
that we<BR>&nbsp; // return immediately from this function even if no data
is<BR>&nbsp; // currently available.<BR>&nbsp; //<BR>&nbsp; // If the device
can be implemented as a readable socket, then one easy<BR>&nbsp; // way to do
this is using a call to<BR>&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;
envir().taskScheduler().turnOnBackgroundReadHandling( ... )<BR>&nbsp; // (See
examples of this call in the "liveMedia" directory.)</P>
<P>&nbsp;<BR>&nbsp;</P>
<P>&nbsp; // If, for some reason, the source device stops being
readable<BR>&nbsp; // (e.g., it gets closed), then you do the
following:<BR>&nbsp; if (NULL == m_NCvideo.GrabCurrentFrame() /* the source
stops being readable */) {<BR>&nbsp;&nbsp;&nbsp;
handleClosure(this);<BR>&nbsp;::MessageBoxA(NULL,"In Grab Image V4l, the source
stops being readable !!!!","Error",MB_OK);<BR>&nbsp;&nbsp;&nbsp;
return;<BR>&nbsp; }<BR>&nbsp;&nbsp;&nbsp; deliverFrame();<BR>}</P>
<P>void WebCamDeviceSource::deliverFrame() {<BR>&nbsp; // This would be called
when new frame data is available from the device.<BR>&nbsp; // This function
should deliver the next frame of data from the device,<BR>&nbsp; // using the
following parameters (class members):<BR>&nbsp; // 'in' parameters (these
should *not* be modified by this function):<BR>&nbsp;
//&nbsp;&nbsp;&nbsp;&nbsp; fTo: The frame data is copied to this
address.<BR>&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (Note
that the variable "fTo" is *not* modified.&nbsp; Instead,<BR>&nbsp;
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the frame data is
copied to the address pointed to by "fTo".)<BR>&nbsp;
//&nbsp;&nbsp;&nbsp;&nbsp; fMaxSize: This is the maximum number of bytes that
can be copied<BR>&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (If
the actual frame is larger than this, then it should<BR>&nbsp;
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; be truncated, and
"fNumTruncatedBytes" set accordingly.)<BR>&nbsp; <BR>&nbsp; // 'out' parameters
(these are modified by this function):<BR>&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;
fFrameSize: Should be set to the delivered frame size (&lt;=
fMaxSize).<BR>&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp; fNumTruncatedBytes: Should be
set iff the delivered frame would have been<BR>&nbsp;
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bigger than "fMaxSize", in
which case it's set to the number of bytes<BR>&nbsp;
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; that have been
omitted.<BR>&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp; fPresentationTime: Should be set
to the frame's presentation time<BR>&nbsp;
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (seconds,
microseconds).<BR>&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp; fDurationInMicroseconds:
Should be set to the frame's duration, if known.<BR>&nbsp; if
(!isCurrentlyAwaitingData()){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return; //
we're not ready for the data yet<BR>&nbsp; }<BR>&nbsp; // Deliver the data
here:<BR>&nbsp;&nbsp; </P>
<P>&nbsp;&nbsp;&nbsp; // Draw and encode each frame.</P>
<P><BR>&nbsp;&nbsp; SIZE s=m_NCvideo.GetResolution();<BR>&nbsp;&nbsp;&nbsp;
m_Revelframe.width = (int)s.cx;<BR>&nbsp;&nbsp;&nbsp; m_Revelframe.height =
(int)s.cy;<BR>&nbsp;&nbsp;&nbsp; m_Revelframe.bytesPerPixel =
4;<BR>&nbsp;&nbsp;&nbsp; m_Revelframe.pixelFormat =
REVEL_PF_RGBA;<BR>&nbsp;&nbsp;&nbsp; m_Revelframe.pixels = new
int[m_Revelframe.width*m_Revelframe.height*4];<BR>&nbsp;&nbsp;&nbsp;
memset(m_Revelframe.pixels, 0, m_Revelframe.width*m_Revelframe.height*4);</P>
<P>&nbsp;if(m_NCvideo.GetBufferUsed() &gt;
(long)m_Revelframe.width*m_Revelframe.height*4)<BR>&nbsp;{<BR>&nbsp;&nbsp;::MessageBoxA(NULL,"m_NCvideo.GetBufferUsed()
&gt; (long)m_Revelframe.width*m_Revelframe.height*4","Internel
error",MB_OK);<BR>&nbsp;&nbsp;exit(1);<BR>&nbsp;}</P>
<P>&nbsp;::memcpy(m_Revelframe.pixels,m_NCvideo.GetBufferPointer(),m_NCvideo.GetBufferUsed());</P>
<P><BR>&nbsp;int
frameSize=0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
m_RevelError = Revel_EncodeFrame(m_RevelEncoderHandle, &amp;m_Revelframe,
&amp;frameSize);<BR>&nbsp;&nbsp;&nbsp; &nbsp;if (m_RevelError !=
REVEL_ERR_NONE)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
{<BR>&nbsp;&nbsp;&nbsp;::MessageBoxA(NULL,"Revel Error while encode frame: ",
"Error",MB_OK);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
exit(1);<BR>&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;if((fMaxSize) &lt; frameSize)<BR>&nbsp;{<BR>&nbsp;&nbsp;//"fMaxSize
&lt; framSize so trancate it !!!
<BR>&nbsp;&nbsp;//exit(1);<BR>&nbsp;&nbsp;::memcpy(fTo,
m_Revelframe.pixels,fMaxSize);<BR>&nbsp;&nbsp;fNumTruncatedBytes=frameSize-fMaxSize;<BR>&nbsp;&nbsp;fFrameSize=fMaxSize;<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;<BR>&nbsp;}<BR>&nbsp;else&nbsp;
<BR>&nbsp;{<BR>&nbsp;&nbsp;::memcpy(fTo,
m_Revelframe.pixels,frameSize);<BR>&nbsp;&nbsp;fFrameSize=frameSize;<BR>&nbsp;&nbsp;<BR>&nbsp;}<BR>&nbsp;</P>
<P>&nbsp;</P>
<P>&nbsp;&nbsp;&nbsp; delete []
(int*)m_Revelframe.pixels;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp; // After
delivering the data, switch to another task, and inform<BR>&nbsp; // the reader
that he has data:<BR>&nbsp;// ::MessageBoxA(NULL,"DeliverFrame: successly
delivered!!!!"," !!!!!!!!!!!",MB_OK);<BR>&nbsp;
FramedSource::afterGetting(this);</P>
<P><BR>}</P>