void AudioTrackEncoder::NotifyQueuedTrackChanges(MediaStreamGraph* aGraph, TrackID aID, StreamTime aTrackOffset, uint32_t aTrackEvents, const MediaSegment& aQueuedMedia) { if (mCanceled) { return; } const AudioSegment& audio = static_cast<const AudioSegment&>(aQueuedMedia); // Check and initialize parameters for codec encoder. if (!mInitialized) { mInitCounter++; TRACK_LOG(LogLevel::Debug, ("Init the audio encoder %d times", mInitCounter)); AudioSegment::ChunkIterator iter(const_cast<AudioSegment&>(audio)); while (!iter.IsEnded()) { AudioChunk chunk = *iter; // The number of channels is determined by the first non-null chunk, and // thus the audio encoder is initialized at this time. if (!chunk.IsNull()) { nsresult rv = Init(chunk.mChannelData.Length(), aGraph->GraphRate()); if (NS_FAILED(rv)) { LOG("[AudioTrackEncoder]: Fail to initialize the encoder!"); NotifyCancel(); } break; } iter.Next(); } mNotInitDuration += aQueuedMedia.GetDuration(); if (!mInitialized && (mNotInitDuration / aGraph->GraphRate() > INIT_FAILED_DURATION) && mInitCounter > 1) { LOG("[AudioTrackEncoder]: Initialize failed for 30s."); NotifyEndOfStream(); return; } } // Append and consume this raw segment. AppendAudioSegment(audio); // The stream has stopped and reached the end of track. if (aTrackEvents == MediaStreamListener::TRACK_EVENT_ENDED) { LOG("[AudioTrackEncoder]: Receive TRACK_EVENT_ENDED ."); NotifyEndOfStream(); } }
void VideoTrackEncoder::NotifyQueuedTrackChanges(MediaStreamGraph* aGraph, TrackID aID, StreamTime aTrackOffset, uint32_t aTrackEvents, const MediaSegment& aQueuedMedia) { if (mCanceled) { return; } const VideoSegment& video = static_cast<const VideoSegment&>(aQueuedMedia); // Check and initialize parameters for codec encoder. if (!mInitialized) { mInitCounter++; TRACK_LOG(LogLevel::Debug, ("Init the video encoder %d times", mInitCounter)); VideoSegment::ChunkIterator iter(const_cast<VideoSegment&>(video)); while (!iter.IsEnded()) { VideoChunk chunk = *iter; if (!chunk.IsNull()) { gfx::IntSize imgsize = chunk.mFrame.GetImage()->GetSize(); gfx::IntSize intrinsicSize = chunk.mFrame.GetIntrinsicSize(); nsresult rv = Init(imgsize.width, imgsize.height, intrinsicSize.width, intrinsicSize.height, aGraph->GraphRate()); if (NS_FAILED(rv)) { LOG("[VideoTrackEncoder]: Fail to initialize the encoder!"); NotifyCancel(); } break; } iter.Next(); } mNotInitDuration += aQueuedMedia.GetDuration(); if (!mInitialized && (mNotInitDuration / aGraph->GraphRate() > INIT_FAILED_DURATION) && mInitCounter > 1) { LOG("[VideoTrackEncoder]: Initialize failed for 30s."); NotifyEndOfStream(); return; } } AppendVideoSegment(video); // The stream has stopped and reached the end of track. if (aTrackEvents == MediaStreamListener::TRACK_EVENT_ENDED) { LOG("[VideoTrackEncoder]: Receive TRACK_EVENT_ENDED ."); NotifyEndOfStream(); } }
void MediaEncoder::NotifyQueuedTrackChanges(MediaStreamGraph* aGraph, TrackID aID, StreamTime aTrackOffset, TrackEventCommand aTrackEvents, const MediaSegment& aQueuedMedia, MediaStream* aInputStream, TrackID aInputTrackID) { if (!mDirectConnected) { NotifyRealtimeData(aGraph, aID, aTrackOffset, aTrackEvents, aQueuedMedia); } else { if (aTrackEvents != TrackEventCommand::TRACK_EVENT_NONE) { // forward events (TRACK_EVENT_ENDED) but not the media if (aQueuedMedia.GetType() == MediaSegment::VIDEO) { VideoSegment segment; NotifyRealtimeData(aGraph, aID, aTrackOffset, aTrackEvents, segment); } else { AudioSegment segment; NotifyRealtimeData(aGraph, aID, aTrackOffset, aTrackEvents, segment); } } if (mSuspended == RECORD_RESUMED) { if (mVideoEncoder) { if (aQueuedMedia.GetType() == MediaSegment::VIDEO) { // insert a null frame of duration equal to the first segment passed // after Resume(), so it'll get added to one of the DirectListener frames VideoSegment segment; gfx::IntSize size(0,0); segment.AppendFrame(nullptr, aQueuedMedia.GetDuration(), size, PRINCIPAL_HANDLE_NONE); mVideoEncoder->NotifyQueuedTrackChanges(aGraph, aID, aTrackOffset, aTrackEvents, segment); mSuspended = RECORD_NOT_SUSPENDED; } } else { mSuspended = RECORD_NOT_SUSPENDED; // no video } } } }