Implement keyframe and framesize VPXDecoder helpers

Encapsulate code from WebMDemuxer to query keyframe and frame resolution inside VPXDecoder, so we have a clean wrapper for all the libvpx functions we use.
This commit is contained in:
trav90 2018-10-08 21:14:24 -05:00 • committed by Roy Tam
commit 3b0820badb
2 changed files with 46 additions and 10 deletions

View file

@ -101,17 +101,10 @@ MediaResult
VPXDecoder::DoDecode(MediaRawData* aSample) VPXDecoder::DoDecode(MediaRawData* aSample)
{ {
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn()); MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
#if defined(DEBUG) #if defined(DEBUG)
vpx_codec_stream_info_t si; NS_ASSERTION(IsKeyframe(*aSample, mCodec) == aSample->mKeyframe,
PodZero(&si); "VPX Decode Keyframe error sample->mKeyframe and sample data out of sync");
si.sz = sizeof(si);
if (mCodec == Codec::VP8) {
vpx_codec_peek_stream_info(vpx_codec_vp8_dx(), aSample->Data(), aSample->Size(), &si);
} else if (mCodec == Codec::VP9) {
vpx_codec_peek_stream_info(vpx_codec_vp9_dx(), aSample->Data(), aSample->Size(), &si);
}
NS_ASSERTION(bool(si.is_kf) == aSample->mKeyframe,
"VPX Decode Keyframe error sample->mKeyframe and si.si_kf out of sync");
#endif #endif
if (vpx_codec_err_t r = vpx_codec_decode(&mVPX, aSample->Data(), aSample->Size(), nullptr, 0)) { if (vpx_codec_err_t r = vpx_codec_decode(&mVPX, aSample->Data(), aSample->Size(), nullptr, 0)) {
@ -249,5 +242,41 @@ VPXDecoder::IsVP9(const nsACString& aMimeType)
return IsVPX(aMimeType, VPXDecoder::VP9); return IsVPX(aMimeType, VPXDecoder::VP9);
} }
/* static */
bool
VPXDecoder::IsKeyframe(Span<const uint8_t> aBuffer, Codec aCodec)
{
vpx_codec_stream_info_t si;
PodZero(&si);
si.sz = sizeof(si);
if (aCodec == Codec::VP8) {
vpx_codec_peek_stream_info(vpx_codec_vp8_dx(), aBuffer.Elements(), aBuffer.Length(), &si);
return bool(si.is_kf);
} else if (aCodec == Codec::VP9) {
vpx_codec_peek_stream_info(vpx_codec_vp9_dx(), aBuffer.Elements(), aBuffer.Length(), &si);
return bool(si.is_kf);
}
return false;
}
/* static */
nsIntSize
VPXDecoder::GetFrameSize(Span<const uint8_t> aBuffer, Codec aCodec)
{
vpx_codec_stream_info_t si;
PodZero(&si);
si.sz = sizeof(si);
if (aCodec == Codec::VP8) {
vpx_codec_peek_stream_info(vpx_codec_vp8_dx(), aBuffer.Elements(), aBuffer.Length(), &si);
} else if (aCodec == Codec::VP9) {
vpx_codec_peek_stream_info(vpx_codec_vp9_dx(), aBuffer.Elements(), aBuffer.Length(), &si);
}
return nsIntSize(si.w, si.h);
}
} // namespace mozilla } // namespace mozilla
#undef LOG #undef LOG

View file

@ -7,6 +7,7 @@
#define VPXDecoder_h_ #define VPXDecoder_h_
#include "PlatformDecoderModule.h" #include "PlatformDecoderModule.h"
#include "mozilla/Span.h"
#include <stdint.h> #include <stdint.h>
#define VPX_DONT_DEFINE_STDINT_TYPES #define VPX_DONT_DEFINE_STDINT_TYPES
@ -47,6 +48,12 @@ public:
static bool IsVP8(const nsACString& aMimeType); static bool IsVP8(const nsACString& aMimeType);
static bool IsVP9(const nsACString& aMimeType); static bool IsVP9(const nsACString& aMimeType);
// Return true if a sample is a keyframe for the specified codec.
static bool IsKeyframe(Span<const uint8_t> aBuffer, Codec aCodec);
// Return the frame dimensions for a sample for the specified codec.
static nsIntSize GetFrameSize(Span<const uint8_t> aBuffer, Codec aCodec);
private: private:
void ProcessDecode(MediaRawData* aSample); void ProcessDecode(MediaRawData* aSample);
MediaResult DoDecode(MediaRawData* aSample); MediaResult DoDecode(MediaRawData* aSample);