[FFmpeg-cvslog] avcodec/h264: keep SPS and PPS bitstream data

wm4 git at videolan.org
Fri Oct 2 19:15:44 CEST 2015


ffmpeg | branch: master | wm4 <nfxjfg at googlemail.com> | Fri Oct  2 17:18:00 2015 +0200| [069190f7078e1e3abbfa27e2d97a10f33ae05fef] | committer: wm4

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.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=069190f7078e1e3abbfa27e2d97a10f33ae05fef
---

 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 7356288..769abda 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 52d235c..fd16a95 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]) {



More information about the ffmpeg-cvslog mailing list