[FFmpeg-devel] [PATCH 2/6] avcodec/extract_extradata_bsf: use the parsing code from h264_split()
James Almer
jamrial at gmail.com
Sat Mar 25 00:31:43 EET 2017
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 <jamrial at 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
More information about the ffmpeg-devel
mailing list