[Live-devel] Question about DeviceSource implementation....

Chin-Fu Tsao cftsao at cmlab.csie.ntu.edu.tw
Mon Feb 23 16:57:15 PST 2004


Dear all,

I try to stream MPEG2 PS over the network polling from
a 656/I2S Capture card (this card will capture the dvd player signal and 
encode it in MPEG2 format) directly.

Now i am making a DeviceSource implementation by modifying 
ByteStreamFileSource and change the fread from doGetNextFrame() to 
Mydevice->Read that implements the read from capture card and than hook 
mydevice implementation into filesink to record my input data into a file 
but i meet some problems. First, the record file seems too bigger and always 
play the same frames (1~3) recursively. it seems that that the donextframe 
always send the same data...

Below you can see MyDeviceSource implementation and Read implementation.
 
Any help will be appreciated !

Alan..


/**Modified from ByteStreamFileSource**/

#if defined(__WIN32__) || defined(_WIN32)
#include <io.h>
#include <fcntl.h>
//#include <winioctl.h> //add for standard windows ioctl
#endif

#include "XCODEDeviceSource.hh"
//#include "XCODEManager.hh" //xcode operations
#include "GroupsockHelper.hh"

////////// MyDeviceSource //////////

XCODEDeviceSource::XCODEDeviceSource(UsageEnvironment& env,
					   Manager* chipsettings,
					   unsigned preferredFrameSize,
					   unsigned playTimePerFrame)
  : FramedSource(env),fPreferredFrameSize(preferredFrameSize),
    fPlayTimePerFrame(playTimePerFrame),fLastPlayTime(0) 
{
     fManager = chipsettings;
}

XCODEDeviceSource::~XCODEDeviceSource() {
}

XCODEDeviceSource*
XCODEDeviceSource::createNew(UsageEnvironment& env,
				Manager* chipsettings,
				unsigned preferredFrameSize,
				unsigned playTimePerFrame) {

  // Open the chip and initialize params
  if (chipsettings->initialize(0,720,480,30000)==-1){
  	    return NULL;}

  do {
    return new XCODEDeviceSource(env, chipsettings,preferredFrameSize,
				 playTimePerFrame);
  } while (0);

  return NULL;
}

#ifdef BSD
static struct timezone Idunno;
#else
static int Idunno;
#endif

void MyDeviceSource::doGetNextFrame() {

  // Try to read as many bytes as will fit in the
  // buffer provided or "fPreferredFrameSize" if less)

  if (fPreferredFrameSize > 0 && fPreferredFrameSize < fMaxSize) {
    fMaxSize = fPreferredFrameSize;
  }


  // Get data from the xcode chip...
  fFrameSize = fManager->receive(fTo,fMaxSize);
  printf ("I have read %i bytes from the card.\n",fFrameSize);

    // Set the 'presentation time':
  if (fPlayTimePerFrame > 0 && fPreferredFrameSize >0) {
    //fprintf ( file, "fPlayTimePerFrame %i > 0 && fPreferredFrameSize %i\n", 
fPlayTimePerFrame,
    //fPreferredFrameSize);
    if (fPresentationTime.tv_sec == 0 && fPresentationTime.tv_usec == 0) {
      // This is the first frame, so use the current time:
      gettimeofday(&fPresentationTime, &Idunno);
    } else {
      // Increment by the play time of the previous data:
      unsigned uSeconds	= fPresentationTime.tv_usec + fLastPlayTime;
      fPresentationTime.tv_sec += uSeconds/1000000;
      fPresentationTime.tv_usec = uSeconds%1000000;
    }

    // Remember the play time of this data:
    fLastPlayTime = (fPlayTimePerFrame*fFrameSize)/fPreferredFrameSize;
    //fprintf ( file, "fLastPlayTime %i\n",fLastPlayTime);
    fDurationInMicroseconds = fLastPlayTime;
  } else {
    // We don't know a specific play time duration for this data,
    // so just record the current time as being the 'presentation time':
    gettimeofday(&fPresentationTime, &Idunno);
  }

  // Switch to another task, and inform the reader that he has data:
  nextTask() = envir().taskScheduler().scheduleDelayedTask(0,
				(TaskFunc*)FramedSource::afterGetting, 
this);
}

int XCODEManager::receive(unsigned char* buffer,unsigned MaxSize){
	uint				rc;
/*
	Reset parameters for the Receive IOCTL
	Note : before the call .size = the amount of space in the buffer, 
	on return .size = the amount of data received in the buffer.
*/
    ioctl_recv_strm.buffer                        = (pvoid)buffer;
    ioctl_recv_strm.flags                         = SDEV_IO_PS |SDEV_IO_VIDEO;
    ioctl_recv_strm.size                          = MaxSize;
    ioctl_recv_strm.stream_handle                 =  
ioctl_open_strm_capture.stream_handle;

	// call IOCTL function to RECEIVE PS data
#ifdef W2K
uint32	v;
    rc = DeviceIoControl((HANDLE)XCodeHandle,
                         IOCTL_CMD,
                         NULL,
                         0,
                         &ioctl_recv_strm,
                         sizeof(IOCTLSDEVRECV),
                         &v,
                         NULL);
#elif LINUX
	rc = ioctl(XCodeHandle, IOCTL_CMD, &ioctl_recv_strm);
#endif
/*
	Received nResult bytes of data in the buffer.
*/
	return(ioctl_recv_strm.size);
	}



More information about the live-devel mailing list