[Live-devel] Streaming Live Video. But only for a few sec.

Till May vahaha at pisem.net
Sat Apr 7 04:25:33 PDT 2007



  Howdy List !!! 

  I'm a student and  doing my degree thesis.
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  & 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. 

  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 I can stop it using watchVarible in any time user
want. 

  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.
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,  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... 

  Here doGetNextFrame and dilverFrame codes. Your suggestions are
greatly appreciated. Thank you. 

  void WebCamDeviceSource::doGetNextFrame() { 

    // Arrange here for our "deliverFrame" member function to be
called
  // when the next frame of data becomes available from the device.
  // This must be done in a non-blocking fashion - i.e., so that we
  // return immediately from this function even if no data is
  // currently available.
  //
  // If the device can be implemented as a readable socket, then one
easy
  // way to do this is using a call to
  //     envir().taskScheduler().turnOnBackgroundReadHandling( ... )
  // (See examples of this call in the "liveMedia" directory.) 

    // If, for some reason, the source device stops being readable
  // (e.g., it gets closed), then you do the following:
  if (NULL == m_NCvideo.GrabCurrentFrame() /* the source stops being
readable */) {
    handleClosure(this);
 ::MessageBoxA(NULL,"In Grab Image V4l, the source stops being
readable !!!!","Error",MB_OK);
    return;
  }
    deliverFrame();
} 

  void WebCamDeviceSource::deliverFrame() {
  // This would be called when new frame data is available from the
device.
  // This function should deliver the next frame of data from the
device,
  // using the following parameters (class members):
  // 'in' parameters (these should *not* be modified by this
function):
  //     fTo: The frame data is copied to this address.
  //         (Note that the variable "fTo" is *not* modified. 
Instead,
  //          the frame data is copied to the address pointed to by
"fTo".)
  //     fMaxSize: This is the maximum number of bytes that can be
copied
  //         (If the actual frame is larger than this, then it should
  //          be truncated, and "fNumTruncatedBytes" set
accordingly.)

  // 'out' parameters (these are modified by this function):
  //     fFrameSize: Should be set to the delivered frame size (<=
fMaxSize).
  //     fNumTruncatedBytes: Should be set iff the delivered frame
would have been
  //         bigger than "fMaxSize", in which case it's set to the
number of bytes
  //         that have been omitted.
  //     fPresentationTime: Should be set to the frame's presentation
time
  //         (seconds, microseconds).
  //     fDurationInMicroseconds: Should be set to the frame's
duration, if known.
  if (!isCurrentlyAwaitingData()){
      return; // we're not ready for the data yet
  }
  // Deliver the data here:

      // Draw and encode each frame. 

   SIZE s=m_NCvideo.GetResolution();
    m_Revelframe.width = (int)s.cx;
    m_Revelframe.height = (int)s.cy;
    m_Revelframe.bytesPerPixel = 4;
    m_Revelframe.pixelFormat = REVEL_PF_RGBA;
    m_Revelframe.pixels = new
int[m_Revelframe.width*m_Revelframe.height*4];
    memset(m_Revelframe.pixels, 0,
m_Revelframe.width*m_Revelframe.height*4); 

   if(m_NCvideo.GetBufferUsed() >
(long)m_Revelframe.width*m_Revelframe.height*4)
 {
  ::MessageBoxA(NULL,"m_NCvideo.GetBufferUsed() >
(long)m_Revelframe.width*m_Revelframe.height*4","Internel
error",MB_OK);
  exit(1);
 } 

  
::memcpy(m_Revelframe.pixels,m_NCvideo.GetBufferPointer(),m_NCvideo.GetBufferUsed());


 int frameSize=0;
           m_RevelError = Revel_EncodeFrame(m_RevelEncoderHandle,
&m_Revelframe, &frameSize);
     if (m_RevelError != REVEL_ERR_NONE)
        {
   ::MessageBoxA(NULL,"Revel Error while encode frame: ",
"Error",MB_OK);
         exit(1);
     } 

   if((fMaxSize) < frameSize)
 {
  //"fMaxSize < framSize so trancate it !!! 
  //exit(1);
  ::memcpy(fTo, m_Revelframe.pixels,fMaxSize);
  fNumTruncatedBytes=frameSize-fMaxSize;
  fFrameSize=fMaxSize;

 }
 else  
 {
  ::memcpy(fTo, m_Revelframe.pixels,frameSize);
  fFrameSize=frameSize;

 }

      delete [] (int*)m_Revelframe.pixels;      
  // After delivering the data, switch to another task, and inform
  // the reader that he has data:
 // ::MessageBoxA(NULL,"DeliverFrame: successly delivered!!!!","
!!!!!!!!!!!",MB_OK);
  FramedSource::afterGetting(this); 

}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.live555.com/pipermail/live-devel/attachments/20070407/e9b08ebb/attachment-0001.html 


More information about the live-devel mailing list