/*---------------------------------------------------------------------- | IsIFrame +---------------------------------------------------------------------*/ static bool IsIFrame(AP4_Sample& sample, AP4_AvcSampleDescription* avc_desc) { AP4_DataBuffer sample_data; if (AP4_FAILED(sample.ReadData(sample_data))) { return false; } const unsigned char* data = sample_data.GetData(); AP4_Size size = sample_data.GetDataSize(); while (size >= avc_desc->GetNaluLengthSize()) { unsigned int nalu_length = 0; if (avc_desc->GetNaluLengthSize() == 1) { nalu_length = *data++; --size; } else if (avc_desc->GetNaluLengthSize() == 2) { nalu_length = AP4_BytesToUInt16BE(data); data += 2; size -= 2; } else if (avc_desc->GetNaluLengthSize() == 4) { nalu_length = AP4_BytesToUInt32BE(data); data += 4; size -= 4; } else { return false; } if (nalu_length <= size) { size -= nalu_length; } else { size = 0; } switch (*data & 0x1F) { case 1: { AP4_BitStream bits; bits.WriteBytes(data+1, 8); ReadGolomb(bits); unsigned int slice_type = ReadGolomb(bits); if (slice_type == 2 || slice_type == 7) { return true; } else { return false; // only show first slice type } } case 5: return true; } data += nalu_length; } return false; }
/*---------------------------------------------------------------------- | PrintSliceInfo +---------------------------------------------------------------------*/ static void PrintSliceInfo(const unsigned char* data) { AP4_BitStream bits; bits.WriteBytes(data, 8); ReadGolomb(bits); unsigned int slice_type = ReadGolomb(bits); const char* slice_type_name = AP4_AvcNalParser::SliceTypeName(slice_type); if (slice_type_name == NULL) slice_type_name = "?"; printf(" slice=%d (%s)", slice_type, slice_type_name); }