This will allow memcpy-free passing frames to lavfi.
The results of some fate tests are changed, because avconv's
get_buffer() doesn't memset() the frame to 128:
* bethsoftvid: the first frame is completely black, same as the second.
makes sense for it to have the same checksum.
* cdgraphics: the new output looks more correct (blue background instead
of gray
* ansi: the new output looks more correct (black background instead of
gray)
*fraps-v1: the topmost line is now black instead of gray (probably more
correct)
* qtrle-1bit: the topmost line is now solid white instead of dashed.
Probably not more wrong than before.
* aasc: the last line is now black instead of gray. This is probably
* more correct (or possibly as wrong as before).
---
avconv.c | 136 +++++++++++++++++++++++++++++++++++++++++++
tests/ref/fate/aasc | 46 +++++++-------
tests/ref/fate/ansi | 6 +-
tests/ref/fate/bethsoft-vid | 2 +-
tests/ref/fate/cdgraphics | 32 +++++-----
tests/ref/fate/fraps-v1 | 2 +-
tests/ref/fate/qtrle-1bit | 76 ++++++++++++------------
7 files changed, 218 insertions(+), 82 deletions(-)
diff --git a/avconv.c b/avconv.c
index dfef98f..a07198d 100644
--- a/avconv.c
+++ b/avconv.c
@@ -44,6 +44,7 @@
#include "libavutil/pixdesc.h"
#include "libavutil/avstring.h"
#include "libavutil/libm.h"
+#include "libavutil/imgutils.h"
#include "libavformat/os_support.h"
#if CONFIG_AVFILTER
@@ -139,6 +140,19 @@ static unsigned int allocated_audio_out_size,
allocated_audio_buf_size;
#define DEFAULT_PASS_LOGFILENAME_PREFIX "av2pass"
+typedef struct FrameBuffer {
+ uint8_t *base[4];
+ uint8_t *data[4];
+ int linesize[4];
+
+ int h, w;
+ enum PixelFormat pix_fmt;
+
+ int refcount;
+ struct InputStream *ist;
+ struct FrameBuffer *next;
+} FrameBuffer;
+
typedef struct InputStream {
int file_index;
AVStream *st;
@@ -157,6 +171,9 @@ typedef struct InputStream {
int is_start; /* is 1 at the start and after a discontinuity */
int showed_multi_packet_warning;
AVDictionary *opts;
+
+ /* a pool of free buffers for decoded data */
+ FrameBuffer *buffer_pool;
} InputStream;
typedef struct InputFile {
@@ -394,6 +411,118 @@ static void reset_options(OptionsContext *o)
init_opts();
}
+static int alloc_buffer(InputStream *ist, FrameBuffer **pbuf)
+{
+ AVCodecContext *s = ist->st->codec;
+ FrameBuffer *buf = av_mallocz(sizeof(*buf));
+ int ret;
+ const int pixel_size =
av_pix_fmt_descriptors[s->pix_fmt].comp[0].step_minus1+1;
+ int h_chroma_shift, v_chroma_shift;
+ int edge = 32; // XXX should be avcodec_get_edge_width(), but that fails
on svq1
+ int w = s->width, h = s->height;
+
+ if (!buf)
+ return AVERROR(ENOMEM);
+
+ if (!(s->flags & CODEC_FLAG_EMU_EDGE)) {
+ w += 2*edge;
+ h += 2*edge;
+ }
+
+ avcodec_align_dimensions(s, &w, &h);
+ if ((ret = av_image_alloc(buf->base, buf->linesize, w, h,
+ s->pix_fmt, 32)) < 0) {
+ av_freep(&buf);
+ return ret;
+ }
+
+ avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift,
&v_chroma_shift);
+ for (int i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) {
+ const int h_shift = i==0 ? 0 : h_chroma_shift;
+ const int v_shift = i==0 ? 0 : v_chroma_shift;
+ if (s->flags & CODEC_FLAG_EMU_EDGE)
+ buf->data[i] = buf->base[i];
+ else
+ buf->data[i] = buf->base[i] +
+ FFALIGN((buf->linesize[i]*edge >> v_shift) +
+ (pixel_size*edge >> h_shift), 32);
+ }
+ buf->w = s->width;
+ buf->h = s->height;
+ buf->pix_fmt = s->pix_fmt;
+ buf->ist = ist;
+
+ *pbuf = buf;
+ return 0;
+}
+
+static void free_buffer_pool(InputStream *ist)
+{
+ FrameBuffer *buf = ist->buffer_pool;
+ while (buf) {
+ ist->buffer_pool = buf->next;
+ av_freep(&buf->base[0]);
+ av_free(buf);
+ buf = ist->buffer_pool;
+ }
+}
+
+static void unref_buffer(InputStream *ist, FrameBuffer *buf)
+{
+ av_assert0(buf->refcount);
+ buf->refcount--;
+ if (!buf->refcount) {
+ buf->next = ist->buffer_pool;
+ ist->buffer_pool = buf;
+ }
+}
+
+static int codec_get_buffer(AVCodecContext *s, AVFrame *frame)
+{
+ InputStream *ist = s->opaque;
+ FrameBuffer *buf;
+ int ret, i;
+
+ if (!ist->buffer_pool && (ret = alloc_buffer(ist, &ist->buffer_pool)) < 0)
+ return ret;
+
+ buf = ist->buffer_pool;
+ ist->buffer_pool = buf->next;
+ buf->next = NULL;
+ if (buf->w != s->width || buf->h != s->height || buf->pix_fmt !=
s->pix_fmt) {
+ av_freep(&buf->base[0]);
+ av_free(buf);
+ if ((ret = alloc_buffer(ist, &buf)) < 0)
+ return ret;
+ }
+ buf->refcount++;
+
+ frame->opaque = buf;
+ frame->type = FF_BUFFER_TYPE_USER;
+ frame->extended_data = frame->data;
+ frame->pkt_pts = s->pkt ? s->pkt->pts : AV_NOPTS_VALUE;
+
+ for (i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) {
+ frame->base[i] = buf->base[i]; // XXX h264.c uses base though it
shouldn't
+ frame->data[i] = buf->data[i];
+ frame->linesize[i] = buf->linesize[i];
+ }
+
+ return 0;
+}
+
+static void codec_release_buffer(AVCodecContext *s, AVFrame *frame)
+{
+ InputStream *ist = s->opaque;
+ FrameBuffer *buf = frame->opaque;
+ int i;
+
+ for (i = 0; i < FF_ARRAY_ELEMS(frame->data); i++)
+ frame->data[i] = NULL;
+
+ unref_buffer(ist, buf);
+}
+
#if CONFIG_AVFILTER
static int configure_video_filters(InputStream *ist, OutputStream *ost)
@@ -531,6 +660,7 @@ void exit_program(int ret)
av_freep(&input_streams[i].decoded_frame);
av_freep(&input_streams[i].filtered_frame);
av_dict_free(&input_streams[i].opts);
+ free_buffer_pool(&input_streams[i]);
}
if (vstats_file)
@@ -1985,6 +2115,12 @@ static int init_input_stream(int ist_index, OutputStream
*output_streams, int nb
}
}
+ if (codec->type == AVMEDIA_TYPE_VIDEO && codec->capabilities &
CODEC_CAP_DR1) {
+ ist->st->codec->get_buffer = codec_get_buffer;
+ ist->st->codec->release_buffer = codec_release_buffer;
+ ist->st->codec->opaque = ist;
+ }
+
if (avcodec_open2(ist->st->codec, codec, &ist->opts) < 0) {
snprintf(error, error_len, "Error while opening decoder for input
stream #%d:%d",
ist->file_index, ist->st->index);
diff --git a/tests/ref/fate/aasc b/tests/ref/fate/aasc
index 7ec02ba..2941d79 100644
--- a/tests/ref/fate/aasc
+++ b/tests/ref/fate/aasc
@@ -1,23 +1,23 @@
-0, 0, 168000, 0x45addf8f
-0, 3600, 168000, 0x45addf8f
-0, 7200, 168000, 0x45addf8f
-0, 10800, 168000, 0x45addf8f
-0, 14400, 168000, 0x45addf8f
-0, 18000, 168000, 0x45addf8f
-0, 21600, 168000, 0x45addf8f
-0, 25200, 168000, 0x45addf8f
-0, 28800, 168000, 0x45addf8f
-0, 32400, 168000, 0x45addf8f
-0, 36000, 168000, 0x45addf8f
-0, 39600, 168000, 0x45addf8f
-0, 43200, 168000, 0x8730699b
-0, 46800, 168000, 0x08b095df
-0, 50400, 168000, 0x203526e3
-0, 54000, 168000, 0x0ebc5142
-0, 57600, 168000, 0xd168e7c2
-0, 61200, 168000, 0xcc7da0e6
-0, 64800, 168000, 0x72ac60b8
-0, 68400, 168000, 0xb691e27c
-0, 72000, 168000, 0x646fa087
-0, 75600, 168000, 0x404450a2
-0, 79200, 168000, 0x5214c456
+0, 0, 168000, 0x00000000
+0, 3600, 168000, 0x00000000
+0, 7200, 168000, 0x00000000
+0, 10800, 168000, 0x00000000
+0, 14400, 168000, 0x00000000
+0, 18000, 168000, 0x00000000
+0, 21600, 168000, 0x00000000
+0, 25200, 168000, 0x00000000
+0, 28800, 168000, 0x00000000
+0, 32400, 168000, 0x00000000
+0, 36000, 168000, 0x00000000
+0, 39600, 168000, 0x00000000
+0, 43200, 168000, 0x418389fd
+0, 46800, 168000, 0xc2f4b641
+0, 50400, 168000, 0xda794745
+0, 54000, 168000, 0xc90071a4
+0, 57600, 168000, 0x8bbb0833
+0, 61200, 168000, 0x86d0c148
+0, 64800, 168000, 0x2cff811a
+0, 68400, 168000, 0x70e402ed
+0, 72000, 168000, 0x1ec2c0e9
+0, 75600, 168000, 0xfa887104
+0, 79200, 168000, 0x0c67e4b8
diff --git a/tests/ref/fate/ansi b/tests/ref/fate/ansi
index bb9f35f..09c51a4 100644
--- a/tests/ref/fate/ansi
+++ b/tests/ref/fate/ansi
@@ -1,6 +1,6 @@
-0, 0, 768000, 0x3032d0de
-0, 3600, 768000, 0xc3be5922
-0, 7200, 768000, 0xf530c476
+0, 0, 768000, 0x772dd3d0
+0, 3600, 768000, 0xd7dab1d1
+0, 7200, 768000, 0x0e56f2d3
0, 10800, 768000, 0x11c1fb8e
0, 14400, 768000, 0x72d12da9
0, 18000, 768000, 0x39c7a70d
diff --git a/tests/ref/fate/bethsoft-vid b/tests/ref/fate/bethsoft-vid
index 0886bfc..6299a47 100644
--- a/tests/ref/fate/bethsoft-vid
+++ b/tests/ref/fate/bethsoft-vid
@@ -1,4 +1,4 @@
-0, 0, 192000, 0xdecc683b
+0, 0, 192000, 0x00000000
1, 0, 1480, 0x00000000
0, 1500, 192000, 0x00000000
0, 3000, 192000, 0x01a6cf45
diff --git a/tests/ref/fate/cdgraphics b/tests/ref/fate/cdgraphics
index 10873fd..e52f084 100644
--- a/tests/ref/fate/cdgraphics
+++ b/tests/ref/fate/cdgraphics
@@ -1,19 +1,19 @@
-0, 0, 194400, 0xd919c635
-0, 300, 194400, 0xd919c635
-0, 600, 194400, 0x516a1007
-0, 900, 194400, 0x516a1007
-0, 1200, 194400, 0x516a1007
-0, 1500, 194400, 0x516a1007
-0, 1800, 194400, 0x516a1007
-0, 2100, 194400, 0x516a1007
-0, 2400, 194400, 0x516a1007
-0, 2700, 194400, 0x516a1007
-0, 3000, 194400, 0x516a1007
-0, 3300, 194400, 0x516a1007
-0, 3600, 194400, 0x516a1007
-0, 3900, 194400, 0x516a1007
-0, 4200, 194400, 0x516a1007
-0, 4500, 194400, 0x516a1007
+0, 0, 194400, 0x46ad80da
+0, 300, 194400, 0x46ad80da
+0, 600, 194400, 0x9392c3b9
+0, 900, 194400, 0x9392c3b9
+0, 1200, 194400, 0x9392c3b9
+0, 1500, 194400, 0x9392c3b9
+0, 1800, 194400, 0x9392c3b9
+0, 2100, 194400, 0x9392c3b9
+0, 2400, 194400, 0x9392c3b9
+0, 2700, 194400, 0x9392c3b9
+0, 3000, 194400, 0x9392c3b9
+0, 3300, 194400, 0x9392c3b9
+0, 3600, 194400, 0x9392c3b9
+0, 3900, 194400, 0x9392c3b9
+0, 4200, 194400, 0x9392c3b9
+0, 4500, 194400, 0x9392c3b9
0, 4800, 194400, 0x46ad80da
0, 5100, 194400, 0x46ad80da
0, 5400, 194400, 0x46ad80da
diff --git a/tests/ref/fate/fraps-v1 b/tests/ref/fate/fraps-v1
index 7d09310..b4704d3 100644
--- a/tests/ref/fate/fraps-v1
+++ b/tests/ref/fate/fraps-v1
@@ -1 +1 @@
-0, 0, 230400, 0x6bc891ff
+0, 0, 230400, 0xca28b1e1
diff --git a/tests/ref/fate/qtrle-1bit b/tests/ref/fate/qtrle-1bit
index 040c9bf..ec626f8 100644
--- a/tests/ref/fate/qtrle-1bit
+++ b/tests/ref/fate/qtrle-1bit
@@ -1,107 +1,107 @@
-0, 0, 9600, 0xc1632102
+0, 0, 9600, 0x1b8f0d02
1, 0, 2040, 0x0a157db4
1, 4163, 2040, 0x00c63e08
-0, 7500, 9600, 0x0f6c0521
+0, 7500, 9600, 0x6989f112
1, 8327, 2040, 0xacf2a25b
1, 12490, 2040, 0xd6189e85
-0, 15000, 9600, 0x04b90b5a
+0, 15000, 9600, 0x5ed6f74b
1, 16653, 2040, 0x8276f843
1, 20816, 2040, 0xadebae73
-0, 22500, 9600, 0x2ebd4500
+0, 22500, 9600, 0x88da3100
1, 24980, 2040, 0x5da76697
1, 29143, 2040, 0x469d0ea7
-0, 30000, 9600, 0x726f46f4
+0, 30000, 9600, 0xcc8c32f4
1, 33306, 2040, 0x0d7412e1
1, 37469, 2040, 0x2f2cc63f
-0, 37500, 9600, 0x37f6968e
+0, 37500, 9600, 0x9213828e
1, 41633, 2040, 0x10106eb7
-0, 45000, 9600, 0x7305872e
+0, 45000, 9600, 0xcd22732e
1, 45796, 2040, 0x300124c7
1, 49959, 2040, 0xa329f8e8
-0, 52500, 9600, 0x222eff5e
+0, 52500, 9600, 0x7c4beb5e
1, 54122, 2040, 0xcea35ca5
1, 58286, 2040, 0x55105aef
-0, 60000, 9600, 0x9317e227
+0, 60000, 9600, 0xed34ce27
1, 62449, 2040, 0x08980ce1
1, 66612, 2040, 0x367faf24
-0, 67500, 9600, 0x421eee9d
+0, 67500, 9600, 0x9c3bda9d
1, 70776, 2040, 0x75bfef06
1, 74939, 2040, 0x34f1daf4
-0, 75000, 9600, 0xcbcfaaff
+0, 75000, 9600, 0x25fb96ff
1, 79102, 2040, 0x97050317
-0, 82500, 9600, 0xe7d43be2
+0, 82500, 9600, 0x420027e2
1, 83265, 2040, 0xd297c536
1, 87429, 2040, 0xa8abad5a
-0, 90000, 9600, 0x0b71e28c
+0, 90000, 9600, 0x658ece8c
1, 91592, 2040, 0x445ce8e0
1, 95755, 2040, 0xa3f4d940
-0, 97500, 9600, 0xd6a050ca
+0, 97500, 9600, 0x30cc3cca
1, 99918, 2040, 0x0ebb7b26
1, 104082, 2040, 0x4372f6f6
-0, 105000, 9600, 0x0ac6dbf5
+0, 105000, 9600, 0x64e3c7f5
1, 108245, 2040, 0xd4365079
1, 112408, 2040, 0x56f902f7
-0, 112500, 9600, 0x5c036038
+0, 112500, 9600, 0xb6204c38
1, 116571, 2040, 0x4153938a
-0, 120000, 9600, 0x6e417ed6
+0, 120000, 9600, 0xc85e6ad6
1, 120735, 2040, 0x14996d86
1, 124898, 2040, 0x3f99c318
-0, 127500, 9600, 0x8bd0dc22
+0, 127500, 9600, 0xe5edc822
1, 129061, 2040, 0x939978a5
1, 133224, 2040, 0x7086bd44
-0, 135000, 9600, 0xdf3b0877
+0, 135000, 9600, 0x3967f468
1, 137388, 276, 0x25b89d22
1, 137951, 2040, 0xf3edb106
1, 142114, 2040, 0x0ca61430
-0, 142500, 9600, 0xae6e7823
+0, 142500, 9600, 0x089a6423
1, 146278, 2040, 0x7229c458
-0, 150000, 9600, 0x8ff0ac32
+0, 150000, 9600, 0xea0d9832
1, 150441, 2040, 0xc37edd31
1, 154604, 2040, 0xa3da98b4
-0, 157500, 9600, 0xa2d9e2ce
+0, 157500, 9600, 0xfcf6cece
1, 158767, 2040, 0x69704803
1, 162931, 2040, 0xa79bf334
-0, 165000, 9600, 0x5fd92b65
+0, 165000, 9600, 0xb9f61765
1, 167094, 2040, 0x59d8d4c4
1, 171257, 2040, 0xf9ff0271
-0, 172500, 9600, 0x81c1c824
+0, 172500, 9600, 0xdbdeb424
1, 175420, 2040, 0xc4ced9d6
1, 179584, 2040, 0x859f1912
-0, 180000, 9600, 0xb8a2ace4
+0, 180000, 9600, 0x12ce98e4
1, 183747, 2040, 0xe7955aa6
-0, 187500, 9600, 0x65b70404
+0, 187500, 9600, 0xbfd4eff5
1, 187910, 2040, 0x374624fd
1, 192073, 2040, 0x52121097
-0, 195000, 9600, 0xc5349eb2
+0, 195000, 9600, 0x1f608ab2
1, 196237, 2040, 0x660fe645
1, 200400, 2040, 0xf624176a
-0, 202500, 9600, 0xf60cc2b8
+0, 202500, 9600, 0x5038aeb8
1, 204563, 2040, 0x1f2246dd
1, 208727, 2040, 0x940e0a32
-0, 210000, 9600, 0x31474595
+0, 210000, 9600, 0x8b643195
1, 212890, 2040, 0x9c6d338c
1, 217053, 2040, 0xfce0d30a
-0, 217500, 9600, 0xf602635b
+0, 217500, 9600, 0x502e4f5b
1, 221216, 2040, 0xd0ec9aa5
-0, 225000, 9600, 0x873cbd87
+0, 225000, 9600, 0xe159a987
1, 225380, 2040, 0x58012141
1, 229543, 2040, 0xde67fc43
-0, 232500, 9600, 0xb9793ffe
+0, 232500, 9600, 0x13a52bfe
1, 233706, 2040, 0x6baa0450
1, 237869, 2040, 0xf4f80252
-0, 240000, 9600, 0x42eb2831
+0, 240000, 9600, 0x9d081431
1, 242033, 2040, 0x0cd47ee3
1, 246196, 2040, 0x129cbaa7
-0, 247500, 9600, 0x44cc1dab
+0, 247500, 9600, 0x9ee909ab
1, 250359, 2040, 0x5ef5c0a1
1, 254522, 2040, 0xf660baa7
-0, 255000, 9600, 0xbdcbbb87
+0, 255000, 9600, 0x17f7a787
1, 258686, 2040, 0xe48bc0a1
-0, 262500, 9600, 0x29c22df7
+0, 262500, 9600, 0x83df19f7
1, 262849, 2040, 0xdfeabaa7
1, 267012, 2040, 0xed04c0a1
-0, 270000, 9600, 0xde502ef5
+0, 270000, 9600, 0x387c1af5
1, 271176, 2040, 0xd771baa7
1, 275339, 300, 0x521f24e9
1, 275951, 1476, 0x9b9394b1
-0, 277500, 9600, 0xaf311aeb
+0, 277500, 9600, 0x095d06eb
--
1.7.7.3
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel