void DecodedStream::SendData() { AssertOwnerThread(); MOZ_ASSERT(mStartTime.isSome(), "Must be called after StartPlayback()"); // Not yet created on the main thread. MDSM will try again later. if (!mData) { return; } // Nothing to do when the stream is finished. if (mData->mHaveSentFinish) { return; } InitTracks(); SendAudio(mParams.mVolume, mSameOrigin); SendVideo(mSameOrigin); AdvanceTracks(); bool finished = (!mInfo.HasAudio() || mAudioQueue.IsFinished()) && (!mInfo.HasVideo() || mVideoQueue.IsFinished()); if (finished && !mData->mHaveSentFinish) { mData->mHaveSentFinish = true; mData->mStream->Finish(); } }
TEST_F(JsepTrackTest, NonDefaultOpusParameters) { InitCodecs(); for (auto& codec : mAnsCodecs.values) { if (codec->mName == "opus") { JsepAudioCodecDescription* audioCodec = static_cast<JsepAudioCodecDescription*>(codec); audioCodec->mMaxPlaybackRate = 16000; audioCodec->mForceMono = true; } } InitTracks(SdpMediaSection::kAudio); InitSdp(SdpMediaSection::kAudio); OfferAnswer(); VERIFY_OPUS_MAX_PLAYBACK_RATE(*mSendOff, 16000U); VERIFY_OPUS_FORCE_MONO(*mSendOff, true); VERIFY_OPUS_MAX_PLAYBACK_RATE(*mSendAns, SdpFmtpAttributeList::OpusParameters::kDefaultMaxPlaybackRate); VERIFY_OPUS_FORCE_MONO(*mSendAns, false); VERIFY_OPUS_MAX_PLAYBACK_RATE(*mRecvOff, 0U); VERIFY_OPUS_FORCE_MONO(*mRecvOff, false); VERIFY_OPUS_MAX_PLAYBACK_RATE(*mRecvAns, 16000U); VERIFY_OPUS_FORCE_MONO(*mRecvAns, true); }
TEST_F(JsepTrackTest, VideoNegotiationOfferAnswerRemb) { InitCodecs(); // enable remb on the offer and answer codecs ((JsepVideoCodecDescription*)mOffCodecs.values[2])->EnableRemb(); ((JsepVideoCodecDescription*)mAnsCodecs.values[2])->EnableRemb(); InitTracks(SdpMediaSection::kVideo); InitSdp(SdpMediaSection::kVideo); OfferAnswer(); // make sure REMB is on offer and on answer ASSERT_NE(mOffer->ToString().find("a=rtcp-fb:120 goog-remb"), std::string::npos); ASSERT_NE(mAnswer->ToString().find("a=rtcp-fb:120 goog-remb"), std::string::npos); CheckOffEncodingCount(1); CheckAnsEncodingCount(1); CheckOtherFbsSize(*mSendOff, 1); CheckOtherFbsSize(*mRecvAns, 1); CheckOtherFbExists(*mSendOff, SdpRtcpFbAttributeList::kRemb); CheckOtherFbExists(*mRecvAns, SdpRtcpFbAttributeList::kRemb); CheckOtherFbsSize(*mSendAns, 1); CheckOtherFbsSize(*mRecvOff, 1); CheckOtherFbExists(*mSendAns, SdpRtcpFbAttributeList::kRemb); CheckOtherFbExists(*mRecvOff, SdpRtcpFbAttributeList::kRemb); }
bool Aka4Splitter::Open(unsigned* isom_err_code, bool alloc_max_pkt_buf) { memset(&_info, 0, sizeof(_info)); _process_tracks_start_time_offset = nullptr; _track_num_start_with_zero = false; _sample_prev_filepos = 0; if (_stm == nullptr) return false; if (uint64_t(_stm->GetSize()) > INT64_MAX) return false; if (_parser.get() != nullptr) return false; _stm->Seek(0); auto parser = std::make_shared<Isom::Parser>(_stm); if (parser == nullptr) return false; unsigned err = parser->Parse(); if (isom_err_code != nullptr) *isom_err_code = err; if (err != ISOM_ERR_OK) return false; if (!InitGlobalInfo(parser)) return false; if (!InitTracks(parser)) return false; if (_info.Duration < 0.1) { unsigned index = 0; auto dur = GetLongestTrackDuration(&index); if (dur > 0) { auto p = _tracks[index]; if (p->InternalTrack->MediaInfo.TimeScale > 0) _info.Duration = double(dur) / double(p->InternalTrack->MediaInfo.TimeScale); } } _best_seek_track_index = FindBestSeekTrackIndex(); _parser = std::move(parser); if (alloc_max_pkt_buf) if (!PreallocMaxPacketBuffer()) return false; return true; }
void Init(SdpMediaSection::MediaType type) { InitCodecs(); InitTracks(type); InitSdp(type); }