[FFmpeg-devel] [PATCH 07/18] av1/h264_metadata, filter_units: Count down when deleting units

Andreas Rheinhardt andreas.rheinhardt at gmail.com
Mon Jun 17 06:42:12 EEST 2019


When testing whether a particular unit should be kept or discarded, it
is best to start at the very last unit of a fragment and count down,
because that way a unit that will eventually be deleted won't be
memmoved during earlier deletions; and frag/au->nb_units need only be
evaluated once in this case and the counter is automatically correct
when a unit got deleted.

It also works for double loops, i.e. when looping over all SEI messages
in all SEI units of an access unit.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at gmail.com>
---
 libavcodec/av1_metadata_bsf.c  |  3 +--
 libavcodec/filter_units_bsf.c  |  6 ++----
 libavcodec/h264_metadata_bsf.c | 18 ++++++------------
 3 files changed, 9 insertions(+), 18 deletions(-)

diff --git a/libavcodec/av1_metadata_bsf.c b/libavcodec/av1_metadata_bsf.c
index e294d7a24e..842b80c201 100644
--- a/libavcodec/av1_metadata_bsf.c
+++ b/libavcodec/av1_metadata_bsf.c
@@ -160,14 +160,13 @@ static int av1_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
     }
 
     if (ctx->delete_padding) {
-        for (i = 0; i < frag->nb_units; i++) {
+        for (i = frag->nb_units - 1; i >= 0; i--) {
             if (frag->units[i].type == AV1_OBU_PADDING) {
                 err = ff_cbs_delete_unit(ctx->cbc, frag, i);
                 if (err < 0) {
                     av_log(bsf, AV_LOG_ERROR, "Failed to delete Padding OBU.\n");
                     goto fail;
                 }
-                --i;
             }
         }
     }
diff --git a/libavcodec/filter_units_bsf.c b/libavcodec/filter_units_bsf.c
index f3691a5755..380f23e5a7 100644
--- a/libavcodec/filter_units_bsf.c
+++ b/libavcodec/filter_units_bsf.c
@@ -117,16 +117,14 @@ static int filter_units_filter(AVBSFContext *bsf, AVPacket *pkt)
         goto fail;
     }
 
-    for (i = 0; i < frag->nb_units; i++) {
+    for (i = frag->nb_units - 1; i >= 0; i--) {
         for (j = 0; j < ctx->nb_types; j++) {
             if (frag->units[i].type == ctx->type_list[j])
                 break;
         }
         if (ctx->mode == REMOVE ? j <  ctx->nb_types
-                                : j >= ctx->nb_types) {
+                                : j >= ctx->nb_types)
             ff_cbs_delete_unit(ctx->cbc, frag, i);
-            --i;
-        }
     }
 
     if (frag->nb_units == 0) {
diff --git a/libavcodec/h264_metadata_bsf.c b/libavcodec/h264_metadata_bsf.c
index ae54929b85..b95d2341dc 100644
--- a/libavcodec/h264_metadata_bsf.c
+++ b/libavcodec/h264_metadata_bsf.c
@@ -428,7 +428,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *out)
     }
 
     if (ctx->delete_filler) {
-        for (i = 0; i < au->nb_units; i++) {
+        for (i = au->nb_units - 1; i >= 0; i--) {
             if (au->units[i].type == H264_NAL_FILLER_DATA) {
                 // Filler NAL units.
                 err = ff_cbs_delete_unit(ctx->cbc, au, i);
@@ -437,7 +437,6 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *out)
                            "filler NAL.\n");
                     goto fail;
                 }
-                --i;
                 continue;
             }
 
@@ -445,7 +444,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *out)
                 // Filler SEI messages.
                 H264RawSEI *sei = au->units[i].content;
 
-                for (j = 0; j < sei->payload_count; j++) {
+                for (j = sei->payload_count - 1; j >= 0; j--) {
                     if (sei->payload[j].payload_type ==
                         H264_SEI_TYPE_FILLER_PAYLOAD) {
                         err = ff_cbs_h264_delete_sei_message(ctx->cbc, au,
@@ -455,10 +454,6 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *out)
                                    "filler SEI message.\n");
                             goto fail;
                         }
-                        // Renumbering might have happened, start again at
-                        // the same NAL unit position.
-                        --i;
-                        break;
                     }
                 }
             }
@@ -466,13 +461,13 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *out)
     }
 
     if (ctx->display_orientation != PASS) {
-        for (i = 0; i < au->nb_units; i++) {
+        for (i = au->nb_units - 1; i >= 0; i--) {
             H264RawSEI *sei;
             if (au->units[i].type != H264_NAL_SEI)
                 continue;
             sei = au->units[i].content;
 
-            for (j = 0; j < sei->payload_count; j++) {
+            for (j = sei->payload_count - 1; j >= 0; j--) {
                 H264RawSEIDisplayOrientation *disp;
                 int32_t *matrix;
 
@@ -490,8 +485,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *out)
                                "display orientation SEI message.\n");
                         goto fail;
                     }
-                    --i;
-                    break;
+                    continue;
                 }
 
                 matrix = av_mallocz(9 * sizeof(int32_t));
@@ -506,7 +500,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *out)
                 av_display_matrix_flip(matrix, disp->hor_flip, disp->ver_flip);
 
                 // If there are multiple display orientation messages in an
-                // access unit then ignore all but the last one.
+                // access unit then ignore all but the first one.
                 av_freep(&displaymatrix_side_data);
 
                 displaymatrix_side_data      = (uint8_t*)matrix;
-- 
2.21.0



More information about the ffmpeg-devel mailing list