[FFmpeg-devel] [PATCH] avcodec/decode: use the context's internal buffer_pkt in avcodec_decode_subtitle2()

James Almer jamrial at gmail.com
Thu Mar 4 01:17:36 EET 2021


This removes stack usage of AVPacket, and ensures proper handling of packet
references.

Signed-off-by: James Almer <jamrial at gmail.com>
---
 libavcodec/decode.c | 29 ++++++++++-------------------
 1 file changed, 10 insertions(+), 19 deletions(-)

diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 5e5d0c7066..ae1043b985 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -877,11 +877,10 @@ static int recode_subtitle(AVCodecContext *avctx,
     int ret = 0;
     char *inb, *outb;
     size_t inl, outl;
-    AVPacket tmp;
 #endif
 
     if (avctx->sub_charenc_mode != FF_SUB_CHARENC_MODE_PRE_DECODER || inpkt->size == 0)
-        return 0;
+        return av_packet_ref(outpkt, inpkt);
 
 #if CONFIG_ICONV
     cd = iconv_open("UTF-8", avctx->sub_charenc);
@@ -896,12 +895,12 @@ static int recode_subtitle(AVCodecContext *avctx,
         goto end;
     }
 
-    ret = av_new_packet(&tmp, inl * UTF8_MAX_BYTES);
+    ret = av_new_packet(outpkt, inl * UTF8_MAX_BYTES);
+    if (ret < 0)
+        goto end;
+    ret = av_packet_copy_props(outpkt, inpkt);
     if (ret < 0)
         goto end;
-    outpkt->buf  = tmp.buf;
-    outpkt->data = tmp.data;
-    outpkt->size = tmp.size;
     outb = outpkt->data;
     outl = outpkt->size;
 
@@ -911,7 +910,6 @@ static int recode_subtitle(AVCodecContext *avctx,
         ret = FFMIN(AVERROR(errno), -1);
         av_log(avctx, AV_LOG_ERROR, "Unable to recode subtitle event \"%s\" "
                "from %s to UTF-8\n", inpkt->data, avctx->sub_charenc);
-        av_packet_unref(&tmp);
         goto end;
     }
     outpkt->size -= outl;
@@ -1040,20 +1038,21 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
     get_subtitle_defaults(sub);
 
     if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size) {
-        AVPacket pkt_recoded = *avpkt;
+        AVCodecInternal *avci = avctx->internal;
 
-        ret = recode_subtitle(avctx, &pkt_recoded, avpkt);
+        av_packet_unref(avci->buffer_pkt);
+        ret = recode_subtitle(avctx, avci->buffer_pkt, avpkt);
         if (ret < 0) {
             *got_sub_ptr = 0;
         } else {
-             ret = extract_packet_props(avctx->internal, &pkt_recoded);
+             ret = extract_packet_props(avctx->internal, avci->buffer_pkt);
              if (ret < 0)
                 return ret;
 
             if (avctx->pkt_timebase.num && avpkt->pts != AV_NOPTS_VALUE)
                 sub->pts = av_rescale_q(avpkt->pts,
                                         avctx->pkt_timebase, AV_TIME_BASE_Q);
-            ret = avctx->codec->decode(avctx, sub, got_sub_ptr, &pkt_recoded);
+            ret = avctx->codec->decode(avctx, sub, got_sub_ptr, avci->buffer_pkt);
             av_assert1((ret >= 0) >= !!*got_sub_ptr &&
                        !!*got_sub_ptr >= !!sub->num_rects);
 
@@ -1091,14 +1090,6 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
                     break;
                 }
             }
-
-            if (avpkt->data != pkt_recoded.data) { // did we recode?
-                /* prevent from destroying side data from original packet */
-                pkt_recoded.side_data = NULL;
-                pkt_recoded.side_data_elems = 0;
-
-                av_packet_unref(&pkt_recoded);
-            }
         }
 
         if (*got_sub_ptr)
-- 
2.30.1



More information about the ffmpeg-devel mailing list