void MPEG2TransportFileServerMediaSubsession ::pauseStream(unsigned clientSessionId, void* streamToken) { if (fIndexFile != NULL) { // we support 'trick play' ClientTrickPlayState* client = lookupClient(clientSessionId); if (client != NULL) { client->updateStateOnPlayChange(False); } } // Call the original, default version of this routine: OnDemandServerMediaSubsession::pauseStream(clientSessionId, streamToken); }
void MPEG2TransportFileServerMediaSubsession ::setStreamScale(unsigned clientSessionId, void* streamToken, float scale) { if (fIndexFile != NULL) { // we support 'trick play' ClientTrickPlayState* client = lookupClient(clientSessionId); if (client != NULL) { client->setNextScale(scale); // scale won't take effect until the next "PLAY" } } // Call the original, default version of this routine: OnDemandServerMediaSubsession::setStreamScale(clientSessionId, streamToken, scale); }
void MPEG2TransportFileServerMediaSubsession ::seekStream(unsigned clientSessionId, void* streamToken, float seekNPT) { if (fIndexFile != NULL) { // we support 'trick play' ClientTrickPlayState* client = lookupClient(clientSessionId); if (client != NULL) { client->updateStateFromNPT(seekNPT); } } // Call the original, default version of this routine: OnDemandServerMediaSubsession::seekStream(clientSessionId, streamToken, seekNPT); }
void MPEG2TransportFileServerMediaSubsession ::seekStream(unsigned clientSessionId, void* streamToken, double& seekNPT, double streamDuration, u_int64_t& numBytes) { // Begin by calling the original, default version of this routine: OnDemandServerMediaSubsession::seekStream(clientSessionId, streamToken, seekNPT, streamDuration, numBytes); // Then, special handling specific to indexed Transport Stream files: if (fIndexFile != NULL) { // we support 'trick play' ClientTrickPlayState* client = lookupClient(clientSessionId); if (client != NULL) { unsigned long numTSPacketsToStream = client->updateStateFromNPT(seekNPT, streamDuration); numBytes = numTSPacketsToStream*TRANSPORT_PACKET_SIZE; } } }
void MPEG2TransportFileServerMediaSubsession ::startStream(unsigned clientSessionId, void* streamToken, TaskFunc* rtcpRRHandler, void* rtcpRRHandlerClientData, unsigned short& rtpSeqNum, unsigned& rtpTimestamp) { if (fIndexFile != NULL) { // we support 'trick play' ClientTrickPlayState* client = lookupClient(clientSessionId); if (client != NULL && client->areChangingScale()) { // First, handle this like a "PAUSE", except that we back up to the previous VSH client->updateStateOnPlayChange(True); OnDemandServerMediaSubsession::pauseStream(clientSessionId, streamToken); // Then, adjust for the change of scale: client->updateStateOnScaleChange(); } } // Call the original, default version of this routine: OnDemandServerMediaSubsession::startStream(clientSessionId, streamToken, rtcpRRHandler, rtcpRRHandlerClientData, rtpSeqNum, rtpTimestamp); }
FramedSource *MPEG2TransportFileServerMediaSubsession ::createNewStreamSource(unsigned clientSessionId, unsigned &estBitrate) { // Create the video source: unsigned const inputDataChunkSize = TRANSPORT_PACKETS_PER_NETWORK_PACKET * TRANSPORT_PACKET_SIZE; ByteStreamFileSource *fileSource = ByteStreamFileSource::createNew(envir(), fFileName, inputDataChunkSize); if (fileSource == NULL) return NULL; fFileSize = fileSource->fileSize(); // Use the file size and the duration to estimate the stream's bitrate: if (fFileSize > 0 && fDuration > 0.0) { estBitrate = (unsigned)((int64_t)fFileSize / (125 * fDuration) + 0.5); // kbps, rounded } else { estBitrate = 5000; // kbps, estimate } // Create a framer for the Transport Stream: MPEG2TransportStreamFramer *framer = MPEG2TransportStreamFramer::createNew(envir(), fileSource); if (fIndexFile != NULL) // we support 'trick play' { // Keep state for this client (if we don't already have it): ClientTrickPlayState *client = lookupClient(clientSessionId); if (client == NULL) { client = new ClientTrickPlayState(fIndexFile); fClientSessionHashTable->Add((char const *)clientSessionId, client); } client->setSource(framer); } return framer; }