diff mbox

[FFmpeg-devel,2/4] decode: add a method for attaching lavc-internal data to frames

Message ID 20171110160317.3584-2-timo@rothenpieler.org
State New
Headers show

Commit Message

Timo Rothenpieler Nov. 10, 2017, 4:03 p.m. UTC
From: Anton Khirnov <anton@khirnov.net>

Use the AVFrame.private_ref field.

This new struct will be useful in the following commits.

Merges Libav commit 359a8a3e2d1194b52b6c386f94fd0929567dfb67.
---
 libavcodec/decode.c          | 51 ++++++++++++++++++++++++++++++++++++++++++--
 libavcodec/decode.h          | 11 ++++++++++
 libavcodec/wrapped_avframe.c |  7 ++++++
 3 files changed, 67 insertions(+), 2 deletions(-)

Comments

Michael Niedermayer Nov. 11, 2017, 1:42 a.m. UTC | #1
On Fri, Nov 10, 2017 at 05:03:15PM +0100, Timo Rothenpieler wrote:
> From: Anton Khirnov <anton@khirnov.net>
> 
> Use the AVFrame.private_ref field.
> 
> This new struct will be useful in the following commits.
> 
> Merges Libav commit 359a8a3e2d1194b52b6c386f94fd0929567dfb67.
> ---
>  libavcodec/decode.c          | 51 ++++++++++++++++++++++++++++++++++++++++++--
>  libavcodec/decode.h          | 11 ++++++++++
>  libavcodec/wrapped_avframe.c |  7 ++++++
>  3 files changed, 67 insertions(+), 2 deletions(-)

this causes assertion failures
ill send you the input file

[wmavoice @ 0x116bdbe0] Superframe encodes > 480 samples (3919), not allowed
==19367==    at 0x11B304C: VALGRIND_PRINTF_BACKTRACE (valgrind.h:4550)
==19367==    by 0x11B3ABC: av_log_default_callback (log.c:355)
==19367==    by 0x11B3C5B: av_vlog (log.c:383)
==19367==    by 0x11B3C1B: av_log (log.c:375)
==19367==    by 0xCFC25F: synth_superframe (wmavoice.c:1731)
==19367==    by 0xCFCE23: wmavoice_decode_packet (wmavoice.c:1950)
==19367==    by 0x86BD5B: decode_simple_internal (decode.c:397)
==19367==    by 0x86C9E2: decode_simple_receive_frame (decode.c:593)
==19367==    by 0x86CAAD: decode_receive_frame_internal (decode.c:611)
==19367==    by 0x86CF8E: avcodec_receive_frame (decode.c:725)
==19367==    by 0x4335A4: decode (ffmpeg.c:2238)
==19367==    by 0x433801: decode_audio (ffmpeg.c:2288)
==19367==    by 0x434DC2: process_input_packet (ffmpeg.c:2612)
==19367==    by 0x43BF5A: process_input (ffmpeg.c:4422)
==19367==    by 0x43C503: transcode_step (ffmpeg.c:4542)
==19367==    by 0x43C67F: transcode (ffmpeg.c:4596)
==19367==    by 0x43CE50: main (ffmpeg.c:4802)
Error while decoding stream #0:0: Invalid data found when processing input
==19367==    at 0x11B304C: VALGRIND_PRINTF_BACKTRACE (valgrind.h:4550)
==19367==    by 0x11B3ABC: av_log_default_callback (log.c:355)
==19367==    by 0x11B3C5B: av_vlog (log.c:383)
==19367==    by 0x11B3C1B: av_log (log.c:375)
==19367==    by 0x435169: process_input_packet (ffmpeg.c:2660)
==19367==    by 0x43BF5A: process_input (ffmpeg.c:4422)
==19367==    by 0x43C503: transcode_step (ffmpeg.c:4542)
==19367==    by 0x43C67F: transcode (ffmpeg.c:4596)
==19367==    by 0x43CE50: main (ffmpeg.c:4802)
[wmavoice @ 0x116bdbe0] Invalid frame type VLC code, skipping
==19367==    at 0x11B304C: VALGRIND_PRINTF_BACKTRACE (valgrind.h:4550)
==19367==    by 0x11B3ABC: av_log_default_callback (log.c:355)
==19367==    by 0x11B3C5B: av_vlog (log.c:383)
==19367==    by 0x11B3C1B: av_log (log.c:375)
==19367==    by 0xCFB3E4: synth_frame (wmavoice.c:1486)
==19367==    by 0xCFC7FD: synth_superframe (wmavoice.c:1781)
==19367==    by 0xCFCCE7: wmavoice_decode_packet (wmavoice.c:1927)
==19367==    by 0x86BD5B: decode_simple_internal (decode.c:397)
==19367==    by 0x86C9E2: decode_simple_receive_frame (decode.c:593)
==19367==    by 0x86CAAD: decode_receive_frame_internal (decode.c:611)
==19367==    by 0x86CD25: avcodec_send_packet (decode.c:673)
==19367==    by 0x43357A: decode (ffmpeg.c:2231)
==19367==    by 0x433801: decode_audio (ffmpeg.c:2288)
==19367==    by 0x434DC2: process_input_packet (ffmpeg.c:2612)
==19367==    by 0x43BF5A: process_input (ffmpeg.c:4422)
==19367==    by 0x43C503: transcode_step (ffmpeg.c:4542)
==19367==    by 0x43C67F: transcode (ffmpeg.c:4596)
==19367==    by 0x43CE50: main (ffmpeg.c:4802)
[wmavoice @ 0x116bdbe0] WMAPro-in-WMAVoice is not implemented. Update your FFmpeg version to the newest one from Git. If the problem still occurs, it means that your file has a feature which has not been implemented.
[wmavoice @ 0x116bdbe0] If you want to help, upload a sample of this file to ftp://upload.ffmpeg.org/incoming/ and contact the ffmpeg-devel mailing list. (ffmpeg-devel@ffmpeg.org)
Error while decoding stream #0:0: Not yet implemented in FFmpeg, patches welcome
==19367==    at 0x11B304C: VALGRIND_PRINTF_BACKTRACE (valgrind.h:4550)
==19367==    by 0x11B3ABC: av_log_default_callback (log.c:355)
==19367==    by 0x11B3C5B: av_vlog (log.c:383)
==19367==    by 0x11B3C1B: av_log (log.c:375)
==19367==    by 0x435169: process_input_packet (ffmpeg.c:2660)
==19367==    by 0x43BF5A: process_input (ffmpeg.c:4422)
==19367==    by 0x43C503: transcode_step (ffmpeg.c:4542)
==19367==    by 0x43C67F: transcode (ffmpeg.c:4596)
==19367==    by 0x43CE50: main (ffmpeg.c:4802)
Assertion !frame->private_ref failed at libavcodec/decode.c:1599
==19367==    at 0x11B304C: VALGRIND_PRINTF_BACKTRACE (valgrind.h:4550)
==19367==    by 0x11B3ABC: av_log_default_callback (log.c:355)
==19367==    by 0x11B3C5B: av_vlog (log.c:383)
==19367==    by 0x11B3C1B: av_log (log.c:375)
==19367==    by 0x86F7AC: ff_attach_decode_data (decode.c:1599)
==19367==    by 0x86FA68: get_buffer_internal (decode.c:1659)
==19367==    by 0x86FAF4: ff_get_buffer (decode.c:1678)
==19367==    by 0xCFC579: synth_superframe (wmavoice.c:1761)
==19367==    by 0xCFCE23: wmavoice_decode_packet (wmavoice.c:1950)
==19367==    by 0x86BD5B: decode_simple_internal (decode.c:397)
==19367==    by 0x86C9E2: decode_simple_receive_frame (decode.c:593)
==19367==    by 0x86CAAD: decode_receive_frame_internal (decode.c:611)
==19367==    by 0x86CD25: avcodec_send_packet (decode.c:673)
==19367==    by 0x43357A: decode (ffmpeg.c:2231)
==19367==    by 0x433801: decode_audio (ffmpeg.c:2288)
==19367==    by 0x434DC2: process_input_packet (ffmpeg.c:2612)
==19367==    by 0x43BF5A: process_input (ffmpeg.c:4422)
==19367==    by 0x43C503: transcode_step (ffmpeg.c:4542)
==19367==    by 0x43C67F: transcode (ffmpeg.c:4596)
==19367==    by 0x43CE50: main (ffmpeg.c:4802)

[...]
diff mbox

Patch

diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 86fe5aef52..0f215d6915 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -613,6 +613,16 @@  static int decode_receive_frame_internal(AVCodecContext *avctx, AVFrame *frame)
     if (ret == AVERROR_EOF)
         avci->draining_done = 1;
 
+    /* free the per-frame decode data */
+    if (!ret) {
+        /* the only case where decode data is not set should be decoders
+         * that do not call ff_get_buffer() */
+        av_assert0((frame->private_ref && frame->private_ref->size == sizeof(FrameDecodeData)) ||
+                   !(avctx->codec->capabilities & AV_CODEC_CAP_DR1));
+
+        av_buffer_unref(&frame->private_ref);
+    }
+
     return ret;
 }
 
@@ -1552,6 +1562,37 @@  static void validate_avframe_allocation(AVCodecContext *avctx, AVFrame *frame)
     }
 }
 
+static void decode_data_free(void *opaque, uint8_t *data)
+{
+    FrameDecodeData *fdd = (FrameDecodeData*)data;
+
+    av_freep(&fdd);
+}
+
+int ff_attach_decode_data(AVFrame *frame)
+{
+    AVBufferRef *fdd_buf;
+    FrameDecodeData *fdd;
+
+    av_assert1(!frame->private_ref);
+    av_buffer_unref(&frame->private_ref);
+
+    fdd = av_mallocz(sizeof(*fdd));
+    if (!fdd)
+        return AVERROR(ENOMEM);
+
+    fdd_buf = av_buffer_create((uint8_t*)fdd, sizeof(*fdd), decode_data_free,
+                               NULL, AV_BUFFER_FLAG_READONLY);
+    if (!fdd_buf) {
+        av_freep(&fdd);
+        return AVERROR(ENOMEM);
+    }
+
+    frame->private_ref = fdd_buf;
+
+    return 0;
+}
+
 static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags)
 {
     const AVHWAccel *hwaccel = avctx->hwaccel;
@@ -1588,8 +1629,14 @@  static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags)
         avctx->sw_pix_fmt = avctx->pix_fmt;
 
     ret = avctx->get_buffer2(avctx, frame, flags);
-    if (ret >= 0)
-        validate_avframe_allocation(avctx, frame);
+    if (ret < 0)
+        goto end;
+
+    validate_avframe_allocation(avctx, frame);
+
+    ret = ff_attach_decode_data(frame);
+    if (ret < 0)
+        goto end;
 
 end:
     if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && !override_dimensions &&
diff --git a/libavcodec/decode.h b/libavcodec/decode.h
index c9630228dc..519f875c98 100644
--- a/libavcodec/decode.h
+++ b/libavcodec/decode.h
@@ -21,8 +21,17 @@ 
 #ifndef AVCODEC_DECODE_H
 #define AVCODEC_DECODE_H
 
+#include "libavutil/buffer.h"
+
 #include "avcodec.h"
 
+/**
+ * This struct stores per-frame lavc-internal data and is attached to it via
+ * private_ref.
+ */
+typedef struct FrameDecodeData {
+} FrameDecodeData;
+
 /**
  * Called by decoders to get the next packet for decoding.
  *
@@ -36,4 +45,6 @@  int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt);
 
 void ff_decode_bsfs_uninit(AVCodecContext *avctx);
 
+int ff_attach_decode_data(AVFrame *frame);
+
 #endif /* AVCODEC_DECODE_H */
diff --git a/libavcodec/wrapped_avframe.c b/libavcodec/wrapped_avframe.c
index 5f88a668b9..85ff32d13a 100644
--- a/libavcodec/wrapped_avframe.c
+++ b/libavcodec/wrapped_avframe.c
@@ -25,6 +25,7 @@ 
  */
 
 #include "avcodec.h"
+#include "decode.h"
 #include "internal.h"
 
 #include "libavutil/internal.h"
@@ -98,6 +99,12 @@  static int wrapped_avframe_decode(AVCodecContext *avctx, void *data,
 
     av_frame_move_ref(out, in);
 
+    err = ff_attach_decode_data(out);
+    if (err < 0) {
+        av_frame_unref(out);
+        return err;
+    }
+
     *got_frame = 1;
     return 0;
 }