Bug 1657521 - P1. Add method to generate a vpcC box from the VP9 bitstream. r=jolin

The mac VP9 decoder; like the H264 requires some out of band settings before it can be created.

This information is only found in the mp4 container, we can create it from the vp9 bitstream.

For now we ignore the colors information as we can't handle it properly yet in our compositor and this is not available in the bytestream.

Differential Revision: https://phabricator.services.mozilla.com/D86542
This commit is contained in:
Jean-Yves Avenard 2020-08-13 02:14:11 +00:00
Родитель 2ae86bbfac
Коммит 7255c5ff5c
2 изменённых файлов: 118 добавлений и 5 удалений

Просмотреть файл

@ -5,18 +5,20 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "VPXDecoder.h"
#include <algorithm>
#include "BitReader.h"
#include "ByteWriter.h"
#include "ImageContainer.h"
#include "TimeUnits.h"
#include "gfx2DGlue.h"
#include "mozilla/PodOperations.h"
#include "mozilla/SyncRunnable.h"
#include "mozilla/Unused.h"
#include "ImageContainer.h"
#include "nsError.h"
#include "prsystem.h"
#include <algorithm>
#undef LOG
#define LOG(arg, ...) \
DDMOZ_LOG(sPDMLog, mozilla::LogLevel::Debug, "::%s: " arg, __func__, \
@ -482,5 +484,60 @@ bool VPXDecoder::GetStreamInfo(Span<const uint8_t> aBuffer,
return true;
}
// Ref: "VP Codec ISO Media File Format Binding, v1.0, 2017-03-31"
// <https://www.webmproject.org/vp9/mp4/>
//
// class VPCodecConfigurationBox extends FullBox('vpcC', version = 1, 0)
// {
// VPCodecConfigurationRecord() vpcConfig;
// }
//
// aligned (8) class VPCodecConfigurationRecord {
// unsigned int (8) profile;
// unsigned int (8) level;
// unsigned int (4) bitDepth;
// unsigned int (3) chromaSubsampling;
// unsigned int (1) videoFullRangeFlag;
// unsigned int (8) colourPrimaries;
// unsigned int (8) transferCharacteristics;
// unsigned int (8) matrixCoefficients;
// unsigned int (16) codecIntializationDataSize;
// unsigned int (8)[] codecIntializationData;
// }
/* static */
void VPXDecoder::GetVPCCBox(MediaByteBuffer* aDestBox,
const VPXStreamInfo& aInfo) {
ByteWriter<BigEndian> writer(*aDestBox);
int chroma = [&]() {
if (aInfo.mSubSampling_x && aInfo.mSubSampling_y) {
return 1; // 420 Colocated;
}
if (aInfo.mSubSampling_x && !aInfo.mSubSampling_y) {
return 2; // 422
}
if (!aInfo.mSubSampling_x && !aInfo.mSubSampling_y) {
return 3; // 444
}
// This indicates 4:4:0 subsampling, which is not expressable in the
// 'vpcC' box. Default to 4:2:0.
return 1;
}();
MOZ_ALWAYS_TRUE(writer.WriteU32(1 << 24)); // version & flag
MOZ_ALWAYS_TRUE(writer.WriteU8(aInfo.mProfile)); // profile
MOZ_ALWAYS_TRUE(writer.WriteU8(10)); // level set it to 1.0
MOZ_ALWAYS_TRUE(writer.WriteU8(
(0xF & aInfo.mBitDepth) << 4 | (0x7 & chroma) << 1 |
(0x1 & aInfo.mFullRange))); // bitdepth (4 bits), chroma (3 bits),
// video full/restrice range (1 bit)
MOZ_ALWAYS_TRUE(writer.WriteU8(2)); // color primaries: unknown
MOZ_ALWAYS_TRUE(writer.WriteU8(2)); // transfer characteristics: unknown
MOZ_ALWAYS_TRUE(writer.WriteU8(2)); // matrix coefficient: unknown
MOZ_ALWAYS_TRUE(
writer.WriteU16(0)); // codecIntializationDataSize (must be 0 for VP9)
}
} // namespace mozilla
#undef LOG

Просмотреть файл

@ -6,10 +6,10 @@
#if !defined(VPXDecoder_h_)
# define VPXDecoder_h_
# include <stdint.h>
# include "PlatformDecoderModule.h"
# include "mozilla/Span.h"
# include <stdint.h>
# include "mozilla/gfx/Types.h"
# include "vpx/vp8dx.h"
# include "vpx/vpx_codec.h"
@ -94,6 +94,60 @@ class VPXDecoder : public MediaDataDecoder,
}
}
// Ref: ISO/IEC 23091-2:2019
enum class ColorPrimaries {
BT_709_6 = 1,
Unspecified = 2,
BT_470_6_M = 4,
BT_470_7_BG = 5,
BT_601_7 = 6,
SMPTE_ST_240 = 7,
Film = 8,
BT_2020_Nonconstant_Luminance = 9,
SMPTE_ST_428_1 = 10,
SMPTE_RP_431_2 = 11,
SMPTE_EG_432_1 = 12,
EBU_Tech_3213_E = 22,
};
// Ref: ISO/IEC 23091-2:2019
enum class TransferCharacteristics {
BT_709_6 = 1,
Unspecified = 2,
BT_470_6_M = 4,
BT_470_7_BG = 5,
BT_601_7 = 6,
SMPTE_ST_240 = 7,
Linear = 8,
Logrithmic = 9,
Logrithmic_Sqrt = 10,
IEC_61966_2_4 = 11,
BT_1361_0 = 12,
IEC_61966_2_1 = 13,
BT_2020_10bit = 14,
BT_2020_12bit = 15,
SMPTE_ST_2084 = 16,
SMPTE_ST_428_1 = 17,
BT_2100_HLG = 18,
};
enum class MatrixCoefficients {
Identity = 0,
BT_709_6 = 1,
Unspecified = 2,
FCC = 4,
BT_470_7_BG = 5,
BT_601_7 = 6,
SMPTE_ST_240 = 7,
YCgCo = 8,
BT_2020_Nonconstant_Luminance = 9,
BT_2020_Constant_Luminance = 10,
SMPTE_ST_2085 = 11,
Chromacity_Constant_Luminance = 12,
Chromacity_Nonconstant_Luminance = 13,
BT_2100_ICC = 14,
};
/*
mFullRange == false then:
For BitDepth equals 8:
@ -138,6 +192,8 @@ class VPXDecoder : public MediaDataDecoder,
static bool GetStreamInfo(Span<const uint8_t> aBuffer, VPXStreamInfo& aInfo,
Codec aCodec);
static void GetVPCCBox(MediaByteBuffer* aDestBox, const VPXStreamInfo& aInfo);
private:
~VPXDecoder();
RefPtr<DecodePromise> ProcessDecode(MediaRawData* aSample);