/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim:set ts=2 sw=2 sts=2 et cindent: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
UniquePtr<SampleMetadata> sampleData; if (auto entryHandle = mSamples.Lookup(decodedFrame->Timestamp())) {
sampleData = std::move(entryHandle.Data());
entryHandle.Remove();
} else {
GMP_LOG_DEBUG( "GMPVideoDecoder::Decoded(this=%p) missing sample metadata for " "time %" PRIu64, this, decodedFrame->Timestamp()); if (mSamples.IsEmpty()) { // If we have no remaining samples in the table, then we have processed // all outstanding decode requests.
ProcessReorderQueue(mDecodePromise, __func__);
} return;
}
if (mReorderFrames) {
mReorderQueue.Push(std::move(v));
} else {
mUnorderedData.AppendElement(std::move(v));
}
if (mSamples.IsEmpty()) { // If we have no remaining samples in the table, then we have processed // all outstanding decode requests.
ProcessReorderQueue(mDecodePromise, __func__);
}
}
// GMP implementations have interpreted the meaning of GMP_BufferLength32 // differently. The OpenH264 GMP expects GMP_BufferLength32 to behave as // specified in the GMP API, where each buffer is prefixed by a 32-bit // host-endian buffer length that includes the size of the buffer length // field. Other existing GMPs currently expect GMP_BufferLength32 (when // combined with kGMPVideoCodecH264) to mean "like AVCC but restricted to // 4-byte NAL lengths" (i.e. buffer lengths are specified in big-endian // and do not include the length of the buffer length field.
mConvertNALUnitLengths = isOpenH264;
RefPtr<MediaRawData> sample(aSample); if (!mGMP) { return DecodePromise::CreateAndReject(
MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
RESULT_DETAIL("mGMP not initialized")),
__func__);
}
if (mTrackingId) {
MediaInfoFlag flag = MediaInfoFlag::None;
flag |= (aSample->mKeyframe ? MediaInfoFlag::KeyFrame
: MediaInfoFlag::NonKeyFrame); if (mGMP->GetPluginType() == GMPPluginType::OpenH264) {
flag |= MediaInfoFlag::SoftwareDecoding;
} if (MP4Decoder::IsH264(mConfig.mMimeType)) {
flag |= MediaInfoFlag::VIDEO_H264;
} elseif (VPXDecoder::IsVP8(mConfig.mMimeType)) {
flag |= MediaInfoFlag::VIDEO_VP8;
} elseif (VPXDecoder::IsVP9(mConfig.mMimeType)) {
flag |= MediaInfoFlag::VIDEO_VP9;
}
mPerformanceRecorder.Start(aSample->mTime.ToMicroseconds(), "GMPVideoDecoder"_ns, *mTrackingId, flag);
}
GMPUniquePtr<GMPVideoEncodedFrame> frame = CreateFrame(sample); if (!frame) { return DecodePromise::CreateAndReject(
MediaResult(NS_ERROR_OUT_OF_MEMORY,
RESULT_DETAIL("CreateFrame returned null")),
__func__);
}
uint64_t frameTimestamp = frame->TimeStamp();
RefPtr<DecodePromise> p = mDecodePromise.Ensure(__func__);
nsTArray<uint8_t> info; // No codec specific per-frame info to pass.
nsresult rv = mGMP->Decode(std::move(frame), false, info, 0); if (NS_FAILED(rv)) {
mDecodePromise.Reject(MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
RESULT_DETAIL("mGMP->Decode:%" PRIx32, static_cast<uint32_t>(rv))),
__func__);
}
// If we have multiple outstanding frames, we need to track which offset // belongs to which frame. During seek, it is possible to get the same frame // requested twice, if the old frame is still outstanding. We will simply drop // the extra decoded frame and request more input if the last outstanding.
mSamples.WithEntryHandle(frameTimestamp, [&](auto entryHandle) { auto sampleData = MakeUnique<SampleMetadata>(sample);
entryHandle.InsertOrUpdate(std::move(sampleData));
});
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.