<div style="line-height:1.7;color:#000000;font-size:14px;font-family:arial"><DIV style="LINE-HEIGHT: 1.7; FONT-FAMILY: arial; COLOR: #000000; FONT-SIZE: 14px">
<P>hi,experts </P>
<P>i modify DeviceSource.cpp to stream a live encoder,but i find triggerEvent could not trigger <BR>deliverFrame0 function which is registered by eventTriggerId = env.taskScheduler().createEventTrigger(deliverFrame0);<BR>what is wrong with me? <BR>because my encoder has multi channel,i have to modify static variable EventTriggerId to non-static<BR>here is my code<BR>//***********************************************************<BR>#include "DeviceSource.hh"<BR>#include <GroupsockHelper.hh> // for "gettimeofday()"</P>
<P>DeviceSource*<BR>DeviceSource::createNew(UsageEnvironment& env /*,<BR>   DeviceParameters params*/) {<BR>  return new DeviceSource(env/*, params*/);<BR>}<BR>//for non-static eventtriggerid<BR>//EventTriggerId DeviceSource::eventTriggerId = 0;<BR>//unsigned DeviceSource::referenceCount = 0;</P>
<P><BR>DeviceSource::DeviceSource(UsageEnvironment& env/*,<BR>      DeviceParameters params*/)<BR>  : FramedSource(env)/*, fParams(params)*/ {<BR>//****************************************<BR>/*  <BR> if (referenceCount == 0) {<BR>    // Any global initialization of the device would be done here:<BR>    //%%% TO BE WRITTEN %%%<BR>  }<BR>  ++referenceCount;<BR>*/<BR>//***********************************</P>
<P>  // Any instance-specific initialization of the device would be done here:<BR>  //%%% TO BE WRITTEN %%%</P>
<P>  // We arrange here for our "deliverFrame" member function to be called<BR>  // whenever the next frame of data becomes available from the device.<BR>  //<BR>  // If the device can be accessed as a readable socket, then one easy way to do this is using a call to<BR>  //     envir().taskScheduler().turnOnBackgroundReadHandling( ... )<BR>  // (See examples of this call in the "liveMedia" directory.)<BR>  //<BR>  // If, however, the device *cannot* be accessed as a readable socket, then instead we can implement it using 'event triggers':<BR>  // Create an 'event trigger' for this device (if it hasn't already been done):<BR>  if (eventTriggerId == 0) {<BR>    eventTriggerId = env.taskScheduler().createEventTrigger(deliverFrame0);<BR>  }<BR>}</P>
<P>DeviceSource::~DeviceSource() {<BR>  // Any instance-specific 'destruction' (i.e., resetting) of the device would be done here:<BR>  //%%% TO BE WRITTEN %%%</P>
<P>  //*****************************<BR>  /*--referenceCount;<BR>  if (referenceCount == 0) {*/<BR>    // Any global 'destruction' (i.e., resetting) of the device would be done here:<BR>    //%%% TO BE WRITTEN %%%</P>
<P>    // Reclaim our 'event trigger'<BR>    envir().taskScheduler().deleteEventTrigger(eventTriggerId);<BR>    eventTriggerId = 0;<BR> //************************************* }<BR>}</P>
<P>void DeviceSource::doGetNextFrame() {</P>
<P>}</P>
<P>void DeviceSource::deliverFrame0(void* clientData) {</P>
<P> ((DeviceSource*)clientData)->deliverFrame();<BR>  return;<BR>}</P>
<P>void DeviceSource::deliverFrame() {<BR>  // This function is called when new frame data is available from the device.<BR>  // We deliver this data by copying it to the 'downstream' object, using the following parameters (class members):<BR>  // 'in' parameters (these should *not* be modified by this function):<BR>  //     fTo: The frame data is copied to this address.<BR>  //         (Note that the variable "fTo" is *not* modified.  Instead,<BR>  //          the frame data is copied to the address pointed to by "fTo".)<BR>  //     fMaxSize: This is the maximum number of bytes that can be copied<BR>  //         (If the actual frame is larger than this, then it should<BR>  //          be truncated, and "fNumTruncatedBytes" set accordingly.)<BR>  // 'out' parameters (these are modified by this function):<BR>  //     fFrameSize: Should be set to the delivered frame size (<= fMaxSize).<BR>  //     fNumTruncatedBytes: Should be set iff the delivered frame would have been<BR>  //         bigger than "fMaxSize", in which case it's set to the number of bytes<BR>  //         that have been omitted.<BR>  //     fPresentationTime: Should be set to the frame's presentation time<BR>  //         (seconds, microseconds).  This time must be aligned with 'wall-clock time' - i.e., the time that you would get<BR>  //         by calling "gettimeofday()".<BR>  //     fDurationInMicroseconds: Should be set to the frame's duration, if known.<BR>  //         If, however, the device is a 'live source' (e.g., encoded from a camera or microphone), then we probably don't need<BR>  //         to set this variable, because - in this case - data will never arrive 'early'.<BR>  // Note the code below.<BR> <BR>//***************************************************<BR>  if (!isCurrentlyAwaitingData()) {return;} // we're not ready for the data yet</P>
<P>  // Deliver the data here:<BR>  if (newFrameSize > fMaxSize) {<BR>    fFrameSize = fMaxSize;<BR>    fNumTruncatedBytes = newFrameSize - fMaxSize;<BR>  } else {<BR>    fFrameSize = newFrameSize; <BR>  }<BR>  //gettimeofday(&fPresentationTime, NULL); // If you have a more accurate time - e.g., from an encoder - then use that instead.<BR>  // If the device is *not* a 'live source' (e.g., it comes instead from a file or buffer), then set "fDurationInMicroseconds" here.<BR>  memmove(fTo, newFrameDataStart, fFrameSize);<BR>  requestData = true; <BR>  // After delivering the data, inform the reader that it is now available:<BR>  FramedSource::afterGetting(this);<BR>//***************************************************<BR>}<BR>void DeviceSource::signalNewFrameData(UsageEnvironment* ourenv,DeviceSource* ourDevice) {<BR>  //TaskScheduler ourScheduler ;<BR>  //ourScheduler = env->taskScheduler(); //%%% TO BE WRITTEN %%%<BR>  //DeviceSource* ourDevice  = NULL; //%%% TO BE WRITTEN %%%</P>
<P>  //if (ourScheduler != NULL) { // sanity check<BR>    ourenv->taskScheduler().triggerEvent(ourDevice->eventTriggerId, ourDevice);<BR>  //}<BR>}</P>
<P><BR>here is DeviceSource.hh</P>
<P>/**********<BR>This library is free software; you can redistribute it and/or modify it under<BR>the terms of the GNU Lesser General Public License as published by the<BR>Free Software Foundation; either version 2.1 of the License, or (at your<BR>option) any later version. (See <<A href="http://www.gnu.org/copyleft/lesser.html">http://www.gnu.org/copyleft/lesser.html</A>>.)</P>
<P>This library is distributed in the hope that it will be useful, but WITHOUT<BR>ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS<BR>FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for<BR>more details.</P>
<P>You should have received a copy of the GNU Lesser General Public License<BR>along with this library; if not, write to the Free Software Foundation, Inc.,<BR>51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA<BR>**********/<BR>// "liveMedia"<BR>// Copyright (c) 1996-2011 Live Networks, Inc.  All rights reserved.<BR>// A template for a MediaSource encapsulating an audio/video input device<BR>// <BR>// NOTE: Sections of this code labeled "%%% TO BE WRITTEN %%%" are incomplete, and needto be written by the programmer<BR>// (depending on the features of the particulardevice).<BR>// C++ header</P>
<P>#ifndef _DEVICE_SOURCE_HH<BR>#define _DEVICE_SOURCE_HH</P>
<P>#ifndef _FRAMED_SOURCE_HH<BR>#include "FramedSource.hh"<BR>#endif</P>
<P>// The following class can be used to define specific encoder parameters<BR>/*class DeviceParameters {<BR>  //%%% TO BE WRITTEN %%%<BR>};*/</P>
<P>class DeviceSource: public FramedSource {<BR>public:<BR>  static DeviceSource* createNew(UsageEnvironment& env /*,<BR>     DeviceParameters params*/);</P>
<P>public:<BR>  //static EventTriggerId eventTriggerId; <BR> EventTriggerId eventTriggerId; //here change static into non-static<BR>protected:<BR>  DeviceSource(UsageEnvironment& env /*, DeviceParameters params*/);<BR>  // called only by createNew(), or by subclass constructors<BR>  virtual ~DeviceSource();</P>
<P>private:<BR>  // redefined virtual functions:<BR>  virtual void doGetNextFrame();</P>
<P>private:<BR>  static void deliverFrame0(void* clientData); <BR>public:<BR>  void signalNewFrameData(UsageEnvironment* env,DeviceSource* ourDevice);//new func added by me<BR>public:<BR>  void deliverFrame();</P>
<P>private:<BR>  //static unsigned referenceCount; // used to count how many instances of this class currently exist<BR>  //DeviceParameters fParams; <BR>public:<BR>   bool requestData; <BR>public:<BR>  u_int8_t* newFrameDataStart; <BR>  unsigned newFrameSize; <BR>};</P>
<P>#endif</P>
<P> </P>
<P>at last,here is my main code part</P>
<P>note that DVRChSource[i]'s type is DeviceSource *<BR>......<BR>     if(DVRChSource[i]->requestData){<BR> <BR>      DVRChSource[i]->newFrameDataStart=(u_int8_t*)ChannelBuffer[i];<BR>      DVRChSource[i]->newFrameSize=ChannelBufferSize[i];<BR>       <BR>      DVRChSource[i]->requestData=false; <BR>      //env->taskScheduler().triggerEvent(DVRChSource[i]->eventTriggerId, DVRChSource[i]);  <BR>      <BR>      DVRChSource[i]->signalNewFrameData(env,DVRChSource[i]);</P>
<P>     }<BR>......</P>
<P>i debug and trace these code,i find deliverFrame0 could not be triggered <BR>after ourenv->taskScheduler().triggerEvent(ourDevice->eventTriggerId, ourDevice); executed.<BR>any light or any DeviceSource sample would be appreciated.thanks a lot.</P>
<P>jounin</P></DIV><BR><BR><SPAN title="neteasefooter"><SPAN id="netease_mail_footer"></SPAN></SPAN></div><br><br><span title="neteasefooter"><span id="netease_mail_footer"></span></span>