From 069190f7078e1e3abbfa27e2d97a10f33ae05fef Mon Sep 17 00:00:00 2001 From: wm4 <nfxjfg@googlemail.com> Date: Fri, 2 Oct 2015 17:18:00 +0200 Subject: [PATCH] avcodec/h264: keep SPS and PPS bitstream data We assume an upper bound of 4096 bytes for each raw SPS/PPS. It's hard to determine an exact maximum size, but this value was was considered high enough and safe. Needed for the following VideotoolBox commit. --- libavcodec/h264.h | 4 ++++ libavcodec/h264_ps.c | 20 ++++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/libavcodec/h264.h b/libavcodec/h264.h index 73562882cdb..769abdad4bf 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -229,6 +229,8 @@ typedef struct SPS { int residual_color_transform_flag; ///< residual_colour_transform_flag int constraint_set_flags; ///< constraint_set[0-3]_flag int new; ///< flag to keep track if the decoder context needs re-init due to changed SPS + uint8_t data[4096]; + size_t data_size; } SPS; /** @@ -254,6 +256,8 @@ typedef struct PPS { uint8_t scaling_matrix8[6][64]; uint8_t chroma_qp_table[2][QP_MAX_NUM+1]; ///< pre-scaled (with chroma_qp_index_offset) version of qp_table int chroma_qp_diff; + uint8_t data[4096]; + size_t data_size; } PPS; /** diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c index 52d235cbaa9..fd16a958ed8 100644 --- a/libavcodec/h264_ps.c +++ b/libavcodec/h264_ps.c @@ -307,6 +307,15 @@ int ff_h264_decode_seq_parameter_set(H264Context *h, int ignore_truncation) int i, log2_max_frame_num_minus4; SPS *sps; + sps = av_mallocz(sizeof(SPS)); + if (!sps) + return AVERROR(ENOMEM); + + sps->data_size = h->gb.buffer_end - h->gb.buffer; + if (sps->data_size > sizeof(sps->data)) + goto fail; + memcpy(sps->data, h->gb.buffer, sps->data_size); + profile_idc = get_bits(&h->gb, 8); constraint_set_flags |= get_bits1(&h->gb) << 0; // constraint_set0_flag constraint_set_flags |= get_bits1(&h->gb) << 1; // constraint_set1_flag @@ -320,11 +329,8 @@ int ff_h264_decode_seq_parameter_set(H264Context *h, int ignore_truncation) if (sps_id >= MAX_SPS_COUNT) { av_log(h->avctx, AV_LOG_ERROR, "sps_id %u out of range\n", sps_id); - return AVERROR_INVALIDDATA; + goto fail; } - sps = av_mallocz(sizeof(SPS)); - if (!sps) - return AVERROR(ENOMEM); sps->sps_id = sps_id; sps->time_offset_length = 24; @@ -603,6 +609,12 @@ int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length) pps = av_mallocz(sizeof(PPS)); if (!pps) return AVERROR(ENOMEM); + pps->data_size = h->gb.buffer_end - h->gb.buffer; + if (pps->data_size > sizeof(pps->data)) { + ret = AVERROR_INVALIDDATA; + goto fail; + } + memcpy(pps->data, h->gb.buffer, pps->data_size); pps->sps_id = get_ue_golomb_31(&h->gb); if ((unsigned)pps->sps_id >= MAX_SPS_COUNT || !h->sps_buffers[pps->sps_id]) { -- GitLab