Commit 069190f7 authored by wm4's avatar 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.
parent 74ef5449
...@@ -229,6 +229,8 @@ typedef struct SPS { ...@@ -229,6 +229,8 @@ typedef struct SPS {
int residual_color_transform_flag; ///< residual_colour_transform_flag int residual_color_transform_flag; ///< residual_colour_transform_flag
int constraint_set_flags; ///< constraint_set[0-3]_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 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; } SPS;
/** /**
...@@ -254,6 +256,8 @@ typedef struct PPS { ...@@ -254,6 +256,8 @@ typedef struct PPS {
uint8_t scaling_matrix8[6][64]; 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 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; int chroma_qp_diff;
uint8_t data[4096];
size_t data_size;
} PPS; } PPS;
/** /**
......
...@@ -307,6 +307,15 @@ int ff_h264_decode_seq_parameter_set(H264Context *h, int ignore_truncation) ...@@ -307,6 +307,15 @@ int ff_h264_decode_seq_parameter_set(H264Context *h, int ignore_truncation)
int i, log2_max_frame_num_minus4; int i, log2_max_frame_num_minus4;
SPS *sps; 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); 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) << 0; // constraint_set0_flag
constraint_set_flags |= get_bits1(&h->gb) << 1; // constraint_set1_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) ...@@ -320,11 +329,8 @@ int ff_h264_decode_seq_parameter_set(H264Context *h, int ignore_truncation)
if (sps_id >= MAX_SPS_COUNT) { if (sps_id >= MAX_SPS_COUNT) {
av_log(h->avctx, AV_LOG_ERROR, "sps_id %u out of range\n", sps_id); 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->sps_id = sps_id;
sps->time_offset_length = 24; sps->time_offset_length = 24;
...@@ -603,6 +609,12 @@ int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length) ...@@ -603,6 +609,12 @@ int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length)
pps = av_mallocz(sizeof(PPS)); pps = av_mallocz(sizeof(PPS));
if (!pps) if (!pps)
return AVERROR(ENOMEM); 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); pps->sps_id = get_ue_golomb_31(&h->gb);
if ((unsigned)pps->sps_id >= MAX_SPS_COUNT || if ((unsigned)pps->sps_id >= MAX_SPS_COUNT ||
!h->sps_buffers[pps->sps_id]) { !h->sps_buffers[pps->sps_id]) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment