diff options
author | Anton Khirnov <anton@khirnov.net> | 2017-05-01 21:42:54 +0200 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2020-04-10 15:52:41 +0200 |
commit | 5e316096fa9ba4493d9dbb48847ad8e0b0e188c3 (patch) | |
tree | c0c6cb248b47ef3b71dbb83bb8f4756d45ac86cd /libavcodec/h264_ps.c | |
parent | ec7f33a38e341807c0ff9530e4dc7e175a86f437 (diff) |
h264_ps: make the PPS hold a reference to its SPS
It represents the relationship between them more naturally and will be
useful in the following commits.
Allows significantly more frames in fate-h264-attachment-631 to be
decoded.
Diffstat (limited to 'libavcodec/h264_ps.c')
-rw-r--r-- | libavcodec/h264_ps.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c index 8df195e0a9..e774929e21 100644 --- a/libavcodec/h264_ps.c +++ b/libavcodec/h264_ps.c @@ -324,7 +324,6 @@ void ff_h264_ps_uninit(H264ParamSets *ps) for (i = 0; i < MAX_PPS_COUNT; i++) av_buffer_unref(&ps->pps_list[i]); - av_buffer_unref(&ps->sps_ref); av_buffer_unref(&ps->pps_ref); ps->pps = NULL; @@ -738,6 +737,15 @@ static int more_rbsp_data_in_pps(const SPS *sps, void *logctx) return 1; } +static void pps_free(void *opaque, uint8_t *data) +{ + PPS *pps = (PPS*)data; + + av_buffer_unref(&pps->sps_ref); + + av_freep(&data); +} + int ff_h264_decode_picture_parameter_set(GetBitContext *gb, AVCodecContext *avctx, H264ParamSets *ps, int bit_length) { @@ -754,10 +762,15 @@ int ff_h264_decode_picture_parameter_set(GetBitContext *gb, AVCodecContext *avct return AVERROR_INVALIDDATA; } - pps_buf = av_buffer_allocz(sizeof(*pps)); - if (!pps_buf) + pps = av_mallocz(sizeof(*pps)); + if (!pps) return AVERROR(ENOMEM); - pps = (PPS*)pps_buf->data; + pps_buf = av_buffer_create((uint8_t*)pps, sizeof(*pps), + pps_free, NULL, 0); + if (!pps_buf) { + av_freep(&pps); + return AVERROR(ENOMEM); + } pps->data_size = gb->buffer_end - gb->buffer; if (pps->data_size > sizeof(pps->data)) { @@ -775,7 +788,14 @@ int ff_h264_decode_picture_parameter_set(GetBitContext *gb, AVCodecContext *avct ret = AVERROR_INVALIDDATA; goto fail; } - sps = (const SPS*)ps->sps_list[pps->sps_id]->data; + pps->sps_ref = av_buffer_ref(ps->sps_list[pps->sps_id]); + if (!pps->sps_ref) { + ret = AVERROR(ENOMEM); + goto fail; + } + pps->sps = (const SPS*)pps->sps_ref->data; + sps = pps->sps; + if (sps->bit_depth_luma > 14) { av_log(avctx, AV_LOG_ERROR, "Invalid luma bit depth=%d\n", |