liveMedia/MPEG4VideoFileServerMediaSubsession.cpp

Go to the documentation of this file.
00001 /**********
00002 This library is free software; you can redistribute it and/or modify it under
00003 the terms of the GNU Lesser General Public License as published by the
00004 Free Software Foundation; either version 2.1 of the License, or (at your
00005 option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
00006 
00007 This library is distributed in the hope that it will be useful, but WITHOUT
00008 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00009 FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
00010 more details.
00011 
00012 You should have received a copy of the GNU Lesser General Public License
00013 along with this library; if not, write to the Free Software Foundation, Inc.,
00014 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00015 **********/
00016 // "liveMedia"
00017 // Copyright (c) 1996-2008 Live Networks, Inc.  All rights reserved.
00018 // A 'ServerMediaSubsession' object that creates new, unicast, "RTPSink"s
00019 // on demand, from a MPEG-4 video file.
00020 // Implementation
00021 
00022 #include "MPEG4VideoFileServerMediaSubsession.hh"
00023 #include "MPEG4ESVideoRTPSink.hh"
00024 #include "ByteStreamFileSource.hh"
00025 #include "MPEG4VideoStreamFramer.hh"
00026 
00027 MPEG4VideoFileServerMediaSubsession*
00028 MPEG4VideoFileServerMediaSubsession::createNew(UsageEnvironment& env,
00029                                                char const* fileName,
00030                                                Boolean reuseFirstSource) {
00031   return new MPEG4VideoFileServerMediaSubsession(env, fileName, reuseFirstSource);
00032 }
00033 
00034 MPEG4VideoFileServerMediaSubsession
00035 ::MPEG4VideoFileServerMediaSubsession(UsageEnvironment& env,
00036                                       char const* fileName, Boolean reuseFirstSource)
00037   : FileServerMediaSubsession(env, fileName, reuseFirstSource),
00038     fDoneFlag(0) {
00039 }
00040 
00041 MPEG4VideoFileServerMediaSubsession
00042 ::~MPEG4VideoFileServerMediaSubsession() {
00043 }
00044 
00045 static void afterPlayingDummy(void* clientData) {
00046   MPEG4VideoFileServerMediaSubsession* subsess
00047     = (MPEG4VideoFileServerMediaSubsession*)clientData;
00048   subsess->afterPlayingDummy1();
00049 }
00050 
00051 void MPEG4VideoFileServerMediaSubsession::afterPlayingDummy1() {
00052   // Unschedule any pending 'checking' task:
00053   envir().taskScheduler().unscheduleDelayedTask(nextTask());
00054   // Signal the event loop that we're done:
00055   setDoneFlag();
00056 }
00057 
00058 static void checkForAuxSDPLine(void* clientData) {
00059   MPEG4VideoFileServerMediaSubsession* subsess
00060     = (MPEG4VideoFileServerMediaSubsession*)clientData;
00061   subsess->checkForAuxSDPLine1();
00062 }
00063 
00064 void MPEG4VideoFileServerMediaSubsession::checkForAuxSDPLine1() {
00065   if (fDummyRTPSink->auxSDPLine() != NULL) {
00066     // Signal the event loop that we're done:
00067     setDoneFlag();
00068   } else {
00069     // try again after a brief delay:
00070     int uSecsToDelay = 100000; // 100 ms
00071     nextTask() = envir().taskScheduler().scheduleDelayedTask(uSecsToDelay,
00072                               (TaskFunc*)checkForAuxSDPLine, this);
00073   }
00074 }
00075 
00076 char const* MPEG4VideoFileServerMediaSubsession
00077 ::getAuxSDPLine(RTPSink* rtpSink, FramedSource* inputSource) {
00078   // Note: For MPEG-4 video files, the 'config' information isn't known
00079   // until we start reading the file.  This means that "rtpSink"s
00080   // "auxSDPLine()" will be NULL initially, and we need to start reading
00081   // data from our file until this changes.
00082   fDummyRTPSink = rtpSink;
00083     
00084   // Start reading the file:
00085   fDummyRTPSink->startPlaying(*inputSource, afterPlayingDummy, this);
00086     
00087   // Check whether the sink's 'auxSDPLine()' is ready:
00088   checkForAuxSDPLine(this);
00089     
00090   envir().taskScheduler().doEventLoop(&fDoneFlag);
00091     
00092   char const* auxSDPLine = fDummyRTPSink->auxSDPLine();
00093   return auxSDPLine;
00094 }
00095 
00096 FramedSource* MPEG4VideoFileServerMediaSubsession
00097 ::createNewStreamSource(unsigned /*clientSessionId*/, unsigned& estBitrate) {
00098   estBitrate = 500; // kbps, estimate
00099 
00100   // Create the video source:
00101   ByteStreamFileSource* fileSource
00102     = ByteStreamFileSource::createNew(envir(), fFileName);
00103   if (fileSource == NULL) return NULL;
00104   fFileSize = fileSource->fileSize();
00105 
00106   // Create a framer for the Video Elementary Stream:
00107   return MPEG4VideoStreamFramer::createNew(envir(), fileSource);
00108 }
00109 
00110 RTPSink* MPEG4VideoFileServerMediaSubsession
00111 ::createNewRTPSink(Groupsock* rtpGroupsock,
00112                    unsigned char rtpPayloadTypeIfDynamic,
00113                    FramedSource* /*inputSource*/) {
00114   return MPEG4ESVideoRTPSink::createNew(envir(), rtpGroupsock,
00115                                         rtpPayloadTypeIfDynamic);
00116 }

Generated on Tue Jul 22 06:39:06 2008 for live by  doxygen 1.5.2