The current code discards every non SPS/PPS NAL from extradata, which even if in theory they aren't needed there, some samples fail to decode without them, like "11159 HD-PVR sample.mpg".
Signed-off-by: James Almer <jamr...@gmail.com> --- Someone who wants to look why those filtered NALs are needed by such samples, or if there's some problem in the ff_h2645_packet_split() based parsing code, would come in handy and be very welcome. libavcodec/extract_extradata_bsf.c | 66 ++++++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 14 deletions(-) diff --git a/libavcodec/extract_extradata_bsf.c b/libavcodec/extract_extradata_bsf.c index d909ee6d17..bb2e9bf68c 100644 --- a/libavcodec/extract_extradata_bsf.c +++ b/libavcodec/extract_extradata_bsf.c @@ -49,15 +49,58 @@ static int val_in_array(const int *arr, int len, int val) return 0; } -static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt, - uint8_t **data, int *size) +static int extract_extradata_h264(AVBSFContext *ctx, AVPacket *pkt, + uint8_t **data, int *size) +{ + ExtractExtradataContext *s = ctx->priv_data; + uint32_t state = UINT32_MAX; + const uint8_t *ptr = pkt->data, *end = pkt->data + pkt->size; + int has_sps = 0; + int has_pps = 0; + int nalu_type; + + while (ptr < end) { + ptr = avpriv_find_start_code(ptr, end, &state); + if ((state & 0xFFFFFF00) != 0x100) + break; + nalu_type = state & 0x1F; + if (nalu_type == H264_NAL_SPS) { + has_sps = 1; + } else if (nalu_type == H264_NAL_PPS) + has_pps = 1; + else if ((nalu_type != H264_NAL_SEI || has_pps) && + nalu_type != H264_NAL_AUD && nalu_type != H264_NAL_SPS_EXT && + nalu_type != 0x0f) { + if (has_sps) { + while (ptr - 4 > pkt->data && ptr[-5] == 0) + ptr--; + if (ptr - pkt->data > 4) { + *size = ptr - 4 - pkt->data; + *data = av_malloc(*size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!*data) + return AVERROR(ENOMEM); + + memcpy(*data, pkt->data, *size); + + if (s->remove) { + pkt->data += *size; + pkt->size -= *size; + } + } + return 0; + } + } + } + + return 0; +} + +static int extract_extradata_h265(AVBSFContext *ctx, AVPacket *pkt, + uint8_t **data, int *size) { static const int extradata_nal_types_hevc[] = { HEVC_NAL_VPS, HEVC_NAL_SPS, HEVC_NAL_PPS, }; - static const int extradata_nal_types_h264[] = { - H264_NAL_SPS, H264_NAL_PPS, - }; ExtractExtradataContext *s = ctx->priv_data; @@ -67,13 +110,8 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt, int nb_extradata_nal_types; int i, ret = 0; - if (ctx->par_in->codec_id == AV_CODEC_ID_HEVC) { - extradata_nal_types = extradata_nal_types_hevc; - nb_extradata_nal_types = FF_ARRAY_ELEMS(extradata_nal_types_hevc); - } else { - extradata_nal_types = extradata_nal_types_h264; - nb_extradata_nal_types = FF_ARRAY_ELEMS(extradata_nal_types_h264); - } + extradata_nal_types = extradata_nal_types_hevc; + nb_extradata_nal_types = FF_ARRAY_ELEMS(extradata_nal_types_hevc); ret = ff_h2645_packet_split(&h2645_pkt, pkt->data, pkt->size, ctx, 0, 0, ctx->par_in->codec_id, 1); @@ -236,8 +274,8 @@ static const struct { uint8_t **data, int *size); } extract_tab[] = { { AV_CODEC_ID_CAVS, extract_extradata_mpeg4 }, - { AV_CODEC_ID_H264, extract_extradata_h2645 }, - { AV_CODEC_ID_HEVC, extract_extradata_h2645 }, + { AV_CODEC_ID_H264, extract_extradata_h264 }, + { AV_CODEC_ID_HEVC, extract_extradata_h265 }, { AV_CODEC_ID_MPEG1VIDEO, extract_extradata_mpeg12 }, { AV_CODEC_ID_MPEG2VIDEO, extract_extradata_mpeg12 }, { AV_CODEC_ID_MPEG4, extract_extradata_mpeg4 }, -- 2.12.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel