[FFmpeg-devel] [PATCH 07/11] avcodec/h264_parser: Try to avoid (un)referencing

Andreas Rheinhardt andreas.rheinhardt at gmail.com
Fri Aug 16 06:05:27 EEST 2019


When a slice is encountered, the H.264 parser up until now always
unreferenced and reset the currently active SPS and PPS; immediately
afterwards, the currently active parameter sets are set which includes
referencing them. Given that it is not uncommon for the active parameter
sets to change only seldomly, most of the time the new active parameter
sets will be the old ones. Therefore this commit checks for this and
only unreferences an active parameter set if it changed.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at gmail.com>
---
 libavcodec/h264_parser.c | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
index 5f7aea0c76..188ba41c0b 100644
--- a/libavcodec/h264_parser.c
+++ b/libavcodec/h264_parser.c
@@ -363,25 +363,33 @@ static inline int parse_nal_units(AVCodecParserContext *s,
                 goto fail;
             }
 
+            if (p->ps.pps != (const PPS*)p->ps.pps_list[pps_id]->data) {
             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;
+            if (!p->ps.pps_ref) {
+            p->ps.pps = NULL;
+                goto unref_sps;
+            }
             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);
+            unref_sps:
+            av_buffer_unref(&p->ps.sps_ref);
+            p->ps.sps = NULL;
                 goto fail;
             }
-
+            if (p->ps.sps != (const SPS*)p->ps.sps_list[p->ps.pps->sps_id]->data) {
+            av_buffer_unref(&p->ps.sps_ref);
             p->ps.sps_ref = av_buffer_ref(p->ps.sps_list[p->ps.pps->sps_id]);
-            if (!p->ps.sps_ref)
+            if (!p->ps.sps_ref) {
+            p->ps.sps = NULL;
                 goto fail;
+            }
             p->ps.sps = (const SPS*)p->ps.sps_ref->data;
+            }
 
             sps = p->ps.sps;
 
-- 
2.21.0



More information about the ffmpeg-devel mailing list