зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1570337 - p2: extend and expose H.264 utility functions. r=jya
Some existing functions that manipulates H.264 bitstream already cover most of the efforts for converting Android encoder output. With some minor changes, they can be called by the encoder to avoid code duplications. Differential Revision: https://phabricator.services.mozilla.com/D43686 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
04a8aad2d9
Коммит
c0c0d0e714
|
@ -255,7 +255,8 @@ static Result<mozilla::Ok, nsresult> ParseNALUnits(ByteWriter<BigEndian>& aBw,
|
|||
return Ok();
|
||||
}
|
||||
|
||||
bool AnnexB::ConvertSampleToAVCC(mozilla::MediaRawData* aSample) {
|
||||
bool AnnexB::ConvertSampleToAVCC(mozilla::MediaRawData* aSample,
|
||||
const RefPtr<MediaByteBuffer>& aAVCCHeader) {
|
||||
if (IsAVCC(aSample)) {
|
||||
return ConvertSampleTo4BytesAVCC(aSample).isOk();
|
||||
}
|
||||
|
@ -275,8 +276,14 @@ bool AnnexB::ConvertSampleToAVCC(mozilla::MediaRawData* aSample) {
|
|||
if (!samplewriter->Replace(nalu.Elements(), nalu.Length())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aAVCCHeader) {
|
||||
aSample->mExtraData = aAVCCHeader;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Create the AVCC header.
|
||||
RefPtr<mozilla::MediaByteBuffer> extradata = new mozilla::MediaByteBuffer;
|
||||
auto extradata = MakeRefPtr<mozilla::MediaByteBuffer>();
|
||||
static const uint8_t kFakeExtraData[] = {
|
||||
1 /* version */,
|
||||
0x64 /* profile (High) */,
|
||||
|
@ -289,7 +296,7 @@ bool AnnexB::ConvertSampleToAVCC(mozilla::MediaRawData* aSample) {
|
|||
if (!extradata->AppendElements(kFakeExtraData, ArrayLength(kFakeExtraData))) {
|
||||
return false;
|
||||
}
|
||||
aSample->mExtraData = extradata;
|
||||
aSample->mExtraData = std::move(extradata);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,9 @@ class AnnexB {
|
|||
mozilla::MediaRawData* aSample, bool aAddSPS = true);
|
||||
// Convert a sample from Annex B to AVCC.
|
||||
// an AVCC extradata must not be set.
|
||||
static bool ConvertSampleToAVCC(mozilla::MediaRawData* aSample);
|
||||
static bool ConvertSampleToAVCC(
|
||||
mozilla::MediaRawData* aSample,
|
||||
const RefPtr<mozilla::MediaByteBuffer>& aAVCCHeader = nullptr);
|
||||
static mozilla::Result<mozilla::Ok, nsresult> ConvertSampleTo4BytesAVCC(
|
||||
mozilla::MediaRawData* aSample);
|
||||
|
||||
|
|
|
@ -1305,29 +1305,40 @@ bool H264::DecodeRecoverySEI(const mozilla::MediaByteBuffer* aSEI,
|
|||
RefPtr<MediaByteBuffer> encodedSPS =
|
||||
EncodeNALUnit(sps->Elements(), sps->Length());
|
||||
extraData->Clear();
|
||||
extraData->AppendElement(1);
|
||||
extraData->AppendElement(aProfile);
|
||||
extraData->AppendElement(aConstraints);
|
||||
extraData->AppendElement(aLevel);
|
||||
extraData->AppendElement(3); // nalLENSize-1
|
||||
extraData->AppendElement(1); // numPPS
|
||||
uint8_t c[2];
|
||||
mozilla::BigEndian::writeUint16(&c[0], encodedSPS->Length() + 1);
|
||||
extraData->AppendElements(c, 2);
|
||||
extraData->AppendElement((0x00 << 7) | (0x3 << 5) | H264_NAL_SPS);
|
||||
extraData->AppendElements(*encodedSPS);
|
||||
|
||||
const uint8_t PPS[] = {0xeb, 0xef, 0x20};
|
||||
|
||||
extraData->AppendElement(1); // numPPS
|
||||
mozilla::BigEndian::writeUint16(&c[0], sizeof(PPS) + 1);
|
||||
extraData->AppendElements(c, 2);
|
||||
extraData->AppendElement((0x00 << 7) | (0x3 << 5) | H264_NAL_PPS);
|
||||
extraData->AppendElements(PPS, sizeof(PPS));
|
||||
WriteExtraData(
|
||||
extraData, aProfile, aConstraints, aLevel,
|
||||
MakeSpan<const uint8_t>(encodedSPS->Elements(), encodedSPS->Length()),
|
||||
MakeSpan<const uint8_t>(PPS, sizeof(PPS)));
|
||||
|
||||
return extraData.forget();
|
||||
}
|
||||
|
||||
void H264::WriteExtraData(MediaByteBuffer* aDestExtraData,
|
||||
const uint8_t aProfile, const uint8_t aConstraints,
|
||||
const uint8_t aLevel, const Span<const uint8_t> aSPS,
|
||||
const Span<const uint8_t> aPPS) {
|
||||
aDestExtraData->AppendElement(1);
|
||||
aDestExtraData->AppendElement(aProfile);
|
||||
aDestExtraData->AppendElement(aConstraints);
|
||||
aDestExtraData->AppendElement(aLevel);
|
||||
aDestExtraData->AppendElement(3); // nalLENSize-1
|
||||
aDestExtraData->AppendElement(1); // numPPS
|
||||
uint8_t c[2];
|
||||
mozilla::BigEndian::writeUint16(&c[0], aSPS.Length() + 1);
|
||||
aDestExtraData->AppendElements(c, 2);
|
||||
aDestExtraData->AppendElement((0x00 << 7) | (0x3 << 5) | H264_NAL_SPS);
|
||||
aDestExtraData->AppendElements(aSPS.Elements(), aSPS.Length());
|
||||
|
||||
aDestExtraData->AppendElement(1); // numPPS
|
||||
mozilla::BigEndian::writeUint16(&c[0], aPPS.Length() + 1);
|
||||
aDestExtraData->AppendElements(c, 2);
|
||||
aDestExtraData->AppendElement((0x00 << 7) | (0x3 << 5) | H264_NAL_PPS);
|
||||
aDestExtraData->AppendElements(aPPS.Elements(), aPPS.Length());
|
||||
}
|
||||
|
||||
#undef READUE
|
||||
#undef READSE
|
||||
|
||||
|
|
|
@ -469,6 +469,8 @@ class H264 {
|
|||
|
||||
static bool DecodeSPSFromExtraData(const mozilla::MediaByteBuffer* aExtraData,
|
||||
SPSData& aDest);
|
||||
/* Decode SPS NAL RBSP and fill SPSData structure */
|
||||
static bool DecodeSPS(const mozilla::MediaByteBuffer* aSPS, SPSData& aDest);
|
||||
|
||||
// If the given aExtraData is valid, return the aExtraData.max_num_ref_frames
|
||||
// clamped to be in the range of [4, 16]; otherwise return 4.
|
||||
|
@ -489,6 +491,11 @@ class H264 {
|
|||
static already_AddRefed<mozilla::MediaByteBuffer> CreateExtraData(
|
||||
uint8_t aProfile, uint8_t aConstraints, uint8_t aLevel,
|
||||
const gfx::IntSize& aSize);
|
||||
static void WriteExtraData(mozilla::MediaByteBuffer* aDestExtraData,
|
||||
const uint8_t aProfile, const uint8_t aConstraints,
|
||||
const uint8_t aLevel,
|
||||
const Span<const uint8_t> aSPS,
|
||||
const Span<const uint8_t> aPPS);
|
||||
|
||||
private:
|
||||
friend class SPSNAL;
|
||||
|
@ -500,8 +507,6 @@ class H264 {
|
|||
const uint8_t* aNAL, size_t aLength);
|
||||
static already_AddRefed<mozilla::MediaByteBuffer> EncodeNALUnit(
|
||||
const uint8_t* aNAL, size_t aLength);
|
||||
/* Decode SPS NAL RBSP and fill SPSData structure */
|
||||
static bool DecodeSPS(const mozilla::MediaByteBuffer* aSPS, SPSData& aDest);
|
||||
static bool vui_parameters(mozilla::BitReader& aBr, SPSData& aDest);
|
||||
// Read HRD parameters, all data is ignored.
|
||||
static void hrd_parameters(mozilla::BitReader& aBr);
|
||||
|
|
Загрузка…
Ссылка в новой задаче