Bug 1300296: P1. Add method to determine if an H264 frame is an I-Frame. r=jesup

We do so by checking the frame data for NAL of type 5 as per ISO IEC 14496-2.

MozReview-Commit-ID: JFeLysrZ6aG

--HG--
extra : rebase_source : edf599210fd3a995f3538a7e54e083894620bf9e
This commit is contained in:
Jean-Yves Avenard 2016-09-04 21:28:24 +10:00
Родитель ac33516b3c
Коммит 4b2bec7900
2 изменённых файлов: 48 добавлений и 0 удалений

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

@ -488,4 +488,41 @@ H264::ComputeMaxRefFrames(const mozilla::MediaByteBuffer* aExtraData)
return maxRefFrames;
}
/* static */ H264::FrameType
H264::GetFrameType(const mozilla::MediaRawData* aSample)
{
if (!AnnexB::IsAVCC(aSample)) {
// We must have a valid AVCC frame with extradata.
return FrameType::INVALID;
}
MOZ_ASSERT(aSample->Data());
int nalLenSize = ((*aSample->mExtraData)[4] & 3) + 1;
ByteReader reader(aSample->Data(), aSample->Size());
while (reader.Remaining() >= nalLenSize) {
uint32_t nalLen;
switch (nalLenSize) {
case 1: nalLen = reader.ReadU8(); break;
case 2: nalLen = reader.ReadU16(); break;
case 3: nalLen = reader.ReadU24(); break;
case 4: nalLen = reader.ReadU32(); break;
}
if (!nalLen) {
continue;
}
const uint8_t* p = reader.Read(nalLen);
if (!p) {
return FrameType::INVALID;
}
if ((p[0] & 0x1f) == 5) {
// IDR NAL.
return FrameType::I_FRAME;
}
}
return FrameType::OTHER;
}
} // namespace mp4_demuxer

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

@ -350,6 +350,17 @@ public:
// clamped to be in the range of [4, 16]; otherwise return 4.
static uint32_t ComputeMaxRefFrames(const mozilla::MediaByteBuffer* aExtraData);
enum class FrameType
{
I_FRAME,
OTHER,
INVALID,
};
// Returns the frame type. Returns I_FRAME if the sample is an IDR
// (Instantaneous Decoding Refresh) Picture.
static FrameType GetFrameType(const mozilla::MediaRawData* aSample);
private:
static void vui_parameters(BitReader& aBr, SPSData& aDest);
// Read HRD parameters, all data is ignored.