[FFmpeg-devel] [PATCH 1/2] avcodec/mmaldec: Stop needlessly wrapping extradata in AVPacket

Andreas Rheinhardt andreas.rheinhardt at gmail.com
Sat Mar 6 01:21:03 EET 2021


Up until now the function to add packets to the waiting buffers list
uses an AVPacket as parameter; therefore extradata that is also sent
once gets wrapped in an AVPacket. Yet this is unnecessary as the
function does not really need a complete AVPacket, but mostly the data.
Therefore this commit modifies the function to accept a pointer for the
data and int for the size as well as the AVPacket* parameter, which is
NULL for extradata.

Furthermore, this commit adds const to the pointed to types if the data
doesn't change. The MMAL_BUFFER_HEADER_T struct unfortunately uses
uint8_t* for data that is not modified, necessitating a cast.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at gmail.com>
---
These two commits are completely untested; I just hope they compile.
Could please someone test them? Thanks in advance.
This commit provides an alternative way to avoid AVPackets on the stack
and av_init_packet; furthermore, this commit also aims to make this
decoder compatible with receiving a const AVPacket*.

 libavcodec/mmaldec.c | 45 ++++++++++++++++++++------------------------
 1 file changed, 20 insertions(+), 25 deletions(-)

diff --git a/libavcodec/mmaldec.c b/libavcodec/mmaldec.c
index cb15ac072a..7486f3c526 100644
--- a/libavcodec/mmaldec.c
+++ b/libavcodec/mmaldec.c
@@ -46,7 +46,7 @@
 
 typedef struct FFBufferEntry {
     AVBufferRef *ref;
-    void *data;
+    const void *data;
     size_t length;
     int64_t pts, dts;
     int flags;
@@ -476,27 +476,22 @@ fail:
 // (due to us not reading/returning enough output buffers) and won't accept
 // new input. (This wouldn't be an issue if MMAL input buffers always were
 // complete frames - then the input buffer just would have to be big enough.)
-// If is_extradata is set, send it as MMAL_BUFFER_HEADER_FLAG_CONFIG.
-static int ffmmal_add_packet(AVCodecContext *avctx, AVPacket *avpkt,
-                             int is_extradata)
+// Extradata (avpkt == NULL) is sent as MMAL_BUFFER_HEADER_FLAG_CONFIG.
+static int ffmmal_add_packet(AVCodecContext *avctx, const AVPacket *avpkt,
+                             const uint8_t *data, int size)
 {
     MMALDecodeContext *ctx = avctx->priv_data;
     AVBufferRef *buf = NULL;
-    int size = 0;
-    uint8_t *data = (uint8_t *)"";
-    uint8_t *start;
+    const uint8_t *start;
     int ret = 0;
 
-    if (avpkt->size) {
-        if (avpkt->buf) {
+    if (size) {
+        if (avpkt) {
             buf = av_buffer_ref(avpkt->buf);
-            size = avpkt->size;
-            data = avpkt->data;
         } else {
-            buf = av_buffer_alloc(avpkt->size);
+            buf = av_buffer_alloc(size);
             if (buf) {
-                memcpy(buf->data, avpkt->data, avpkt->size);
-                size = buf->size;
+                memcpy(buf->data, data, size);
                 data = buf->data;
             }
         }
@@ -504,9 +499,10 @@ static int ffmmal_add_packet(AVCodecContext *avctx, AVPacket *avpkt,
             ret = AVERROR(ENOMEM);
             goto done;
         }
-        if (!is_extradata)
+        if (avpkt)
             ctx->packets_sent++;
     } else {
+        data = "";
         if (ctx->eos_sent)
             goto done;
         if (!ctx->packets_sent) {
@@ -529,7 +525,7 @@ static int ffmmal_add_packet(AVCodecContext *avctx, AVPacket *avpkt,
         buffer->data = data;
         buffer->length = FFMIN(size, ctx->decoder->input[0]->buffer_size);
 
-        if (is_extradata)
+        if (!avpkt)
             buffer->flags |= MMAL_BUFFER_HEADER_FLAG_CONFIG;
 
         if (data == start)
@@ -538,8 +534,10 @@ static int ffmmal_add_packet(AVCodecContext *avctx, AVPacket *avpkt,
         data += buffer->length;
         size -= buffer->length;
 
-        buffer->pts = avpkt->pts == AV_NOPTS_VALUE ? MMAL_TIME_UNKNOWN : avpkt->pts;
-        buffer->dts = avpkt->dts == AV_NOPTS_VALUE ? MMAL_TIME_UNKNOWN : avpkt->dts;
+        buffer->pts = !avpkt || avpkt->pts == AV_NOPTS_VALUE ?
+                          MMAL_TIME_UNKNOWN : avpkt->pts;
+        buffer->dts = !avpkt || avpkt->dts == AV_NOPTS_VALUE ?
+                          MMAL_TIME_UNKNOWN : avpkt->dts;
 
         if (!size) {
             buffer->flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_END;
@@ -594,7 +592,7 @@ static int ffmmal_fill_input_port(AVCodecContext *avctx)
         mbuffer->pts = buffer->pts;
         mbuffer->dts = buffer->dts;
         mbuffer->flags = buffer->flags;
-        mbuffer->data = buffer->data;
+        mbuffer->data = (uint8_t*)buffer->data;
         mbuffer->length = buffer->length;
         mbuffer->user_data = buffer;
         mbuffer->alloc_size = ctx->decoder->input[0]->buffer_size;
@@ -776,16 +774,13 @@ static int ffmmal_decode(AVCodecContext *avctx, void *data, int *got_frame,
     int ret = 0;
 
     if (avctx->extradata_size && !ctx->extradata_sent) {
-        AVPacket pkt = {0};
-        av_init_packet(&pkt);
-        pkt.data = avctx->extradata;
-        pkt.size = avctx->extradata_size;
         ctx->extradata_sent = 1;
-        if ((ret = ffmmal_add_packet(avctx, &pkt, 1)) < 0)
+        if ((ret = ffmmal_add_packet(avctx, NULL, avctx->extradata,
+                                     avctx->extradata_size)) < 0)
             return ret;
     }
 
-    if ((ret = ffmmal_add_packet(avctx, avpkt, 0)) < 0)
+    if ((ret = ffmmal_add_packet(avctx, avpkt, pkt->data, pkt->size)) < 0)
         return ret;
 
     if ((ret = ffmmal_fill_input_port(avctx)) < 0)
-- 
2.27.0



More information about the ffmpeg-devel mailing list