/*---------------------------------------------------------------------- | AP4_LinearReader::ReadNextSample +---------------------------------------------------------------------*/ AP4_Result AP4_LinearReader::ReadNextSample(AP4_UI32 track_id, AP4_Sample& sample, AP4_DataBuffer& sample_data) { if (m_Trackers.ItemCount() == 0) { return AP4_ERROR_NO_SUCH_ITEM; } // look for a sample from a specific track Tracker* tracker = FindTracker(track_id); if (tracker == NULL) return AP4_ERROR_INVALID_PARAMETERS; for(;;) { if (tracker->m_Eos) return AP4_ERROR_EOS; // pop a sample if we can if (PopSample(tracker, sample, sample_data)) return AP4_SUCCESS; AP4_Result result = Advance(); if (AP4_FAILED(result)) return result; } return AP4_ERROR_EOS; }
void MP4Reader::Update(TrackType aTrack) { MOZ_ASSERT(GetTaskQueue()->IsCurrentThreadIn()); if (mShutdown) { return; } // Record number of frames decoded and parsed. Automatically update the // stats counters using the AutoNotifyDecoded stack-based class. AbstractMediaDecoder::AutoNotifyDecoded a(mDecoder); bool needInput = false; bool needOutput = false; auto& decoder = GetDecoderData(aTrack); { MonitorAutoLock lock(decoder.mMonitor); decoder.mUpdateScheduled = false; if (NeedInput(decoder)) { needInput = true; decoder.mInputExhausted = false; decoder.mNumSamplesInput++; } if (aTrack == kVideo) { uint64_t delta = decoder.mNumSamplesOutput - mLastReportedNumDecodedFrames; a.mDecoded = static_cast<uint32_t>(delta); mLastReportedNumDecodedFrames = decoder.mNumSamplesOutput; } if (decoder.HasPromise()) { needOutput = true; if (!decoder.mOutput.IsEmpty()) { nsRefPtr<MediaData> output = decoder.mOutput[0]; decoder.mOutput.RemoveElementAt(0); ReturnOutput(output, aTrack); } else if (decoder.mDrainComplete) { decoder.RejectPromise(END_OF_STREAM, __func__); } } } VLOG("Update(%s) ni=%d no=%d iex=%d fl=%d", TrackTypeToStr(aTrack), needInput, needOutput, decoder.mInputExhausted, decoder.mIsFlushing); if (needInput) { nsAutoPtr<MediaSample> sample(PopSample(aTrack)); // Collect telemetry from h264 Annex B SPS. if (!mFoundSPSForTelemetry && sample && AnnexB::HasSPS(sample->mMp4Sample)) { nsRefPtr<ByteBuffer> extradata = AnnexB::ExtractExtraData(sample->mMp4Sample); mFoundSPSForTelemetry = AccumulateSPSTelemetry(extradata); } if (sample) { decoder.mDecoder->Input(sample->mMp4Sample.forget()); if (aTrack == kVideo) { a.mParsed++; } } else { { MonitorAutoLock lock(decoder.mMonitor); MOZ_ASSERT(!decoder.mDemuxEOS); decoder.mDemuxEOS = true; } // DrainComplete takes care of reporting EOS upwards decoder.mDecoder->Drain(); } } }