[FFmpeg-cvslog] h264_ps: make the PPS hold a reference to its SPS
Anton Khirnov
git at videolan.org
Fri Apr 10 17:53:34 EEST 2020
ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Mon May 1 21:42:54 2017 +0200| [5e316096fa9ba4493d9dbb48847ad8e0b0e188c3] | committer: Anton Khirnov
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.
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=5e316096fa9ba4493d9dbb48847ad8e0b0e188c3
---
libavcodec/h264_parser.c | 16 +---
libavcodec/h264_ps.c | 30 ++++++--
libavcodec/h264_ps.h | 4 +-
libavcodec/h264_slice.c | 27 ++-----
libavcodec/h264dec.c | 4 +-
tests/ref/fate/h264-attachment-631 | 148 +++++++++++++++++++++++++++++++++++++
6 files changed, 184 insertions(+), 45 deletions(-)
diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
index ec1cbc6a66..aacd44cf3b 100644
--- a/libavcodec/h264_parser.c
+++ b/libavcodec/h264_parser.c
@@ -361,26 +361,14 @@ static inline int parse_nal_units(AVCodecParserContext *s,
}
av_buffer_unref(&p->ps.pps_ref);
- av_buffer_unref(&p->ps.sps_ref);
p->ps.pps = NULL;
p->ps.sps = NULL;
p->ps.pps_ref = av_buffer_ref(p->ps.pps_list[pps_id]);
if (!p->ps.pps_ref)
goto fail;
p->ps.pps = (const PPS*)p->ps.pps_ref->data;
-
- if (!p->ps.sps_list[p->ps.pps->sps_id]) {
- av_log(avctx, AV_LOG_ERROR,
- "non-existing SPS %u referenced\n", p->ps.pps->sps_id);
- goto fail;
- }
-
- p->ps.sps_ref = av_buffer_ref(p->ps.sps_list[p->ps.pps->sps_id]);
- if (!p->ps.sps_ref)
- goto fail;
- p->ps.sps = (const SPS*)p->ps.sps_ref->data;
-
- sps = p->ps.sps;
+ p->ps.sps = p->ps.pps->sps;
+ sps = p->ps.sps;
// heuristic to detect non marked keyframes
if (p->ps.sps->ref_frame_count <= 1 && p->ps.pps->ref_count[0] <= 1 && s->pict_type == AV_PICTURE_TYPE_I)
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",
diff --git a/libavcodec/h264_ps.h b/libavcodec/h264_ps.h
index d6798ca0ef..3f1ab72e38 100644
--- a/libavcodec/h264_ps.h
+++ b/libavcodec/h264_ps.h
@@ -135,6 +135,9 @@ typedef struct PPS {
uint32_t dequant8_buffer[6][QP_MAX_NUM + 1][64];
uint32_t(*dequant4_coeff[6])[16];
uint32_t(*dequant8_coeff[6])[64];
+
+ AVBufferRef *sps_ref;
+ const SPS *sps;
} PPS;
typedef struct H264ParamSets {
@@ -142,7 +145,6 @@ typedef struct H264ParamSets {
AVBufferRef *pps_list[MAX_PPS_COUNT];
AVBufferRef *pps_ref;
- AVBufferRef *sps_ref;
/* currently active parameters sets */
const PPS *pps;
const SPS *sps;
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index c6072738d7..5a8a4a7f86 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -333,7 +333,6 @@ int ff_h264_update_thread_context(AVCodecContext *dst,
}
av_buffer_unref(&h->ps.pps_ref);
- av_buffer_unref(&h->ps.sps_ref);
h->ps.pps = NULL;
h->ps.sps = NULL;
if (h1->ps.pps_ref) {
@@ -341,12 +340,7 @@ int ff_h264_update_thread_context(AVCodecContext *dst,
if (!h->ps.pps_ref)
return AVERROR(ENOMEM);
h->ps.pps = (const PPS*)h->ps.pps_ref->data;
- }
- if (h1->ps.sps_ref) {
- h->ps.sps_ref = av_buffer_ref(h1->ps.sps_ref);
- if (!h->ps.sps_ref)
- return AVERROR(ENOMEM);
- h->ps.sps = (const SPS*)h->ps.sps_ref->data;
+ h->ps.sps = h->ps.pps->sps;
}
if (need_reinit || !inited) {
@@ -1013,13 +1007,8 @@ static int h264_init_ps(H264Context *h, const H264SliceContext *sl, int first_sl
h->ps.pps = (const PPS*)h->ps.pps_ref->data;
}
- if (h->ps.sps != (const SPS*)h->ps.sps_list[h->ps.pps->sps_id]->data) {
- av_buffer_unref(&h->ps.sps_ref);
- h->ps.sps = NULL;
- h->ps.sps_ref = av_buffer_ref(h->ps.sps_list[h->ps.pps->sps_id]);
- if (!h->ps.sps_ref)
- return AVERROR(ENOMEM);
- h->ps.sps = (const SPS*)h->ps.sps_ref->data;
+ if (h->ps.sps != h->ps.pps->sps) {
+ h->ps.sps = (const SPS*)h->ps.pps->sps;
if (h->mb_width != h->ps.sps->mb_width ||
h->mb_height != h->ps.sps->mb_height ||
@@ -1779,13 +1768,7 @@ static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl,
return AVERROR_INVALIDDATA;
}
pps = (const PPS*)h->ps.pps_list[sl->pps_id]->data;
-
- if (!h->ps.sps_list[pps->sps_id]) {
- av_log(h->avctx, AV_LOG_ERROR,
- "non-existing SPS %u referenced\n", pps->sps_id);
- return AVERROR_INVALIDDATA;
- }
- sps = (const SPS*)h->ps.sps_list[pps->sps_id]->data;
+ sps = pps->sps;
sl->frame_num = get_bits(&sl->gb, sps->log2_max_frame_num);
if (!first_slice) {
@@ -2171,7 +2154,7 @@ int ff_h264_queue_decode_slice(H264Context *h, const H2645NAL *nal)
av_log(h->avctx, AV_LOG_ERROR, "PPS changed between slices\n");
return AVERROR_INVALIDDATA;
}
- if (h->ps.sps != (const SPS*)h->ps.sps_list[h->ps.pps->sps_id]->data) {
+ if (h->ps.sps != pps->sps) {
av_log(h->avctx, AV_LOG_ERROR,
"SPS changed in the middle of the frame\n");
return AVERROR_INVALIDDATA;
diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
index 8673d5a2c2..b8a1879522 100644
--- a/libavcodec/h264dec.c
+++ b/libavcodec/h264dec.c
@@ -764,9 +764,7 @@ end:
* past end by one (callers fault) and resync_mb_y != 0
* causes problems for the first MB line, too.
*/
- if (!FIELD_PICTURE(h) && h->current_slice &&
- h->ps.sps == (const SPS*)h->ps.sps_list[h->ps.pps->sps_id]->data &&
- h->enable_er) {
+ if (!FIELD_PICTURE(h) && h->current_slice && h->enable_er) {
H264SliceContext *sl = h->slice_ctx;
int use_last_pic = h->last_pic_for_ec.f->buf[0] && !sl->ref_count[0];
diff --git a/tests/ref/fate/h264-attachment-631 b/tests/ref/fate/h264-attachment-631
index ebb5eb4fcd..5ac45e70a4 100644
--- a/tests/ref/fate/h264-attachment-631
+++ b/tests/ref/fate/h264-attachment-631
@@ -3,6 +3,154 @@
#codec_id 0: rawvideo
#dimensions 0: 720x480
#sar 0: 8/9
+0, 6, 6, 1, 518400, 0xd2068698
+0, 10, 10, 1, 518400, 0x2ee4865f
+0, 14, 14, 1, 518400, 0x2a01b188
+0, 18, 18, 1, 518400, 0xa4bc9572
+0, 22, 22, 1, 518400, 0x4e882f72
+0, 26, 26, 1, 518400, 0xf79cfc9c
+0, 30, 30, 1, 518400, 0x93afec23
+0, 34, 34, 1, 518400, 0xadf210e6
+0, 38, 38, 1, 518400, 0xb0bdd1f1
+0, 42, 42, 1, 518400, 0x4bbb4a24
+0, 46, 46, 1, 518400, 0x49db06c8
+0, 50, 50, 1, 518400, 0xf9781bfb
+0, 54, 54, 1, 518400, 0xd3a373bc
+0, 58, 58, 1, 518400, 0xccfb31c5
+0, 62, 62, 1, 518400, 0x276423a7
+0, 66, 66, 1, 518400, 0xb3729230
+0, 70, 70, 1, 518400, 0xeaf4586d
+0, 74, 74, 1, 518400, 0x9e629b29
+0, 78, 78, 1, 518400, 0x921d6e58
+0, 82, 82, 1, 518400, 0xc988f527
+0, 86, 86, 1, 518400, 0x4e1fed4b
+0, 90, 90, 1, 518400, 0xe3819724
+0, 94, 94, 1, 518400, 0xc07602ba
+0, 98, 98, 1, 518400, 0xc6b1e8d0
+0, 102, 102, 1, 518400, 0x12d94755
+0, 106, 106, 1, 518400, 0x257a5264
+0, 110, 110, 1, 518400, 0x4f985461
+0, 114, 114, 1, 518400, 0x77577244
+0, 118, 118, 1, 518400, 0x81a59edf
+0, 122, 122, 1, 518400, 0x9f33c0fa
+0, 126, 126, 1, 518400, 0xa89cbb3f
+0, 130, 130, 1, 518400, 0x6b1bcc1c
+0, 134, 134, 1, 518400, 0x520acb74
+0, 138, 138, 1, 518400, 0x006dda91
+0, 142, 142, 1, 518400, 0x7377f96f
+0, 146, 146, 1, 518400, 0x0b713224
+0, 150, 150, 1, 518400, 0x98943e53
+0, 154, 154, 1, 518400, 0x59f967e2
+0, 158, 158, 1, 518400, 0x976a2461
+0, 162, 162, 1, 518400, 0xcb4d3872
+0, 166, 166, 1, 518400, 0x0a174f59
+0, 170, 170, 1, 518400, 0x7cbe6c4f
+0, 174, 174, 1, 518400, 0x475cbce4
+0, 178, 178, 1, 518400, 0x2c281bb9
+0, 182, 182, 1, 518400, 0xadee7826
+0, 186, 186, 1, 518400, 0x936059a6
+0, 190, 190, 1, 518400, 0xba09ae20
+0, 194, 194, 1, 518400, 0x355e94d7
+0, 198, 198, 1, 518400, 0xafc3a0b3
+0, 202, 202, 1, 518400, 0x55bd78af
+0, 206, 206, 1, 518400, 0x9678c886
+0, 210, 210, 1, 518400, 0x4d69a62a
+0, 214, 214, 1, 518400, 0x406e617c
+0, 218, 218, 1, 518400, 0x7031ebdb
+0, 222, 222, 1, 518400, 0xf862127d
+0, 226, 226, 1, 518400, 0x619b8a53
+0, 230, 230, 1, 518400, 0x0fde6b72
+0, 234, 234, 1, 518400, 0xd137deff
+0, 238, 238, 1, 518400, 0x9ae6ac2e
+0, 242, 242, 1, 518400, 0x6cefb571
+0, 246, 246, 1, 518400, 0x7694dda2
+0, 250, 250, 1, 518400, 0x2253f6a2
+0, 254, 254, 1, 518400, 0x770db468
+0, 258, 258, 1, 518400, 0xf4c815a5
+0, 262, 262, 1, 518400, 0x0a0f38b6
+0, 266, 266, 1, 518400, 0x17490907
+0, 270, 270, 1, 518400, 0xbc362ed6
+0, 274, 274, 1, 518400, 0x24de1b5c
+0, 278, 278, 1, 518400, 0x55d20b2a
+0, 282, 282, 1, 518400, 0xca1af9b1
+0, 286, 286, 1, 518400, 0x7e7b7473
+0, 290, 290, 1, 518400, 0xed30dd23
+0, 294, 294, 1, 518400, 0xb694c58f
+0, 298, 298, 1, 518400, 0x8270deb7
+0, 302, 302, 1, 518400, 0x91b3b4f7
+0, 306, 306, 1, 518400, 0x37fcb63c
+0, 310, 310, 1, 518400, 0x7ebcafca
+0, 314, 314, 1, 518400, 0x8508b6da
+0, 318, 318, 1, 518400, 0xe7e0b15e
+0, 322, 322, 1, 518400, 0x9618fa0e
+0, 326, 326, 1, 518400, 0xd4c3b20c
+0, 330, 330, 1, 518400, 0x1aad03d1
+0, 334, 334, 1, 518400, 0xb5c18e20
+0, 338, 338, 1, 518400, 0x70144034
+0, 342, 342, 1, 518400, 0x937ee203
+0, 346, 346, 1, 518400, 0x680d72ad
+0, 350, 350, 1, 518400, 0x8c9647b1
+0, 354, 354, 1, 518400, 0x65fce70a
+0, 358, 358, 1, 518400, 0xa3d785dd
+0, 362, 362, 1, 518400, 0xaf1a54c2
+0, 366, 366, 1, 518400, 0x301c6f4c
+0, 370, 370, 1, 518400, 0x0255b5ac
+0, 374, 374, 1, 518400, 0x967da8de
+0, 378, 378, 1, 518400, 0x1f7e6c8c
+0, 382, 382, 1, 518400, 0xb41badbf
+0, 386, 386, 1, 518400, 0xca853613
+0, 390, 390, 1, 518400, 0x9f8696cb
+0, 394, 394, 1, 518400, 0x55ec8427
+0, 398, 398, 1, 518400, 0x08779f91
+0, 402, 402, 1, 518400, 0x171fbc34
+0, 406, 406, 1, 518400, 0x5e9c6ddd
+0, 410, 410, 1, 518400, 0xd9a55786
+0, 414, 414, 1, 518400, 0xdb509948
+0, 418, 418, 1, 518400, 0x2a326178
+0, 422, 422, 1, 518400, 0x4842c411
+0, 426, 426, 1, 518400, 0x35399db4
+0, 430, 430, 1, 518400, 0xa182b9aa
+0, 434, 434, 1, 518400, 0xb6df772d
+0, 438, 438, 1, 518400, 0xfe61b651
+0, 442, 442, 1, 518400, 0x031cb305
+0, 446, 446, 1, 518400, 0xde553506
+0, 450, 450, 1, 518400, 0x24ab8557
+0, 454, 454, 1, 518400, 0xadf5e251
+0, 458, 458, 1, 518400, 0xb3a3c6c5
+0, 462, 462, 1, 518400, 0x9cedc6ac
+0, 466, 466, 1, 518400, 0x6ddf9b26
+0, 470, 470, 1, 518400, 0x3bfaf200
+0, 474, 474, 1, 518400, 0x0337d6f1
+0, 478, 478, 1, 518400, 0x71367bc7
+0, 482, 482, 1, 518400, 0x9e1876b8
+0, 486, 486, 1, 518400, 0x37b89366
+0, 490, 490, 1, 518400, 0x6e349056
+0, 494, 494, 1, 518400, 0x718a9543
+0, 498, 498, 1, 518400, 0x48e46e57
+0, 502, 502, 1, 518400, 0xb2ae494c
+0, 506, 506, 1, 518400, 0x0ec937dc
+0, 510, 510, 1, 518400, 0xb1e88149
+0, 514, 514, 1, 518400, 0xedbba51d
+0, 518, 518, 1, 518400, 0x8955d114
+0, 522, 522, 1, 518400, 0x951e8716
+0, 526, 526, 1, 518400, 0x119064de
+0, 530, 530, 1, 518400, 0xc06bd99a
+0, 534, 534, 1, 518400, 0xdfccd738
+0, 538, 538, 1, 518400, 0x6c2de0a5
+0, 542, 542, 1, 518400, 0x11c1fdf7
+0, 546, 546, 1, 518400, 0xdcd26a62
+0, 550, 550, 1, 518400, 0x0ff63f3d
+0, 554, 554, 1, 518400, 0x6443382a
+0, 558, 558, 1, 518400, 0x28ce5ce3
+0, 562, 562, 1, 518400, 0xe0d47fbd
+0, 566, 566, 1, 518400, 0xfdc0beed
+0, 570, 570, 1, 518400, 0x9adeddc4
+0, 574, 574, 1, 518400, 0x8e5669fc
+0, 578, 578, 1, 518400, 0xf0beb8ae
+0, 582, 582, 1, 518400, 0xbdd68806
+0, 586, 586, 1, 518400, 0xe3c6ae23
+0, 590, 590, 1, 518400, 0xeba952c1
+0, 594, 594, 1, 518400, 0x734ff153
0, 598, 598, 1, 518400, 0xc3c0f1cf
0, 603, 603, 1, 518400, 0x21a5df80
0, 607, 607, 1, 518400, 0x5b8e115b
More information about the ffmpeg-cvslog
mailing list