[Live-devel] How to create a custom sink that streams to both the network and a local file

Hoang Bui Vu buivuhoang15 at gmail.com
Mon Dec 19 02:46:38 PST 2011


Hi Ross,
Thank you very much for your attention.
I am facing with some kind of difficulties, because I don't know what is
missing, the data just seems not to be fed to the output of the filter.

That looks fine - but don't forget to enter the event loop, by calling
> env->taskScheduler().doEventLoop();
> at the end of this code, otherwise nothing will happen.


Actually I am using the code of the testMPEG4VideoStreamer, so that
function is called after play(), in the main function.
        *env << "Beginning streaming...\n";
play();
env->taskScheduler().doEventLoop(); // does not return

What I am confused about is when replacing historyFilter with videoSource
in videoSink->startPlaying, then it works perfectly.

videoSink->startPlaying(*historyFilter, afterPlaying, videoSink);

This indicates that the problem is somewhere within the filter class
itself, however, as I said before, I couldn't find anything out of order.

On Mon, Dec 19, 2011 at 4:51 AM, Ross Finlayson <finlayson at live555.com>wrote:

> I have been playing with the FramedFilter class for a while, and created a
> simple filter that will just deliver its input to its output. However, it
> is not working for some reason. Can you point me to the point that I'm
> missing?
>
> [...]
>
> void HistoryFilter::doGetNextFrame()
> {
> fFrameSize=0;
>
> You don't need to do this here (although it does no harm), because you are
> (properly) setting "fFrameSize" later, in your 'after getting' function.
>
> void HistoryFilter::afterGettingFrame(void* clientData, unsigned
>  frameSize, unsigned /*numTruncatedBytes*/, struct timeval
>  presentationTime, unsigned /*durationInMicroseconds*/)
> {
> HistoryFilter* filter = (HistoryFilter*)clientData;
>  filter->afterGettingFrame1(frameSize, presentationTime);
> }
>
> void HistoryFilter::afterGettingFrame1(unsigned frameSize, struct timeval
> presentationTime)
> {
> fFrameSize = frameSize;
> fPresentationTime = presentationTime;
>  afterGetting(this);
> }
>
>
> Your filter also needs to be setting "fNumTruncatedBytes" and
> "fDurationInMicroseconds" (in your case, because you're making a direct
> copy, these will be the values of the "numTruncatedBytes" and
> "durationInMicroseconds" parameters, respectively).
>
>
> In my main server play() function, I put in this code:
>
> FramedSource* videoES = fileSource;
> // Create a framer for the Video Elementary Stream:
> videoSource = MPEG4VideoStreamFramer::createNew(*env, videoES);
> historyFilter = HistoryFilter::createNew(*env, videoSource, "history.mp4");
> // Finally, start playing:
> *env << "Beginning to read from file...\n";
> videoSink->startPlaying(*historyFilter, afterPlaying, videoSink);
>
>
> That looks fine - but don't forget to enter the event loop, by calling
> env->taskScheduler().doEventLoop();
> at the end of this code, otherwise nothing will happen.  (In a
> LIVE555-based application, almost everything gets done within the event
> loop).
>
>
> Ross Finlayson
> Live Networks, Inc.
> http://www.live555.com/
>
>
> _______________________________________________
> live-devel mailing list
> live-devel at lists.live555.com
> http://lists.live555.com/mailman/listinfo/live-devel
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.live555.com/pipermail/live-devel/attachments/20111219/52acb6ca/attachment.html>


More information about the live-devel mailing list