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