Add AOMDecoder::IsKeyframe method.
draft
Add AOMDecoder::IsKeyframe method.
WebMDemuxer needs to ask the decoder if a given sample
is a keyframe, to relay that information to higher
levels for planning purposes. Right now it just calls
the libvpx keyframe check directly, but that doesn't
work for av1 data. Add a method on AOMDecoder to do
this for us.
MozReview-Commit-ID: 3wiLBJUThWl
--- a/dom/media/platforms/agnostic/AOMDecoder.cpp
+++ b/dom/media/platforms/agnostic/AOMDecoder.cpp
@@ -222,11 +222,25 @@ AOMDecoder::Drain()
/* static */
bool
AOMDecoder::IsAV1(const nsACString& aMimeType)
{
return aMimeType.EqualsLiteral("video/webm; codecs=av1")
|| aMimeType.EqualsLiteral("video/av1");
}
+/* static */
+bool IsKeyframe(Span<const uint8_t>& packet) {
+ aom_codec_stream_info_t info;
+ auto res = aom_codec_peek_stream_info(aom_codec_av1_dx(),
+ packet.Elements(),
+ packet.Length(),
+ &info);
+ if (res != AOM_CODEC_OK) {
+ LOG_RESULT(res, "aom_codec_peek_stream_info");
+ return false;
+ }
+
+ return bool(info.is_kf);
+}
} // namespace mozilla
#undef LOG
--- a/dom/media/platforms/agnostic/AOMDecoder.h
+++ b/dom/media/platforms/agnostic/AOMDecoder.h
@@ -5,16 +5,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#if !defined(AOMDecoder_h_)
#define AOMDecoder_h_
#include "PlatformDecoderModule.h"
#include <stdint.h>
#include "aom/aom_decoder.h"
+#include "mozilla/Span.h"
namespace mozilla {
class AOMDecoder : public MediaDataDecoder
{
public:
explicit AOMDecoder(const CreateDecoderParams& aParams);
@@ -27,16 +28,19 @@ public:
{
return "libaom (AV1) video decoder";
}
// Return true if aMimeType is a one of the strings used
// by our demuxers to identify AV1 streams.
static bool IsAV1(const nsACString& aMimeType);
+ // Return true if a sample is a keyframe.
+ static bool IsKeyframe(Span<const uint8_t>& packet);
+
private:
~AOMDecoder();
RefPtr<DecodePromise> ProcessDecode(MediaRawData* aSample);
const RefPtr<layers::ImageContainer> mImageContainer;
const RefPtr<TaskQueue> mTaskQueue;
// AOM decoder state
--- a/dom/media/webm/WebMDemuxer.cpp
+++ b/dom/media/webm/WebMDemuxer.cpp
@@ -23,16 +23,18 @@
#include "prprf.h" // leaving it for PR_vsnprintf()
#include "mozilla/IntegerPrintfMacros.h"
#include "mozilla/SizePrintfMacros.h"
#include "mozilla/Sprintf.h"
#include <algorithm>
#include <stdint.h>
+#include "aom/aom_decoder.h"
+#include "aom/aomdx.h"
#define VPX_DONT_DEFINE_STDINT_TYPES
#include "vpx/vp8dx.h"
#include "vpx/vpx_decoder.h"
#include <numeric>
#define WEBM_DEBUG(arg, ...) MOZ_LOG(gMediaDemuxerLog, mozilla::LogLevel::Debug, ("WebMDemuxer(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
extern mozilla::LazyLogModule gMediaDemuxerLog;
@@ -681,22 +683,28 @@ WebMDemuxer::GetNextPacket(TrackInfo::Tr
== NESTEGG_PACKET_HAS_KEYFRAME_TRUE;
} else {
vpx_codec_stream_info_t si;
PodZero(&si);
si.sz = sizeof(si);
switch (mVideoCodec) {
case NESTEGG_CODEC_VP8:
vpx_codec_peek_stream_info(vpx_codec_vp8_dx(), data, length, &si);
+ isKeyframe = si.is_kf;
break;
case NESTEGG_CODEC_VP9:
vpx_codec_peek_stream_info(vpx_codec_vp9_dx(), data, length, &si);
+ isKeyframe = si.is_kf;
+ break;
+ case NESTEGG_CODEC_AV1:
+ aom_codec_stream_info_t info;
+ aom_codec_peek_stream_info(aom_codec_av1_dx(), data, length, &info);
+ isKeyframe = info.is_kf;
break;
}
- isKeyframe = si.is_kf;
if (isKeyframe) {
// We only look for resolution changes on keyframes for both VP8 and
// VP9. Other resolution changes are invalid.
if (mLastSeenFrameWidth.isSome()
&& mLastSeenFrameHeight.isSome()
&& (si.w != mLastSeenFrameWidth.value()
|| si.h != mLastSeenFrameHeight.value())) {
mInfo.mVideo.mDisplay = nsIntSize(si.w, si.h);