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

Submitted by Andreas Rheinhardt on Aug. 16, 2019, 3:05 a.m.

Details

Message ID 20190816030531.4775-7-andreas.rheinhardt@gmail.com
State New
Headers show

Commit Message

Andreas Rheinhardt Aug. 16, 2019, 3:05 a.m.
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@gmail.com>
---
 libavcodec/h264_parser.c | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

Patch hide | download patch | download mbox

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;