[SCM] libav/upstream.snapshot: Imported Upstream version 0.8.99-2253-gf27386c
siretart at users.alioth.debian.org
siretart at users.alioth.debian.org
Sat Jul 7 10:07:05 UTC 2012
The following commit has been merged in the upstream.snapshot branch:
commit 6e1f609fbb63b782c1b822b3db37255415cc5b7e
Author: Reinhard Tartler <siretart at tauware.de>
Date: Sat Jul 7 12:03:30 2012 +0200
Imported Upstream version 0.8.99-2253-gf27386c
diff --git a/.gitignore b/.gitignore
index 31a02c0..56b3040 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,47 +1,48 @@
-.config
-.version
*.a
*.o
*.d
+*.def
+*.dll
*.exe
*.ho
+*.lib
*.pc
*.so
*.so.*
*.ver
*-example
*-test
-config.*
-doc/*.1
-doc/*.html
-doc/*.pod
-doxy
-avconv
-avplay
-avprobe
-avserver
-doc/avoptions_codec.texi
-doc/avoptions_format.texi
-doc/print_options
-libavcodec/*_tablegen
-libavcodec/*_tables.c
-libavcodec/*_tables.h
-libavutil/avconfig.h
-tests/audiogen
-tests/base64
-tests/data
-tests/rotozoom
-tests/tiny_psnr
-tests/videogen
-tests/vsynth1
-tests/vsynth2
-tools/aviocat
-tools/cws2fws
-tools/graph2dot
-tools/ismindex
-tools/lavfi-showfiltfmts
-tools/pktdumper
-tools/probetest
-tools/qt-faststart
-tools/trasher
-version.h
+/.config
+/.version
+/avconv
+/avplay
+/avprobe
+/avserver
+/config.*
+/version.h
+/doc/*.1
+/doc/*.html
+/doc/*.pod
+/doc/avoptions_codec.texi
+/doc/avoptions_format.texi
+/doc/print_options
+/doxy/
+/libavcodec/*_tablegen
+/libavcodec/*_tables.c
+/libavcodec/*_tables.h
+/libavutil/avconfig.h
+/tests/audiogen
+/tests/base64
+/tests/data/
+/tests/rotozoom
+/tests/tiny_psnr
+/tests/videogen
+/tests/vsynth1/
+/tools/aviocat
+/tools/cws2fws
+/tools/graph2dot
+/tools/ismindex
+/tools/pktdumper
+/tools/probetest
+/tools/qt-faststart
+/tools/trasher
diff --git a/Changelog b/Changelog
index 99fc1dc..39ad8a3 100644
--- a/Changelog
+++ b/Changelog
@@ -17,6 +17,20 @@ version <next>:
- ZeroCodec decoder
- drop support for avconv without libavfilter
- add libavresample audio conversion library
+- audio filters support in libavfilter and avconv
+- add fps filter
+- audio split filter
+- audio mix filter
+- avprobe output is now standard INI or JSON. The old format can still
+ be used with -of old.
+- Indeo Audio decoder
+- channelsplit audio filter
+- RTMPT protocol support
+- iLBC encoding/decoding via libilbc
+- Microsoft Screen 1 decoder
+- join audio filter
+- audio channel mapping filter
+- Microsoft ATC Screen decoder
version 0.8:
diff --git a/Makefile b/Makefile
index 5da4d51..28568f9 100644
--- a/Makefile
+++ b/Makefile
@@ -184,6 +184,8 @@ distclean::
config:
$(SRC_PATH)/configure $(value LIBAV_CONFIGURATION)
+check: all alltools checkheaders examples testprogs fate
+
include $(SRC_PATH)/doc/Makefile
include $(SRC_PATH)/tests/Makefile
@@ -198,5 +200,5 @@ $(sort $(OBJDIRS)):
# so this saves some time on slow systems.
.SUFFIXES:
-.PHONY: all all-yes alltools *clean config examples install*
+.PHONY: all all-yes alltools check *clean config examples install*
.PHONY: testprogs uninstall*
diff --git a/avconv.c b/avconv.c
index f702d9d..fad0626 100644
--- a/avconv.c
+++ b/avconv.c
@@ -27,7 +27,6 @@
#include <errno.h>
#include <signal.h>
#include <limits.h>
-#include <unistd.h>
#include "libavformat/avformat.h"
#include "libavdevice/avdevice.h"
#include "libswscale/swscale.h"
@@ -45,16 +44,16 @@
#include "libavutil/avstring.h"
#include "libavutil/libm.h"
#include "libavutil/imgutils.h"
+#include "libavutil/time.h"
#include "libavformat/os_support.h"
# include "libavfilter/avfilter.h"
# include "libavfilter/avfiltergraph.h"
# include "libavfilter/buffersrc.h"
-# include "libavfilter/vsrc_buffer.h"
+# include "libavfilter/buffersink.h"
#if HAVE_SYS_RESOURCE_H
#include <sys/types.h>
-#include <sys/time.h>
#include <sys/resource.h>
#elif HAVE_GETPROCESSTIMES
#include <windows.h>
@@ -68,6 +67,10 @@
#include <sys/select.h>
#endif
+#if HAVE_PTHREADS
+#include <pthread.h>
+#endif
+
#include <time.h>
#include "cmdutils.h"
@@ -139,10 +142,10 @@ static float dts_delta_threshold = 10;
static int print_stats = 1;
-static uint8_t *audio_buf;
-static unsigned int allocated_audio_buf_size;
-static uint8_t *async_buf;
-static unsigned int allocated_async_buf_size;
+#if HAVE_PTHREADS
+/* signal to input threads that they should exit; set by the main thread */
+static int transcoding_finished;
+#endif
#define DEFAULT_PASS_LOGFILENAME_PREFIX "av2pass"
@@ -150,12 +153,14 @@ typedef struct InputFilter {
AVFilterContext *filter;
struct InputStream *ist;
struct FilterGraph *graph;
+ uint8_t *name;
} InputFilter;
typedef struct OutputFilter {
AVFilterContext *filter;
struct OutputStream *ost;
struct FilterGraph *graph;
+ uint8_t *name;
/* temporary storage until stream maps are processed */
AVFilterInOut *out_tmp;
@@ -173,19 +178,6 @@ typedef struct FilterGraph {
int nb_outputs;
} FilterGraph;
-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;
@@ -205,16 +197,22 @@ typedef struct InputStream {
int is_start; /* is 1 at the start and after a discontinuity */
int showed_multi_packet_warning;
AVDictionary *opts;
+ AVRational framerate; /* framerate forced with -r */
int resample_height;
int resample_width;
int resample_pix_fmt;
+ int resample_sample_fmt;
+ int resample_sample_rate;
+ int resample_channels;
+ uint64_t resample_channel_layout;
+
/* a pool of free buffers for decoded data */
FrameBuffer *buffer_pool;
/* decoded data from this stream goes into all those filters
- * currently video only */
+ * currently video and audio only */
InputFilter **filters;
int nb_filters;
} InputStream;
@@ -228,6 +226,15 @@ typedef struct InputFile {
int nb_streams; /* number of stream that avconv is aware of; may be different
from ctx.nb_streams if new streams appear during av_read_frame() */
int rate_emu;
+
+#if HAVE_PTHREADS
+ pthread_t thread; /* thread reading from this file */
+ int finished; /* the thread has exited */
+ int joined; /* the thread has been joined */
+ pthread_mutex_t fifo_lock; /* lock for access to fifo */
+ pthread_cond_t fifo_cond; /* the main thread will signal on this cond after reading from fifo */
+ AVFifoBuffer *fifo; /* demuxed packets are stored here; freed by the main thread */
+#endif
} InputFile;
typedef struct OutputStream {
@@ -248,7 +255,6 @@ typedef struct OutputStream {
AVBitStreamFilterContext *bitstream_filters;
AVCodec *enc;
int64_t max_frames;
- AVFrame *output_frame;
AVFrame *filtered_frame;
/* video only */
@@ -263,15 +269,8 @@ typedef struct OutputStream {
int64_t *forced_kf_pts;
int forced_kf_count;
int forced_kf_index;
+ char *forced_keyframes;
- /* audio only */
- int audio_resample;
- AVAudioResampleContext *avr;
- int resample_sample_fmt;
- int resample_channels;
- uint64_t resample_channel_layout;
- int resample_sample_rate;
- AVFifoBuffer *fifo; /* for compression: one audio fifo per codec */
FILE *logfile;
OutputFilter *filter;
@@ -454,224 +453,61 @@ static void reset_options(OptionsContext *o)
init_opts();
}
-static int alloc_buffer(InputStream *ist, AVCodecContext *s, FrameBuffer **pbuf)
-{
- FrameBuffer *buf = av_mallocz(sizeof(*buf));
- int i, 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;
- }
- /* XXX this shouldn't be needed, but some tests break without this line
- * those decoders are buggy and need to be fixed.
- * the following tests fail:
- * cdgraphics, ansi, aasc, fraps-v1, qtrle-1bit
- */
- memset(buf->base[0], 128, ret);
-
- avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift);
- for (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, s, &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, s, &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;
- frame->width = buf->w;
- frame->height = buf->h;
- frame->format = buf->pix_fmt;
- frame->sample_aspect_ratio = s->sample_aspect_ratio;
-
- 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);
+/**
+ * Define a function for building a string containing a list of
+ * allowed formats,
+ */
+#define DEF_CHOOSE_FORMAT(type, var, supported_list, none, get_name, separator) \
+static char *choose_ ## var ## s(OutputStream *ost) \
+{ \
+ if (ost->st->codec->var != none) { \
+ get_name(ost->st->codec->var); \
+ return av_strdup(name); \
+ } else if (ost->enc->supported_list) { \
+ const type *p; \
+ AVIOContext *s = NULL; \
+ uint8_t *ret; \
+ int len; \
+ \
+ if (avio_open_dyn_buf(&s) < 0) \
+ exit_program(1); \
+ \
+ for (p = ost->enc->supported_list; *p != none; p++) { \
+ get_name(*p); \
+ avio_printf(s, "%s" separator, name); \
+ } \
+ len = avio_close_dyn_buf(s, &ret); \
+ ret[len - 1] = 0; \
+ return ret; \
+ } else \
+ return NULL; \
}
-static void filter_release_buffer(AVFilterBuffer *fb)
-{
- FrameBuffer *buf = fb->priv;
- av_free(fb);
- unref_buffer(buf->ist, buf);
-}
+#define GET_PIX_FMT_NAME(pix_fmt)\
+ const char *name = av_get_pix_fmt_name(pix_fmt);
-static const enum PixelFormat *choose_pixel_fmts(OutputStream *ost)
-{
- if (ost->st->codec->pix_fmt != PIX_FMT_NONE) {
- ost->pix_fmts[0] = ost->st->codec->pix_fmt;
- return ost->pix_fmts;
- } else if (ost->enc->pix_fmts)
- return ost->enc->pix_fmts;
- else
- return NULL;
-}
+DEF_CHOOSE_FORMAT(enum PixelFormat, pix_fmt, pix_fmts, PIX_FMT_NONE,
+ GET_PIX_FMT_NAME, ":")
-static int configure_video_filters(FilterGraph *fg)
-{
- InputStream *ist = fg->inputs[0]->ist;
- OutputStream *ost = fg->outputs[0]->ost;
- AVFilterContext *last_filter, *filter;
- /** filter graph containing all filters including input & output */
- AVCodecContext *codec = ost->st->codec;
- SinkContext sink_ctx = { .pix_fmts = choose_pixel_fmts(ost) };
- AVRational sample_aspect_ratio;
- char args[255];
- int ret;
+#define GET_SAMPLE_FMT_NAME(sample_fmt)\
+ const char *name = av_get_sample_fmt_name(sample_fmt)
- avfilter_graph_free(&fg->graph);
- fg->graph = avfilter_graph_alloc();
+DEF_CHOOSE_FORMAT(enum AVSampleFormat, sample_fmt, sample_fmts,
+ AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME, ",")
- if (ist->st->sample_aspect_ratio.num) {
- sample_aspect_ratio = ist->st->sample_aspect_ratio;
- } else
- sample_aspect_ratio = ist->st->codec->sample_aspect_ratio;
+#define GET_SAMPLE_RATE_NAME(rate)\
+ char name[16];\
+ snprintf(name, sizeof(name), "%d", rate);
- snprintf(args, 255, "%d:%d:%d:%d:%d:%d:%d", ist->st->codec->width,
- ist->st->codec->height, ist->st->codec->pix_fmt, 1, AV_TIME_BASE,
- sample_aspect_ratio.num, sample_aspect_ratio.den);
+DEF_CHOOSE_FORMAT(int, sample_rate, supported_samplerates, 0,
+ GET_SAMPLE_RATE_NAME, ",")
- ret = avfilter_graph_create_filter(&fg->inputs[0]->filter,
- avfilter_get_by_name("buffer"),
- "src", args, NULL, fg->graph);
- if (ret < 0)
- return ret;
- ret = avfilter_graph_create_filter(&fg->outputs[0]->filter, &sink,
- "out", NULL, &sink_ctx, fg->graph);
- if (ret < 0)
- return ret;
- last_filter = fg->inputs[0]->filter;
+#define GET_CH_LAYOUT_NAME(ch_layout)\
+ char name[16];\
+ snprintf(name, sizeof(name), "0x%"PRIx64, ch_layout);
- if (codec->width || codec->height) {
- snprintf(args, 255, "%d:%d:flags=0x%X",
- codec->width,
- codec->height,
- (unsigned)ost->sws_flags);
- if ((ret = avfilter_graph_create_filter(&filter, avfilter_get_by_name("scale"),
- NULL, args, NULL, fg->graph)) < 0)
- return ret;
- if ((ret = avfilter_link(last_filter, 0, filter, 0)) < 0)
- return ret;
- last_filter = filter;
- }
-
- snprintf(args, sizeof(args), "flags=0x%X", (unsigned)ost->sws_flags);
- fg->graph->scale_sws_opts = av_strdup(args);
-
- if (ost->avfilter) {
- AVFilterInOut *outputs = avfilter_inout_alloc();
- AVFilterInOut *inputs = avfilter_inout_alloc();
-
- outputs->name = av_strdup("in");
- outputs->filter_ctx = last_filter;
- outputs->pad_idx = 0;
- outputs->next = NULL;
-
- inputs->name = av_strdup("out");
- inputs->filter_ctx = fg->outputs[0]->filter;
- inputs->pad_idx = 0;
- inputs->next = NULL;
-
- if ((ret = avfilter_graph_parse(fg->graph, ost->avfilter, inputs, outputs, NULL)) < 0)
- return ret;
- } else {
- if ((ret = avfilter_link(last_filter, 0, fg->outputs[0]->filter, 0)) < 0)
- return ret;
- }
-
- if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0)
- return ret;
-
- ost->filter = fg->outputs[0];
-
- return 0;
-}
+DEF_CHOOSE_FORMAT(uint64_t, channel_layout, channel_layouts, 0,
+ GET_CH_LAYOUT_NAME, ",")
static FilterGraph *init_simple_filtergraph(InputStream *ist, OutputStream *ost)
{
@@ -688,6 +524,8 @@ static FilterGraph *init_simple_filtergraph(InputStream *ist, OutputStream *ost)
fg->outputs[0]->ost = ost;
fg->outputs[0]->graph = fg;
+ ost->filter = fg->outputs[0];
+
fg->inputs = grow_array(fg->inputs, sizeof(*fg->inputs), &fg->nb_inputs,
fg->nb_inputs + 1);
if (!(fg->inputs[0] = av_mallocz(sizeof(*fg->inputs[0]))))
@@ -708,13 +546,14 @@ static FilterGraph *init_simple_filtergraph(InputStream *ist, OutputStream *ost)
static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
{
- InputStream *ist;
- enum AVMediaType type = in->filter_ctx->input_pads[in->pad_idx].type;
+ InputStream *ist = NULL;
+ enum AVMediaType type = avfilter_pad_get_type(in->filter_ctx->input_pads, in->pad_idx);
int i;
// TODO: support other filter types
- if (type != AVMEDIA_TYPE_VIDEO) {
- av_log(NULL, AV_LOG_FATAL, "Only video filters supported currently.\n");
+ if (type != AVMEDIA_TYPE_VIDEO && type != AVMEDIA_TYPE_AUDIO) {
+ av_log(NULL, AV_LOG_FATAL, "Only video and audio filters supported "
+ "currently.\n");
exit_program(1);
}
@@ -759,6 +598,8 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
exit_program(1);
}
}
+ av_assert0(ist);
+
ist->discard = 0;
ist->decoding_needed = 1;
ist->st->discard = AVDISCARD_NONE;
@@ -775,32 +616,143 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
ist->filters[ist->nb_filters - 1] = fg->inputs[fg->nb_inputs - 1];
}
-static int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
+static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
{
- SinkContext sink_ctx;
- AVCodecContext *codec = ofilter->ost->st->codec;
+ char *pix_fmts;
+ OutputStream *ost = ofilter->ost;
+ AVCodecContext *codec = ost->st->codec;
AVFilterContext *last_filter = out->filter_ctx;
int pad_idx = out->pad_idx;
int ret;
+ char name[255];
- sink_ctx.pix_fmts = choose_pixel_fmts(ofilter->ost);
-
- ret = avfilter_graph_create_filter(&ofilter->filter, &sink,
- "out", NULL, &sink_ctx, fg->graph);
+ snprintf(name, sizeof(name), "output stream %d:%d", ost->file_index, ost->index);
+ ret = avfilter_graph_create_filter(&ofilter->filter,
+ avfilter_get_by_name("buffersink"),
+ name, NULL, pix_fmts, fg->graph);
if (ret < 0)
return ret;
if (codec->width || codec->height) {
char args[255];
+ AVFilterContext *filter;
+
snprintf(args, sizeof(args), "%d:%d:flags=0x%X",
codec->width,
codec->height,
- (unsigned)ofilter->ost->sws_flags);
- if ((ret = avfilter_graph_create_filter(&last_filter, avfilter_get_by_name("scale"),
- NULL, args, NULL, fg->graph)) < 0)
+ (unsigned)ost->sws_flags);
+ snprintf(name, sizeof(name), "scaler for output stream %d:%d",
+ ost->file_index, ost->index);
+ if ((ret = avfilter_graph_create_filter(&filter, avfilter_get_by_name("scale"),
+ name, args, NULL, fg->graph)) < 0)
+ return ret;
+ if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
+ return ret;
+
+ last_filter = filter;
+ pad_idx = 0;
+ }
+
+ if ((pix_fmts = choose_pix_fmts(ost))) {
+ AVFilterContext *filter;
+ snprintf(name, sizeof(name), "pixel format for output stream %d:%d",
+ ost->file_index, ost->index);
+ if ((ret = avfilter_graph_create_filter(&filter,
+ avfilter_get_by_name("format"),
+ "format", pix_fmts, NULL,
+ fg->graph)) < 0)
+ return ret;
+ if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
+ return ret;
+
+ last_filter = filter;
+ pad_idx = 0;
+ av_freep(&pix_fmts);
+ }
+
+ if (ost->frame_rate.num) {
+ AVFilterContext *fps;
+ char args[255];
+
+ snprintf(args, sizeof(args), "fps=%d/%d", ost->frame_rate.num,
+ ost->frame_rate.den);
+ snprintf(name, sizeof(name), "fps for output stream %d:%d",
+ ost->file_index, ost->index);
+ ret = avfilter_graph_create_filter(&fps, avfilter_get_by_name("fps"),
+ name, args, NULL, fg->graph);
+ if (ret < 0)
+ return ret;
+
+ ret = avfilter_link(last_filter, pad_idx, fps, 0);
+ if (ret < 0)
+ return ret;
+ last_filter = fps;
+ pad_idx = 0;
+ }
+
+ if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
+ return ret;
+
+ return 0;
+}
+
+static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
+{
+ OutputStream *ost = ofilter->ost;
+ AVCodecContext *codec = ost->st->codec;
+ AVFilterContext *last_filter = out->filter_ctx;
+ int pad_idx = out->pad_idx;
+ char *sample_fmts, *sample_rates, *channel_layouts;
+ char name[255];
+ int ret;
+
+
+ snprintf(name, sizeof(name), "output stream %d:%d", ost->file_index, ost->index);
+ ret = avfilter_graph_create_filter(&ofilter->filter,
+ avfilter_get_by_name("abuffersink"),
+ name, NULL, NULL, fg->graph);
+ if (ret < 0)
+ return ret;
+
+ if (codec->channels && !codec->channel_layout)
+ codec->channel_layout = av_get_default_channel_layout(codec->channels);
+
+ sample_fmts = choose_sample_fmts(ost);
+ sample_rates = choose_sample_rates(ost);
+ channel_layouts = choose_channel_layouts(ost);
+ if (sample_fmts || sample_rates || channel_layouts) {
+ AVFilterContext *format;
+ char args[256];
+ int len = 0;
+
+ if (sample_fmts)
+ len += snprintf(args + len, sizeof(args) - len, "sample_fmts=%s:",
+ sample_fmts);
+ if (sample_rates)
+ len += snprintf(args + len, sizeof(args) - len, "sample_rates=%s:",
+ sample_rates);
+ if (channel_layouts)
+ len += snprintf(args + len, sizeof(args) - len, "channel_layouts=%s:",
+ channel_layouts);
+ args[len - 1] = 0;
+
+ av_freep(&sample_fmts);
+ av_freep(&sample_rates);
+ av_freep(&channel_layouts);
+
+ snprintf(name, sizeof(name), "audio format for output stream %d:%d",
+ ost->file_index, ost->index);
+ ret = avfilter_graph_create_filter(&format,
+ avfilter_get_by_name("aformat"),
+ name, args, NULL, fg->graph);
+ if (ret < 0)
return ret;
- if ((ret = avfilter_link(out->filter_ctx, out->pad_idx, last_filter, 0)) < 0)
+
+ ret = avfilter_link(last_filter, pad_idx, format, 0);
+ if (ret < 0)
return ret;
+
+ last_filter = format;
pad_idx = 0;
}
@@ -810,44 +762,193 @@ static int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFil
return 0;
}
-static int configure_complex_filter(FilterGraph *fg)
+#define DESCRIBE_FILTER_LINK(f, inout, in) \
+{ \
+ AVFilterContext *ctx = inout->filter_ctx; \
+ AVFilterPad *pads = in ? ctx->input_pads : ctx->output_pads; \
+ int nb_pads = in ? ctx->input_count : ctx->output_count; \
+ AVIOContext *pb; \
+ \
+ if (avio_open_dyn_buf(&pb) < 0) \
+ exit_program(1); \
+ \
+ avio_printf(pb, "%s", ctx->filter->name); \
+ if (nb_pads > 1) \
+ avio_printf(pb, ":%s", avfilter_pad_get_name(pads, inout->pad_idx));\
+ avio_w8(pb, 0); \
+ avio_close_dyn_buf(pb, &f->name); \
+}
+
+static int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
+{
+ av_freep(&ofilter->name);
+ DESCRIBE_FILTER_LINK(ofilter, out, 0);
+
+ switch (avfilter_pad_get_type(out->filter_ctx->output_pads, out->pad_idx)) {
+ case AVMEDIA_TYPE_VIDEO: return configure_output_video_filter(fg, ofilter, out);
+ case AVMEDIA_TYPE_AUDIO: return configure_output_audio_filter(fg, ofilter, out);
+ default: av_assert0(0);
+ }
+}
+
+static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
+ AVFilterInOut *in)
+{
+ AVFilterContext *first_filter = in->filter_ctx;
+ AVFilter *filter = avfilter_get_by_name("buffer");
+ InputStream *ist = ifilter->ist;
+ AVRational tb = ist->framerate.num ? (AVRational){ist->framerate.den,
+ ist->framerate.num} :
+ ist->st->time_base;
+ AVRational sar;
+ char args[255], name[255];
+ int pad_idx = in->pad_idx;
+ int ret;
+
+ sar = ist->st->sample_aspect_ratio.num ?
+ ist->st->sample_aspect_ratio :
+ ist->st->codec->sample_aspect_ratio;
+ snprintf(args, sizeof(args), "%d:%d:%d:%d:%d:%d:%d", ist->st->codec->width,
+ ist->st->codec->height, ist->st->codec->pix_fmt,
+ tb.num, tb.den, sar.num, sar.den);
+ snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index,
+ ist->file_index, ist->st->index);
+
+ if ((ret = avfilter_graph_create_filter(&ifilter->filter, filter, name,
+ args, NULL, fg->graph)) < 0)
+ return ret;
+
+ if (ist->framerate.num) {
+ AVFilterContext *setpts;
+
+ snprintf(name, sizeof(name), "force CFR for input from stream %d:%d",
+ ist->file_index, ist->st->index);
+ if ((ret = avfilter_graph_create_filter(&setpts,
+ avfilter_get_by_name("setpts"),
+ name, "N", NULL,
+ fg->graph)) < 0)
+ return ret;
+
+ if ((ret = avfilter_link(setpts, 0, first_filter, pad_idx)) < 0)
+ return ret;
+
+ first_filter = setpts;
+ pad_idx = 0;
+ }
+
+ if ((ret = avfilter_link(ifilter->filter, 0, first_filter, pad_idx)) < 0)
+ return ret;
+ return 0;
+}
+
+static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
+ AVFilterInOut *in)
+{
+ AVFilterContext *first_filter = in->filter_ctx;
+ AVFilter *filter = avfilter_get_by_name("abuffer");
+ InputStream *ist = ifilter->ist;
+ int pad_idx = in->pad_idx;
+ char args[255], name[255];
+ int ret;
+
+ snprintf(args, sizeof(args), "time_base=%d/%d:sample_rate=%d:sample_fmt=%s"
+ ":channel_layout=0x%"PRIx64,
+ 1, ist->st->codec->sample_rate,
+ ist->st->codec->sample_rate,
+ av_get_sample_fmt_name(ist->st->codec->sample_fmt),
+ ist->st->codec->channel_layout);
+ snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index,
+ ist->file_index, ist->st->index);
+
+ if ((ret = avfilter_graph_create_filter(&ifilter->filter, filter,
+ name, args, NULL,
+ fg->graph)) < 0)
+ return ret;
+
+ if (audio_sync_method > 0) {
+ AVFilterContext *async;
+ char args[256];
+ int len = 0;
+
+ av_log(NULL, AV_LOG_WARNING, "-async has been deprecated. Used the "
+ "asyncts audio filter instead.\n");
+
+ if (audio_sync_method > 1)
+ len += snprintf(args + len, sizeof(args) - len, "compensate=1:"
+ "max_comp=%d:", audio_sync_method);
+ snprintf(args + len, sizeof(args) - len, "min_delta=%f",
+ audio_drift_threshold);
+
+ snprintf(name, sizeof(name), "graph %d audio sync for input stream %d:%d",
+ fg->index, ist->file_index, ist->st->index);
+ ret = avfilter_graph_create_filter(&async,
+ avfilter_get_by_name("asyncts"),
+ name, args, NULL, fg->graph);
+ if (ret < 0)
+ return ret;
+
+ ret = avfilter_link(async, 0, first_filter, pad_idx);
+ if (ret < 0)
+ return ret;
+
+ first_filter = async;
+ pad_idx = 0;
+ }
+ if ((ret = avfilter_link(ifilter->filter, 0, first_filter, pad_idx)) < 0)
+ return ret;
+
+ return 0;
+}
+
+static int configure_input_filter(FilterGraph *fg, InputFilter *ifilter,
+ AVFilterInOut *in)
+{
+ av_freep(&ifilter->name);
+ DESCRIBE_FILTER_LINK(ifilter, in, 1);
+
+ switch (avfilter_pad_get_type(in->filter_ctx->input_pads, in->pad_idx)) {
+ case AVMEDIA_TYPE_VIDEO: return configure_input_video_filter(fg, ifilter, in);
+ case AVMEDIA_TYPE_AUDIO: return configure_input_audio_filter(fg, ifilter, in);
+ default: av_assert0(0);
+ }
+}
+
+static int configure_filtergraph(FilterGraph *fg)
{
AVFilterInOut *inputs, *outputs, *cur;
- int ret, i, init = !fg->graph;
+ int ret, i, init = !fg->graph, simple = !fg->graph_desc;
+ const char *graph_desc = simple ? fg->outputs[0]->ost->avfilter :
+ fg->graph_desc;
avfilter_graph_free(&fg->graph);
if (!(fg->graph = avfilter_graph_alloc()))
return AVERROR(ENOMEM);
- if ((ret = avfilter_graph_parse2(fg->graph, fg->graph_desc, &inputs, &outputs)) < 0)
+ if (simple) {
+ OutputStream *ost = fg->outputs[0]->ost;
+ char args[255];
+ snprintf(args, sizeof(args), "flags=0x%X", (unsigned)ost->sws_flags);
+ fg->graph->scale_sws_opts = av_strdup(args);
+ }
+
+ if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, &outputs)) < 0)
return ret;
- for (cur = inputs; init && cur; cur = cur->next)
+ if (simple && (!inputs || inputs->next || !outputs || outputs->next)) {
+ av_log(NULL, AV_LOG_ERROR, "Simple filtergraph '%s' does not have "
+ "exactly one input and output.\n", graph_desc);
+ return AVERROR(EINVAL);
+ }
+
+ for (cur = inputs; !simple && init && cur; cur = cur->next)
init_input_filter(fg, cur);
- for (cur = inputs, i = 0; cur; cur = cur->next, i++) {
- InputFilter *ifilter = fg->inputs[i];
- InputStream *ist = ifilter->ist;
- AVRational sar;
- char args[255];
-
- sar = ist->st->sample_aspect_ratio.num ? ist->st->sample_aspect_ratio :
- ist->st->codec->sample_aspect_ratio;
- snprintf(args, sizeof(args), "%d:%d:%d:%d:%d:%d:%d", ist->st->codec->width,
- ist->st->codec->height, ist->st->codec->pix_fmt, 1, AV_TIME_BASE,
- sar.num, sar.den);
-
- if ((ret = avfilter_graph_create_filter(&ifilter->filter,
- avfilter_get_by_name("buffer"), cur->name,
- args, NULL, fg->graph)) < 0)
- return ret;
- if ((ret = avfilter_link(ifilter->filter, 0,
- cur->filter_ctx, cur->pad_idx)) < 0)
+ for (cur = inputs, i = 0; cur; cur = cur->next, i++)
+ if ((ret = configure_input_filter(fg, fg->inputs[i], cur)) < 0)
return ret;
- }
avfilter_inout_free(&inputs);
- if (!init) {
+ if (!init || simple) {
/* we already know the mappings between lavfi outputs and output streams,
* so we can finish the setup */
for (cur = outputs, i = 0; cur; cur = cur->next, i++)
@@ -879,16 +980,11 @@ static int configure_complex_filters(void)
for (i = 0; i < nb_filtergraphs; i++)
if (!filtergraphs[i]->graph &&
- (ret = configure_complex_filter(filtergraphs[i])) < 0)
+ (ret = configure_filtergraph(filtergraphs[i])) < 0)
return ret;
return 0;
}
-static int configure_filtergraph(FilterGraph *fg)
-{
- return fg->graph_desc ? configure_complex_filter(fg) : configure_video_filters(fg);
-}
-
static int ist_in_filtergraph(FilterGraph *fg, InputStream *ist)
{
int i;
@@ -936,11 +1032,15 @@ void exit_program(int ret)
for (i = 0; i < nb_filtergraphs; i++) {
avfilter_graph_free(&filtergraphs[i]->graph);
- for (j = 0; j < filtergraphs[i]->nb_inputs; j++)
+ for (j = 0; j < filtergraphs[i]->nb_inputs; j++) {
+ av_freep(&filtergraphs[i]->inputs[j]->name);
av_freep(&filtergraphs[i]->inputs[j]);
+ }
av_freep(&filtergraphs[i]->inputs);
- for (j = 0; j < filtergraphs[i]->nb_outputs; j++)
+ for (j = 0; j < filtergraphs[i]->nb_outputs; j++) {
+ av_freep(&filtergraphs[i]->outputs[j]->name);
av_freep(&filtergraphs[i]->outputs[j]);
+ }
av_freep(&filtergraphs[i]->outputs);
av_freep(&filtergraphs[i]);
}
@@ -964,13 +1064,7 @@ void exit_program(int ret)
}
output_streams[i]->bitstream_filters = NULL;
- if (output_streams[i]->output_frame) {
- AVFrame *frame = output_streams[i]->output_frame;
- if (frame->extended_data != frame->data)
- av_freep(&frame->extended_data);
- av_freep(&frame);
- }
-
+ av_freep(&output_streams[i]->forced_keyframes);
av_freep(&output_streams[i]->avfilter);
av_freep(&output_streams[i]->filtered_frame);
av_freep(&output_streams[i]);
@@ -982,7 +1076,7 @@ void exit_program(int ret)
for (i = 0; i < nb_input_streams; i++) {
av_freep(&input_streams[i]->decoded_frame);
av_dict_free(&input_streams[i]->opts);
- free_buffer_pool(input_streams[i]);
+ free_buffer_pool(&input_streams[i]->buffer_pool);
av_freep(&input_streams[i]->filters);
av_freep(&input_streams[i]);
}
@@ -997,10 +1091,6 @@ void exit_program(int ret)
av_freep(&output_files);
uninit_opts();
- av_free(audio_buf);
- allocated_audio_buf_size = 0;
- av_free(async_buf);
- allocated_async_buf_size = 0;
avfilter_uninit();
avformat_network_deinit();
@@ -1040,25 +1130,6 @@ static void assert_codec_experimental(AVCodecContext *c, int encoder)
}
}
-static void choose_sample_fmt(AVStream *st, AVCodec *codec)
-{
- if (codec && codec->sample_fmts) {
- const enum AVSampleFormat *p = codec->sample_fmts;
- for (; *p != -1; p++) {
- if (*p == st->codec->sample_fmt)
- break;
- }
- if (*p == -1) {
- av_log(NULL, AV_LOG_WARNING,
- "Incompatible sample format '%s' for codec '%s', auto-selecting format '%s'\n",
- av_get_sample_fmt_name(st->codec->sample_fmt),
- codec->name,
- av_get_sample_fmt_name(codec->sample_fmts[0]));
- st->codec->sample_fmt = codec->sample_fmts[0];
- }
- }
-}
-
/**
* Update the requested input sample format based on the output sample format.
* This is currently only used to request float output from decoders which
@@ -1099,33 +1170,6 @@ static void update_sample_fmt(AVCodecContext *dec, AVCodec *dec_codec,
}
}
-static void choose_sample_rate(AVStream *st, AVCodec *codec)
-{
- if (codec && codec->supported_samplerates) {
- const int *p = codec->supported_samplerates;
- int best = 0;
- int best_dist = INT_MAX;
- for (; *p; p++) {
- int dist = abs(st->codec->sample_rate - *p);
- if (dist < best_dist) {
- best_dist = dist;
- best = *p;
- }
- }
- if (best_dist) {
- av_log(st->codec, AV_LOG_WARNING, "Requested sampling rate unsupported using closest supported (%d)\n", best);
- }
- st->codec->sample_rate = best;
- }
-}
-
-static double
-get_sync_ipts(const OutputStream *ost, int64_t pts)
-{
- OutputFile *of = output_files[ost->file_index];
- return (double)(pts - of->start_time) / AV_TIME_BASE;
-}
-
static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
{
AVBitStreamFilterContext *bsfc = ost->bitstream_filters;
@@ -1190,107 +1234,24 @@ static int check_recording_time(OutputStream *ost)
return 1;
}
-static void get_default_channel_layouts(OutputStream *ost, InputStream *ist)
-{
- char layout_name[256];
- AVCodecContext *enc = ost->st->codec;
- AVCodecContext *dec = ist->st->codec;
-
- if (dec->channel_layout &&
- av_get_channel_layout_nb_channels(dec->channel_layout) != dec->channels) {
- av_get_channel_layout_string(layout_name, sizeof(layout_name),
- dec->channels, dec->channel_layout);
- av_log(NULL, AV_LOG_ERROR, "New channel layout (%s) is invalid\n",
- layout_name);
- dec->channel_layout = 0;
- }
- if (!dec->channel_layout) {
- if (enc->channel_layout && dec->channels == enc->channels) {
- dec->channel_layout = enc->channel_layout;
- } else {
- dec->channel_layout = av_get_default_channel_layout(dec->channels);
-
- if (!dec->channel_layout) {
- av_log(NULL, AV_LOG_FATAL, "Unable to find default channel "
- "layout for Input Stream #%d.%d\n", ist->file_index,
- ist->st->index);
- exit_program(1);
- }
- }
- av_get_channel_layout_string(layout_name, sizeof(layout_name),
- dec->channels, dec->channel_layout);
- av_log(NULL, AV_LOG_WARNING, "Guessed Channel Layout for Input Stream "
- "#%d.%d : %s\n", ist->file_index, ist->st->index, layout_name);
- }
- if (!enc->channel_layout) {
- if (dec->channels == enc->channels) {
- enc->channel_layout = dec->channel_layout;
- return;
- } else {
- enc->channel_layout = av_get_default_channel_layout(enc->channels);
- }
- if (!enc->channel_layout) {
- av_log(NULL, AV_LOG_FATAL, "Unable to find default channel layout "
- "for Output Stream #%d.%d\n", ost->file_index,
- ost->st->index);
- exit_program(1);
- }
- av_get_channel_layout_string(layout_name, sizeof(layout_name),
- enc->channels, enc->channel_layout);
- av_log(NULL, AV_LOG_WARNING, "Guessed Channel Layout for Output Stream "
- "#%d.%d : %s\n", ost->file_index, ost->st->index, layout_name);
- }
-}
-
-static void generate_silence(uint8_t* buf, enum AVSampleFormat sample_fmt, size_t size)
-{
- int fill_char = 0x00;
- if (sample_fmt == AV_SAMPLE_FMT_U8)
- fill_char = 0x80;
- memset(buf, fill_char, size);
-}
-
-static int encode_audio_frame(AVFormatContext *s, OutputStream *ost,
- const uint8_t *buf, int buf_size)
+static void do_audio_out(AVFormatContext *s, OutputStream *ost,
+ AVFrame *frame)
{
AVCodecContext *enc = ost->st->codec;
- AVFrame *frame = NULL;
AVPacket pkt;
- int ret, got_packet;
+ int got_packet = 0;
av_init_packet(&pkt);
pkt.data = NULL;
pkt.size = 0;
- if (buf) {
- if (!ost->output_frame) {
- ost->output_frame = avcodec_alloc_frame();
- if (!ost->output_frame) {
- av_log(NULL, AV_LOG_FATAL, "out-of-memory in encode_audio_frame()\n");
- exit_program(1);
- }
- }
- frame = ost->output_frame;
- if (frame->extended_data != frame->data)
- av_freep(&frame->extended_data);
- avcodec_get_frame_defaults(frame);
-
- frame->nb_samples = buf_size /
- (enc->channels * av_get_bytes_per_sample(enc->sample_fmt));
- if ((ret = avcodec_fill_audio_frame(frame, enc->channels, enc->sample_fmt,
- buf, buf_size, 1)) < 0) {
- av_log(NULL, AV_LOG_FATAL, "Audio encoding failed\n");
- exit_program(1);
- }
-
- if (!check_recording_time(ost))
- return 0;
+ if (!check_recording_time(ost))
+ return;
+ if (frame->pts == AV_NOPTS_VALUE || audio_sync_method < 0)
frame->pts = ost->sync_opts;
- ost->sync_opts += frame->nb_samples;
- }
+ ost->sync_opts = frame->pts + frame->nb_samples;
- got_packet = 0;
if (avcodec_encode_audio2(enc, &pkt, frame, &got_packet) < 0) {
av_log(NULL, AV_LOG_FATAL, "Audio encoding failed\n");
exit_program(1);
@@ -1308,207 +1269,6 @@ static int encode_audio_frame(AVFormatContext *s, OutputStream *ost,
audio_size += pkt.size;
}
-
- return pkt.size;
-}
-
-static int alloc_audio_output_buf(AVCodecContext *dec, AVCodecContext *enc,
- int nb_samples, int *buf_linesize)
-{
- int64_t audio_buf_samples;
- int audio_buf_size;
-
- /* calculate required number of samples to allocate */
- audio_buf_samples = ((int64_t)nb_samples * enc->sample_rate + dec->sample_rate) /
- dec->sample_rate;
- audio_buf_samples = 4 * audio_buf_samples + 16; // safety factors for resampling
- audio_buf_samples = FFMAX(audio_buf_samples, enc->frame_size);
- if (audio_buf_samples > INT_MAX)
- return AVERROR(EINVAL);
-
- audio_buf_size = av_samples_get_buffer_size(buf_linesize, enc->channels,
- audio_buf_samples,
- enc->sample_fmt, 0);
- if (audio_buf_size < 0)
- return audio_buf_size;
-
- av_fast_malloc(&audio_buf, &allocated_audio_buf_size, audio_buf_size);
- if (!audio_buf)
- return AVERROR(ENOMEM);
-
- return 0;
-}
-
-static void do_audio_out(AVFormatContext *s, OutputStream *ost,
- InputStream *ist, AVFrame *decoded_frame)
-{
- uint8_t *buftmp;
-
- int size_out, frame_bytes, resample_changed, ret;
- AVCodecContext *enc = ost->st->codec;
- AVCodecContext *dec = ist->st->codec;
- int osize = av_get_bytes_per_sample(enc->sample_fmt);
- int isize = av_get_bytes_per_sample(dec->sample_fmt);
- uint8_t *buf = decoded_frame->data[0];
- int size = decoded_frame->nb_samples * dec->channels * isize;
- int out_linesize = 0;
- int buf_linesize = decoded_frame->linesize[0];
-
- get_default_channel_layouts(ost, ist);
-
- if (alloc_audio_output_buf(dec, enc, decoded_frame->nb_samples, &out_linesize) < 0) {
- av_log(NULL, AV_LOG_FATAL, "Error allocating audio buffer\n");
- exit_program(1);
- }
-
- if (audio_sync_method > 1 ||
- enc->channels != dec->channels ||
- enc->channel_layout != dec->channel_layout ||
- enc->sample_rate != dec->sample_rate ||
- dec->sample_fmt != enc->sample_fmt)
- ost->audio_resample = 1;
-
- resample_changed = ost->resample_sample_fmt != dec->sample_fmt ||
- ost->resample_channels != dec->channels ||
- ost->resample_channel_layout != dec->channel_layout ||
- ost->resample_sample_rate != dec->sample_rate;
-
- if ((ost->audio_resample && !ost->avr) || resample_changed) {
- if (resample_changed) {
- av_log(NULL, AV_LOG_INFO, "Input stream #%d:%d frame changed from rate:%d fmt:%s ch:%d chl:0x%"PRIx64" to rate:%d fmt:%s ch:%d chl:0x%"PRIx64"\n",
- ist->file_index, ist->st->index,
- ost->resample_sample_rate, av_get_sample_fmt_name(ost->resample_sample_fmt),
- ost->resample_channels, ost->resample_channel_layout,
- dec->sample_rate, av_get_sample_fmt_name(dec->sample_fmt),
- dec->channels, dec->channel_layout);
- ost->resample_sample_fmt = dec->sample_fmt;
- ost->resample_channels = dec->channels;
- ost->resample_channel_layout = dec->channel_layout;
- ost->resample_sample_rate = dec->sample_rate;
- if (ost->avr)
- avresample_close(ost->avr);
- }
- /* if audio_sync_method is >1 the resampler is needed for audio drift compensation */
- if (audio_sync_method <= 1 &&
- ost->resample_sample_fmt == enc->sample_fmt &&
- ost->resample_channels == enc->channels &&
- ost->resample_channel_layout == enc->channel_layout &&
- ost->resample_sample_rate == enc->sample_rate) {
- ost->audio_resample = 0;
- } else if (ost->audio_resample) {
- if (!ost->avr) {
- ost->avr = avresample_alloc_context();
- if (!ost->avr) {
- av_log(NULL, AV_LOG_FATAL, "Error allocating context for libavresample\n");
- exit_program(1);
- }
- }
-
- av_opt_set_int(ost->avr, "in_channel_layout", dec->channel_layout, 0);
- av_opt_set_int(ost->avr, "in_sample_fmt", dec->sample_fmt, 0);
- av_opt_set_int(ost->avr, "in_sample_rate", dec->sample_rate, 0);
- av_opt_set_int(ost->avr, "out_channel_layout", enc->channel_layout, 0);
- av_opt_set_int(ost->avr, "out_sample_fmt", enc->sample_fmt, 0);
- av_opt_set_int(ost->avr, "out_sample_rate", enc->sample_rate, 0);
- if (audio_sync_method > 1)
- av_opt_set_int(ost->avr, "force_resampling", 1, 0);
-
- /* if both the input and output formats are s16 or u8, use s16 as
- the internal sample format */
- if (av_get_bytes_per_sample(dec->sample_fmt) <= 2 &&
- av_get_bytes_per_sample(enc->sample_fmt) <= 2) {
- av_opt_set_int(ost->avr, "internal_sample_fmt", AV_SAMPLE_FMT_S16P, 0);
- }
-
- ret = avresample_open(ost->avr);
- if (ret < 0) {
- av_log(NULL, AV_LOG_FATAL, "Error opening libavresample\n");
- exit_program(1);
- }
- }
- }
-
- if (audio_sync_method > 0) {
- double delta = get_sync_ipts(ost, ist->last_dts) * enc->sample_rate - ost->sync_opts -
- av_fifo_size(ost->fifo) / (enc->channels * osize);
- int idelta = delta * dec->sample_rate / enc->sample_rate;
- int byte_delta = idelta * isize * dec->channels;
-
- // FIXME resample delay
- if (fabs(delta) > 50) {
- if (ist->is_start || fabs(delta) > audio_drift_threshold*enc->sample_rate) {
- if (byte_delta < 0) {
- byte_delta = FFMAX(byte_delta, -size);
- size += byte_delta;
- buf -= byte_delta;
- av_log(NULL, AV_LOG_VERBOSE, "discarding %d audio samples\n",
- -byte_delta / (isize * dec->channels));
- if (!size)
- return;
- ist->is_start = 0;
- } else {
- av_fast_malloc(&async_buf, &allocated_async_buf_size,
- byte_delta + size);
- if (!async_buf) {
- av_log(NULL, AV_LOG_FATAL, "Out of memory in do_audio_out\n");
- exit_program(1);
- }
-
- if (alloc_audio_output_buf(dec, enc, decoded_frame->nb_samples + idelta, &out_linesize) < 0) {
- av_log(NULL, AV_LOG_FATAL, "Error allocating audio buffer\n");
- exit_program(1);
- }
- ist->is_start = 0;
-
- generate_silence(async_buf, dec->sample_fmt, byte_delta);
- memcpy(async_buf + byte_delta, buf, size);
- buf = async_buf;
- size += byte_delta;
- buf_linesize = allocated_async_buf_size;
- av_log(NULL, AV_LOG_VERBOSE, "adding %d audio samples of silence\n", idelta);
- }
- } else if (audio_sync_method > 1) {
- int comp = av_clip(delta, -audio_sync_method, audio_sync_method);
- av_log(NULL, AV_LOG_VERBOSE, "compensating audio timestamp drift:%f compensation:%d in:%d\n",
- delta, comp, enc->sample_rate);
-// fprintf(stderr, "drift:%f len:%d opts:%"PRId64" ipts:%"PRId64" fifo:%d\n", delta, -1, ost->sync_opts, (int64_t)(get_sync_ipts(ost) * enc->sample_rate), av_fifo_size(ost->fifo)/(ost->st->codec->channels * 2));
- avresample_set_compensation(ost->avr, comp, enc->sample_rate);
- }
- }
- } else if (audio_sync_method == 0)
- ost->sync_opts = lrintf(get_sync_ipts(ost, ist->last_dts) * enc->sample_rate) -
- av_fifo_size(ost->fifo) / (enc->channels * osize); // FIXME wrong
-
- if (ost->audio_resample) {
- buftmp = audio_buf;
- size_out = avresample_convert(ost->avr, (void **)&buftmp,
- allocated_audio_buf_size, out_linesize,
- (void **)&buf, buf_linesize,
- size / (dec->channels * isize));
- size_out = size_out * enc->channels * osize;
- } else {
- buftmp = buf;
- size_out = size;
- }
-
- /* now encode as many frames as possible */
- if (!(enc->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)) {
- /* output resampled raw samples */
- if (av_fifo_realloc2(ost->fifo, av_fifo_size(ost->fifo) + size_out) < 0) {
- av_log(NULL, AV_LOG_FATAL, "av_fifo_realloc2() failed\n");
- exit_program(1);
- }
- av_fifo_generic_write(ost->fifo, buftmp, size_out, NULL);
-
- frame_bytes = enc->frame_size * osize * enc->channels;
-
- while (av_fifo_size(ost->fifo) >= frame_bytes) {
- av_fifo_generic_read(ost->fifo, audio_buf, frame_bytes, NULL);
- encode_audio_frame(s, ost, audio_buf, frame_bytes);
- }
- } else {
- encode_audio_frame(s, ost, buftmp, size_out);
- }
}
static void pre_process_video_frame(InputStream *ist, AVPicture *picture, void **bufp)
@@ -1621,17 +1381,9 @@ static void do_video_out(AVFormatContext *s,
AVFrame *in_picture,
int *frame_size, float quality)
{
- int nb_frames, i, ret, format_video_sync;
- AVCodecContext *enc;
- double sync_ipts, delta;
-
- enc = ost->st->codec;
-
- sync_ipts = get_sync_ipts(ost, in_picture->pts) / av_q2d(enc->time_base);
- delta = sync_ipts - ost->sync_opts;
-
- /* by default, we output a single frame */
- nb_frames = 1;
+ int ret, format_video_sync;
+ AVPacket pkt;
+ AVCodecContext *enc = ost->st->codec;
*frame_size = 0;
@@ -1639,120 +1391,98 @@ static void do_video_out(AVFormatContext *s,
if (format_video_sync == VSYNC_AUTO)
format_video_sync = (s->oformat->flags & AVFMT_NOTIMESTAMPS) ? VSYNC_PASSTHROUGH :
(s->oformat->flags & AVFMT_VARIABLE_FPS) ? VSYNC_VFR : VSYNC_CFR;
-
- switch (format_video_sync) {
- case VSYNC_CFR:
- // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
- if (delta < -1.1)
- nb_frames = 0;
- else if (delta > 1.1)
- nb_frames = lrintf(delta);
- break;
- case VSYNC_VFR:
- if (delta <= -0.6)
- nb_frames = 0;
- else if (delta > 0.6)
- ost->sync_opts = lrintf(sync_ipts);
- break;
- case VSYNC_PASSTHROUGH:
- ost->sync_opts = lrintf(sync_ipts);
- break;
- default:
- av_assert0(0);
- }
-
- nb_frames = FFMIN(nb_frames, ost->max_frames - ost->frame_number);
- if (nb_frames == 0) {
+ if (format_video_sync != VSYNC_PASSTHROUGH &&
+ ost->frame_number &&
+ in_picture->pts != AV_NOPTS_VALUE &&
+ in_picture->pts < ost->sync_opts) {
nb_frames_drop++;
av_log(NULL, AV_LOG_VERBOSE, "*** drop!\n");
return;
- } else if (nb_frames > 1) {
- nb_frames_dup += nb_frames - 1;
- av_log(NULL, AV_LOG_VERBOSE, "*** %d dup!\n", nb_frames - 1);
}
+ if (in_picture->pts == AV_NOPTS_VALUE)
+ in_picture->pts = ost->sync_opts;
+ ost->sync_opts = in_picture->pts;
+
+
if (!ost->frame_number)
- ost->first_pts = ost->sync_opts;
+ ost->first_pts = in_picture->pts;
- /* duplicates frame if needed */
- for (i = 0; i < nb_frames; i++) {
- AVPacket pkt;
- av_init_packet(&pkt);
- pkt.data = NULL;
- pkt.size = 0;
+ av_init_packet(&pkt);
+ pkt.data = NULL;
+ pkt.size = 0;
- if (!check_recording_time(ost))
- return;
+ if (!check_recording_time(ost) ||
+ ost->frame_number >= ost->max_frames)
+ return;
- if (s->oformat->flags & AVFMT_RAWPICTURE &&
- enc->codec->id == CODEC_ID_RAWVIDEO) {
- /* raw pictures are written as AVPicture structure to
- avoid any copies. We support temporarily the older
- method. */
- enc->coded_frame->interlaced_frame = in_picture->interlaced_frame;
- enc->coded_frame->top_field_first = in_picture->top_field_first;
- pkt.data = (uint8_t *)in_picture;
- pkt.size = sizeof(AVPicture);
- pkt.pts = av_rescale_q(ost->sync_opts, enc->time_base, ost->st->time_base);
- pkt.flags |= AV_PKT_FLAG_KEY;
+ if (s->oformat->flags & AVFMT_RAWPICTURE &&
+ enc->codec->id == CODEC_ID_RAWVIDEO) {
+ /* raw pictures are written as AVPicture structure to
+ avoid any copies. We support temporarily the older
+ method. */
+ enc->coded_frame->interlaced_frame = in_picture->interlaced_frame;
+ enc->coded_frame->top_field_first = in_picture->top_field_first;
+ pkt.data = (uint8_t *)in_picture;
+ pkt.size = sizeof(AVPicture);
+ pkt.pts = av_rescale_q(in_picture->pts, enc->time_base, ost->st->time_base);
+ pkt.flags |= AV_PKT_FLAG_KEY;
- write_frame(s, &pkt, ost);
- } else {
- int got_packet;
- AVFrame big_picture;
-
- big_picture = *in_picture;
- /* better than nothing: use input picture interlaced
- settings */
- big_picture.interlaced_frame = in_picture->interlaced_frame;
- if (ost->st->codec->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME)) {
- if (ost->top_field_first == -1)
- big_picture.top_field_first = in_picture->top_field_first;
- else
- big_picture.top_field_first = !!ost->top_field_first;
- }
+ write_frame(s, &pkt, ost);
+ } else {
+ int got_packet;
+ AVFrame big_picture;
+
+ big_picture = *in_picture;
+ /* better than nothing: use input picture interlaced
+ settings */
+ big_picture.interlaced_frame = in_picture->interlaced_frame;
+ if (ost->st->codec->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME)) {
+ if (ost->top_field_first == -1)
+ big_picture.top_field_first = in_picture->top_field_first;
+ else
+ big_picture.top_field_first = !!ost->top_field_first;
+ }
- /* handles same_quant here. This is not correct because it may
- not be a global option */
- big_picture.quality = quality;
- if (!enc->me_threshold)
- big_picture.pict_type = 0;
- big_picture.pts = ost->sync_opts;
- if (ost->forced_kf_index < ost->forced_kf_count &&
- big_picture.pts >= ost->forced_kf_pts[ost->forced_kf_index]) {
- big_picture.pict_type = AV_PICTURE_TYPE_I;
- ost->forced_kf_index++;
- }
- ret = avcodec_encode_video2(enc, &pkt, &big_picture, &got_packet);
- if (ret < 0) {
- av_log(NULL, AV_LOG_FATAL, "Video encoding failed\n");
- exit_program(1);
- }
+ /* handles same_quant here. This is not correct because it may
+ not be a global option */
+ big_picture.quality = quality;
+ if (!enc->me_threshold)
+ big_picture.pict_type = 0;
+ if (ost->forced_kf_index < ost->forced_kf_count &&
+ big_picture.pts >= ost->forced_kf_pts[ost->forced_kf_index]) {
+ big_picture.pict_type = AV_PICTURE_TYPE_I;
+ ost->forced_kf_index++;
+ }
+ ret = avcodec_encode_video2(enc, &pkt, &big_picture, &got_packet);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_FATAL, "Video encoding failed\n");
+ exit_program(1);
+ }
- if (got_packet) {
- if (pkt.pts != AV_NOPTS_VALUE)
- pkt.pts = av_rescale_q(pkt.pts, enc->time_base, ost->st->time_base);
- if (pkt.dts != AV_NOPTS_VALUE)
- pkt.dts = av_rescale_q(pkt.dts, enc->time_base, ost->st->time_base);
+ if (got_packet) {
+ if (pkt.pts != AV_NOPTS_VALUE)
+ pkt.pts = av_rescale_q(pkt.pts, enc->time_base, ost->st->time_base);
+ if (pkt.dts != AV_NOPTS_VALUE)
+ pkt.dts = av_rescale_q(pkt.dts, enc->time_base, ost->st->time_base);
- write_frame(s, &pkt, ost);
- *frame_size = pkt.size;
- video_size += pkt.size;
+ write_frame(s, &pkt, ost);
+ *frame_size = pkt.size;
+ video_size += pkt.size;
- /* if two pass, output log */
- if (ost->logfile && enc->stats_out) {
- fprintf(ost->logfile, "%s", enc->stats_out);
- }
+ /* if two pass, output log */
+ if (ost->logfile && enc->stats_out) {
+ fprintf(ost->logfile, "%s", enc->stats_out);
}
}
- ost->sync_opts++;
- /*
- * For video, number of frames in == number of packets out.
- * But there may be reordering, so we can't throw away frames on encoder
- * flush, we need to limit them here, before they go into encoder.
- */
- ost->frame_number++;
}
+ ost->sync_opts++;
+ /*
+ * For video, number of frames in == number of packets out.
+ * But there may be reordering, so we can't throw away frames on encoder
+ * flush, we need to limit them here, before they go into encoder.
+ */
+ ost->frame_number++;
}
static double psnr(double d)
@@ -1802,13 +1532,14 @@ static int poll_filters(void)
{
AVFilterBufferRef *picref;
AVFrame *filtered_frame = NULL;
- int i, frame_size, ret;
+ int i, frame_size;
for (i = 0; i < nb_output_streams; i++) {
OutputStream *ost = output_streams[i];
OutputFile *of = output_files[ost->file_index];
+ int ret = 0;
- if (!ost->filter || ost->is_past_recording_time)
+ if (!ost->filter)
continue;
if (!ost->filtered_frame && !(ost->filtered_frame = avcodec_alloc_frame())) {
@@ -1817,16 +1548,31 @@ static int poll_filters(void)
avcodec_get_frame_defaults(ost->filtered_frame);
filtered_frame = ost->filtered_frame;
- while (avfilter_poll_frame(ost->filter->filter->inputs[0])) {
- AVRational ist_pts_tb;
- if ((ret = get_filtered_video_frame(ost->filter->filter,
- filtered_frame, &picref,
- &ist_pts_tb)) < 0)
- return ret;
- filtered_frame->pts = av_rescale_q(picref->pts, ist_pts_tb, AV_TIME_BASE_Q);
+ while (ret >= 0 && !ost->is_past_recording_time) {
+ if (ost->enc->type == AVMEDIA_TYPE_AUDIO &&
+ !(ost->enc->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE))
+ ret = av_buffersink_read_samples(ost->filter->filter, &picref,
+ ost->st->codec->frame_size);
+ else
+ ret = av_buffersink_read(ost->filter->filter, &picref);
- if (of->start_time && filtered_frame->pts < of->start_time)
- return 0;
+ if (ret < 0)
+ break;
+
+ avfilter_copy_buf_props(filtered_frame, picref);
+ if (picref->pts != AV_NOPTS_VALUE) {
+ filtered_frame->pts = av_rescale_q(picref->pts,
+ ost->filter->filter->inputs[0]->time_base,
+ ost->st->codec->time_base) -
+ av_rescale_q(of->start_time,
+ AV_TIME_BASE_Q,
+ ost->st->codec->time_base);
+
+ if (of->start_time && filtered_frame->pts < 0) {
+ avfilter_unref_buffer(picref);
+ continue;
+ }
+ }
switch (ost->filter->filter->inputs[0]->type) {
case AVMEDIA_TYPE_VIDEO:
@@ -1839,8 +1585,11 @@ static int poll_filters(void)
if (vstats_filename && frame_size)
do_video_stats(of->ctx, ost, frame_size);
break;
+ case AVMEDIA_TYPE_AUDIO:
+ do_audio_out(of->ctx, ost, filtered_frame);
+ break;
default:
- // TODO support audio/subtitle filters
+ // TODO support subtitle filters
av_assert0(0);
}
@@ -1990,46 +1739,38 @@ static void flush_encoders(void)
continue;
for (;;) {
- AVPacket pkt;
- int fifo_bytes, got_packet;
- av_init_packet(&pkt);
- pkt.data = NULL;
- pkt.size = 0;
+ int (*encode)(AVCodecContext*, AVPacket*, const AVFrame*, int*) = NULL;
+ const char *desc;
+ int64_t *size;
switch (ost->st->codec->codec_type) {
case AVMEDIA_TYPE_AUDIO:
- fifo_bytes = av_fifo_size(ost->fifo);
- if (fifo_bytes > 0) {
- /* encode any samples remaining in fifo */
- int frame_bytes = fifo_bytes;
-
- av_fifo_generic_read(ost->fifo, audio_buf, fifo_bytes, NULL);
-
- /* pad last frame with silence if needed */
- if (!(enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME)) {
- frame_bytes = enc->frame_size * enc->channels *
- av_get_bytes_per_sample(enc->sample_fmt);
- if (allocated_audio_buf_size < frame_bytes)
- exit_program(1);
- generate_silence(audio_buf+fifo_bytes, enc->sample_fmt, frame_bytes - fifo_bytes);
- }
- encode_audio_frame(os, ost, audio_buf, frame_bytes);
- } else {
- /* flush encoder with NULL frames until it is done
- returning packets */
- if (encode_audio_frame(os, ost, NULL, 0) == 0) {
- stop_encoding = 1;
- break;
- }
- }
+ encode = avcodec_encode_audio2;
+ desc = "Audio";
+ size = &audio_size;
break;
case AVMEDIA_TYPE_VIDEO:
- ret = avcodec_encode_video2(enc, &pkt, NULL, &got_packet);
+ encode = avcodec_encode_video2;
+ desc = "Video";
+ size = &video_size;
+ break;
+ default:
+ stop_encoding = 1;
+ }
+
+ if (encode) {
+ AVPacket pkt;
+ int got_packet;
+ av_init_packet(&pkt);
+ pkt.data = NULL;
+ pkt.size = 0;
+
+ ret = encode(enc, &pkt, NULL, &got_packet);
if (ret < 0) {
- av_log(NULL, AV_LOG_FATAL, "Video encoding failed\n");
+ av_log(NULL, AV_LOG_FATAL, "%s encoding failed\n", desc);
exit_program(1);
}
- video_size += ret;
+ *size += ret;
if (ost->logfile && enc->stats_out) {
fprintf(ost->logfile, "%s", enc->stats_out);
}
@@ -2042,10 +1783,8 @@ static void flush_encoders(void)
if (pkt.dts != AV_NOPTS_VALUE)
pkt.dts = av_rescale_q(pkt.dts, enc->time_base, ost->st->time_base);
write_frame(os, &pkt, ost);
- break;
- default:
- stop_encoding = 1;
}
+
if (stop_encoding)
break;
}
@@ -2133,16 +1872,34 @@ static void rate_emu_sleep(InputStream *ist)
int64_t pts = av_rescale(ist->last_dts, 1000000, AV_TIME_BASE);
int64_t now = av_gettime() - ist->start;
if (pts > now)
- usleep(pts - now);
+ av_usleep(pts - now);
+ }
+}
+
+static int guess_input_channel_layout(InputStream *ist)
+{
+ AVCodecContext *dec = ist->st->codec;
+
+ if (!dec->channel_layout) {
+ char layout_name[256];
+
+ dec->channel_layout = av_get_default_channel_layout(dec->channels);
+ if (!dec->channel_layout)
+ return 0;
+ av_get_channel_layout_string(layout_name, sizeof(layout_name),
+ dec->channels, dec->channel_layout);
+ av_log(NULL, AV_LOG_WARNING, "Guessed Channel Layout for Input Stream "
+ "#%d.%d : %s\n", ist->file_index, ist->st->index, layout_name);
}
+ return 1;
}
-static int transcode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
+static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
{
AVFrame *decoded_frame;
AVCodecContext *avctx = ist->st->codec;
int bps = av_get_bytes_per_sample(ist->st->codec->sample_fmt);
- int i, ret;
+ int i, ret, resample_changed;
if (!ist->decoded_frame && !(ist->decoded_frame = avcodec_alloc_frame()))
return AVERROR(ENOMEM);
@@ -2157,6 +1914,9 @@ static int transcode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
if (!*got_output) {
/* no audio frame */
+ if (!pkt->size)
+ for (i = 0; i < ist->nb_filters; i++)
+ av_buffersrc_buffer(ist->filters[i]->filter, NULL);
return ret;
}
@@ -2164,11 +1924,10 @@ static int transcode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
the decoder could be delaying output by a packet or more. */
if (decoded_frame->pts != AV_NOPTS_VALUE)
ist->next_dts = decoded_frame->pts;
-
- /* increment next_dts to use for the case where the input stream does not
- have timestamps or there are multiple frames in the packet */
- ist->next_dts += ((int64_t)AV_TIME_BASE * decoded_frame->nb_samples) /
- avctx->sample_rate;
+ else if (pkt->pts != AV_NOPTS_VALUE) {
+ decoded_frame->pts = pkt->pts;
+ pkt->pts = AV_NOPTS_VALUE;
+ }
// preprocess audio (volume)
if (audio_volume != 256) {
@@ -2230,18 +1989,58 @@ static int transcode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
rate_emu_sleep(ist);
- for (i = 0; i < nb_output_streams; i++) {
- OutputStream *ost = output_streams[i];
+ resample_changed = ist->resample_sample_fmt != decoded_frame->format ||
+ ist->resample_channels != avctx->channels ||
+ ist->resample_channel_layout != decoded_frame->channel_layout ||
+ ist->resample_sample_rate != decoded_frame->sample_rate;
+ if (resample_changed) {
+ char layout1[64], layout2[64];
- if (!check_output_constraints(ist, ost) || !ost->encoding_needed)
- continue;
- do_audio_out(output_files[ost->file_index]->ctx, ost, ist, decoded_frame);
+ if (!guess_input_channel_layout(ist)) {
+ av_log(NULL, AV_LOG_FATAL, "Unable to find default channel "
+ "layout for Input Stream #%d.%d\n", ist->file_index,
+ ist->st->index);
+ exit_program(1);
+ }
+ decoded_frame->channel_layout = avctx->channel_layout;
+
+ av_get_channel_layout_string(layout1, sizeof(layout1), ist->resample_channels,
+ ist->resample_channel_layout);
+ av_get_channel_layout_string(layout2, sizeof(layout2), avctx->channels,
+ decoded_frame->channel_layout);
+
+ av_log(NULL, AV_LOG_INFO,
+ "Input stream #%d:%d frame changed from rate:%d fmt:%s ch:%d chl:%s to rate:%d fmt:%s ch:%d chl:%s\n",
+ ist->file_index, ist->st->index,
+ ist->resample_sample_rate, av_get_sample_fmt_name(ist->resample_sample_fmt),
+ ist->resample_channels, layout1,
+ decoded_frame->sample_rate, av_get_sample_fmt_name(decoded_frame->format),
+ avctx->channels, layout2);
+
+ ist->resample_sample_fmt = decoded_frame->format;
+ ist->resample_sample_rate = decoded_frame->sample_rate;
+ ist->resample_channel_layout = decoded_frame->channel_layout;
+ ist->resample_channels = avctx->channels;
+
+ for (i = 0; i < nb_filtergraphs; i++)
+ if (ist_in_filtergraph(filtergraphs[i], ist) &&
+ configure_filtergraph(filtergraphs[i]) < 0) {
+ av_log(NULL, AV_LOG_FATAL, "Error reinitializing filters!\n");
+ exit_program(1);
+ }
}
+ if (decoded_frame->pts != AV_NOPTS_VALUE)
+ decoded_frame->pts = av_rescale_q(decoded_frame->pts,
+ ist->st->time_base,
+ (AVRational){1, ist->st->codec->sample_rate});
+ for (i = 0; i < ist->nb_filters; i++)
+ av_buffersrc_write_frame(ist->filters[i]->filter, decoded_frame);
+
return ret;
}
-static int transcode_video(InputStream *ist, AVPacket *pkt, int *got_output, int64_t *pkt_pts)
+static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output)
{
AVFrame *decoded_frame;
void *buffer_to_free = NULL;
@@ -2253,9 +2052,6 @@ static int transcode_video(InputStream *ist, AVPacket *pkt, int *got_output, int
else
avcodec_get_frame_defaults(ist->decoded_frame);
decoded_frame = ist->decoded_frame;
- pkt->pts = *pkt_pts;
- pkt->dts = ist->last_dts;
- *pkt_pts = AV_NOPTS_VALUE;
ret = avcodec_decode_video2(ist->st->codec,
decoded_frame, got_output, pkt);
@@ -2322,8 +2118,7 @@ static int transcode_video(InputStream *ist, AVPacket *pkt, int *got_output, int
buf->refcount++;
av_buffersrc_buffer(ist->filters[i]->filter, fb);
} else
- av_vsrc_buffer_add_frame(ist->filters[i]->filter, decoded_frame,
- decoded_frame->pts, decoded_frame->sample_aspect_ratio);
+ av_buffersrc_write_frame(ist->filters[i]->filter, decoded_frame);
}
av_free(buffer_to_free);
@@ -2360,7 +2155,6 @@ static int output_packet(InputStream *ist, const AVPacket *pkt)
{
int i;
int got_output;
- int64_t pkt_pts = AV_NOPTS_VALUE;
AVPacket avpkt;
if (ist->next_dts == AV_NOPTS_VALUE)
@@ -2378,8 +2172,6 @@ static int output_packet(InputStream *ist, const AVPacket *pkt)
if (pkt->dts != AV_NOPTS_VALUE)
ist->next_dts = ist->last_dts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q);
- if (pkt->pts != AV_NOPTS_VALUE)
- pkt_pts = av_rescale_q(pkt->pts, ist->st->time_base, AV_TIME_BASE_Q);
// while we have more to decode or while the decoder did output something on EOF
while (ist->decoding_needed && (avpkt.size > 0 || (!pkt && got_output))) {
@@ -2396,10 +2188,10 @@ static int output_packet(InputStream *ist, const AVPacket *pkt)
switch (ist->st->codec->codec_type) {
case AVMEDIA_TYPE_AUDIO:
- ret = transcode_audio (ist, &avpkt, &got_output);
+ ret = decode_audio (ist, &avpkt, &got_output);
break;
case AVMEDIA_TYPE_VIDEO:
- ret = transcode_video (ist, &avpkt, &got_output, &pkt_pts);
+ ret = decode_video (ist, &avpkt, &got_output);
if (avpkt.duration)
ist->next_dts += av_rescale_q(avpkt.duration, ist->st->time_base, AV_TIME_BASE_Q);
else if (ist->st->r_frame_rate.num)
@@ -2504,7 +2296,7 @@ static int init_input_stream(int ist_index, char *error, int error_len)
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;
+ ist->st->codec->opaque = &ist->buffer_pool;
}
if (!av_dict_get(ist->opts, "threads", NULL, 0))
@@ -2516,17 +2308,6 @@ static int init_input_stream(int ist_index, char *error, int error_len)
}
assert_codec_experimental(ist->st->codec, 0);
assert_avoptions(ist->opts);
-
- if (ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
- for (i = 0; i < nb_output_streams; i++) {
- OutputStream *ost = output_streams[i];
- if (ost->source_index == ist_index) {
- if (!ist->st->codec->channel_layout || !ost->st->codec->channel_layout)
- get_default_channel_layouts(ost, ist);
- break;
- }
- }
- }
}
ist->last_dts = ist->st->avg_frame_rate.num ? - ist->st->codec->has_b_frames * AV_TIME_BASE / av_q2d(ist->st->avg_frame_rate) : 0;
@@ -2554,6 +2335,37 @@ static InputStream *get_input_stream(OutputStream *ost)
return NULL;
}
+static void parse_forced_key_frames(char *kf, OutputStream *ost,
+ AVCodecContext *avctx)
+{
+ char *p;
+ int n = 1, i;
+ int64_t t;
+
+ for (p = kf; *p; p++)
+ if (*p == ',')
+ n++;
+ ost->forced_kf_count = n;
+ ost->forced_kf_pts = av_malloc(sizeof(*ost->forced_kf_pts) * n);
+ if (!ost->forced_kf_pts) {
+ av_log(NULL, AV_LOG_FATAL, "Could not allocate forced key frames array.\n");
+ exit_program(1);
+ }
+
+ p = kf;
+ for (i = 0; i < n; i++) {
+ char *next = strchr(p, ',');
+
+ if (next)
+ *next++ = 0;
+
+ t = parse_time_or_die("force_key_frames", p, 1);
+ ost->forced_kf_pts[i] = av_rescale_q(t, AV_TIME_BASE_Q, avctx->time_base);
+
+ p = next;
+ }
+}
+
static int transcode_init(void)
{
int ret = 0, i, j, k;
@@ -2698,71 +2510,48 @@ static int transcode_init(void)
ist->decoding_needed = 1;
ost->encoding_needed = 1;
- switch (codec->codec_type) {
- case AVMEDIA_TYPE_AUDIO:
- ost->fifo = av_fifo_alloc(1024);
- if (!ost->fifo) {
- return AVERROR(ENOMEM);
+ /*
+ * We want CFR output if and only if one of those is true:
+ * 1) user specified output framerate with -r
+ * 2) user specified -vsync cfr
+ * 3) output format is CFR and the user didn't force vsync to
+ * something else than CFR
+ *
+ * in such a case, set ost->frame_rate
+ */
+ if (codec->codec_type == AVMEDIA_TYPE_VIDEO &&
+ !ost->frame_rate.num && ist &&
+ (video_sync_method == VSYNC_CFR ||
+ (video_sync_method == VSYNC_AUTO &&
+ !(oc->oformat->flags & (AVFMT_NOTIMESTAMPS | AVFMT_VARIABLE_FPS))))) {
+ ost->frame_rate = ist->st->r_frame_rate.num ? ist->st->r_frame_rate : (AVRational){25, 1};
+ if (ost->enc && ost->enc->supported_framerates && !ost->force_fps) {
+ int idx = av_find_nearest_q_idx(ost->frame_rate, ost->enc->supported_framerates);
+ ost->frame_rate = ost->enc->supported_framerates[idx];
}
+ }
- if (!codec->sample_rate)
- codec->sample_rate = icodec->sample_rate;
- choose_sample_rate(ost->st, ost->enc);
- codec->time_base = (AVRational){ 1, codec->sample_rate };
-
- if (codec->sample_fmt == AV_SAMPLE_FMT_NONE)
- codec->sample_fmt = icodec->sample_fmt;
- choose_sample_fmt(ost->st, ost->enc);
-
- if (!codec->channels)
- codec->channels = icodec->channels;
- if (!codec->channel_layout)
- codec->channel_layout = icodec->channel_layout;
- if (av_get_channel_layout_nb_channels(codec->channel_layout) != codec->channels)
- codec->channel_layout = 0;
-
- icodec->request_channels = codec-> channels;
- ost->resample_sample_fmt = icodec->sample_fmt;
- ost->resample_sample_rate = icodec->sample_rate;
- ost->resample_channels = icodec->channels;
- ost->resample_channel_layout = icodec->channel_layout;
- break;
- case AVMEDIA_TYPE_VIDEO:
- if (!ost->filter) {
+ if (!ost->filter &&
+ (codec->codec_type == AVMEDIA_TYPE_VIDEO ||
+ codec->codec_type == AVMEDIA_TYPE_AUDIO)) {
FilterGraph *fg;
fg = init_simple_filtergraph(ist, ost);
- if (configure_video_filters(fg)) {
+ if (configure_filtergraph(fg)) {
av_log(NULL, AV_LOG_FATAL, "Error opening filters!\n");
exit(1);
}
- }
+ }
- /*
- * We want CFR output if and only if one of those is true:
- * 1) user specified output framerate with -r
- * 2) user specified -vsync cfr
- * 3) output format is CFR and the user didn't force vsync to
- * something else than CFR
- *
- * in such a case, set ost->frame_rate
- */
- if (!ost->frame_rate.num && ist &&
- (video_sync_method == VSYNC_CFR ||
- (video_sync_method == VSYNC_AUTO &&
- !(oc->oformat->flags & (AVFMT_NOTIMESTAMPS | AVFMT_VARIABLE_FPS))))) {
- ost->frame_rate = ist->st->r_frame_rate.num ? ist->st->r_frame_rate : (AVRational){25, 1};
- if (ost->enc && ost->enc->supported_framerates && !ost->force_fps) {
- int idx = av_find_nearest_q_idx(ost->frame_rate, ost->enc->supported_framerates);
- ost->frame_rate = ost->enc->supported_framerates[idx];
- }
- }
- if (ost->frame_rate.num) {
- codec->time_base = (AVRational){ost->frame_rate.den, ost->frame_rate.num};
- video_sync_method = VSYNC_CFR;
- } else if (ist)
- codec->time_base = ist->st->time_base;
- else
- codec->time_base = ost->filter->filter->inputs[0]->time_base;
+ switch (codec->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ codec->sample_fmt = ost->filter->filter->inputs[0]->format;
+ codec->sample_rate = ost->filter->filter->inputs[0]->sample_rate;
+ codec->channel_layout = ost->filter->filter->inputs[0]->channel_layout;
+ codec->channels = av_get_channel_layout_nb_channels(codec->channel_layout);
+ codec->time_base = (AVRational){ 1, codec->sample_rate };
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ codec->time_base = ost->filter->filter->inputs[0]->time_base;
codec->width = ost->filter->filter->inputs[0]->w;
codec->height = ost->filter->filter->inputs[0]->h;
@@ -2778,6 +2567,9 @@ static int transcode_init(void)
codec->bits_per_raw_sample = 0;
}
+ if (ost->forced_keyframes)
+ parse_forced_key_frames(ost->forced_keyframes, ost,
+ ost->st->codec);
break;
case AVMEDIA_TYPE_SUBTITLE:
codec->time_base = (AVRational){1, 1000};
@@ -2883,8 +2675,12 @@ static int transcode_init(void)
for (i = 0; i < nb_output_files; i++) {
oc = output_files[i]->ctx;
oc->interrupt_callback = int_cb;
- if (avformat_write_header(oc, &output_files[i]->opts) < 0) {
- snprintf(error, sizeof(error), "Could not write header for output file #%d (incorrect codec parameters ?)", i);
+ if ((ret = avformat_write_header(oc, &output_files[i]->opts)) < 0) {
+ char errbuf[128];
+ const char *errbuf_ptr = errbuf;
+ if (av_strerror(ret, errbuf, sizeof(errbuf)) < 0)
+ errbuf_ptr = strerror(AVUNERROR(ret));
+ snprintf(error, sizeof(error), "Could not write header for output file #%d (incorrect codec parameters ?): %s", i, errbuf_ptr);
ret = AVERROR(EINVAL);
goto dump_format;
}
@@ -2907,13 +2703,10 @@ static int transcode_init(void)
ist = input_streams[i];
for (j = 0; j < ist->nb_filters; j++) {
- AVFilterLink *link = ist->filters[j]->filter->outputs[0];
if (ist->filters[j]->graph->graph_desc) {
av_log(NULL, AV_LOG_INFO, " Stream #%d:%d (%s) -> %s",
ist->file_index, ist->st->index, ist->dec ? ist->dec->name : "?",
- link->dst->filter->name);
- if (link->dst->input_count > 1)
- av_log(NULL, AV_LOG_INFO, ":%s", link->dstpad->name);
+ ist->filters[j]->name);
if (nb_filtergraphs > 1)
av_log(NULL, AV_LOG_INFO, " (graph %d)", ist->filters[j]->graph->index);
av_log(NULL, AV_LOG_INFO, "\n");
@@ -2933,10 +2726,7 @@ static int transcode_init(void)
if (ost->filter && ost->filter->graph->graph_desc) {
/* output from a complex graph */
- AVFilterLink *link = ost->filter->filter->inputs[0];
- av_log(NULL, AV_LOG_INFO, " %s", link->src->filter->name);
- if (link->src->output_count > 1)
- av_log(NULL, AV_LOG_INFO, ":%s", link->srcpad->name);
+ av_log(NULL, AV_LOG_INFO, " %s", ost->filter->name);
if (nb_filtergraphs > 1)
av_log(NULL, AV_LOG_INFO, " (graph %d)", ost->filter->graph->index);
@@ -2975,6 +2765,176 @@ static int transcode_init(void)
return 0;
}
+/**
+ * @return 1 if there are still streams where more output is wanted,
+ * 0 otherwise
+ */
+static int need_output(void)
+{
+ int i;
+
+ for (i = 0; i < nb_output_streams; i++) {
+ OutputStream *ost = output_streams[i];
+ OutputFile *of = output_files[ost->file_index];
+ AVFormatContext *os = output_files[ost->file_index]->ctx;
+
+ if (ost->is_past_recording_time ||
+ (os->pb && avio_tell(os->pb) >= of->limit_filesize))
+ continue;
+ if (ost->frame_number >= ost->max_frames) {
+ int j;
+ for (j = 0; j < of->ctx->nb_streams; j++)
+ output_streams[of->ost_index + j]->is_past_recording_time = 1;
+ continue;
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static int select_input_file(uint8_t *no_packet)
+{
+ int64_t ipts_min = INT64_MAX;
+ int i, file_index = -1;
+
+ for (i = 0; i < nb_input_streams; i++) {
+ InputStream *ist = input_streams[i];
+ int64_t ipts = ist->last_dts;
+
+ if (ist->discard || no_packet[ist->file_index])
+ continue;
+ if (!input_files[ist->file_index]->eof_reached) {
+ if (ipts < ipts_min) {
+ ipts_min = ipts;
+ file_index = ist->file_index;
+ }
+ }
+ }
+
+ return file_index;
+}
+
+#if HAVE_PTHREADS
+static void *input_thread(void *arg)
+{
+ InputFile *f = arg;
+ int ret = 0;
+
+ while (!transcoding_finished && ret >= 0) {
+ AVPacket pkt;
+ ret = av_read_frame(f->ctx, &pkt);
+
+ if (ret == AVERROR(EAGAIN)) {
+ av_usleep(10000);
+ ret = 0;
+ continue;
+ } else if (ret < 0)
+ break;
+
+ pthread_mutex_lock(&f->fifo_lock);
+ while (!av_fifo_space(f->fifo))
+ pthread_cond_wait(&f->fifo_cond, &f->fifo_lock);
+
+ av_dup_packet(&pkt);
+ av_fifo_generic_write(f->fifo, &pkt, sizeof(pkt), NULL);
+
+ pthread_mutex_unlock(&f->fifo_lock);
+ }
+
+ f->finished = 1;
+ return NULL;
+}
+
+static void free_input_threads(void)
+{
+ int i;
+
+ if (nb_input_files == 1)
+ return;
+
+ transcoding_finished = 1;
+
+ for (i = 0; i < nb_input_files; i++) {
+ InputFile *f = input_files[i];
+ AVPacket pkt;
+
+ if (!f->fifo || f->joined)
+ continue;
+
+ pthread_mutex_lock(&f->fifo_lock);
+ while (av_fifo_size(f->fifo)) {
+ av_fifo_generic_read(f->fifo, &pkt, sizeof(pkt), NULL);
+ av_free_packet(&pkt);
+ }
+ pthread_cond_signal(&f->fifo_cond);
+ pthread_mutex_unlock(&f->fifo_lock);
+
+ pthread_join(f->thread, NULL);
+ f->joined = 1;
+
+ while (av_fifo_size(f->fifo)) {
+ av_fifo_generic_read(f->fifo, &pkt, sizeof(pkt), NULL);
+ av_free_packet(&pkt);
+ }
+ av_fifo_free(f->fifo);
+ }
+}
+
+static int init_input_threads(void)
+{
+ int i, ret;
+
+ if (nb_input_files == 1)
+ return 0;
+
+ for (i = 0; i < nb_input_files; i++) {
+ InputFile *f = input_files[i];
+
+ if (!(f->fifo = av_fifo_alloc(8*sizeof(AVPacket))))
+ return AVERROR(ENOMEM);
+
+ pthread_mutex_init(&f->fifo_lock, NULL);
+ pthread_cond_init (&f->fifo_cond, NULL);
+
+ if ((ret = pthread_create(&f->thread, NULL, input_thread, f)))
+ return AVERROR(ret);
+ }
+ return 0;
+}
+
+static int get_input_packet_mt(InputFile *f, AVPacket *pkt)
+{
+ int ret = 0;
+
+ pthread_mutex_lock(&f->fifo_lock);
+
+ if (av_fifo_size(f->fifo)) {
+ av_fifo_generic_read(f->fifo, pkt, sizeof(*pkt), NULL);
+ pthread_cond_signal(&f->fifo_cond);
+ } else {
+ if (f->finished)
+ ret = AVERROR_EOF;
+ else
+ ret = AVERROR(EAGAIN);
+ }
+
+ pthread_mutex_unlock(&f->fifo_lock);
+
+ return ret;
+}
+#endif
+
+static int get_input_packet(InputFile *f, AVPacket *pkt)
+{
+#if HAVE_PTHREADS
+ if (nb_input_files > 1)
+ return get_input_packet_mt(f, pkt);
+#endif
+ return av_read_frame(f->ctx, pkt);
+}
+
/*
* The following code is the main loop of the file converter
*/
@@ -3000,63 +2960,38 @@ static int transcode(void)
timer_start = av_gettime();
+#if HAVE_PTHREADS
+ if ((ret = init_input_threads()) < 0)
+ goto fail;
+#endif
+
for (; received_sigterm == 0;) {
- int file_index, ist_index, past_recording_time = 1;
+ int file_index, ist_index;
AVPacket pkt;
- int64_t ipts_min;
-
- ipts_min = INT64_MAX;
/* check if there's any stream where output is still needed */
- for (i = 0; i < nb_output_streams; i++) {
- OutputFile *of;
- ost = output_streams[i];
- of = output_files[ost->file_index];
- os = output_files[ost->file_index]->ctx;
- if (ost->is_past_recording_time ||
- (os->pb && avio_tell(os->pb) >= of->limit_filesize))
- continue;
- if (ost->frame_number > ost->max_frames) {
- int j;
- for (j = 0; j < of->ctx->nb_streams; j++)
- output_streams[of->ost_index + j]->is_past_recording_time = 1;
- continue;
- }
- past_recording_time = 0;
- }
- if (past_recording_time)
+ if (!need_output()) {
+ av_log(NULL, AV_LOG_VERBOSE, "No more output streams to write to, finishing.\n");
break;
-
- /* select the stream that we must read now by looking at the
- smallest output pts */
- file_index = -1;
- for (i = 0; i < nb_input_streams; i++) {
- int64_t ipts;
- ist = input_streams[i];
- ipts = ist->last_dts;
- if (ist->discard || no_packet[ist->file_index])
- continue;
- if (!input_files[ist->file_index]->eof_reached) {
- if (ipts < ipts_min) {
- ipts_min = ipts;
- file_index = ist->file_index;
- }
- }
}
+
+ /* select the stream that we must read now */
+ file_index = select_input_file(no_packet);
/* if none, if is finished */
if (file_index < 0) {
if (no_packet_count) {
no_packet_count = 0;
memset(no_packet, 0, nb_input_files);
- usleep(10000);
+ av_usleep(10000);
continue;
}
+ av_log(NULL, AV_LOG_VERBOSE, "No more inputs to read from, finishing.\n");
break;
}
- /* read a frame from it and output it in the fifo */
is = input_files[file_index]->ctx;
- ret = av_read_frame(is, &pkt);
+ ret = get_input_packet(input_files[file_index], &pkt);
+
if (ret == AVERROR(EAGAIN)) {
no_packet[file_index] = 1;
no_packet_count++;
@@ -3138,6 +3073,9 @@ static int transcode(void)
/* dump report by using the output first video and audio streams */
print_report(0, timer_start);
}
+#if HAVE_PTHREADS
+ free_input_threads();
+#endif
/* at the end of stream, we must flush the decoder buffers */
for (i = 0; i < nb_input_streams; i++) {
@@ -3182,6 +3120,9 @@ static int transcode(void)
fail:
av_freep(&no_packet);
+#if HAVE_PTHREADS
+ free_input_threads();
+#endif
if (output_streams) {
for (i = 0; i < nb_output_streams; i++) {
@@ -3193,12 +3134,8 @@ static int transcode(void)
fclose(ost->logfile);
ost->logfile = NULL;
}
- av_fifo_free(ost->fifo); /* works even if fifo is not
- initialized but set to zero */
av_freep(&ost->st->codec->subtitle_header);
av_free(ost->forced_kf_pts);
- if (ost->avr)
- avresample_free(&ost->avr);
av_dict_free(&ost->opts);
}
}
@@ -3426,6 +3363,7 @@ static int copy_metadata(char *outspec, char *inspec, AVFormatContext *oc, AVFor
METADATA_CHECK_INDEX(index, context->nb_programs, "program")\
meta = &context->programs[index]->metadata;\
break;\
+ default: av_assert0(0);\
}\
SET_DICT(type_in, meta_in, ic, idx_in);
@@ -3504,6 +3442,7 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
AVStream *st = ic->streams[i];
AVCodecContext *dec = st->codec;
InputStream *ist = av_mallocz(sizeof(*ist));
+ char *framerate = NULL;
if (!ist)
exit_program(1);
@@ -3515,7 +3454,7 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
ist->file_index = nb_input_files;
ist->discard = 1;
st->discard = AVDISCARD_ALL;
- ist->opts = filter_codec_opts(codec_opts, ist->st->codec->codec_id, ic, st);
+ ist->opts = filter_codec_opts(codec_opts, ist->st->codec->codec_id, ic, st, NULL);
ist->ts_scale = 1.0;
MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
@@ -3528,8 +3467,24 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
ist->resample_width = dec->width;
ist->resample_pix_fmt = dec->pix_fmt;
+ MATCH_PER_STREAM_OPT(frame_rates, str, framerate, ic, st);
+ if (framerate && av_parse_video_rate(&ist->framerate,
+ framerate) < 0) {
+ av_log(NULL, AV_LOG_ERROR, "Error parsing framerate %s.\n",
+ framerate);
+ exit_program(1);
+ }
+
break;
case AVMEDIA_TYPE_AUDIO:
+ guess_input_channel_layout(ist);
+
+ ist->resample_sample_fmt = dec->sample_fmt;
+ ist->resample_sample_rate = dec->sample_rate;
+ ist->resample_channels = dec->channels;
+ ist->resample_channel_layout = dec->channel_layout;
+
+ break;
case AVMEDIA_TYPE_DATA:
case AVMEDIA_TYPE_SUBTITLE:
case AVMEDIA_TYPE_ATTACHMENT:
@@ -3641,7 +3596,14 @@ static int opt_input_file(OptionsContext *o, const char *opt, const char *filena
}
}
if (o->nb_frame_rates) {
- av_dict_set(&format_opts, "framerate", o->frame_rates[o->nb_frame_rates - 1].u.str, 0);
+ /* set the format-level framerate option;
+ * this is important for video grabbers, e.g. x11 */
+ if (file_iformat && file_iformat->priv_class &&
+ av_opt_find(&file_iformat->priv_class, "framerate", NULL, 0,
+ AV_OPT_SEARCH_FAKE_OBJ)) {
+ av_dict_set(&format_opts, "framerate",
+ o->frame_rates[o->nb_frame_rates - 1].u.str, 0);
+ }
}
if (o->nb_frame_sizes) {
av_dict_set(&format_opts, "video_size", o->frame_sizes[o->nb_frame_sizes - 1].u.str, 0);
@@ -3726,29 +3688,6 @@ static int opt_input_file(OptionsContext *o, const char *opt, const char *filena
return 0;
}
-static void parse_forced_key_frames(char *kf, OutputStream *ost,
- AVCodecContext *avctx)
-{
- char *p;
- int n = 1, i;
- int64_t t;
-
- for (p = kf; *p; p++)
- if (*p == ',')
- n++;
- ost->forced_kf_count = n;
- ost->forced_kf_pts = av_malloc(sizeof(*ost->forced_kf_pts) * n);
- if (!ost->forced_kf_pts) {
- av_log(NULL, AV_LOG_FATAL, "Could not allocate forced key frames array.\n");
- exit_program(1);
- }
- for (i = 0; i < n; i++) {
- p = i ? strchr(p, ',') + 1 : kf;
- t = parse_time_or_die("force_key_frames", p, 1);
- ost->forced_kf_pts[i] = av_rescale_q(t, AV_TIME_BASE_Q, avctx->time_base);
- }
-}
-
static uint8_t *get_line(AVIOContext *s)
{
AVIOContext *line;
@@ -3842,7 +3781,7 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
st->codec->codec_type = type;
choose_encoder(o, oc, ost);
if (ost->enc) {
- ost->opts = filter_codec_opts(codec_opts, ost->enc->id, oc, st);
+ ost->opts = filter_codec_opts(codec_opts, ost->enc->id, oc, st, ost->enc);
}
avcodec_get_context_defaults3(st->codec, ost->enc);
@@ -3946,9 +3885,10 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc)
if (!ost->stream_copy) {
const char *p = NULL;
- char *forced_key_frames = NULL, *frame_rate = NULL, *frame_size = NULL;
+ char *frame_rate = NULL, *frame_size = NULL;
char *frame_aspect_ratio = NULL, *frame_pix_fmt = NULL;
- char *intra_matrix = NULL, *inter_matrix = NULL, *filters = NULL;
+ char *intra_matrix = NULL, *inter_matrix = NULL;
+ const char *filters = "null";
int i;
MATCH_PER_STREAM_OPT(frame_rates, str, frame_rate, oc, st);
@@ -4029,9 +3969,9 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc)
}
}
- MATCH_PER_STREAM_OPT(forced_key_frames, str, forced_key_frames, oc, st);
- if (forced_key_frames)
- parse_forced_key_frames(forced_key_frames, ost, video_enc);
+ MATCH_PER_STREAM_OPT(forced_key_frames, str, ost->forced_keyframes, oc, st);
+ if (ost->forced_keyframes)
+ ost->forced_keyframes = av_strdup(ost->forced_keyframes);
MATCH_PER_STREAM_OPT(force_fps, i, ost->force_fps, oc, st);
@@ -4039,8 +3979,7 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc)
MATCH_PER_STREAM_OPT(top_field_first, i, ost->top_field_first, oc, st);
MATCH_PER_STREAM_OPT(filters, str, filters, oc, st);
- if (filters)
- ost->avfilter = av_strdup(filters);
+ ost->avfilter = av_strdup(filters);
} else {
MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, ost->copy_initial_nonkeyframes, oc ,st);
}
@@ -4062,6 +4001,7 @@ static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc)
if (!ost->stream_copy) {
char *sample_fmt = NULL;
+ const char *filters = "anull";
MATCH_PER_STREAM_OPT(audio_channels, i, audio_enc->channels, oc, st);
@@ -4073,6 +4013,9 @@ static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc)
}
MATCH_PER_STREAM_OPT(audio_sample_rate, i, audio_enc->sample_rate, oc, st);
+
+ MATCH_PER_STREAM_OPT(filters, str, filters, oc, st);
+ ost->avfilter = av_strdup(filters);
}
return ost;
@@ -4180,12 +4123,16 @@ static void init_output_filter(OutputFilter *ofilter, OptionsContext *o,
{
OutputStream *ost;
- if (ofilter->out_tmp->filter_ctx->output_pads[ofilter->out_tmp->pad_idx].type != AVMEDIA_TYPE_VIDEO) {
- av_log(NULL, AV_LOG_FATAL, "Only video filters are supported currently.\n");
+ switch (avfilter_pad_get_type(ofilter->out_tmp->filter_ctx->output_pads,
+ ofilter->out_tmp->pad_idx)) {
+ case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(o, oc); break;
+ case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc); break;
+ default:
+ av_log(NULL, AV_LOG_FATAL, "Only video and audio filters are supported "
+ "currently.\n");
exit_program(1);
}
- ost = new_video_stream(o, oc);
ost->source_index = -1;
ost->filter = ofilter;
@@ -4256,7 +4203,8 @@ static void opt_output_file(void *optctx, const char *filename)
if (!ofilter->out_tmp || ofilter->out_tmp->name)
continue;
- switch (ofilter->out_tmp->filter_ctx->output_pads[ofilter->out_tmp->pad_idx].type) {
+ switch (avfilter_pad_get_type(ofilter->out_tmp->filter_ctx->output_pads,
+ ofilter->out_tmp->pad_idx)) {
case AVMEDIA_TYPE_VIDEO: o->video_disable = 1; break;
case AVMEDIA_TYPE_AUDIO: o->audio_disable = 1; break;
case AVMEDIA_TYPE_SUBTITLE: o->subtitle_disable = 1; break;
@@ -4513,7 +4461,6 @@ loop_end:
} else if (ret < 0)
exit_program(1);
}
- printf("ret %d, stream_spec %s\n", ret, stream_spec);
}
else {
switch (type) {
@@ -4816,6 +4763,11 @@ static int opt_video_filters(OptionsContext *o, const char *opt, const char *arg
return parse_option(o, "filter:v", arg, options);
}
+static int opt_audio_filters(OptionsContext *o, const char *opt, const char *arg)
+{
+ return parse_option(o, "filter:a", arg, options);
+}
+
static int opt_vsync(const char *opt, const char *arg)
{
if (!av_strcasecmp(arg, "cfr")) video_sync_method = VSYNC_CFR;
@@ -4988,6 +4940,7 @@ static const OptionDef options[] = {
{ "vol", OPT_INT | HAS_ARG | OPT_AUDIO, {(void*)&audio_volume}, "change audio volume (256=normal)" , "volume" }, //
{ "sample_fmt", HAS_ARG | OPT_EXPERT | OPT_AUDIO | OPT_SPEC | OPT_STRING, {.off = OFFSET(sample_fmts)}, "set sample format", "format" },
{ "channel_layout", HAS_ARG | OPT_EXPERT | OPT_AUDIO | OPT_FUNC2, {(void*)opt_channel_layout}, "set channel layout", "layout" },
+ { "af", HAS_ARG | OPT_AUDIO | OPT_FUNC2, {(void*)opt_audio_filters}, "audio filters", "filter list" },
/* subtitle options */
{ "sn", OPT_BOOL | OPT_SUBTITLE | OPT_OFFSET, {.off = OFFSET(subtitle_disable)}, "disable subtitle" },
diff --git a/avplay.c b/avplay.c
index 0d72f46..1961f5f 100644
--- a/avplay.c
+++ b/avplay.c
@@ -31,16 +31,19 @@
#include "libavutil/dict.h"
#include "libavutil/parseutils.h"
#include "libavutil/samplefmt.h"
+#include "libavutil/time.h"
#include "libavformat/avformat.h"
#include "libavdevice/avdevice.h"
#include "libswscale/swscale.h"
-#include "libavcodec/audioconvert.h"
+#include "libavresample/avresample.h"
#include "libavutil/opt.h"
#include "libavcodec/avfft.h"
#if CONFIG_AVFILTER
# include "libavfilter/avfilter.h"
# include "libavfilter/avfiltergraph.h"
+# include "libavfilter/buffersink.h"
+# include "libavfilter/buffersrc.h"
#endif
#include "cmdutils.h"
@@ -52,7 +55,6 @@
#undef main /* We don't want SDL to override our main() */
#endif
-#include <unistd.h>
#include <assert.h>
const char program_name[] = "avplay";
@@ -159,8 +161,12 @@ typedef struct VideoState {
int audio_buf_index; /* in bytes */
AVPacket audio_pkt_temp;
AVPacket audio_pkt;
- enum AVSampleFormat audio_src_fmt;
- AVAudioConvert *reformat_ctx;
+ enum AVSampleFormat sdl_sample_fmt;
+ uint64_t sdl_channel_layout;
+ int sdl_channels;
+ enum AVSampleFormat resample_sample_fmt;
+ uint64_t resample_channel_layout;
+ AVAudioResampleContext *avr;
AVFrame *frame;
int show_audio; /* if true, display audio samples */
@@ -207,7 +213,10 @@ typedef struct VideoState {
PtsCorrectionContext pts_ctx;
#if CONFIG_AVFILTER
+ AVFilterContext *in_video_filter; ///< the first filter in the video chain
AVFilterContext *out_video_filter; ///< the last filter in the video chain
+ int use_dr1;
+ FrameBuffer *buffer_pool;
#endif
float skip_frames;
@@ -255,6 +264,7 @@ static int exit_on_keydown;
static int exit_on_mousedown;
static int loop = 1;
static int framedrop = 1;
+static int infinite_buffer = 0;
static int rdftspeed = 20;
#if CONFIG_AVFILTER
@@ -743,7 +753,7 @@ static void video_audio_display(VideoState *s)
nb_freq = 1 << (rdft_bits - 1);
/* compute display index : center on currently output samples */
- channels = s->audio_st->codec->channels;
+ channels = s->sdl_channels;
nb_display_channels = channels;
if (!s->paused) {
int data_used = s->show_audio == 1 ? s->width : (2 * nb_freq);
@@ -943,7 +953,7 @@ static int refresh_thread(void *opaque)
is->refresh = 1;
SDL_PushEvent(&event);
}
- usleep(is->audio_st && is->show_audio ? rdftspeed * 1000 : 5000); // FIXME ideally we should wait the correct time but SDLs event passing is so slow it would be silly
+ av_usleep(is->audio_st && is->show_audio ? rdftspeed * 1000 : 5000); // FIXME ideally we should wait the correct time but SDLs event passing is so slow it would be silly
}
return 0;
}
@@ -957,8 +967,8 @@ static double get_audio_clock(VideoState *is)
hw_buf_size = audio_write_get_buf_size(is);
bytes_per_sec = 0;
if (is->audio_st) {
- bytes_per_sec = is->audio_st->codec->sample_rate *
- 2 * is->audio_st->codec->channels;
+ bytes_per_sec = is->audio_st->codec->sample_rate * is->sdl_channels *
+ av_get_bytes_per_sample(is->sdl_sample_fmt);
}
if (bytes_per_sec)
pts -= (double)hw_buf_size / bytes_per_sec;
@@ -1512,213 +1522,41 @@ static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacke
}
#if CONFIG_AVFILTER
-typedef struct {
- VideoState *is;
- AVFrame *frame;
- int use_dr1;
-} FilterPriv;
-
-static int input_get_buffer(AVCodecContext *codec, AVFrame *pic)
-{
- AVFilterContext *ctx = codec->opaque;
- AVFilterBufferRef *ref;
- int perms = AV_PERM_WRITE;
- int i, w, h, stride[AV_NUM_DATA_POINTERS];
- unsigned edge;
- int pixel_size;
-
- if (codec->codec->capabilities & CODEC_CAP_NEG_LINESIZES)
- perms |= AV_PERM_NEG_LINESIZES;
-
- if (pic->buffer_hints & FF_BUFFER_HINTS_VALID) {
- if (pic->buffer_hints & FF_BUFFER_HINTS_READABLE) perms |= AV_PERM_READ;
- if (pic->buffer_hints & FF_BUFFER_HINTS_PRESERVE) perms |= AV_PERM_PRESERVE;
- if (pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE) perms |= AV_PERM_REUSE2;
- }
- if (pic->reference) perms |= AV_PERM_READ | AV_PERM_PRESERVE;
-
- w = codec->width;
- h = codec->height;
- avcodec_align_dimensions2(codec, &w, &h, stride);
- edge = codec->flags & CODEC_FLAG_EMU_EDGE ? 0 : avcodec_get_edge_width();
- w += edge << 1;
- h += edge << 1;
-
- if (!(ref = avfilter_get_video_buffer(ctx->outputs[0], perms, w, h)))
- return -1;
-
- pixel_size = av_pix_fmt_descriptors[ref->format].comp[0].step_minus1 + 1;
- ref->video->w = codec->width;
- ref->video->h = codec->height;
- for (i = 0; i < 4; i ++) {
- unsigned hshift = (i == 1 || i == 2) ? av_pix_fmt_descriptors[ref->format].log2_chroma_w : 0;
- unsigned vshift = (i == 1 || i == 2) ? av_pix_fmt_descriptors[ref->format].log2_chroma_h : 0;
-
- if (ref->data[i]) {
- ref->data[i] += ((edge * pixel_size) >> hshift) + ((edge * ref->linesize[i]) >> vshift);
- }
- pic->data[i] = ref->data[i];
- pic->linesize[i] = ref->linesize[i];
- }
- pic->opaque = ref;
- pic->type = FF_BUFFER_TYPE_USER;
- pic->reordered_opaque = codec->reordered_opaque;
- pic->width = codec->width;
- pic->height = codec->height;
- pic->format = codec->pix_fmt;
- pic->sample_aspect_ratio = codec->sample_aspect_ratio;
- if (codec->pkt) pic->pkt_pts = codec->pkt->pts;
- else pic->pkt_pts = AV_NOPTS_VALUE;
- return 0;
-}
-
-static void input_release_buffer(AVCodecContext *codec, AVFrame *pic)
-{
- memset(pic->data, 0, sizeof(pic->data));
- avfilter_unref_buffer(pic->opaque);
-}
-
-static int input_reget_buffer(AVCodecContext *codec, AVFrame *pic)
-{
- AVFilterBufferRef *ref = pic->opaque;
-
- if (pic->data[0] == NULL) {
- pic->buffer_hints |= FF_BUFFER_HINTS_READABLE;
- return codec->get_buffer(codec, pic);
- }
-
- if ((codec->width != ref->video->w) || (codec->height != ref->video->h) ||
- (codec->pix_fmt != ref->format)) {
- av_log(codec, AV_LOG_ERROR, "Picture properties changed.\n");
- return -1;
- }
-
- pic->reordered_opaque = codec->reordered_opaque;
- if (codec->pkt) pic->pkt_pts = codec->pkt->pts;
- else pic->pkt_pts = AV_NOPTS_VALUE;
- return 0;
-}
-
-static int input_init(AVFilterContext *ctx, const char *args, void *opaque)
-{
- FilterPriv *priv = ctx->priv;
- AVCodecContext *codec;
- if (!opaque) return -1;
-
- priv->is = opaque;
- codec = priv->is->video_st->codec;
- codec->opaque = ctx;
- if (codec->codec->capabilities & CODEC_CAP_DR1) {
- priv->use_dr1 = 1;
- codec->get_buffer = input_get_buffer;
- codec->release_buffer = input_release_buffer;
- codec->reget_buffer = input_reget_buffer;
- codec->thread_safe_callbacks = 1;
- }
-
- priv->frame = avcodec_alloc_frame();
-
- return 0;
-}
-
-static void input_uninit(AVFilterContext *ctx)
-{
- FilterPriv *priv = ctx->priv;
- av_free(priv->frame);
-}
-
-static int input_request_frame(AVFilterLink *link)
-{
- FilterPriv *priv = link->src->priv;
- AVFilterBufferRef *picref;
- int64_t pts = 0;
- AVPacket pkt;
- int ret;
-
- while (!(ret = get_video_frame(priv->is, priv->frame, &pts, &pkt)))
- av_free_packet(&pkt);
- if (ret < 0)
- return -1;
-
- if (priv->use_dr1) {
- picref = avfilter_ref_buffer(priv->frame->opaque, ~0);
- } else {
- picref = avfilter_get_video_buffer(link, AV_PERM_WRITE, link->w, link->h);
- av_image_copy(picref->data, picref->linesize,
- priv->frame->data, priv->frame->linesize,
- picref->format, link->w, link->h);
- }
- av_free_packet(&pkt);
-
- avfilter_copy_frame_props(picref, priv->frame);
- picref->pts = pts;
-
- avfilter_start_frame(link, picref);
- avfilter_draw_slice(link, 0, link->h, 1);
- avfilter_end_frame(link);
-
- return 0;
-}
-
-static int input_query_formats(AVFilterContext *ctx)
-{
- FilterPriv *priv = ctx->priv;
- enum PixelFormat pix_fmts[] = {
- priv->is->video_st->codec->pix_fmt, PIX_FMT_NONE
- };
-
- avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
- return 0;
-}
-
-static int input_config_props(AVFilterLink *link)
-{
- FilterPriv *priv = link->src->priv;
- AVCodecContext *c = priv->is->video_st->codec;
-
- link->w = c->width;
- link->h = c->height;
- link->time_base = priv->is->video_st->time_base;
-
- return 0;
-}
-
-static AVFilter input_filter =
-{
- .name = "avplay_input",
-
- .priv_size = sizeof(FilterPriv),
-
- .init = input_init,
- .uninit = input_uninit,
-
- .query_formats = input_query_formats,
-
- .inputs = (AVFilterPad[]) {{ .name = NULL }},
- .outputs = (AVFilterPad[]) {{ .name = "default",
- .type = AVMEDIA_TYPE_VIDEO,
- .request_frame = input_request_frame,
- .config_props = input_config_props, },
- { .name = NULL }},
-};
-
static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters)
{
- static const enum PixelFormat pix_fmts[] = { PIX_FMT_YUV420P, PIX_FMT_NONE };
char sws_flags_str[128];
+ char buffersrc_args[256];
int ret;
- SinkContext sink_ctx = { .pix_fmts = pix_fmts };
- AVFilterContext *filt_src = NULL, *filt_out = NULL;
+ AVFilterContext *filt_src = NULL, *filt_out = NULL, *filt_format;
+ AVCodecContext *codec = is->video_st->codec;
+
snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%d", sws_flags);
graph->scale_sws_opts = av_strdup(sws_flags_str);
- if ((ret = avfilter_graph_create_filter(&filt_src, &input_filter, "src",
- NULL, is, graph)) < 0)
+ snprintf(buffersrc_args, sizeof(buffersrc_args), "%d:%d:%d:%d:%d:%d:%d",
+ codec->width, codec->height, codec->pix_fmt,
+ is->video_st->time_base.num, is->video_st->time_base.den,
+ codec->sample_aspect_ratio.num, codec->sample_aspect_ratio.den);
+
+
+ if ((ret = avfilter_graph_create_filter(&filt_src,
+ avfilter_get_by_name("buffer"),
+ "src", buffersrc_args, NULL,
+ graph)) < 0)
return ret;
- if ((ret = avfilter_graph_create_filter(&filt_out, &sink, "out",
- NULL, &sink_ctx, graph)) < 0)
+ if ((ret = avfilter_graph_create_filter(&filt_out,
+ avfilter_get_by_name("buffersink"),
+ "out", NULL, NULL, graph)) < 0)
return ret;
+ if ((ret = avfilter_graph_create_filter(&filt_format,
+ avfilter_get_by_name("format"),
+ "format", "yuv420p", NULL, graph)) < 0)
+ return ret;
+ if ((ret = avfilter_link(filt_format, 0, filt_out, 0)) < 0)
+ return ret;
+
+
if (vfilters) {
AVFilterInOut *outputs = avfilter_inout_alloc();
AVFilterInOut *inputs = avfilter_inout_alloc();
@@ -1729,22 +1567,30 @@ static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c
outputs->next = NULL;
inputs->name = av_strdup("out");
- inputs->filter_ctx = filt_out;
+ inputs->filter_ctx = filt_format;
inputs->pad_idx = 0;
inputs->next = NULL;
if ((ret = avfilter_graph_parse(graph, vfilters, inputs, outputs, NULL)) < 0)
return ret;
} else {
- if ((ret = avfilter_link(filt_src, 0, filt_out, 0)) < 0)
+ if ((ret = avfilter_link(filt_src, 0, filt_format, 0)) < 0)
return ret;
}
if ((ret = avfilter_graph_config(graph, NULL)) < 0)
return ret;
+ is->in_video_filter = filt_src;
is->out_video_filter = filt_out;
+ if (codec->codec->capabilities & CODEC_CAP_DR1) {
+ is->use_dr1 = 1;
+ codec->get_buffer = codec_get_buffer;
+ codec->release_buffer = codec_release_buffer;
+ codec->opaque = &is->buffer_pool;
+ }
+
return ret;
}
@@ -1752,6 +1598,7 @@ static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c
static int video_thread(void *arg)
{
+ AVPacket pkt = { 0 };
VideoState *is = arg;
AVFrame *frame = avcodec_alloc_frame();
int64_t pts_int;
@@ -1760,25 +1607,34 @@ static int video_thread(void *arg)
#if CONFIG_AVFILTER
AVFilterGraph *graph = avfilter_graph_alloc();
- AVFilterContext *filt_out = NULL;
+ AVFilterContext *filt_out = NULL, *filt_in = NULL;
int64_t pos;
int last_w = is->video_st->codec->width;
int last_h = is->video_st->codec->height;
if ((ret = configure_video_filters(graph, is, vfilters)) < 0)
goto the_end;
+ filt_in = is->in_video_filter;
filt_out = is->out_video_filter;
#endif
for (;;) {
-#if !CONFIG_AVFILTER
- AVPacket pkt;
-#else
+#if CONFIG_AVFILTER
AVFilterBufferRef *picref;
AVRational tb;
#endif
while (is->paused && !is->videoq.abort_request)
SDL_Delay(10);
+
+ av_free_packet(&pkt);
+
+ ret = get_video_frame(is, frame, &pts_int, &pkt);
+ if (ret < 0)
+ goto the_end;
+
+ if (!ret)
+ continue;
+
#if CONFIG_AVFILTER
if ( last_w != is->video_st->codec->width
|| last_h != is->video_st->codec->height) {
@@ -1788,43 +1644,61 @@ static int video_thread(void *arg)
graph = avfilter_graph_alloc();
if ((ret = configure_video_filters(graph, is, vfilters)) < 0)
goto the_end;
+ filt_in = is->in_video_filter;
filt_out = is->out_video_filter;
last_w = is->video_st->codec->width;
last_h = is->video_st->codec->height;
}
- ret = get_filtered_video_frame(filt_out, frame, &picref, &tb);
- if (picref) {
+
+ frame->pts = pts_int;
+ if (is->use_dr1) {
+ FrameBuffer *buf = frame->opaque;
+ AVFilterBufferRef *fb = avfilter_get_video_buffer_ref_from_arrays(
+ frame->data, frame->linesize,
+ AV_PERM_READ | AV_PERM_PRESERVE,
+ frame->width, frame->height,
+ frame->format);
+
+ avfilter_copy_frame_props(fb, frame);
+ fb->buf->priv = buf;
+ fb->buf->free = filter_release_buffer;
+
+ buf->refcount++;
+ av_buffersrc_buffer(filt_in, fb);
+
+ } else
+ av_buffersrc_write_frame(filt_in, frame);
+
+ while (ret >= 0) {
+ ret = av_buffersink_read(filt_out, &picref);
+ if (ret < 0) {
+ ret = 0;
+ break;
+ }
+
+ avfilter_copy_buf_props(frame, picref);
+
pts_int = picref->pts;
+ tb = filt_out->inputs[0]->time_base;
pos = picref->pos;
frame->opaque = picref;
- }
- if (ret >= 0 && av_cmp_q(tb, is->video_st->time_base)) {
- av_unused int64_t pts1 = pts_int;
- pts_int = av_rescale_q(pts_int, tb, is->video_st->time_base);
- av_dlog(NULL, "video_thread(): "
- "tb:%d/%d pts:%"PRId64" -> tb:%d/%d pts:%"PRId64"\n",
- tb.num, tb.den, pts1,
- is->video_st->time_base.num, is->video_st->time_base.den, pts_int);
+ if (av_cmp_q(tb, is->video_st->time_base)) {
+ av_unused int64_t pts1 = pts_int;
+ pts_int = av_rescale_q(pts_int, tb, is->video_st->time_base);
+ av_dlog(NULL, "video_thread(): "
+ "tb:%d/%d pts:%"PRId64" -> tb:%d/%d pts:%"PRId64"\n",
+ tb.num, tb.den, pts1,
+ is->video_st->time_base.num, is->video_st->time_base.den, pts_int);
+ }
+ pts = pts_int * av_q2d(is->video_st->time_base);
+ ret = output_picture2(is, frame, pts, pos);
}
#else
- ret = get_video_frame(is, frame, &pts_int, &pkt);
-#endif
-
- if (ret < 0)
- goto the_end;
-
- if (!ret)
- continue;
-
pts = pts_int * av_q2d(is->video_st->time_base);
-
-#if CONFIG_AVFILTER
- ret = output_picture2(is, frame, pts, pos);
-#else
ret = output_picture2(is, frame, pts, pkt.pos);
- av_free_packet(&pkt);
#endif
+
if (ret < 0)
goto the_end;
@@ -1837,6 +1711,7 @@ static int video_thread(void *arg)
av_freep(&vfilters);
avfilter_graph_free(&graph);
#endif
+ av_free_packet(&pkt);
av_free(frame);
return 0;
}
@@ -1937,7 +1812,7 @@ static int synchronize_audio(VideoState *is, short *samples,
int n, samples_size;
double ref_clock;
- n = 2 * is->audio_st->codec->channels;
+ n = is->sdl_channels * av_get_bytes_per_sample(is->sdl_sample_fmt);
samples_size = samples_size1;
/* if not master, then we try to remove or add samples to correct the clock */
@@ -2018,6 +1893,8 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr)
for (;;) {
/* NOTE: the audio packet can contain several frames */
while (pkt_temp->size > 0 || (!pkt_temp->data && new_packet)) {
+ int resample_changed, audio_resample;
+
if (!is->frame) {
if (!(is->frame = avcodec_alloc_frame()))
return AVERROR(ENOMEM);
@@ -2047,39 +1924,69 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr)
is->frame->nb_samples,
dec->sample_fmt, 1);
- if (dec->sample_fmt != is->audio_src_fmt) {
- if (is->reformat_ctx)
- av_audio_convert_free(is->reformat_ctx);
- is->reformat_ctx= av_audio_convert_alloc(AV_SAMPLE_FMT_S16, 1,
- dec->sample_fmt, 1, NULL, 0);
- if (!is->reformat_ctx) {
- fprintf(stderr, "Cannot convert %s sample format to %s sample format\n",
- av_get_sample_fmt_name(dec->sample_fmt),
- av_get_sample_fmt_name(AV_SAMPLE_FMT_S16));
+ audio_resample = dec->sample_fmt != is->sdl_sample_fmt ||
+ dec->channel_layout != is->sdl_channel_layout;
+
+ resample_changed = dec->sample_fmt != is->resample_sample_fmt ||
+ dec->channel_layout != is->resample_channel_layout;
+
+ if ((!is->avr && audio_resample) || resample_changed) {
+ int ret;
+ if (is->avr)
+ avresample_close(is->avr);
+ else if (audio_resample) {
+ is->avr = avresample_alloc_context();
+ if (!is->avr) {
+ fprintf(stderr, "error allocating AVAudioResampleContext\n");
break;
+ }
}
- is->audio_src_fmt= dec->sample_fmt;
+ if (audio_resample) {
+ av_opt_set_int(is->avr, "in_channel_layout", dec->channel_layout, 0);
+ av_opt_set_int(is->avr, "in_sample_fmt", dec->sample_fmt, 0);
+ av_opt_set_int(is->avr, "in_sample_rate", dec->sample_rate, 0);
+ av_opt_set_int(is->avr, "out_channel_layout", is->sdl_channel_layout, 0);
+ av_opt_set_int(is->avr, "out_sample_fmt", is->sdl_sample_fmt, 0);
+ av_opt_set_int(is->avr, "out_sample_rate", dec->sample_rate, 0);
+ if (av_get_bytes_per_sample(dec->sample_fmt) <= 2)
+ av_opt_set_int(is->avr, "internal_sample_fmt", AV_SAMPLE_FMT_S16P, 0);
+
+ if ((ret = avresample_open(is->avr)) < 0) {
+ fprintf(stderr, "error initializing libavresample\n");
+ break;
+ }
+ }
+ is->resample_sample_fmt = dec->sample_fmt;
+ is->resample_channel_layout = dec->channel_layout;
}
- if (is->reformat_ctx) {
- const void *ibuf[6] = { is->frame->data[0] };
- void *obuf[6];
- int istride[6] = { av_get_bytes_per_sample(dec->sample_fmt) };
- int ostride[6] = { 2 };
- int len= data_size/istride[0];
- obuf[0] = av_realloc(is->audio_buf1, FFALIGN(len * ostride[0], 32));
- if (!obuf[0]) {
+ if (audio_resample) {
+ void *tmp_out;
+ int out_samples, out_size, out_linesize;
+ int osize = av_get_bytes_per_sample(is->sdl_sample_fmt);
+ int nb_samples = is->frame->nb_samples;
+
+ out_size = av_samples_get_buffer_size(&out_linesize,
+ is->sdl_channels,
+ nb_samples,
+ is->sdl_sample_fmt, 0);
+ tmp_out = av_realloc(is->audio_buf1, out_size);
+ if (!tmp_out)
return AVERROR(ENOMEM);
- }
- is->audio_buf1 = obuf[0];
- if (av_audio_convert(is->reformat_ctx, obuf, ostride, ibuf, istride, len) < 0) {
- printf("av_audio_convert() failed\n");
+ is->audio_buf1 = tmp_out;
+
+ out_samples = avresample_convert(is->avr,
+ (void **)&is->audio_buf1,
+ out_linesize, nb_samples,
+ (void **)is->frame->data,
+ is->frame->linesize[0],
+ is->frame->nb_samples);
+ if (out_samples < 0) {
+ fprintf(stderr, "avresample_convert() failed\n");
break;
}
is->audio_buf = is->audio_buf1;
- /* FIXME: existing code assume that data_size equals framesize*channels*2
- remove this legacy cruft */
- data_size = len * 2;
+ data_size = out_samples * osize * is->sdl_channels;
} else {
is->audio_buf = is->frame->data[0];
}
@@ -2087,7 +1994,7 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr)
/* if no pts, then compute it */
pts = is->audio_clock;
*pts_ptr = pts;
- n = 2 * dec->channels;
+ n = is->sdl_channels * av_get_bytes_per_sample(is->sdl_sample_fmt);
is->audio_clock += (double)data_size /
(double)(n * dec->sample_rate);
#ifdef DEBUG
@@ -2178,7 +2085,7 @@ static int stream_component_open(VideoState *is, int stream_index)
return -1;
avctx = ic->streams[stream_index]->codec;
- opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index]);
+ opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], NULL);
codec = avcodec_find_decoder(avctx->codec_id);
avctx->debug_mv = debug_mv;
@@ -2206,7 +2113,20 @@ static int stream_component_open(VideoState *is, int stream_index)
if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
wanted_spec.freq = avctx->sample_rate;
wanted_spec.format = AUDIO_S16SYS;
- wanted_spec.channels = avctx->channels;
+
+ if (!avctx->channel_layout)
+ avctx->channel_layout = av_get_default_channel_layout(avctx->channels);
+ if (!avctx->channel_layout) {
+ fprintf(stderr, "unable to guess channel layout\n");
+ return -1;
+ }
+ if (avctx->channels == 1)
+ is->sdl_channel_layout = AV_CH_LAYOUT_MONO;
+ else
+ is->sdl_channel_layout = AV_CH_LAYOUT_STEREO;
+ is->sdl_channels = av_get_channel_layout_nb_channels(is->sdl_channel_layout);
+
+ wanted_spec.channels = is->sdl_channels;
wanted_spec.silence = 0;
wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
wanted_spec.callback = sdl_audio_callback;
@@ -2216,7 +2136,9 @@ static int stream_component_open(VideoState *is, int stream_index)
return -1;
}
is->audio_hw_buf_size = spec.size;
- is->audio_src_fmt = AV_SAMPLE_FMT_S16;
+ is->sdl_sample_fmt = AV_SAMPLE_FMT_S16;
+ is->resample_sample_fmt = is->sdl_sample_fmt;
+ is->resample_channel_layout = is->sdl_channel_layout;
}
ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
@@ -2275,9 +2197,8 @@ static void stream_component_close(VideoState *is, int stream_index)
packet_queue_end(&is->audioq);
av_free_packet(&is->audio_pkt);
- if (is->reformat_ctx)
- av_audio_convert_free(is->reformat_ctx);
- is->reformat_ctx = NULL;
+ if (is->avr)
+ avresample_free(&is->avr);
av_freep(&is->audio_buf1);
is->audio_buf = NULL;
av_freep(&is->frame);
@@ -2323,6 +2244,7 @@ static void stream_component_close(VideoState *is, int stream_index)
ic->streams[stream_index]->discard = AVDISCARD_ALL;
avcodec_close(avctx);
+ free_buffer_pool(&is->buffer_pool);
switch (avctx->codec_type) {
case AVMEDIA_TYPE_AUDIO:
is->audio_st = NULL;
@@ -2519,10 +2441,11 @@ static int decode_thread(void *arg)
}
/* if the queue are full, no need to read more */
- if ( is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
+ if (!infinite_buffer &&
+ (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
|| ( (is->audioq .size > MIN_AUDIOQ_SIZE || is->audio_stream < 0)
&& (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0)
- && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0))) {
+ && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0)))) {
/* wait 10 ms */
SDL_Delay(10);
continue;
@@ -2690,13 +2613,13 @@ static void stream_cycle_channel(VideoState *is, int codec_type)
static void toggle_full_screen(void)
{
- is_full_screen = !is_full_screen;
#if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
/* OS X needs to empty the picture_queue */
- for (int i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {
+ int i;
+ for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
cur_stream->pictq[i].reallocate = 1;
- }
#endif
+ is_full_screen = !is_full_screen;
video_open(cur_stream);
}
@@ -2987,6 +2910,7 @@ static const OptionDef options[] = {
{ "exitonmousedown", OPT_BOOL | OPT_EXPERT, { (void*)&exit_on_mousedown }, "exit on mouse down", "" },
{ "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&loop }, "set number of times the playback shall be looped", "loop count" },
{ "framedrop", OPT_BOOL | OPT_EXPERT, { (void*)&framedrop }, "drop frames when cpu is too slow", "" },
+ { "infbuf", OPT_BOOL | OPT_EXPERT, { (void*)&infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
{ "window_title", OPT_STRING | HAS_ARG, { (void*)&window_title }, "set window title", "window title" },
#if CONFIG_AVFILTER
{ "vf", OPT_STRING | HAS_ARG, { (void*)&vfilters }, "video filters", "filter list" },
diff --git a/avprobe.c b/avprobe.c
index fe2b6e2..8e93d05 100644
--- a/avprobe.c
+++ b/avprobe.c
@@ -33,6 +33,8 @@ const char program_name[] = "avprobe";
const int program_birth_year = 2007;
static int do_show_format = 0;
+static AVDictionary *fmt_entries_to_show = NULL;
+static int nb_fmt_entries_to_show;
static int do_show_packets = 0;
static int do_show_streams = 0;
@@ -58,9 +60,398 @@ static const char unit_bit_per_second_str[] = "bit/s";
void exit_program(int ret)
{
+ av_dict_free(&fmt_entries_to_show);
exit(ret);
}
+/*
+ * The output is structured in array and objects that might contain items
+ * Array could require the objects within to not be named.
+ * Object could require the items within to be named.
+ *
+ * For flat representation the name of each section is saved on prefix so it
+ * can be rendered in order to represent nested structures (e.g. array of
+ * objects for the packets list).
+ *
+ * Within an array each element can need an unique identifier or an index.
+ *
+ * Nesting level is accounted separately.
+ */
+
+typedef enum {
+ ARRAY,
+ OBJECT
+} ProbeElementType;
+
+typedef struct {
+ const char *name;
+ ProbeElementType type;
+ int64_t index;
+ int64_t nb_elems;
+} ProbeElement;
+
+typedef struct {
+ ProbeElement *prefix;
+ int level;
+ void (*print_header)(void);
+ void (*print_footer)(void);
+
+ void (*print_array_header) (const char *name);
+ void (*print_array_footer) (const char *name);
+ void (*print_object_header)(const char *name);
+ void (*print_object_footer)(const char *name);
+
+ void (*print_integer) (const char *key, int64_t value);
+ void (*print_string) (const char *key, const char *value);
+} OutputContext;
+
+static AVIOContext *probe_out = NULL;
+static OutputContext octx;
+#define AVP_INDENT() avio_printf(probe_out, "%*c", octx.level * 2, ' ')
+
+/*
+ * Default format, INI
+ *
+ * - all key and values are utf8
+ * - '.' is the subgroup separator
+ * - newlines and the following characters are escaped
+ * - '\' is the escape character
+ * - '#' is the comment
+ * - '=' is the key/value separators
+ * - ':' is not used but usually parsed as key/value separator
+ */
+
+static void ini_print_header(void)
+{
+ avio_printf(probe_out, "# avprobe output\n\n");
+}
+static void ini_print_footer(void)
+{
+ avio_w8(probe_out, '\n');
+}
+
+static void ini_escape_print(const char *s)
+{
+ int i = 0;
+ char c = 0;
+
+ while (c = s[i++]) {
+ switch (c) {
+ case '\r': avio_printf(probe_out, "%s", "\\r"); break;
+ case '\n': avio_printf(probe_out, "%s", "\\n"); break;
+ case '\f': avio_printf(probe_out, "%s", "\\f"); break;
+ case '\b': avio_printf(probe_out, "%s", "\\b"); break;
+ case '\t': avio_printf(probe_out, "%s", "\\t"); break;
+ case '\\':
+ case '#' :
+ case '=' :
+ case ':' : avio_w8(probe_out, '\\');
+ default:
+ if ((unsigned char)c < 32)
+ avio_printf(probe_out, "\\x00%02x", c & 0xff);
+ else
+ avio_w8(probe_out, c);
+ break;
+ }
+ }
+}
+
+static void ini_print_array_header(const char *name)
+{
+ if (octx.prefix[octx.level -1].nb_elems)
+ avio_printf(probe_out, "\n");
+}
+
+static void ini_print_object_header(const char *name)
+{
+ int i;
+ ProbeElement *el = octx.prefix + octx.level -1;
+
+ if (el->nb_elems)
+ avio_printf(probe_out, "\n");
+
+ avio_printf(probe_out, "[");
+
+ for (i = 1; i < octx.level; i++) {
+ el = octx.prefix + i;
+ avio_printf(probe_out, "%s.", el->name);
+ if (el->index >= 0)
+ avio_printf(probe_out, "%"PRId64".", el->index);
+ }
+
+ avio_printf(probe_out, "%s", name);
+ if (el && el->type == ARRAY)
+ avio_printf(probe_out, ".%"PRId64"", el->nb_elems);
+ avio_printf(probe_out, "]\n");
+}
+
+static void ini_print_integer(const char *key, int64_t value)
+{
+ ini_escape_print(key);
+ avio_printf(probe_out, "=%"PRId64"\n", value);
+}
+
+
+static void ini_print_string(const char *key, const char *value)
+{
+ ini_escape_print(key);
+ avio_printf(probe_out, "=");
+ ini_escape_print(value);
+ avio_w8(probe_out, '\n');
+}
+
+/*
+ * Alternate format, JSON
+ */
+
+static void json_print_header(void)
+{
+ avio_printf(probe_out, "{");
+}
+static void json_print_footer(void)
+{
+ avio_printf(probe_out, "}\n");
+}
+
+static void json_print_array_header(const char *name)
+{
+ if (octx.prefix[octx.level -1].nb_elems)
+ avio_printf(probe_out, ",\n");
+ AVP_INDENT();
+ avio_printf(probe_out, "\"%s\" : ", name);
+ avio_printf(probe_out, "[\n");
+}
+
+static void json_print_array_footer(const char *name)
+{
+ avio_printf(probe_out, "\n");
+ AVP_INDENT();
+ avio_printf(probe_out, "]");
+}
+
+static void json_print_object_header(const char *name)
+{
+ if (octx.prefix[octx.level -1].nb_elems)
+ avio_printf(probe_out, ",\n");
+ AVP_INDENT();
+ if (octx.prefix[octx.level -1].type == OBJECT)
+ avio_printf(probe_out, "\"%s\" : ", name);
+ avio_printf(probe_out, "{\n");
+}
+
+static void json_print_object_footer(const char *name)
+{
+ avio_printf(probe_out, "\n");
+ AVP_INDENT();
+ avio_printf(probe_out, "}");
+}
+
+static void json_print_integer(const char *key, int64_t value)
+{
+ if (octx.prefix[octx.level -1].nb_elems)
+ avio_printf(probe_out, ",\n");
+ AVP_INDENT();
+ avio_printf(probe_out, "\"%s\" : %"PRId64"", key, value);
+}
+
+static void json_escape_print(const char *s)
+{
+ int i = 0;
+ char c = 0;
+
+ while (c = s[i++]) {
+ switch (c) {
+ case '\r': avio_printf(probe_out, "%s", "\\r"); break;
+ case '\n': avio_printf(probe_out, "%s", "\\n"); break;
+ case '\f': avio_printf(probe_out, "%s", "\\f"); break;
+ case '\b': avio_printf(probe_out, "%s", "\\b"); break;
+ case '\t': avio_printf(probe_out, "%s", "\\t"); break;
+ case '\\':
+ case '"' : avio_w8(probe_out, '\\');
+ default:
+ if ((unsigned char)c < 32)
+ avio_printf(probe_out, "\\u00%02x", c & 0xff);
+ else
+ avio_w8(probe_out, c);
+ break;
+ }
+ }
+}
+
+static void json_print_string(const char *key, const char *value)
+{
+ if (octx.prefix[octx.level -1].nb_elems)
+ avio_printf(probe_out, ",\n");
+ AVP_INDENT();
+ avio_w8(probe_out, '\"');
+ json_escape_print(key);
+ avio_printf(probe_out, "\" : \"");
+ json_escape_print(value);
+ avio_w8(probe_out, '\"');
+}
+
+/*
+ * old-style pseudo-INI
+ */
+static void old_print_object_header(const char *name)
+{
+ char *str, *p;
+
+ if (!strcmp(name, "tags"))
+ return;
+
+ str = p = av_strdup(name);
+ while (*p) {
+ *p = toupper(*p);
+ p++;
+ }
+
+ avio_printf(probe_out, "[%s]\n", str);
+ av_freep(&str);
+}
+
+static void old_print_object_footer(const char *name)
+{
+ char *str, *p;
+
+ if (!strcmp(name, "tags"))
+ return;
+
+ str = p = av_strdup(name);
+ while (*p) {
+ *p = toupper(*p);
+ p++;
+ }
+
+ avio_printf(probe_out, "[/%s]\n", str);
+ av_freep(&str);
+}
+
+static void old_print_string(const char *key, const char *value)
+{
+ if (!strcmp(octx.prefix[octx.level - 1].name, "tags"))
+ avio_printf(probe_out, "TAG:");
+ ini_print_string(key, value);
+}
+
+/*
+ * Simple Formatter for single entries.
+ */
+
+static void show_format_entry_integer(const char *key, int64_t value)
+{
+ if (key && av_dict_get(fmt_entries_to_show, key, NULL, 0)) {
+ if (nb_fmt_entries_to_show > 1)
+ avio_printf(probe_out, "%s=", key);
+ avio_printf(probe_out, "%"PRId64"\n", value);
+ }
+}
+
+static void show_format_entry_string(const char *key, const char *value)
+{
+ if (key && av_dict_get(fmt_entries_to_show, key, NULL, 0)) {
+ if (nb_fmt_entries_to_show > 1)
+ avio_printf(probe_out, "%s=", key);
+ avio_printf(probe_out, "%s\n", value);
+ }
+}
+
+static void probe_group_enter(const char *name, int type)
+{
+ int64_t count = -1;
+
+ octx.prefix =
+ av_realloc(octx.prefix, sizeof(ProbeElement) * (octx.level + 1));
+
+ if (!octx.prefix || !name) {
+ fprintf(stderr, "Out of memory\n");
+ exit(1);
+ }
+
+ if (octx.level) {
+ ProbeElement *parent = octx.prefix + octx.level -1;
+ if (parent->type == ARRAY)
+ count = parent->nb_elems;
+ parent->nb_elems++;
+ }
+
+ octx.prefix[octx.level++] = (ProbeElement){name, type, count, 0};
+}
+
+static void probe_group_leave(void)
+{
+ --octx.level;
+}
+
+static void probe_header(void)
+{
+ if (octx.print_header)
+ octx.print_header();
+ probe_group_enter("root", OBJECT);
+}
+
+static void probe_footer(void)
+{
+ if (octx.print_footer)
+ octx.print_footer();
+ probe_group_leave();
+}
+
+
+static void probe_array_header(const char *name)
+{
+ if (octx.print_array_header)
+ octx.print_array_header(name);
+
+ probe_group_enter(name, ARRAY);
+}
+
+static void probe_array_footer(const char *name)
+{
+ probe_group_leave();
+ if (octx.print_array_footer)
+ octx.print_array_footer(name);
+}
+
+static void probe_object_header(const char *name)
+{
+ if (octx.print_object_header)
+ octx.print_object_header(name);
+
+ probe_group_enter(name, OBJECT);
+}
+
+static void probe_object_footer(const char *name)
+{
+ probe_group_leave();
+ if (octx.print_object_footer)
+ octx.print_object_footer(name);
+}
+
+static void probe_int(const char *key, int64_t value)
+{
+ octx.print_integer(key, value);
+ octx.prefix[octx.level -1].nb_elems++;
+}
+
+static void probe_str(const char *key, const char *value)
+{
+ octx.print_string(key, value);
+ octx.prefix[octx.level -1].nb_elems++;
+}
+
+static void probe_dict(AVDictionary *dict, const char *name)
+{
+ AVDictionaryEntry *entry = NULL;
+ if (!dict)
+ return;
+ probe_object_header(name);
+ while ((entry = av_dict_get(dict, "", entry, AV_DICT_IGNORE_SUFFIX))) {
+ probe_str(entry->key, entry->value);
+ }
+ probe_object_footer(name);
+}
+
static char *value_string(char *buf, int buf_size, double val, const char *unit)
{
if (unit == unit_second_str && use_value_sexagesimal_format) {
@@ -87,11 +478,12 @@ static char *value_string(char *buf, int buf_size, double val, const char *unit)
val /= pow(10, index * 3);
prefix_string = decimal_unit_prefixes[index];
}
-
- snprintf(buf, buf_size, "%.3f %s%s", val, prefix_string,
+ snprintf(buf, buf_size, "%.*f%s%s",
+ index ? 3 : 0, val,
+ prefix_string,
show_value_unit ? unit : "");
} else {
- snprintf(buf, buf_size, "%f %s", val, show_value_unit ? unit : "");
+ snprintf(buf, buf_size, "%f%s", val, show_value_unit ? unit : "");
}
return buf;
@@ -109,7 +501,7 @@ static char *time_value_string(char *buf, int buf_size, int64_t val,
return buf;
}
-static char *ts_value_string (char *buf, int buf_size, int64_t ts)
+static char *ts_value_string(char *buf, int buf_size, int64_t ts)
{
if (ts == AV_NOPTS_VALUE) {
snprintf(buf, buf_size, "N/A");
@@ -120,6 +512,21 @@ static char *ts_value_string (char *buf, int buf_size, int64_t ts)
return buf;
}
+static char *rational_string(char *buf, int buf_size, const char *sep,
+ const AVRational *rat)
+{
+ snprintf(buf, buf_size, "%d%s%d", rat->num, sep, rat->den);
+ return buf;
+}
+
+static char *tag_string(char *buf, int buf_size, int tag)
+{
+ snprintf(buf, buf_size, "0x%04x", tag);
+ return buf;
+}
+
+
+
static const char *media_type_string(enum AVMediaType media_type)
{
switch (media_type) {
@@ -137,25 +544,25 @@ static void show_packet(AVFormatContext *fmt_ctx, AVPacket *pkt)
char val_str[128];
AVStream *st = fmt_ctx->streams[pkt->stream_index];
- printf("[PACKET]\n");
- printf("codec_type=%s\n", media_type_string(st->codec->codec_type));
- printf("stream_index=%d\n", pkt->stream_index);
- printf("pts=%s\n", ts_value_string(val_str, sizeof(val_str), pkt->pts));
- printf("pts_time=%s\n", time_value_string(val_str, sizeof(val_str),
- pkt->pts, &st->time_base));
- printf("dts=%s\n", ts_value_string(val_str, sizeof(val_str), pkt->dts));
- printf("dts_time=%s\n", time_value_string(val_str, sizeof(val_str),
- pkt->dts, &st->time_base));
- printf("duration=%s\n", ts_value_string(val_str, sizeof(val_str),
- pkt->duration));
- printf("duration_time=%s\n", time_value_string(val_str, sizeof(val_str),
- pkt->duration,
- &st->time_base));
- printf("size=%s\n", value_string(val_str, sizeof(val_str),
- pkt->size, unit_byte_str));
- printf("pos=%"PRId64"\n", pkt->pos);
- printf("flags=%c\n", pkt->flags & AV_PKT_FLAG_KEY ? 'K' : '_');
- printf("[/PACKET]\n");
+ probe_object_header("packet");
+ probe_str("codec_type", media_type_string(st->codec->codec_type));
+ probe_int("stream_index", pkt->stream_index);
+ probe_str("pts", ts_value_string(val_str, sizeof(val_str), pkt->pts));
+ probe_str("pts_time", time_value_string(val_str, sizeof(val_str),
+ pkt->pts, &st->time_base));
+ probe_str("dts", ts_value_string(val_str, sizeof(val_str), pkt->dts));
+ probe_str("dts_time", time_value_string(val_str, sizeof(val_str),
+ pkt->dts, &st->time_base));
+ probe_str("duration", ts_value_string(val_str, sizeof(val_str),
+ pkt->duration));
+ probe_str("duration_time", time_value_string(val_str, sizeof(val_str),
+ pkt->duration,
+ &st->time_base));
+ probe_str("size", value_string(val_str, sizeof(val_str),
+ pkt->size, unit_byte_str));
+ probe_int("pos", pkt->pos);
+ probe_str("flags", pkt->flags & AV_PKT_FLAG_KEY ? "K" : "_");
+ probe_object_footer("packet");
}
static void show_packets(AVFormatContext *fmt_ctx)
@@ -163,9 +570,10 @@ static void show_packets(AVFormatContext *fmt_ctx)
AVPacket pkt;
av_init_packet(&pkt);
-
+ probe_array_header("packets");
while (!av_read_frame(fmt_ctx, &pkt))
show_packet(fmt_ctx, &pkt);
+ probe_array_footer("packets");
}
static void show_stream(AVFormatContext *fmt_ctx, int stream_idx)
@@ -173,120 +581,126 @@ static void show_stream(AVFormatContext *fmt_ctx, int stream_idx)
AVStream *stream = fmt_ctx->streams[stream_idx];
AVCodecContext *dec_ctx;
AVCodec *dec;
+ const char *profile;
char val_str[128];
- AVDictionaryEntry *tag = NULL;
AVRational display_aspect_ratio;
- printf("[STREAM]\n");
+ probe_object_header("stream");
- printf("index=%d\n", stream->index);
+ probe_int("index", stream->index);
if ((dec_ctx = stream->codec)) {
if ((dec = dec_ctx->codec)) {
- printf("codec_name=%s\n", dec->name);
- printf("codec_long_name=%s\n", dec->long_name);
+ probe_str("codec_name", dec->name);
+ probe_str("codec_long_name", dec->long_name);
} else {
- printf("codec_name=unknown\n");
+ probe_str("codec_name", "unknown");
}
- printf("codec_type=%s\n", media_type_string(dec_ctx->codec_type));
- printf("codec_time_base=%d/%d\n",
- dec_ctx->time_base.num, dec_ctx->time_base.den);
+ probe_str("codec_type", media_type_string(dec_ctx->codec_type));
+ probe_str("codec_time_base",
+ rational_string(val_str, sizeof(val_str),
+ "/", &dec_ctx->time_base));
/* print AVI/FourCC tag */
av_get_codec_tag_string(val_str, sizeof(val_str), dec_ctx->codec_tag);
- printf("codec_tag_string=%s\n", val_str);
- printf("codec_tag=0x%04x\n", dec_ctx->codec_tag);
+ probe_str("codec_tag_string", val_str);
+ probe_str("codec_tag", tag_string(val_str, sizeof(val_str),
+ dec_ctx->codec_tag));
+
+ /* print profile, if there is one */
+ if (dec && (profile = av_get_profile_name(dec, dec_ctx->profile)))
+ probe_str("profile", profile);
switch (dec_ctx->codec_type) {
case AVMEDIA_TYPE_VIDEO:
- printf("width=%d\n", dec_ctx->width);
- printf("height=%d\n", dec_ctx->height);
- printf("has_b_frames=%d\n", dec_ctx->has_b_frames);
+ probe_int("width", dec_ctx->width);
+ probe_int("height", dec_ctx->height);
+ probe_int("has_b_frames", dec_ctx->has_b_frames);
if (dec_ctx->sample_aspect_ratio.num) {
- printf("sample_aspect_ratio=%d:%d\n",
- dec_ctx->sample_aspect_ratio.num,
- dec_ctx->sample_aspect_ratio.den);
+ probe_str("sample_aspect_ratio",
+ rational_string(val_str, sizeof(val_str), ":",
+ &dec_ctx->sample_aspect_ratio));
av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
dec_ctx->width * dec_ctx->sample_aspect_ratio.num,
dec_ctx->height * dec_ctx->sample_aspect_ratio.den,
1024*1024);
- printf("display_aspect_ratio=%d:%d\n",
- display_aspect_ratio.num, display_aspect_ratio.den);
+ probe_str("display_aspect_ratio",
+ rational_string(val_str, sizeof(val_str), ":",
+ &display_aspect_ratio));
}
- printf("pix_fmt=%s\n",
- dec_ctx->pix_fmt != PIX_FMT_NONE ? av_pix_fmt_descriptors[dec_ctx->pix_fmt].name
+ probe_str("pix_fmt",
+ dec_ctx->pix_fmt != PIX_FMT_NONE ? av_pix_fmt_descriptors[dec_ctx->pix_fmt].name
: "unknown");
- printf("level=%d\n", dec_ctx->level);
+ probe_int("level", dec_ctx->level);
break;
case AVMEDIA_TYPE_AUDIO:
- printf("sample_rate=%s\n", value_string(val_str, sizeof(val_str),
- dec_ctx->sample_rate,
- unit_hertz_str));
- printf("channels=%d\n", dec_ctx->channels);
- printf("bits_per_sample=%d\n",
- av_get_bits_per_sample(dec_ctx->codec_id));
+ probe_str("sample_rate",
+ value_string(val_str, sizeof(val_str),
+ dec_ctx->sample_rate,
+ unit_hertz_str));
+ probe_int("channels", dec_ctx->channels);
+ probe_int("bits_per_sample",
+ av_get_bits_per_sample(dec_ctx->codec_id));
break;
}
} else {
- printf("codec_type=unknown\n");
+ probe_str("codec_type", "unknown");
}
if (fmt_ctx->iformat->flags & AVFMT_SHOW_IDS)
- printf("id=0x%x\n", stream->id);
- printf("r_frame_rate=%d/%d\n",
- stream->r_frame_rate.num, stream->r_frame_rate.den);
- printf("avg_frame_rate=%d/%d\n",
- stream->avg_frame_rate.num, stream->avg_frame_rate.den);
- printf("time_base=%d/%d\n",
- stream->time_base.num, stream->time_base.den);
- printf("start_time=%s\n",
- time_value_string(val_str, sizeof(val_str),
- stream->start_time, &stream->time_base));
- printf("duration=%s\n",
- time_value_string(val_str, sizeof(val_str),
- stream->duration, &stream->time_base));
+ probe_int("id", stream->id);
+ probe_str("r_frame_rate",
+ rational_string(val_str, sizeof(val_str), "/",
+ &stream->r_frame_rate));
+ probe_str("avg_frame_rate",
+ rational_string(val_str, sizeof(val_str), "/",
+ &stream->avg_frame_rate));
+ probe_str("time_base",
+ rational_string(val_str, sizeof(val_str), "/",
+ &stream->time_base));
+ probe_str("start_time",
+ time_value_string(val_str, sizeof(val_str),
+ stream->start_time, &stream->time_base));
+ probe_str("duration",
+ time_value_string(val_str, sizeof(val_str),
+ stream->duration, &stream->time_base));
if (stream->nb_frames)
- printf("nb_frames=%"PRId64"\n", stream->nb_frames);
+ probe_int("nb_frames", stream->nb_frames);
- while ((tag = av_dict_get(stream->metadata, "", tag,
- AV_DICT_IGNORE_SUFFIX)))
- printf("TAG:%s=%s\n", tag->key, tag->value);
+ probe_dict(stream->metadata, "tags");
- printf("[/STREAM]\n");
+ probe_object_footer("stream");
}
static void show_format(AVFormatContext *fmt_ctx)
{
- AVDictionaryEntry *tag = NULL;
char val_str[128];
int64_t size = fmt_ctx->pb ? avio_size(fmt_ctx->pb) : -1;
- printf("[FORMAT]\n");
-
- printf("filename=%s\n", fmt_ctx->filename);
- printf("nb_streams=%d\n", fmt_ctx->nb_streams);
- printf("format_name=%s\n", fmt_ctx->iformat->name);
- printf("format_long_name=%s\n", fmt_ctx->iformat->long_name);
- printf("start_time=%s\n",
- time_value_string(val_str, sizeof(val_str),
- fmt_ctx->start_time, &AV_TIME_BASE_Q));
- printf("duration=%s\n",
- time_value_string(val_str, sizeof(val_str),
- fmt_ctx->duration, &AV_TIME_BASE_Q));
- printf("size=%s\n", size >= 0 ? value_string(val_str, sizeof(val_str),
- size, unit_byte_str)
+ probe_object_header("format");
+ probe_str("filename", fmt_ctx->filename);
+ probe_int("nb_streams", fmt_ctx->nb_streams);
+ probe_str("format_name", fmt_ctx->iformat->name);
+ probe_str("format_long_name", fmt_ctx->iformat->long_name);
+ probe_str("start_time",
+ time_value_string(val_str, sizeof(val_str),
+ fmt_ctx->start_time, &AV_TIME_BASE_Q));
+ probe_str("duration",
+ time_value_string(val_str, sizeof(val_str),
+ fmt_ctx->duration, &AV_TIME_BASE_Q));
+ probe_str("size",
+ size >= 0 ? value_string(val_str, sizeof(val_str),
+ size, unit_byte_str)
: "unknown");
- printf("bit_rate=%s\n",
- value_string(val_str, sizeof(val_str),
- fmt_ctx->bit_rate, unit_bit_per_second_str));
+ probe_str("bit_rate",
+ value_string(val_str, sizeof(val_str),
+ fmt_ctx->bit_rate, unit_bit_per_second_str));
- while ((tag = av_dict_get(fmt_ctx->metadata, "", tag,
- AV_DICT_IGNORE_SUFFIX)))
- printf("TAG:%s=%s\n", tag->key, tag->value);
+ probe_dict(fmt_ctx->metadata, "tags");
- printf("[/FORMAT]\n");
+ probe_object_footer("format");
}
static int open_input_file(AVFormatContext **fmt_ctx_ptr, const char *filename)
@@ -319,7 +733,10 @@ static int open_input_file(AVFormatContext **fmt_ctx_ptr, const char *filename)
AVStream *stream = fmt_ctx->streams[i];
AVCodec *codec;
- if (!(codec = avcodec_find_decoder(stream->codec->codec_id))) {
+ if (stream->codec->codec_id == CODEC_ID_PROBE) {
+ fprintf(stderr, "Failed to probe codec for input stream %d\n",
+ stream->index);
+ } else if (!(codec = avcodec_find_decoder(stream->codec->codec_id))) {
fprintf(stderr,
"Unsupported codec with id %d for input stream %d\n",
stream->codec->codec_id, stream->index);
@@ -333,6 +750,20 @@ static int open_input_file(AVFormatContext **fmt_ctx_ptr, const char *filename)
return 0;
}
+static void close_input_file(AVFormatContext **ctx_ptr)
+{
+ int i;
+ AVFormatContext *fmt_ctx = *ctx_ptr;
+
+ /* close decoder for each stream */
+ for (i = 0; i < fmt_ctx->nb_streams; i++) {
+ AVStream *stream = fmt_ctx->streams[i];
+
+ avcodec_close(stream->codec);
+ }
+ avformat_close_input(ctx_ptr);
+}
+
static int probe_file(const char *filename)
{
AVFormatContext *fmt_ctx;
@@ -341,17 +772,20 @@ static int probe_file(const char *filename)
if ((ret = open_input_file(&fmt_ctx, filename)))
return ret;
- if (do_show_packets)
- show_packets(fmt_ctx);
+ if (do_show_format)
+ show_format(fmt_ctx);
- if (do_show_streams)
+ if (do_show_streams) {
+ probe_array_header("streams");
for (i = 0; i < fmt_ctx->nb_streams; i++)
show_stream(fmt_ctx, i);
+ probe_array_footer("streams");
+ }
- if (do_show_format)
- show_format(fmt_ctx);
+ if (do_show_packets)
+ show_packets(fmt_ctx);
- avformat_close_input(&fmt_ctx);
+ close_input_file(&fmt_ctx);
return 0;
}
@@ -372,6 +806,57 @@ static int opt_format(const char *opt, const char *arg)
return 0;
}
+static int opt_output_format(const char *opt, const char *arg)
+{
+
+ if (!strcmp(arg, "json")) {
+ octx.print_header = json_print_header;
+ octx.print_footer = json_print_footer;
+ octx.print_array_header = json_print_array_header;
+ octx.print_array_footer = json_print_array_footer;
+ octx.print_object_header = json_print_object_header;
+ octx.print_object_footer = json_print_object_footer;
+
+ octx.print_integer = json_print_integer;
+ octx.print_string = json_print_string;
+ } else if (!strcmp(arg, "ini")) {
+ octx.print_header = ini_print_header;
+ octx.print_footer = ini_print_footer;
+ octx.print_array_header = ini_print_array_header;
+ octx.print_object_header = ini_print_object_header;
+
+ octx.print_integer = ini_print_integer;
+ octx.print_string = ini_print_string;
+ } else if (!strcmp(arg, "old")) {
+ octx.print_header = NULL;
+ octx.print_object_header = old_print_object_header;
+ octx.print_object_footer = old_print_object_footer;
+
+ octx.print_string = old_print_string;
+ } else {
+ av_log(NULL, AV_LOG_ERROR, "Unsupported formatter %s\n", arg);
+ return AVERROR(EINVAL);
+ }
+ return 0;
+}
+
+static int opt_show_format_entry(const char *opt, const char *arg)
+{
+ do_show_format = 1;
+ nb_fmt_entries_to_show++;
+ octx.print_header = NULL;
+ octx.print_footer = NULL;
+ octx.print_array_header = NULL;
+ octx.print_array_footer = NULL;
+ octx.print_object_header = NULL;
+ octx.print_object_footer = NULL;
+
+ octx.print_integer = show_format_entry_integer;
+ octx.print_string = show_format_entry_string;
+ av_dict_set(&fmt_entries_to_show, arg, "", 0);
+ return 0;
+}
+
static void opt_input_file(void *optctx, const char *arg)
{
if (input_filename) {
@@ -405,6 +890,7 @@ static void opt_pretty(void)
static const OptionDef options[] = {
#include "cmdutils_common_opts.h"
{ "f", HAS_ARG, {(void*)opt_format}, "force format", "format" },
+ { "of", HAS_ARG, {(void*)&opt_output_format}, "output the document either as ini or json", "output_format" },
{ "unit", OPT_BOOL, {(void*)&show_value_unit},
"show unit of the displayed values" },
{ "prefix", OPT_BOOL, {(void*)&use_value_prefix},
@@ -416,6 +902,8 @@ static const OptionDef options[] = {
{ "pretty", 0, {(void*)&opt_pretty},
"prettify the format of displayed values, make it more human readable" },
{ "show_format", OPT_BOOL, {(void*)&do_show_format} , "show format/container info" },
+ { "show_format_entry", HAS_ARG, {(void*)opt_show_format_entry},
+ "show a particular entry from the format/container info", "entry" },
{ "show_packets", OPT_BOOL, {(void*)&do_show_packets}, "show packets info" },
{ "show_streams", OPT_BOOL, {(void*)&do_show_streams}, "show streams info" },
{ "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default},
@@ -423,9 +911,21 @@ static const OptionDef options[] = {
{ NULL, },
};
+static int probe_buf_write(void *opaque, uint8_t *buf, int buf_size)
+{
+ printf("%.*s", buf_size, buf);
+ return 0;
+}
+
+#define AVP_BUFFSIZE 4096
+
int main(int argc, char **argv)
{
int ret;
+ uint8_t *buffer = av_malloc(AVP_BUFFSIZE);
+
+ if (!buffer)
+ exit(1);
parse_loglevel(argc, argv, options);
av_register_all();
@@ -436,6 +936,16 @@ int main(int argc, char **argv)
#endif
show_banner();
+
+ octx.print_header = ini_print_header;
+ octx.print_footer = ini_print_footer;
+
+ octx.print_array_header = ini_print_array_header;
+ octx.print_object_header = ini_print_object_header;
+
+ octx.print_integer = ini_print_integer;
+ octx.print_string = ini_print_string;
+
parse_options(NULL, argc, argv, options, opt_input_file);
if (!input_filename) {
@@ -447,7 +957,16 @@ int main(int argc, char **argv)
exit(1);
}
+ probe_out = avio_alloc_context(buffer, AVP_BUFFSIZE, 1, NULL, NULL,
+ probe_buf_write, NULL);
+ if (!probe_out)
+ exit(1);
+
+ probe_header();
ret = probe_file(input_filename);
+ probe_footer();
+ avio_flush(probe_out);
+ avio_close(probe_out);
avformat_network_deinit();
diff --git a/avserver.c b/avserver.c
index 2b16932..6050965 100644
--- a/avserver.c
+++ b/avserver.c
@@ -51,7 +51,6 @@
#include <poll.h>
#endif
#include <errno.h>
-#include <sys/time.h>
#include <time.h>
#include <sys/wait.h>
#include <signal.h>
@@ -2572,8 +2571,11 @@ static int http_start_receive_data(HTTPContext *c)
if (c->stream->truncate) {
/* truncate feed file */
ffm_write_write_index(c->feed_fd, FFM_PACKET_SIZE);
- ftruncate(c->feed_fd, FFM_PACKET_SIZE);
http_log("Truncating feed file '%s'\n", c->stream->feed_filename);
+ if (ftruncate(c->feed_fd, FFM_PACKET_SIZE) < 0) {
+ http_log("Error truncating feed file: %s\n", strerror(errno));
+ return -1;
+ }
} else {
if ((c->stream->feed_write_index = ffm_read_write_index(fd)) < 0) {
http_log("Error reading write index from feed file: %s\n", strerror(errno));
diff --git a/cmdutils.c b/cmdutils.c
index 6d2e97f..6d13bd6 100644
--- a/cmdutils.c
+++ b/cmdutils.c
@@ -34,8 +34,10 @@
#include "libavdevice/avdevice.h"
#include "libavresample/avresample.h"
#include "libswscale/swscale.h"
+#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
#include "libavutil/mathematics.h"
+#include "libavutil/imgutils.h"
#include "libavutil/parseutils.h"
#include "libavutil/pixdesc.h"
#include "libavutil/eval.h"
@@ -905,6 +907,7 @@ int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
case 's': type = AVMEDIA_TYPE_SUBTITLE; break;
case 'd': type = AVMEDIA_TYPE_DATA; break;
case 't': type = AVMEDIA_TYPE_ATTACHMENT; break;
+ default: av_assert0(0);
}
if (type != st->codec->codec_type)
return 0;
@@ -945,18 +948,19 @@ int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
}
AVDictionary *filter_codec_opts(AVDictionary *opts, enum CodecID codec_id,
- AVFormatContext *s, AVStream *st)
+ AVFormatContext *s, AVStream *st, AVCodec *codec)
{
AVDictionary *ret = NULL;
AVDictionaryEntry *t = NULL;
- AVCodec *codec = s->oformat ? avcodec_find_encoder(codec_id)
- : avcodec_find_decoder(codec_id);
int flags = s->oformat ? AV_OPT_FLAG_ENCODING_PARAM
: AV_OPT_FLAG_DECODING_PARAM;
char prefix = 0;
const AVClass *cc = avcodec_get_class();
if (!codec)
+ codec = s->oformat ? avcodec_find_encoder(codec_id)
+ : avcodec_find_decoder(codec_id);
+ if (!codec)
return NULL;
switch (codec->type) {
@@ -1017,93 +1021,154 @@ AVDictionary **setup_find_stream_info_opts(AVFormatContext *s,
}
for (i = 0; i < s->nb_streams; i++)
opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codec->codec_id,
- s, s->streams[i]);
+ s, s->streams[i], NULL);
return opts;
}
-#if CONFIG_AVFILTER
+void *grow_array(void *array, int elem_size, int *size, int new_size)
+{
+ if (new_size >= INT_MAX / elem_size) {
+ av_log(NULL, AV_LOG_ERROR, "Array too big.\n");
+ exit_program(1);
+ }
+ if (*size < new_size) {
+ uint8_t *tmp = av_realloc(array, new_size*elem_size);
+ if (!tmp) {
+ av_log(NULL, AV_LOG_ERROR, "Could not alloc buffer.\n");
+ exit_program(1);
+ }
+ memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size);
+ *size = new_size;
+ return tmp;
+ }
+ return array;
+}
-static int sink_init(AVFilterContext *ctx, const char *args, void *opaque)
+static int alloc_buffer(FrameBuffer **pool, AVCodecContext *s, FrameBuffer **pbuf)
{
- SinkContext *priv = ctx->priv;
+ FrameBuffer *buf = av_mallocz(sizeof(*buf));
+ int i, 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 (!opaque)
- return AVERROR(EINVAL);
- *priv = *(SinkContext *)opaque;
+ 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;
+ }
+ /* XXX this shouldn't be needed, but some tests break without this line
+ * those decoders are buggy and need to be fixed.
+ * the following tests fail:
+ * cdgraphics, ansi, aasc, fraps-v1, qtrle-1bit
+ */
+ memset(buf->base[0], 128, ret);
+
+ avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift);
+ for (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->pool = pool;
+
+ *pbuf = buf;
return 0;
}
-static void null_end_frame(AVFilterLink *inlink) { }
-
-static int sink_query_formats(AVFilterContext *ctx)
+int codec_get_buffer(AVCodecContext *s, AVFrame *frame)
{
- SinkContext *priv = ctx->priv;
+ FrameBuffer **pool = s->opaque;
+ FrameBuffer *buf;
+ int ret, i;
+
+ if (!*pool && (ret = alloc_buffer(pool, s, pool)) < 0)
+ return ret;
+
+ buf = *pool;
+ *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(pool, s, &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;
+ frame->width = buf->w;
+ frame->height = buf->h;
+ frame->format = buf->pix_fmt;
+ frame->sample_aspect_ratio = s->sample_aspect_ratio;
+
+ 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];
+ }
- if (priv->pix_fmts)
- avfilter_set_common_formats(ctx, avfilter_make_format_list(priv->pix_fmts));
- else
- avfilter_default_query_formats(ctx);
return 0;
}
-AVFilter sink = {
- .name = "sink",
- .priv_size = sizeof(SinkContext),
- .init = sink_init,
-
- .query_formats = sink_query_formats,
+static void unref_buffer(FrameBuffer *buf)
+{
+ FrameBuffer **pool = buf->pool;
- .inputs = (AVFilterPad[]) {{ .name = "default",
- .type = AVMEDIA_TYPE_VIDEO,
- .end_frame = null_end_frame,
- .min_perms = AV_PERM_READ, },
- { .name = NULL }},
- .outputs = (AVFilterPad[]) {{ .name = NULL }},
-};
+ av_assert0(buf->refcount);
+ buf->refcount--;
+ if (!buf->refcount) {
+ buf->next = *pool;
+ *pool = buf;
+ }
+}
-int get_filtered_video_frame(AVFilterContext *ctx, AVFrame *frame,
- AVFilterBufferRef **picref_ptr, AVRational *tb)
+void codec_release_buffer(AVCodecContext *s, AVFrame *frame)
{
- int ret;
- AVFilterBufferRef *picref;
+ FrameBuffer *buf = frame->opaque;
+ int i;
- if ((ret = avfilter_request_frame(ctx->inputs[0])) < 0)
- return ret;
- if (!(picref = ctx->inputs[0]->cur_buf))
- return AVERROR(ENOENT);
- *picref_ptr = picref;
- ctx->inputs[0]->cur_buf = NULL;
- *tb = ctx->inputs[0]->time_base;
-
- memcpy(frame->data, picref->data, sizeof(frame->data));
- memcpy(frame->linesize, picref->linesize, sizeof(frame->linesize));
- frame->interlaced_frame = picref->video->interlaced;
- frame->top_field_first = picref->video->top_field_first;
- frame->key_frame = picref->video->key_frame;
- frame->pict_type = picref->video->pict_type;
- frame->sample_aspect_ratio = picref->video->pixel_aspect;
-
- return 1;
+ for (i = 0; i < FF_ARRAY_ELEMS(frame->data); i++)
+ frame->data[i] = NULL;
+
+ unref_buffer(buf);
}
-#endif /* CONFIG_AVFILTER */
+void filter_release_buffer(AVFilterBuffer *fb)
+{
+ FrameBuffer *buf = fb->priv;
+ av_free(fb);
+ unref_buffer(buf);
+}
-void *grow_array(void *array, int elem_size, int *size, int new_size)
+void free_buffer_pool(FrameBuffer **pool)
{
- if (new_size >= INT_MAX / elem_size) {
- av_log(NULL, AV_LOG_ERROR, "Array too big.\n");
- exit_program(1);
+ FrameBuffer *buf = *pool;
+ while (buf) {
+ *pool = buf->next;
+ av_freep(&buf->base[0]);
+ av_free(buf);
+ buf = *pool;
}
- if (*size < new_size) {
- uint8_t *tmp = av_realloc(array, new_size*elem_size);
- if (!tmp) {
- av_log(NULL, AV_LOG_ERROR, "Could not alloc buffer.\n");
- exit_program(1);
- }
- memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size);
- *size = new_size;
- return tmp;
- }
- return array;
}
diff --git a/cmdutils.h b/cmdutils.h
index 792254c..ca4f4c1 100644
--- a/cmdutils.h
+++ b/cmdutils.h
@@ -214,10 +214,12 @@ int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec);
*
* @param s Corresponding format context.
* @param st A stream from s for which the options should be filtered.
+ * @param codec The particular codec for which the options should be filtered.
+ * If null, the default one is looked up according to the codec id.
* @return a pointer to the created dictionary
*/
AVDictionary *filter_codec_opts(AVDictionary *opts, enum CodecID codec_id,
- AVFormatContext *s, AVStream *st);
+ AVFormatContext *s, AVStream *st, AVCodec *codec);
/**
* Setup AVCodecContext options for avformat_find_stream_info().
@@ -367,26 +369,11 @@ int64_t guess_correct_pts(PtsCorrectionContext *ctx, int64_t pts, int64_t dts);
FILE *get_preset_file(char *filename, size_t filename_size,
const char *preset_name, int is_path, const char *codec_name);
-typedef struct {
- const enum PixelFormat *pix_fmts;
-} SinkContext;
-
-extern AVFilter sink;
-
-/**
- * Extract a frame from sink.
- *
- * @return a negative error in case of failure, 1 if one frame has
- * been extracted successfully.
- */
-int get_filtered_video_frame(AVFilterContext *sink, AVFrame *frame,
- AVFilterBufferRef **picref, AVRational *pts_tb);
-
/**
* Do all the necessary cleanup and abort.
* This function is implemented in the avtools, not cmdutils.
*/
-void exit_program(int ret);
+av_noreturn void exit_program(int ret);
/**
* Realloc array to hold new_size elements of elem_size.
@@ -398,4 +385,46 @@ void exit_program(int ret);
*/
void *grow_array(void *array, int elem_size, int *size, int new_size);
+typedef struct FrameBuffer {
+ uint8_t *base[4];
+ uint8_t *data[4];
+ int linesize[4];
+
+ int h, w;
+ enum PixelFormat pix_fmt;
+
+ int refcount;
+ struct FrameBuffer **pool; ///< head of the buffer pool
+ struct FrameBuffer *next;
+} FrameBuffer;
+
+/**
+ * Get a frame from the pool. This is intended to be used as a callback for
+ * AVCodecContext.get_buffer.
+ *
+ * @param s codec context. s->opaque must be a pointer to the head of the
+ * buffer pool.
+ * @param frame frame->opaque will be set to point to the FrameBuffer
+ * containing the frame data.
+ */
+int codec_get_buffer(AVCodecContext *s, AVFrame *frame);
+
+/**
+ * A callback to be used for AVCodecContext.release_buffer along with
+ * codec_get_buffer().
+ */
+void codec_release_buffer(AVCodecContext *s, AVFrame *frame);
+
+/**
+ * A callback to be used for AVFilterBuffer.free.
+ * @param fb buffer to free. fb->priv must be a pointer to the FrameBuffer
+ * containing the buffer data.
+ */
+void filter_release_buffer(AVFilterBuffer *fb);
+
+/**
+ * Free all the buffers in the pool. This must be called after all the
+ * buffers have been released.
+ */
+void free_buffer_pool(FrameBuffer **pool);
#endif /* LIBAV_CMDUTILS_H */
diff --git a/common.mak b/common.mak
index 7f2c367..98c274e 100644
--- a/common.mak
+++ b/common.mak
@@ -47,6 +47,6 @@ OBJDIRS := $(OBJDIRS) $(dir $(OBJS) $(HOSTOBJS) $(TESTOBJS))
CLEANSUFFIXES = *.d *.o *~ *.ho *.map *.ver
DISTCLEANSUFFIXES = *.pc
-LIBSUFFIXES = *.a *.lib *.so *.so.* *.dylib *.dll *.def *.dll.a *.exp
+LIBSUFFIXES = *.a *.lib *.so *.so.* *.dylib *.dll *.def *.dll.a
-include $(wildcard $(OBJS:.o=.d) $(TESTOBJS:.o=.d))
diff --git a/configure b/configure
index 1dc2e3e..a08b3af 100755
--- a/configure
+++ b/configure
@@ -166,18 +166,17 @@ External library support:
--enable-bzlib enable bzlib [autodetect]
--enable-frei0r enable frei0r video filtering
--enable-gnutls enable gnutls [no]
- --enable-libopencore-amrnb enable AMR-NB de/encoding via libopencore-amrnb [no]
- --enable-libopencore-amrwb enable AMR-WB decoding via libopencore-amrwb [no]
- --enable-libopencv enable video filtering via libopencv [no]
--enable-libcdio enable audio CD grabbing with libcdio
--enable-libdc1394 enable IIDC-1394 grabbing using libdc1394
and libraw1394 [no]
--enable-libfaac enable FAAC support via libfaac [no]
--enable-libfreetype enable libfreetype [no]
--enable-libgsm enable GSM support via libgsm [no]
+ --enable-libilbc enable iLBC de/encoding via libilbc [no]
--enable-libmp3lame enable MP3 encoding via libmp3lame [no]
- --enable-libnut enable NUT (de)muxing via libnut,
- native (de)muxer exists [no]
+ --enable-libopencore-amrnb enable AMR-NB de/encoding via libopencore-amrnb [no]
+ --enable-libopencore-amrwb enable AMR-WB decoding via libopencore-amrwb [no]
+ --enable-libopencv enable video filtering via libopencv [no]
--enable-libopenjpeg enable JPEG 2000 decoding via OpenJPEG [no]
--enable-libpulse enable Pulseaudio input via libpulse [no]
--enable-librtmp enable RTMP[E] support via librtmp [no]
@@ -258,7 +257,7 @@ Developer options (useful when working on Libav itself):
--disable-optimizations disable compiler optimizations
--enable-extra-warnings enable more compiler warnings
--samples=PATH location of test samples for FATE, if not set use
- \$FATE_SAMPLES at make invocation time.
+ \$LIBAV_SAMPLES at make invocation time.
--enable-xmm-clobber-test check XMM registers for clobbering (Win64-only;
should be used only for debugging purposes)
@@ -661,6 +660,20 @@ check_ld(){
check_cmd $ld $LDFLAGS $flags -o $TMPE $TMPO $libs $extralibs
}
+check_code(){
+ log check_code "$@"
+ check=$1
+ headers=$2
+ code=$3
+ shift 3
+ {
+ for hdr in $headers; do
+ echo "#include <$hdr>"
+ done
+ echo "int main(void) { $code; return 0; }"
+ } | check_$check "$@"
+}
+
check_cppflags(){
log check_cppflags "$@"
set -- $($filter_cppflags "$@")
@@ -818,15 +831,7 @@ check_type(){
type=$2
shift 2
disable_safe "$type"
- incs=""
- for hdr in $headers; do
- incs="$incs
-#include <$hdr>"
- done
- check_cc "$@" <<EOF && enable_safe "$type"
-$incs
-$type v;
-EOF
+ check_code cc "$headers" "$type v" "$@" && enable_safe "$type"
}
check_struct(){
@@ -836,15 +841,8 @@ check_struct(){
member=$3
shift 3
disable_safe "${struct}_${member}"
- incs=""
- for hdr in $headers; do
- incs="$incs
-#include <$hdr>"
- done
- check_cc "$@" <<EOF && enable_safe "${struct}_${member}"
-$incs
-const void *p = &(($struct *)0)->$member;
-EOF
+ check_code cc "$headers" "const void *p = &(($struct *)0)->$member" "$@" &&
+ enable_safe "${struct}_${member}"
}
require(){
@@ -947,8 +945,8 @@ CONFIG_LIST="
libfaac
libfreetype
libgsm
+ libilbc
libmp3lame
- libnut
libopencore_amrnb
libopencore_amrwb
libopencv
@@ -1052,6 +1050,7 @@ HAVE_LIST="
$ARCH_EXT_LIST
$HAVE_LIST_PUB
$THREADS_LIST
+ aligned_malloc
aligned_stack
alsa_asoundlib_h
altivec_h
@@ -1059,6 +1058,7 @@ HAVE_LIST="
asm_mod_y
attribute_may_alias
attribute_packed
+ cbrtf
closesocket
cmov
dcbzl
@@ -1070,6 +1070,7 @@ HAVE_LIST="
dlfcn_h
dlopen
dos_paths
+ dxva_h
ebp_available
ebx_available
exp2
@@ -1084,12 +1085,18 @@ HAVE_LIST="
GetProcessAffinityMask
GetProcessMemoryInfo
GetProcessTimes
+ GetSystemTimeAsFileTime
getrusage
+ gettimeofday
gnu_as
ibm_asm
inet_aton
inline_asm
+ io_h
isatty
+ isinf
+ isnan
+ jack_port_get_latency_range
ldbrx
libdc1394_1
libdc1394_2
@@ -1110,6 +1117,8 @@ HAVE_LIST="
memalign
mkstemp
mmap
+ nanosleep
+ netinet_sctp_h
poll_h
posix_memalign
round
@@ -1119,6 +1128,7 @@ HAVE_LIST="
sdl_video_size
setmode
setrlimit
+ Sleep
sndio_h
socklen_t
soundcard_h
@@ -1126,7 +1136,10 @@ HAVE_LIST="
strptime
strtok_r
struct_addrinfo
+ struct_group_source_req
+ struct_ip_mreq_source
struct_ipv6_mreq
+ struct_pollfd
struct_rusage_ru_maxrss
struct_sockaddr_in6
struct_sockaddr_sa_len
@@ -1142,12 +1155,16 @@ HAVE_LIST="
sys_resource_h
sys_select_h
sys_soundcard_h
+ sys_time_h
sys_videoio_h
threads
trunc
truncf
+ unistd_h
+ usleep
vfp_args
VirtualAlloc
+ windows_h
winsock2_h
xform_asm
xmm_clobbers
@@ -1316,6 +1333,7 @@ h264_dxva2_hwaccel_select="dxva2 h264_decoder"
h264_vaapi_hwaccel_select="vaapi h264_decoder"
h264_vda_hwaccel_select="vda h264_decoder"
h264_vdpau_decoder_select="vdpau h264_decoder"
+iac_decoder_select="fft mdct sinewin"
imc_decoder_select="fft mdct sinewin"
jpegls_decoder_select="golomb"
jpegls_encoder_select="golomb"
@@ -1427,6 +1445,8 @@ libgsm_decoder_deps="libgsm"
libgsm_encoder_deps="libgsm"
libgsm_ms_decoder_deps="libgsm"
libgsm_ms_encoder_deps="libgsm"
+libilbc_decoder_deps="libilbc"
+libilbc_encoder_deps="libilbc"
libmp3lame_encoder_deps="libmp3lame"
libopencore_amrnb_decoder_deps="libopencore_amrnb"
libopencore_amrnb_encoder_deps="libopencore_amrnb"
@@ -1454,13 +1474,12 @@ dirac_demuxer_select="dirac_parser"
eac3_demuxer_select="ac3_parser"
flac_demuxer_select="flac_parser"
ipod_muxer_select="mov_muxer"
-libnut_demuxer_deps="libnut"
-libnut_muxer_deps="libnut"
matroska_audio_muxer_select="matroska_muxer"
matroska_demuxer_suggest="zlib bzlib"
mov_demuxer_suggest="zlib"
mp3_demuxer_select="mpegaudio_parser"
mp4_muxer_select="mov_muxer"
+mpegts_muxer_select="adts_muxer latm_muxer"
mpegtsraw_demuxer_select="mpegts_demuxer"
mxf_d10_muxer_select="mxf_muxer"
ogg_demuxer_select="golomb"
@@ -1512,7 +1531,12 @@ mmsh_protocol_select="http_protocol"
mmst_protocol_deps="network"
rtmp_protocol_deps="!librtmp_protocol"
rtmp_protocol_select="tcp_protocol"
+rtmphttp_protocol_deps="!librtmp_protocol"
+rtmphttp_protocol_select="http_protocol"
+rtmpt_protocol_deps="!librtmp_protocol"
+rtmpt_protocol_select="rtmphttp_protocol"
rtp_protocol_select="udp_protocol"
+sctp_protocol_deps="network netinet_sctp_h"
tcp_protocol_deps="network"
tls_protocol_deps_any="openssl gnutls"
tls_protocol_select="tcp_protocol"
@@ -1529,6 +1553,7 @@ frei0r_filter_extralibs='$ldl'
frei0r_src_filter_deps="frei0r dlopen strtok_r"
frei0r_src_filter_extralibs='$ldl'
hqdn3d_filter_deps="gpl"
+resample_filter_deps="avresample"
ocv_filter_deps="libopencv"
scale_filter_deps="swscale"
yadif_filter_deps="gpl"
@@ -1538,7 +1563,9 @@ avdevice_deps="avcodec avformat"
avformat_deps="avcodec"
# programs
-avconv_deps="avcodec avfilter avformat avresample swscale"
+avconv_deps="avcodec avfilter avformat avresample swscale
+ aformat_filter asyncts_filter
+ format_filter fps_filter scale_filter setpts_filter"
avplay_deps="avcodec avformat swscale sdl"
avplay_select="rdft"
avprobe_deps="avcodec avformat"
@@ -1565,56 +1592,6 @@ test_deps(){
mxf_d10_test_deps="avfilter"
seek_lavf_mxf_d10_test_deps="mxf_d10_test"
-test_deps _encoder _decoder \
- adpcm_ima_qt \
- adpcm_ima_wav \
- adpcm_ms \
- adpcm_swf \
- adpcm_yamaha=adpcm_yam \
- alac \
- asv1 \
- asv2 \
- bmp \
- dnxhd="dnxhd_1080i dnxhd_720p dnxhd_720p_rd" \
- dvvideo="dv dv_411 dv50" \
- ffv1 \
- flac \
- flashsv \
- flv \
- adpcm_g726=g726 \
- gif \
- h261 \
- h263="h263 h263p" \
- huffyuv \
- jpegls \
- mjpeg="jpg mjpeg ljpeg" \
- mp2 \
- mpeg1video="mpeg mpeg1b" \
- mpeg2video="mpeg2 mpeg2_422 mpeg2_idct_int mpeg2_ilace mpeg2_ivlc_qprd" \
- mpeg2video="mpeg2thread mpeg2thread_ilace" \
- mpeg4="mpeg4 mpeg4_adap mpeg4_qpel mpeg4_qprd mpeg4adv mpeg4nr" \
- mpeg4="mpeg4thread error rc" \
- msmpeg4v3=msmpeg4 \
- msmpeg4v2 \
- pbm=pbmpipe \
- pcx \
- pgm="pgm pgmpipe" \
- png \
- ppm="ppm ppmpipe" \
- rawvideo="rgb yuv" \
- roq \
- rv10 \
- rv20 \
- sgi \
- snow="snow snowll" \
- svq1 \
- targa=tga \
- tiff \
- wmav1 \
- wmav2 \
- wmv1 \
- wmv2 \
-
test_deps _muxer _demuxer \
aiff \
pcm_alaw=alaw \
@@ -1640,7 +1617,6 @@ test_deps _muxer _demuxer \
wav \
yuv4mpegpipe=yuv4mpeg \
-ac3_fixed_test_deps="ac3_fixed_encoder ac3_decoder"
mpg_test_deps="mpeg1system_muxer mpegps_demuxer"
# default parameters
@@ -1719,7 +1695,7 @@ SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR) $(SLIBNAME)'
AS_O='-o $@'
CC_O='-o $@'
-host_cflags='-D_ISOC99_SOURCE -O3 -g'
+host_cflags='-D_ISOC99_SOURCE -D_XOPEN_SOURCE=600 -O3 -g'
host_libs='-lm'
target_path='$(CURDIR)'
@@ -1784,15 +1760,11 @@ find_tests(){
map "echo ${2}\${v}_test" $(ls "$source_path"/tests/ref/$1 | grep -v '[^-a-z0-9_]')
}
-ACODEC_TESTS=$(find_tests acodec)
-VCODEC_TESTS=$(find_tests vsynth1)
LAVF_TESTS=$(find_tests lavf)
LAVFI_TESTS=$(find_tests lavfi)
SEEK_TESTS=$(find_tests seek seek_)
-ALL_TESTS="$ACODEC_TESTS $VCODEC_TESTS $LAVF_TESTS $LAVFI_TESTS $SEEK_TESTS"
-
-pcm_test_deps=$(map 'echo ${v%_*}_decoder $v' $(filter pcm_* $ENCODER_LIST))
+ALL_TESTS="$LAVF_TESTS $LAVFI_TESTS $SEEK_TESTS"
for n in $COMPONENT_LIST; do
v=$(toupper ${n%s})_LIST
@@ -2279,9 +2251,12 @@ elif enabled ppc; then
74*|ppc74*|powerpc74*)
cpuflags="-mcpu=7400 -mpowerpc-gfxopt"
;;
- g5|970|ppc970|powerpc970|power4*)
+ g5|970|ppc970|powerpc970)
cpuflags="-mcpu=970 -mpowerpc-gfxopt -mpowerpc64"
;;
+ power[3-7]*)
+ cpuflags="-mcpu=$cpu -mpowerpc-gfxopt -mpowerpc64"
+ ;;
cell)
cpuflags="-mcpu=cell"
enable ldbrx
@@ -2423,9 +2398,7 @@ case "$arch" in
;;
x86)
subarch="x86_32"
- check_cc <<EOF && subarch="x86_64"
- int test[(int)sizeof(char*) - 7];
-EOF
+ check_code cc "" "int test[(int)sizeof(char*) - 7]" && subarch="x86_64"
if test "$subarch" = "x86_64"; then
spic=$shared
fi
@@ -2447,7 +2420,7 @@ case $target_os in
SHFLAGS='-shared -Wl,-h,$$(@F)'
enabled x86 && SHFLAGS="-mimpure-text $SHFLAGS"
network_extralibs="-lsocket -lnsl"
- add_cppflags -D__EXTENSIONS__
+ add_cppflags -D__EXTENSIONS__ -D_XOPEN_SOURCE=600
# When using suncc to build, the Solaris linker will mark
# an executable with each instruction set encountered by
# the Solaris assembler. As our libraries contain their own
@@ -2462,7 +2435,6 @@ case $target_os in
oss_outdev_extralibs="-lossaudio"
;;
openbsd)
- enable malloc_aligned
# On OpenBSD 4.5. the compiler does not use PIC unless
# explicitly using -fPIC. Libav builds fine without PIC,
# however the generated executable will not do anything
@@ -2475,17 +2447,14 @@ case $target_os in
oss_outdev_extralibs="-lossaudio"
;;
dragonfly)
- enable malloc_aligned
disable symver
;;
freebsd)
- enable malloc_aligned
;;
bsd/os)
add_extralibs -lpoll -lgnugetopt
;;
darwin)
- enable malloc_aligned
gas="gas-preprocessor.pl $cc"
enabled ppc && add_asflags -force_cpusubtype_ALL
SHFLAGS='-dynamiclib -Wl,-single_module -Wl,-install_name,$(SHLIBDIR)/$(SLIBNAME_WITH_MAJOR),-current_version,$(LIBVERSION),-compatibility_version,$(LIBMAJOR)'
@@ -2508,7 +2477,6 @@ case $target_os in
fi
LIBTARGET=i386
if enabled x86_64; then
- enable malloc_aligned
LIBTARGET="i386:x86-64"
elif enabled arm; then
LIBTARGET=arm-wince
@@ -2844,10 +2812,14 @@ fi
if enabled network; then
check_type "sys/types.h sys/socket.h" socklen_t
check_type netdb.h "struct addrinfo"
+ check_type netinet/in.h "struct group_source_req" -D_BSD_SOURCE
+ check_type netinet/in.h "struct ip_mreq_source" -D_BSD_SOURCE
check_type netinet/in.h "struct ipv6_mreq" -D_DARWIN_C_SOURCE
check_type netinet/in.h "struct sockaddr_in6"
+ check_type poll.h "struct pollfd"
check_type "sys/types.h sys/socket.h" "struct sockaddr_storage"
check_struct "sys/types.h sys/socket.h" "struct sockaddr" sa_len
+ check_header netinet/sctp.h
# Prefer arpa/inet.h over winsock2
if check_header arpa/inet.h ; then
check_func closesocket
@@ -2858,7 +2830,10 @@ if enabled network; then
network_extralibs="-lws2_32"; }
check_type ws2tcpip.h socklen_t
check_type ws2tcpip.h "struct addrinfo"
+ check_type ws2tcpip.h "struct group_source_req"
+ check_type ws2tcpip.h "struct ip_mreq_source"
check_type ws2tcpip.h "struct ipv6_mreq"
+ check_type winsock2.h "struct pollfd"
check_type ws2tcpip.h "struct sockaddr_in6"
check_type ws2tcpip.h "struct sockaddr_storage"
check_struct winsock2.h "struct sockaddr" sa_len
@@ -2876,6 +2851,7 @@ check_func getaddrinfo $network_extralibs
check_func gethrtime
check_func getrusage
check_struct "sys/time.h sys/resource.h" "struct rusage" ru_maxrss
+check_func gettimeofday
check_func inet_aton $network_extralibs
check_func isatty
check_func localtime_r
@@ -2883,6 +2859,7 @@ check_func ${malloc_prefix}memalign && enable memalign
check_func mkstemp
check_func mmap
check_func ${malloc_prefix}posix_memalign && enable posix_memalign
+check_func_headers malloc.h _aligned_malloc && enable aligned_malloc
check_func setrlimit
check_func strerror_r
check_func strptime
@@ -2890,23 +2867,31 @@ check_func strtok_r
check_func sched_getaffinity
check_func sysconf
check_func sysctl
+check_func usleep
check_func_headers io.h setmode
check_lib2 "windows.h psapi.h" GetProcessMemoryInfo -lpsapi
check_func_headers windows.h GetProcessAffinityMask
check_func_headers windows.h GetProcessTimes
+check_func_headers windows.h GetSystemTimeAsFileTime
check_func_headers windows.h MapViewOfFile
+check_func_headers windows.h Sleep
check_func_headers windows.h VirtualAlloc
check_header dlfcn.h
+check_header dxva.h
check_header dxva2api.h
+check_header io.h
check_header malloc.h
check_header poll.h
check_header sys/mman.h
check_header sys/param.h
check_header sys/resource.h
check_header sys/select.h
+check_header sys/time.h
+check_header unistd.h
check_header vdpau/vdpau.h
check_header vdpau/vdpau_x11.h
+check_header windows.h
check_header X11/extensions/XvMClib.h
disabled zlib || check_lib zlib.h zlibVersion -lz || disable zlib
@@ -2946,8 +2931,11 @@ done
check_lib math.h sin -lm && LIBM="-lm"
enabled vaapi && require vaapi va/va.h vaInitialize -lva
+check_mathfunc cbrtf
check_mathfunc exp2
check_mathfunc exp2f
+check_mathfunc isinf
+check_mathfunc isnan
check_mathfunc llrint
check_mathfunc llrintf
check_mathfunc log2
@@ -2966,8 +2954,8 @@ enabled gnutls && require_pkg_config gnutls gnutls/gnutls.h gnutls_global_in
enabled libfaac && require2 libfaac "stdint.h faac.h" faacEncGetVersion -lfaac
enabled libfreetype && require_pkg_config freetype2 "ft2build.h freetype/freetype.h" FT_Init_FreeType
enabled libgsm && require libgsm gsm/gsm.h gsm_create -lgsm
+enabled libilbc && require libilbc ilbc.h WebRtcIlbcfix_InitDecode -lilbc
enabled libmp3lame && require "libmp3lame >= 3.98.3" lame/lame.h lame_set_VBR_quality -lmp3lame
-enabled libnut && require libnut libnut.h nut_demuxer_init -lnut
enabled libopencore_amrnb && require libopencore_amrnb opencore-amrnb/interf_dec.h Decoder_Interface_init -lopencore-amrnb
enabled libopencore_amrwb && require libopencore_amrwb opencore-amrwb/dec_if.h D_IF_init -lopencore-amrwb
enabled libopencv && require_pkg_config opencv opencv/cv.h cvCreateImageHeader
@@ -3038,7 +3026,8 @@ check_header soundcard.h
enabled_any alsa_indev alsa_outdev && check_lib2 alsa/asoundlib.h snd_pcm_htimestamp -lasound
-enabled jack_indev && check_lib2 jack/jack.h jack_client_open -ljack
+enabled jack_indev && check_lib2 jack/jack.h jack_client_open -ljack &&
+ check_func jack_port_get_latency_range -ljack
enabled_any sndio_indev sndio_outdev && check_lib2 sndio.h sio_open -lsndio
@@ -3188,7 +3177,7 @@ check_deps $CONFIG_LIST \
enabled asm || { arch=c; disable $ARCH_LIST $ARCH_EXT_LIST; }
-! enabled_any memalign posix_memalign malloc_aligned &&
+! enabled_any memalign posix_memalign aligned_malloc &&
enabled_any $need_memalign && enable memalign_hack
echo "install prefix $prefix"
@@ -3255,8 +3244,8 @@ echo "libcdio support ${libcdio-no}"
echo "libdc1394 support ${libdc1394-no}"
echo "libfaac enabled ${libfaac-no}"
echo "libgsm enabled ${libgsm-no}"
+echo "libilbc enabled ${libilbc-no}"
echo "libmp3lame enabled ${libmp3lame-no}"
-echo "libnut enabled ${libnut-no}"
echo "libopencore-amrnb support ${libopencore_amrnb-no}"
echo "libopencore-amrwb support ${libopencore_amrwb-no}"
echo "libopencv support ${libopencv-no}"
@@ -3372,26 +3361,26 @@ SLIB_INSTALL_NAME=${SLIB_INSTALL_NAME}
SLIB_INSTALL_LINKS=${SLIB_INSTALL_LINKS}
SLIB_INSTALL_EXTRA_LIB=${SLIB_INSTALL_EXTRA_LIB}
SLIB_INSTALL_EXTRA_SHLIB=${SLIB_INSTALL_EXTRA_SHLIB}
-SAMPLES:=${samples:-\$(FATE_SAMPLES)}
+SAMPLES:=${samples:-\$(LIBAV_SAMPLES)}
EOF
get_version(){
- name=$1
- file=$source_path/$2
+ lcname=$1
+ name=$(toupper $lcname)
+ file=$source_path/$lcname/version.h
eval $(grep "#define ${name}_VERSION_M" "$file" | awk '{ print $2"="$3 }')
eval ${name}_VERSION=\$${name}_VERSION_MAJOR.\$${name}_VERSION_MINOR.\$${name}_VERSION_MICRO
- lcname=$(tolower $name)
eval echo "${lcname}_VERSION=\$${name}_VERSION" >> config.mak
eval echo "${lcname}_VERSION_MAJOR=\$${name}_VERSION_MAJOR" >> config.mak
}
-get_version LIBAVCODEC libavcodec/version.h
-get_version LIBAVDEVICE libavdevice/avdevice.h
-get_version LIBAVFILTER libavfilter/version.h
-get_version LIBAVFORMAT libavformat/version.h
-get_version LIBAVRESAMPLE libavresample/version.h
-get_version LIBAVUTIL libavutil/avutil.h
-get_version LIBSWSCALE libswscale/swscale.h
+get_version libavcodec
+get_version libavdevice
+get_version libavfilter
+get_version libavformat
+get_version libavresample
+get_version libavutil
+get_version libswscale
cat > $TMPH <<EOF
/* Automatically generated by configure - do not modify! */
@@ -3411,15 +3400,6 @@ EOF
test -n "$malloc_prefix" &&
echo "#define MALLOC_PREFIX $malloc_prefix" >>$TMPH
-if enabled small || disabled optimizations; then
- echo "#undef av_always_inline" >> $TMPH
- if enabled small; then
- echo "#define av_always_inline inline" >> $TMPH
- else
- echo "#define av_always_inline av_unused" >> $TMPH
- fi
-fi
-
if enabled yasm; then
append config_files $TMPASM
printf '' >$TMPASM
@@ -3432,8 +3412,6 @@ print_config CONFIG_ "$config_files" $CONFIG_LIST \
$ALL_COMPONENTS \
cat >>config.mak <<EOF
-ACODEC_TESTS=$(print_enabled -n _test $ACODEC_TESTS)
-VCODEC_TESTS=$(print_enabled -n _test $VCODEC_TESTS)
LAVF_TESTS=$(print_enabled -n _test $LAVF_TESTS)
LAVFI_TESTS=$(print_enabled -n _test $LAVFI_TESTS)
SEEK_TESTS=$(print_enabled -n _test $SEEK_TESTS)
diff --git a/doc/APIchanges b/doc/APIchanges
index 4d3810a..990e36e 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -4,22 +4,77 @@ since the last major version increase.
The last version increases were:
libavcodec: 2012-01-27
libavdevice: 2011-04-18
-libavfilter: 2011-04-18
+libavfilter: 2012-06-22
libavformat: 2012-01-27
-libavresample: 2012-xx-xx
+libavresample: 2012-04-24
libswscale: 2011-06-20
libavutil: 2011-04-18
API changes, most recent first:
-2012-04-25 - xxxxxxx - lavu 51.29.0 - cpu.h
+2012-06-22 - xxxxxxx - lavu 51.34.0
+ Add av_usleep()
+
+2012-06-20 - ae0a301 - lavu 51.33.0
+ Move av_gettime() to libavutil, add libavutil/time.h
+
+2012-xx-xx - xxxxxxx - lavr 0.0.3
+ Add a parameter to avresample_build_matrix() for Dolby/DPLII downmixing.
+
+2012-xx-xx - xxxxxxx - lavfi 2.23.0 - avfilter.h
+ Add AVFilterContext.nb_inputs/outputs. Deprecate
+ AVFilterContext.input/output_count.
+
+2012-xx-xx - xxxxxxx - lavfi 2.22.0 - avfilter.h
+ Add avfilter_pad_get_type() and avfilter_pad_get_name(). Those
+ should now be used instead of accessing AVFilterPad members
+ directly.
+
+2012-xx-xx - xxxxxxx - lavu 51.32.0 - audioconvert.h
+ Add av_get_channel_layout_channel_index(), av_get_channel_name()
+ and av_channel_layout_extract_channel().
+
+2012-05-25 - e0e0793 - lavu 51.31.0 - opt.h
+ Add av_opt_set_bin()
+
+2012-05-xx - xxxxxxx - lavf 54.3.0
+ Add AVFMT_TS_NONSTRICT format flag to indicate that a muxer supports
+ non-increasing monotone timestamps.
+
+2012-05-15 - lavfi 2.17.0
+ Add support for audio filters
+ ac71230/a2cd9be - add video/audio buffer sink in a new installed
+ header buffersink.h
+ 720c6b7 - add av_buffersrc_write_frame(), deprecate
+ av_vsrc_buffer_add_frame()
+ ab16504 - add avfilter_copy_buf_props()
+ 9453c9e - add extended_data to AVFilterBuffer
+ 1b8c927 - add avfilter_get_audio_buffer_ref_from_arrays()
+
+2012-05-09 - lavu 51.30.0 - samplefmt.h
+ 142e740 - add av_samples_copy()
+ 6d7f617 - add av_samples_set_silence()
+
+2012-05-09 - a5117a2 - lavc 54.13.1
+ For audio formats with fixed frame size, the last frame
+ no longer needs to be padded with silence, libavcodec
+ will handle this internally (effectively all encoders
+ behave as if they had CODEC_CAP_SMALL_LAST_FRAME set).
+
+2012-05-07 - 828bd08 - lavc 54.13.0 - avcodec.h
+ Add sample_rate and channel_layout fields to AVFrame.
+
+2012-05-01 - 4010d72 - lavr 0.0.1
+ Change AV_MIX_COEFF_TYPE_Q6 to AV_MIX_COEFF_TYPE_Q8.
+
+2012-04-25 - 3527a73 - lavu 51.29.0 - cpu.h
Add av_parse_cpu_flags()
-2012-xx-xx - xxxxxxx - lavr 0.0.0
+2012-04-24 - c8af852 - lavr 0.0.0
Add libavresample audio conversion library
-2012-xx-xx - xxxxxxx - lavu 51.28.0 - audio_fifo.h
+2012-04-20 - 0c0d1bc - lavu 51.28.0 - audio_fifo.h
Add audio FIFO functions:
av_audio_fifo_free()
av_audio_fifo_alloc()
@@ -31,14 +86,14 @@ API changes, most recent first:
av_audio_fifo_size()
av_audio_fifo_space()
-2012-xx-xx - xxxxxxx - lavfi 2.16.0 - avfiltergraph.h
- Add avfilter_graph_parse2(), avfilter_inout_alloc() and
- avfilter_inout_free() functions.
+2012-04-14 - lavfi 2.16.0 - avfiltergraph.h
+ d7bcc71 Add avfilter_graph_parse2().
+ 91d3cbe Add avfilter_inout_alloc() and avfilter_inout_free().
-2012-xx-xx - xxxxxxx - lavu 51.27.0 - samplefmt.h
+2012-04-08 - 4d693b0 - lavu 51.27.0 - samplefmt.h
Add av_get_packed_sample_fmt() and av_get_planar_sample_fmt()
-2012-xx-xx - xxxxxxx - lavu 51.26.0 - audioconvert.h
+2012-04-05 - 5cc51a5 - lavu 51.26.0 - audioconvert.h
Add av_get_default_channel_layout()
2012-03-06 - 4d851f8 - lavu 51.25.0 - cpu.h
diff --git a/doc/avconv.texi b/doc/avconv.texi
index bf72c4c..776a326 100644
--- a/doc/avconv.texi
+++ b/doc/avconv.texi
@@ -79,6 +79,126 @@ The format option may be needed for raw input files.
@c man end DESCRIPTION
+ at chapter Detailed description
+ at c man begin DETAILED DESCRIPTION
+
+The transcoding process in @command{avconv} for each output can be described by
+the following diagram:
+
+ at example
+ _______ ______________ _________ ______________ ________
+| | | | | | | | | |
+| input | demuxer | encoded data | decoder | decoded | encoder | encoded data | muxer | output |
+| file | ---------> | packets | ---------> | frames | ---------> | packets | -------> | file |
+|_______| |______________| |_________| |______________| |________|
+
+ at end example
+
+ at command{avconv} calls the libavformat library (containing demuxers) to read
+input files and get packets containing encoded data from them. When there are
+multiple input files, @command{avconv} tries to keep them synchronized by
+tracking lowest timestamp on any active input stream.
+
+Encoded packets are then passed to the decoder (unless streamcopy is selected
+for the stream, see further for a description). The decoder produces
+uncompressed frames (raw video/PCM audio/...) which can be processed further by
+filtering (see next section). After filtering the frames are passed to the
+encoder, which encodes them and outputs encoded packets again. Finally those are
+passed to the muxer, which writes the encoded packets to the output file.
+
+ at section Filtering
+Before encoding, @command{avconv} can process raw audio and video frames using
+filters from the libavfilter library. Several chained filters form a filter
+graph. @command{avconv} distinguishes between two types of filtergraphs -
+simple and complex.
+
+ at subsection Simple filtergraphs
+Simple filtergraphs are those that have exactly one input and output, both of
+the same type. In the above diagram they can be represented by simply inserting
+an additional step between decoding and encoding:
+
+ at example
+ _________ __________ ______________
+| | | | | |
+| decoded | simple filtergraph | filtered | encoder | encoded data |
+| frames | -------------------> | frames | ---------> | packets |
+|_________| |__________| |______________|
+
+ at end example
+
+Simple filtergraphs are configured with the per-stream @option{-filter} option
+(with @option{-vf} and @option{-af} aliases for video and audio respectively).
+A simple filtergraph for video can look for example like this:
+
+ at example
+ _______ _____________ _______ _____ ________
+| | | | | | | | | |
+| input | ---> | deinterlace | ---> | scale | ---> | fps | ---> | output |
+|_______| |_____________| |_______| |_____| |________|
+
+ at end example
+
+Note that some filters change frame properties but not frame contents. E.g. the
+ at code{fps} filter in the example above changes number of frames, but does not
+touch the frame contents. Another example is the @code{setpts} filter, which
+only sets timestamps and otherwise passes the frames unchanged.
+
+ at subsection Complex filtergraphs
+Complex filtergraphs are those which cannot be described as simply a linear
+processing chain applied to one stream. This is the case e.g. when the graph has
+more than one input and/or output, or when output stream type is different from
+input. They can be represented with the following diagram:
+
+ at example
+ _________
+| |
+| input 0 |\ __________
+|_________| \ | |
+ \ _________ /| output 0 |
+ \ | | / |__________|
+ _________ \| complex | /
+| | | |/
+| input 1 |---->| filter |\
+|_________| | | \ __________
+ /| graph | \ | |
+ / | | \| output 1 |
+ _________ / |_________| |__________|
+| | /
+| input 2 |/
+|_________|
+
+ at end example
+
+Complex filtergraphs are configured with the @option{-filter_complex} option.
+Note that this option is global, since a complex filtergraph by its nature
+cannot be unambiguously associated with a single stream or file.
+
+A trivial example of a complex filtergraph is the @code{overlay} filter, which
+has two video inputs and one video output, containing one video overlaid on top
+of the other. Its audio counterpart is the @code{amix} filter.
+
+ at section Stream copy
+Stream copy is a mode selected by supplying the @code{copy} parameter to the
+ at option{-codec} option. It makes @command{avconv} omit the decoding and encoding
+step for the specified stream, so it does only demuxing and muxing. It is useful
+for changing the container format or modifying container-level metadata. The
+diagram above will in this case simplify to this:
+
+ at example
+ _______ ______________ ________
+| | | | | |
+| input | demuxer | encoded data | muxer | output |
+| file | ---------> | packets | -------> | file |
+|_______| |______________| |________|
+
+ at end example
+
+Since there is no decoding or encoding, it is very fast and there is no quality
+loss. However it might not work in some cases because of many factors. Applying
+filters is obviously also impossible, since filters work on uncompressed data.
+
+ at c man end DETAILED DESCRIPTION
+
@chapter Stream selection
@c man begin STREAM SELECTION
@@ -257,11 +377,28 @@ attachments.
@item -vframes @var{number} (@emph{output})
Set the number of video frames to record. This is an alias for @code{-frames:v}.
@item -r[:@var{stream_specifier}] @var{fps} (@emph{input/output,per-stream})
-Set frame rate (Hz value, fraction or abbreviation), (default = 25). For output
-streams implies @code{-vsync cfr}.
+Set frame rate (Hz value, fraction or abbreviation).
+
+As an input option, ignore any timestamps stored in the file and instead
+generate timestamps assuming constant frame rate @var{fps}.
+
+As an output option, duplicate or drop input frames to achieve constant output
+frame rate @var{fps} (note that this actually causes the @code{fps} filter to be
+inserted to the end of the corresponding filtergraph).
+
@item -s[:@var{stream_specifier}] @var{size} (@emph{input/output,per-stream})
-Set frame size. The format is @samp{wxh} (default - same as source).
-The following abbreviations are recognized:
+Set frame size.
+
+As an input option, this is a shortcut for the @option{video_size} private
+option, recognized by some demuxers for which the frame size is either not
+stored in the file or is configurable -- e.g. raw video or video grabbers.
+
+As an output option, this inserts the @code{scale} video filter to the
+ at emph{end} of the corresponding filtergraph. Please use the @code{scale} filter
+directly to insert it at the beginning or some other place.
+
+The format is @samp{wxh} (default - same as source). The following
+abbreviations are recognized:
@table @samp
@item sqcif
128x96
@@ -435,6 +572,11 @@ Set the audio codec. This is an alias for @code{-codec:a}.
@item -sample_fmt[:@var{stream_specifier}] @var{sample_fmt} (@emph{output,per-stream})
Set the audio sample format. Use @code{-sample_fmts} to get a list
of supported sample formats.
+ at item -af @var{filter_graph} (@emph{output})
+ at var{filter_graph} is a description of the filter graph to apply to
+the input audio.
+Use the option "-filters" to show all the available filters (including
+also sources and sinks). This is an alias for @code{-filter:a}.
@end table
@section Advanced Audio options:
@@ -605,6 +747,7 @@ Audio sync method. "Stretches/squeezes" the audio stream to match the timestamps
the parameter is the maximum samples per second by which the audio is changed.
-async 1 is a special case where only the start of the audio stream is corrected
without any later correction.
+This option has been deprecated. Use the @code{asyncts} audio filter instead.
@item -copyts
Copy timestamps from input to output.
@item -copytb
@@ -712,7 +855,7 @@ frame rate or decrease the frame size.
@item
If your computer is not fast enough, you can speed up the
compression at the expense of the compression ratio. You can use
-'-me zero' to speed up motion estimation, and '-intra' to disable
+'-me zero' to speed up motion estimation, and '-g 0' to disable
motion estimation completely (you have only I-frames, which means it
is about as good as JPEG compression).
diff --git a/doc/avprobe.texi b/doc/avprobe.texi
index 6b2c800..7e6fedf 100644
--- a/doc/avprobe.texi
+++ b/doc/avprobe.texi
@@ -41,19 +41,8 @@ Options are used to list some of the formats supported by avprobe or
for specifying which information to display, and for setting how
avprobe will show it.
-avprobe output is designed to be easily parsable by a textual filter,
-and consists of one or more sections of the form:
- at example
-[SECTION]
-key1=val1
-...
-keyN=valN
-[/SECTION]
- at end example
-
-Metadata tags stored in the container or in the streams are recognized
-and printed in the corresponding "FORMAT" or "STREAM" section, and
-are prefixed by the string "TAG:".
+avprobe output is designed to be easily parsable by any INI or JSON
+parsers.
@c man end
@@ -69,6 +58,19 @@ are prefixed by the string "TAG:".
@item -f @var{format}
Force format to use.
+ at item -of @var{formatter}
+Use a specific formatter to output the document. The following
+formatters are available
+ at table @option
+ at item ini
+
+ at item json
+
+ at item old
+Pseudo-INI format that used to be the only one available in old
+avprobe versions.
+ at end table
+
@item -unit
Show the unit of the displayed values.
@@ -94,6 +96,11 @@ stream.
All the container format information is printed within a section with
name "FORMAT".
+ at item -show_format_entry @var{name}
+Like @option{-show_format}, but only prints the specified entry of the
+container format information, rather than all. This option may be given more
+than once, then all specified entries will be shown.
+
@item -show_packets
Show information about each packet contained in the input multimedia
stream.
diff --git a/doc/developer.texi b/doc/developer.texi
index de64239..d36f53f 100644
--- a/doc/developer.texi
+++ b/doc/developer.texi
@@ -73,6 +73,10 @@ const char *avfilter_configuration(void)
@}
@end example
@item
+Do not check for NULL values by comparison, @samp{if (p)} and
+ at samp{if (!p)} are correct; @samp{if (p == NULL)} and @samp{if (p != NULL)}
+are not.
+ at item
In case of a single-statement if, no curly braces are required:
@example
if (!pic || !picref)
@@ -428,9 +432,7 @@ send a reminder by email. Your patch should eventually be dealt with.
@enumerate
@item
- Does @code{make fate} pass with the patch applied?
- at item
- Does @code{make checkheaders} pass with the patch applied?
+ Does @code{make check} pass with the patch applied?
@item
Is the patch against latest Libav git master branch?
@item
@@ -486,6 +488,10 @@ send a reminder by email. Your patch should eventually be dealt with.
@item
Lines with similar content should be aligned vertically when doing so
improves readability.
+ at item
+ Make sure you check the return values of function and return appropriate
+ error codes. Especially memory allocation functions like @code{malloc()}
+ are notoriously left unchecked, which is a serious problem.
@end enumerate
@section Patch review process
diff --git a/doc/eval.texi b/doc/eval.texi
index 7f8f365..e1fd7ee 100644
--- a/doc/eval.texi
+++ b/doc/eval.texi
@@ -34,6 +34,8 @@ The following functions are available:
@item abs(x)
@item squish(x)
@item gauss(x)
+ at item isinf(x)
+Return 1.0 if @var{x} is +/-INFINITY, 0.0 otherwise.
@item isnan(x)
Return 1.0 if @var{x} is NAN, 0.0 otherwise.
diff --git a/doc/fate.texi b/doc/fate.texi
index c1011e7..975f40a 100644
--- a/doc/fate.texi
+++ b/doc/fate.texi
@@ -26,9 +26,12 @@ that is provided separately from the actual source distribution.
To inform the build system about the testsuite location, pass
@option{--samples=<path to the samples>} to @command{configure} or set the
- at var{SAMPLES} Make variable or the @var{FATE_SAMPLES} environment variable
+ at var{SAMPLES} Make variable or the @var{LIBAV_SAMPLES} environment variable
to a suitable value.
+To use a custom wrapper to run the test, pass @option{--target-exec} to
+ at command{configure} or set the @var{TARGET_EXEC} Make variable.
+
The dataset is available through @command{rsync}, is possible to fetch
the current sample using the straight rsync command or through a specific
@ref{Makefile target}.
@@ -57,7 +60,7 @@ Shortcut to download the fate test samples to the specified testsuite location.
Run the FATE test suite (requires the fate-suite dataset).
@end table
- at section Fate Makefile variables
+ at section FATE Makefile variables
@table @option
@item V
Verbosity level, can be set to 0, 1 or 2.
@@ -75,8 +78,13 @@ meaning only while running the regression tests.
@item THREADS
Specify how many threads to use while running regression tests, it is
quite useful to detect thread-related regressions.
+ at item THREAD_TYPE
+Specify which threading strategy test, either @var{slice} or @var{frame},
+by default @var{slice+frame}
@item CPUFLAGS
Specify a mask to be applied to autodetected CPU flags.
+ at item TARGET_EXEC
+Specify or override the wrapper used to run the tests.
@end table
@example
@@ -87,8 +95,9 @@ Specify a mask to be applied to autodetected CPU flags.
In order to automatically testing specific configurations, e.g. multiple
compilers, @command{tests/fate.sh} is provided.
-This shell script builds Libav, runs the regression tests and prepares a
-report that can be sent to @url{fate.libav.org} or directly examined locally.
+This shell script builds Libav, runs the regression tests and prepares
+a report that can be sent to @url{http://fate.libav.org/} or directly
+examined locally.
@section Testing Profiles
The configuration file passed to @command{fate.sh} is shell scripts as well.
@@ -130,6 +139,11 @@ makeopts= # extra options passed to 'make'
# stdout, defaults to 'tar c'
@end example
+ at section Special Instances
+The @var{TARGET_EXEC} option provides a way to run FATE wrapped in
+ at command{valgrind}, @command{qemu-user} or @command{wine} or on remote targets
+through @command{ssh}.
+
@section Submitting Reports
In order to send reports you need to create an @command{ssh} key and send it
to @email{root@@libav.org}.
diff --git a/doc/filters.texi b/doc/filters.texi
index b012dc7..d3543b3 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -107,10 +107,207 @@ build.
Below is a description of the currently available audio filters.
+ at section aformat
+
+Convert the input audio to one of the specified formats. The framework will
+negotiate the most appropriate format to minimize conversions.
+
+The filter accepts the following named parameters:
+ at table @option
+
+ at item sample_fmts
+A comma-separated list of requested sample formats.
+
+ at item sample_rates
+A comma-separated list of requested sample rates.
+
+ at item channel_layouts
+A comma-separated list of requested channel layouts.
+
+ at end table
+
+If a parameter is omitted, all values are allowed.
+
+For example to force the output to either unsigned 8-bit or signed 16-bit stereo:
+ at example
+aformat=sample_fmts\=u8\,s16:channel_layouts\=stereo
+ at end example
+
+ at section amix
+
+Mixes multiple audio inputs into a single output.
+
+For example
+ at example
+avconv -i INPUT1 -i INPUT2 -i INPUT3 -filter_complex amix=inputs=3:duration=first:dropout_transition=3 OUTPUT
+ at end example
+will mix 3 input audio streams to a single output with the same duration as the
+first input and a dropout transition time of 3 seconds.
+
+The filter accepts the following named parameters:
+ at table @option
+
+ at item inputs
+Number of inputs. If unspecified, it defaults to 2.
+
+ at item duration
+How to determine the end-of-stream.
+ at table @option
+
+ at item longest
+Duration of longest input. (default)
+
+ at item shortest
+Duration of shortest input.
+
+ at item first
+Duration of first input.
+
+ at end table
+
+ at item dropout_transition
+Transition time, in seconds, for volume renormalization when an input
+stream ends. The default value is 2 seconds.
+
+ at end table
+
@section anull
Pass the audio source unchanged to the output.
+ at section asplit
+
+Split input audio into several identical outputs.
+
+The filter accepts a single parameter which specifies the number of outputs. If
+unspecified, it defaults to 2.
+
+For example
+ at example
+avconv -i INPUT -filter_complex asplit=5 OUTPUT
+ at end example
+will create 5 copies of the input audio.
+
+ at section asyncts
+Synchronize audio data with timestamps by squeezing/stretching it and/or
+dropping samples/adding silence when needed.
+
+The filter accepts the following named parameters:
+ at table @option
+
+ at item compensate
+Enable stretching/squeezing the data to make it match the timestamps.
+
+ at item min_delta
+Minimum difference between timestamps and audio data (in seconds) to trigger
+adding/dropping samples.
+
+ at item max_comp
+Maximum compensation in samples per second.
+
+ at end table
+
+ at section channelsplit
+Split each channel in input audio stream into a separate output stream.
+
+This filter accepts the following named parameters:
+ at table @option
+ at item channel_layout
+Channel layout of the input stream. Default is "stereo".
+ at end table
+
+For example, assuming a stereo input MP3 file
+ at example
+avconv -i in.mp3 -filter_complex channelsplit out.mkv
+ at end example
+will create an output Matroska file with two audio streams, one containing only
+the left channel and the other the right channel.
+
+To split a 5.1 WAV file into per-channel files
+ at example
+avconv -i in.wav -filter_complex
+'channelsplit=channel_layout=5.1[FL][FR][FC][LFE][SL][SR]'
+-map '[FL]' front_left.wav -map '[FR]' front_right.wav -map '[FC]'
+front_center.wav -map '[LFE]' lfe.wav -map '[SL]' side_left.wav -map '[SR]'
+side_right.wav
+ at end example
+
+ at section channelmap
+Remap input channels to new locations.
+
+This filter accepts the following named parameters:
+ at table @option
+ at item channel_layout
+Channel layout of the output stream.
+
+ at item map
+Map channels from input to output. The argument is a comma-separated list of
+mappings, each in the @code{@var{in_channel}- at var{out_channel}} or
+ at var{in_channel} form. @var{in_channel} can be either the name of the input
+channel (e.g. FL for front left) or its index in the input channel layout.
+ at var{out_channel} is the name of the output channel or its index in the output
+channel layout. If @var{out_channel} is not given then it is implicitly an
+index, starting with zero and increasing by one for each mapping.
+ at end table
+
+If no mapping is present, the filter will implicitly map input channels to
+output channels preserving index.
+
+For example, assuming a 5.1+downmix input MOV file
+ at example
+avconv -i in.mov -filter 'channelmap=map=DL-FL\,DR-FR' out.wav
+ at end example
+will create an output WAV file tagged as stereo from the downmix channels of
+the input.
+
+To fix a 5.1 WAV improperly encoded in AAC's native channel order
+ at example
+avconv -i in.wav -filter 'channelmap=1\,2\,0\,5\,3\,4:channel_layout=5.1' out.wav
+ at end example
+
+ at section join
+Join multiple input streams into one multi-channel stream.
+
+The filter accepts the following named parameters:
+ at table @option
+
+ at item inputs
+Number of input streams. Defaults to 2.
+
+ at item channel_layout
+Desired output channel layout. Defaults to stereo.
+
+ at item map
+Map channels from inputs to output. The argument is a comma-separated list of
+mappings, each in the @code{@var{input_idx}. at var{in_channel}- at var{out_channel}}
+form. @var{input_idx} is the 0-based index of the input stream. @var{in_channel}
+can be either the name of the input channel (e.g. FL for front left) or its
+index in the specified input stream. @var{out_channel} is the name of the output
+channel.
+ at end table
+
+The filter will attempt to guess the mappings when those are not specified
+explicitly. It does so by first trying to find an unused matching input channel
+and if that fails it picks the first unused input channel.
+
+E.g. to join 3 inputs (with properly set channel layouts)
+ at example
+avconv -i INPUT1 -i INPUT2 -i INPUT3 -filter_complex join=inputs=3 OUTPUT
+ at end example
+
+To build a 5.1 output from 6 single-channel streams:
+ at example
+avconv -i fl -i fr -i fc -i sl -i sr -i lfe -filter_complex
+'join=inputs=6:channel_layout=5.1:map=0.0-FL\,1.0-FR\,2.0-FC\,3.0-SL\,4.0-SR\,5.0-LFE'
+out
+ at end example
+
+ at section resample
+Convert the audio sample format, sample rate and channel layout. This filter is
+not meant to be used directly, it is inserted automatically by libavfilter
+whenever conversion is needed. Use the @var{aformat} filter to force a specific
+conversion.
+
@c man end AUDIO FILTERS
@chapter Audio Sources
@@ -145,6 +342,33 @@ anullsrc=48000:4
anullsrc=48000:mono
@end example
+ at section abuffer
+Buffer audio frames, and make them available to the filter chain.
+
+This source is not intended to be part of user-supplied graph descriptions but
+for insertion by calling programs through the interface defined in
+ at file{libavfilter/buffersrc.h}.
+
+It accepts the following named parameters:
+ at table @option
+
+ at item time_base
+Timebase which will be used for timestamps of submitted frames. It must be
+either a floating-point number or in @var{numerator}/@var{denominator} form.
+
+ at item sample_rate
+Audio sample rate.
+
+ at item sample_fmt
+Name of the sample format, as returned by @code{av_get_sample_fmt_name()}.
+
+ at item channel_layout
+Channel layout of the audio data, in the form that can be accepted by
+ at code{av_get_channel_layout()}.
+ at end table
+
+All the parameters need to be explicitly defined.
+
@c man end AUDIO SOURCES
@chapter Audio Sinks
@@ -158,6 +382,13 @@ Null audio sink, do absolutely nothing with the input audio. It is
mainly useful as a template and to be employed in analysis / debugging
tools.
+ at section abuffersink
+This sink is intended for programmatic use. Frames that arrive on this sink can
+be retrieved by the calling program using the interface defined in
+ at file{libavfilter/buffersink.h}.
+
+This filter accepts no parameters.
+
@c man end AUDIO SINKS
@chapter Video Filters
@@ -729,6 +960,19 @@ format=yuv420p
format=yuv420p:yuv444p:yuv410p
@end example
+ at section fps
+
+Convert the video to specified constant framerate by duplicating or dropping
+frames as necessary.
+
+This filter accepts the following named parameters:
+ at table @option
+
+ at item fps
+Desired output framerate.
+
+ at end table
+
@anchor{frei0r}
@section frei0r
@@ -1666,6 +1910,19 @@ not specified it will use the default value of 16.
Adding this in the beginning of filter chains should make filtering
faster due to better use of the memory cache.
+ at section split
+
+Split input video into several identical outputs.
+
+The filter accepts a single parameter which specifies the number of outputs. If
+unspecified, it defaults to 2.
+
+For example
+ at example
+avconv -i INPUT -filter_complex split=5 OUTPUT
+ at end example
+will create 5 copies of the input video.
+
@section transpose
Transpose rows with columns in the input video and optionally flip it.
@@ -2065,6 +2322,14 @@ will generate a video with a duration of 5.3 seconds, with size
Below is a description of the currently available video sinks.
+ at section buffersink
+
+Buffer video frames, and make them available to the end of the filter
+graph.
+
+This sink is intended for a programmatic use through the interface defined in
+ at file{libavfilter/buffersink.h}.
+
@section nullsink
Null video sink, do absolutely nothing with the input video. It is
diff --git a/doc/general.texi b/doc/general.texi
index 090e4c5..4ea47b4 100644
--- a/doc/general.texi
+++ b/doc/general.texi
@@ -13,7 +13,8 @@
Libav can be hooked up with a number of external libraries to add support
for more formats. None of them are used by default, their use has to be
-explicitly requested by passing the appropriate flags to @file{./configure}.
+explicitly requested by passing the appropriate flags to
+ at command{./configure}.
@section OpenCORE and VisualOn libraries
@@ -84,6 +85,17 @@ x264 is under the GNU Public License Version 2 or later
details), you must upgrade Libav's license to GPL in order to use it.
@end float
+ at section libilbc
+
+iLBC is a narrowband speech codec that has been made freely available
+by Google as part of the WebRTC project. libilbc is a packaging friendly
+copy of the iLBC codec. Libav can make use of the libilbc library for
+iLBC encoding and decoding.
+
+Go to @url{https://github.com/dekkers/libilbc} and follow the instructions for
+installing the library. Then pass @code{--enable-libilbc} to configure to
+enable it.
+
@chapter Supported File Formats and Codecs
@@ -172,6 +184,7 @@ library:
@item IEC61937 encapsulation @tab X @tab X
@item IFF @tab @tab X
@tab Interchange File Format
+ at item iLBC @tab X @tab X
@item Interplay MVE @tab @tab X
@tab Format used in various Interplay computer games.
@item IV8 @tab @tab X
@@ -518,7 +531,11 @@ following image formats are supported:
@item LCL (LossLess Codec Library) ZLIB @tab E @tab E
@item LOCO @tab @tab X
@item lossless MJPEG @tab X @tab X
+ at item Microsoft ATC Screen @tab @tab X
+ @tab Also known as Microsoft Screen 3.
@item Microsoft RLE @tab @tab X
+ at item Microsoft Screen 1 @tab @tab X
+ @tab Also known as Windows Media Video V7 Screen.
@item Microsoft Video 1 @tab @tab X
@item Mimic @tab @tab X
@tab Used in MSN Messenger Webcam streams.
@@ -705,6 +722,9 @@ following image formats are supported:
@tab encoding supported through external library libgsm
@item GSM Microsoft variant @tab E @tab X
@tab encoding supported through external library libgsm
+ at item IAC (Indeo Audio Coder) @tab @tab X
+ at item iLBC (Internet Low Bitrate Codec) @tab E @tab E
+ @tab encoding and decoding supported through external library libilbc
@item IMC (Intel Music Coder) @tab @tab X
@item MACE (Macintosh Audio Compression/Expansion) 3:1 @tab @tab X
@item MACE (Macintosh Audio Compression/Expansion) 6:1 @tab @tab X
@@ -802,19 +822,30 @@ performance on systems without hardware floating point support).
@multitable @columnfractions .4 .1
@item Name @tab Support
- at item Apple HTTP Live Streaming @tab X
@item file @tab X
@item Gopher @tab X
+ at item HLS @tab X
@item HTTP @tab X
- at item MMS @tab X
+ at item HTTPS @tab X
+ at item MMSH @tab X
+ at item MMST @tab X
@item pipe @tab X
+ at item RTMP @tab X
+ at item RTMPE @tab E
+ at item RTMPS @tab E
+ at item RTMPT @tab X
+ at item RTMPTE @tab E
@item RTP @tab X
+ at item SCTP @tab X
@item TCP @tab X
+ at item TLS @tab X
@item UDP @tab X
@end multitable
@code{X} means that the protocol is supported.
+ at code{E} means that support is provided through an external library.
+
@section Input/Output Devices
diff --git a/doc/git-howto.texi b/doc/git-howto.texi
index 4d3e235..938e165 100644
--- a/doc/git-howto.texi
+++ b/doc/git-howto.texi
@@ -346,6 +346,61 @@ git checkout -b svn_23456 $SHA1
where @var{$SHA1} is the commit hash from the @command{git log} output.
+
+ at chapter pre-push checklist
+
+Once you have a set of commits that you feel are ready for pushing,
+work through the following checklist to doublecheck everything is in
+proper order. This list tries to be exhaustive. In case you are just
+pushing a typo in a comment, some of the steps may be unnecessary.
+Apply your common sense, but if in doubt, err on the side of caution.
+
+First make sure your Git repository is on a branch that is a direct
+descendant of the Libav master branch, which is the only one from which
+pushing to Libav is possible. Then run the following command:
+
+ at itemize
+ at item @command{git log --patch --stat origin/master..}
+
+to make sure that only the commits you want to push are pending, that
+the log messages of the commits are correct and descriptive and contain
+no cruft from @command{git am} and to doublecheck that the commits you
+want to push really only contain the changes they are supposed to contain.
+
+ at item @command{git status}
+
+to ensure no local changes still need to be committed and that no local
+changes may have thrown off the results of your testing.
+ at end itemize
+
+Next let the code pass through a full run of our testsuite. Before you do,
+the command @command{make fate-rsync} will update the test samples. Changes
+to the samples set are not very common and commits depending on samples
+changes are delayed for at least 24 hours to allow the new samples to
+propagate, so updating it once per day is sufficient. Now execute
+
+ at itemize
+ at item @command{make distclean}
+ at item @command{/path/to/libav/configure}
+ at item @command{make check}
+ at end itemize
+
+While the test suite covers a wide range of possible problems, it is not
+a panacea. Do not hesitate to perform any other tests necessary to convince
+yourself that the changes you are about to push actually work as expected.
+
+Also note that every single commit should pass the test suite, not just
+the result of a series of patches. So if you have a series of related
+commits, run the test suite on every single commit.
+
+Finally, after pushing, mark all patches as committed on
+ at url{http://patches.libav.org/,patchwork}.
+Sometimes this is not automatically done when a patch has been
+slightly modified from the version on the mailing list.
+Also update previous incarnations of the patches you push so that
+patchwork is not cluttered with cruft.
+
+
@chapter Server Issues
Contact the project admins @email{git@@libav.org} if you have technical
diff --git a/doc/platform.texi b/doc/platform.texi
index 97e97c2..46e36c3 100644
--- a/doc/platform.texi
+++ b/doc/platform.texi
@@ -27,11 +27,11 @@ to configure.
@section BSD
BSD make will not build Libav, you need to install and use GNU Make
-(@file{gmake}).
+(@command{gmake}).
@section (Open)Solaris
-GNU Make is required to build Libav, so you have to invoke (@file{gmake}),
+GNU Make is required to build Libav, so you have to invoke (@command{gmake}),
standard Solaris Make will not work. When building with a non-c99 front-end
(gcc, generic suncc) add either @code{--extra-libs=/usr/lib/values-xpg6.o}
or @code{--extra-libs=/usr/lib/64/values-xpg6.o} to the configure options
@@ -84,7 +84,7 @@ instructions in the download section and the FAQ.
Libav does not build out-of-the-box with the packages the automated MinGW
installer provides. It also requires coreutils to be installed and many other
-packages updated to the latest version. The minimum version for some packages
+packages updated to the latest version. The minimum versions for some packages
are listed below:
@itemize
@@ -104,17 +104,14 @@ Notes:
@item Building natively using MSYS can be sped up by disabling implicit rules
in the Makefile by calling @code{make -r} instead of plain @code{make}. This
speed up is close to non-existent for normal one-off builds and is only
-noticeable when running make for a second time (for example in
+noticeable when running make for a second time (for example during
@code{make install}).
@item In order to compile AVplay, you must have the MinGW development library
-of @uref{http://www.libsdl.org/, SDL}.
-Edit the @file{bin/sdl-config} script so that it points to the correct prefix
-where SDL was installed. Verify that @file{sdl-config} can be launched from
-the MSYS command line.
+of @uref{http://www.libsdl.org/, SDL} and @code{pkg-config} installed.
@item By using @code{./configure --enable-shared} when configuring Libav,
-you can build libavutil, libavcodec and libavformat as DLLs.
+you can build all libraries as DLLs.
@end itemize
@@ -134,7 +131,7 @@ you might have to modify the procedures slightly.
@subsection Using static libraries
-Assuming you have just built and installed Libav in @file{/usr/local}.
+Assuming you have just built and installed Libav in @file{/usr/local}:
@enumerate
@@ -244,7 +241,7 @@ To create import libraries that work with the @code{/OPT:REF} option
@enumerate
- at item Open @file{Visual Studio 2005 Command Prompt}.
+ at item Open @emph{Visual Studio 2005 Command Prompt}.
Alternatively, in a normal command line prompt, call @file{vcvars32.bat}
which sets up the environment variables for the Visual C++ tools
@@ -254,17 +251,14 @@ which sets up the environment variables for the Visual C++ tools
@item Enter the @file{bin} directory where the created LIB and DLL files
are stored.
- at item Generate new import libraries with @file{lib.exe}:
+ at item Generate new import libraries with @command{lib.exe}:
@example
-lib /machine:i386 /def:..\lib\avcodec-53.def /out:avcodec.lib
-lib /machine:i386 /def:..\lib\avdevice-53.def /out:avdevice.lib
-lib /machine:i386 /def:..\lib\avfilter-2.def /out:avfilter.lib
-lib /machine:i386 /def:..\lib\avformat-53.def /out:avformat.lib
-lib /machine:i386 /def:..\lib\avutil-51.def /out:avutil.lib
-lib /machine:i386 /def:..\lib\swscale-2.def /out:swscale.lib
+lib /machine:i386 /def:..\lib\foo-version.def /out:foo.lib
@end example
+Replace @code{foo-version} and @code{foo} with the respective library names.
+
@end enumerate
@anchor{Cross compilation for Windows with Linux}
@@ -306,8 +300,8 @@ Then run
to make a static build.
-The current @code{gcc4-core} package is buggy and needs this flag to build
-shared libraries:
+To build shared libraries add a special compiler flag to work around current
+ at code{gcc4-core} package bugs in addition to the normal configure flags:
@example
./configure --enable-shared --disable-static --extra-cflags=-fno-reorder-functions
@@ -327,11 +321,8 @@ yasm, libSDL-devel, libfaac-devel, libgsm-devel, libmp3lame-devel,
libschroedinger1.0-devel, speex-devel, libtheora-devel, libxvidcore-devel
@end example
-The recommendation for libnut and x264 is to build them from source by
-yourself, as they evolve too quickly for Cygwin Ports to be up to date.
-
-Cygwin 1.7.x has IPv6 support. You can add IPv6 to Cygwin 1.5.x by means
-of the @code{libgetaddrinfo-devel} package, available at Cygwin Ports.
+The recommendation for x264 is to build it from source, as it evolves too
+quickly for Cygwin Ports to be up to date.
@section Crosscompilation for Windows under Cygwin
diff --git a/doc/protocols.texi b/doc/protocols.texi
index b08233e..e75f108 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -36,7 +36,7 @@ resource to be concatenated, each one possibly specifying a distinct
protocol.
For example to read a sequence of files @file{split1.mpeg},
- at file{split2.mpeg}, @file{split3.mpeg} with @file{avplay} use the
+ at file{split2.mpeg}, @file{split3.mpeg} with @command{avplay} use the
command:
@example
avplay concat:split1.mpeg\|split2.mpeg\|split3.mpeg
@@ -164,7 +164,7 @@ content across a TCP/IP network.
The required syntax is:
@example
-rtmp://@var{server}[:@var{port}][/@var{app}][/@var{playpath}]
+rtmp://@var{server}[:@var{port}][/@var{app}][/@var{instance}][/@var{playpath}]
@end example
The accepted parameters are:
@@ -179,20 +179,82 @@ The number of the TCP port to use (by default is 1935).
@item app
It is the name of the application to access. It usually corresponds to
the path where the application is installed on the RTMP server
-(e.g. @file{/ondemand/}, @file{/flash/live/}, etc.).
+(e.g. @file{/ondemand/}, @file{/flash/live/}, etc.). You can override
+the value parsed from the URI through the @code{rtmp_app} option, too.
@item playpath
It is the path or name of the resource to play with reference to the
-application specified in @var{app}, may be prefixed by "mp4:".
+application specified in @var{app}, may be prefixed by "mp4:". You
+can override the value parsed from the URI through the @code{rtmp_playpath}
+option, too.
@end table
-For example to read with @file{avplay} a multimedia resource named
+Additionally, the following parameters can be set via command line options
+(or in code via @code{AVOption}s):
+ at table @option
+
+ at item rtmp_app
+Name of application to connect on the RTMP server. This option
+overrides the parameter specified in the URI.
+
+ at item rtmp_buffer
+Set the client buffer time in milliseconds. The default is 3000.
+
+ at item rtmp_conn
+Extra arbitrary AMF connection parameters, parsed from a string,
+e.g. like @code{B:1 S:authMe O:1 NN:code:1.23 NS:flag:ok O:0}.
+Each value is prefixed by a single character denoting the type,
+B for Boolean, N for number, S for string, O for object, or Z for null,
+followed by a colon. For Booleans the data must be either 0 or 1 for
+FALSE or TRUE, respectively. Likewise for Objects the data must be 0 or
+1 to end or begin an object, respectively. Data items in subobjects may
+be named, by prefixing the type with 'N' and specifying the name before
+the value (i.e. @code{NB:myFlag:1}). This option may be used multiple
+times to construct arbitrary AMF sequences.
+
+ at item rtmp_flashver
+Version of the Flash plugin used to run the SWF player. The default
+is LNX 9,0,124,2.
+
+ at item rtmp_flush_interval
+Number of packets flushed in the same request (RTMPT only). The default
+is 10.
+
+ at item rtmp_live
+Specify that the media is a live stream. No resuming or seeking in
+live streams is possible. The default value is @code{any}, which means the
+subscriber first tries to play the live stream specified in the
+playpath. If a live stream of that name is not found, it plays the
+recorded stream. The other possible values are @code{live} and
+ at code{recorded}.
+
+ at item rtmp_playpath
+Stream identifier to play or to publish. This option overrides the
+parameter specified in the URI.
+
+ at item rtmp_swfurl
+URL of the SWF player for the media. By default no value will be sent.
+
+ at item rtmp_tcurl
+URL of the target stream.
+
+ at end table
+
+For example to read with @command{avplay} a multimedia resource named
"sample" from the application "vod" from an RTMP server "myserver":
@example
avplay rtmp://myserver/vod/sample
@end example
+ at section rtmpt
+
+Real-Time Messaging Protocol tunneled through HTTP.
+
+The Real-Time Messaging Protocol tunneled through HTTP (RTMPT) is used
+for streaming multimedia content within HTTP requests to traverse
+firewalls.
+
@section rtmp, rtmpe, rtmps, rtmpt, rtmpte
Real-Time Messaging Protocol and its variants supported through
@@ -228,7 +290,7 @@ For example, to stream a file in real-time to an RTMP server using
avconv -re -i myfile -f flv rtmp://myserver/live/mystream
@end example
-To play the same stream using @file{avplay}:
+To play the same stream using @command{avplay}:
@example
avplay "rtmp://myserver/live/mystream live=1"
@end example
@@ -253,7 +315,7 @@ The required syntax for a RTSP url is:
rtsp://@var{hostname}[:@var{port}]/@var{path}
@end example
-The following options (set on the @command{avconv}/@file{avplay} command
+The following options (set on the @command{avconv}/@command{avplay} command
line, or set in code via @code{AVOption}s or in @code{avformat_open_input}),
are supported:
@@ -292,7 +354,7 @@ When receiving data over UDP, the demuxer tries to reorder received packets
can be disabled by setting the maximum demuxing delay to zero (via
the @code{max_delay} field of AVFormatContext).
-When watching multi-bitrate Real-RTSP streams with @file{avplay}, the
+When watching multi-bitrate Real-RTSP streams with @command{avplay}, the
streams to display can be chosen with @code{-vst} @var{n} and
@code{-ast} @var{n} for video and audio respectively, and can be switched
on the fly by pressing @code{v} and @code{a}.
@@ -474,6 +536,14 @@ and makes writes return with AVERROR(ECONNREFUSED) if "destination
unreachable" is received.
For receiving, this gives the benefit of only receiving packets from
the specified peer address/port.
+
+ at item sources=@var{address}[, at var{address}]
+Only receive packets sent to the multicast group from one of the
+specified sender IP addresses.
+
+ at item block=@var{address}[, at var{address}]
+Ignore packets sent to the multicast group from the specified
+sender IP addresses.
@end table
Some usage examples of the udp protocol with @command{avconv} follow.
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 657f6a0..b23bc29 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -1,7 +1,14 @@
NAME = avcodec
FFLIBS = avutil
-HEADERS = avcodec.h avfft.h dxva2.h vaapi.h vda.h vdpau.h version.h xvmc.h
+HEADERS = avcodec.h \
+ avfft.h \
+ dxva2.h \
+ vaapi.h \
+ vda.h \
+ vdpau.h \
+ version.h \
+ xvmc.h \
OBJS = allcodecs.o \
audioconvert.o \
@@ -35,6 +42,7 @@ OBJS-$(CONFIG_GOLOMB) += golomb.o
OBJS-$(CONFIG_H264DSP) += h264dsp.o h264idct.o
OBJS-$(CONFIG_H264PRED) += h264pred.o
OBJS-$(CONFIG_HUFFMAN) += huffman.o
+OBJS-$(CONFIG_LIBXVID) += libxvid_rc.o
OBJS-$(CONFIG_LPC) += lpc.o
OBJS-$(CONFIG_LSP) += lsp.o
OBJS-$(CONFIG_MDCT) += mdct_fixed.o mdct_float.o
@@ -53,7 +61,7 @@ OBJS-$(CONFIG_A64MULTI_ENCODER) += a64multienc.o elbg.o
OBJS-$(CONFIG_A64MULTI5_ENCODER) += a64multienc.o elbg.o
OBJS-$(CONFIG_AAC_DECODER) += aacdec.o aactab.o aacsbr.o aacps.o \
aacadtsdec.o mpeg4audio.o kbdwin.o \
- sbrdsp.o
+ sbrdsp.o aacpsdsp.o
OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o aaccoder.o \
aacpsy.o aactab.o \
psymodel.o iirfilter.o \
@@ -126,8 +134,8 @@ OBJS-$(CONFIG_DVBSUB_DECODER) += dvbsubdec.o
OBJS-$(CONFIG_DVBSUB_ENCODER) += dvbsub.o
OBJS-$(CONFIG_DVDSUB_DECODER) += dvdsubdec.o
OBJS-$(CONFIG_DVDSUB_ENCODER) += dvdsubenc.o
-OBJS-$(CONFIG_DVVIDEO_DECODER) += dvdec.o dv.o dvdata.o
-OBJS-$(CONFIG_DVVIDEO_ENCODER) += dv.o dvdata.o
+OBJS-$(CONFIG_DVVIDEO_DECODER) += dvdec.o dv.o dvdata.o dv_profile.o
+OBJS-$(CONFIG_DVVIDEO_ENCODER) += dv.o dvdata.o dv_profile.o
OBJS-$(CONFIG_DXA_DECODER) += dxa.o
OBJS-$(CONFIG_DXTORY_DECODER) += dxtory.o
OBJS-$(CONFIG_EAC3_DECODER) += eac3dec.o eac3_data.o
@@ -150,7 +158,7 @@ OBJS-$(CONFIG_FFV1_DECODER) += ffv1.o rangecoder.o
OBJS-$(CONFIG_FFV1_ENCODER) += ffv1.o rangecoder.o
OBJS-$(CONFIG_FFVHUFF_DECODER) += huffyuv.o
OBJS-$(CONFIG_FFVHUFF_ENCODER) += huffyuv.o
-OBJS-$(CONFIG_FLAC_DECODER) += flacdec.o flacdata.o flac.o
+OBJS-$(CONFIG_FLAC_DECODER) += flacdec.o flacdata.o flac.o flacdsp.o
OBJS-$(CONFIG_FLAC_ENCODER) += flacenc.o flacdata.o flac.o
OBJS-$(CONFIG_FLASHSV_DECODER) += flashsv.o
OBJS-$(CONFIG_FLASHSV_ENCODER) += flashsvenc.o
@@ -189,6 +197,7 @@ OBJS-$(CONFIG_H264_VAAPI_HWACCEL) += vaapi_h264.o
OBJS-$(CONFIG_H264_VDA_HWACCEL) += vda_h264.o
OBJS-$(CONFIG_HUFFYUV_DECODER) += huffyuv.o
OBJS-$(CONFIG_HUFFYUV_ENCODER) += huffyuv.o
+OBJS-$(CONFIG_IAC_DECODER) += imc.o
OBJS-$(CONFIG_IDCIN_DECODER) += idcinvideo.o
OBJS-$(CONFIG_IFF_BYTERUN1_DECODER) += iff.o
OBJS-$(CONFIG_IFF_ILBM_DECODER) += iff.o
@@ -283,6 +292,8 @@ OBJS-$(CONFIG_MSMPEG4V3_ENCODER) += msmpeg4.o msmpeg4enc.o msmpeg4data.o \
h263dec.o h263.o ituh263dec.o \
mpeg4videodec.o
OBJS-$(CONFIG_MSRLE_DECODER) += msrle.o msrledec.o
+OBJS-$(CONFIG_MSA1_DECODER) += mss3.o
+OBJS-$(CONFIG_MSS1_DECODER) += mss1.o
OBJS-$(CONFIG_MSVIDEO1_DECODER) += msvideo1.o
OBJS-$(CONFIG_MSZH_DECODER) += lcldec.o
OBJS-$(CONFIG_MXPEG_DECODER) += mxpegdec.o mjpegdec.o mjpeg.o
@@ -551,8 +562,8 @@ OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcmenc.o adpcm_data.o
OBJS-$(CONFIG_ADTS_MUXER) += mpeg4audio.o
OBJS-$(CONFIG_ADX_DEMUXER) += adx.o
OBJS-$(CONFIG_CAF_DEMUXER) += mpeg4audio.o mpegaudiodata.o
-OBJS-$(CONFIG_DV_DEMUXER) += dvdata.o
-OBJS-$(CONFIG_DV_MUXER) += dvdata.o
+OBJS-$(CONFIG_DV_DEMUXER) += dv_profile.o
+OBJS-$(CONFIG_DV_MUXER) += dv_profile.o
OBJS-$(CONFIG_FLAC_DEMUXER) += flacdec.o flacdata.o flac.o
OBJS-$(CONFIG_FLAC_MUXER) += flacdec.o flacdata.o flac.o
OBJS-$(CONFIG_FLV_DEMUXER) += mpeg4audio.o
@@ -587,6 +598,8 @@ OBJS-$(CONFIG_LIBGSM_DECODER) += libgsm.o
OBJS-$(CONFIG_LIBGSM_ENCODER) += libgsm.o
OBJS-$(CONFIG_LIBGSM_MS_DECODER) += libgsm.o
OBJS-$(CONFIG_LIBGSM_MS_ENCODER) += libgsm.o
+OBJS-$(CONFIG_LIBILBC_DECODER) += libilbc.o
+OBJS-$(CONFIG_LIBILBC_ENCODER) += libilbc.o
OBJS-$(CONFIG_LIBMP3LAME_ENCODER) += libmp3lame.o mpegaudiodecheader.o \
audio_frame_queue.o
OBJS-$(CONFIG_LIBOPENCORE_AMRNB_DECODER) += libopencore-amr.o
@@ -594,11 +607,9 @@ OBJS-$(CONFIG_LIBOPENCORE_AMRNB_ENCODER) += libopencore-amr.o
OBJS-$(CONFIG_LIBOPENCORE_AMRWB_DECODER) += libopencore-amr.o
OBJS-$(CONFIG_LIBOPENJPEG_DECODER) += libopenjpeg.o
OBJS-$(CONFIG_LIBSCHROEDINGER_DECODER) += libschroedingerdec.o \
- libschroedinger.o \
- libdirac_libschro.o
+ libschroedinger.o
OBJS-$(CONFIG_LIBSCHROEDINGER_ENCODER) += libschroedingerenc.o \
- libschroedinger.o \
- libdirac_libschro.o
+ libschroedinger.o
OBJS-$(CONFIG_LIBSPEEX_DECODER) += libspeexdec.o
OBJS-$(CONFIG_LIBSPEEX_ENCODER) += libspeexenc.o audio_frame_queue.o
OBJS-$(CONFIG_LIBTHEORA_ENCODER) += libtheoraenc.o
@@ -610,7 +621,7 @@ OBJS-$(CONFIG_LIBVPX_DECODER) += libvpxdec.o
OBJS-$(CONFIG_LIBVPX_ENCODER) += libvpxenc.o
OBJS-$(CONFIG_LIBX264_ENCODER) += libx264.o
OBJS-$(CONFIG_LIBXAVS_ENCODER) += libxavs.o
-OBJS-$(CONFIG_LIBXVID) += libxvidff.o libxvid_rc.o
+OBJS-$(CONFIG_LIBXVID_ENCODER) += libxvid.o
# parsers
OBJS-$(CONFIG_AAC_PARSER) += aac_parser.o aac_ac3_parser.o \
@@ -689,7 +700,8 @@ SKIPHEADERS += %_tablegen.h \
aac_tablegen_decl.h \
fft-internal.h \
tableprint.h \
- $(ARCH)/vp56_arith.h
+ $(ARCH)/vp56_arith.h \
+
SKIPHEADERS-$(CONFIG_DXVA2) += dxva2.h dxva2_internal.h
SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER) += libschroedinger.h
SKIPHEADERS-$(CONFIG_MPEG_XVMC_DECODER) += xvmc.h
@@ -700,13 +712,27 @@ SKIPHEADERS-$(HAVE_W32THREADS) += w32pthreads.h
EXAMPLES = api
-TESTPROGS = cabac dct fft fft-fixed golomb iirfilter rangecoder
+TESTPROGS = cabac \
+ dct \
+ fft \
+ fft-fixed \
+ golomb \
+ iirfilter \
+ rangecoder \
+
TESTPROGS-$(HAVE_MMX) += motion
TESTOBJS = dctref.o
-HOSTPROGS = aac_tablegen aacps_tablegen cbrt_tablegen cos_tablegen \
- dv_tablegen motionpixels_tablegen mpegaudio_tablegen \
- pcm_tablegen qdm2_tablegen sinewin_tablegen
+HOSTPROGS = aac_tablegen \
+ aacps_tablegen \
+ cbrt_tablegen \
+ cos_tablegen \
+ dv_tablegen \
+ motionpixels_tablegen \
+ mpegaudio_tablegen \
+ pcm_tablegen \
+ qdm2_tablegen \
+ sinewin_tablegen \
CLEANFILES = *_tables.c *_tables.h *_tablegen$(HOSTEXESUF)
diff --git a/libavcodec/aac.h b/libavcodec/aac.h
index 1b6013e..45aacd1 100644
--- a/libavcodec/aac.h
+++ b/libavcodec/aac.h
@@ -30,6 +30,7 @@
#ifndef AVCODEC_AAC_H
#define AVCODEC_AAC_H
+#include "libavutil/float_dsp.h"
#include "avcodec.h"
#include "dsputil.h"
#include "fft.h"
@@ -292,6 +293,7 @@ typedef struct {
FFTContext mdct_ltp;
DSPContext dsp;
FmtConvertContext fmt_conv;
+ AVFloatDSPContext fdsp;
int random_state;
/** @} */
diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c
index bd5ba00..4be5255 100644
--- a/libavcodec/aacdec.c
+++ b/libavcodec/aacdec.c
@@ -79,7 +79,7 @@
Parametric Stereo.
*/
-
+#include "libavutil/float_dsp.h"
#include "avcodec.h"
#include "internal.h"
#include "get_bits.h"
@@ -368,7 +368,7 @@ static void pop_output_configuration(AACContext *ac) {
if (ac->oc[1].status != OC_LOCKED) {
ac->oc[1] = ac->oc[0];
ac->avctx->channels = ac->oc[1].channels;
- ac->avctx->channel_layout = ac->oc[1].channels;
+ ac->avctx->channel_layout = ac->oc[1].channel_layout;
}
}
@@ -461,6 +461,7 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id)
return NULL;
ac->oc[1].m4ac.chan_config = 2;
+ ac->oc[1].m4ac.ps = 0;
}
// And vice-versa
if (!ac->tags_mapped && type == TYPE_SCE && ac->oc[1].m4ac.chan_config == 2) {
@@ -476,6 +477,8 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id)
return NULL;
ac->oc[1].m4ac.chan_config = 1;
+ if (ac->oc[1].m4ac.sbr)
+ ac->oc[1].m4ac.ps = -1;
}
// For indexed channel configurations map the channels solely based on position.
switch (ac->oc[1].m4ac.chan_config) {
@@ -864,6 +867,7 @@ static av_cold int aac_decode_init(AVCodecContext *avctx)
ff_dsputil_init(&ac->dsp, avctx);
ff_fmt_convert_init(&ac->fmt_conv, avctx);
+ avpriv_float_dsp_init(&ac->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
ac->random_state = 0x1f2e3d4c;
@@ -1267,7 +1271,7 @@ static inline float *VMUL4S(float *dst, const float *v, unsigned idx,
t.i = s.i ^ (sign & 1U<<31);
*dst++ = v[idx>>4 & 3] * t.f;
- sign <<= nz & 1; nz >>= 1;
+ sign <<= nz & 1;
t.i = s.i ^ (sign & 1U<<31);
*dst++ = v[idx>>6 & 3] * t.f;
@@ -2029,10 +2033,10 @@ static void windowing_and_mdct_ltp(AACContext *ac, float *out,
const float *swindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_short_128 : ff_sine_128;
if (ics->window_sequence[0] != LONG_STOP_SEQUENCE) {
- ac->dsp.vector_fmul(in, in, lwindow_prev, 1024);
+ ac->fdsp.vector_fmul(in, in, lwindow_prev, 1024);
} else {
memset(in, 0, 448 * sizeof(float));
- ac->dsp.vector_fmul(in + 448, in + 448, swindow_prev, 128);
+ ac->fdsp.vector_fmul(in + 448, in + 448, swindow_prev, 128);
}
if (ics->window_sequence[0] != LONG_START_SEQUENCE) {
ac->dsp.vector_fmul_reverse(in + 1024, in + 1024, lwindow, 1024);
diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c
index 6021c37..0186011 100644
--- a/libavcodec/aacenc.c
+++ b/libavcodec/aacenc.c
@@ -30,6 +30,7 @@
* add temporal noise shaping
***********************************/
+#include "libavutil/float_dsp.h"
#include "libavutil/opt.h"
#include "avcodec.h"
#include "put_bits.h"
@@ -182,7 +183,9 @@ static void put_audio_specific_config(AVCodecContext *avctx)
}
#define WINDOW_FUNC(type) \
-static void apply_ ##type ##_window(DSPContext *dsp, SingleChannelElement *sce, const float *audio)
+static void apply_ ##type ##_window(DSPContext *dsp, AVFloatDSPContext *fdsp, \
+ SingleChannelElement *sce, \
+ const float *audio)
WINDOW_FUNC(only_long)
{
@@ -190,7 +193,7 @@ WINDOW_FUNC(only_long)
const float *pwindow = sce->ics.use_kb_window[1] ? ff_aac_kbd_long_1024 : ff_sine_1024;
float *out = sce->ret;
- dsp->vector_fmul (out, audio, lwindow, 1024);
+ fdsp->vector_fmul (out, audio, lwindow, 1024);
dsp->vector_fmul_reverse(out + 1024, audio + 1024, pwindow, 1024);
}
@@ -200,7 +203,7 @@ WINDOW_FUNC(long_start)
const float *swindow = sce->ics.use_kb_window[0] ? ff_aac_kbd_short_128 : ff_sine_128;
float *out = sce->ret;
- dsp->vector_fmul(out, audio, lwindow, 1024);
+ fdsp->vector_fmul(out, audio, lwindow, 1024);
memcpy(out + 1024, audio + 1024, sizeof(out[0]) * 448);
dsp->vector_fmul_reverse(out + 1024 + 448, audio + 1024 + 448, swindow, 128);
memset(out + 1024 + 576, 0, sizeof(out[0]) * 448);
@@ -213,7 +216,7 @@ WINDOW_FUNC(long_stop)
float *out = sce->ret;
memset(out, 0, sizeof(out[0]) * 448);
- dsp->vector_fmul(out + 448, audio + 448, swindow, 128);
+ fdsp->vector_fmul(out + 448, audio + 448, swindow, 128);
memcpy(out + 576, audio + 576, sizeof(out[0]) * 448);
dsp->vector_fmul_reverse(out + 1024, audio + 1024, lwindow, 1024);
}
@@ -227,7 +230,7 @@ WINDOW_FUNC(eight_short)
int w;
for (w = 0; w < 8; w++) {
- dsp->vector_fmul (out, in, w ? pwindow : swindow, 128);
+ fdsp->vector_fmul (out, in, w ? pwindow : swindow, 128);
out += 128;
in += 128;
dsp->vector_fmul_reverse(out, in, swindow, 128);
@@ -235,7 +238,9 @@ WINDOW_FUNC(eight_short)
}
}
-static void (*const apply_window[4])(DSPContext *dsp, SingleChannelElement *sce, const float *audio) = {
+static void (*const apply_window[4])(DSPContext *dsp, AVFloatDSPContext *fdsp,
+ SingleChannelElement *sce,
+ const float *audio) = {
[ONLY_LONG_SEQUENCE] = apply_only_long_window,
[LONG_START_SEQUENCE] = apply_long_start_window,
[EIGHT_SHORT_SEQUENCE] = apply_eight_short_window,
@@ -248,7 +253,7 @@ static void apply_window_and_mdct(AACEncContext *s, SingleChannelElement *sce,
int i;
float *output = sce->ret;
- apply_window[sce->ics.window_sequence[0]](&s->dsp, sce, audio);
+ apply_window[sce->ics.window_sequence[0]](&s->dsp, &s->fdsp, sce, audio);
if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE)
s->mdct1024.mdct_calc(&s->mdct1024, sce->coeffs, output);
@@ -694,6 +699,7 @@ static av_cold int dsp_init(AVCodecContext *avctx, AACEncContext *s)
int ret = 0;
ff_dsputil_init(&s->dsp, avctx);
+ avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
// window init
ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024);
diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h
index f4e531a..81ffb97 100644
--- a/libavcodec/aacenc.h
+++ b/libavcodec/aacenc.h
@@ -22,6 +22,7 @@
#ifndef AVCODEC_AACENC_H
#define AVCODEC_AACENC_H
+#include "libavutil/float_dsp.h"
#include "avcodec.h"
#include "put_bits.h"
#include "dsputil.h"
@@ -58,6 +59,7 @@ typedef struct AACEncContext {
FFTContext mdct1024; ///< long (1024 samples) frame transform context
FFTContext mdct128; ///< short (128 samples) frame transform context
DSPContext dsp;
+ AVFloatDSPContext fdsp;
float *planar_samples[6]; ///< saved preprocessed input
int samplerate_index; ///< MPEG-4 samplerate index
diff --git a/libavcodec/aacps.c b/libavcodec/aacps.c
index 6c9dcf2..fa7e9ac 100644
--- a/libavcodec/aacps.c
+++ b/libavcodec/aacps.c
@@ -27,6 +27,7 @@
#include "aacps.h"
#include "aacps_tablegen.h"
#include "aacpsdata.c"
+#include "dsputil.h"
#define PS_BASELINE 0 ///< Operate in Baseline PS mode
///< Baseline implies 10 or 20 stereo bands,
@@ -284,7 +285,7 @@ err:
/** Split one subband into 2 subsubbands with a symmetric real filter.
* The filter must have its non-center even coefficients equal to zero. */
-static void hybrid2_re(float (*in)[2], float (*out)[32][2], const float filter[7], int len, int reverse)
+static void hybrid2_re(float (*in)[2], float (*out)[32][2], const float filter[8], int len, int reverse)
{
int i, j;
for (i = 0; i < len; i++, in++) {
@@ -304,26 +305,14 @@ static void hybrid2_re(float (*in)[2], float (*out)[32][2], const float filter[7
}
/** Split one subband into 6 subsubbands with a complex filter */
-static void hybrid6_cx(float (*in)[2], float (*out)[32][2], const float (*filter)[7][2], int len)
+static void hybrid6_cx(PSDSPContext *dsp, float (*in)[2], float (*out)[32][2], const float (*filter)[8][2], int len)
{
- int i, j, ssb;
+ int i;
int N = 8;
- float temp[8][2];
+ LOCAL_ALIGNED_16(float, temp, [8], [2]);
for (i = 0; i < len; i++, in++) {
- for (ssb = 0; ssb < N; ssb++) {
- float sum_re = filter[ssb][6][0] * in[6][0], sum_im = filter[ssb][6][0] * in[6][1];
- for (j = 0; j < 6; j++) {
- float in0_re = in[j][0];
- float in0_im = in[j][1];
- float in1_re = in[12-j][0];
- float in1_im = in[12-j][1];
- sum_re += filter[ssb][j][0] * (in0_re + in1_re) - filter[ssb][j][1] * (in0_im - in1_im);
- sum_im += filter[ssb][j][0] * (in0_im + in1_im) + filter[ssb][j][1] * (in0_re - in1_re);
- }
- temp[ssb][0] = sum_re;
- temp[ssb][1] = sum_im;
- }
+ dsp->hybrid_analysis(temp, in, filter, 1, N);
out[0][i][0] = temp[6][0];
out[0][i][1] = temp[6][1];
out[1][i][0] = temp[7][0];
@@ -339,28 +328,18 @@ static void hybrid6_cx(float (*in)[2], float (*out)[32][2], const float (*filter
}
}
-static void hybrid4_8_12_cx(float (*in)[2], float (*out)[32][2], const float (*filter)[7][2], int N, int len)
+static void hybrid4_8_12_cx(PSDSPContext *dsp, float (*in)[2], float (*out)[32][2], const float (*filter)[8][2], int N, int len)
{
- int i, j, ssb;
+ int i;
for (i = 0; i < len; i++, in++) {
- for (ssb = 0; ssb < N; ssb++) {
- float sum_re = filter[ssb][6][0] * in[6][0], sum_im = filter[ssb][6][0] * in[6][1];
- for (j = 0; j < 6; j++) {
- float in0_re = in[j][0];
- float in0_im = in[j][1];
- float in1_re = in[12-j][0];
- float in1_im = in[12-j][1];
- sum_re += filter[ssb][j][0] * (in0_re + in1_re) - filter[ssb][j][1] * (in0_im - in1_im);
- sum_im += filter[ssb][j][0] * (in0_im + in1_im) + filter[ssb][j][1] * (in0_re - in1_re);
- }
- out[ssb][i][0] = sum_re;
- out[ssb][i][1] = sum_im;
- }
+ dsp->hybrid_analysis(out[0] + i, in, filter, 32, N);
}
}
-static void hybrid_analysis(float out[91][32][2], float in[5][44][2], float L[2][38][64], int is34, int len)
+static void hybrid_analysis(PSDSPContext *dsp, float out[91][32][2],
+ float in[5][44][2], float L[2][38][64],
+ int is34, int len)
{
int i, j;
for (i = 0; i < 5; i++) {
@@ -370,27 +349,17 @@ static void hybrid_analysis(float out[91][32][2], float in[5][44][2], float L[2]
}
}
if (is34) {
- hybrid4_8_12_cx(in[0], out, f34_0_12, 12, len);
- hybrid4_8_12_cx(in[1], out+12, f34_1_8, 8, len);
- hybrid4_8_12_cx(in[2], out+20, f34_2_4, 4, len);
- hybrid4_8_12_cx(in[3], out+24, f34_2_4, 4, len);
- hybrid4_8_12_cx(in[4], out+28, f34_2_4, 4, len);
- for (i = 0; i < 59; i++) {
- for (j = 0; j < len; j++) {
- out[i+32][j][0] = L[0][j][i+5];
- out[i+32][j][1] = L[1][j][i+5];
- }
- }
+ hybrid4_8_12_cx(dsp, in[0], out, f34_0_12, 12, len);
+ hybrid4_8_12_cx(dsp, in[1], out+12, f34_1_8, 8, len);
+ hybrid4_8_12_cx(dsp, in[2], out+20, f34_2_4, 4, len);
+ hybrid4_8_12_cx(dsp, in[3], out+24, f34_2_4, 4, len);
+ hybrid4_8_12_cx(dsp, in[4], out+28, f34_2_4, 4, len);
+ dsp->hybrid_analysis_ileave(out + 27, L, 5, len);
} else {
- hybrid6_cx(in[0], out, f20_0_8, len);
+ hybrid6_cx(dsp, in[0], out, f20_0_8, len);
hybrid2_re(in[1], out+6, g1_Q2, len, 1);
hybrid2_re(in[2], out+8, g1_Q2, len, 0);
- for (i = 0; i < 61; i++) {
- for (j = 0; j < len; j++) {
- out[i+10][j][0] = L[0][j][i+3];
- out[i+10][j][1] = L[1][j][i+3];
- }
- }
+ dsp->hybrid_analysis_ileave(out + 7, L, 3, len);
}
//update in_buf
for (i = 0; i < 5; i++) {
@@ -398,7 +367,8 @@ static void hybrid_analysis(float out[91][32][2], float in[5][44][2], float L[2]
}
}
-static void hybrid_synthesis(float out[2][38][64], float in[91][32][2], int is34, int len)
+static void hybrid_synthesis(PSDSPContext *dsp, float out[2][38][64],
+ float in[91][32][2], int is34, int len)
{
int i, n;
if (is34) {
@@ -422,12 +392,7 @@ static void hybrid_synthesis(float out[2][38][64], float in[91][32][2], int is34
out[1][n][4] += in[28+i][n][1];
}
}
- for (i = 0; i < 59; i++) {
- for (n = 0; n < len; n++) {
- out[0][n][i+5] = in[i+32][n][0];
- out[1][n][i+5] = in[i+32][n][1];
- }
- }
+ dsp->hybrid_synthesis_deint(out, in + 27, 5, len);
} else {
for (n = 0; n < len; n++) {
out[0][n][0] = in[0][n][0] + in[1][n][0] + in[2][n][0] +
@@ -439,12 +404,7 @@ static void hybrid_synthesis(float out[2][38][64], float in[91][32][2], int is34
out[0][n][2] = in[8][n][0] + in[9][n][0];
out[1][n][2] = in[8][n][1] + in[9][n][1];
}
- for (i = 0; i < 61; i++) {
- for (n = 0; n < len; n++) {
- out[0][n][i+3] = in[i+10][n][0];
- out[1][n][i+3] = in[i+10][n][1];
- }
- }
+ dsp->hybrid_synthesis_deint(out, in + 7, 3, len);
}
}
@@ -648,8 +608,8 @@ static void map_val_20_to_34(float par[PS_MAX_NR_IIDICC])
static void decorrelation(PSContext *ps, float (*out)[32][2], const float (*s)[32][2], int is34)
{
- float power[34][PS_QMF_TIME_SLOTS] = {{0}};
- float transient_gain[34][PS_QMF_TIME_SLOTS];
+ LOCAL_ALIGNED_16(float, power, [34], [PS_QMF_TIME_SLOTS]);
+ LOCAL_ALIGNED_16(float, transient_gain, [34], [PS_QMF_TIME_SLOTS]);
float *peak_decay_nrg = ps->peak_decay_nrg;
float *power_smooth = ps->power_smooth;
float *peak_decay_diff_smooth = ps->peak_decay_diff_smooth;
@@ -661,10 +621,8 @@ static void decorrelation(PSContext *ps, float (*out)[32][2], const float (*s)[3
const float a_smooth = 0.25f; ///< Smoothing coefficient
int i, k, m, n;
int n0 = 0, nL = 32;
- static const int link_delay[] = { 3, 4, 5 };
- static const float a[] = { 0.65143905753106f,
- 0.56471812200776f,
- 0.48954165955695f };
+
+ memset(power, 0, 34 * sizeof(*power));
if (is34 != ps->is34bands_old) {
memset(ps->peak_decay_nrg, 0, sizeof(ps->peak_decay_nrg));
@@ -674,11 +632,9 @@ static void decorrelation(PSContext *ps, float (*out)[32][2], const float (*s)[3
memset(ps->ap_delay, 0, sizeof(ps->ap_delay));
}
- for (n = n0; n < nL; n++) {
- for (k = 0; k < NR_BANDS[is34]; k++) {
- int i = k_to_i[k];
- power[i][n] += s[k][n][0] * s[k][n][0] + s[k][n][1] * s[k][n][1];
- }
+ for (k = 0; k < NR_BANDS[is34]; k++) {
+ int i = k_to_i[k];
+ ps->dsp.add_squares(power[i], s[k], nL - n0);
}
//Transient detection
@@ -706,54 +662,31 @@ static void decorrelation(PSContext *ps, float (*out)[32][2], const float (*s)[3
for (k = 0; k < NR_ALLPASS_BANDS[is34]; k++) {
int b = k_to_i[k];
float g_decay_slope = 1.f - DECAY_SLOPE * (k - DECAY_CUTOFF[is34]);
- float ag[PS_AP_LINKS];
g_decay_slope = av_clipf(g_decay_slope, 0.f, 1.f);
memcpy(delay[k], delay[k]+nL, PS_MAX_DELAY*sizeof(delay[k][0]));
memcpy(delay[k]+PS_MAX_DELAY, s[k], numQMFSlots*sizeof(delay[k][0]));
for (m = 0; m < PS_AP_LINKS; m++) {
memcpy(ap_delay[k][m], ap_delay[k][m]+numQMFSlots, 5*sizeof(ap_delay[k][m][0]));
- ag[m] = a[m] * g_decay_slope;
- }
- for (n = n0; n < nL; n++) {
- float in_re = delay[k][n+PS_MAX_DELAY-2][0] * phi_fract[is34][k][0] -
- delay[k][n+PS_MAX_DELAY-2][1] * phi_fract[is34][k][1];
- float in_im = delay[k][n+PS_MAX_DELAY-2][0] * phi_fract[is34][k][1] +
- delay[k][n+PS_MAX_DELAY-2][1] * phi_fract[is34][k][0];
- for (m = 0; m < PS_AP_LINKS; m++) {
- float a_re = ag[m] * in_re;
- float a_im = ag[m] * in_im;
- float link_delay_re = ap_delay[k][m][n+5-link_delay[m]][0];
- float link_delay_im = ap_delay[k][m][n+5-link_delay[m]][1];
- float fractional_delay_re = Q_fract_allpass[is34][k][m][0];
- float fractional_delay_im = Q_fract_allpass[is34][k][m][1];
- ap_delay[k][m][n+5][0] = in_re;
- ap_delay[k][m][n+5][1] = in_im;
- in_re = link_delay_re * fractional_delay_re - link_delay_im * fractional_delay_im - a_re;
- in_im = link_delay_re * fractional_delay_im + link_delay_im * fractional_delay_re - a_im;
- ap_delay[k][m][n+5][0] += ag[m] * in_re;
- ap_delay[k][m][n+5][1] += ag[m] * in_im;
- }
- out[k][n][0] = transient_gain[b][n] * in_re;
- out[k][n][1] = transient_gain[b][n] * in_im;
}
+ ps->dsp.decorrelate(out[k], delay[k] + PS_MAX_DELAY - 2, ap_delay[k],
+ phi_fract[is34][k], Q_fract_allpass[is34][k],
+ transient_gain[b], g_decay_slope, nL - n0);
}
for (; k < SHORT_DELAY_BAND[is34]; k++) {
+ int i = k_to_i[k];
memcpy(delay[k], delay[k]+nL, PS_MAX_DELAY*sizeof(delay[k][0]));
memcpy(delay[k]+PS_MAX_DELAY, s[k], numQMFSlots*sizeof(delay[k][0]));
- for (n = n0; n < nL; n++) {
- //H = delay 14
- out[k][n][0] = transient_gain[k_to_i[k]][n] * delay[k][n+PS_MAX_DELAY-14][0];
- out[k][n][1] = transient_gain[k_to_i[k]][n] * delay[k][n+PS_MAX_DELAY-14][1];
- }
+ //H = delay 14
+ ps->dsp.mul_pair_single(out[k], delay[k] + PS_MAX_DELAY - 14,
+ transient_gain[i], nL - n0);
}
for (; k < NR_BANDS[is34]; k++) {
+ int i = k_to_i[k];
memcpy(delay[k], delay[k]+nL, PS_MAX_DELAY*sizeof(delay[k][0]));
memcpy(delay[k]+PS_MAX_DELAY, s[k], numQMFSlots*sizeof(delay[k][0]));
- for (n = n0; n < nL; n++) {
- //H = delay 1
- out[k][n][0] = transient_gain[k_to_i[k]][n] * delay[k][n+PS_MAX_DELAY-1][0];
- out[k][n][1] = transient_gain[k_to_i[k]][n] * delay[k][n+PS_MAX_DELAY-1][1];
- }
+ //H = delay 1
+ ps->dsp.mul_pair_single(out[k], delay[k] + PS_MAX_DELAY - 1,
+ transient_gain[i], nL - n0);
}
}
@@ -797,7 +730,7 @@ static void remap20(int8_t (**p_par_mapped)[PS_MAX_NR_IIDICC],
static void stereo_processing(PSContext *ps, float (*l)[32][2], float (*r)[32][2], int is34)
{
- int e, b, k, n;
+ int e, b, k;
float (*H11)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H11;
float (*H12)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H12;
@@ -909,78 +842,52 @@ static void stereo_processing(PSContext *ps, float (*l)[32][2], float (*r)[32][2
H22[0][e+1][b] = h22;
}
for (k = 0; k < NR_BANDS[is34]; k++) {
- float h11r, h12r, h21r, h22r;
- float h11i, h12i, h21i, h22i;
- float h11r_step, h12r_step, h21r_step, h22r_step;
- float h11i_step, h12i_step, h21i_step, h22i_step;
+ float h[2][4];
+ float h_step[2][4];
int start = ps->border_position[e];
int stop = ps->border_position[e+1];
float width = 1.f / (stop - start);
b = k_to_i[k];
- h11r = H11[0][e][b];
- h12r = H12[0][e][b];
- h21r = H21[0][e][b];
- h22r = H22[0][e][b];
+ h[0][0] = H11[0][e][b];
+ h[0][1] = H12[0][e][b];
+ h[0][2] = H21[0][e][b];
+ h[0][3] = H22[0][e][b];
if (!PS_BASELINE && ps->enable_ipdopd) {
//Is this necessary? ps_04_new seems unchanged
if ((is34 && k <= 13 && k >= 9) || (!is34 && k <= 1)) {
- h11i = -H11[1][e][b];
- h12i = -H12[1][e][b];
- h21i = -H21[1][e][b];
- h22i = -H22[1][e][b];
+ h[1][0] = -H11[1][e][b];
+ h[1][1] = -H12[1][e][b];
+ h[1][2] = -H21[1][e][b];
+ h[1][3] = -H22[1][e][b];
} else {
- h11i = H11[1][e][b];
- h12i = H12[1][e][b];
- h21i = H21[1][e][b];
- h22i = H22[1][e][b];
+ h[1][0] = H11[1][e][b];
+ h[1][1] = H12[1][e][b];
+ h[1][2] = H21[1][e][b];
+ h[1][3] = H22[1][e][b];
}
}
//Interpolation
- h11r_step = (H11[0][e+1][b] - h11r) * width;
- h12r_step = (H12[0][e+1][b] - h12r) * width;
- h21r_step = (H21[0][e+1][b] - h21r) * width;
- h22r_step = (H22[0][e+1][b] - h22r) * width;
+ h_step[0][0] = (H11[0][e+1][b] - h[0][0]) * width;
+ h_step[0][1] = (H12[0][e+1][b] - h[0][1]) * width;
+ h_step[0][2] = (H21[0][e+1][b] - h[0][2]) * width;
+ h_step[0][3] = (H22[0][e+1][b] - h[0][3]) * width;
if (!PS_BASELINE && ps->enable_ipdopd) {
- h11i_step = (H11[1][e+1][b] - h11i) * width;
- h12i_step = (H12[1][e+1][b] - h12i) * width;
- h21i_step = (H21[1][e+1][b] - h21i) * width;
- h22i_step = (H22[1][e+1][b] - h22i) * width;
- }
- for (n = start + 1; n <= stop; n++) {
- //l is s, r is d
- float l_re = l[k][n][0];
- float l_im = l[k][n][1];
- float r_re = r[k][n][0];
- float r_im = r[k][n][1];
- h11r += h11r_step;
- h12r += h12r_step;
- h21r += h21r_step;
- h22r += h22r_step;
- if (!PS_BASELINE && ps->enable_ipdopd) {
- h11i += h11i_step;
- h12i += h12i_step;
- h21i += h21i_step;
- h22i += h22i_step;
-
- l[k][n][0] = h11r*l_re + h21r*r_re - h11i*l_im - h21i*r_im;
- l[k][n][1] = h11r*l_im + h21r*r_im + h11i*l_re + h21i*r_re;
- r[k][n][0] = h12r*l_re + h22r*r_re - h12i*l_im - h22i*r_im;
- r[k][n][1] = h12r*l_im + h22r*r_im + h12i*l_re + h22i*r_re;
- } else {
- l[k][n][0] = h11r*l_re + h21r*r_re;
- l[k][n][1] = h11r*l_im + h21r*r_im;
- r[k][n][0] = h12r*l_re + h22r*r_re;
- r[k][n][1] = h12r*l_im + h22r*r_im;
- }
+ h_step[1][0] = (H11[1][e+1][b] - h[1][0]) * width;
+ h_step[1][1] = (H12[1][e+1][b] - h[1][1]) * width;
+ h_step[1][2] = (H21[1][e+1][b] - h[1][2]) * width;
+ h_step[1][3] = (H22[1][e+1][b] - h[1][3]) * width;
}
+ ps->dsp.stereo_interpolate[!PS_BASELINE && ps->enable_ipdopd](
+ l[k] + start + 1, r[k] + start + 1,
+ h, h_step, stop - start);
}
}
}
int ff_ps_apply(AVCodecContext *avctx, PSContext *ps, float L[2][38][64], float R[2][38][64], int top)
{
- float Lbuf[91][32][2];
- float Rbuf[91][32][2];
+ LOCAL_ALIGNED_16(float, Lbuf, [91], [32][2]);
+ LOCAL_ALIGNED_16(float, Rbuf, [91], [32][2]);
const int len = 32;
int is34 = ps->is34bands;
@@ -989,11 +896,11 @@ int ff_ps_apply(AVCodecContext *avctx, PSContext *ps, float L[2][38][64], float
if (top < NR_ALLPASS_BANDS[is34])
memset(ps->ap_delay + top, 0, (NR_ALLPASS_BANDS[is34] - top)*sizeof(ps->ap_delay[0]));
- hybrid_analysis(Lbuf, ps->in_buf, L, is34, len);
+ hybrid_analysis(&ps->dsp, Lbuf, ps->in_buf, L, is34, len);
decorrelation(ps, Rbuf, Lbuf, is34);
stereo_processing(ps, Lbuf, Rbuf, is34);
- hybrid_synthesis(L, Lbuf, is34, len);
- hybrid_synthesis(R, Rbuf, is34, len);
+ hybrid_synthesis(&ps->dsp, L, Lbuf, is34, len);
+ hybrid_synthesis(&ps->dsp, R, Rbuf, is34, len);
return 0;
}
@@ -1041,4 +948,5 @@ av_cold void ff_ps_init(void) {
av_cold void ff_ps_ctx_init(PSContext *ps)
{
+ ff_psdsp_init(&ps->dsp);
}
diff --git a/libavcodec/aacps.h b/libavcodec/aacps.h
index 124fbee..6cdac24 100644
--- a/libavcodec/aacps.h
+++ b/libavcodec/aacps.h
@@ -24,6 +24,7 @@
#include <stdint.h>
+#include "aacpsdsp.h"
#include "avcodec.h"
#include "get_bits.h"
@@ -60,18 +61,19 @@ typedef struct {
int is34bands;
int is34bands_old;
- float in_buf[5][44][2];
- float delay[PS_MAX_SSB][PS_QMF_TIME_SLOTS + PS_MAX_DELAY][2];
- float ap_delay[PS_MAX_AP_BANDS][PS_AP_LINKS][PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2];
- float peak_decay_nrg[34];
- float power_smooth[34];
- float peak_decay_diff_smooth[34];
- float H11[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC];
- float H12[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC];
- float H21[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC];
- float H22[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC];
+ DECLARE_ALIGNED(16, float, in_buf)[5][44][2];
+ DECLARE_ALIGNED(16, float, delay)[PS_MAX_SSB][PS_QMF_TIME_SLOTS + PS_MAX_DELAY][2];
+ DECLARE_ALIGNED(16, float, ap_delay)[PS_MAX_AP_BANDS][PS_AP_LINKS][PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2];
+ DECLARE_ALIGNED(16, float, peak_decay_nrg)[34];
+ DECLARE_ALIGNED(16, float, power_smooth)[34];
+ DECLARE_ALIGNED(16, float, peak_decay_diff_smooth)[34];
+ DECLARE_ALIGNED(16, float, H11)[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC];
+ DECLARE_ALIGNED(16, float, H12)[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC];
+ DECLARE_ALIGNED(16, float, H21)[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC];
+ DECLARE_ALIGNED(16, float, H22)[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC];
int8_t opd_hist[PS_MAX_NR_IIDICC];
int8_t ipd_hist[PS_MAX_NR_IIDICC];
+ PSDSPContext dsp;
} PSContext;
void ff_ps_init(void);
diff --git a/libavcodec/aacps_tablegen.c b/libavcodec/aacps_tablegen.c
index 8650226..635737d 100644
--- a/libavcodec/aacps_tablegen.c
+++ b/libavcodec/aacps_tablegen.c
@@ -69,23 +69,23 @@ int main(void)
write_float_3d_array(HB, 46, 8, 4);
printf("};\n");
- printf("static const float f20_0_8[8][7][2] = {\n");
- write_float_3d_array(f20_0_8, 8, 7, 2);
+ printf("static const DECLARE_ALIGNED(16, float, f20_0_8)[8][8][2] = {\n");
+ write_float_3d_array(f20_0_8, 8, 8, 2);
printf("};\n");
- printf("static const float f34_0_12[12][7][2] = {\n");
- write_float_3d_array(f34_0_12, 12, 7, 2);
+ printf("static const DECLARE_ALIGNED(16, float, f34_0_12)[12][8][2] = {\n");
+ write_float_3d_array(f34_0_12, 12, 8, 2);
printf("};\n");
- printf("static const float f34_1_8[8][7][2] = {\n");
- write_float_3d_array(f34_1_8, 8, 7, 2);
+ printf("static const DECLARE_ALIGNED(16, float, f34_1_8)[8][8][2] = {\n");
+ write_float_3d_array(f34_1_8, 8, 8, 2);
printf("};\n");
- printf("static const float f34_2_4[4][7][2] = {\n");
- write_float_3d_array(f34_2_4, 4, 7, 2);
+ printf("static const DECLARE_ALIGNED(16, float, f34_2_4)[4][8][2] = {\n");
+ write_float_3d_array(f34_2_4, 4, 8, 2);
printf("};\n");
- printf("static const float Q_fract_allpass[2][50][3][2] = {\n");
+ printf("static const DECLARE_ALIGNED(16, float, Q_fract_allpass)[2][50][3][2] = {\n");
write_float_4d_array(Q_fract_allpass, 2, 50, 3, 2);
printf("};\n");
- printf("static const float phi_fract[2][50][2] = {\n");
+ printf("static const DECLARE_ALIGNED(16, float, phi_fract)[2][50][2] = {\n");
write_float_3d_array(phi_fract, 2, 50, 2);
printf("};\n");
diff --git a/libavcodec/aacps_tablegen.h b/libavcodec/aacps_tablegen.h
index 5041f44..bd4e695 100644
--- a/libavcodec/aacps_tablegen.h
+++ b/libavcodec/aacps_tablegen.h
@@ -23,6 +23,7 @@
#ifndef AACPS_TABLEGEN_H
#define AACPS_TABLEGEN_H
+#include <math.h>
#include <stdint.h>
#if CONFIG_HARDCODED_TABLES
@@ -31,6 +32,7 @@
#else
#include "libavutil/common.h"
#include "libavutil/mathematics.h"
+#include "libavutil/mem.h"
#define NR_ALLPASS_BANDS20 30
#define NR_ALLPASS_BANDS34 50
#define PS_AP_LINKS 3
@@ -38,12 +40,12 @@ static float pd_re_smooth[8*8*8];
static float pd_im_smooth[8*8*8];
static float HA[46][8][4];
static float HB[46][8][4];
-static float f20_0_8 [ 8][7][2];
-static float f34_0_12[12][7][2];
-static float f34_1_8 [ 8][7][2];
-static float f34_2_4 [ 4][7][2];
-static float Q_fract_allpass[2][50][3][2];
-static float phi_fract[2][50][2];
+static DECLARE_ALIGNED(16, float, f20_0_8) [ 8][8][2];
+static DECLARE_ALIGNED(16, float, f34_0_12)[12][8][2];
+static DECLARE_ALIGNED(16, float, f34_1_8) [ 8][8][2];
+static DECLARE_ALIGNED(16, float, f34_2_4) [ 4][8][2];
+static DECLARE_ALIGNED(16, float, Q_fract_allpass)[2][50][3][2];
+static DECLARE_ALIGNED(16, float, phi_fract)[2][50][2];
static const float g0_Q8[] = {
0.00746082949812f, 0.02270420949825f, 0.04546865930473f, 0.07266113929591f,
@@ -65,7 +67,7 @@ static const float g2_Q4[] = {
0.16486303567403f, 0.23279856662996f, 0.25f
};
-static void make_filters_from_proto(float (*filter)[7][2], const float *proto, int bands)
+static void make_filters_from_proto(float (*filter)[8][2], const float *proto, int bands)
{
int q, n;
for (q = 0; q < bands; q++) {
diff --git a/libavcodec/aacpsdsp.c b/libavcodec/aacpsdsp.c
new file mode 100644
index 0000000..e90c50b
--- /dev/null
+++ b/libavcodec/aacpsdsp.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2010 Alex Converse <alex.converse at gmail.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "libavutil/attributes.h"
+#include "aacpsdsp.h"
+
+static void ps_add_squares_c(float *dst, const float (*src)[2], int n)
+{
+ int i;
+ for (i = 0; i < n; i++)
+ dst[i] += src[i][0] * src[i][0] + src[i][1] * src[i][1];
+}
+
+static void ps_mul_pair_single_c(float (*dst)[2], float (*src0)[2], float *src1,
+ int n)
+{
+ int i;
+ for (i = 0; i < n; i++) {
+ dst[i][0] = src0[i][0] * src1[i];
+ dst[i][1] = src0[i][1] * src1[i];
+ }
+}
+
+static void ps_hybrid_analysis_c(float (*out)[2], float (*in)[2],
+ const float (*filter)[8][2],
+ int stride, int n)
+{
+ int i, j;
+
+ for (i = 0; i < n; i++) {
+ float sum_re = filter[i][6][0] * in[6][0];
+ float sum_im = filter[i][6][0] * in[6][1];
+
+ for (j = 0; j < 6; j++) {
+ float in0_re = in[j][0];
+ float in0_im = in[j][1];
+ float in1_re = in[12-j][0];
+ float in1_im = in[12-j][1];
+ sum_re += filter[i][j][0] * (in0_re + in1_re) -
+ filter[i][j][1] * (in0_im - in1_im);
+ sum_im += filter[i][j][0] * (in0_im + in1_im) +
+ filter[i][j][1] * (in0_re - in1_re);
+ }
+ out[i * stride][0] = sum_re;
+ out[i * stride][1] = sum_im;
+ }
+}
+
+static void ps_hybrid_analysis_ileave_c(float (*out)[32][2], float L[2][38][64],
+ int i, int len)
+{
+ int j;
+
+ for (; i < 64; i++) {
+ for (j = 0; j < len; j++) {
+ out[i][j][0] = L[0][j][i];
+ out[i][j][1] = L[1][j][i];
+ }
+ }
+}
+
+static void ps_hybrid_synthesis_deint_c(float out[2][38][64],
+ float (*in)[32][2],
+ int i, int len)
+{
+ int n;
+
+ for (; i < 64; i++) {
+ for (n = 0; n < len; n++) {
+ out[0][n][i] = in[i][n][0];
+ out[1][n][i] = in[i][n][1];
+ }
+ }
+}
+
+static void ps_decorrelate_c(float (*out)[2], float (*delay)[2],
+ float (*ap_delay)[PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2],
+ const float phi_fract[2], float (*Q_fract)[2],
+ const float *transient_gain,
+ float g_decay_slope,
+ int len)
+{
+ static const float a[] = { 0.65143905753106f,
+ 0.56471812200776f,
+ 0.48954165955695f };
+ float ag[PS_AP_LINKS];
+ int m, n;
+
+ for (m = 0; m < PS_AP_LINKS; m++)
+ ag[m] = a[m] * g_decay_slope;
+
+ for (n = 0; n < len; n++) {
+ float in_re = delay[n][0] * phi_fract[0] - delay[n][1] * phi_fract[1];
+ float in_im = delay[n][0] * phi_fract[1] + delay[n][1] * phi_fract[0];
+ for (m = 0; m < PS_AP_LINKS; m++) {
+ float a_re = ag[m] * in_re;
+ float a_im = ag[m] * in_im;
+ float link_delay_re = ap_delay[m][n+2-m][0];
+ float link_delay_im = ap_delay[m][n+2-m][1];
+ float fractional_delay_re = Q_fract[m][0];
+ float fractional_delay_im = Q_fract[m][1];
+ float apd_re = in_re;
+ float apd_im = in_im;
+ in_re = link_delay_re * fractional_delay_re -
+ link_delay_im * fractional_delay_im - a_re;
+ in_im = link_delay_re * fractional_delay_im +
+ link_delay_im * fractional_delay_re - a_im;
+ ap_delay[m][n+5][0] = apd_re + ag[m] * in_re;
+ ap_delay[m][n+5][1] = apd_im + ag[m] * in_im;
+ }
+ out[n][0] = transient_gain[n] * in_re;
+ out[n][1] = transient_gain[n] * in_im;
+ }
+}
+
+static void ps_stereo_interpolate_c(float (*l)[2], float (*r)[2],
+ float h[2][4], float h_step[2][4],
+ int len)
+{
+ float h0 = h[0][0];
+ float h1 = h[0][1];
+ float h2 = h[0][2];
+ float h3 = h[0][3];
+ float hs0 = h_step[0][0];
+ float hs1 = h_step[0][1];
+ float hs2 = h_step[0][2];
+ float hs3 = h_step[0][3];
+ int n;
+
+ for (n = 0; n < len; n++) {
+ //l is s, r is d
+ float l_re = l[n][0];
+ float l_im = l[n][1];
+ float r_re = r[n][0];
+ float r_im = r[n][1];
+ h0 += hs0;
+ h1 += hs1;
+ h2 += hs2;
+ h3 += hs3;
+ l[n][0] = h0 * l_re + h2 * r_re;
+ l[n][1] = h0 * l_im + h2 * r_im;
+ r[n][0] = h1 * l_re + h3 * r_re;
+ r[n][1] = h1 * l_im + h3 * r_im;
+ }
+}
+
+static void ps_stereo_interpolate_ipdopd_c(float (*l)[2], float (*r)[2],
+ float h[2][4], float h_step[2][4],
+ int len)
+{
+ float h00 = h[0][0], h10 = h[1][0];
+ float h01 = h[0][1], h11 = h[1][1];
+ float h02 = h[0][2], h12 = h[1][2];
+ float h03 = h[0][3], h13 = h[1][3];
+ float hs00 = h_step[0][0], hs10 = h_step[1][0];
+ float hs01 = h_step[0][1], hs11 = h_step[1][1];
+ float hs02 = h_step[0][2], hs12 = h_step[1][2];
+ float hs03 = h_step[0][3], hs13 = h_step[1][3];
+ int n;
+
+ for (n = 0; n < len; n++) {
+ //l is s, r is d
+ float l_re = l[n][0];
+ float l_im = l[n][1];
+ float r_re = r[n][0];
+ float r_im = r[n][1];
+ h00 += hs00;
+ h01 += hs01;
+ h02 += hs02;
+ h03 += hs03;
+ h10 += hs10;
+ h11 += hs11;
+ h12 += hs12;
+ h13 += hs13;
+
+ l[n][0] = h00 * l_re + h02 * r_re - h10 * l_im - h12 * r_im;
+ l[n][1] = h00 * l_im + h02 * r_im + h10 * l_re + h12 * r_re;
+ r[n][0] = h01 * l_re + h03 * r_re - h11 * l_im - h13 * r_im;
+ r[n][1] = h01 * l_im + h03 * r_im + h11 * l_re + h13 * r_re;
+ }
+}
+
+av_cold void ff_psdsp_init(PSDSPContext *s)
+{
+ s->add_squares = ps_add_squares_c;
+ s->mul_pair_single = ps_mul_pair_single_c;
+ s->hybrid_analysis = ps_hybrid_analysis_c;
+ s->hybrid_analysis_ileave = ps_hybrid_analysis_ileave_c;
+ s->hybrid_synthesis_deint = ps_hybrid_synthesis_deint_c;
+ s->decorrelate = ps_decorrelate_c;
+ s->stereo_interpolate[0] = ps_stereo_interpolate_c;
+ s->stereo_interpolate[1] = ps_stereo_interpolate_ipdopd_c;
+
+ if (ARCH_ARM)
+ ff_psdsp_init_arm(s);
+}
diff --git a/libavcodec/aacpsdsp.h b/libavcodec/aacpsdsp.h
new file mode 100644
index 0000000..93737d2
--- /dev/null
+++ b/libavcodec/aacpsdsp.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012 Mans Rullgard
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef LIBAVCODEC_AACPSDSP_H
+#define LIBAVCODEC_AACPSDSP_H
+
+#define PS_QMF_TIME_SLOTS 32
+#define PS_AP_LINKS 3
+#define PS_MAX_AP_DELAY 5
+
+typedef struct PSDSPContext {
+ void (*add_squares)(float *dst, const float (*src)[2], int n);
+ void (*mul_pair_single)(float (*dst)[2], float (*src0)[2], float *src1,
+ int n);
+ void (*hybrid_analysis)(float (*out)[2], float (*in)[2],
+ const float (*filter)[8][2],
+ int stride, int n);
+ void (*hybrid_analysis_ileave)(float (*out)[32][2], float L[2][38][64],
+ int i, int len);
+ void (*hybrid_synthesis_deint)(float out[2][38][64], float (*in)[32][2],
+ int i, int len);
+ void (*decorrelate)(float (*out)[2], float (*delay)[2],
+ float (*ap_delay)[PS_QMF_TIME_SLOTS+PS_MAX_AP_DELAY][2],
+ const float phi_fract[2], float (*Q_fract)[2],
+ const float *transient_gain,
+ float g_decay_slope,
+ int len);
+ void (*stereo_interpolate[2])(float (*l)[2], float (*r)[2],
+ float h[2][4], float h_step[2][4],
+ int len);
+} PSDSPContext;
+
+void ff_psdsp_init(PSDSPContext *s);
+void ff_psdsp_init_arm(PSDSPContext *s);
+
+#endif /* LIBAVCODEC_AACPSDSP_H */
diff --git a/libavcodec/aacsbrdata.h b/libavcodec/aacsbrdata.h
index fb02a77..f309059 100644
--- a/libavcodec/aacsbrdata.h
+++ b/libavcodec/aacsbrdata.h
@@ -267,8 +267,8 @@ static const int8_t sbr_offset[6][16] = {
};
///< window coefficients for analysis/synthesis QMF banks
-static DECLARE_ALIGNED(16, float, sbr_qmf_window_ds)[320];
-static DECLARE_ALIGNED(16, float, sbr_qmf_window_us)[640] = {
+static DECLARE_ALIGNED(32, float, sbr_qmf_window_ds)[320];
+static DECLARE_ALIGNED(32, float, sbr_qmf_window_us)[640] = {
0.0000000000, -0.0005525286, -0.0005617692, -0.0004947518,
-0.0004875227, -0.0004893791, -0.0005040714, -0.0005226564,
-0.0005466565, -0.0005677802, -0.0005870930, -0.0006132747,
diff --git a/libavcodec/aactab.c b/libavcodec/aactab.c
index 46886b1..9176e37 100644
--- a/libavcodec/aactab.c
+++ b/libavcodec/aactab.c
@@ -33,8 +33,8 @@
#include <stdint.h>
-DECLARE_ALIGNED(16, float, ff_aac_kbd_long_1024)[1024];
-DECLARE_ALIGNED(16, float, ff_aac_kbd_short_128)[128];
+DECLARE_ALIGNED(32, float, ff_aac_kbd_long_1024)[1024];
+DECLARE_ALIGNED(32, float, ff_aac_kbd_short_128)[128];
const uint8_t ff_aac_num_swb_1024[] = {
41, 41, 47, 49, 49, 51, 47, 47, 43, 43, 43, 40, 40
diff --git a/libavcodec/aactab.h b/libavcodec/aactab.h
index c76d65d..56e5796 100644
--- a/libavcodec/aactab.h
+++ b/libavcodec/aactab.h
@@ -44,8 +44,8 @@
/* @name window coefficients
* @{
*/
-DECLARE_ALIGNED(16, extern float, ff_aac_kbd_long_1024)[1024];
-DECLARE_ALIGNED(16, extern float, ff_aac_kbd_short_128)[128];
+DECLARE_ALIGNED(32, extern float, ff_aac_kbd_long_1024)[1024];
+DECLARE_ALIGNED(32, extern float, ff_aac_kbd_short_128)[128];
// @}
/* @name number of scalefactor window bands for long and short transform windows respectively
diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c
index 3962fab..50d7f70 100644
--- a/libavcodec/ac3enc.c
+++ b/libavcodec/ac3enc.c
@@ -2494,6 +2494,7 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx)
#endif
ff_dsputil_init(&s->dsp, avctx);
+ avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
ff_ac3dsp_init(&s->ac3dsp, avctx->flags & CODEC_FLAG_BITEXACT);
dprint_options(s);
diff --git a/libavcodec/ac3enc.h b/libavcodec/ac3enc.h
index e8415a2..be9dcf2 100644
--- a/libavcodec/ac3enc.h
+++ b/libavcodec/ac3enc.h
@@ -29,6 +29,8 @@
#define AVCODEC_AC3ENC_H
#include <stdint.h>
+
+#include "libavutil/float_dsp.h"
#include "ac3.h"
#include "ac3dsp.h"
#include "avcodec.h"
@@ -158,6 +160,7 @@ typedef struct AC3EncodeContext {
AVCodecContext *avctx; ///< parent AVCodecContext
PutBitContext pb; ///< bitstream writer context
DSPContext dsp;
+ AVFloatDSPContext fdsp;
AC3DSPContext ac3dsp; ///< AC-3 optimized functions
FFTContext mdct; ///< FFT context for MDCT calculation
const SampleType *mdct_window; ///< MDCT window function array
diff --git a/libavcodec/ac3enc_fixed.c b/libavcodec/ac3enc_fixed.c
index 8d75ee3..cc8f158 100644
--- a/libavcodec/ac3enc_fixed.c
+++ b/libavcodec/ac3enc_fixed.c
@@ -68,10 +68,11 @@ av_cold int AC3_NAME(mdct_init)(AC3EncodeContext *s)
/*
* Apply KBD window to input samples prior to MDCT.
*/
-static void apply_window(DSPContext *dsp, int16_t *output, const int16_t *input,
+static void apply_window(void *dsp, int16_t *output, const int16_t *input,
const int16_t *window, unsigned int len)
{
- dsp->apply_window_int16(output, input, window, len);
+ DSPContext *dsp0 = dsp;
+ dsp0->apply_window_int16(output, input, window, len);
}
diff --git a/libavcodec/ac3enc_float.c b/libavcodec/ac3enc_float.c
index 0b9e1de..9eff5c5 100644
--- a/libavcodec/ac3enc_float.c
+++ b/libavcodec/ac3enc_float.c
@@ -86,10 +86,12 @@ av_cold int ff_ac3_float_mdct_init(AC3EncodeContext *s)
/*
* Apply KBD window to input samples prior to MDCT.
*/
-static void apply_window(DSPContext *dsp, float *output, const float *input,
- const float *window, unsigned int len)
+static void apply_window(void *dsp, float *output,
+ const float *input, const float *window,
+ unsigned int len)
{
- dsp->vector_fmul(output, input, window, len);
+ AVFloatDSPContext *fdsp = dsp;
+ fdsp->vector_fmul(output, input, window, len);
}
diff --git a/libavcodec/ac3enc_template.c b/libavcodec/ac3enc_template.c
index 9427cfe..6e0a2b6 100644
--- a/libavcodec/ac3enc_template.c
+++ b/libavcodec/ac3enc_template.c
@@ -33,7 +33,7 @@
static void scale_coefficients(AC3EncodeContext *s);
-static void apply_window(DSPContext *dsp, SampleType *output,
+static void apply_window(void *dsp, SampleType *output,
const SampleType *input, const SampleType *window,
unsigned int len);
@@ -107,8 +107,13 @@ static void apply_mdct(AC3EncodeContext *s)
AC3Block *block = &s->blocks[blk];
const SampleType *input_samples = &s->planar_samples[ch][blk * AC3_BLOCK_SIZE];
+#if CONFIG_AC3ENC_FLOAT
+ apply_window(&s->fdsp, s->windowed_samples, input_samples,
+ s->mdct_window, AC3_WINDOW_SIZE);
+#else
apply_window(&s->dsp, s->windowed_samples, input_samples,
s->mdct_window, AC3_WINDOW_SIZE);
+#endif
if (s->fixed_point)
block->coeff_shift[ch+1] = normalize_samples(s);
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index 41d0d98..8170e7f 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -1209,12 +1209,14 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
int prev[2][2];
int ch;
- for (i = 0; i < 32; i++)
- table[0][i] = sign_extend(bytestream2_get_be16u(&gb), 16);
+ for (i = 0; i < 2; i++)
+ for (n = 0; n < 16; n++)
+ table[i][n] = sign_extend(bytestream2_get_be16u(&gb), 16);
/* Initialize the previous sample. */
- for (i = 0; i < 4; i++)
- prev[0][i] = sign_extend(bytestream2_get_be16u(&gb), 16);
+ for (i = 0; i < 2; i++)
+ for (n = 0; n < 2; n++)
+ prev[i][n] = sign_extend(bytestream2_get_be16u(&gb), 16);
for (ch = 0; ch <= st; ch++) {
samples = (short *)c->frame.data[0] + ch;
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index a1df47a..cb08e33 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -152,10 +152,12 @@ void avcodec_register_all(void)
REGISTER_DECODER (MPEG4_VDPAU, mpeg4_vdpau);
REGISTER_DECODER (MPEG_VDPAU, mpeg_vdpau);
REGISTER_DECODER (MPEG1_VDPAU, mpeg1_vdpau);
+ REGISTER_DECODER (MSA1, msa1);
REGISTER_DECODER (MSMPEG4V1, msmpeg4v1);
REGISTER_ENCDEC (MSMPEG4V2, msmpeg4v2);
REGISTER_ENCDEC (MSMPEG4V3, msmpeg4v3);
REGISTER_DECODER (MSRLE, msrle);
+ REGISTER_DECODER (MSS1, mss1);
REGISTER_DECODER (MSVIDEO1, msvideo1);
REGISTER_DECODER (MSZH, mszh);
REGISTER_DECODER (MXPEG, mxpeg);
@@ -260,6 +262,7 @@ void avcodec_register_all(void)
REGISTER_ENCDEC (FLAC, flac);
REGISTER_DECODER (GSM, gsm);
REGISTER_DECODER (GSM_MS, gsm_ms);
+ REGISTER_DECODER (IAC, iac);
REGISTER_DECODER (IMC, imc);
REGISTER_DECODER (MACE3, mace3);
REGISTER_DECODER (MACE6, mace6);
@@ -378,6 +381,7 @@ void avcodec_register_all(void)
REGISTER_ENCODER (LIBFAAC, libfaac);
REGISTER_ENCDEC (LIBGSM, libgsm);
REGISTER_ENCDEC (LIBGSM_MS, libgsm_ms);
+ REGISTER_ENCDEC (LIBILBC, libilbc);
REGISTER_ENCODER (LIBMP3LAME, libmp3lame);
REGISTER_ENCDEC (LIBOPENCORE_AMRNB, libopencore_amrnb);
REGISTER_DECODER (LIBOPENCORE_AMRWB, libopencore_amrwb);
diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c
index 3d4f2bd..c411d57 100644
--- a/libavcodec/alsdec.c
+++ b/libavcodec/alsdec.c
@@ -756,7 +756,7 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd)
int delta[8];
unsigned int k [8];
unsigned int b = av_clip((av_ceil_log2(bd->block_length) - 3) >> 1, 0, 5);
- unsigned int i = start;
+ unsigned int i;
// read most significant bits
unsigned int high;
@@ -767,7 +767,7 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd)
current_res = bd->raw_samples + start;
- for (sb = 0; sb < sub_blocks; sb++, i = 0) {
+ for (sb = 0; sb < sub_blocks; sb++) {
k [sb] = s[sb] > b ? s[sb] - b : 0;
delta[sb] = 5 - s[sb] + k[sb];
diff --git a/libavcodec/amr.h b/libavcodec/amr.h
index ae6e4d1..9498d57 100644
--- a/libavcodec/amr.h
+++ b/libavcodec/amr.h
@@ -61,7 +61,7 @@ static inline void ff_amr_bit_reorder(uint16_t *out, int size,
field <<= 1;
field |= data[bit >> 3] >> (bit & 7) & 1;
}
- out[field_offset] = field;
+ out[field_offset >> 1] = field;
}
}
diff --git a/libavcodec/amrnbdata.h b/libavcodec/amrnbdata.h
index 26ff7fb..c2e2f8a 100644
--- a/libavcodec/amrnbdata.h
+++ b/libavcodec/amrnbdata.h
@@ -71,7 +71,7 @@ typedef struct {
} AMRNBFrame;
/** The index of a frame parameter */
-#define AMR_BIT(field) (offsetof(AMRNBFrame, field) >> 1)
+#define AMR_BIT(field) (offsetof(AMRNBFrame, field))
/** The index of a subframe-specific parameter */
#define AMR_OF(frame_num, variable) AMR_BIT(subframe[frame_num].variable)
diff --git a/libavcodec/amrwbdata.h b/libavcodec/amrwbdata.h
index 5421c23..83a93e9 100644
--- a/libavcodec/amrwbdata.h
+++ b/libavcodec/amrwbdata.h
@@ -82,7 +82,7 @@ typedef struct {
} AMRWBFrame;
/** The index of a frame parameter */
-#define AMR_BIT(field) (offsetof(AMRWBFrame, field) >> 1)
+#define AMR_BIT(field) (offsetof(AMRWBFrame, field))
/** The index of a subframe-specific parameter */
#define AMR_OF(frame_num, variable) AMR_BIT(subframe[frame_num].variable)
diff --git a/libavcodec/anm.c b/libavcodec/anm.c
index 831cdfb..d979ba4 100644
--- a/libavcodec/anm.c
+++ b/libavcodec/anm.c
@@ -55,8 +55,9 @@ static av_cold int decode_init(AVCodecContext *avctx)
/**
* Perform decode operation
- * @param dst, dst_end Destination image buffer
- * @param gb, GetByteContext (optional, see below)
+ * @param dst pointer to destination image buffer
+ * @param dst_end pointer to end of destination image buffer
+ * @param gb GetByteContext (optional, see below)
* @param pixel Fill color (optional, see below)
* @param count Pixel count
* @param x Pointer to x-axis counter
@@ -65,8 +66,8 @@ static av_cold int decode_init(AVCodecContext *avctx)
* @return non-zero if destination buffer is exhausted
*
* a copy operation is achieved when 'gb' is set
- * a fill operation is acheived when 'gb' is null and pixel is >= 0
- * a skip operation is acheived when 'gb' is null and pixel is < 0
+ * a fill operation is achieved when 'gb' is null and pixel is >= 0
+ * a skip operation is achieved when 'gb' is null and pixel is < 0
*/
static inline int op(uint8_t **dst, const uint8_t *dst_end,
GetByteContext *gb,
diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c
index e41f555..b07f3a0 100644
--- a/libavcodec/apedec.c
+++ b/libavcodec/apedec.c
@@ -393,7 +393,7 @@ static inline int range_get_symbol(APEContext *ctx,
}
/** @} */ // group rangecoder
-static inline void update_rice(APERice *rice, int x)
+static inline void update_rice(APERice *rice, unsigned int x)
{
int lim = rice->k ? (1 << (rice->k + 4)) : 0;
rice->ksum += ((x + 1) / 2) - ((rice->ksum + 16) >> 5);
@@ -406,7 +406,7 @@ static inline void update_rice(APERice *rice, int x)
static inline int ape_decode_value(APEContext *ctx, APERice *rice)
{
- int x, overflow;
+ unsigned int x, overflow;
if (ctx->fileversion < 3990) {
int tmpk;
diff --git a/libavcodec/arm/Makefile b/libavcodec/arm/Makefile
index 3d002cc..d2bdd50 100644
--- a/libavcodec/arm/Makefile
+++ b/libavcodec/arm/Makefile
@@ -1,7 +1,8 @@
OBJS-$(CONFIG_AC3DSP) += arm/ac3dsp_init_arm.o \
arm/ac3dsp_arm.o
-OBJS-$(CONFIG_AAC_DECODER) += arm/sbrdsp_init_arm.o
+OBJS-$(CONFIG_AAC_DECODER) += arm/sbrdsp_init_arm.o \
+ arm/aacpsdsp_init_arm.o
OBJS-$(CONFIG_DCA_DECODER) += arm/dcadsp_init_arm.o \
@@ -59,7 +60,8 @@ NEON-OBJS-$(CONFIG_H264PRED) += arm/h264pred_neon.o \
NEON-OBJS-$(CONFIG_AC3DSP) += arm/ac3dsp_neon.o
-NEON-OBJS-$(CONFIG_AAC_DECODER) += arm/sbrdsp_neon.o
+NEON-OBJS-$(CONFIG_AAC_DECODER) += arm/sbrdsp_neon.o \
+ arm/aacpsdsp_neon.o
NEON-OBJS-$(CONFIG_DCA_DECODER) += arm/dcadsp_neon.o \
arm/synth_filter_neon.o \
diff --git a/libavcodec/arm/aacpsdsp_init_arm.c b/libavcodec/arm/aacpsdsp_init_arm.c
new file mode 100644
index 0000000..6326376
--- /dev/null
+++ b/libavcodec/arm/aacpsdsp_init_arm.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012 Mans Rullgard
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+
+#include "libavutil/arm/cpu.h"
+#include "libavutil/attributes.h"
+#include "libavcodec/aacpsdsp.h"
+
+void ff_ps_add_squares_neon(float *dst, const float (*src)[2], int n);
+void ff_ps_mul_pair_single_neon(float (*dst)[2], float (*src0)[2],
+ float *src1, int n);
+void ff_ps_hybrid_analysis_neon(float (*out)[2], float (*in)[2],
+ const float (*filter)[8][2],
+ int stride, int n);
+void ff_ps_hybrid_analysis_ileave_neon(float (*out)[32][2], float L[2][38][64],
+ int i, int len);
+void ff_ps_hybrid_synthesis_deint_neon(float out[2][38][64], float (*in)[32][2],
+ int i, int len);
+void ff_ps_decorrelate_neon(float (*out)[2], float (*delay)[2],
+ float (*ap_delay)[PS_QMF_TIME_SLOTS+PS_MAX_AP_DELAY][2],
+ const float phi_fract[2], float (*Q_fract)[2],
+ const float *transient_gain, float g_decay_slope,
+ int len);
+void ff_ps_stereo_interpolate_neon(float (*l)[2], float (*r)[2],
+ float h[2][4], float h_step[2][4],
+ int len);
+
+av_cold void ff_psdsp_init_arm(PSDSPContext *s)
+{
+ int cpu_flags = av_get_cpu_flags();
+
+ if (have_neon(cpu_flags)) {
+ s->add_squares = ff_ps_add_squares_neon;
+ s->mul_pair_single = ff_ps_mul_pair_single_neon;
+ s->hybrid_synthesis_deint = ff_ps_hybrid_synthesis_deint_neon;
+ s->hybrid_analysis = ff_ps_hybrid_analysis_neon;
+ s->stereo_interpolate[0] = ff_ps_stereo_interpolate_neon;
+ }
+}
diff --git a/libavcodec/arm/aacpsdsp_neon.S b/libavcodec/arm/aacpsdsp_neon.S
new file mode 100644
index 0000000..fb00900
--- /dev/null
+++ b/libavcodec/arm/aacpsdsp_neon.S
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2012 Mans Rullgard
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/arm/asm.S"
+
+function ff_ps_add_squares_neon, export=1
+ mov r3, r0
+ sub r2, r2, #4
+ vld1.32 {q0}, [r1,:128]!
+ vmul.f32 q0, q0, q0
+ vld1.32 {q2}, [r1,:128]!
+ vmul.f32 q2, q2, q2
+ vld1.32 {q1}, [r0,:128]!
+1:
+ vpadd.f32 d6, d0, d1
+ vld1.32 {q0}, [r1,:128]!
+ vpadd.f32 d7, d4, d5
+ vmul.f32 q0, q0, q0
+ vld1.32 {q2}, [r1,:128]!
+ vadd.f32 q3, q1, q3
+ vld1.32 {q1}, [r0,:128]!
+ vmul.f32 q2, q2, q2
+ vst1.32 {q3}, [r3,:128]!
+ subs r2, r2, #4
+ bgt 1b
+ vpadd.f32 d6, d0, d1
+ vpadd.f32 d7, d4, d5
+ vadd.f32 q1, q1, q3
+ vst1.32 {q1}, [r3,:128]!
+ bx lr
+endfunc
+
+function ff_ps_mul_pair_single_neon, export=1
+ sub r3, r3, #4
+ tst r1, #8
+ bne 2f
+ vld1.32 {q0}, [r1,:128]!
+1:
+ vld1.32 {q3}, [r2,:128]!
+ vmul.f32 d4, d0, d6[0]
+ vmul.f32 d5, d1, d6[1]
+ vld1.32 {q1}, [r1,:128]!
+ vmul.f32 d6, d2, d7[0]
+ vmul.f32 d7, d3, d7[1]
+ vld1.32 {q0}, [r1,:128]!
+ vst1.32 {q2,q3}, [r0,:128]!
+ subs r3, r3, #4
+ bgt 1b
+ vld1.32 {q3}, [r2,:128]!
+ vmul.f32 d4, d0, d6[0]
+ vmul.f32 d5, d1, d6[1]
+ vld1.32 {q1}, [r1,:128]!
+ vmul.f32 d6, d2, d7[0]
+ vmul.f32 d7, d3, d7[1]
+ vst1.32 {q2,q3}, [r0,:128]!
+ bx lr
+2:
+ vld1.32 {d0}, [r1,:64]!
+ vld1.32 {d1,d2}, [r1,:128]!
+1:
+ vld1.32 {q3}, [r2,:128]!
+ vmul.f32 d4, d0, d6[0]
+ vmul.f32 d5, d1, d6[1]
+ vld1.32 {d0,d1}, [r1,:128]!
+ vmul.f32 d6, d2, d7[0]
+ vmul.f32 d7, d0, d7[1]
+ vmov d0, d1
+ vld1.32 {d1,d2}, [r1,:128]!
+ vst1.32 {q2,q3}, [r0,:128]!
+ subs r3, r3, #4
+ bgt 1b
+ vld1.32 {q3}, [r2,:128]!
+ vmul.f32 d4, d0, d6[0]
+ vmul.f32 d5, d1, d6[1]
+ vld1.32 {d0}, [r1,:64]!
+ vmul.f32 d6, d2, d7[0]
+ vmul.f32 d7, d0, d7[1]
+ vst1.32 {q2,q3}, [r0,:128]!
+ bx lr
+endfunc
+
+function ff_ps_hybrid_synthesis_deint_neon, export=1
+ push {r4-r8,lr}
+ add r0, r0, r2, lsl #2
+ add r1, r1, r2, lsl #5+1+2
+ rsb r2, r2, #64
+ mov r5, #64*4
+ mov lr, r0
+ add r4, r0, #38*64*4
+ mov r12, r3
+2:
+ vld1.32 {d0,d1}, [r1,:128]!
+ vst1.32 {d0[0]}, [lr,:32], r5
+ vst1.32 {d0[1]}, [r4,:32], r5
+ vst1.32 {d1[0]}, [lr,:32], r5
+ vst1.32 {d1[1]}, [r4,:32], r5
+ subs r12, r12, #2
+ bgt 2b
+ add r0, r0, #4
+ sub r2, r2, #1
+ tst r2, #2
+ bne 6f
+1:
+ mov lr, r0
+ add r4, r0, #38*64*4
+ add r6, r1, # 32*2*4
+ add r7, r1, #2*32*2*4
+ add r8, r1, #3*32*2*4
+ mov r12, r3
+2:
+ vld1.32 {d0,d1}, [r1,:128]!
+ vld1.32 {d2,d3}, [r6,:128]!
+ vld1.32 {d4,d5}, [r7,:128]!
+ vld1.32 {d6,d7}, [r8,:128]!
+ vst4.32 {d0[0],d2[0],d4[0],d6[0]}, [lr,:128], r5
+ vst4.32 {d0[1],d2[1],d4[1],d6[1]}, [r4,:128], r5
+ vst4.32 {d1[0],d3[0],d5[0],d7[0]}, [lr,:128], r5
+ vst4.32 {d1[1],d3[1],d5[1],d7[1]}, [r4,:128], r5
+ subs r12, r12, #2
+ bgt 2b
+ add r0, r0, #16
+ add r1, r1, #3*32*2*4
+ subs r2, r2, #4
+ bgt 1b
+ pop {r4-r8,pc}
+6:
+ mov lr, r0
+ add r4, r0, #38*64*4
+ add r6, r1, #32*2*4
+ mov r12, r3
+2:
+ vld1.32 {d0,d1}, [r1,:128]!
+ vld1.32 {d2,d3}, [r6,:128]!
+ vst2.32 {d0[0],d2[0]}, [lr,:64], r5
+ vst2.32 {d0[1],d2[1]}, [r4,:64], r5
+ vst2.32 {d1[0],d3[0]}, [lr,:64], r5
+ vst2.32 {d1[1],d3[1]}, [r4,:64], r5
+ subs r12, r12, #2
+ bgt 2b
+ add r0, r0, #8
+ add r1, r1, #32*2*4
+ sub r2, r2, #2
+ b 1b
+endfunc
+
+function ff_ps_hybrid_analysis_neon, export=1
+ vldm r1, {d19-d31}
+ ldr r12, [sp]
+ lsl r3, r3, #3
+ vadd.f32 d16, d19, d31
+ vadd.f32 d17, d20, d30
+ vsub.f32 d18, d19, d31
+ vsub.f32 d19, d20, d30
+ vsub.f32 d0, d21, d29
+ vsub.f32 d1, d22, d28
+ vadd.f32 d2, d21, d29
+ vadd.f32 d3, d22, d28
+ vadd.f32 d20, d23, d27
+ vadd.f32 d21, d24, d26
+ vsub.f32 d22, d23, d27
+ vsub.f32 d23, d24, d26
+ vmov.i32 d6, #1<<31
+ vmov.i32 d7, #0
+ vmov.f32 q14, #0.0
+ vmov.f32 q15, #0.0
+ vtrn.32 d6, d7
+ vrev64.32 q9, q9
+ vrev64.32 q0, q0
+ vrev64.32 q11, q11
+ veor q9, q9, q3
+ veor q0, q0, q3
+ veor q11, q11, q3
+ vld1.32 {q13}, [r2,:128]!
+ vtrn.32 q8, q9
+ vtrn.32 q1, q0
+ vtrn.32 q10, q11
+ sub r12, r12, #1
+ vmla.f32 q14, q8, q13
+ vld1.32 {q2}, [r2,:128]!
+ vmla.f32 q15, q9, q13
+1:
+ vmla.f32 q14, q1, q2
+ vld1.32 {q13}, [r2,:128]!
+ vmla.f32 q15, q0, q2
+ vmla.f32 q14, q10, q13
+ vld1.32 {q2}, [r2,:128]!
+ vmla.f32 q15, q11, q13
+ vld1.32 {q13}, [r2,:128]!
+ vadd.f32 d6, d28, d29
+ vadd.f32 d7, d30, d31
+ vmov.f32 q14, #0.0
+ vmov.f32 q15, #0.0
+ vmla.f32 q14, q8, q13
+ vpadd.f32 d6, d6, d7
+ vmla.f32 q15, q9, q13
+ vmla.f32 d6, d25, d4[0]
+ vld1.32 {q2}, [r2,:128]!
+ vst1.32 {d6}, [r0,:64], r3
+ subs r12, r12, #1
+ bgt 1b
+ vmla.f32 q14, q1, q2
+ vld1.32 {q13}, [r2,:128]!
+ vmla.f32 q15, q0, q2
+ vmla.f32 q14, q10, q13
+ vld1.32 {q2}, [r2,:128]!
+ vmla.f32 q15, q11, q13
+ vadd.f32 d6, d28, d29
+ vadd.f32 d7, d30, d31
+ vpadd.f32 d6, d6, d7
+ vmla.f32 d6, d25, d4[0]
+ vst1.32 {d6}, [r0,:64], r3
+ bx lr
+endfunc
+
+function ff_ps_stereo_interpolate_neon, export=1
+ vld1.32 {q0}, [r2]
+ vld1.32 {q14}, [r3]
+ vadd.f32 q15, q14, q14
+ mov r2, r0
+ mov r3, r1
+ ldr r12, [sp]
+ vadd.f32 q1, q0, q14
+ vadd.f32 q0, q0, q15
+ vld1.32 {q2}, [r0,:64]!
+ vld1.32 {q3}, [r1,:64]!
+ subs r12, r12, #1
+ beq 2f
+1:
+ vmul.f32 d16, d4, d2[0]
+ vmul.f32 d17, d5, d0[0]
+ vmul.f32 d18, d4, d2[1]
+ vmul.f32 d19, d5, d0[1]
+ vmla.f32 d16, d6, d3[0]
+ vmla.f32 d17, d7, d1[0]
+ vmla.f32 d18, d6, d3[1]
+ vmla.f32 d19, d7, d1[1]
+ vadd.f32 q1, q1, q15
+ vadd.f32 q0, q0, q15
+ vld1.32 {q2}, [r0,:64]!
+ vld1.32 {q3}, [r1,:64]!
+ vst1.32 {q8}, [r2,:64]!
+ vst1.32 {q9}, [r3,:64]!
+ subs r12, r12, #2
+ bgt 1b
+ it lt
+ bxlt lr
+2:
+ vmul.f32 d16, d4, d2[0]
+ vmul.f32 d18, d4, d2[1]
+ vmla.f32 d16, d6, d3[0]
+ vmla.f32 d18, d6, d3[1]
+ vst1.32 {d16}, [r2,:64]!
+ vst1.32 {d18}, [r3,:64]!
+ bx lr
+endfunc
diff --git a/libavcodec/arm/ac3dsp_arm.S b/libavcodec/arm/ac3dsp_arm.S
index 9a7d20e..ed8eb37 100644
--- a/libavcodec/arm/ac3dsp_arm.S
+++ b/libavcodec/arm/ac3dsp_arm.S
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
function ff_ac3_update_bap_counts_arm, export=1
push {lr}
diff --git a/libavcodec/arm/ac3dsp_armv6.S b/libavcodec/arm/ac3dsp_armv6.S
index df8bfba..f6f297a 100644
--- a/libavcodec/arm/ac3dsp_armv6.S
+++ b/libavcodec/arm/ac3dsp_armv6.S
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
function ff_ac3_bit_alloc_calc_bap_armv6, export=1
ldr r12, [sp]
@@ -26,8 +26,8 @@ function ff_ac3_bit_alloc_calc_bap_armv6, export=1
beq 4f
push {r4-r11,lr}
add r5, sp, #40
- movrel r4, X(ff_ac3_bin_to_band_tab)
- movrel lr, X(ff_ac3_band_start_tab)
+ movrelx r4, X(ff_ac3_bin_to_band_tab), r11
+ movrelx lr, X(ff_ac3_band_start_tab)
ldm r5, {r5-r7}
ldrb r4, [r4, r2]
add r1, r1, r2, lsl #1 @ psd + start
diff --git a/libavcodec/arm/ac3dsp_neon.S b/libavcodec/arm/ac3dsp_neon.S
index e97197c..82ff8af 100644
--- a/libavcodec/arm/ac3dsp_neon.S
+++ b/libavcodec/arm/ac3dsp_neon.S
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
function ff_ac3_max_msb_abs_int16_neon, export=1
vmov.i16 q0, #0
diff --git a/libavcodec/arm/asm.S b/libavcodec/arm/asm.S
deleted file mode 100644
index 6038a63..0000000
--- a/libavcodec/arm/asm.S
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright (c) 2008 Mans Rullgard <mans at mansr.com>
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config.h"
-
-#ifdef __ELF__
-# define ELF
-#else
-# define ELF @
-#endif
-
-#if CONFIG_THUMB
-# define A @
-# define T
-#else
-# define A
-# define T @
-#endif
-
-#if HAVE_NEON
- .arch armv7-a
-#elif HAVE_ARMV6T2
- .arch armv6t2
-#elif HAVE_ARMV6
- .arch armv6
-#elif HAVE_ARMV5TE
- .arch armv5te
-#endif
-
-#if HAVE_NEON
- .fpu neon
-#elif HAVE_ARMVFP
- .fpu vfp
-#endif
-
- .syntax unified
-T .thumb
-
-.macro require8 val=1
-ELF .eabi_attribute 24, \val
-.endm
-
-.macro preserve8 val=1
-ELF .eabi_attribute 25, \val
-.endm
-
-.macro function name, export=0
- .macro endfunc
-ELF .size \name, . - \name
- .endfunc
- .purgem endfunc
- .endm
- .text
- .align 2
- .if \export
- .global EXTERN_ASM\name
-EXTERN_ASM\name:
- .endif
-ELF .type \name, %function
- .func \name
-\name:
-.endm
-
-.macro const name, align=2
- .macro endconst
-ELF .size \name, . - \name
- .purgem endconst
- .endm
- .section .rodata
- .align \align
-\name:
-.endm
-
-#if !HAVE_ARMV6T2
-.macro movw rd, val
- mov \rd, \val & 255
- orr \rd, \val & ~255
-.endm
-#endif
-
-.macro mov32 rd, val
-#if HAVE_ARMV6T2
- movw \rd, #(\val) & 0xffff
- .if (\val) >> 16
- movt \rd, #(\val) >> 16
- .endif
-#else
- ldr \rd, =\val
-#endif
-.endm
-
-.macro movrel rd, val
-#if HAVE_ARMV6T2 && !CONFIG_PIC && !defined(__APPLE__)
- movw \rd, #:lower16:\val
- movt \rd, #:upper16:\val
-#else
- ldr \rd, =\val
-#endif
-.endm
-
-.macro ldr_pre rt, rn, rm:vararg
-A ldr \rt, [\rn, \rm]!
-T add \rn, \rn, \rm
-T ldr \rt, [\rn]
-.endm
-
-.macro ldr_dpre rt, rn, rm:vararg
-A ldr \rt, [\rn, -\rm]!
-T sub \rn, \rn, \rm
-T ldr \rt, [\rn]
-.endm
-
-.macro ldr_nreg rt, rn, rm:vararg
-A ldr \rt, [\rn, -\rm]
-T sub \rt, \rn, \rm
-T ldr \rt, [\rt]
-.endm
-
-.macro ldr_post rt, rn, rm:vararg
-A ldr \rt, [\rn], \rm
-T ldr \rt, [\rn]
-T add \rn, \rn, \rm
-.endm
-
-.macro ldrd_reg rt, rt2, rn, rm
-A ldrd \rt, \rt2, [\rn, \rm]
-T add \rt, \rn, \rm
-T ldrd \rt, \rt2, [\rt]
-.endm
-
-.macro ldrd_post rt, rt2, rn, rm
-A ldrd \rt, \rt2, [\rn], \rm
-T ldrd \rt, \rt2, [\rn]
-T add \rn, \rn, \rm
-.endm
-
-.macro ldrh_pre rt, rn, rm
-A ldrh \rt, [\rn, \rm]!
-T add \rn, \rn, \rm
-T ldrh \rt, [\rn]
-.endm
-
-.macro ldrh_dpre rt, rn, rm
-A ldrh \rt, [\rn, -\rm]!
-T sub \rn, \rn, \rm
-T ldrh \rt, [\rn]
-.endm
-
-.macro ldrh_post rt, rn, rm
-A ldrh \rt, [\rn], \rm
-T ldrh \rt, [\rn]
-T add \rn, \rn, \rm
-.endm
-
-.macro ldrb_post rt, rn, rm
-A ldrb \rt, [\rn], \rm
-T ldrb \rt, [\rn]
-T add \rn, \rn, \rm
-.endm
-
-.macro str_post rt, rn, rm:vararg
-A str \rt, [\rn], \rm
-T str \rt, [\rn]
-T add \rn, \rn, \rm
-.endm
-
-.macro strb_post rt, rn, rm:vararg
-A strb \rt, [\rn], \rm
-T strb \rt, [\rn]
-T add \rn, \rn, \rm
-.endm
-
-.macro strd_post rt, rt2, rn, rm
-A strd \rt, \rt2, [\rn], \rm
-T strd \rt, \rt2, [\rn]
-T add \rn, \rn, \rm
-.endm
-
-.macro strh_pre rt, rn, rm
-A strh \rt, [\rn, \rm]!
-T add \rn, \rn, \rm
-T strh \rt, [\rn]
-.endm
-
-.macro strh_dpre rt, rn, rm
-A strh \rt, [\rn, -\rm]!
-T sub \rn, \rn, \rm
-T strh \rt, [\rn]
-.endm
-
-.macro strh_post rt, rn, rm
-A strh \rt, [\rn], \rm
-T strh \rt, [\rn]
-T add \rn, \rn, \rm
-.endm
-
-.macro strh_dpost rt, rn, rm
-A strh \rt, [\rn], -\rm
-T strh \rt, [\rn]
-T sub \rn, \rn, \rm
-.endm
-
-#if HAVE_VFP_ARGS
- .eabi_attribute 28, 1
-# define VFP
-# define NOVFP @
-#else
-# define VFP @
-# define NOVFP
-#endif
-
-#define GLUE(a, b) a ## b
-#define JOIN(a, b) GLUE(a, b)
-#define X(s) JOIN(EXTERN_ASM, s)
diff --git a/libavcodec/arm/dcadsp_neon.S b/libavcodec/arm/dcadsp_neon.S
index 71f5dd8..fe3aae8 100644
--- a/libavcodec/arm/dcadsp_neon.S
+++ b/libavcodec/arm/dcadsp_neon.S
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
function ff_dca_lfe_fir_neon, export=1
push {r4-r6,lr}
diff --git a/libavcodec/arm/dsputil_arm.S b/libavcodec/arm/dsputil_arm.S
index 136551f..dd65f70 100644
--- a/libavcodec/arm/dsputil_arm.S
+++ b/libavcodec/arm/dsputil_arm.S
@@ -20,7 +20,7 @@
@
#include "config.h"
-#include "asm.S"
+#include "libavutil/arm/asm.S"
preserve8
diff --git a/libavcodec/arm/dsputil_armv6.S b/libavcodec/arm/dsputil_armv6.S
index becf851..6eabeee 100644
--- a/libavcodec/arm/dsputil_armv6.S
+++ b/libavcodec/arm/dsputil_armv6.S
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
preserve8
diff --git a/libavcodec/arm/dsputil_init_neon.c b/libavcodec/arm/dsputil_init_neon.c
index d3ef850..65db20d 100644
--- a/libavcodec/arm/dsputil_init_neon.c
+++ b/libavcodec/arm/dsputil_init_neon.c
@@ -150,13 +150,10 @@ void ff_avg_h264_chroma_mc2_neon(uint8_t *, uint8_t *, int, int, int, int);
void ff_vp3_v_loop_filter_neon(uint8_t *, int, int *);
void ff_vp3_h_loop_filter_neon(uint8_t *, int, int *);
-void ff_vector_fmul_neon(float *dst, const float *src0, const float *src1, int len);
void ff_vector_fmul_window_neon(float *dst, const float *src0,
const float *src1, const float *win, int len);
void ff_vector_fmul_scalar_neon(float *dst, const float *src, float mul,
int len);
-void ff_vector_fmac_scalar_neon(float *dst, const float *src, float mul,
- int len);
void ff_butterflies_float_neon(float *v1, float *v2, int len);
float ff_scalarproduct_float_neon(const float *v1, const float *v2, int len);
void ff_vector_fmul_reverse_neon(float *dst, const float *src0,
@@ -328,10 +325,8 @@ void ff_dsputil_init_neon(DSPContext *c, AVCodecContext *avctx)
c->vp3_idct_dc_add = ff_vp3_idct_dc_add_neon;
}
- c->vector_fmul = ff_vector_fmul_neon;
c->vector_fmul_window = ff_vector_fmul_window_neon;
c->vector_fmul_scalar = ff_vector_fmul_scalar_neon;
- c->vector_fmac_scalar = ff_vector_fmac_scalar_neon;
c->butterflies_float = ff_butterflies_float_neon;
c->scalarproduct_float = ff_scalarproduct_float_neon;
c->vector_fmul_reverse = ff_vector_fmul_reverse_neon;
diff --git a/libavcodec/arm/dsputil_init_vfp.c b/libavcodec/arm/dsputil_init_vfp.c
index d5e2d3b..d77d686 100644
--- a/libavcodec/arm/dsputil_init_vfp.c
+++ b/libavcodec/arm/dsputil_init_vfp.c
@@ -18,20 +18,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "libavutil/arm/cpu.h"
#include "libavcodec/dsputil.h"
#include "dsputil_arm.h"
-void ff_vector_fmul_vfp(float *dst, const float *src0,
- const float *src1, int len);
void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
const float *src1, int len);
void ff_dsputil_init_vfp(DSPContext* c, AVCodecContext *avctx)
{
- int cpu_flags = av_get_cpu_flags();
-
- if (!have_vfpv3(cpu_flags))
- c->vector_fmul = ff_vector_fmul_vfp;
c->vector_fmul_reverse = ff_vector_fmul_reverse_vfp;
}
diff --git a/libavcodec/arm/dsputil_neon.S b/libavcodec/arm/dsputil_neon.S
index d49aedd..358ed61 100644
--- a/libavcodec/arm/dsputil_neon.S
+++ b/libavcodec/arm/dsputil_neon.S
@@ -20,7 +20,7 @@
*/
#include "config.h"
-#include "asm.S"
+#include "libavutil/arm/asm.S"
preserve8
@@ -44,22 +44,22 @@ endfunc
.if \avg
mov r12, r0
.endif
-1: vld1.64 {q0}, [r1], r2
- vld1.64 {q1}, [r1], r2
- vld1.64 {q2}, [r1], r2
+1: vld1.8 {q0}, [r1], r2
+ vld1.8 {q1}, [r1], r2
+ vld1.8 {q2}, [r1], r2
pld [r1, r2, lsl #2]
- vld1.64 {q3}, [r1], r2
+ vld1.8 {q3}, [r1], r2
pld [r1]
pld [r1, r2]
pld [r1, r2, lsl #1]
.if \avg
- vld1.64 {q8}, [r12,:128], r2
+ vld1.8 {q8}, [r12,:128], r2
vrhadd.u8 q0, q0, q8
- vld1.64 {q9}, [r12,:128], r2
+ vld1.8 {q9}, [r12,:128], r2
vrhadd.u8 q1, q1, q9
- vld1.64 {q10}, [r12,:128], r2
+ vld1.8 {q10}, [r12,:128], r2
vrhadd.u8 q2, q2, q10
- vld1.64 {q11}, [r12,:128], r2
+ vld1.8 {q11}, [r12,:128], r2
vrhadd.u8 q3, q3, q11
.endif
subs r3, r3, #4
@@ -72,8 +72,8 @@ endfunc
.endm
.macro pixels16_x2 rnd=1, avg=0
-1: vld1.64 {d0-d2}, [r1], r2
- vld1.64 {d4-d6}, [r1], r2
+1: vld1.8 {d0-d2}, [r1], r2
+ vld1.8 {d4-d6}, [r1], r2
pld [r1]
pld [r1, r2]
subs r3, r3, #2
@@ -88,20 +88,21 @@ endfunc
vrhadd.u8 q2, q2, q3
sub r0, r0, r2
.endif
- vst1.64 {q0}, [r0,:128], r2
- vst1.64 {q2}, [r0,:128], r2
+ vst1.8 {q0}, [r0,:128], r2
+ vst1.8 {q2}, [r0,:128], r2
bne 1b
bx lr
.endm
.macro pixels16_y2 rnd=1, avg=0
- vld1.64 {q0}, [r1], r2
- vld1.64 {q1}, [r1], r2
+ sub r3, r3, #2
+ vld1.8 {q0}, [r1], r2
+ vld1.8 {q1}, [r1], r2
1: subs r3, r3, #2
avg q2, q0, q1
- vld1.64 {q0}, [r1], r2
+ vld1.8 {q0}, [r1], r2
avg q3, q0, q1
- vld1.64 {q1}, [r1], r2
+ vld1.8 {q1}, [r1], r2
pld [r1]
pld [r1, r2]
.if \avg
@@ -111,18 +112,31 @@ endfunc
vrhadd.u8 q3, q3, q9
sub r0, r0, r2
.endif
- vst1.64 {q2}, [r0,:128], r2
- vst1.64 {q3}, [r0,:128], r2
+ vst1.8 {q2}, [r0,:128], r2
+ vst1.8 {q3}, [r0,:128], r2
bne 1b
+
+ avg q2, q0, q1
+ vld1.8 {q0}, [r1], r2
+ avg q3, q0, q1
+ .if \avg
+ vld1.8 {q8}, [r0,:128], r2
+ vld1.8 {q9}, [r0,:128]
+ vrhadd.u8 q2, q2, q8
+ vrhadd.u8 q3, q3, q9
+ sub r0, r0, r2
+ .endif
+ vst1.8 {q2}, [r0,:128], r2
+ vst1.8 {q3}, [r0,:128], r2
+
bx lr
.endm
.macro pixels16_xy2 rnd=1, avg=0
- vld1.64 {d0-d2}, [r1], r2
- vld1.64 {d4-d6}, [r1], r2
- .ifeq \rnd
- vmov.i16 q13, #1
- .endif
+ sub r3, r3, #2
+ vld1.8 {d0-d2}, [r1], r2
+ vld1.8 {d4-d6}, [r1], r2
+NRND vmov.i16 q13, #1
pld [r1]
pld [r1, r2]
vext.8 q1, q0, q1, #1
@@ -132,38 +146,30 @@ endfunc
vaddl.u8 q9, d4, d6
vaddl.u8 q11, d5, d7
1: subs r3, r3, #2
- vld1.64 {d0-d2}, [r1], r2
+ vld1.8 {d0-d2}, [r1], r2
vadd.u16 q12, q8, q9
pld [r1]
- .ifeq \rnd
- vadd.u16 q12, q12, q13
- .endif
+NRND vadd.u16 q12, q12, q13
vext.8 q15, q0, q1, #1
vadd.u16 q1 , q10, q11
shrn d28, q12, #2
- .ifeq \rnd
- vadd.u16 q1, q1, q13
- .endif
+NRND vadd.u16 q1, q1, q13
shrn d29, q1, #2
.if \avg
vld1.8 {q8}, [r0,:128]
vrhadd.u8 q14, q14, q8
.endif
vaddl.u8 q8, d0, d30
- vld1.64 {d2-d4}, [r1], r2
+ vld1.8 {d2-d4}, [r1], r2
vaddl.u8 q10, d1, d31
- vst1.64 {q14}, [r0,:128], r2
+ vst1.8 {q14}, [r0,:128], r2
vadd.u16 q12, q8, q9
pld [r1, r2]
- .ifeq \rnd
- vadd.u16 q12, q12, q13
- .endif
+NRND vadd.u16 q12, q12, q13
vext.8 q2, q1, q2, #1
vadd.u16 q0, q10, q11
shrn d30, q12, #2
- .ifeq \rnd
- vadd.u16 q0, q0, q13
- .endif
+NRND vadd.u16 q0, q0, q13
shrn d31, q0, #2
.if \avg
vld1.8 {q9}, [r0,:128]
@@ -171,44 +177,72 @@ endfunc
.endif
vaddl.u8 q9, d2, d4
vaddl.u8 q11, d3, d5
- vst1.64 {q15}, [r0,:128], r2
+ vst1.8 {q15}, [r0,:128], r2
bgt 1b
+
+ vld1.8 {d0-d2}, [r1], r2
+ vadd.u16 q12, q8, q9
+NRND vadd.u16 q12, q12, q13
+ vext.8 q15, q0, q1, #1
+ vadd.u16 q1 , q10, q11
+ shrn d28, q12, #2
+NRND vadd.u16 q1, q1, q13
+ shrn d29, q1, #2
+ .if \avg
+ vld1.8 {q8}, [r0,:128]
+ vrhadd.u8 q14, q14, q8
+ .endif
+ vaddl.u8 q8, d0, d30
+ vaddl.u8 q10, d1, d31
+ vst1.8 {q14}, [r0,:128], r2
+ vadd.u16 q12, q8, q9
+NRND vadd.u16 q12, q12, q13
+ vadd.u16 q0, q10, q11
+ shrn d30, q12, #2
+NRND vadd.u16 q0, q0, q13
+ shrn d31, q0, #2
+ .if \avg
+ vld1.8 {q9}, [r0,:128]
+ vrhadd.u8 q15, q15, q9
+ .endif
+ vst1.8 {q15}, [r0,:128], r2
+
bx lr
.endm
.macro pixels8 rnd=1, avg=0
-1: vld1.64 {d0}, [r1], r2
- vld1.64 {d1}, [r1], r2
- vld1.64 {d2}, [r1], r2
+1: vld1.8 {d0}, [r1], r2
+ vld1.8 {d1}, [r1], r2
+ vld1.8 {d2}, [r1], r2
pld [r1, r2, lsl #2]
- vld1.64 {d3}, [r1], r2
+ vld1.8 {d3}, [r1], r2
pld [r1]
pld [r1, r2]
pld [r1, r2, lsl #1]
.if \avg
- vld1.64 {d4}, [r0,:64], r2
+ vld1.8 {d4}, [r0,:64], r2
vrhadd.u8 d0, d0, d4
- vld1.64 {d5}, [r0,:64], r2
+ vld1.8 {d5}, [r0,:64], r2
vrhadd.u8 d1, d1, d5
- vld1.64 {d6}, [r0,:64], r2
+ vld1.8 {d6}, [r0,:64], r2
vrhadd.u8 d2, d2, d6
- vld1.64 {d7}, [r0,:64], r2
+ vld1.8 {d7}, [r0,:64], r2
vrhadd.u8 d3, d3, d7
sub r0, r0, r2, lsl #2
.endif
subs r3, r3, #4
- vst1.64 {d0}, [r0,:64], r2
- vst1.64 {d1}, [r0,:64], r2
- vst1.64 {d2}, [r0,:64], r2
- vst1.64 {d3}, [r0,:64], r2
+ vst1.8 {d0}, [r0,:64], r2
+ vst1.8 {d1}, [r0,:64], r2
+ vst1.8 {d2}, [r0,:64], r2
+ vst1.8 {d3}, [r0,:64], r2
bne 1b
bx lr
.endm
.macro pixels8_x2 rnd=1, avg=0
-1: vld1.64 {q0}, [r1], r2
+1: vld1.8 {q0}, [r1], r2
vext.8 d1, d0, d1, #1
- vld1.64 {q1}, [r1], r2
+ vld1.8 {q1}, [r1], r2
vext.8 d3, d2, d3, #1
pld [r1]
pld [r1, r2]
@@ -221,20 +255,21 @@ endfunc
vrhadd.u8 q0, q0, q2
sub r0, r0, r2
.endif
- vst1.64 {d0}, [r0,:64], r2
- vst1.64 {d1}, [r0,:64], r2
+ vst1.8 {d0}, [r0,:64], r2
+ vst1.8 {d1}, [r0,:64], r2
bne 1b
bx lr
.endm
.macro pixels8_y2 rnd=1, avg=0
- vld1.64 {d0}, [r1], r2
- vld1.64 {d1}, [r1], r2
+ sub r3, r3, #2
+ vld1.8 {d0}, [r1], r2
+ vld1.8 {d1}, [r1], r2
1: subs r3, r3, #2
avg d4, d0, d1
- vld1.64 {d0}, [r1], r2
+ vld1.8 {d0}, [r1], r2
avg d5, d0, d1
- vld1.64 {d1}, [r1], r2
+ vld1.8 {d1}, [r1], r2
pld [r1]
pld [r1, r2]
.if \avg
@@ -243,18 +278,30 @@ endfunc
vrhadd.u8 q2, q2, q1
sub r0, r0, r2
.endif
- vst1.64 {d4}, [r0,:64], r2
- vst1.64 {d5}, [r0,:64], r2
+ vst1.8 {d4}, [r0,:64], r2
+ vst1.8 {d5}, [r0,:64], r2
bne 1b
+
+ avg d4, d0, d1
+ vld1.8 {d0}, [r1], r2
+ avg d5, d0, d1
+ .if \avg
+ vld1.8 {d2}, [r0,:64], r2
+ vld1.8 {d3}, [r0,:64]
+ vrhadd.u8 q2, q2, q1
+ sub r0, r0, r2
+ .endif
+ vst1.8 {d4}, [r0,:64], r2
+ vst1.8 {d5}, [r0,:64], r2
+
bx lr
.endm
.macro pixels8_xy2 rnd=1, avg=0
- vld1.64 {q0}, [r1], r2
- vld1.64 {q1}, [r1], r2
- .ifeq \rnd
- vmov.i16 q11, #1
- .endif
+ sub r3, r3, #2
+ vld1.8 {q0}, [r1], r2
+ vld1.8 {q1}, [r1], r2
+NRND vmov.i16 q11, #1
pld [r1]
pld [r1, r2]
vext.8 d4, d0, d1, #1
@@ -262,26 +309,22 @@ endfunc
vaddl.u8 q8, d0, d4
vaddl.u8 q9, d2, d6
1: subs r3, r3, #2
- vld1.64 {q0}, [r1], r2
+ vld1.8 {q0}, [r1], r2
pld [r1]
vadd.u16 q10, q8, q9
vext.8 d4, d0, d1, #1
- .ifeq \rnd
- vadd.u16 q10, q10, q11
- .endif
+NRND vadd.u16 q10, q10, q11
vaddl.u8 q8, d0, d4
shrn d5, q10, #2
- vld1.64 {q1}, [r1], r2
+ vld1.8 {q1}, [r1], r2
vadd.u16 q10, q8, q9
pld [r1, r2]
.if \avg
vld1.8 {d7}, [r0,:64]
vrhadd.u8 d5, d5, d7
.endif
- .ifeq \rnd
- vadd.u16 q10, q10, q11
- .endif
- vst1.64 {d5}, [r0,:64], r2
+NRND vadd.u16 q10, q10, q11
+ vst1.8 {d5}, [r0,:64], r2
shrn d7, q10, #2
.if \avg
vld1.8 {d5}, [r0,:64]
@@ -289,8 +332,29 @@ endfunc
.endif
vext.8 d6, d2, d3, #1
vaddl.u8 q9, d2, d6
- vst1.64 {d7}, [r0,:64], r2
+ vst1.8 {d7}, [r0,:64], r2
bgt 1b
+
+ vld1.8 {q0}, [r1], r2
+ vadd.u16 q10, q8, q9
+ vext.8 d4, d0, d1, #1
+NRND vadd.u16 q10, q10, q11
+ vaddl.u8 q8, d0, d4
+ shrn d5, q10, #2
+ vadd.u16 q10, q8, q9
+ .if \avg
+ vld1.8 {d7}, [r0,:64]
+ vrhadd.u8 d5, d5, d7
+ .endif
+NRND vadd.u16 q10, q10, q11
+ vst1.8 {d5}, [r0,:64], r2
+ shrn d7, q10, #2
+ .if \avg
+ vld1.8 {d5}, [r0,:64]
+ vrhadd.u8 d7, d7, d5
+ .endif
+ vst1.8 {d7}, [r0,:64], r2
+
bx lr
.endm
@@ -302,6 +366,8 @@ endfunc
.macro shrn rd, rn, rm
vrshrn.u16 \rd, \rn, \rm
.endm
+ .macro NRND insn:vararg
+ .endm
.else
.macro avg rd, rn, rm
vhadd.u8 \rd, \rn, \rm
@@ -309,12 +375,16 @@ endfunc
.macro shrn rd, rn, rm
vshrn.u16 \rd, \rn, \rm
.endm
+ .macro NRND insn:vararg
+ \insn
+ .endm
.endif
function ff_\pfx\name\suf\()_neon, export=1
\name \rnd, \avg
endfunc
.purgem avg
.purgem shrn
+ .purgem NRND
.endm
.macro pixfunc2 pfx, name, avg=0
@@ -359,147 +429,108 @@ endfunc
pixfunc2 avg_, pixels8_xy2, avg=1
function ff_put_pixels_clamped_neon, export=1
- vld1.64 {d16-d19}, [r0,:128]!
+ vld1.16 {d16-d19}, [r0,:128]!
vqmovun.s16 d0, q8
- vld1.64 {d20-d23}, [r0,:128]!
+ vld1.16 {d20-d23}, [r0,:128]!
vqmovun.s16 d1, q9
- vld1.64 {d24-d27}, [r0,:128]!
+ vld1.16 {d24-d27}, [r0,:128]!
vqmovun.s16 d2, q10
- vld1.64 {d28-d31}, [r0,:128]!
+ vld1.16 {d28-d31}, [r0,:128]!
vqmovun.s16 d3, q11
- vst1.64 {d0}, [r1,:64], r2
+ vst1.8 {d0}, [r1,:64], r2
vqmovun.s16 d4, q12
- vst1.64 {d1}, [r1,:64], r2
+ vst1.8 {d1}, [r1,:64], r2
vqmovun.s16 d5, q13
- vst1.64 {d2}, [r1,:64], r2
+ vst1.8 {d2}, [r1,:64], r2
vqmovun.s16 d6, q14
- vst1.64 {d3}, [r1,:64], r2
+ vst1.8 {d3}, [r1,:64], r2
vqmovun.s16 d7, q15
- vst1.64 {d4}, [r1,:64], r2
- vst1.64 {d5}, [r1,:64], r2
- vst1.64 {d6}, [r1,:64], r2
- vst1.64 {d7}, [r1,:64], r2
+ vst1.8 {d4}, [r1,:64], r2
+ vst1.8 {d5}, [r1,:64], r2
+ vst1.8 {d6}, [r1,:64], r2
+ vst1.8 {d7}, [r1,:64], r2
bx lr
endfunc
function ff_put_signed_pixels_clamped_neon, export=1
vmov.u8 d31, #128
- vld1.64 {d16-d17}, [r0,:128]!
+ vld1.16 {d16-d17}, [r0,:128]!
vqmovn.s16 d0, q8
- vld1.64 {d18-d19}, [r0,:128]!
+ vld1.16 {d18-d19}, [r0,:128]!
vqmovn.s16 d1, q9
- vld1.64 {d16-d17}, [r0,:128]!
+ vld1.16 {d16-d17}, [r0,:128]!
vqmovn.s16 d2, q8
- vld1.64 {d18-d19}, [r0,:128]!
+ vld1.16 {d18-d19}, [r0,:128]!
vadd.u8 d0, d0, d31
- vld1.64 {d20-d21}, [r0,:128]!
+ vld1.16 {d20-d21}, [r0,:128]!
vadd.u8 d1, d1, d31
- vld1.64 {d22-d23}, [r0,:128]!
+ vld1.16 {d22-d23}, [r0,:128]!
vadd.u8 d2, d2, d31
- vst1.64 {d0}, [r1,:64], r2
+ vst1.8 {d0}, [r1,:64], r2
vqmovn.s16 d3, q9
- vst1.64 {d1}, [r1,:64], r2
+ vst1.8 {d1}, [r1,:64], r2
vqmovn.s16 d4, q10
- vst1.64 {d2}, [r1,:64], r2
+ vst1.8 {d2}, [r1,:64], r2
vqmovn.s16 d5, q11
- vld1.64 {d24-d25}, [r0,:128]!
+ vld1.16 {d24-d25}, [r0,:128]!
vadd.u8 d3, d3, d31
- vld1.64 {d26-d27}, [r0,:128]!
+ vld1.16 {d26-d27}, [r0,:128]!
vadd.u8 d4, d4, d31
vadd.u8 d5, d5, d31
- vst1.64 {d3}, [r1,:64], r2
+ vst1.8 {d3}, [r1,:64], r2
vqmovn.s16 d6, q12
- vst1.64 {d4}, [r1,:64], r2
+ vst1.8 {d4}, [r1,:64], r2
vqmovn.s16 d7, q13
- vst1.64 {d5}, [r1,:64], r2
+ vst1.8 {d5}, [r1,:64], r2
vadd.u8 d6, d6, d31
vadd.u8 d7, d7, d31
- vst1.64 {d6}, [r1,:64], r2
- vst1.64 {d7}, [r1,:64], r2
+ vst1.8 {d6}, [r1,:64], r2
+ vst1.8 {d7}, [r1,:64], r2
bx lr
endfunc
function ff_add_pixels_clamped_neon, export=1
mov r3, r1
- vld1.64 {d16}, [r1,:64], r2
- vld1.64 {d0-d1}, [r0,:128]!
+ vld1.8 {d16}, [r1,:64], r2
+ vld1.16 {d0-d1}, [r0,:128]!
vaddw.u8 q0, q0, d16
- vld1.64 {d17}, [r1,:64], r2
- vld1.64 {d2-d3}, [r0,:128]!
+ vld1.8 {d17}, [r1,:64], r2
+ vld1.16 {d2-d3}, [r0,:128]!
vqmovun.s16 d0, q0
- vld1.64 {d18}, [r1,:64], r2
+ vld1.8 {d18}, [r1,:64], r2
vaddw.u8 q1, q1, d17
- vld1.64 {d4-d5}, [r0,:128]!
+ vld1.16 {d4-d5}, [r0,:128]!
vaddw.u8 q2, q2, d18
- vst1.64 {d0}, [r3,:64], r2
+ vst1.8 {d0}, [r3,:64], r2
vqmovun.s16 d2, q1
- vld1.64 {d19}, [r1,:64], r2
- vld1.64 {d6-d7}, [r0,:128]!
+ vld1.8 {d19}, [r1,:64], r2
+ vld1.16 {d6-d7}, [r0,:128]!
vaddw.u8 q3, q3, d19
vqmovun.s16 d4, q2
- vst1.64 {d2}, [r3,:64], r2
- vld1.64 {d16}, [r1,:64], r2
+ vst1.8 {d2}, [r3,:64], r2
+ vld1.8 {d16}, [r1,:64], r2
vqmovun.s16 d6, q3
- vld1.64 {d0-d1}, [r0,:128]!
+ vld1.16 {d0-d1}, [r0,:128]!
vaddw.u8 q0, q0, d16
- vst1.64 {d4}, [r3,:64], r2
- vld1.64 {d17}, [r1,:64], r2
- vld1.64 {d2-d3}, [r0,:128]!
+ vst1.8 {d4}, [r3,:64], r2
+ vld1.8 {d17}, [r1,:64], r2
+ vld1.16 {d2-d3}, [r0,:128]!
vaddw.u8 q1, q1, d17
- vst1.64 {d6}, [r3,:64], r2
+ vst1.8 {d6}, [r3,:64], r2
vqmovun.s16 d0, q0
- vld1.64 {d18}, [r1,:64], r2
- vld1.64 {d4-d5}, [r0,:128]!
+ vld1.8 {d18}, [r1,:64], r2
+ vld1.16 {d4-d5}, [r0,:128]!
vaddw.u8 q2, q2, d18
- vst1.64 {d0}, [r3,:64], r2
+ vst1.8 {d0}, [r3,:64], r2
vqmovun.s16 d2, q1
- vld1.64 {d19}, [r1,:64], r2
+ vld1.8 {d19}, [r1,:64], r2
vqmovun.s16 d4, q2
- vld1.64 {d6-d7}, [r0,:128]!
+ vld1.16 {d6-d7}, [r0,:128]!
vaddw.u8 q3, q3, d19
- vst1.64 {d2}, [r3,:64], r2
+ vst1.8 {d2}, [r3,:64], r2
vqmovun.s16 d6, q3
- vst1.64 {d4}, [r3,:64], r2
- vst1.64 {d6}, [r3,:64], r2
- bx lr
-endfunc
-
-function ff_vector_fmul_neon, export=1
- subs r3, r3, #8
- vld1.64 {d0-d3}, [r1,:128]!
- vld1.64 {d4-d7}, [r2,:128]!
- vmul.f32 q8, q0, q2
- vmul.f32 q9, q1, q3
- beq 3f
- bics ip, r3, #15
- beq 2f
-1: subs ip, ip, #16
- vld1.64 {d0-d1}, [r1,:128]!
- vld1.64 {d4-d5}, [r2,:128]!
- vmul.f32 q10, q0, q2
- vld1.64 {d2-d3}, [r1,:128]!
- vld1.64 {d6-d7}, [r2,:128]!
- vmul.f32 q11, q1, q3
- vst1.64 {d16-d19},[r0,:128]!
- vld1.64 {d0-d1}, [r1,:128]!
- vld1.64 {d4-d5}, [r2,:128]!
- vmul.f32 q8, q0, q2
- vld1.64 {d2-d3}, [r1,:128]!
- vld1.64 {d6-d7}, [r2,:128]!
- vmul.f32 q9, q1, q3
- vst1.64 {d20-d23},[r0,:128]!
- bne 1b
- ands r3, r3, #15
- beq 3f
-2: vld1.64 {d0-d1}, [r1,:128]!
- vld1.64 {d4-d5}, [r2,:128]!
- vst1.64 {d16-d17},[r0,:128]!
- vmul.f32 q8, q0, q2
- vld1.64 {d2-d3}, [r1,:128]!
- vld1.64 {d6-d7}, [r2,:128]!
- vst1.64 {d18-d19},[r0,:128]!
- vmul.f32 q9, q1, q3
-3: vst1.64 {d16-d19},[r0,:128]!
+ vst1.8 {d4}, [r3,:64], r2
+ vst1.8 {d6}, [r3,:64], r2
bx lr
endfunc
@@ -512,10 +543,10 @@ function ff_vector_fmul_window_neon, export=1
add r4, r3, r5, lsl #3
add ip, r0, r5, lsl #3
mov r5, #-16
- vld1.64 {d0,d1}, [r1,:128]!
- vld1.64 {d2,d3}, [r2,:128], r5
- vld1.64 {d4,d5}, [r3,:128]!
- vld1.64 {d6,d7}, [r4,:128], r5
+ vld1.32 {d0,d1}, [r1,:128]!
+ vld1.32 {d2,d3}, [r2,:128], r5
+ vld1.32 {d4,d5}, [r3,:128]!
+ vld1.32 {d6,d7}, [r4,:128], r5
1: subs lr, lr, #4
vmul.f32 d22, d0, d4
vrev64.32 q3, q3
@@ -525,19 +556,19 @@ function ff_vector_fmul_window_neon, export=1
vmul.f32 d21, d1, d6
beq 2f
vmla.f32 d22, d3, d7
- vld1.64 {d0,d1}, [r1,:128]!
+ vld1.32 {d0,d1}, [r1,:128]!
vmla.f32 d23, d2, d6
- vld1.64 {d18,d19},[r2,:128], r5
+ vld1.32 {d18,d19},[r2,:128], r5
vmls.f32 d20, d3, d4
- vld1.64 {d24,d25},[r3,:128]!
+ vld1.32 {d24,d25},[r3,:128]!
vmls.f32 d21, d2, d5
- vld1.64 {d6,d7}, [r4,:128], r5
+ vld1.32 {d6,d7}, [r4,:128], r5
vmov q1, q9
vrev64.32 q11, q11
vmov q2, q12
vswp d22, d23
- vst1.64 {d20,d21},[r0,:128]!
- vst1.64 {d22,d23},[ip,:128], r5
+ vst1.32 {d20,d21},[r0,:128]!
+ vst1.32 {d22,d23},[ip,:128], r5
b 1b
2: vmla.f32 d22, d3, d7
vmla.f32 d23, d2, d6
@@ -545,8 +576,8 @@ function ff_vector_fmul_window_neon, export=1
vmls.f32 d21, d2, d5
vrev64.32 q11, q11
vswp d22, d23
- vst1.64 {d20,d21},[r0,:128]!
- vst1.64 {d22,d23},[ip,:128], r5
+ vst1.32 {d20,d21},[r0,:128]!
+ vst1.32 {d22,d23},[ip,:128], r5
pop {r4,r5,pc}
endfunc
@@ -651,54 +682,6 @@ NOVFP vdup.32 q8, r2
.unreq len
endfunc
-function ff_vector_fmac_scalar_neon, export=1
-VFP len .req r2
-VFP acc .req r3
-NOVFP len .req r3
-NOVFP acc .req r2
-VFP vdup.32 q15, d0[0]
-NOVFP vdup.32 q15, r2
- bics r12, len, #15
- mov acc, r0
- beq 3f
- vld1.32 {q0}, [r1,:128]!
- vld1.32 {q8}, [acc,:128]!
- vld1.32 {q1}, [r1,:128]!
- vld1.32 {q9}, [acc,:128]!
-1: vmla.f32 q8, q0, q15
- vld1.32 {q2}, [r1,:128]!
- vld1.32 {q10}, [acc,:128]!
- vmla.f32 q9, q1, q15
- vld1.32 {q3}, [r1,:128]!
- vld1.32 {q11}, [acc,:128]!
- vmla.f32 q10, q2, q15
- vst1.32 {q8}, [r0,:128]!
- vmla.f32 q11, q3, q15
- vst1.32 {q9}, [r0,:128]!
- subs r12, r12, #16
- beq 2f
- vld1.32 {q0}, [r1,:128]!
- vld1.32 {q8}, [acc,:128]!
- vst1.32 {q10}, [r0,:128]!
- vld1.32 {q1}, [r1,:128]!
- vld1.32 {q9}, [acc,:128]!
- vst1.32 {q11}, [r0,:128]!
- b 1b
-2: vst1.32 {q10}, [r0,:128]!
- vst1.32 {q11}, [r0,:128]!
- ands len, len, #15
- it eq
- bxeq lr
-3: vld1.32 {q0}, [r1,:128]!
- vld1.32 {q8}, [acc,:128]!
- vmla.f32 q8, q0, q15
- vst1.32 {q8}, [r0,:128]!
- subs len, len, #4
- bgt 3b
- bx lr
- .unreq len
-endfunc
-
function ff_butterflies_float_neon, export=1
1: vld1.32 {q0},[r0,:128]
vld1.32 {q1},[r1,:128]
diff --git a/libavcodec/arm/dsputil_vfp.S b/libavcodec/arm/dsputil_vfp.S
index cbc4bd6..9df955d 100644
--- a/libavcodec/arm/dsputil_vfp.S
+++ b/libavcodec/arm/dsputil_vfp.S
@@ -19,7 +19,7 @@
*/
#include "config.h"
-#include "asm.S"
+#include "libavutil/arm/asm.S"
/*
* VFP is a floating point coprocessor used in some ARM cores. VFP11 has 1 cycle
@@ -37,53 +37,6 @@
*/
/**
- * ARM VFP optimized implementation of 'vector_fmul_c' function.
- * Assume that len is a positive number and is multiple of 8
- */
-@ void ff_vector_fmul_vfp(float *dst, const float *src0, const float *src1, int len)
-function ff_vector_fmul_vfp, export=1
- vpush {d8-d15}
- fmrx r12, fpscr
- orr r12, r12, #(3 << 16) /* set vector size to 4 */
- fmxr fpscr, r12
-
- vldmia r1!, {s0-s3}
- vldmia r2!, {s8-s11}
- vldmia r1!, {s4-s7}
- vldmia r2!, {s12-s15}
- vmul.f32 s8, s0, s8
-1:
- subs r3, r3, #16
- vmul.f32 s12, s4, s12
- itttt ge
- vldmiage r1!, {s16-s19}
- vldmiage r2!, {s24-s27}
- vldmiage r1!, {s20-s23}
- vldmiage r2!, {s28-s31}
- it ge
- vmulge.f32 s24, s16, s24
- vstmia r0!, {s8-s11}
- vstmia r0!, {s12-s15}
- it ge
- vmulge.f32 s28, s20, s28
- itttt gt
- vldmiagt r1!, {s0-s3}
- vldmiagt r2!, {s8-s11}
- vldmiagt r1!, {s4-s7}
- vldmiagt r2!, {s12-s15}
- ittt ge
- vmulge.f32 s8, s0, s8
- vstmiage r0!, {s24-s27}
- vstmiage r0!, {s28-s31}
- bgt 1b
-
- bic r12, r12, #(7 << 16) /* set vector size back to 1 */
- fmxr fpscr, r12
- vpop {d8-d15}
- bx lr
-endfunc
-
-/**
* ARM VFP optimized implementation of 'vector_fmul_reverse_c' function.
* Assume that len is a positive number and is multiple of 8
*/
diff --git a/libavcodec/arm/fft_fixed_neon.S b/libavcodec/arm/fft_fixed_neon.S
index 0508088..faddc00 100644
--- a/libavcodec/arm/fft_fixed_neon.S
+++ b/libavcodec/arm/fft_fixed_neon.S
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
.macro bflies d0, d1, r0, r1
vrev64.32 \r0, \d1 @ t5, t6, t1, t2
@@ -214,7 +214,7 @@ function fft\n\()_neon
bl fft\n4\()_neon
mov r0, r4
pop {r4, lr}
- movrel r1, X(ff_cos_\n\()_fixed)
+ movrelx r1, X(ff_cos_\n\()_fixed)
mov r2, #\n4/2
b fft_pass_neon
endfunc
diff --git a/libavcodec/arm/fft_neon.S b/libavcodec/arm/fft_neon.S
index a458985..c4d8918 100644
--- a/libavcodec/arm/fft_neon.S
+++ b/libavcodec/arm/fft_neon.S
@@ -24,7 +24,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
#define M_SQRT1_2 0.70710678118654752440
@@ -143,7 +143,7 @@ function fft16_neon
vswp d29, d30 @ q14{r12,i12,i14,r15} q15{r13,i13,i15,r14}
vadd.f32 q0, q12, q13 @ {t1,t2,t5,t6}
vadd.f32 q1, q14, q15 @ {t1a,t2a,t5a,t6a}
- movrel r2, X(ff_cos_16)
+ movrelx r2, X(ff_cos_16)
vsub.f32 q13, q12, q13 @ {t3,t4,t7,t8}
vrev64.32 d1, d1
vsub.f32 q15, q14, q15 @ {t3a,t4a,t7a,t8a}
@@ -290,7 +290,7 @@ function fft\n\()_neon
bl fft\n4\()_neon
mov r0, r4
pop {r4, lr}
- movrel r1, X(ff_cos_\n)
+ movrelx r1, X(ff_cos_\n)
mov r2, #\n4/2
b fft_pass_neon
endfunc
diff --git a/libavcodec/arm/fmtconvert_neon.S b/libavcodec/arm/fmtconvert_neon.S
index ad1c15d..66ff166 100644
--- a/libavcodec/arm/fmtconvert_neon.S
+++ b/libavcodec/arm/fmtconvert_neon.S
@@ -20,7 +20,7 @@
*/
#include "config.h"
-#include "asm.S"
+#include "libavutil/arm/asm.S"
preserve8
diff --git a/libavcodec/arm/fmtconvert_vfp.S b/libavcodec/arm/fmtconvert_vfp.S
index f7b0e3d..8aeec2a 100644
--- a/libavcodec/arm/fmtconvert_vfp.S
+++ b/libavcodec/arm/fmtconvert_vfp.S
@@ -19,7 +19,7 @@
*/
#include "config.h"
-#include "asm.S"
+#include "libavutil/arm/asm.S"
/**
* ARM VFP optimized float to int16 conversion.
diff --git a/libavcodec/arm/h264cmc_neon.S b/libavcodec/arm/h264cmc_neon.S
index a6feadd..e82394d 100644
--- a/libavcodec/arm/h264cmc_neon.S
+++ b/libavcodec/arm/h264cmc_neon.S
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
/* chroma_mc8(uint8_t *dst, uint8_t *src, int stride, int h, int x, int y) */
.macro h264_chroma_mc8 type, codec=h264
diff --git a/libavcodec/arm/h264dsp_neon.S b/libavcodec/arm/h264dsp_neon.S
index a4abf66..4ad8863 100644
--- a/libavcodec/arm/h264dsp_neon.S
+++ b/libavcodec/arm/h264dsp_neon.S
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
#include "neon.S"
/* H.264 loop filter */
diff --git a/libavcodec/arm/h264idct_neon.S b/libavcodec/arm/h264idct_neon.S
index edb2ae5..182d3b2 100644
--- a/libavcodec/arm/h264idct_neon.S
+++ b/libavcodec/arm/h264idct_neon.S
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
preserve8
diff --git a/libavcodec/arm/h264pred_neon.S b/libavcodec/arm/h264pred_neon.S
index 815b67b..332f94b 100644
--- a/libavcodec/arm/h264pred_neon.S
+++ b/libavcodec/arm/h264pred_neon.S
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
.macro ldcol.8 rd, rs, rt, n=8, hi=0
.if \n == 8 || \hi == 0
diff --git a/libavcodec/arm/int_neon.S b/libavcodec/arm/int_neon.S
index ea479bb..92cc518 100644
--- a/libavcodec/arm/int_neon.S
+++ b/libavcodec/arm/int_neon.S
@@ -19,7 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
preserve8
.fpu neon
diff --git a/libavcodec/arm/jrevdct_arm.S b/libavcodec/arm/jrevdct_arm.S
index 93cbbbe..331ad85 100644
--- a/libavcodec/arm/jrevdct_arm.S
+++ b/libavcodec/arm/jrevdct_arm.S
@@ -25,7 +25,7 @@
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
#define FIX_0_298631336 2446
#define FIX_0_541196100 4433
diff --git a/libavcodec/arm/mdct_fixed_neon.S b/libavcodec/arm/mdct_fixed_neon.S
index d219216..08a3887 100644
--- a/libavcodec/arm/mdct_fixed_neon.S
+++ b/libavcodec/arm/mdct_fixed_neon.S
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
preserve8
diff --git a/libavcodec/arm/mdct_neon.S b/libavcodec/arm/mdct_neon.S
index 5669075..09dfdf4 100644
--- a/libavcodec/arm/mdct_neon.S
+++ b/libavcodec/arm/mdct_neon.S
@@ -19,7 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
preserve8
diff --git a/libavcodec/arm/mpegaudiodsp_fixed_armv6.S b/libavcodec/arm/mpegaudiodsp_fixed_armv6.S
index b517b97..49bd0bc 100644
--- a/libavcodec/arm/mpegaudiodsp_fixed_armv6.S
+++ b/libavcodec/arm/mpegaudiodsp_fixed_armv6.S
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
.macro skip args:vararg
.endm
diff --git a/libavcodec/arm/mpegvideo_armv5te_s.S b/libavcodec/arm/mpegvideo_armv5te_s.S
index 952c8d7..ec95346 100644
--- a/libavcodec/arm/mpegvideo_armv5te_s.S
+++ b/libavcodec/arm/mpegvideo_armv5te_s.S
@@ -20,7 +20,7 @@
*/
#include "config.h"
-#include "asm.S"
+#include "libavutil/arm/asm.S"
/*
* Special optimized version of dct_unquantize_h263_helper_c, it
diff --git a/libavcodec/arm/mpegvideo_neon.S b/libavcodec/arm/mpegvideo_neon.S
index 206a71a..0c6c428 100644
--- a/libavcodec/arm/mpegvideo_neon.S
+++ b/libavcodec/arm/mpegvideo_neon.S
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
#include "asm-offsets.h"
function ff_dct_unquantize_h263_inter_neon, export=1
diff --git a/libavcodec/arm/rdft_neon.S b/libavcodec/arm/rdft_neon.S
index fba275e..eb7433a 100644
--- a/libavcodec/arm/rdft_neon.S
+++ b/libavcodec/arm/rdft_neon.S
@@ -19,7 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
preserve8
diff --git a/libavcodec/arm/rv34dsp_neon.S b/libavcodec/arm/rv34dsp_neon.S
index 15a015d..522e387 100644
--- a/libavcodec/arm/rv34dsp_neon.S
+++ b/libavcodec/arm/rv34dsp_neon.S
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
#include "neon.S"
.macro rv34_inv_transform r0
diff --git a/libavcodec/arm/rv40dsp_neon.S b/libavcodec/arm/rv40dsp_neon.S
index f68f382..6bd45eb 100644
--- a/libavcodec/arm/rv40dsp_neon.S
+++ b/libavcodec/arm/rv40dsp_neon.S
@@ -19,7 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
#include "neon.S"
.macro qpel_lowpass r0, r1, rc1, rc2, shift
diff --git a/libavcodec/arm/sbrdsp_neon.S b/libavcodec/arm/sbrdsp_neon.S
index 835c32c..610397f 100644
--- a/libavcodec/arm/sbrdsp_neon.S
+++ b/libavcodec/arm/sbrdsp_neon.S
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
function ff_sbr_sum64x5_neon, export=1
push {lr}
@@ -307,8 +307,8 @@ function ff_sbr_hf_apply_noise_0_neon, export=1
vmov.i32 d3, #0
.Lhf_apply_noise_0:
push {r4,lr}
+ movrelx r4, X(ff_sbr_noise_table)
ldr r12, [sp, #12]
- movrel r4, X(ff_sbr_noise_table)
add r3, r3, #1
bfc r3, #9, #23
sub r12, r12, #1
@@ -355,8 +355,8 @@ function ff_sbr_hf_apply_noise_1_neon, export=1
eor lr, r12, #1<<31
vmov d3, r12, lr
.Lhf_apply_noise_1:
+ movrelx r4, X(ff_sbr_noise_table)
ldr r12, [sp, #12]
- movrel r4, X(ff_sbr_noise_table)
add r3, r3, #1
bfc r3, #9, #23
sub r12, r12, #1
diff --git a/libavcodec/arm/simple_idct_arm.S b/libavcodec/arm/simple_idct_arm.S
index a9c3095..c6540a1 100644
--- a/libavcodec/arm/simple_idct_arm.S
+++ b/libavcodec/arm/simple_idct_arm.S
@@ -23,7 +23,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
/* useful constants for the algorithm, they are save in __constant_ptr__ at */
/* the end of the source code.*/
diff --git a/libavcodec/arm/simple_idct_armv5te.S b/libavcodec/arm/simple_idct_armv5te.S
index 24641e4..e880a8a 100644
--- a/libavcodec/arm/simple_idct_armv5te.S
+++ b/libavcodec/arm/simple_idct_armv5te.S
@@ -21,7 +21,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
#define W1 22725 /* cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 */
#define W2 21407 /* cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 */
diff --git a/libavcodec/arm/simple_idct_armv6.S b/libavcodec/arm/simple_idct_armv6.S
index 284eb1f..9395f88 100644
--- a/libavcodec/arm/simple_idct_armv6.S
+++ b/libavcodec/arm/simple_idct_armv6.S
@@ -21,7 +21,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
#define W1 22725 /* cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 */
#define W2 21407 /* cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 */
diff --git a/libavcodec/arm/simple_idct_neon.S b/libavcodec/arm/simple_idct_neon.S
index 0c4e05d..df24a45 100644
--- a/libavcodec/arm/simple_idct_neon.S
+++ b/libavcodec/arm/simple_idct_neon.S
@@ -23,7 +23,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
#define W1 22725 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
#define W2 21407 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
diff --git a/libavcodec/arm/synth_filter_neon.S b/libavcodec/arm/synth_filter_neon.S
index 1d6e5b2..6dabce6 100644
--- a/libavcodec/arm/synth_filter_neon.S
+++ b/libavcodec/arm/synth_filter_neon.S
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
preserve8
diff --git a/libavcodec/arm/vp3dsp_neon.S b/libavcodec/arm/vp3dsp_neon.S
index 279b132..2a9b25f 100644
--- a/libavcodec/arm/vp3dsp_neon.S
+++ b/libavcodec/arm/vp3dsp_neon.S
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
const vp3_idct_constants, align=4
.short 64277, 60547, 54491, 46341, 36410, 25080, 12785
@@ -116,9 +116,8 @@ function vp3_idct_start_neon
vadd.s16 q1, q8, q12
vsub.s16 q8, q8, q12
vld1.64 {d28-d31}, [r2,:128]!
-endfunc
-function vp3_idct_core_neon
+vp3_idct_core_neon:
vmull.s16 q2, d18, xC1S7 // (ip[1] * C1) << 16
vmull.s16 q3, d19, xC1S7
vmull.s16 q4, d2, xC4S4 // ((ip[0] + ip[4]) * C4) << 16
diff --git a/libavcodec/arm/vp56dsp_neon.S b/libavcodec/arm/vp56dsp_neon.S
index b95d8ab..10b4d0f 100644
--- a/libavcodec/arm/vp56dsp_neon.S
+++ b/libavcodec/arm/vp56dsp_neon.S
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
.macro vp6_edge_filter
vdup.16 q3, r2 @ t
diff --git a/libavcodec/arm/vp8_armv6.S b/libavcodec/arm/vp8_armv6.S
index c9dc30b..1b668bc 100644
--- a/libavcodec/arm/vp8_armv6.S
+++ b/libavcodec/arm/vp8_armv6.S
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
.macro rac_get_prob h, bs, buf, cw, pr, t0, t1
adds \bs, \bs, \t0
@@ -65,7 +65,7 @@ T orrcs \cw, \cw, \t1
function ff_decode_block_coeffs_armv6, export=1
push {r0,r1,r4-r11,lr}
- movrel lr, X(ff_vp56_norm_shift)
+ movrelx lr, X(ff_vp56_norm_shift)
ldrd r4, r5, [sp, #44] @ token_prob, qmul
cmp r3, #0
ldr r11, [r5]
@@ -206,7 +206,7 @@ A orrcs r8, r8, r10, lsl r6
mov r9, #8
it ge
addge r12, r12, #1
- movrel r4, X(ff_vp8_dct_cat_prob)
+ movrelx r4, X(ff_vp8_dct_cat_prob), r1
lsl r9, r9, r12
ldr r4, [r4, r12, lsl #2]
add r12, r9, #3
diff --git a/libavcodec/arm/vp8dsp_armv6.S b/libavcodec/arm/vp8dsp_armv6.S
index 08054ff..a26a2a9 100644
--- a/libavcodec/arm/vp8dsp_armv6.S
+++ b/libavcodec/arm/vp8dsp_armv6.S
@@ -52,7 +52,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
@ idct
diff --git a/libavcodec/arm/vp8dsp_neon.S b/libavcodec/arm/vp8dsp_neon.S
index c1a91e1..0cd2efa 100644
--- a/libavcodec/arm/vp8dsp_neon.S
+++ b/libavcodec/arm/vp8dsp_neon.S
@@ -21,7 +21,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "asm.S"
+#include "libavutil/arm/asm.S"
#include "neon.S"
function ff_vp8_luma_dc_wht_neon, export=1
diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c
index f468f11..638889b 100644
--- a/libavcodec/atrac3.c
+++ b/libavcodec/atrac3.c
@@ -36,9 +36,9 @@
#include <stddef.h>
#include <stdio.h>
+#include "libavutil/float_dsp.h"
#include "avcodec.h"
#include "get_bits.h"
-#include "dsputil.h"
#include "bytestream.h"
#include "fft.h"
#include "fmtconvert.h"
@@ -125,13 +125,13 @@ typedef struct {
FFTContext mdct_ctx;
FmtConvertContext fmt_conv;
+ AVFloatDSPContext fdsp;
} ATRAC3Context;
static DECLARE_ALIGNED(32, float, mdct_window)[MDCT_SIZE];
static VLC spectral_coeff_tab[7];
static float gain_tab1[16];
static float gain_tab2[31];
-static DSPContext dsp;
/**
@@ -164,7 +164,7 @@ static void IMLT(ATRAC3Context *q, float *pInput, float *pOutput, int odd_band)
q->mdct_ctx.imdct_calc(&q->mdct_ctx,pOutput,pInput);
/* Perform windowing on the output. */
- dsp.vector_fmul(pOutput, pOutput, mdct_window, MDCT_SIZE);
+ q->fdsp.vector_fmul(pOutput, pOutput, mdct_window, MDCT_SIZE);
}
@@ -1039,7 +1039,7 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx)
q->matrix_coeff_index_next[i] = 3;
}
- ff_dsputil_init(&dsp, avctx);
+ avpriv_float_dsp_init(&q->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
ff_fmt_convert_init(&q->fmt_conv, avctx);
q->pUnits = av_mallocz(sizeof(channel_unit)*q->channels);
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 0fda1cb..2b70b96 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -255,6 +255,8 @@ enum CodecID {
CODEC_ID_CDXL,
CODEC_ID_XBM,
CODEC_ID_ZEROCODEC,
+ CODEC_ID_MSS1,
+ CODEC_ID_MSA1,
/* various PCM "codecs" */
CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
@@ -393,6 +395,8 @@ enum CodecID {
CODEC_ID_8SVX_FIB,
CODEC_ID_BMV_AUDIO,
CODEC_ID_RALF,
+ CODEC_ID_IAC,
+ CODEC_ID_ILBC,
/* subtitle codecs */
CODEC_ID_FIRST_SUBTITLE = 0x17000, ///< A dummy ID pointing at the start of subtitle codecs.
@@ -465,49 +469,51 @@ enum Motion_Est_ID {
enum AVDiscard{
/* We leave some space between them for extensions (drop some
* keyframes for intra-only or drop just some bidir frames). */
- AVDISCARD_NONE =-16, ///< discard nothing
- AVDISCARD_DEFAULT= 0, ///< discard useless packets like 0 size packets in avi
- AVDISCARD_NONREF = 8, ///< discard all non reference
- AVDISCARD_BIDIR = 16, ///< discard all bidirectional frames
- AVDISCARD_NONKEY = 32, ///< discard all frames except keyframes
- AVDISCARD_ALL = 48, ///< discard all
+ AVDISCARD_NONE =-16, ///< discard nothing
+ AVDISCARD_DEFAULT = 0, ///< discard useless packets like 0 size packets in avi
+ AVDISCARD_NONREF = 8, ///< discard all non reference
+ AVDISCARD_BIDIR = 16, ///< discard all bidirectional frames
+ AVDISCARD_NONKEY = 32, ///< discard all frames except keyframes
+ AVDISCARD_ALL = 48, ///< discard all
};
enum AVColorPrimaries{
- AVCOL_PRI_BT709 =1, ///< also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B
- AVCOL_PRI_UNSPECIFIED=2,
- AVCOL_PRI_BT470M =4,
- AVCOL_PRI_BT470BG =5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM
- AVCOL_PRI_SMPTE170M =6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
- AVCOL_PRI_SMPTE240M =7, ///< functionally identical to above
- AVCOL_PRI_FILM =8,
- AVCOL_PRI_NB , ///< Not part of ABI
+ AVCOL_PRI_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B
+ AVCOL_PRI_UNSPECIFIED = 2,
+ AVCOL_PRI_BT470M = 4,
+ AVCOL_PRI_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM
+ AVCOL_PRI_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
+ AVCOL_PRI_SMPTE240M = 7, ///< functionally identical to above
+ AVCOL_PRI_FILM = 8,
+ AVCOL_PRI_NB , ///< Not part of ABI
};
enum AVColorTransferCharacteristic{
- AVCOL_TRC_BT709 =1, ///< also ITU-R BT1361
- AVCOL_TRC_UNSPECIFIED=2,
- AVCOL_TRC_GAMMA22 =4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
- AVCOL_TRC_GAMMA28 =5, ///< also ITU-R BT470BG
- AVCOL_TRC_NB , ///< Not part of ABI
+ AVCOL_TRC_BT709 = 1, ///< also ITU-R BT1361
+ AVCOL_TRC_UNSPECIFIED = 2,
+ AVCOL_TRC_GAMMA22 = 4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
+ AVCOL_TRC_GAMMA28 = 5, ///< also ITU-R BT470BG
+ AVCOL_TRC_SMPTE240M = 7,
+ AVCOL_TRC_NB , ///< Not part of ABI
};
enum AVColorSpace{
- AVCOL_SPC_RGB =0,
- AVCOL_SPC_BT709 =1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
- AVCOL_SPC_UNSPECIFIED=2,
- AVCOL_SPC_FCC =4,
- AVCOL_SPC_BT470BG =5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
- AVCOL_SPC_SMPTE170M =6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
- AVCOL_SPC_SMPTE240M =7,
- AVCOL_SPC_NB , ///< Not part of ABI
+ AVCOL_SPC_RGB = 0,
+ AVCOL_SPC_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
+ AVCOL_SPC_UNSPECIFIED = 2,
+ AVCOL_SPC_FCC = 4,
+ AVCOL_SPC_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
+ AVCOL_SPC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
+ AVCOL_SPC_SMPTE240M = 7,
+ AVCOL_SPC_YCOCG = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16
+ AVCOL_SPC_NB , ///< Not part of ABI
};
enum AVColorRange{
- AVCOL_RANGE_UNSPECIFIED=0,
- AVCOL_RANGE_MPEG =1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges
- AVCOL_RANGE_JPEG =2, ///< the normal 2^n-1 "JPEG" YUV ranges
- AVCOL_RANGE_NB , ///< Not part of ABI
+ AVCOL_RANGE_UNSPECIFIED = 0,
+ AVCOL_RANGE_MPEG = 1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges
+ AVCOL_RANGE_JPEG = 2, ///< the normal 2^n-1 "JPEG" YUV ranges
+ AVCOL_RANGE_NB , ///< Not part of ABI
};
/**
@@ -516,14 +522,14 @@ enum AVColorRange{
* X X 5 6 X 0 is undefined/unknown position
*/
enum AVChromaLocation{
- AVCHROMA_LOC_UNSPECIFIED=0,
- AVCHROMA_LOC_LEFT =1, ///< mpeg2/4, h264 default
- AVCHROMA_LOC_CENTER =2, ///< mpeg1, jpeg, h263
- AVCHROMA_LOC_TOPLEFT =3, ///< DV
- AVCHROMA_LOC_TOP =4,
- AVCHROMA_LOC_BOTTOMLEFT =5,
- AVCHROMA_LOC_BOTTOM =6,
- AVCHROMA_LOC_NB , ///< Not part of ABI
+ AVCHROMA_LOC_UNSPECIFIED = 0,
+ AVCHROMA_LOC_LEFT = 1, ///< mpeg2/4, h264 default
+ AVCHROMA_LOC_CENTER = 2, ///< mpeg1, jpeg, h263
+ AVCHROMA_LOC_TOPLEFT = 3, ///< DV
+ AVCHROMA_LOC_TOP = 4,
+ AVCHROMA_LOC_BOTTOMLEFT = 5,
+ AVCHROMA_LOC_BOTTOM = 6,
+ AVCHROMA_LOC_NB , ///< Not part of ABI
};
enum AVAudioServiceType {
@@ -1205,6 +1211,22 @@ typedef struct AVFrame {
* - decoding: Set by libavcodec.
*/
uint8_t motion_subsample_log2;
+
+ /**
+ * Sample rate of the audio data.
+ *
+ * - encoding: unused
+ * - decoding: set by get_buffer()
+ */
+ int sample_rate;
+
+ /**
+ * Channel layout of the audio data.
+ *
+ * - encoding: unused
+ * - decoding: set by get_buffer()
+ */
+ uint64_t channel_layout;
} AVFrame;
struct AVCodecInternal;
@@ -2624,7 +2646,7 @@ typedef struct AVCodecContext {
/**
* Set by the client if its custom get_buffer() callback can be called
- * from another thread, which allows faster multithreaded decoding.
+ * synchronously from another thread, which allows faster multithreaded decoding.
* draw_horiz_band() will be called from other threads regardless of this setting.
* Ignored if the default get_buffer() is used.
* - encoding: Set by user.
@@ -3264,6 +3286,9 @@ void av_destruct_packet(AVPacket *pkt);
/**
* Initialize optional fields of a packet with default values.
*
+ * Note, this does not touch the data and size members, which have to be
+ * initialized separately.
+ *
* @param pkt packet
*/
void av_init_packet(AVPacket *pkt);
@@ -3842,15 +3867,11 @@ int attribute_deprecated avcodec_encode_audio(AVCodecContext *avctx,
* @param[in] frame AVFrame containing the raw audio data to be encoded.
* May be NULL when flushing an encoder that has the
* CODEC_CAP_DELAY capability set.
- * There are 2 codec capabilities that affect the allowed
- * values of frame->nb_samples.
- * If CODEC_CAP_SMALL_LAST_FRAME is set, then only the final
- * frame may be smaller than avctx->frame_size, and all other
- * frames must be equal to avctx->frame_size.
* If CODEC_CAP_VARIABLE_FRAME_SIZE is set, then each frame
* can have any number of samples.
- * If neither is set, frame->nb_samples must be equal to
- * avctx->frame_size for all frames.
+ * If it is not set, frame->nb_samples must be equal to
+ * avctx->frame_size for all frames except the last.
+ * The final frame may be smaller than avctx->frame_size.
* @param[out] got_packet_ptr This field is set to 1 by libavcodec if the
* output packet is non-empty, and to 0 if it is
* empty. If the function returns an error, the
diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c
index 5e2292d..4b85081 100644
--- a/libavcodec/avpacket.c
+++ b/libavcodec/avpacket.c
@@ -146,7 +146,7 @@ int av_dup_packet(AVPacket *pkt)
pkt->side_data_elems * sizeof(*pkt->side_data));
for (i = 0; i < pkt->side_data_elems; i++)
DUP_DATA(pkt->side_data[i].data, tmp_pkt.side_data[i].data,
- pkt->side_data[i].size, 1);
+ tmp_pkt.side_data[i].size, 1);
}
}
return 0;
diff --git a/libavcodec/bmv.c b/libavcodec/bmv.c
index 49346a4..4d49643 100644
--- a/libavcodec/bmv.c
+++ b/libavcodec/bmv.c
@@ -52,7 +52,7 @@ typedef struct BMVDecContext {
static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame, int frame_off)
{
- int val, saved_val = 0;
+ unsigned val, saved_val = 0;
int tmplen = src_len;
const uint8_t *src, *source_end = source + src_len;
uint8_t *frame_end = frame + SCREEN_WIDE * SCREEN_HIGH;
@@ -140,7 +140,9 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame,
case 1:
if (forward) {
if (dst - frame + SCREEN_WIDE < frame_off ||
- frame_end - dst < frame_off + len)
+ dst - frame + SCREEN_WIDE + frame_off < 0 ||
+ frame_end - dst < frame_off + len ||
+ frame_end - dst < len)
return -1;
for (i = 0; i < len; i++)
dst[i] = dst[frame_off + i];
@@ -148,7 +150,9 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame,
} else {
dst -= len;
if (dst - frame + SCREEN_WIDE < frame_off ||
- frame_end - dst < frame_off + len)
+ dst - frame + SCREEN_WIDE + frame_off < 0 ||
+ frame_end - dst < frame_off + len ||
+ frame_end - dst < len)
return -1;
for (i = len - 1; i >= 0; i--)
dst[i] = dst[frame_off + i];
diff --git a/libavcodec/celp_filters.c b/libavcodec/celp_filters.c
index 25a6744..849cda4 100644
--- a/libavcodec/celp_filters.c
+++ b/libavcodec/celp_filters.c
@@ -133,9 +133,8 @@ void ff_celp_lp_synthesis_filterf(float *out, const float *filter_coeffs,
out2 -= val * old_out2;
out3 -= val * old_out3;
- old_out3 = out[-5];
-
for (i = 5; i <= filter_length; i += 2) {
+ old_out3 = out[-i];
val = filter_coeffs[i-1];
out0 -= val * old_out3;
@@ -154,7 +153,6 @@ void ff_celp_lp_synthesis_filterf(float *out, const float *filter_coeffs,
FFSWAP(float, old_out0, old_out2);
old_out1 = old_out3;
- old_out3 = out[-i-2];
}
tmp0 = out0;
diff --git a/libavcodec/cos_tablegen.c b/libavcodec/cos_tablegen.c
index 5e52c48..8a90857 100644
--- a/libavcodec/cos_tablegen.c
+++ b/libavcodec/cos_tablegen.c
@@ -24,9 +24,6 @@
#include <string.h>
#include <math.h>
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
#define BITS 16
#define FLOATFMT "%.18e"
#define FIXEDFMT "%6d"
diff --git a/libavcodec/dca.c b/libavcodec/dca.c
index 103f058..b37dc49 100644
--- a/libavcodec/dca.c
+++ b/libavcodec/dca.c
@@ -27,6 +27,7 @@
#include <stdio.h>
#include "libavutil/common.h"
+#include "libavutil/float_dsp.h"
#include "libavutil/intmath.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
@@ -383,7 +384,7 @@ typedef struct {
int profile;
int debug_flag; ///< used for suppressing repeated error messages output
- DSPContext dsp;
+ AVFloatDSPContext fdsp;
FFTContext imdct;
SynthFilterContext synth;
DCADSPContext dcadsp;
@@ -1865,8 +1866,8 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
float *back_chan = s->samples + s->channel_order_tab[s->xch_base_channel] * 256;
float *lt_chan = s->samples + s->channel_order_tab[s->xch_base_channel - 2] * 256;
float *rt_chan = s->samples + s->channel_order_tab[s->xch_base_channel - 1] * 256;
- s->dsp.vector_fmac_scalar(lt_chan, back_chan, -M_SQRT1_2, 256);
- s->dsp.vector_fmac_scalar(rt_chan, back_chan, -M_SQRT1_2, 256);
+ s->fdsp.vector_fmac_scalar(lt_chan, back_chan, -M_SQRT1_2, 256);
+ s->fdsp.vector_fmac_scalar(rt_chan, back_chan, -M_SQRT1_2, 256);
}
if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT) {
@@ -1908,7 +1909,7 @@ static av_cold int dca_decode_init(AVCodecContext *avctx)
s->avctx = avctx;
dca_init_vlcs();
- ff_dsputil_init(&s->dsp, avctx);
+ avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
ff_mdct_init(&s->imdct, 6, 1, 1.0);
ff_synth_filter_init(&s->synth);
ff_dcadsp_init(&s->dcadsp);
diff --git a/libavcodec/dct-test.c b/libavcodec/dct-test.c
index bc5f2c5..4647642 100644
--- a/libavcodec/dct-test.c
+++ b/libavcodec/dct-test.c
@@ -28,13 +28,13 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <sys/time.h>
#include <unistd.h>
#include <math.h>
#include "libavutil/cpu.h"
#include "libavutil/common.h"
#include "libavutil/lfg.h"
+#include "libavutil/time.h"
#include "simple_idct.h"
#include "aandcttab.h"
@@ -143,13 +143,6 @@ static const struct algo idct_tab[] = {
#define AANSCALE_BITS 12
-static int64_t gettime(void)
-{
- struct timeval tv;
- gettimeofday(&tv, NULL);
- return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
-}
-
#define NB_ITS 20000
#define NB_ITS_SPEED 50000
@@ -181,14 +174,6 @@ static void idct_mmx_init(void)
DECLARE_ALIGNED(16, static DCTELEM, block)[64];
DECLARE_ALIGNED(8, static DCTELEM, block1)[64];
-static inline void mmx_emms(void)
-{
-#if HAVE_MMX
- if (cpu_flags & AV_CPU_FLAG_MMX)
- __asm__ volatile ("emms\n\t");
-#endif
-}
-
static void init_block(DCTELEM block[64], int test, int is_idct, AVLFG *prng)
{
int i, j;
@@ -263,7 +248,7 @@ static int dct_error(const struct algo *dct, int test, int is_idct, int speed)
permute(block, block1, dct->format);
dct->func(block);
- mmx_emms();
+ emms_c();
if (dct->format == SCALE_PERM) {
for (i = 0; i < 64; i++) {
@@ -320,7 +305,7 @@ static int dct_error(const struct algo *dct, int test, int is_idct, int speed)
init_block(block, test, is_idct, &prng);
permute(block1, block, dct->format);
- ti = gettime();
+ ti = av_gettime();
it1 = 0;
do {
for (it = 0; it < NB_ITS_SPEED; it++) {
@@ -328,9 +313,9 @@ static int dct_error(const struct algo *dct, int test, int is_idct, int speed)
dct->func(block);
}
it1 += NB_ITS_SPEED;
- ti1 = gettime() - ti;
+ ti1 = av_gettime() - ti;
} while (ti1 < 1000000);
- mmx_emms();
+ emms_c();
printf("%s %s: %0.1f kdct/s\n", is_idct ? "IDCT" : "DCT", dct->name,
(double) it1 * 1000.0 / (double) ti1);
@@ -461,7 +446,7 @@ static void idct248_error(const char *name,
if (!speed)
return;
- ti = gettime();
+ ti = av_gettime();
it1 = 0;
do {
for (it = 0; it < NB_ITS_SPEED; it++) {
@@ -470,9 +455,9 @@ static void idct248_error(const char *name,
idct248_put(img_dest, 8, block);
}
it1 += NB_ITS_SPEED;
- ti1 = gettime() - ti;
+ ti1 = av_gettime() - ti;
} while (ti1 < 1000000);
- mmx_emms();
+ emms_c();
printf("%s %s: %0.1f kdct/s\n", 1 ? "IDCT248" : "DCT248", name,
(double) it1 * 1000.0 / (double) ti1);
diff --git a/libavcodec/dfa.c b/libavcodec/dfa.c
index 788e9ca..7b6c5d5 100644
--- a/libavcodec/dfa.c
+++ b/libavcodec/dfa.c
@@ -49,7 +49,7 @@ static int decode_copy(GetByteContext *gb, uint8_t *frame, int width, int height
const int size = width * height;
if (bytestream2_get_buffer(gb, frame, size) != size)
- return -1;
+ return AVERROR_INVALIDDATA;
return 0;
}
@@ -64,23 +64,23 @@ static int decode_tsw1(GetByteContext *gb, uint8_t *frame, int width, int height
segments = bytestream2_get_le32(gb);
offset = bytestream2_get_le32(gb);
if (frame_end - frame <= offset)
- return -1;
+ return AVERROR_INVALIDDATA;
frame += offset;
while (segments--) {
if (bytestream2_get_bytes_left(gb) < 2)
- return -1;
+ return AVERROR_INVALIDDATA;
if (mask == 0x10000) {
bitbuf = bytestream2_get_le16u(gb);
mask = 1;
}
if (frame_end - frame < 2)
- return -1;
+ return AVERROR_INVALIDDATA;
if (bitbuf & mask) {
v = bytestream2_get_le16(gb);
offset = (v & 0x1FFF) << 1;
count = ((v >> 13) + 2) << 1;
if (frame - frame_start < offset || frame_end - frame < count)
- return -1;
+ return AVERROR_INVALIDDATA;
av_memcpy_backptr(frame, offset, count);
frame += count;
} else {
@@ -103,19 +103,19 @@ static int decode_dsw1(GetByteContext *gb, uint8_t *frame, int width, int height
segments = bytestream2_get_le16(gb);
while (segments--) {
if (bytestream2_get_bytes_left(gb) < 2)
- return -1;
+ return AVERROR_INVALIDDATA;
if (mask == 0x10000) {
bitbuf = bytestream2_get_le16u(gb);
mask = 1;
}
if (frame_end - frame < 2)
- return -1;
+ return AVERROR_INVALIDDATA;
if (bitbuf & mask) {
v = bytestream2_get_le16(gb);
offset = (v & 0x1FFF) << 1;
count = ((v >> 13) + 2) << 1;
if (frame - frame_start < offset || frame_end - frame < count)
- return -1;
+ return AVERROR_INVALIDDATA;
// can't use av_memcpy_backptr() since it can overwrite following pixels
for (v = 0; v < count; v++)
frame[v] = frame[v - offset];
@@ -142,19 +142,19 @@ static int decode_dds1(GetByteContext *gb, uint8_t *frame, int width, int height
segments = bytestream2_get_le16(gb);
while (segments--) {
if (bytestream2_get_bytes_left(gb) < 2)
- return -1;
+ return AVERROR_INVALIDDATA;
if (mask == 0x10000) {
bitbuf = bytestream2_get_le16u(gb);
mask = 1;
}
if (frame_end - frame < 2)
- return -1;
+ return AVERROR_INVALIDDATA;
if (bitbuf & mask) {
v = bytestream2_get_le16(gb);
offset = (v & 0x1FFF) << 2;
count = ((v >> 13) + 2) << 1;
if (frame - frame_start < offset || frame_end - frame < count*2 + width)
- return -1;
+ return AVERROR_INVALIDDATA;
for (i = 0; i < count; i++) {
frame[0] = frame[1] =
frame[width] = frame[width + 1] = frame[-offset];
@@ -164,6 +164,8 @@ static int decode_dds1(GetByteContext *gb, uint8_t *frame, int width, int height
} else if (bitbuf & (mask << 1)) {
frame += bytestream2_get_le16(gb) * 2;
} else {
+ if (frame_end - frame < width + 2)
+ return AVERROR_INVALIDDATA;
frame[0] = frame[1] =
frame[width] = frame[width + 1] = bytestream2_get_byte(gb);
frame += 2;
@@ -184,32 +186,32 @@ static int decode_bdlt(GetByteContext *gb, uint8_t *frame, int width, int height
count = bytestream2_get_le16(gb);
if (count >= height)
- return -1;
+ return AVERROR_INVALIDDATA;
frame += width * count;
lines = bytestream2_get_le16(gb);
if (count + lines > height)
- return -1;
+ return AVERROR_INVALIDDATA;
while (lines--) {
if (bytestream2_get_bytes_left(gb) < 1)
- return -1;
+ return AVERROR_INVALIDDATA;
line_ptr = frame;
frame += width;
segments = bytestream2_get_byteu(gb);
while (segments--) {
if (frame - line_ptr <= bytestream2_peek_byte(gb))
- return -1;
+ return AVERROR_INVALIDDATA;
line_ptr += bytestream2_get_byte(gb);
count = (int8_t)bytestream2_get_byte(gb);
if (count >= 0) {
if (frame - line_ptr < count)
- return -1;
+ return AVERROR_INVALIDDATA;
if (bytestream2_get_buffer(gb, line_ptr, count) != count)
- return -1;
+ return AVERROR_INVALIDDATA;
} else {
count = -count;
if (frame - line_ptr < count)
- return -1;
+ return AVERROR_INVALIDDATA;
memset(line_ptr, bytestream2_get_byte(gb), count);
}
line_ptr += count;
@@ -224,20 +226,23 @@ static int decode_wdlt(GetByteContext *gb, uint8_t *frame, int width, int height
const uint8_t *frame_end = frame + width * height;
uint8_t *line_ptr;
int count, i, v, lines, segments;
+ int y = 0;
lines = bytestream2_get_le16(gb);
if (lines > height)
- return -1;
+ return AVERROR_INVALIDDATA;
while (lines--) {
if (bytestream2_get_bytes_left(gb) < 2)
- return -1;
+ return AVERROR_INVALIDDATA;
segments = bytestream2_get_le16u(gb);
while ((segments & 0xC000) == 0xC000) {
+ unsigned skip_lines = -(int16_t)segments;
unsigned delta = -((int16_t)segments * width);
- if (frame_end - frame <= delta)
- return -1;
+ if (frame_end - frame <= delta || y + lines + skip_lines > height)
+ return AVERROR_INVALIDDATA;
frame += delta;
+ y += skip_lines;
segments = bytestream2_get_le16(gb);
}
if (segments & 0x8000) {
@@ -246,21 +251,22 @@ static int decode_wdlt(GetByteContext *gb, uint8_t *frame, int width, int height
}
line_ptr = frame;
frame += width;
+ y++;
while (segments--) {
if (frame - line_ptr <= bytestream2_peek_byte(gb))
- return -1;
+ return AVERROR_INVALIDDATA;
line_ptr += bytestream2_get_byte(gb);
count = (int8_t)bytestream2_get_byte(gb);
if (count >= 0) {
if (frame - line_ptr < count * 2)
- return -1;
+ return AVERROR_INVALIDDATA;
if (bytestream2_get_buffer(gb, line_ptr, count * 2) != count * 2)
- return -1;
+ return AVERROR_INVALIDDATA;
line_ptr += count * 2;
} else {
count = -count;
if (frame - line_ptr < count * 2)
- return -1;
+ return AVERROR_INVALIDDATA;
v = bytestream2_get_le16(gb);
for (i = 0; i < count; i++)
bytestream_put_le16(&line_ptr, v);
@@ -273,7 +279,7 @@ static int decode_wdlt(GetByteContext *gb, uint8_t *frame, int width, int height
static int decode_unk6(GetByteContext *gb, uint8_t *frame, int width, int height)
{
- return -1;
+ return AVERROR_PATCHWELCOME;
}
static int decode_blck(GetByteContext *gb, uint8_t *frame, int width, int height)
@@ -332,7 +338,7 @@ static int dfa_decode_frame(AVCodecContext *avctx,
if (decoder[chunk_type - 2](&gb, s->frame_buf, avctx->width, avctx->height)) {
av_log(avctx, AV_LOG_ERROR, "Error decoding %s chunk\n",
chunk_name[chunk_type - 2]);
- return -1;
+ return AVERROR_INVALIDDATA;
}
} else {
av_log(avctx, AV_LOG_WARNING, "Ignoring unknown chunk type %d\n",
diff --git a/libavcodec/dirac.c b/libavcodec/dirac.c
index bf56088..07329e3 100644
--- a/libavcodec/dirac.c
+++ b/libavcodec/dirac.c
@@ -108,7 +108,7 @@ static const enum PixelFormat dirac_pix_fmt[2][3] = {
static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb,
dirac_source_params *source)
{
- AVRational frame_rate = (AVRational){0,0};
+ AVRational frame_rate = {0,0};
unsigned luma_depth = 8, luma_offset = 16;
int idx;
diff --git a/libavcodec/dnxhdenc.h b/libavcodec/dnxhdenc.h
index 861546a..7e2f96f 100644
--- a/libavcodec/dnxhdenc.h
+++ b/libavcodec/dnxhdenc.h
@@ -92,7 +92,7 @@ typedef struct DNXHDEncContext {
RCCMPEntry *mb_cmp;
RCEntry (*mb_rc)[8160];
- void (*get_pixels_8x4_sym)(DCTELEM */*align 16*/, const uint8_t *, int);
+ void (*get_pixels_8x4_sym)(DCTELEM * /*align 16*/, const uint8_t *, int);
} DNXHDEncContext;
void ff_dnxhd_init_mmx(DNXHDEncContext *ctx);
diff --git a/libavcodec/dsicinav.c b/libavcodec/dsicinav.c
index d3b2cbd..7e64b97 100644
--- a/libavcodec/dsicinav.c
+++ b/libavcodec/dsicinav.c
@@ -121,7 +121,7 @@ static int cin_decode_huffman(const unsigned char *src, int src_size, unsigned c
unsigned char *dst_end = dst + dst_size;
const unsigned char *src_end = src + src_size;
- memcpy(huff_code_table, src, 15); src += 15; src_size -= 15;
+ memcpy(huff_code_table, src, 15); src += 15;
while (src < src_end) {
huff_code = *src++;
diff --git a/libavcodec/dsputil.c b/libavcodec/dsputil.c
index f42c585..15f184e 100644
--- a/libavcodec/dsputil.c
+++ b/libavcodec/dsputil.c
@@ -2363,12 +2363,6 @@ WRAPPER8_16_SQ(quant_psnr8x8_c, quant_psnr16_c)
WRAPPER8_16_SQ(rd8x8_c, rd16_c)
WRAPPER8_16_SQ(bit8x8_c, bit16_c)
-static void vector_fmul_c(float *dst, const float *src0, const float *src1, int len){
- int i;
- for(i=0; i<len; i++)
- dst[i] = src0[i] * src1[i];
-}
-
static void vector_fmul_reverse_c(float *dst, const float *src0, const float *src1, int len){
int i;
src1 += len-1;
@@ -2407,14 +2401,6 @@ static void vector_fmul_scalar_c(float *dst, const float *src, float mul,
dst[i] = src[i] * mul;
}
-static void vector_fmac_scalar_c(float *dst, const float *src, float mul,
- int len)
-{
- int i;
- for (i = 0; i < len; i++)
- dst[i] += src[i] * mul;
-}
-
static void butterflies_float_c(float *restrict v1, float *restrict v2,
int len)
{
@@ -2898,7 +2884,6 @@ av_cold void ff_dsputil_init(DSPContext* c, AVCodecContext *avctx)
#if CONFIG_AC3_DECODER
c->ac3_downmix = ff_ac3_downmix_c;
#endif
- c->vector_fmul = vector_fmul_c;
c->vector_fmul_reverse = vector_fmul_reverse_c;
c->vector_fmul_add = vector_fmul_add_c;
c->vector_fmul_window = vector_fmul_window_c;
@@ -2911,7 +2896,6 @@ av_cold void ff_dsputil_init(DSPContext* c, AVCodecContext *avctx)
c->butterflies_float = butterflies_float_c;
c->butterflies_float_interleave = butterflies_float_interleave_c;
c->vector_fmul_scalar = vector_fmul_scalar_c;
- c->vector_fmac_scalar = vector_fmac_scalar_c;
c->shrink[0]= av_image_copy_plane;
c->shrink[1]= ff_shrink22;
diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h
index 3906119..77980e0 100644
--- a/libavcodec/dsputil.h
+++ b/libavcodec/dsputil.h
@@ -398,8 +398,7 @@ typedef struct DSPContext {
/* assume len is a multiple of 4, and arrays are 16-byte aligned */
void (*vorbis_inverse_coupling)(float *mag, float *ang, int blocksize);
void (*ac3_downmix)(float (*samples)[256], float (*matrix)[2], int out_ch, int in_ch, int len);
- /* assume len is a multiple of 8, and arrays are 16-byte aligned */
- void (*vector_fmul)(float *dst, const float *src0, const float *src1, int len);
+ /* assume len is a multiple of 16, and arrays are 32-byte aligned */
void (*vector_fmul_reverse)(float *dst, const float *src0, const float *src1, int len);
/* assume len is a multiple of 8, and src arrays are 16-byte aligned */
void (*vector_fmul_add)(float *dst, const float *src0, const float *src1, const float *src2, int len);
@@ -418,17 +417,6 @@ typedef struct DSPContext {
void (*vector_fmul_scalar)(float *dst, const float *src, float mul,
int len);
/**
- * Multiply a vector of floats by a scalar float and add to
- * destination vector. Source and destination vectors must
- * overlap exactly or not at all.
- * @param dst result vector, 16-byte aligned
- * @param src input vector, 16-byte aligned
- * @param mul scalar value
- * @param len length of vector, multiple of 4
- */
- void (*vector_fmac_scalar)(float *dst, const float *src, float mul,
- int len);
- /**
* Calculate the scalar product of two vectors of floats.
* @param v1 first vector, 16-byte aligned
* @param v2 second vector, 16-byte aligned
@@ -560,9 +548,9 @@ typedef struct DSPContext {
* @param src source array
* constraints: 16-byte aligned
* @param min minimum value
- * constraints: must in the the range [-(1<<24), 1<<24]
+ * constraints: must be in the range [-(1 << 24), 1 << 24]
* @param max maximum value
- * constraints: must in the the range [-(1<<24), 1<<24]
+ * constraints: must be in the range [-(1 << 24), 1 << 24]
* @param len number of elements in the array
* constraints: multiple of 32 greater than zero
*/
diff --git a/libavcodec/dv.c b/libavcodec/dv.c
index 79e73dd..16be0ed 100644
--- a/libavcodec/dv.c
+++ b/libavcodec/dv.c
@@ -662,7 +662,7 @@ static int dv_encode_video_segment(AVCodecContext *avctx, void *arg)
int mb_x, mb_y, c_offset, linesize, y_stride;
uint8_t* y_ptr;
uint8_t* dif;
- LOCAL_ALIGNED_8(uint8_t, scratch, [64]);
+ LOCAL_ALIGNED_8(uint8_t, scratch, [128]);
EncBlockInfo enc_blks[5*DV_MAX_BPM];
PutBitContext pbs[5*DV_MAX_BPM];
PutBitContext* pb;
@@ -717,10 +717,10 @@ static int dv_encode_video_segment(AVCodecContext *avctx, void *arg)
b[0] = c_ptr[0]; b[1] = c_ptr[1]; b[2] = c_ptr[2]; b[3] = c_ptr[3];
b[4] = d[0]; b[5] = d[1]; b[6] = d[2]; b[7] = d[3];
c_ptr += linesize;
- b += 8;
+ b += 16;
}
c_ptr = scratch;
- linesize = 8;
+ linesize = 16;
}
vs_bit_size += dv_init_enc_block( enc_blk++, c_ptr , linesize, s, 1);
diff --git a/libavcodec/dv_profile.c b/libavcodec/dv_profile.c
new file mode 100644
index 0000000..8b604c2
--- /dev/null
+++ b/libavcodec/dv_profile.c
@@ -0,0 +1,331 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+
+#include "libavutil/log.h"
+#include "libavutil/pixdesc.h"
+#include "avcodec.h"
+#include "dv_profile.h"
+
+static DVwork_chunk work_chunks_dv25pal [1*12*27];
+static DVwork_chunk work_chunks_dv25pal411[1*12*27];
+static DVwork_chunk work_chunks_dv25ntsc [1*10*27];
+static DVwork_chunk work_chunks_dv50pal [2*12*27];
+static DVwork_chunk work_chunks_dv50ntsc [2*10*27];
+static DVwork_chunk work_chunks_dv100palp [2*12*27];
+static DVwork_chunk work_chunks_dv100ntscp[2*10*27];
+static DVwork_chunk work_chunks_dv100pali [4*12*27];
+static DVwork_chunk work_chunks_dv100ntsci[4*10*27];
+
+static uint32_t dv_idct_factor_sd [2*2*22*64];
+static uint32_t dv_idct_factor_hd1080[2*4*16*64];
+static uint32_t dv_idct_factor_hd720 [2*4*16*64];
+
+static const uint8_t dv_audio_shuffle525[10][9] = {
+ { 0, 30, 60, 20, 50, 80, 10, 40, 70 }, /* 1st channel */
+ { 6, 36, 66, 26, 56, 86, 16, 46, 76 },
+ { 12, 42, 72, 2, 32, 62, 22, 52, 82 },
+ { 18, 48, 78, 8, 38, 68, 28, 58, 88 },
+ { 24, 54, 84, 14, 44, 74, 4, 34, 64 },
+
+ { 1, 31, 61, 21, 51, 81, 11, 41, 71 }, /* 2nd channel */
+ { 7, 37, 67, 27, 57, 87, 17, 47, 77 },
+ { 13, 43, 73, 3, 33, 63, 23, 53, 83 },
+ { 19, 49, 79, 9, 39, 69, 29, 59, 89 },
+ { 25, 55, 85, 15, 45, 75, 5, 35, 65 },
+};
+
+static const uint8_t dv_audio_shuffle625[12][9] = {
+ { 0, 36, 72, 26, 62, 98, 16, 52, 88}, /* 1st channel */
+ { 6, 42, 78, 32, 68, 104, 22, 58, 94},
+ { 12, 48, 84, 2, 38, 74, 28, 64, 100},
+ { 18, 54, 90, 8, 44, 80, 34, 70, 106},
+ { 24, 60, 96, 14, 50, 86, 4, 40, 76},
+ { 30, 66, 102, 20, 56, 92, 10, 46, 82},
+
+ { 1, 37, 73, 27, 63, 99, 17, 53, 89}, /* 2nd channel */
+ { 7, 43, 79, 33, 69, 105, 23, 59, 95},
+ { 13, 49, 85, 3, 39, 75, 29, 65, 101},
+ { 19, 55, 91, 9, 45, 81, 35, 71, 107},
+ { 25, 61, 97, 15, 51, 87, 5, 41, 77},
+ { 31, 67, 103, 21, 57, 93, 11, 47, 83},
+};
+
+/* macroblock bit budgets */
+static const uint8_t block_sizes_dv2550[8] = {
+ 112, 112, 112, 112, 80, 80, 0, 0,
+};
+
+static const uint8_t block_sizes_dv100[8] = {
+ 80, 80, 80, 80, 80, 80, 64, 64,
+};
+
+static const DVprofile dv_profiles[] = {
+ { .dsf = 0,
+ .video_stype = 0x0,
+ .frame_size = 120000, /* IEC 61834, SMPTE-314M - 525/60 (NTSC) */
+ .difseg_size = 10,
+ .n_difchan = 1,
+ .time_base = { 1001, 30000 },
+ .ltc_divisor = 30,
+ .height = 480,
+ .width = 720,
+ .sar = {{8, 9}, {32, 27}},
+ .work_chunks = &work_chunks_dv25ntsc[0],
+ .idct_factor = &dv_idct_factor_sd[0],
+ .pix_fmt = PIX_FMT_YUV411P,
+ .bpm = 6,
+ .block_sizes = block_sizes_dv2550,
+ .audio_stride = 90,
+ .audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */
+ .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */
+ .audio_shuffle = dv_audio_shuffle525,
+ },
+ { .dsf = 1,
+ .video_stype = 0x0,
+ .frame_size = 144000, /* IEC 61834 - 625/50 (PAL) */
+ .difseg_size = 12,
+ .n_difchan = 1,
+ .time_base = { 1, 25 },
+ .ltc_divisor = 25,
+ .height = 576,
+ .width = 720,
+ .sar = {{16, 15}, {64, 45}},
+ .work_chunks = &work_chunks_dv25pal[0],
+ .idct_factor = &dv_idct_factor_sd[0],
+ .pix_fmt = PIX_FMT_YUV420P,
+ .bpm = 6,
+ .block_sizes = block_sizes_dv2550,
+ .audio_stride = 108,
+ .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
+ .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
+ .audio_shuffle = dv_audio_shuffle625,
+ },
+ { .dsf = 1,
+ .video_stype = 0x0,
+ .frame_size = 144000, /* SMPTE-314M - 625/50 (PAL) */
+ .difseg_size = 12,
+ .n_difchan = 1,
+ .time_base = { 1, 25 },
+ .ltc_divisor = 25,
+ .height = 576,
+ .width = 720,
+ .sar = {{16, 15}, {64, 45}},
+ .work_chunks = &work_chunks_dv25pal411[0],
+ .idct_factor = &dv_idct_factor_sd[0],
+ .pix_fmt = PIX_FMT_YUV411P,
+ .bpm = 6,
+ .block_sizes = block_sizes_dv2550,
+ .audio_stride = 108,
+ .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
+ .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
+ .audio_shuffle = dv_audio_shuffle625,
+ },
+ { .dsf = 0,
+ .video_stype = 0x4,
+ .frame_size = 240000, /* SMPTE-314M - 525/60 (NTSC) 50 Mbps */
+ .difseg_size = 10, /* also known as "DVCPRO50" */
+ .n_difchan = 2,
+ .time_base = { 1001, 30000 },
+ .ltc_divisor = 30,
+ .height = 480,
+ .width = 720,
+ .sar = {{8, 9}, {32, 27}},
+ .work_chunks = &work_chunks_dv50ntsc[0],
+ .idct_factor = &dv_idct_factor_sd[0],
+ .pix_fmt = PIX_FMT_YUV422P,
+ .bpm = 6,
+ .block_sizes = block_sizes_dv2550,
+ .audio_stride = 90,
+ .audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */
+ .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */
+ .audio_shuffle = dv_audio_shuffle525,
+ },
+ { .dsf = 1,
+ .video_stype = 0x4,
+ .frame_size = 288000, /* SMPTE-314M - 625/50 (PAL) 50 Mbps */
+ .difseg_size = 12, /* also known as "DVCPRO50" */
+ .n_difchan = 2,
+ .time_base = { 1, 25 },
+ .ltc_divisor = 25,
+ .height = 576,
+ .width = 720,
+ .sar = {{16, 15}, {64, 45}},
+ .work_chunks = &work_chunks_dv50pal[0],
+ .idct_factor = &dv_idct_factor_sd[0],
+ .pix_fmt = PIX_FMT_YUV422P,
+ .bpm = 6,
+ .block_sizes = block_sizes_dv2550,
+ .audio_stride = 108,
+ .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
+ .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
+ .audio_shuffle = dv_audio_shuffle625,
+ },
+ { .dsf = 0,
+ .video_stype = 0x14,
+ .frame_size = 480000, /* SMPTE-370M - 1080i60 100 Mbps */
+ .difseg_size = 10, /* also known as "DVCPRO HD" */
+ .n_difchan = 4,
+ .time_base = { 1001, 30000 },
+ .ltc_divisor = 30,
+ .height = 1080,
+ .width = 1280,
+ .sar = {{1, 1}, {3, 2}},
+ .work_chunks = &work_chunks_dv100ntsci[0],
+ .idct_factor = &dv_idct_factor_hd1080[0],
+ .pix_fmt = PIX_FMT_YUV422P,
+ .bpm = 8,
+ .block_sizes = block_sizes_dv100,
+ .audio_stride = 90,
+ .audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */
+ .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */
+ .audio_shuffle = dv_audio_shuffle525,
+ },
+ { .dsf = 1,
+ .video_stype = 0x14,
+ .frame_size = 576000, /* SMPTE-370M - 1080i50 100 Mbps */
+ .difseg_size = 12, /* also known as "DVCPRO HD" */
+ .n_difchan = 4,
+ .time_base = { 1, 25 },
+ .ltc_divisor = 25,
+ .height = 1080,
+ .width = 1440,
+ .sar = {{1, 1}, {4, 3}},
+ .work_chunks = &work_chunks_dv100pali[0],
+ .idct_factor = &dv_idct_factor_hd1080[0],
+ .pix_fmt = PIX_FMT_YUV422P,
+ .bpm = 8,
+ .block_sizes = block_sizes_dv100,
+ .audio_stride = 108,
+ .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
+ .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
+ .audio_shuffle = dv_audio_shuffle625,
+ },
+ { .dsf = 0,
+ .video_stype = 0x18,
+ .frame_size = 240000, /* SMPTE-370M - 720p60 100 Mbps */
+ .difseg_size = 10, /* also known as "DVCPRO HD" */
+ .n_difchan = 2,
+ .time_base = { 1001, 60000 },
+ .ltc_divisor = 60,
+ .height = 720,
+ .width = 960,
+ .sar = {{1, 1}, {4, 3}},
+ .work_chunks = &work_chunks_dv100ntscp[0],
+ .idct_factor = &dv_idct_factor_hd720[0],
+ .pix_fmt = PIX_FMT_YUV422P,
+ .bpm = 8,
+ .block_sizes = block_sizes_dv100,
+ .audio_stride = 90,
+ .audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */
+ .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */
+ .audio_shuffle = dv_audio_shuffle525,
+ },
+ { .dsf = 1,
+ .video_stype = 0x18,
+ .frame_size = 288000, /* SMPTE-370M - 720p50 100 Mbps */
+ .difseg_size = 12, /* also known as "DVCPRO HD" */
+ .n_difchan = 2,
+ .time_base = { 1, 50 },
+ .ltc_divisor = 50,
+ .height = 720,
+ .width = 960,
+ .sar = {{1, 1}, {4, 3}},
+ .work_chunks = &work_chunks_dv100palp[0],
+ .idct_factor = &dv_idct_factor_hd720[0],
+ .pix_fmt = PIX_FMT_YUV422P,
+ .bpm = 8,
+ .block_sizes = block_sizes_dv100,
+ .audio_stride = 90,
+ .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
+ .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
+ .audio_shuffle = dv_audio_shuffle625,
+ },
+ { .dsf = 1,
+ .video_stype = 0x1,
+ .frame_size = 144000, /* IEC 61883-5 - 625/50 (PAL) */
+ .difseg_size = 12,
+ .n_difchan = 1,
+ .time_base = { 1, 25 },
+ .ltc_divisor = 25,
+ .height = 576,
+ .width = 720,
+ .sar = {{16, 15}, {64, 45}},
+ .work_chunks = &work_chunks_dv25pal[0],
+ .idct_factor = &dv_idct_factor_sd[0],
+ .pix_fmt = PIX_FMT_YUV420P,
+ .bpm = 6,
+ .block_sizes = block_sizes_dv2550,
+ .audio_stride = 108,
+ .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
+ .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
+ .audio_shuffle = dv_audio_shuffle625,
+ }
+};
+
+const DVprofile* avpriv_dv_frame_profile(const DVprofile *sys,
+ const uint8_t* frame, unsigned buf_size)
+{
+ int i, dsf, stype;
+
+ if (buf_size < 80 * 5 + 48 + 4)
+ return NULL;
+
+ dsf = (frame[3] & 0x80) >> 7;
+ stype = frame[80 * 5 + 48 + 3] & 0x1f;
+
+ /* 576i50 25Mbps 4:1:1 is a special case */
+ if (dsf == 1 && stype == 0 && frame[4] & 0x07 /* the APT field */) {
+ return &dv_profiles[2];
+ }
+
+ for (i = 0; i < FF_ARRAY_ELEMS(dv_profiles); i++)
+ if (dsf == dv_profiles[i].dsf && stype == dv_profiles[i].video_stype)
+ return &dv_profiles[i];
+
+ /* check if old sys matches and assumes corrupted input */
+ if (sys && buf_size == sys->frame_size)
+ return sys;
+
+ return NULL;
+}
+
+const DVprofile* avpriv_dv_codec_profile(AVCodecContext* codec)
+{
+ int i;
+
+ for (i=0; i<FF_ARRAY_ELEMS(dv_profiles); i++)
+ if (codec->height == dv_profiles[i].height &&
+ codec->pix_fmt == dv_profiles[i].pix_fmt &&
+ codec->width == dv_profiles[i].width)
+ return &dv_profiles[i];
+
+ return NULL;
+}
+
+void ff_dv_print_profiles(void *logctx, int loglevel)
+{
+ int i;
+ for (i = 0; i < FF_ARRAY_ELEMS(dv_profiles); i++) {
+ const DVprofile *p = &dv_profiles[i];
+ av_log(logctx, loglevel, "Frame size: %dx%d; pixel format: %s, "
+ "framerate: %d/%d\n", p->width, p->height, av_get_pix_fmt_name(p->pix_fmt),
+ p->time_base.den, p->time_base.num);
+ }
+}
diff --git a/libavcodec/dv_profile.h b/libavcodec/dv_profile.h
new file mode 100644
index 0000000..4fcf3e1
--- /dev/null
+++ b/libavcodec/dv_profile.h
@@ -0,0 +1,72 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_DV_PROFILE_H
+#define AVCODEC_DV_PROFILE_H
+
+#include <stdint.h>
+
+#include "libavutil/pixfmt.h"
+#include "libavutil/rational.h"
+#include "avcodec.h"
+
+typedef struct DVwork_chunk {
+ uint16_t buf_offset;
+ uint16_t mb_coordinates[5];
+} DVwork_chunk;
+
+/*
+ * DVprofile is used to express the differences between various
+ * DV flavors. For now it's primarily used for differentiating
+ * 525/60 and 625/50, but the plans are to use it for various
+ * DV specs as well (e.g. SMPTE314M vs. IEC 61834).
+ */
+typedef struct DVprofile {
+ int dsf; /* value of the dsf in the DV header */
+ int video_stype; /* stype for VAUX source pack */
+ int frame_size; /* total size of one frame in bytes */
+ int difseg_size; /* number of DIF segments per DIF channel */
+ int n_difchan; /* number of DIF channels per frame */
+ AVRational time_base; /* 1/framerate */
+ int ltc_divisor; /* FPS from the LTS standpoint */
+ int height; /* picture height in pixels */
+ int width; /* picture width in pixels */
+ AVRational sar[2]; /* sample aspect ratios for 4:3 and 16:9 */
+ DVwork_chunk *work_chunks; /* each thread gets its own chunk of frame to work on */
+ uint32_t *idct_factor; /* set of iDCT factor tables */
+ enum PixelFormat pix_fmt; /* picture pixel format */
+ int bpm; /* blocks per macroblock */
+ const uint8_t *block_sizes; /* AC block sizes, in bits */
+ int audio_stride; /* size of audio_shuffle table */
+ int audio_min_samples[3]; /* min amount of audio samples */
+ /* for 48kHz, 44.1kHz and 32kHz */
+ int audio_samples_dist[5]; /* how many samples are supposed to be */
+ /* in each frame in a 5 frames window */
+ const uint8_t (*audio_shuffle)[9]; /* PCM shuffling table */
+} DVprofile;
+
+const DVprofile* avpriv_dv_frame_profile(const DVprofile *sys,
+ const uint8_t* frame, unsigned buf_size);
+const DVprofile* avpriv_dv_codec_profile(AVCodecContext* codec);
+
+/**
+ * Print all allowed DV profiles into logctx at specified logging level.
+ */
+void ff_dv_print_profiles(void *logctx, int loglevel);
+
+#endif /* AVCODEC_DV_PROFILE_H */
diff --git a/libavcodec/dvdata.c b/libavcodec/dvdata.c
index 353ecd5..c779277 100644
--- a/libavcodec/dvdata.c
+++ b/libavcodec/dvdata.c
@@ -24,8 +24,6 @@
* Constants for DV codec.
*/
-#include "libavutil/rational.h"
-#include "libavutil/pixdesc.h"
#include "avcodec.h"
#include "dvdata.h"
@@ -122,308 +120,3 @@ const int ff_dv_iweight_720_c[64] = {
394, 406, 418, 438, 418, 464, 464, 492,
};
-static DVwork_chunk work_chunks_dv25pal [1*12*27];
-static DVwork_chunk work_chunks_dv25pal411[1*12*27];
-static DVwork_chunk work_chunks_dv25ntsc [1*10*27];
-static DVwork_chunk work_chunks_dv50pal [2*12*27];
-static DVwork_chunk work_chunks_dv50ntsc [2*10*27];
-static DVwork_chunk work_chunks_dv100palp [2*12*27];
-static DVwork_chunk work_chunks_dv100ntscp[2*10*27];
-static DVwork_chunk work_chunks_dv100pali [4*12*27];
-static DVwork_chunk work_chunks_dv100ntsci[4*10*27];
-
-static uint32_t dv_idct_factor_sd [2*2*22*64];
-static uint32_t dv_idct_factor_hd1080[2*4*16*64];
-static uint32_t dv_idct_factor_hd720 [2*4*16*64];
-
-static const uint8_t dv_audio_shuffle525[10][9] = {
- { 0, 30, 60, 20, 50, 80, 10, 40, 70 }, /* 1st channel */
- { 6, 36, 66, 26, 56, 86, 16, 46, 76 },
- { 12, 42, 72, 2, 32, 62, 22, 52, 82 },
- { 18, 48, 78, 8, 38, 68, 28, 58, 88 },
- { 24, 54, 84, 14, 44, 74, 4, 34, 64 },
-
- { 1, 31, 61, 21, 51, 81, 11, 41, 71 }, /* 2nd channel */
- { 7, 37, 67, 27, 57, 87, 17, 47, 77 },
- { 13, 43, 73, 3, 33, 63, 23, 53, 83 },
- { 19, 49, 79, 9, 39, 69, 29, 59, 89 },
- { 25, 55, 85, 15, 45, 75, 5, 35, 65 },
-};
-
-static const uint8_t dv_audio_shuffle625[12][9] = {
- { 0, 36, 72, 26, 62, 98, 16, 52, 88}, /* 1st channel */
- { 6, 42, 78, 32, 68, 104, 22, 58, 94},
- { 12, 48, 84, 2, 38, 74, 28, 64, 100},
- { 18, 54, 90, 8, 44, 80, 34, 70, 106},
- { 24, 60, 96, 14, 50, 86, 4, 40, 76},
- { 30, 66, 102, 20, 56, 92, 10, 46, 82},
-
- { 1, 37, 73, 27, 63, 99, 17, 53, 89}, /* 2nd channel */
- { 7, 43, 79, 33, 69, 105, 23, 59, 95},
- { 13, 49, 85, 3, 39, 75, 29, 65, 101},
- { 19, 55, 91, 9, 45, 81, 35, 71, 107},
- { 25, 61, 97, 15, 51, 87, 5, 41, 77},
- { 31, 67, 103, 21, 57, 93, 11, 47, 83},
-};
-
-/* macroblock bit budgets */
-static const uint8_t block_sizes_dv2550[8] = {
- 112, 112, 112, 112, 80, 80, 0, 0,
-};
-
-static const uint8_t block_sizes_dv100[8] = {
- 80, 80, 80, 80, 80, 80, 64, 64,
-};
-static const DVprofile dv_profiles[] = {
- { .dsf = 0,
- .video_stype = 0x0,
- .frame_size = 120000, /* IEC 61834, SMPTE-314M - 525/60 (NTSC) */
- .difseg_size = 10,
- .n_difchan = 1,
- .time_base = { 1001, 30000 },
- .ltc_divisor = 30,
- .height = 480,
- .width = 720,
- .sar = {{8, 9}, {32, 27}},
- .work_chunks = &work_chunks_dv25ntsc[0],
- .idct_factor = &dv_idct_factor_sd[0],
- .pix_fmt = PIX_FMT_YUV411P,
- .bpm = 6,
- .block_sizes = block_sizes_dv2550,
- .audio_stride = 90,
- .audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */
- .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */
- .audio_shuffle = dv_audio_shuffle525,
- },
- { .dsf = 1,
- .video_stype = 0x0,
- .frame_size = 144000, /* IEC 61834 - 625/50 (PAL) */
- .difseg_size = 12,
- .n_difchan = 1,
- .time_base = { 1, 25 },
- .ltc_divisor = 25,
- .height = 576,
- .width = 720,
- .sar = {{16, 15}, {64, 45}},
- .work_chunks = &work_chunks_dv25pal[0],
- .idct_factor = &dv_idct_factor_sd[0],
- .pix_fmt = PIX_FMT_YUV420P,
- .bpm = 6,
- .block_sizes = block_sizes_dv2550,
- .audio_stride = 108,
- .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
- .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
- .audio_shuffle = dv_audio_shuffle625,
- },
- { .dsf = 1,
- .video_stype = 0x0,
- .frame_size = 144000, /* SMPTE-314M - 625/50 (PAL) */
- .difseg_size = 12,
- .n_difchan = 1,
- .time_base = { 1, 25 },
- .ltc_divisor = 25,
- .height = 576,
- .width = 720,
- .sar = {{16, 15}, {64, 45}},
- .work_chunks = &work_chunks_dv25pal411[0],
- .idct_factor = &dv_idct_factor_sd[0],
- .pix_fmt = PIX_FMT_YUV411P,
- .bpm = 6,
- .block_sizes = block_sizes_dv2550,
- .audio_stride = 108,
- .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
- .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
- .audio_shuffle = dv_audio_shuffle625,
- },
- { .dsf = 0,
- .video_stype = 0x4,
- .frame_size = 240000, /* SMPTE-314M - 525/60 (NTSC) 50 Mbps */
- .difseg_size = 10, /* also known as "DVCPRO50" */
- .n_difchan = 2,
- .time_base = { 1001, 30000 },
- .ltc_divisor = 30,
- .height = 480,
- .width = 720,
- .sar = {{8, 9}, {32, 27}},
- .work_chunks = &work_chunks_dv50ntsc[0],
- .idct_factor = &dv_idct_factor_sd[0],
- .pix_fmt = PIX_FMT_YUV422P,
- .bpm = 6,
- .block_sizes = block_sizes_dv2550,
- .audio_stride = 90,
- .audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */
- .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */
- .audio_shuffle = dv_audio_shuffle525,
- },
- { .dsf = 1,
- .video_stype = 0x4,
- .frame_size = 288000, /* SMPTE-314M - 625/50 (PAL) 50 Mbps */
- .difseg_size = 12, /* also known as "DVCPRO50" */
- .n_difchan = 2,
- .time_base = { 1, 25 },
- .ltc_divisor = 25,
- .height = 576,
- .width = 720,
- .sar = {{16, 15}, {64, 45}},
- .work_chunks = &work_chunks_dv50pal[0],
- .idct_factor = &dv_idct_factor_sd[0],
- .pix_fmt = PIX_FMT_YUV422P,
- .bpm = 6,
- .block_sizes = block_sizes_dv2550,
- .audio_stride = 108,
- .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
- .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
- .audio_shuffle = dv_audio_shuffle625,
- },
- { .dsf = 0,
- .video_stype = 0x14,
- .frame_size = 480000, /* SMPTE-370M - 1080i60 100 Mbps */
- .difseg_size = 10, /* also known as "DVCPRO HD" */
- .n_difchan = 4,
- .time_base = { 1001, 30000 },
- .ltc_divisor = 30,
- .height = 1080,
- .width = 1280,
- .sar = {{1, 1}, {3, 2}},
- .work_chunks = &work_chunks_dv100ntsci[0],
- .idct_factor = &dv_idct_factor_hd1080[0],
- .pix_fmt = PIX_FMT_YUV422P,
- .bpm = 8,
- .block_sizes = block_sizes_dv100,
- .audio_stride = 90,
- .audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */
- .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */
- .audio_shuffle = dv_audio_shuffle525,
- },
- { .dsf = 1,
- .video_stype = 0x14,
- .frame_size = 576000, /* SMPTE-370M - 1080i50 100 Mbps */
- .difseg_size = 12, /* also known as "DVCPRO HD" */
- .n_difchan = 4,
- .time_base = { 1, 25 },
- .ltc_divisor = 25,
- .height = 1080,
- .width = 1440,
- .sar = {{1, 1}, {4, 3}},
- .work_chunks = &work_chunks_dv100pali[0],
- .idct_factor = &dv_idct_factor_hd1080[0],
- .pix_fmt = PIX_FMT_YUV422P,
- .bpm = 8,
- .block_sizes = block_sizes_dv100,
- .audio_stride = 108,
- .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
- .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
- .audio_shuffle = dv_audio_shuffle625,
- },
- { .dsf = 0,
- .video_stype = 0x18,
- .frame_size = 240000, /* SMPTE-370M - 720p60 100 Mbps */
- .difseg_size = 10, /* also known as "DVCPRO HD" */
- .n_difchan = 2,
- .time_base = { 1001, 60000 },
- .ltc_divisor = 60,
- .height = 720,
- .width = 960,
- .sar = {{1, 1}, {4, 3}},
- .work_chunks = &work_chunks_dv100ntscp[0],
- .idct_factor = &dv_idct_factor_hd720[0],
- .pix_fmt = PIX_FMT_YUV422P,
- .bpm = 8,
- .block_sizes = block_sizes_dv100,
- .audio_stride = 90,
- .audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */
- .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */
- .audio_shuffle = dv_audio_shuffle525,
- },
- { .dsf = 1,
- .video_stype = 0x18,
- .frame_size = 288000, /* SMPTE-370M - 720p50 100 Mbps */
- .difseg_size = 12, /* also known as "DVCPRO HD" */
- .n_difchan = 2,
- .time_base = { 1, 50 },
- .ltc_divisor = 50,
- .height = 720,
- .width = 960,
- .sar = {{1, 1}, {4, 3}},
- .work_chunks = &work_chunks_dv100palp[0],
- .idct_factor = &dv_idct_factor_hd720[0],
- .pix_fmt = PIX_FMT_YUV422P,
- .bpm = 8,
- .block_sizes = block_sizes_dv100,
- .audio_stride = 90,
- .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
- .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
- .audio_shuffle = dv_audio_shuffle625,
- },
- { .dsf = 1,
- .video_stype = 0x1,
- .frame_size = 144000, /* IEC 61883-5 - 625/50 (PAL) */
- .difseg_size = 12,
- .n_difchan = 1,
- .time_base = { 1, 25 },
- .ltc_divisor = 25,
- .height = 576,
- .width = 720,
- .sar = {{16, 15}, {64, 45}},
- .work_chunks = &work_chunks_dv25pal[0],
- .idct_factor = &dv_idct_factor_sd[0],
- .pix_fmt = PIX_FMT_YUV420P,
- .bpm = 6,
- .block_sizes = block_sizes_dv2550,
- .audio_stride = 108,
- .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
- .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
- .audio_shuffle = dv_audio_shuffle625,
- }
-};
-
-const DVprofile* avpriv_dv_frame_profile(const DVprofile *sys,
- const uint8_t* frame, unsigned buf_size)
-{
- int i, dsf, stype;
-
- if (buf_size < 80 * 5 + 48 + 4)
- return NULL;
-
- dsf = (frame[3] & 0x80) >> 7;
- stype = frame[80 * 5 + 48 + 3] & 0x1f;
-
- /* 576i50 25Mbps 4:1:1 is a special case */
- if (dsf == 1 && stype == 0 && frame[4] & 0x07 /* the APT field */) {
- return &dv_profiles[2];
- }
-
- for (i = 0; i < FF_ARRAY_ELEMS(dv_profiles); i++)
- if (dsf == dv_profiles[i].dsf && stype == dv_profiles[i].video_stype)
- return &dv_profiles[i];
-
- /* check if old sys matches and assumes corrupted input */
- if (sys && buf_size == sys->frame_size)
- return sys;
-
- return NULL;
-}
-
-const DVprofile* avpriv_dv_codec_profile(AVCodecContext* codec)
-{
- int i;
-
- for (i=0; i<FF_ARRAY_ELEMS(dv_profiles); i++)
- if (codec->height == dv_profiles[i].height &&
- codec->pix_fmt == dv_profiles[i].pix_fmt &&
- codec->width == dv_profiles[i].width)
- return &dv_profiles[i];
-
- return NULL;
-}
-
-void ff_dv_print_profiles(void *logctx, int loglevel)
-{
- int i;
- for (i = 0; i < FF_ARRAY_ELEMS(dv_profiles); i++) {
- const DVprofile *p = &dv_profiles[i];
- av_log(logctx, loglevel, "Frame size: %dx%d; pixel format: %s, "
- "framerate: %d/%d\n", p->width, p->height, av_get_pix_fmt_name(p->pix_fmt),
- p->time_base.den, p->time_base.num);
- }
-}
diff --git a/libavcodec/dvdata.h b/libavcodec/dvdata.h
index 54a4bf1..c50fa5f 100644
--- a/libavcodec/dvdata.h
+++ b/libavcodec/dvdata.h
@@ -27,45 +27,10 @@
#ifndef AVCODEC_DVDATA_H
#define AVCODEC_DVDATA_H
-#include "libavutil/rational.h"
#include "avcodec.h"
#include "dsputil.h"
#include "get_bits.h"
-
-typedef struct DVwork_chunk {
- uint16_t buf_offset;
- uint16_t mb_coordinates[5];
-} DVwork_chunk;
-
-/*
- * DVprofile is used to express the differences between various
- * DV flavors. For now it's primarily used for differentiating
- * 525/60 and 625/50, but the plans are to use it for various
- * DV specs as well (e.g. SMPTE314M vs. IEC 61834).
- */
-typedef struct DVprofile {
- int dsf; /* value of the dsf in the DV header */
- int video_stype; /* stype for VAUX source pack */
- int frame_size; /* total size of one frame in bytes */
- int difseg_size; /* number of DIF segments per DIF channel */
- int n_difchan; /* number of DIF channels per frame */
- AVRational time_base; /* 1/framerate */
- int ltc_divisor; /* FPS from the LTS standpoint */
- int height; /* picture height in pixels */
- int width; /* picture width in pixels */
- AVRational sar[2]; /* sample aspect ratios for 4:3 and 16:9 */
- DVwork_chunk *work_chunks; /* each thread gets its own chunk of frame to work on */
- uint32_t *idct_factor; /* set of iDCT factor tables */
- enum PixelFormat pix_fmt; /* picture pixel format */
- int bpm; /* blocks per macroblock */
- const uint8_t *block_sizes; /* AC block sizes, in bits */
- int audio_stride; /* size of audio_shuffle table */
- int audio_min_samples[3]; /* min amount of audio samples */
- /* for 48kHz, 44.1kHz and 32kHz */
- int audio_samples_dist[5]; /* how many samples are supposed to be */
- /* in each frame in a 5 frames window */
- const uint8_t (*audio_shuffle)[9]; /* PCM shuffling table */
-} DVprofile;
+#include "dv_profile.h"
typedef struct DVVideoContext {
const DVprofile *sys;
@@ -136,10 +101,6 @@ extern const int ff_dv_iweight_720_c[64];
extern RL_VLC_ELEM ff_dv_rl_vlc[1184];
-const DVprofile* avpriv_dv_frame_profile(const DVprofile *sys,
- const uint8_t* frame, unsigned buf_size);
-const DVprofile* avpriv_dv_codec_profile(AVCodecContext* codec);
-
int ff_dv_init_dynamic_tables(const DVprofile *d);
int ff_dvvideo_init(AVCodecContext *avctx);
@@ -164,9 +125,4 @@ static inline void dv_calculate_mb_xy(DVVideoContext *s, DVwork_chunk *work_chun
}
}
-/**
- * Print all allowed DV profiles into logctx at specified logging level.
- */
-void ff_dv_print_profiles(void *logctx, int loglevel);
-
#endif /* AVCODEC_DVDATA_H */
diff --git a/libavcodec/dvdec.c b/libavcodec/dvdec.c
index ffa9c6d..8a21267 100644
--- a/libavcodec/dvdec.c
+++ b/libavcodec/dvdec.c
@@ -313,7 +313,7 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
AVPacket *avpkt)
{
- const uint8_t *buf = avpkt->data;
+ uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
DVVideoContext *s = avctx->priv_data;
const uint8_t* vsc_pack;
diff --git a/libavcodec/dwt.c b/libavcodec/dwt.c
index 2c5b56c..56e4a57 100644
--- a/libavcodec/dwt.c
+++ b/libavcodec/dwt.c
@@ -22,27 +22,43 @@
#include "dsputil.h"
#include "dwt.h"
-void ff_slice_buffer_init(slice_buffer * buf, int line_count, int max_allocated_lines, int line_width, IDWTELEM * base_buffer)
+int ff_slice_buffer_init(slice_buffer *buf, int line_count,
+ int max_allocated_lines, int line_width,
+ IDWTELEM *base_buffer)
{
int i;
buf->base_buffer = base_buffer;
- buf->line_count = line_count;
- buf->line_width = line_width;
- buf->data_count = max_allocated_lines;
- buf->line = av_mallocz (sizeof(IDWTELEM *) * line_count);
- buf->data_stack = av_malloc (sizeof(IDWTELEM *) * max_allocated_lines);
-
- for(i = 0; i < max_allocated_lines; i++){
- buf->data_stack[i] = av_malloc (sizeof(IDWTELEM) * line_width);
+ buf->line_count = line_count;
+ buf->line_width = line_width;
+ buf->data_count = max_allocated_lines;
+ buf->line = av_mallocz(sizeof(IDWTELEM *) * line_count);
+ if (!buf->line)
+ return AVERROR(ENOMEM);
+ buf->data_stack = av_malloc(sizeof(IDWTELEM *) * max_allocated_lines);
+ if (!buf->data_stack) {
+ av_free(buf->line);
+ return AVERROR(ENOMEM);
+ }
+
+ for (i = 0; i < max_allocated_lines; i++) {
+ buf->data_stack[i] = av_malloc(sizeof(IDWTELEM) * line_width);
+ if (!buf->data_stack[i]) {
+ for (i--; i >=0; i--)
+ av_free(buf->data_stack[i]);
+ av_free(buf->data_stack);
+ av_free(buf->line);
+ return AVERROR(ENOMEM);
+ }
}
buf->data_stack_top = max_allocated_lines - 1;
+ return 0;
}
-IDWTELEM * ff_slice_buffer_load_line(slice_buffer * buf, int line)
+IDWTELEM *ff_slice_buffer_load_line(slice_buffer *buf, int line)
{
- IDWTELEM * buffer;
+ IDWTELEM *buffer;
assert(buf->data_stack_top >= 0);
// assert(!buf->line[line]);
@@ -56,9 +72,9 @@ IDWTELEM * ff_slice_buffer_load_line(slice_buffer * buf, int line)
return buffer;
}
-void ff_slice_buffer_release(slice_buffer * buf, int line)
+void ff_slice_buffer_release(slice_buffer *buf, int line)
{
- IDWTELEM * buffer;
+ IDWTELEM *buffer;
assert(line >= 0 && line < buf->line_count);
assert(buf->line[line]);
@@ -66,778 +82,916 @@ void ff_slice_buffer_release(slice_buffer * buf, int line)
buffer = buf->line[line];
buf->data_stack_top++;
buf->data_stack[buf->data_stack_top] = buffer;
- buf->line[line] = NULL;
+ buf->line[line] = NULL;
}
-void ff_slice_buffer_flush(slice_buffer * buf)
+void ff_slice_buffer_flush(slice_buffer *buf)
{
int i;
- for(i = 0; i < buf->line_count; i++){
+ for (i = 0; i < buf->line_count; i++)
if (buf->line[i])
ff_slice_buffer_release(buf, i);
- }
}
-void ff_slice_buffer_destroy(slice_buffer * buf)
+void ff_slice_buffer_destroy(slice_buffer *buf)
{
int i;
ff_slice_buffer_flush(buf);
- for(i = buf->data_count - 1; i >= 0; i--){
+ for (i = buf->data_count - 1; i >= 0; i--)
av_freep(&buf->data_stack[i]);
- }
av_freep(&buf->data_stack);
av_freep(&buf->line);
}
-static inline int mirror(int v, int m){
- while((unsigned)v > (unsigned)m){
- v=-v;
- if(v<0) v+= 2*m;
+static inline int mirror(int v, int m)
+{
+ while ((unsigned)v > (unsigned)m) {
+ v = -v;
+ if (v < 0)
+ v += 2 * m;
}
return v;
}
-static av_always_inline void
-lift(DWTELEM *dst, DWTELEM *src, DWTELEM *ref,
- int dst_step, int src_step, int ref_step,
- int width, int mul, int add, int shift,
- int highpass, int inverse){
- const int mirror_left= !highpass;
- const int mirror_right= (width&1) ^ highpass;
- const int w= (width>>1) - 1 + (highpass & width);
+static av_always_inline void lift(DWTELEM *dst, DWTELEM *src, DWTELEM *ref,
+ int dst_step, int src_step, int ref_step,
+ int width, int mul, int add, int shift,
+ int highpass, int inverse)
+{
+ const int mirror_left = !highpass;
+ const int mirror_right = (width & 1) ^ highpass;
+ const int w = (width >> 1) - 1 + (highpass & width);
int i;
-#define LIFT(src, ref, inv) ((src) + ((inv) ? - (ref) : + (ref)))
- if(mirror_left){
- dst[0] = LIFT(src[0], ((mul*2*ref[0]+add)>>shift), inverse);
- dst += dst_step;
- src += src_step;
+#define LIFT(src, ref, inv) ((src) + ((inv) ? -(ref) : +(ref)))
+ if (mirror_left) {
+ dst[0] = LIFT(src[0], ((mul * 2 * ref[0] + add) >> shift), inverse);
+ dst += dst_step;
+ src += src_step;
}
- for(i=0; i<w; i++){
- dst[i*dst_step] =
- LIFT(src[i*src_step],
- ((mul*(ref[i*ref_step] + ref[(i+1)*ref_step])+add)>>shift),
- inverse);
- }
+ for (i = 0; i < w; i++)
+ dst[i * dst_step] = LIFT(src[i * src_step],
+ ((mul * (ref[i * ref_step] +
+ ref[(i + 1) * ref_step]) +
+ add) >> shift),
+ inverse);
- if(mirror_right){
- dst[w*dst_step] =
- LIFT(src[w*src_step],
- ((mul*2*ref[w*ref_step]+add)>>shift),
- inverse);
- }
+ if (mirror_right)
+ dst[w * dst_step] = LIFT(src[w * src_step],
+ ((mul * 2 * ref[w * ref_step] + add) >> shift),
+ inverse);
}
-static av_always_inline void
-inv_lift(IDWTELEM *dst, IDWTELEM *src, IDWTELEM *ref,
- int dst_step, int src_step, int ref_step,
- int width, int mul, int add, int shift,
- int highpass, int inverse){
- const int mirror_left= !highpass;
- const int mirror_right= (width&1) ^ highpass;
- const int w= (width>>1) - 1 + (highpass & width);
+static av_always_inline void inv_lift(IDWTELEM *dst, IDWTELEM *src, IDWTELEM *ref,
+ int dst_step, int src_step, int ref_step,
+ int width, int mul, int add, int shift,
+ int highpass, int inverse)
+{
+ const int mirror_left = !highpass;
+ const int mirror_right = (width & 1) ^ highpass;
+ const int w = (width >> 1) - 1 + (highpass & width);
int i;
-#define LIFT(src, ref, inv) ((src) + ((inv) ? - (ref) : + (ref)))
- if(mirror_left){
- dst[0] = LIFT(src[0], ((mul*2*ref[0]+add)>>shift), inverse);
- dst += dst_step;
- src += src_step;
+#define LIFT(src, ref, inv) ((src) + ((inv) ? -(ref) : +(ref)))
+ if (mirror_left) {
+ dst[0] = LIFT(src[0], ((mul * 2 * ref[0] + add) >> shift), inverse);
+ dst += dst_step;
+ src += src_step;
}
- for(i=0; i<w; i++){
- dst[i*dst_step] =
- LIFT(src[i*src_step],
- ((mul*(ref[i*ref_step] + ref[(i+1)*ref_step])+add)>>shift),
- inverse);
- }
+ for (i = 0; i < w; i++)
+ dst[i * dst_step] = LIFT(src[i * src_step],
+ ((mul * (ref[i * ref_step] +
+ ref[(i + 1) * ref_step]) +
+ add) >> shift),
+ inverse);
- if(mirror_right){
- dst[w*dst_step] =
- LIFT(src[w*src_step],
- ((mul*2*ref[w*ref_step]+add)>>shift),
- inverse);
+ if (mirror_right) {
+ dst[w * dst_step] = LIFT(src[w * src_step],
+ ((mul * 2 * ref[w * ref_step] + add) >> shift),
+ inverse);
}
}
#ifndef liftS
-static av_always_inline void
-liftS(DWTELEM *dst, DWTELEM *src, DWTELEM *ref,
- int dst_step, int src_step, int ref_step,
- int width, int mul, int add, int shift,
- int highpass, int inverse){
- const int mirror_left= !highpass;
- const int mirror_right= (width&1) ^ highpass;
- const int w= (width>>1) - 1 + (highpass & width);
+static av_always_inline void liftS(DWTELEM *dst, DWTELEM *src, DWTELEM *ref,
+ int dst_step, int src_step, int ref_step,
+ int width, int mul, int add, int shift,
+ int highpass, int inverse)
+{
+ const int mirror_left = !highpass;
+ const int mirror_right = (width & 1) ^ highpass;
+ const int w = (width >> 1) - 1 + (highpass & width);
int i;
assert(shift == 4);
-#define LIFTS(src, ref, inv) \
- ((inv) ? \
- (src) + (((ref) + 4*(src))>>shift): \
- -((-16*(src) + (ref) + add/4 + 1 + (5<<25))/(5*4) - (1<<23)))
- if(mirror_left){
- dst[0] = LIFTS(src[0], mul*2*ref[0]+add, inverse);
- dst += dst_step;
- src += src_step;
- }
-
- for(i=0; i<w; i++){
- dst[i*dst_step] =
- LIFTS(src[i*src_step],
- mul*(ref[i*ref_step] + ref[(i+1)*ref_step])+add,
- inverse);
- }
-
- if(mirror_right){
- dst[w*dst_step] =
- LIFTS(src[w*src_step], mul*2*ref[w*ref_step]+add, inverse);
- }
-}
-static av_always_inline void
-inv_liftS(IDWTELEM *dst, IDWTELEM *src, IDWTELEM *ref,
- int dst_step, int src_step, int ref_step,
- int width, int mul, int add, int shift,
- int highpass, int inverse){
- const int mirror_left= !highpass;
- const int mirror_right= (width&1) ^ highpass;
- const int w= (width>>1) - 1 + (highpass & width);
+#define LIFTS(src, ref, inv) \
+ ((inv) ? (src) + (((ref) + 4 * (src)) >> shift) \
+ : -((-16 * (src) + (ref) + add / \
+ 4 + 1 + (5 << 25)) / (5 * 4) - (1 << 23)))
+ if (mirror_left) {
+ dst[0] = LIFTS(src[0], mul * 2 * ref[0] + add, inverse);
+ dst += dst_step;
+ src += src_step;
+ }
+
+ for (i = 0; i < w; i++)
+ dst[i * dst_step] = LIFTS(src[i * src_step],
+ mul * (ref[i * ref_step] +
+ ref[(i + 1) * ref_step]) + add,
+ inverse);
+
+ if (mirror_right)
+ dst[w * dst_step] = LIFTS(src[w * src_step],
+ mul * 2 * ref[w * ref_step] + add,
+ inverse);
+}
+
+static av_always_inline void inv_liftS(IDWTELEM *dst, IDWTELEM *src,
+ IDWTELEM *ref, int dst_step,
+ int src_step, int ref_step,
+ int width, int mul, int add, int shift,
+ int highpass, int inverse)
+{
+ const int mirror_left = !highpass;
+ const int mirror_right = (width & 1) ^ highpass;
+ const int w = (width >> 1) - 1 + (highpass & width);
int i;
assert(shift == 4);
-#define LIFTS(src, ref, inv) \
- ((inv) ? \
- (src) + (((ref) + 4*(src))>>shift): \
- -((-16*(src) + (ref) + add/4 + 1 + (5<<25))/(5*4) - (1<<23)))
- if(mirror_left){
- dst[0] = LIFTS(src[0], mul*2*ref[0]+add, inverse);
- dst += dst_step;
- src += src_step;
- }
-
- for(i=0; i<w; i++){
- dst[i*dst_step] =
- LIFTS(src[i*src_step],
- mul*(ref[i*ref_step] + ref[(i+1)*ref_step])+add,
- inverse);
- }
-
- if(mirror_right){
- dst[w*dst_step] =
- LIFTS(src[w*src_step], mul*2*ref[w*ref_step]+add, inverse);
- }
+#define LIFTS(src, ref, inv) \
+ ((inv) ? (src) + (((ref) + 4 * (src)) >> shift) \
+ : -((-16 * (src) + (ref) + add / \
+ 4 + 1 + (5 << 25)) / (5 * 4) - (1 << 23)))
+ if (mirror_left) {
+ dst[0] = LIFTS(src[0], mul * 2 * ref[0] + add, inverse);
+ dst += dst_step;
+ src += src_step;
+ }
+
+ for (i = 0; i < w; i++)
+ dst[i * dst_step] = LIFTS(src[i * src_step],
+ mul * (ref[i * ref_step] +
+ ref[(i + 1) * ref_step]) + add,
+ inverse);
+
+ if (mirror_right)
+ dst[w * dst_step] = LIFTS(src[w * src_step],
+ mul * 2 * ref[w * ref_step] + add, inverse);
}
#endif /* ! liftS */
-static void horizontal_decompose53i(DWTELEM *b, int width){
- DWTELEM temp[width];
- const int width2= width>>1;
+static void horizontal_decompose53i(DWTELEM *b, DWTELEM *temp, int width)
+{
+ const int width2 = width >> 1;
int x;
- const int w2= (width+1)>>1;
+ const int w2 = (width + 1) >> 1;
- for(x=0; x<width2; x++){
- temp[x ]= b[2*x ];
- temp[x+w2]= b[2*x + 1];
+ for (x = 0; x < width2; x++) {
+ temp[x] = b[2 * x];
+ temp[x + w2] = b[2 * x + 1];
}
- if(width&1)
- temp[x ]= b[2*x ];
+ if (width & 1)
+ temp[x] = b[2 * x];
#if 0
{
- int A1,A2,A3,A4;
- A2= temp[1 ];
- A4= temp[0 ];
- A1= temp[0+width2];
- A1 -= (A2 + A4)>>1;
- A4 += (A1 + 1)>>1;
- b[0+width2] = A1;
- b[0 ] = A4;
- for(x=1; x+1<width2; x+=2){
- A3= temp[x+width2];
- A4= temp[x+1 ];
- A3 -= (A2 + A4)>>1;
- A2 += (A1 + A3 + 2)>>2;
- b[x+width2] = A3;
- b[x ] = A2;
-
- A1= temp[x+1+width2];
- A2= temp[x+2 ];
- A1 -= (A2 + A4)>>1;
- A4 += (A1 + A3 + 2)>>2;
- b[x+1+width2] = A1;
- b[x+1 ] = A4;
- }
- A3= temp[width-1];
- A3 -= A2;
- A2 += (A1 + A3 + 2)>>2;
- b[width -1] = A3;
- b[width2-1] = A2;
+ int A1, A2, A3, A4;
+ A2 = temp[1];
+ A4 = temp[0];
+ A1 = temp[0 + width2];
+ A1 -= (A2 + A4) >> 1;
+ A4 += (A1 + 1) >> 1;
+ b[0 + width2] = A1;
+ b[0] = A4;
+ for (x = 1; x + 1 < width2; x += 2) {
+ A3 = temp[x + width2];
+ A4 = temp[x + 1];
+ A3 -= (A2 + A4) >> 1;
+ A2 += (A1 + A3 + 2) >> 2;
+ b[x + width2] = A3;
+ b[x] = A2;
+
+ A1 = temp[x + 1 + width2];
+ A2 = temp[x + 2];
+ A1 -= (A2 + A4) >> 1;
+ A4 += (A1 + A3 + 2) >> 2;
+ b[x + 1 + width2] = A1;
+ b[x + 1] = A4;
+ }
+ A3 = temp[width - 1];
+ A3 -= A2;
+ A2 += (A1 + A3 + 2) >> 2;
+ b[width - 1] = A3;
+ b[width2 - 1] = A2;
}
#else
- lift(b+w2, temp+w2, temp, 1, 1, 1, width, -1, 0, 1, 1, 0);
- lift(b , temp , b+w2, 1, 1, 1, width, 1, 2, 2, 0, 0);
+ lift(b + w2, temp + w2, temp, 1, 1, 1, width, -1, 0, 1, 1, 0);
+ lift(b, temp, b + w2, 1, 1, 1, width, 1, 2, 2, 0, 0);
#endif /* 0 */
}
-static void vertical_decompose53iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){
+static void vertical_decompose53iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
+ int width)
+{
int i;
- for(i=0; i<width; i++){
- b1[i] -= (b0[i] + b2[i])>>1;
- }
+ for (i = 0; i < width; i++)
+ b1[i] -= (b0[i] + b2[i]) >> 1;
}
-static void vertical_decompose53iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){
+static void vertical_decompose53iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
+ int width)
+{
int i;
- for(i=0; i<width; i++){
- b1[i] += (b0[i] + b2[i] + 2)>>2;
- }
+ for (i = 0; i < width; i++)
+ b1[i] += (b0[i] + b2[i] + 2) >> 2;
}
-static void spatial_decompose53i(DWTELEM *buffer, int width, int height, int stride){
+static void spatial_decompose53i(DWTELEM *buffer, DWTELEM *temp,
+ int width, int height, int stride)
+{
int y;
- DWTELEM *b0= buffer + mirror(-2-1, height-1)*stride;
- DWTELEM *b1= buffer + mirror(-2 , height-1)*stride;
+ DWTELEM *b0 = buffer + mirror(-2 - 1, height - 1) * stride;
+ DWTELEM *b1 = buffer + mirror(-2, height - 1) * stride;
- for(y=-2; y<height; y+=2){
- DWTELEM *b2= buffer + mirror(y+1, height-1)*stride;
- DWTELEM *b3= buffer + mirror(y+2, height-1)*stride;
+ for (y = -2; y < height; y += 2) {
+ DWTELEM *b2 = buffer + mirror(y + 1, height - 1) * stride;
+ DWTELEM *b3 = buffer + mirror(y + 2, height - 1) * stride;
- if(y+1<(unsigned)height) horizontal_decompose53i(b2, width);
- if(y+2<(unsigned)height) horizontal_decompose53i(b3, width);
+ if (y + 1 < (unsigned)height)
+ horizontal_decompose53i(b2, temp, width);
+ if (y + 2 < (unsigned)height)
+ horizontal_decompose53i(b3, temp, width);
- if(y+1<(unsigned)height) vertical_decompose53iH0(b1, b2, b3, width);
- if(y+0<(unsigned)height) vertical_decompose53iL0(b0, b1, b2, width);
+ if (y + 1 < (unsigned)height)
+ vertical_decompose53iH0(b1, b2, b3, width);
+ if (y + 0 < (unsigned)height)
+ vertical_decompose53iL0(b0, b1, b2, width);
- b0=b2;
- b1=b3;
+ b0 = b2;
+ b1 = b3;
}
}
-static void horizontal_decompose97i(DWTELEM *b, int width){
- DWTELEM temp[width];
- const int w2= (width+1)>>1;
+static void horizontal_decompose97i(DWTELEM *b, DWTELEM *temp, int width)
+{
+ const int w2 = (width + 1) >> 1;
- lift (temp+w2, b +1, b , 1, 2, 2, width, W_AM, W_AO, W_AS, 1, 1);
- liftS(temp , b , temp+w2, 1, 2, 1, width, W_BM, W_BO, W_BS, 0, 0);
- lift (b +w2, temp+w2, temp , 1, 1, 1, width, W_CM, W_CO, W_CS, 1, 0);
- lift (b , temp , b +w2, 1, 1, 1, width, W_DM, W_DO, W_DS, 0, 0);
+ lift(temp + w2, b + 1, b, 1, 2, 2, width, W_AM, W_AO, W_AS, 1, 1);
+ liftS(temp, b, temp + w2, 1, 2, 1, width, W_BM, W_BO, W_BS, 0, 0);
+ lift(b + w2, temp + w2, temp, 1, 1, 1, width, W_CM, W_CO, W_CS, 1, 0);
+ lift(b, temp, b + w2, 1, 1, 1, width, W_DM, W_DO, W_DS, 0, 0);
}
-
-static void vertical_decompose97iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){
+static void vertical_decompose97iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
+ int width)
+{
int i;
- for(i=0; i<width; i++){
- b1[i] -= (W_AM*(b0[i] + b2[i])+W_AO)>>W_AS;
- }
+ for (i = 0; i < width; i++)
+ b1[i] -= (W_AM * (b0[i] + b2[i]) + W_AO) >> W_AS;
}
-static void vertical_decompose97iH1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){
+static void vertical_decompose97iH1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
+ int width)
+{
int i;
- for(i=0; i<width; i++){
- b1[i] += (W_CM*(b0[i] + b2[i])+W_CO)>>W_CS;
- }
+ for (i = 0; i < width; i++)
+ b1[i] += (W_CM * (b0[i] + b2[i]) + W_CO) >> W_CS;
}
-static void vertical_decompose97iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){
+static void vertical_decompose97iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
+ int width)
+{
int i;
- for(i=0; i<width; i++){
+ for (i = 0; i < width; i++)
#ifdef liftS
- b1[i] -= (W_BM*(b0[i] + b2[i])+W_BO)>>W_BS;
+ b1[i] -= (W_BM * (b0[i] + b2[i]) + W_BO) >> W_BS;
#else
- b1[i] = (16*4*b1[i] - 4*(b0[i] + b2[i]) + W_BO*5 + (5<<27)) / (5*16) - (1<<23);
+ b1[i] = (16 * 4 * b1[i] - 4 * (b0[i] + b2[i]) + W_BO * 5 + (5 << 27)) /
+ (5 * 16) - (1 << 23);
#endif
- }
}
-static void vertical_decompose97iL1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){
+static void vertical_decompose97iL1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
+ int width)
+{
int i;
- for(i=0; i<width; i++){
- b1[i] += (W_DM*(b0[i] + b2[i])+W_DO)>>W_DS;
- }
+ for (i = 0; i < width; i++)
+ b1[i] += (W_DM * (b0[i] + b2[i]) + W_DO) >> W_DS;
}
-static void spatial_decompose97i(DWTELEM *buffer, int width, int height, int stride){
+static void spatial_decompose97i(DWTELEM *buffer, DWTELEM *temp,
+ int width, int height, int stride)
+{
int y;
- DWTELEM *b0= buffer + mirror(-4-1, height-1)*stride;
- DWTELEM *b1= buffer + mirror(-4 , height-1)*stride;
- DWTELEM *b2= buffer + mirror(-4+1, height-1)*stride;
- DWTELEM *b3= buffer + mirror(-4+2, height-1)*stride;
-
- for(y=-4; y<height; y+=2){
- DWTELEM *b4= buffer + mirror(y+3, height-1)*stride;
- DWTELEM *b5= buffer + mirror(y+4, height-1)*stride;
-
- if(y+3<(unsigned)height) horizontal_decompose97i(b4, width);
- if(y+4<(unsigned)height) horizontal_decompose97i(b5, width);
-
- if(y+3<(unsigned)height) vertical_decompose97iH0(b3, b4, b5, width);
- if(y+2<(unsigned)height) vertical_decompose97iL0(b2, b3, b4, width);
- if(y+1<(unsigned)height) vertical_decompose97iH1(b1, b2, b3, width);
- if(y+0<(unsigned)height) vertical_decompose97iL1(b0, b1, b2, width);
-
- b0=b2;
- b1=b3;
- b2=b4;
- b3=b5;
- }
-}
-
-void ff_spatial_dwt(DWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count){
+ DWTELEM *b0 = buffer + mirror(-4 - 1, height - 1) * stride;
+ DWTELEM *b1 = buffer + mirror(-4, height - 1) * stride;
+ DWTELEM *b2 = buffer + mirror(-4 + 1, height - 1) * stride;
+ DWTELEM *b3 = buffer + mirror(-4 + 2, height - 1) * stride;
+
+ for (y = -4; y < height; y += 2) {
+ DWTELEM *b4 = buffer + mirror(y + 3, height - 1) * stride;
+ DWTELEM *b5 = buffer + mirror(y + 4, height - 1) * stride;
+
+ if (y + 3 < (unsigned)height)
+ horizontal_decompose97i(b4, temp, width);
+ if (y + 4 < (unsigned)height)
+ horizontal_decompose97i(b5, temp, width);
+
+ if (y + 3 < (unsigned)height)
+ vertical_decompose97iH0(b3, b4, b5, width);
+ if (y + 2 < (unsigned)height)
+ vertical_decompose97iL0(b2, b3, b4, width);
+ if (y + 1 < (unsigned)height)
+ vertical_decompose97iH1(b1, b2, b3, width);
+ if (y + 0 < (unsigned)height)
+ vertical_decompose97iL1(b0, b1, b2, width);
+
+ b0 = b2;
+ b1 = b3;
+ b2 = b4;
+ b3 = b5;
+ }
+}
+
+void ff_spatial_dwt(DWTELEM *buffer, DWTELEM *temp, int width, int height,
+ int stride, int type, int decomposition_count)
+{
int level;
- for(level=0; level<decomposition_count; level++){
- switch(type){
- case DWT_97: spatial_decompose97i(buffer, width>>level, height>>level, stride<<level); break;
- case DWT_53: spatial_decompose53i(buffer, width>>level, height>>level, stride<<level); break;
+ for (level = 0; level < decomposition_count; level++) {
+ switch (type) {
+ case DWT_97:
+ spatial_decompose97i(buffer, temp,
+ width >> level, height >> level,
+ stride << level);
+ break;
+ case DWT_53:
+ spatial_decompose53i(buffer, temp,
+ width >> level, height >> level,
+ stride << level);
+ break;
}
}
}
-static void horizontal_compose53i(IDWTELEM *b, int width){
- IDWTELEM temp[width];
- const int width2= width>>1;
- const int w2= (width+1)>>1;
+static void horizontal_compose53i(IDWTELEM *b, IDWTELEM *temp, int width)
+{
+ const int width2 = width >> 1;
+ const int w2 = (width + 1) >> 1;
int x;
- for(x=0; x<width2; x++){
- temp[2*x ]= b[x ];
- temp[2*x + 1]= b[x+w2];
+ for (x = 0; x < width2; x++) {
+ temp[2 * x] = b[x];
+ temp[2 * x + 1] = b[x + w2];
}
- if(width&1)
- temp[2*x ]= b[x ];
+ if (width & 1)
+ temp[2 * x] = b[x];
- b[0] = temp[0] - ((temp[1]+1)>>1);
- for(x=2; x<width-1; x+=2){
- b[x ] = temp[x ] - ((temp[x-1] + temp[x+1]+2)>>2);
- b[x-1] = temp[x-1] + ((b [x-2] + b [x ]+1)>>1);
+ b[0] = temp[0] - ((temp[1] + 1) >> 1);
+ for (x = 2; x < width - 1; x += 2) {
+ b[x] = temp[x] - ((temp[x - 1] + temp[x + 1] + 2) >> 2);
+ b[x - 1] = temp[x - 1] + ((b[x - 2] + b[x] + 1) >> 1);
}
- if(width&1){
- b[x ] = temp[x ] - ((temp[x-1]+1)>>1);
- b[x-1] = temp[x-1] + ((b [x-2] + b [x ]+1)>>1);
- }else
- b[x-1] = temp[x-1] + b[x-2];
+ if (width & 1) {
+ b[x] = temp[x] - ((temp[x - 1] + 1) >> 1);
+ b[x - 1] = temp[x - 1] + ((b[x - 2] + b[x] + 1) >> 1);
+ } else
+ b[x - 1] = temp[x - 1] + b[x - 2];
}
-static void vertical_compose53iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width){
+static void vertical_compose53iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
+ int width)
+{
int i;
- for(i=0; i<width; i++){
- b1[i] += (b0[i] + b2[i])>>1;
- }
+ for (i = 0; i < width; i++)
+ b1[i] += (b0[i] + b2[i]) >> 1;
}
-static void vertical_compose53iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width){
+static void vertical_compose53iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
+ int width)
+{
int i;
- for(i=0; i<width; i++){
- b1[i] -= (b0[i] + b2[i] + 2)>>2;
- }
+ for (i = 0; i < width; i++)
+ b1[i] -= (b0[i] + b2[i] + 2) >> 2;
}
-static void spatial_compose53i_buffered_init(DWTCompose *cs, slice_buffer * sb, int height, int stride_line){
- cs->b0 = slice_buffer_get_line(sb, mirror(-1-1, height-1) * stride_line);
- cs->b1 = slice_buffer_get_line(sb, mirror(-1 , height-1) * stride_line);
- cs->y = -1;
+static void spatial_compose53i_buffered_init(DWTCompose *cs, slice_buffer *sb,
+ int height, int stride_line)
+{
+ cs->b0 = slice_buffer_get_line(sb,
+ mirror(-1 - 1, height - 1) * stride_line);
+ cs->b1 = slice_buffer_get_line(sb, mirror(-1, height - 1) * stride_line);
+ cs->y = -1;
}
-static void spatial_compose53i_init(DWTCompose *cs, IDWTELEM *buffer, int height, int stride){
- cs->b0 = buffer + mirror(-1-1, height-1)*stride;
- cs->b1 = buffer + mirror(-1 , height-1)*stride;
- cs->y = -1;
+static void spatial_compose53i_init(DWTCompose *cs, IDWTELEM *buffer,
+ int height, int stride)
+{
+ cs->b0 = buffer + mirror(-1 - 1, height - 1) * stride;
+ cs->b1 = buffer + mirror(-1, height - 1) * stride;
+ cs->y = -1;
}
-static void spatial_compose53i_dy_buffered(DWTCompose *cs, slice_buffer * sb, int width, int height, int stride_line){
- int y= cs->y;
+static void spatial_compose53i_dy_buffered(DWTCompose *cs, slice_buffer *sb,
+ IDWTELEM *temp,
+ int width, int height,
+ int stride_line)
+{
+ int y = cs->y;
- IDWTELEM *b0= cs->b0;
- IDWTELEM *b1= cs->b1;
- IDWTELEM *b2= slice_buffer_get_line(sb, mirror(y+1, height-1) * stride_line);
- IDWTELEM *b3= slice_buffer_get_line(sb, mirror(y+2, height-1) * stride_line);
+ IDWTELEM *b0 = cs->b0;
+ IDWTELEM *b1 = cs->b1;
+ IDWTELEM *b2 = slice_buffer_get_line(sb,
+ mirror(y + 1, height - 1) *
+ stride_line);
+ IDWTELEM *b3 = slice_buffer_get_line(sb,
+ mirror(y + 2, height - 1) *
+ stride_line);
- if(y+1<(unsigned)height && y<(unsigned)height){
+ if (y + 1 < (unsigned)height && y < (unsigned)height) {
int x;
- for(x=0; x<width; x++){
- b2[x] -= (b1[x] + b3[x] + 2)>>2;
- b1[x] += (b0[x] + b2[x])>>1;
+ for (x = 0; x < width; x++) {
+ b2[x] -= (b1[x] + b3[x] + 2) >> 2;
+ b1[x] += (b0[x] + b2[x]) >> 1;
}
- }else{
- if(y+1<(unsigned)height) vertical_compose53iL0(b1, b2, b3, width);
- if(y+0<(unsigned)height) vertical_compose53iH0(b0, b1, b2, width);
+ } else {
+ if (y + 1 < (unsigned)height)
+ vertical_compose53iL0(b1, b2, b3, width);
+ if (y + 0 < (unsigned)height)
+ vertical_compose53iH0(b0, b1, b2, width);
}
- if(y-1<(unsigned)height) horizontal_compose53i(b0, width);
- if(y+0<(unsigned)height) horizontal_compose53i(b1, width);
+ if (y - 1 < (unsigned)height)
+ horizontal_compose53i(b0, temp, width);
+ if (y + 0 < (unsigned)height)
+ horizontal_compose53i(b1, temp, width);
- cs->b0 = b2;
- cs->b1 = b3;
- cs->y += 2;
+ cs->b0 = b2;
+ cs->b1 = b3;
+ cs->y += 2;
}
-static void spatial_compose53i_dy(DWTCompose *cs, IDWTELEM *buffer, int width, int height, int stride){
- int y= cs->y;
- IDWTELEM *b0= cs->b0;
- IDWTELEM *b1= cs->b1;
- IDWTELEM *b2= buffer + mirror(y+1, height-1)*stride;
- IDWTELEM *b3= buffer + mirror(y+2, height-1)*stride;
+static void spatial_compose53i_dy(DWTCompose *cs, IDWTELEM *buffer,
+ IDWTELEM *temp, int width, int height,
+ int stride)
+{
+ int y = cs->y;
+ IDWTELEM *b0 = cs->b0;
+ IDWTELEM *b1 = cs->b1;
+ IDWTELEM *b2 = buffer + mirror(y + 1, height - 1) * stride;
+ IDWTELEM *b3 = buffer + mirror(y + 2, height - 1) * stride;
- if(y+1<(unsigned)height) vertical_compose53iL0(b1, b2, b3, width);
- if(y+0<(unsigned)height) vertical_compose53iH0(b0, b1, b2, width);
+ if (y + 1 < (unsigned)height)
+ vertical_compose53iL0(b1, b2, b3, width);
+ if (y + 0 < (unsigned)height)
+ vertical_compose53iH0(b0, b1, b2, width);
- if(y-1<(unsigned)height) horizontal_compose53i(b0, width);
- if(y+0<(unsigned)height) horizontal_compose53i(b1, width);
+ if (y - 1 < (unsigned)height)
+ horizontal_compose53i(b0, temp, width);
+ if (y + 0 < (unsigned)height)
+ horizontal_compose53i(b1, temp, width);
- cs->b0 = b2;
- cs->b1 = b3;
- cs->y += 2;
+ cs->b0 = b2;
+ cs->b1 = b3;
+ cs->y += 2;
}
-static void av_unused spatial_compose53i(IDWTELEM *buffer, int width, int height, int stride){
+static void av_unused spatial_compose53i(IDWTELEM *buffer, IDWTELEM *temp,
+ int width, int height, int stride)
+{
DWTCompose cs;
spatial_compose53i_init(&cs, buffer, height, stride);
- while(cs.y <= height)
- spatial_compose53i_dy(&cs, buffer, width, height, stride);
+ while (cs.y <= height)
+ spatial_compose53i_dy(&cs, buffer, temp, width, height, stride);
}
-
-void ff_snow_horizontal_compose97i(IDWTELEM *b, int width){
- IDWTELEM temp[width];
- const int w2= (width+1)>>1;
+void ff_snow_horizontal_compose97i(IDWTELEM *b, IDWTELEM *temp, int width)
+{
+ const int w2 = (width + 1) >> 1;
#if 0 //maybe more understadable but slower
- inv_lift (temp , b , b +w2, 2, 1, 1, width, W_DM, W_DO, W_DS, 0, 1);
- inv_lift (temp+1 , b +w2, temp , 2, 1, 2, width, W_CM, W_CO, W_CS, 1, 1);
+ inv_lift(temp, b, b + w2, 2, 1, 1, width, W_DM, W_DO, W_DS, 0, 1);
+ inv_lift(temp + 1, b + w2, temp, 2, 1, 2, width, W_CM, W_CO, W_CS, 1, 1);
- inv_liftS(b , temp , temp+1 , 2, 2, 2, width, W_BM, W_BO, W_BS, 0, 1);
- inv_lift (b+1 , temp+1 , b , 2, 2, 2, width, W_AM, W_AO, W_AS, 1, 0);
+ inv_liftS(b, temp, temp + 1, 2, 2, 2, width, W_BM, W_BO, W_BS, 0, 1);
+ inv_lift(b + 1, temp + 1, b, 2, 2, 2, width, W_AM, W_AO, W_AS, 1, 0);
#else
int x;
- temp[0] = b[0] - ((3*b[w2]+2)>>2);
- for(x=1; x<(width>>1); x++){
- temp[2*x ] = b[x ] - ((3*(b [x+w2-1] + b[x+w2])+4)>>3);
- temp[2*x-1] = b[x+w2-1] - temp[2*x-2] - temp[2*x];
- }
- if(width&1){
- temp[2*x ] = b[x ] - ((3*b [x+w2-1]+2)>>2);
- temp[2*x-1] = b[x+w2-1] - temp[2*x-2] - temp[2*x];
- }else
- temp[2*x-1] = b[x+w2-1] - 2*temp[2*x-2];
-
- b[0] = temp[0] + ((2*temp[0] + temp[1]+4)>>3);
- for(x=2; x<width-1; x+=2){
- b[x ] = temp[x ] + ((4*temp[x ] + temp[x-1] + temp[x+1]+8)>>4);
- b[x-1] = temp[x-1] + ((3*(b [x-2] + b [x ] ))>>1);
- }
- if(width&1){
- b[x ] = temp[x ] + ((2*temp[x ] + temp[x-1]+4)>>3);
- b[x-1] = temp[x-1] + ((3*(b [x-2] + b [x ] ))>>1);
- }else
- b[x-1] = temp[x-1] + 3*b [x-2];
+ temp[0] = b[0] - ((3 * b[w2] + 2) >> 2);
+ for (x = 1; x < (width >> 1); x++) {
+ temp[2 * x] = b[x] - ((3 * (b[x + w2 - 1] + b[x + w2]) + 4) >> 3);
+ temp[2 * x - 1] = b[x + w2 - 1] - temp[2 * x - 2] - temp[2 * x];
+ }
+ if (width & 1) {
+ temp[2 * x] = b[x] - ((3 * b[x + w2 - 1] + 2) >> 2);
+ temp[2 * x - 1] = b[x + w2 - 1] - temp[2 * x - 2] - temp[2 * x];
+ } else
+ temp[2 * x - 1] = b[x + w2 - 1] - 2 * temp[2 * x - 2];
+
+ b[0] = temp[0] + ((2 * temp[0] + temp[1] + 4) >> 3);
+ for (x = 2; x < width - 1; x += 2) {
+ b[x] = temp[x] + ((4 * temp[x] + temp[x - 1] + temp[x + 1] + 8) >> 4);
+ b[x - 1] = temp[x - 1] + ((3 * (b[x - 2] + b[x])) >> 1);
+ }
+ if (width & 1) {
+ b[x] = temp[x] + ((2 * temp[x] + temp[x - 1] + 4) >> 3);
+ b[x - 1] = temp[x - 1] + ((3 * (b[x - 2] + b[x])) >> 1);
+ } else
+ b[x - 1] = temp[x - 1] + 3 * b[x - 2];
#endif
}
-static void vertical_compose97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width){
+static void vertical_compose97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
+ int width)
+{
int i;
- for(i=0; i<width; i++){
- b1[i] += (W_AM*(b0[i] + b2[i])+W_AO)>>W_AS;
- }
+ for (i = 0; i < width; i++)
+ b1[i] += (W_AM * (b0[i] + b2[i]) + W_AO) >> W_AS;
}
-static void vertical_compose97iH1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width){
+static void vertical_compose97iH1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
+ int width)
+{
int i;
- for(i=0; i<width; i++){
- b1[i] -= (W_CM*(b0[i] + b2[i])+W_CO)>>W_CS;
- }
+ for (i = 0; i < width; i++)
+ b1[i] -= (W_CM * (b0[i] + b2[i]) + W_CO) >> W_CS;
}
-static void vertical_compose97iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width){
+static void vertical_compose97iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
+ int width)
+{
int i;
- for(i=0; i<width; i++){
+ for (i = 0; i < width; i++)
#ifdef liftS
- b1[i] += (W_BM*(b0[i] + b2[i])+W_BO)>>W_BS;
+ b1[i] += (W_BM * (b0[i] + b2[i]) + W_BO) >> W_BS;
#else
- b1[i] += (W_BM*(b0[i] + b2[i])+4*b1[i]+W_BO)>>W_BS;
+ b1[i] += (W_BM * (b0[i] + b2[i]) + 4 * b1[i] + W_BO) >> W_BS;
#endif
- }
}
-static void vertical_compose97iL1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width){
+static void vertical_compose97iL1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
+ int width)
+{
int i;
- for(i=0; i<width; i++){
- b1[i] -= (W_DM*(b0[i] + b2[i])+W_DO)>>W_DS;
- }
+ for (i = 0; i < width; i++)
+ b1[i] -= (W_DM * (b0[i] + b2[i]) + W_DO) >> W_DS;
}
-void ff_snow_vertical_compose97i(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width){
+void ff_snow_vertical_compose97i(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
+ IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5,
+ int width)
+{
int i;
- for(i=0; i<width; i++){
- b4[i] -= (W_DM*(b3[i] + b5[i])+W_DO)>>W_DS;
- b3[i] -= (W_CM*(b2[i] + b4[i])+W_CO)>>W_CS;
+ for (i = 0; i < width; i++) {
+ b4[i] -= (W_DM * (b3[i] + b5[i]) + W_DO) >> W_DS;
+ b3[i] -= (W_CM * (b2[i] + b4[i]) + W_CO) >> W_CS;
#ifdef liftS
- b2[i] += (W_BM*(b1[i] + b3[i])+W_BO)>>W_BS;
+ b2[i] += (W_BM * (b1[i] + b3[i]) + W_BO) >> W_BS;
#else
- b2[i] += (W_BM*(b1[i] + b3[i])+4*b2[i]+W_BO)>>W_BS;
+ b2[i] += (W_BM * (b1[i] + b3[i]) + 4 * b2[i] + W_BO) >> W_BS;
#endif
- b1[i] += (W_AM*(b0[i] + b2[i])+W_AO)>>W_AS;
+ b1[i] += (W_AM * (b0[i] + b2[i]) + W_AO) >> W_AS;
}
}
-static void spatial_compose97i_buffered_init(DWTCompose *cs, slice_buffer * sb, int height, int stride_line){
- cs->b0 = slice_buffer_get_line(sb, mirror(-3-1, height-1) * stride_line);
- cs->b1 = slice_buffer_get_line(sb, mirror(-3 , height-1) * stride_line);
- cs->b2 = slice_buffer_get_line(sb, mirror(-3+1, height-1) * stride_line);
- cs->b3 = slice_buffer_get_line(sb, mirror(-3+2, height-1) * stride_line);
- cs->y = -3;
+static void spatial_compose97i_buffered_init(DWTCompose *cs, slice_buffer *sb,
+ int height, int stride_line)
+{
+ cs->b0 = slice_buffer_get_line(sb, mirror(-3 - 1, height - 1) * stride_line);
+ cs->b1 = slice_buffer_get_line(sb, mirror(-3, height - 1) * stride_line);
+ cs->b2 = slice_buffer_get_line(sb, mirror(-3 + 1, height - 1) * stride_line);
+ cs->b3 = slice_buffer_get_line(sb, mirror(-3 + 2, height - 1) * stride_line);
+ cs->y = -3;
}
-static void spatial_compose97i_init(DWTCompose *cs, IDWTELEM *buffer, int height, int stride){
- cs->b0 = buffer + mirror(-3-1, height-1)*stride;
- cs->b1 = buffer + mirror(-3 , height-1)*stride;
- cs->b2 = buffer + mirror(-3+1, height-1)*stride;
- cs->b3 = buffer + mirror(-3+2, height-1)*stride;
- cs->y = -3;
+static void spatial_compose97i_init(DWTCompose *cs, IDWTELEM *buffer, int height,
+ int stride)
+{
+ cs->b0 = buffer + mirror(-3 - 1, height - 1) * stride;
+ cs->b1 = buffer + mirror(-3, height - 1) * stride;
+ cs->b2 = buffer + mirror(-3 + 1, height - 1) * stride;
+ cs->b3 = buffer + mirror(-3 + 2, height - 1) * stride;
+ cs->y = -3;
}
-static void spatial_compose97i_dy_buffered(DWTContext *dsp, DWTCompose *cs, slice_buffer * sb, int width, int height, int stride_line){
+static void spatial_compose97i_dy_buffered(DWTContext *dsp, DWTCompose *cs,
+ slice_buffer * sb, IDWTELEM *temp,
+ int width, int height,
+ int stride_line)
+{
int y = cs->y;
- IDWTELEM *b0= cs->b0;
- IDWTELEM *b1= cs->b1;
- IDWTELEM *b2= cs->b2;
- IDWTELEM *b3= cs->b3;
- IDWTELEM *b4= slice_buffer_get_line(sb, mirror(y + 3, height - 1) * stride_line);
- IDWTELEM *b5= slice_buffer_get_line(sb, mirror(y + 4, height - 1) * stride_line);
-
- if(y>0 && y+4<height){
+ IDWTELEM *b0 = cs->b0;
+ IDWTELEM *b1 = cs->b1;
+ IDWTELEM *b2 = cs->b2;
+ IDWTELEM *b3 = cs->b3;
+ IDWTELEM *b4 = slice_buffer_get_line(sb,
+ mirror(y + 3, height - 1) *
+ stride_line);
+ IDWTELEM *b5 = slice_buffer_get_line(sb,
+ mirror(y + 4, height - 1) *
+ stride_line);
+
+ if (y > 0 && y + 4 < height) {
dsp->vertical_compose97i(b0, b1, b2, b3, b4, b5, width);
- }else{
- if(y+3<(unsigned)height) vertical_compose97iL1(b3, b4, b5, width);
- if(y+2<(unsigned)height) vertical_compose97iH1(b2, b3, b4, width);
- if(y+1<(unsigned)height) vertical_compose97iL0(b1, b2, b3, width);
- if(y+0<(unsigned)height) vertical_compose97iH0(b0, b1, b2, width);
- }
-
- if(y-1<(unsigned)height) dsp->horizontal_compose97i(b0, width);
- if(y+0<(unsigned)height) dsp->horizontal_compose97i(b1, width);
-
- cs->b0=b2;
- cs->b1=b3;
- cs->b2=b4;
- cs->b3=b5;
- cs->y += 2;
-}
-
-static void spatial_compose97i_dy(DWTCompose *cs, IDWTELEM *buffer, int width, int height, int stride){
- int y = cs->y;
- IDWTELEM *b0= cs->b0;
- IDWTELEM *b1= cs->b1;
- IDWTELEM *b2= cs->b2;
- IDWTELEM *b3= cs->b3;
- IDWTELEM *b4= buffer + mirror(y+3, height-1)*stride;
- IDWTELEM *b5= buffer + mirror(y+4, height-1)*stride;
-
- if(y+3<(unsigned)height) vertical_compose97iL1(b3, b4, b5, width);
- if(y+2<(unsigned)height) vertical_compose97iH1(b2, b3, b4, width);
- if(y+1<(unsigned)height) vertical_compose97iL0(b1, b2, b3, width);
- if(y+0<(unsigned)height) vertical_compose97iH0(b0, b1, b2, width);
-
- if(y-1<(unsigned)height) ff_snow_horizontal_compose97i(b0, width);
- if(y+0<(unsigned)height) ff_snow_horizontal_compose97i(b1, width);
-
- cs->b0=b2;
- cs->b1=b3;
- cs->b2=b4;
- cs->b3=b5;
- cs->y += 2;
-}
-
-static void av_unused spatial_compose97i(IDWTELEM *buffer, int width, int height, int stride){
+ } else {
+ if (y + 3 < (unsigned)height)
+ vertical_compose97iL1(b3, b4, b5, width);
+ if (y + 2 < (unsigned)height)
+ vertical_compose97iH1(b2, b3, b4, width);
+ if (y + 1 < (unsigned)height)
+ vertical_compose97iL0(b1, b2, b3, width);
+ if (y + 0 < (unsigned)height)
+ vertical_compose97iH0(b0, b1, b2, width);
+ }
+
+ if (y - 1 < (unsigned)height)
+ dsp->horizontal_compose97i(b0, temp, width);
+ if (y + 0 < (unsigned)height)
+ dsp->horizontal_compose97i(b1, temp, width);
+
+ cs->b0 = b2;
+ cs->b1 = b3;
+ cs->b2 = b4;
+ cs->b3 = b5;
+ cs->y += 2;
+}
+
+static void spatial_compose97i_dy(DWTCompose *cs, IDWTELEM *buffer,
+ IDWTELEM *temp, int width, int height,
+ int stride)
+{
+ int y = cs->y;
+ IDWTELEM *b0 = cs->b0;
+ IDWTELEM *b1 = cs->b1;
+ IDWTELEM *b2 = cs->b2;
+ IDWTELEM *b3 = cs->b3;
+ IDWTELEM *b4 = buffer + mirror(y + 3, height - 1) * stride;
+ IDWTELEM *b5 = buffer + mirror(y + 4, height - 1) * stride;
+
+ if (y + 3 < (unsigned)height)
+ vertical_compose97iL1(b3, b4, b5, width);
+ if (y + 2 < (unsigned)height)
+ vertical_compose97iH1(b2, b3, b4, width);
+ if (y + 1 < (unsigned)height)
+ vertical_compose97iL0(b1, b2, b3, width);
+ if (y + 0 < (unsigned)height)
+ vertical_compose97iH0(b0, b1, b2, width);
+
+ if (y - 1 < (unsigned)height)
+ ff_snow_horizontal_compose97i(b0, temp, width);
+ if (y + 0 < (unsigned)height)
+ ff_snow_horizontal_compose97i(b1, temp, width);
+
+ cs->b0 = b2;
+ cs->b1 = b3;
+ cs->b2 = b4;
+ cs->b3 = b5;
+ cs->y += 2;
+}
+
+static void av_unused spatial_compose97i(IDWTELEM *buffer, IDWTELEM *temp,
+ int width, int height, int stride)
+{
DWTCompose cs;
spatial_compose97i_init(&cs, buffer, height, stride);
- while(cs.y <= height)
- spatial_compose97i_dy(&cs, buffer, width, height, stride);
+ while (cs.y <= height)
+ spatial_compose97i_dy(&cs, buffer, temp, width, height, stride);
}
-void ff_spatial_idwt_buffered_init(DWTCompose *cs, slice_buffer * sb, int width, int height, int stride_line, int type, int decomposition_count){
+void ff_spatial_idwt_buffered_init(DWTCompose *cs, slice_buffer *sb, int width,
+ int height, int stride_line, int type,
+ int decomposition_count)
+{
int level;
- for(level=decomposition_count-1; level>=0; level--){
- switch(type){
- case DWT_97: spatial_compose97i_buffered_init(cs+level, sb, height>>level, stride_line<<level); break;
- case DWT_53: spatial_compose53i_buffered_init(cs+level, sb, height>>level, stride_line<<level); break;
+ for (level = decomposition_count - 1; level >= 0; level--) {
+ switch (type) {
+ case DWT_97:
+ spatial_compose97i_buffered_init(cs + level, sb, height >> level,
+ stride_line << level);
+ break;
+ case DWT_53:
+ spatial_compose53i_buffered_init(cs + level, sb, height >> level,
+ stride_line << level);
+ break;
}
}
}
-void ff_spatial_idwt_buffered_slice(DWTContext *dsp, DWTCompose *cs, slice_buffer * slice_buf, int width, int height, int stride_line, int type, int decomposition_count, int y){
- const int support = type==1 ? 3 : 5;
+void ff_spatial_idwt_buffered_slice(DWTContext *dsp, DWTCompose *cs,
+ slice_buffer *slice_buf, IDWTELEM *temp,
+ int width, int height, int stride_line,
+ int type, int decomposition_count, int y)
+{
+ const int support = type == 1 ? 3 : 5;
int level;
- if(type==2) return;
-
- for(level=decomposition_count-1; level>=0; level--){
- while(cs[level].y <= FFMIN((y>>level)+support, height>>level)){
- switch(type){
- case DWT_97: spatial_compose97i_dy_buffered(dsp, cs+level, slice_buf, width>>level, height>>level, stride_line<<level);
+ if (type == 2)
+ return;
+
+ for (level = decomposition_count - 1; level >= 0; level--)
+ while (cs[level].y <= FFMIN((y >> level) + support, height >> level)) {
+ switch (type) {
+ case DWT_97:
+ spatial_compose97i_dy_buffered(dsp, cs + level, slice_buf, temp,
+ width >> level,
+ height >> level,
+ stride_line << level);
break;
- case DWT_53: spatial_compose53i_dy_buffered(cs+level, slice_buf, width>>level, height>>level, stride_line<<level);
+ case DWT_53:
+ spatial_compose53i_dy_buffered(cs + level, slice_buf, temp,
+ width >> level,
+ height >> level,
+ stride_line << level);
break;
}
}
- }
}
-static void ff_spatial_idwt_init(DWTCompose *cs, IDWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count){
+static void ff_spatial_idwt_init(DWTCompose *cs, IDWTELEM *buffer, int width,
+ int height, int stride, int type,
+ int decomposition_count)
+{
int level;
- for(level=decomposition_count-1; level>=0; level--){
- switch(type){
- case DWT_97: spatial_compose97i_init(cs+level, buffer, height>>level, stride<<level); break;
- case DWT_53: spatial_compose53i_init(cs+level, buffer, height>>level, stride<<level); break;
+ for (level = decomposition_count - 1; level >= 0; level--) {
+ switch (type) {
+ case DWT_97:
+ spatial_compose97i_init(cs + level, buffer, height >> level,
+ stride << level);
+ break;
+ case DWT_53:
+ spatial_compose53i_init(cs + level, buffer, height >> level,
+ stride << level);
+ break;
}
}
}
-static void ff_spatial_idwt_slice(DWTCompose *cs, IDWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count, int y){
- const int support = type==1 ? 3 : 5;
+static void ff_spatial_idwt_slice(DWTCompose *cs, IDWTELEM *buffer,
+ IDWTELEM *temp, int width, int height,
+ int stride, int type,
+ int decomposition_count, int y)
+{
+ const int support = type == 1 ? 3 : 5;
int level;
- if(type==2) return;
-
- for(level=decomposition_count-1; level>=0; level--){
- while(cs[level].y <= FFMIN((y>>level)+support, height>>level)){
- switch(type){
- case DWT_97: spatial_compose97i_dy(cs+level, buffer, width>>level, height>>level, stride<<level);
+ if (type == 2)
+ return;
+
+ for (level = decomposition_count - 1; level >= 0; level--)
+ while (cs[level].y <= FFMIN((y >> level) + support, height >> level)) {
+ switch (type) {
+ case DWT_97:
+ spatial_compose97i_dy(cs + level, buffer, temp, width >> level,
+ height >> level, stride << level);
break;
- case DWT_53: spatial_compose53i_dy(cs+level, buffer, width>>level, height>>level, stride<<level);
+ case DWT_53:
+ spatial_compose53i_dy(cs + level, buffer, temp, width >> level,
+ height >> level, stride << level);
break;
}
}
- }
}
-void ff_spatial_idwt(IDWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count){
- DWTCompose cs[MAX_DECOMPOSITIONS];
- int y;
- ff_spatial_idwt_init(cs, buffer, width, height, stride, type, decomposition_count);
- for(y=0; y<height; y+=4)
- ff_spatial_idwt_slice(cs, buffer, width, height, stride, type, decomposition_count, y);
+void ff_spatial_idwt(IDWTELEM *buffer, IDWTELEM *temp, int width, int height,
+ int stride, int type, int decomposition_count)
+{
+ DWTCompose cs[MAX_DECOMPOSITIONS];
+ int y;
+ ff_spatial_idwt_init(cs, buffer, width, height, stride, type,
+ decomposition_count);
+ for (y = 0; y < height; y += 4)
+ ff_spatial_idwt_slice(cs, buffer, temp, width, height, stride, type,
+ decomposition_count, y);
}
-static inline int w_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int w, int h, int type){
+static inline int w_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size,
+ int w, int h, int type)
+{
int s, i, j;
- const int dec_count= w==8 ? 3 : 4;
- int tmp[32*32];
+ const int dec_count = w == 8 ? 3 : 4;
+ int tmp[32 * 32], tmp2[32];
int level, ori;
- static const int scale[2][2][4][4]={
- {
+ static const int scale[2][2][4][4] = {
{
- // 9/7 8x8 dec=3
- {268, 239, 239, 213},
- { 0, 224, 224, 152},
- { 0, 135, 135, 110},
- },{
- // 9/7 16x16 or 32x32 dec=4
- {344, 310, 310, 280},
- { 0, 320, 320, 228},
- { 0, 175, 175, 136},
- { 0, 129, 129, 102},
- }
- },{
+ { // 9/7 8x8 dec=3
+ { 268, 239, 239, 213 },
+ { 0, 224, 224, 152 },
+ { 0, 135, 135, 110 },
+ },
+ { // 9/7 16x16 or 32x32 dec=4
+ { 344, 310, 310, 280 },
+ { 0, 320, 320, 228 },
+ { 0, 175, 175, 136 },
+ { 0, 129, 129, 102 },
+ }
+ },
{
- // 5/3 8x8 dec=3
- {275, 245, 245, 218},
- { 0, 230, 230, 156},
- { 0, 138, 138, 113},
- },{
- // 5/3 16x16 or 32x32 dec=4
- {352, 317, 317, 286},
- { 0, 328, 328, 233},
- { 0, 180, 180, 140},
- { 0, 132, 132, 105},
+ { // 5/3 8x8 dec=3
+ { 275, 245, 245, 218 },
+ { 0, 230, 230, 156 },
+ { 0, 138, 138, 113 },
+ },
+ { // 5/3 16x16 or 32x32 dec=4
+ { 352, 317, 317, 286 },
+ { 0, 328, 328, 233 },
+ { 0, 180, 180, 140 },
+ { 0, 132, 132, 105 },
+ }
}
- }
};
for (i = 0; i < h; i++) {
- for (j = 0; j < w; j+=4) {
- tmp[32*i+j+0] = (pix1[j+0] - pix2[j+0])<<4;
- tmp[32*i+j+1] = (pix1[j+1] - pix2[j+1])<<4;
- tmp[32*i+j+2] = (pix1[j+2] - pix2[j+2])<<4;
- tmp[32*i+j+3] = (pix1[j+3] - pix2[j+3])<<4;
+ for (j = 0; j < w; j += 4) {
+ tmp[32 * i + j + 0] = (pix1[j + 0] - pix2[j + 0]) << 4;
+ tmp[32 * i + j + 1] = (pix1[j + 1] - pix2[j + 1]) << 4;
+ tmp[32 * i + j + 2] = (pix1[j + 2] - pix2[j + 2]) << 4;
+ tmp[32 * i + j + 3] = (pix1[j + 3] - pix2[j + 3]) << 4;
}
pix1 += line_size;
pix2 += line_size;
}
- ff_spatial_dwt(tmp, w, h, 32, type, dec_count);
+ ff_spatial_dwt(tmp, tmp2, w, h, 32, type, dec_count);
- s=0;
- assert(w==h);
- for(level=0; level<dec_count; level++){
- for(ori= level ? 1 : 0; ori<4; ori++){
- int size= w>>(dec_count-level);
- int sx= (ori&1) ? size : 0;
- int stride= 32<<(dec_count-level);
- int sy= (ori&2) ? stride>>1 : 0;
+ s = 0;
+ assert(w == h);
+ for (level = 0; level < dec_count; level++)
+ for (ori = level ? 1 : 0; ori < 4; ori++) {
+ int size = w >> (dec_count - level);
+ int sx = (ori & 1) ? size : 0;
+ int stride = 32 << (dec_count - level);
+ int sy = (ori & 2) ? stride >> 1 : 0;
- for(i=0; i<size; i++){
- for(j=0; j<size; j++){
- int v= tmp[sx + sy + i*stride + j] * scale[type][dec_count-3][level][ori];
+ for (i = 0; i < size; i++)
+ for (j = 0; j < size; j++) {
+ int v = tmp[sx + sy + i * stride + j] *
+ scale[type][dec_count - 3][level][ori];
s += FFABS(v);
}
- }
}
- }
- assert(s>=0);
- return s>>9;
+ assert(s >= 0);
+ return s >> 9;
}
-static int w53_8_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){
- return w_c(v, pix1, pix2, line_size, 8, h, 1);
+static int w53_8_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
+{
+ return w_c(v, pix1, pix2, line_size, 8, h, 1);
}
-static int w97_8_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){
- return w_c(v, pix1, pix2, line_size, 8, h, 0);
+static int w97_8_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
+{
+ return w_c(v, pix1, pix2, line_size, 8, h, 0);
}
-static int w53_16_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){
+static int w53_16_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
+{
return w_c(v, pix1, pix2, line_size, 16, h, 1);
}
-static int w97_16_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){
+static int w97_16_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
+{
return w_c(v, pix1, pix2, line_size, 16, h, 0);
}
-int ff_w53_32_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){
+int ff_w53_32_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
+{
return w_c(v, pix1, pix2, line_size, 32, h, 1);
}
-int ff_w97_32_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){
+int ff_w97_32_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
+{
return w_c(v, pix1, pix2, line_size, 32, h, 0);
}
void ff_dsputil_init_dwt(DSPContext *c)
{
- c->w53[0]= w53_16_c;
- c->w53[1]= w53_8_c;
- c->w97[0]= w97_16_c;
- c->w97[1]= w97_8_c;
+ c->w53[0] = w53_16_c;
+ c->w53[1] = w53_8_c;
+ c->w97[0] = w97_16_c;
+ c->w97[1] = w97_8_c;
}
void ff_dwt_init(DWTContext *c)
{
- c->vertical_compose97i = ff_snow_vertical_compose97i;
+ c->vertical_compose97i = ff_snow_vertical_compose97i;
c->horizontal_compose97i = ff_snow_horizontal_compose97i;
- c->inner_add_yblock = ff_snow_inner_add_yblock;
+ c->inner_add_yblock = ff_snow_inner_add_yblock;
- if (HAVE_MMX) ff_dwt_init_x86(c);
+ if (HAVE_MMX)
+ ff_dwt_init_x86(c);
}
diff --git a/libavcodec/dwt.h b/libavcodec/dwt.h
index fc73fe7..771a9bf 100644
--- a/libavcodec/dwt.h
+++ b/libavcodec/dwt.h
@@ -34,21 +34,27 @@ typedef struct {
int y;
} DWTCompose;
-/** Used to minimize the amount of memory used in order to optimize cache performance. **/
+/** Used to minimize the amount of memory used in order to
+ * optimize cache performance. **/
typedef struct slice_buffer_s {
- IDWTELEM * * line; ///< For use by idwt and predict_slices.
- IDWTELEM * * data_stack; ///< Used for internal purposes.
+ IDWTELEM **line; ///< For use by idwt and predict_slices.
+ IDWTELEM **data_stack; ///< Used for internal purposes.
int data_stack_top;
int line_count;
int line_width;
int data_count;
- IDWTELEM * base_buffer; ///< Buffer that this structure is caching.
+ IDWTELEM *base_buffer; ///< Buffer that this structure is caching.
} slice_buffer;
typedef struct DWTContext {
- void (*vertical_compose97i)(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width);
- void (*horizontal_compose97i)(IDWTELEM *b, int width);
- void (*inner_add_yblock)(const uint8_t *obmc, const int obmc_stride, uint8_t * * block, int b_w, int b_h, int src_x, int src_y, int src_stride, slice_buffer * sb, int add, uint8_t * dst8);
+ void (*vertical_compose97i)(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
+ IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5,
+ int width);
+ void (*horizontal_compose97i)(IDWTELEM *b, IDWTELEM *temp, int width);
+ void (*inner_add_yblock)(const uint8_t *obmc, const int obmc_stride,
+ uint8_t **block, int b_w, int b_h, int src_x,
+ int src_y, int src_stride, slice_buffer *sb,
+ int add, uint8_t *dst8);
} DWTContext;
#define MAX_DECOMPOSITIONS 8
@@ -126,27 +132,43 @@ typedef struct DWTContext {
#define W_DS 9
#endif
-#define slice_buffer_get_line(slice_buf, line_num) ((slice_buf)->line[line_num] ? (slice_buf)->line[line_num] : ff_slice_buffer_load_line((slice_buf), (line_num)))
-//#define slice_buffer_get_line(slice_buf, line_num) (ff_slice_buffer_load_line((slice_buf), (line_num)))
-
-void ff_slice_buffer_init(slice_buffer * buf, int line_count, int max_allocated_lines, int line_width, IDWTELEM * base_buffer);
-void ff_slice_buffer_release(slice_buffer * buf, int line);
-void ff_slice_buffer_flush(slice_buffer * buf);
-void ff_slice_buffer_destroy(slice_buffer * buf);
-IDWTELEM * ff_slice_buffer_load_line(slice_buffer * buf, int line);
-
-void ff_snow_vertical_compose97i(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width);
-void ff_snow_horizontal_compose97i(IDWTELEM *b, int width);
-void ff_snow_inner_add_yblock(const uint8_t *obmc, const int obmc_stride, uint8_t * * block, int b_w, int b_h, int src_x, int src_y, int src_stride, slice_buffer * sb, int add, uint8_t * dst8);
-
-int ff_w53_32_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h);
-int ff_w97_32_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h);
-
-void ff_spatial_dwt(int *buffer, int width, int height, int stride, int type, int decomposition_count);
-
-void ff_spatial_idwt_buffered_init(DWTCompose *cs, slice_buffer * sb, int width, int height, int stride_line, int type, int decomposition_count);
-void ff_spatial_idwt_buffered_slice(DWTContext *dsp, DWTCompose *cs, slice_buffer * slice_buf, int width, int height, int stride_line, int type, int decomposition_count, int y);
-void ff_spatial_idwt(IDWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count);
+#define slice_buffer_get_line(slice_buf, line_num) \
+ ((slice_buf)->line[line_num] ? (slice_buf)->line[line_num] \
+ : ff_slice_buffer_load_line((slice_buf), \
+ (line_num)))
+
+int ff_slice_buffer_init(slice_buffer *buf, int line_count,
+ int max_allocated_lines, int line_width,
+ IDWTELEM *base_buffer);
+void ff_slice_buffer_release(slice_buffer *buf, int line);
+void ff_slice_buffer_flush(slice_buffer *buf);
+void ff_slice_buffer_destroy(slice_buffer *buf);
+IDWTELEM *ff_slice_buffer_load_line(slice_buffer *buf, int line);
+
+void ff_snow_vertical_compose97i(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
+ IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5,
+ int width);
+void ff_snow_horizontal_compose97i(IDWTELEM *b, IDWTELEM *temp, int width);
+void ff_snow_inner_add_yblock(const uint8_t *obmc, const int obmc_stride,
+ uint8_t **block, int b_w, int b_h, int src_x,
+ int src_y, int src_stride, slice_buffer *sb,
+ int add, uint8_t *dst8);
+
+int ff_w53_32_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h);
+int ff_w97_32_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h);
+
+void ff_spatial_dwt(int *buffer, int *temp, int width, int height, int stride,
+ int type, int decomposition_count);
+
+void ff_spatial_idwt_buffered_init(DWTCompose *cs, slice_buffer *sb, int width,
+ int height, int stride_line, int type,
+ int decomposition_count);
+void ff_spatial_idwt_buffered_slice(DWTContext *dsp, DWTCompose *cs,
+ slice_buffer *slice_buf, IDWTELEM *temp,
+ int width, int height, int stride_line,
+ int type, int decomposition_count, int y);
+void ff_spatial_idwt(IDWTELEM *buffer, IDWTELEM *temp, int width, int height,
+ int stride, int type, int decomposition_count);
void ff_dwt_init(DWTContext *c);
void ff_dwt_init_x86(DWTContext *c);
diff --git a/libavcodec/dxva2_h264.c b/libavcodec/dxva2_h264.c
index ffe71a9..5cdf5de 100644
--- a/libavcodec/dxva2_h264.c
+++ b/libavcodec/dxva2_h264.c
@@ -93,7 +93,8 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context
pp->num_ref_frames = h->sps.ref_frame_count;
pp->wBitFields = ((s->picture_structure != PICT_FRAME) << 0) |
- (h->sps.mb_aff << 1) |
+ ((h->sps.mb_aff &&
+ (s->picture_structure == PICT_FRAME)) << 1) |
(h->sps.residual_color_transform_flag << 2) |
/* sp_for_switch_flag (not implemented by Libav) */
(0 << 3) |
diff --git a/libavcodec/dxva2_internal.h b/libavcodec/dxva2_internal.h
index 57fc7bd..e2305b1 100644
--- a/libavcodec/dxva2_internal.h
+++ b/libavcodec/dxva2_internal.h
@@ -25,7 +25,14 @@
#define _WIN32_WINNT 0x0600
#define COBJMACROS
+
+#include "config.h"
+
#include "dxva2.h"
+#if HAVE_DXVA_H
+#include <dxva.h>
+#endif
+
#include "avcodec.h"
#include "mpegvideo.h"
diff --git a/libavcodec/eatgv.c b/libavcodec/eatgv.c
index 34b79af..60058b2 100644
--- a/libavcodec/eatgv.c
+++ b/libavcodec/eatgv.c
@@ -136,7 +136,6 @@ static int unpack(const uint8_t *src, const uint8_t *src_end, unsigned char *dst
* @return 0 on success, -1 on critical buffer underflow
*/
static int tgv_decode_inter(TgvContext * s, const uint8_t *buf, const uint8_t *buf_end){
- unsigned char *frame0_end = s->last_frame.data[0] + s->avctx->width*s->last_frame.linesize[0];
int num_mvs;
int num_blocks_raw;
int num_blocks_packed;
@@ -155,6 +154,12 @@ static int tgv_decode_inter(TgvContext * s, const uint8_t *buf, const uint8_t *b
vector_bits = AV_RL16(&buf[6]);
buf += 12;
+ if (vector_bits > MIN_CACHE_BITS || !vector_bits) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Invalid value for motion vector bits: %d\n", vector_bits);
+ return AVERROR_INVALIDDATA;
+ }
+
/* allocate codebook buffers as necessary */
if (num_mvs > s->num_mvs) {
s->mv_codebook = av_realloc(s->mv_codebook, num_mvs*2*sizeof(int));
@@ -205,12 +210,15 @@ static int tgv_decode_inter(TgvContext * s, const uint8_t *buf, const uint8_t *b
int src_stride;
if (vector < num_mvs) {
- src = s->last_frame.data[0] +
- (y*4 + s->mv_codebook[vector][1])*s->last_frame.linesize[0] +
- x*4 + s->mv_codebook[vector][0];
- src_stride = s->last_frame.linesize[0];
- if (src+3*src_stride+3>=frame0_end)
+ int mx = x * 4 + s->mv_codebook[vector][0];
+ int my = y * 4 + s->mv_codebook[vector][1];
+
+ if ( mx < 0 || mx + 4 > s->avctx->width
+ || my < 0 || my + 4 > s->avctx->height)
continue;
+
+ src = s->last_frame.data[0] + mx + my * s->last_frame.linesize[0];
+ src_stride = s->last_frame.linesize[0];
}else{
int offset = vector - num_mvs;
if (offset<num_blocks_raw)
diff --git a/libavcodec/eatqi.c b/libavcodec/eatqi.c
index 2d7da5a..9824940 100644
--- a/libavcodec/eatqi.c
+++ b/libavcodec/eatqi.c
@@ -57,12 +57,15 @@ static av_cold int tqi_decode_init(AVCodecContext *avctx)
return 0;
}
-static void tqi_decode_mb(MpegEncContext *s, DCTELEM (*block)[64])
+static int tqi_decode_mb(MpegEncContext *s, DCTELEM (*block)[64])
{
int n;
s->dsp.clear_blocks(block[0]);
for (n=0; n<6; n++)
- ff_mpeg1_decode_block_intra(s, block[n], n);
+ if (ff_mpeg1_decode_block_intra(s, block[n], n) < 0)
+ return -1;
+
+ return 0;
}
static inline void tqi_idct_put(TqiContext *t, DCTELEM (*block)[64])
@@ -135,7 +138,8 @@ static int tqi_decode_frame(AVCodecContext *avctx,
for (s->mb_y=0; s->mb_y<(avctx->height+15)/16; s->mb_y++)
for (s->mb_x=0; s->mb_x<(avctx->width+15)/16; s->mb_x++)
{
- tqi_decode_mb(s, t->block);
+ if (tqi_decode_mb(s, t->block) < 0)
+ break;
tqi_idct_put(t, t->block);
}
diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c
index fa1e008..9cebb6d 100644
--- a/libavcodec/error_resilience.c
+++ b/libavcodec/error_resilience.c
@@ -388,7 +388,7 @@ static void v_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h,
static void guess_mv(MpegEncContext *s)
{
- uint8_t fixed[s->mb_stride * s->mb_height];
+ uint8_t *fixed = s->er_temp_buffer;
#define MV_FROZEN 3
#define MV_CHANGED 2
#define MV_UNCHANGED 1
diff --git a/libavcodec/fft-test.c b/libavcodec/fft-test.c
index 70c0655..75941a1 100644
--- a/libavcodec/fft-test.c
+++ b/libavcodec/fft-test.c
@@ -27,6 +27,7 @@
#include "libavutil/mathematics.h"
#include "libavutil/lfg.h"
#include "libavutil/log.h"
+#include "libavutil/time.h"
#include "fft.h"
#if CONFIG_FFT_FLOAT
#include "dct.h"
@@ -34,7 +35,6 @@
#endif
#include <math.h>
#include <unistd.h>
-#include <sys/time.h>
#include <stdlib.h>
#include <string.h>
@@ -186,13 +186,6 @@ static FFTSample frandom(AVLFG *prng)
return (int16_t)av_lfg_get(prng) / 32768.0 * RANGE;
}
-static int64_t gettime(void)
-{
- struct timeval tv;
- gettimeofday(&tv,NULL);
- return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
-}
-
static int check_diff(FFTSample *tab1, FFTSample *tab2, int n, double scale)
{
int i;
@@ -430,7 +423,7 @@ int main(int argc, char **argv)
/* we measure during about 1 seconds */
nb_its = 1;
for(;;) {
- time_start = gettime();
+ time_start = av_gettime();
for (it = 0; it < nb_its; it++) {
switch (transform) {
case TRANSFORM_MDCT:
@@ -456,7 +449,7 @@ int main(int argc, char **argv)
#endif
}
}
- duration = gettime() - time_start;
+ duration = av_gettime() - time_start;
if (duration >= 1000000)
break;
nb_its *= 2;
diff --git a/libavcodec/flac.c b/libavcodec/flac.c
index e6a427a..ac36376 100644
--- a/libavcodec/flac.c
+++ b/libavcodec/flac.c
@@ -55,8 +55,9 @@ int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,
if (fi->ch_mode < FLAC_MAX_CHANNELS) {
fi->channels = fi->ch_mode + 1;
fi->ch_mode = FLAC_CHMODE_INDEPENDENT;
- } else if (fi->ch_mode <= FLAC_CHMODE_MID_SIDE) {
+ } else if (fi->ch_mode < FLAC_MAX_CHANNELS + FLAC_CHMODE_MID_SIDE) {
fi->channels = 2;
+ fi->ch_mode -= FLAC_MAX_CHANNELS - 1;
} else {
av_log(avctx, AV_LOG_ERROR + log_level_offset,
"invalid channel mode: %d\n", fi->ch_mode);
diff --git a/libavcodec/flac.h b/libavcodec/flac.h
index b826fd4..55bacea 100644
--- a/libavcodec/flac.h
+++ b/libavcodec/flac.h
@@ -37,10 +37,10 @@
#define FLAC_MIN_FRAME_SIZE 11
enum {
- FLAC_CHMODE_INDEPENDENT = 0,
- FLAC_CHMODE_LEFT_SIDE = 8,
- FLAC_CHMODE_RIGHT_SIDE = 9,
- FLAC_CHMODE_MID_SIDE = 10,
+ FLAC_CHMODE_INDEPENDENT = 0,
+ FLAC_CHMODE_LEFT_SIDE = 1,
+ FLAC_CHMODE_RIGHT_SIDE = 2,
+ FLAC_CHMODE_MID_SIDE = 3,
};
enum {
diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c
index cd2a693..89819e3 100644
--- a/libavcodec/flacdec.c
+++ b/libavcodec/flacdec.c
@@ -42,6 +42,7 @@
#include "golomb.h"
#include "flac.h"
#include "flacdata.h"
+#include "flacdsp.h"
#undef NDEBUG
#include <assert.h>
@@ -54,13 +55,13 @@ typedef struct FLACContext {
GetBitContext gb; ///< GetBitContext initialized to start at the current frame
int blocksize; ///< number of samples in the current frame
- int curr_bps; ///< bps for current subframe, adjusted for channel correlation and wasted bits
int sample_shift; ///< shift required to make output samples 16-bit or 32-bit
- int is32; ///< flag to indicate if output should be 32-bit instead of 16-bit
int ch_mode; ///< channel decorrelation type in the current frame
int got_streaminfo; ///< indicates if the STREAMINFO has been read
int32_t *decoded[FLAC_MAX_CHANNELS]; ///< decoded samples
+
+ FLACDSPContext dsp;
} FLACContext;
static const int64_t flac_channel_layouts[6] = {
@@ -101,6 +102,28 @@ int avpriv_flac_is_extradata_valid(AVCodecContext *avctx,
return 1;
}
+static void flac_set_bps(FLACContext *s)
+{
+ enum AVSampleFormat req = s->avctx->request_sample_fmt;
+ int need32 = s->bps > 16;
+ int want32 = av_get_bytes_per_sample(req) > 2;
+ int planar = av_sample_fmt_is_planar(req);
+
+ if (need32 || want32) {
+ if (planar)
+ s->avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
+ else
+ s->avctx->sample_fmt = AV_SAMPLE_FMT_S32;
+ s->sample_shift = 32 - s->bps;
+ } else {
+ if (planar)
+ s->avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
+ else
+ s->avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+ s->sample_shift = 16 - s->bps;
+ }
+}
+
static av_cold int flac_decode_init(AVCodecContext *avctx)
{
enum FLACExtradataFormat format;
@@ -108,8 +131,6 @@ static av_cold int flac_decode_init(AVCodecContext *avctx)
FLACContext *s = avctx->priv_data;
s->avctx = avctx;
- avctx->sample_fmt = AV_SAMPLE_FMT_S16;
-
/* for now, the raw FLAC header is allowed to be passed to the decoder as
frame data instead of extradata. */
if (!avctx->extradata)
@@ -120,11 +141,9 @@ static av_cold int flac_decode_init(AVCodecContext *avctx)
/* initialize based on the demuxer-supplied streamdata header */
avpriv_flac_parse_streaminfo(avctx, (FLACStreaminfo *)s, streaminfo);
- if (s->bps > 16)
- avctx->sample_fmt = AV_SAMPLE_FMT_S32;
- else
- avctx->sample_fmt = AV_SAMPLE_FMT_S16;
allocate_buffers(s);
+ flac_set_bps(s);
+ ff_flacdsp_init(&s->dsp, avctx->sample_fmt, s->bps);
s->got_streaminfo = 1;
avcodec_get_frame_defaults(&s->frame);
@@ -152,8 +171,7 @@ static void allocate_buffers(FLACContext *s)
assert(s->max_blocksize);
for (i = 0; i < s->channels; i++) {
- s->decoded[i] = av_realloc(s->decoded[i],
- sizeof(int32_t)*s->max_blocksize);
+ s->decoded[i] = av_malloc(sizeof(int32_t)*s->max_blocksize);
}
}
@@ -225,6 +243,8 @@ static int parse_streaminfo(FLACContext *s, const uint8_t *buf, int buf_size)
}
avpriv_flac_parse_streaminfo(s->avctx, (FLACStreaminfo *)s, &buf[8]);
allocate_buffers(s);
+ flac_set_bps(s);
+ ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt, s->bps);
s->got_streaminfo = 1;
return 0;
@@ -297,7 +317,8 @@ static int decode_residuals(FLACContext *s, int channel, int pred_order)
return 0;
}
-static int decode_subframe_fixed(FLACContext *s, int channel, int pred_order)
+static int decode_subframe_fixed(FLACContext *s, int channel, int pred_order,
+ int bps)
{
const int blocksize = s->blocksize;
int32_t *decoded = s->decoded[channel];
@@ -305,7 +326,7 @@ static int decode_subframe_fixed(FLACContext *s, int channel, int pred_order)
/* warm up samples */
for (i = 0; i < pred_order; i++) {
- decoded[i] = get_sbits_long(&s->gb, s->curr_bps);
+ decoded[i] = get_sbits_long(&s->gb, bps);
}
if (decode_residuals(s, channel, pred_order) < 0)
@@ -347,16 +368,17 @@ static int decode_subframe_fixed(FLACContext *s, int channel, int pred_order)
return 0;
}
-static int decode_subframe_lpc(FLACContext *s, int channel, int pred_order)
+static int decode_subframe_lpc(FLACContext *s, int channel, int pred_order,
+ int bps)
{
- int i, j;
+ int i;
int coeff_prec, qlevel;
int coeffs[32];
int32_t *decoded = s->decoded[channel];
/* warm up samples */
for (i = 0; i < pred_order; i++) {
- decoded[i] = get_sbits_long(&s->gb, s->curr_bps);
+ decoded[i] = get_sbits_long(&s->gb, bps);
}
coeff_prec = get_bits(&s->gb, 4) + 1;
@@ -378,38 +400,7 @@ static int decode_subframe_lpc(FLACContext *s, int channel, int pred_order)
if (decode_residuals(s, channel, pred_order) < 0)
return -1;
- if (s->bps > 16) {
- int64_t sum;
- for (i = pred_order; i < s->blocksize; i++) {
- sum = 0;
- for (j = 0; j < pred_order; j++)
- sum += (int64_t)coeffs[j] * decoded[i-j-1];
- decoded[i] += sum >> qlevel;
- }
- } else {
- for (i = pred_order; i < s->blocksize-1; i += 2) {
- int c;
- int d = decoded[i-pred_order];
- int s0 = 0, s1 = 0;
- for (j = pred_order-1; j > 0; j--) {
- c = coeffs[j];
- s0 += c*d;
- d = decoded[i-j];
- s1 += c*d;
- }
- c = coeffs[0];
- s0 += c*d;
- d = decoded[i] += s0 >> qlevel;
- s1 += c*d;
- decoded[i+1] += s1 >> qlevel;
- }
- if (i < s->blocksize) {
- int sum = 0;
- for (j = 0; j < pred_order; j++)
- sum += coeffs[j] * decoded[i-j-1];
- decoded[i] += sum >> qlevel;
- }
- }
+ s->dsp.lpc(decoded, coeffs, pred_order, qlevel, s->blocksize);
return 0;
}
@@ -417,15 +408,15 @@ static int decode_subframe_lpc(FLACContext *s, int channel, int pred_order)
static inline int decode_subframe(FLACContext *s, int channel)
{
int type, wasted = 0;
+ int bps = s->bps;
int i, tmp;
- s->curr_bps = s->bps;
if (channel == 0) {
if (s->ch_mode == FLAC_CHMODE_RIGHT_SIDE)
- s->curr_bps++;
+ bps++;
} else {
if (s->ch_mode == FLAC_CHMODE_LEFT_SIDE || s->ch_mode == FLAC_CHMODE_MID_SIDE)
- s->curr_bps++;
+ bps++;
}
if (get_bits1(&s->gb)) {
@@ -438,35 +429,35 @@ static inline int decode_subframe(FLACContext *s, int channel)
int left = get_bits_left(&s->gb);
wasted = 1;
if ( left < 0 ||
- (left < s->curr_bps && !show_bits_long(&s->gb, left)) ||
- !show_bits_long(&s->gb, s->curr_bps)) {
+ (left < bps && !show_bits_long(&s->gb, left)) ||
+ !show_bits_long(&s->gb, bps)) {
av_log(s->avctx, AV_LOG_ERROR,
"Invalid number of wasted bits > available bits (%d) - left=%d\n",
- s->curr_bps, left);
+ bps, left);
return AVERROR_INVALIDDATA;
}
while (!get_bits1(&s->gb))
wasted++;
- s->curr_bps -= wasted;
+ bps -= wasted;
}
- if (s->curr_bps > 32) {
+ if (bps > 32) {
av_log_missing_feature(s->avctx, "decorrelated bit depth > 32", 0);
return -1;
}
//FIXME use av_log2 for types
if (type == 0) {
- tmp = get_sbits_long(&s->gb, s->curr_bps);
+ tmp = get_sbits_long(&s->gb, bps);
for (i = 0; i < s->blocksize; i++)
s->decoded[channel][i] = tmp;
} else if (type == 1) {
for (i = 0; i < s->blocksize; i++)
- s->decoded[channel][i] = get_sbits_long(&s->gb, s->curr_bps);
+ s->decoded[channel][i] = get_sbits_long(&s->gb, bps);
} else if ((type >= 8) && (type <= 12)) {
- if (decode_subframe_fixed(s, channel, type & ~0x8) < 0)
+ if (decode_subframe_fixed(s, channel, type & ~0x8, bps) < 0)
return -1;
} else if (type >= 32) {
- if (decode_subframe_lpc(s, channel, (type & ~0x20)+1) < 0)
+ if (decode_subframe_lpc(s, channel, (type & ~0x20)+1, bps) < 0)
return -1;
} else {
av_log(s->avctx, AV_LOG_ERROR, "invalid coding type\n");
@@ -512,16 +503,10 @@ static int decode_frame(FLACContext *s)
"supported\n");
return -1;
}
- s->bps = s->avctx->bits_per_raw_sample = fi.bps;
- if (s->bps > 16) {
- s->avctx->sample_fmt = AV_SAMPLE_FMT_S32;
- s->sample_shift = 32 - s->bps;
- s->is32 = 1;
- } else {
- s->avctx->sample_fmt = AV_SAMPLE_FMT_S16;
- s->sample_shift = 16 - s->bps;
- s->is32 = 0;
+ if (!s->bps) {
+ s->bps = s->avctx->bits_per_raw_sample = fi.bps;
+ flac_set_bps(s);
}
if (!s->max_blocksize)
@@ -548,6 +533,7 @@ static int decode_frame(FLACContext *s)
if (!s->got_streaminfo) {
allocate_buffers(s);
+ ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt, s->bps);
s->got_streaminfo = 1;
dump_headers(s->avctx, (FLACStreaminfo *)s);
}
@@ -574,9 +560,7 @@ static int flac_decode_frame(AVCodecContext *avctx, void *data,
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
FLACContext *s = avctx->priv_data;
- int i, j = 0, bytes_read = 0;
- int16_t *samples_16;
- int32_t *samples_32;
+ int bytes_read = 0;
int ret;
*got_frame_ptr = 0;
@@ -616,42 +600,9 @@ static int flac_decode_frame(AVCodecContext *avctx, void *data,
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return ret;
}
- samples_16 = (int16_t *)s->frame.data[0];
- samples_32 = (int32_t *)s->frame.data[0];
-
-#define DECORRELATE(left, right)\
- assert(s->channels == 2);\
- for (i = 0; i < s->blocksize; i++) {\
- int a= s->decoded[0][i];\
- int b= s->decoded[1][i];\
- if (s->is32) {\
- *samples_32++ = (left) << s->sample_shift;\
- *samples_32++ = (right) << s->sample_shift;\
- } else {\
- *samples_16++ = (left) << s->sample_shift;\
- *samples_16++ = (right) << s->sample_shift;\
- }\
- }\
- break;
-
- switch (s->ch_mode) {
- case FLAC_CHMODE_INDEPENDENT:
- for (j = 0; j < s->blocksize; j++) {
- for (i = 0; i < s->channels; i++) {
- if (s->is32)
- *samples_32++ = s->decoded[i][j] << s->sample_shift;
- else
- *samples_16++ = s->decoded[i][j] << s->sample_shift;
- }
- }
- break;
- case FLAC_CHMODE_LEFT_SIDE:
- DECORRELATE(a,a-b)
- case FLAC_CHMODE_RIGHT_SIDE:
- DECORRELATE(a+b,b)
- case FLAC_CHMODE_MID_SIDE:
- DECORRELATE( (a-=b>>1) + b, a)
- }
+
+ s->dsp.decorrelate[s->ch_mode](s->frame.data, s->decoded, s->channels,
+ s->blocksize, s->sample_shift);
if (bytes_read > buf_size) {
av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", bytes_read - buf_size);
@@ -690,4 +641,9 @@ AVCodec ff_flac_decoder = {
.decode = flac_decode_frame,
.capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),
+ .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16,
+ AV_SAMPLE_FMT_S16P,
+ AV_SAMPLE_FMT_S32,
+ AV_SAMPLE_FMT_S32P,
+ -1 },
};
diff --git a/libavcodec/flacdsp.c b/libavcodec/flacdsp.c
new file mode 100644
index 0000000..a2e335b
--- /dev/null
+++ b/libavcodec/flacdsp.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2012 Mans Rullgard <mans at mansr.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/attributes.h"
+#include "libavutil/samplefmt.h"
+#include "flacdsp.h"
+
+#define SAMPLE_SIZE 16
+#define PLANAR 0
+#include "flacdsp_template.c"
+
+#undef PLANAR
+#define PLANAR 1
+#include "flacdsp_template.c"
+
+#undef SAMPLE_SIZE
+#undef PLANAR
+#define SAMPLE_SIZE 32
+#define PLANAR 0
+#include "flacdsp_template.c"
+
+#undef PLANAR
+#define PLANAR 1
+#include "flacdsp_template.c"
+
+static void flac_lpc_16_c(int32_t *decoded, const int coeffs[32],
+ int pred_order, int qlevel, int len)
+{
+ int i, j;
+
+ for (i = pred_order; i < len - 1; i += 2) {
+ int c;
+ int d = decoded[i-pred_order];
+ int s0 = 0, s1 = 0;
+ for (j = pred_order-1; j > 0; j--) {
+ c = coeffs[j];
+ s0 += c*d;
+ d = decoded[i-j];
+ s1 += c*d;
+ }
+ c = coeffs[0];
+ s0 += c*d;
+ d = decoded[i] += s0 >> qlevel;
+ s1 += c*d;
+ decoded[i+1] += s1 >> qlevel;
+ }
+ if (i < len) {
+ int sum = 0;
+ for (j = 0; j < pred_order; j++)
+ sum += coeffs[j] * decoded[i-j-1];
+ decoded[i] += sum >> qlevel;
+ }
+}
+
+static void flac_lpc_32_c(int32_t *decoded, const int coeffs[32],
+ int pred_order, int qlevel, int len)
+{
+ int i, j;
+
+ for (i = pred_order; i < len; i++) {
+ int64_t sum = 0;
+ for (j = 0; j < pred_order; j++)
+ sum += (int64_t)coeffs[j] * decoded[i-j-1];
+ decoded[i] += sum >> qlevel;
+ }
+
+}
+
+av_cold void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt,
+ int bps)
+{
+ if (bps > 16)
+ c->lpc = flac_lpc_32_c;
+ else
+ c->lpc = flac_lpc_16_c;
+
+ switch (fmt) {
+ case AV_SAMPLE_FMT_S32:
+ c->decorrelate[0] = flac_decorrelate_indep_c_32;
+ c->decorrelate[1] = flac_decorrelate_ls_c_32;
+ c->decorrelate[2] = flac_decorrelate_rs_c_32;
+ c->decorrelate[3] = flac_decorrelate_ms_c_32;
+ break;
+
+ case AV_SAMPLE_FMT_S32P:
+ c->decorrelate[0] = flac_decorrelate_indep_c_32p;
+ c->decorrelate[1] = flac_decorrelate_ls_c_32p;
+ c->decorrelate[2] = flac_decorrelate_rs_c_32p;
+ c->decorrelate[3] = flac_decorrelate_ms_c_32p;
+ break;
+
+ case AV_SAMPLE_FMT_S16:
+ c->decorrelate[0] = flac_decorrelate_indep_c_16;
+ c->decorrelate[1] = flac_decorrelate_ls_c_16;
+ c->decorrelate[2] = flac_decorrelate_rs_c_16;
+ c->decorrelate[3] = flac_decorrelate_ms_c_16;
+ break;
+
+ case AV_SAMPLE_FMT_S16P:
+ c->decorrelate[0] = flac_decorrelate_indep_c_16p;
+ c->decorrelate[1] = flac_decorrelate_ls_c_16p;
+ c->decorrelate[2] = flac_decorrelate_rs_c_16p;
+ c->decorrelate[3] = flac_decorrelate_ms_c_16p;
+ break;
+ }
+}
diff --git a/libavcodec/flacdsp.h b/libavcodec/flacdsp.h
new file mode 100644
index 0000000..1651553
--- /dev/null
+++ b/libavcodec/flacdsp.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_FLACDSP_H
+#define AVCODEC_FLACDSP_H
+
+#include <stdint.h>
+#include "libavutil/samplefmt.h"
+
+typedef struct FLACDSPContext {
+ void (*decorrelate[4])(uint8_t **out, int32_t **in, int channels,
+ int len, int shift);
+ void (*lpc)(int32_t *samples, const int coeffs[32], int order,
+ int qlevel, int len);
+} FLACDSPContext;
+
+void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt, int bps);
+
+#endif /* AVCODEC_FLACDSP_H */
diff --git a/libavcodec/flacdsp_template.c b/libavcodec/flacdsp_template.c
new file mode 100644
index 0000000..0affe22
--- /dev/null
+++ b/libavcodec/flacdsp_template.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2012 Mans Rullgard <mans at mansr.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include "libavutil/avutil.h"
+
+#undef FUNC
+#undef FSUF
+#undef sample
+#undef sample_type
+#undef OUT
+#undef S
+
+#if SAMPLE_SIZE == 32
+# define sample_type int32_t
+#else
+# define sample_type int16_t
+#endif
+
+#if PLANAR
+# define FSUF AV_JOIN(SAMPLE_SIZE, p)
+# define sample sample_type *
+# define OUT(n) n
+# define S(s, c, i) (s[c][i])
+#else
+# define FSUF SAMPLE_SIZE
+# define sample sample_type
+# define OUT(n) n[0]
+# define S(s, c, i) (*s++)
+#endif
+
+#define FUNC(n) AV_JOIN(n ## _, FSUF)
+
+static void FUNC(flac_decorrelate_indep_c)(uint8_t **out, int32_t **in,
+ int channels, int len, int shift)
+{
+ sample *samples = (sample *) OUT(out);
+ int i, j;
+
+ for (j = 0; j < len; j++)
+ for (i = 0; i < channels; i++)
+ S(samples, i, j) = in[i][j] << shift;
+}
+
+static void FUNC(flac_decorrelate_ls_c)(uint8_t **out, int32_t **in,
+ int channels, int len, int shift)
+{
+ sample *samples = (sample *) OUT(out);
+ int i;
+
+ for (i = 0; i < len; i++) {
+ int a = in[0][i];
+ int b = in[1][i];
+ S(samples, 0, i) = a << shift;
+ S(samples, 1, i) = (a - b) << shift;
+ }
+}
+
+static void FUNC(flac_decorrelate_rs_c)(uint8_t **out, int32_t **in,
+ int channels, int len, int shift)
+{
+ sample *samples = (sample *) OUT(out);
+ int i;
+
+ for (i = 0; i < len; i++) {
+ int a = in[0][i];
+ int b = in[1][i];
+ S(samples, 0, i) = (a + b) << shift;
+ S(samples, 1, i) = b << shift;
+ }
+}
+
+static void FUNC(flac_decorrelate_ms_c)(uint8_t **out, int32_t **in,
+ int channels, int len, int shift)
+{
+ sample *samples = (sample *) OUT(out);
+ int i;
+
+ for (i = 0; i < len; i++) {
+ int a = in[0][i];
+ int b = in[1][i];
+ a -= b >> 1;
+ S(samples, 0, i) = (a + b) << shift;
+ S(samples, 1, i) = a << shift;
+ }
+}
diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c
index fc1f00a..e2a3705 100644
--- a/libavcodec/flacenc.c
+++ b/libavcodec/flacenc.c
@@ -53,6 +53,7 @@ typedef struct CompressionOptions {
int prediction_order_method;
int min_partition_order;
int max_partition_order;
+ int ch_mode;
} CompressionOptions;
typedef struct RiceContext {
@@ -1000,15 +1001,8 @@ static int estimate_stereo_mode(int32_t *left_ch, int32_t *right_ch, int n)
for (i = 1; i < 4; i++)
if (score[i] < score[best])
best = i;
- if (best == 0) {
- return FLAC_CHMODE_INDEPENDENT;
- } else if (best == 1) {
- return FLAC_CHMODE_LEFT_SIDE;
- } else if (best == 2) {
- return FLAC_CHMODE_RIGHT_SIDE;
- } else {
- return FLAC_CHMODE_MID_SIDE;
- }
+
+ return best;
}
@@ -1031,7 +1025,10 @@ static void channel_decorrelation(FlacEncodeContext *s)
return;
}
- frame->ch_mode = estimate_stereo_mode(left, right, n);
+ if (s->options.ch_mode < 0)
+ frame->ch_mode = estimate_stereo_mode(left, right, n);
+ else
+ frame->ch_mode = s->options.ch_mode;
/* perform decorrelation and adjust bits-per-sample */
if (frame->ch_mode == FLAC_CHMODE_INDEPENDENT)
@@ -1077,7 +1074,7 @@ static void write_frame_header(FlacEncodeContext *s)
if (frame->ch_mode == FLAC_CHMODE_INDEPENDENT)
put_bits(&s->pb, 4, s->channels-1);
else
- put_bits(&s->pb, 4, frame->ch_mode);
+ put_bits(&s->pb, 4, frame->ch_mode + FLAC_MAX_CHANNELS - 1);
put_bits(&s->pb, 3, 4); /* bits-per-sample code */
put_bits(&s->pb, 1, 0);
@@ -1288,6 +1285,12 @@ static const AVOption options[] = {
{ "8level", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = ORDER_METHOD_8LEVEL }, INT_MIN, INT_MAX, FLAGS, "predm" },
{ "search", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = ORDER_METHOD_SEARCH }, INT_MIN, INT_MAX, FLAGS, "predm" },
{ "log", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = ORDER_METHOD_LOG }, INT_MIN, INT_MAX, FLAGS, "predm" },
+{ "ch_mode", "Stereo decorrelation mode", offsetof(FlacEncodeContext, options.ch_mode), AV_OPT_TYPE_INT, { .dbl = -1 }, -1, FLAC_CHMODE_MID_SIDE, FLAGS, "ch_mode" },
+{ "auto", NULL, 0, AV_OPT_TYPE_CONST, { .dbl = -1 }, INT_MIN, INT_MAX, FLAGS, "ch_mode" },
+{ "indep", NULL, 0, AV_OPT_TYPE_CONST, { .dbl = FLAC_CHMODE_INDEPENDENT }, INT_MIN, INT_MAX, FLAGS, "ch_mode" },
+{ "left_side", NULL, 0, AV_OPT_TYPE_CONST, { .dbl = FLAC_CHMODE_LEFT_SIDE }, INT_MIN, INT_MAX, FLAGS, "ch_mode" },
+{ "right_side", NULL, 0, AV_OPT_TYPE_CONST, { .dbl = FLAC_CHMODE_RIGHT_SIDE }, INT_MIN, INT_MAX, FLAGS, "ch_mode" },
+{ "mid_side", NULL, 0, AV_OPT_TYPE_CONST, { .dbl = FLAC_CHMODE_MID_SIDE }, INT_MIN, INT_MAX, FLAGS, "ch_mode" },
{ NULL },
};
diff --git a/libavcodec/golomb.h b/libavcodec/golomb.h
index 1712540..b6b8cc8 100644
--- a/libavcodec/golomb.h
+++ b/libavcodec/golomb.h
@@ -301,7 +301,7 @@ static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, int
return buf;
}else{
int i;
- for (i = 0; i < limit && SHOW_UBITS(re, gb, 1) == 0; i++) {
+ for (i = 0; i < limit && SHOW_UBITS(re, gb, 1) == 0 && HAVE_BITS_REMAINING(re, gb); i++) {
LAST_SKIP_BITS(re, gb, 1);
UPDATE_CACHE(re, gb);
}
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index cfd9a77..6dba8ce 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -430,6 +430,13 @@ retry:
if (ret < 0){
av_log(s->avctx, AV_LOG_ERROR, "header damaged\n");
return -1;
+ } else if ((s->width != avctx->coded_width ||
+ s->height != avctx->coded_height ||
+ (s->width + 15) >> 4 != s->mb_width ||
+ (s->height + 15) >> 4 != s->mb_height) &&
+ (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))) {
+ av_log_missing_feature(s->avctx, "Width/height/bit depth/chroma idc changing with threads is", 0);
+ return AVERROR_PATCHWELCOME; // width / height changed during parallelized decoding
}
avctx->has_b_frames= !s->low_delay;
@@ -571,11 +578,6 @@ retry:
/* H.263 could change picture size any time */
ParseContext pc= s->parse_context; //FIXME move these demuxng hack to avformat
- if (HAVE_THREADS && (s->avctx->active_thread_type&FF_THREAD_FRAME)) {
- av_log_missing_feature(s->avctx, "Width/height/bit depth/chroma idc changing with threads is", 0);
- return -1; // width / height changed during parallelized decoding
- }
-
s->parse_context.buffer=0;
ff_MPV_common_end(s);
s->parse_context= pc;
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 890dd22..a4afcc8 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -714,33 +714,6 @@ static av_always_inline void mc_part_weighted(H264Context *h, int n, int square,
}
}
-static av_always_inline void mc_part(H264Context *h, int n, int square,
- int height, int delta,
- uint8_t *dest_y, uint8_t *dest_cb,
- uint8_t *dest_cr,
- int x_offset, int y_offset,
- qpel_mc_func *qpix_put,
- h264_chroma_mc_func chroma_put,
- qpel_mc_func *qpix_avg,
- h264_chroma_mc_func chroma_avg,
- h264_weight_func *weight_op,
- h264_biweight_func *weight_avg,
- int list0, int list1,
- int pixel_shift, int chroma_idc)
-{
- if ((h->use_weight == 2 && list0 && list1 &&
- (h->implicit_weight[h->ref_cache[0][scan8[n]]][h->ref_cache[1][scan8[n]]][h->s.mb_y & 1] != 32)) ||
- h->use_weight == 1)
- mc_part_weighted(h, n, square, height, delta, dest_y, dest_cb, dest_cr,
- x_offset, y_offset, qpix_put, chroma_put,
- weight_op[0], weight_op[1], weight_avg[0],
- weight_avg[1], list0, list1, pixel_shift, chroma_idc);
- else
- mc_part_std(h, n, square, height, delta, dest_y, dest_cb, dest_cr,
- x_offset, y_offset, qpix_put, chroma_put, qpix_avg,
- chroma_avg, list0, list1, pixel_shift, chroma_idc);
-}
-
static av_always_inline void prefetch_motion(H264Context *h, int list,
int pixel_shift, int chroma_idc)
{
@@ -768,146 +741,6 @@ static av_always_inline void prefetch_motion(H264Context *h, int list,
}
}
-static av_always_inline void hl_motion(H264Context *h, uint8_t *dest_y,
- uint8_t *dest_cb, uint8_t *dest_cr,
- qpel_mc_func(*qpix_put)[16],
- h264_chroma_mc_func(*chroma_put),
- qpel_mc_func(*qpix_avg)[16],
- h264_chroma_mc_func(*chroma_avg),
- h264_weight_func *weight_op,
- h264_biweight_func *weight_avg,
- int pixel_shift, int chroma_idc)
-{
- MpegEncContext *const s = &h->s;
- const int mb_xy = h->mb_xy;
- const int mb_type = s->current_picture.f.mb_type[mb_xy];
-
- assert(IS_INTER(mb_type));
-
- if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
- await_references(h);
- prefetch_motion(h, 0, pixel_shift, chroma_idc);
-
- if (IS_16X16(mb_type)) {
- mc_part(h, 0, 1, 16, 0, dest_y, dest_cb, dest_cr, 0, 0,
- qpix_put[0], chroma_put[0], qpix_avg[0], chroma_avg[0],
- weight_op, weight_avg,
- IS_DIR(mb_type, 0, 0), IS_DIR(mb_type, 0, 1),
- pixel_shift, chroma_idc);
- } else if (IS_16X8(mb_type)) {
- mc_part(h, 0, 0, 8, 8 << pixel_shift, dest_y, dest_cb, dest_cr, 0, 0,
- qpix_put[1], chroma_put[0], qpix_avg[1], chroma_avg[0],
- weight_op, weight_avg,
- IS_DIR(mb_type, 0, 0), IS_DIR(mb_type, 0, 1),
- pixel_shift, chroma_idc);
- mc_part(h, 8, 0, 8, 8 << pixel_shift, dest_y, dest_cb, dest_cr, 0, 4,
- qpix_put[1], chroma_put[0], qpix_avg[1], chroma_avg[0],
- weight_op, weight_avg,
- IS_DIR(mb_type, 1, 0), IS_DIR(mb_type, 1, 1),
- pixel_shift, chroma_idc);
- } else if (IS_8X16(mb_type)) {
- mc_part(h, 0, 0, 16, 8 * h->mb_linesize, dest_y, dest_cb, dest_cr, 0, 0,
- qpix_put[1], chroma_put[1], qpix_avg[1], chroma_avg[1],
- &weight_op[1], &weight_avg[1],
- IS_DIR(mb_type, 0, 0), IS_DIR(mb_type, 0, 1),
- pixel_shift, chroma_idc);
- mc_part(h, 4, 0, 16, 8 * h->mb_linesize, dest_y, dest_cb, dest_cr, 4, 0,
- qpix_put[1], chroma_put[1], qpix_avg[1], chroma_avg[1],
- &weight_op[1], &weight_avg[1],
- IS_DIR(mb_type, 1, 0), IS_DIR(mb_type, 1, 1),
- pixel_shift, chroma_idc);
- } else {
- int i;
-
- assert(IS_8X8(mb_type));
-
- for (i = 0; i < 4; i++) {
- const int sub_mb_type = h->sub_mb_type[i];
- const int n = 4 * i;
- int x_offset = (i & 1) << 2;
- int y_offset = (i & 2) << 1;
-
- if (IS_SUB_8X8(sub_mb_type)) {
- mc_part(h, n, 1, 8, 0, dest_y, dest_cb, dest_cr,
- x_offset, y_offset,
- qpix_put[1], chroma_put[1], qpix_avg[1], chroma_avg[1],
- &weight_op[1], &weight_avg[1],
- IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1),
- pixel_shift, chroma_idc);
- } else if (IS_SUB_8X4(sub_mb_type)) {
- mc_part(h, n, 0, 4, 4 << pixel_shift, dest_y, dest_cb, dest_cr,
- x_offset, y_offset,
- qpix_put[2], chroma_put[1], qpix_avg[2], chroma_avg[1],
- &weight_op[1], &weight_avg[1],
- IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1),
- pixel_shift, chroma_idc);
- mc_part(h, n + 2, 0, 4, 4 << pixel_shift,
- dest_y, dest_cb, dest_cr, x_offset, y_offset + 2,
- qpix_put[2], chroma_put[1], qpix_avg[2], chroma_avg[1],
- &weight_op[1], &weight_avg[1],
- IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1),
- pixel_shift, chroma_idc);
- } else if (IS_SUB_4X8(sub_mb_type)) {
- mc_part(h, n, 0, 8, 4 * h->mb_linesize,
- dest_y, dest_cb, dest_cr, x_offset, y_offset,
- qpix_put[2], chroma_put[2], qpix_avg[2], chroma_avg[2],
- &weight_op[2], &weight_avg[2],
- IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1),
- pixel_shift, chroma_idc);
- mc_part(h, n + 1, 0, 8, 4 * h->mb_linesize,
- dest_y, dest_cb, dest_cr, x_offset + 2, y_offset,
- qpix_put[2], chroma_put[2], qpix_avg[2], chroma_avg[2],
- &weight_op[2], &weight_avg[2],
- IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1),
- pixel_shift, chroma_idc);
- } else {
- int j;
- assert(IS_SUB_4X4(sub_mb_type));
- for (j = 0; j < 4; j++) {
- int sub_x_offset = x_offset + 2 * (j & 1);
- int sub_y_offset = y_offset + (j & 2);
- mc_part(h, n + j, 1, 4, 0,
- dest_y, dest_cb, dest_cr, sub_x_offset, sub_y_offset,
- qpix_put[2], chroma_put[2], qpix_avg[2], chroma_avg[2],
- &weight_op[2], &weight_avg[2],
- IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1),
- pixel_shift, chroma_idc);
- }
- }
- }
- }
-
- prefetch_motion(h, 1, pixel_shift, chroma_idc);
-}
-
-static av_always_inline void hl_motion_420(H264Context *h, uint8_t *dest_y,
- uint8_t *dest_cb, uint8_t *dest_cr,
- qpel_mc_func(*qpix_put)[16],
- h264_chroma_mc_func(*chroma_put),
- qpel_mc_func(*qpix_avg)[16],
- h264_chroma_mc_func(*chroma_avg),
- h264_weight_func *weight_op,
- h264_biweight_func *weight_avg,
- int pixel_shift)
-{
- hl_motion(h, dest_y, dest_cb, dest_cr, qpix_put, chroma_put,
- qpix_avg, chroma_avg, weight_op, weight_avg, pixel_shift, 1);
-}
-
-static av_always_inline void hl_motion_422(H264Context *h, uint8_t *dest_y,
- uint8_t *dest_cb, uint8_t *dest_cr,
- qpel_mc_func(*qpix_put)[16],
- h264_chroma_mc_func(*chroma_put),
- qpel_mc_func(*qpix_avg)[16],
- h264_chroma_mc_func(*chroma_avg),
- h264_weight_func *weight_op,
- h264_biweight_func *weight_avg,
- int pixel_shift)
-{
- hl_motion(h, dest_y, dest_cb, dest_cr, qpix_put, chroma_put,
- qpix_avg, chroma_avg, weight_op, weight_avg, pixel_shift, 2);
-}
-
static void free_tables(H264Context *h, int free_rbsp)
{
int i;
@@ -1744,7 +1577,7 @@ static av_always_inline void backup_mb_border(H264Context *h, uint8_t *src_y,
}
top_border = h->top_borders[top_idx][s->mb_x];
- /* There are two lines saved, the line above the the top macroblock
+ /* There are two lines saved, the line above the top macroblock
* of a pair, and the line above the bottom macroblock. */
AV_COPY128(top_border, src_y + 16 * linesize);
if (pixel_shift)
@@ -2077,373 +1910,17 @@ static av_always_inline void hl_decode_mb_idct_luma(H264Context *h, int mb_type,
}
}
-static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple,
- int pixel_shift)
-{
- MpegEncContext *const s = &h->s;
- const int mb_x = s->mb_x;
- const int mb_y = s->mb_y;
- const int mb_xy = h->mb_xy;
- const int mb_type = s->current_picture.f.mb_type[mb_xy];
- uint8_t *dest_y, *dest_cb, *dest_cr;
- int linesize, uvlinesize /*dct_offset*/;
- int i, j;
- int *block_offset = &h->block_offset[0];
- const int transform_bypass = !simple && (s->qscale == 0 && h->sps.transform_bypass);
- /* is_h264 should always be true if SVQ3 is disabled. */
- const int is_h264 = !CONFIG_SVQ3_DECODER || simple || s->codec_id == CODEC_ID_H264;
- void (*idct_add)(uint8_t *dst, DCTELEM *block, int stride);
- const int block_h = 16 >> s->chroma_y_shift;
- const int chroma422 = CHROMA422;
-
- dest_y = s->current_picture.f.data[0] + ((mb_x << pixel_shift) + mb_y * s->linesize) * 16;
- dest_cb = s->current_picture.f.data[1] + (mb_x << pixel_shift) * 8 + mb_y * s->uvlinesize * block_h;
- dest_cr = s->current_picture.f.data[2] + (mb_x << pixel_shift) * 8 + mb_y * s->uvlinesize * block_h;
-
- s->dsp.prefetch(dest_y + (s->mb_x & 3) * 4 * s->linesize + (64 << pixel_shift), s->linesize, 4);
- s->dsp.prefetch(dest_cb + (s->mb_x & 7) * s->uvlinesize + (64 << pixel_shift), dest_cr - dest_cb, 2);
-
- h->list_counts[mb_xy] = h->list_count;
-
- if (!simple && MB_FIELD) {
- linesize = h->mb_linesize = s->linesize * 2;
- uvlinesize = h->mb_uvlinesize = s->uvlinesize * 2;
- block_offset = &h->block_offset[48];
- if (mb_y & 1) { // FIXME move out of this function?
- dest_y -= s->linesize * 15;
- dest_cb -= s->uvlinesize * (block_h - 1);
- dest_cr -= s->uvlinesize * (block_h - 1);
- }
- if (FRAME_MBAFF) {
- int list;
- for (list = 0; list < h->list_count; list++) {
- if (!USES_LIST(mb_type, list))
- continue;
- if (IS_16X16(mb_type)) {
- int8_t *ref = &h->ref_cache[list][scan8[0]];
- fill_rectangle(ref, 4, 4, 8, (16 + *ref) ^ (s->mb_y & 1), 1);
- } else {
- for (i = 0; i < 16; i += 4) {
- int ref = h->ref_cache[list][scan8[i]];
- if (ref >= 0)
- fill_rectangle(&h->ref_cache[list][scan8[i]], 2, 2,
- 8, (16 + ref) ^ (s->mb_y & 1), 1);
- }
- }
- }
- }
- } else {
- linesize = h->mb_linesize = s->linesize;
- uvlinesize = h->mb_uvlinesize = s->uvlinesize;
- // dct_offset = s->linesize * 16;
- }
+#define BITS 8
+#define SIMPLE 1
+#include "h264_mb_template.c"
- if (!simple && IS_INTRA_PCM(mb_type)) {
- if (pixel_shift) {
- const int bit_depth = h->sps.bit_depth_luma;
- int j;
- GetBitContext gb;
- init_get_bits(&gb, (uint8_t *)h->mb,
- ff_h264_mb_sizes[h->sps.chroma_format_idc] * bit_depth);
-
- for (i = 0; i < 16; i++) {
- uint16_t *tmp_y = (uint16_t *)(dest_y + i * linesize);
- for (j = 0; j < 16; j++)
- tmp_y[j] = get_bits(&gb, bit_depth);
- }
- if (simple || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
- if (!h->sps.chroma_format_idc) {
- for (i = 0; i < block_h; i++) {
- uint16_t *tmp_cb = (uint16_t *)(dest_cb + i * uvlinesize);
- for (j = 0; j < 8; j++)
- tmp_cb[j] = 1 << (bit_depth - 1);
- }
- for (i = 0; i < block_h; i++) {
- uint16_t *tmp_cr = (uint16_t *)(dest_cr + i * uvlinesize);
- for (j = 0; j < 8; j++)
- tmp_cr[j] = 1 << (bit_depth - 1);
- }
- } else {
- for (i = 0; i < block_h; i++) {
- uint16_t *tmp_cb = (uint16_t *)(dest_cb + i * uvlinesize);
- for (j = 0; j < 8; j++)
- tmp_cb[j] = get_bits(&gb, bit_depth);
- }
- for (i = 0; i < block_h; i++) {
- uint16_t *tmp_cr = (uint16_t *)(dest_cr + i * uvlinesize);
- for (j = 0; j < 8; j++)
- tmp_cr[j] = get_bits(&gb, bit_depth);
- }
- }
- }
- } else {
- for (i = 0; i < 16; i++)
- memcpy(dest_y + i * linesize, (uint8_t *)h->mb + i * 16, 16);
- if (simple || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
- if (!h->sps.chroma_format_idc) {
- for (i = 0; i < block_h; i++) {
- memset(dest_cb + i * uvlinesize, 128, 8);
- memset(dest_cr + i * uvlinesize, 128, 8);
- }
- } else {
- uint8_t *src_cb = (uint8_t *)h->mb + 256;
- uint8_t *src_cr = (uint8_t *)h->mb + 256 + block_h * 8;
- for (i = 0; i < block_h; i++) {
- memcpy(dest_cb + i * uvlinesize, src_cb + i * 8, 8);
- memcpy(dest_cr + i * uvlinesize, src_cr + i * 8, 8);
- }
- }
- }
- }
- } else {
- if (IS_INTRA(mb_type)) {
- if (h->deblocking_filter)
- xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize,
- uvlinesize, 1, 0, simple, pixel_shift);
-
- if (simple || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
- h->hpc.pred8x8[h->chroma_pred_mode](dest_cb, uvlinesize);
- h->hpc.pred8x8[h->chroma_pred_mode](dest_cr, uvlinesize);
- }
-
- hl_decode_mb_predict_luma(h, mb_type, is_h264, simple,
- transform_bypass, pixel_shift,
- block_offset, linesize, dest_y, 0);
-
- if (h->deblocking_filter)
- xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize,
- uvlinesize, 0, 0, simple, pixel_shift);
- } else if (is_h264) {
- if (chroma422) {
- hl_motion_422(h, dest_y, dest_cb, dest_cr,
- s->me.qpel_put, s->dsp.put_h264_chroma_pixels_tab,
- s->me.qpel_avg, s->dsp.avg_h264_chroma_pixels_tab,
- h->h264dsp.weight_h264_pixels_tab,
- h->h264dsp.biweight_h264_pixels_tab,
- pixel_shift);
- } else {
- hl_motion_420(h, dest_y, dest_cb, dest_cr,
- s->me.qpel_put, s->dsp.put_h264_chroma_pixels_tab,
- s->me.qpel_avg, s->dsp.avg_h264_chroma_pixels_tab,
- h->h264dsp.weight_h264_pixels_tab,
- h->h264dsp.biweight_h264_pixels_tab,
- pixel_shift);
- }
- }
-
- hl_decode_mb_idct_luma(h, mb_type, is_h264, simple, transform_bypass,
- pixel_shift, block_offset, linesize, dest_y, 0);
-
- if ((simple || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) &&
- (h->cbp & 0x30)) {
- uint8_t *dest[2] = { dest_cb, dest_cr };
- if (transform_bypass) {
- if (IS_INTRA(mb_type) && h->sps.profile_idc == 244 &&
- (h->chroma_pred_mode == VERT_PRED8x8 ||
- h->chroma_pred_mode == HOR_PRED8x8)) {
- h->hpc.pred8x8_add[h->chroma_pred_mode](dest[0],
- block_offset + 16,
- h->mb + (16 * 16 * 1 << pixel_shift),
- uvlinesize);
- h->hpc.pred8x8_add[h->chroma_pred_mode](dest[1],
- block_offset + 32,
- h->mb + (16 * 16 * 2 << pixel_shift),
- uvlinesize);
- } else {
- idct_add = s->dsp.add_pixels4;
- for (j = 1; j < 3; j++) {
- for (i = j * 16; i < j * 16 + 4; i++)
- if (h->non_zero_count_cache[scan8[i]] ||
- dctcoef_get(h->mb, pixel_shift, i * 16))
- idct_add(dest[j - 1] + block_offset[i],
- h->mb + (i * 16 << pixel_shift),
- uvlinesize);
- if (chroma422) {
- for (i = j * 16 + 4; i < j * 16 + 8; i++)
- if (h->non_zero_count_cache[scan8[i + 4]] ||
- dctcoef_get(h->mb, pixel_shift, i * 16))
- idct_add(dest[j - 1] + block_offset[i + 4],
- h->mb + (i * 16 << pixel_shift),
- uvlinesize);
- }
- }
- }
- } else {
- if (is_h264) {
- int qp[2];
- if (chroma422) {
- qp[0] = h->chroma_qp[0] + 3;
- qp[1] = h->chroma_qp[1] + 3;
- } else {
- qp[0] = h->chroma_qp[0];
- qp[1] = h->chroma_qp[1];
- }
- if (h->non_zero_count_cache[scan8[CHROMA_DC_BLOCK_INDEX + 0]])
- h->h264dsp.h264_chroma_dc_dequant_idct(h->mb + (16 * 16 * 1 << pixel_shift),
- h->dequant4_coeff[IS_INTRA(mb_type) ? 1 : 4][qp[0]][0]);
- if (h->non_zero_count_cache[scan8[CHROMA_DC_BLOCK_INDEX + 1]])
- h->h264dsp.h264_chroma_dc_dequant_idct(h->mb + (16 * 16 * 2 << pixel_shift),
- h->dequant4_coeff[IS_INTRA(mb_type) ? 2 : 5][qp[1]][0]);
- h->h264dsp.h264_idct_add8(dest, block_offset,
- h->mb, uvlinesize,
- h->non_zero_count_cache);
- } else if (CONFIG_SVQ3_DECODER) {
- h->h264dsp.h264_chroma_dc_dequant_idct(h->mb + 16 * 16 * 1,
- h->dequant4_coeff[IS_INTRA(mb_type) ? 1 : 4][h->chroma_qp[0]][0]);
- h->h264dsp.h264_chroma_dc_dequant_idct(h->mb + 16 * 16 * 2,
- h->dequant4_coeff[IS_INTRA(mb_type) ? 2 : 5][h->chroma_qp[1]][0]);
- for (j = 1; j < 3; j++) {
- for (i = j * 16; i < j * 16 + 4; i++)
- if (h->non_zero_count_cache[scan8[i]] || h->mb[i * 16]) {
- uint8_t *const ptr = dest[j - 1] + block_offset[i];
- ff_svq3_add_idct_c(ptr, h->mb + i * 16,
- uvlinesize,
- ff_h264_chroma_qp[0][s->qscale + 12] - 12, 2);
- }
- }
- }
- }
- }
- }
- if (h->cbp || IS_INTRA(mb_type)) {
- s->dsp.clear_blocks(h->mb);
- s->dsp.clear_blocks(h->mb + (24 * 16 << pixel_shift));
- }
-}
+#undef BITS
+#define BITS 16
+#include "h264_mb_template.c"
-static av_always_inline void hl_decode_mb_444_internal(H264Context *h,
- int simple,
- int pixel_shift)
-{
- MpegEncContext *const s = &h->s;
- const int mb_x = s->mb_x;
- const int mb_y = s->mb_y;
- const int mb_xy = h->mb_xy;
- const int mb_type = s->current_picture.f.mb_type[mb_xy];
- uint8_t *dest[3];
- int linesize;
- int i, j, p;
- int *block_offset = &h->block_offset[0];
- const int transform_bypass = !simple && (s->qscale == 0 && h->sps.transform_bypass);
- const int plane_count = (simple || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) ? 3 : 1;
-
- for (p = 0; p < plane_count; p++) {
- dest[p] = s->current_picture.f.data[p] +
- ((mb_x << pixel_shift) + mb_y * s->linesize) * 16;
- s->dsp.prefetch(dest[p] + (s->mb_x & 3) * 4 * s->linesize + (64 << pixel_shift),
- s->linesize, 4);
- }
-
- h->list_counts[mb_xy] = h->list_count;
-
- if (!simple && MB_FIELD) {
- linesize = h->mb_linesize = h->mb_uvlinesize = s->linesize * 2;
- block_offset = &h->block_offset[48];
- if (mb_y & 1) // FIXME move out of this function?
- for (p = 0; p < 3; p++)
- dest[p] -= s->linesize * 15;
- if (FRAME_MBAFF) {
- int list;
- for (list = 0; list < h->list_count; list++) {
- if (!USES_LIST(mb_type, list))
- continue;
- if (IS_16X16(mb_type)) {
- int8_t *ref = &h->ref_cache[list][scan8[0]];
- fill_rectangle(ref, 4, 4, 8, (16 + *ref) ^ (s->mb_y & 1), 1);
- } else {
- for (i = 0; i < 16; i += 4) {
- int ref = h->ref_cache[list][scan8[i]];
- if (ref >= 0)
- fill_rectangle(&h->ref_cache[list][scan8[i]], 2, 2,
- 8, (16 + ref) ^ (s->mb_y & 1), 1);
- }
- }
- }
- }
- } else {
- linesize = h->mb_linesize = h->mb_uvlinesize = s->linesize;
- }
-
- if (!simple && IS_INTRA_PCM(mb_type)) {
- if (pixel_shift) {
- const int bit_depth = h->sps.bit_depth_luma;
- GetBitContext gb;
- init_get_bits(&gb, (uint8_t *)h->mb, 768 * bit_depth);
-
- for (p = 0; p < plane_count; p++)
- for (i = 0; i < 16; i++) {
- uint16_t *tmp = (uint16_t *)(dest[p] + i * linesize);
- for (j = 0; j < 16; j++)
- tmp[j] = get_bits(&gb, bit_depth);
- }
- } else {
- for (p = 0; p < plane_count; p++)
- for (i = 0; i < 16; i++)
- memcpy(dest[p] + i * linesize,
- (uint8_t *)h->mb + p * 256 + i * 16, 16);
- }
- } else {
- if (IS_INTRA(mb_type)) {
- if (h->deblocking_filter)
- xchg_mb_border(h, dest[0], dest[1], dest[2], linesize,
- linesize, 1, 1, simple, pixel_shift);
-
- for (p = 0; p < plane_count; p++)
- hl_decode_mb_predict_luma(h, mb_type, 1, simple,
- transform_bypass, pixel_shift,
- block_offset, linesize, dest[p], p);
-
- if (h->deblocking_filter)
- xchg_mb_border(h, dest[0], dest[1], dest[2], linesize,
- linesize, 0, 1, simple, pixel_shift);
- } else {
- hl_motion(h, dest[0], dest[1], dest[2],
- s->me.qpel_put, s->dsp.put_h264_chroma_pixels_tab,
- s->me.qpel_avg, s->dsp.avg_h264_chroma_pixels_tab,
- h->h264dsp.weight_h264_pixels_tab,
- h->h264dsp.biweight_h264_pixels_tab, pixel_shift, 3);
- }
-
- for (p = 0; p < plane_count; p++)
- hl_decode_mb_idct_luma(h, mb_type, 1, simple, transform_bypass,
- pixel_shift, block_offset, linesize,
- dest[p], p);
- }
- if (h->cbp || IS_INTRA(mb_type)) {
- s->dsp.clear_blocks(h->mb);
- s->dsp.clear_blocks(h->mb + (24 * 16 << pixel_shift));
- }
-}
-
-/**
- * Process a macroblock; this case avoids checks for expensive uncommon cases.
- */
-#define hl_decode_mb_simple(sh, bits) \
-static void hl_decode_mb_simple_ ## bits(H264Context *h) \
-{ \
- hl_decode_mb_internal(h, 1, sh); \
-}
-
-hl_decode_mb_simple(0, 8)
-hl_decode_mb_simple(1, 16)
-
-/**
- * Process a macroblock; this handles edge cases, such as interlacing.
- */
-static av_noinline void hl_decode_mb_complex(H264Context *h)
-{
- hl_decode_mb_internal(h, 0, h->pixel_shift);
-}
-
-static av_noinline void hl_decode_mb_444_complex(H264Context *h)
-{
- hl_decode_mb_444_internal(h, 0, h->pixel_shift);
-}
-
-static av_noinline void hl_decode_mb_444_simple(H264Context *h)
-{
- hl_decode_mb_444_internal(h, 1, 0);
-}
+#undef SIMPLE
+#define SIMPLE 0
+#include "h264_mb_template.c"
void ff_h264_hl_decode_mb(H264Context *h)
{
@@ -2456,7 +1933,7 @@ void ff_h264_hl_decode_mb(H264Context *h)
if (is_complex || h->pixel_shift)
hl_decode_mb_444_complex(h);
else
- hl_decode_mb_444_simple(h);
+ hl_decode_mb_444_simple_8(h);
} else if (is_complex) {
hl_decode_mb_complex(h);
} else if (h->pixel_shift) {
@@ -2968,13 +2445,19 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
else
s->height = 16 * s->mb_height - (2 << s->chroma_y_shift) * FFMIN(h->sps.crop_bottom, (16 >> s->chroma_y_shift) - 1);
+ if (FFALIGN(s->avctx->width, 16) == s->width &&
+ FFALIGN(s->avctx->height, 16) == s->height) {
+ s->width = s->avctx->width;
+ s->height = s->avctx->height;
+ }
+
if (s->context_initialized &&
(s->width != s->avctx->width || s->height != s->avctx->height ||
av_cmp_q(h->sps.sar, s->avctx->sample_aspect_ratio))) {
- if (h != h0) {
+ if (h != h0 || (HAVE_THREADS && h->s.avctx->active_thread_type & FF_THREAD_FRAME)) {
av_log_missing_feature(s->avctx,
"Width/height changing with threads is", 0);
- return -1; // width / height changed during parallelized decoding
+ return AVERROR_PATCHWELCOME; // width / height changed during parallelized decoding
}
free_tables(h, 0);
flush_dpb(s->avctx);
@@ -4369,7 +3852,7 @@ again:
if (ff_h264_decode_seq_parameter_set(h) < 0 &&
h->is_avc && (nalsize != consumed) && nalsize) {
av_log(h->s.avctx, AV_LOG_DEBUG,
- "SPS decoding failure, try parsing the coomplete NAL\n");
+ "SPS decoding failure, trying again with the complete NAL\n");
init_get_bits(&s->gb, buf + buf_index + 1 - consumed,
8 * (nalsize - 1));
ff_h264_decode_seq_parameter_set(h);
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index ce06f61..570ce2f 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -37,14 +37,14 @@
#include "rectangle.h"
#define interlaced_dct interlaced_dct_is_a_bad_name
-#define mb_intra mb_intra_is_not_initialized_see_mb_type
+#define mb_intra mb_intra_is_not_initialized_see_mb_type
-#define MAX_SPS_COUNT 32
-#define MAX_PPS_COUNT 256
+#define MAX_SPS_COUNT 32
+#define MAX_PPS_COUNT 256
-#define MAX_MMCO_COUNT 66
+#define MAX_MMCO_COUNT 66
-#define MAX_DELAYED_PIC_COUNT 16
+#define MAX_DELAYED_PIC_COUNT 16
/* Compiling in interlaced support reduces the speed
* of progressive decoding by about 2%. */
@@ -59,25 +59,25 @@
#define MAX_SLICES 16
#ifdef ALLOW_INTERLACE
-#define MB_MBAFF h->mb_mbaff
-#define MB_FIELD h->mb_field_decoding_flag
+#define MB_MBAFF h->mb_mbaff
+#define MB_FIELD h->mb_field_decoding_flag
#define FRAME_MBAFF h->mb_aff_frame
#define FIELD_PICTURE (s->picture_structure != PICT_FRAME)
#define LEFT_MBS 2
-#define LTOP 0
-#define LBOT 1
-#define LEFT(i) (i)
+#define LTOP 0
+#define LBOT 1
+#define LEFT(i) (i)
#else
-#define MB_MBAFF 0
-#define MB_FIELD 0
-#define FRAME_MBAFF 0
+#define MB_MBAFF 0
+#define MB_FIELD 0
+#define FRAME_MBAFF 0
#define FIELD_PICTURE 0
#undef IS_INTERLACED
#define IS_INTERLACED(mb_type) 0
#define LEFT_MBS 1
-#define LTOP 0
-#define LBOT 0
-#define LEFT(i) 0
+#define LTOP 0
+#define LBOT 0
+#define LEFT(i) 0
#endif
#define FIELD_OR_MBAFF_PICTURE (FRAME_MBAFF || FIELD_PICTURE)
@@ -88,9 +88,9 @@
#define CHROMA422 (h->sps.chroma_format_idc == 2)
#define CHROMA444 (h->sps.chroma_format_idc == 3)
-#define EXTENDED_SAR 255
+#define EXTENDED_SAR 255
-#define MB_TYPE_REF0 MB_TYPE_ACPRED //dirty but it fits in 16 bit
+#define MB_TYPE_REF0 MB_TYPE_ACPRED // dirty but it fits in 16 bit
#define MB_TYPE_8x8DCT 0x01000000
#define IS_REF0(a) ((a) & MB_TYPE_REF0)
#define IS_8x8DCT(a) ((a) & MB_TYPE_8x8DCT)
@@ -101,11 +101,11 @@
*/
#define DELAYED_PIC_REF 4
-#define QP_MAX_NUM (51 + 2*6) // The maximum supported qp
+#define QP_MAX_NUM (51 + 2 * 6) // The maximum supported qp
/* NAL unit types */
enum {
- NAL_SLICE=1,
+ NAL_SLICE = 1,
NAL_DPA,
NAL_DPB,
NAL_DPC,
@@ -118,17 +118,17 @@ enum {
NAL_END_STREAM,
NAL_FILLER_DATA,
NAL_SPS_EXT,
- NAL_AUXILIARY_SLICE=19
+ NAL_AUXILIARY_SLICE = 19
};
/**
* SEI message types
*/
typedef enum {
- SEI_BUFFERING_PERIOD = 0, ///< buffering period (H.264, D.1.1)
- SEI_TYPE_PIC_TIMING = 1, ///< picture timing
- SEI_TYPE_USER_DATA_UNREGISTERED = 5, ///< unregistered user data
- SEI_TYPE_RECOVERY_POINT = 6 ///< recovery point (frame # to decoder sync)
+ SEI_BUFFERING_PERIOD = 0, ///< buffering period (H.264, D.1.1)
+ SEI_TYPE_PIC_TIMING = 1, ///< picture timing
+ SEI_TYPE_USER_DATA_UNREGISTERED = 5, ///< unregistered user data
+ SEI_TYPE_RECOVERY_POINT = 6 ///< recovery point (frame # to decoder sync)
} SEI_Type;
/**
@@ -149,8 +149,7 @@ typedef enum {
/**
* Sequence parameter set
*/
-typedef struct SPS{
-
+typedef struct SPS {
int profile_idc;
int level_idc;
int chroma_format_idc;
@@ -167,9 +166,9 @@ typedef struct SPS{
int mb_width; ///< pic_width_in_mbs_minus1 + 1
int mb_height; ///< pic_height_in_map_units_minus1 + 1
int frame_mbs_only_flag;
- int mb_aff; ///<mb_adaptive_frame_field_flag
+ int mb_aff; ///< mb_adaptive_frame_field_flag
int direct_8x8_inference_flag;
- int crop; ///< frame_cropping_flag
+ int crop; ///< frame_cropping_flag
unsigned int crop_left; ///< frame_cropping_rect_left_offset
unsigned int crop_right; ///< frame_cropping_rect_right_offset
unsigned int crop_top; ///< frame_cropping_rect_top_offset
@@ -186,7 +185,7 @@ typedef struct SPS{
uint32_t num_units_in_tick;
uint32_t time_scale;
int fixed_frame_rate_flag;
- short offset_for_ref_frame[256]; //FIXME dyn aloc?
+ short offset_for_ref_frame[256]; // FIXME dyn aloc?
int bitstream_restriction_flag;
int num_reorder_frames;
int scaling_matrix_present;
@@ -196,20 +195,20 @@ typedef struct SPS{
int vcl_hrd_parameters_present_flag;
int pic_struct_present_flag;
int time_offset_length;
- int cpb_cnt; ///< See H.264 E.1.2
- int initial_cpb_removal_delay_length; ///< initial_cpb_removal_delay_length_minus1 +1
- int cpb_removal_delay_length; ///< cpb_removal_delay_length_minus1 + 1
- int dpb_output_delay_length; ///< dpb_output_delay_length_minus1 + 1
- int bit_depth_luma; ///< bit_depth_luma_minus8 + 8
- int bit_depth_chroma; ///< bit_depth_chroma_minus8 + 8
- int residual_color_transform_flag; ///< residual_colour_transform_flag
- int constraint_set_flags; ///< constraint_set[0-3]_flag
-}SPS;
+ int cpb_cnt; ///< See H.264 E.1.2
+ int initial_cpb_removal_delay_length; ///< initial_cpb_removal_delay_length_minus1 + 1
+ int cpb_removal_delay_length; ///< cpb_removal_delay_length_minus1 + 1
+ int dpb_output_delay_length; ///< dpb_output_delay_length_minus1 + 1
+ int bit_depth_luma; ///< bit_depth_luma_minus8 + 8
+ int bit_depth_chroma; ///< bit_depth_chroma_minus8 + 8
+ int residual_color_transform_flag; ///< residual_colour_transform_flag
+ int constraint_set_flags; ///< constraint_set[0-3]_flag
+} SPS;
/**
* Picture parameter set
*/
-typedef struct PPS{
+typedef struct PPS {
unsigned int sps_id;
int cabac; ///< entropy_coding_mode_flag
int pic_order_present; ///< pic_order_present_flag
@@ -222,20 +221,20 @@ typedef struct PPS{
int init_qs; ///< pic_init_qs_minus26 + 26
int chroma_qp_index_offset[2];
int deblocking_filter_parameters_present; ///< deblocking_filter_parameters_present_flag
- int constrained_intra_pred; ///< constrained_intra_pred_flag
- int redundant_pic_cnt_present; ///< redundant_pic_cnt_present_flag
- int transform_8x8_mode; ///< transform_8x8_mode_flag
+ int constrained_intra_pred; ///< constrained_intra_pred_flag
+ int redundant_pic_cnt_present; ///< redundant_pic_cnt_present_flag
+ int transform_8x8_mode; ///< transform_8x8_mode_flag
uint8_t scaling_matrix4[6][16];
uint8_t scaling_matrix8[6][64];
- uint8_t chroma_qp_table[2][64]; ///< pre-scaled (with chroma_qp_index_offset) version of qp_table
+ uint8_t chroma_qp_table[2][64]; ///< pre-scaled (with chroma_qp_index_offset) version of qp_table
int chroma_qp_diff;
-}PPS;
+} PPS;
/**
* Memory management control operation opcode.
*/
-typedef enum MMCOOpcode{
- MMCO_END=0,
+typedef enum MMCOOpcode {
+ MMCO_END = 0,
MMCO_SHORT2UNUSED,
MMCO_LONG2UNUSED,
MMCO_SHORT2LONG,
@@ -247,7 +246,7 @@ typedef enum MMCOOpcode{
/**
* Memory management control operation.
*/
-typedef struct MMCO{
+typedef struct MMCO {
MMCOOpcode opcode;
int short_pic_num; ///< pic_num without wrapping (pic_num & max_pic_num)
int long_arg; ///< index, pic_num, or num long refs depending on opcode
@@ -256,18 +255,18 @@ typedef struct MMCO{
/**
* H264Context
*/
-typedef struct H264Context{
+typedef struct H264Context {
MpegEncContext s;
H264DSPContext h264dsp;
int pixel_shift; ///< 0 for 8-bit H264, 1 for high-bit-depth H264
- int chroma_qp[2]; //QPc
+ int chroma_qp[2]; // QPc
int qp_thresh; ///< QP threshold to skip loopfilter
int prev_mb_skipped;
int next_mb_skipped;
- //prediction stuff
+ // prediction stuff
int chroma_pred_mode;
int intra16x16_pred_mode;
@@ -281,32 +280,32 @@ typedef struct H264Context{
int topright_type;
int left_type[LEFT_MBS];
- const uint8_t * left_block;
+ const uint8_t *left_block;
int topleft_partition;
- int8_t intra4x4_pred_mode_cache[5*8];
- int8_t (*intra4x4_pred_mode);
+ int8_t intra4x4_pred_mode_cache[5 * 8];
+ int8_t(*intra4x4_pred_mode);
H264PredContext hpc;
unsigned int topleft_samples_available;
unsigned int top_samples_available;
unsigned int topright_samples_available;
unsigned int left_samples_available;
- uint8_t (*top_borders[2])[(16*3)*2];
+ uint8_t (*top_borders[2])[(16 * 3) * 2];
/**
* non zero coeff count cache.
* is 64 if not available.
*/
- DECLARE_ALIGNED(8, uint8_t, non_zero_count_cache)[15*8];
+ DECLARE_ALIGNED(8, uint8_t, non_zero_count_cache)[15 * 8];
uint8_t (*non_zero_count)[48];
/**
* Motion vector cache.
*/
- DECLARE_ALIGNED(16, int16_t, mv_cache)[2][5*8][2];
- DECLARE_ALIGNED(8, int8_t, ref_cache)[2][5*8];
-#define LIST_NOT_USED -1 //FIXME rename?
+ DECLARE_ALIGNED(16, int16_t, mv_cache)[2][5 * 8][2];
+ DECLARE_ALIGNED(8, int8_t, ref_cache)[2][5 * 8];
+#define LIST_NOT_USED -1 // FIXME rename?
#define PART_NOT_AVAILABLE -2
/**
@@ -318,13 +317,13 @@ typedef struct H264Context{
* block_offset[ 0..23] for frame macroblocks
* block_offset[24..47] for field macroblocks
*/
- int block_offset[2*(16*3)];
+ int block_offset[2 * (16 * 3)];
- uint32_t *mb2b_xy; //FIXME are these 4 a good idea?
+ uint32_t *mb2b_xy; // FIXME are these 4 a good idea?
uint32_t *mb2br_xy;
- int b_stride; //FIXME use s->b4_stride
+ int b_stride; // FIXME use s->b4_stride
- int mb_linesize; ///< may be equal to s->linesize or s->linesize*2, for mbaff
+ int mb_linesize; ///< may be equal to s->linesize or s->linesize * 2, for mbaff
int mb_uvlinesize;
int emu_edge_width;
@@ -335,32 +334,32 @@ typedef struct H264Context{
/**
* current pps
*/
- PPS pps; //FIXME move to Picture perhaps? (->no) do we need that?
+ PPS pps; // FIXME move to Picture perhaps? (->no) do we need that?
- uint32_t dequant4_buffer[6][QP_MAX_NUM+1][16]; //FIXME should these be moved down?
- uint32_t dequant8_buffer[6][QP_MAX_NUM+1][64];
- uint32_t (*dequant4_coeff[6])[16];
- uint32_t (*dequant8_coeff[6])[64];
+ uint32_t dequant4_buffer[6][QP_MAX_NUM + 1][16]; // FIXME should these be moved down?
+ uint32_t dequant8_buffer[6][QP_MAX_NUM + 1][64];
+ uint32_t(*dequant4_coeff[6])[16];
+ uint32_t(*dequant8_coeff[6])[64];
int slice_num;
- uint16_t *slice_table; ///< slice_table_base + 2*mb_stride + 1
+ uint16_t *slice_table; ///< slice_table_base + 2*mb_stride + 1
int slice_type;
- int slice_type_nos; ///< S free slice type (SI/SP are remapped to I/P)
+ int slice_type_nos; ///< S free slice type (SI/SP are remapped to I/P)
int slice_type_fixed;
- //interlacing specific flags
+ // interlacing specific flags
int mb_aff_frame;
int mb_field_decoding_flag;
- int mb_mbaff; ///< mb_aff_frame && mb_field_decoding_flag
+ int mb_mbaff; ///< mb_aff_frame && mb_field_decoding_flag
DECLARE_ALIGNED(8, uint16_t, sub_mb_type)[4];
- //Weighted pred stuff
+ // Weighted pred stuff
int use_weight;
int use_weight_chroma;
int luma_log2_weight_denom;
int chroma_log2_weight_denom;
- //The following 2 can be changed to int8_t but that causes 10cpu cycles speedloss
+ // The following 2 can be changed to int8_t but that causes 10cpu cycles speedloss
int luma_weight[48][2][2];
int chroma_weight[48][2][2][2];
int implicit_weight[48][48][2];
@@ -370,48 +369,48 @@ typedef struct H264Context{
int col_fieldoff;
int dist_scale_factor[16];
int dist_scale_factor_field[2][32];
- int map_col_to_list0[2][16+32];
- int map_col_to_list0_field[2][2][16+32];
+ int map_col_to_list0[2][16 + 32];
+ int map_col_to_list0_field[2][2][16 + 32];
/**
* num_ref_idx_l0/1_active_minus1 + 1
*/
- unsigned int ref_count[2]; ///< counts frames or fields, depending on current mb mode
+ unsigned int ref_count[2]; ///< counts frames or fields, depending on current mb mode
unsigned int list_count;
- uint8_t *list_counts; ///< Array of list_count per MB specifying the slice type
- Picture ref_list[2][48]; /**< 0..15: frame refs, 16..47: mbaff field refs.
- Reordered version of default_ref_list
- according to picture reordering in slice header */
- int ref2frm[MAX_SLICES][2][64]; ///< reference to frame number lists, used in the loop filter, the first 2 are for -2,-1
+ uint8_t *list_counts; ///< Array of list_count per MB specifying the slice type
+ Picture ref_list[2][48]; /**< 0..15: frame refs, 16..47: mbaff field refs.
+ * Reordered version of default_ref_list
+ * according to picture reordering in slice header */
+ int ref2frm[MAX_SLICES][2][64]; ///< reference to frame number lists, used in the loop filter, the first 2 are for -2,-1
- //data partitioning
+ // data partitioning
GetBitContext intra_gb;
GetBitContext inter_gb;
GetBitContext *intra_gb_ptr;
GetBitContext *inter_gb_ptr;
- DECLARE_ALIGNED(16, DCTELEM, mb)[16*48*2]; ///< as a dct coeffecient is int32_t in high depth, we need to reserve twice the space.
- DECLARE_ALIGNED(16, DCTELEM, mb_luma_dc)[3][16*2];
- DCTELEM mb_padding[256*2]; ///< as mb is addressed by scantable[i] and scantable is uint8_t we can either check that i is not too large or ensure that there is some unused stuff after mb
+ DECLARE_ALIGNED(16, DCTELEM, mb)[16 * 48 * 2]; ///< as a dct coeffecient is int32_t in high depth, we need to reserve twice the space.
+ DECLARE_ALIGNED(16, DCTELEM, mb_luma_dc)[3][16 * 2];
+ DCTELEM mb_padding[256 * 2]; ///< as mb is addressed by scantable[i] and scantable is uint8_t we can either check that i is not too large or ensure that there is some unused stuff after mb
/**
* Cabac
*/
CABACContext cabac;
- uint8_t cabac_state[1024];
+ uint8_t cabac_state[1024];
- /* 0x100 -> non null luma_dc, 0x80/0x40 -> non null chroma_dc (cb/cr), 0x?0 -> chroma_cbp(0,1,2), 0x0? luma_cbp */
- uint16_t *cbp_table;
+ /* 0x100 -> non null luma_dc, 0x80/0x40 -> non null chroma_dc (cb/cr), 0x?0 -> chroma_cbp(0, 1, 2), 0x0? luma_cbp */
+ uint16_t *cbp_table;
int cbp;
int top_cbp;
int left_cbp;
/* chroma_pred_mode for i4x4 or i16x16, else 0 */
- uint8_t *chroma_pred_mode_table;
- int last_qscale_diff;
- uint8_t (*mvd_table[2])[2];
- DECLARE_ALIGNED(16, uint8_t, mvd_cache)[2][5*8][2];
- uint8_t *direct_table;
- uint8_t direct_cache[5*8];
+ uint8_t *chroma_pred_mode_table;
+ int last_qscale_diff;
+ uint8_t (*mvd_table[2])[2];
+ DECLARE_ALIGNED(16, uint8_t, mvd_cache)[2][5 * 8][2];
+ uint8_t *direct_table;
+ uint8_t direct_cache[5 * 8];
uint8_t zigzag_scan[16];
uint8_t zigzag_scan8x8[64];
@@ -432,13 +431,13 @@ typedef struct H264Context{
int is_complex;
- //deblock
- int deblocking_filter; ///< disable_deblocking_filter_idc with 1<->0
+ // deblock
+ int deblocking_filter; ///< disable_deblocking_filter_idc with 1 <-> 0
int slice_alpha_c0_offset;
int slice_beta_offset;
-//=============================================================
- //Things below are not used in the MB or more inner code
+ // =============================================================
+ // Things below are not used in the MB or more inner code
int nal_ref_idc;
int nal_unit_type;
@@ -448,37 +447,36 @@ typedef struct H264Context{
/**
* Used to parse AVC variant of h264
*/
- int is_avc; ///< this flag is != 0 if codec is avc1
- int nal_length_size; ///< Number of bytes used for nal length (1, 2 or 4)
- int got_first; ///< this flag is != 0 if we've parsed a frame
+ int is_avc; ///< this flag is != 0 if codec is avc1
+ int nal_length_size; ///< Number of bytes used for nal length (1, 2 or 4)
+ int got_first; ///< this flag is != 0 if we've parsed a frame
SPS *sps_buffers[MAX_SPS_COUNT];
PPS *pps_buffers[MAX_PPS_COUNT];
- int dequant_coeff_pps; ///< reinit tables when pps changes
+ int dequant_coeff_pps; ///< reinit tables when pps changes
uint16_t *slice_table_base;
-
- //POC stuff
+ // POC stuff
int poc_lsb;
int poc_msb;
int delta_poc_bottom;
int delta_poc[2];
int frame_num;
- int prev_poc_msb; ///< poc_msb of the last reference pic for POC type 0
- int prev_poc_lsb; ///< poc_lsb of the last reference pic for POC type 0
- int frame_num_offset; ///< for POC type 2
- int prev_frame_num_offset; ///< for POC type 2
- int prev_frame_num; ///< frame_num of the last pic for POC type 1/2
+ int prev_poc_msb; ///< poc_msb of the last reference pic for POC type 0
+ int prev_poc_lsb; ///< poc_lsb of the last reference pic for POC type 0
+ int frame_num_offset; ///< for POC type 2
+ int prev_frame_num_offset; ///< for POC type 2
+ int prev_frame_num; ///< frame_num of the last pic for POC type 1/2
/**
- * frame_num for frames or 2*frame_num+1 for field pics.
+ * frame_num for frames or 2 * frame_num + 1 for field pics.
*/
int curr_pic_num;
/**
- * max_frame_num or 2*max_frame_num for field pics.
+ * max_frame_num or 2 * max_frame_num for field pics.
*/
int max_pic_num;
@@ -487,7 +485,7 @@ typedef struct H264Context{
Picture *short_ref[32];
Picture *long_ref[32];
Picture default_ref_list[2][32]; ///< base reference list for all slices of a coded picture
- Picture *delayed_pic[MAX_DELAYED_PIC_COUNT+2]; //FIXME size?
+ Picture *delayed_pic[MAX_DELAYED_PIC_COUNT + 2]; // FIXME size?
int last_pocs[MAX_DELAYED_PIC_COUNT];
Picture *next_output_pic;
int outputed_poc;
@@ -500,10 +498,10 @@ typedef struct H264Context{
int mmco_index;
int mmco_reset;
- int long_ref_count; ///< number of actual long term references
- int short_ref_count; ///< number of actual short term references
+ int long_ref_count; ///< number of actual long term references
+ int short_ref_count; ///< number of actual short term references
- int cabac_init_idc;
+ int cabac_init_idc;
/**
* @name Members for slice based multithreading
@@ -572,18 +570,17 @@ typedef struct H264Context{
*/
int sei_recovery_frame_cnt;
- int luma_weight_flag[2]; ///< 7.4.3.2 luma_weight_lX_flag
- int chroma_weight_flag[2]; ///< 7.4.3.2 chroma_weight_lX_flag
+ int luma_weight_flag[2]; ///< 7.4.3.2 luma_weight_lX_flag
+ int chroma_weight_flag[2]; ///< 7.4.3.2 chroma_weight_lX_flag
// Timestamp stuff
- int sei_buffering_period_present; ///< Buffering period SEI flag
- int initial_cpb_removal_delay[32]; ///< Initial timestamps for CPBs
+ int sei_buffering_period_present; ///< Buffering period SEI flag
+ int initial_cpb_removal_delay[32]; ///< Initial timestamps for CPBs
int cur_chroma_format_idc;
-}H264Context;
+} H264Context;
-
-extern const uint8_t ff_h264_chroma_qp[3][QP_MAX_NUM+1]; ///< One chroma qp table for each supported bit depth (8, 9, 10).
+extern const uint8_t ff_h264_chroma_qp[3][QP_MAX_NUM + 1]; ///< One chroma qp table for each supported bit depth (8, 9, 10).
extern const uint16_t ff_h264_mb_sizes[4];
/**
@@ -610,13 +607,16 @@ int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length);
* Decode a network abstraction layer unit.
* @param consumed is the number of bytes used as input
* @param length is the length of the array
- * @param dst_length is the number of decoded bytes FIXME here or a decode rbsp tailing?
+ * @param dst_length is the number of decoded bytes FIXME here
+ * or a decode rbsp tailing?
* @return decoded bytes, might be src+1 if no escapes
*/
-const uint8_t *ff_h264_decode_nal(H264Context *h, const uint8_t *src, int *dst_length, int *consumed, int length);
+const uint8_t *ff_h264_decode_nal(H264Context *h, const uint8_t *src,
+ int *dst_length, int *consumed, int length);
/**
- * Free any data that may have been allocated in the H264 context like SPS, PPS etc.
+ * Free any data that may have been allocated in the H264 context
+ * like SPS, PPS etc.
*/
av_cold void ff_h264_free_context(H264Context *h);
@@ -649,14 +649,15 @@ int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb);
void ff_generate_sliding_window_mmcos(H264Context *h);
-
/**
- * Check if the top & left blocks are available if needed & change the dc mode so it only uses the available blocks.
+ * Check if the top & left blocks are available if needed & change the
+ * dc mode so it only uses the available blocks.
*/
int ff_h264_check_intra4x4_pred_mode(H264Context *h);
/**
- * Check if the top & left blocks are available if needed & change the dc mode so it only uses the available blocks.
+ * Check if the top & left blocks are available if needed & change the
+ * dc mode so it only uses the available blocks.
*/
int ff_h264_check_intra_pred_mode(H264Context *h, int mode, int is_chroma);
@@ -668,24 +669,28 @@ av_cold void ff_h264_decode_init_vlc(void);
/**
* Decode a macroblock
- * @return 0 if OK, ER_AC_ERROR / ER_DC_ERROR / ER_MV_ERROR if an error is noticed
+ * @return 0 if OK, ER_AC_ERROR / ER_DC_ERROR / ER_MV_ERROR on error
*/
int ff_h264_decode_mb_cavlc(H264Context *h);
/**
* Decode a CABAC coded macroblock
- * @return 0 if OK, ER_AC_ERROR / ER_DC_ERROR / ER_MV_ERROR if an error is noticed
+ * @return 0 if OK, ER_AC_ERROR / ER_DC_ERROR / ER_MV_ERROR on error
*/
int ff_h264_decode_mb_cabac(H264Context *h);
void ff_h264_init_cabac_states(H264Context *h);
-void ff_h264_direct_dist_scale_factor(H264Context * const h);
-void ff_h264_direct_ref_list_init(H264Context * const h);
-void ff_h264_pred_direct_motion(H264Context * const h, int *mb_type);
+void ff_h264_direct_dist_scale_factor(H264Context *const h);
+void ff_h264_direct_ref_list_init(H264Context *const h);
+void ff_h264_pred_direct_motion(H264Context *const h, int *mb_type);
-void ff_h264_filter_mb_fast( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize);
-void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize);
+void ff_h264_filter_mb_fast(H264Context *h, int mb_x, int mb_y,
+ uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr,
+ unsigned int linesize, unsigned int uvlinesize);
+void ff_h264_filter_mb(H264Context *h, int mb_x, int mb_y,
+ uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr,
+ unsigned int linesize, unsigned int uvlinesize);
/**
* Reset SEI values at the beginning of the frame.
@@ -694,16 +699,15 @@ void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint
*/
void ff_h264_reset_sei(H264Context *h);
-
/*
-o-o o-o
- / / /
-o-o o-o
- ,---'
-o-o o-o
- / / /
-o-o o-o
-*/
+ * o-o o-o
+ * / / /
+ * o-o o-o
+ * ,---'
+ * o-o o-o
+ * / / /
+ * o-o o-o
+ */
/* Scan8 organization:
* 0 1 2 3 4 5 6 7
@@ -728,156 +732,173 @@ o-o o-o
#define LUMA_DC_BLOCK_INDEX 48
#define CHROMA_DC_BLOCK_INDEX 49
-//This table must be here because scan8[constant] must be known at compiletime
-static const uint8_t scan8[16*3 + 3]={
- 4+ 1*8, 5+ 1*8, 4+ 2*8, 5+ 2*8,
- 6+ 1*8, 7+ 1*8, 6+ 2*8, 7+ 2*8,
- 4+ 3*8, 5+ 3*8, 4+ 4*8, 5+ 4*8,
- 6+ 3*8, 7+ 3*8, 6+ 4*8, 7+ 4*8,
- 4+ 6*8, 5+ 6*8, 4+ 7*8, 5+ 7*8,
- 6+ 6*8, 7+ 6*8, 6+ 7*8, 7+ 7*8,
- 4+ 8*8, 5+ 8*8, 4+ 9*8, 5+ 9*8,
- 6+ 8*8, 7+ 8*8, 6+ 9*8, 7+ 9*8,
- 4+11*8, 5+11*8, 4+12*8, 5+12*8,
- 6+11*8, 7+11*8, 6+12*8, 7+12*8,
- 4+13*8, 5+13*8, 4+14*8, 5+14*8,
- 6+13*8, 7+13*8, 6+14*8, 7+14*8,
- 0+ 0*8, 0+ 5*8, 0+10*8
+// This table must be here because scan8[constant] must be known at compiletime
+static const uint8_t scan8[16 * 3 + 3] = {
+ 4 + 1 * 8, 5 + 1 * 8, 4 + 2 * 8, 5 + 2 * 8,
+ 6 + 1 * 8, 7 + 1 * 8, 6 + 2 * 8, 7 + 2 * 8,
+ 4 + 3 * 8, 5 + 3 * 8, 4 + 4 * 8, 5 + 4 * 8,
+ 6 + 3 * 8, 7 + 3 * 8, 6 + 4 * 8, 7 + 4 * 8,
+ 4 + 6 * 8, 5 + 6 * 8, 4 + 7 * 8, 5 + 7 * 8,
+ 6 + 6 * 8, 7 + 6 * 8, 6 + 7 * 8, 7 + 7 * 8,
+ 4 + 8 * 8, 5 + 8 * 8, 4 + 9 * 8, 5 + 9 * 8,
+ 6 + 8 * 8, 7 + 8 * 8, 6 + 9 * 8, 7 + 9 * 8,
+ 4 + 11 * 8, 5 + 11 * 8, 4 + 12 * 8, 5 + 12 * 8,
+ 6 + 11 * 8, 7 + 11 * 8, 6 + 12 * 8, 7 + 12 * 8,
+ 4 + 13 * 8, 5 + 13 * 8, 4 + 14 * 8, 5 + 14 * 8,
+ 6 + 13 * 8, 7 + 13 * 8, 6 + 14 * 8, 7 + 14 * 8,
+ 0 + 0 * 8, 0 + 5 * 8, 0 + 10 * 8
};
-static av_always_inline uint32_t pack16to32(int a, int b){
+static av_always_inline uint32_t pack16to32(int a, int b)
+{
#if HAVE_BIGENDIAN
- return (b&0xFFFF) + (a<<16);
+ return (b & 0xFFFF) + (a << 16);
#else
- return (a&0xFFFF) + (b<<16);
+ return (a & 0xFFFF) + (b << 16);
#endif
}
-static av_always_inline uint16_t pack8to16(int a, int b){
+static av_always_inline uint16_t pack8to16(int a, int b)
+{
#if HAVE_BIGENDIAN
- return (b&0xFF) + (a<<8);
+ return (b & 0xFF) + (a << 8);
#else
- return (a&0xFF) + (b<<8);
+ return (a & 0xFF) + (b << 8);
#endif
}
/**
* Get the chroma qp.
*/
-static av_always_inline int get_chroma_qp(H264Context *h, int t, int qscale){
+static av_always_inline int get_chroma_qp(H264Context *h, int t, int qscale)
+{
return h->pps.chroma_qp_table[t][qscale];
}
/**
* Get the predicted intra4x4 prediction mode.
*/
-static av_always_inline int pred_intra_mode(H264Context *h, int n){
- const int index8= scan8[n];
- const int left= h->intra4x4_pred_mode_cache[index8 - 1];
- const int top = h->intra4x4_pred_mode_cache[index8 - 8];
- const int min= FFMIN(left, top);
+static av_always_inline int pred_intra_mode(H264Context *h, int n)
+{
+ const int index8 = scan8[n];
+ const int left = h->intra4x4_pred_mode_cache[index8 - 1];
+ const int top = h->intra4x4_pred_mode_cache[index8 - 8];
+ const int min = FFMIN(left, top);
- tprintf(h->s.avctx, "mode:%d %d min:%d\n", left ,top, min);
+ tprintf(h->s.avctx, "mode:%d %d min:%d\n", left, top, min);
- if(min<0) return DC_PRED;
- else return min;
+ if (min < 0)
+ return DC_PRED;
+ else
+ return min;
}
-static av_always_inline void write_back_intra_pred_mode(H264Context *h){
- int8_t *i4x4= h->intra4x4_pred_mode + h->mb2br_xy[h->mb_xy];
- int8_t *i4x4_cache= h->intra4x4_pred_mode_cache;
+static av_always_inline void write_back_intra_pred_mode(H264Context *h)
+{
+ int8_t *i4x4 = h->intra4x4_pred_mode + h->mb2br_xy[h->mb_xy];
+ int8_t *i4x4_cache = h->intra4x4_pred_mode_cache;
- AV_COPY32(i4x4, i4x4_cache + 4 + 8*4);
- i4x4[4]= i4x4_cache[7+8*3];
- i4x4[5]= i4x4_cache[7+8*2];
- i4x4[6]= i4x4_cache[7+8*1];
+ AV_COPY32(i4x4, i4x4_cache + 4 + 8 * 4);
+ i4x4[4] = i4x4_cache[7 + 8 * 3];
+ i4x4[5] = i4x4_cache[7 + 8 * 2];
+ i4x4[6] = i4x4_cache[7 + 8 * 1];
}
-static av_always_inline void write_back_non_zero_count(H264Context *h){
- const int mb_xy= h->mb_xy;
- uint8_t *nnz = h->non_zero_count[mb_xy];
+static av_always_inline void write_back_non_zero_count(H264Context *h)
+{
+ const int mb_xy = h->mb_xy;
+ uint8_t *nnz = h->non_zero_count[mb_xy];
uint8_t *nnz_cache = h->non_zero_count_cache;
- AV_COPY32(&nnz[ 0], &nnz_cache[4+8* 1]);
- AV_COPY32(&nnz[ 4], &nnz_cache[4+8* 2]);
- AV_COPY32(&nnz[ 8], &nnz_cache[4+8* 3]);
- AV_COPY32(&nnz[12], &nnz_cache[4+8* 4]);
- AV_COPY32(&nnz[16], &nnz_cache[4+8* 6]);
- AV_COPY32(&nnz[20], &nnz_cache[4+8* 7]);
- AV_COPY32(&nnz[32], &nnz_cache[4+8*11]);
- AV_COPY32(&nnz[36], &nnz_cache[4+8*12]);
-
- if(!h->s.chroma_y_shift){
- AV_COPY32(&nnz[24], &nnz_cache[4+8* 8]);
- AV_COPY32(&nnz[28], &nnz_cache[4+8* 9]);
- AV_COPY32(&nnz[40], &nnz_cache[4+8*13]);
- AV_COPY32(&nnz[44], &nnz_cache[4+8*14]);
+ AV_COPY32(&nnz[ 0], &nnz_cache[4 + 8 * 1]);
+ AV_COPY32(&nnz[ 4], &nnz_cache[4 + 8 * 2]);
+ AV_COPY32(&nnz[ 8], &nnz_cache[4 + 8 * 3]);
+ AV_COPY32(&nnz[12], &nnz_cache[4 + 8 * 4]);
+ AV_COPY32(&nnz[16], &nnz_cache[4 + 8 * 6]);
+ AV_COPY32(&nnz[20], &nnz_cache[4 + 8 * 7]);
+ AV_COPY32(&nnz[32], &nnz_cache[4 + 8 * 11]);
+ AV_COPY32(&nnz[36], &nnz_cache[4 + 8 * 12]);
+
+ if (!h->s.chroma_y_shift) {
+ AV_COPY32(&nnz[24], &nnz_cache[4 + 8 * 8]);
+ AV_COPY32(&nnz[28], &nnz_cache[4 + 8 * 9]);
+ AV_COPY32(&nnz[40], &nnz_cache[4 + 8 * 13]);
+ AV_COPY32(&nnz[44], &nnz_cache[4 + 8 * 14]);
}
}
-static av_always_inline void write_back_motion_list(H264Context *h, MpegEncContext * const s, int b_stride,
- int b_xy, int b8_xy, int mb_type, int list )
+static av_always_inline void write_back_motion_list(H264Context *h,
+ MpegEncContext *const s,
+ int b_stride,
+ int b_xy, int b8_xy,
+ int mb_type, int list)
{
- int16_t (*mv_dst)[2] = &s->current_picture.f.motion_val[list][b_xy];
- int16_t (*mv_src)[2] = &h->mv_cache[list][scan8[0]];
- AV_COPY128(mv_dst + 0*b_stride, mv_src + 8*0);
- AV_COPY128(mv_dst + 1*b_stride, mv_src + 8*1);
- AV_COPY128(mv_dst + 2*b_stride, mv_src + 8*2);
- AV_COPY128(mv_dst + 3*b_stride, mv_src + 8*3);
- if( CABAC ) {
- uint8_t (*mvd_dst)[2] = &h->mvd_table[list][FMO ? 8*h->mb_xy : h->mb2br_xy[h->mb_xy]];
- uint8_t (*mvd_src)[2] = &h->mvd_cache[list][scan8[0]];
- if(IS_SKIP(mb_type))
+ int16_t(*mv_dst)[2] = &s->current_picture.f.motion_val[list][b_xy];
+ int16_t(*mv_src)[2] = &h->mv_cache[list][scan8[0]];
+ AV_COPY128(mv_dst + 0 * b_stride, mv_src + 8 * 0);
+ AV_COPY128(mv_dst + 1 * b_stride, mv_src + 8 * 1);
+ AV_COPY128(mv_dst + 2 * b_stride, mv_src + 8 * 2);
+ AV_COPY128(mv_dst + 3 * b_stride, mv_src + 8 * 3);
+ if (CABAC) {
+ uint8_t (*mvd_dst)[2] = &h->mvd_table[list][FMO ? 8 * h->mb_xy
+ : h->mb2br_xy[h->mb_xy]];
+ uint8_t(*mvd_src)[2] = &h->mvd_cache[list][scan8[0]];
+ if (IS_SKIP(mb_type)) {
AV_ZERO128(mvd_dst);
- else{
- AV_COPY64(mvd_dst, mvd_src + 8*3);
- AV_COPY16(mvd_dst + 3 + 3, mvd_src + 3 + 8*0);
- AV_COPY16(mvd_dst + 3 + 2, mvd_src + 3 + 8*1);
- AV_COPY16(mvd_dst + 3 + 1, mvd_src + 3 + 8*2);
+ } else {
+ AV_COPY64(mvd_dst, mvd_src + 8 * 3);
+ AV_COPY16(mvd_dst + 3 + 3, mvd_src + 3 + 8 * 0);
+ AV_COPY16(mvd_dst + 3 + 2, mvd_src + 3 + 8 * 1);
+ AV_COPY16(mvd_dst + 3 + 1, mvd_src + 3 + 8 * 2);
}
}
{
int8_t *ref_index = &s->current_picture.f.ref_index[list][b8_xy];
int8_t *ref_cache = h->ref_cache[list];
- ref_index[0+0*2]= ref_cache[scan8[0]];
- ref_index[1+0*2]= ref_cache[scan8[4]];
- ref_index[0+1*2]= ref_cache[scan8[8]];
- ref_index[1+1*2]= ref_cache[scan8[12]];
+ ref_index[0 + 0 * 2] = ref_cache[scan8[0]];
+ ref_index[1 + 0 * 2] = ref_cache[scan8[4]];
+ ref_index[0 + 1 * 2] = ref_cache[scan8[8]];
+ ref_index[1 + 1 * 2] = ref_cache[scan8[12]];
}
}
-static av_always_inline void write_back_motion(H264Context *h, int mb_type){
- MpegEncContext * const s = &h->s;
- const int b_stride = h->b_stride;
- const int b_xy = 4*s->mb_x + 4*s->mb_y*h->b_stride; //try mb2b(8)_xy
- const int b8_xy= 4*h->mb_xy;
+static av_always_inline void write_back_motion(H264Context *h, int mb_type)
+{
+ MpegEncContext *const s = &h->s;
+ const int b_stride = h->b_stride;
+ const int b_xy = 4 * s->mb_x + 4 * s->mb_y * h->b_stride; // try mb2b(8)_xy
+ const int b8_xy = 4 * h->mb_xy;
- if(USES_LIST(mb_type, 0)){
+ if (USES_LIST(mb_type, 0)) {
write_back_motion_list(h, s, b_stride, b_xy, b8_xy, mb_type, 0);
- }else{
+ } else {
fill_rectangle(&s->current_picture.f.ref_index[0][b8_xy],
2, 2, 2, (uint8_t)LIST_NOT_USED, 1);
}
- if(USES_LIST(mb_type, 1)){
+ if (USES_LIST(mb_type, 1))
write_back_motion_list(h, s, b_stride, b_xy, b8_xy, mb_type, 1);
- }
- if(h->slice_type_nos == AV_PICTURE_TYPE_B && CABAC){
- if(IS_8X8(mb_type)){
- uint8_t *direct_table = &h->direct_table[4*h->mb_xy];
- direct_table[1] = h->sub_mb_type[1]>>1;
- direct_table[2] = h->sub_mb_type[2]>>1;
- direct_table[3] = h->sub_mb_type[3]>>1;
+ if (h->slice_type_nos == AV_PICTURE_TYPE_B && CABAC) {
+ if (IS_8X8(mb_type)) {
+ uint8_t *direct_table = &h->direct_table[4 * h->mb_xy];
+ direct_table[1] = h->sub_mb_type[1] >> 1;
+ direct_table[2] = h->sub_mb_type[2] >> 1;
+ direct_table[3] = h->sub_mb_type[3] >> 1;
}
}
}
-static av_always_inline int get_dct8x8_allowed(H264Context *h){
- if(h->sps.direct_8x8_inference_flag)
- return !(AV_RN64A(h->sub_mb_type) & ((MB_TYPE_16x8|MB_TYPE_8x16|MB_TYPE_8x8 )*0x0001000100010001ULL));
+static av_always_inline int get_dct8x8_allowed(H264Context *h)
+{
+ if (h->sps.direct_8x8_inference_flag)
+ return !(AV_RN64A(h->sub_mb_type) &
+ ((MB_TYPE_16x8 | MB_TYPE_8x16 | MB_TYPE_8x8) *
+ 0x0001000100010001ULL));
else
- return !(AV_RN64A(h->sub_mb_type) & ((MB_TYPE_16x8|MB_TYPE_8x16|MB_TYPE_8x8|MB_TYPE_DIRECT2)*0x0001000100010001ULL));
+ return !(AV_RN64A(h->sub_mb_type) &
+ ((MB_TYPE_16x8 | MB_TYPE_8x16 | MB_TYPE_8x8 | MB_TYPE_DIRECT2) *
+ 0x0001000100010001ULL));
}
#endif /* AVCODEC_H264_H */
diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c
index 08a6a5b..2bf08b5 100644
--- a/libavcodec/h264_cabac.c
+++ b/libavcodec/h264_cabac.c
@@ -1652,14 +1652,14 @@ decode_cabac_residual_internal(H264Context *h, DCTELEM *block,
index[coeff_count++] = last;\
}
const uint8_t *sig_off = significant_coeff_flag_offset_8x8[MB_FIELD];
-#if ARCH_X86 && HAVE_7REGS
- coeff_count= decode_significance_8x8_x86(CC, significant_coeff_ctx_base, index,
+#ifdef decode_significance
+ coeff_count = decode_significance_8x8(CC, significant_coeff_ctx_base, index,
last_coeff_ctx_base, sig_off);
} else {
if (is_dc && chroma422) { // dc 422
DECODE_SIGNIFICANCE(7, sig_coeff_offset_dc[last], sig_coeff_offset_dc[last]);
} else {
- coeff_count= decode_significance_x86(CC, max_coeff, significant_coeff_ctx_base, index,
+ coeff_count = decode_significance(CC, max_coeff, significant_coeff_ctx_base, index,
last_coeff_ctx_base-significant_coeff_ctx_base);
}
#else
diff --git a/libavcodec/h264_mb_template.c b/libavcodec/h264_mb_template.c
new file mode 100644
index 0000000..b7856cb
--- /dev/null
+++ b/libavcodec/h264_mb_template.c
@@ -0,0 +1,380 @@
+/*
+ * H.26L/H.264/AVC/JVT/14496-10/... decoder
+ * Copyright (c) 2003 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#undef FUNC
+#undef PIXEL_SHIFT
+
+#if SIMPLE
+# define FUNC(n) AV_JOIN(n ## _simple_, BITS)
+# define PIXEL_SHIFT (BITS >> 4)
+#else
+# define FUNC(n) n ## _complex
+# define PIXEL_SHIFT h->pixel_shift
+#endif
+
+#undef CHROMA_IDC
+#define CHROMA_IDC 1
+#include "h264_mc_template.c"
+
+#undef CHROMA_IDC
+#define CHROMA_IDC 2
+#include "h264_mc_template.c"
+
+static av_noinline void FUNC(hl_decode_mb)(H264Context *h)
+{
+ MpegEncContext *const s = &h->s;
+ const int mb_x = s->mb_x;
+ const int mb_y = s->mb_y;
+ const int mb_xy = h->mb_xy;
+ const int mb_type = s->current_picture.f.mb_type[mb_xy];
+ uint8_t *dest_y, *dest_cb, *dest_cr;
+ int linesize, uvlinesize /*dct_offset*/;
+ int i, j;
+ int *block_offset = &h->block_offset[0];
+ const int transform_bypass = !SIMPLE && (s->qscale == 0 && h->sps.transform_bypass);
+ /* is_h264 should always be true if SVQ3 is disabled. */
+ const int is_h264 = !CONFIG_SVQ3_DECODER || SIMPLE || s->codec_id == CODEC_ID_H264;
+ void (*idct_add)(uint8_t *dst, DCTELEM *block, int stride);
+ const int block_h = 16 >> s->chroma_y_shift;
+ const int chroma422 = CHROMA422;
+
+ dest_y = s->current_picture.f.data[0] + ((mb_x << PIXEL_SHIFT) + mb_y * s->linesize) * 16;
+ dest_cb = s->current_picture.f.data[1] + (mb_x << PIXEL_SHIFT) * 8 + mb_y * s->uvlinesize * block_h;
+ dest_cr = s->current_picture.f.data[2] + (mb_x << PIXEL_SHIFT) * 8 + mb_y * s->uvlinesize * block_h;
+
+ s->dsp.prefetch(dest_y + (s->mb_x & 3) * 4 * s->linesize + (64 << PIXEL_SHIFT), s->linesize, 4);
+ s->dsp.prefetch(dest_cb + (s->mb_x & 7) * s->uvlinesize + (64 << PIXEL_SHIFT), dest_cr - dest_cb, 2);
+
+ h->list_counts[mb_xy] = h->list_count;
+
+ if (!SIMPLE && MB_FIELD) {
+ linesize = h->mb_linesize = s->linesize * 2;
+ uvlinesize = h->mb_uvlinesize = s->uvlinesize * 2;
+ block_offset = &h->block_offset[48];
+ if (mb_y & 1) { // FIXME move out of this function?
+ dest_y -= s->linesize * 15;
+ dest_cb -= s->uvlinesize * (block_h - 1);
+ dest_cr -= s->uvlinesize * (block_h - 1);
+ }
+ if (FRAME_MBAFF) {
+ int list;
+ for (list = 0; list < h->list_count; list++) {
+ if (!USES_LIST(mb_type, list))
+ continue;
+ if (IS_16X16(mb_type)) {
+ int8_t *ref = &h->ref_cache[list][scan8[0]];
+ fill_rectangle(ref, 4, 4, 8, (16 + *ref) ^ (s->mb_y & 1), 1);
+ } else {
+ for (i = 0; i < 16; i += 4) {
+ int ref = h->ref_cache[list][scan8[i]];
+ if (ref >= 0)
+ fill_rectangle(&h->ref_cache[list][scan8[i]], 2, 2,
+ 8, (16 + ref) ^ (s->mb_y & 1), 1);
+ }
+ }
+ }
+ }
+ } else {
+ linesize = h->mb_linesize = s->linesize;
+ uvlinesize = h->mb_uvlinesize = s->uvlinesize;
+ // dct_offset = s->linesize * 16;
+ }
+
+ if (!SIMPLE && IS_INTRA_PCM(mb_type)) {
+ if (PIXEL_SHIFT) {
+ const int bit_depth = h->sps.bit_depth_luma;
+ int j;
+ GetBitContext gb;
+ init_get_bits(&gb, (uint8_t *)h->mb,
+ ff_h264_mb_sizes[h->sps.chroma_format_idc] * bit_depth);
+
+ for (i = 0; i < 16; i++) {
+ uint16_t *tmp_y = (uint16_t *)(dest_y + i * linesize);
+ for (j = 0; j < 16; j++)
+ tmp_y[j] = get_bits(&gb, bit_depth);
+ }
+ if (SIMPLE || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+ if (!h->sps.chroma_format_idc) {
+ for (i = 0; i < block_h; i++) {
+ uint16_t *tmp_cb = (uint16_t *)(dest_cb + i * uvlinesize);
+ for (j = 0; j < 8; j++)
+ tmp_cb[j] = 1 << (bit_depth - 1);
+ }
+ for (i = 0; i < block_h; i++) {
+ uint16_t *tmp_cr = (uint16_t *)(dest_cr + i * uvlinesize);
+ for (j = 0; j < 8; j++)
+ tmp_cr[j] = 1 << (bit_depth - 1);
+ }
+ } else {
+ for (i = 0; i < block_h; i++) {
+ uint16_t *tmp_cb = (uint16_t *)(dest_cb + i * uvlinesize);
+ for (j = 0; j < 8; j++)
+ tmp_cb[j] = get_bits(&gb, bit_depth);
+ }
+ for (i = 0; i < block_h; i++) {
+ uint16_t *tmp_cr = (uint16_t *)(dest_cr + i * uvlinesize);
+ for (j = 0; j < 8; j++)
+ tmp_cr[j] = get_bits(&gb, bit_depth);
+ }
+ }
+ }
+ } else {
+ for (i = 0; i < 16; i++)
+ memcpy(dest_y + i * linesize, (uint8_t *)h->mb + i * 16, 16);
+ if (SIMPLE || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+ if (!h->sps.chroma_format_idc) {
+ for (i = 0; i < block_h; i++) {
+ memset(dest_cb + i * uvlinesize, 128, 8);
+ memset(dest_cr + i * uvlinesize, 128, 8);
+ }
+ } else {
+ uint8_t *src_cb = (uint8_t *)h->mb + 256;
+ uint8_t *src_cr = (uint8_t *)h->mb + 256 + block_h * 8;
+ for (i = 0; i < block_h; i++) {
+ memcpy(dest_cb + i * uvlinesize, src_cb + i * 8, 8);
+ memcpy(dest_cr + i * uvlinesize, src_cr + i * 8, 8);
+ }
+ }
+ }
+ }
+ } else {
+ if (IS_INTRA(mb_type)) {
+ if (h->deblocking_filter)
+ xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize,
+ uvlinesize, 1, 0, SIMPLE, PIXEL_SHIFT);
+
+ if (SIMPLE || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+ h->hpc.pred8x8[h->chroma_pred_mode](dest_cb, uvlinesize);
+ h->hpc.pred8x8[h->chroma_pred_mode](dest_cr, uvlinesize);
+ }
+
+ hl_decode_mb_predict_luma(h, mb_type, is_h264, SIMPLE,
+ transform_bypass, PIXEL_SHIFT,
+ block_offset, linesize, dest_y, 0);
+
+ if (h->deblocking_filter)
+ xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize,
+ uvlinesize, 0, 0, SIMPLE, PIXEL_SHIFT);
+ } else if (is_h264) {
+ if (chroma422) {
+ FUNC(hl_motion_422)(h, dest_y, dest_cb, dest_cr,
+ s->me.qpel_put, s->dsp.put_h264_chroma_pixels_tab,
+ s->me.qpel_avg, s->dsp.avg_h264_chroma_pixels_tab,
+ h->h264dsp.weight_h264_pixels_tab,
+ h->h264dsp.biweight_h264_pixels_tab);
+ } else {
+ FUNC(hl_motion_420)(h, dest_y, dest_cb, dest_cr,
+ s->me.qpel_put, s->dsp.put_h264_chroma_pixels_tab,
+ s->me.qpel_avg, s->dsp.avg_h264_chroma_pixels_tab,
+ h->h264dsp.weight_h264_pixels_tab,
+ h->h264dsp.biweight_h264_pixels_tab);
+ }
+ }
+
+ hl_decode_mb_idct_luma(h, mb_type, is_h264, SIMPLE, transform_bypass,
+ PIXEL_SHIFT, block_offset, linesize, dest_y, 0);
+
+ if ((SIMPLE || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) &&
+ (h->cbp & 0x30)) {
+ uint8_t *dest[2] = { dest_cb, dest_cr };
+ if (transform_bypass) {
+ if (IS_INTRA(mb_type) && h->sps.profile_idc == 244 &&
+ (h->chroma_pred_mode == VERT_PRED8x8 ||
+ h->chroma_pred_mode == HOR_PRED8x8)) {
+ h->hpc.pred8x8_add[h->chroma_pred_mode](dest[0],
+ block_offset + 16,
+ h->mb + (16 * 16 * 1 << PIXEL_SHIFT),
+ uvlinesize);
+ h->hpc.pred8x8_add[h->chroma_pred_mode](dest[1],
+ block_offset + 32,
+ h->mb + (16 * 16 * 2 << PIXEL_SHIFT),
+ uvlinesize);
+ } else {
+ idct_add = s->dsp.add_pixels4;
+ for (j = 1; j < 3; j++) {
+ for (i = j * 16; i < j * 16 + 4; i++)
+ if (h->non_zero_count_cache[scan8[i]] ||
+ dctcoef_get(h->mb, PIXEL_SHIFT, i * 16))
+ idct_add(dest[j - 1] + block_offset[i],
+ h->mb + (i * 16 << PIXEL_SHIFT),
+ uvlinesize);
+ if (chroma422) {
+ for (i = j * 16 + 4; i < j * 16 + 8; i++)
+ if (h->non_zero_count_cache[scan8[i + 4]] ||
+ dctcoef_get(h->mb, PIXEL_SHIFT, i * 16))
+ idct_add(dest[j - 1] + block_offset[i + 4],
+ h->mb + (i * 16 << PIXEL_SHIFT),
+ uvlinesize);
+ }
+ }
+ }
+ } else {
+ if (is_h264) {
+ int qp[2];
+ if (chroma422) {
+ qp[0] = h->chroma_qp[0] + 3;
+ qp[1] = h->chroma_qp[1] + 3;
+ } else {
+ qp[0] = h->chroma_qp[0];
+ qp[1] = h->chroma_qp[1];
+ }
+ if (h->non_zero_count_cache[scan8[CHROMA_DC_BLOCK_INDEX + 0]])
+ h->h264dsp.h264_chroma_dc_dequant_idct(h->mb + (16 * 16 * 1 << PIXEL_SHIFT),
+ h->dequant4_coeff[IS_INTRA(mb_type) ? 1 : 4][qp[0]][0]);
+ if (h->non_zero_count_cache[scan8[CHROMA_DC_BLOCK_INDEX + 1]])
+ h->h264dsp.h264_chroma_dc_dequant_idct(h->mb + (16 * 16 * 2 << PIXEL_SHIFT),
+ h->dequant4_coeff[IS_INTRA(mb_type) ? 2 : 5][qp[1]][0]);
+ h->h264dsp.h264_idct_add8(dest, block_offset,
+ h->mb, uvlinesize,
+ h->non_zero_count_cache);
+ } else if (CONFIG_SVQ3_DECODER) {
+ h->h264dsp.h264_chroma_dc_dequant_idct(h->mb + 16 * 16 * 1,
+ h->dequant4_coeff[IS_INTRA(mb_type) ? 1 : 4][h->chroma_qp[0]][0]);
+ h->h264dsp.h264_chroma_dc_dequant_idct(h->mb + 16 * 16 * 2,
+ h->dequant4_coeff[IS_INTRA(mb_type) ? 2 : 5][h->chroma_qp[1]][0]);
+ for (j = 1; j < 3; j++) {
+ for (i = j * 16; i < j * 16 + 4; i++)
+ if (h->non_zero_count_cache[scan8[i]] || h->mb[i * 16]) {
+ uint8_t *const ptr = dest[j - 1] + block_offset[i];
+ ff_svq3_add_idct_c(ptr, h->mb + i * 16,
+ uvlinesize,
+ ff_h264_chroma_qp[0][s->qscale + 12] - 12, 2);
+ }
+ }
+ }
+ }
+ }
+ }
+ if (h->cbp || IS_INTRA(mb_type)) {
+ s->dsp.clear_blocks(h->mb);
+ s->dsp.clear_blocks(h->mb + (24 * 16 << PIXEL_SHIFT));
+ }
+}
+
+#if !SIMPLE || BITS == 8
+
+#undef CHROMA_IDC
+#define CHROMA_IDC 3
+#include "h264_mc_template.c"
+
+static av_noinline void FUNC(hl_decode_mb_444)(H264Context *h)
+{
+ MpegEncContext *const s = &h->s;
+ const int mb_x = s->mb_x;
+ const int mb_y = s->mb_y;
+ const int mb_xy = h->mb_xy;
+ const int mb_type = s->current_picture.f.mb_type[mb_xy];
+ uint8_t *dest[3];
+ int linesize;
+ int i, j, p;
+ int *block_offset = &h->block_offset[0];
+ const int transform_bypass = !SIMPLE && (s->qscale == 0 && h->sps.transform_bypass);
+ const int plane_count = (SIMPLE || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) ? 3 : 1;
+
+ for (p = 0; p < plane_count; p++) {
+ dest[p] = s->current_picture.f.data[p] +
+ ((mb_x << PIXEL_SHIFT) + mb_y * s->linesize) * 16;
+ s->dsp.prefetch(dest[p] + (s->mb_x & 3) * 4 * s->linesize + (64 << PIXEL_SHIFT),
+ s->linesize, 4);
+ }
+
+ h->list_counts[mb_xy] = h->list_count;
+
+ if (!SIMPLE && MB_FIELD) {
+ linesize = h->mb_linesize = h->mb_uvlinesize = s->linesize * 2;
+ block_offset = &h->block_offset[48];
+ if (mb_y & 1) // FIXME move out of this function?
+ for (p = 0; p < 3; p++)
+ dest[p] -= s->linesize * 15;
+ if (FRAME_MBAFF) {
+ int list;
+ for (list = 0; list < h->list_count; list++) {
+ if (!USES_LIST(mb_type, list))
+ continue;
+ if (IS_16X16(mb_type)) {
+ int8_t *ref = &h->ref_cache[list][scan8[0]];
+ fill_rectangle(ref, 4, 4, 8, (16 + *ref) ^ (s->mb_y & 1), 1);
+ } else {
+ for (i = 0; i < 16; i += 4) {
+ int ref = h->ref_cache[list][scan8[i]];
+ if (ref >= 0)
+ fill_rectangle(&h->ref_cache[list][scan8[i]], 2, 2,
+ 8, (16 + ref) ^ (s->mb_y & 1), 1);
+ }
+ }
+ }
+ }
+ } else {
+ linesize = h->mb_linesize = h->mb_uvlinesize = s->linesize;
+ }
+
+ if (!SIMPLE && IS_INTRA_PCM(mb_type)) {
+ if (PIXEL_SHIFT) {
+ const int bit_depth = h->sps.bit_depth_luma;
+ GetBitContext gb;
+ init_get_bits(&gb, (uint8_t *)h->mb, 768 * bit_depth);
+
+ for (p = 0; p < plane_count; p++)
+ for (i = 0; i < 16; i++) {
+ uint16_t *tmp = (uint16_t *)(dest[p] + i * linesize);
+ for (j = 0; j < 16; j++)
+ tmp[j] = get_bits(&gb, bit_depth);
+ }
+ } else {
+ for (p = 0; p < plane_count; p++)
+ for (i = 0; i < 16; i++)
+ memcpy(dest[p] + i * linesize,
+ (uint8_t *)h->mb + p * 256 + i * 16, 16);
+ }
+ } else {
+ if (IS_INTRA(mb_type)) {
+ if (h->deblocking_filter)
+ xchg_mb_border(h, dest[0], dest[1], dest[2], linesize,
+ linesize, 1, 1, SIMPLE, PIXEL_SHIFT);
+
+ for (p = 0; p < plane_count; p++)
+ hl_decode_mb_predict_luma(h, mb_type, 1, SIMPLE,
+ transform_bypass, PIXEL_SHIFT,
+ block_offset, linesize, dest[p], p);
+
+ if (h->deblocking_filter)
+ xchg_mb_border(h, dest[0], dest[1], dest[2], linesize,
+ linesize, 0, 1, SIMPLE, PIXEL_SHIFT);
+ } else {
+ FUNC(hl_motion_444)(h, dest[0], dest[1], dest[2],
+ s->me.qpel_put, s->dsp.put_h264_chroma_pixels_tab,
+ s->me.qpel_avg, s->dsp.avg_h264_chroma_pixels_tab,
+ h->h264dsp.weight_h264_pixels_tab,
+ h->h264dsp.biweight_h264_pixels_tab);
+ }
+
+ for (p = 0; p < plane_count; p++)
+ hl_decode_mb_idct_luma(h, mb_type, 1, SIMPLE, transform_bypass,
+ PIXEL_SHIFT, block_offset, linesize,
+ dest[p], p);
+ }
+ if (h->cbp || IS_INTRA(mb_type)) {
+ s->dsp.clear_blocks(h->mb);
+ s->dsp.clear_blocks(h->mb + (24 * 16 << PIXEL_SHIFT));
+ }
+}
+
+#endif
diff --git a/libavcodec/h264_mc_template.c b/libavcodec/h264_mc_template.c
new file mode 100644
index 0000000..a3af39b
--- /dev/null
+++ b/libavcodec/h264_mc_template.c
@@ -0,0 +1,160 @@
+/*
+ * H.26L/H.264/AVC/JVT/14496-10/... decoder
+ * Copyright (c) 2003 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#undef MCFUNC
+
+#if CHROMA_IDC == 1
+# define MCFUNC(n) FUNC(n ## _420)
+#elif CHROMA_IDC == 2
+# define MCFUNC(n) FUNC(n ## _422)
+#elif CHROMA_IDC == 3
+# define MCFUNC(n) FUNC(n ## _444)
+#endif
+
+#undef mc_part
+#define mc_part MCFUNC(mc_part)
+
+static void mc_part(H264Context *h, int n, int square,
+ int height, int delta,
+ uint8_t *dest_y, uint8_t *dest_cb,
+ uint8_t *dest_cr,
+ int x_offset, int y_offset,
+ qpel_mc_func *qpix_put,
+ h264_chroma_mc_func chroma_put,
+ qpel_mc_func *qpix_avg,
+ h264_chroma_mc_func chroma_avg,
+ h264_weight_func *weight_op,
+ h264_biweight_func *weight_avg,
+ int list0, int list1)
+{
+ if ((h->use_weight == 2 && list0 && list1 &&
+ (h->implicit_weight[h->ref_cache[0][scan8[n]]][h->ref_cache[1][scan8[n]]][h->s.mb_y & 1] != 32)) ||
+ h->use_weight == 1)
+ mc_part_weighted(h, n, square, height, delta, dest_y, dest_cb, dest_cr,
+ x_offset, y_offset, qpix_put, chroma_put,
+ weight_op[0], weight_op[1], weight_avg[0],
+ weight_avg[1], list0, list1, PIXEL_SHIFT, CHROMA_IDC);
+ else
+ mc_part_std(h, n, square, height, delta, dest_y, dest_cb, dest_cr,
+ x_offset, y_offset, qpix_put, chroma_put, qpix_avg,
+ chroma_avg, list0, list1, PIXEL_SHIFT, CHROMA_IDC);
+}
+
+static void MCFUNC(hl_motion)(H264Context *h, uint8_t *dest_y,
+ uint8_t *dest_cb, uint8_t *dest_cr,
+ qpel_mc_func(*qpix_put)[16],
+ h264_chroma_mc_func(*chroma_put),
+ qpel_mc_func(*qpix_avg)[16],
+ h264_chroma_mc_func(*chroma_avg),
+ h264_weight_func *weight_op,
+ h264_biweight_func *weight_avg)
+{
+ MpegEncContext *const s = &h->s;
+ const int mb_xy = h->mb_xy;
+ const int mb_type = s->current_picture.f.mb_type[mb_xy];
+
+ assert(IS_INTER(mb_type));
+
+ if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
+ await_references(h);
+ prefetch_motion(h, 0, PIXEL_SHIFT, CHROMA_IDC);
+
+ if (IS_16X16(mb_type)) {
+ mc_part(h, 0, 1, 16, 0, dest_y, dest_cb, dest_cr, 0, 0,
+ qpix_put[0], chroma_put[0], qpix_avg[0], chroma_avg[0],
+ weight_op, weight_avg,
+ IS_DIR(mb_type, 0, 0), IS_DIR(mb_type, 0, 1));
+ } else if (IS_16X8(mb_type)) {
+ mc_part(h, 0, 0, 8, 8 << PIXEL_SHIFT, dest_y, dest_cb, dest_cr, 0, 0,
+ qpix_put[1], chroma_put[0], qpix_avg[1], chroma_avg[0],
+ weight_op, weight_avg,
+ IS_DIR(mb_type, 0, 0), IS_DIR(mb_type, 0, 1));
+ mc_part(h, 8, 0, 8, 8 << PIXEL_SHIFT, dest_y, dest_cb, dest_cr, 0, 4,
+ qpix_put[1], chroma_put[0], qpix_avg[1], chroma_avg[0],
+ weight_op, weight_avg,
+ IS_DIR(mb_type, 1, 0), IS_DIR(mb_type, 1, 1));
+ } else if (IS_8X16(mb_type)) {
+ mc_part(h, 0, 0, 16, 8 * h->mb_linesize, dest_y, dest_cb, dest_cr, 0, 0,
+ qpix_put[1], chroma_put[1], qpix_avg[1], chroma_avg[1],
+ &weight_op[1], &weight_avg[1],
+ IS_DIR(mb_type, 0, 0), IS_DIR(mb_type, 0, 1));
+ mc_part(h, 4, 0, 16, 8 * h->mb_linesize, dest_y, dest_cb, dest_cr, 4, 0,
+ qpix_put[1], chroma_put[1], qpix_avg[1], chroma_avg[1],
+ &weight_op[1], &weight_avg[1],
+ IS_DIR(mb_type, 1, 0), IS_DIR(mb_type, 1, 1));
+ } else {
+ int i;
+
+ assert(IS_8X8(mb_type));
+
+ for (i = 0; i < 4; i++) {
+ const int sub_mb_type = h->sub_mb_type[i];
+ const int n = 4 * i;
+ int x_offset = (i & 1) << 2;
+ int y_offset = (i & 2) << 1;
+
+ if (IS_SUB_8X8(sub_mb_type)) {
+ mc_part(h, n, 1, 8, 0, dest_y, dest_cb, dest_cr,
+ x_offset, y_offset,
+ qpix_put[1], chroma_put[1], qpix_avg[1], chroma_avg[1],
+ &weight_op[1], &weight_avg[1],
+ IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1));
+ } else if (IS_SUB_8X4(sub_mb_type)) {
+ mc_part(h, n, 0, 4, 4 << PIXEL_SHIFT, dest_y, dest_cb, dest_cr,
+ x_offset, y_offset,
+ qpix_put[2], chroma_put[1], qpix_avg[2], chroma_avg[1],
+ &weight_op[1], &weight_avg[1],
+ IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1));
+ mc_part(h, n + 2, 0, 4, 4 << PIXEL_SHIFT,
+ dest_y, dest_cb, dest_cr, x_offset, y_offset + 2,
+ qpix_put[2], chroma_put[1], qpix_avg[2], chroma_avg[1],
+ &weight_op[1], &weight_avg[1],
+ IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1));
+ } else if (IS_SUB_4X8(sub_mb_type)) {
+ mc_part(h, n, 0, 8, 4 * h->mb_linesize,
+ dest_y, dest_cb, dest_cr, x_offset, y_offset,
+ qpix_put[2], chroma_put[2], qpix_avg[2], chroma_avg[2],
+ &weight_op[2], &weight_avg[2],
+ IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1));
+ mc_part(h, n + 1, 0, 8, 4 * h->mb_linesize,
+ dest_y, dest_cb, dest_cr, x_offset + 2, y_offset,
+ qpix_put[2], chroma_put[2], qpix_avg[2], chroma_avg[2],
+ &weight_op[2], &weight_avg[2],
+ IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1));
+ } else {
+ int j;
+ assert(IS_SUB_4X4(sub_mb_type));
+ for (j = 0; j < 4; j++) {
+ int sub_x_offset = x_offset + 2 * (j & 1);
+ int sub_y_offset = y_offset + (j & 2);
+ mc_part(h, n + j, 1, 4, 0,
+ dest_y, dest_cb, dest_cr, sub_x_offset, sub_y_offset,
+ qpix_put[2], chroma_put[2], qpix_avg[2], chroma_avg[2],
+ &weight_op[2], &weight_avg[2],
+ IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1));
+ }
+ }
+ }
+ }
+
+ prefetch_motion(h, 1, PIXEL_SHIFT, CHROMA_IDC);
+}
+
diff --git a/libavcodec/h264_mvpred.h b/libavcodec/h264_mvpred.h
index 2bd4458..5244c29 100644
--- a/libavcodec/h264_mvpred.h
+++ b/libavcodec/h264_mvpred.h
@@ -35,53 +35,53 @@
//#undef NDEBUG
#include <assert.h>
-static av_always_inline int fetch_diagonal_mv(H264Context *h, const int16_t **C, int i, int list, int part_width){
- const int topright_ref= h->ref_cache[list][ i - 8 + part_width ];
- MpegEncContext *s = &h->s;
+static av_always_inline int fetch_diagonal_mv(H264Context *h, const int16_t **C,
+ int i, int list, int part_width)
+{
+ const int topright_ref = h->ref_cache[list][i - 8 + part_width];
+ MpegEncContext *s = &h->s;
/* there is no consistent mapping of mvs to neighboring locations that will
* make mbaff happy, so we can't move all this logic to fill_caches */
- if(FRAME_MBAFF){
-
-#define SET_DIAG_MV(MV_OP, REF_OP, XY, Y4)\
- const int xy = XY, y4 = Y4;\
- const int mb_type = mb_types[xy+(y4>>2)*s->mb_stride];\
- if(!USES_LIST(mb_type,list))\
- return LIST_NOT_USED;\
- mv = s->current_picture_ptr->f.motion_val[list][h->mb2b_xy[xy] + 3 + y4*h->b_stride];\
- h->mv_cache[list][scan8[0]-2][0] = mv[0];\
- h->mv_cache[list][scan8[0]-2][1] = mv[1] MV_OP;\
- return s->current_picture_ptr->f.ref_index[list][4*xy + 1 + (y4 & ~1)] REF_OP;
-
- if(topright_ref == PART_NOT_AVAILABLE
- && i >= scan8[0]+8 && (i&7)==4
- && h->ref_cache[list][scan8[0]-1] != PART_NOT_AVAILABLE){
+ if (FRAME_MBAFF) {
+#define SET_DIAG_MV(MV_OP, REF_OP, XY, Y4) \
+ const int xy = XY, y4 = Y4; \
+ const int mb_type = mb_types[xy + (y4 >> 2) * s->mb_stride]; \
+ if (!USES_LIST(mb_type, list)) \
+ return LIST_NOT_USED; \
+ mv = s->current_picture_ptr->f.motion_val[list][h->mb2b_xy[xy] + 3 + y4 * h->b_stride]; \
+ h->mv_cache[list][scan8[0] - 2][0] = mv[0]; \
+ h->mv_cache[list][scan8[0] - 2][1] = mv[1] MV_OP; \
+ return s->current_picture_ptr->f.ref_index[list][4 * xy + 1 + (y4 & ~1)] REF_OP;
+
+ if (topright_ref == PART_NOT_AVAILABLE
+ && i >= scan8[0] + 8 && (i & 7) == 4
+ && h->ref_cache[list][scan8[0] - 1] != PART_NOT_AVAILABLE) {
const uint32_t *mb_types = s->current_picture_ptr->f.mb_type;
const int16_t *mv;
- AV_ZERO32(h->mv_cache[list][scan8[0]-2]);
- *C = h->mv_cache[list][scan8[0]-2];
+ AV_ZERO32(h->mv_cache[list][scan8[0] - 2]);
+ *C = h->mv_cache[list][scan8[0] - 2];
- if(!MB_FIELD
- && IS_INTERLACED(h->left_type[0])){
- SET_DIAG_MV(*2, >>1, h->left_mb_xy[0]+s->mb_stride, (s->mb_y&1)*2+(i>>5));
+ if (!MB_FIELD && IS_INTERLACED(h->left_type[0])) {
+ SET_DIAG_MV(* 2, >> 1, h->left_mb_xy[0] + s->mb_stride,
+ (s->mb_y & 1) * 2 + (i >> 5));
}
- if(MB_FIELD
- && !IS_INTERLACED(h->left_type[0])){
+ if (MB_FIELD && !IS_INTERLACED(h->left_type[0])) {
// left shift will turn LIST_NOT_USED into PART_NOT_AVAILABLE, but that's OK.
- SET_DIAG_MV(/2, <<1, h->left_mb_xy[i>=36], ((i>>2))&3);
+ SET_DIAG_MV(/ 2, << 1, h->left_mb_xy[i >= 36], ((i >> 2)) & 3);
}
}
#undef SET_DIAG_MV
}
- if(topright_ref != PART_NOT_AVAILABLE){
- *C= h->mv_cache[list][ i - 8 + part_width ];
+ if (topright_ref != PART_NOT_AVAILABLE) {
+ *C = h->mv_cache[list][i - 8 + part_width];
return topright_ref;
- }else{
+ } else {
tprintf(s->avctx, "topright MV not available\n");
- *C= h->mv_cache[list][ i - 8 - 1 ];
- return h->ref_cache[list][ i - 8 - 1 ];
+ *C = h->mv_cache[list][i - 8 - 1];
+ return h->ref_cache[list][i - 8 - 1];
}
}
@@ -92,53 +92,61 @@ static av_always_inline int fetch_diagonal_mv(H264Context *h, const int16_t **C,
* @param mx the x component of the predicted motion vector
* @param my the y component of the predicted motion vector
*/
-static av_always_inline void pred_motion(H264Context * const h, int n, int part_width, int list, int ref, int * const mx, int * const my){
- const int index8= scan8[n];
- const int top_ref= h->ref_cache[list][ index8 - 8 ];
- const int left_ref= h->ref_cache[list][ index8 - 1 ];
- const int16_t * const A= h->mv_cache[list][ index8 - 1 ];
- const int16_t * const B= h->mv_cache[list][ index8 - 8 ];
- const int16_t * C;
+static av_always_inline void pred_motion(H264Context *const h, int n,
+ int part_width, int list, int ref,
+ int *const mx, int *const my)
+{
+ const int index8 = scan8[n];
+ const int top_ref = h->ref_cache[list][index8 - 8];
+ const int left_ref = h->ref_cache[list][index8 - 1];
+ const int16_t *const A = h->mv_cache[list][index8 - 1];
+ const int16_t *const B = h->mv_cache[list][index8 - 8];
+ const int16_t *C;
int diagonal_ref, match_count;
- assert(part_width==1 || part_width==2 || part_width==4);
+ assert(part_width == 1 || part_width == 2 || part_width == 4);
/* mv_cache
- B . . A T T T T
- U . . L . . , .
- U . . L . . . .
- U . . L . . , .
- . . . L . . . .
-*/
-
- diagonal_ref= fetch_diagonal_mv(h, &C, index8, list, part_width);
- match_count= (diagonal_ref==ref) + (top_ref==ref) + (left_ref==ref);
+ * B . . A T T T T
+ * U . . L . . , .
+ * U . . L . . . .
+ * U . . L . . , .
+ * . . . L . . . .
+ */
+
+ diagonal_ref = fetch_diagonal_mv(h, &C, index8, list, part_width);
+ match_count = (diagonal_ref == ref) + (top_ref == ref) + (left_ref == ref);
tprintf(h->s.avctx, "pred_motion match_count=%d\n", match_count);
- if(match_count > 1){ //most common
- *mx= mid_pred(A[0], B[0], C[0]);
- *my= mid_pred(A[1], B[1], C[1]);
- }else if(match_count==1){
- if(left_ref==ref){
- *mx= A[0];
- *my= A[1];
- }else if(top_ref==ref){
- *mx= B[0];
- *my= B[1];
- }else{
- *mx= C[0];
- *my= C[1];
+ if (match_count > 1) { //most common
+ *mx = mid_pred(A[0], B[0], C[0]);
+ *my = mid_pred(A[1], B[1], C[1]);
+ } else if (match_count == 1) {
+ if (left_ref == ref) {
+ *mx = A[0];
+ *my = A[1];
+ } else if (top_ref == ref) {
+ *mx = B[0];
+ *my = B[1];
+ } else {
+ *mx = C[0];
+ *my = C[1];
}
- }else{
- if(top_ref == PART_NOT_AVAILABLE && diagonal_ref == PART_NOT_AVAILABLE && left_ref != PART_NOT_AVAILABLE){
- *mx= A[0];
- *my= A[1];
- }else{
- *mx= mid_pred(A[0], B[0], C[0]);
- *my= mid_pred(A[1], B[1], C[1]);
+ } else {
+ if (top_ref == PART_NOT_AVAILABLE &&
+ diagonal_ref == PART_NOT_AVAILABLE &&
+ left_ref != PART_NOT_AVAILABLE) {
+ *mx = A[0];
+ *my = A[1];
+ } else {
+ *mx = mid_pred(A[0], B[0], C[0]);
+ *my = mid_pred(A[1], B[1], C[1]);
}
}
- tprintf(h->s.avctx, "pred_motion (%2d %2d %2d) (%2d %2d %2d) (%2d %2d %2d) -> (%2d %2d %2d) at %2d %2d %d list %d\n", top_ref, B[0], B[1], diagonal_ref, C[0], C[1], left_ref, A[0], A[1], ref, *mx, *my, h->s.mb_x, h->s.mb_y, n, list);
+ tprintf(h->s.avctx,
+ "pred_motion (%2d %2d %2d) (%2d %2d %2d) (%2d %2d %2d) -> (%2d %2d %2d) at %2d %2d %d list %d\n",
+ top_ref, B[0], B[1], diagonal_ref, C[0], C[1], left_ref,
+ A[0], A[1], ref, *mx, *my, h->s.mb_x, h->s.mb_y, n, list);
}
/**
@@ -147,27 +155,32 @@ static av_always_inline void pred_motion(H264Context * const h, int n, int part_
* @param mx the x component of the predicted motion vector
* @param my the y component of the predicted motion vector
*/
-static av_always_inline void pred_16x8_motion(H264Context * const h, int n, int list, int ref, int * const mx, int * const my){
- if(n==0){
- const int top_ref= h->ref_cache[list][ scan8[0] - 8 ];
- const int16_t * const B= h->mv_cache[list][ scan8[0] - 8 ];
-
- tprintf(h->s.avctx, "pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n", top_ref, B[0], B[1], h->s.mb_x, h->s.mb_y, n, list);
-
- if(top_ref == ref){
- *mx= B[0];
- *my= B[1];
+static av_always_inline void pred_16x8_motion(H264Context *const h,
+ int n, int list, int ref,
+ int *const mx, int *const my)
+{
+ if (n == 0) {
+ const int top_ref = h->ref_cache[list][scan8[0] - 8];
+ const int16_t *const B = h->mv_cache[list][scan8[0] - 8];
+
+ tprintf(h->s.avctx, "pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n",
+ top_ref, B[0], B[1], h->s.mb_x, h->s.mb_y, n, list);
+
+ if (top_ref == ref) {
+ *mx = B[0];
+ *my = B[1];
return;
}
- }else{
- const int left_ref= h->ref_cache[list][ scan8[8] - 1 ];
- const int16_t * const A= h->mv_cache[list][ scan8[8] - 1 ];
+ } else {
+ const int left_ref = h->ref_cache[list][scan8[8] - 1];
+ const int16_t *const A = h->mv_cache[list][scan8[8] - 1];
- tprintf(h->s.avctx, "pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n", left_ref, A[0], A[1], h->s.mb_x, h->s.mb_y, n, list);
+ tprintf(h->s.avctx, "pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n",
+ left_ref, A[0], A[1], h->s.mb_x, h->s.mb_y, n, list);
- if(left_ref == ref){
- *mx= A[0];
- *my= A[1];
+ if (left_ref == ref) {
+ *mx = A[0];
+ *my = A[1];
return;
}
}
@@ -182,29 +195,34 @@ static av_always_inline void pred_16x8_motion(H264Context * const h, int n, int
* @param mx the x component of the predicted motion vector
* @param my the y component of the predicted motion vector
*/
-static av_always_inline void pred_8x16_motion(H264Context * const h, int n, int list, int ref, int * const mx, int * const my){
- if(n==0){
- const int left_ref= h->ref_cache[list][ scan8[0] - 1 ];
- const int16_t * const A= h->mv_cache[list][ scan8[0] - 1 ];
-
- tprintf(h->s.avctx, "pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n", left_ref, A[0], A[1], h->s.mb_x, h->s.mb_y, n, list);
-
- if(left_ref == ref){
- *mx= A[0];
- *my= A[1];
+static av_always_inline void pred_8x16_motion(H264Context *const h,
+ int n, int list, int ref,
+ int *const mx, int *const my)
+{
+ if (n == 0) {
+ const int left_ref = h->ref_cache[list][scan8[0] - 1];
+ const int16_t *const A = h->mv_cache[list][scan8[0] - 1];
+
+ tprintf(h->s.avctx, "pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n",
+ left_ref, A[0], A[1], h->s.mb_x, h->s.mb_y, n, list);
+
+ if (left_ref == ref) {
+ *mx = A[0];
+ *my = A[1];
return;
}
- }else{
- const int16_t * C;
+ } else {
+ const int16_t *C;
int diagonal_ref;
- diagonal_ref= fetch_diagonal_mv(h, &C, scan8[4], list, 2);
+ diagonal_ref = fetch_diagonal_mv(h, &C, scan8[4], list, 2);
- tprintf(h->s.avctx, "pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n", diagonal_ref, C[0], C[1], h->s.mb_x, h->s.mb_y, n, list);
+ tprintf(h->s.avctx, "pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n",
+ diagonal_ref, C[0], C[1], h->s.mb_x, h->s.mb_y, n, list);
- if(diagonal_ref == ref){
- *mx= C[0];
- *my= C[1];
+ if (diagonal_ref == ref) {
+ *mx = C[0];
+ *my = C[1];
return;
}
}
@@ -213,168 +231,174 @@ static av_always_inline void pred_8x16_motion(H264Context * const h, int n, int
pred_motion(h, n, 2, list, ref, mx, my);
}
-#define FIX_MV_MBAFF(type, refn, mvn, idx)\
- if(FRAME_MBAFF){\
- if(MB_FIELD){\
- if(!IS_INTERLACED(type)){\
- refn <<= 1;\
- AV_COPY32(mvbuf[idx], mvn);\
- mvbuf[idx][1] /= 2;\
- mvn = mvbuf[idx];\
- }\
- }else{\
- if(IS_INTERLACED(type)){\
- refn >>= 1;\
- AV_COPY32(mvbuf[idx], mvn);\
- mvbuf[idx][1] <<= 1;\
- mvn = mvbuf[idx];\
- }\
- }\
+#define FIX_MV_MBAFF(type, refn, mvn, idx) \
+ if (FRAME_MBAFF) { \
+ if (MB_FIELD) { \
+ if (!IS_INTERLACED(type)) { \
+ refn <<= 1; \
+ AV_COPY32(mvbuf[idx], mvn); \
+ mvbuf[idx][1] /= 2; \
+ mvn = mvbuf[idx]; \
+ } \
+ } else { \
+ if (IS_INTERLACED(type)) { \
+ refn >>= 1; \
+ AV_COPY32(mvbuf[idx], mvn); \
+ mvbuf[idx][1] <<= 1; \
+ mvn = mvbuf[idx]; \
+ } \
+ } \
}
-static av_always_inline void pred_pskip_motion(H264Context * const h){
- DECLARE_ALIGNED(4, static const int16_t, zeromv)[2] = {0};
+static av_always_inline void pred_pskip_motion(H264Context *const h)
+{
+ DECLARE_ALIGNED(4, static const int16_t, zeromv)[2] = { 0 };
DECLARE_ALIGNED(4, int16_t, mvbuf)[3][2];
- MpegEncContext * const s = &h->s;
- int8_t *ref = s->current_picture.f.ref_index[0];
- int16_t (*mv)[2] = s->current_picture.f.motion_val[0];
+ MpegEncContext *const s = &h->s;
+ int8_t *ref = s->current_picture.f.ref_index[0];
+ int16_t(*mv)[2] = s->current_picture.f.motion_val[0];
int top_ref, left_ref, diagonal_ref, match_count, mx, my;
const int16_t *A, *B, *C;
int b_stride = h->b_stride;
fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, 0, 1);
- /* To avoid doing an entire fill_decode_caches, we inline the relevant parts here.
- * FIXME: this is a partial duplicate of the logic in fill_decode_caches, but it's
- * faster this way. Is there a way to avoid this duplication?
+ /* To avoid doing an entire fill_decode_caches, we inline the relevant
+ * parts here.
+ * FIXME: this is a partial duplicate of the logic in fill_decode_caches,
+ * but it's faster this way. Is there a way to avoid this duplication?
*/
- if(USES_LIST(h->left_type[LTOP], 0)){
- left_ref = ref[4*h->left_mb_xy[LTOP] + 1 + (h->left_block[0]&~1)];
- A = mv[h->mb2b_xy[h->left_mb_xy[LTOP]] + 3 + b_stride*h->left_block[0]];
+ if (USES_LIST(h->left_type[LTOP], 0)) {
+ left_ref = ref[4 * h->left_mb_xy[LTOP] + 1 + (h->left_block[0] & ~1)];
+ A = mv[h->mb2b_xy[h->left_mb_xy[LTOP]] + 3 + b_stride * h->left_block[0]];
FIX_MV_MBAFF(h->left_type[LTOP], left_ref, A, 0);
- if(!(left_ref | AV_RN32A(A))){
+ if (!(left_ref | AV_RN32A(A)))
goto zeromv;
- }
- }else if(h->left_type[LTOP]){
+ } else if (h->left_type[LTOP]) {
left_ref = LIST_NOT_USED;
- A = zeromv;
- }else{
+ A = zeromv;
+ } else {
goto zeromv;
}
- if(USES_LIST(h->top_type, 0)){
- top_ref = ref[4*h->top_mb_xy + 2];
- B = mv[h->mb2b_xy[h->top_mb_xy] + 3*b_stride];
+ if (USES_LIST(h->top_type, 0)) {
+ top_ref = ref[4 * h->top_mb_xy + 2];
+ B = mv[h->mb2b_xy[h->top_mb_xy] + 3 * b_stride];
FIX_MV_MBAFF(h->top_type, top_ref, B, 1);
- if(!(top_ref | AV_RN32A(B))){
+ if (!(top_ref | AV_RN32A(B)))
goto zeromv;
- }
- }else if(h->top_type){
+ } else if (h->top_type) {
top_ref = LIST_NOT_USED;
- B = zeromv;
- }else{
+ B = zeromv;
+ } else {
goto zeromv;
}
- tprintf(h->s.avctx, "pred_pskip: (%d) (%d) at %2d %2d\n", top_ref, left_ref, h->s.mb_x, h->s.mb_y);
+ tprintf(h->s.avctx, "pred_pskip: (%d) (%d) at %2d %2d\n",
+ top_ref, left_ref, h->s.mb_x, h->s.mb_y);
- if(USES_LIST(h->topright_type, 0)){
- diagonal_ref = ref[4*h->topright_mb_xy + 2];
- C = mv[h->mb2b_xy[h->topright_mb_xy] + 3*b_stride];
+ if (USES_LIST(h->topright_type, 0)) {
+ diagonal_ref = ref[4 * h->topright_mb_xy + 2];
+ C = mv[h->mb2b_xy[h->topright_mb_xy] + 3 * b_stride];
FIX_MV_MBAFF(h->topright_type, diagonal_ref, C, 2);
- }else if(h->topright_type){
+ } else if (h->topright_type) {
diagonal_ref = LIST_NOT_USED;
C = zeromv;
- }else{
- if(USES_LIST(h->topleft_type, 0)){
- diagonal_ref = ref[4*h->topleft_mb_xy + 1 + (h->topleft_partition & 2)];
- C = mv[h->mb2b_xy[h->topleft_mb_xy] + 3 + b_stride + (h->topleft_partition & 2*b_stride)];
+ } else {
+ if (USES_LIST(h->topleft_type, 0)) {
+ diagonal_ref = ref[4 * h->topleft_mb_xy + 1 +
+ (h->topleft_partition & 2)];
+ C = mv[h->mb2b_xy[h->topleft_mb_xy] + 3 + b_stride +
+ (h->topleft_partition & 2 * b_stride)];
FIX_MV_MBAFF(h->topleft_type, diagonal_ref, C, 2);
- }else if(h->topleft_type){
+ } else if (h->topleft_type) {
diagonal_ref = LIST_NOT_USED;
- C = zeromv;
- }else{
+ C = zeromv;
+ } else {
diagonal_ref = PART_NOT_AVAILABLE;
- C = zeromv;
+ C = zeromv;
}
}
- match_count= !diagonal_ref + !top_ref + !left_ref;
+ match_count = !diagonal_ref + !top_ref + !left_ref;
tprintf(h->s.avctx, "pred_pskip_motion match_count=%d\n", match_count);
- if(match_count > 1){
+ if (match_count > 1) {
mx = mid_pred(A[0], B[0], C[0]);
my = mid_pred(A[1], B[1], C[1]);
- }else if(match_count==1){
- if(!left_ref){
+ } else if (match_count == 1) {
+ if (!left_ref) {
mx = A[0];
my = A[1];
- }else if(!top_ref){
+ } else if (!top_ref) {
mx = B[0];
my = B[1];
- }else{
+ } else {
mx = C[0];
my = C[1];
}
- }else{
+ } else {
mx = mid_pred(A[0], B[0], C[0]);
my = mid_pred(A[1], B[1], C[1]);
}
- fill_rectangle( h->mv_cache[0][scan8[0]], 4, 4, 8, pack16to32(mx,my), 4);
+ fill_rectangle(h->mv_cache[0][scan8[0]], 4, 4, 8, pack16to32(mx, my), 4);
return;
+
zeromv:
- fill_rectangle( h->mv_cache[0][scan8[0]], 4, 4, 8, 0, 4);
+ fill_rectangle(h->mv_cache[0][scan8[0]], 4, 4, 8, 0, 4);
return;
}
-static void fill_decode_neighbors(H264Context *h, int mb_type){
- MpegEncContext * const s = &h->s;
- const int mb_xy= h->mb_xy;
+static void fill_decode_neighbors(H264Context *h, int mb_type)
+{
+ MpegEncContext *const s = &h->s;
+ const int mb_xy = h->mb_xy;
int topleft_xy, top_xy, topright_xy, left_xy[LEFT_MBS];
- static const uint8_t left_block_options[4][32]={
- {0,1,2,3,7,10,8,11,3+0*4, 3+1*4, 3+2*4, 3+3*4, 1+4*4, 1+8*4, 1+5*4, 1+9*4},
- {2,2,3,3,8,11,8,11,3+2*4, 3+2*4, 3+3*4, 3+3*4, 1+5*4, 1+9*4, 1+5*4, 1+9*4},
- {0,0,1,1,7,10,7,10,3+0*4, 3+0*4, 3+1*4, 3+1*4, 1+4*4, 1+8*4, 1+4*4, 1+8*4},
- {0,2,0,2,7,10,7,10,3+0*4, 3+2*4, 3+0*4, 3+2*4, 1+4*4, 1+8*4, 1+4*4, 1+8*4}
+ static const uint8_t left_block_options[4][32] = {
+ { 0, 1, 2, 3, 7, 10, 8, 11, 3 + 0 * 4, 3 + 1 * 4, 3 + 2 * 4, 3 + 3 * 4, 1 + 4 * 4, 1 + 8 * 4, 1 + 5 * 4, 1 + 9 * 4 },
+ { 2, 2, 3, 3, 8, 11, 8, 11, 3 + 2 * 4, 3 + 2 * 4, 3 + 3 * 4, 3 + 3 * 4, 1 + 5 * 4, 1 + 9 * 4, 1 + 5 * 4, 1 + 9 * 4 },
+ { 0, 0, 1, 1, 7, 10, 7, 10, 3 + 0 * 4, 3 + 0 * 4, 3 + 1 * 4, 3 + 1 * 4, 1 + 4 * 4, 1 + 8 * 4, 1 + 4 * 4, 1 + 8 * 4 },
+ { 0, 2, 0, 2, 7, 10, 7, 10, 3 + 0 * 4, 3 + 2 * 4, 3 + 0 * 4, 3 + 2 * 4, 1 + 4 * 4, 1 + 8 * 4, 1 + 4 * 4, 1 + 8 * 4 }
};
- h->topleft_partition= -1;
+ h->topleft_partition = -1;
- top_xy = mb_xy - (s->mb_stride << MB_FIELD);
+ top_xy = mb_xy - (s->mb_stride << MB_FIELD);
/* Wow, what a mess, why didn't they simplify the interlacing & intra
* stuff, I can't imagine that these complex rules are worth it. */
- topleft_xy = top_xy - 1;
- topright_xy= top_xy + 1;
- left_xy[LBOT] = left_xy[LTOP] = mb_xy-1;
+ topleft_xy = top_xy - 1;
+ topright_xy = top_xy + 1;
+ left_xy[LBOT] = left_xy[LTOP] = mb_xy - 1;
h->left_block = left_block_options[0];
- if(FRAME_MBAFF){
+ if (FRAME_MBAFF) {
const int left_mb_field_flag = IS_INTERLACED(s->current_picture.f.mb_type[mb_xy - 1]);
const int curr_mb_field_flag = IS_INTERLACED(mb_type);
- if(s->mb_y&1){
+ if (s->mb_y & 1) {
if (left_mb_field_flag != curr_mb_field_flag) {
left_xy[LBOT] = left_xy[LTOP] = mb_xy - s->mb_stride - 1;
if (curr_mb_field_flag) {
left_xy[LBOT] += s->mb_stride;
- h->left_block = left_block_options[3];
+ h->left_block = left_block_options[3];
} else {
topleft_xy += s->mb_stride;
- // take top left mv from the middle of the mb, as opposed to all other modes which use the bottom right partition
+ /* take top left mv from the middle of the mb, as opposed
+ * to all other modes which use the bottom right partition */
h->topleft_partition = 0;
- h->left_block = left_block_options[1];
+ h->left_block = left_block_options[1];
}
}
- }else{
- if(curr_mb_field_flag){
+ } else {
+ if (curr_mb_field_flag) {
topleft_xy += s->mb_stride & (((s->current_picture.f.mb_type[top_xy - 1] >> 7) & 1) - 1);
topright_xy += s->mb_stride & (((s->current_picture.f.mb_type[top_xy + 1] >> 7) & 1) - 1);
- top_xy += s->mb_stride & (((s->current_picture.f.mb_type[top_xy ] >> 7) & 1) - 1);
+ top_xy += s->mb_stride & (((s->current_picture.f.mb_type[top_xy] >> 7) & 1) - 1);
}
if (left_mb_field_flag != curr_mb_field_flag) {
if (curr_mb_field_flag) {
left_xy[LBOT] += s->mb_stride;
- h->left_block = left_block_options[3];
+ h->left_block = left_block_options[3];
} else {
h->left_block = left_block_options[2];
}
@@ -382,9 +406,9 @@ static void fill_decode_neighbors(H264Context *h, int mb_type){
}
}
- h->topleft_mb_xy = topleft_xy;
- h->top_mb_xy = top_xy;
- h->topright_mb_xy= topright_xy;
+ h->topleft_mb_xy = topleft_xy;
+ h->top_mb_xy = top_xy;
+ h->topright_mb_xy = topright_xy;
h->left_mb_xy[LTOP] = left_xy[LTOP];
h->left_mb_xy[LBOT] = left_xy[LBOT];
//FIXME do we need all in the context?
@@ -395,351 +419,372 @@ static void fill_decode_neighbors(H264Context *h, int mb_type){
h->left_type[LTOP] = s->current_picture.f.mb_type[left_xy[LTOP]];
h->left_type[LBOT] = s->current_picture.f.mb_type[left_xy[LBOT]];
- if(FMO){
- if(h->slice_table[topleft_xy ] != h->slice_num) h->topleft_type = 0;
- if(h->slice_table[top_xy ] != h->slice_num) h->top_type = 0;
- if(h->slice_table[left_xy[LTOP] ] != h->slice_num) h->left_type[LTOP] = h->left_type[LBOT] = 0;
- }else{
- if(h->slice_table[topleft_xy ] != h->slice_num){
+ if (FMO) {
+ if (h->slice_table[topleft_xy] != h->slice_num)
+ h->topleft_type = 0;
+ if (h->slice_table[top_xy] != h->slice_num)
+ h->top_type = 0;
+ if (h->slice_table[left_xy[LTOP]] != h->slice_num)
+ h->left_type[LTOP] = h->left_type[LBOT] = 0;
+ } else {
+ if (h->slice_table[topleft_xy] != h->slice_num) {
h->topleft_type = 0;
- if(h->slice_table[top_xy ] != h->slice_num) h->top_type = 0;
- if(h->slice_table[left_xy[LTOP] ] != h->slice_num) h->left_type[LTOP] = h->left_type[LBOT] = 0;
+ if (h->slice_table[top_xy] != h->slice_num)
+ h->top_type = 0;
+ if (h->slice_table[left_xy[LTOP]] != h->slice_num)
+ h->left_type[LTOP] = h->left_type[LBOT] = 0;
}
}
- if(h->slice_table[topright_xy] != h->slice_num) h->topright_type= 0;
+ if (h->slice_table[topright_xy] != h->slice_num)
+ h->topright_type = 0;
}
-static void fill_decode_caches(H264Context *h, int mb_type){
- MpegEncContext * const s = &h->s;
+static void fill_decode_caches(H264Context *h, int mb_type)
+{
+ MpegEncContext *const s = &h->s;
int topleft_xy, top_xy, topright_xy, left_xy[LEFT_MBS];
int topleft_type, top_type, topright_type, left_type[LEFT_MBS];
- const uint8_t * left_block= h->left_block;
+ const uint8_t *left_block = h->left_block;
int i;
uint8_t *nnz;
uint8_t *nnz_cache;
- topleft_xy = h->topleft_mb_xy;
- top_xy = h->top_mb_xy;
- topright_xy = h->topright_mb_xy;
- left_xy[LTOP] = h->left_mb_xy[LTOP];
- left_xy[LBOT] = h->left_mb_xy[LBOT];
- topleft_type = h->topleft_type;
- top_type = h->top_type;
- topright_type = h->topright_type;
- left_type[LTOP]= h->left_type[LTOP];
- left_type[LBOT]= h->left_type[LBOT];
-
- if(!IS_SKIP(mb_type)){
- if(IS_INTRA(mb_type)){
- int type_mask= h->pps.constrained_intra_pred ? IS_INTRA(-1) : -1;
- h->topleft_samples_available=
- h->top_samples_available=
- h->left_samples_available= 0xFFFF;
- h->topright_samples_available= 0xEEEA;
-
- if(!(top_type & type_mask)){
- h->topleft_samples_available= 0xB3FF;
- h->top_samples_available= 0x33FF;
- h->topright_samples_available= 0x26EA;
+ topleft_xy = h->topleft_mb_xy;
+ top_xy = h->top_mb_xy;
+ topright_xy = h->topright_mb_xy;
+ left_xy[LTOP] = h->left_mb_xy[LTOP];
+ left_xy[LBOT] = h->left_mb_xy[LBOT];
+ topleft_type = h->topleft_type;
+ top_type = h->top_type;
+ topright_type = h->topright_type;
+ left_type[LTOP] = h->left_type[LTOP];
+ left_type[LBOT] = h->left_type[LBOT];
+
+ if (!IS_SKIP(mb_type)) {
+ if (IS_INTRA(mb_type)) {
+ int type_mask = h->pps.constrained_intra_pred ? IS_INTRA(-1) : -1;
+ h->topleft_samples_available =
+ h->top_samples_available =
+ h->left_samples_available = 0xFFFF;
+ h->topright_samples_available = 0xEEEA;
+
+ if (!(top_type & type_mask)) {
+ h->topleft_samples_available = 0xB3FF;
+ h->top_samples_available = 0x33FF;
+ h->topright_samples_available = 0x26EA;
}
- if(IS_INTERLACED(mb_type) != IS_INTERLACED(left_type[LTOP])){
- if(IS_INTERLACED(mb_type)){
- if(!(left_type[LTOP] & type_mask)){
- h->topleft_samples_available&= 0xDFFF;
- h->left_samples_available&= 0x5FFF;
+ if (IS_INTERLACED(mb_type) != IS_INTERLACED(left_type[LTOP])) {
+ if (IS_INTERLACED(mb_type)) {
+ if (!(left_type[LTOP] & type_mask)) {
+ h->topleft_samples_available &= 0xDFFF;
+ h->left_samples_available &= 0x5FFF;
}
- if(!(left_type[LBOT] & type_mask)){
- h->topleft_samples_available&= 0xFF5F;
- h->left_samples_available&= 0xFF5F;
+ if (!(left_type[LBOT] & type_mask)) {
+ h->topleft_samples_available &= 0xFF5F;
+ h->left_samples_available &= 0xFF5F;
}
- }else{
+ } else {
int left_typei = s->current_picture.f.mb_type[left_xy[LTOP] + s->mb_stride];
assert(left_xy[LTOP] == left_xy[LBOT]);
- if(!((left_typei & type_mask) && (left_type[LTOP] & type_mask))){
- h->topleft_samples_available&= 0xDF5F;
- h->left_samples_available&= 0x5F5F;
+ if (!((left_typei & type_mask) && (left_type[LTOP] & type_mask))) {
+ h->topleft_samples_available &= 0xDF5F;
+ h->left_samples_available &= 0x5F5F;
}
}
- }else{
- if(!(left_type[LTOP] & type_mask)){
- h->topleft_samples_available&= 0xDF5F;
- h->left_samples_available&= 0x5F5F;
+ } else {
+ if (!(left_type[LTOP] & type_mask)) {
+ h->topleft_samples_available &= 0xDF5F;
+ h->left_samples_available &= 0x5F5F;
}
}
- if(!(topleft_type & type_mask))
- h->topleft_samples_available&= 0x7FFF;
+ if (!(topleft_type & type_mask))
+ h->topleft_samples_available &= 0x7FFF;
- if(!(topright_type & type_mask))
- h->topright_samples_available&= 0xFBFF;
+ if (!(topright_type & type_mask))
+ h->topright_samples_available &= 0xFBFF;
- if(IS_INTRA4x4(mb_type)){
- if(IS_INTRA4x4(top_type)){
- AV_COPY32(h->intra4x4_pred_mode_cache+4+8*0, h->intra4x4_pred_mode + h->mb2br_xy[top_xy]);
- }else{
- h->intra4x4_pred_mode_cache[4+8*0]=
- h->intra4x4_pred_mode_cache[5+8*0]=
- h->intra4x4_pred_mode_cache[6+8*0]=
- h->intra4x4_pred_mode_cache[7+8*0]= 2 - 3*!(top_type & type_mask);
+ if (IS_INTRA4x4(mb_type)) {
+ if (IS_INTRA4x4(top_type)) {
+ AV_COPY32(h->intra4x4_pred_mode_cache + 4 + 8 * 0, h->intra4x4_pred_mode + h->mb2br_xy[top_xy]);
+ } else {
+ h->intra4x4_pred_mode_cache[4 + 8 * 0] =
+ h->intra4x4_pred_mode_cache[5 + 8 * 0] =
+ h->intra4x4_pred_mode_cache[6 + 8 * 0] =
+ h->intra4x4_pred_mode_cache[7 + 8 * 0] = 2 - 3 * !(top_type & type_mask);
}
- for(i=0; i<2; i++){
- if(IS_INTRA4x4(left_type[LEFT(i)])){
- int8_t *mode= h->intra4x4_pred_mode + h->mb2br_xy[left_xy[LEFT(i)]];
- h->intra4x4_pred_mode_cache[3+8*1 + 2*8*i]= mode[6-left_block[0+2*i]];
- h->intra4x4_pred_mode_cache[3+8*2 + 2*8*i]= mode[6-left_block[1+2*i]];
- }else{
- h->intra4x4_pred_mode_cache[3+8*1 + 2*8*i]=
- h->intra4x4_pred_mode_cache[3+8*2 + 2*8*i]= 2 - 3*!(left_type[LEFT(i)] & type_mask);
+ for (i = 0; i < 2; i++) {
+ if (IS_INTRA4x4(left_type[LEFT(i)])) {
+ int8_t *mode = h->intra4x4_pred_mode + h->mb2br_xy[left_xy[LEFT(i)]];
+ h->intra4x4_pred_mode_cache[3 + 8 * 1 + 2 * 8 * i] = mode[6 - left_block[0 + 2 * i]];
+ h->intra4x4_pred_mode_cache[3 + 8 * 2 + 2 * 8 * i] = mode[6 - left_block[1 + 2 * i]];
+ } else {
+ h->intra4x4_pred_mode_cache[3 + 8 * 1 + 2 * 8 * i] =
+ h->intra4x4_pred_mode_cache[3 + 8 * 2 + 2 * 8 * i] = 2 - 3 * !(left_type[LEFT(i)] & type_mask);
}
}
}
}
-
-/*
-0 . T T. T T T T
-1 L . .L . . . .
-2 L . .L . . . .
-3 . T TL . . . .
-4 L . .L . . . .
-5 L . .. . . . .
-*/
-//FIXME constraint_intra_pred & partitioning & nnz (let us hope this is just a typo in the spec)
- nnz_cache = h->non_zero_count_cache;
- if(top_type){
- nnz = h->non_zero_count[top_xy];
- AV_COPY32(&nnz_cache[4+8* 0], &nnz[4*3]);
- if(!s->chroma_y_shift){
- AV_COPY32(&nnz_cache[4+8* 5], &nnz[4* 7]);
- AV_COPY32(&nnz_cache[4+8*10], &nnz[4*11]);
- }else{
- AV_COPY32(&nnz_cache[4+8* 5], &nnz[4* 5]);
- AV_COPY32(&nnz_cache[4+8*10], &nnz[4* 9]);
+ /*
+ * 0 . T T. T T T T
+ * 1 L . .L . . . .
+ * 2 L . .L . . . .
+ * 3 . T TL . . . .
+ * 4 L . .L . . . .
+ * 5 L . .. . . . .
+ */
+ /* FIXME: constraint_intra_pred & partitioning & nnz
+ * (let us hope this is just a typo in the spec) */
+ nnz_cache = h->non_zero_count_cache;
+ if (top_type) {
+ nnz = h->non_zero_count[top_xy];
+ AV_COPY32(&nnz_cache[4 + 8 * 0], &nnz[4 * 3]);
+ if (!s->chroma_y_shift) {
+ AV_COPY32(&nnz_cache[4 + 8 * 5], &nnz[4 * 7]);
+ AV_COPY32(&nnz_cache[4 + 8 * 10], &nnz[4 * 11]);
+ } else {
+ AV_COPY32(&nnz_cache[4 + 8 * 5], &nnz[4 * 5]);
+ AV_COPY32(&nnz_cache[4 + 8 * 10], &nnz[4 * 9]);
+ }
+ } else {
+ uint32_t top_empty = CABAC && !IS_INTRA(mb_type) ? 0 : 0x40404040;
+ AV_WN32A(&nnz_cache[4 + 8 * 0], top_empty);
+ AV_WN32A(&nnz_cache[4 + 8 * 5], top_empty);
+ AV_WN32A(&nnz_cache[4 + 8 * 10], top_empty);
}
- }else{
- uint32_t top_empty = CABAC && !IS_INTRA(mb_type) ? 0 : 0x40404040;
- AV_WN32A(&nnz_cache[4+8* 0], top_empty);
- AV_WN32A(&nnz_cache[4+8* 5], top_empty);
- AV_WN32A(&nnz_cache[4+8*10], top_empty);
- }
- for (i=0; i<2; i++) {
- if(left_type[LEFT(i)]){
- nnz = h->non_zero_count[left_xy[LEFT(i)]];
- nnz_cache[3+8* 1 + 2*8*i]= nnz[left_block[8+0+2*i]];
- nnz_cache[3+8* 2 + 2*8*i]= nnz[left_block[8+1+2*i]];
- if(CHROMA444){
- nnz_cache[3+8* 6 + 2*8*i]= nnz[left_block[8+0+2*i]+4*4];
- nnz_cache[3+8* 7 + 2*8*i]= nnz[left_block[8+1+2*i]+4*4];
- nnz_cache[3+8*11 + 2*8*i]= nnz[left_block[8+0+2*i]+8*4];
- nnz_cache[3+8*12 + 2*8*i]= nnz[left_block[8+1+2*i]+8*4];
- }else if(CHROMA422) {
- nnz_cache[3+8* 6 + 2*8*i]= nnz[left_block[8+0+2*i]-2+4*4];
- nnz_cache[3+8* 7 + 2*8*i]= nnz[left_block[8+1+2*i]-2+4*4];
- nnz_cache[3+8*11 + 2*8*i]= nnz[left_block[8+0+2*i]-2+8*4];
- nnz_cache[3+8*12 + 2*8*i]= nnz[left_block[8+1+2*i]-2+8*4];
- }else{
- nnz_cache[3+8* 6 + 8*i]= nnz[left_block[8+4+2*i]];
- nnz_cache[3+8*11 + 8*i]= nnz[left_block[8+5+2*i]];
+ for (i = 0; i < 2; i++) {
+ if (left_type[LEFT(i)]) {
+ nnz = h->non_zero_count[left_xy[LEFT(i)]];
+ nnz_cache[3 + 8 * 1 + 2 * 8 * i] = nnz[left_block[8 + 0 + 2 * i]];
+ nnz_cache[3 + 8 * 2 + 2 * 8 * i] = nnz[left_block[8 + 1 + 2 * i]];
+ if (CHROMA444) {
+ nnz_cache[3 + 8 * 6 + 2 * 8 * i] = nnz[left_block[8 + 0 + 2 * i] + 4 * 4];
+ nnz_cache[3 + 8 * 7 + 2 * 8 * i] = nnz[left_block[8 + 1 + 2 * i] + 4 * 4];
+ nnz_cache[3 + 8 * 11 + 2 * 8 * i] = nnz[left_block[8 + 0 + 2 * i] + 8 * 4];
+ nnz_cache[3 + 8 * 12 + 2 * 8 * i] = nnz[left_block[8 + 1 + 2 * i] + 8 * 4];
+ } else if (CHROMA422) {
+ nnz_cache[3 + 8 * 6 + 2 * 8 * i] = nnz[left_block[8 + 0 + 2 * i] - 2 + 4 * 4];
+ nnz_cache[3 + 8 * 7 + 2 * 8 * i] = nnz[left_block[8 + 1 + 2 * i] - 2 + 4 * 4];
+ nnz_cache[3 + 8 * 11 + 2 * 8 * i] = nnz[left_block[8 + 0 + 2 * i] - 2 + 8 * 4];
+ nnz_cache[3 + 8 * 12 + 2 * 8 * i] = nnz[left_block[8 + 1 + 2 * i] - 2 + 8 * 4];
+ } else {
+ nnz_cache[3 + 8 * 6 + 8 * i] = nnz[left_block[8 + 4 + 2 * i]];
+ nnz_cache[3 + 8 * 11 + 8 * i] = nnz[left_block[8 + 5 + 2 * i]];
+ }
+ } else {
+ nnz_cache[3 + 8 * 1 + 2 * 8 * i] =
+ nnz_cache[3 + 8 * 2 + 2 * 8 * i] =
+ nnz_cache[3 + 8 * 6 + 2 * 8 * i] =
+ nnz_cache[3 + 8 * 7 + 2 * 8 * i] =
+ nnz_cache[3 + 8 * 11 + 2 * 8 * i] =
+ nnz_cache[3 + 8 * 12 + 2 * 8 * i] = CABAC && !IS_INTRA(mb_type) ? 0 : 64;
}
- }else{
- nnz_cache[3+8* 1 + 2*8*i]=
- nnz_cache[3+8* 2 + 2*8*i]=
- nnz_cache[3+8* 6 + 2*8*i]=
- nnz_cache[3+8* 7 + 2*8*i]=
- nnz_cache[3+8*11 + 2*8*i]=
- nnz_cache[3+8*12 + 2*8*i]= CABAC && !IS_INTRA(mb_type) ? 0 : 64;
}
- }
- if( CABAC ) {
- // top_cbp
- if(top_type) {
- h->top_cbp = h->cbp_table[top_xy];
- } else {
- h->top_cbp = IS_INTRA(mb_type) ? 0x7CF : 0x00F;
- }
- // left_cbp
- if (left_type[LTOP]) {
- h->left_cbp = (h->cbp_table[left_xy[LTOP]] & 0x7F0)
- | ((h->cbp_table[left_xy[LTOP]]>>(left_block[0]&(~1)))&2)
- | (((h->cbp_table[left_xy[LBOT]]>>(left_block[2]&(~1)))&2) << 2);
- } else {
- h->left_cbp = IS_INTRA(mb_type) ? 0x7CF : 0x00F;
+ if (CABAC) {
+ // top_cbp
+ if (top_type)
+ h->top_cbp = h->cbp_table[top_xy];
+ else
+ h->top_cbp = IS_INTRA(mb_type) ? 0x7CF : 0x00F;
+ // left_cbp
+ if (left_type[LTOP]) {
+ h->left_cbp = (h->cbp_table[left_xy[LTOP]] & 0x7F0) |
+ ((h->cbp_table[left_xy[LTOP]] >> (left_block[0] & (~1))) & 2) |
+ (((h->cbp_table[left_xy[LBOT]] >> (left_block[2] & (~1))) & 2) << 2);
+ } else {
+ h->left_cbp = IS_INTRA(mb_type) ? 0x7CF : 0x00F;
+ }
}
}
- }
- if(IS_INTER(mb_type) || (IS_DIRECT(mb_type) && h->direct_spatial_mv_pred)){
+ if (IS_INTER(mb_type) || (IS_DIRECT(mb_type) && h->direct_spatial_mv_pred)) {
int list;
int b_stride = h->b_stride;
- for(list=0; list<h->list_count; list++){
+ for (list = 0; list < h->list_count; list++) {
int8_t *ref_cache = &h->ref_cache[list][scan8[0]];
int8_t *ref = s->current_picture.f.ref_index[list];
- int16_t (*mv_cache)[2] = &h->mv_cache[list][scan8[0]];
- int16_t (*mv)[2] = s->current_picture.f.motion_val[list];
- if(!USES_LIST(mb_type, list)){
+ int16_t(*mv_cache)[2] = &h->mv_cache[list][scan8[0]];
+ int16_t(*mv)[2] = s->current_picture.f.motion_val[list];
+ if (!USES_LIST(mb_type, list))
continue;
- }
assert(!(IS_DIRECT(mb_type) && !h->direct_spatial_mv_pred));
- if(USES_LIST(top_type, list)){
- const int b_xy= h->mb2b_xy[top_xy] + 3*b_stride;
- AV_COPY128(mv_cache[0 - 1*8], mv[b_xy + 0]);
- ref_cache[0 - 1*8]=
- ref_cache[1 - 1*8]= ref[4*top_xy + 2];
- ref_cache[2 - 1*8]=
- ref_cache[3 - 1*8]= ref[4*top_xy + 3];
- }else{
- AV_ZERO128(mv_cache[0 - 1*8]);
- AV_WN32A(&ref_cache[0 - 1*8], ((top_type ? LIST_NOT_USED : PART_NOT_AVAILABLE)&0xFF)*0x01010101u);
+ if (USES_LIST(top_type, list)) {
+ const int b_xy = h->mb2b_xy[top_xy] + 3 * b_stride;
+ AV_COPY128(mv_cache[0 - 1 * 8], mv[b_xy + 0]);
+ ref_cache[0 - 1 * 8] =
+ ref_cache[1 - 1 * 8] = ref[4 * top_xy + 2];
+ ref_cache[2 - 1 * 8] =
+ ref_cache[3 - 1 * 8] = ref[4 * top_xy + 3];
+ } else {
+ AV_ZERO128(mv_cache[0 - 1 * 8]);
+ AV_WN32A(&ref_cache[0 - 1 * 8],
+ ((top_type ? LIST_NOT_USED : PART_NOT_AVAILABLE) & 0xFF) * 0x01010101u);
}
- if(mb_type & (MB_TYPE_16x8|MB_TYPE_8x8)){
- for(i=0; i<2; i++){
- int cache_idx = -1 + i*2*8;
- if(USES_LIST(left_type[LEFT(i)], list)){
- const int b_xy= h->mb2b_xy[left_xy[LEFT(i)]] + 3;
- const int b8_xy= 4*left_xy[LEFT(i)] + 1;
- AV_COPY32(mv_cache[cache_idx ], mv[b_xy + b_stride*left_block[0+i*2]]);
- AV_COPY32(mv_cache[cache_idx+8], mv[b_xy + b_stride*left_block[1+i*2]]);
- ref_cache[cache_idx ]= ref[b8_xy + (left_block[0+i*2]&~1)];
- ref_cache[cache_idx+8]= ref[b8_xy + (left_block[1+i*2]&~1)];
- }else{
- AV_ZERO32(mv_cache[cache_idx ]);
- AV_ZERO32(mv_cache[cache_idx+8]);
- ref_cache[cache_idx ]=
- ref_cache[cache_idx+8]= (left_type[LEFT(i)]) ? LIST_NOT_USED : PART_NOT_AVAILABLE;
+ if (mb_type & (MB_TYPE_16x8 | MB_TYPE_8x8)) {
+ for (i = 0; i < 2; i++) {
+ int cache_idx = -1 + i * 2 * 8;
+ if (USES_LIST(left_type[LEFT(i)], list)) {
+ const int b_xy = h->mb2b_xy[left_xy[LEFT(i)]] + 3;
+ const int b8_xy = 4 * left_xy[LEFT(i)] + 1;
+ AV_COPY32(mv_cache[cache_idx],
+ mv[b_xy + b_stride * left_block[0 + i * 2]]);
+ AV_COPY32(mv_cache[cache_idx + 8],
+ mv[b_xy + b_stride * left_block[1 + i * 2]]);
+ ref_cache[cache_idx] = ref[b8_xy + (left_block[0 + i * 2] & ~1)];
+ ref_cache[cache_idx + 8] = ref[b8_xy + (left_block[1 + i * 2] & ~1)];
+ } else {
+ AV_ZERO32(mv_cache[cache_idx]);
+ AV_ZERO32(mv_cache[cache_idx + 8]);
+ ref_cache[cache_idx] =
+ ref_cache[cache_idx + 8] = (left_type[LEFT(i)]) ? LIST_NOT_USED
+ : PART_NOT_AVAILABLE;
+ }
}
- }
- }else{
- if(USES_LIST(left_type[LTOP], list)){
- const int b_xy= h->mb2b_xy[left_xy[LTOP]] + 3;
- const int b8_xy= 4*left_xy[LTOP] + 1;
- AV_COPY32(mv_cache[-1], mv[b_xy + b_stride*left_block[0]]);
- ref_cache[-1]= ref[b8_xy + (left_block[0]&~1)];
- }else{
+ } else {
+ if (USES_LIST(left_type[LTOP], list)) {
+ const int b_xy = h->mb2b_xy[left_xy[LTOP]] + 3;
+ const int b8_xy = 4 * left_xy[LTOP] + 1;
+ AV_COPY32(mv_cache[-1], mv[b_xy + b_stride * left_block[0]]);
+ ref_cache[-1] = ref[b8_xy + (left_block[0] & ~1)];
+ } else {
AV_ZERO32(mv_cache[-1]);
- ref_cache[-1]= left_type[LTOP] ? LIST_NOT_USED : PART_NOT_AVAILABLE;
+ ref_cache[-1] = left_type[LTOP] ? LIST_NOT_USED
+ : PART_NOT_AVAILABLE;
}
}
- if(USES_LIST(topright_type, list)){
- const int b_xy= h->mb2b_xy[topright_xy] + 3*b_stride;
- AV_COPY32(mv_cache[4 - 1*8], mv[b_xy]);
- ref_cache[4 - 1*8]= ref[4*topright_xy + 2];
- }else{
- AV_ZERO32(mv_cache[4 - 1*8]);
- ref_cache[4 - 1*8]= topright_type ? LIST_NOT_USED : PART_NOT_AVAILABLE;
+ if (USES_LIST(topright_type, list)) {
+ const int b_xy = h->mb2b_xy[topright_xy] + 3 * b_stride;
+ AV_COPY32(mv_cache[4 - 1 * 8], mv[b_xy]);
+ ref_cache[4 - 1 * 8] = ref[4 * topright_xy + 2];
+ } else {
+ AV_ZERO32(mv_cache[4 - 1 * 8]);
+ ref_cache[4 - 1 * 8] = topright_type ? LIST_NOT_USED
+ : PART_NOT_AVAILABLE;
}
- if(ref_cache[4 - 1*8] < 0){
- if(USES_LIST(topleft_type, list)){
- const int b_xy = h->mb2b_xy[topleft_xy] + 3 + b_stride + (h->topleft_partition & 2*b_stride);
- const int b8_xy= 4*topleft_xy + 1 + (h->topleft_partition & 2);
- AV_COPY32(mv_cache[-1 - 1*8], mv[b_xy]);
- ref_cache[-1 - 1*8]= ref[b8_xy];
- }else{
- AV_ZERO32(mv_cache[-1 - 1*8]);
- ref_cache[-1 - 1*8]= topleft_type ? LIST_NOT_USED : PART_NOT_AVAILABLE;
+ if (ref_cache[4 - 1 * 8] < 0) {
+ if (USES_LIST(topleft_type, list)) {
+ const int b_xy = h->mb2b_xy[topleft_xy] + 3 + b_stride +
+ (h->topleft_partition & 2 * b_stride);
+ const int b8_xy = 4 * topleft_xy + 1 + (h->topleft_partition & 2);
+ AV_COPY32(mv_cache[-1 - 1 * 8], mv[b_xy]);
+ ref_cache[-1 - 1 * 8] = ref[b8_xy];
+ } else {
+ AV_ZERO32(mv_cache[-1 - 1 * 8]);
+ ref_cache[-1 - 1 * 8] = topleft_type ? LIST_NOT_USED
+ : PART_NOT_AVAILABLE;
}
}
- if((mb_type&(MB_TYPE_SKIP|MB_TYPE_DIRECT2)) && !FRAME_MBAFF)
+ if ((mb_type & (MB_TYPE_SKIP | MB_TYPE_DIRECT2)) && !FRAME_MBAFF)
continue;
- if(!(mb_type&(MB_TYPE_SKIP|MB_TYPE_DIRECT2))){
- uint8_t (*mvd_cache)[2] = &h->mvd_cache[list][scan8[0]];
- uint8_t (*mvd)[2] = h->mvd_table[list];
- ref_cache[2+8*0] =
- ref_cache[2+8*2] = PART_NOT_AVAILABLE;
- AV_ZERO32(mv_cache[2+8*0]);
- AV_ZERO32(mv_cache[2+8*2]);
-
- if( CABAC ) {
- if(USES_LIST(top_type, list)){
- const int b_xy= h->mb2br_xy[top_xy];
- AV_COPY64(mvd_cache[0 - 1*8], mvd[b_xy + 0]);
- }else{
- AV_ZERO64(mvd_cache[0 - 1*8]);
+ if (!(mb_type & (MB_TYPE_SKIP | MB_TYPE_DIRECT2))) {
+ uint8_t(*mvd_cache)[2] = &h->mvd_cache[list][scan8[0]];
+ uint8_t(*mvd)[2] = h->mvd_table[list];
+ ref_cache[2 + 8 * 0] =
+ ref_cache[2 + 8 * 2] = PART_NOT_AVAILABLE;
+ AV_ZERO32(mv_cache[2 + 8 * 0]);
+ AV_ZERO32(mv_cache[2 + 8 * 2]);
+
+ if (CABAC) {
+ if (USES_LIST(top_type, list)) {
+ const int b_xy = h->mb2br_xy[top_xy];
+ AV_COPY64(mvd_cache[0 - 1 * 8], mvd[b_xy + 0]);
+ } else {
+ AV_ZERO64(mvd_cache[0 - 1 * 8]);
}
- if(USES_LIST(left_type[LTOP], list)){
- const int b_xy= h->mb2br_xy[left_xy[LTOP]] + 6;
- AV_COPY16(mvd_cache[-1 + 0*8], mvd[b_xy - left_block[0]]);
- AV_COPY16(mvd_cache[-1 + 1*8], mvd[b_xy - left_block[1]]);
- }else{
- AV_ZERO16(mvd_cache[-1 + 0*8]);
- AV_ZERO16(mvd_cache[-1 + 1*8]);
+ if (USES_LIST(left_type[LTOP], list)) {
+ const int b_xy = h->mb2br_xy[left_xy[LTOP]] + 6;
+ AV_COPY16(mvd_cache[-1 + 0 * 8], mvd[b_xy - left_block[0]]);
+ AV_COPY16(mvd_cache[-1 + 1 * 8], mvd[b_xy - left_block[1]]);
+ } else {
+ AV_ZERO16(mvd_cache[-1 + 0 * 8]);
+ AV_ZERO16(mvd_cache[-1 + 1 * 8]);
}
- if(USES_LIST(left_type[LBOT], list)){
- const int b_xy= h->mb2br_xy[left_xy[LBOT]] + 6;
- AV_COPY16(mvd_cache[-1 + 2*8], mvd[b_xy - left_block[2]]);
- AV_COPY16(mvd_cache[-1 + 3*8], mvd[b_xy - left_block[3]]);
- }else{
- AV_ZERO16(mvd_cache[-1 + 2*8]);
- AV_ZERO16(mvd_cache[-1 + 3*8]);
+ if (USES_LIST(left_type[LBOT], list)) {
+ const int b_xy = h->mb2br_xy[left_xy[LBOT]] + 6;
+ AV_COPY16(mvd_cache[-1 + 2 * 8], mvd[b_xy - left_block[2]]);
+ AV_COPY16(mvd_cache[-1 + 3 * 8], mvd[b_xy - left_block[3]]);
+ } else {
+ AV_ZERO16(mvd_cache[-1 + 2 * 8]);
+ AV_ZERO16(mvd_cache[-1 + 3 * 8]);
}
- AV_ZERO16(mvd_cache[2+8*0]);
- AV_ZERO16(mvd_cache[2+8*2]);
- if(h->slice_type_nos == AV_PICTURE_TYPE_B){
+ AV_ZERO16(mvd_cache[2 + 8 * 0]);
+ AV_ZERO16(mvd_cache[2 + 8 * 2]);
+ if (h->slice_type_nos == AV_PICTURE_TYPE_B) {
uint8_t *direct_cache = &h->direct_cache[scan8[0]];
uint8_t *direct_table = h->direct_table;
- fill_rectangle(direct_cache, 4, 4, 8, MB_TYPE_16x16>>1, 1);
-
- if(IS_DIRECT(top_type)){
- AV_WN32A(&direct_cache[-1*8], 0x01010101u*(MB_TYPE_DIRECT2>>1));
- }else if(IS_8X8(top_type)){
- int b8_xy = 4*top_xy;
- direct_cache[0 - 1*8]= direct_table[b8_xy + 2];
- direct_cache[2 - 1*8]= direct_table[b8_xy + 3];
- }else{
- AV_WN32A(&direct_cache[-1*8], 0x01010101*(MB_TYPE_16x16>>1));
+ fill_rectangle(direct_cache, 4, 4, 8, MB_TYPE_16x16 >> 1, 1);
+
+ if (IS_DIRECT(top_type)) {
+ AV_WN32A(&direct_cache[-1 * 8],
+ 0x01010101u * (MB_TYPE_DIRECT2 >> 1));
+ } else if (IS_8X8(top_type)) {
+ int b8_xy = 4 * top_xy;
+ direct_cache[0 - 1 * 8] = direct_table[b8_xy + 2];
+ direct_cache[2 - 1 * 8] = direct_table[b8_xy + 3];
+ } else {
+ AV_WN32A(&direct_cache[-1 * 8],
+ 0x01010101 * (MB_TYPE_16x16 >> 1));
}
- if(IS_DIRECT(left_type[LTOP]))
- direct_cache[-1 + 0*8]= MB_TYPE_DIRECT2>>1;
- else if(IS_8X8(left_type[LTOP]))
- direct_cache[-1 + 0*8]= direct_table[4*left_xy[LTOP] + 1 + (left_block[0]&~1)];
+ if (IS_DIRECT(left_type[LTOP]))
+ direct_cache[-1 + 0 * 8] = MB_TYPE_DIRECT2 >> 1;
+ else if (IS_8X8(left_type[LTOP]))
+ direct_cache[-1 + 0 * 8] = direct_table[4 * left_xy[LTOP] + 1 + (left_block[0] & ~1)];
else
- direct_cache[-1 + 0*8]= MB_TYPE_16x16>>1;
+ direct_cache[-1 + 0 * 8] = MB_TYPE_16x16 >> 1;
- if(IS_DIRECT(left_type[LBOT]))
- direct_cache[-1 + 2*8]= MB_TYPE_DIRECT2>>1;
- else if(IS_8X8(left_type[LBOT]))
- direct_cache[-1 + 2*8]= direct_table[4*left_xy[LBOT] + 1 + (left_block[2]&~1)];
+ if (IS_DIRECT(left_type[LBOT]))
+ direct_cache[-1 + 2 * 8] = MB_TYPE_DIRECT2 >> 1;
+ else if (IS_8X8(left_type[LBOT]))
+ direct_cache[-1 + 2 * 8] = direct_table[4 * left_xy[LBOT] + 1 + (left_block[2] & ~1)];
else
- direct_cache[-1 + 2*8]= MB_TYPE_16x16>>1;
+ direct_cache[-1 + 2 * 8] = MB_TYPE_16x16 >> 1;
}
}
}
- if(FRAME_MBAFF){
-#define MAP_MVS\
- MAP_F2F(scan8[0] - 1 - 1*8, topleft_type)\
- MAP_F2F(scan8[0] + 0 - 1*8, top_type)\
- MAP_F2F(scan8[0] + 1 - 1*8, top_type)\
- MAP_F2F(scan8[0] + 2 - 1*8, top_type)\
- MAP_F2F(scan8[0] + 3 - 1*8, top_type)\
- MAP_F2F(scan8[0] + 4 - 1*8, topright_type)\
- MAP_F2F(scan8[0] - 1 + 0*8, left_type[LTOP])\
- MAP_F2F(scan8[0] - 1 + 1*8, left_type[LTOP])\
- MAP_F2F(scan8[0] - 1 + 2*8, left_type[LBOT])\
- MAP_F2F(scan8[0] - 1 + 3*8, left_type[LBOT])
- if(MB_FIELD){
-#define MAP_F2F(idx, mb_type)\
- if(!IS_INTERLACED(mb_type) && h->ref_cache[list][idx] >= 0){\
- h->ref_cache[list][idx] <<= 1;\
- h->mv_cache[list][idx][1] /= 2;\
- h->mvd_cache[list][idx][1] >>=1;\
- }
+
+#define MAP_MVS \
+ MAP_F2F(scan8[0] - 1 - 1 * 8, topleft_type) \
+ MAP_F2F(scan8[0] + 0 - 1 * 8, top_type) \
+ MAP_F2F(scan8[0] + 1 - 1 * 8, top_type) \
+ MAP_F2F(scan8[0] + 2 - 1 * 8, top_type) \
+ MAP_F2F(scan8[0] + 3 - 1 * 8, top_type) \
+ MAP_F2F(scan8[0] + 4 - 1 * 8, topright_type) \
+ MAP_F2F(scan8[0] - 1 + 0 * 8, left_type[LTOP]) \
+ MAP_F2F(scan8[0] - 1 + 1 * 8, left_type[LTOP]) \
+ MAP_F2F(scan8[0] - 1 + 2 * 8, left_type[LBOT]) \
+ MAP_F2F(scan8[0] - 1 + 3 * 8, left_type[LBOT])
+
+ if (FRAME_MBAFF) {
+ if (MB_FIELD) {
+
+#define MAP_F2F(idx, mb_type) \
+ if (!IS_INTERLACED(mb_type) && h->ref_cache[list][idx] >= 0) { \
+ h->ref_cache[list][idx] <<= 1; \
+ h->mv_cache[list][idx][1] /= 2; \
+ h->mvd_cache[list][idx][1] >>= 1; \
+ }
+
MAP_MVS
+ } else {
+
#undef MAP_F2F
- }else{
-#define MAP_F2F(idx, mb_type)\
- if(IS_INTERLACED(mb_type) && h->ref_cache[list][idx] >= 0){\
- h->ref_cache[list][idx] >>= 1;\
- h->mv_cache[list][idx][1] <<= 1;\
- h->mvd_cache[list][idx][1] <<= 1;\
- }
+#define MAP_F2F(idx, mb_type) \
+ if (IS_INTERLACED(mb_type) && h->ref_cache[list][idx] >= 0) { \
+ h->ref_cache[list][idx] >>= 1; \
+ h->mv_cache[list][idx][1] <<= 1; \
+ h->mvd_cache[list][idx][1] <<= 1; \
+ }
+
MAP_MVS
#undef MAP_F2F
}
@@ -747,36 +792,34 @@ static void fill_decode_caches(H264Context *h, int mb_type){
}
}
- h->neighbor_transform_size= !!IS_8x8DCT(top_type) + !!IS_8x8DCT(left_type[LTOP]);
+ h->neighbor_transform_size = !!IS_8x8DCT(top_type) + !!IS_8x8DCT(left_type[LTOP]);
}
/**
* decodes a P_SKIP or B_SKIP macroblock
*/
-static void av_unused decode_mb_skip(H264Context *h){
- MpegEncContext * const s = &h->s;
- const int mb_xy= h->mb_xy;
- int mb_type=0;
+static void av_unused decode_mb_skip(H264Context *h)
+{
+ MpegEncContext *const s = &h->s;
+ const int mb_xy = h->mb_xy;
+ int mb_type = 0;
memset(h->non_zero_count[mb_xy], 0, 48);
- if(MB_FIELD)
- mb_type|= MB_TYPE_INTERLACED;
+ if (MB_FIELD)
+ mb_type |= MB_TYPE_INTERLACED;
- if( h->slice_type_nos == AV_PICTURE_TYPE_B )
- {
+ if (h->slice_type_nos == AV_PICTURE_TYPE_B) {
// just for fill_caches. pred_direct_motion will set the real mb_type
- mb_type|= MB_TYPE_L0L1|MB_TYPE_DIRECT2|MB_TYPE_SKIP;
- if(h->direct_spatial_mv_pred){
+ mb_type |= MB_TYPE_L0L1 | MB_TYPE_DIRECT2 | MB_TYPE_SKIP;
+ if (h->direct_spatial_mv_pred) {
fill_decode_neighbors(h, mb_type);
- fill_decode_caches(h, mb_type); //FIXME check what is needed and what not ...
+ fill_decode_caches(h, mb_type); //FIXME check what is needed and what not ...
}
ff_h264_pred_direct_motion(h, &mb_type);
- mb_type|= MB_TYPE_SKIP;
- }
- else
- {
- mb_type|= MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P1L0|MB_TYPE_SKIP;
+ mb_type |= MB_TYPE_SKIP;
+ } else {
+ mb_type |= MB_TYPE_16x16 | MB_TYPE_P0L0 | MB_TYPE_P1L0 | MB_TYPE_SKIP;
fill_decode_neighbors(h, mb_type);
pred_pskip_motion(h);
@@ -785,8 +828,8 @@ static void av_unused decode_mb_skip(H264Context *h){
write_back_motion(h, mb_type);
s->current_picture.f.mb_type[mb_xy] = mb_type;
s->current_picture.f.qscale_table[mb_xy] = s->qscale;
- h->slice_table[ mb_xy ]= h->slice_num;
- h->prev_mb_skipped= 1;
+ h->slice_table[mb_xy] = h->slice_num;
+ h->prev_mb_skipped = 1;
}
#endif /* AVCODEC_H264_MVPRED_H */
diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c
index 354469c..3f53af8 100644
--- a/libavcodec/h264_ps.c
+++ b/libavcodec/h264_ps.c
@@ -475,6 +475,9 @@ int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length){
if(pps_id >= MAX_PPS_COUNT) {
av_log(h->s.avctx, AV_LOG_ERROR, "pps_id (%d) out of range\n", pps_id);
return -1;
+ } else if (h->sps.bit_depth_luma > 10) {
+ av_log(h->s.avctx, AV_LOG_ERROR, "Unimplemented luma bit depth=%d (max=10)\n", h->sps.bit_depth_luma);
+ return AVERROR_PATCHWELCOME;
}
pps= av_mallocz(sizeof(PPS));
diff --git a/libavcodec/h264data.h b/libavcodec/h264data.h
index 2cfa548..5311c21 100644
--- a/libavcodec/h264data.h
+++ b/libavcodec/h264data.h
@@ -30,240 +30,243 @@
#define AVCODEC_H264DATA_H
#include <stdint.h>
+
#include "libavutil/rational.h"
#include "mpegvideo.h"
#include "h264.h"
+static const uint8_t golomb_to_pict_type[5] = {
+ AV_PICTURE_TYPE_P, AV_PICTURE_TYPE_B, AV_PICTURE_TYPE_I,
+ AV_PICTURE_TYPE_SP, AV_PICTURE_TYPE_SI
+};
-static const uint8_t golomb_to_pict_type[5]=
-{AV_PICTURE_TYPE_P, AV_PICTURE_TYPE_B, AV_PICTURE_TYPE_I, AV_PICTURE_TYPE_SP, AV_PICTURE_TYPE_SI};
-
-static const uint8_t golomb_to_intra4x4_cbp[48]={
- 47, 31, 15, 0, 23, 27, 29, 30, 7, 11, 13, 14, 39, 43, 45, 46,
- 16, 3, 5, 10, 12, 19, 21, 26, 28, 35, 37, 42, 44, 1, 2, 4,
- 8, 17, 18, 20, 24, 6, 9, 22, 25, 32, 33, 34, 36, 40, 38, 41
+static const uint8_t golomb_to_intra4x4_cbp[48] = {
+ 47, 31, 15, 0, 23, 27, 29, 30, 7, 11, 13, 14, 39, 43, 45, 46,
+ 16, 3, 5, 10, 12, 19, 21, 26, 28, 35, 37, 42, 44, 1, 2, 4,
+ 8, 17, 18, 20, 24, 6, 9, 22, 25, 32, 33, 34, 36, 40, 38, 41
};
-static const uint8_t golomb_to_inter_cbp[48]={
- 0, 16, 1, 2, 4, 8, 32, 3, 5, 10, 12, 15, 47, 7, 11, 13,
- 14, 6, 9, 31, 35, 37, 42, 44, 33, 34, 36, 40, 39, 43, 45, 46,
- 17, 18, 20, 24, 19, 21, 26, 28, 23, 27, 29, 30, 22, 25, 38, 41
+static const uint8_t golomb_to_inter_cbp[48] = {
+ 0, 16, 1, 2, 4, 8, 32, 3, 5, 10, 12, 15, 47, 7, 11, 13,
+ 14, 6, 9, 31, 35, 37, 42, 44, 33, 34, 36, 40, 39, 43, 45, 46,
+ 17, 18, 20, 24, 19, 21, 26, 28, 23, 27, 29, 30, 22, 25, 38, 41
};
-static const uint8_t zigzag_scan[16]={
- 0+0*4, 1+0*4, 0+1*4, 0+2*4,
- 1+1*4, 2+0*4, 3+0*4, 2+1*4,
- 1+2*4, 0+3*4, 1+3*4, 2+2*4,
- 3+1*4, 3+2*4, 2+3*4, 3+3*4,
+static const uint8_t zigzag_scan[16] = {
+ 0 + 0 * 4, 1 + 0 * 4, 0 + 1 * 4, 0 + 2 * 4,
+ 1 + 1 * 4, 2 + 0 * 4, 3 + 0 * 4, 2 + 1 * 4,
+ 1 + 2 * 4, 0 + 3 * 4, 1 + 3 * 4, 2 + 2 * 4,
+ 3 + 1 * 4, 3 + 2 * 4, 2 + 3 * 4, 3 + 3 * 4,
};
-static const uint8_t field_scan[16]={
- 0+0*4, 0+1*4, 1+0*4, 0+2*4,
- 0+3*4, 1+1*4, 1+2*4, 1+3*4,
- 2+0*4, 2+1*4, 2+2*4, 2+3*4,
- 3+0*4, 3+1*4, 3+2*4, 3+3*4,
+static const uint8_t field_scan[16] = {
+ 0 + 0 * 4, 0 + 1 * 4, 1 + 0 * 4, 0 + 2 * 4,
+ 0 + 3 * 4, 1 + 1 * 4, 1 + 2 * 4, 1 + 3 * 4,
+ 2 + 0 * 4, 2 + 1 * 4, 2 + 2 * 4, 2 + 3 * 4,
+ 3 + 0 * 4, 3 + 1 * 4, 3 + 2 * 4, 3 + 3 * 4,
};
-static const uint8_t luma_dc_zigzag_scan[16]={
- 0*16 + 0*64, 1*16 + 0*64, 2*16 + 0*64, 0*16 + 2*64,
- 3*16 + 0*64, 0*16 + 1*64, 1*16 + 1*64, 2*16 + 1*64,
- 1*16 + 2*64, 2*16 + 2*64, 3*16 + 2*64, 0*16 + 3*64,
- 3*16 + 1*64, 1*16 + 3*64, 2*16 + 3*64, 3*16 + 3*64,
+static const uint8_t luma_dc_zigzag_scan[16] = {
+ 0 * 16 + 0 * 64, 1 * 16 + 0 * 64, 2 * 16 + 0 * 64, 0 * 16 + 2 * 64,
+ 3 * 16 + 0 * 64, 0 * 16 + 1 * 64, 1 * 16 + 1 * 64, 2 * 16 + 1 * 64,
+ 1 * 16 + 2 * 64, 2 * 16 + 2 * 64, 3 * 16 + 2 * 64, 0 * 16 + 3 * 64,
+ 3 * 16 + 1 * 64, 1 * 16 + 3 * 64, 2 * 16 + 3 * 64, 3 * 16 + 3 * 64,
};
-static const uint8_t luma_dc_field_scan[16]={
- 0*16 + 0*64, 2*16 + 0*64, 1*16 + 0*64, 0*16 + 2*64,
- 2*16 + 2*64, 3*16 + 0*64, 1*16 + 2*64, 3*16 + 2*64,
- 0*16 + 1*64, 2*16 + 1*64, 0*16 + 3*64, 2*16 + 3*64,
- 1*16 + 1*64, 3*16 + 1*64, 1*16 + 3*64, 3*16 + 3*64,
+static const uint8_t luma_dc_field_scan[16] = {
+ 0 * 16 + 0 * 64, 2 * 16 + 0 * 64, 1 * 16 + 0 * 64, 0 * 16 + 2 * 64,
+ 2 * 16 + 2 * 64, 3 * 16 + 0 * 64, 1 * 16 + 2 * 64, 3 * 16 + 2 * 64,
+ 0 * 16 + 1 * 64, 2 * 16 + 1 * 64, 0 * 16 + 3 * 64, 2 * 16 + 3 * 64,
+ 1 * 16 + 1 * 64, 3 * 16 + 1 * 64, 1 * 16 + 3 * 64, 3 * 16 + 3 * 64,
};
-static const uint8_t chroma_dc_scan[4]={
- (0+0*2)*16, (1+0*2)*16,
- (0+1*2)*16, (1+1*2)*16,
+static const uint8_t chroma_dc_scan[4] = {
+ (0 + 0 * 2) * 16, (1 + 0 * 2) * 16,
+ (0 + 1 * 2) * 16, (1 + 1 * 2) * 16,
};
-static const uint8_t chroma422_dc_scan[8]={
- (0+0*2)*16, (0+1*2)*16,
- (1+0*2)*16, (0+2*2)*16,
- (0+3*2)*16, (1+1*2)*16,
- (1+2*2)*16, (1+3*2)*16,
+static const uint8_t chroma422_dc_scan[8] = {
+ (0 + 0 * 2) * 16, (0 + 1 * 2) * 16,
+ (1 + 0 * 2) * 16, (0 + 2 * 2) * 16,
+ (0 + 3 * 2) * 16, (1 + 1 * 2) * 16,
+ (1 + 2 * 2) * 16, (1 + 3 * 2) * 16,
};
// zigzag_scan8x8_cavlc[i] = zigzag_scan8x8[(i/4) + 16*(i%4)]
-static const uint8_t zigzag_scan8x8_cavlc[64]={
- 0+0*8, 1+1*8, 1+2*8, 2+2*8,
- 4+1*8, 0+5*8, 3+3*8, 7+0*8,
- 3+4*8, 1+7*8, 5+3*8, 6+3*8,
- 2+7*8, 6+4*8, 5+6*8, 7+5*8,
- 1+0*8, 2+0*8, 0+3*8, 3+1*8,
- 3+2*8, 0+6*8, 4+2*8, 6+1*8,
- 2+5*8, 2+6*8, 6+2*8, 5+4*8,
- 3+7*8, 7+3*8, 4+7*8, 7+6*8,
- 0+1*8, 3+0*8, 0+4*8, 4+0*8,
- 2+3*8, 1+5*8, 5+1*8, 5+2*8,
- 1+6*8, 3+5*8, 7+1*8, 4+5*8,
- 4+6*8, 7+4*8, 5+7*8, 6+7*8,
- 0+2*8, 2+1*8, 1+3*8, 5+0*8,
- 1+4*8, 2+4*8, 6+0*8, 4+3*8,
- 0+7*8, 4+4*8, 7+2*8, 3+6*8,
- 5+5*8, 6+5*8, 6+6*8, 7+7*8,
+static const uint8_t zigzag_scan8x8_cavlc[64] = {
+ 0 + 0 * 8, 1 + 1 * 8, 1 + 2 * 8, 2 + 2 * 8,
+ 4 + 1 * 8, 0 + 5 * 8, 3 + 3 * 8, 7 + 0 * 8,
+ 3 + 4 * 8, 1 + 7 * 8, 5 + 3 * 8, 6 + 3 * 8,
+ 2 + 7 * 8, 6 + 4 * 8, 5 + 6 * 8, 7 + 5 * 8,
+ 1 + 0 * 8, 2 + 0 * 8, 0 + 3 * 8, 3 + 1 * 8,
+ 3 + 2 * 8, 0 + 6 * 8, 4 + 2 * 8, 6 + 1 * 8,
+ 2 + 5 * 8, 2 + 6 * 8, 6 + 2 * 8, 5 + 4 * 8,
+ 3 + 7 * 8, 7 + 3 * 8, 4 + 7 * 8, 7 + 6 * 8,
+ 0 + 1 * 8, 3 + 0 * 8, 0 + 4 * 8, 4 + 0 * 8,
+ 2 + 3 * 8, 1 + 5 * 8, 5 + 1 * 8, 5 + 2 * 8,
+ 1 + 6 * 8, 3 + 5 * 8, 7 + 1 * 8, 4 + 5 * 8,
+ 4 + 6 * 8, 7 + 4 * 8, 5 + 7 * 8, 6 + 7 * 8,
+ 0 + 2 * 8, 2 + 1 * 8, 1 + 3 * 8, 5 + 0 * 8,
+ 1 + 4 * 8, 2 + 4 * 8, 6 + 0 * 8, 4 + 3 * 8,
+ 0 + 7 * 8, 4 + 4 * 8, 7 + 2 * 8, 3 + 6 * 8,
+ 5 + 5 * 8, 6 + 5 * 8, 6 + 6 * 8, 7 + 7 * 8,
};
-static const uint8_t field_scan8x8[64]={
- 0+0*8, 0+1*8, 0+2*8, 1+0*8,
- 1+1*8, 0+3*8, 0+4*8, 1+2*8,
- 2+0*8, 1+3*8, 0+5*8, 0+6*8,
- 0+7*8, 1+4*8, 2+1*8, 3+0*8,
- 2+2*8, 1+5*8, 1+6*8, 1+7*8,
- 2+3*8, 3+1*8, 4+0*8, 3+2*8,
- 2+4*8, 2+5*8, 2+6*8, 2+7*8,
- 3+3*8, 4+1*8, 5+0*8, 4+2*8,
- 3+4*8, 3+5*8, 3+6*8, 3+7*8,
- 4+3*8, 5+1*8, 6+0*8, 5+2*8,
- 4+4*8, 4+5*8, 4+6*8, 4+7*8,
- 5+3*8, 6+1*8, 6+2*8, 5+4*8,
- 5+5*8, 5+6*8, 5+7*8, 6+3*8,
- 7+0*8, 7+1*8, 6+4*8, 6+5*8,
- 6+6*8, 6+7*8, 7+2*8, 7+3*8,
- 7+4*8, 7+5*8, 7+6*8, 7+7*8,
+static const uint8_t field_scan8x8[64] = {
+ 0 + 0 * 8, 0 + 1 * 8, 0 + 2 * 8, 1 + 0 * 8,
+ 1 + 1 * 8, 0 + 3 * 8, 0 + 4 * 8, 1 + 2 * 8,
+ 2 + 0 * 8, 1 + 3 * 8, 0 + 5 * 8, 0 + 6 * 8,
+ 0 + 7 * 8, 1 + 4 * 8, 2 + 1 * 8, 3 + 0 * 8,
+ 2 + 2 * 8, 1 + 5 * 8, 1 + 6 * 8, 1 + 7 * 8,
+ 2 + 3 * 8, 3 + 1 * 8, 4 + 0 * 8, 3 + 2 * 8,
+ 2 + 4 * 8, 2 + 5 * 8, 2 + 6 * 8, 2 + 7 * 8,
+ 3 + 3 * 8, 4 + 1 * 8, 5 + 0 * 8, 4 + 2 * 8,
+ 3 + 4 * 8, 3 + 5 * 8, 3 + 6 * 8, 3 + 7 * 8,
+ 4 + 3 * 8, 5 + 1 * 8, 6 + 0 * 8, 5 + 2 * 8,
+ 4 + 4 * 8, 4 + 5 * 8, 4 + 6 * 8, 4 + 7 * 8,
+ 5 + 3 * 8, 6 + 1 * 8, 6 + 2 * 8, 5 + 4 * 8,
+ 5 + 5 * 8, 5 + 6 * 8, 5 + 7 * 8, 6 + 3 * 8,
+ 7 + 0 * 8, 7 + 1 * 8, 6 + 4 * 8, 6 + 5 * 8,
+ 6 + 6 * 8, 6 + 7 * 8, 7 + 2 * 8, 7 + 3 * 8,
+ 7 + 4 * 8, 7 + 5 * 8, 7 + 6 * 8, 7 + 7 * 8,
};
-static const uint8_t field_scan8x8_cavlc[64]={
- 0+0*8, 1+1*8, 2+0*8, 0+7*8,
- 2+2*8, 2+3*8, 2+4*8, 3+3*8,
- 3+4*8, 4+3*8, 4+4*8, 5+3*8,
- 5+5*8, 7+0*8, 6+6*8, 7+4*8,
- 0+1*8, 0+3*8, 1+3*8, 1+4*8,
- 1+5*8, 3+1*8, 2+5*8, 4+1*8,
- 3+5*8, 5+1*8, 4+5*8, 6+1*8,
- 5+6*8, 7+1*8, 6+7*8, 7+5*8,
- 0+2*8, 0+4*8, 0+5*8, 2+1*8,
- 1+6*8, 4+0*8, 2+6*8, 5+0*8,
- 3+6*8, 6+0*8, 4+6*8, 6+2*8,
- 5+7*8, 6+4*8, 7+2*8, 7+6*8,
- 1+0*8, 1+2*8, 0+6*8, 3+0*8,
- 1+7*8, 3+2*8, 2+7*8, 4+2*8,
- 3+7*8, 5+2*8, 4+7*8, 5+4*8,
- 6+3*8, 6+5*8, 7+3*8, 7+7*8,
+static const uint8_t field_scan8x8_cavlc[64] = {
+ 0 + 0 * 8, 1 + 1 * 8, 2 + 0 * 8, 0 + 7 * 8,
+ 2 + 2 * 8, 2 + 3 * 8, 2 + 4 * 8, 3 + 3 * 8,
+ 3 + 4 * 8, 4 + 3 * 8, 4 + 4 * 8, 5 + 3 * 8,
+ 5 + 5 * 8, 7 + 0 * 8, 6 + 6 * 8, 7 + 4 * 8,
+ 0 + 1 * 8, 0 + 3 * 8, 1 + 3 * 8, 1 + 4 * 8,
+ 1 + 5 * 8, 3 + 1 * 8, 2 + 5 * 8, 4 + 1 * 8,
+ 3 + 5 * 8, 5 + 1 * 8, 4 + 5 * 8, 6 + 1 * 8,
+ 5 + 6 * 8, 7 + 1 * 8, 6 + 7 * 8, 7 + 5 * 8,
+ 0 + 2 * 8, 0 + 4 * 8, 0 + 5 * 8, 2 + 1 * 8,
+ 1 + 6 * 8, 4 + 0 * 8, 2 + 6 * 8, 5 + 0 * 8,
+ 3 + 6 * 8, 6 + 0 * 8, 4 + 6 * 8, 6 + 2 * 8,
+ 5 + 7 * 8, 6 + 4 * 8, 7 + 2 * 8, 7 + 6 * 8,
+ 1 + 0 * 8, 1 + 2 * 8, 0 + 6 * 8, 3 + 0 * 8,
+ 1 + 7 * 8, 3 + 2 * 8, 2 + 7 * 8, 4 + 2 * 8,
+ 3 + 7 * 8, 5 + 2 * 8, 4 + 7 * 8, 5 + 4 * 8,
+ 6 + 3 * 8, 6 + 5 * 8, 7 + 3 * 8, 7 + 7 * 8,
};
-typedef struct IMbInfo{
+typedef struct IMbInfo {
uint16_t type;
uint8_t pred_mode;
uint8_t cbp;
} IMbInfo;
-static const IMbInfo i_mb_type_info[26]={
-{MB_TYPE_INTRA4x4 , -1, -1},
-{MB_TYPE_INTRA16x16, 2, 0},
-{MB_TYPE_INTRA16x16, 1, 0},
-{MB_TYPE_INTRA16x16, 0, 0},
-{MB_TYPE_INTRA16x16, 3, 0},
-{MB_TYPE_INTRA16x16, 2, 16},
-{MB_TYPE_INTRA16x16, 1, 16},
-{MB_TYPE_INTRA16x16, 0, 16},
-{MB_TYPE_INTRA16x16, 3, 16},
-{MB_TYPE_INTRA16x16, 2, 32},
-{MB_TYPE_INTRA16x16, 1, 32},
-{MB_TYPE_INTRA16x16, 0, 32},
-{MB_TYPE_INTRA16x16, 3, 32},
-{MB_TYPE_INTRA16x16, 2, 15+0},
-{MB_TYPE_INTRA16x16, 1, 15+0},
-{MB_TYPE_INTRA16x16, 0, 15+0},
-{MB_TYPE_INTRA16x16, 3, 15+0},
-{MB_TYPE_INTRA16x16, 2, 15+16},
-{MB_TYPE_INTRA16x16, 1, 15+16},
-{MB_TYPE_INTRA16x16, 0, 15+16},
-{MB_TYPE_INTRA16x16, 3, 15+16},
-{MB_TYPE_INTRA16x16, 2, 15+32},
-{MB_TYPE_INTRA16x16, 1, 15+32},
-{MB_TYPE_INTRA16x16, 0, 15+32},
-{MB_TYPE_INTRA16x16, 3, 15+32},
-{MB_TYPE_INTRA_PCM , -1, -1},
+static const IMbInfo i_mb_type_info[26] = {
+ { MB_TYPE_INTRA4x4, -1, -1 },
+ { MB_TYPE_INTRA16x16, 2, 0 },
+ { MB_TYPE_INTRA16x16, 1, 0 },
+ { MB_TYPE_INTRA16x16, 0, 0 },
+ { MB_TYPE_INTRA16x16, 3, 0 },
+ { MB_TYPE_INTRA16x16, 2, 16 },
+ { MB_TYPE_INTRA16x16, 1, 16 },
+ { MB_TYPE_INTRA16x16, 0, 16 },
+ { MB_TYPE_INTRA16x16, 3, 16 },
+ { MB_TYPE_INTRA16x16, 2, 32 },
+ { MB_TYPE_INTRA16x16, 1, 32 },
+ { MB_TYPE_INTRA16x16, 0, 32 },
+ { MB_TYPE_INTRA16x16, 3, 32 },
+ { MB_TYPE_INTRA16x16, 2, 15 + 0 },
+ { MB_TYPE_INTRA16x16, 1, 15 + 0 },
+ { MB_TYPE_INTRA16x16, 0, 15 + 0 },
+ { MB_TYPE_INTRA16x16, 3, 15 + 0 },
+ { MB_TYPE_INTRA16x16, 2, 15 + 16 },
+ { MB_TYPE_INTRA16x16, 1, 15 + 16 },
+ { MB_TYPE_INTRA16x16, 0, 15 + 16 },
+ { MB_TYPE_INTRA16x16, 3, 15 + 16 },
+ { MB_TYPE_INTRA16x16, 2, 15 + 32 },
+ { MB_TYPE_INTRA16x16, 1, 15 + 32 },
+ { MB_TYPE_INTRA16x16, 0, 15 + 32 },
+ { MB_TYPE_INTRA16x16, 3, 15 + 32 },
+ { MB_TYPE_INTRA_PCM, -1, -1 },
};
-typedef struct PMbInfo{
+typedef struct PMbInfo {
uint16_t type;
uint8_t partition_count;
} PMbInfo;
-static const PMbInfo p_mb_type_info[5]={
-{MB_TYPE_16x16|MB_TYPE_P0L0 , 1},
-{MB_TYPE_16x8 |MB_TYPE_P0L0|MB_TYPE_P1L0, 2},
-{MB_TYPE_8x16 |MB_TYPE_P0L0|MB_TYPE_P1L0, 2},
-{MB_TYPE_8x8 |MB_TYPE_P0L0|MB_TYPE_P1L0, 4},
-{MB_TYPE_8x8 |MB_TYPE_P0L0|MB_TYPE_P1L0|MB_TYPE_REF0, 4},
+static const PMbInfo p_mb_type_info[5] = {
+ { MB_TYPE_16x16 | MB_TYPE_P0L0, 1 },
+ { MB_TYPE_16x8 | MB_TYPE_P0L0 | MB_TYPE_P1L0, 2 },
+ { MB_TYPE_8x16 | MB_TYPE_P0L0 | MB_TYPE_P1L0, 2 },
+ { MB_TYPE_8x8 | MB_TYPE_P0L0 | MB_TYPE_P1L0, 4 },
+ { MB_TYPE_8x8 | MB_TYPE_P0L0 | MB_TYPE_P1L0 | MB_TYPE_REF0, 4 },
};
-static const PMbInfo p_sub_mb_type_info[4]={
-{MB_TYPE_16x16|MB_TYPE_P0L0 , 1},
-{MB_TYPE_16x8 |MB_TYPE_P0L0 , 2},
-{MB_TYPE_8x16 |MB_TYPE_P0L0 , 2},
-{MB_TYPE_8x8 |MB_TYPE_P0L0 , 4},
+static const PMbInfo p_sub_mb_type_info[4] = {
+ { MB_TYPE_16x16 | MB_TYPE_P0L0, 1 },
+ { MB_TYPE_16x8 | MB_TYPE_P0L0, 2 },
+ { MB_TYPE_8x16 | MB_TYPE_P0L0, 2 },
+ { MB_TYPE_8x8 | MB_TYPE_P0L0, 4 },
};
-static const PMbInfo b_mb_type_info[23]={
-{MB_TYPE_DIRECT2|MB_TYPE_L0L1 , 1, },
-{MB_TYPE_16x16|MB_TYPE_P0L0 , 1, },
-{MB_TYPE_16x16 |MB_TYPE_P0L1 , 1, },
-{MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1 , 1, },
-{MB_TYPE_16x8 |MB_TYPE_P0L0 |MB_TYPE_P1L0 , 2, },
-{MB_TYPE_8x16 |MB_TYPE_P0L0 |MB_TYPE_P1L0 , 2, },
-{MB_TYPE_16x8 |MB_TYPE_P0L1 |MB_TYPE_P1L1, 2, },
-{MB_TYPE_8x16 |MB_TYPE_P0L1 |MB_TYPE_P1L1, 2, },
-{MB_TYPE_16x8 |MB_TYPE_P0L0 |MB_TYPE_P1L1, 2, },
-{MB_TYPE_8x16 |MB_TYPE_P0L0 |MB_TYPE_P1L1, 2, },
-{MB_TYPE_16x8 |MB_TYPE_P0L1|MB_TYPE_P1L0 , 2, },
-{MB_TYPE_8x16 |MB_TYPE_P0L1|MB_TYPE_P1L0 , 2, },
-{MB_TYPE_16x8 |MB_TYPE_P0L0 |MB_TYPE_P1L0|MB_TYPE_P1L1, 2, },
-{MB_TYPE_8x16 |MB_TYPE_P0L0 |MB_TYPE_P1L0|MB_TYPE_P1L1, 2, },
-{MB_TYPE_16x8 |MB_TYPE_P0L1|MB_TYPE_P1L0|MB_TYPE_P1L1, 2, },
-{MB_TYPE_8x16 |MB_TYPE_P0L1|MB_TYPE_P1L0|MB_TYPE_P1L1, 2, },
-{MB_TYPE_16x8 |MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_P1L0 , 2, },
-{MB_TYPE_8x16 |MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_P1L0 , 2, },
-{MB_TYPE_16x8 |MB_TYPE_P0L0|MB_TYPE_P0L1 |MB_TYPE_P1L1, 2, },
-{MB_TYPE_8x16 |MB_TYPE_P0L0|MB_TYPE_P0L1 |MB_TYPE_P1L1, 2, },
-{MB_TYPE_16x8 |MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_P1L0|MB_TYPE_P1L1, 2, },
-{MB_TYPE_8x16 |MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_P1L0|MB_TYPE_P1L1, 2, },
-{MB_TYPE_8x8 |MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_P1L0|MB_TYPE_P1L1, 4, },
+static const PMbInfo b_mb_type_info[23] = {
+ { MB_TYPE_DIRECT2 | MB_TYPE_L0L1, 1, },
+ { MB_TYPE_16x16 | MB_TYPE_P0L0, 1, },
+ { MB_TYPE_16x16 | MB_TYPE_P0L1, 1, },
+ { MB_TYPE_16x16 | MB_TYPE_P0L0 | MB_TYPE_P0L1, 1, },
+ { MB_TYPE_16x8 | MB_TYPE_P0L0 | MB_TYPE_P1L0, 2, },
+ { MB_TYPE_8x16 | MB_TYPE_P0L0 | MB_TYPE_P1L0, 2, },
+ { MB_TYPE_16x8 | MB_TYPE_P0L1 | MB_TYPE_P1L1, 2, },
+ { MB_TYPE_8x16 | MB_TYPE_P0L1 | MB_TYPE_P1L1, 2, },
+ { MB_TYPE_16x8 | MB_TYPE_P0L0 | MB_TYPE_P1L1, 2, },
+ { MB_TYPE_8x16 | MB_TYPE_P0L0 | MB_TYPE_P1L1, 2, },
+ { MB_TYPE_16x8 | MB_TYPE_P0L1 | MB_TYPE_P1L0, 2, },
+ { MB_TYPE_8x16 | MB_TYPE_P0L1 | MB_TYPE_P1L0, 2, },
+ { MB_TYPE_16x8 | MB_TYPE_P0L0 | MB_TYPE_P1L0 | MB_TYPE_P1L1, 2, },
+ { MB_TYPE_8x16 | MB_TYPE_P0L0 | MB_TYPE_P1L0 | MB_TYPE_P1L1, 2, },
+ { MB_TYPE_16x8 | MB_TYPE_P0L1 | MB_TYPE_P1L0 | MB_TYPE_P1L1, 2, },
+ { MB_TYPE_8x16 | MB_TYPE_P0L1 | MB_TYPE_P1L0 | MB_TYPE_P1L1, 2, },
+ { MB_TYPE_16x8 | MB_TYPE_P0L0 | MB_TYPE_P0L1 | MB_TYPE_P1L0, 2, },
+ { MB_TYPE_8x16 | MB_TYPE_P0L0 | MB_TYPE_P0L1 | MB_TYPE_P1L0, 2, },
+ { MB_TYPE_16x8 | MB_TYPE_P0L0 | MB_TYPE_P0L1 | MB_TYPE_P1L1, 2, },
+ { MB_TYPE_8x16 | MB_TYPE_P0L0 | MB_TYPE_P0L1 | MB_TYPE_P1L1, 2, },
+ { MB_TYPE_16x8 | MB_TYPE_P0L0 | MB_TYPE_P0L1 | MB_TYPE_P1L0 | MB_TYPE_P1L1, 2, },
+ { MB_TYPE_8x16 | MB_TYPE_P0L0 | MB_TYPE_P0L1 | MB_TYPE_P1L0 | MB_TYPE_P1L1, 2, },
+ { MB_TYPE_8x8 | MB_TYPE_P0L0 | MB_TYPE_P0L1 | MB_TYPE_P1L0 | MB_TYPE_P1L1, 4, },
};
-static const PMbInfo b_sub_mb_type_info[13]={
-{MB_TYPE_DIRECT2 , 1, },
-{MB_TYPE_16x16|MB_TYPE_P0L0 , 1, },
-{MB_TYPE_16x16 |MB_TYPE_P0L1 , 1, },
-{MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1 , 1, },
-{MB_TYPE_16x8 |MB_TYPE_P0L0 |MB_TYPE_P1L0 , 2, },
-{MB_TYPE_8x16 |MB_TYPE_P0L0 |MB_TYPE_P1L0 , 2, },
-{MB_TYPE_16x8 |MB_TYPE_P0L1 |MB_TYPE_P1L1, 2, },
-{MB_TYPE_8x16 |MB_TYPE_P0L1 |MB_TYPE_P1L1, 2, },
-{MB_TYPE_16x8 |MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_P1L0|MB_TYPE_P1L1, 2, },
-{MB_TYPE_8x16 |MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_P1L0|MB_TYPE_P1L1, 2, },
-{MB_TYPE_8x8 |MB_TYPE_P0L0 |MB_TYPE_P1L0 , 4, },
-{MB_TYPE_8x8 |MB_TYPE_P0L1 |MB_TYPE_P1L1, 4, },
-{MB_TYPE_8x8 |MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_P1L0|MB_TYPE_P1L1, 4, },
+static const PMbInfo b_sub_mb_type_info[13] = {
+ { MB_TYPE_DIRECT2, 1, },
+ { MB_TYPE_16x16 | MB_TYPE_P0L0, 1, },
+ { MB_TYPE_16x16 | MB_TYPE_P0L1, 1, },
+ { MB_TYPE_16x16 | MB_TYPE_P0L0 | MB_TYPE_P0L1, 1, },
+ { MB_TYPE_16x8 | MB_TYPE_P0L0 | MB_TYPE_P1L0, 2, },
+ { MB_TYPE_8x16 | MB_TYPE_P0L0 | MB_TYPE_P1L0, 2, },
+ { MB_TYPE_16x8 | MB_TYPE_P0L1 | MB_TYPE_P1L1, 2, },
+ { MB_TYPE_8x16 | MB_TYPE_P0L1 | MB_TYPE_P1L1, 2, },
+ { MB_TYPE_16x8 | MB_TYPE_P0L0 | MB_TYPE_P0L1 | MB_TYPE_P1L0 | MB_TYPE_P1L1, 2, },
+ { MB_TYPE_8x16 | MB_TYPE_P0L0 | MB_TYPE_P0L1 | MB_TYPE_P1L0 | MB_TYPE_P1L1, 2, },
+ { MB_TYPE_8x8 | MB_TYPE_P0L0 | MB_TYPE_P1L0, 4, },
+ { MB_TYPE_8x8 | MB_TYPE_P0L1 | MB_TYPE_P1L1, 4, },
+ { MB_TYPE_8x8 | MB_TYPE_P0L0 | MB_TYPE_P0L1 | MB_TYPE_P1L0 | MB_TYPE_P1L1, 4, },
};
-static const uint8_t dequant4_coeff_init[6][3]={
- {10,13,16},
- {11,14,18},
- {13,16,20},
- {14,18,23},
- {16,20,25},
- {18,23,29},
+static const uint8_t dequant4_coeff_init[6][3] = {
+ { 10, 13, 16 },
+ { 11, 14, 18 },
+ { 13, 16, 20 },
+ { 14, 18, 23 },
+ { 16, 20, 25 },
+ { 18, 23, 29 },
};
static const uint8_t dequant8_coeff_init_scan[16] = {
- 0,3,4,3, 3,1,5,1, 4,5,2,5, 3,1,5,1
+ 0, 3, 4, 3, 3, 1, 5, 1, 4, 5, 2, 5, 3, 1, 5, 1
};
-static const uint8_t dequant8_coeff_init[6][6]={
- {20,18,32,19,25,24},
- {22,19,35,21,28,26},
- {26,23,42,24,33,31},
- {28,25,45,26,35,33},
- {32,28,51,30,40,38},
- {36,32,58,34,46,43},
+
+static const uint8_t dequant8_coeff_init[6][6] = {
+ { 20, 18, 32, 19, 25, 24 },
+ { 22, 19, 35, 21, 28, 26 },
+ { 26, 23, 42, 24, 33, 31 },
+ { 28, 25, 45, 26, 35, 33 },
+ { 32, 28, 51, 30, 40, 38 },
+ { 36, 32, 58, 34, 46, 43 },
};
#endif /* AVCODEC_H264DATA_H */
diff --git a/libavcodec/h264dsp.h b/libavcodec/h264dsp.h
index 7cae215..248c7d0 100644
--- a/libavcodec/h264dsp.h
+++ b/libavcodec/h264dsp.h
@@ -28,57 +28,90 @@
#define AVCODEC_H264DSP_H
#include <stdint.h>
+
#include "dsputil.h"
-//typedef void (*h264_chroma_mc_func)(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int srcStride, int h, int x, int y);
typedef void (*h264_weight_func)(uint8_t *block, int stride, int height,
int log2_denom, int weight, int offset);
-typedef void (*h264_biweight_func)(uint8_t *dst, uint8_t *src, int stride, int height,
- int log2_denom, int weightd, int weights, int offset);
+typedef void (*h264_biweight_func)(uint8_t *dst, uint8_t *src,
+ int stride, int height, int log2_denom,
+ int weightd, int weights, int offset);
/**
* Context for storing H.264 DSP functions
*/
-typedef struct H264DSPContext{
+typedef struct H264DSPContext {
/* weighted MC */
h264_weight_func weight_h264_pixels_tab[4];
h264_biweight_func biweight_h264_pixels_tab[4];
/* loop filter */
- void (*h264_v_loop_filter_luma)(uint8_t *pix/*align 16*/, int stride, int alpha, int beta, int8_t *tc0);
- void (*h264_h_loop_filter_luma)(uint8_t *pix/*align 4 */, int stride, int alpha, int beta, int8_t *tc0);
- void (*h264_h_loop_filter_luma_mbaff)(uint8_t *pix/*align 16*/, int stride, int alpha, int beta, int8_t *tc0);
+ void (*h264_v_loop_filter_luma)(uint8_t *pix /*align 16*/, int stride,
+ int alpha, int beta, int8_t *tc0);
+ void (*h264_h_loop_filter_luma)(uint8_t *pix /*align 4 */, int stride,
+ int alpha, int beta, int8_t *tc0);
+ void (*h264_h_loop_filter_luma_mbaff)(uint8_t *pix /*align 16*/, int stride,
+ int alpha, int beta, int8_t *tc0);
/* v/h_loop_filter_luma_intra: align 16 */
- void (*h264_v_loop_filter_luma_intra)(uint8_t *pix, int stride, int alpha, int beta);
- void (*h264_h_loop_filter_luma_intra)(uint8_t *pix, int stride, int alpha, int beta);
- void (*h264_h_loop_filter_luma_mbaff_intra)(uint8_t *pix/*align 16*/, int stride, int alpha, int beta);
- void (*h264_v_loop_filter_chroma)(uint8_t *pix/*align 8*/, int stride, int alpha, int beta, int8_t *tc0);
- void (*h264_h_loop_filter_chroma)(uint8_t *pix/*align 4*/, int stride, int alpha, int beta, int8_t *tc0);
- void (*h264_h_loop_filter_chroma_mbaff)(uint8_t *pix/*align 8*/, int stride, int alpha, int beta, int8_t *tc0);
- void (*h264_v_loop_filter_chroma_intra)(uint8_t *pix/*align 8*/, int stride, int alpha, int beta);
- void (*h264_h_loop_filter_chroma_intra)(uint8_t *pix/*align 8*/, int stride, int alpha, int beta);
- void (*h264_h_loop_filter_chroma_mbaff_intra)(uint8_t *pix/*align 8*/, int stride, int alpha, int beta);
+ void (*h264_v_loop_filter_luma_intra)(uint8_t *pix, int stride,
+ int alpha, int beta);
+ void (*h264_h_loop_filter_luma_intra)(uint8_t *pix, int stride,
+ int alpha, int beta);
+ void (*h264_h_loop_filter_luma_mbaff_intra)(uint8_t *pix /*align 16*/,
+ int stride, int alpha, int beta);
+ void (*h264_v_loop_filter_chroma)(uint8_t *pix /*align 8*/, int stride,
+ int alpha, int beta, int8_t *tc0);
+ void (*h264_h_loop_filter_chroma)(uint8_t *pix /*align 4*/, int stride,
+ int alpha, int beta, int8_t *tc0);
+ void (*h264_h_loop_filter_chroma_mbaff)(uint8_t *pix /*align 8*/,
+ int stride, int alpha, int beta,
+ int8_t *tc0);
+ void (*h264_v_loop_filter_chroma_intra)(uint8_t *pix /*align 8*/,
+ int stride, int alpha, int beta);
+ void (*h264_h_loop_filter_chroma_intra)(uint8_t *pix /*align 8*/,
+ int stride, int alpha, int beta);
+ void (*h264_h_loop_filter_chroma_mbaff_intra)(uint8_t *pix /*align 8*/,
+ int stride, int alpha, int beta);
// h264_loop_filter_strength: simd only. the C version is inlined in h264.c
- void (*h264_loop_filter_strength)(int16_t bS[2][4][4], uint8_t nnz[40], int8_t ref[2][40], int16_t mv[2][40][2],
- int bidir, int edges, int step, int mask_mv0, int mask_mv1, int field);
+ void (*h264_loop_filter_strength)(int16_t bS[2][4][4], uint8_t nnz[40],
+ int8_t ref[2][40], int16_t mv[2][40][2],
+ int bidir, int edges, int step,
+ int mask_mv0, int mask_mv1, int field);
/* IDCT */
- void (*h264_idct_add)(uint8_t *dst/*align 4*/, DCTELEM *block/*align 16*/, int stride);
- void (*h264_idct8_add)(uint8_t *dst/*align 8*/, DCTELEM *block/*align 16*/, int stride);
- void (*h264_idct_dc_add)(uint8_t *dst/*align 4*/, DCTELEM *block/*align 16*/, int stride);
- void (*h264_idct8_dc_add)(uint8_t *dst/*align 8*/, DCTELEM *block/*align 16*/, int stride);
+ void (*h264_idct_add)(uint8_t *dst /*align 4*/,
+ DCTELEM *block /*align 16*/, int stride);
+ void (*h264_idct8_add)(uint8_t *dst /*align 8*/,
+ DCTELEM *block /*align 16*/, int stride);
+ void (*h264_idct_dc_add)(uint8_t *dst /*align 4*/,
+ DCTELEM *block /*align 16*/, int stride);
+ void (*h264_idct8_dc_add)(uint8_t *dst /*align 8*/,
+ DCTELEM *block /*align 16*/, int stride);
- void (*h264_idct_add16)(uint8_t *dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[15*8]);
- void (*h264_idct8_add4)(uint8_t *dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[15*8]);
- void (*h264_idct_add8)(uint8_t **dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[15*8]);
- void (*h264_idct_add16intra)(uint8_t *dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[15*8]);
- void (*h264_luma_dc_dequant_idct)(DCTELEM *output, DCTELEM *input/*align 16*/, int qmul);
+ void (*h264_idct_add16)(uint8_t *dst /*align 16*/, const int *blockoffset,
+ DCTELEM *block /*align 16*/, int stride,
+ const uint8_t nnzc[15 * 8]);
+ void (*h264_idct8_add4)(uint8_t *dst /*align 16*/, const int *blockoffset,
+ DCTELEM *block /*align 16*/, int stride,
+ const uint8_t nnzc[15 * 8]);
+ void (*h264_idct_add8)(uint8_t **dst /*align 16*/, const int *blockoffset,
+ DCTELEM *block /*align 16*/, int stride,
+ const uint8_t nnzc[15 * 8]);
+ void (*h264_idct_add16intra)(uint8_t *dst /*align 16*/, const int *blockoffset,
+ DCTELEM *block /*align 16*/,
+ int stride, const uint8_t nnzc[15 * 8]);
+ void (*h264_luma_dc_dequant_idct)(DCTELEM *output,
+ DCTELEM *input /*align 16*/, int qmul);
void (*h264_chroma_dc_dequant_idct)(DCTELEM *block, int qmul);
-}H264DSPContext;
+} H264DSPContext;
-void ff_h264dsp_init(H264DSPContext *c, const int bit_depth, const int chroma_format_idc);
-void ff_h264dsp_init_arm(H264DSPContext *c, const int bit_depth, const int chroma_format_idc);
-void ff_h264dsp_init_ppc(H264DSPContext *c, const int bit_depth, const int chroma_format_idc);
-void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth, const int chroma_format_idc);
+void ff_h264dsp_init(H264DSPContext *c, const int bit_depth,
+ const int chroma_format_idc);
+void ff_h264dsp_init_arm(H264DSPContext *c, const int bit_depth,
+ const int chroma_format_idc);
+void ff_h264dsp_init_ppc(H264DSPContext *c, const int bit_depth,
+ const int chroma_format_idc);
+void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth,
+ const int chroma_format_idc);
#endif /* AVCODEC_H264DSP_H */
diff --git a/libavcodec/h264pred.h b/libavcodec/h264pred.h
index b880446..a964ae3 100644
--- a/libavcodec/h264pred.h
+++ b/libavcodec/h264pred.h
@@ -35,18 +35,18 @@
* Prediction types
*/
//@{
-#define VERT_PRED 0
-#define HOR_PRED 1
-#define DC_PRED 2
-#define DIAG_DOWN_LEFT_PRED 3
-#define DIAG_DOWN_RIGHT_PRED 4
-#define VERT_RIGHT_PRED 5
-#define HOR_DOWN_PRED 6
-#define VERT_LEFT_PRED 7
-#define HOR_UP_PRED 8
+#define VERT_PRED 0
+#define HOR_PRED 1
+#define DC_PRED 2
+#define DIAG_DOWN_LEFT_PRED 3
+#define DIAG_DOWN_RIGHT_PRED 4
+#define VERT_RIGHT_PRED 5
+#define HOR_DOWN_PRED 6
+#define VERT_LEFT_PRED 7
+#define HOR_UP_PRED 8
// DC edge (not for VP8)
-#define LEFT_DC_PRED 9
+#define LEFT_DC_PRED 9
#define TOP_DC_PRED 10
#define DC_128_PRED 11
@@ -56,7 +56,7 @@
#define VERT_LEFT_PRED_RV40_NODOWN 14
// VP8 specific
-#define TM_VP8_PRED 9 ///< "True Motion", used instead of plane
+#define TM_VP8_PRED 9 ///< "True Motion", used instead of plane
#define VERT_VP8_PRED 10 ///< for VP8, #VERT_PRED is the average of
///< (left col+cur col x2+right col) / 4;
///< this is the "unaveraged" one
@@ -65,44 +65,53 @@
#define DC_127_PRED 12
#define DC_129_PRED 13
-#define DC_PRED8x8 0
-#define HOR_PRED8x8 1
-#define VERT_PRED8x8 2
-#define PLANE_PRED8x8 3
+#define DC_PRED8x8 0
+#define HOR_PRED8x8 1
+#define VERT_PRED8x8 2
+#define PLANE_PRED8x8 3
// DC edge
-#define LEFT_DC_PRED8x8 4
-#define TOP_DC_PRED8x8 5
-#define DC_128_PRED8x8 6
+#define LEFT_DC_PRED8x8 4
+#define TOP_DC_PRED8x8 5
+#define DC_128_PRED8x8 6
// H264/SVQ3 (8x8) specific
-#define ALZHEIMER_DC_L0T_PRED8x8 7
-#define ALZHEIMER_DC_0LT_PRED8x8 8
-#define ALZHEIMER_DC_L00_PRED8x8 9
+#define ALZHEIMER_DC_L0T_PRED8x8 7
+#define ALZHEIMER_DC_0LT_PRED8x8 8
+#define ALZHEIMER_DC_L00_PRED8x8 9
#define ALZHEIMER_DC_0L0_PRED8x8 10
// VP8 specific
-#define DC_127_PRED8x8 7
-#define DC_129_PRED8x8 8
+#define DC_127_PRED8x8 7
+#define DC_129_PRED8x8 8
//@}
/**
* Context for storing H.264 prediction functions
*/
-typedef struct H264PredContext{
- void (*pred4x4 [9+3+3])(uint8_t *src, const uint8_t *topright, int stride);//FIXME move to dsp?
- void (*pred8x8l [9+3])(uint8_t *src, int topleft, int topright, int stride);
- void (*pred8x8 [4+3+4])(uint8_t *src, int stride);
- void (*pred16x16[4+3+2])(uint8_t *src, int stride);
+typedef struct H264PredContext {
+ void(*pred4x4[9 + 3 + 3])(uint8_t *src, const uint8_t *topright, int stride); //FIXME move to dsp?
+ void(*pred8x8l[9 + 3])(uint8_t *src, int topleft, int topright, int stride);
+ void(*pred8x8[4 + 3 + 4])(uint8_t *src, int stride);
+ void(*pred16x16[4 + 3 + 2])(uint8_t *src, int stride);
- void (*pred4x4_add [2])(uint8_t *pix/*align 4*/, const DCTELEM *block/*align 16*/, int stride);
- void (*pred8x8l_add [2])(uint8_t *pix/*align 8*/, const DCTELEM *block/*align 16*/, int stride);
- void (*pred8x8_add [3])(uint8_t *pix/*align 8*/, const int *block_offset, const DCTELEM *block/*align 16*/, int stride);
- void (*pred16x16_add[3])(uint8_t *pix/*align 16*/, const int *block_offset, const DCTELEM *block/*align 16*/, int stride);
-}H264PredContext;
+ void(*pred4x4_add[2])(uint8_t *pix /*align 4*/,
+ const DCTELEM *block /*align 16*/, int stride);
+ void(*pred8x8l_add[2])(uint8_t *pix /*align 8*/,
+ const DCTELEM *block /*align 16*/, int stride);
+ void(*pred8x8_add[3])(uint8_t *pix /*align 8*/,
+ const int *block_offset,
+ const DCTELEM *block /*align 16*/, int stride);
+ void(*pred16x16_add[3])(uint8_t *pix /*align 16*/,
+ const int *block_offset,
+ const DCTELEM *block /*align 16*/, int stride);
+} H264PredContext;
-void ff_h264_pred_init(H264PredContext *h, int codec_id, const int bit_depth, const int chroma_format_idc);
-void ff_h264_pred_init_arm(H264PredContext *h, int codec_id, const int bit_depth, const int chroma_format_idc);
-void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth, const int chroma_format_idc);
+void ff_h264_pred_init(H264PredContext *h, int codec_id,
+ const int bit_depth, const int chroma_format_idc);
+void ff_h264_pred_init_arm(H264PredContext *h, int codec_id,
+ const int bit_depth, const int chroma_format_idc);
+void ff_h264_pred_init_x86(H264PredContext *h, int codec_id,
+ const int bit_depth, const int chroma_format_idc);
#endif /* AVCODEC_H264PRED_H */
diff --git a/libavcodec/imc.c b/libavcodec/imc.c
index 2c9efb9..6df3e58 100644
--- a/libavcodec/imc.c
+++ b/libavcodec/imc.c
@@ -25,7 +25,7 @@
* @file
* IMC - Intel Music Coder
* A mdct based codec using a 256 points large transform
- * divied into 32 bands with some mix of scale factors.
+ * divided into 32 bands with some mix of scale factors.
* Only mono is supported.
*
*/
@@ -49,9 +49,7 @@
#define BANDS 32
#define COEFFS 256
-typedef struct {
- AVFrame frame;
-
+typedef struct IMCChannel {
float old_floor[BANDS];
float flcoeffs1[BANDS];
float flcoeffs2[BANDS];
@@ -61,16 +59,6 @@ typedef struct {
float flcoeffs6[BANDS];
float CWdecoded[COEFFS];
- /** MDCT tables */
- //@{
- float mdct_sine_window[COEFFS];
- float post_cos[COEFFS];
- float post_sin[COEFFS];
- float pre_coef1[COEFFS];
- float pre_coef2[COEFFS];
- float last_fft_im[COEFFS];
- //@}
-
int bandWidthT[BANDS]; ///< codewords per band
int bitsBandT[BANDS]; ///< how many bits per codeword in band
int CWlengthT[COEFFS]; ///< how many bits in each codeword
@@ -82,15 +70,37 @@ typedef struct {
int skipFlagCount[BANDS]; ///< skipped coeffients per band
int skipFlags[COEFFS]; ///< skip coefficient decoding or not
int codewords[COEFFS]; ///< raw codewords read from bitstream
+
+ float last_fft_im[COEFFS];
+
+ int decoder_reset;
+} IMCChannel;
+
+typedef struct {
+ AVFrame frame;
+
+ IMCChannel chctx[2];
+
+ /** MDCT tables */
+ //@{
+ float mdct_sine_window[COEFFS];
+ float post_cos[COEFFS];
+ float post_sin[COEFFS];
+ float pre_coef1[COEFFS];
+ float pre_coef2[COEFFS];
+ //@}
+
float sqrt_tab[30];
GetBitContext gb;
- int decoder_reset;
float one_div_log2;
DSPContext dsp;
FFTContext fft;
- DECLARE_ALIGNED(32, FFTComplex, samples)[COEFFS/2];
+ DECLARE_ALIGNED(32, FFTComplex, samples)[COEFFS / 2];
float *out_samples;
+
+ int8_t cyclTab[32], cyclTab2[32];
+ float weights1[31], weights2[31];
} IMCContext;
static VLC huffman_vlc[4][4];
@@ -99,60 +109,117 @@ static VLC huffman_vlc[4][4];
static const int vlc_offsets[17] = {
0, 640, 1156, 1732, 2308, 2852, 3396, 3924,
- 4452, 5220, 5860, 6628, 7268, 7908, 8424, 8936, VLC_TABLES_SIZE};
+ 4452, 5220, 5860, 6628, 7268, 7908, 8424, 8936, VLC_TABLES_SIZE
+};
static VLC_TYPE vlc_tables[VLC_TABLES_SIZE][2];
-static av_cold int imc_decode_init(AVCodecContext * avctx)
+static inline double freq2bark(double freq)
+{
+ return 3.5 * atan((freq / 7500.0) * (freq / 7500.0)) + 13.0 * atan(freq * 0.00076);
+}
+
+static av_cold void iac_generate_tabs(IMCContext *q, int sampling_rate)
+{
+ double freqmin[32], freqmid[32], freqmax[32];
+ double scale = sampling_rate / (256.0 * 2.0 * 2.0);
+ double nyquist_freq = sampling_rate * 0.5;
+ double freq, bark, prev_bark = 0, tf, tb;
+ int i, j;
+
+ for (i = 0; i < 32; i++) {
+ freq = (band_tab[i] + band_tab[i + 1] - 1) * scale;
+ bark = freq2bark(freq);
+
+ if (i > 0) {
+ tb = bark - prev_bark;
+ q->weights1[i - 1] = pow(10.0, -1.0 * tb);
+ q->weights2[i - 1] = pow(10.0, -2.7 * tb);
+ }
+ prev_bark = bark;
+
+ freqmid[i] = freq;
+
+ tf = freq;
+ while (tf < nyquist_freq) {
+ tf += 0.5;
+ tb = freq2bark(tf);
+ if (tb > bark + 0.5)
+ break;
+ }
+ freqmax[i] = tf;
+
+ tf = freq;
+ while (tf > 0.0) {
+ tf -= 0.5;
+ tb = freq2bark(tf);
+ if (tb <= bark - 0.5)
+ break;
+ }
+ freqmin[i] = tf;
+ }
+
+ for (i = 0; i < 32; i++) {
+ freq = freqmax[i];
+ for (j = 31; j > 0 && freq <= freqmid[j]; j--);
+ q->cyclTab[i] = j + 1;
+
+ freq = freqmin[i];
+ for (j = 0; j < 32 && freq >= freqmid[j]; j++);
+ q->cyclTab2[i] = j - 1;
+ }
+}
+
+static av_cold int imc_decode_init(AVCodecContext *avctx)
{
int i, j, ret;
IMCContext *q = avctx->priv_data;
double r1, r2;
- if (avctx->channels != 1) {
+ if ((avctx->codec_id == CODEC_ID_IMC && avctx->channels != 1)
+ || (avctx->codec_id == CODEC_ID_IAC && avctx->channels > 2)) {
av_log_ask_for_sample(avctx, "Number of channels is not supported\n");
return AVERROR_PATCHWELCOME;
}
- q->decoder_reset = 1;
+ for (j = 0; j < avctx->channels; j++) {
+ q->chctx[j].decoder_reset = 1;
- for(i = 0; i < BANDS; i++)
- q->old_floor[i] = 1.0;
+ for (i = 0; i < BANDS; i++)
+ q->chctx[j].old_floor[i] = 1.0;
+
+ for (i = 0; i < COEFFS / 2; i++)
+ q->chctx[j].last_fft_im[i] = 0;
+ }
/* Build mdct window, a simple sine window normalized with sqrt(2) */
ff_sine_window_init(q->mdct_sine_window, COEFFS);
- for(i = 0; i < COEFFS; i++)
+ for (i = 0; i < COEFFS; i++)
q->mdct_sine_window[i] *= sqrt(2.0);
- for(i = 0; i < COEFFS/2; i++){
+ for (i = 0; i < COEFFS / 2; i++) {
q->post_cos[i] = (1.0f / 32768) * cos(i / 256.0 * M_PI);
q->post_sin[i] = (1.0f / 32768) * sin(i / 256.0 * M_PI);
r1 = sin((i * 4.0 + 1.0) / 1024.0 * M_PI);
r2 = cos((i * 4.0 + 1.0) / 1024.0 * M_PI);
- if (i & 0x1)
- {
+ if (i & 0x1) {
q->pre_coef1[i] = (r1 + r2) * sqrt(2.0);
q->pre_coef2[i] = -(r1 - r2) * sqrt(2.0);
- }
- else
- {
+ } else {
q->pre_coef1[i] = -(r1 + r2) * sqrt(2.0);
q->pre_coef2[i] = (r1 - r2) * sqrt(2.0);
}
-
- q->last_fft_im[i] = 0;
}
/* Generate a square root table */
- for(i = 0; i < 30; i++) {
+ for (i = 0; i < 30; i++)
q->sqrt_tab[i] = sqrt(i);
- }
/* initialize the VLC tables */
- for(i = 0; i < 4 ; i++) {
- for(j = 0; j < 4; j++) {
+ for (i = 0; i < 4 ; i++) {
+ for (j = 0; j < 4; j++) {
huffman_vlc[i][j].table = &vlc_tables[vlc_offsets[i * 4 + j]];
huffman_vlc[i][j].table_allocated = vlc_offsets[i * 4 + j + 1] - vlc_offsets[i * 4 + j];
init_vlc(&huffman_vlc[i][j], 9, imc_huffman_sizes[i],
@@ -160,15 +227,28 @@ static av_cold int imc_decode_init(AVCodecContext * avctx)
imc_huffman_bits[i][j], 2, 2, INIT_VLC_USE_NEW_STATIC);
}
}
- q->one_div_log2 = 1/log(2);
+ q->one_div_log2 = 1 / log(2);
+
+ if (avctx->codec_id == CODEC_ID_IAC) {
+ }
+
+ if (avctx->codec_id == CODEC_ID_IAC) {
+ iac_generate_tabs(q, avctx->sample_rate);
+ } else {
+ memcpy(q->cyclTab, cyclTab, sizeof(cyclTab));
+ memcpy(q->cyclTab2, cyclTab2, sizeof(cyclTab2));
+ memcpy(q->weights1, imc_weights1, sizeof(imc_weights1));
+ memcpy(q->weights2, imc_weights2, sizeof(imc_weights2));
+ }
if ((ret = ff_fft_init(&q->fft, 7, 1))) {
av_log(avctx, AV_LOG_INFO, "FFT init failed\n");
return ret;
}
ff_dsputil_init(&q->dsp, avctx);
- avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
- avctx->channel_layout = AV_CH_LAYOUT_MONO;
+ avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+ avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO
+ : AV_CH_LAYOUT_STEREO;
avcodec_get_frame_defaults(&q->frame);
avctx->coded_frame = &q->frame;
@@ -176,8 +256,9 @@ static av_cold int imc_decode_init(AVCodecContext * avctx)
return 0;
}
-static void imc_calculate_coeffs(IMCContext* q, float* flcoeffs1, float* flcoeffs2, int* bandWidthT,
- float* flcoeffs3, float* flcoeffs5)
+static void imc_calculate_coeffs(IMCContext *q, float *flcoeffs1,
+ float *flcoeffs2, int *bandWidthT,
+ float *flcoeffs3, float *flcoeffs5)
{
float workT1[BANDS];
float workT2[BANDS];
@@ -186,13 +267,13 @@ static void imc_calculate_coeffs(IMCContext* q, float* flcoeffs1, float* flcoeff
float accum = 0.0;
int i, cnt2;
- for(i = 0; i < BANDS; i++) {
+ for (i = 0; i < BANDS; i++) {
flcoeffs5[i] = workT2[i] = 0.0;
- if (bandWidthT[i]){
+ if (bandWidthT[i]) {
workT1[i] = flcoeffs1[i] * flcoeffs1[i];
flcoeffs3[i] = 2.0 * flcoeffs2[i];
} else {
- workT1[i] = 0.0;
+ workT1[i] = 0.0;
flcoeffs3[i] = -30000.0;
}
workT3[i] = bandWidthT[i] * workT1[i] * 0.01;
@@ -200,37 +281,38 @@ static void imc_calculate_coeffs(IMCContext* q, float* flcoeffs1, float* flcoeff
workT3[i] = 0.0;
}
- for(i = 0; i < BANDS; i++) {
- for(cnt2 = i; cnt2 < cyclTab[i]; cnt2++)
+ for (i = 0; i < BANDS; i++) {
+ for (cnt2 = i; cnt2 < q->cyclTab[i]; cnt2++)
flcoeffs5[cnt2] = flcoeffs5[cnt2] + workT3[i];
- workT2[cnt2-1] = workT2[cnt2-1] + workT3[i];
+ workT2[cnt2 - 1] = workT2[cnt2 - 1] + workT3[i];
}
- for(i = 1; i < BANDS; i++) {
- accum = (workT2[i-1] + accum) * imc_weights1[i-1];
+ for (i = 1; i < BANDS; i++) {
+ accum = (workT2[i - 1] + accum) * q->weights1[i - 1];
flcoeffs5[i] += accum;
}
- for(i = 0; i < BANDS; i++)
+ for (i = 0; i < BANDS; i++)
workT2[i] = 0.0;
- for(i = 0; i < BANDS; i++) {
- for(cnt2 = i-1; cnt2 > cyclTab2[i]; cnt2--)
+ for (i = 0; i < BANDS; i++) {
+ for (cnt2 = i - 1; cnt2 > q->cyclTab2[i]; cnt2--)
flcoeffs5[cnt2] += workT3[i];
workT2[cnt2+1] += workT3[i];
}
accum = 0.0;
- for(i = BANDS-2; i >= 0; i--) {
- accum = (workT2[i+1] + accum) * imc_weights2[i];
+ for (i = BANDS-2; i >= 0; i--) {
+ accum = (workT2[i+1] + accum) * q->weights2[i];
flcoeffs5[i] += accum;
- //there is missing code here, but it seems to never be triggered
+ // there is missing code here, but it seems to never be triggered
}
}
-static void imc_read_level_coeffs(IMCContext* q, int stream_format_code, int* levlCoeffs)
+static void imc_read_level_coeffs(IMCContext *q, int stream_format_code,
+ int *levlCoeffs)
{
int i;
VLC *hufftab[4];
@@ -245,41 +327,42 @@ static void imc_read_level_coeffs(IMCContext* q, int stream_format_code, int* le
hufftab[3] = &huffman_vlc[s][3];
cb_sel = imc_cb_select[s];
- if(stream_format_code & 4)
+ if (stream_format_code & 4)
start = 1;
- if(start)
+ if (start)
levlCoeffs[0] = get_bits(&q->gb, 7);
- for(i = start; i < BANDS; i++){
- levlCoeffs[i] = get_vlc2(&q->gb, hufftab[cb_sel[i]]->table, hufftab[cb_sel[i]]->bits, 2);
- if(levlCoeffs[i] == 17)
+ for (i = start; i < BANDS; i++) {
+ levlCoeffs[i] = get_vlc2(&q->gb, hufftab[cb_sel[i]]->table,
+ hufftab[cb_sel[i]]->bits, 2);
+ if (levlCoeffs[i] == 17)
levlCoeffs[i] += get_bits(&q->gb, 4);
}
}
-static void imc_decode_level_coefficients(IMCContext* q, int* levlCoeffBuf, float* flcoeffs1,
- float* flcoeffs2)
+static void imc_decode_level_coefficients(IMCContext *q, int *levlCoeffBuf,
+ float *flcoeffs1, float *flcoeffs2)
{
int i, level;
float tmp, tmp2;
- //maybe some frequency division thingy
+ // maybe some frequency division thingy
flcoeffs1[0] = 20000.0 / pow (2, levlCoeffBuf[0] * 0.18945); // 0.18945 = log2(10) * 0.05703125
- flcoeffs2[0] = log(flcoeffs1[0])/log(2);
- tmp = flcoeffs1[0];
+ flcoeffs2[0] = log(flcoeffs1[0]) / log(2);
+ tmp = flcoeffs1[0];
tmp2 = flcoeffs2[0];
- for(i = 1; i < BANDS; i++) {
+ for (i = 1; i < BANDS; i++) {
level = levlCoeffBuf[i];
if (level == 16) {
flcoeffs1[i] = 1.0;
flcoeffs2[i] = 0.0;
} else {
if (level < 17)
- level -=7;
+ level -= 7;
else if (level <= 24)
- level -=32;
+ level -= 32;
else
- level -=16;
+ level -= 16;
tmp *= imc_exp_tab[15 + level];
tmp2 += 0.83048 * level; // 0.83048 = log2(10) * 0.25
@@ -290,17 +373,20 @@ static void imc_decode_level_coefficients(IMCContext* q, int* levlCoeffBuf, floa
}
-static void imc_decode_level_coefficients2(IMCContext* q, int* levlCoeffBuf, float* old_floor, float* flcoeffs1,
- float* flcoeffs2) {
+static void imc_decode_level_coefficients2(IMCContext *q, int *levlCoeffBuf,
+ float *old_floor, float *flcoeffs1,
+ float *flcoeffs2)
+{
int i;
- //FIXME maybe flag_buf = noise coding and flcoeffs1 = new scale factors
- // and flcoeffs2 old scale factors
- // might be incomplete due to a missing table that is in the binary code
- for(i = 0; i < BANDS; i++) {
+ /* FIXME maybe flag_buf = noise coding and flcoeffs1 = new scale factors
+ * and flcoeffs2 old scale factors
+ * might be incomplete due to a missing table that is in the binary code
+ */
+ for (i = 0; i < BANDS; i++) {
flcoeffs1[i] = 0;
- if(levlCoeffBuf[i] < 16) {
+ if (levlCoeffBuf[i] < 16) {
flcoeffs1[i] = imc_exp_tab2[levlCoeffBuf[i]] * old_floor[i];
- flcoeffs2[i] = (levlCoeffBuf[i]-7) * 0.83048 + flcoeffs2[i]; // 0.83048 = log2(10) * 0.25
+ flcoeffs2[i] = (levlCoeffBuf[i] - 7) * 0.83048 + flcoeffs2[i]; // 0.83048 = log2(10) * 0.25
} else {
flcoeffs1[i] = old_floor[i];
}
@@ -310,7 +396,9 @@ static void imc_decode_level_coefficients2(IMCContext* q, int* levlCoeffBuf, flo
/**
* Perform bit allocation depending on bits available
*/
-static int bit_allocation (IMCContext* q, int stream_format_code, int freebits, int flag) {
+static int bit_allocation(IMCContext *q, IMCChannel *chctx,
+ int stream_format_code, int freebits, int flag)
+{
int i, j;
const float limit = -1.e20;
float highest = 0.0;
@@ -327,63 +415,63 @@ static int bit_allocation (IMCContext* q, int stream_format_code, int freebits,
int flg;
int found_indx = 0;
- for(i = 0; i < BANDS; i++)
- highest = FFMAX(highest, q->flcoeffs1[i]);
+ for (i = 0; i < BANDS; i++)
+ highest = FFMAX(highest, chctx->flcoeffs1[i]);
- for(i = 0; i < BANDS-1; i++) {
- q->flcoeffs4[i] = q->flcoeffs3[i] - log(q->flcoeffs5[i])/log(2);
- }
- q->flcoeffs4[BANDS - 1] = limit;
+ for (i = 0; i < BANDS - 1; i++)
+ chctx->flcoeffs4[i] = chctx->flcoeffs3[i] - log(chctx->flcoeffs5[i]) / log(2);
+ chctx->flcoeffs4[BANDS - 1] = limit;
highest = highest * 0.25;
- for(i = 0; i < BANDS; i++) {
+ for (i = 0; i < BANDS; i++) {
indx = -1;
- if ((band_tab[i+1] - band_tab[i]) == q->bandWidthT[i])
+ if ((band_tab[i + 1] - band_tab[i]) == chctx->bandWidthT[i])
indx = 0;
- if ((band_tab[i+1] - band_tab[i]) > q->bandWidthT[i])
+ if ((band_tab[i + 1] - band_tab[i]) > chctx->bandWidthT[i])
indx = 1;
- if (((band_tab[i+1] - band_tab[i])/2) >= q->bandWidthT[i])
+ if (((band_tab[i + 1] - band_tab[i]) / 2) >= chctx->bandWidthT[i])
indx = 2;
if (indx == -1)
return AVERROR_INVALIDDATA;
- q->flcoeffs4[i] = q->flcoeffs4[i] + xTab[(indx*2 + (q->flcoeffs1[i] < highest)) * 2 + flag];
+ chctx->flcoeffs4[i] += xTab[(indx * 2 + (chctx->flcoeffs1[i] < highest)) * 2 + flag];
}
if (stream_format_code & 0x2) {
- q->flcoeffs4[0] = limit;
- q->flcoeffs4[1] = limit;
- q->flcoeffs4[2] = limit;
- q->flcoeffs4[3] = limit;
+ chctx->flcoeffs4[0] = limit;
+ chctx->flcoeffs4[1] = limit;
+ chctx->flcoeffs4[2] = limit;
+ chctx->flcoeffs4[3] = limit;
}
- for(i = (stream_format_code & 0x2)?4:0; i < BANDS-1; i++) {
- iacc += q->bandWidthT[i];
- summa += q->bandWidthT[i] * q->flcoeffs4[i];
+ for (i = (stream_format_code & 0x2) ? 4 : 0; i < BANDS - 1; i++) {
+ iacc += chctx->bandWidthT[i];
+ summa += chctx->bandWidthT[i] * chctx->flcoeffs4[i];
}
- q->bandWidthT[BANDS-1] = 0;
+ chctx->bandWidthT[BANDS - 1] = 0;
summa = (summa * 0.5 - freebits) / iacc;
- for(i = 0; i < BANDS/2; i++) {
+ for (i = 0; i < BANDS / 2; i++) {
rres = summer - freebits;
- if((rres >= -8) && (rres <= 8)) break;
+ if ((rres >= -8) && (rres <= 8))
+ break;
summer = 0;
- iacc = 0;
+ iacc = 0;
- for(j = (stream_format_code & 0x2)?4:0; j < BANDS; j++) {
- cwlen = av_clipf(((q->flcoeffs4[j] * 0.5) - summa + 0.5), 0, 6);
+ for (j = (stream_format_code & 0x2) ? 4 : 0; j < BANDS; j++) {
+ cwlen = av_clipf(((chctx->flcoeffs4[j] * 0.5) - summa + 0.5), 0, 6);
- q->bitsBandT[j] = cwlen;
- summer += q->bandWidthT[j] * cwlen;
+ chctx->bitsBandT[j] = cwlen;
+ summer += chctx->bandWidthT[j] * cwlen;
if (cwlen > 0)
- iacc += q->bandWidthT[j];
+ iacc += chctx->bandWidthT[j];
}
flg = t2;
@@ -392,32 +480,33 @@ static int bit_allocation (IMCContext* q, int stream_format_code, int freebits,
t2 = -1;
if (i == 0)
flg = t2;
- if(flg != t2)
+ if (flg != t2)
t1++;
summa = (float)(summer - freebits) / ((t1 + 1) * iacc) + summa;
}
- for(i = (stream_format_code & 0x2)?4:0; i < BANDS; i++) {
- for(j = band_tab[i]; j < band_tab[i+1]; j++)
- q->CWlengthT[j] = q->bitsBandT[i];
+ for (i = (stream_format_code & 0x2) ? 4 : 0; i < BANDS; i++) {
+ for (j = band_tab[i]; j < band_tab[i + 1]; j++)
+ chctx->CWlengthT[j] = chctx->bitsBandT[i];
}
if (freebits > summer) {
- for(i = 0; i < BANDS; i++) {
- workT[i] = (q->bitsBandT[i] == 6) ? -1.e20 : (q->bitsBandT[i] * -2 + q->flcoeffs4[i] - 0.415);
+ for (i = 0; i < BANDS; i++) {
+ workT[i] = (chctx->bitsBandT[i] == 6) ? -1.e20
+ : (chctx->bitsBandT[i] * -2 + chctx->flcoeffs4[i] - 0.415);
}
highest = 0.0;
- do{
+ do {
if (highest <= -1.e20)
break;
found_indx = 0;
highest = -1.e20;
- for(i = 0; i < BANDS; i++) {
+ for (i = 0; i < BANDS; i++) {
if (workT[i] > highest) {
highest = workT[i];
found_indx = i;
@@ -426,19 +515,20 @@ static int bit_allocation (IMCContext* q, int stream_format_code, int freebits,
if (highest > -1.e20) {
workT[found_indx] -= 2.0;
- if (++(q->bitsBandT[found_indx]) == 6)
+ if (++chctx->bitsBandT[found_indx] == 6)
workT[found_indx] = -1.e20;
- for(j = band_tab[found_indx]; j < band_tab[found_indx+1] && (freebits > summer); j++){
- q->CWlengthT[j]++;
+ for (j = band_tab[found_indx]; j < band_tab[found_indx + 1] && (freebits > summer); j++) {
+ chctx->CWlengthT[j]++;
summer++;
}
}
- }while (freebits > summer);
+ } while (freebits > summer);
}
if (freebits < summer) {
- for(i = 0; i < BANDS; i++) {
- workT[i] = q->bitsBandT[i] ? (q->bitsBandT[i] * -2 + q->flcoeffs4[i] + 1.585) : 1.e20;
+ for (i = 0; i < BANDS; i++) {
+ workT[i] = chctx->bitsBandT[i] ? (chctx->bitsBandT[i] * -2 + chctx->flcoeffs4[i] + 1.585)
+ : 1.e20;
}
if (stream_format_code & 0x2) {
workT[0] = 1.e20;
@@ -446,24 +536,25 @@ static int bit_allocation (IMCContext* q, int stream_format_code, int freebits,
workT[2] = 1.e20;
workT[3] = 1.e20;
}
- while (freebits < summer){
- lowest = 1.e10;
+ while (freebits < summer) {
+ lowest = 1.e10;
low_indx = 0;
- for(i = 0; i < BANDS; i++) {
+ for (i = 0; i < BANDS; i++) {
if (workT[i] < lowest) {
- lowest = workT[i];
+ lowest = workT[i];
low_indx = i;
}
}
- //if(lowest >= 1.e10) break;
+ // if (lowest >= 1.e10)
+ // break;
workT[low_indx] = lowest + 2.0;
- if (!(--q->bitsBandT[low_indx]))
+ if (!--chctx->bitsBandT[low_indx])
workT[low_indx] = 1.e20;
- for(j = band_tab[low_indx]; j < band_tab[low_indx+1] && (freebits < summer); j++){
- if(q->CWlengthT[j] > 0){
- q->CWlengthT[j]--;
+ for (j = band_tab[low_indx]; j < band_tab[low_indx+1] && (freebits < summer); j++) {
+ if (chctx->CWlengthT[j] > 0) {
+ chctx->CWlengthT[j]--;
summer--;
}
}
@@ -472,52 +563,54 @@ static int bit_allocation (IMCContext* q, int stream_format_code, int freebits,
return 0;
}
-static void imc_get_skip_coeff(IMCContext* q) {
+static void imc_get_skip_coeff(IMCContext *q, IMCChannel *chctx)
+{
int i, j;
- memset(q->skipFlagBits, 0, sizeof(q->skipFlagBits));
- memset(q->skipFlagCount, 0, sizeof(q->skipFlagCount));
- for(i = 0; i < BANDS; i++) {
- if (!q->bandFlagsBuf[i] || !q->bandWidthT[i])
+ memset(chctx->skipFlagBits, 0, sizeof(chctx->skipFlagBits));
+ memset(chctx->skipFlagCount, 0, sizeof(chctx->skipFlagCount));
+ for (i = 0; i < BANDS; i++) {
+ if (!chctx->bandFlagsBuf[i] || !chctx->bandWidthT[i])
continue;
- if (!q->skipFlagRaw[i]) {
- q->skipFlagBits[i] = band_tab[i+1] - band_tab[i];
+ if (!chctx->skipFlagRaw[i]) {
+ chctx->skipFlagBits[i] = band_tab[i + 1] - band_tab[i];
- for(j = band_tab[i]; j < band_tab[i+1]; j++) {
- if ((q->skipFlags[j] = get_bits1(&q->gb)))
- q->skipFlagCount[i]++;
+ for (j = band_tab[i]; j < band_tab[i + 1]; j++) {
+ chctx->skipFlags[j] = get_bits1(&q->gb);
+ if (chctx->skipFlags[j])
+ chctx->skipFlagCount[i]++;
}
} else {
- for(j = band_tab[i]; j < (band_tab[i+1]-1); j += 2) {
- if(!get_bits1(&q->gb)){//0
- q->skipFlagBits[i]++;
- q->skipFlags[j]=1;
- q->skipFlags[j+1]=1;
- q->skipFlagCount[i] += 2;
- }else{
- if(get_bits1(&q->gb)){//11
- q->skipFlagBits[i] +=2;
- q->skipFlags[j]=0;
- q->skipFlags[j+1]=1;
- q->skipFlagCount[i]++;
- }else{
- q->skipFlagBits[i] +=3;
- q->skipFlags[j+1]=0;
- if(!get_bits1(&q->gb)){//100
- q->skipFlags[j]=1;
- q->skipFlagCount[i]++;
- }else{//101
- q->skipFlags[j]=0;
+ for (j = band_tab[i]; j < band_tab[i + 1] - 1; j += 2) {
+ if (!get_bits1(&q->gb)) { // 0
+ chctx->skipFlagBits[i]++;
+ chctx->skipFlags[j] = 1;
+ chctx->skipFlags[j + 1] = 1;
+ chctx->skipFlagCount[i] += 2;
+ } else {
+ if (get_bits1(&q->gb)) { // 11
+ chctx->skipFlagBits[i] += 2;
+ chctx->skipFlags[j] = 0;
+ chctx->skipFlags[j + 1] = 1;
+ chctx->skipFlagCount[i]++;
+ } else {
+ chctx->skipFlagBits[i] += 3;
+ chctx->skipFlags[j + 1] = 0;
+ if (!get_bits1(&q->gb)) { // 100
+ chctx->skipFlags[j] = 1;
+ chctx->skipFlagCount[i]++;
+ } else { // 101
+ chctx->skipFlags[j] = 0;
}
}
}
}
- if (j < band_tab[i+1]) {
- q->skipFlagBits[i]++;
- if ((q->skipFlags[j] = get_bits1(&q->gb)))
- q->skipFlagCount[i]++;
+ if (j < band_tab[i + 1]) {
+ chctx->skipFlagBits[i]++;
+ if ((chctx->skipFlags[j] = get_bits1(&q->gb)))
+ chctx->skipFlagCount[i]++;
}
}
}
@@ -526,24 +619,27 @@ static void imc_get_skip_coeff(IMCContext* q) {
/**
* Increase highest' band coefficient sizes as some bits won't be used
*/
-static void imc_adjust_bit_allocation (IMCContext* q, int summer) {
+static void imc_adjust_bit_allocation(IMCContext *q, IMCChannel *chctx,
+ int summer)
+{
float workT[32];
int corrected = 0;
int i, j;
- float highest = 0;
- int found_indx=0;
+ float highest = 0;
+ int found_indx = 0;
- for(i = 0; i < BANDS; i++) {
- workT[i] = (q->bitsBandT[i] == 6) ? -1.e20 : (q->bitsBandT[i] * -2 + q->flcoeffs4[i] - 0.415);
+ for (i = 0; i < BANDS; i++) {
+ workT[i] = (chctx->bitsBandT[i] == 6) ? -1.e20
+ : (chctx->bitsBandT[i] * -2 + chctx->flcoeffs4[i] - 0.415);
}
while (corrected < summer) {
- if(highest <= -1.e20)
+ if (highest <= -1.e20)
break;
highest = -1.e20;
- for(i = 0; i < BANDS; i++) {
+ for (i = 0; i < BANDS; i++) {
if (workT[i] > highest) {
highest = workT[i];
found_indx = i;
@@ -552,12 +648,12 @@ static void imc_adjust_bit_allocation (IMCContext* q, int summer) {
if (highest > -1.e20) {
workT[found_indx] -= 2.0;
- if (++(q->bitsBandT[found_indx]) == 6)
+ if (++(chctx->bitsBandT[found_indx]) == 6)
workT[found_indx] = -1.e20;
- for(j = band_tab[found_indx]; j < band_tab[found_indx+1] && (corrected < summer); j++) {
- if (!q->skipFlags[j] && (q->CWlengthT[j] < 6)) {
- q->CWlengthT[j]++;
+ for (j = band_tab[found_indx]; j < band_tab[found_indx+1] && (corrected < summer); j++) {
+ if (!chctx->skipFlags[j] && (chctx->CWlengthT[j] < 6)) {
+ chctx->CWlengthT[j]++;
corrected++;
}
}
@@ -565,63 +661,72 @@ static void imc_adjust_bit_allocation (IMCContext* q, int summer) {
}
}
-static void imc_imdct256(IMCContext *q) {
+static void imc_imdct256(IMCContext *q, IMCChannel *chctx, int channels)
+{
int i;
float re, im;
+ float *dst1 = q->out_samples;
+ float *dst2 = q->out_samples + (COEFFS - 1) * channels;
/* prerotation */
- for(i=0; i < COEFFS/2; i++){
- q->samples[i].re = -(q->pre_coef1[i] * q->CWdecoded[COEFFS-1-i*2]) -
- (q->pre_coef2[i] * q->CWdecoded[i*2]);
- q->samples[i].im = (q->pre_coef2[i] * q->CWdecoded[COEFFS-1-i*2]) -
- (q->pre_coef1[i] * q->CWdecoded[i*2]);
+ for (i = 0; i < COEFFS / 2; i++) {
+ q->samples[i].re = -(q->pre_coef1[i] * chctx->CWdecoded[COEFFS - 1 - i * 2]) -
+ (q->pre_coef2[i] * chctx->CWdecoded[i * 2]);
+ q->samples[i].im = (q->pre_coef2[i] * chctx->CWdecoded[COEFFS - 1 - i * 2]) -
+ (q->pre_coef1[i] * chctx->CWdecoded[i * 2]);
}
/* FFT */
q->fft.fft_permute(&q->fft, q->samples);
- q->fft.fft_calc (&q->fft, q->samples);
+ q->fft.fft_calc(&q->fft, q->samples);
/* postrotation, window and reorder */
- for(i = 0; i < COEFFS/2; i++){
- re = (q->samples[i].re * q->post_cos[i]) + (-q->samples[i].im * q->post_sin[i]);
- im = (-q->samples[i].im * q->post_cos[i]) - (q->samples[i].re * q->post_sin[i]);
- q->out_samples[i*2] = (q->mdct_sine_window[COEFFS-1-i*2] * q->last_fft_im[i]) + (q->mdct_sine_window[i*2] * re);
- q->out_samples[COEFFS-1-i*2] = (q->mdct_sine_window[i*2] * q->last_fft_im[i]) - (q->mdct_sine_window[COEFFS-1-i*2] * re);
- q->last_fft_im[i] = im;
+ for (i = 0; i < COEFFS / 2; i++) {
+ re = ( q->samples[i].re * q->post_cos[i]) + (-q->samples[i].im * q->post_sin[i]);
+ im = (-q->samples[i].im * q->post_cos[i]) - ( q->samples[i].re * q->post_sin[i]);
+ *dst1 = (q->mdct_sine_window[COEFFS - 1 - i * 2] * chctx->last_fft_im[i])
+ + (q->mdct_sine_window[i * 2] * re);
+ *dst2 = (q->mdct_sine_window[i * 2] * chctx->last_fft_im[i])
+ - (q->mdct_sine_window[COEFFS - 1 - i * 2] * re);
+ dst1 += channels * 2;
+ dst2 -= channels * 2;
+ chctx->last_fft_im[i] = im;
}
}
-static int inverse_quant_coeff (IMCContext* q, int stream_format_code) {
+static int inverse_quant_coeff(IMCContext *q, IMCChannel *chctx,
+ int stream_format_code)
+{
int i, j;
int middle_value, cw_len, max_size;
- const float* quantizer;
+ const float *quantizer;
- for(i = 0; i < BANDS; i++) {
- for(j = band_tab[i]; j < band_tab[i+1]; j++) {
- q->CWdecoded[j] = 0;
- cw_len = q->CWlengthT[j];
+ for (i = 0; i < BANDS; i++) {
+ for (j = band_tab[i]; j < band_tab[i + 1]; j++) {
+ chctx->CWdecoded[j] = 0;
+ cw_len = chctx->CWlengthT[j];
- if (cw_len <= 0 || q->skipFlags[j])
+ if (cw_len <= 0 || chctx->skipFlags[j])
continue;
- max_size = 1 << cw_len;
+ max_size = 1 << cw_len;
middle_value = max_size >> 1;
- if (q->codewords[j] >= max_size || q->codewords[j] < 0)
+ if (chctx->codewords[j] >= max_size || chctx->codewords[j] < 0)
return AVERROR_INVALIDDATA;
- if (cw_len >= 4){
+ if (cw_len >= 4) {
quantizer = imc_quantizer2[(stream_format_code & 2) >> 1];
- if (q->codewords[j] >= middle_value)
- q->CWdecoded[j] = quantizer[q->codewords[j] - 8] * q->flcoeffs6[i];
+ if (chctx->codewords[j] >= middle_value)
+ chctx->CWdecoded[j] = quantizer[chctx->codewords[j] - 8] * chctx->flcoeffs6[i];
else
- q->CWdecoded[j] = -quantizer[max_size - q->codewords[j] - 8 - 1] * q->flcoeffs6[i];
+ chctx->CWdecoded[j] = -quantizer[max_size - chctx->codewords[j] - 8 - 1] * chctx->flcoeffs6[i];
}else{
- quantizer = imc_quantizer1[((stream_format_code & 2) >> 1) | (q->bandFlagsBuf[i] << 1)];
- if (q->codewords[j] >= middle_value)
- q->CWdecoded[j] = quantizer[q->codewords[j] - 1] * q->flcoeffs6[i];
+ quantizer = imc_quantizer1[((stream_format_code & 2) >> 1) | (chctx->bandFlagsBuf[i] << 1)];
+ if (chctx->codewords[j] >= middle_value)
+ chctx->CWdecoded[j] = quantizer[chctx->codewords[j] - 1] * chctx->flcoeffs6[i];
else
- q->CWdecoded[j] = -quantizer[max_size - 2 - q->codewords[j]] * q->flcoeffs6[i];
+ chctx->CWdecoded[j] = -quantizer[max_size - 2 - chctx->codewords[j]] * chctx->flcoeffs6[i];
}
}
}
@@ -629,209 +734,251 @@ static int inverse_quant_coeff (IMCContext* q, int stream_format_code) {
}
-static int imc_get_coeffs (IMCContext* q) {
+static int imc_get_coeffs(IMCContext *q, IMCChannel *chctx)
+{
int i, j, cw_len, cw;
- for(i = 0; i < BANDS; i++) {
- if(!q->sumLenArr[i]) continue;
- if (q->bandFlagsBuf[i] || q->bandWidthT[i]) {
- for(j = band_tab[i]; j < band_tab[i+1]; j++) {
- cw_len = q->CWlengthT[j];
+ for (i = 0; i < BANDS; i++) {
+ if (!chctx->sumLenArr[i])
+ continue;
+ if (chctx->bandFlagsBuf[i] || chctx->bandWidthT[i]) {
+ for (j = band_tab[i]; j < band_tab[i + 1]; j++) {
+ cw_len = chctx->CWlengthT[j];
cw = 0;
- if (get_bits_count(&q->gb) + cw_len > 512){
-//av_log(NULL,0,"Band %i coeff %i cw_len %i\n",i,j,cw_len);
+ if (get_bits_count(&q->gb) + cw_len > 512) {
+ // av_log(NULL, 0, "Band %i coeff %i cw_len %i\n", i, j, cw_len);
return AVERROR_INVALIDDATA;
}
- if(cw_len && (!q->bandFlagsBuf[i] || !q->skipFlags[j]))
+ if (cw_len && (!chctx->bandFlagsBuf[i] || !chctx->skipFlags[j]))
cw = get_bits(&q->gb, cw_len);
- q->codewords[j] = cw;
+ chctx->codewords[j] = cw;
}
}
}
return 0;
}
-static int imc_decode_frame(AVCodecContext * avctx, void *data,
- int *got_frame_ptr, AVPacket *avpkt)
+static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch)
{
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
-
- IMCContext *q = avctx->priv_data;
-
int stream_format_code;
int imc_hdr, i, j, ret;
int flag;
int bits, summer;
int counter, bitscount;
- LOCAL_ALIGNED_16(uint16_t, buf16, [IMC_BLOCK_SIZE / 2]);
-
- if (buf_size < IMC_BLOCK_SIZE) {
- av_log(avctx, AV_LOG_ERROR, "imc frame too small!\n");
- return AVERROR_INVALIDDATA;
- }
+ IMCChannel *chctx = q->chctx + ch;
- /* get output buffer */
- q->frame.nb_samples = COEFFS;
- if ((ret = avctx->get_buffer(avctx, &q->frame)) < 0) {
- av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
- return ret;
- }
- q->out_samples = (float *)q->frame.data[0];
-
- q->dsp.bswap16_buf(buf16, (const uint16_t*)buf, IMC_BLOCK_SIZE / 2);
-
- init_get_bits(&q->gb, (const uint8_t*)buf16, IMC_BLOCK_SIZE * 8);
/* Check the frame header */
imc_hdr = get_bits(&q->gb, 9);
- if (imc_hdr != IMC_FRAME_ID) {
- av_log(avctx, AV_LOG_ERROR, "imc frame header check failed!\n");
- av_log(avctx, AV_LOG_ERROR, "got %x instead of 0x21.\n", imc_hdr);
+ if (imc_hdr & 0x18) {
+ av_log(avctx, AV_LOG_ERROR, "frame header check failed!\n");
+ av_log(avctx, AV_LOG_ERROR, "got %X.\n", imc_hdr);
return AVERROR_INVALIDDATA;
}
stream_format_code = get_bits(&q->gb, 3);
- if(stream_format_code & 1){
- av_log(avctx, AV_LOG_ERROR, "Stream code format %X is not supported\n", stream_format_code);
- return AVERROR_INVALIDDATA;
+ if (stream_format_code & 1) {
+ av_log_ask_for_sample(avctx, "Stream format %X is not supported\n",
+ stream_format_code);
+ return AVERROR_PATCHWELCOME;
}
// av_log(avctx, AV_LOG_DEBUG, "stream_format_code = %d\n", stream_format_code);
if (stream_format_code & 0x04)
- q->decoder_reset = 1;
+ chctx->decoder_reset = 1;
- if(q->decoder_reset) {
+ if (chctx->decoder_reset) {
memset(q->out_samples, 0, sizeof(q->out_samples));
- for(i = 0; i < BANDS; i++)q->old_floor[i] = 1.0;
- for(i = 0; i < COEFFS; i++)q->CWdecoded[i] = 0;
- q->decoder_reset = 0;
+ for (i = 0; i < BANDS; i++)
+ chctx->old_floor[i] = 1.0;
+ for (i = 0; i < COEFFS; i++)
+ chctx->CWdecoded[i] = 0;
+ chctx->decoder_reset = 0;
}
flag = get_bits1(&q->gb);
- imc_read_level_coeffs(q, stream_format_code, q->levlCoeffBuf);
+ imc_read_level_coeffs(q, stream_format_code, chctx->levlCoeffBuf);
if (stream_format_code & 0x4)
- imc_decode_level_coefficients(q, q->levlCoeffBuf, q->flcoeffs1, q->flcoeffs2);
+ imc_decode_level_coefficients(q, chctx->levlCoeffBuf,
+ chctx->flcoeffs1, chctx->flcoeffs2);
else
- imc_decode_level_coefficients2(q, q->levlCoeffBuf, q->old_floor, q->flcoeffs1, q->flcoeffs2);
+ imc_decode_level_coefficients2(q, chctx->levlCoeffBuf, chctx->old_floor,
+ chctx->flcoeffs1, chctx->flcoeffs2);
- memcpy(q->old_floor, q->flcoeffs1, 32 * sizeof(float));
+ memcpy(chctx->old_floor, chctx->flcoeffs1, 32 * sizeof(float));
counter = 0;
- for (i=0 ; i<BANDS ; i++) {
- if (q->levlCoeffBuf[i] == 16) {
- q->bandWidthT[i] = 0;
+ for (i = 0; i < BANDS; i++) {
+ if (chctx->levlCoeffBuf[i] == 16) {
+ chctx->bandWidthT[i] = 0;
counter++;
} else
- q->bandWidthT[i] = band_tab[i+1] - band_tab[i];
+ chctx->bandWidthT[i] = band_tab[i + 1] - band_tab[i];
}
- memset(q->bandFlagsBuf, 0, BANDS * sizeof(int));
- for(i = 0; i < BANDS-1; i++) {
- if (q->bandWidthT[i])
- q->bandFlagsBuf[i] = get_bits1(&q->gb);
+ memset(chctx->bandFlagsBuf, 0, BANDS * sizeof(int));
+ for (i = 0; i < BANDS - 1; i++) {
+ if (chctx->bandWidthT[i])
+ chctx->bandFlagsBuf[i] = get_bits1(&q->gb);
}
- imc_calculate_coeffs(q, q->flcoeffs1, q->flcoeffs2, q->bandWidthT, q->flcoeffs3, q->flcoeffs5);
+ imc_calculate_coeffs(q, chctx->flcoeffs1, chctx->flcoeffs2, chctx->bandWidthT, chctx->flcoeffs3, chctx->flcoeffs5);
bitscount = 0;
/* first 4 bands will be assigned 5 bits per coefficient */
if (stream_format_code & 0x2) {
bitscount += 15;
- q->bitsBandT[0] = 5;
- q->CWlengthT[0] = 5;
- q->CWlengthT[1] = 5;
- q->CWlengthT[2] = 5;
- for(i = 1; i < 4; i++){
- bits = (q->levlCoeffBuf[i] == 16) ? 0 : 5;
- q->bitsBandT[i] = bits;
- for(j = band_tab[i]; j < band_tab[i+1]; j++) {
- q->CWlengthT[j] = bits;
- bitscount += bits;
+ chctx->bitsBandT[0] = 5;
+ chctx->CWlengthT[0] = 5;
+ chctx->CWlengthT[1] = 5;
+ chctx->CWlengthT[2] = 5;
+ for (i = 1; i < 4; i++) {
+ bits = (chctx->levlCoeffBuf[i] == 16) ? 0 : 5;
+ chctx->bitsBandT[i] = bits;
+ for (j = band_tab[i]; j < band_tab[i + 1]; j++) {
+ chctx->CWlengthT[j] = bits;
+ bitscount += bits;
}
}
}
+ if (avctx->codec_id == CODEC_ID_IAC) {
+ bitscount += !!chctx->bandWidthT[BANDS - 1];
+ if (!(stream_format_code & 0x2))
+ bitscount += 16;
+ }
- if((ret = bit_allocation (q, stream_format_code,
- 512 - bitscount - get_bits_count(&q->gb), flag)) < 0) {
+ if ((ret = bit_allocation(q, chctx, stream_format_code,
+ 512 - bitscount - get_bits_count(&q->gb),
+ flag)) < 0) {
av_log(avctx, AV_LOG_ERROR, "Bit allocations failed\n");
- q->decoder_reset = 1;
+ chctx->decoder_reset = 1;
return ret;
}
- for(i = 0; i < BANDS; i++) {
- q->sumLenArr[i] = 0;
- q->skipFlagRaw[i] = 0;
- for(j = band_tab[i]; j < band_tab[i+1]; j++)
- q->sumLenArr[i] += q->CWlengthT[j];
- if (q->bandFlagsBuf[i])
- if( (((band_tab[i+1] - band_tab[i]) * 1.5) > q->sumLenArr[i]) && (q->sumLenArr[i] > 0))
- q->skipFlagRaw[i] = 1;
+ for (i = 0; i < BANDS; i++) {
+ chctx->sumLenArr[i] = 0;
+ chctx->skipFlagRaw[i] = 0;
+ for (j = band_tab[i]; j < band_tab[i + 1]; j++)
+ chctx->sumLenArr[i] += chctx->CWlengthT[j];
+ if (chctx->bandFlagsBuf[i])
+ if ((((band_tab[i + 1] - band_tab[i]) * 1.5) > chctx->sumLenArr[i]) && (chctx->sumLenArr[i] > 0))
+ chctx->skipFlagRaw[i] = 1;
}
- imc_get_skip_coeff(q);
+ imc_get_skip_coeff(q, chctx);
- for(i = 0; i < BANDS; i++) {
- q->flcoeffs6[i] = q->flcoeffs1[i];
+ for (i = 0; i < BANDS; i++) {
+ chctx->flcoeffs6[i] = chctx->flcoeffs1[i];
/* band has flag set and at least one coded coefficient */
- if (q->bandFlagsBuf[i] && (band_tab[i+1] - band_tab[i]) != q->skipFlagCount[i]){
- q->flcoeffs6[i] *= q->sqrt_tab[band_tab[i+1] - band_tab[i]] /
- q->sqrt_tab[(band_tab[i+1] - band_tab[i] - q->skipFlagCount[i])];
+ if (chctx->bandFlagsBuf[i] && (band_tab[i + 1] - band_tab[i]) != chctx->skipFlagCount[i]) {
+ chctx->flcoeffs6[i] *= q->sqrt_tab[ band_tab[i + 1] - band_tab[i]] /
+ q->sqrt_tab[(band_tab[i + 1] - band_tab[i] - chctx->skipFlagCount[i])];
}
}
/* calculate bits left, bits needed and adjust bit allocation */
bits = summer = 0;
- for(i = 0; i < BANDS; i++) {
- if (q->bandFlagsBuf[i]) {
- for(j = band_tab[i]; j < band_tab[i+1]; j++) {
- if(q->skipFlags[j]) {
- summer += q->CWlengthT[j];
- q->CWlengthT[j] = 0;
+ for (i = 0; i < BANDS; i++) {
+ if (chctx->bandFlagsBuf[i]) {
+ for (j = band_tab[i]; j < band_tab[i + 1]; j++) {
+ if (chctx->skipFlags[j]) {
+ summer += chctx->CWlengthT[j];
+ chctx->CWlengthT[j] = 0;
}
}
- bits += q->skipFlagBits[i];
- summer -= q->skipFlagBits[i];
+ bits += chctx->skipFlagBits[i];
+ summer -= chctx->skipFlagBits[i];
}
}
- imc_adjust_bit_allocation(q, summer);
+ imc_adjust_bit_allocation(q, chctx, summer);
- for(i = 0; i < BANDS; i++) {
- q->sumLenArr[i] = 0;
+ for (i = 0; i < BANDS; i++) {
+ chctx->sumLenArr[i] = 0;
- for(j = band_tab[i]; j < band_tab[i+1]; j++)
- if (!q->skipFlags[j])
- q->sumLenArr[i] += q->CWlengthT[j];
+ for (j = band_tab[i]; j < band_tab[i + 1]; j++)
+ if (!chctx->skipFlags[j])
+ chctx->sumLenArr[i] += chctx->CWlengthT[j];
}
- memset(q->codewords, 0, sizeof(q->codewords));
+ memset(chctx->codewords, 0, sizeof(chctx->codewords));
- if(imc_get_coeffs(q) < 0) {
+ if (imc_get_coeffs(q, chctx) < 0) {
av_log(avctx, AV_LOG_ERROR, "Read coefficients failed\n");
- q->decoder_reset = 1;
+ chctx->decoder_reset = 1;
return AVERROR_INVALIDDATA;
}
- if(inverse_quant_coeff(q, stream_format_code) < 0) {
+ if (inverse_quant_coeff(q, chctx, stream_format_code) < 0) {
av_log(avctx, AV_LOG_ERROR, "Inverse quantization of coefficients failed\n");
- q->decoder_reset = 1;
+ chctx->decoder_reset = 1;
+ return AVERROR_INVALIDDATA;
+ }
+
+ memset(chctx->skipFlags, 0, sizeof(chctx->skipFlags));
+
+ imc_imdct256(q, chctx, avctx->channels);
+
+ return 0;
+}
+
+static int imc_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ int ret, i;
+
+ IMCContext *q = avctx->priv_data;
+
+ LOCAL_ALIGNED_16(uint16_t, buf16, [IMC_BLOCK_SIZE / 2]);
+
+ if (buf_size < IMC_BLOCK_SIZE * avctx->channels) {
+ av_log(avctx, AV_LOG_ERROR, "frame too small!\n");
return AVERROR_INVALIDDATA;
}
- memset(q->skipFlags, 0, sizeof(q->skipFlags));
+ /* get output buffer */
+ q->frame.nb_samples = COEFFS;
+ if ((ret = avctx->get_buffer(avctx, &q->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+
+ for (i = 0; i < avctx->channels; i++) {
+ q->out_samples = (float*)q->frame.data[0] + i;
+
+ q->dsp.bswap16_buf(buf16, (const uint16_t*)buf, IMC_BLOCK_SIZE / 2);
+
+ init_get_bits(&q->gb, (const uint8_t*)buf16, IMC_BLOCK_SIZE * 8);
- imc_imdct256(q);
+ buf += IMC_BLOCK_SIZE;
+
+ if ((ret = imc_decode_block(avctx, q, i)) < 0)
+ return ret;
+ }
+
+ if (avctx->channels == 2) {
+ float *src = (float*)q->frame.data[0], t1, t2;
+
+ for (i = 0; i < COEFFS; i++) {
+ t1 = src[0];
+ t2 = src[1];
+ src[0] = t1 + t2;
+ src[1] = t1 - t2;
+ src += 2;
+ }
+ }
*got_frame_ptr = 1;
*(AVFrame *)data = q->frame;
- return IMC_BLOCK_SIZE;
+ return IMC_BLOCK_SIZE * avctx->channels;
}
@@ -856,3 +1003,15 @@ AVCodec ff_imc_decoder = {
.capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("IMC (Intel Music Coder)"),
};
+
+AVCodec ff_iac_decoder = {
+ .name = "iac",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_IAC,
+ .priv_data_size = sizeof(IMCContext),
+ .init = imc_decode_init,
+ .close = imc_decode_close,
+ .decode = imc_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
+ .long_name = NULL_IF_CONFIG_SMALL("IAC (Indeo Audio Coder)"),
+};
diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c
index ed3535a..d526d91 100644
--- a/libavcodec/indeo3.c
+++ b/libavcodec/indeo3.c
@@ -194,6 +194,8 @@ static av_cold int allocate_frame_buffers(Indeo3DecodeContext *ctx,
/* set buffer pointers = buf_ptr + pitch and thus skip the INTRA prediction line */
ctx->planes[p].pixels[0] = ctx->planes[p].buffers[0] + ctx->planes[p].pitch;
ctx->planes[p].pixels[1] = ctx->planes[p].buffers[1] + ctx->planes[p].pitch;
+ memset(ctx->planes[p].pixels[0], 0, ctx->planes[p].pitch * ctx->planes[p].height);
+ memset(ctx->planes[p].pixels[1], 0, ctx->planes[p].pitch * ctx->planes[p].height);
}
return 0;
@@ -207,6 +209,7 @@ static av_cold void free_frame_buffers(Indeo3DecodeContext *ctx)
for (p = 0; p < 3; p++) {
av_freep(&ctx->planes[p].buffers[0]);
av_freep(&ctx->planes[p].buffers[1]);
+ ctx->planes[p].pixels[0] = ctx->planes[p].pixels[1] = 0;
}
}
@@ -344,8 +347,10 @@ if (*data_ptr >= last_ptr) \
fill_64(dst, pix64, num_lines << 1, row_offset)
#define APPLY_DELTA_4 \
- AV_WN16A(dst + line_offset , AV_RN16A(ref ) + delta_tab->deltas[dyad1]);\
- AV_WN16A(dst + line_offset + 2, AV_RN16A(ref + 2) + delta_tab->deltas[dyad2]);\
+ AV_WN16A(dst + line_offset ,\
+ (AV_RN16A(ref ) + delta_tab->deltas[dyad1]) & 0x7F7F);\
+ AV_WN16A(dst + line_offset + 2,\
+ (AV_RN16A(ref + 2) + delta_tab->deltas[dyad2]) & 0x7F7F);\
if (mode >= 3) {\
if (is_top_of_cell && !cell->ypos) {\
AV_COPY32(dst, dst + row_offset);\
@@ -358,14 +363,14 @@ if (*data_ptr >= last_ptr) \
/* apply two 32-bit VQ deltas to next even line */\
if (is_top_of_cell) { \
AV_WN32A(dst + row_offset , \
- replicate32(AV_RN32A(ref )) + delta_tab->deltas_m10[dyad1]);\
+ (replicate32(AV_RN32A(ref )) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\
AV_WN32A(dst + row_offset + 4, \
- replicate32(AV_RN32A(ref + 4)) + delta_tab->deltas_m10[dyad2]);\
+ (replicate32(AV_RN32A(ref + 4)) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\
} else { \
AV_WN32A(dst + row_offset , \
- AV_RN32A(ref ) + delta_tab->deltas_m10[dyad1]);\
+ (AV_RN32A(ref ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\
AV_WN32A(dst + row_offset + 4, \
- AV_RN32A(ref + 4) + delta_tab->deltas_m10[dyad2]);\
+ (AV_RN32A(ref + 4) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\
} \
/* odd lines are not coded but rather interpolated/replicated */\
/* first line of the cell on the top of image? - replicate */\
@@ -379,22 +384,22 @@ if (*data_ptr >= last_ptr) \
#define APPLY_DELTA_1011_INTER \
if (mode == 10) { \
AV_WN32A(dst , \
- AV_RN32A(dst ) + delta_tab->deltas_m10[dyad1]);\
+ (AV_RN32A(dst ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\
AV_WN32A(dst + 4 , \
- AV_RN32A(dst + 4 ) + delta_tab->deltas_m10[dyad2]);\
+ (AV_RN32A(dst + 4 ) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\
AV_WN32A(dst + row_offset , \
- AV_RN32A(dst + row_offset ) + delta_tab->deltas_m10[dyad1]);\
+ (AV_RN32A(dst + row_offset ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\
AV_WN32A(dst + row_offset + 4, \
- AV_RN32A(dst + row_offset + 4) + delta_tab->deltas_m10[dyad2]);\
+ (AV_RN32A(dst + row_offset + 4) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\
} else { \
AV_WN16A(dst , \
- AV_RN16A(dst ) + delta_tab->deltas[dyad1]);\
+ (AV_RN16A(dst ) + delta_tab->deltas[dyad1]) & 0x7F7F);\
AV_WN16A(dst + 2 , \
- AV_RN16A(dst + 2 ) + delta_tab->deltas[dyad2]);\
+ (AV_RN16A(dst + 2 ) + delta_tab->deltas[dyad2]) & 0x7F7F);\
AV_WN16A(dst + row_offset , \
- AV_RN16A(dst + row_offset ) + delta_tab->deltas[dyad1]);\
+ (AV_RN16A(dst + row_offset ) + delta_tab->deltas[dyad1]) & 0x7F7F);\
AV_WN16A(dst + row_offset + 2, \
- AV_RN16A(dst + row_offset + 2) + delta_tab->deltas[dyad2]);\
+ (AV_RN16A(dst + row_offset + 2) + delta_tab->deltas[dyad2]) & 0x7F7F);\
}
@@ -773,12 +778,12 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
/* get motion vector index and setup the pointer to the mv set */
if (!ctx->need_resync)
ctx->next_cell_data = &ctx->gb.buffer[(get_bits_count(&ctx->gb) + 7) >> 3];
- mv_idx = *(ctx->next_cell_data++) << 1;
+ mv_idx = *(ctx->next_cell_data++);
if (mv_idx >= ctx->num_vectors) {
av_log(avctx, AV_LOG_ERROR, "motion vector index out of range\n");
return AVERROR_INVALIDDATA;
}
- curr_cell.mv_ptr = &ctx->mc_vectors[mv_idx];
+ curr_cell.mv_ptr = &ctx->mc_vectors[mv_idx << 1];
curr_cell.tree = 1; /* enter the VQ tree */
UPDATE_BITPOS(8);
} else { /* VQ tree DATA code */
@@ -895,6 +900,14 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
av_dlog(avctx, "Frame dimensions changed!\n");
+ if (width < 16 || width > 640 ||
+ height < 16 || height > 480 ||
+ width & 3 || height & 3) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Invalid picture dimensions: %d x %d!\n", width, height);
+ return AVERROR_INVALIDDATA;
+ }
+
ctx->width = width;
ctx->height = height;
diff --git a/libavcodec/indeo4.c b/libavcodec/indeo4.c
index 3e8a398..b4e14f6 100644
--- a/libavcodec/indeo4.c
+++ b/libavcodec/indeo4.c
@@ -35,15 +35,12 @@
#include "ivi_common.h"
#include "indeo4data.h"
-#define IVI4_STREAM_ANALYSER 0
-#define IVI4_DEBUG_CHECKSUM 0
-
/**
* Indeo 4 frame types.
*/
enum {
FRAMETYPE_INTRA = 0,
- FRAMETYPE_BIDIR1 = 1, ///< bidirectional frame
+ FRAMETYPE_INTRA1 = 1, ///< intra frame with slightly different bitstream coding
FRAMETYPE_INTER = 2, ///< non-droppable P-frame
FRAMETYPE_BIDIR = 3, ///< bidirectional frame
FRAMETYPE_INTER_NOREF = 4, ///< droppable P-frame
@@ -54,46 +51,6 @@ enum {
#define IVI4_PIC_SIZE_ESC 7
-typedef struct {
- GetBitContext gb;
- AVFrame frame;
- RVMapDesc rvmap_tabs[9]; ///< local corrected copy of the static rvmap tables
-
- uint32_t frame_num;
- int frame_type;
- int prev_frame_type; ///< frame type of the previous frame
- uint32_t data_size; ///< size of the frame data in bytes from picture header
- int is_scalable;
- int transp_status; ///< transparency mode status: 1 - enabled
-
- IVIPicConfig pic_conf;
- IVIPlaneDesc planes[3]; ///< color planes
-
- int buf_switch; ///< used to switch between three buffers
- int dst_buf; ///< buffer index for the currently decoded frame
- int ref_buf; ///< inter frame reference buffer index
-
- IVIHuffTab mb_vlc; ///< current macroblock table descriptor
- IVIHuffTab blk_vlc; ///< current block table descriptor
-
- uint16_t checksum; ///< frame checksum
-
- uint8_t rvmap_sel;
- uint8_t in_imf;
- uint8_t in_q; ///< flag for explicitly stored quantiser delta
- uint8_t pic_glob_quant;
- uint8_t unknown1;
-
-#if IVI4_STREAM_ANALYSER
- uint8_t has_b_frames;
- uint8_t has_transp;
- uint8_t uses_tiling;
- uint8_t uses_haar;
- uint8_t uses_fullpel;
-#endif
-} IVI4DecContext;
-
-
static const struct {
InvTransformPtr *inv_trans;
DCTransformPtr *dc_trans;
@@ -158,7 +115,7 @@ static inline int scale_tile_size(int def_size, int size_factor)
* @param[in] avctx pointer to the AVCodecContext
* @return result code: 0 = OK, negative number = error
*/
-static int decode_pic_hdr(IVI4DecContext *ctx, AVCodecContext *avctx)
+static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx)
{
int pic_size_indx, i, p;
IVIPicConfig pic_conf;
@@ -176,8 +133,7 @@ static int decode_pic_hdr(IVI4DecContext *ctx, AVCodecContext *avctx)
}
#if IVI4_STREAM_ANALYSER
- if ( ctx->frame_type == FRAMETYPE_BIDIR1
- || ctx->frame_type == FRAMETYPE_BIDIR)
+ if (ctx->frame_type == FRAMETYPE_BIDIR)
ctx->has_b_frames = 1;
#endif
@@ -322,7 +278,7 @@ static int decode_pic_hdr(IVI4DecContext *ctx, AVCodecContext *avctx)
* @param[in] avctx pointer to the AVCodecContext
* @return result code: 0 = OK, negative number = error
*/
-static int decode_band_hdr(IVI4DecContext *ctx, IVIBandDesc *band,
+static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band,
AVCodecContext *avctx)
{
int plane, band_num, indx, transform_id, scan_indx;
@@ -458,7 +414,7 @@ static int decode_band_hdr(IVI4DecContext *ctx, IVIBandDesc *band,
* @param[in] avctx pointer to the AVCodecContext
* @return result code: 0 = OK, negative number = error
*/
-static int decode_mb_info(IVI4DecContext *ctx, IVIBandDesc *band,
+static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band,
IVITile *tile, AVCodecContext *avctx)
{
int x, y, mv_x, mv_y, mv_delta, offs, mb_offset, blks_per_mb,
@@ -514,7 +470,8 @@ static int decode_mb_info(IVI4DecContext *ctx, IVIBandDesc *band,
} else {
if (band->inherit_mv) {
mb->type = ref_mb->type; /* copy mb_type from corresponding reference mb */
- } else if (ctx->frame_type == FRAMETYPE_INTRA) {
+ } else if (ctx->frame_type == FRAMETYPE_INTRA ||
+ ctx->frame_type == FRAMETYPE_INTRA1) {
mb->type = 0; /* mb_type is always INTRA for intra-frames */
} else {
mb->type = get_bits(&ctx->gb, mb_type_bits);
@@ -574,128 +531,15 @@ static int decode_mb_info(IVI4DecContext *ctx, IVIBandDesc *band,
/**
- * Decode an Indeo 4 band.
- *
- * @param[in,out] ctx pointer to the decoder context
- * @param[in,out] band pointer to the band descriptor
- * @param[in] avctx pointer to the AVCodecContext
- * @return result code: 0 = OK, negative number = error
- */
-static int decode_band(IVI4DecContext *ctx, int plane_num,
- IVIBandDesc *band, AVCodecContext *avctx)
-{
- int result, i, t, pos, idx1, idx2;
- IVITile *tile;
-
- band->buf = band->bufs[ctx->dst_buf];
- band->ref_buf = band->bufs[ctx->ref_buf];
-
- result = decode_band_hdr(ctx, band, avctx);
- if (result) {
- av_log(avctx, AV_LOG_ERROR, "Error decoding band header\n");
- return result;
- }
-
- if (band->is_empty) {
- av_log(avctx, AV_LOG_ERROR, "Empty band encountered!\n");
- return AVERROR_INVALIDDATA;
- }
-
- band->rv_map = &ctx->rvmap_tabs[band->rvmap_sel];
-
- /* apply corrections to the selected rvmap table if present */
- for (i = 0; i < band->num_corr; i++) {
- idx1 = band->corr[i * 2];
- idx2 = band->corr[i * 2 + 1];
- FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]);
- FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);
- }
-
- pos = get_bits_count(&ctx->gb);
-
- for (t = 0; t < band->num_tiles; t++) {
- tile = &band->tiles[t];
-
- tile->is_empty = get_bits1(&ctx->gb);
- if (tile->is_empty) {
- ff_ivi_process_empty_tile(avctx, band, tile,
- (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3));
- av_dlog(avctx, "Empty tile encountered!\n");
- } else {
- tile->data_size = ff_ivi_dec_tile_data_size(&ctx->gb);
- if (!tile->data_size) {
- av_log(avctx, AV_LOG_ERROR, "Tile data size is zero!\n");
- return AVERROR_INVALIDDATA;
- }
-
- result = decode_mb_info(ctx, band, tile, avctx);
- if (result < 0)
- break;
-
- result = ff_ivi_decode_blocks(&ctx->gb, band, tile);
- if (result < 0 || ((get_bits_count(&ctx->gb) - pos) >> 3) != tile->data_size) {
- av_log(avctx, AV_LOG_ERROR, "Corrupted tile data encountered!\n");
- break;
- }
-
- pos += tile->data_size << 3; // skip to next tile
- }
- }
-
- /* restore the selected rvmap table by applying its corrections in reverse order */
- for (i = band->num_corr - 1; i >= 0; i--) {
- idx1 = band->corr[i * 2];
- idx2 = band->corr[i * 2 + 1];
- FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]);
- FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);
- }
-
-#if defined(DEBUG) && IVI4_DEBUG_CHECKSUM
- if (band->checksum_present) {
- uint16_t chksum = ivi_calc_band_checksum(band);
- if (chksum != band->checksum) {
- av_log(avctx, AV_LOG_ERROR,
- "Band checksum mismatch! Plane %d, band %d, received: %x, calculated: %x\n",
- band->plane, band->band_num, band->checksum, chksum);
- }
- }
-#endif
-
- align_get_bits(&ctx->gb);
-
- return 0;
-}
-
-
-static av_cold int decode_init(AVCodecContext *avctx)
-{
- IVI4DecContext *ctx = avctx->priv_data;
-
- ff_ivi_init_static_vlc();
-
- /* copy rvmap tables in our context so we can apply changes to them */
- memcpy(ctx->rvmap_tabs, ff_ivi_rvmap_tabs, sizeof(ff_ivi_rvmap_tabs));
-
- /* Force allocation of the internal buffers */
- /* during picture header decoding. */
- ctx->pic_conf.pic_width = 0;
- ctx->pic_conf.pic_height = 0;
-
- avctx->pix_fmt = PIX_FMT_YUV410P;
-
- return 0;
-}
-
-
-/**
* Rearrange decoding and reference buffers.
*
* @param[in,out] ctx pointer to the decoder context
*/
-static void switch_buffers(IVI4DecContext *ctx)
+static void switch_buffers(IVI45DecContext *ctx)
{
switch (ctx->prev_frame_type) {
case FRAMETYPE_INTRA:
+ case FRAMETYPE_INTRA1:
case FRAMETYPE_INTER:
ctx->buf_switch ^= 1;
ctx->dst_buf = ctx->buf_switch;
@@ -707,6 +551,7 @@ static void switch_buffers(IVI4DecContext *ctx)
switch (ctx->frame_type) {
case FRAMETYPE_INTRA:
+ case FRAMETYPE_INTRA1:
ctx->buf_switch = 0;
/* FALLTHROUGH */
case FRAMETYPE_INTER:
@@ -721,95 +566,33 @@ static void switch_buffers(IVI4DecContext *ctx)
}
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
- AVPacket *avpkt)
+static int is_nonnull_frame(IVI45DecContext *ctx)
{
- IVI4DecContext *ctx = avctx->priv_data;
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- int result, p, b;
-
- init_get_bits(&ctx->gb, buf, buf_size * 8);
-
- result = decode_pic_hdr(ctx, avctx);
- if (result) {
- av_log(avctx, AV_LOG_ERROR, "Error decoding picture header\n");
- return result;
- }
-
- switch_buffers(ctx);
-
- if (ctx->frame_type < FRAMETYPE_NULL_FIRST) {
- for (p = 0; p < 3; p++) {
- for (b = 0; b < ctx->planes[p].num_bands; b++) {
- result = decode_band(ctx, p, &ctx->planes[p].bands[b], avctx);
- if (result) {
- av_log(avctx, AV_LOG_ERROR,
- "Error decoding band: %d, plane: %d\n", b, p);
- return result;
- }
- }
- }
- }
-
- /* If the bidirectional mode is enabled, next I and the following P frame will */
- /* be sent together. Unfortunately the approach below seems to be the only way */
- /* to handle the B-frames mode. That's exactly the same Intel decoders do. */
- if (ctx->frame_type == FRAMETYPE_INTRA) {
- while (get_bits(&ctx->gb, 8)); // skip version string
- skip_bits_long(&ctx->gb, 64); // skip padding, TODO: implement correct 8-bytes alignment
- if (get_bits_left(&ctx->gb) > 18 && show_bits(&ctx->gb, 18) == 0x3FFF8)
- av_log(avctx, AV_LOG_ERROR, "Buffer contains IP frames!\n");
- }
-
- if (ctx->frame.data[0])
- avctx->release_buffer(avctx, &ctx->frame);
-
- ctx->frame.reference = 0;
- if ((result = avctx->get_buffer(avctx, &ctx->frame)) < 0) {
- av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
- return result;
- }
-
- if (ctx->is_scalable) {
- ff_ivi_recompose_haar(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0], 4);
- } else {
- ff_ivi_output_plane(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]);
- }
-
- ff_ivi_output_plane(&ctx->planes[2], ctx->frame.data[1], ctx->frame.linesize[1]);
- ff_ivi_output_plane(&ctx->planes[1], ctx->frame.data[2], ctx->frame.linesize[2]);
-
- *data_size = sizeof(AVFrame);
- *(AVFrame*)data = ctx->frame;
-
- return buf_size;
+ return ctx->frame_type < FRAMETYPE_NULL_FIRST;
}
-static av_cold int decode_close(AVCodecContext *avctx)
+static av_cold int decode_init(AVCodecContext *avctx)
{
- IVI4DecContext *ctx = avctx->priv_data;
+ IVI45DecContext *ctx = avctx->priv_data;
- ff_ivi_free_buffers(&ctx->planes[0]);
+ ff_ivi_init_static_vlc();
- if (ctx->frame.data[0])
- avctx->release_buffer(avctx, &ctx->frame);
+ /* copy rvmap tables in our context so we can apply changes to them */
+ memcpy(ctx->rvmap_tabs, ff_ivi_rvmap_tabs, sizeof(ff_ivi_rvmap_tabs));
-#if IVI4_STREAM_ANALYSER
- if (ctx->is_scalable)
- av_log(avctx, AV_LOG_ERROR, "This video uses scalability mode!\n");
- if (ctx->uses_tiling)
- av_log(avctx, AV_LOG_ERROR, "This video uses local decoding!\n");
- if (ctx->has_b_frames)
- av_log(avctx, AV_LOG_ERROR, "This video contains B-frames!\n");
- if (ctx->has_transp)
- av_log(avctx, AV_LOG_ERROR, "Transparency mode is enabled!\n");
- if (ctx->uses_haar)
- av_log(avctx, AV_LOG_ERROR, "This video uses Haar transform!\n");
- if (ctx->uses_fullpel)
- av_log(avctx, AV_LOG_ERROR, "This video uses fullpel motion vectors!\n");
-#endif
+ /* Force allocation of the internal buffers */
+ /* during picture header decoding. */
+ ctx->pic_conf.pic_width = 0;
+ ctx->pic_conf.pic_height = 0;
+
+ avctx->pix_fmt = PIX_FMT_YUV410P;
+
+ ctx->decode_pic_hdr = decode_pic_hdr;
+ ctx->decode_band_hdr = decode_band_hdr;
+ ctx->decode_mb_info = decode_mb_info;
+ ctx->switch_buffers = switch_buffers;
+ ctx->is_nonnull_frame = is_nonnull_frame;
return 0;
}
@@ -819,9 +602,9 @@ AVCodec ff_indeo4_decoder = {
.name = "indeo4",
.type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_INDEO4,
- .priv_data_size = sizeof(IVI4DecContext),
+ .priv_data_size = sizeof(IVI45DecContext),
.init = decode_init,
- .close = decode_close,
- .decode = decode_frame,
+ .close = ff_ivi_decode_close,
+ .decode = ff_ivi_decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 4"),
};
diff --git a/libavcodec/indeo5.c b/libavcodec/indeo5.c
index deb76b9..d903cb2 100644
--- a/libavcodec/indeo5.c
+++ b/libavcodec/indeo5.c
@@ -48,37 +48,6 @@ enum {
#define IVI5_PIC_SIZE_ESC 15
-#define IVI5_IS_PROTECTED 0x20
-
-typedef struct {
- GetBitContext gb;
- AVFrame frame;
- RVMapDesc rvmap_tabs[9]; ///< local corrected copy of the static rvmap tables
- IVIPlaneDesc planes[3]; ///< color planes
- const uint8_t *frame_data; ///< input frame data pointer
- int buf_switch; ///< used to switch between three buffers
- int inter_scal; ///< signals a sequence of scalable inter frames
- int dst_buf; ///< buffer index for the currently decoded frame
- int ref_buf; ///< inter frame reference buffer index
- int ref2_buf; ///< temporal storage for switching buffers
- uint32_t frame_size; ///< frame size in bytes
- int frame_type;
- int prev_frame_type; ///< frame type of the previous frame
- int frame_num;
- uint32_t pic_hdr_size; ///< picture header size in bytes
- uint8_t frame_flags;
- uint16_t checksum; ///< frame checksum
-
- IVIHuffTab mb_vlc; ///< vlc table for decoding macroblock data
-
- uint16_t gop_hdr_size;
- uint8_t gop_flags;
- int is_scalable;
- uint32_t lock_word;
- IVIPicConfig pic_conf;
-} IVI5DecContext;
-
-
/**
* Decode Indeo5 GOP (Group of pictures) header.
* This header is present in key frames only.
@@ -88,7 +57,7 @@ typedef struct {
* @param[in] avctx ptr to the AVCodecContext
* @return result code: 0 = OK, -1 = error
*/
-static int decode_gop_header(IVI5DecContext *ctx, AVCodecContext *avctx)
+static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx)
{
int result, i, p, tile_size, pic_size_indx, mb_size, blk_size;
int quant_mat, blk_size_changed = 0;
@@ -318,7 +287,7 @@ static inline void skip_hdr_extension(GetBitContext *gb)
* @param[in] avctx ptr to the AVCodecContext
* @return result code: 0 = OK, -1 = error
*/
-static int decode_pic_hdr(IVI5DecContext *ctx, AVCodecContext *avctx)
+static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx)
{
if (get_bits(&ctx->gb, 5) != 0x1F) {
av_log(avctx, AV_LOG_ERROR, "Invalid picture start code!\n");
@@ -371,7 +340,7 @@ static int decode_pic_hdr(IVI5DecContext *ctx, AVCodecContext *avctx)
* @param[in] avctx ptr to the AVCodecContext
* @return result code: 0 = OK, -1 = error
*/
-static int decode_band_hdr(IVI5DecContext *ctx, IVIBandDesc *band,
+static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band,
AVCodecContext *avctx)
{
int i;
@@ -441,7 +410,7 @@ static int decode_band_hdr(IVI5DecContext *ctx, IVIBandDesc *band,
* @param[in] avctx ptr to the AVCodecContext
* @return result code: 0 = OK, -1 = error
*/
-static int decode_mb_info(IVI5DecContext *ctx, IVIBandDesc *band,
+static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band,
IVITile *tile, AVCodecContext *avctx)
{
int x, y, mv_x, mv_y, mv_delta, offs, mb_offset,
@@ -561,101 +530,11 @@ static int decode_mb_info(IVI5DecContext *ctx, IVIBandDesc *band,
/**
- * Decode an Indeo5 band.
- *
- * @param[in,out] ctx ptr to the decoder context
- * @param[in,out] band ptr to the band descriptor
- * @param[in] avctx ptr to the AVCodecContext
- * @return result code: 0 = OK, -1 = error
- */
-static int decode_band(IVI5DecContext *ctx, int plane_num,
- IVIBandDesc *band, AVCodecContext *avctx)
-{
- int result, i, t, idx1, idx2, pos;
- IVITile *tile;
-
- band->buf = band->bufs[ctx->dst_buf];
- band->ref_buf = band->bufs[ctx->ref_buf];
- band->data_ptr = ctx->frame_data + (get_bits_count(&ctx->gb) >> 3);
-
- result = decode_band_hdr(ctx, band, avctx);
- if (result) {
- av_log(avctx, AV_LOG_ERROR, "Error while decoding band header: %d\n",
- result);
- return -1;
- }
-
- if (band->is_empty) {
- av_log(avctx, AV_LOG_ERROR, "Empty band encountered!\n");
- return -1;
- }
-
- band->rv_map = &ctx->rvmap_tabs[band->rvmap_sel];
-
- /* apply corrections to the selected rvmap table if present */
- for (i = 0; i < band->num_corr; i++) {
- idx1 = band->corr[i*2];
- idx2 = band->corr[i*2+1];
- FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]);
- FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);
- }
-
- pos = get_bits_count(&ctx->gb);
-
- for (t = 0; t < band->num_tiles; t++) {
- tile = &band->tiles[t];
-
- tile->is_empty = get_bits1(&ctx->gb);
- if (tile->is_empty) {
- ff_ivi_process_empty_tile(avctx, band, tile,
- (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3));
- } else {
- tile->data_size = ff_ivi_dec_tile_data_size(&ctx->gb);
-
- result = decode_mb_info(ctx, band, tile, avctx);
- if (result < 0)
- break;
-
- result = ff_ivi_decode_blocks(&ctx->gb, band, tile);
- if (result < 0 || (get_bits_count(&ctx->gb) - pos) >> 3 != tile->data_size) {
- av_log(avctx, AV_LOG_ERROR, "Corrupted tile data encountered!\n");
- break;
- }
- pos += tile->data_size << 3; // skip to next tile
- }
- }
-
- /* restore the selected rvmap table by applying its corrections in reverse order */
- for (i = band->num_corr-1; i >= 0; i--) {
- idx1 = band->corr[i*2];
- idx2 = band->corr[i*2+1];
- FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]);
- FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);
- }
-
-#ifdef DEBUG
- if (band->checksum_present) {
- uint16_t chksum = ivi_calc_band_checksum(band);
- if (chksum != band->checksum) {
- av_log(avctx, AV_LOG_ERROR,
- "Band checksum mismatch! Plane %d, band %d, received: %x, calculated: %x\n",
- band->plane, band->band_num, band->checksum, chksum);
- }
- }
-#endif
-
- align_get_bits(&ctx->gb);
-
- return result;
-}
-
-
-/**
* Switch buffers.
*
* @param[in,out] ctx ptr to the decoder context
*/
-static void switch_buffers(IVI5DecContext *ctx)
+static void switch_buffers(IVI45DecContext *ctx)
{
switch (ctx->prev_frame_type) {
case FRAMETYPE_INTRA:
@@ -693,12 +572,18 @@ static void switch_buffers(IVI5DecContext *ctx)
}
+static int is_nonnull_frame(IVI45DecContext *ctx)
+{
+ return ctx->frame_type != FRAMETYPE_NULL;
+}
+
+
/**
* Initialize Indeo5 decoder.
*/
static av_cold int decode_init(AVCodecContext *avctx)
{
- IVI5DecContext *ctx = avctx->priv_data;
+ IVI45DecContext *ctx = avctx->priv_data;
int result;
ff_ivi_init_static_vlc();
@@ -726,97 +611,13 @@ static av_cold int decode_init(AVCodecContext *avctx)
ctx->buf_switch = 0;
ctx->inter_scal = 0;
- avctx->pix_fmt = PIX_FMT_YUV410P;
-
- return 0;
-}
-
-
-/**
- * main decoder function
- */
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
- AVPacket *avpkt)
-{
- IVI5DecContext *ctx = avctx->priv_data;
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- int result, p, b;
-
- init_get_bits(&ctx->gb, buf, buf_size * 8);
- ctx->frame_data = buf;
- ctx->frame_size = buf_size;
-
- result = decode_pic_hdr(ctx, avctx);
- if (result) {
- av_log(avctx, AV_LOG_ERROR,
- "Error while decoding picture header: %d\n", result);
- return -1;
- }
-
- if (ctx->gop_flags & IVI5_IS_PROTECTED) {
- av_log(avctx, AV_LOG_ERROR, "Password-protected clip!\n");
- return -1;
- }
+ ctx->decode_pic_hdr = decode_pic_hdr;
+ ctx->decode_band_hdr = decode_band_hdr;
+ ctx->decode_mb_info = decode_mb_info;
+ ctx->switch_buffers = switch_buffers;
+ ctx->is_nonnull_frame = is_nonnull_frame;
- switch_buffers(ctx);
-
- //{ START_TIMER;
-
- if (ctx->frame_type != FRAMETYPE_NULL) {
- for (p = 0; p < 3; p++) {
- for (b = 0; b < ctx->planes[p].num_bands; b++) {
- result = decode_band(ctx, p, &ctx->planes[p].bands[b], avctx);
- if (result) {
- av_log(avctx, AV_LOG_ERROR,
- "Error while decoding band: %d, plane: %d\n", b, p);
- return -1;
- }
- }
- }
- }
-
- //STOP_TIMER("decode_planes"); }
-
- if (ctx->frame.data[0])
- avctx->release_buffer(avctx, &ctx->frame);
-
- ctx->frame.reference = 0;
- if (avctx->get_buffer(avctx, &ctx->frame) < 0) {
- av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
- return -1;
- }
-
- if (ctx->is_scalable) {
- ff_ivi_recompose53 (&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0], 4);
- } else {
- ff_ivi_output_plane(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]);
- }
-
- ff_ivi_output_plane(&ctx->planes[2], ctx->frame.data[1], ctx->frame.linesize[1]);
- ff_ivi_output_plane(&ctx->planes[1], ctx->frame.data[2], ctx->frame.linesize[2]);
-
- *data_size = sizeof(AVFrame);
- *(AVFrame*)data = ctx->frame;
-
- return buf_size;
-}
-
-
-/**
- * Close Indeo5 decoder and clean up its context.
- */
-static av_cold int decode_close(AVCodecContext *avctx)
-{
- IVI5DecContext *ctx = avctx->priv_data;
-
- ff_ivi_free_buffers(&ctx->planes[0]);
-
- if (ctx->mb_vlc.cust_tab.table)
- ff_free_vlc(&ctx->mb_vlc.cust_tab);
-
- if (ctx->frame.data[0])
- avctx->release_buffer(avctx, &ctx->frame);
+ avctx->pix_fmt = PIX_FMT_YUV410P;
return 0;
}
@@ -826,9 +627,9 @@ AVCodec ff_indeo5_decoder = {
.name = "indeo5",
.type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_INDEO5,
- .priv_data_size = sizeof(IVI5DecContext),
+ .priv_data_size = sizeof(IVI45DecContext),
.init = decode_init,
- .close = decode_close,
- .decode = decode_frame,
+ .close = ff_ivi_decode_close,
+ .decode = ff_ivi_decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 5"),
};
diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index bedb2ed..57d551d 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -70,6 +70,12 @@ typedef struct AVCodecInternal {
*/
int sample_count;
#endif
+
+ /**
+ * An audio frame with less than required samples has been submitted and
+ * padded with silence. Reject all subsequent frames.
+ */
+ int last_audio_frame;
} AVCodecInternal;
struct AVCodecDefault {
diff --git a/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c
index f52ac7a..73e8bf5 100644
--- a/libavcodec/ituh263dec.c
+++ b/libavcodec/ituh263dec.c
@@ -1083,6 +1083,22 @@ int ff_h263_decode_picture_header(MpegEncContext *s)
skip_bits(&s->gb, 2); /* Quantization information for B-pictures */
}
+ if (s->pict_type!=AV_PICTURE_TYPE_B) {
+ s->time = s->picture_number;
+ s->pp_time = s->time - s->last_non_b_time;
+ s->last_non_b_time = s->time;
+ }else{
+ s->time = s->picture_number;
+ s->pb_time = s->pp_time - (s->last_non_b_time - s->time);
+ if (s->pp_time <=s->pb_time ||
+ s->pp_time <= s->pp_time - s->pb_time ||
+ s->pp_time <= 0){
+ s->pp_time = 2;
+ s->pb_time = 1;
+ }
+ ff_mpeg4_init_direct_mv(s);
+ }
+
/* PEI */
while (get_bits1(&s->gb) != 0) {
skip_bits(&s->gb, 8);
diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c
index b9ec1c2..cbcd970 100644
--- a/libavcodec/ivi_common.c
+++ b/libavcodec/ivi_common.c
@@ -123,6 +123,10 @@ int ff_ivi_dec_huff_desc(GetBitContext *gb, int desc_coded, int which_tab,
if (huff_tab->tab_sel == 7) {
/* custom huffman table (explicitly encoded) */
new_huff.num_rows = get_bits(gb, 4);
+ if (!new_huff.num_rows) {
+ av_log(avctx, AV_LOG_ERROR, "Empty custom Huffman table!\n");
+ return AVERROR_INVALIDDATA;
+ }
for (i = 0; i < new_huff.num_rows; i++)
new_huff.xbits[i] = get_bits(gb, 4);
@@ -136,9 +140,10 @@ int ff_ivi_dec_huff_desc(GetBitContext *gb, int desc_coded, int which_tab,
result = ff_ivi_create_huff_from_desc(&huff_tab->cust_desc,
&huff_tab->cust_tab, 0);
if (result) {
+ huff_tab->cust_desc.num_rows = 0; // reset faulty description
av_log(avctx, AV_LOG_ERROR,
"Error while initializing custom vlc table!\n");
- return -1;
+ return result;
}
}
huff_tab->tab = &huff_tab->cust_tab;
@@ -207,14 +212,15 @@ av_cold int ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg)
band->width = b_width;
band->height = b_height;
band->pitch = width_aligned;
- band->bufs[0] = av_malloc(buf_size);
- band->bufs[1] = av_malloc(buf_size);
+ band->aheight = height_aligned;
+ band->bufs[0] = av_mallocz(buf_size);
+ band->bufs[1] = av_mallocz(buf_size);
if (!band->bufs[0] || !band->bufs[1])
return AVERROR(ENOMEM);
/* allocate the 3rd band buffer for scalability mode */
if (cfg->luma_bands > 1) {
- band->bufs[2] = av_malloc(buf_size);
+ band->bufs[2] = av_mallocz(buf_size);
if (!band->bufs[2])
return AVERROR(ENOMEM);
}
@@ -282,6 +288,7 @@ av_cold int ff_ivi_init_tiles(IVIPlaneDesc *planes, int tile_width, int tile_hei
for (x = 0; x < band->width; x += t_width) {
tile->xpos = x;
tile->ypos = y;
+ tile->mb_size = band->mb_size;
tile->width = FFMIN(band->width - x, t_width);
tile->height = FFMIN(band->height - y, t_height);
tile->is_empty = tile->data_size = 0;
@@ -375,6 +382,21 @@ int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile)
mv_x >>= 1;
mv_y >>= 1; /* convert halfpel vectors into fullpel ones */
}
+ if (mb->type) {
+ int dmv_x, dmv_y, cx, cy;
+
+ dmv_x = mb->mv_x >> band->is_halfpel;
+ dmv_y = mb->mv_y >> band->is_halfpel;
+ cx = mb->mv_x & band->is_halfpel;
+ cy = mb->mv_y & band->is_halfpel;
+
+ if ( mb->xpos + dmv_x < 0
+ || mb->xpos + dmv_x + band->mb_size + cx > band->pitch
+ || mb->ypos + dmv_y < 0
+ || mb->ypos + dmv_y + band->mb_size + cy > band->aheight) {
+ return AVERROR_INVALIDDATA;
+ }
+ }
}
for (blk = 0; blk < num_blocks; blk++) {
@@ -562,7 +584,7 @@ void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band,
#ifdef DEBUG
-uint16_t ivi_calc_band_checksum (IVIBandDesc *band)
+static uint16_t ivi_calc_band_checksum(IVIBandDesc *band)
{
int x, y;
int16_t *src, checksum;
@@ -576,31 +598,6 @@ uint16_t ivi_calc_band_checksum (IVIBandDesc *band)
return checksum;
}
-
-int ivi_check_band (IVIBandDesc *band, const uint8_t *ref, int pitch)
-{
- int x, y, result;
- uint8_t t1, t2;
- int16_t *src;
-
- src = band->buf;
- result = 0;
-
- for (y = 0; y < band->height; src += band->pitch, y++) {
- for (x = 0; x < band->width; x++) {
- t1 = av_clip(src[x] + 128, 0, 255);
- t2 = ref[x];
- if (t1 != t2) {
- av_log(NULL, AV_LOG_ERROR, "Data mismatch: row %d, column %d\n",
- y / band->blk_size, x / band->blk_size);
- result = -1;
- }
- }
- ref += pitch;
- }
-
- return result;
-}
#endif
void ff_ivi_output_plane(IVIPlaneDesc *plane, uint8_t *dst, int dst_pitch)
@@ -620,6 +617,225 @@ void ff_ivi_output_plane(IVIPlaneDesc *plane, uint8_t *dst, int dst_pitch)
}
}
+/**
+ * Decode an Indeo 4 or 5 band.
+ *
+ * @param[in,out] ctx ptr to the decoder context
+ * @param[in,out] band ptr to the band descriptor
+ * @param[in] avctx ptr to the AVCodecContext
+ * @return result code: 0 = OK, -1 = error
+ */
+static int decode_band(IVI45DecContext *ctx, int plane_num,
+ IVIBandDesc *band, AVCodecContext *avctx)
+{
+ int result, i, t, idx1, idx2, pos;
+ IVITile *tile;
+
+ band->buf = band->bufs[ctx->dst_buf];
+ if (!band->buf) {
+ av_log(avctx, AV_LOG_ERROR, "Band buffer points to no data!\n");
+ return AVERROR_INVALIDDATA;
+ }
+ band->ref_buf = band->bufs[ctx->ref_buf];
+ band->data_ptr = ctx->frame_data + (get_bits_count(&ctx->gb) >> 3);
+
+ result = ctx->decode_band_hdr(ctx, band, avctx);
+ if (result) {
+ av_log(avctx, AV_LOG_ERROR, "Error while decoding band header: %d\n",
+ result);
+ return result;
+ }
+
+ if (band->is_empty) {
+ av_log(avctx, AV_LOG_ERROR, "Empty band encountered!\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ band->rv_map = &ctx->rvmap_tabs[band->rvmap_sel];
+
+ /* apply corrections to the selected rvmap table if present */
+ for (i = 0; i < band->num_corr; i++) {
+ idx1 = band->corr[i * 2];
+ idx2 = band->corr[i * 2 + 1];
+ FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]);
+ FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);
+ }
+
+ pos = get_bits_count(&ctx->gb);
+
+ for (t = 0; t < band->num_tiles; t++) {
+ tile = &band->tiles[t];
+
+ if (tile->mb_size != band->mb_size) {
+ av_log(avctx, AV_LOG_ERROR, "MB sizes mismatch: %d vs. %d\n",
+ band->mb_size, tile->mb_size);
+ return AVERROR_INVALIDDATA;
+ }
+ tile->is_empty = get_bits1(&ctx->gb);
+ if (tile->is_empty) {
+ ff_ivi_process_empty_tile(avctx, band, tile,
+ (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3));
+ av_dlog(avctx, "Empty tile encountered!\n");
+ } else {
+ tile->data_size = ff_ivi_dec_tile_data_size(&ctx->gb);
+ if (!tile->data_size) {
+ av_log(avctx, AV_LOG_ERROR, "Tile data size is zero!\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ result = ctx->decode_mb_info(ctx, band, tile, avctx);
+ if (result < 0)
+ break;
+
+ result = ff_ivi_decode_blocks(&ctx->gb, band, tile);
+ if (result < 0 || ((get_bits_count(&ctx->gb) - pos) >> 3) != tile->data_size) {
+ av_log(avctx, AV_LOG_ERROR, "Corrupted tile data encountered!\n");
+ break;
+ }
+
+ pos += tile->data_size << 3; // skip to next tile
+ }
+ }
+
+ /* restore the selected rvmap table by applying its corrections in reverse order */
+ for (i = band->num_corr-1; i >= 0; i--) {
+ idx1 = band->corr[i*2];
+ idx2 = band->corr[i*2+1];
+ FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]);
+ FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);
+ }
+
+#ifdef DEBUG
+ if (band->checksum_present) {
+ uint16_t chksum = ivi_calc_band_checksum(band);
+ if (chksum != band->checksum) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Band checksum mismatch! Plane %d, band %d, received: %x, calculated: %x\n",
+ band->plane, band->band_num, band->checksum, chksum);
+ }
+ }
+#endif
+
+ align_get_bits(&ctx->gb);
+
+ return result;
+}
+
+int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+ AVPacket *avpkt)
+{
+ IVI45DecContext *ctx = avctx->priv_data;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ int result, p, b;
+
+ init_get_bits(&ctx->gb, buf, buf_size * 8);
+ ctx->frame_data = buf;
+ ctx->frame_size = buf_size;
+
+ result = ctx->decode_pic_hdr(ctx, avctx);
+ if (result) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Error while decoding picture header: %d\n", result);
+ return -1;
+ }
+
+ if (ctx->gop_flags & IVI5_IS_PROTECTED) {
+ av_log(avctx, AV_LOG_ERROR, "Password-protected clip!\n");
+ return -1;
+ }
+
+ ctx->switch_buffers(ctx);
+
+ //{ START_TIMER;
+
+ if (ctx->is_nonnull_frame(ctx)) {
+ for (p = 0; p < 3; p++) {
+ for (b = 0; b < ctx->planes[p].num_bands; b++) {
+ result = decode_band(ctx, p, &ctx->planes[p].bands[b], avctx);
+ if (result) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Error while decoding band: %d, plane: %d\n", b, p);
+ return -1;
+ }
+ }
+ }
+ }
+
+ //STOP_TIMER("decode_planes"); }
+
+ /* If the bidirectional mode is enabled, next I and the following P frame will */
+ /* be sent together. Unfortunately the approach below seems to be the only way */
+ /* to handle the B-frames mode. That's exactly the same Intel decoders do. */
+ if (avctx->codec_id == CODEC_ID_INDEO4 && ctx->frame_type == 0/*FRAMETYPE_INTRA*/) {
+ while (get_bits(&ctx->gb, 8)); // skip version string
+ skip_bits_long(&ctx->gb, 64); // skip padding, TODO: implement correct 8-bytes alignment
+ if (get_bits_left(&ctx->gb) > 18 && show_bits(&ctx->gb, 18) == 0x3FFF8)
+ av_log(avctx, AV_LOG_ERROR, "Buffer contains IP frames!\n");
+ }
+
+ if (ctx->frame.data[0])
+ avctx->release_buffer(avctx, &ctx->frame);
+
+ ctx->frame.reference = 0;
+ if ((result = avctx->get_buffer(avctx, &ctx->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return result;
+ }
+
+ if (ctx->is_scalable) {
+ if (avctx->codec_id == CODEC_ID_INDEO4)
+ ff_ivi_recompose_haar(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0], 4);
+ else
+ ff_ivi_recompose53 (&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0], 4);
+ } else {
+ ff_ivi_output_plane(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]);
+ }
+
+ ff_ivi_output_plane(&ctx->planes[2], ctx->frame.data[1], ctx->frame.linesize[1]);
+ ff_ivi_output_plane(&ctx->planes[1], ctx->frame.data[2], ctx->frame.linesize[2]);
+
+ *data_size = sizeof(AVFrame);
+ *(AVFrame*)data = ctx->frame;
+
+ return buf_size;
+}
+
+/**
+ * Close Indeo5 decoder and clean up its context.
+ */
+av_cold int ff_ivi_decode_close(AVCodecContext *avctx)
+{
+ IVI45DecContext *ctx = avctx->priv_data;
+
+ ff_ivi_free_buffers(&ctx->planes[0]);
+
+ if (ctx->mb_vlc.cust_tab.table)
+ ff_free_vlc(&ctx->mb_vlc.cust_tab);
+
+ if (ctx->frame.data[0])
+ avctx->release_buffer(avctx, &ctx->frame);
+
+#if IVI4_STREAM_ANALYSER
+ if (avctx->codec_id == CODEC_ID_INDEO4) {
+ if (ctx->is_scalable)
+ av_log(avctx, AV_LOG_ERROR, "This video uses scalability mode!\n");
+ if (ctx->uses_tiling)
+ av_log(avctx, AV_LOG_ERROR, "This video uses local decoding!\n");
+ if (ctx->has_b_frames)
+ av_log(avctx, AV_LOG_ERROR, "This video contains B-frames!\n");
+ if (ctx->has_transp)
+ av_log(avctx, AV_LOG_ERROR, "Transparency mode is enabled!\n");
+ if (ctx->uses_haar)
+ av_log(avctx, AV_LOG_ERROR, "This video uses Haar transform!\n");
+ if (ctx->uses_fullpel)
+ av_log(avctx, AV_LOG_ERROR, "This video uses fullpel motion vectors!\n");
+ }
+#endif
+
+ return 0;
+}
+
/**
* These are 2x8 predefined Huffman codebooks for coding macroblock/block
diff --git a/libavcodec/ivi_common.h b/libavcodec/ivi_common.h
index 4b2ae06..1ba431b 100644
--- a/libavcodec/ivi_common.h
+++ b/libavcodec/ivi_common.h
@@ -34,6 +34,8 @@
#include <stdint.h>
#define IVI_VLC_BITS 13 ///< max number of bits of the ivi's huffman codes
+#define IVI4_STREAM_ANALYSER 0
+#define IVI5_IS_PROTECTED 0x20
/**
* huffman codebook descriptor
@@ -116,6 +118,7 @@ typedef struct {
int ypos;
int width;
int height;
+ int mb_size;
int is_empty; ///< = 1 if this tile doesn't contain any data
int data_size; ///< size of the data in bytes
int num_MBs; ///< number of macroblocks in this tile
@@ -132,6 +135,7 @@ typedef struct {
int band_num; ///< band number
int width;
int height;
+ int aheight; ///< aligned band height
const uint8_t *data_ptr; ///< ptr to the first byte of the band data
int data_size; ///< size of the band data
int16_t *buf; ///< pointer to the output buffer for this band
@@ -192,6 +196,60 @@ typedef struct {
uint8_t chroma_bands;
} IVIPicConfig;
+typedef struct IVI45DecContext {
+ GetBitContext gb;
+ AVFrame frame;
+ RVMapDesc rvmap_tabs[9]; ///< local corrected copy of the static rvmap tables
+
+ uint32_t frame_num;
+ int frame_type;
+ int prev_frame_type; ///< frame type of the previous frame
+ uint32_t data_size; ///< size of the frame data in bytes from picture header
+ int is_scalable;
+ int transp_status; ///< transparency mode status: 1 - enabled
+ const uint8_t *frame_data; ///< input frame data pointer
+ int inter_scal; ///< signals a sequence of scalable inter frames
+ uint32_t frame_size; ///< frame size in bytes
+ uint32_t pic_hdr_size; ///< picture header size in bytes
+ uint8_t frame_flags;
+ uint16_t checksum; ///< frame checksum
+
+ IVIPicConfig pic_conf;
+ IVIPlaneDesc planes[3]; ///< color planes
+
+ int buf_switch; ///< used to switch between three buffers
+ int dst_buf; ///< buffer index for the currently decoded frame
+ int ref_buf; ///< inter frame reference buffer index
+ int ref2_buf; ///< temporal storage for switching buffers
+
+ IVIHuffTab mb_vlc; ///< current macroblock table descriptor
+ IVIHuffTab blk_vlc; ///< current block table descriptor
+
+ uint8_t rvmap_sel;
+ uint8_t in_imf;
+ uint8_t in_q; ///< flag for explicitly stored quantiser delta
+ uint8_t pic_glob_quant;
+ uint8_t unknown1;
+
+ uint16_t gop_hdr_size;
+ uint8_t gop_flags;
+ uint32_t lock_word;
+
+#if IVI4_STREAM_ANALYSER
+ uint8_t has_b_frames;
+ uint8_t has_transp;
+ uint8_t uses_tiling;
+ uint8_t uses_haar;
+ uint8_t uses_fullpel;
+#endif
+
+ int (*decode_pic_hdr) (struct IVI45DecContext *ctx, AVCodecContext *avctx);
+ int (*decode_band_hdr) (struct IVI45DecContext *ctx, IVIBandDesc *band, AVCodecContext *avctx);
+ int (*decode_mb_info) (struct IVI45DecContext *ctx, IVIBandDesc *band, IVITile *tile, AVCodecContext *avctx);
+ void (*switch_buffers) (struct IVI45DecContext *ctx);
+ int (*is_nonnull_frame)(struct IVI45DecContext *ctx);
+} IVI45DecContext;
+
/** compare some properties of two pictures */
static inline int ivi_pic_config_cmp(IVIPicConfig *str1, IVIPicConfig *str2)
{
@@ -338,14 +396,8 @@ void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band,
*/
void ff_ivi_output_plane(IVIPlaneDesc *plane, uint8_t *dst, int dst_pitch);
-/**
- * Calculate band checksum from band data.
- */
-uint16_t ivi_calc_band_checksum (IVIBandDesc *band);
-
-/**
- * Verify that band data lies in range.
- */
-int ivi_check_band (IVIBandDesc *band, const uint8_t *ref, int pitch);
+int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+ AVPacket *avpkt);
+av_cold int ff_ivi_decode_close(AVCodecContext *avctx);
#endif /* AVCODEC_IVI_COMMON_H */
diff --git a/libavcodec/jpeglsdec.c b/libavcodec/jpeglsdec.c
index 43bf765..25b3c30 100644
--- a/libavcodec/jpeglsdec.c
+++ b/libavcodec/jpeglsdec.c
@@ -51,10 +51,9 @@
*/
int ff_jpegls_decode_lse(MJpegDecodeContext *s)
{
- int len, id;
+ int id;
- /* XXX: verify len field validity */
- len = get_bits(&s->gb, 16);
+ skip_bits(&s->gb, 16); /* length: FIXME: verify field validity */
id = get_bits(&s->gb, 8);
switch(id){
diff --git a/libavcodec/lagarith.c b/libavcodec/lagarith.c
index d6921ea..35f5a07 100644
--- a/libavcodec/lagarith.c
+++ b/libavcodec/lagarith.c
@@ -269,6 +269,40 @@ static void lag_pred_line(LagarithContext *l, uint8_t *buf,
}
}
+static void lag_pred_line_yuy2(LagarithContext *l, uint8_t *buf,
+ int width, int stride, int line,
+ int is_luma)
+{
+ int L, TL;
+
+ if (!line) {
+ if (is_luma) {
+ buf++;
+ width--;
+ }
+ l->dsp.add_hfyu_left_prediction(buf + 1, buf + 1, width - 1, buf[0]);
+ return;
+ }
+ if (line == 1) {
+ const int HEAD = is_luma ? 4 : 2;
+ int i;
+
+ L = buf[width - stride - 1];
+ TL = buf[HEAD - stride - 1];
+ for (i = 0; i < HEAD; i++) {
+ L += buf[i];
+ buf[i] = L;
+ }
+ buf += HEAD;
+ width -= HEAD;
+ } else {
+ TL = buf[width - (2 * stride) - 1];
+ L = buf[width - stride - 1];
+ }
+ l->dsp.add_hfyu_median_prediction(buf, buf - stride, buf, width,
+ &L, &TL);
+}
+
static int lag_decode_line(LagarithContext *l, lag_rac *rac,
uint8_t *dst, int width, int stride,
int esc_count)
@@ -432,9 +466,17 @@ static int lag_decode_arith_plane(LagarithContext *l, uint8_t *dst,
return -1;
}
- for (i = 0; i < height; i++) {
- lag_pred_line(l, dst, width, stride, i);
- dst += stride;
+ if (l->avctx->pix_fmt != PIX_FMT_YUV422P) {
+ for (i = 0; i < height; i++) {
+ lag_pred_line(l, dst, width, stride, i);
+ dst += stride;
+ }
+ } else {
+ for (i = 0; i < height; i++) {
+ lag_pred_line_yuy2(l, dst, width, stride, i,
+ width == l->avctx->width);
+ dst += stride;
+ }
}
return 0;
@@ -457,7 +499,7 @@ static int lag_decode_frame(AVCodecContext *avctx,
AVFrame *const p = &l->picture;
uint8_t frametype = 0;
uint32_t offset_gu = 0, offset_bv = 0, offset_ry = 9;
- int offs[4];
+ uint32_t offs[4];
uint8_t *srcs[4], *dst;
int i, j, planes = 3;
@@ -496,7 +538,8 @@ static int lag_decode_frame(AVCodecContext *avctx,
offset_ry += 4;
offs[3] = AV_RL32(buf + 9);
case FRAME_ARITH_RGB24:
- if (frametype == FRAME_ARITH_RGB24)
+ case FRAME_U_RGB24:
+ if (frametype == FRAME_ARITH_RGB24 || frametype == FRAME_U_RGB24)
avctx->pix_fmt = PIX_FMT_RGB24;
if (avctx->get_buffer(avctx, p) < 0) {
@@ -556,6 +599,32 @@ static int lag_decode_frame(AVCodecContext *avctx,
srcs[i] += l->rgb_stride;
}
break;
+ case FRAME_ARITH_YUY2:
+ avctx->pix_fmt = PIX_FMT_YUV422P;
+
+ if (avctx->get_buffer(avctx, p) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return -1;
+ }
+
+ if (offset_ry >= buf_size ||
+ offset_gu >= buf_size ||
+ offset_bv >= buf_size) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Invalid frame offsets\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ lag_decode_arith_plane(l, p->data[0], avctx->width, avctx->height,
+ p->linesize[0], buf + offset_ry,
+ buf_size - offset_ry);
+ lag_decode_arith_plane(l, p->data[2], avctx->width / 2,
+ avctx->height, p->linesize[2],
+ buf + offset_gu, buf_size - offset_gu);
+ lag_decode_arith_plane(l, p->data[1], avctx->width / 2,
+ avctx->height, p->linesize[1],
+ buf + offset_bv, buf_size - offset_bv);
+ break;
case FRAME_ARITH_YV12:
avctx->pix_fmt = PIX_FMT_YUV420P;
diff --git a/libavcodec/libdirac_libschro.c b/libavcodec/libdirac_libschro.c
deleted file mode 100644
index 45b5b83..0000000
--- a/libavcodec/libdirac_libschro.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot com >
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
-* @file
-* functions common to libdirac and libschroedinger
-*/
-
-#include "libdirac_libschro.h"
-
-static const DiracSchroVideoFormatInfo ff_dirac_schro_video_format_info[] = {
- { 640, 480, 24000, 1001},
- { 176, 120, 15000, 1001},
- { 176, 144, 25, 2 },
- { 352, 240, 15000, 1001},
- { 352, 288, 25, 2 },
- { 704, 480, 15000, 1001},
- { 704, 576, 25, 2 },
- { 720, 480, 30000, 1001},
- { 720, 576, 25, 1 },
- { 1280, 720, 60000, 1001},
- { 1280, 720, 50, 1 },
- { 1920, 1080, 30000, 1001},
- { 1920, 1080, 25, 1 },
- { 1920, 1080, 60000, 1001},
- { 1920, 1080, 50, 1 },
- { 2048, 1080, 24, 1 },
- { 4096, 2160, 24, 1 },
-};
-
-unsigned int ff_dirac_schro_get_video_format_idx(AVCodecContext *avccontext)
-{
- unsigned int ret_idx = 0;
- unsigned int idx;
- unsigned int num_formats = sizeof(ff_dirac_schro_video_format_info) /
- sizeof(ff_dirac_schro_video_format_info[0]);
-
- for (idx = 1; idx < num_formats; ++idx) {
- const DiracSchroVideoFormatInfo *vf = &ff_dirac_schro_video_format_info[idx];
- if (avccontext->width == vf->width &&
- avccontext->height == vf->height) {
- ret_idx = idx;
- if (avccontext->time_base.den == vf->frame_rate_num &&
- avccontext->time_base.num == vf->frame_rate_denom)
- return idx;
- }
- }
- return ret_idx;
-}
-
-void ff_dirac_schro_queue_init(DiracSchroQueue *queue)
-{
- queue->p_head = queue->p_tail = NULL;
- queue->size = 0;
-}
-
-void ff_dirac_schro_queue_free(DiracSchroQueue *queue,
- void (*free_func)(void *))
-{
- while (queue->p_head)
- free_func(ff_dirac_schro_queue_pop(queue));
-}
-
-int ff_dirac_schro_queue_push_back(DiracSchroQueue *queue, void *p_data)
-{
- DiracSchroQueueElement *p_new = av_mallocz(sizeof(DiracSchroQueueElement));
-
- if (!p_new)
- return -1;
-
- p_new->data = p_data;
-
- if (!queue->p_head)
- queue->p_head = p_new;
- else
- queue->p_tail->next = p_new;
- queue->p_tail = p_new;
-
- ++queue->size;
- return 0;
-}
-
-void *ff_dirac_schro_queue_pop(DiracSchroQueue *queue)
-{
- DiracSchroQueueElement *top = queue->p_head;
-
- if (top) {
- void *data = top->data;
- queue->p_head = queue->p_head->next;
- --queue->size;
- av_freep(&top);
- return data;
- }
-
- return NULL;
-}
diff --git a/libavcodec/libdirac_libschro.h b/libavcodec/libdirac_libschro.h
deleted file mode 100644
index a80558f..0000000
--- a/libavcodec/libdirac_libschro.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot com >
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
-* @file
-* data structures common to libdirac and libschroedinger
-*/
-
-#ifndef AVCODEC_LIBDIRAC_LIBSCHRO_H
-#define AVCODEC_LIBDIRAC_LIBSCHRO_H
-
-#include "avcodec.h"
-
-typedef struct {
- uint16_t width;
- uint16_t height;
- uint16_t frame_rate_num;
- uint16_t frame_rate_denom;
-} DiracSchroVideoFormatInfo;
-
-/**
-* Returns the index into the Dirac Schro common video format info table
-*/
-unsigned int ff_dirac_schro_get_video_format_idx(AVCodecContext *avccontext);
-
-/**
-* contains a single encoded frame returned from Dirac or Schroedinger
-*/
-typedef struct DiracSchroEncodedFrame {
- /** encoded frame data */
- uint8_t *p_encbuf;
-
- /** encoded frame size */
- uint32_t size;
-
- /** encoded frame number. Will be used as pts */
- uint32_t frame_num;
-
- /** key frame flag. 1 : is key frame , 0 : in not key frame */
- uint16_t key_frame;
-} DiracSchroEncodedFrame;
-
-/**
-* queue element
-*/
-typedef struct DiracSchroQueueElement {
- /** Data to be stored in queue*/
- void *data;
- /** Pointer to next element queue */
- struct DiracSchroQueueElement *next;
-} DiracSchroQueueElement;
-
-
-/**
-* A simple queue implementation used in libdirac and libschroedinger
-*/
-typedef struct DiracSchroQueue {
- /** Pointer to head of queue */
- DiracSchroQueueElement *p_head;
- /** Pointer to tail of queue */
- DiracSchroQueueElement *p_tail;
- /** Queue size*/
- int size;
-} DiracSchroQueue;
-
-/**
-* Initialise the queue
-*/
-void ff_dirac_schro_queue_init(DiracSchroQueue *queue);
-
-/**
-* Add an element to the end of the queue
-*/
-int ff_dirac_schro_queue_push_back(DiracSchroQueue *queue, void *p_data);
-
-/**
-* Return the first element in the queue
-*/
-void *ff_dirac_schro_queue_pop(DiracSchroQueue *queue);
-
-/**
-* Free the queue resources. free_func is a function supplied by the caller to
-* free any resources allocated by the caller. The data field of the queue
-* element is passed to it.
-*/
-void ff_dirac_schro_queue_free(DiracSchroQueue *queue,
- void (*free_func)(void *));
-#endif /* AVCODEC_LIBDIRAC_LIBSCHRO_H */
diff --git a/libavcodec/libilbc.c b/libavcodec/libilbc.c
new file mode 100644
index 0000000..1c056d5
--- /dev/null
+++ b/libavcodec/libilbc.c
@@ -0,0 +1,209 @@
+/*
+ * iLBC decoder/encoder stub
+ * Copyright (c) 2012 Martin Storsjo
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <ilbc.h>
+
+#include "avcodec.h"
+#include "libavutil/opt.h"
+#include "internal.h"
+
+static int get_mode(AVCodecContext *avctx)
+{
+ if (avctx->block_align == 38)
+ return 20;
+ else if (avctx->block_align == 50)
+ return 30;
+ else if (avctx->bit_rate > 0)
+ return avctx->bit_rate <= 14000 ? 30 : 20;
+ else
+ return -1;
+}
+
+typedef struct ILBCDecContext {
+ const AVClass *class;
+ AVFrame frame;
+ iLBC_Dec_Inst_t decoder;
+ int enhance;
+} ILBCDecContext;
+
+static const AVOption ilbc_dec_options[] = {
+ { "enhance", "Enhance the decoded audio (adds delay)", offsetof(ILBCDecContext, enhance), AV_OPT_TYPE_INT, { 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM },
+ { NULL }
+};
+
+static const AVClass ilbc_dec_class = {
+ "libilbc", av_default_item_name, ilbc_dec_options, LIBAVUTIL_VERSION_INT
+};
+
+static av_cold int ilbc_decode_init(AVCodecContext *avctx)
+{
+ ILBCDecContext *s = avctx->priv_data;
+ int mode;
+
+ if ((mode = get_mode(avctx)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "iLBC frame mode not indicated\n");
+ return AVERROR(EINVAL);
+ }
+
+ WebRtcIlbcfix_InitDecode(&s->decoder, mode, s->enhance);
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
+
+ avctx->channels = 1;
+ avctx->sample_rate = 8000;
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+
+ return 0;
+}
+
+static int ilbc_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ ILBCDecContext *s = avctx->priv_data;
+ int ret;
+
+ if (s->decoder.no_of_bytes > buf_size) {
+ av_log(avctx, AV_LOG_ERROR, "iLBC frame too short (%u, should be %u)\n",
+ buf_size, s->decoder.no_of_bytes);
+ return AVERROR_INVALIDDATA;
+ }
+
+ s->frame.nb_samples = s->decoder.blockl;
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+
+ WebRtcIlbcfix_DecodeImpl((WebRtc_Word16*) s->frame.data[0],
+ (const WebRtc_UWord16*) buf, &s->decoder, 1);
+
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
+
+ return s->decoder.no_of_bytes;
+}
+
+AVCodec ff_libilbc_decoder = {
+ .name = "libilbc",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_ILBC,
+ .priv_data_size = sizeof(ILBCDecContext),
+ .init = ilbc_decode_init,
+ .decode = ilbc_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
+ .long_name = NULL_IF_CONFIG_SMALL("Internet Low Bitrate Codec (iLBC)"),
+ .priv_class = &ilbc_dec_class,
+};
+
+typedef struct ILBCEncContext {
+ const AVClass *class;
+ iLBC_Enc_Inst_t encoder;
+ int mode;
+} ILBCEncContext;
+
+static const AVOption ilbc_enc_options[] = {
+ { "mode", "iLBC mode (20 or 30 ms frames)", offsetof(ILBCEncContext, mode), AV_OPT_TYPE_INT, { 20 }, 20, 30, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
+ { NULL }
+};
+
+static const AVClass ilbc_enc_class = {
+ "libilbc", av_default_item_name, ilbc_enc_options, LIBAVUTIL_VERSION_INT
+};
+
+static av_cold int ilbc_encode_init(AVCodecContext *avctx)
+{
+ ILBCEncContext *s = avctx->priv_data;
+ int mode;
+
+ if (avctx->sample_rate != 8000) {
+ av_log(avctx, AV_LOG_ERROR, "Only 8000Hz sample rate supported\n");
+ return AVERROR(EINVAL);
+ }
+
+ if (avctx->channels != 1) {
+ av_log(avctx, AV_LOG_ERROR, "Only mono supported\n");
+ return AVERROR(EINVAL);
+ }
+
+ if ((mode = get_mode(avctx)) > 0)
+ s->mode = mode;
+ else
+ s->mode = s->mode != 30 ? 20 : 30;
+ WebRtcIlbcfix_InitEncode(&s->encoder, s->mode);
+
+ avctx->block_align = s->encoder.no_of_bytes;
+ avctx->frame_size = s->encoder.blockl;
+#if FF_API_OLD_ENCODE_AUDIO
+ avctx->coded_frame = avcodec_alloc_frame();
+ if (!avctx->coded_frame)
+ return AVERROR(ENOMEM);
+#endif
+
+ return 0;
+}
+
+static av_cold int ilbc_encode_close(AVCodecContext *avctx)
+{
+#if FF_API_OLD_ENCODE_AUDIO
+ av_freep(&avctx->coded_frame);
+#endif
+ return 0;
+}
+
+static int ilbc_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
+ const AVFrame *frame, int *got_packet_ptr)
+{
+ ILBCEncContext *s = avctx->priv_data;
+ int ret;
+
+ if ((ret = ff_alloc_packet(avpkt, 50))) {
+ av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
+ return ret;
+ }
+
+ WebRtcIlbcfix_EncodeImpl((WebRtc_UWord16*) avpkt->data, (const WebRtc_Word16*) frame->data[0], &s->encoder);
+
+ avpkt->size = s->encoder.no_of_bytes;
+ *got_packet_ptr = 1;
+ return 0;
+}
+
+static const AVCodecDefault ilbc_encode_defaults[] = {
+ { "b", "0" },
+ { NULL }
+};
+
+AVCodec ff_libilbc_encoder = {
+ .name = "libilbc",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_ILBC,
+ .priv_data_size = sizeof(ILBCEncContext),
+ .init = ilbc_encode_init,
+ .encode2 = ilbc_encode_frame,
+ .close = ilbc_encode_close,
+ .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
+ AV_SAMPLE_FMT_NONE },
+ .long_name = NULL_IF_CONFIG_SMALL("Internet Low Bitrate Codec (iLBC)"),
+ .defaults = ilbc_encode_defaults,
+ .priv_class = &ilbc_enc_class,
+};
diff --git a/libavcodec/libmp3lame.c b/libavcodec/libmp3lame.c
index c7abb99..a747f65 100644
--- a/libavcodec/libmp3lame.c
+++ b/libavcodec/libmp3lame.c
@@ -26,6 +26,7 @@
#include <lame/lame.h>
+#include "libavutil/audioconvert.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/log.h"
#include "libavutil/opt.h"
@@ -76,11 +77,6 @@ static av_cold int mp3lame_encode_init(AVCodecContext *avctx)
if ((s->gfp = lame_init()) == NULL)
return AVERROR(ENOMEM);
- /* channels */
- if (avctx->channels > 2) {
- ret = AVERROR(EINVAL);
- goto error;
- }
lame_set_num_channels(s->gfp, avctx->channels);
lame_set_mode(s->gfp, avctx->channels > 1 ? JOINT_STEREO : MONO);
@@ -308,6 +304,9 @@ AVCodec ff_libmp3lame_encoder = {
AV_SAMPLE_FMT_S16,
AV_SAMPLE_FMT_NONE },
.supported_samplerates = libmp3lame_sample_rates,
+ .channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO,
+ AV_CH_LAYOUT_STEREO,
+ 0 },
.long_name = NULL_IF_CONFIG_SMALL("libmp3lame MP3 (MPEG audio layer 3)"),
.priv_class = &libmp3lame_class,
.defaults = libmp3lame_defaults,
diff --git a/libavcodec/libschroedinger.c b/libavcodec/libschroedinger.c
index 527c492..2046761 100644
--- a/libavcodec/libschroedinger.c
+++ b/libavcodec/libschroedinger.c
@@ -23,12 +23,97 @@
* function definitions common to libschroedinger decoder and encoder
*/
-#include "libdirac_libschro.h"
#include "libschroedinger.h"
+static const SchroVideoFormatInfo ff_schro_video_format_info[] = {
+ { 640, 480, 24000, 1001},
+ { 176, 120, 15000, 1001},
+ { 176, 144, 25, 2 },
+ { 352, 240, 15000, 1001},
+ { 352, 288, 25, 2 },
+ { 704, 480, 15000, 1001},
+ { 704, 576, 25, 2 },
+ { 720, 480, 30000, 1001},
+ { 720, 576, 25, 1 },
+ { 1280, 720, 60000, 1001},
+ { 1280, 720, 50, 1 },
+ { 1920, 1080, 30000, 1001},
+ { 1920, 1080, 25, 1 },
+ { 1920, 1080, 60000, 1001},
+ { 1920, 1080, 50, 1 },
+ { 2048, 1080, 24, 1 },
+ { 4096, 2160, 24, 1 },
+};
+
+static unsigned int get_video_format_idx(AVCodecContext *avccontext)
+{
+ unsigned int ret_idx = 0;
+ unsigned int idx;
+ unsigned int num_formats = sizeof(ff_schro_video_format_info) /
+ sizeof(ff_schro_video_format_info[0]);
+
+ for (idx = 1; idx < num_formats; ++idx) {
+ const SchroVideoFormatInfo *vf = &ff_schro_video_format_info[idx];
+ if (avccontext->width == vf->width &&
+ avccontext->height == vf->height) {
+ ret_idx = idx;
+ if (avccontext->time_base.den == vf->frame_rate_num &&
+ avccontext->time_base.num == vf->frame_rate_denom)
+ return idx;
+ }
+ }
+ return ret_idx;
+}
+
+void ff_schro_queue_init(FFSchroQueue *queue)
+{
+ queue->p_head = queue->p_tail = NULL;
+ queue->size = 0;
+}
+
+void ff_schro_queue_free(FFSchroQueue *queue, void (*free_func)(void *))
+{
+ while (queue->p_head)
+ free_func(ff_schro_queue_pop(queue));
+}
+
+int ff_schro_queue_push_back(FFSchroQueue *queue, void *p_data)
+{
+ FFSchroQueueElement *p_new = av_mallocz(sizeof(FFSchroQueueElement));
+
+ if (!p_new)
+ return -1;
+
+ p_new->data = p_data;
+
+ if (!queue->p_head)
+ queue->p_head = p_new;
+ else
+ queue->p_tail->next = p_new;
+ queue->p_tail = p_new;
+
+ ++queue->size;
+ return 0;
+}
+
+void *ff_schro_queue_pop(FFSchroQueue *queue)
+{
+ FFSchroQueueElement *top = queue->p_head;
+
+ if (top) {
+ void *data = top->data;
+ queue->p_head = queue->p_head->next;
+ --queue->size;
+ av_freep(&top);
+ return data;
+ }
+
+ return NULL;
+}
+
/**
* Schroedinger video preset table. Ensure that this tables matches up correctly
-* with the ff_dirac_schro_video_format_info table in libdirac_libschro.c.
+* with the ff_schro_video_format_info table.
*/
static const SchroVideoFormatEnum ff_schro_video_formats[]={
SCHRO_VIDEO_FORMAT_CUSTOM ,
@@ -55,7 +140,7 @@ SchroVideoFormatEnum ff_get_schro_video_format_preset(AVCodecContext *avccontext
unsigned int num_formats = sizeof(ff_schro_video_formats) /
sizeof(ff_schro_video_formats[0]);
- unsigned int idx = ff_dirac_schro_get_video_format_idx (avccontext);
+ unsigned int idx = get_video_format_idx(avccontext);
return (idx < num_formats) ? ff_schro_video_formats[idx] :
SCHRO_VIDEO_FORMAT_CUSTOM;
@@ -78,7 +163,7 @@ int ff_get_schro_frame_format (SchroChromaFormat schro_pix_fmt,
return -1;
}
-static void FreeSchroFrame(SchroFrame *frame, void *priv)
+static void free_schro_frame(SchroFrame *frame, void *priv)
{
AVPicture *p_pic = priv;
@@ -110,7 +195,7 @@ SchroFrame *ff_create_schro_frame(AVCodecContext *avccontext,
p_frame->format = schro_frame_fmt;
p_frame->width = y_width;
p_frame->height = y_height;
- schro_frame_set_free_callback(p_frame, FreeSchroFrame, (void *)p_pic);
+ schro_frame_set_free_callback(p_frame, free_schro_frame, (void *)p_pic);
for (i = 0; i < 3; ++i) {
p_frame->components[i].width = i ? uv_width : y_width;
diff --git a/libavcodec/libschroedinger.h b/libavcodec/libschroedinger.h
index 8147821..8d04d2c 100644
--- a/libavcodec/libschroedinger.h
+++ b/libavcodec/libschroedinger.h
@@ -28,8 +28,78 @@
#include <schroedinger/schrobitstream.h>
#include <schroedinger/schroframe.h>
+
#include "avcodec.h"
+typedef struct {
+ uint16_t width;
+ uint16_t height;
+ uint16_t frame_rate_num;
+ uint16_t frame_rate_denom;
+} SchroVideoFormatInfo;
+
+/**
+* contains a single encoded frame returned from Dirac or Schroedinger
+*/
+typedef struct FFSchroEncodedFrame {
+ /** encoded frame data */
+ uint8_t *p_encbuf;
+
+ /** encoded frame size */
+ uint32_t size;
+
+ /** encoded frame number. Will be used as pts */
+ uint32_t frame_num;
+
+ /** key frame flag. 1 : is key frame , 0 : in not key frame */
+ uint16_t key_frame;
+} FFSchroEncodedFrame;
+
+/**
+* queue element
+*/
+typedef struct FFSchroQueueElement {
+ /** Data to be stored in queue*/
+ void *data;
+ /** Pointer to next element queue */
+ struct FFSchroQueueElement *next;
+} FFSchroQueueElement;
+
+
+/**
+* A simple queue implementation used in libschroedinger
+*/
+typedef struct FFSchroQueue {
+ /** Pointer to head of queue */
+ FFSchroQueueElement *p_head;
+ /** Pointer to tail of queue */
+ FFSchroQueueElement *p_tail;
+ /** Queue size*/
+ int size;
+} FFSchroQueue;
+
+/**
+* Initialise the queue
+*/
+void ff_schro_queue_init(FFSchroQueue *queue);
+
+/**
+* Add an element to the end of the queue
+*/
+int ff_schro_queue_push_back(FFSchroQueue *queue, void *p_data);
+
+/**
+* Return the first element in the queue
+*/
+void *ff_schro_queue_pop(FFSchroQueue *queue);
+
+/**
+* Free the queue resources. free_func is a function supplied by the caller to
+* free any resources allocated by the caller. The data field of the queue
+* element is passed to it.
+*/
+void ff_schro_queue_free(FFSchroQueue *queue, void (*free_func)(void *));
+
static const struct {
enum PixelFormat ff_pix_fmt;
SchroChromaFormat schro_pix_fmt;
diff --git a/libavcodec/libschroedingerdec.c b/libavcodec/libschroedingerdec.c
index 68d9a25..77f4289 100644
--- a/libavcodec/libschroedingerdec.c
+++ b/libavcodec/libschroedingerdec.c
@@ -28,8 +28,8 @@
*/
#include "libavutil/imgutils.h"
+#include "libavutil/intreadwrite.h"
#include "avcodec.h"
-#include "libdirac_libschro.h"
#include "libschroedinger.h"
#undef NDEBUG
@@ -40,6 +40,12 @@
#include <schroedinger/schrodebug.h>
#include <schroedinger/schrovideoformat.h>
+/** SchroFrame and Pts relation */
+typedef struct LibSchroFrameContext {
+ SchroFrame *frame;
+ int64_t pts;
+} LibSchroFrameContext;
+
/** libschroedinger decoder private data */
typedef struct SchroDecoderParams {
/** Schroedinger video format */
@@ -52,7 +58,7 @@ typedef struct SchroDecoderParams {
SchroDecoder* decoder;
/** queue storing decoded frames */
- DiracSchroQueue dec_frame_queue;
+ FFSchroQueue dec_frame_queue;
/** end of sequence signalled */
int eos_signalled;
@@ -61,7 +67,7 @@ typedef struct SchroDecoderParams {
int eos_pulled;
/** decoded picture */
- AVPicture dec_pic;
+ AVFrame dec_frame;
} SchroDecoderParams;
typedef struct SchroParseUnitContext {
@@ -71,16 +77,19 @@ typedef struct SchroParseUnitContext {
static void libschroedinger_decode_buffer_free(SchroBuffer *schro_buf,
- void *priv);
+ void *priv)
+{
+ av_freep(&priv);
+}
-static void SchroParseContextInit(SchroParseUnitContext *parse_ctx,
- const uint8_t *buf, int buf_size)
+static void parse_context_init(SchroParseUnitContext *parse_ctx,
+ const uint8_t *buf, int buf_size)
{
parse_ctx->buf = buf;
parse_ctx->buf_size = buf_size;
}
-static SchroBuffer *FindNextSchroParseUnit(SchroParseUnitContext *parse_ctx)
+static SchroBuffer *find_next_parse_unit(SchroParseUnitContext *parse_ctx)
{
SchroBuffer *enc_buf = NULL;
int next_pu_offset = 0;
@@ -152,16 +161,10 @@ static av_cold int libschroedinger_decode_init(AVCodecContext *avccontext)
return -1;
/* Initialize the decoded frame queue. */
- ff_dirac_schro_queue_init(&p_schro_params->dec_frame_queue);
+ ff_schro_queue_init(&p_schro_params->dec_frame_queue);
return 0;
}
-static void libschroedinger_decode_buffer_free(SchroBuffer *schro_buf,
- void *priv)
-{
- av_freep(&priv);
-}
-
static void libschroedinger_decode_frame_free(void *frame)
{
schro_frame_unref(frame);
@@ -175,8 +178,8 @@ static void libschroedinger_handle_first_access_unit(AVCodecContext *avccontext)
p_schro_params->format = schro_decoder_get_video_format(decoder);
/* Tell Libav about sequence details. */
- if (av_image_check_size(p_schro_params->format->width, p_schro_params->format->height,
- 0, avccontext) < 0) {
+ if (av_image_check_size(p_schro_params->format->width,
+ p_schro_params->format->height, 0, avccontext) < 0) {
av_log(avccontext, AV_LOG_ERROR, "invalid dimensions (%dx%d)\n",
p_schro_params->format->width, p_schro_params->format->height);
avccontext->height = avccontext->width = 0;
@@ -196,12 +199,6 @@ static void libschroedinger_handle_first_access_unit(AVCodecContext *avccontext)
avccontext->time_base.den = p_schro_params->format->frame_rate_numerator;
avccontext->time_base.num = p_schro_params->format->frame_rate_denominator;
-
- if (!p_schro_params->dec_pic.data[0])
- avpicture_alloc(&p_schro_params->dec_pic,
- avccontext->pix_fmt,
- avccontext->width,
- avccontext->height);
}
static int libschroedinger_decode_frame(AVCodecContext *avccontext,
@@ -210,20 +207,22 @@ static int libschroedinger_decode_frame(AVCodecContext *avccontext,
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
+ int64_t pts = avpkt->pts;
+ SchroTag *tag;
SchroDecoderParams *p_schro_params = avccontext->priv_data;
SchroDecoder *decoder = p_schro_params->decoder;
- AVPicture *picture = data;
SchroBuffer *enc_buf;
SchroFrame* frame;
int state;
int go = 1;
int outer = 1;
SchroParseUnitContext parse_ctx;
+ LibSchroFrameContext *framewithpts = NULL;
*data_size = 0;
- SchroParseContextInit(&parse_ctx, buf, buf_size);
+ parse_context_init(&parse_ctx, buf, buf_size);
if (!buf_size) {
if (!p_schro_params->eos_signalled) {
state = schro_decoder_push_end_of_stream(decoder);
@@ -233,7 +232,14 @@ static int libschroedinger_decode_frame(AVCodecContext *avccontext,
/* Loop through all the individual parse units in the input buffer */
do {
- if ((enc_buf = FindNextSchroParseUnit(&parse_ctx))) {
+ if ((enc_buf = find_next_parse_unit(&parse_ctx))) {
+ /* Set Schrotag with the pts to be recovered after decoding*/
+ enc_buf->tag = schro_tag_new(av_malloc(sizeof(int64_t)), av_free);
+ if (!enc_buf->tag->value) {
+ av_log(avccontext, AV_LOG_ERROR, "Unable to allocate SchroTag\n");
+ return AVERROR(ENOMEM);
+ }
+ AV_WN(64, enc_buf->tag->value, pts);
/* Push buffer into decoder. */
if (SCHRO_PARSE_CODE_IS_PICTURE(enc_buf->data[4]) &&
SCHRO_PARSE_CODE_NUM_REFS(enc_buf->data[4]) > 0)
@@ -267,11 +273,21 @@ static int libschroedinger_decode_frame(AVCodecContext *avccontext,
case SCHRO_DECODER_OK:
/* Pull a frame out of the decoder. */
+ tag = schro_decoder_get_picture_tag(decoder);
frame = schro_decoder_pull(decoder);
- if (frame)
- ff_dirac_schro_queue_push_back(&p_schro_params->dec_frame_queue,
- frame);
+ if (frame) {
+ /* Add relation between schroframe and pts. */
+ framewithpts = av_malloc(sizeof(LibSchroFrameContext));
+ if (!framewithpts) {
+ av_log(avccontext, AV_LOG_ERROR, "Unable to allocate FrameWithPts\n");
+ return AVERROR(ENOMEM);
+ }
+ framewithpts->frame = frame;
+ framewithpts->pts = AV_RN64(tag->value);
+ ff_schro_queue_push_back(&p_schro_params->dec_frame_queue,
+ framewithpts);
+ }
break;
case SCHRO_DECODER_EOS:
go = 0;
@@ -288,30 +304,46 @@ static int libschroedinger_decode_frame(AVCodecContext *avccontext,
} while (outer);
/* Grab next frame to be returned from the top of the queue. */
- frame = ff_dirac_schro_queue_pop(&p_schro_params->dec_frame_queue);
+ framewithpts = ff_schro_queue_pop(&p_schro_params->dec_frame_queue);
+
+ if (framewithpts && framewithpts->frame) {
+ if (p_schro_params->dec_frame.data[0])
+ avccontext->release_buffer(avccontext, &p_schro_params->dec_frame);
+ if (avccontext->get_buffer(avccontext, &p_schro_params->dec_frame) < 0) {
+ av_log(avccontext, AV_LOG_ERROR, "Unable to allocate buffer\n");
+ return AVERROR(ENOMEM);
+ }
- if (frame) {
- memcpy(p_schro_params->dec_pic.data[0],
- frame->components[0].data,
- frame->components[0].length);
+ memcpy(p_schro_params->dec_frame.data[0],
+ framewithpts->frame->components[0].data,
+ framewithpts->frame->components[0].length);
- memcpy(p_schro_params->dec_pic.data[1],
- frame->components[1].data,
- frame->components[1].length);
+ memcpy(p_schro_params->dec_frame.data[1],
+ framewithpts->frame->components[1].data,
+ framewithpts->frame->components[1].length);
- memcpy(p_schro_params->dec_pic.data[2],
- frame->components[2].data,
- frame->components[2].length);
+ memcpy(p_schro_params->dec_frame.data[2],
+ framewithpts->frame->components[2].data,
+ framewithpts->frame->components[2].length);
- /* Fill picture with current buffer data from Schroedinger. */
- avpicture_fill(picture, p_schro_params->dec_pic.data[0],
- avccontext->pix_fmt,
- avccontext->width, avccontext->height);
+ /* Fill frame with current buffer data from Schroedinger. */
+ p_schro_params->dec_frame.format = -1; /* Unknown -1 */
+ p_schro_params->dec_frame.width = framewithpts->frame->width;
+ p_schro_params->dec_frame.height = framewithpts->frame->height;
+ p_schro_params->dec_frame.pkt_pts = framewithpts->pts;
+ p_schro_params->dec_frame.linesize[0] = framewithpts->frame->components[0].stride;
+ p_schro_params->dec_frame.linesize[1] = framewithpts->frame->components[1].stride;
+ p_schro_params->dec_frame.linesize[2] = framewithpts->frame->components[2].stride;
- *data_size = sizeof(AVPicture);
+ *(AVFrame*)data = p_schro_params->dec_frame;
+ *data_size = sizeof(AVFrame);
/* Now free the frame resources. */
- libschroedinger_decode_frame_free(frame);
+ libschroedinger_decode_frame_free(framewithpts->frame);
+ av_free(framewithpts);
+ } else {
+ data = NULL;
+ *data_size = 0;
}
return buf_size;
}
@@ -324,11 +356,12 @@ static av_cold int libschroedinger_decode_close(AVCodecContext *avccontext)
schro_decoder_free(p_schro_params->decoder);
av_freep(&p_schro_params->format);
- avpicture_free(&p_schro_params->dec_pic);
+ if (p_schro_params->dec_frame.data[0])
+ avccontext->release_buffer(avccontext, &p_schro_params->dec_frame);
/* Free data in the output frame queue. */
- ff_dirac_schro_queue_free(&p_schro_params->dec_frame_queue,
- libschroedinger_decode_frame_free);
+ ff_schro_queue_free(&p_schro_params->dec_frame_queue,
+ libschroedinger_decode_frame_free);
return 0;
}
@@ -340,10 +373,10 @@ static void libschroedinger_flush(AVCodecContext *avccontext)
SchroDecoderParams *p_schro_params = avccontext->priv_data;
/* Free data in the output frame queue. */
- ff_dirac_schro_queue_free(&p_schro_params->dec_frame_queue,
- libschroedinger_decode_frame_free);
+ ff_schro_queue_free(&p_schro_params->dec_frame_queue,
+ libschroedinger_decode_frame_free);
- ff_dirac_schro_queue_init(&p_schro_params->dec_frame_queue);
+ ff_schro_queue_init(&p_schro_params->dec_frame_queue);
schro_decoder_reset(p_schro_params->decoder);
p_schro_params->eos_pulled = 0;
p_schro_params->eos_signalled = 0;
diff --git a/libavcodec/libschroedingerenc.c b/libavcodec/libschroedingerenc.c
index f07c83e..63d354e 100644
--- a/libavcodec/libschroedingerenc.c
+++ b/libavcodec/libschroedingerenc.c
@@ -36,7 +36,6 @@
#include "avcodec.h"
#include "internal.h"
-#include "libdirac_libschro.h"
#include "libschroedinger.h"
#include "bytestream.h"
@@ -65,7 +64,7 @@ typedef struct SchroEncoderParams {
int enc_buf_size;
/** queue storing encoded frames */
- DiracSchroQueue enc_frame_queue;
+ FFSchroQueue enc_frame_queue;
/** end of sequence signalled */
int eos_signalled;
@@ -80,7 +79,7 @@ typedef struct SchroEncoderParams {
/**
* Works out Schro-compatible chroma format.
*/
-static int SetSchroChromaFormat(AVCodecContext *avccontext)
+static int set_chroma_format(AVCodecContext *avccontext)
{
int num_formats = sizeof(schro_pixel_format_map) /
sizeof(schro_pixel_format_map[0]);
@@ -129,7 +128,7 @@ static int libschroedinger_encode_init(AVCodecContext *avccontext)
p_schro_params->format->width = avccontext->width;
p_schro_params->format->height = avccontext->height;
- if (SetSchroChromaFormat(avccontext) == -1)
+ if (set_chroma_format(avccontext) == -1)
return -1;
if (avccontext->color_primaries == AVCOL_PRI_BT709) {
@@ -236,7 +235,7 @@ static int libschroedinger_encode_init(AVCodecContext *avccontext)
schro_encoder_start(p_schro_params->encoder);
/* Initialize the encoded frame queue. */
- ff_dirac_schro_queue_init(&p_schro_params->enc_frame_queue);
+ ff_schro_queue_init(&p_schro_params->enc_frame_queue);
return 0;
}
@@ -259,9 +258,9 @@ static SchroFrame *libschroedinger_frame_from_data(AVCodecContext *avccontext,
return in_frame;
}
-static void SchroedingerFreeFrame(void *data)
+static void libschroedinger_free_frame(void *data)
{
- DiracSchroEncodedFrame *enc_frame = data;
+ FFSchroEncodedFrame *enc_frame = data;
av_freep(&enc_frame->p_encbuf);
av_free(enc_frame);
@@ -273,7 +272,7 @@ static int libschroedinger_encode_frame(AVCodecContext *avccontext, AVPacket *pk
int enc_size = 0;
SchroEncoderParams *p_schro_params = avccontext->priv_data;
SchroEncoder *encoder = p_schro_params->encoder;
- struct DiracSchroEncodedFrame *p_frame_output = NULL;
+ struct FFSchroEncodedFrame *p_frame_output = NULL;
int go = 1;
SchroBuffer *enc_buf;
int presentation_frame;
@@ -333,7 +332,7 @@ static int libschroedinger_encode_frame(AVCodecContext *avccontext, AVPacket *pk
}
/* Create output frame. */
- p_frame_output = av_mallocz(sizeof(DiracSchroEncodedFrame));
+ p_frame_output = av_mallocz(sizeof(FFSchroEncodedFrame));
/* Set output data. */
p_frame_output->size = p_schro_params->enc_buf_size;
p_frame_output->p_encbuf = p_schro_params->enc_buf;
@@ -345,8 +344,8 @@ static int libschroedinger_encode_frame(AVCodecContext *avccontext, AVPacket *pk
* through 17 represesent the frame number. */
p_frame_output->frame_num = AV_RB32(enc_buf->data + 13);
- ff_dirac_schro_queue_push_back(&p_schro_params->enc_frame_queue,
- p_frame_output);
+ ff_schro_queue_push_back(&p_schro_params->enc_frame_queue,
+ p_frame_output);
p_schro_params->enc_buf_size = 0;
p_schro_params->enc_buf = NULL;
@@ -373,7 +372,7 @@ static int libschroedinger_encode_frame(AVCodecContext *avccontext, AVPacket *pk
p_schro_params->eos_pulled)
last_frame_in_sequence = 1;
- p_frame_output = ff_dirac_schro_queue_pop(&p_schro_params->enc_frame_queue);
+ p_frame_output = ff_schro_queue_pop(&p_schro_params->enc_frame_queue);
if (!p_frame_output)
return 0;
@@ -412,7 +411,7 @@ static int libschroedinger_encode_frame(AVCodecContext *avccontext, AVPacket *pk
error:
/* free frame */
- SchroedingerFreeFrame(p_frame_output);
+ libschroedinger_free_frame(p_frame_output);
return ret;
}
@@ -425,8 +424,8 @@ static int libschroedinger_encode_close(AVCodecContext *avccontext)
schro_encoder_free(p_schro_params->encoder);
/* Free data in the output frame queue. */
- ff_dirac_schro_queue_free(&p_schro_params->enc_frame_queue,
- SchroedingerFreeFrame);
+ ff_schro_queue_free(&p_schro_params->enc_frame_queue,
+ libschroedinger_free_frame);
/* Free the encoder buffer. */
diff --git a/libavcodec/libspeexenc.c b/libavcodec/libspeexenc.c
index faf470e..8a869a0 100644
--- a/libavcodec/libspeexenc.c
+++ b/libavcodec/libspeexenc.c
@@ -67,6 +67,8 @@
#include <speex/speex.h>
#include <speex/speex_header.h>
#include <speex/speex_stereo.h>
+
+#include "libavutil/audioconvert.h"
#include "libavutil/opt.h"
#include "avcodec.h"
#include "internal.h"
@@ -334,6 +336,10 @@ AVCodec ff_libspeex_encoder = {
.capabilities = CODEC_CAP_DELAY,
.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
AV_SAMPLE_FMT_NONE },
+ .channel_layouts = (const uint64_t[]){ AV_CH_LAYOUT_MONO,
+ AV_CH_LAYOUT_STEREO,
+ 0 },
+ .supported_samplerates = (const int[]){ 8000, 16000, 32000, 0 },
.long_name = NULL_IF_CONFIG_SMALL("libspeex Speex"),
.priv_class = &class,
.defaults = defaults,
diff --git a/libavcodec/libxvid.c b/libavcodec/libxvid.c
new file mode 100644
index 0000000..3d63bea
--- /dev/null
+++ b/libavcodec/libxvid.c
@@ -0,0 +1,788 @@
+/*
+ * Interface to xvidcore for mpeg4 encoding
+ * Copyright (c) 2004 Adam Thayer <krevnik at comcast.net>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Interface to xvidcore for MPEG-4 compliant encoding.
+ * @author Adam Thayer (krevnik at comcast.net)
+ */
+
+#include <xvid.h>
+#include <unistd.h>
+#include "avcodec.h"
+#include "libavutil/cpu.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/mathematics.h"
+#include "libxvid.h"
+#include "mpegvideo.h"
+
+/**
+ * Buffer management macros.
+ */
+#define BUFFER_SIZE 1024
+#define BUFFER_REMAINING(x) (BUFFER_SIZE - strlen(x))
+#define BUFFER_CAT(x) (&((x)[strlen(x)]))
+
+/**
+ * Structure for the private Xvid context.
+ * This stores all the private context for the codec.
+ */
+struct xvid_context {
+ void *encoder_handle; /**< Handle for Xvid encoder */
+ int xsize; /**< Frame x size */
+ int ysize; /**< Frame y size */
+ int vop_flags; /**< VOP flags for Xvid encoder */
+ int vol_flags; /**< VOL flags for Xvid encoder */
+ int me_flags; /**< Motion Estimation flags */
+ int qscale; /**< Do we use constant scale? */
+ int quicktime_format; /**< Are we in a QT-based format? */
+ AVFrame encoded_picture; /**< Encoded frame information */
+ char *twopassbuffer; /**< Character buffer for two-pass */
+ char *old_twopassbuffer; /**< Old character buffer (two-pass) */
+ char *twopassfile; /**< second pass temp file name */
+ unsigned char *intra_matrix; /**< P-Frame Quant Matrix */
+ unsigned char *inter_matrix; /**< I-Frame Quant Matrix */
+};
+
+/**
+ * Structure for the private first-pass plugin.
+ */
+struct xvid_ff_pass1 {
+ int version; /**< Xvid version */
+ struct xvid_context *context; /**< Pointer to private context */
+};
+
+/*
+ * Xvid 2-Pass Kludge Section
+ *
+ * Xvid's default 2-pass doesn't allow us to create data as we need to, so
+ * this section spends time replacing the first pass plugin so we can write
+ * statistic information as libavcodec requests in. We have another kludge
+ * that allows us to pass data to the second pass in Xvid without a custom
+ * rate-control plugin.
+ */
+
+/**
+ * Initialize the two-pass plugin and context.
+ *
+ * @param param Input construction parameter structure
+ * @param handle Private context handle
+ * @return Returns XVID_ERR_xxxx on failure, or 0 on success.
+ */
+static int xvid_ff_2pass_create(xvid_plg_create_t * param,
+ void ** handle) {
+ struct xvid_ff_pass1 *x = (struct xvid_ff_pass1 *)param->param;
+ char *log = x->context->twopassbuffer;
+
+ /* Do a quick bounds check */
+ if( log == NULL )
+ return XVID_ERR_FAIL;
+
+ /* We use snprintf() */
+ /* This is because we can safely prevent a buffer overflow */
+ log[0] = 0;
+ snprintf(log, BUFFER_REMAINING(log),
+ "# avconv 2-pass log file, using xvid codec\n");
+ snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log),
+ "# Do not modify. libxvidcore version: %d.%d.%d\n\n",
+ XVID_VERSION_MAJOR(XVID_VERSION),
+ XVID_VERSION_MINOR(XVID_VERSION),
+ XVID_VERSION_PATCH(XVID_VERSION));
+
+ *handle = x->context;
+ return 0;
+}
+
+/**
+ * Destroy the two-pass plugin context.
+ *
+ * @param ref Context pointer for the plugin
+ * @param param Destrooy context
+ * @return Returns 0, success guaranteed
+ */
+static int xvid_ff_2pass_destroy(struct xvid_context *ref,
+ xvid_plg_destroy_t *param) {
+ /* Currently cannot think of anything to do on destruction */
+ /* Still, the framework should be here for reference/use */
+ if( ref->twopassbuffer != NULL )
+ ref->twopassbuffer[0] = 0;
+ return 0;
+}
+
+/**
+ * Enable fast encode mode during the first pass.
+ *
+ * @param ref Context pointer for the plugin
+ * @param param Frame data
+ * @return Returns 0, success guaranteed
+ */
+static int xvid_ff_2pass_before(struct xvid_context *ref,
+ xvid_plg_data_t *param) {
+ int motion_remove;
+ int motion_replacements;
+ int vop_remove;
+
+ /* Nothing to do here, result is changed too much */
+ if( param->zone && param->zone->mode == XVID_ZONE_QUANT )
+ return 0;
+
+ /* We can implement a 'turbo' first pass mode here */
+ param->quant = 2;
+
+ /* Init values */
+ motion_remove = ~XVID_ME_CHROMA_PVOP &
+ ~XVID_ME_CHROMA_BVOP &
+ ~XVID_ME_EXTSEARCH16 &
+ ~XVID_ME_ADVANCEDDIAMOND16;
+ motion_replacements = XVID_ME_FAST_MODEINTERPOLATE |
+ XVID_ME_SKIP_DELTASEARCH |
+ XVID_ME_FASTREFINE16 |
+ XVID_ME_BFRAME_EARLYSTOP;
+ vop_remove = ~XVID_VOP_MODEDECISION_RD &
+ ~XVID_VOP_FAST_MODEDECISION_RD &
+ ~XVID_VOP_TRELLISQUANT &
+ ~XVID_VOP_INTER4V &
+ ~XVID_VOP_HQACPRED;
+
+ param->vol_flags &= ~XVID_VOL_GMC;
+ param->vop_flags &= vop_remove;
+ param->motion_flags &= motion_remove;
+ param->motion_flags |= motion_replacements;
+
+ return 0;
+}
+
+/**
+ * Capture statistic data and write it during first pass.
+ *
+ * @param ref Context pointer for the plugin
+ * @param param Statistic data
+ * @return Returns XVID_ERR_xxxx on failure, or 0 on success
+ */
+static int xvid_ff_2pass_after(struct xvid_context *ref,
+ xvid_plg_data_t *param) {
+ char *log = ref->twopassbuffer;
+ const char *frame_types = " ipbs";
+ char frame_type;
+
+ /* Quick bounds check */
+ if( log == NULL )
+ return XVID_ERR_FAIL;
+
+ /* Convert the type given to us into a character */
+ if( param->type < 5 && param->type > 0 ) {
+ frame_type = frame_types[param->type];
+ } else {
+ return XVID_ERR_FAIL;
+ }
+
+ snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log),
+ "%c %d %d %d %d %d %d\n",
+ frame_type, param->stats.quant, param->stats.kblks, param->stats.mblks,
+ param->stats.ublks, param->stats.length, param->stats.hlength);
+
+ return 0;
+}
+
+/**
+ * Dispatch function for our custom plugin.
+ * This handles the dispatch for the Xvid plugin. It passes data
+ * on to other functions for actual processing.
+ *
+ * @param ref Context pointer for the plugin
+ * @param cmd The task given for us to complete
+ * @param p1 First parameter (varies)
+ * @param p2 Second parameter (varies)
+ * @return Returns XVID_ERR_xxxx on failure, or 0 on success
+ */
+static int xvid_ff_2pass(void *ref, int cmd, void *p1, void *p2)
+{
+ switch( cmd ) {
+ case XVID_PLG_INFO:
+ case XVID_PLG_FRAME:
+ return 0;
+
+ case XVID_PLG_BEFORE:
+ return xvid_ff_2pass_before(ref, p1);
+
+ case XVID_PLG_CREATE:
+ return xvid_ff_2pass_create(p1, p2);
+
+ case XVID_PLG_AFTER:
+ return xvid_ff_2pass_after(ref, p1);
+
+ case XVID_PLG_DESTROY:
+ return xvid_ff_2pass_destroy(ref, p1);
+
+ default:
+ return XVID_ERR_FAIL;
+ }
+}
+
+/**
+ * Routine to create a global VO/VOL header for MP4 container.
+ * What we do here is extract the header from the Xvid bitstream
+ * as it is encoded. We also strip the repeated headers from the
+ * bitstream when a global header is requested for MPEG-4 ISO
+ * compliance.
+ *
+ * @param avctx AVCodecContext pointer to context
+ * @param frame Pointer to encoded frame data
+ * @param header_len Length of header to search
+ * @param frame_len Length of encoded frame data
+ * @return Returns new length of frame data
+ */
+static int xvid_strip_vol_header(AVCodecContext *avctx,
+ AVPacket *pkt,
+ unsigned int header_len,
+ unsigned int frame_len) {
+ int vo_len = 0, i;
+
+ for( i = 0; i < header_len - 3; i++ ) {
+ if( pkt->data[i] == 0x00 &&
+ pkt->data[i+1] == 0x00 &&
+ pkt->data[i+2] == 0x01 &&
+ pkt->data[i+3] == 0xB6 ) {
+ vo_len = i;
+ break;
+ }
+ }
+
+ if( vo_len > 0 ) {
+ /* We need to store the header, so extract it */
+ if( avctx->extradata == NULL ) {
+ avctx->extradata = av_malloc(vo_len);
+ memcpy(avctx->extradata, pkt->data, vo_len);
+ avctx->extradata_size = vo_len;
+ }
+ /* Less dangerous now, memmove properly copies the two
+ chunks of overlapping data */
+ memmove(pkt->data, &pkt->data[vo_len], frame_len - vo_len);
+ pkt->size = frame_len - vo_len;
+ }
+ return 0;
+}
+
+/**
+ * Routine to correct a possibly erroneous framerate being fed to us.
+ * Xvid currently chokes on framerates where the ticks per frame is
+ * extremely large. This function works to correct problems in this area
+ * by estimating a new framerate and taking the simpler fraction of
+ * the two presented.
+ *
+ * @param avctx Context that contains the framerate to correct.
+ */
+static void xvid_correct_framerate(AVCodecContext *avctx)
+{
+ int frate, fbase;
+ int est_frate, est_fbase;
+ int gcd;
+ float est_fps, fps;
+
+ frate = avctx->time_base.den;
+ fbase = avctx->time_base.num;
+
+ gcd = av_gcd(frate, fbase);
+ if( gcd > 1 ) {
+ frate /= gcd;
+ fbase /= gcd;
+ }
+
+ if( frate <= 65000 && fbase <= 65000 ) {
+ avctx->time_base.den = frate;
+ avctx->time_base.num = fbase;
+ return;
+ }
+
+ fps = (float)frate / (float)fbase;
+ est_fps = roundf(fps * 1000.0) / 1000.0;
+
+ est_frate = (int)est_fps;
+ if( est_fps > (int)est_fps ) {
+ est_frate = (est_frate + 1) * 1000;
+ est_fbase = (int)roundf((float)est_frate / est_fps);
+ } else
+ est_fbase = 1;
+
+ gcd = av_gcd(est_frate, est_fbase);
+ if( gcd > 1 ) {
+ est_frate /= gcd;
+ est_fbase /= gcd;
+ }
+
+ if( fbase > est_fbase ) {
+ avctx->time_base.den = est_frate;
+ avctx->time_base.num = est_fbase;
+ av_log(avctx, AV_LOG_DEBUG,
+ "Xvid: framerate re-estimated: %.2f, %.3f%% correction\n",
+ est_fps, (((est_fps - fps)/fps) * 100.0));
+ } else {
+ avctx->time_base.den = frate;
+ avctx->time_base.num = fbase;
+ }
+}
+
+/**
+ * Create the private context for the encoder.
+ * All buffers are allocated, settings are loaded from the user,
+ * and the encoder context created.
+ *
+ * @param avctx AVCodecContext pointer to context
+ * @return Returns 0 on success, -1 on failure
+ */
+static av_cold int xvid_encode_init(AVCodecContext *avctx) {
+ int xerr, i;
+ int xvid_flags = avctx->flags;
+ struct xvid_context *x = avctx->priv_data;
+ uint16_t *intra, *inter;
+ int fd;
+
+ xvid_plugin_single_t single = { 0 };
+ struct xvid_ff_pass1 rc2pass1 = { 0 };
+ xvid_plugin_2pass2_t rc2pass2 = { 0 };
+ xvid_gbl_init_t xvid_gbl_init = { 0 };
+ xvid_enc_create_t xvid_enc_create = { 0 };
+ xvid_enc_plugin_t plugins[7];
+
+ /* Bring in VOP flags from avconv command-line */
+ x->vop_flags = XVID_VOP_HALFPEL; /* Bare minimum quality */
+ if( xvid_flags & CODEC_FLAG_4MV )
+ x->vop_flags |= XVID_VOP_INTER4V; /* Level 3 */
+ if( avctx->trellis
+ )
+ x->vop_flags |= XVID_VOP_TRELLISQUANT; /* Level 5 */
+ if( xvid_flags & CODEC_FLAG_AC_PRED )
+ x->vop_flags |= XVID_VOP_HQACPRED; /* Level 6 */
+ if( xvid_flags & CODEC_FLAG_GRAY )
+ x->vop_flags |= XVID_VOP_GREYSCALE;
+
+ /* Decide which ME quality setting to use */
+ x->me_flags = 0;
+ switch( avctx->me_method ) {
+ case ME_FULL: /* Quality 6 */
+ x->me_flags |= XVID_ME_EXTSEARCH16
+ | XVID_ME_EXTSEARCH8;
+
+ case ME_EPZS: /* Quality 4 */
+ x->me_flags |= XVID_ME_ADVANCEDDIAMOND8
+ | XVID_ME_HALFPELREFINE8
+ | XVID_ME_CHROMA_PVOP
+ | XVID_ME_CHROMA_BVOP;
+
+ case ME_LOG: /* Quality 2 */
+ case ME_PHODS:
+ case ME_X1:
+ x->me_flags |= XVID_ME_ADVANCEDDIAMOND16
+ | XVID_ME_HALFPELREFINE16;
+
+ case ME_ZERO: /* Quality 0 */
+ default:
+ break;
+ }
+
+ /* Decide how we should decide blocks */
+ switch( avctx->mb_decision ) {
+ case 2:
+ x->vop_flags |= XVID_VOP_MODEDECISION_RD;
+ x->me_flags |= XVID_ME_HALFPELREFINE8_RD
+ | XVID_ME_QUARTERPELREFINE8_RD
+ | XVID_ME_EXTSEARCH_RD
+ | XVID_ME_CHECKPREDICTION_RD;
+ case 1:
+ if( !(x->vop_flags & XVID_VOP_MODEDECISION_RD) )
+ x->vop_flags |= XVID_VOP_FAST_MODEDECISION_RD;
+ x->me_flags |= XVID_ME_HALFPELREFINE16_RD
+ | XVID_ME_QUARTERPELREFINE16_RD;
+
+ default:
+ break;
+ }
+
+ /* Bring in VOL flags from avconv command-line */
+ x->vol_flags = 0;
+ if( xvid_flags & CODEC_FLAG_GMC ) {
+ x->vol_flags |= XVID_VOL_GMC;
+ x->me_flags |= XVID_ME_GME_REFINE;
+ }
+ if( xvid_flags & CODEC_FLAG_QPEL ) {
+ x->vol_flags |= XVID_VOL_QUARTERPEL;
+ x->me_flags |= XVID_ME_QUARTERPELREFINE16;
+ if( x->vop_flags & XVID_VOP_INTER4V )
+ x->me_flags |= XVID_ME_QUARTERPELREFINE8;
+ }
+
+ xvid_gbl_init.version = XVID_VERSION;
+ xvid_gbl_init.debug = 0;
+
+#if ARCH_PPC
+ /* Xvid's PPC support is borked, use libavcodec to detect */
+#if HAVE_ALTIVEC
+ if (av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) {
+ xvid_gbl_init.cpu_flags = XVID_CPU_FORCE | XVID_CPU_ALTIVEC;
+ } else
+#endif
+ xvid_gbl_init.cpu_flags = XVID_CPU_FORCE;
+#else
+ /* Xvid can detect on x86 */
+ xvid_gbl_init.cpu_flags = 0;
+#endif
+
+ /* Initialize */
+ xvid_global(NULL, XVID_GBL_INIT, &xvid_gbl_init, NULL);
+
+ /* Create the encoder reference */
+ xvid_enc_create.version = XVID_VERSION;
+
+ /* Store the desired frame size */
+ xvid_enc_create.width = x->xsize = avctx->width;
+ xvid_enc_create.height = x->ysize = avctx->height;
+
+ /* Xvid can determine the proper profile to use */
+ /* xvid_enc_create.profile = XVID_PROFILE_S_L3; */
+
+ /* We don't use zones */
+ xvid_enc_create.zones = NULL;
+ xvid_enc_create.num_zones = 0;
+
+ xvid_enc_create.num_threads = avctx->thread_count;
+
+ xvid_enc_create.plugins = plugins;
+ xvid_enc_create.num_plugins = 0;
+
+ /* Initialize Buffers */
+ x->twopassbuffer = NULL;
+ x->old_twopassbuffer = NULL;
+ x->twopassfile = NULL;
+
+ if( xvid_flags & CODEC_FLAG_PASS1 ) {
+ rc2pass1.version = XVID_VERSION;
+ rc2pass1.context = x;
+ x->twopassbuffer = av_malloc(BUFFER_SIZE);
+ x->old_twopassbuffer = av_malloc(BUFFER_SIZE);
+ if( x->twopassbuffer == NULL || x->old_twopassbuffer == NULL ) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Xvid: Cannot allocate 2-pass log buffers\n");
+ return -1;
+ }
+ x->twopassbuffer[0] = x->old_twopassbuffer[0] = 0;
+
+ plugins[xvid_enc_create.num_plugins].func = xvid_ff_2pass;
+ plugins[xvid_enc_create.num_plugins].param = &rc2pass1;
+ xvid_enc_create.num_plugins++;
+ } else if( xvid_flags & CODEC_FLAG_PASS2 ) {
+ rc2pass2.version = XVID_VERSION;
+ rc2pass2.bitrate = avctx->bit_rate;
+
+ fd = ff_tempfile("xvidff.", &x->twopassfile);
+ if( fd == -1 ) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Xvid: Cannot write 2-pass pipe\n");
+ return -1;
+ }
+
+ if( avctx->stats_in == NULL ) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Xvid: No 2-pass information loaded for second pass\n");
+ return -1;
+ }
+
+ if( strlen(avctx->stats_in) >
+ write(fd, avctx->stats_in, strlen(avctx->stats_in)) ) {
+ close(fd);
+ av_log(avctx, AV_LOG_ERROR,
+ "Xvid: Cannot write to 2-pass pipe\n");
+ return -1;
+ }
+
+ close(fd);
+ rc2pass2.filename = x->twopassfile;
+ plugins[xvid_enc_create.num_plugins].func = xvid_plugin_2pass2;
+ plugins[xvid_enc_create.num_plugins].param = &rc2pass2;
+ xvid_enc_create.num_plugins++;
+ } else if( !(xvid_flags & CODEC_FLAG_QSCALE) ) {
+ /* Single Pass Bitrate Control! */
+ single.version = XVID_VERSION;
+ single.bitrate = avctx->bit_rate;
+
+ plugins[xvid_enc_create.num_plugins].func = xvid_plugin_single;
+ plugins[xvid_enc_create.num_plugins].param = &single;
+ xvid_enc_create.num_plugins++;
+ }
+
+ /* Luminance Masking */
+ if( 0.0 != avctx->lumi_masking ) {
+ plugins[xvid_enc_create.num_plugins].func = xvid_plugin_lumimasking;
+ plugins[xvid_enc_create.num_plugins].param = NULL;
+ xvid_enc_create.num_plugins++;
+ }
+
+ /* Frame Rate and Key Frames */
+ xvid_correct_framerate(avctx);
+ xvid_enc_create.fincr = avctx->time_base.num;
+ xvid_enc_create.fbase = avctx->time_base.den;
+ if( avctx->gop_size > 0 )
+ xvid_enc_create.max_key_interval = avctx->gop_size;
+ else
+ xvid_enc_create.max_key_interval = 240; /* Xvid's best default */
+
+ /* Quants */
+ if( xvid_flags & CODEC_FLAG_QSCALE ) x->qscale = 1;
+ else x->qscale = 0;
+
+ xvid_enc_create.min_quant[0] = avctx->qmin;
+ xvid_enc_create.min_quant[1] = avctx->qmin;
+ xvid_enc_create.min_quant[2] = avctx->qmin;
+ xvid_enc_create.max_quant[0] = avctx->qmax;
+ xvid_enc_create.max_quant[1] = avctx->qmax;
+ xvid_enc_create.max_quant[2] = avctx->qmax;
+
+ /* Quant Matrices */
+ x->intra_matrix = x->inter_matrix = NULL;
+ if( avctx->mpeg_quant )
+ x->vol_flags |= XVID_VOL_MPEGQUANT;
+ if( (avctx->intra_matrix || avctx->inter_matrix) ) {
+ x->vol_flags |= XVID_VOL_MPEGQUANT;
+
+ if( avctx->intra_matrix ) {
+ intra = avctx->intra_matrix;
+ x->intra_matrix = av_malloc(sizeof(unsigned char) * 64);
+ } else
+ intra = NULL;
+ if( avctx->inter_matrix ) {
+ inter = avctx->inter_matrix;
+ x->inter_matrix = av_malloc(sizeof(unsigned char) * 64);
+ } else
+ inter = NULL;
+
+ for( i = 0; i < 64; i++ ) {
+ if( intra )
+ x->intra_matrix[i] = (unsigned char)intra[i];
+ if( inter )
+ x->inter_matrix[i] = (unsigned char)inter[i];
+ }
+ }
+
+ /* Misc Settings */
+ xvid_enc_create.frame_drop_ratio = 0;
+ xvid_enc_create.global = 0;
+ if( xvid_flags & CODEC_FLAG_CLOSED_GOP )
+ xvid_enc_create.global |= XVID_GLOBAL_CLOSED_GOP;
+
+ /* Determines which codec mode we are operating in */
+ avctx->extradata = NULL;
+ avctx->extradata_size = 0;
+ if( xvid_flags & CODEC_FLAG_GLOBAL_HEADER ) {
+ /* In this case, we are claiming to be MPEG4 */
+ x->quicktime_format = 1;
+ avctx->codec_id = CODEC_ID_MPEG4;
+ } else {
+ /* We are claiming to be Xvid */
+ x->quicktime_format = 0;
+ if(!avctx->codec_tag)
+ avctx->codec_tag = AV_RL32("xvid");
+ }
+
+ /* Bframes */
+ xvid_enc_create.max_bframes = avctx->max_b_frames;
+ xvid_enc_create.bquant_offset = 100 * avctx->b_quant_offset;
+ xvid_enc_create.bquant_ratio = 100 * avctx->b_quant_factor;
+ if( avctx->max_b_frames > 0 && !x->quicktime_format ) xvid_enc_create.global |= XVID_GLOBAL_PACKED;
+
+ /* Create encoder context */
+ xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL);
+ if( xerr ) {
+ av_log(avctx, AV_LOG_ERROR, "Xvid: Could not create encoder reference\n");
+ return -1;
+ }
+
+ x->encoder_handle = xvid_enc_create.handle;
+ avctx->coded_frame = &x->encoded_picture;
+
+ return 0;
+}
+
+/**
+ * Encode a single frame.
+ *
+ * @param avctx AVCodecContext pointer to context
+ * @param frame Pointer to encoded frame buffer
+ * @param buf_size Size of encoded frame buffer
+ * @param data Pointer to AVFrame of unencoded frame
+ * @return Returns 0 on success, -1 on failure
+ */
+static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
+ const AVFrame *picture, int *got_packet)
+{
+ int xerr, i, ret, user_packet = !!pkt->data;
+ char *tmp;
+ struct xvid_context *x = avctx->priv_data;
+ AVFrame *p = &x->encoded_picture;
+ int mb_width = (avctx->width + 15) / 16;
+ int mb_height = (avctx->height + 15) / 16;
+
+ xvid_enc_frame_t xvid_enc_frame = { 0 };
+ xvid_enc_stats_t xvid_enc_stats = { 0 };
+
+ if (!user_packet &&
+ (ret = av_new_packet(pkt, mb_width*mb_height*MAX_MB_BYTES + FF_MIN_BUFFER_SIZE)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
+ return ret;
+ }
+
+ /* Start setting up the frame */
+ xvid_enc_frame.version = XVID_VERSION;
+ xvid_enc_stats.version = XVID_VERSION;
+ *p = *picture;
+
+ /* Let Xvid know where to put the frame. */
+ xvid_enc_frame.bitstream = pkt->data;
+ xvid_enc_frame.length = pkt->size;
+
+ /* Initialize input image fields */
+ if( avctx->pix_fmt != PIX_FMT_YUV420P ) {
+ av_log(avctx, AV_LOG_ERROR, "Xvid: Color spaces other than 420p not supported\n");
+ return -1;
+ }
+
+ xvid_enc_frame.input.csp = XVID_CSP_PLANAR; /* YUV420P */
+
+ for( i = 0; i < 4; i++ ) {
+ xvid_enc_frame.input.plane[i] = picture->data[i];
+ xvid_enc_frame.input.stride[i] = picture->linesize[i];
+ }
+
+ /* Encoder Flags */
+ xvid_enc_frame.vop_flags = x->vop_flags;
+ xvid_enc_frame.vol_flags = x->vol_flags;
+ xvid_enc_frame.motion = x->me_flags;
+ xvid_enc_frame.type =
+ picture->pict_type == AV_PICTURE_TYPE_I ? XVID_TYPE_IVOP :
+ picture->pict_type == AV_PICTURE_TYPE_P ? XVID_TYPE_PVOP :
+ picture->pict_type == AV_PICTURE_TYPE_B ? XVID_TYPE_BVOP :
+ XVID_TYPE_AUTO;
+
+ /* Pixel aspect ratio setting */
+ if (avctx->sample_aspect_ratio.num < 1 || avctx->sample_aspect_ratio.num > 255 ||
+ avctx->sample_aspect_ratio.den < 1 || avctx->sample_aspect_ratio.den > 255) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid pixel aspect ratio %i/%i\n",
+ avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den);
+ return -1;
+ }
+ xvid_enc_frame.par = XVID_PAR_EXT;
+ xvid_enc_frame.par_width = avctx->sample_aspect_ratio.num;
+ xvid_enc_frame.par_height = avctx->sample_aspect_ratio.den;
+
+ /* Quant Setting */
+ if( x->qscale ) xvid_enc_frame.quant = picture->quality / FF_QP2LAMBDA;
+ else xvid_enc_frame.quant = 0;
+
+ /* Matrices */
+ xvid_enc_frame.quant_intra_matrix = x->intra_matrix;
+ xvid_enc_frame.quant_inter_matrix = x->inter_matrix;
+
+ /* Encode */
+ xerr = xvid_encore(x->encoder_handle, XVID_ENC_ENCODE,
+ &xvid_enc_frame, &xvid_enc_stats);
+
+ /* Two-pass log buffer swapping */
+ avctx->stats_out = NULL;
+ if( x->twopassbuffer ) {
+ tmp = x->old_twopassbuffer;
+ x->old_twopassbuffer = x->twopassbuffer;
+ x->twopassbuffer = tmp;
+ x->twopassbuffer[0] = 0;
+ if( x->old_twopassbuffer[0] != 0 ) {
+ avctx->stats_out = x->old_twopassbuffer;
+ }
+ }
+
+ if (xerr > 0) {
+ *got_packet = 1;
+
+ p->quality = xvid_enc_stats.quant * FF_QP2LAMBDA;
+ if( xvid_enc_stats.type == XVID_TYPE_PVOP )
+ p->pict_type = AV_PICTURE_TYPE_P;
+ else if( xvid_enc_stats.type == XVID_TYPE_BVOP )
+ p->pict_type = AV_PICTURE_TYPE_B;
+ else if( xvid_enc_stats.type == XVID_TYPE_SVOP )
+ p->pict_type = AV_PICTURE_TYPE_S;
+ else
+ p->pict_type = AV_PICTURE_TYPE_I;
+ if( xvid_enc_frame.out_flags & XVID_KEYFRAME ) {
+ p->key_frame = 1;
+ pkt->flags |= AV_PKT_FLAG_KEY;
+ if( x->quicktime_format )
+ return xvid_strip_vol_header(avctx, pkt,
+ xvid_enc_stats.hlength, xerr);
+ } else
+ p->key_frame = 0;
+
+ pkt->size = xerr;
+
+ return 0;
+ } else {
+ if (!user_packet)
+ av_free_packet(pkt);
+ if (!xerr)
+ return 0;
+ av_log(avctx, AV_LOG_ERROR, "Xvid: Encoding Error Occurred: %i\n", xerr);
+ return -1;
+ }
+}
+
+/**
+ * Destroy the private context for the encoder.
+ * All buffers are freed, and the Xvid encoder context is destroyed.
+ *
+ * @param avctx AVCodecContext pointer to context
+ * @return Returns 0, success guaranteed
+ */
+static av_cold int xvid_encode_close(AVCodecContext *avctx) {
+ struct xvid_context *x = avctx->priv_data;
+
+ xvid_encore(x->encoder_handle, XVID_ENC_DESTROY, NULL, NULL);
+
+ av_freep(&avctx->extradata);
+ if( x->twopassbuffer != NULL ) {
+ av_free(x->twopassbuffer);
+ av_free(x->old_twopassbuffer);
+ }
+ av_free(x->twopassfile);
+ av_free(x->intra_matrix);
+ av_free(x->inter_matrix);
+
+ return 0;
+}
+
+/**
+ * Xvid codec definition for libavcodec.
+ */
+AVCodec ff_libxvid_encoder = {
+ .name = "libxvid",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MPEG4,
+ .priv_data_size = sizeof(struct xvid_context),
+ .init = xvid_encode_init,
+ .encode2 = xvid_encode_frame,
+ .close = xvid_encode_close,
+ .pix_fmts = (const enum PixelFormat[]){ PIX_FMT_YUV420P, PIX_FMT_NONE },
+ .long_name = NULL_IF_CONFIG_SMALL("libxvidcore MPEG-4 part 2"),
+};
diff --git a/libavcodec/libxvid.h b/libavcodec/libxvid.h
new file mode 100644
index 0000000..413d353
--- /dev/null
+++ b/libavcodec/libxvid.h
@@ -0,0 +1,32 @@
+/*
+ * copyright (C) 2006 Corey Hickey
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_LIBXVID_H
+#define AVCODEC_LIBXVID_H
+
+/**
+ * @file
+ * common functions for use with the Xvid wrappers
+ */
+
+
+int ff_tempfile(const char *prefix, char **filename);
+
+#endif /* AVCODEC_LIBXVID_H */
diff --git a/libavcodec/libxvid_internal.h b/libavcodec/libxvid_internal.h
deleted file mode 100644
index a2dc6ef..0000000
--- a/libavcodec/libxvid_internal.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * copyright (C) 2006 Corey Hickey
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef AVCODEC_LIBXVID_INTERNAL_H
-#define AVCODEC_LIBXVID_INTERNAL_H
-
-/**
- * @file
- * common functions for use with the Xvid wrappers
- */
-
-
-int ff_tempfile(const char *prefix, char **filename);
-
-#endif /* AVCODEC_LIBXVID_INTERNAL_H */
diff --git a/libavcodec/libxvid_rc.c b/libavcodec/libxvid_rc.c
index c830767..bf9f6f0 100644
--- a/libavcodec/libxvid_rc.c
+++ b/libavcodec/libxvid_rc.c
@@ -20,16 +20,57 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "config.h"
#include <xvid.h>
#include <unistd.h>
+#if !HAVE_MKSTEMP
+#include <fcntl.h>
+#endif
+
#include "avcodec.h"
-#include "libxvid_internal.h"
+#include "libxvid.h"
//#include "dsputil.h"
#include "mpegvideo.h"
#undef NDEBUG
#include <assert.h>
+/* Wrapper to work around the lack of mkstemp() on mingw.
+ * Also, tries to create file in /tmp first, if possible.
+ * *prefix can be a character constant; *filename will be allocated internally.
+ * @return file descriptor of opened file (or -1 on error)
+ * and opened file name in **filename. */
+int ff_tempfile(const char *prefix, char **filename) {
+ int fd=-1;
+#if !HAVE_MKSTEMP
+ *filename = tempnam(".", prefix);
+#else
+ size_t len = strlen(prefix) + 12; /* room for "/tmp/" and "XXXXXX\0" */
+ *filename = av_malloc(len);
+#endif
+ /* -----common section-----*/
+ if (*filename == NULL) {
+ av_log(NULL, AV_LOG_ERROR, "ff_tempfile: Cannot allocate file name\n");
+ return -1;
+ }
+#if !HAVE_MKSTEMP
+ fd = open(*filename, O_RDWR | O_BINARY | O_CREAT, 0444);
+#else
+ snprintf(*filename, len, "/tmp/%sXXXXXX", prefix);
+ fd = mkstemp(*filename);
+ if (fd < 0) {
+ snprintf(*filename, len, "./%sXXXXXX", prefix);
+ fd = mkstemp(*filename);
+ }
+#endif
+ /* -----common section-----*/
+ if (fd < 0) {
+ av_log(NULL, AV_LOG_ERROR, "ff_tempfile: Cannot open temporary file %s\n", *filename);
+ return -1;
+ }
+ return fd; /* success */
+}
+
int ff_xvid_rate_control_init(MpegEncContext *s){
char *tmp_name;
int fd, i;
diff --git a/libavcodec/libxvidff.c b/libavcodec/libxvidff.c
deleted file mode 100644
index def80b3..0000000
--- a/libavcodec/libxvidff.c
+++ /dev/null
@@ -1,827 +0,0 @@
-/*
- * Interface to xvidcore for mpeg4 encoding
- * Copyright (c) 2004 Adam Thayer <krevnik at comcast.net>
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * Interface to xvidcore for MPEG-4 compliant encoding.
- * @author Adam Thayer (krevnik at comcast.net)
- */
-
-#include <xvid.h>
-#include <unistd.h>
-#include "avcodec.h"
-#include "libavutil/cpu.h"
-#include "libavutil/intreadwrite.h"
-#include "libavutil/mathematics.h"
-#include "libxvid_internal.h"
-#include "mpegvideo.h"
-#if !HAVE_MKSTEMP
-#include <fcntl.h>
-#endif
-
-/**
- * Buffer management macros.
- */
-#define BUFFER_SIZE 1024
-#define BUFFER_REMAINING(x) (BUFFER_SIZE - strlen(x))
-#define BUFFER_CAT(x) (&((x)[strlen(x)]))
-
-/**
- * Structure for the private Xvid context.
- * This stores all the private context for the codec.
- */
-struct xvid_context {
- void *encoder_handle; /**< Handle for Xvid encoder */
- int xsize; /**< Frame x size */
- int ysize; /**< Frame y size */
- int vop_flags; /**< VOP flags for Xvid encoder */
- int vol_flags; /**< VOL flags for Xvid encoder */
- int me_flags; /**< Motion Estimation flags */
- int qscale; /**< Do we use constant scale? */
- int quicktime_format; /**< Are we in a QT-based format? */
- AVFrame encoded_picture; /**< Encoded frame information */
- char *twopassbuffer; /**< Character buffer for two-pass */
- char *old_twopassbuffer; /**< Old character buffer (two-pass) */
- char *twopassfile; /**< second pass temp file name */
- unsigned char *intra_matrix; /**< P-Frame Quant Matrix */
- unsigned char *inter_matrix; /**< I-Frame Quant Matrix */
-};
-
-/**
- * Structure for the private first-pass plugin.
- */
-struct xvid_ff_pass1 {
- int version; /**< Xvid version */
- struct xvid_context *context; /**< Pointer to private context */
-};
-
-/*
- * Xvid 2-Pass Kludge Section
- *
- * Xvid's default 2-pass doesn't allow us to create data as we need to, so
- * this section spends time replacing the first pass plugin so we can write
- * statistic information as libavcodec requests in. We have another kludge
- * that allows us to pass data to the second pass in Xvid without a custom
- * rate-control plugin.
- */
-
-/* Wrapper to work around the lack of mkstemp() on mingw.
- * Also, tries to create file in /tmp first, if possible.
- * *prefix can be a character constant; *filename will be allocated internally.
- * @return file descriptor of opened file (or -1 on error)
- * and opened file name in **filename. */
-int ff_tempfile(const char *prefix, char **filename) {
- int fd=-1;
-#if !HAVE_MKSTEMP
- *filename = tempnam(".", prefix);
-#else
- size_t len = strlen(prefix) + 12; /* room for "/tmp/" and "XXXXXX\0" */
- *filename = av_malloc(len);
-#endif
- /* -----common section-----*/
- if (*filename == NULL) {
- av_log(NULL, AV_LOG_ERROR, "ff_tempfile: Cannot allocate file name\n");
- return -1;
- }
-#if !HAVE_MKSTEMP
- fd = open(*filename, O_RDWR | O_BINARY | O_CREAT, 0444);
-#else
- snprintf(*filename, len, "/tmp/%sXXXXXX", prefix);
- fd = mkstemp(*filename);
- if (fd < 0) {
- snprintf(*filename, len, "./%sXXXXXX", prefix);
- fd = mkstemp(*filename);
- }
-#endif
- /* -----common section-----*/
- if (fd < 0) {
- av_log(NULL, AV_LOG_ERROR, "ff_tempfile: Cannot open temporary file %s\n", *filename);
- return -1;
- }
- return fd; /* success */
-}
-
-/**
- * Initialize the two-pass plugin and context.
- *
- * @param param Input construction parameter structure
- * @param handle Private context handle
- * @return Returns XVID_ERR_xxxx on failure, or 0 on success.
- */
-static int xvid_ff_2pass_create(xvid_plg_create_t * param,
- void ** handle) {
- struct xvid_ff_pass1 *x = (struct xvid_ff_pass1 *)param->param;
- char *log = x->context->twopassbuffer;
-
- /* Do a quick bounds check */
- if( log == NULL )
- return XVID_ERR_FAIL;
-
- /* We use snprintf() */
- /* This is because we can safely prevent a buffer overflow */
- log[0] = 0;
- snprintf(log, BUFFER_REMAINING(log),
- "# avconv 2-pass log file, using xvid codec\n");
- snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log),
- "# Do not modify. libxvidcore version: %d.%d.%d\n\n",
- XVID_VERSION_MAJOR(XVID_VERSION),
- XVID_VERSION_MINOR(XVID_VERSION),
- XVID_VERSION_PATCH(XVID_VERSION));
-
- *handle = x->context;
- return 0;
-}
-
-/**
- * Destroy the two-pass plugin context.
- *
- * @param ref Context pointer for the plugin
- * @param param Destrooy context
- * @return Returns 0, success guaranteed
- */
-static int xvid_ff_2pass_destroy(struct xvid_context *ref,
- xvid_plg_destroy_t *param) {
- /* Currently cannot think of anything to do on destruction */
- /* Still, the framework should be here for reference/use */
- if( ref->twopassbuffer != NULL )
- ref->twopassbuffer[0] = 0;
- return 0;
-}
-
-/**
- * Enable fast encode mode during the first pass.
- *
- * @param ref Context pointer for the plugin
- * @param param Frame data
- * @return Returns 0, success guaranteed
- */
-static int xvid_ff_2pass_before(struct xvid_context *ref,
- xvid_plg_data_t *param) {
- int motion_remove;
- int motion_replacements;
- int vop_remove;
-
- /* Nothing to do here, result is changed too much */
- if( param->zone && param->zone->mode == XVID_ZONE_QUANT )
- return 0;
-
- /* We can implement a 'turbo' first pass mode here */
- param->quant = 2;
-
- /* Init values */
- motion_remove = ~XVID_ME_CHROMA_PVOP &
- ~XVID_ME_CHROMA_BVOP &
- ~XVID_ME_EXTSEARCH16 &
- ~XVID_ME_ADVANCEDDIAMOND16;
- motion_replacements = XVID_ME_FAST_MODEINTERPOLATE |
- XVID_ME_SKIP_DELTASEARCH |
- XVID_ME_FASTREFINE16 |
- XVID_ME_BFRAME_EARLYSTOP;
- vop_remove = ~XVID_VOP_MODEDECISION_RD &
- ~XVID_VOP_FAST_MODEDECISION_RD &
- ~XVID_VOP_TRELLISQUANT &
- ~XVID_VOP_INTER4V &
- ~XVID_VOP_HQACPRED;
-
- param->vol_flags &= ~XVID_VOL_GMC;
- param->vop_flags &= vop_remove;
- param->motion_flags &= motion_remove;
- param->motion_flags |= motion_replacements;
-
- return 0;
-}
-
-/**
- * Capture statistic data and write it during first pass.
- *
- * @param ref Context pointer for the plugin
- * @param param Statistic data
- * @return Returns XVID_ERR_xxxx on failure, or 0 on success
- */
-static int xvid_ff_2pass_after(struct xvid_context *ref,
- xvid_plg_data_t *param) {
- char *log = ref->twopassbuffer;
- const char *frame_types = " ipbs";
- char frame_type;
-
- /* Quick bounds check */
- if( log == NULL )
- return XVID_ERR_FAIL;
-
- /* Convert the type given to us into a character */
- if( param->type < 5 && param->type > 0 ) {
- frame_type = frame_types[param->type];
- } else {
- return XVID_ERR_FAIL;
- }
-
- snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log),
- "%c %d %d %d %d %d %d\n",
- frame_type, param->stats.quant, param->stats.kblks, param->stats.mblks,
- param->stats.ublks, param->stats.length, param->stats.hlength);
-
- return 0;
-}
-
-/**
- * Dispatch function for our custom plugin.
- * This handles the dispatch for the Xvid plugin. It passes data
- * on to other functions for actual processing.
- *
- * @param ref Context pointer for the plugin
- * @param cmd The task given for us to complete
- * @param p1 First parameter (varies)
- * @param p2 Second parameter (varies)
- * @return Returns XVID_ERR_xxxx on failure, or 0 on success
- */
-static int xvid_ff_2pass(void *ref, int cmd, void *p1, void *p2)
-{
- switch( cmd ) {
- case XVID_PLG_INFO:
- case XVID_PLG_FRAME:
- return 0;
-
- case XVID_PLG_BEFORE:
- return xvid_ff_2pass_before(ref, p1);
-
- case XVID_PLG_CREATE:
- return xvid_ff_2pass_create(p1, p2);
-
- case XVID_PLG_AFTER:
- return xvid_ff_2pass_after(ref, p1);
-
- case XVID_PLG_DESTROY:
- return xvid_ff_2pass_destroy(ref, p1);
-
- default:
- return XVID_ERR_FAIL;
- }
-}
-
-/**
- * Routine to create a global VO/VOL header for MP4 container.
- * What we do here is extract the header from the Xvid bitstream
- * as it is encoded. We also strip the repeated headers from the
- * bitstream when a global header is requested for MPEG-4 ISO
- * compliance.
- *
- * @param avctx AVCodecContext pointer to context
- * @param frame Pointer to encoded frame data
- * @param header_len Length of header to search
- * @param frame_len Length of encoded frame data
- * @return Returns new length of frame data
- */
-static int xvid_strip_vol_header(AVCodecContext *avctx,
- AVPacket *pkt,
- unsigned int header_len,
- unsigned int frame_len) {
- int vo_len = 0, i;
-
- for( i = 0; i < header_len - 3; i++ ) {
- if( pkt->data[i] == 0x00 &&
- pkt->data[i+1] == 0x00 &&
- pkt->data[i+2] == 0x01 &&
- pkt->data[i+3] == 0xB6 ) {
- vo_len = i;
- break;
- }
- }
-
- if( vo_len > 0 ) {
- /* We need to store the header, so extract it */
- if( avctx->extradata == NULL ) {
- avctx->extradata = av_malloc(vo_len);
- memcpy(avctx->extradata, pkt->data, vo_len);
- avctx->extradata_size = vo_len;
- }
- /* Less dangerous now, memmove properly copies the two
- chunks of overlapping data */
- memmove(pkt->data, &pkt->data[vo_len], frame_len - vo_len);
- pkt->size = frame_len - vo_len;
- }
- return 0;
-}
-
-/**
- * Routine to correct a possibly erroneous framerate being fed to us.
- * Xvid currently chokes on framerates where the ticks per frame is
- * extremely large. This function works to correct problems in this area
- * by estimating a new framerate and taking the simpler fraction of
- * the two presented.
- *
- * @param avctx Context that contains the framerate to correct.
- */
-static void xvid_correct_framerate(AVCodecContext *avctx)
-{
- int frate, fbase;
- int est_frate, est_fbase;
- int gcd;
- float est_fps, fps;
-
- frate = avctx->time_base.den;
- fbase = avctx->time_base.num;
-
- gcd = av_gcd(frate, fbase);
- if( gcd > 1 ) {
- frate /= gcd;
- fbase /= gcd;
- }
-
- if( frate <= 65000 && fbase <= 65000 ) {
- avctx->time_base.den = frate;
- avctx->time_base.num = fbase;
- return;
- }
-
- fps = (float)frate / (float)fbase;
- est_fps = roundf(fps * 1000.0) / 1000.0;
-
- est_frate = (int)est_fps;
- if( est_fps > (int)est_fps ) {
- est_frate = (est_frate + 1) * 1000;
- est_fbase = (int)roundf((float)est_frate / est_fps);
- } else
- est_fbase = 1;
-
- gcd = av_gcd(est_frate, est_fbase);
- if( gcd > 1 ) {
- est_frate /= gcd;
- est_fbase /= gcd;
- }
-
- if( fbase > est_fbase ) {
- avctx->time_base.den = est_frate;
- avctx->time_base.num = est_fbase;
- av_log(avctx, AV_LOG_DEBUG,
- "Xvid: framerate re-estimated: %.2f, %.3f%% correction\n",
- est_fps, (((est_fps - fps)/fps) * 100.0));
- } else {
- avctx->time_base.den = frate;
- avctx->time_base.num = fbase;
- }
-}
-
-/**
- * Create the private context for the encoder.
- * All buffers are allocated, settings are loaded from the user,
- * and the encoder context created.
- *
- * @param avctx AVCodecContext pointer to context
- * @return Returns 0 on success, -1 on failure
- */
-static av_cold int xvid_encode_init(AVCodecContext *avctx) {
- int xerr, i;
- int xvid_flags = avctx->flags;
- struct xvid_context *x = avctx->priv_data;
- uint16_t *intra, *inter;
- int fd;
-
- xvid_plugin_single_t single = { 0 };
- struct xvid_ff_pass1 rc2pass1 = { 0 };
- xvid_plugin_2pass2_t rc2pass2 = { 0 };
- xvid_gbl_init_t xvid_gbl_init = { 0 };
- xvid_enc_create_t xvid_enc_create = { 0 };
- xvid_enc_plugin_t plugins[7];
-
- /* Bring in VOP flags from avconv command-line */
- x->vop_flags = XVID_VOP_HALFPEL; /* Bare minimum quality */
- if( xvid_flags & CODEC_FLAG_4MV )
- x->vop_flags |= XVID_VOP_INTER4V; /* Level 3 */
- if( avctx->trellis
- )
- x->vop_flags |= XVID_VOP_TRELLISQUANT; /* Level 5 */
- if( xvid_flags & CODEC_FLAG_AC_PRED )
- x->vop_flags |= XVID_VOP_HQACPRED; /* Level 6 */
- if( xvid_flags & CODEC_FLAG_GRAY )
- x->vop_flags |= XVID_VOP_GREYSCALE;
-
- /* Decide which ME quality setting to use */
- x->me_flags = 0;
- switch( avctx->me_method ) {
- case ME_FULL: /* Quality 6 */
- x->me_flags |= XVID_ME_EXTSEARCH16
- | XVID_ME_EXTSEARCH8;
-
- case ME_EPZS: /* Quality 4 */
- x->me_flags |= XVID_ME_ADVANCEDDIAMOND8
- | XVID_ME_HALFPELREFINE8
- | XVID_ME_CHROMA_PVOP
- | XVID_ME_CHROMA_BVOP;
-
- case ME_LOG: /* Quality 2 */
- case ME_PHODS:
- case ME_X1:
- x->me_flags |= XVID_ME_ADVANCEDDIAMOND16
- | XVID_ME_HALFPELREFINE16;
-
- case ME_ZERO: /* Quality 0 */
- default:
- break;
- }
-
- /* Decide how we should decide blocks */
- switch( avctx->mb_decision ) {
- case 2:
- x->vop_flags |= XVID_VOP_MODEDECISION_RD;
- x->me_flags |= XVID_ME_HALFPELREFINE8_RD
- | XVID_ME_QUARTERPELREFINE8_RD
- | XVID_ME_EXTSEARCH_RD
- | XVID_ME_CHECKPREDICTION_RD;
- case 1:
- if( !(x->vop_flags & XVID_VOP_MODEDECISION_RD) )
- x->vop_flags |= XVID_VOP_FAST_MODEDECISION_RD;
- x->me_flags |= XVID_ME_HALFPELREFINE16_RD
- | XVID_ME_QUARTERPELREFINE16_RD;
-
- default:
- break;
- }
-
- /* Bring in VOL flags from avconv command-line */
- x->vol_flags = 0;
- if( xvid_flags & CODEC_FLAG_GMC ) {
- x->vol_flags |= XVID_VOL_GMC;
- x->me_flags |= XVID_ME_GME_REFINE;
- }
- if( xvid_flags & CODEC_FLAG_QPEL ) {
- x->vol_flags |= XVID_VOL_QUARTERPEL;
- x->me_flags |= XVID_ME_QUARTERPELREFINE16;
- if( x->vop_flags & XVID_VOP_INTER4V )
- x->me_flags |= XVID_ME_QUARTERPELREFINE8;
- }
-
- xvid_gbl_init.version = XVID_VERSION;
- xvid_gbl_init.debug = 0;
-
-#if ARCH_PPC
- /* Xvid's PPC support is borked, use libavcodec to detect */
-#if HAVE_ALTIVEC
- if (av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) {
- xvid_gbl_init.cpu_flags = XVID_CPU_FORCE | XVID_CPU_ALTIVEC;
- } else
-#endif
- xvid_gbl_init.cpu_flags = XVID_CPU_FORCE;
-#else
- /* Xvid can detect on x86 */
- xvid_gbl_init.cpu_flags = 0;
-#endif
-
- /* Initialize */
- xvid_global(NULL, XVID_GBL_INIT, &xvid_gbl_init, NULL);
-
- /* Create the encoder reference */
- xvid_enc_create.version = XVID_VERSION;
-
- /* Store the desired frame size */
- xvid_enc_create.width = x->xsize = avctx->width;
- xvid_enc_create.height = x->ysize = avctx->height;
-
- /* Xvid can determine the proper profile to use */
- /* xvid_enc_create.profile = XVID_PROFILE_S_L3; */
-
- /* We don't use zones */
- xvid_enc_create.zones = NULL;
- xvid_enc_create.num_zones = 0;
-
- xvid_enc_create.num_threads = avctx->thread_count;
-
- xvid_enc_create.plugins = plugins;
- xvid_enc_create.num_plugins = 0;
-
- /* Initialize Buffers */
- x->twopassbuffer = NULL;
- x->old_twopassbuffer = NULL;
- x->twopassfile = NULL;
-
- if( xvid_flags & CODEC_FLAG_PASS1 ) {
- rc2pass1.version = XVID_VERSION;
- rc2pass1.context = x;
- x->twopassbuffer = av_malloc(BUFFER_SIZE);
- x->old_twopassbuffer = av_malloc(BUFFER_SIZE);
- if( x->twopassbuffer == NULL || x->old_twopassbuffer == NULL ) {
- av_log(avctx, AV_LOG_ERROR,
- "Xvid: Cannot allocate 2-pass log buffers\n");
- return -1;
- }
- x->twopassbuffer[0] = x->old_twopassbuffer[0] = 0;
-
- plugins[xvid_enc_create.num_plugins].func = xvid_ff_2pass;
- plugins[xvid_enc_create.num_plugins].param = &rc2pass1;
- xvid_enc_create.num_plugins++;
- } else if( xvid_flags & CODEC_FLAG_PASS2 ) {
- rc2pass2.version = XVID_VERSION;
- rc2pass2.bitrate = avctx->bit_rate;
-
- fd = ff_tempfile("xvidff.", &x->twopassfile);
- if( fd == -1 ) {
- av_log(avctx, AV_LOG_ERROR,
- "Xvid: Cannot write 2-pass pipe\n");
- return -1;
- }
-
- if( avctx->stats_in == NULL ) {
- av_log(avctx, AV_LOG_ERROR,
- "Xvid: No 2-pass information loaded for second pass\n");
- return -1;
- }
-
- if( strlen(avctx->stats_in) >
- write(fd, avctx->stats_in, strlen(avctx->stats_in)) ) {
- close(fd);
- av_log(avctx, AV_LOG_ERROR,
- "Xvid: Cannot write to 2-pass pipe\n");
- return -1;
- }
-
- close(fd);
- rc2pass2.filename = x->twopassfile;
- plugins[xvid_enc_create.num_plugins].func = xvid_plugin_2pass2;
- plugins[xvid_enc_create.num_plugins].param = &rc2pass2;
- xvid_enc_create.num_plugins++;
- } else if( !(xvid_flags & CODEC_FLAG_QSCALE) ) {
- /* Single Pass Bitrate Control! */
- single.version = XVID_VERSION;
- single.bitrate = avctx->bit_rate;
-
- plugins[xvid_enc_create.num_plugins].func = xvid_plugin_single;
- plugins[xvid_enc_create.num_plugins].param = &single;
- xvid_enc_create.num_plugins++;
- }
-
- /* Luminance Masking */
- if( 0.0 != avctx->lumi_masking ) {
- plugins[xvid_enc_create.num_plugins].func = xvid_plugin_lumimasking;
- plugins[xvid_enc_create.num_plugins].param = NULL;
- xvid_enc_create.num_plugins++;
- }
-
- /* Frame Rate and Key Frames */
- xvid_correct_framerate(avctx);
- xvid_enc_create.fincr = avctx->time_base.num;
- xvid_enc_create.fbase = avctx->time_base.den;
- if( avctx->gop_size > 0 )
- xvid_enc_create.max_key_interval = avctx->gop_size;
- else
- xvid_enc_create.max_key_interval = 240; /* Xvid's best default */
-
- /* Quants */
- if( xvid_flags & CODEC_FLAG_QSCALE ) x->qscale = 1;
- else x->qscale = 0;
-
- xvid_enc_create.min_quant[0] = avctx->qmin;
- xvid_enc_create.min_quant[1] = avctx->qmin;
- xvid_enc_create.min_quant[2] = avctx->qmin;
- xvid_enc_create.max_quant[0] = avctx->qmax;
- xvid_enc_create.max_quant[1] = avctx->qmax;
- xvid_enc_create.max_quant[2] = avctx->qmax;
-
- /* Quant Matrices */
- x->intra_matrix = x->inter_matrix = NULL;
- if( avctx->mpeg_quant )
- x->vol_flags |= XVID_VOL_MPEGQUANT;
- if( (avctx->intra_matrix || avctx->inter_matrix) ) {
- x->vol_flags |= XVID_VOL_MPEGQUANT;
-
- if( avctx->intra_matrix ) {
- intra = avctx->intra_matrix;
- x->intra_matrix = av_malloc(sizeof(unsigned char) * 64);
- } else
- intra = NULL;
- if( avctx->inter_matrix ) {
- inter = avctx->inter_matrix;
- x->inter_matrix = av_malloc(sizeof(unsigned char) * 64);
- } else
- inter = NULL;
-
- for( i = 0; i < 64; i++ ) {
- if( intra )
- x->intra_matrix[i] = (unsigned char)intra[i];
- if( inter )
- x->inter_matrix[i] = (unsigned char)inter[i];
- }
- }
-
- /* Misc Settings */
- xvid_enc_create.frame_drop_ratio = 0;
- xvid_enc_create.global = 0;
- if( xvid_flags & CODEC_FLAG_CLOSED_GOP )
- xvid_enc_create.global |= XVID_GLOBAL_CLOSED_GOP;
-
- /* Determines which codec mode we are operating in */
- avctx->extradata = NULL;
- avctx->extradata_size = 0;
- if( xvid_flags & CODEC_FLAG_GLOBAL_HEADER ) {
- /* In this case, we are claiming to be MPEG4 */
- x->quicktime_format = 1;
- avctx->codec_id = CODEC_ID_MPEG4;
- } else {
- /* We are claiming to be Xvid */
- x->quicktime_format = 0;
- if(!avctx->codec_tag)
- avctx->codec_tag = AV_RL32("xvid");
- }
-
- /* Bframes */
- xvid_enc_create.max_bframes = avctx->max_b_frames;
- xvid_enc_create.bquant_offset = 100 * avctx->b_quant_offset;
- xvid_enc_create.bquant_ratio = 100 * avctx->b_quant_factor;
- if( avctx->max_b_frames > 0 && !x->quicktime_format ) xvid_enc_create.global |= XVID_GLOBAL_PACKED;
-
- /* Create encoder context */
- xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL);
- if( xerr ) {
- av_log(avctx, AV_LOG_ERROR, "Xvid: Could not create encoder reference\n");
- return -1;
- }
-
- x->encoder_handle = xvid_enc_create.handle;
- avctx->coded_frame = &x->encoded_picture;
-
- return 0;
-}
-
-/**
- * Encode a single frame.
- *
- * @param avctx AVCodecContext pointer to context
- * @param frame Pointer to encoded frame buffer
- * @param buf_size Size of encoded frame buffer
- * @param data Pointer to AVFrame of unencoded frame
- * @return Returns 0 on success, -1 on failure
- */
-static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
- const AVFrame *picture, int *got_packet)
-{
- int xerr, i, ret, user_packet = !!pkt->data;
- char *tmp;
- struct xvid_context *x = avctx->priv_data;
- AVFrame *p = &x->encoded_picture;
- int mb_width = (avctx->width + 15) / 16;
- int mb_height = (avctx->height + 15) / 16;
-
- xvid_enc_frame_t xvid_enc_frame = { 0 };
- xvid_enc_stats_t xvid_enc_stats = { 0 };
-
- if (!user_packet &&
- (ret = av_new_packet(pkt, mb_width*mb_height*MAX_MB_BYTES + FF_MIN_BUFFER_SIZE)) < 0) {
- av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
- return ret;
- }
-
- /* Start setting up the frame */
- xvid_enc_frame.version = XVID_VERSION;
- xvid_enc_stats.version = XVID_VERSION;
- *p = *picture;
-
- /* Let Xvid know where to put the frame. */
- xvid_enc_frame.bitstream = pkt->data;
- xvid_enc_frame.length = pkt->size;
-
- /* Initialize input image fields */
- if( avctx->pix_fmt != PIX_FMT_YUV420P ) {
- av_log(avctx, AV_LOG_ERROR, "Xvid: Color spaces other than 420p not supported\n");
- return -1;
- }
-
- xvid_enc_frame.input.csp = XVID_CSP_PLANAR; /* YUV420P */
-
- for( i = 0; i < 4; i++ ) {
- xvid_enc_frame.input.plane[i] = picture->data[i];
- xvid_enc_frame.input.stride[i] = picture->linesize[i];
- }
-
- /* Encoder Flags */
- xvid_enc_frame.vop_flags = x->vop_flags;
- xvid_enc_frame.vol_flags = x->vol_flags;
- xvid_enc_frame.motion = x->me_flags;
- xvid_enc_frame.type =
- picture->pict_type == AV_PICTURE_TYPE_I ? XVID_TYPE_IVOP :
- picture->pict_type == AV_PICTURE_TYPE_P ? XVID_TYPE_PVOP :
- picture->pict_type == AV_PICTURE_TYPE_B ? XVID_TYPE_BVOP :
- XVID_TYPE_AUTO;
-
- /* Pixel aspect ratio setting */
- if (avctx->sample_aspect_ratio.num < 1 || avctx->sample_aspect_ratio.num > 255 ||
- avctx->sample_aspect_ratio.den < 1 || avctx->sample_aspect_ratio.den > 255) {
- av_log(avctx, AV_LOG_ERROR, "Invalid pixel aspect ratio %i/%i\n",
- avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den);
- return -1;
- }
- xvid_enc_frame.par = XVID_PAR_EXT;
- xvid_enc_frame.par_width = avctx->sample_aspect_ratio.num;
- xvid_enc_frame.par_height = avctx->sample_aspect_ratio.den;
-
- /* Quant Setting */
- if( x->qscale ) xvid_enc_frame.quant = picture->quality / FF_QP2LAMBDA;
- else xvid_enc_frame.quant = 0;
-
- /* Matrices */
- xvid_enc_frame.quant_intra_matrix = x->intra_matrix;
- xvid_enc_frame.quant_inter_matrix = x->inter_matrix;
-
- /* Encode */
- xerr = xvid_encore(x->encoder_handle, XVID_ENC_ENCODE,
- &xvid_enc_frame, &xvid_enc_stats);
-
- /* Two-pass log buffer swapping */
- avctx->stats_out = NULL;
- if( x->twopassbuffer ) {
- tmp = x->old_twopassbuffer;
- x->old_twopassbuffer = x->twopassbuffer;
- x->twopassbuffer = tmp;
- x->twopassbuffer[0] = 0;
- if( x->old_twopassbuffer[0] != 0 ) {
- avctx->stats_out = x->old_twopassbuffer;
- }
- }
-
- if (xerr > 0) {
- *got_packet = 1;
-
- p->quality = xvid_enc_stats.quant * FF_QP2LAMBDA;
- if( xvid_enc_stats.type == XVID_TYPE_PVOP )
- p->pict_type = AV_PICTURE_TYPE_P;
- else if( xvid_enc_stats.type == XVID_TYPE_BVOP )
- p->pict_type = AV_PICTURE_TYPE_B;
- else if( xvid_enc_stats.type == XVID_TYPE_SVOP )
- p->pict_type = AV_PICTURE_TYPE_S;
- else
- p->pict_type = AV_PICTURE_TYPE_I;
- if( xvid_enc_frame.out_flags & XVID_KEYFRAME ) {
- p->key_frame = 1;
- pkt->flags |= AV_PKT_FLAG_KEY;
- if( x->quicktime_format )
- return xvid_strip_vol_header(avctx, pkt,
- xvid_enc_stats.hlength, xerr);
- } else
- p->key_frame = 0;
-
- pkt->size = xerr;
-
- return 0;
- } else {
- if (!user_packet)
- av_free_packet(pkt);
- if (!xerr)
- return 0;
- av_log(avctx, AV_LOG_ERROR, "Xvid: Encoding Error Occurred: %i\n", xerr);
- return -1;
- }
-}
-
-/**
- * Destroy the private context for the encoder.
- * All buffers are freed, and the Xvid encoder context is destroyed.
- *
- * @param avctx AVCodecContext pointer to context
- * @return Returns 0, success guaranteed
- */
-static av_cold int xvid_encode_close(AVCodecContext *avctx) {
- struct xvid_context *x = avctx->priv_data;
-
- xvid_encore(x->encoder_handle, XVID_ENC_DESTROY, NULL, NULL);
-
- av_freep(&avctx->extradata);
- if( x->twopassbuffer != NULL ) {
- av_free(x->twopassbuffer);
- av_free(x->old_twopassbuffer);
- }
- av_free(x->twopassfile);
- av_free(x->intra_matrix);
- av_free(x->inter_matrix);
-
- return 0;
-}
-
-/**
- * Xvid codec definition for libavcodec.
- */
-AVCodec ff_libxvid_encoder = {
- .name = "libxvid",
- .type = AVMEDIA_TYPE_VIDEO,
- .id = CODEC_ID_MPEG4,
- .priv_data_size = sizeof(struct xvid_context),
- .init = xvid_encode_init,
- .encode2 = xvid_encode_frame,
- .close = xvid_encode_close,
- .pix_fmts = (const enum PixelFormat[]){ PIX_FMT_YUV420P, PIX_FMT_NONE },
- .long_name = NULL_IF_CONFIG_SMALL("libxvidcore MPEG-4 part 2"),
-};
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 8552ec1..7864d38 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -301,9 +301,7 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
s->first_picture = 0;
}
- if (s->interlaced && (s->bottom_field == !s->interlace_polarity))
- return 0;
-
+ if (!(s->interlaced && (s->bottom_field == !s->interlace_polarity))) {
/* XXX: not complete test ! */
pix_fmt_id = (s->h_count[0] << 28) | (s->v_count[0] << 24) |
(s->h_count[1] << 20) | (s->v_count[1] << 16) |
@@ -370,6 +368,7 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
if (len != (8 + (3 * nb_components)))
av_log(s->avctx, AV_LOG_DEBUG, "decode_sof0: error, len(%d) mismatch\n", len);
+ }
/* totally blank picture as progressive JPEG will only add details to it */
if (s->progressive) {
diff --git a/libavcodec/mmvideo.c b/libavcodec/mmvideo.c
index 6c81fd4..1a9dfdd 100644
--- a/libavcodec/mmvideo.c
+++ b/libavcodec/mmvideo.c
@@ -84,8 +84,7 @@ static int mm_decode_pal(MmContext *s)
*/
static int mm_decode_intra(MmContext * s, int half_horiz, int half_vert)
{
- int i, x, y;
- i=0; x=0; y=0;
+ int x = 0, y = 0;
while (bytestream2_get_bytes_left(&s->gb) > 0) {
int run_length, color;
diff --git a/libavcodec/motion-test.c b/libavcodec/motion-test.c
index a22cb1e..bf63182 100644
--- a/libavcodec/motion-test.c
+++ b/libavcodec/motion-test.c
@@ -32,6 +32,7 @@
#include "config.h"
#include "dsputil.h"
#include "libavutil/lfg.h"
+#include "libavutil/time.h"
#undef printf
@@ -48,11 +49,7 @@ static void fill_random(uint8_t *tab, int size)
av_lfg_init(&prng, 1);
for(i=0;i<size;i++) {
-#if 1
tab[i] = av_lfg_get(&prng) % 256;
-#else
- tab[i] = i;
-#endif
}
}
@@ -62,13 +59,6 @@ static void help(void)
"test motion implementations\n");
}
-static int64_t gettime(void)
-{
- struct timeval tv;
- gettimeofday(&tv,NULL);
- return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
-}
-
#define NB_ITS 500
int dummy;
@@ -101,7 +91,7 @@ static void test_motion(const char *name,
emms_c();
/* speed test */
- ti = gettime();
+ ti = av_gettime();
d1 = 0;
for(it=0;it<NB_ITS;it++) {
for(y=0;y<HEIGHT-17;y++) {
@@ -113,7 +103,7 @@ static void test_motion(const char *name,
}
emms_c();
dummy = d1; /* avoid optimization */
- ti = gettime() - ti;
+ ti = av_gettime() - ti;
printf(" %0.0f kop/s\n",
(double)NB_ITS * (WIDTH - 16) * (HEIGHT - 16) /
diff --git a/libavcodec/motionpixels.c b/libavcodec/motionpixels.c
index 6151e6a..8a3c870 100644
--- a/libavcodec/motionpixels.c
+++ b/libavcodec/motionpixels.c
@@ -190,10 +190,13 @@ static void mp_decode_line(MotionPixelsContext *mp, GetBitContext *gb, int y)
p = mp_get_yuv_from_rgb(mp, x - 1, y);
} else {
p.y += mp_gradient(mp, 0, mp_get_vlc(mp, gb));
+ p.y = av_clip(p.y, 0, 31);
if ((x & 3) == 0) {
if ((y & 3) == 0) {
p.v += mp_gradient(mp, 1, mp_get_vlc(mp, gb));
+ p.v = av_clip(p.v, -32, 31);
p.u += mp_gradient(mp, 2, mp_get_vlc(mp, gb));
+ p.u = av_clip(p.u, -32, 31);
mp->hpt[((y / 4) * mp->avctx->width + x) / 4] = p;
} else {
p.v = mp->hpt[((y / 4) * mp->avctx->width + x) / 4].v;
@@ -217,9 +220,12 @@ static void mp_decode_frame_helper(MotionPixelsContext *mp, GetBitContext *gb)
p = mp_get_yuv_from_rgb(mp, 0, y);
} else {
p.y += mp_gradient(mp, 0, mp_get_vlc(mp, gb));
+ p.y = av_clip(p.y, 0, 31);
if ((y & 3) == 0) {
p.v += mp_gradient(mp, 1, mp_get_vlc(mp, gb));
+ p.v = av_clip(p.v, -32, 31);
p.u += mp_gradient(mp, 2, mp_get_vlc(mp, gb));
+ p.u = av_clip(p.u, -32, 31);
}
mp->vpt[y] = p;
mp_set_rgb_from_yuv(mp, 0, y, &p);
diff --git a/libavcodec/mpc8.c b/libavcodec/mpc8.c
index f682edb..f2e8342 100644
--- a/libavcodec/mpc8.c
+++ b/libavcodec/mpc8.c
@@ -270,7 +270,7 @@ static int mpc8_decode_frame(AVCodecContext * avctx, void *data,
maxband = c->last_max_band + get_vlc2(gb, band_vlc.table, MPC8_BANDS_BITS, 2);
if(maxband > 32) maxband -= 33;
}
- if(maxband > c->maxbands)
+ if(maxband > c->maxbands + 1)
return AVERROR_INVALIDDATA;
c->last_max_band = maxband;
@@ -405,7 +405,8 @@ static int mpc8_decode_frame(AVCodecContext * avctx, void *data,
}
}
- ff_mpc_dequantize_and_synth(c, maxband, c->frame.data[0], avctx->channels);
+ ff_mpc_dequantize_and_synth(c, maxband - 1, c->frame.data[0],
+ avctx->channels);
c->cur_frame++;
diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c
index 40ba97b..c40649d 100644
--- a/libavcodec/mpeg12.c
+++ b/libavcodec/mpeg12.c
@@ -2161,6 +2161,7 @@ int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size,
pc->frame_start_found = 4;
}
if (state == SEQ_END_CODE) {
+ pc->frame_start_found = 0;
pc->state=-1;
return i+1;
}
diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c
index f72e65c..6c1e8af 100644
--- a/libavcodec/mpegaudiodec.c
+++ b/libavcodec/mpegaudiodec.c
@@ -174,9 +174,12 @@ static void ff_region_offset2size(GranuleDef *g)
static void ff_init_short_region(MPADecodeContext *s, GranuleDef *g)
{
- if (g->block_type == 2)
- g->region_size[0] = (36 / 2);
- else {
+ if (g->block_type == 2) {
+ if (s->sample_rate_index != 8)
+ g->region_size[0] = (36 / 2);
+ else
+ g->region_size[0] = (72 / 2);
+ } else {
if (s->sample_rate_index <= 2)
g->region_size[0] = (36 / 2);
else if (s->sample_rate_index != 8)
@@ -201,14 +204,12 @@ static void ff_compute_band_indexes(MPADecodeContext *s, GranuleDef *g)
if (g->block_type == 2) {
if (g->switch_point) {
/* if switched mode, we handle the 36 first samples as
- long blocks. For 8000Hz, we handle the 48 first
- exponents as long blocks (XXX: check this!) */
+ long blocks. For 8000Hz, we handle the 72 first
+ exponents as long blocks */
if (s->sample_rate_index <= 2)
g->long_end = 8;
- else if (s->sample_rate_index != 8)
- g->long_end = 6;
else
- g->long_end = 4; /* 8000 Hz */
+ g->long_end = 6;
g->short_start = 2 + (s->sample_rate_index != 8);
} else {
@@ -1018,7 +1019,7 @@ static void reorder_block(MPADecodeContext *s, GranuleDef *g)
if (s->sample_rate_index != 8)
ptr = g->sb_hybrid + 36;
else
- ptr = g->sb_hybrid + 48;
+ ptr = g->sb_hybrid + 72;
} else {
ptr = g->sb_hybrid;
}
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index d1c4233..574893e 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -798,6 +798,11 @@ av_cold int ff_MPV_common_init(MpegEncContext *s)
FF_ALLOCZ_OR_GOTO(s->avctx, s->dct_offset,
2 * 64 * sizeof(uint16_t), fail);
}
+
+ FF_ALLOC_OR_GOTO(s->avctx, s->cplx_tab,
+ mb_array_size * sizeof(float), fail);
+ FF_ALLOC_OR_GOTO(s->avctx, s->bits_tab,
+ mb_array_size * sizeof(float), fail);
}
}
@@ -809,6 +814,8 @@ av_cold int ff_MPV_common_init(MpegEncContext *s)
}
if (s->width && s->height) {
+ FF_ALLOC_OR_GOTO(s->avctx, s->er_temp_buffer,
+ mb_array_size * sizeof(uint8_t), fail);
FF_ALLOCZ_OR_GOTO(s->avctx, s->error_status_table,
mb_array_size * sizeof(uint8_t), fail);
@@ -974,6 +981,7 @@ void ff_MPV_common_end(MpegEncContext *s)
av_freep(&s->avctx->stats_out);
av_freep(&s->ac_stats);
av_freep(&s->error_status_table);
+ av_freep(&s->er_temp_buffer);
av_freep(&s->mb_index2xy);
av_freep(&s->lambda_table);
av_freep(&s->q_intra_matrix);
@@ -983,6 +991,8 @@ void ff_MPV_common_end(MpegEncContext *s)
av_freep(&s->input_picture);
av_freep(&s->reordered_input_picture);
av_freep(&s->dct_offset);
+ av_freep(&s->cplx_tab);
+ av_freep(&s->bits_tab);
if (s->picture && !s->avctx->internal->is_copy) {
for (i = 0; i < s->picture_count; i++) {
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index b73da41..f5b20e6 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -696,6 +696,12 @@ typedef struct MpegEncContext {
int mpv_flags; ///< flags set by private options
int quantizer_noise_shaping;
+
+ /* error resilience stuff */
+ uint8_t *er_temp_buffer;
+
+ /* temp buffers for rate control */
+ float *cplx_tab, *bits_tab;
} MpegEncContext;
#define REBASE_PICTURE(pic, new_ctx, old_ctx) (pic ? \
diff --git a/libavcodec/mpegvideo_common.h b/libavcodec/mpegvideo_common.h
index ebf9c7d..0a73126 100644
--- a/libavcodec/mpegvideo_common.h
+++ b/libavcodec/mpegvideo_common.h
@@ -719,7 +719,8 @@ static av_always_inline void MPV_motion_internal(MpegEncContext *s,
0, 0, 0,
ref_picture, pix_op, qpix_op,
s->mv[dir][0][0], s->mv[dir][0][1], 16);
- }else if(!is_mpeg12 && (CONFIG_WMV2_DECODER || CONFIG_WMV2_ENCODER) && s->mspel){
+ } else if (!is_mpeg12 && (CONFIG_WMV2_DECODER || CONFIG_WMV2_ENCODER) &&
+ s->mspel && s->codec_id == CODEC_ID_WMV2) {
ff_mspel_motion(s, dest_y, dest_cb, dest_cr,
ref_picture, pix_op,
s->mv[dir][0][0], s->mv[dir][0][1], 16);
diff --git a/libavcodec/mss1.c b/libavcodec/mss1.c
new file mode 100644
index 0000000..523a961
--- /dev/null
+++ b/libavcodec/mss1.c
@@ -0,0 +1,851 @@
+/*
+ * Microsoft Screen 1 (aka Windows Media Video V7 Screen) decoder
+ * Copyright (c) 2012 Konstantin Shishkov
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Microsoft Screen 1 (aka Windows Media Video V7 Screen) decoder
+ */
+
+#include "libavutil/intfloat.h"
+#include "libavutil/intreadwrite.h"
+#include "avcodec.h"
+#include "get_bits.h"
+
+enum SplitMode {
+ SPLIT_VERT = 0,
+ SPLIT_HOR,
+ SPLIT_NONE
+};
+
+typedef struct ArithCoder {
+ int low, high, value;
+ GetBitContext *gb;
+} ArithCoder;
+
+#define MODEL_MIN_SYMS 2
+#define MODEL_MAX_SYMS 256
+#define THRESH_ADAPTIVE -1
+#define THRESH_LOW 15
+#define THRESH_HIGH 50
+
+typedef struct Model {
+ int cum_prob[MODEL_MAX_SYMS + 1];
+ int weights[MODEL_MAX_SYMS + 1];
+ int idx2sym[MODEL_MAX_SYMS + 1];
+ int sym2idx[MODEL_MAX_SYMS + 1];
+ int num_syms;
+ int thr_weight, threshold;
+} Model;
+
+static const int sec_order_sizes[4] = { 1, 7, 6, 1 };
+
+enum ContextDirection {
+ TOP_LEFT = 0,
+ TOP,
+ TOP_RIGHT,
+ LEFT
+};
+
+typedef struct PixContext {
+ int cache_size, num_syms;
+ uint8_t cache[12];
+ Model cache_model, full_model;
+ Model sec_models[4][8][4];
+} PixContext;
+
+typedef struct MSS1Context {
+ AVCodecContext *avctx;
+ AVFrame pic;
+ uint8_t *pic_start;
+ int pic_stride;
+ uint8_t *mask;
+ int mask_linesize;
+ uint32_t pal[256];
+ int free_colours;
+ Model intra_region, inter_region;
+ Model pivot, edge_mode, split_mode;
+ PixContext intra_pix_ctx, inter_pix_ctx;
+ int corrupted;
+} MSS1Context;
+
+static void arith_init(ArithCoder *c, GetBitContext *gb)
+{
+ c->low = 0;
+ c->high = 0xFFFF;
+ c->value = get_bits(gb, 16);
+ c->gb = gb;
+}
+
+static void arith_normalise(ArithCoder *c)
+{
+ for (;;) {
+ if (c->high >= 0x8000) {
+ if (c->low < 0x8000) {
+ if (c->low >= 0x4000 && c->high < 0xC000) {
+ c->value -= 0x4000;
+ c->low -= 0x4000;
+ c->high -= 0x4000;
+ } else {
+ return;
+ }
+ } else {
+ c->value -= 0x8000;
+ c->low -= 0x8000;
+ c->high -= 0x8000;
+ }
+ }
+ c->value <<= 1;
+ c->low <<= 1;
+ c->high <<= 1;
+ c->high |= 1;
+ c->value |= get_bits1(c->gb);
+ }
+}
+
+static int arith_get_bit(ArithCoder *c)
+{
+ int range = c->high - c->low + 1;
+ int bit = (((c->value - c->low) << 1) + 1) / range;
+
+ if (bit)
+ c->low += range >> 1;
+ else
+ c->high = c->low + (range >> 1) - 1;
+
+ arith_normalise(c);
+
+ return bit;
+}
+
+static int arith_get_bits(ArithCoder *c, int bits)
+{
+ int range = c->high - c->low + 1;
+ int val = (((c->value - c->low + 1) << bits) - 1) / range;
+ int prob = range * val;
+
+ c->high = ((prob + range) >> bits) + c->low - 1;
+ c->low += prob >> bits;
+
+ arith_normalise(c);
+
+ return val;
+}
+
+static int arith_get_number(ArithCoder *c, int mod_val)
+{
+ int range = c->high - c->low + 1;
+ int val = ((c->value - c->low + 1) * mod_val - 1) / range;
+ int prob = range * val;
+
+ c->high = (prob + range) / mod_val + c->low - 1;
+ c->low += prob / mod_val;
+
+ arith_normalise(c);
+
+ return val;
+}
+
+static int arith_get_prob(ArithCoder *c, int *probs)
+{
+ int range = c->high - c->low + 1;
+ int val = ((c->value - c->low + 1) * probs[0] - 1) / range;
+ int sym = 1;
+
+ while (probs[sym] > val)
+ sym++;
+
+ c->high = range * probs[sym - 1] / probs[0] + c->low - 1;
+ c->low += range * probs[sym] / probs[0];
+
+ return sym;
+}
+
+static int model_calc_threshold(Model *m)
+{
+ int thr;
+
+ if (m->thr_weight == -1) {
+ thr = 2 * m->weights[m->num_syms] - 1;
+ thr = ((thr >> 1) + 4 * m->cum_prob[0]) / thr;
+ } else {
+ thr = m->num_syms * m->thr_weight;
+ }
+
+ return FFMIN(thr, 0x3FFF);
+}
+
+static void model_reset(Model *m)
+{
+ int i;
+
+ for (i = 0; i <= m->num_syms; i++) {
+ m->weights[i] = 1;
+ m->cum_prob[i] = m->num_syms - i;
+ }
+ m->weights[0] = -1;
+ m->idx2sym[0] = -1;
+ m->sym2idx[m->num_syms] = -1;
+ for (i = 0; i < m->num_syms; i++) {
+ m->sym2idx[i] = i + 1;
+ m->idx2sym[i + 1] = i;
+ }
+}
+
+static av_cold void model_init(Model *m, int num_syms, int thr_weight)
+{
+ m->num_syms = num_syms;
+ m->thr_weight = thr_weight;
+ m->threshold = model_calc_threshold(m);
+ model_reset(m);
+}
+
+static void model_rescale_weights(Model *m)
+{
+ int i;
+ int cum_prob;
+
+ if (m->thr_weight == -1)
+ m->threshold = model_calc_threshold(m);
+ while (m->cum_prob[0] > m->threshold) {
+ cum_prob = 0;
+ for (i = m->num_syms; i >= 0; i--) {
+ m->cum_prob[i] = cum_prob;
+ m->weights[i] = (m->weights[i] + 1) >> 1;
+ cum_prob += m->weights[i];
+ }
+ }
+}
+
+static void model_update(Model *m, int val)
+{
+ int i;
+
+ if (m->weights[val] == m->weights[val - 1]) {
+ for (i = val; m->weights[i - 1] == m->weights[val]; i--);
+ if (i != val) {
+ int sym1, sym2;
+
+ sym1 = m->idx2sym[val];
+ sym2 = m->idx2sym[i];
+
+ m->idx2sym[val] = sym2;
+ m->idx2sym[i] = sym1;
+ m->sym2idx[sym1] = i;
+ m->sym2idx[sym2] = val;
+
+ val = i;
+ }
+ }
+ m->weights[val]++;
+ for (i = val - 1; i >= 0; i--)
+ m->cum_prob[i]++;
+ model_rescale_weights(m);
+}
+
+static int arith_get_model_sym(ArithCoder *c, Model *m)
+{
+ int idx, val;
+
+ idx = arith_get_prob(c, m->cum_prob);
+
+ val = m->idx2sym[idx];
+ model_update(m, idx);
+
+ arith_normalise(c);
+
+ return val;
+}
+
+static void pixctx_reset(PixContext *ctx)
+{
+ int i, j, k;
+
+ for (i = 0; i < ctx->cache_size; i++)
+ ctx->cache[i] = i;
+
+ model_reset(&ctx->cache_model);
+ model_reset(&ctx->full_model);
+
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < sec_order_sizes[i]; j++)
+ for (k = 0; k < 4; k++)
+ model_reset(&ctx->sec_models[i][j][k]);
+}
+
+static av_cold void pixctx_init(PixContext *ctx, int cache_size)
+{
+ int i, j, k;
+
+ ctx->cache_size = cache_size + 4;
+ ctx->num_syms = cache_size;
+
+ for (i = 0; i < ctx->cache_size; i++)
+ ctx->cache[i] = i;
+
+ model_init(&ctx->cache_model, ctx->num_syms + 1, THRESH_LOW);
+ model_init(&ctx->full_model, 256, THRESH_HIGH);
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < sec_order_sizes[i]; j++) {
+ for (k = 0; k < 4; k++) {
+ model_init(&ctx->sec_models[i][j][k], 2 + i,
+ i ? THRESH_LOW : THRESH_ADAPTIVE);
+ }
+ }
+ }
+}
+
+static int decode_top_left_pixel(ArithCoder *acoder, PixContext *pctx)
+{
+ int i, val, pix;
+
+ val = arith_get_model_sym(acoder, &pctx->cache_model);
+ if (val < pctx->num_syms) {
+ pix = pctx->cache[val];
+ } else {
+ pix = arith_get_model_sym(acoder, &pctx->full_model);
+ for (i = 0; i < pctx->cache_size - 1; i++)
+ if (pctx->cache[i] == pix)
+ break;
+ val = i;
+ }
+ if (val) {
+ for (i = val; i > 0; i--)
+ pctx->cache[i] = pctx->cache[i - 1];
+ pctx->cache[0] = pix;
+ }
+
+ return pix;
+}
+
+static int decode_pixel(ArithCoder *acoder, PixContext *pctx,
+ uint8_t *ngb, int num_ngb)
+{
+ int i, val, pix;
+
+ val = arith_get_model_sym(acoder, &pctx->cache_model);
+ if (val < pctx->num_syms) {
+ int idx, j;
+
+
+ idx = 0;
+ for (i = 0; i < pctx->cache_size; i++) {
+ for (j = 0; j < num_ngb; j++)
+ if (pctx->cache[i] == ngb[j])
+ break;
+ if (j == num_ngb) {
+ if (idx == val)
+ break;
+ idx++;
+ }
+ }
+ val = FFMIN(i, pctx->cache_size - 1);
+ pix = pctx->cache[val];
+ } else {
+ pix = arith_get_model_sym(acoder, &pctx->full_model);
+ for (i = 0; i < pctx->cache_size - 1; i++)
+ if (pctx->cache[i] == pix)
+ break;
+ val = i;
+ }
+ if (val) {
+ for (i = val; i > 0; i--)
+ pctx->cache[i] = pctx->cache[i - 1];
+ pctx->cache[0] = pix;
+ }
+
+ return pix;
+}
+
+static int decode_pixel_in_context(ArithCoder *acoder, PixContext *pctx,
+ uint8_t *src, int stride, int x, int y,
+ int has_right)
+{
+ uint8_t neighbours[4];
+ uint8_t ref_pix[4];
+ int nlen;
+ int layer = 0, sub;
+ int pix;
+ int i, j;
+
+ if (!y) {
+ memset(neighbours, src[-1], 4);
+ } else {
+ neighbours[TOP] = src[-stride];
+ if (!x) {
+ neighbours[TOP_LEFT] = neighbours[LEFT] = neighbours[TOP];
+ } else {
+ neighbours[TOP_LEFT] = src[-stride - 1];
+ neighbours[ LEFT] = src[-1];
+ }
+ if (has_right)
+ neighbours[TOP_RIGHT] = src[-stride + 1];
+ else
+ neighbours[TOP_RIGHT] = neighbours[TOP];
+ }
+
+ sub = 0;
+ if (x >= 2 && src[-2] == neighbours[LEFT])
+ sub = 1;
+ if (y >= 2 && src[-2 * stride] == neighbours[TOP])
+ sub |= 2;
+
+ nlen = 1;
+ ref_pix[0] = neighbours[0];
+ for (i = 1; i < 4; i++) {
+ for (j = 0; j < nlen; j++)
+ if (ref_pix[j] == neighbours[i])
+ break;
+ if (j == nlen)
+ ref_pix[nlen++] = neighbours[i];
+ }
+
+ switch (nlen) {
+ case 1:
+ case 4:
+ layer = 0;
+ break;
+ case 2:
+ if (neighbours[TOP] == neighbours[TOP_LEFT]) {
+ if (neighbours[TOP_RIGHT] == neighbours[TOP_LEFT])
+ layer = 3;
+ else if (neighbours[LEFT] == neighbours[TOP_LEFT])
+ layer = 2;
+ else
+ layer = 4;
+ } else if (neighbours[TOP_RIGHT] == neighbours[TOP_LEFT]) {
+ if (neighbours[LEFT] == neighbours[TOP_LEFT])
+ layer = 1;
+ else
+ layer = 5;
+ } else if (neighbours[LEFT] == neighbours[TOP_LEFT]) {
+ layer = 6;
+ } else {
+ layer = 0;
+ }
+ break;
+ case 3:
+ if (neighbours[TOP] == neighbours[TOP_LEFT])
+ layer = 0;
+ else if (neighbours[TOP_RIGHT] == neighbours[TOP_LEFT])
+ layer = 1;
+ else if (neighbours[LEFT] == neighbours[TOP_LEFT])
+ layer = 2;
+ else if (neighbours[TOP_RIGHT] == neighbours[TOP])
+ layer = 3;
+ else if (neighbours[TOP] == neighbours[LEFT])
+ layer = 4;
+ else
+ layer = 5;
+ break;
+ }
+
+ pix = arith_get_model_sym(acoder, &pctx->sec_models[nlen - 1][layer][sub]);
+ if (pix < nlen)
+ return ref_pix[pix];
+ else
+ return decode_pixel(acoder, pctx, ref_pix, nlen);
+}
+
+static int decode_region(MSS1Context *ctx, ArithCoder *acoder, uint8_t *dst,
+ int x, int y, int width, int height, int stride,
+ PixContext *pctx)
+{
+ int i, j;
+
+ dst += x + y * stride;
+
+ dst[0] = decode_top_left_pixel(acoder, pctx);
+ for (j = 0; j < height; j++) {
+ for (i = 0; i < width; i++) {
+ if (!i && !j)
+ continue;
+
+ dst[i] = decode_pixel_in_context(acoder, pctx, dst + i, stride,
+ i, j, width - i - 1);
+ }
+ dst += stride;
+ }
+
+ return 0;
+}
+
+static int decode_region_masked(MSS1Context *ctx, ArithCoder *acoder,
+ uint8_t *dst, int stride, uint8_t *mask,
+ int mask_stride, int x, int y,
+ int width, int height,
+ PixContext *pctx)
+{
+ int i, j;
+
+ dst += x + y * stride;
+ mask += x + y * mask_stride;
+
+ if (mask[0] != 0xFF)
+ dst[0] = decode_top_left_pixel(acoder, pctx);
+ for (j = 0; j < height; j++) {
+ for (i = 0; i < width; i++) {
+ if (!i && !j || mask[i] != 0xFF)
+ continue;
+
+ dst[i] = decode_pixel_in_context(acoder, pctx, dst + i, stride,
+ i, j, width - i - 1);
+ }
+ dst += stride;
+ mask += mask_stride;
+ }
+
+ return 0;
+}
+
+static av_cold void codec_init(MSS1Context *ctx)
+{
+ model_init(&ctx->intra_region, 2, THRESH_ADAPTIVE);
+ model_init(&ctx->inter_region, 2, THRESH_ADAPTIVE);
+ model_init(&ctx->split_mode, 3, THRESH_HIGH);
+ model_init(&ctx->edge_mode, 2, THRESH_HIGH);
+ model_init(&ctx->pivot, 3, THRESH_LOW);
+ pixctx_init(&ctx->intra_pix_ctx, 8);
+ pixctx_init(&ctx->inter_pix_ctx, 2);
+ ctx->corrupted = 1;
+}
+
+static void codec_reset(MSS1Context *ctx)
+{
+ model_reset(&ctx->intra_region);
+ model_reset(&ctx->inter_region);
+ model_reset(&ctx->split_mode);
+ model_reset(&ctx->edge_mode);
+ model_reset(&ctx->pivot);
+ pixctx_reset(&ctx->intra_pix_ctx);
+ pixctx_reset(&ctx->inter_pix_ctx);
+
+ ctx->corrupted = 0;
+}
+
+static int decode_pal(MSS1Context *ctx, ArithCoder *acoder)
+{
+ int i, ncol, r, g, b;
+ uint32_t *pal = ctx->pal + 256 - ctx->free_colours;
+
+ if (!ctx->free_colours)
+ return 0;
+
+ ncol = arith_get_number(acoder, ctx->free_colours + 1);
+ for (i = 0; i < ncol; i++) {
+ r = arith_get_bits(acoder, 8);
+ g = arith_get_bits(acoder, 8);
+ b = arith_get_bits(acoder, 8);
+ *pal++ = (r << 16) | (g << 8) | b;
+ }
+
+ return !!ncol;
+}
+
+static int decode_pivot(MSS1Context *ctx, ArithCoder *acoder, int base)
+{
+ int val, inv;
+
+ inv = arith_get_model_sym(acoder, &ctx->edge_mode);
+ val = arith_get_model_sym(acoder, &ctx->pivot) + 1;
+
+ if (val > 2) {
+ if ((base + 1) / 2 - 2 <= 0) {
+ ctx->corrupted = 1;
+ return 0;
+ }
+ val = arith_get_number(acoder, (base + 1) / 2 - 2) + 3;
+ }
+
+ if (val == base) {
+ ctx->corrupted = 1;
+ return 0;
+ }
+
+ return inv ? base - val : val;
+}
+
+static int decode_region_intra(MSS1Context *ctx, ArithCoder *acoder,
+ int x, int y, int width, int height)
+{
+ int mode;
+
+ mode = arith_get_model_sym(acoder, &ctx->intra_region);
+
+ if (!mode) {
+ int i, pix;
+ int stride = ctx->pic_stride;
+ uint8_t *dst = ctx->pic_start + x + y * stride;
+
+ pix = decode_top_left_pixel(acoder, &ctx->intra_pix_ctx);
+ for (i = 0; i < height; i++, dst += stride)
+ memset(dst, pix, width);
+ } else {
+ return decode_region(ctx, acoder, ctx->pic_start,
+ x, y, width, height, ctx->pic_stride,
+ &ctx->intra_pix_ctx);
+ }
+
+ return 0;
+}
+
+static int decode_intra(MSS1Context *ctx, ArithCoder *acoder,
+ int x, int y, int width, int height)
+{
+ int mode, pivot;
+
+ if (ctx->corrupted)
+ return -1;
+
+ mode = arith_get_model_sym(acoder, &ctx->split_mode);
+
+ switch (mode) {
+ case SPLIT_VERT:
+ pivot = decode_pivot(ctx, acoder, height);
+ if (ctx->corrupted)
+ return -1;
+ if (decode_intra(ctx, acoder, x, y, width, pivot))
+ return -1;
+ if (decode_intra(ctx, acoder, x, y + pivot, width, height - pivot))
+ return -1;
+ break;
+ case SPLIT_HOR:
+ pivot = decode_pivot(ctx, acoder, width);
+ if (ctx->corrupted)
+ return -1;
+ if (decode_intra(ctx, acoder, x, y, pivot, height))
+ return -1;
+ if (decode_intra(ctx, acoder, x + pivot, y, width - pivot, height))
+ return -1;
+ break;
+ case SPLIT_NONE:
+ return decode_region_intra(ctx, acoder, x, y, width, height);
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+static int decode_region_inter(MSS1Context *ctx, ArithCoder *acoder,
+ int x, int y, int width, int height)
+{
+ int mode;
+
+ mode = arith_get_model_sym(acoder, &ctx->inter_region);
+
+ if (!mode) {
+ mode = decode_top_left_pixel(acoder, &ctx->inter_pix_ctx);
+ if (mode != 0xFF) {
+ return 0;
+ } else {
+ return decode_region_intra(ctx, acoder, x, y, width, height);
+ }
+ } else {
+ if (decode_region(ctx, acoder, ctx->mask,
+ x, y, width, height, ctx->mask_linesize,
+ &ctx->inter_pix_ctx) < 0)
+ return -1;
+ return decode_region_masked(ctx, acoder, ctx->pic_start,
+ -ctx->pic.linesize[0], ctx->mask,
+ ctx->mask_linesize,
+ x, y, width, height,
+ &ctx->intra_pix_ctx);
+ }
+
+ return 0;
+}
+
+static int decode_inter(MSS1Context *ctx, ArithCoder *acoder,
+ int x, int y, int width, int height)
+{
+ int mode, pivot;
+
+ if (ctx->corrupted)
+ return -1;
+
+ mode = arith_get_model_sym(acoder, &ctx->split_mode);
+
+ switch (mode) {
+ case SPLIT_VERT:
+ pivot = decode_pivot(ctx, acoder, height);
+ if (decode_inter(ctx, acoder, x, y, width, pivot))
+ return -1;
+ if (decode_inter(ctx, acoder, x, y + pivot, width, height - pivot))
+ return -1;
+ break;
+ case SPLIT_HOR:
+ pivot = decode_pivot(ctx, acoder, width);
+ if (decode_inter(ctx, acoder, x, y, pivot, height))
+ return -1;
+ if (decode_inter(ctx, acoder, x + pivot, y, width - pivot, height))
+ return -1;
+ break;
+ case SPLIT_NONE:
+ return decode_region_inter(ctx, acoder, x, y, width, height);
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+static int mss1_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+ AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ MSS1Context *c = avctx->priv_data;
+ GetBitContext gb;
+ ArithCoder acoder;
+ int pal_changed = 0;
+ int ret;
+
+ init_get_bits(&gb, buf, buf_size * 8);
+ arith_init(&acoder, &gb);
+
+ c->pic.reference = 3;
+ c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
+ FF_BUFFER_HINTS_REUSABLE;
+ if ((ret = avctx->reget_buffer(avctx, &c->pic)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
+ return ret;
+ }
+
+ c->pic_start = c->pic.data[0] + c->pic.linesize[0] * (avctx->height - 1);
+ c->pic_stride = -c->pic.linesize[0];
+ if (!arith_get_bit(&acoder)) {
+ codec_reset(c);
+ pal_changed = decode_pal(c, &acoder);
+ c->corrupted = decode_intra(c, &acoder, 0, 0,
+ avctx->width, avctx->height);
+ c->pic.key_frame = 1;
+ c->pic.pict_type = AV_PICTURE_TYPE_I;
+ } else {
+ if (c->corrupted)
+ return AVERROR_INVALIDDATA;
+ c->corrupted = decode_inter(c, &acoder, 0, 0,
+ avctx->width, avctx->height);
+ c->pic.key_frame = 0;
+ c->pic.pict_type = AV_PICTURE_TYPE_P;
+ }
+ if (c->corrupted)
+ return AVERROR_INVALIDDATA;
+ memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE);
+ c->pic.palette_has_changed = pal_changed;
+
+ *data_size = sizeof(AVFrame);
+ *(AVFrame*)data = c->pic;
+
+ /* always report that the buffer was completely consumed */
+ return buf_size;
+}
+
+static av_cold int mss1_decode_init(AVCodecContext *avctx)
+{
+ MSS1Context * const c = avctx->priv_data;
+ int i;
+
+ c->avctx = avctx;
+
+ if (avctx->extradata_size < 52 + 256 * 3) {
+ av_log(avctx, AV_LOG_ERROR, "Insufficient extradata size %d\n",
+ avctx->extradata_size);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (AV_RB32(avctx->extradata) < avctx->extradata_size) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Insufficient extradata size: expected %d got %d\n",
+ AV_RB32(avctx->extradata),
+ avctx->extradata_size);
+ return AVERROR_INVALIDDATA;
+ }
+
+ av_log(avctx, AV_LOG_DEBUG, "Encoder version %d.%d\n",
+ AV_RB32(avctx->extradata + 4), AV_RB32(avctx->extradata + 8));
+ c->free_colours = AV_RB32(avctx->extradata + 48);
+ if ((unsigned)c->free_colours > 256) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Incorrect number of changeable palette entries: %d\n",
+ c->free_colours);
+ return AVERROR_INVALIDDATA;
+ }
+ av_log(avctx, AV_LOG_DEBUG, "%d free colour(s)\n", c->free_colours);
+ avctx->coded_width = AV_RB32(avctx->extradata + 20);
+ avctx->coded_height = AV_RB32(avctx->extradata + 24);
+
+ av_log(avctx, AV_LOG_DEBUG, "Display dimensions %dx%d\n",
+ AV_RB32(avctx->extradata + 12), AV_RB32(avctx->extradata + 16));
+ av_log(avctx, AV_LOG_DEBUG, "Coded dimensions %dx%d\n",
+ avctx->coded_width, avctx->coded_height);
+ av_log(avctx, AV_LOG_DEBUG, "%g frames per second\n",
+ av_int2float(AV_RB32(avctx->extradata + 28)));
+ av_log(avctx, AV_LOG_DEBUG, "Bitrate %d bps\n",
+ AV_RB32(avctx->extradata + 32));
+ av_log(avctx, AV_LOG_DEBUG, "Max. lead time %g ms\n",
+ av_int2float(AV_RB32(avctx->extradata + 36)));
+ av_log(avctx, AV_LOG_DEBUG, "Max. lag time %g ms\n",
+ av_int2float(AV_RB32(avctx->extradata + 40)));
+ av_log(avctx, AV_LOG_DEBUG, "Max. seek time %g ms\n",
+ av_int2float(AV_RB32(avctx->extradata + 44)));
+
+ for (i = 0; i < 256; i++)
+ c->pal[i] = AV_RB24(avctx->extradata + 52 + i * 3);
+
+ avctx->pix_fmt = PIX_FMT_PAL8;
+
+ c->mask_linesize = FFALIGN(avctx->width, 16);
+ c->mask = av_malloc(c->mask_linesize * avctx->height);
+ if (!c->mask) {
+ av_log(avctx, AV_LOG_ERROR, "Cannot allocate mask plane\n");
+ return AVERROR(ENOMEM);
+ }
+
+ avctx->coded_frame = &c->pic;
+
+ codec_init(c);
+
+ return 0;
+}
+
+static av_cold int mss1_decode_end(AVCodecContext *avctx)
+{
+ MSS1Context * const c = avctx->priv_data;
+
+ if (c->pic.data[0])
+ avctx->release_buffer(avctx, &c->pic);
+ av_freep(&c->mask);
+
+ return 0;
+}
+
+AVCodec ff_mss1_decoder = {
+ .name = "mss1",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MSS1,
+ .priv_data_size = sizeof(MSS1Context),
+ .init = mss1_decode_init,
+ .close = mss1_decode_end,
+ .decode = mss1_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
+ .long_name = NULL_IF_CONFIG_SMALL("MS Screen 1"),
+};
diff --git a/libavcodec/mss3.c b/libavcodec/mss3.c
new file mode 100644
index 0000000..25163c6
--- /dev/null
+++ b/libavcodec/mss3.c
@@ -0,0 +1,967 @@
+/*
+ * Microsoft Screen 3 (aka Microsoft ATC Screen) decoder
+ * Copyright (c) 2012 Konstantin Shishkov
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Microsoft Screen 3 (aka Microsoft ATC Screen) decoder
+ */
+
+#include "avcodec.h"
+#include "bytestream.h"
+
+#define HEADER_SIZE 27
+
+#define MODEL2_SCALE 13
+#define MODEL_SCALE 15
+#define MODEL256_SEC_SCALE 9
+
+typedef struct Model2 {
+ int upd_val, till_rescale;
+ unsigned zero_freq, zero_weight;
+ unsigned total_freq, total_weight;
+} Model2;
+
+typedef struct Model {
+ int weights[16], freqs[16];
+ int num_syms;
+ int tot_weight;
+ int upd_val, max_upd_val, till_rescale;
+} Model;
+
+typedef struct Model256 {
+ int weights[256], freqs[256];
+ int tot_weight;
+ int secondary[68];
+ int sec_size;
+ int upd_val, max_upd_val, till_rescale;
+} Model256;
+
+#define RAC_BOTTOM 0x01000000
+typedef struct RangeCoder {
+ const uint8_t *src, *src_end;
+
+ uint32_t range, low;
+ int got_error;
+} RangeCoder;
+
+enum BlockType {
+ FILL_BLOCK = 0,
+ IMAGE_BLOCK,
+ DCT_BLOCK,
+ HAAR_BLOCK,
+ SKIP_BLOCK
+};
+
+typedef struct BlockTypeContext {
+ int last_type;
+ Model bt_model[5];
+} BlockTypeContext;
+
+typedef struct FillBlockCoder {
+ int fill_val;
+ Model coef_model;
+} FillBlockCoder;
+
+typedef struct ImageBlockCoder {
+ Model256 esc_model, vec_entry_model;
+ Model vec_size_model;
+ Model vq_model[125];
+} ImageBlockCoder;
+
+typedef struct DCTBlockCoder {
+ int *prev_dc;
+ int prev_dc_stride;
+ int prev_dc_height;
+ int quality;
+ uint16_t qmat[64];
+ Model dc_model;
+ Model2 sign_model;
+ Model256 ac_model;
+} DCTBlockCoder;
+
+typedef struct HaarBlockCoder {
+ int quality, scale;
+ Model256 coef_model;
+ Model coef_hi_model;
+} HaarBlockCoder;
+
+typedef struct MSS3Context {
+ AVCodecContext *avctx;
+ AVFrame pic;
+
+ int got_error;
+ RangeCoder coder;
+ BlockTypeContext btype[3];
+ FillBlockCoder fill_coder[3];
+ ImageBlockCoder image_coder[3];
+ DCTBlockCoder dct_coder[3];
+ HaarBlockCoder haar_coder[3];
+
+ int dctblock[64];
+ int hblock[16 * 16];
+} MSS3Context;
+
+static const uint8_t mss3_luma_quant[64] = {
+ 16, 11, 10, 16, 24, 40, 51, 61,
+ 12, 12, 14, 19, 26, 58, 60, 55,
+ 14, 13, 16, 24, 40, 57, 69, 56,
+ 14, 17, 22, 29, 51, 87, 80, 62,
+ 18, 22, 37, 56, 68, 109, 103, 77,
+ 24, 35, 55, 64, 81, 104, 113, 92,
+ 49, 64, 78, 87, 103, 121, 120, 101,
+ 72, 92, 95, 98, 112, 100, 103, 99
+};
+
+static const uint8_t mss3_chroma_quant[64] = {
+ 17, 18, 24, 47, 99, 99, 99, 99,
+ 18, 21, 26, 66, 99, 99, 99, 99,
+ 24, 26, 56, 99, 99, 99, 99, 99,
+ 47, 66, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99
+};
+
+static const uint8_t zigzag_scan[64] = {
+ 0, 1, 8, 16, 9, 2, 3, 10,
+ 17, 24, 32, 25, 18, 11, 4, 5,
+ 12, 19, 26, 33, 40, 48, 41, 34,
+ 27, 20, 13, 6, 7, 14, 21, 28,
+ 35, 42, 49, 56, 57, 50, 43, 36,
+ 29, 22, 15, 23, 30, 37, 44, 51,
+ 58, 59, 52, 45, 38, 31, 39, 46,
+ 53, 60, 61, 54, 47, 55, 62, 63
+};
+
+
+static void model2_reset(Model2 *m)
+{
+ m->zero_weight = 1;
+ m->total_weight = 2;
+ m->zero_freq = 0x1000;
+ m->total_freq = 0x2000;
+ m->upd_val = 4;
+ m->till_rescale = 4;
+}
+
+static void model2_update(Model2 *m, int bit)
+{
+ unsigned scale;
+
+ if (!bit)
+ m->zero_weight++;
+ m->till_rescale--;
+ if (m->till_rescale)
+ return;
+
+ m->total_weight += m->upd_val;
+ if (m->total_weight > 0x2000) {
+ m->total_weight = (m->total_weight + 1) >> 1;
+ m->zero_weight = (m->zero_weight + 1) >> 1;
+ if (m->total_weight == m->zero_weight)
+ m->total_weight = m->zero_weight + 1;
+ }
+ m->upd_val = m->upd_val * 5 >> 2;
+ if (m->upd_val > 64)
+ m->upd_val = 64;
+ scale = 0x80000000u / m->total_weight;
+ m->zero_freq = m->zero_weight * scale >> 18;
+ m->total_freq = m->total_weight * scale >> 18;
+ m->till_rescale = m->upd_val;
+}
+
+static void model_update(Model *m, int val)
+{
+ int i, sum = 0;
+ unsigned scale;
+
+ m->weights[val]++;
+ m->till_rescale--;
+ if (m->till_rescale)
+ return;
+ m->tot_weight += m->upd_val;
+
+ if (m->tot_weight > 0x8000) {
+ m->tot_weight = 0;
+ for (i = 0; i < m->num_syms; i++) {
+ m->weights[i] = (m->weights[i] + 1) >> 1;
+ m->tot_weight += m->weights[i];
+ }
+ }
+ scale = 0x80000000u / m->tot_weight;
+ for (i = 0; i < m->num_syms; i++) {
+ m->freqs[i] = sum * scale >> 16;
+ sum += m->weights[i];
+ }
+
+ m->upd_val = m->upd_val * 5 >> 2;
+ if (m->upd_val > m->max_upd_val)
+ m->upd_val = m->max_upd_val;
+ m->till_rescale = m->upd_val;
+}
+
+static void model_reset(Model *m)
+{
+ int i;
+
+ m->tot_weight = 0;
+ for (i = 0; i < m->num_syms - 1; i++)
+ m->weights[i] = 1;
+ m->weights[m->num_syms - 1] = 0;
+
+ m->upd_val = m->num_syms;
+ m->till_rescale = 1;
+ model_update(m, m->num_syms - 1);
+ m->till_rescale =
+ m->upd_val = (m->num_syms + 6) >> 1;
+}
+
+static av_cold void model_init(Model *m, int num_syms)
+{
+ m->num_syms = num_syms;
+ m->max_upd_val = 8 * num_syms + 48;
+
+ model_reset(m);
+}
+
+static void model256_update(Model256 *m, int val)
+{
+ int i, sum = 0;
+ unsigned scale;
+ int send, sidx = 1;
+
+ m->weights[val]++;
+ m->till_rescale--;
+ if (m->till_rescale)
+ return;
+ m->tot_weight += m->upd_val;
+
+ if (m->tot_weight > 0x8000) {
+ m->tot_weight = 0;
+ for (i = 0; i < 256; i++) {
+ m->weights[i] = (m->weights[i] + 1) >> 1;
+ m->tot_weight += m->weights[i];
+ }
+ }
+ scale = 0x80000000u / m->tot_weight;
+ m->secondary[0] = 0;
+ for (i = 0; i < 256; i++) {
+ m->freqs[i] = sum * scale >> 16;
+ sum += m->weights[i];
+ send = m->freqs[i] >> MODEL256_SEC_SCALE;
+ while (sidx <= send)
+ m->secondary[sidx++] = i - 1;
+ }
+ while (sidx < m->sec_size)
+ m->secondary[sidx++] = 255;
+
+ m->upd_val = m->upd_val * 5 >> 2;
+ if (m->upd_val > m->max_upd_val)
+ m->upd_val = m->max_upd_val;
+ m->till_rescale = m->upd_val;
+}
+
+static void model256_reset(Model256 *m)
+{
+ int i;
+
+ for (i = 0; i < 255; i++)
+ m->weights[i] = 1;
+ m->weights[255] = 0;
+
+ m->tot_weight = 0;
+ m->upd_val = 256;
+ m->till_rescale = 1;
+ model256_update(m, 255);
+ m->till_rescale =
+ m->upd_val = (256 + 6) >> 1;
+}
+
+static av_cold void model256_init(Model256 *m)
+{
+ m->max_upd_val = 8 * 256 + 48;
+ m->sec_size = (1 << 6) + 2;
+
+ model256_reset(m);
+}
+
+static void rac_init(RangeCoder *c, const uint8_t *src, int size)
+{
+ int i;
+
+ c->src = src;
+ c->src_end = src + size;
+ c->low = 0;
+ for (i = 0; i < FFMIN(size, 4); i++)
+ c->low = (c->low << 8) | *c->src++;
+ c->range = 0xFFFFFFFF;
+ c->got_error = 0;
+}
+
+static void rac_normalise(RangeCoder *c)
+{
+ for (;;) {
+ c->range <<= 8;
+ c->low <<= 8;
+ if (c->src < c->src_end) {
+ c->low |= *c->src++;
+ } else if (!c->low) {
+ c->got_error = 1;
+ return;
+ }
+ if (c->range >= RAC_BOTTOM)
+ return;
+ }
+}
+
+static int rac_get_bit(RangeCoder *c)
+{
+ int bit;
+
+ c->range >>= 1;
+
+ bit = (c->range <= c->low);
+ if (bit)
+ c->low -= c->range;
+
+ if (c->range < RAC_BOTTOM)
+ rac_normalise(c);
+
+ return bit;
+}
+
+static int rac_get_bits(RangeCoder *c, int nbits)
+{
+ int val;
+
+ c->range >>= nbits;
+ val = c->low / c->range;
+ c->low -= c->range * val;
+
+ if (c->range < RAC_BOTTOM)
+ rac_normalise(c);
+
+ return val;
+}
+
+static int rac_get_model2_sym(RangeCoder *c, Model2 *m)
+{
+ int bit, helper;
+
+ helper = m->zero_freq * (c->range >> MODEL2_SCALE);
+ bit = (c->low >= helper);
+ if (bit) {
+ c->low -= helper;
+ c->range -= helper;
+ } else {
+ c->range = helper;
+ }
+
+ if (c->range < RAC_BOTTOM)
+ rac_normalise(c);
+
+ model2_update(m, bit);
+
+ return bit;
+}
+
+static int rac_get_model_sym(RangeCoder *c, Model *m)
+{
+ int prob, prob2, helper, val;
+ int end, end2;
+
+ prob = 0;
+ prob2 = c->range;
+ c->range >>= MODEL_SCALE;
+ val = 0;
+ end = m->num_syms >> 1;
+ end2 = m->num_syms;
+ do {
+ helper = m->freqs[end] * c->range;
+ if (helper <= c->low) {
+ val = end;
+ prob = helper;
+ } else {
+ end2 = end;
+ prob2 = helper;
+ }
+ end = (end2 + val) >> 1;
+ } while (end != val);
+ c->low -= prob;
+ c->range = prob2 - prob;
+ if (c->range < RAC_BOTTOM)
+ rac_normalise(c);
+
+ model_update(m, val);
+
+ return val;
+}
+
+static int rac_get_model256_sym(RangeCoder *c, Model256 *m)
+{
+ int prob, prob2, helper, val;
+ int start, end;
+ int ssym;
+
+ prob2 = c->range;
+ c->range >>= MODEL_SCALE;
+
+ helper = c->low / c->range;
+ ssym = helper >> MODEL256_SEC_SCALE;
+ val = m->secondary[ssym];
+
+ end = start = m->secondary[ssym + 1] + 1;
+ while (end > val + 1) {
+ ssym = (end + val) >> 1;
+ if (m->freqs[ssym] <= helper) {
+ end = start;
+ val = ssym;
+ } else {
+ end = (end + val) >> 1;
+ start = ssym;
+ }
+ }
+ prob = m->freqs[val] * c->range;
+ if (val != 255)
+ prob2 = m->freqs[val + 1] * c->range;
+
+ c->low -= prob;
+ c->range = prob2 - prob;
+ if (c->range < RAC_BOTTOM)
+ rac_normalise(c);
+
+ model256_update(m, val);
+
+ return val;
+}
+
+static int decode_block_type(RangeCoder *c, BlockTypeContext *bt)
+{
+ bt->last_type = rac_get_model_sym(c, &bt->bt_model[bt->last_type]);
+
+ return bt->last_type;
+}
+
+static int decode_coeff(RangeCoder *c, Model *m)
+{
+ int val, sign;
+
+ val = rac_get_model_sym(c, m);
+ if (val) {
+ sign = rac_get_bit(c);
+ if (val > 1) {
+ val--;
+ val = (1 << val) + rac_get_bits(c, val);
+ }
+ if (!sign)
+ val = -val;
+ }
+
+ return val;
+}
+
+static void decode_fill_block(RangeCoder *c, FillBlockCoder *fc,
+ uint8_t *dst, int stride, int block_size)
+{
+ int i;
+
+ fc->fill_val += decode_coeff(c, &fc->coef_model);
+
+ for (i = 0; i < block_size; i++, dst += stride)
+ memset(dst, fc->fill_val, block_size);
+}
+
+static void decode_image_block(RangeCoder *c, ImageBlockCoder *ic,
+ uint8_t *dst, int stride, int block_size)
+{
+ int i, j;
+ int vec_size;
+ int vec[4];
+ int prev_line[16];
+ int A, B, C;
+
+ vec_size = rac_get_model_sym(c, &ic->vec_size_model) + 2;
+ for (i = 0; i < vec_size; i++)
+ vec[i] = rac_get_model256_sym(c, &ic->vec_entry_model);
+ for (; i < 4; i++)
+ vec[i] = 0;
+ memset(prev_line, 0, sizeof(prev_line));
+
+ for (j = 0; j < block_size; j++) {
+ A = 0;
+ B = 0;
+ for (i = 0; i < block_size; i++) {
+ C = B;
+ B = prev_line[i];
+ A = rac_get_model_sym(c, &ic->vq_model[A + B * 5 + C * 25]);
+
+ prev_line[i] = A;
+ if (A < 4)
+ dst[i] = vec[A];
+ else
+ dst[i] = rac_get_model256_sym(c, &ic->esc_model);
+ }
+ dst += stride;
+ }
+}
+
+static int decode_dct(RangeCoder *c, DCTBlockCoder *bc, int *block,
+ int bx, int by)
+{
+ int skip, val, sign, pos = 1, zz_pos, dc;
+ int blk_pos = bx + by * bc->prev_dc_stride;
+
+ memset(block, 0, sizeof(*block) * 64);
+
+ dc = decode_coeff(c, &bc->dc_model);
+ if (by) {
+ if (bx) {
+ int l, tl, t;
+
+ l = bc->prev_dc[blk_pos - 1];
+ tl = bc->prev_dc[blk_pos - 1 - bc->prev_dc_stride];
+ t = bc->prev_dc[blk_pos - bc->prev_dc_stride];
+
+ if (FFABS(t - tl) <= FFABS(l - tl))
+ dc += l;
+ else
+ dc += t;
+ } else {
+ dc += bc->prev_dc[blk_pos - bc->prev_dc_stride];
+ }
+ } else if (bx) {
+ dc += bc->prev_dc[bx - 1];
+ }
+ bc->prev_dc[blk_pos] = dc;
+ block[0] = dc * bc->qmat[0];
+
+ while (pos < 64) {
+ val = rac_get_model256_sym(c, &bc->ac_model);
+ if (!val)
+ return 0;
+ if (val == 0xF0) {
+ pos += 16;
+ continue;
+ }
+ skip = val >> 4;
+ val = val & 0xF;
+ if (!val)
+ return -1;
+ pos += skip;
+ if (pos >= 64)
+ return -1;
+
+ sign = rac_get_model2_sym(c, &bc->sign_model);
+ if (val > 1) {
+ val--;
+ val = (1 << val) + rac_get_bits(c, val);
+ }
+ if (!sign)
+ val = -val;
+
+ zz_pos = zigzag_scan[pos];
+ block[zz_pos] = val * bc->qmat[zz_pos];
+ pos++;
+ }
+
+ return pos == 64 ? 0 : -1;
+}
+
+#define DCT_TEMPLATE(blk, step, SOP, shift) \
+ const int t0 = -39409 * blk[7 * step] - 58980 * blk[1 * step]; \
+ const int t1 = 39410 * blk[1 * step] - 58980 * blk[7 * step]; \
+ const int t2 = -33410 * blk[5 * step] - 167963 * blk[3 * step]; \
+ const int t3 = 33410 * blk[3 * step] - 167963 * blk[5 * step]; \
+ const int t4 = blk[3 * step] + blk[7 * step]; \
+ const int t5 = blk[1 * step] + blk[5 * step]; \
+ const int t6 = 77062 * t4 + 51491 * t5; \
+ const int t7 = 77062 * t5 - 51491 * t4; \
+ const int t8 = 35470 * blk[2 * step] - 85623 * blk[6 * step]; \
+ const int t9 = 35470 * blk[6 * step] + 85623 * blk[2 * step]; \
+ const int tA = SOP(blk[0 * step] - blk[4 * step]); \
+ const int tB = SOP(blk[0 * step] + blk[4 * step]); \
+ \
+ blk[0 * step] = ( t1 + t6 + t9 + tB) >> shift; \
+ blk[1 * step] = ( t3 + t7 + t8 + tA) >> shift; \
+ blk[2 * step] = ( t2 + t6 - t8 + tA) >> shift; \
+ blk[3 * step] = ( t0 + t7 - t9 + tB) >> shift; \
+ blk[4 * step] = (-(t0 + t7) - t9 + tB) >> shift; \
+ blk[5 * step] = (-(t2 + t6) - t8 + tA) >> shift; \
+ blk[6 * step] = (-(t3 + t7) + t8 + tA) >> shift; \
+ blk[7 * step] = (-(t1 + t6) + t9 + tB) >> shift; \
+
+#define SOP_ROW(a) ((a) << 16) + 0x2000
+#define SOP_COL(a) ((a + 32) << 16)
+
+static void dct_put(uint8_t *dst, int stride, int *block)
+{
+ int i, j;
+ int *ptr;
+
+ ptr = block;
+ for (i = 0; i < 8; i++) {
+ DCT_TEMPLATE(ptr, 1, SOP_ROW, 13);
+ ptr += 8;
+ }
+
+ ptr = block;
+ for (i = 0; i < 8; i++) {
+ DCT_TEMPLATE(ptr, 8, SOP_COL, 22);
+ ptr++;
+ }
+
+ ptr = block;
+ for (j = 0; j < 8; j++) {
+ for (i = 0; i < 8; i++)
+ dst[i] = av_clip_uint8(ptr[i] + 128);
+ dst += stride;
+ ptr += 8;
+ }
+}
+
+static void decode_dct_block(RangeCoder *c, DCTBlockCoder *bc,
+ uint8_t *dst, int stride, int block_size,
+ int *block, int mb_x, int mb_y)
+{
+ int i, j;
+ int bx, by;
+ int nblocks = block_size >> 3;
+
+ bx = mb_x * nblocks;
+ by = mb_y * nblocks;
+
+ for (j = 0; j < nblocks; j++) {
+ for (i = 0; i < nblocks; i++) {
+ if (decode_dct(c, bc, block, bx + i, by + j)) {
+ c->got_error = 1;
+ return;
+ }
+ dct_put(dst + i * 8, stride, block);
+ }
+ dst += 8 * stride;
+ }
+}
+
+static void decode_haar_block(RangeCoder *c, HaarBlockCoder *hc,
+ uint8_t *dst, int stride, int block_size,
+ int *block)
+{
+ const int hsize = block_size >> 1;
+ int A, B, C, D, t1, t2, t3, t4;
+ int i, j;
+
+ for (j = 0; j < block_size; j++) {
+ for (i = 0; i < block_size; i++) {
+ if (i < hsize && j < hsize)
+ block[i] = rac_get_model256_sym(c, &hc->coef_model);
+ else
+ block[i] = decode_coeff(c, &hc->coef_hi_model);
+ block[i] *= hc->scale;
+ }
+ block += block_size;
+ }
+ block -= block_size * block_size;
+
+ for (j = 0; j < hsize; j++) {
+ for (i = 0; i < hsize; i++) {
+ A = block[i];
+ B = block[i + hsize];
+ C = block[i + hsize * block_size];
+ D = block[i + hsize * block_size + hsize];
+
+ t1 = A - B;
+ t2 = C - D;
+ t3 = A + B;
+ t4 = C + D;
+ dst[i * 2] = av_clip_uint8(t1 - t2);
+ dst[i * 2 + stride] = av_clip_uint8(t1 + t2);
+ dst[i * 2 + 1] = av_clip_uint8(t3 - t4);
+ dst[i * 2 + 1 + stride] = av_clip_uint8(t3 + t4);
+ }
+ block += block_size;
+ dst += stride * 2;
+ }
+}
+
+static void gen_quant_mat(uint16_t *qmat, const uint8_t *ref, float scale)
+{
+ int i;
+
+ for (i = 0; i < 64; i++)
+ qmat[i] = (uint16_t)(ref[i] * scale + 50.0) / 100;
+}
+
+static void reset_coders(MSS3Context *ctx, int quality)
+{
+ int i, j;
+
+ for (i = 0; i < 3; i++) {
+ ctx->btype[i].last_type = SKIP_BLOCK;
+ for (j = 0; j < 5; j++)
+ model_reset(&ctx->btype[i].bt_model[j]);
+ ctx->fill_coder[i].fill_val = 0;
+ model_reset(&ctx->fill_coder[i].coef_model);
+ model256_reset(&ctx->image_coder[i].esc_model);
+ model256_reset(&ctx->image_coder[i].vec_entry_model);
+ model_reset(&ctx->image_coder[i].vec_size_model);
+ for (j = 0; j < 125; j++)
+ model_reset(&ctx->image_coder[i].vq_model[j]);
+ if (ctx->dct_coder[i].quality != quality) {
+ float scale;
+ ctx->dct_coder[i].quality = quality;
+ if (quality > 50)
+ scale = 200.0f - 2 * quality;
+ else
+ scale = 5000.0f / quality;
+ gen_quant_mat(ctx->dct_coder[i].qmat,
+ i ? mss3_chroma_quant : mss3_luma_quant,
+ scale);
+ }
+ memset(ctx->dct_coder[i].prev_dc, 0,
+ sizeof(*ctx->dct_coder[i].prev_dc) *
+ ctx->dct_coder[i].prev_dc_stride *
+ ctx->dct_coder[i].prev_dc_height);
+ model_reset(&ctx->dct_coder[i].dc_model);
+ model2_reset(&ctx->dct_coder[i].sign_model);
+ model256_reset(&ctx->dct_coder[i].ac_model);
+ if (ctx->haar_coder[i].quality != quality) {
+ ctx->haar_coder[i].quality = quality;
+ ctx->haar_coder[i].scale = 17 - 7 * quality / 50;
+ }
+ model_reset(&ctx->haar_coder[i].coef_hi_model);
+ model256_reset(&ctx->haar_coder[i].coef_model);
+ }
+}
+
+static av_cold void init_coders(MSS3Context *ctx)
+{
+ int i, j;
+
+ for (i = 0; i < 3; i++) {
+ for (j = 0; j < 5; j++)
+ model_init(&ctx->btype[i].bt_model[j], 5);
+ model_init(&ctx->fill_coder[i].coef_model, 12);
+ model256_init(&ctx->image_coder[i].esc_model);
+ model256_init(&ctx->image_coder[i].vec_entry_model);
+ model_init(&ctx->image_coder[i].vec_size_model, 3);
+ for (j = 0; j < 125; j++)
+ model_init(&ctx->image_coder[i].vq_model[j], 5);
+ model_init(&ctx->dct_coder[i].dc_model, 12);
+ model256_init(&ctx->dct_coder[i].ac_model);
+ model_init(&ctx->haar_coder[i].coef_hi_model, 12);
+ model256_init(&ctx->haar_coder[i].coef_model);
+ }
+}
+
+static int mss3_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+ AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ MSS3Context *c = avctx->priv_data;
+ RangeCoder *acoder = &c->coder;
+ GetByteContext gb;
+ uint8_t *dst[3];
+ int dec_width, dec_height, dec_x, dec_y, quality, keyframe;
+ int x, y, i, mb_width, mb_height, blk_size, btype;
+ int ret;
+
+ if (buf_size < HEADER_SIZE) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Frame should have at least %d bytes, got %d instead\n",
+ HEADER_SIZE, buf_size);
+ return AVERROR_INVALIDDATA;
+ }
+
+ bytestream2_init(&gb, buf, buf_size);
+ keyframe = bytestream2_get_be32(&gb);
+ if (keyframe & ~0x301) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid frame type %X\n", keyframe);
+ return AVERROR_INVALIDDATA;
+ }
+ keyframe = !(keyframe & 1);
+ bytestream2_skip(&gb, 6);
+ dec_x = bytestream2_get_be16(&gb);
+ dec_y = bytestream2_get_be16(&gb);
+ dec_width = bytestream2_get_be16(&gb);
+ dec_height = bytestream2_get_be16(&gb);
+
+ if (dec_x + dec_width > avctx->width ||
+ dec_y + dec_height > avctx->height ||
+ (dec_width | dec_height) & 0xF) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid frame dimensions %dx%d +%d,%d\n",
+ dec_width, dec_height, dec_x, dec_y);
+ return AVERROR_INVALIDDATA;
+ }
+ bytestream2_skip(&gb, 4);
+ quality = bytestream2_get_byte(&gb);
+ if (quality < 1 || quality > 100) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid quality setting %d\n", quality);
+ return AVERROR_INVALIDDATA;
+ }
+ bytestream2_skip(&gb, 4);
+
+ if (keyframe && !bytestream2_get_bytes_left(&gb)) {
+ av_log(avctx, AV_LOG_ERROR, "Keyframe without data found\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (!keyframe && c->got_error)
+ return buf_size;
+ c->got_error = 0;
+
+ c->pic.reference = 3;
+ c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
+ FF_BUFFER_HINTS_REUSABLE;
+ if ((ret = avctx->reget_buffer(avctx, &c->pic)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
+ return ret;
+ }
+ c->pic.key_frame = keyframe;
+ c->pic.pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+ if (!bytestream2_get_bytes_left(&gb)) {
+ *data_size = sizeof(AVFrame);
+ *(AVFrame*)data = c->pic;
+
+ return buf_size;
+ }
+
+ reset_coders(c, quality);
+
+ rac_init(acoder, buf + HEADER_SIZE, buf_size - HEADER_SIZE);
+
+ mb_width = dec_width >> 4;
+ mb_height = dec_height >> 4;
+ dst[0] = c->pic.data[0] + dec_x + dec_y * c->pic.linesize[0];
+ dst[1] = c->pic.data[1] + dec_x / 2 + (dec_y / 2) * c->pic.linesize[1];
+ dst[2] = c->pic.data[2] + dec_x / 2 + (dec_y / 2) * c->pic.linesize[2];
+ for (y = 0; y < mb_height; y++) {
+ for (x = 0; x < mb_width; x++) {
+ for (i = 0; i < 3; i++) {
+ blk_size = 8 << !i;
+
+ btype = decode_block_type(acoder, c->btype + i);
+ switch (btype) {
+ case FILL_BLOCK:
+ decode_fill_block(acoder, c->fill_coder + i,
+ dst[i] + x * blk_size,
+ c->pic.linesize[i], blk_size);
+ break;
+ case IMAGE_BLOCK:
+ decode_image_block(acoder, c->image_coder + i,
+ dst[i] + x * blk_size,
+ c->pic.linesize[i], blk_size);
+ break;
+ case DCT_BLOCK:
+ decode_dct_block(acoder, c->dct_coder + i,
+ dst[i] + x * blk_size,
+ c->pic.linesize[i], blk_size,
+ c->dctblock, x, y);
+ break;
+ case HAAR_BLOCK:
+ decode_haar_block(acoder, c->haar_coder + i,
+ dst[i] + x * blk_size,
+ c->pic.linesize[i], blk_size,
+ c->hblock);
+ break;
+ }
+ if (c->got_error || acoder->got_error) {
+ av_log(avctx, AV_LOG_ERROR, "Error decoding block %d,%d\n",
+ x, y);
+ c->got_error = 1;
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ }
+ dst[0] += c->pic.linesize[0] * 16;
+ dst[1] += c->pic.linesize[1] * 8;
+ dst[2] += c->pic.linesize[2] * 8;
+ }
+
+ *data_size = sizeof(AVFrame);
+ *(AVFrame*)data = c->pic;
+
+ return buf_size;
+}
+
+static av_cold int mss3_decode_init(AVCodecContext *avctx)
+{
+ MSS3Context * const c = avctx->priv_data;
+ int i;
+
+ c->avctx = avctx;
+
+ if ((avctx->width & 0xF) || (avctx->height & 0xF)) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Image dimensions should be a multiple of 16.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ c->got_error = 0;
+ for (i = 0; i < 3; i++) {
+ int b_width = avctx->width >> (2 + !!i);
+ int b_height = avctx->height >> (2 + !!i);
+ c->dct_coder[i].prev_dc_stride = b_width;
+ c->dct_coder[i].prev_dc_height = b_height;
+ c->dct_coder[i].prev_dc = av_malloc(sizeof(*c->dct_coder[i].prev_dc) *
+ b_width * b_height);
+ if (!c->dct_coder[i].prev_dc) {
+ av_log(avctx, AV_LOG_ERROR, "Cannot allocate buffer\n");
+ while (i >= 0) {
+ av_freep(&c->dct_coder[i].prev_dc);
+ i--;
+ }
+ return AVERROR(ENOMEM);
+ }
+ }
+
+ avctx->pix_fmt = PIX_FMT_YUV420P;
+ avctx->coded_frame = &c->pic;
+
+ init_coders(c);
+
+ return 0;
+}
+
+static av_cold int mss3_decode_end(AVCodecContext *avctx)
+{
+ MSS3Context * const c = avctx->priv_data;
+ int i;
+
+ if (c->pic.data[0])
+ avctx->release_buffer(avctx, &c->pic);
+ for (i = 0; i < 3; i++)
+ av_freep(&c->dct_coder[i].prev_dc);
+
+ return 0;
+}
+
+AVCodec ff_msa1_decoder = {
+ .name = "msa1",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MSA1,
+ .priv_data_size = sizeof(MSS3Context),
+ .init = mss3_decode_init,
+ .close = mss3_decode_end,
+ .decode = mss3_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
+ .long_name = NULL_IF_CONFIG_SMALL("MS ATC Screen"),
+};
diff --git a/libavcodec/nellymoserenc.c b/libavcodec/nellymoserenc.c
index e1b1d79..18ea684 100644
--- a/libavcodec/nellymoserenc.c
+++ b/libavcodec/nellymoserenc.c
@@ -35,6 +35,7 @@
* http://wiki.multimedia.cx/index.php?title=Nellymoser
*/
+#include "libavutil/float_dsp.h"
#include "libavutil/mathematics.h"
#include "nellymoser.h"
#include "avcodec.h"
@@ -55,6 +56,7 @@ typedef struct NellyMoserEncodeContext {
AVCodecContext *avctx;
int last_frame;
DSPContext dsp;
+ AVFloatDSPContext fdsp;
FFTContext mdct_ctx;
AudioFrameQueue afq;
DECLARE_ALIGNED(32, float, mdct_out)[NELLY_SAMPLES];
@@ -120,11 +122,11 @@ static void apply_mdct(NellyMoserEncodeContext *s)
float *in1 = s->buf + NELLY_BUF_LEN;
float *in2 = s->buf + 2 * NELLY_BUF_LEN;
- s->dsp.vector_fmul (s->in_buff, in0, ff_sine_128, NELLY_BUF_LEN);
+ s->fdsp.vector_fmul (s->in_buff, in0, ff_sine_128, NELLY_BUF_LEN);
s->dsp.vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, in1, ff_sine_128, NELLY_BUF_LEN);
s->mdct_ctx.mdct_calc(&s->mdct_ctx, s->mdct_out, s->in_buff);
- s->dsp.vector_fmul (s->in_buff, in1, ff_sine_128, NELLY_BUF_LEN);
+ s->fdsp.vector_fmul (s->in_buff, in1, ff_sine_128, NELLY_BUF_LEN);
s->dsp.vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, in2, ff_sine_128, NELLY_BUF_LEN);
s->mdct_ctx.mdct_calc(&s->mdct_ctx, s->mdct_out + NELLY_BUF_LEN, s->in_buff);
}
@@ -172,6 +174,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
if ((ret = ff_mdct_init(&s->mdct_ctx, 8, 0, 32768.0)) < 0)
goto error;
ff_dsputil_init(&s->dsp, avctx);
+ avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
/* Generate overlap window */
ff_sine_window_init(ff_sine_128, 128);
diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h
index 1e2560c..7f5b643 100644
--- a/libavcodec/options_table.h
+++ b/libavcodec/options_table.h
@@ -20,6 +20,12 @@
#ifndef AVCODEC_OPTIONS_TABLE
#define AVCODEC_OPTIONS_TABLE
+#include <float.h>
+#include <limits.h>
+
+#include "libavutil/opt.h"
+#include "avcodec.h"
+
#define OFFSET(x) offsetof(AVCodecContext,x)
#define DEFAULT 0 //should be NAN but it does not work as it is not a constant in glibc as required by ANSI/ISO C
//these names are too long to be readable
@@ -153,7 +159,6 @@ static const AVOption options[]={
{"block_align", NULL, OFFSET(block_align), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
{"mpeg_quant", "use MPEG quantizers instead of H.263", OFFSET(mpeg_quant), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
{"stats_out", NULL, OFFSET(stats_out), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX},
-{"stats_in", NULL, OFFSET(stats_in), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX},
{"qsquish", "how to keep quantizer between qmin and qmax (0 = clip, 1 = use differentiable function)", OFFSET(rc_qsquish), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, 0, 99, V|E},
{"rc_qmod_amp", "experimental quantizer modulation", OFFSET(rc_qmod_amp), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, -FLT_MAX, FLT_MAX, V|E},
{"rc_qmod_freq", "experimental quantizer modulation", OFFSET(rc_qmod_freq), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
@@ -386,6 +391,11 @@ static const AVOption options[]={
{"s32", "32-bit signed integer", 0, AV_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_S32 }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
{"flt", "32-bit float", 0, AV_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_FLT }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
{"dbl", "64-bit double", 0, AV_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_DBL }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
+{"u8p" , "8-bit unsigned integer planar", 0, AV_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_U8P }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
+{"s16p", "16-bit signed integer planar", 0, AV_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_S16P }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
+{"s32p", "32-bit signed integer planar", 0, AV_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_S32P }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
+{"fltp", "32-bit float planar", 0, AV_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_FLTP }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
+{"dblp", "64-bit double planar", 0, AV_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_DBLP }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
{NULL},
};
diff --git a/libavcodec/pcm-mpeg.c b/libavcodec/pcm-mpeg.c
index 3604013..014fc91 100644
--- a/libavcodec/pcm-mpeg.c
+++ b/libavcodec/pcm-mpeg.c
@@ -70,13 +70,14 @@ static int pcm_bluray_parse_header(AVCodecContext *avctx,
/* get the sample depth and derive the sample format from it */
avctx->bits_per_coded_sample = bits_per_samples[header[3] >> 6];
if (!avctx->bits_per_coded_sample) {
- av_log(avctx, AV_LOG_ERROR, "unsupported sample depth (0)\n");
+ av_log(avctx, AV_LOG_ERROR, "reserved sample depth (0)\n");
return -1;
}
avctx->sample_fmt = avctx->bits_per_coded_sample == 16 ? AV_SAMPLE_FMT_S16 :
AV_SAMPLE_FMT_S32;
+ avctx->bits_per_raw_sample = avctx->bits_per_coded_sample;
- /* get the sample rate. Not all values are known or exist. */
+ /* get the sample rate. Not all values are used. */
switch (header[2] & 0x0f) {
case 1:
avctx->sample_rate = 48000;
@@ -89,13 +90,13 @@ static int pcm_bluray_parse_header(AVCodecContext *avctx,
break;
default:
avctx->sample_rate = 0;
- av_log(avctx, AV_LOG_ERROR, "unsupported sample rate (%d)\n",
+ av_log(avctx, AV_LOG_ERROR, "reserved sample rate (%d)\n",
header[2] & 0x0f);
return -1;
}
/*
- * get the channel number (and mapping). Not all values are known or exist.
+ * get the channel number (and mapping). Not all values are used.
* It must be noted that the number of channels in the MPEG stream can
* differ from the actual meaningful number, e.g. mono audio still has two
* channels, one being empty.
@@ -103,7 +104,7 @@ static int pcm_bluray_parse_header(AVCodecContext *avctx,
avctx->channel_layout = channel_layouts[channel_layout];
avctx->channels = channels[channel_layout];
if (!avctx->channels) {
- av_log(avctx, AV_LOG_ERROR, "unsupported channel configuration (%d)\n",
+ av_log(avctx, AV_LOG_ERROR, "reserved channel configuration (%d)\n",
channel_layout);
return -1;
}
@@ -310,7 +311,7 @@ static int pcm_bluray_decode_frame(AVCodecContext *avctx, void *data,
if (avctx->debug & FF_DEBUG_BITSTREAM)
av_dlog(avctx, "pcm_bluray_decode_frame: decoded %d -> %d bytes\n",
retval, buf_size);
- return retval;
+ return retval + 4;
}
AVCodec ff_pcm_bluray_decoder = {
diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c
index 9614e8c..5f43f9b 100644
--- a/libavcodec/pcm.c
+++ b/libavcodec/pcm.c
@@ -48,6 +48,7 @@ static av_cold int pcm_encode_init(AVCodecContext *avctx)
avctx->bits_per_coded_sample = av_get_bits_per_sample(avctx->codec->id);
avctx->block_align = avctx->channels * avctx->bits_per_coded_sample / 8;
+ avctx->bit_rate = avctx->block_align * avctx->sample_rate * 8;
avctx->coded_frame = avcodec_alloc_frame();
if (!avctx->coded_frame)
return AVERROR(ENOMEM);
diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c
index 087abae..871f2b2 100644
--- a/libavcodec/pngdec.c
+++ b/libavcodec/pngdec.c
@@ -479,9 +479,11 @@ static int decode_frame(AVCodecContext *avctx,
} else if (s->bit_depth == 1 &&
s->color_type == PNG_COLOR_TYPE_GRAY) {
avctx->pix_fmt = PIX_FMT_MONOBLACK;
- } else if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
+ } else if (s->bit_depth == 8 &&
+ s->color_type == PNG_COLOR_TYPE_PALETTE) {
avctx->pix_fmt = PIX_FMT_PAL8;
- } else if (s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
+ } else if (s->bit_depth == 8 &&
+ s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
avctx->pix_fmt = PIX_FMT_Y400A;
} else {
goto fail;
diff --git a/libavcodec/ppc/dsputil_altivec.c b/libavcodec/ppc/dsputil_altivec.c
index d27a2bc..9ad73ef 100644
--- a/libavcodec/ppc/dsputil_altivec.c
+++ b/libavcodec/ppc/dsputil_altivec.c
@@ -24,9 +24,9 @@
#if HAVE_ALTIVEC_H
#include <altivec.h>
#endif
+#include "libavutil/ppc/types_altivec.h"
+#include "libavutil/ppc/util_altivec.h"
#include "libavcodec/dsputil.h"
-#include "util_altivec.h"
-#include "types_altivec.h"
#include "dsputil_altivec.h"
static int sad16_x2_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
@@ -34,7 +34,9 @@ static int sad16_x2_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size
int i;
int s;
const vector unsigned char zero = (const vector unsigned char)vec_splat_u8(0);
- vector unsigned char *tv;
+ vector unsigned char perm1 = vec_lvsl(0, pix2);
+ vector unsigned char perm2 = vec_add(perm1, vec_splat_u8(1));
+ vector unsigned char pix2l, pix2r;
vector unsigned char pix1v, pix2v, pix2iv, avgv, t5;
vector unsigned int sad;
vector signed int sumdiffs;
@@ -45,14 +47,11 @@ static int sad16_x2_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size
/* Read unaligned pixels into our vectors. The vectors are as follows:
pix1v: pix1[0]-pix1[15]
pix2v: pix2[0]-pix2[15] pix2iv: pix2[1]-pix2[16] */
- tv = (vector unsigned char *) pix1;
- pix1v = vec_perm(tv[0], tv[1], vec_lvsl(0, pix1));
-
- tv = (vector unsigned char *) &pix2[0];
- pix2v = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix2[0]));
-
- tv = (vector unsigned char *) &pix2[1];
- pix2iv = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix2[1]));
+ pix1v = vec_ld( 0, pix1);
+ pix2l = vec_ld( 0, pix2);
+ pix2r = vec_ld(16, pix2);
+ pix2v = vec_perm(pix2l, pix2r, perm1);
+ pix2iv = vec_perm(pix2l, pix2r, perm2);
/* Calculate the average vector */
avgv = vec_avg(pix2v, pix2iv);
@@ -79,7 +78,8 @@ static int sad16_y2_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size
int i;
int s;
const vector unsigned char zero = (const vector unsigned char)vec_splat_u8(0);
- vector unsigned char *tv;
+ vector unsigned char perm = vec_lvsl(0, pix2);
+ vector unsigned char pix2l, pix2r;
vector unsigned char pix1v, pix2v, pix3v, avgv, t5;
vector unsigned int sad;
vector signed int sumdiffs;
@@ -95,18 +95,19 @@ static int sad16_y2_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size
Read unaligned pixels into our vectors. The vectors are as follows:
pix2v: pix2[0]-pix2[15]
Split the pixel vectors into shorts */
- tv = (vector unsigned char *) &pix2[0];
- pix2v = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix2[0]));
+ pix2l = vec_ld( 0, pix2);
+ pix2r = vec_ld(15, pix2);
+ pix2v = vec_perm(pix2l, pix2r, perm);
for (i = 0; i < h; i++) {
/* Read unaligned pixels into our vectors. The vectors are as follows:
pix1v: pix1[0]-pix1[15]
pix3v: pix3[0]-pix3[15] */
- tv = (vector unsigned char *) pix1;
- pix1v = vec_perm(tv[0], tv[1], vec_lvsl(0, pix1));
+ pix1v = vec_ld(0, pix1);
- tv = (vector unsigned char *) &pix3[0];
- pix3v = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix3[0]));
+ pix2l = vec_ld( 0, pix3);
+ pix2r = vec_ld(15, pix3);
+ pix3v = vec_perm(pix2l, pix2r, perm);
/* Calculate the average vector */
avgv = vec_avg(pix2v, pix3v);
@@ -137,7 +138,10 @@ static int sad16_xy2_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_siz
uint8_t *pix3 = pix2 + line_size;
const vector unsigned char zero = (const vector unsigned char)vec_splat_u8(0);
const vector unsigned short two = (const vector unsigned short)vec_splat_u16(2);
- vector unsigned char *tv, avgv, t5;
+ vector unsigned char avgv, t5;
+ vector unsigned char perm1 = vec_lvsl(0, pix2);
+ vector unsigned char perm2 = vec_add(perm1, vec_splat_u8(1));
+ vector unsigned char pix2l, pix2r;
vector unsigned char pix1v, pix2v, pix3v, pix2iv, pix3iv;
vector unsigned short pix2lv, pix2hv, pix2ilv, pix2ihv;
vector unsigned short pix3lv, pix3hv, pix3ilv, pix3ihv;
@@ -157,11 +161,10 @@ static int sad16_xy2_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_siz
Read unaligned pixels into our vectors. The vectors are as follows:
pix2v: pix2[0]-pix2[15] pix2iv: pix2[1]-pix2[16]
Split the pixel vectors into shorts */
- tv = (vector unsigned char *) &pix2[0];
- pix2v = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix2[0]));
-
- tv = (vector unsigned char *) &pix2[1];
- pix2iv = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix2[1]));
+ pix2l = vec_ld( 0, pix2);
+ pix2r = vec_ld(16, pix2);
+ pix2v = vec_perm(pix2l, pix2r, perm1);
+ pix2iv = vec_perm(pix2l, pix2r, perm2);
pix2hv = (vector unsigned short) vec_mergeh(zero, pix2v);
pix2lv = (vector unsigned short) vec_mergel(zero, pix2v);
@@ -174,14 +177,12 @@ static int sad16_xy2_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_siz
/* Read unaligned pixels into our vectors. The vectors are as follows:
pix1v: pix1[0]-pix1[15]
pix3v: pix3[0]-pix3[15] pix3iv: pix3[1]-pix3[16] */
- tv = (vector unsigned char *) pix1;
- pix1v = vec_perm(tv[0], tv[1], vec_lvsl(0, pix1));
-
- tv = (vector unsigned char *) &pix3[0];
- pix3v = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix3[0]));
+ pix1v = vec_ld(0, pix1);
- tv = (vector unsigned char *) &pix3[1];
- pix3iv = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix3[1]));
+ pix2l = vec_ld( 0, pix3);
+ pix2r = vec_ld(16, pix3);
+ pix3v = vec_perm(pix2l, pix2r, perm1);
+ pix3iv = vec_perm(pix2l, pix2r, perm2);
/* Note that AltiVec does have vec_avg, but this works on vector pairs
and rounds up. We could do avg(avg(a,b),avg(c,d)), but the rounding
@@ -230,7 +231,7 @@ static int sad16_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, i
int i;
int s;
const vector unsigned int zero = (const vector unsigned int)vec_splat_u32(0);
- vector unsigned char perm1, perm2, pix1v_low, pix1v_high, pix2v_low, pix2v_high;
+ vector unsigned char perm = vec_lvsl(0, pix2);
vector unsigned char t1, t2, t3,t4, t5;
vector unsigned int sad;
vector signed int sumdiffs;
@@ -240,14 +241,10 @@ static int sad16_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, i
for (i = 0; i < h; i++) {
/* Read potentially unaligned pixels into t1 and t2 */
- perm1 = vec_lvsl(0, pix1);
- pix1v_high = vec_ld( 0, pix1);
- pix1v_low = vec_ld(15, pix1);
- perm2 = vec_lvsl(0, pix2);
- pix2v_high = vec_ld( 0, pix2);
- pix2v_low = vec_ld(15, pix2);
- t1 = vec_perm(pix1v_high, pix1v_low, perm1);
- t2 = vec_perm(pix2v_high, pix2v_low, perm2);
+ vector unsigned char pix2l = vec_ld( 0, pix2);
+ vector unsigned char pix2r = vec_ld(15, pix2);
+ t1 = vec_ld(0, pix1);
+ t2 = vec_perm(pix2l, pix2r, perm);
/* Calculate a sum of abs differences vector */
t3 = vec_max(t1, t2);
@@ -274,25 +271,25 @@ static int sad8_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, in
int i;
int s;
const vector unsigned int zero = (const vector unsigned int)vec_splat_u32(0);
- vector unsigned char perm1, perm2, permclear, *pix1v, *pix2v;
+ const vector unsigned char permclear = (vector unsigned char){255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0};
+ vector unsigned char perm1 = vec_lvsl(0, pix1);
+ vector unsigned char perm2 = vec_lvsl(0, pix2);
vector unsigned char t1, t2, t3,t4, t5;
vector unsigned int sad;
vector signed int sumdiffs;
sad = (vector unsigned int)vec_splat_u32(0);
- permclear = (vector unsigned char){255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0};
-
for (i = 0; i < h; i++) {
/* Read potentially unaligned pixels into t1 and t2
Since we're reading 16 pixels, and actually only want 8,
mask out the last 8 pixels. The 0s don't change the sum. */
- perm1 = vec_lvsl(0, pix1);
- pix1v = (vector unsigned char *) pix1;
- perm2 = vec_lvsl(0, pix2);
- pix2v = (vector unsigned char *) pix2;
- t1 = vec_and(vec_perm(pix1v[0], pix1v[1], perm1), permclear);
- t2 = vec_and(vec_perm(pix2v[0], pix2v[1], perm2), permclear);
+ vector unsigned char pix1l = vec_ld( 0, pix1);
+ vector unsigned char pix1r = vec_ld(15, pix1);
+ vector unsigned char pix2l = vec_ld( 0, pix2);
+ vector unsigned char pix2r = vec_ld(15, pix2);
+ t1 = vec_and(vec_perm(pix1l, pix1r, perm1), permclear);
+ t2 = vec_and(vec_perm(pix2l, pix2r, perm2), permclear);
/* Calculate a sum of abs differences vector */
t3 = vec_max(t1, t2);
@@ -319,7 +316,7 @@ static int pix_norm1_altivec(uint8_t *pix, int line_size)
int i;
int s;
const vector unsigned int zero = (const vector unsigned int)vec_splat_u32(0);
- vector unsigned char *tv;
+ vector unsigned char perm = vec_lvsl(0, pix);
vector unsigned char pixv;
vector unsigned int sv;
vector signed int sum;
@@ -329,8 +326,9 @@ static int pix_norm1_altivec(uint8_t *pix, int line_size)
s = 0;
for (i = 0; i < 16; i++) {
/* Read in the potentially unaligned pixels */
- tv = (vector unsigned char *) pix;
- pixv = vec_perm(tv[0], tv[1], vec_lvsl(0, pix));
+ vector unsigned char pixl = vec_ld( 0, pix);
+ vector unsigned char pixr = vec_ld(15, pix);
+ pixv = vec_perm(pixl, pixr, perm);
/* Square the values, and add them to our sum */
sv = vec_msum(pixv, pixv, sv);
@@ -355,26 +353,25 @@ static int sse8_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, in
int i;
int s;
const vector unsigned int zero = (const vector unsigned int)vec_splat_u32(0);
- vector unsigned char perm1, perm2, permclear, *pix1v, *pix2v;
+ const vector unsigned char permclear = (vector unsigned char){255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0};
+ vector unsigned char perm1 = vec_lvsl(0, pix1);
+ vector unsigned char perm2 = vec_lvsl(0, pix2);
vector unsigned char t1, t2, t3,t4, t5;
vector unsigned int sum;
vector signed int sumsqr;
sum = (vector unsigned int)vec_splat_u32(0);
- permclear = (vector unsigned char){255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0};
-
-
for (i = 0; i < h; i++) {
/* Read potentially unaligned pixels into t1 and t2
Since we're reading 16 pixels, and actually only want 8,
mask out the last 8 pixels. The 0s don't change the sum. */
- perm1 = vec_lvsl(0, pix1);
- pix1v = (vector unsigned char *) pix1;
- perm2 = vec_lvsl(0, pix2);
- pix2v = (vector unsigned char *) pix2;
- t1 = vec_and(vec_perm(pix1v[0], pix1v[1], perm1), permclear);
- t2 = vec_and(vec_perm(pix2v[0], pix2v[1], perm2), permclear);
+ vector unsigned char pix1l = vec_ld( 0, pix1);
+ vector unsigned char pix1r = vec_ld(15, pix1);
+ vector unsigned char pix2l = vec_ld( 0, pix2);
+ vector unsigned char pix2r = vec_ld(15, pix2);
+ t1 = vec_and(vec_perm(pix1l, pix1r, perm1), permclear);
+ t2 = vec_and(vec_perm(pix2l, pix2r, perm2), permclear);
/* Since we want to use unsigned chars, we can take advantage
of the fact that abs(a-b)^2 = (a-b)^2. */
@@ -409,7 +406,7 @@ static int sse16_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, i
int i;
int s;
const vector unsigned int zero = (const vector unsigned int)vec_splat_u32(0);
- vector unsigned char perm1, perm2, *pix1v, *pix2v;
+ vector unsigned char perm = vec_lvsl(0, pix2);
vector unsigned char t1, t2, t3,t4, t5;
vector unsigned int sum;
vector signed int sumsqr;
@@ -418,12 +415,10 @@ static int sse16_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, i
for (i = 0; i < h; i++) {
/* Read potentially unaligned pixels into t1 and t2 */
- perm1 = vec_lvsl(0, pix1);
- pix1v = (vector unsigned char *) pix1;
- perm2 = vec_lvsl(0, pix2);
- pix2v = (vector unsigned char *) pix2;
- t1 = vec_perm(pix1v[0], pix1v[1], perm1);
- t2 = vec_perm(pix2v[0], pix2v[1], perm2);
+ vector unsigned char pix2l = vec_ld( 0, pix2);
+ vector unsigned char pix2r = vec_ld(15, pix2);
+ t1 = vec_ld(0, pix1);
+ t2 = vec_perm(pix2l, pix2r, perm);
/* Since we want to use unsigned chars, we can take advantage
of the fact that abs(a-b)^2 = (a-b)^2. */
@@ -451,7 +446,7 @@ static int sse16_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, i
static int pix_sum_altivec(uint8_t * pix, int line_size)
{
const vector unsigned int zero = (const vector unsigned int)vec_splat_u32(0);
- vector unsigned char perm, *pixv;
+ vector unsigned char perm = vec_lvsl(0, pix);
vector unsigned char t1;
vector unsigned int sad;
vector signed int sumdiffs;
@@ -463,9 +458,9 @@ static int pix_sum_altivec(uint8_t * pix, int line_size)
for (i = 0; i < 16; i++) {
/* Read the potentially unaligned 16 pixels into t1 */
- perm = vec_lvsl(0, pix);
- pixv = (vector unsigned char *) pix;
- t1 = vec_perm(pixv[0], pixv[1], perm);
+ vector unsigned char pixl = vec_ld( 0, pix);
+ vector unsigned char pixr = vec_ld(15, pix);
+ t1 = vec_perm(pixl, pixr, perm);
/* Add each 4 pixel group together and put 4 results into sad */
sad = vec_sum4s(t1, sad);
@@ -484,7 +479,8 @@ static int pix_sum_altivec(uint8_t * pix, int line_size)
static void get_pixels_altivec(DCTELEM *restrict block, const uint8_t *pixels, int line_size)
{
int i;
- vector unsigned char perm, bytes, *pixv;
+ vector unsigned char perm = vec_lvsl(0, pixels);
+ vector unsigned char bytes;
const vector unsigned char zero = (const vector unsigned char)vec_splat_u8(0);
vector signed short shorts;
@@ -492,9 +488,9 @@ static void get_pixels_altivec(DCTELEM *restrict block, const uint8_t *pixels, i
// Read potentially unaligned pixels.
// We're reading 16 pixels, and actually only want 8,
// but we simply ignore the extras.
- perm = vec_lvsl(0, pixels);
- pixv = (vector unsigned char *) pixels;
- bytes = vec_perm(pixv[0], pixv[1], perm);
+ vector unsigned char pixl = vec_ld( 0, pixels);
+ vector unsigned char pixr = vec_ld(15, pixels);
+ bytes = vec_perm(pixl, pixr, perm);
// convert the bytes into shorts
shorts = (vector signed short)vec_mergeh(zero, bytes);
@@ -510,7 +506,9 @@ static void diff_pixels_altivec(DCTELEM *restrict block, const uint8_t *s1,
const uint8_t *s2, int stride)
{
int i;
- vector unsigned char perm, bytes, *pixv;
+ vector unsigned char perm1 = vec_lvsl(0, s1);
+ vector unsigned char perm2 = vec_lvsl(0, s2);
+ vector unsigned char bytes, pixl, pixr;
const vector unsigned char zero = (const vector unsigned char)vec_splat_u8(0);
vector signed short shorts1, shorts2;
@@ -518,17 +516,17 @@ static void diff_pixels_altivec(DCTELEM *restrict block, const uint8_t *s1,
// Read potentially unaligned pixels
// We're reading 16 pixels, and actually only want 8,
// but we simply ignore the extras.
- perm = vec_lvsl(0, s1);
- pixv = (vector unsigned char *) s1;
- bytes = vec_perm(pixv[0], pixv[1], perm);
+ pixl = vec_ld( 0, s1);
+ pixr = vec_ld(15, s1);
+ bytes = vec_perm(pixl, pixr, perm1);
// convert the bytes into shorts
shorts1 = (vector signed short)vec_mergeh(zero, bytes);
// Do the same for the second block of pixels
- perm = vec_lvsl(0, s2);
- pixv = (vector unsigned char *) s2;
- bytes = vec_perm(pixv[0], pixv[1], perm);
+ pixl = vec_ld( 0, s2);
+ pixr = vec_ld(15, s2);
+ bytes = vec_perm(pixl, pixr, perm2);
// convert the bytes into shorts
shorts2 = (vector signed short)vec_mergeh(zero, bytes);
@@ -550,17 +548,17 @@ static void diff_pixels_altivec(DCTELEM *restrict block, const uint8_t *s1,
// Read potentially unaligned pixels
// We're reading 16 pixels, and actually only want 8,
// but we simply ignore the extras.
- perm = vec_lvsl(0, s1);
- pixv = (vector unsigned char *) s1;
- bytes = vec_perm(pixv[0], pixv[1], perm);
+ pixl = vec_ld( 0, s1);
+ pixr = vec_ld(15, s1);
+ bytes = vec_perm(pixl, pixr, perm1);
// convert the bytes into shorts
shorts1 = (vector signed short)vec_mergeh(zero, bytes);
// Do the same for the second block of pixels
- perm = vec_lvsl(0, s2);
- pixv = (vector unsigned char *) s2;
- bytes = vec_perm(pixv[0], pixv[1], perm);
+ pixl = vec_ld( 0, s2);
+ pixr = vec_ld(15, s2);
+ bytes = vec_perm(pixl, pixr, perm2);
// convert the bytes into shorts
shorts2 = (vector signed short)vec_mergeh(zero, bytes);
diff --git a/libavcodec/ppc/fft_altivec.c b/libavcodec/ppc/fft_altivec.c
index 39830b2..c85d04f 100644
--- a/libavcodec/ppc/fft_altivec.c
+++ b/libavcodec/ppc/fft_altivec.c
@@ -19,9 +19,10 @@
* License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+
+#include "libavutil/ppc/types_altivec.h"
+#include "libavutil/ppc/util_altivec.h"
#include "libavcodec/fft.h"
-#include "util_altivec.h"
-#include "types_altivec.h"
/**
* Do a complex FFT with the parameters defined in ff_fft_init(). The
diff --git a/libavcodec/ppc/float_altivec.c b/libavcodec/ppc/float_altivec.c
index 8253716..5068fd4 100644
--- a/libavcodec/ppc/float_altivec.c
+++ b/libavcodec/ppc/float_altivec.c
@@ -18,25 +18,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/ppc/util_altivec.h"
#include "libavcodec/dsputil.h"
#include "dsputil_altivec.h"
-#include "util_altivec.h"
-
-static void vector_fmul_altivec(float *dst, const float *src0, const float *src1, int len)
-{
- int i;
- vector float d0, d1, s, zero = (vector float)vec_splat_u32(0);
- for(i=0; i<len-7; i+=8) {
- d0 = vec_ld(0, src0+i);
- s = vec_ld(0, src1+i);
- d1 = vec_ld(16, src0+i);
- d0 = vec_madd(d0, s, zero);
- d1 = vec_madd(d1, vec_ld(16,src1+i), zero);
- vec_st(d0, 0, dst+i);
- vec_st(d1, 16, dst+i);
- }
-}
static void vector_fmul_reverse_altivec(float *dst, const float *src0,
const float *src1, int len)
@@ -124,7 +109,6 @@ static void vector_fmul_window_altivec(float *dst, const float *src0, const floa
void ff_float_init_altivec(DSPContext* c, AVCodecContext *avctx)
{
- c->vector_fmul = vector_fmul_altivec;
c->vector_fmul_reverse = vector_fmul_reverse_altivec;
c->vector_fmul_add = vector_fmul_add_altivec;
if(!(avctx->flags & CODEC_FLAG_BITEXACT)) {
diff --git a/libavcodec/ppc/fmtconvert_altivec.c b/libavcodec/ppc/fmtconvert_altivec.c
index b1eaf9b..20a05d7 100644
--- a/libavcodec/ppc/fmtconvert_altivec.c
+++ b/libavcodec/ppc/fmtconvert_altivec.c
@@ -20,8 +20,8 @@
#include "libavcodec/fmtconvert.h"
+#include "libavutil/ppc/util_altivec.h"
#include "dsputil_altivec.h"
-#include "util_altivec.h"
static void int32_to_float_fmul_scalar_altivec(float *dst, const int *src, float mul, int len)
{
diff --git a/libavcodec/ppc/gmc_altivec.c b/libavcodec/ppc/gmc_altivec.c
index fb67b9e..45243c2 100644
--- a/libavcodec/ppc/gmc_altivec.c
+++ b/libavcodec/ppc/gmc_altivec.c
@@ -20,9 +20,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/ppc/types_altivec.h"
+#include "libavutil/ppc/util_altivec.h"
#include "libavcodec/dsputil.h"
-#include "util_altivec.h"
-#include "types_altivec.h"
#include "dsputil_altivec.h"
/*
diff --git a/libavcodec/ppc/h264_altivec.c b/libavcodec/ppc/h264_altivec.c
index 79e1714..05a5c51 100644
--- a/libavcodec/ppc/h264_altivec.c
+++ b/libavcodec/ppc/h264_altivec.c
@@ -19,13 +19,13 @@
*/
#include "libavutil/cpu.h"
+#include "libavutil/ppc/types_altivec.h"
+#include "libavutil/ppc/util_altivec.h"
#include "libavcodec/dsputil.h"
#include "libavcodec/h264data.h"
#include "libavcodec/h264dsp.h"
#include "dsputil_altivec.h"
-#include "util_altivec.h"
-#include "types_altivec.h"
#define PUT_OP_U8_ALTIVEC(d, s, dst) d = s
#define AVG_OP_U8_ALTIVEC(d, s, dst) d = vec_avg(dst, s)
@@ -39,7 +39,7 @@
#define PREFIX_h264_qpel16_v_lowpass_num altivec_put_h264_qpel16_v_lowpass_num
#define PREFIX_h264_qpel16_hv_lowpass_altivec put_h264_qpel16_hv_lowpass_altivec
#define PREFIX_h264_qpel16_hv_lowpass_num altivec_put_h264_qpel16_hv_lowpass_num
-#include "h264_template_altivec.c"
+#include "h264_altivec_template.c"
#undef OP_U8_ALTIVEC
#undef PREFIX_h264_chroma_mc8_altivec
#undef PREFIX_h264_chroma_mc8_num
@@ -59,7 +59,7 @@
#define PREFIX_h264_qpel16_v_lowpass_num altivec_avg_h264_qpel16_v_lowpass_num
#define PREFIX_h264_qpel16_hv_lowpass_altivec avg_h264_qpel16_hv_lowpass_altivec
#define PREFIX_h264_qpel16_hv_lowpass_num altivec_avg_h264_qpel16_hv_lowpass_num
-#include "h264_template_altivec.c"
+#include "h264_altivec_template.c"
#undef OP_U8_ALTIVEC
#undef PREFIX_h264_chroma_mc8_altivec
#undef PREFIX_h264_chroma_mc8_num
diff --git a/libavcodec/ppc/h264_template_altivec.c b/libavcodec/ppc/h264_altivec_template.c
similarity index 100%
rename from libavcodec/ppc/h264_template_altivec.c
rename to libavcodec/ppc/h264_altivec_template.c
diff --git a/libavcodec/ppc/idct_altivec.c b/libavcodec/ppc/idct_altivec.c
index d2e9017..e599491 100644
--- a/libavcodec/ppc/idct_altivec.c
+++ b/libavcodec/ppc/idct_altivec.c
@@ -41,8 +41,8 @@
#if HAVE_ALTIVEC_H
#include <altivec.h>
#endif
+#include "libavutil/ppc/types_altivec.h"
#include "libavcodec/dsputil.h"
-#include "types_altivec.h"
#include "dsputil_altivec.h"
#define IDCT_HALF \
diff --git a/libavcodec/ppc/int_altivec.c b/libavcodec/ppc/int_altivec.c
index f81b478..4fcdf77 100644
--- a/libavcodec/ppc/int_altivec.c
+++ b/libavcodec/ppc/int_altivec.c
@@ -28,12 +28,11 @@
#include <altivec.h>
#endif
+#include "libavutil/ppc/types_altivec.h"
#include "libavcodec/dsputil.h"
#include "dsputil_altivec.h"
-#include "types_altivec.h"
-
static int ssd_int8_vs_int16_altivec(const int8_t *pix1, const int16_t *pix2,
int size) {
int i, size16;
@@ -79,28 +78,20 @@ static int ssd_int8_vs_int16_altivec(const int8_t *pix1, const int16_t *pix2,
return u.score[3];
}
-static int32_t scalarproduct_int16_altivec(int16_t *v1, const int16_t *v2,
- int order, const int shift)
+static int32_t scalarproduct_int16_altivec(const int16_t *v1, const int16_t *v2,
+ int order)
{
int i;
LOAD_ZERO;
- register vec_s16 vec1, *pv;
+ const vec_s16 *pv;
+ register vec_s16 vec1;
register vec_s32 res = vec_splat_s32(0), t;
- register vec_u32 shifts;
int32_t ires;
- shifts = zero_u32v;
- if(shift & 0x10) shifts = vec_add(shifts, vec_sl(vec_splat_u32(0x08), vec_splat_u32(0x1)));
- if(shift & 0x08) shifts = vec_add(shifts, vec_splat_u32(0x08));
- if(shift & 0x04) shifts = vec_add(shifts, vec_splat_u32(0x04));
- if(shift & 0x02) shifts = vec_add(shifts, vec_splat_u32(0x02));
- if(shift & 0x01) shifts = vec_add(shifts, vec_splat_u32(0x01));
-
for(i = 0; i < order; i += 8){
- pv = (vec_s16*)v1;
+ pv = (const vec_s16*)v1;
vec1 = vec_perm(pv[0], pv[1], vec_lvsl(0, v1));
t = vec_msum(vec1, vec_ld(0, v2), zero_s32v);
- t = vec_sr(t, shifts);
res = vec_sums(t, res);
v1 += 8;
v2 += 8;
@@ -114,31 +105,31 @@ static int32_t scalarproduct_and_madd_int16_altivec(int16_t *v1, const int16_t *
{
LOAD_ZERO;
vec_s16 *pv1 = (vec_s16*)v1;
- vec_s16 *pv2 = (vec_s16*)v2;
- vec_s16 *pv3 = (vec_s16*)v3;
register vec_s16 muls = {mul,mul,mul,mul,mul,mul,mul,mul};
- register vec_s16 t0, t1, i0, i1;
- register vec_s16 i2 = pv2[0], i3 = pv3[0];
+ register vec_s16 t0, t1, i0, i1, i4;
+ register vec_s16 i2 = vec_ld(0, v2), i3 = vec_ld(0, v3);
register vec_s32 res = zero_s32v;
register vec_u8 align = vec_lvsl(0, v2);
int32_t ires;
order >>= 4;
do {
- t0 = vec_perm(i2, pv2[1], align);
- i2 = pv2[2];
- t1 = vec_perm(pv2[1], i2, align);
+ i1 = vec_ld(16, v2);
+ t0 = vec_perm(i2, i1, align);
+ i2 = vec_ld(32, v2);
+ t1 = vec_perm(i1, i2, align);
i0 = pv1[0];
i1 = pv1[1];
res = vec_msum(t0, i0, res);
res = vec_msum(t1, i1, res);
- t0 = vec_perm(i3, pv3[1], align);
- i3 = pv3[2];
- t1 = vec_perm(pv3[1], i3, align);
+ i4 = vec_ld(16, v3);
+ t0 = vec_perm(i3, i4, align);
+ i3 = vec_ld(32, v3);
+ t1 = vec_perm(i4, i3, align);
pv1[0] = vec_mladd(t0, muls, i0);
pv1[1] = vec_mladd(t1, muls, i1);
pv1 += 2;
- pv2 += 2;
- pv3 += 2;
+ v2 += 8;
+ v3 += 8;
} while(--order);
res = vec_splat(vec_sums(res, zero_s32v), 3);
vec_ste(res, 0, &ires);
diff --git a/libavcodec/ppc/mpegaudiodec_altivec.c b/libavcodec/ppc/mpegaudiodec_altivec.c
index 5df0fda..fabde6a 100644
--- a/libavcodec/ppc/mpegaudiodec_altivec.c
+++ b/libavcodec/ppc/mpegaudiodec_altivec.c
@@ -20,7 +20,7 @@
*/
#include "dsputil_altivec.h"
-#include "util_altivec.h"
+#include "libavutil/ppc/util_altivec.h"
#include "libavcodec/dsputil.h"
#include "libavcodec/mpegaudiodsp.h"
diff --git a/libavcodec/ppc/mpegvideo_altivec.c b/libavcodec/ppc/mpegvideo_altivec.c
index 42702fd..df111e9 100644
--- a/libavcodec/ppc/mpegvideo_altivec.c
+++ b/libavcodec/ppc/mpegvideo_altivec.c
@@ -23,12 +23,13 @@
#include <stdlib.h>
#include <stdio.h>
+
#include "libavutil/cpu.h"
+#include "libavutil/ppc/types_altivec.h"
+#include "libavutil/ppc/util_altivec.h"
#include "libavcodec/dsputil.h"
#include "libavcodec/mpegvideo.h"
-#include "util_altivec.h"
-#include "types_altivec.h"
#include "dsputil_altivec.h"
/* AltiVec version of dct_unquantize_h263
diff --git a/libavcodec/ppc/regs.h b/libavcodec/ppc/regs.h
deleted file mode 100644
index 2edd639..0000000
--- a/libavcodec/ppc/regs.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2010 Mans Rullgard
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef AVCODEC_PPC_REGS_H
-#define AVCODEC_PPC_REGS_H
-
-#include "libavutil/avutil.h"
-#include "config.h"
-
-#if HAVE_IBM_ASM
-# define r(n) AV_TOSTRING(n)
-# define f(n) AV_TOSTRING(n)
-# define v(n) AV_TOSTRING(n)
-#else
-# define r(n) AV_TOSTRING(r ## n)
-# define f(n) AV_TOSTRING(f ## n)
-# define v(n) AV_TOSTRING(v ## n)
-#endif
-
-#endif /* AVCODEC_PPC_REGS_H */
diff --git a/libavcodec/ppc/types_altivec.h b/libavcodec/ppc/types_altivec.h
deleted file mode 100644
index defa20e..0000000
--- a/libavcodec/ppc/types_altivec.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2006 Guillaume Poirier <gpoirier at mplayerhq.hu>
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef AVCODEC_PPC_TYPES_ALTIVEC_H
-#define AVCODEC_PPC_TYPES_ALTIVEC_H
-
-/***********************************************************************
- * Vector types
- **********************************************************************/
-#define vec_u8 vector unsigned char
-#define vec_s8 vector signed char
-#define vec_u16 vector unsigned short
-#define vec_s16 vector signed short
-#define vec_u32 vector unsigned int
-#define vec_s32 vector signed int
-#define vec_f vector float
-
-/***********************************************************************
- * Null vector
- **********************************************************************/
-#define LOAD_ZERO const vec_u8 zerov = vec_splat_u8( 0 )
-
-#define zero_u8v (vec_u8) zerov
-#define zero_s8v (vec_s8) zerov
-#define zero_u16v (vec_u16) zerov
-#define zero_s16v (vec_s16) zerov
-#define zero_u32v (vec_u32) zerov
-#define zero_s32v (vec_s32) zerov
-
-#endif /* AVCODEC_PPC_TYPES_ALTIVEC_H */
diff --git a/libavcodec/ppc/util_altivec.h b/libavcodec/ppc/util_altivec.h
deleted file mode 100644
index 19ea962..0000000
--- a/libavcodec/ppc/util_altivec.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * Contains misc utility macros and inline functions
- */
-
-#ifndef AVCODEC_PPC_UTIL_ALTIVEC_H
-#define AVCODEC_PPC_UTIL_ALTIVEC_H
-
-#include <stdint.h>
-
-#include "config.h"
-
-#if HAVE_ALTIVEC_H
-#include <altivec.h>
-#endif
-
-#include "types_altivec.h"
-
-// used to build registers permutation vectors (vcprm)
-// the 's' are for words in the _s_econd vector
-#define WORD_0 0x00,0x01,0x02,0x03
-#define WORD_1 0x04,0x05,0x06,0x07
-#define WORD_2 0x08,0x09,0x0a,0x0b
-#define WORD_3 0x0c,0x0d,0x0e,0x0f
-#define WORD_s0 0x10,0x11,0x12,0x13
-#define WORD_s1 0x14,0x15,0x16,0x17
-#define WORD_s2 0x18,0x19,0x1a,0x1b
-#define WORD_s3 0x1c,0x1d,0x1e,0x1f
-
-#define vcprm(a,b,c,d) (const vector unsigned char){WORD_ ## a, WORD_ ## b, WORD_ ## c, WORD_ ## d}
-#define vcii(a,b,c,d) (const vector float){FLOAT_ ## a, FLOAT_ ## b, FLOAT_ ## c, FLOAT_ ## d}
-
-// vcprmle is used to keep the same index as in the SSE version.
-// it's the same as vcprm, with the index inversed
-// ('le' is Little Endian)
-#define vcprmle(a,b,c,d) vcprm(d,c,b,a)
-
-// used to build inverse/identity vectors (vcii)
-// n is _n_egative, p is _p_ositive
-#define FLOAT_n -1.
-#define FLOAT_p 1.
-
-
-// Transpose 8x8 matrix of 16-bit elements (in-place)
-#define TRANSPOSE8(a,b,c,d,e,f,g,h) \
-do { \
- vector signed short A1, B1, C1, D1, E1, F1, G1, H1; \
- vector signed short A2, B2, C2, D2, E2, F2, G2, H2; \
- \
- A1 = vec_mergeh (a, e); \
- B1 = vec_mergel (a, e); \
- C1 = vec_mergeh (b, f); \
- D1 = vec_mergel (b, f); \
- E1 = vec_mergeh (c, g); \
- F1 = vec_mergel (c, g); \
- G1 = vec_mergeh (d, h); \
- H1 = vec_mergel (d, h); \
- \
- A2 = vec_mergeh (A1, E1); \
- B2 = vec_mergel (A1, E1); \
- C2 = vec_mergeh (B1, F1); \
- D2 = vec_mergel (B1, F1); \
- E2 = vec_mergeh (C1, G1); \
- F2 = vec_mergel (C1, G1); \
- G2 = vec_mergeh (D1, H1); \
- H2 = vec_mergel (D1, H1); \
- \
- a = vec_mergeh (A2, E2); \
- b = vec_mergel (A2, E2); \
- c = vec_mergeh (B2, F2); \
- d = vec_mergel (B2, F2); \
- e = vec_mergeh (C2, G2); \
- f = vec_mergel (C2, G2); \
- g = vec_mergeh (D2, H2); \
- h = vec_mergel (D2, H2); \
-} while (0)
-
-
-/** @brief loads unaligned vector @a *src with offset @a offset
- and returns it */
-static inline vector unsigned char unaligned_load(int offset, uint8_t *src)
-{
- register vector unsigned char first = vec_ld(offset, src);
- register vector unsigned char second = vec_ld(offset+15, src);
- register vector unsigned char mask = vec_lvsl(offset, src);
- return vec_perm(first, second, mask);
-}
-
-/**
- * loads vector known misalignment
- * @param perm_vec the align permute vector to combine the two loads from lvsl
- */
-static inline vec_u8 load_with_perm_vec(int offset, uint8_t *src, vec_u8 perm_vec)
-{
- vec_u8 a = vec_ld(offset, src);
- vec_u8 b = vec_ld(offset+15, src);
- return vec_perm(a, b, perm_vec);
-}
-
-#endif /* AVCODEC_PPC_UTIL_ALTIVEC_H */
diff --git a/libavcodec/ppc/vc1dsp_altivec.c b/libavcodec/ppc/vc1dsp_altivec.c
index 307e0e9..6c110db 100644
--- a/libavcodec/ppc/vc1dsp_altivec.c
+++ b/libavcodec/ppc/vc1dsp_altivec.c
@@ -19,12 +19,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/ppc/types_altivec.h"
+#include "libavutil/ppc/util_altivec.h"
#include "libavcodec/dsputil.h"
#include "libavcodec/vc1dsp.h"
-#include "util_altivec.h"
-#include "dsputil_altivec.h"
-
// main steps of 8x8 transform
#define STEP8(s0, s1, s2, s3, s4, s5, s6, s7, vec_rnd) \
do { \
@@ -326,13 +325,13 @@ static void vc1_inv_trans_8x4_altivec(uint8_t *dest, int stride, DCTELEM *block)
#define OP_U8_ALTIVEC PUT_OP_U8_ALTIVEC
#define PREFIX_no_rnd_vc1_chroma_mc8_altivec put_no_rnd_vc1_chroma_mc8_altivec
-#include "h264_template_altivec.c"
+#include "h264_altivec_template.c"
#undef OP_U8_ALTIVEC
#undef PREFIX_no_rnd_vc1_chroma_mc8_altivec
#define OP_U8_ALTIVEC AVG_OP_U8_ALTIVEC
#define PREFIX_no_rnd_vc1_chroma_mc8_altivec avg_no_rnd_vc1_chroma_mc8_altivec
-#include "h264_template_altivec.c"
+#include "h264_altivec_template.c"
#undef OP_U8_ALTIVEC
#undef PREFIX_no_rnd_vc1_chroma_mc8_altivec
diff --git a/libavcodec/ppc/vp3dsp_altivec.c b/libavcodec/ppc/vp3dsp_altivec.c
index bbe9170..938502e 100644
--- a/libavcodec/ppc/vp3dsp_altivec.c
+++ b/libavcodec/ppc/vp3dsp_altivec.c
@@ -18,9 +18,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/ppc/types_altivec.h"
+#include "libavutil/ppc/util_altivec.h"
#include "libavcodec/dsputil.h"
-#include "util_altivec.h"
-#include "types_altivec.h"
#include "dsputil_altivec.h"
static const vec_s16 constants =
diff --git a/libavcodec/ppc/vp8dsp_altivec.c b/libavcodec/ppc/vp8dsp_altivec.c
index c3f6502..f570000 100644
--- a/libavcodec/ppc/vp8dsp_altivec.c
+++ b/libavcodec/ppc/vp8dsp_altivec.c
@@ -21,10 +21,10 @@
*/
#include "libavutil/cpu.h"
+#include "libavutil/ppc/types_altivec.h"
+#include "libavutil/ppc/util_altivec.h"
#include "libavcodec/vp8dsp.h"
#include "dsputil_altivec.h"
-#include "types_altivec.h"
-#include "util_altivec.h"
#define REPT4(...) { __VA_ARGS__, __VA_ARGS__, __VA_ARGS__, __VA_ARGS__ }
diff --git a/libavcodec/proresenc.c b/libavcodec/proresenc.c
index bee49ee..f821533 100644
--- a/libavcodec/proresenc.c
+++ b/libavcodec/proresenc.c
@@ -724,7 +724,6 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
int sizes[4] = { 0 };
int slice_hdr_size = 2 + 2 * (ctx->num_planes - 1);
int frame_size, picture_size, slice_size;
- int mbs_per_slice = ctx->mbs_per_slice;
int pkt_size, ret;
*avctx->coded_frame = *pic;
@@ -792,7 +791,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
}
for (y = 0; y < ctx->mb_height; y++) {
- mbs_per_slice = ctx->mbs_per_slice;
+ int mbs_per_slice = ctx->mbs_per_slice;
for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
q = ctx->force_quant ? ctx->force_quant
: ctx->slice_q[mb + y * ctx->slices_width];
diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c
index 1889d2a..c7edb9e 100644
--- a/libavcodec/pthread.c
+++ b/libavcodec/pthread.c
@@ -865,6 +865,7 @@ error:
void ff_thread_flush(AVCodecContext *avctx)
{
+ int i;
FrameThreadContext *fctx = avctx->thread_opaque;
if (!avctx->thread_opaque) return;
@@ -880,7 +881,7 @@ void ff_thread_flush(AVCodecContext *avctx)
fctx->next_decoding = fctx->next_finished = 0;
fctx->delaying = 1;
fctx->prev_thread = NULL;
- for (int i = 0; i < avctx->thread_count; i++) {
+ for (i = 0; i < avctx->thread_count; i++) {
PerThreadContext *p = &fctx->threads[i];
// Make sure decode flush calls with size=0 won't return old frames
p->got_frame = 0;
@@ -1015,6 +1016,11 @@ static void validate_thread_parameters(AVCodecContext *avctx)
avctx->thread_count = 1;
avctx->active_thread_type = 0;
}
+
+ if (avctx->thread_count > MAX_AUTO_THREADS)
+ av_log(avctx, AV_LOG_WARNING,
+ "Application has requested %d threads. Using a thread count greater than %d is not recommended.\n",
+ avctx->thread_count, MAX_AUTO_THREADS);
}
int ff_thread_init(AVCodecContext *avctx)
diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c
index 54782a2..4b5ef5c 100644
--- a/libavcodec/qdm2.c
+++ b/libavcodec/qdm2.c
@@ -879,9 +879,13 @@ static void synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int l
break;
case 30:
- if (get_bits_left(gb) >= 4)
- samples[0] = type30_dequant[qdm2_get_vlc(gb, &vlc_tab_type30, 0, 1)];
- else
+ if (get_bits_left(gb) >= 4) {
+ unsigned index = qdm2_get_vlc(gb, &vlc_tab_type30, 0, 1);
+ if (index < FF_ARRAY_ELEMS(type30_dequant)) {
+ samples[0] = type30_dequant[index];
+ } else
+ samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx);
+ } else
samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx);
run = 1;
@@ -895,8 +899,12 @@ static void synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int l
type34_predictor = samples[0];
type34_first = 0;
} else {
- samples[0] = type34_delta[qdm2_get_vlc(gb, &vlc_tab_type34, 0, 1)] / type34_div + type34_predictor;
- type34_predictor = samples[0];
+ unsigned index = qdm2_get_vlc(gb, &vlc_tab_type34, 0, 1);
+ if (index < FF_ARRAY_ELEMS(type34_delta)) {
+ samples[0] = type34_delta[index] / type34_div + type34_predictor;
+ type34_predictor = samples[0];
+ } else
+ samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx);
}
} else {
samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx);
@@ -1664,51 +1672,6 @@ static av_cold void qdm2_init(QDM2Context *q) {
}
-#if 0
-static void dump_context(QDM2Context *q)
-{
- int i;
-#define PRINT(a,b) av_log(NULL,AV_LOG_DEBUG," %s = %d\n", a, b);
- PRINT("compressed_data",q->compressed_data);
- PRINT("compressed_size",q->compressed_size);
- PRINT("frame_size",q->frame_size);
- PRINT("checksum_size",q->checksum_size);
- PRINT("channels",q->channels);
- PRINT("nb_channels",q->nb_channels);
- PRINT("fft_size",q->fft_size);
- PRINT("sub_sampling",q->sub_sampling);
- PRINT("fft_order",q->fft_order);
- PRINT("group_order",q->group_order);
- PRINT("group_size",q->group_size);
- PRINT("sub_packet",q->sub_packet);
- PRINT("frequency_range",q->frequency_range);
- PRINT("has_errors",q->has_errors);
- PRINT("fft_tone_end",q->fft_tone_end);
- PRINT("fft_tone_start",q->fft_tone_start);
- PRINT("fft_coefs_index",q->fft_coefs_index);
- PRINT("coeff_per_sb_select",q->coeff_per_sb_select);
- PRINT("cm_table_select",q->cm_table_select);
- PRINT("noise_idx",q->noise_idx);
-
- for (i = q->fft_tone_start; i < q->fft_tone_end; i++)
- {
- FFTTone *t = &q->fft_tones[i];
-
- av_log(NULL,AV_LOG_DEBUG,"Tone (%d) dump:\n", i);
- av_log(NULL,AV_LOG_DEBUG," level = %f\n", t->level);
-// PRINT(" level", t->level);
- PRINT(" phase", t->phase);
- PRINT(" phase_shift", t->phase_shift);
- PRINT(" duration", t->duration);
- PRINT(" samples_im", t->samples_im);
- PRINT(" samples_re", t->samples_re);
- PRINT(" table", t->table);
- }
-
-}
-#endif
-
-
/**
* Init parameters from codec extradata
*/
@@ -1887,7 +1850,6 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx)
avcodec_get_frame_defaults(&s->frame);
avctx->coded_frame = &s->frame;
-// dump_context(s);
return 0;
}
@@ -1911,8 +1873,6 @@ static int qdm2_decode (QDM2Context *q, const uint8_t *in, int16_t *out)
q->compressed_data = in;
q->compressed_size = q->checksum_size;
-// dump_context(q);
-
/* copy old block, clear new block of output samples */
memmove(q->output_buffer, &q->output_buffer[frame_size], frame_size * sizeof(float));
memset(&q->output_buffer[frame_size], 0, frame_size * sizeof(float));
diff --git a/libavcodec/ra288.c b/libavcodec/ra288.c
index 821e381..aa7ad33 100644
--- a/libavcodec/ra288.c
+++ b/libavcodec/ra288.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/float_dsp.h"
#include "avcodec.h"
#define BITSTREAM_READER_LE
#include "get_bits.h"
@@ -26,7 +27,6 @@
#include "lpc.h"
#include "celp_math.h"
#include "celp_filters.h"
-#include "dsputil.h"
#define MAX_BACKWARD_FILTER_ORDER 36
#define MAX_BACKWARD_FILTER_LEN 40
@@ -38,8 +38,9 @@
typedef struct {
AVFrame frame;
DSPContext dsp;
- DECLARE_ALIGNED(16, float, sp_lpc)[FFALIGN(36, 8)]; ///< LPC coefficients for speech data (spec: A)
- DECLARE_ALIGNED(16, float, gain_lpc)[FFALIGN(10, 8)]; ///< LPC coefficients for gain (spec: GB)
+ AVFloatDSPContext fdsp;
+ DECLARE_ALIGNED(32, float, sp_lpc)[FFALIGN(36, 16)]; ///< LPC coefficients for speech data (spec: A)
+ DECLARE_ALIGNED(32, float, gain_lpc)[FFALIGN(10, 16)]; ///< LPC coefficients for gain (spec: GB)
/** speech data history (spec: SB).
* Its first 70 coefficients are updated only at backward filtering.
@@ -62,7 +63,7 @@ static av_cold int ra288_decode_init(AVCodecContext *avctx)
{
RA288Context *ractx = avctx->priv_data;
avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
- ff_dsputil_init(&ractx->dsp, avctx);
+ avpriv_float_dsp_init(&ractx->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
avcodec_get_frame_defaults(&ractx->frame);
avctx->coded_frame = &ractx->frame;
@@ -133,11 +134,11 @@ static void do_hybrid_window(RA288Context *ractx,
int i;
float buffer1[MAX_BACKWARD_FILTER_ORDER + 1];
float buffer2[MAX_BACKWARD_FILTER_ORDER + 1];
- LOCAL_ALIGNED_16(float, work, [FFALIGN(MAX_BACKWARD_FILTER_ORDER +
- MAX_BACKWARD_FILTER_LEN +
- MAX_BACKWARD_FILTER_NONREC, 8)]);
+ LOCAL_ALIGNED(32, float, work, [FFALIGN(MAX_BACKWARD_FILTER_ORDER +
+ MAX_BACKWARD_FILTER_LEN +
+ MAX_BACKWARD_FILTER_NONREC, 16)]);
- ractx->dsp.vector_fmul(work, window, hist, FFALIGN(order + n + non_rec, 8));
+ ractx->fdsp.vector_fmul(work, window, hist, FFALIGN(order + n + non_rec, 16));
convolve(buffer1, work + order , n , order);
convolve(buffer2, work + order + n, non_rec, order);
@@ -164,7 +165,7 @@ static void backward_filter(RA288Context *ractx,
do_hybrid_window(ractx, order, n, non_rec, temp, hist, rec, window);
if (!compute_lpc_coefs(temp, order, lpc, 0, 1, 1))
- ractx->dsp.vector_fmul(lpc, lpc, tab, FFALIGN(order, 8));
+ ractx->fdsp.vector_fmul(lpc, lpc, tab, FFALIGN(order, 16));
memmove(hist, hist + n, move_size*sizeof(*hist));
}
diff --git a/libavcodec/ra288.h b/libavcodec/ra288.h
index 1c98c16..5e44c82 100644
--- a/libavcodec/ra288.h
+++ b/libavcodec/ra288.h
@@ -97,7 +97,7 @@ static const int16_t codetable[128][5]={
{ 3746, -606, 53, -269, -3301}, { 606, 2018, -1316, 4064, 398}
};
-DECLARE_ALIGNED(16, static const float, syn_window)[FFALIGN(111, 8)]={
+DECLARE_ALIGNED(32, static const float, syn_window)[FFALIGN(111, 16)]={
0.576690972, 0.580838025, 0.585013986, 0.589219987, 0.59345597, 0.597723007,
0.602020264, 0.606384277, 0.610748291, 0.615142822, 0.619598389, 0.624084473,
0.628570557, 0.633117676, 0.637695313, 0.642272949, 0.646911621, 0.651580811,
@@ -119,7 +119,7 @@ DECLARE_ALIGNED(16, static const float, syn_window)[FFALIGN(111, 8)]={
0.142852783, 0.0954284668,0.0477600098
};
-DECLARE_ALIGNED(16, static const float, gain_window)[FFALIGN(38, 8)]={
+DECLARE_ALIGNED(32, static const float, gain_window)[FFALIGN(38, 16)]={
0.505699992, 0.524200022, 0.54339999, 0.563300014, 0.583953857, 0.60534668,
0.627502441, 0.650482178, 0.674316406, 0.699005127, 0.724578857, 0.75112915,
0.778625488, 0.807128906, 0.836669922, 0.86730957, 0.899078369, 0.932006836,
@@ -130,7 +130,7 @@ DECLARE_ALIGNED(16, static const float, gain_window)[FFALIGN(38, 8)]={
};
/** synthesis bandwidth broadening table */
-DECLARE_ALIGNED(16, static const float, syn_bw_tab)[FFALIGN(36, 8)] = {
+DECLARE_ALIGNED(32, static const float, syn_bw_tab)[FFALIGN(36, 16)] = {
0.98828125, 0.976699829, 0.965254128, 0.953942537, 0.942763507, 0.931715488,
0.920796931, 0.910006344, 0.899342179, 0.888803005, 0.878387332, 0.868093729,
0.857920766, 0.847867012, 0.837931097, 0.828111589, 0.818407178, 0.808816493,
@@ -140,7 +140,7 @@ DECLARE_ALIGNED(16, static const float, syn_bw_tab)[FFALIGN(36, 8)] = {
};
/** gain bandwidth broadening table */
-DECLARE_ALIGNED(16, static const float, gain_bw_tab)[FFALIGN(10, 8)] = {
+DECLARE_ALIGNED(32, static const float, gain_bw_tab)[FFALIGN(10, 16)] = {
0.90625, 0.821289063, 0.74432373, 0.674499512, 0.61126709,
0.553955078, 0.50201416, 0.454956055, 0.41229248, 0.373657227
};
diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c
index 5e4b49a..e2e3a54 100644
--- a/libavcodec/ratecontrol.c
+++ b/libavcodec/ratecontrol.c
@@ -508,14 +508,6 @@ static double predict_size(Predictor *p, double q, double var)
return p->coeff*var / (q*p->count);
}
-/*
-static double predict_qp(Predictor *p, double size, double var)
-{
-//printf("coeff:%f, count:%f, var:%f, size:%f//\n", p->coeff, p->count, var, size);
- return p->coeff*var / (size*p->count);
-}
-*/
-
static void update_predictor(Predictor *p, double q, double var, double size)
{
double new_coeff= size*q / (var + 1);
@@ -537,8 +529,8 @@ static void adaptive_quantization(MpegEncContext *s, double q){
const float border_masking = s->avctx->border_masking;
float bits_sum= 0.0;
float cplx_sum= 0.0;
- float cplx_tab[s->mb_num];
- float bits_tab[s->mb_num];
+ float *cplx_tab = s->cplx_tab;
+ float *bits_tab = s->bits_tab;
const int qmin= s->avctx->mb_lmin;
const int qmax= s->avctx->mb_lmax;
Picture * const pic= &s->current_picture;
@@ -555,10 +547,6 @@ static void adaptive_quantization(MpegEncContext *s, double q){
int mb_y = mb_xy / s->mb_stride;
int mb_distance;
float mb_factor = 0.0;
-#if 0
- if(spat_cplx < q/3) spat_cplx= q/3; //FIXME finetune
- if(temp_cplx < q/3) temp_cplx= q/3; //FIXME finetune
-#endif
if(spat_cplx < 4) spat_cplx= 4; //FIXME finetune
if(temp_cplx < 4) temp_cplx= 4; //FIXME finetune
diff --git a/libavcodec/rl2.c b/libavcodec/rl2.c
index 9b21bb6..4d1937a 100644
--- a/libavcodec/rl2.c
+++ b/libavcodec/rl2.c
@@ -64,7 +64,7 @@ static void rl2_rle_decode(Rl2Context *s,const unsigned char* in,int size,
const unsigned char* back_frame = s->back_frame;
const unsigned char* in_end = in + size;
const unsigned char* out_end = out + stride * s->avctx->height;
- unsigned char* line_end = out + s->avctx->width;
+ unsigned char* line_end;
/** copy start of the background frame */
for(i=0;i<=base_y;i++){
diff --git a/libavcodec/roqvideo.h b/libavcodec/roqvideo.h
index fba3d41..4018e35 100644
--- a/libavcodec/roqvideo.h
+++ b/libavcodec/roqvideo.h
@@ -45,7 +45,6 @@ struct RoqTempData;
typedef struct RoqContext {
AVCodecContext *avctx;
- DSPContext dsp;
AVFrame frames[2];
AVFrame *last_frame;
AVFrame *current_frame;
diff --git a/libavcodec/sbr.h b/libavcodec/sbr.h
index 459ee9c..228b158 100644
--- a/libavcodec/sbr.h
+++ b/libavcodec/sbr.h
@@ -78,8 +78,8 @@ typedef struct {
* @name State variables
* @{
*/
- DECLARE_ALIGNED(16, float, synthesis_filterbank_samples)[SBR_SYNTHESIS_BUF_SIZE];
- DECLARE_ALIGNED(16, float, analysis_filterbank_samples) [1312];
+ DECLARE_ALIGNED(32, float, synthesis_filterbank_samples)[SBR_SYNTHESIS_BUF_SIZE];
+ DECLARE_ALIGNED(32, float, analysis_filterbank_samples) [1312];
int synthesis_filterbank_samples_offset;
///l_APrev and l_A
int e_a[2];
@@ -180,7 +180,7 @@ typedef struct {
///Sinusoidal levels
float s_m[7][48];
float gain[7][48];
- DECLARE_ALIGNED(16, float, qmf_filter_scratch)[5][64];
+ DECLARE_ALIGNED(32, float, qmf_filter_scratch)[5][64];
FFTContext mdct_ana;
FFTContext mdct;
SBRDSPContext dsp;
diff --git a/libavcodec/sinewin.h b/libavcodec/sinewin.h
index 8054191..478036d 100644
--- a/libavcodec/sinewin.h
+++ b/libavcodec/sinewin.h
@@ -31,7 +31,7 @@
#endif
#define SINETABLE(size) \
- SINETABLE_CONST DECLARE_ALIGNED(16, float, ff_sine_##size)[size]
+ SINETABLE_CONST DECLARE_ALIGNED(32, float, ff_sine_##size)[size]
/**
* Generate a sine window.
diff --git a/libavcodec/sinewin_tablegen.c b/libavcodec/sinewin_tablegen.c
index d5e0689..90a75c2 100644
--- a/libavcodec/sinewin_tablegen.c
+++ b/libavcodec/sinewin_tablegen.c
@@ -26,9 +26,6 @@
#define SINETABLE(size) \
float ff_sine_##size[size]
#define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
#include "sinewin_tablegen.h"
#include "tableprint.h"
diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c
index 43c206f..32ce48f 100644
--- a/libavcodec/smacker.c
+++ b/libavcodec/smacker.c
@@ -133,13 +133,9 @@ static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx
return -1;
}
if(!get_bits1(gb)){ //Leaf
- int val, i1, i2, b1, b2;
- b1 = get_bits_count(gb);
+ int val, i1, i2;
i1 = ctx->v1->table ? get_vlc2(gb, ctx->v1->table, SMKTREE_BITS, 3) : 0;
- b1 = get_bits_count(gb) - b1;
- b2 = get_bits_count(gb);
i2 = ctx->v2->table ? get_vlc2(gb, ctx->v2->table, SMKTREE_BITS, 3) : 0;
- b2 = get_bits_count(gb) - b2;
if (i1 < 0 || i2 < 0)
return -1;
val = ctx->recode1[i1] | (ctx->recode2[i2] << 8);
diff --git a/libavcodec/snow.c b/libavcodec/snow.c
index 384cda8..d69f452 100644
--- a/libavcodec/snow.c
+++ b/libavcodec/snow.c
@@ -143,7 +143,7 @@ static void mc_block(Plane *p, uint8_t *dst, const uint8_t *src, int stride, int
int x, y, b, r, l;
int16_t tmpIt [64*(32+HTAPS_MAX)];
- uint8_t tmp2t[3][stride*(32+HTAPS_MAX)];
+ uint8_t tmp2t[3][64*(32+HTAPS_MAX)];
int16_t *tmpI= tmpIt;
uint8_t *tmp2= tmp2t[0];
const uint8_t *hpel[11];
@@ -181,7 +181,7 @@ static void mc_block(Plane *p, uint8_t *dst, const uint8_t *src, int stride, int
tmp2[x]= am;
}
tmpI+= 64;
- tmp2+= stride;
+ tmp2+= 64;
src += stride;
}
src -= stride*y;
@@ -210,7 +210,7 @@ static void mc_block(Plane *p, uint8_t *dst, const uint8_t *src, int stride, int
tmp2[x]= am;
}
src += stride;
- tmp2+= stride;
+ tmp2+= 64;
}
src -= stride*y;
}
@@ -237,12 +237,12 @@ static void mc_block(Plane *p, uint8_t *dst, const uint8_t *src, int stride, int
tmp2[x]= am;
}
tmpI+= 64;
- tmp2+= stride;
+ tmp2+= 64;
}
}
hpel[ 0]= src;
- hpel[ 1]= tmp2t[0] + stride*(HTAPS_MAX/2-1);
+ hpel[ 1]= tmp2t[0] + 64*(HTAPS_MAX/2-1);
hpel[ 2]= src + 1;
hpel[ 4]= tmp2t[1];
@@ -250,14 +250,21 @@ static void mc_block(Plane *p, uint8_t *dst, const uint8_t *src, int stride, int
hpel[ 6]= tmp2t[1] + 1;
hpel[ 8]= src + stride;
- hpel[ 9]= hpel[1] + stride;
+ hpel[ 9]= hpel[1] + 64;
hpel[10]= hpel[8] + 1;
+#define MC_STRIDE(x) (needs[x] ? 64 : stride)
+
if(b==15){
- const uint8_t *src1= hpel[dx/8 + dy/8*4 ];
- const uint8_t *src2= hpel[dx/8 + dy/8*4+1];
- const uint8_t *src3= hpel[dx/8 + dy/8*4+4];
- const uint8_t *src4= hpel[dx/8 + dy/8*4+5];
+ int dxy = dx / 8 + dy / 8 * 4;
+ const uint8_t *src1 = hpel[dxy ];
+ const uint8_t *src2 = hpel[dxy + 1];
+ const uint8_t *src3 = hpel[dxy + 4];
+ const uint8_t *src4 = hpel[dxy + 5];
+ int stride1 = MC_STRIDE(dxy);
+ int stride2 = MC_STRIDE(dxy + 1);
+ int stride3 = MC_STRIDE(dxy + 4);
+ int stride4 = MC_STRIDE(dxy + 5);
dx&=7;
dy&=7;
for(y=0; y < b_h; y++){
@@ -265,23 +272,25 @@ static void mc_block(Plane *p, uint8_t *dst, const uint8_t *src, int stride, int
dst[x]= ((8-dx)*(8-dy)*src1[x] + dx*(8-dy)*src2[x]+
(8-dx)* dy *src3[x] + dx* dy *src4[x]+32)>>6;
}
- src1+=stride;
- src2+=stride;
- src3+=stride;
- src4+=stride;
+ src1+=stride1;
+ src2+=stride2;
+ src3+=stride3;
+ src4+=stride4;
dst +=stride;
}
}else{
const uint8_t *src1= hpel[l];
const uint8_t *src2= hpel[r];
+ int stride1 = MC_STRIDE(l);
+ int stride2 = MC_STRIDE(r);
int a= weight[((dx&7) + (8*(dy&7)))];
int b= 8-a;
for(y=0; y < b_h; y++){
for(x=0; x < b_w; x++){
dst[x]= (a*src1[x] + b*src2[x] + 4)>>3;
}
- src1+=stride;
- src2+=stride;
+ src1+=stride1;
+ src2+=stride2;
dst +=stride;
}
}
@@ -385,7 +394,8 @@ mca( 8, 8,8)
av_cold int ff_snow_common_init(AVCodecContext *avctx){
SnowContext *s = avctx->priv_data;
int width, height;
- int i, j;
+ int i, j, ret;
+ int emu_buf_size;
s->avctx= avctx;
s->max_ref_frames=1; //just make sure its not an invalid value in case of no initial keyframe
@@ -438,17 +448,27 @@ av_cold int ff_snow_common_init(AVCodecContext *avctx){
width= s->avctx->width;
height= s->avctx->height;
- s->spatial_idwt_buffer= av_mallocz(width*height*sizeof(IDWTELEM));
- s->spatial_dwt_buffer= av_mallocz(width*height*sizeof(DWTELEM)); //FIXME this does not belong here
+ FF_ALLOCZ_OR_GOTO(avctx, s->spatial_idwt_buffer, width * height * sizeof(IDWTELEM), fail);
+ FF_ALLOCZ_OR_GOTO(avctx, s->spatial_dwt_buffer, width * height * sizeof(DWTELEM), fail); //FIXME this does not belong here
+ FF_ALLOCZ_OR_GOTO(avctx, s->temp_dwt_buffer, width * sizeof(DWTELEM), fail);
+ FF_ALLOCZ_OR_GOTO(avctx, s->temp_idwt_buffer, width * sizeof(IDWTELEM), fail);
+ FF_ALLOC_OR_GOTO(avctx, s->run_buffer, ((width + 1) >> 1) * ((height + 1) >> 1) * sizeof(*s->run_buffer), fail);
for(i=0; i<MAX_REF_FRAMES; i++)
for(j=0; j<MAX_REF_FRAMES; j++)
ff_scale_mv_ref[i][j] = 256*(i+1)/(j+1);
- s->avctx->get_buffer(s->avctx, &s->mconly_picture);
- s->scratchbuf = av_malloc(s->mconly_picture.linesize[0]*7*MB_SIZE);
+ if ((ret = s->avctx->get_buffer(s->avctx, &s->mconly_picture)) < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ FF_ALLOC_OR_GOTO(avctx, s->scratchbuf, s->mconly_picture.linesize[0]*7*MB_SIZE, fail);
+ emu_buf_size = s->mconly_picture.linesize[0] * (2 * MB_SIZE + HTAPS_MAX - 1);
+ FF_ALLOC_OR_GOTO(avctx, s->emu_edge_buffer, emu_buf_size, fail);
return 0;
+fail:
+ return AVERROR(ENOMEM);
}
int ff_snow_common_init_after_header(AVCodecContext *avctx) {
@@ -618,7 +638,10 @@ av_cold void ff_snow_common_end(SnowContext *s)
int plane_index, level, orientation, i;
av_freep(&s->spatial_dwt_buffer);
+ av_freep(&s->temp_dwt_buffer);
av_freep(&s->spatial_idwt_buffer);
+ av_freep(&s->temp_idwt_buffer);
+ av_freep(&s->run_buffer);
s->m.me.temp= NULL;
av_freep(&s->m.me.scratchpad);
@@ -628,6 +651,7 @@ av_cold void ff_snow_common_end(SnowContext *s)
av_freep(&s->block);
av_freep(&s->scratchbuf);
+ av_freep(&s->emu_edge_buffer);
for(i=0; i<MAX_REF_FRAMES; i++){
av_freep(&s->ref_mvs[i]);
diff --git a/libavcodec/snow.h b/libavcodec/snow.h
index 5edb8f8..abf3309 100644
--- a/libavcodec/snow.h
+++ b/libavcodec/snow.h
@@ -132,7 +132,10 @@ typedef struct SnowContext{
int16_t (*ref_mvs[MAX_REF_FRAMES])[2];
uint32_t *ref_scores[MAX_REF_FRAMES];
DWTELEM *spatial_dwt_buffer;
+ DWTELEM *temp_dwt_buffer;
IDWTELEM *spatial_idwt_buffer;
+ IDWTELEM *temp_idwt_buffer;
+ int *run_buffer;
int colorspace_type;
int chroma_h_shift;
int chroma_v_shift;
@@ -162,6 +165,7 @@ typedef struct SnowContext{
MpegEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to eventually make the motion estimation independent of MpegEncContext, so this will be removed then (FIXME/XXX)
uint8_t *scratchbuf;
+ uint8_t *emu_edge_buffer;
}SnowContext;
/* Tables */
diff --git a/libavcodec/snowdec.c b/libavcodec/snowdec.c
index ef5205d..9ea8c49 100644
--- a/libavcodec/snowdec.c
+++ b/libavcodec/snowdec.c
@@ -354,9 +354,14 @@ static int decode_header(SnowContext *s){
static av_cold int decode_init(AVCodecContext *avctx)
{
+ int ret;
+
avctx->pix_fmt= PIX_FMT_YUV420P;
- ff_snow_common_init(avctx);
+ if ((ret = ff_snow_common_init(avctx)) < 0) {
+ ff_snow_common_end(avctx->priv_data);
+ return ret;
+ }
return 0;
}
@@ -396,7 +401,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
// realloc slice buffer for the case that spatial_decomposition_count changed
ff_slice_buffer_destroy(&s->sb);
- ff_slice_buffer_init(&s->sb, s->plane[0].height, (MB_SIZE >> s->block_max_depth) + s->spatial_decomposition_count * 8 + 1, s->plane[0].width, s->spatial_idwt_buffer);
+ if ((res = ff_slice_buffer_init(&s->sb, s->plane[0].height,
+ (MB_SIZE >> s->block_max_depth) +
+ s->spatial_decomposition_count * 8 + 1,
+ s->plane[0].width,
+ s->spatial_idwt_buffer)) < 0)
+ return res;
for(plane_index=0; plane_index<3; plane_index++){
Plane *p= &s->plane[plane_index];
@@ -497,7 +507,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
}
for(; yd<slice_h; yd+=4){
- ff_spatial_idwt_buffered_slice(&s->dwt, cs, &s->sb, w, h, 1, s->spatial_decomposition_type, s->spatial_decomposition_count, yd);
+ ff_spatial_idwt_buffered_slice(&s->dwt, cs, &s->sb, s->temp_idwt_buffer, w, h, 1, s->spatial_decomposition_type, s->spatial_decomposition_count, yd);
}
if(s->qlog == LOSSLESS_QLOG){
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
index 7b010e1..f732820 100644
--- a/libavcodec/snowenc.c
+++ b/libavcodec/snowenc.c
@@ -93,7 +93,7 @@ static void dwt_quantize(SnowContext *s, Plane *p, DWTELEM *buffer, int width, i
//FIXME pass the copy cleanly ?
// memcpy(dwt_buffer, buffer, height * stride * sizeof(DWTELEM));
- ff_spatial_dwt(buffer, width, height, stride, type, s->spatial_decomposition_count);
+ ff_spatial_dwt(buffer, s->temp_dwt_buffer, width, height, stride, type, s->spatial_decomposition_count);
for(level=0; level<s->spatial_decomposition_count; level++){
for(orientation=level ? 1 : 0; orientation<4; orientation++){
@@ -118,7 +118,7 @@ static void dwt_quantize(SnowContext *s, Plane *p, DWTELEM *buffer, int width, i
for(xs= 0; xs<Q2_STEP; xs++){
memcpy(idwt2_buffer, best_dequant, height * stride * sizeof(IDWTELEM));
dequantize_all(s, p, idwt2_buffer, width, height);
- ff_spatial_idwt(idwt2_buffer, width, height, stride, type, s->spatial_decomposition_count);
+ ff_spatial_idwt(idwt2_buffer, s->temp_idwt_buffer, width, height, stride, type, s->spatial_decomposition_count);
find_sse(s, p, best_score, score_stride, idwt2_buffer, s->spatial_idwt_buffer, level, orientation);
memcpy(idwt2_buffer, best_dequant, height * stride * sizeof(IDWTELEM));
for(y=ys; y<b->height; y+= Q2_STEP){
@@ -129,7 +129,7 @@ static void dwt_quantize(SnowContext *s, Plane *p, DWTELEM *buffer, int width, i
}
}
dequantize_all(s, p, idwt2_buffer, width, height);
- ff_spatial_idwt(idwt2_buffer, width, height, stride, type, s->spatial_decomposition_count);
+ ff_spatial_idwt(idwt2_buffer, s->temp_idwt_buffer, width, height, stride, type, s->spatial_decomposition_count);
find_sse(s, p, score, score_stride, idwt2_buffer, s->spatial_idwt_buffer, level, orientation);
for(y=ys; y<b->height; y+= Q2_STEP){
for(x=xs; x<b->width; x+= Q2_STEP){
@@ -155,7 +155,7 @@ static void dwt_quantize(SnowContext *s, Plane *p, DWTELEM *buffer, int width, i
static av_cold int encode_init(AVCodecContext *avctx)
{
SnowContext *s = avctx->priv_data;
- int plane_index;
+ int plane_index, ret;
if(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){
av_log(avctx, AV_LOG_ERROR, "This codec is under development, files encoded with it may not be decodable with future versions!!!\n"
@@ -184,7 +184,10 @@ static av_cold int encode_init(AVCodecContext *avctx)
s->plane[plane_index].fast_mc= 1;
}
- ff_snow_common_init(avctx);
+ if ((ret = ff_snow_common_init(avctx)) < 0) {
+ ff_snow_common_end(avctx->priv_data);
+ return ret;
+ }
ff_snow_alloc_blocks(s);
s->version=0;
@@ -662,7 +665,7 @@ static inline int get_block_bits(SnowContext *s, int x, int y, int w){
}
}
-static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, const uint8_t *obmc_edged){
+static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, uint8_t (*obmc_edged)[MB_SIZE * 2]){
Plane *p= &s->plane[plane_index];
const int block_size = MB_SIZE >> s->block_max_depth;
const int block_w = plane_index ? block_size/2 : block_size;
@@ -672,7 +675,7 @@ static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, con
uint8_t *src= s-> input_picture.data[plane_index];
IDWTELEM *pred= (IDWTELEM*)s->m.obmc_scratchpad + plane_index*block_size*block_size*4;
uint8_t *cur = s->scratchbuf;
- uint8_t tmp[ref_stride*(2*MB_SIZE+HTAPS_MAX-1)];
+ uint8_t *tmp = s->emu_edge_buffer;
const int b_stride = s->b_width << s->block_max_depth;
const int b_height = s->b_height<< s->block_max_depth;
const int w= p->width;
@@ -691,7 +694,7 @@ static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, con
ff_snow_pred_block(s, cur, tmp, ref_stride, sx, sy, block_w*2, block_w*2, &s->block[mb_x + mb_y*b_stride], plane_index, w, h);
for(y=y0; y<y1; y++){
- const uint8_t *obmc1= obmc_edged + y*obmc_stride;
+ const uint8_t *obmc1= obmc_edged[y];
const IDWTELEM *pred1 = pred + y*obmc_stride;
uint8_t *cur1 = cur + y*ref_stride;
uint8_t *dst1 = dst + sx + (sy+y)*ref_stride;
@@ -833,7 +836,7 @@ static int encode_subband_c0run(SnowContext *s, SubBand *b, IDWTELEM *src, IDWTE
if(1){
int run=0;
- int runs[w*h];
+ int *runs = s->run_buffer;
int run_index=0;
int max_index;
@@ -953,7 +956,7 @@ static int encode_subband(SnowContext *s, SubBand *b, IDWTELEM *src, IDWTELEM *p
// encode_subband_dzr(s, b, src, parent, stride, orientation);
}
-static av_always_inline int check_block(SnowContext *s, int mb_x, int mb_y, int p[3], int intra, const uint8_t *obmc_edged, int *best_rd){
+static av_always_inline int check_block(SnowContext *s, int mb_x, int mb_y, int p[3], int intra, uint8_t (*obmc_edged)[MB_SIZE * 2], int *best_rd){
const int b_stride= s->b_width << s->block_max_depth;
BlockNode *block= &s->block[mb_x + mb_y * b_stride];
BlockNode backup= *block;
@@ -994,7 +997,7 @@ static av_always_inline int check_block(SnowContext *s, int mb_x, int mb_y, int
/* special case for int[2] args we discard afterwards,
* fixes compilation problem with gcc 2.95 */
-static av_always_inline int check_block_inter(SnowContext *s, int mb_x, int mb_y, int p0, int p1, const uint8_t *obmc_edged, int *best_rd){
+static av_always_inline int check_block_inter(SnowContext *s, int mb_x, int mb_y, int p0, int p1, uint8_t (*obmc_edged)[MB_SIZE * 2], int *best_rd){
int p[2] = {p0, p1};
return check_block(s, mb_x, mb_y, p, 0, obmc_edged, best_rd);
}
@@ -1074,7 +1077,7 @@ static void iterative_me(SnowContext *s){
BlockNode *blb= mb_x && mb_y+1<b_height ? &s->block[index+b_stride-1] : NULL;
BlockNode *brb= mb_x+1<b_width && mb_y+1<b_height ? &s->block[index+b_stride+1] : NULL;
const int b_w= (MB_SIZE >> s->block_max_depth);
- uint8_t obmc_edged[b_w*2][b_w*2];
+ uint8_t obmc_edged[MB_SIZE * 2][MB_SIZE * 2];
if(pass && (block->type & BLOCK_OPT))
continue;
@@ -1089,7 +1092,8 @@ static void iterative_me(SnowContext *s){
//FIXME precalculate
{
int x, y;
- memcpy(obmc_edged, ff_obmc_tab[s->block_max_depth], b_w*b_w*4);
+ for (y = 0; y < b_w * 2; y++)
+ memcpy(obmc_edged[y], ff_obmc_tab[s->block_max_depth] + y * b_w * 2, b_w * 2);
if(mb_x==0)
for(y=0; y<b_w*2; y++)
memset(obmc_edged[y], obmc_edged[y][0] + obmc_edged[y][b_w-1], b_w);
@@ -1143,9 +1147,9 @@ static void iterative_me(SnowContext *s){
// get previous score (cannot be cached due to OBMC)
if(pass > 0 && (block->type&BLOCK_INTRA)){
int color0[3]= {block->color[0], block->color[1], block->color[2]};
- check_block(s, mb_x, mb_y, color0, 1, *obmc_edged, &best_rd);
+ check_block(s, mb_x, mb_y, color0, 1, obmc_edged, &best_rd);
}else
- check_block_inter(s, mb_x, mb_y, block->mx, block->my, *obmc_edged, &best_rd);
+ check_block_inter(s, mb_x, mb_y, block->mx, block->my, obmc_edged, &best_rd);
ref_b= *block;
ref_rd= best_rd;
@@ -1156,16 +1160,16 @@ static void iterative_me(SnowContext *s){
block->ref= ref;
best_rd= INT_MAX;
- check_block_inter(s, mb_x, mb_y, mvr[0][0], mvr[0][1], *obmc_edged, &best_rd);
- check_block_inter(s, mb_x, mb_y, 0, 0, *obmc_edged, &best_rd);
+ check_block_inter(s, mb_x, mb_y, mvr[0][0], mvr[0][1], obmc_edged, &best_rd);
+ check_block_inter(s, mb_x, mb_y, 0, 0, obmc_edged, &best_rd);
if(tb)
- check_block_inter(s, mb_x, mb_y, mvr[-b_stride][0], mvr[-b_stride][1], *obmc_edged, &best_rd);
+ check_block_inter(s, mb_x, mb_y, mvr[-b_stride][0], mvr[-b_stride][1], obmc_edged, &best_rd);
if(lb)
- check_block_inter(s, mb_x, mb_y, mvr[-1][0], mvr[-1][1], *obmc_edged, &best_rd);
+ check_block_inter(s, mb_x, mb_y, mvr[-1][0], mvr[-1][1], obmc_edged, &best_rd);
if(rb)
- check_block_inter(s, mb_x, mb_y, mvr[1][0], mvr[1][1], *obmc_edged, &best_rd);
+ check_block_inter(s, mb_x, mb_y, mvr[1][0], mvr[1][1], obmc_edged, &best_rd);
if(bb)
- check_block_inter(s, mb_x, mb_y, mvr[b_stride][0], mvr[b_stride][1], *obmc_edged, &best_rd);
+ check_block_inter(s, mb_x, mb_y, mvr[b_stride][0], mvr[b_stride][1], obmc_edged, &best_rd);
/* fullpel ME */
//FIXME avoid subpel interpolation / round to nearest integer
@@ -1173,10 +1177,10 @@ static void iterative_me(SnowContext *s){
dia_change=0;
for(i=0; i<FFMAX(s->avctx->dia_size, 1); i++){
for(j=0; j<i; j++){
- dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+4*(i-j), block->my+(4*j), *obmc_edged, &best_rd);
- dia_change |= check_block_inter(s, mb_x, mb_y, block->mx-4*(i-j), block->my-(4*j), *obmc_edged, &best_rd);
- dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+4*(i-j), block->my-(4*j), *obmc_edged, &best_rd);
- dia_change |= check_block_inter(s, mb_x, mb_y, block->mx-4*(i-j), block->my+(4*j), *obmc_edged, &best_rd);
+ dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+4*(i-j), block->my+(4*j), obmc_edged, &best_rd);
+ dia_change |= check_block_inter(s, mb_x, mb_y, block->mx-4*(i-j), block->my-(4*j), obmc_edged, &best_rd);
+ dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+4*(i-j), block->my-(4*j), obmc_edged, &best_rd);
+ dia_change |= check_block_inter(s, mb_x, mb_y, block->mx-4*(i-j), block->my+(4*j), obmc_edged, &best_rd);
}
}
}while(dia_change);
@@ -1185,7 +1189,7 @@ static void iterative_me(SnowContext *s){
static const int square[8][2]= {{+1, 0},{-1, 0},{ 0,+1},{ 0,-1},{+1,+1},{-1,-1},{+1,-1},{-1,+1},};
dia_change=0;
for(i=0; i<8; i++)
- dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+square[i][0], block->my+square[i][1], *obmc_edged, &best_rd);
+ dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+square[i][0], block->my+square[i][1], obmc_edged, &best_rd);
}while(dia_change);
//FIXME or try the standard 2 pass qpel or similar
@@ -1198,7 +1202,7 @@ static void iterative_me(SnowContext *s){
}
best_rd= ref_rd;
*block= ref_b;
- check_block(s, mb_x, mb_y, color, 1, *obmc_edged, &best_rd);
+ check_block(s, mb_x, mb_y, color, 1, obmc_edged, &best_rd);
//FIXME RD style color selection
if(!same_block(block, &backup)){
if(tb ) tb ->type &= ~BLOCK_OPT;
@@ -1586,7 +1590,7 @@ static void calculate_visual_weight(SnowContext *s, Plane *p){
memset(s->spatial_idwt_buffer, 0, sizeof(*s->spatial_idwt_buffer)*width*height);
ibuf[b->width/2 + b->height/2*b->stride]= 256*16;
- ff_spatial_idwt(s->spatial_idwt_buffer, width, height, width, s->spatial_decomposition_type, s->spatial_decomposition_count);
+ ff_spatial_idwt(s->spatial_idwt_buffer, s->temp_idwt_buffer, width, height, width, s->spatial_decomposition_type, s->spatial_decomposition_count);
for(y=0; y<height; y++){
for(x=0; x<width; x++){
int64_t d= s->spatial_idwt_buffer[x + y*width]*16;
@@ -1775,7 +1779,7 @@ redo_frame:
/* if(QUANTIZE2)
dwt_quantize(s, p, s->spatial_dwt_buffer, w, h, w, s->spatial_decomposition_type);
else*/
- ff_spatial_dwt(s->spatial_dwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count);
+ ff_spatial_dwt(s->spatial_dwt_buffer, s->temp_dwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count);
if(s->pass1_rc && plane_index==0){
int delta_qlog = ratecontrol_1pass(s, pic);
@@ -1814,7 +1818,7 @@ redo_frame:
}
}
- ff_spatial_idwt(s->spatial_idwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count);
+ ff_spatial_idwt(s->spatial_idwt_buffer, s->temp_idwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count);
if(s->qlog == LOSSLESS_QLOG){
for(y=0; y<h; y++){
for(x=0; x<w; x++){
diff --git a/libavcodec/truemotion1.c b/libavcodec/truemotion1.c
index 9e1168a..bc501a2 100644
--- a/libavcodec/truemotion1.c
+++ b/libavcodec/truemotion1.c
@@ -354,14 +354,7 @@ static int truemotion1_decode_header(TrueMotion1Context *s)
if (s->flags & FLAG_SPRITE) {
av_log_ask_for_sample(s->avctx, "SPRITE frame found.\n");
/* FIXME header.width, height, xoffset and yoffset aren't initialized */
-#if 0
- s->w = header.width;
- s->h = header.height;
- s->x = header.xoffset;
- s->y = header.yoffset;
-#else
return -1;
-#endif
} else {
s->w = header.xsize;
s->h = header.ysize;
diff --git a/libavcodec/tta.c b/libavcodec/tta.c
index acaeaaa..0650086 100644
--- a/libavcodec/tta.c
+++ b/libavcodec/tta.c
@@ -61,7 +61,8 @@ typedef struct TTAContext {
GetBitContext gb;
const AVCRC *crc_table;
- int format, channels, bps, data_length;
+ int format, channels, bps;
+ unsigned data_length;
int frame_length, last_frame_length, total_frames;
int32_t *decode_buffer;
@@ -253,7 +254,7 @@ static av_cold int tta_decode_init(AVCodecContext * avctx)
}
// prevent overflow
- if (avctx->sample_rate > 0x7FFFFF) {
+ if (avctx->sample_rate > 0x7FFFFFu) {
av_log(avctx, AV_LOG_ERROR, "sample_rate too large\n");
return AVERROR(EINVAL);
}
@@ -270,7 +271,8 @@ static av_cold int tta_decode_init(AVCodecContext * avctx)
s->data_length, s->frame_length, s->last_frame_length, s->total_frames);
// FIXME: seek table
- if (get_bits_left(&s->gb) < 32 * s->total_frames + 32)
+ if (avctx->extradata_size <= 26 || s->total_frames > INT_MAX / 4 ||
+ avctx->extradata_size - 26 < s->total_frames * 4)
av_log(avctx, AV_LOG_WARNING, "Seek table missing or too small\n");
else if (avctx->err_recognition & AV_EF_CRCCHECK) {
if (tta_check_crc(s, avctx->extradata + 22, s->total_frames * 4))
@@ -414,7 +416,7 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data,
if (cur_chan < (s->channels-1))
cur_chan++;
else {
- // decorrelate in case of stereo integer
+ // decorrelate in case of multiple channels
if (s->channels > 1) {
int32_t *r = p - 1;
for (*p += *r / 2; r > p - s->channels; r--)
diff --git a/libavcodec/twinvq.c b/libavcodec/twinvq.c
index 1577d77..4421074 100644
--- a/libavcodec/twinvq.c
+++ b/libavcodec/twinvq.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/float_dsp.h"
#include "avcodec.h"
#include "get_bits.h"
#include "dsputil.h"
@@ -176,6 +177,7 @@ typedef struct TwinContext {
AVCodecContext *avctx;
AVFrame frame;
DSPContext dsp;
+ AVFloatDSPContext fdsp;
FFTContext mdct_ctx[3];
const ModeTab *mtab;
@@ -787,8 +789,8 @@ static void read_and_decode_spectrum(TwinContext *tctx, GetBitContext *gb,
dec_bark_env(tctx, bark1[i][j], bark_use_hist[i][j], i,
tctx->tmp_buf, gain[sub*i+j], ftype);
- tctx->dsp.vector_fmul(chunk + block_size*j, chunk + block_size*j, tctx->tmp_buf,
- block_size);
+ tctx->fdsp.vector_fmul(chunk + block_size*j, chunk + block_size*j,
+ tctx->tmp_buf, block_size);
}
@@ -809,7 +811,7 @@ static void read_and_decode_spectrum(TwinContext *tctx, GetBitContext *gb,
dec_lpc_spectrum_inv(tctx, lsp, ftype, tctx->tmp_buf);
for (j = 0; j < mtab->fmode[ftype].sub; j++) {
- tctx->dsp.vector_fmul(chunk, chunk, tctx->tmp_buf, block_size);
+ tctx->fdsp.vector_fmul(chunk, chunk, tctx->tmp_buf, block_size);
chunk += block_size;
}
}
@@ -1000,14 +1002,16 @@ static av_cold void construct_perm_table(TwinContext *tctx,enum FrameType ftype)
{
int block_size;
const ModeTab *mtab = tctx->mtab;
- int size = tctx->avctx->channels*mtab->fmode[ftype].sub;
+ int size;
int16_t *tmp_perm = (int16_t *) tctx->tmp_buf;
if (ftype == FT_PPC) {
size = tctx->avctx->channels;
block_size = mtab->ppc_shape_len;
- } else
+ } else {
+ size = tctx->avctx->channels * mtab->fmode[ftype].sub;
block_size = mtab->size / mtab->fmode[ftype].sub;
+ }
permutate_in_line(tmp_perm, tctx->n_div[ftype], size,
block_size, tctx->length[ftype],
@@ -1154,6 +1158,7 @@ static av_cold int twin_decode_init(AVCodecContext *avctx)
}
ff_dsputil_init(&tctx->dsp, avctx);
+ avpriv_float_dsp_init(&tctx->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
if ((ret = init_mdct_win(tctx))) {
av_log(avctx, AV_LOG_ERROR, "Error initializing MDCT\n");
twin_decode_close(avctx);
diff --git a/libavcodec/twinvq_data.h b/libavcodec/twinvq_data.h
index 1f1f334..a236127 100644
--- a/libavcodec/twinvq_data.h
+++ b/libavcodec/twinvq_data.h
@@ -135,7 +135,7 @@ static const uint16_t bark_tab_s44_128[] = {
*
* without risking a segfault on malformed files.
*/
-static const struct {
+static const struct twinvq_data {
float lsp08[504];
int16_t fcb08l[640];
int16_t fcb08m[320];
diff --git a/libavcodec/txd.c b/libavcodec/txd.c
index bfb2bb6..d69f9fa 100644
--- a/libavcodec/txd.c
+++ b/libavcodec/txd.c
@@ -46,7 +46,7 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
GetByteContext gb;
AVFrame *picture = data;
AVFrame * const p = &s->picture;
- unsigned int version, w, h, d3d_format, depth, stride, mipmap_count, flags;
+ unsigned int version, w, h, d3d_format, depth, stride, flags;
unsigned int y, v;
uint8_t *ptr;
uint32_t *pal;
@@ -58,8 +58,7 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
w = bytestream2_get_le16(&gb);
h = bytestream2_get_le16(&gb);
depth = bytestream2_get_byte(&gb);
- mipmap_count = bytestream2_get_byte(&gb);
- bytestream2_skip(&gb, 1);
+ bytestream2_skip(&gb, 2);
flags = bytestream2_get_byte(&gb);
if (version < 8 || version > 9) {
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 4492486..514a1f5 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -356,6 +356,10 @@ static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame)
else frame->pkt_pts = AV_NOPTS_VALUE;
frame->reordered_opaque = avctx->reordered_opaque;
+ frame->sample_rate = avctx->sample_rate;
+ frame->format = avctx->sample_fmt;
+ frame->channel_layout = avctx->channel_layout;
+
if (avctx->debug & FF_DEBUG_BUFFERS)
av_log(avctx, AV_LOG_DEBUG, "default_get_buffer called on frame %p, "
"internal audio buffer used\n", frame);
@@ -853,41 +857,110 @@ int ff_alloc_packet(AVPacket *avpkt, int size)
}
}
+/**
+ * Pad last frame with silence.
+ */
+static int pad_last_frame(AVCodecContext *s, AVFrame **dst, const AVFrame *src)
+{
+ AVFrame *frame = NULL;
+ uint8_t *buf = NULL;
+ int ret;
+
+ if (!(frame = avcodec_alloc_frame()))
+ return AVERROR(ENOMEM);
+ *frame = *src;
+
+ if ((ret = av_samples_get_buffer_size(&frame->linesize[0], s->channels,
+ s->frame_size, s->sample_fmt, 0)) < 0)
+ goto fail;
+
+ if (!(buf = av_malloc(ret))) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ frame->nb_samples = s->frame_size;
+ if ((ret = avcodec_fill_audio_frame(frame, s->channels, s->sample_fmt,
+ buf, ret, 0)) < 0)
+ goto fail;
+ if ((ret = av_samples_copy(frame->extended_data, src->extended_data, 0, 0,
+ src->nb_samples, s->channels, s->sample_fmt)) < 0)
+ goto fail;
+ if ((ret = av_samples_set_silence(frame->extended_data, src->nb_samples,
+ frame->nb_samples - src->nb_samples,
+ s->channels, s->sample_fmt)) < 0)
+ goto fail;
+
+ *dst = frame;
+
+ return 0;
+
+fail:
+ if (frame->extended_data != frame->data)
+ av_freep(&frame->extended_data);
+ av_freep(&buf);
+ av_freep(&frame);
+ return ret;
+}
+
int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx,
AVPacket *avpkt,
const AVFrame *frame,
int *got_packet_ptr)
{
+ AVFrame tmp;
+ AVFrame *padded_frame = NULL;
int ret;
int user_packet = !!avpkt->data;
- int nb_samples;
*got_packet_ptr = 0;
if (!(avctx->codec->capabilities & CODEC_CAP_DELAY) && !frame) {
av_free_packet(avpkt);
av_init_packet(avpkt);
- avpkt->size = 0;
return 0;
}
+ /* ensure that extended_data is properly set */
+ if (frame && !frame->extended_data) {
+ if (av_sample_fmt_is_planar(avctx->sample_fmt) &&
+ avctx->channels > AV_NUM_DATA_POINTERS) {
+ av_log(avctx, AV_LOG_ERROR, "Encoding to a planar sample format, "
+ "with more than %d channels, but extended_data is not set.\n",
+ AV_NUM_DATA_POINTERS);
+ return AVERROR(EINVAL);
+ }
+ av_log(avctx, AV_LOG_WARNING, "extended_data is not set.\n");
+
+ tmp = *frame;
+ tmp.extended_data = tmp.data;
+ frame = &tmp;
+ }
+
/* check for valid frame size */
if (frame) {
- nb_samples = frame->nb_samples;
if (avctx->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) {
- if (nb_samples > avctx->frame_size)
+ if (frame->nb_samples > avctx->frame_size)
return AVERROR(EINVAL);
} else if (!(avctx->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)) {
- if (nb_samples != avctx->frame_size)
+ if (frame->nb_samples < avctx->frame_size &&
+ !avctx->internal->last_audio_frame) {
+ ret = pad_last_frame(avctx, &padded_frame, frame);
+ if (ret < 0)
+ return ret;
+
+ frame = padded_frame;
+ avctx->internal->last_audio_frame = 1;
+ }
+
+ if (frame->nb_samples != avctx->frame_size)
return AVERROR(EINVAL);
}
- } else {
- nb_samples = avctx->frame_size;
}
- if (avctx->codec->encode2) {
- ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr);
- if (!ret && *got_packet_ptr) {
+ ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr);
+ if (!ret) {
+ if (*got_packet_ptr) {
if (!(avctx->codec->capabilities & CODEC_CAP_DELAY)) {
if (avpkt->pts == AV_NOPTS_VALUE)
avpkt->pts = frame->pts;
@@ -899,69 +972,7 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx,
} else {
avpkt->size = 0;
}
- } else {
- /* for compatibility with encoders not supporting encode2(), we need to
- allocate a packet buffer if the user has not provided one or check
- the size otherwise */
- int fs_tmp = 0;
- int buf_size = avpkt->size;
- if (!user_packet) {
- if (avctx->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE) {
- av_assert0(av_get_bits_per_sample(avctx->codec_id) != 0);
- buf_size = nb_samples * avctx->channels *
- av_get_bits_per_sample(avctx->codec_id) / 8;
- } else {
- /* this is a guess as to the required size.
- if an encoder needs more than this, it should probably
- implement encode2() */
- buf_size = 2 * avctx->frame_size * avctx->channels *
- av_get_bytes_per_sample(avctx->sample_fmt);
- buf_size += FF_MIN_BUFFER_SIZE;
- }
- }
- if ((ret = ff_alloc_packet(avpkt, buf_size)))
- return ret;
- /* Encoders using AVCodec.encode() that support
- CODEC_CAP_SMALL_LAST_FRAME require avctx->frame_size to be set to
- the smaller size when encoding the last frame.
- This code can be removed once all encoders supporting
- CODEC_CAP_SMALL_LAST_FRAME use encode2() */
- if ((avctx->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) &&
- nb_samples < avctx->frame_size) {
- fs_tmp = avctx->frame_size;
- avctx->frame_size = nb_samples;
- }
-
- /* encode the frame */
- ret = avctx->codec->encode(avctx, avpkt->data, avpkt->size,
- frame ? frame->data[0] : NULL);
- if (ret >= 0) {
- if (!ret) {
- /* no output. if the packet data was allocated by libavcodec,
- free it */
- if (!user_packet)
- av_freep(&avpkt->data);
- } else {
- if (avctx->coded_frame)
- avpkt->pts = avpkt->dts = avctx->coded_frame->pts;
- /* Set duration for final small packet. This can be removed
- once all encoders supporting CODEC_CAP_SMALL_LAST_FRAME use
- encode2() */
- if (fs_tmp) {
- avpkt->duration = ff_samples_to_time_base(avctx,
- avctx->frame_size);
- }
- }
- avpkt->size = ret;
- *got_packet_ptr = (ret > 0);
- ret = 0;
- }
-
- if (fs_tmp)
- avctx->frame_size = fs_tmp;
- }
- if (!ret) {
if (!user_packet && avpkt->size) {
uint8_t *new_data = av_realloc(avpkt->data, avpkt->size);
if (new_data)
@@ -971,14 +982,24 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx,
avctx->frame_number++;
}
- if (ret < 0 || !*got_packet_ptr)
+ if (ret < 0 || !*got_packet_ptr) {
av_free_packet(avpkt);
+ av_init_packet(avpkt);
+ return ret;
+ }
/* NOTE: if we add any audio encoders which output non-keyframe packets,
this needs to be moved to the encoders, but for now we can do it
here to simplify things */
avpkt->flags |= AV_PKT_FLAG_KEY;
+ if (padded_frame) {
+ av_freep(&padded_frame->data[0]);
+ if (padded_frame->extended_data != padded_frame->data)
+ av_freep(&padded_frame->extended_data);
+ av_freep(&padded_frame);
+ }
+
return ret;
}
@@ -1026,7 +1047,8 @@ int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx,
avctx->sample_fmt, 1);
if ((ret = avcodec_fill_audio_frame(frame, avctx->channels,
avctx->sample_fmt,
- samples, samples_size, 1)))
+ (const uint8_t *) samples,
+ samples_size, 1)))
return ret;
/* fabricate frame pts from sample count.
@@ -1810,6 +1832,11 @@ int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes)
case 29: return 288;
case 37: return 480;
}
+ } else if (id == CODEC_ID_ILBC) {
+ switch (ba) {
+ case 38: return 160;
+ case 50: return 240;
+ }
}
}
diff --git a/libavcodec/utvideo.c b/libavcodec/utvideo.c
index a3b0d7c..471d85a 100644
--- a/libavcodec/utvideo.c
+++ b/libavcodec/utvideo.c
@@ -439,10 +439,17 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
plane_start[i], c->frame_pred == PRED_LEFT);
if (ret)
return ret;
- if (c->frame_pred == PRED_MEDIAN)
- restore_median(c->pic.data[0] + rgb_order[i], c->planes,
- c->pic.linesize[0], avctx->width, avctx->height,
- c->slices, 0);
+ if (c->frame_pred == PRED_MEDIAN) {
+ if (!c->interlaced) {
+ restore_median(c->pic.data[0] + rgb_order[i], c->planes,
+ c->pic.linesize[0], avctx->width,
+ avctx->height, c->slices, 0);
+ } else {
+ restore_median_il(c->pic.data[0] + rgb_order[i], c->planes,
+ c->pic.linesize[0], avctx->width,
+ avctx->height, c->slices, 0);
+ }
+ }
}
restore_rgb_planes(c->pic.data[0], c->planes, c->pic.linesize[0],
avctx->width, avctx->height);
@@ -492,6 +499,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
c->pic.key_frame = 1;
c->pic.pict_type = AV_PICTURE_TYPE_I;
+ c->pic.interlaced_frame = !!c->interlaced;
+
*data_size = sizeof(AVFrame);
*(AVFrame*)data = c->pic;
diff --git a/libavcodec/vc1dsp.c b/libavcodec/vc1dsp.c
index b40824b..7b50af6 100644
--- a/libavcodec/vc1dsp.c
+++ b/libavcodec/vc1dsp.c
@@ -561,7 +561,7 @@ static av_always_inline int vc1_mspel_filter(const uint8_t *src, int stride, int
/** Function used to do motion compensation with bicubic interpolation
*/
#define VC1_MSPEL_MC(OP, OPNAME)\
-static void OPNAME ## vc1_mspel_mc(uint8_t *dst, const uint8_t *src, int stride, int hmode, int vmode, int rnd)\
+static av_always_inline void OPNAME ## vc1_mspel_mc(uint8_t *dst, const uint8_t *src, int stride, int hmode, int vmode, int rnd)\
{\
int i, j;\
\
diff --git a/libavcodec/vcr1.c b/libavcodec/vcr1.c
index 23b0647..3a42612 100644
--- a/libavcodec/vcr1.c
+++ b/libavcodec/vcr1.c
@@ -21,92 +21,111 @@
/**
* @file
- * ati vcr1 codec.
+ * ATI VCR1 codec
*/
#include "avcodec.h"
#include "dsputil.h"
-//#undef NDEBUG
-//#include <assert.h>
-
-/* Disable the encoder. */
-#undef CONFIG_VCR1_ENCODER
-#define CONFIG_VCR1_ENCODER 0
-
-typedef struct VCR1Context{
- AVCodecContext *avctx;
+typedef struct VCR1Context {
AVFrame picture;
int delta[16];
int offset[4];
} VCR1Context;
-static int decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+static av_cold int vcr1_common_init(AVCodecContext *avctx)
+{
+ VCR1Context *const a = avctx->priv_data;
+
+ avctx->coded_frame = &a->picture;
+
+ return 0;
+}
+
+static av_cold int vcr1_decode_init(AVCodecContext *avctx)
+{
+ vcr1_common_init(avctx);
+
+ avctx->pix_fmt = PIX_FMT_YUV410P;
+
+ return 0;
+}
+
+static av_cold int vcr1_decode_end(AVCodecContext *avctx)
{
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- VCR1Context * const a = avctx->priv_data;
- AVFrame *picture = data;
- AVFrame * const p = &a->picture;
- const uint8_t *bytestream= buf;
+ VCR1Context *s = avctx->priv_data;
+
+ if (s->picture.data[0])
+ avctx->release_buffer(avctx, &s->picture);
+
+ return 0;
+}
+
+static int vcr1_decode_frame(AVCodecContext *avctx, void *data,
+ int *data_size, AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ VCR1Context *const a = avctx->priv_data;
+ AVFrame *picture = data;
+ AVFrame *const p = &a->picture;
+ const uint8_t *bytestream = buf;
int i, x, y;
- if(p->data[0])
+ if (p->data[0])
avctx->release_buffer(avctx, p);
- p->reference= 0;
- if(avctx->get_buffer(avctx, p) < 0){
+ p->reference = 0;
+ if (avctx->get_buffer(avctx, p) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return -1;
}
- p->pict_type= AV_PICTURE_TYPE_I;
- p->key_frame= 1;
+ p->pict_type = AV_PICTURE_TYPE_I;
+ p->key_frame = 1;
- for(i=0; i<16; i++){
- a->delta[i]= *(bytestream++);
+ for (i = 0; i < 16; i++) {
+ a->delta[i] = *bytestream++;
bytestream++;
}
- for(y=0; y<avctx->height; y++){
+ for (y = 0; y < avctx->height; y++) {
int offset;
- uint8_t *luma= &a->picture.data[0][ y*a->picture.linesize[0] ];
+ uint8_t *luma = &a->picture.data[0][y * a->picture.linesize[0]];
- if((y&3) == 0){
- uint8_t *cb= &a->picture.data[1][ (y>>2)*a->picture.linesize[1] ];
- uint8_t *cr= &a->picture.data[2][ (y>>2)*a->picture.linesize[2] ];
+ if ((y & 3) == 0) {
+ uint8_t *cb = &a->picture.data[1][(y >> 2) * a->picture.linesize[1]];
+ uint8_t *cr = &a->picture.data[2][(y >> 2) * a->picture.linesize[2]];
- for(i=0; i<4; i++)
- a->offset[i]= *(bytestream++);
+ for (i = 0; i < 4; i++)
+ a->offset[i] = *bytestream++;
- offset= a->offset[0] - a->delta[ bytestream[2]&0xF ];
- for(x=0; x<avctx->width; x+=4){
- luma[0]=( offset += a->delta[ bytestream[2]&0xF ]);
- luma[1]=( offset += a->delta[ bytestream[2]>>4 ]);
- luma[2]=( offset += a->delta[ bytestream[0]&0xF ]);
- luma[3]=( offset += a->delta[ bytestream[0]>>4 ]);
- luma += 4;
+ offset = a->offset[0] - a->delta[bytestream[2] & 0xF];
+ for (x = 0; x < avctx->width; x += 4) {
+ luma[0] = offset += a->delta[bytestream[2] & 0xF];
+ luma[1] = offset += a->delta[bytestream[2] >> 4];
+ luma[2] = offset += a->delta[bytestream[0] & 0xF];
+ luma[3] = offset += a->delta[bytestream[0] >> 4];
+ luma += 4;
- *(cb++) = bytestream[3];
- *(cr++) = bytestream[1];
+ *cb++ = bytestream[3];
+ *cr++ = bytestream[1];
- bytestream+= 4;
+ bytestream += 4;
}
- }else{
- offset= a->offset[y&3] - a->delta[ bytestream[2]&0xF ];
-
- for(x=0; x<avctx->width; x+=8){
- luma[0]=( offset += a->delta[ bytestream[2]&0xF ]);
- luma[1]=( offset += a->delta[ bytestream[2]>>4 ]);
- luma[2]=( offset += a->delta[ bytestream[3]&0xF ]);
- luma[3]=( offset += a->delta[ bytestream[3]>>4 ]);
- luma[4]=( offset += a->delta[ bytestream[0]&0xF ]);
- luma[5]=( offset += a->delta[ bytestream[0]>>4 ]);
- luma[6]=( offset += a->delta[ bytestream[1]&0xF ]);
- luma[7]=( offset += a->delta[ bytestream[1]>>4 ]);
- luma += 8;
- bytestream+= 4;
+ } else {
+ offset = a->offset[y & 3] - a->delta[bytestream[2] & 0xF];
+
+ for (x = 0; x < avctx->width; x += 8) {
+ luma[0] = offset += a->delta[bytestream[2] & 0xF];
+ luma[1] = offset += a->delta[bytestream[2] >> 4];
+ luma[2] = offset += a->delta[bytestream[3] & 0xF];
+ luma[3] = offset += a->delta[bytestream[3] >> 4];
+ luma[4] = offset += a->delta[bytestream[0] & 0xF];
+ luma[5] = offset += a->delta[bytestream[0] >> 4];
+ luma[6] = offset += a->delta[bytestream[1] & 0xF];
+ luma[7] = offset += a->delta[bytestream[1] >> 4];
+ luma += 8;
+ bytestream += 4;
}
}
}
@@ -117,81 +136,53 @@ static int decode_frame(AVCodecContext *avctx,
return buf_size;
}
-#if CONFIG_VCR1_ENCODER
-static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
- VCR1Context * const a = avctx->priv_data;
- AVFrame *pict = data;
- AVFrame * const p = &a->picture;
- int size;
-
- *p = *pict;
- p->pict_type= AV_PICTURE_TYPE_I;
- p->key_frame= 1;
-
- avpriv_align_put_bits(&a->pb);
- while(get_bit_count(&a->pb)&31)
- put_bits(&a->pb, 8, 0);
-
- size= get_bit_count(&a->pb)/32;
-
- return size*4;
-}
-#endif
-
-static av_cold void common_init(AVCodecContext *avctx){
- VCR1Context * const a = avctx->priv_data;
-
- avctx->coded_frame = &a->picture;
- a->avctx= avctx;
-}
-
-static av_cold int decode_init(AVCodecContext *avctx){
-
- common_init(avctx);
-
- avctx->pix_fmt= PIX_FMT_YUV410P;
-
- return 0;
-}
-
-static av_cold int decode_end(AVCodecContext *avctx){
- VCR1Context *s = avctx->priv_data;
-
- if (s->picture.data[0])
- avctx->release_buffer(avctx, &s->picture);
-
- return 0;
-}
-
-#if CONFIG_VCR1_ENCODER
-static av_cold int encode_init(AVCodecContext *avctx){
-
- common_init(avctx);
-
- return 0;
-}
-#endif
-
AVCodec ff_vcr1_decoder = {
.name = "vcr1",
.type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_VCR1,
.priv_data_size = sizeof(VCR1Context),
- .init = decode_init,
- .close = decode_end,
- .decode = decode_frame,
+ .init = vcr1_decode_init,
+ .close = vcr1_decode_end,
+ .decode = vcr1_decode_frame,
.capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("ATI VCR1"),
};
+/* Disable the encoder. */
+#undef CONFIG_VCR1_ENCODER
+#define CONFIG_VCR1_ENCODER 0
+
#if CONFIG_VCR1_ENCODER
+
+#include "put_bits.h"
+
+static int vcr1_encode_frame(AVCodecContext *avctx, unsigned char *buf,
+ int buf_size, void *data)
+{
+ VCR1Context *const a = avctx->priv_data;
+ AVFrame *pict = data;
+ AVFrame *const p = &a->picture;
+ int size;
+
+ *p = *pict;
+ p->pict_type = AV_PICTURE_TYPE_I;
+ p->key_frame = 1;
+
+ avpriv_align_put_bits(&a->pb);
+ flush_put_bits(&a->pb);
+
+ size = put_bits_count(&a->pb) / 32;
+
+ return size * 4;
+}
+
AVCodec ff_vcr1_encoder = {
.name = "vcr1",
.type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_VCR1,
.priv_data_size = sizeof(VCR1Context),
- .init = encode_init,
- .encode = encode_frame,
+ .init = vcr1_common_init,
+ .encode = vcr1_encode_frame,
.long_name = NULL_IF_CONFIG_SMALL("ATI VCR1"),
};
-#endif
+#endif /* CONFIG_VCR1_ENCODER */
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 5119874..cb23738 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -27,7 +27,7 @@
*/
#define LIBAVCODEC_VERSION_MAJOR 54
-#define LIBAVCODEC_VERSION_MINOR 12
+#define LIBAVCODEC_VERSION_MINOR 17
#define LIBAVCODEC_VERSION_MICRO 0
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
@@ -41,9 +41,11 @@
#define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION)
/**
- * Those FF_API_* defines are not part of public API.
- * They may change, break or disappear at any time.
+ * FF_API_* defines may be placed below to indicate public API that will be
+ * dropped at a future version bump. The defines themselves are not part of
+ * the public API and may change, break or disappear at any time.
*/
+
#ifndef FF_API_REQUEST_CHANNELS
#define FF_API_REQUEST_CHANNELS (LIBAVCODEC_VERSION_MAJOR < 55)
#endif
diff --git a/libavcodec/vorbis.c b/libavcodec/vorbis.c
index 52ded8b..16fb998 100644
--- a/libavcodec/vorbis.c
+++ b/libavcodec/vorbis.c
@@ -119,7 +119,8 @@ int ff_vorbis_len2vlc(uint8_t *bits, uint32_t *codes, unsigned num)
return 0;
}
-void ff_vorbis_ready_floor1_list(vorbis_floor1_entry * list, int values)
+int ff_vorbis_ready_floor1_list(AVCodecContext *avccontext,
+ vorbis_floor1_entry *list, int values)
{
int i;
list[0].sort = 0;
@@ -143,6 +144,11 @@ void ff_vorbis_ready_floor1_list(vorbis_floor1_entry * list, int values)
for (i = 0; i < values - 1; i++) {
int j;
for (j = i + 1; j < values; j++) {
+ if (list[i].x == list[j].x) {
+ av_log(avccontext, AV_LOG_ERROR,
+ "Duplicate value found in floor 1 X coordinates\n");
+ return AVERROR_INVALIDDATA;
+ }
if (list[list[i].sort].x > list[list[j].sort].x) {
int tmp = list[i].sort;
list[i].sort = list[j].sort;
@@ -150,6 +156,7 @@ void ff_vorbis_ready_floor1_list(vorbis_floor1_entry * list, int values)
}
}
}
+ return 0;
}
static inline void render_line_unrolled(intptr_t x, int y, int x1,
diff --git a/libavcodec/vorbis.h b/libavcodec/vorbis.h
index 924ca80..ee4967c 100644
--- a/libavcodec/vorbis.h
+++ b/libavcodec/vorbis.h
@@ -36,7 +36,8 @@ typedef struct {
uint16_t high;
} vorbis_floor1_entry;
-void ff_vorbis_ready_floor1_list(vorbis_floor1_entry * list, int values);
+int ff_vorbis_ready_floor1_list(AVCodecContext *avccontext,
+ vorbis_floor1_entry *list, int values);
unsigned int ff_vorbis_nth_root(unsigned int x, unsigned int n); // x^(1/n)
int ff_vorbis_len2vlc(uint8_t *bits, uint32_t *codes, unsigned num);
void ff_vorbis_floor1_render_list(vorbis_floor1_entry * list, int values,
diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c
index 36db356..deaaaa2 100644
--- a/libavcodec/vorbisdec.c
+++ b/libavcodec/vorbisdec.c
@@ -26,6 +26,7 @@
#include <math.h>
#define BITSTREAM_READER_LE
+#include "libavutil/float_dsp.h"
#include "avcodec.h"
#include "get_bits.h"
#include "dsputil.h"
@@ -124,6 +125,7 @@ typedef struct vorbis_context_s {
AVFrame frame;
GetBitContext gb;
DSPContext dsp;
+ AVFloatDSPContext fdsp;
FmtConvertContext fmt_conv;
FFTContext mdct[2];
@@ -574,7 +576,11 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc)
}
// Precalculate order of x coordinates - needed for decode
- ff_vorbis_ready_floor1_list(floor_setup->data.t1.list, floor_setup->data.t1.x_list_dim);
+ if (ff_vorbis_ready_floor1_list(vc->avccontext,
+ floor_setup->data.t1.list,
+ floor_setup->data.t1.x_list_dim)) {
+ return AVERROR_INVALIDDATA;
+ }
} else if (floor_setup->floor_type == 0) {
unsigned max_codebook_dim = 0;
@@ -979,6 +985,7 @@ static av_cold int vorbis_decode_init(AVCodecContext *avccontext)
vc->avccontext = avccontext;
ff_dsputil_init(&vc->dsp, avccontext);
+ avpriv_float_dsp_init(&vc->fdsp, avccontext->flags & CODEC_FLAG_BITEXACT);
ff_fmt_convert_init(&vc->fmt_conv, avccontext);
if (avccontext->request_sample_fmt == AV_SAMPLE_FMT_FLT) {
@@ -1402,17 +1409,24 @@ static av_always_inline int vorbis_residue_decode_internal(vorbis_context *vc,
}
} else if (vr_type == 2) {
- voffs = voffset;
+ unsigned voffs_div = FASTDIV(voffset, ch);
+ unsigned voffs_mod = voffset - voffs_div * ch;
for (k = 0; k < step; ++k) {
coffs = get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * dim;
- for (l = 0; l < dim; ++l, ++voffs) {
- vec[voffs / ch + (voffs % ch) * vlen] += codebook.codevectors[coffs + l]; // FPMATH FIXME use if and counter instead of / and %
+ for (l = 0; l < dim; ++l) {
+ vec[voffs_div + voffs_mod * vlen] +=
+ codebook.codevectors[coffs + l];
av_dlog(NULL, " pass %d offs: %d curr: %f change: %f cv offs.: %d+%d \n",
- pass, voffset / ch + (voffs % ch) * vlen,
- vec[voffset / ch + (voffs % ch) * vlen],
+ pass, voffs_div + voffs_mod * vlen,
+ vec[voffs_div + voffs_mod * vlen],
codebook.codevectors[coffs + l], coffs, l);
+
+ if (++voffs_mod == ch) {
+ voffs_div++;
+ voffs_mod = 0;
+ }
}
}
}
@@ -1601,7 +1615,7 @@ static int vorbis_parse_audio_packet(vorbis_context *vc)
for (j = vc->audio_channels-1;j >= 0; j--) {
ch_floor_ptr = vc->channel_floors + j * blocksize / 2;
ch_res_ptr = vc->channel_residues + res_chan[j] * blocksize / 2;
- vc->dsp.vector_fmul(ch_floor_ptr, ch_floor_ptr, ch_res_ptr, blocksize / 2);
+ vc->fdsp.vector_fmul(ch_floor_ptr, ch_floor_ptr, ch_res_ptr, blocksize / 2);
mdct->imdct_half(mdct, ch_res_ptr, ch_floor_ptr);
}
diff --git a/libavcodec/vorbisenc.c b/libavcodec/vorbisenc.c
index 0b0cacc..173619a 100644
--- a/libavcodec/vorbisenc.c
+++ b/libavcodec/vorbisenc.c
@@ -340,7 +340,8 @@ static int create_vorbis_context(vorbis_enc_context *venc,
};
fc->list[i].x = a[i - 2];
}
- ff_vorbis_ready_floor1_list(fc->list, fc->values);
+ if (ff_vorbis_ready_floor1_list(avccontext, fc->list, fc->values))
+ return AVERROR_BUG;
venc->nresidues = 1;
venc->residues = av_malloc(sizeof(vorbis_enc_residue) * venc->nresidues);
diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
index 1c973d5..94200f6 100644
--- a/libavcodec/vp8.c
+++ b/libavcodec/vp8.c
@@ -707,56 +707,58 @@ void decode_mb_mode(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y, uint8_
* @return 0 if no coeffs were decoded
* otherwise, the index of the last coeff decoded plus one
*/
-static int decode_block_coeffs_internal(VP56RangeCoder *c, DCTELEM block[16],
+static int decode_block_coeffs_internal(VP56RangeCoder *r, DCTELEM block[16],
uint8_t probs[16][3][NUM_DCT_TOKENS-1],
int i, uint8_t *token_prob, int16_t qmul[2])
{
+ VP56RangeCoder c = *r;
goto skip_eob;
do {
int coeff;
- if (!vp56_rac_get_prob_branchy(c, token_prob[0])) // DCT_EOB
- return i;
+ if (!vp56_rac_get_prob_branchy(&c, token_prob[0])) // DCT_EOB
+ break;
skip_eob:
- if (!vp56_rac_get_prob_branchy(c, token_prob[1])) { // DCT_0
+ if (!vp56_rac_get_prob_branchy(&c, token_prob[1])) { // DCT_0
if (++i == 16)
- return i; // invalid input; blocks should end with EOB
+ break; // invalid input; blocks should end with EOB
token_prob = probs[i][0];
goto skip_eob;
}
- if (!vp56_rac_get_prob_branchy(c, token_prob[2])) { // DCT_1
+ if (!vp56_rac_get_prob_branchy(&c, token_prob[2])) { // DCT_1
coeff = 1;
token_prob = probs[i+1][1];
} else {
- if (!vp56_rac_get_prob_branchy(c, token_prob[3])) { // DCT 2,3,4
- coeff = vp56_rac_get_prob_branchy(c, token_prob[4]);
+ if (!vp56_rac_get_prob_branchy(&c, token_prob[3])) { // DCT 2,3,4
+ coeff = vp56_rac_get_prob_branchy(&c, token_prob[4]);
if (coeff)
- coeff += vp56_rac_get_prob(c, token_prob[5]);
+ coeff += vp56_rac_get_prob(&c, token_prob[5]);
coeff += 2;
} else {
// DCT_CAT*
- if (!vp56_rac_get_prob_branchy(c, token_prob[6])) {
- if (!vp56_rac_get_prob_branchy(c, token_prob[7])) { // DCT_CAT1
- coeff = 5 + vp56_rac_get_prob(c, vp8_dct_cat1_prob[0]);
+ if (!vp56_rac_get_prob_branchy(&c, token_prob[6])) {
+ if (!vp56_rac_get_prob_branchy(&c, token_prob[7])) { // DCT_CAT1
+ coeff = 5 + vp56_rac_get_prob(&c, vp8_dct_cat1_prob[0]);
} else { // DCT_CAT2
coeff = 7;
- coeff += vp56_rac_get_prob(c, vp8_dct_cat2_prob[0]) << 1;
- coeff += vp56_rac_get_prob(c, vp8_dct_cat2_prob[1]);
+ coeff += vp56_rac_get_prob(&c, vp8_dct_cat2_prob[0]) << 1;
+ coeff += vp56_rac_get_prob(&c, vp8_dct_cat2_prob[1]);
}
} else { // DCT_CAT3 and up
- int a = vp56_rac_get_prob(c, token_prob[8]);
- int b = vp56_rac_get_prob(c, token_prob[9+a]);
+ int a = vp56_rac_get_prob(&c, token_prob[8]);
+ int b = vp56_rac_get_prob(&c, token_prob[9+a]);
int cat = (a<<1) + b;
coeff = 3 + (8<<cat);
- coeff += vp8_rac_get_coeff(c, ff_vp8_dct_cat_prob[cat]);
+ coeff += vp8_rac_get_coeff(&c, ff_vp8_dct_cat_prob[cat]);
}
}
token_prob = probs[i+1][2];
}
- block[zigzag_scan[i]] = (vp8_rac_get(c) ? -coeff : coeff) * qmul[!!i];
+ block[zigzag_scan[i]] = (vp8_rac_get(&c) ? -coeff : coeff) * qmul[!!i];
} while (++i < 16);
+ *r = c;
return i;
}
#endif
@@ -1833,6 +1835,8 @@ static int vp8_decode_update_thread_context(AVCodecContext *dst, const AVCodecCo
(s_src->mb_width != s->mb_width || s_src->mb_height != s->mb_height)) {
free_buffers(s);
s->maps_are_invalid = 1;
+ s->mb_width = s_src->mb_width;
+ s->mb_height = s_src->mb_height;
}
s->prob[0] = s_src->prob[!s_src->update_probabilities];
diff --git a/libavcodec/vqavideo.c b/libavcodec/vqavideo.c
index 9cca3e7..1bad226 100644
--- a/libavcodec/vqavideo.c
+++ b/libavcodec/vqavideo.c
@@ -151,6 +151,12 @@ static av_cold int vqa_decode_init(AVCodecContext *avctx)
return -1;
}
+ if (s->width & (s->vector_width - 1) ||
+ s->height & (s->vector_height - 1)) {
+ av_log(avctx, AV_LOG_ERROR, "Image size not multiple of block size\n");
+ return AVERROR_INVALIDDATA;
+ }
+
/* allocate codebooks */
s->codebook_size = MAX_CODEBOOK_SIZE;
s->codebook = av_malloc(s->codebook_size);
@@ -462,11 +468,9 @@ static int vqa_decode_chunk(VqaContext *s)
index_shift = 4;
else
index_shift = 3;
- for (y = 0; y < s->frame.linesize[0] * s->height;
- y += s->frame.linesize[0] * s->vector_height) {
-
- for (x = y; x < y + s->width; x += 4, lobytes++, hibytes++) {
- pixel_ptr = x;
+ for (y = 0; y < s->height; y += s->vector_height) {
+ for (x = 0; x < s->width; x += 4, lobytes++, hibytes++) {
+ pixel_ptr = y * s->frame.linesize[0] + x;
/* get the vector index, the method for which varies according to
* VQA file version */
diff --git a/libavcodec/wma.c b/libavcodec/wma.c
index 007653f..b61228b 100644
--- a/libavcodec/wma.c
+++ b/libavcodec/wma.c
@@ -78,7 +78,7 @@ int ff_wma_init(AVCodecContext *avctx, int flags2)
int coef_vlc_table;
if ( avctx->sample_rate <= 0 || avctx->sample_rate > 50000
- || avctx->channels <= 0 || avctx->channels > 8
+ || avctx->channels <= 0 || avctx->channels > 2
|| avctx->bit_rate <= 0)
return -1;
diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c
index 1520a06..cb7f667 100644
--- a/libavcodec/wmalosslessdec.c
+++ b/libavcodec/wmalosslessdec.c
@@ -22,6 +22,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/attributes.h"
#include "avcodec.h"
#include "internal.h"
#include "get_bits.h"
@@ -654,9 +655,9 @@ static void mclms_predict(WmallDecodeCtx *s, int icoef, int *pred)
int num_channels = s->num_channels;
for (ich = 0; ich < num_channels; ich++) {
+ pred[ich] = 0;
if (!s->is_channel_coded[ich])
continue;
- pred[ich] = 0;
for (i = 0; i < order * num_channels; i++)
pred[ich] += s->mclms_prevvalues[i + s->mclms_recent] *
s->mclms_coeffs[i + order * num_channels * ich];
@@ -789,7 +790,7 @@ static void revert_inter_ch_decorr(WmallDecodeCtx *s, int tile_size)
{
if (s->num_channels != 2)
return;
- else if (s->is_channel_coded[0] && s->is_channel_coded[1]) {
+ else if (s->is_channel_coded[0] || s->is_channel_coded[1]) {
int icoef;
for (icoef = 0; icoef < tile_size; icoef++) {
s->channel_residues[0][icoef] -= s->channel_residues[1][icoef] >> 1;
@@ -955,6 +956,8 @@ static int decode_subframe(WmallDecodeCtx *s)
else
use_normal_update_speed(s, i);
revert_cdlms(s, i, 0, subframe_len);
+ } else {
+ memset(s->channel_residues[i], 0, sizeof(**s->channel_residues) * subframe_len);
}
}
if (s->do_mclms)
@@ -977,10 +980,10 @@ static int decode_subframe(WmallDecodeCtx *s)
for (j = 0; j < subframe_len; j++) {
if (s->bits_per_sample == 16) {
- *s->samples_16[c] = (int16_t) s->channel_residues[c][j];
+ *s->samples_16[c] = (int16_t) s->channel_residues[c][j] << padding_zeroes;
s->samples_16[c] += s->num_channels;
} else {
- *s->samples_32[c] = s->channel_residues[c][j];
+ *s->samples_32[c] = s->channel_residues[c][j] << padding_zeroes;
s->samples_32[c] += s->num_channels;
}
}
@@ -1039,7 +1042,7 @@ static int decode_frame(WmallDecodeCtx *s)
/* no idea what these are for, might be the number of samples
that need to be skipped at the beginning or end of a stream */
if (get_bits1(gb)) {
- int skip;
+ int av_unused skip;
/* usually true for the first frame */
if (get_bits1(gb)) {
@@ -1166,6 +1169,8 @@ static int decode_packet(AVCodecContext *avctx, void *data, int *got_frame_ptr,
int buf_size = avpkt->size;
int num_bits_prev_frame, packet_sequence_number, spliced_packet;
+ s->frame.nb_samples = 0;
+
if (s->packet_done || s->packet_loss) {
s->packet_done = 0;
@@ -1209,7 +1214,7 @@ static int decode_packet(AVCodecContext *avctx, void *data, int *got_frame_ptr,
save_bits(s, gb, num_bits_prev_frame, 1);
/* decode the cross packet frame if it is valid */
- if (!s->packet_loss)
+ if (num_bits_prev_frame < remaining_packet_bits && !s->packet_loss)
decode_frame(s);
} else if (s->num_saved_bits - s->frame_offset) {
av_dlog(avctx, "ignoring %x previously saved bits\n",
diff --git a/libavcodec/x86/Makefile b/libavcodec/x86/Makefile
index 6602cce..6464739 100644
--- a/libavcodec/x86/Makefile
+++ b/libavcodec/x86/Makefile
@@ -39,7 +39,6 @@ YASM-OBJS-$(CONFIG_DCT) += x86/dct32_sse.o
YASM-OBJS-$(CONFIG_ENCODERS) += x86/dsputilenc_yasm.o
YASM-OBJS-FFT-$(HAVE_AMD3DNOW) += x86/fft_3dn.o
YASM-OBJS-FFT-$(HAVE_AMD3DNOWEXT) += x86/fft_3dn2.o
-YASM-OBJS-FFT-$(HAVE_SSE) += x86/fft_sse.o
YASM-OBJS-$(CONFIG_FFT) += x86/fft_mmx.o \
$(YASM-OBJS-FFT-yes)
YASM-OBJS-$(CONFIG_H264CHROMA) += x86/h264_chromamc.o \
diff --git a/libavcodec/x86/ac3dsp.asm b/libavcodec/x86/ac3dsp.asm
index 1438811..f1e73d3 100644
--- a/libavcodec/x86/ac3dsp.asm
+++ b/libavcodec/x86/ac3dsp.asm
@@ -91,12 +91,36 @@ AC3_EXPONENT_MIN sse2
; This is used for mmxext and sse2 because they have pminsw/pmaxsw.
;-----------------------------------------------------------------------------
-%macro AC3_MAX_MSB_ABS_INT16 2
-cglobal ac3_max_msb_abs_int16_%1, 2,2,5, src, len
+; logical 'or' of 4 or 8 words in an mmx or xmm register into the low word
+%macro OR_WORDS_HORIZ 2 ; src, tmp
+%if cpuflag(sse2)
+ movhlps %2, %1
+ por %1, %2
+ pshuflw %2, %1, q0032
+ por %1, %2
+ pshuflw %2, %1, q0001
+ por %1, %2
+%elif cpuflag(mmx2)
+ pshufw %2, %1, q0032
+ por %1, %2
+ pshufw %2, %1, q0001
+ por %1, %2
+%else ; mmx
+ movq %2, %1
+ psrlq %2, 32
+ por %1, %2
+ movq %2, %1
+ psrlq %2, 16
+ por %1, %2
+%endif
+%endmacro
+
+%macro AC3_MAX_MSB_ABS_INT16 1
+cglobal ac3_max_msb_abs_int16, 2,2,5, src, len
pxor m2, m2
pxor m3, m3
.loop:
-%ifidn %2, min_max
+%ifidn %1, min_max
mova m0, [srcq]
mova m1, [srcq+mmsize]
pminsw m2, m0
@@ -104,7 +128,7 @@ cglobal ac3_max_msb_abs_int16_%1, 2,2,5, src, len
pmaxsw m3, m0
pmaxsw m3, m1
%else ; or_abs
-%ifidn %1, mmx
+%if notcpuflag(ssse3)
mova m0, [srcq]
mova m1, [srcq+mmsize]
ABS2 m0, m1, m3, m4
@@ -119,34 +143,27 @@ cglobal ac3_max_msb_abs_int16_%1, 2,2,5, src, len
add srcq, mmsize*2
sub lend, mmsize
ja .loop
-%ifidn %2, min_max
+%ifidn %1, min_max
ABS2 m2, m3, m0, m1
por m2, m3
%endif
-%ifidn mmsize, 16
- movhlps m0, m2
- por m2, m0
-%endif
- PSHUFLW m0, m2, 0xe
- por m2, m0
- PSHUFLW m0, m2, 0x1
- por m2, m0
+ OR_WORDS_HORIZ m2, m0
movd eax, m2
and eax, 0xFFFF
RET
%endmacro
-INIT_MMX
+INIT_MMX mmx
%define ABS2 ABS2_MMX
-%define PSHUFLW pshufw
-AC3_MAX_MSB_ABS_INT16 mmx, or_abs
+AC3_MAX_MSB_ABS_INT16 or_abs
+INIT_MMX mmx2
%define ABS2 ABS2_MMX2
-AC3_MAX_MSB_ABS_INT16 mmxext, min_max
-INIT_XMM
-%define PSHUFLW pshuflw
-AC3_MAX_MSB_ABS_INT16 sse2, min_max
+AC3_MAX_MSB_ABS_INT16 min_max
+INIT_XMM sse2
+AC3_MAX_MSB_ABS_INT16 min_max
+INIT_XMM ssse3
%define ABS2 ABS2_SSSE3
-AC3_MAX_MSB_ABS_INT16 ssse3, or_abs
+AC3_MAX_MSB_ABS_INT16 or_abs
;-----------------------------------------------------------------------------
; macro used for ff_ac3_lshift_int16() and ff_ac3_rshift_int32()
diff --git a/libavcodec/x86/ac3dsp_mmx.c b/libavcodec/x86/ac3dsp_mmx.c
index d6bb469..1a43183 100644
--- a/libavcodec/x86/ac3dsp_mmx.c
+++ b/libavcodec/x86/ac3dsp_mmx.c
@@ -27,10 +27,10 @@ extern void ff_ac3_exponent_min_mmx (uint8_t *exp, int num_reuse_blocks, int n
extern void ff_ac3_exponent_min_mmxext(uint8_t *exp, int num_reuse_blocks, int nb_coefs);
extern void ff_ac3_exponent_min_sse2 (uint8_t *exp, int num_reuse_blocks, int nb_coefs);
-extern int ff_ac3_max_msb_abs_int16_mmx (const int16_t *src, int len);
-extern int ff_ac3_max_msb_abs_int16_mmxext(const int16_t *src, int len);
-extern int ff_ac3_max_msb_abs_int16_sse2 (const int16_t *src, int len);
-extern int ff_ac3_max_msb_abs_int16_ssse3 (const int16_t *src, int len);
+extern int ff_ac3_max_msb_abs_int16_mmx (const int16_t *src, int len);
+extern int ff_ac3_max_msb_abs_int16_mmx2 (const int16_t *src, int len);
+extern int ff_ac3_max_msb_abs_int16_sse2 (const int16_t *src, int len);
+extern int ff_ac3_max_msb_abs_int16_ssse3(const int16_t *src, int len);
extern void ff_ac3_lshift_int16_mmx (int16_t *src, unsigned int len, unsigned int shift);
extern void ff_ac3_lshift_int16_sse2(int16_t *src, unsigned int len, unsigned int shift);
@@ -67,7 +67,7 @@ av_cold void ff_ac3dsp_init_x86(AC3DSPContext *c, int bit_exact)
}
if (mm_flags & AV_CPU_FLAG_MMX2 && HAVE_MMX2) {
c->ac3_exponent_min = ff_ac3_exponent_min_mmxext;
- c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_mmxext;
+ c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_mmx2;
}
if (mm_flags & AV_CPU_FLAG_SSE && HAVE_SSE) {
c->float_to_fixed24 = ff_float_to_fixed24_sse;
diff --git a/libavcodec/x86/cabac.h b/libavcodec/x86/cabac.h
index 6fc2ddb..02dbc54 100644
--- a/libavcodec/x86/cabac.h
+++ b/libavcodec/x86/cabac.h
@@ -27,6 +27,8 @@
#include "libavutil/internal.h"
#include "config.h"
+#if HAVE_INLINE_ASM
+
#ifdef BROKEN_RELOCATIONS
#define TABLES_ARG , "r"(tables)
@@ -225,4 +227,5 @@ static av_always_inline int get_cabac_bypass_sign_x86(CABACContext *c, int val)
return val;
}
+#endif /* HAVE_INLINE_ASM */
#endif /* AVCODEC_X86_CABAC_H */
diff --git a/libavcodec/x86/cavsdsp_mmx.c b/libavcodec/x86/cavsdsp_mmx.c
index 3bc62ea..b3d2c27 100644
--- a/libavcodec/x86/cavsdsp_mmx.c
+++ b/libavcodec/x86/cavsdsp_mmx.c
@@ -29,6 +29,14 @@
#include "libavcodec/cavsdsp.h"
#include "dsputil_mmx.h"
+#if HAVE_INLINE_ASM
+
+/* in/out: mma=mma+mmb, mmb=mmb-mma */
+#define SUMSUB_BA( a, b ) \
+ "paddw "#b", "#a" \n\t"\
+ "paddw "#b", "#b" \n\t"\
+ "psubw "#a", "#b" \n\t"
+
/*****************************************************************************
*
* inverse transform
@@ -471,10 +479,14 @@ static void ff_cavsdsp_init_3dnow(CAVSDSPContext* c, AVCodecContext *avctx) {
c->cavs_idct8_add = cavs_idct8_add_mmx;
}
+#endif /* HAVE_INLINE_ASM */
+
void ff_cavsdsp_init_mmx(CAVSDSPContext *c, AVCodecContext *avctx)
{
int mm_flags = av_get_cpu_flags();
+#if HAVE_INLINE_ASM
if (mm_flags & AV_CPU_FLAG_MMX2) ff_cavsdsp_init_mmx2 (c, avctx);
if (mm_flags & AV_CPU_FLAG_3DNOW) ff_cavsdsp_init_3dnow(c, avctx);
+#endif /* HAVE_INLINE_ASM */
}
diff --git a/libavcodec/x86/dnxhd_mmx.c b/libavcodec/x86/dnxhd_mmx.c
index e193d62..54293aa 100644
--- a/libavcodec/x86/dnxhd_mmx.c
+++ b/libavcodec/x86/dnxhd_mmx.c
@@ -24,6 +24,8 @@
#include "libavutil/x86_cpu.h"
#include "libavcodec/dnxhdenc.h"
+#if HAVE_INLINE_ASM
+
static void get_pixels_8x4_sym_sse2(DCTELEM *block, const uint8_t *pixels, int line_size)
{
__asm__ volatile(
@@ -50,10 +52,14 @@ static void get_pixels_8x4_sym_sse2(DCTELEM *block, const uint8_t *pixels, int l
);
}
+#endif /* HAVE_INLINE_ASM */
+
void ff_dnxhd_init_mmx(DNXHDEncContext *ctx)
{
+#if HAVE_INLINE_ASM
if (av_get_cpu_flags() & AV_CPU_FLAG_SSE2) {
if (ctx->cid_table->bit_depth == 8)
ctx->get_pixels_8x4_sym = get_pixels_8x4_sym_sse2;
}
+#endif /* HAVE_INLINE_ASM */
}
diff --git a/libavcodec/x86/dsputil_mmx.c b/libavcodec/x86/dsputil_mmx.c
index 3ef19c5..b695bd2 100644
--- a/libavcodec/x86/dsputil_mmx.c
+++ b/libavcodec/x86/dsputil_mmx.c
@@ -630,6 +630,34 @@ static void add_hfyu_median_prediction_cmov(uint8_t *dst, const uint8_t *top,
}
#endif
+static inline void transpose4x4(uint8_t *dst, uint8_t *src, x86_reg dst_stride, x86_reg src_stride){
+ __asm__ volatile( //FIXME could save 1 instruction if done as 8x4 ...
+ "movd (%1), %%mm0 \n\t"
+ "add %3, %1 \n\t"
+ "movd (%1), %%mm1 \n\t"
+ "movd (%1,%3,1), %%mm2 \n\t"
+ "movd (%1,%3,2), %%mm3 \n\t"
+ "punpcklbw %%mm1, %%mm0 \n\t"
+ "punpcklbw %%mm3, %%mm2 \n\t"
+ "movq %%mm0, %%mm1 \n\t"
+ "punpcklwd %%mm2, %%mm0 \n\t"
+ "punpckhwd %%mm2, %%mm1 \n\t"
+ "movd %%mm0, (%0) \n\t"
+ "add %2, %0 \n\t"
+ "punpckhdq %%mm0, %%mm0 \n\t"
+ "movd %%mm0, (%0) \n\t"
+ "movd %%mm1, (%0,%2,1) \n\t"
+ "punpckhdq %%mm1, %%mm1 \n\t"
+ "movd %%mm1, (%0,%2,2) \n\t"
+
+ : "+&r" (dst),
+ "+&r" (src)
+ : "r" (dst_stride),
+ "r" (src_stride)
+ : "memory"
+ );
+}
+
#define H263_LOOP_FILTER \
"pxor %%mm7, %%mm7 \n\t" \
"movq %0, %%mm0 \n\t" \
@@ -1791,6 +1819,22 @@ QPEL_2TAP(avg_, 16, 3dnow)
QPEL_2TAP(put_, 8, 3dnow)
QPEL_2TAP(avg_, 8, 3dnow)
+void ff_put_rv40_qpel8_mc33_mmx(uint8_t *dst, uint8_t *src, int stride)
+{
+ put_pixels8_xy2_mmx(dst, src, stride, 8);
+}
+void ff_put_rv40_qpel16_mc33_mmx(uint8_t *dst, uint8_t *src, int stride)
+{
+ put_pixels16_xy2_mmx(dst, src, stride, 16);
+}
+void ff_avg_rv40_qpel8_mc33_mmx(uint8_t *dst, uint8_t *src, int stride)
+{
+ avg_pixels8_xy2_mmx(dst, src, stride, 8);
+}
+void ff_avg_rv40_qpel16_mc33_mmx(uint8_t *dst, uint8_t *src, int stride)
+{
+ avg_pixels16_xy2_mmx(dst, src, stride, 16);
+}
#if HAVE_YASM
typedef void emu_edge_core_func(uint8_t *buf, const uint8_t *src,
@@ -2332,135 +2376,6 @@ static void ac3_downmix_sse(float (*samples)[256], float (*matrix)[2],
}
}
-static void vector_fmul_3dnow(float *dst, const float *src0, const float *src1,
- int len)
-{
- x86_reg i = (len - 4) * 4;
- __asm__ volatile (
- "1: \n\t"
- "movq (%2, %0), %%mm0 \n\t"
- "movq 8(%2, %0), %%mm1 \n\t"
- "pfmul (%3, %0), %%mm0 \n\t"
- "pfmul 8(%3, %0), %%mm1 \n\t"
- "movq %%mm0, (%1, %0) \n\t"
- "movq %%mm1, 8(%1, %0) \n\t"
- "sub $16, %0 \n\t"
- "jge 1b \n\t"
- "femms \n\t"
- : "+r"(i)
- : "r"(dst), "r"(src0), "r"(src1)
- : "memory"
- );
-}
-
-static void vector_fmul_sse(float *dst, const float *src0, const float *src1,
- int len)
-{
- x86_reg i = (len - 8) * 4;
- __asm__ volatile (
- "1: \n\t"
- "movaps (%2, %0), %%xmm0 \n\t"
- "movaps 16(%2, %0), %%xmm1 \n\t"
- "mulps (%3, %0), %%xmm0 \n\t"
- "mulps 16(%3, %0), %%xmm1 \n\t"
- "movaps %%xmm0, (%1, %0) \n\t"
- "movaps %%xmm1, 16(%1, %0) \n\t"
- "sub $32, %0 \n\t"
- "jge 1b \n\t"
- : "+r"(i)
- : "r"(dst), "r"(src0), "r"(src1)
- : "memory"
- );
-}
-
-static void vector_fmul_reverse_3dnow2(float *dst, const float *src0,
- const float *src1, int len)
-{
- x86_reg i = len * 4 - 16;
- __asm__ volatile (
- "1: \n\t"
- "pswapd 8(%1), %%mm0 \n\t"
- "pswapd (%1), %%mm1 \n\t"
- "pfmul (%3, %0), %%mm0 \n\t"
- "pfmul 8(%3, %0), %%mm1 \n\t"
- "movq %%mm0, (%2, %0) \n\t"
- "movq %%mm1, 8(%2, %0) \n\t"
- "add $16, %1 \n\t"
- "sub $16, %0 \n\t"
- "jge 1b \n\t"
- : "+r"(i), "+r"(src1)
- : "r"(dst), "r"(src0)
- );
- __asm__ volatile ("femms");
-}
-
-static void vector_fmul_reverse_sse(float *dst, const float *src0,
- const float *src1, int len)
-{
- x86_reg i = len * 4 - 32;
- __asm__ volatile (
- "1: \n\t"
- "movaps 16(%1), %%xmm0 \n\t"
- "movaps (%1), %%xmm1 \n\t"
- "shufps $0x1b, %%xmm0, %%xmm0 \n\t"
- "shufps $0x1b, %%xmm1, %%xmm1 \n\t"
- "mulps (%3, %0), %%xmm0 \n\t"
- "mulps 16(%3, %0), %%xmm1 \n\t"
- "movaps %%xmm0, (%2, %0) \n\t"
- "movaps %%xmm1, 16(%2, %0) \n\t"
- "add $32, %1 \n\t"
- "sub $32, %0 \n\t"
- "jge 1b \n\t"
- : "+r"(i), "+r"(src1)
- : "r"(dst), "r"(src0)
- );
-}
-
-static void vector_fmul_add_3dnow(float *dst, const float *src0,
- const float *src1, const float *src2, int len)
-{
- x86_reg i = (len - 4) * 4;
- __asm__ volatile (
- "1: \n\t"
- "movq (%2, %0), %%mm0 \n\t"
- "movq 8(%2, %0), %%mm1 \n\t"
- "pfmul (%3, %0), %%mm0 \n\t"
- "pfmul 8(%3, %0), %%mm1 \n\t"
- "pfadd (%4, %0), %%mm0 \n\t"
- "pfadd 8(%4, %0), %%mm1 \n\t"
- "movq %%mm0, (%1, %0) \n\t"
- "movq %%mm1, 8(%1, %0) \n\t"
- "sub $16, %0 \n\t"
- "jge 1b \n\t"
- : "+r"(i)
- : "r"(dst), "r"(src0), "r"(src1), "r"(src2)
- : "memory"
- );
- __asm__ volatile ("femms");
-}
-
-static void vector_fmul_add_sse(float *dst, const float *src0,
- const float *src1, const float *src2, int len)
-{
- x86_reg i = (len - 8) * 4;
- __asm__ volatile (
- "1: \n\t"
- "movaps (%2, %0), %%xmm0 \n\t"
- "movaps 16(%2, %0), %%xmm1 \n\t"
- "mulps (%3, %0), %%xmm0 \n\t"
- "mulps 16(%3, %0), %%xmm1 \n\t"
- "addps (%4, %0), %%xmm0 \n\t"
- "addps 16(%4, %0), %%xmm1 \n\t"
- "movaps %%xmm0, (%1, %0) \n\t"
- "movaps %%xmm1, 16(%1, %0) \n\t"
- "sub $32, %0 \n\t"
- "jge 1b \n\t"
- : "+r"(i)
- : "r"(dst), "r"(src0), "r"(src1), "r"(src2)
- : "memory"
- );
-}
-
#if HAVE_6REGS
static void vector_fmul_window_3dnow2(float *dst, const float *src0,
const float *src1, const float *win,
@@ -2615,6 +2530,16 @@ int ff_add_hfyu_left_prediction_sse4(uint8_t *dst, const uint8_t *src,
float ff_scalarproduct_float_sse(const float *v1, const float *v2, int order);
+void ff_vector_fmul_reverse_sse(float *dst, const float *src0,
+ const float *src1, int len);
+void ff_vector_fmul_reverse_avx(float *dst, const float *src0,
+ const float *src1, int len);
+
+void ff_vector_fmul_add_sse(float *dst, const float *src0, const float *src1,
+ const float *src2, int len);
+void ff_vector_fmul_add_avx(float *dst, const float *src0, const float *src1,
+ const float *src2, int len);
+
void ff_vector_clip_int32_mmx (int32_t *dst, const int32_t *src,
int32_t min, int32_t max, unsigned int len);
void ff_vector_clip_int32_sse2 (int32_t *dst, const int32_t *src,
@@ -2902,18 +2827,16 @@ static void dsputil_init_3dnow(DSPContext *c, AVCodecContext *avctx,
#endif
c->vorbis_inverse_coupling = vorbis_inverse_coupling_3dnow;
- c->vector_fmul = vector_fmul_3dnow;
- c->vector_fmul_add = vector_fmul_add_3dnow;
#if HAVE_7REGS
- c->add_hfyu_median_prediction = add_hfyu_median_prediction_cmov;
+ if (mm_flags & AV_CPU_FLAG_CMOV)
+ c->add_hfyu_median_prediction = add_hfyu_median_prediction_cmov;
#endif
}
static void dsputil_init_3dnow2(DSPContext *c, AVCodecContext *avctx,
int mm_flags)
{
- c->vector_fmul_reverse = vector_fmul_reverse_3dnow2;
#if HAVE_6REGS
c->vector_fmul_window = vector_fmul_window_3dnow2;
#endif
@@ -2933,11 +2856,10 @@ static void dsputil_init_sse(DSPContext *c, AVCodecContext *avctx, int mm_flags)
c->vorbis_inverse_coupling = vorbis_inverse_coupling_sse;
c->ac3_downmix = ac3_downmix_sse;
- c->vector_fmul = vector_fmul_sse;
- c->vector_fmul_reverse = vector_fmul_reverse_sse;
-
- if (!(mm_flags & AV_CPU_FLAG_3DNOW))
- c->vector_fmul_add = vector_fmul_add_sse;
+#if HAVE_YASM
+ c->vector_fmul_reverse = ff_vector_fmul_reverse_sse;
+ c->vector_fmul_add = ff_vector_fmul_add_sse;
+#endif
#if HAVE_6REGS
c->vector_fmul_window = vector_fmul_window_sse;
@@ -3096,6 +3018,8 @@ static void dsputil_init_avx(DSPContext *c, AVCodecContext *avctx, int mm_flags)
}
}
c->butterflies_float_interleave = ff_butterflies_float_interleave_avx;
+ c->vector_fmul_reverse = ff_vector_fmul_reverse_avx;
+ c->vector_fmul_add = ff_vector_fmul_add_avx;
#endif
}
diff --git a/libavcodec/x86/dsputil_mmx.h b/libavcodec/x86/dsputil_mmx.h
index 097739c..f1db78d 100644
--- a/libavcodec/x86/dsputil_mmx.h
+++ b/libavcodec/x86/dsputil_mmx.h
@@ -66,24 +66,6 @@ extern const xmm_reg ff_pb_FE;
extern const double ff_pd_1[2];
extern const double ff_pd_2[2];
-#define LOAD4(stride,in,a,b,c,d)\
- "movq 0*"#stride"+"#in", "#a"\n\t"\
- "movq 1*"#stride"+"#in", "#b"\n\t"\
- "movq 2*"#stride"+"#in", "#c"\n\t"\
- "movq 3*"#stride"+"#in", "#d"\n\t"
-
-#define STORE4(stride,out,a,b,c,d)\
- "movq "#a", 0*"#stride"+"#out"\n\t"\
- "movq "#b", 1*"#stride"+"#out"\n\t"\
- "movq "#c", 2*"#stride"+"#out"\n\t"\
- "movq "#d", 3*"#stride"+"#out"\n\t"
-
-/* in/out: mma=mma+mmb, mmb=mmb-mma */
-#define SUMSUB_BA( a, b ) \
- "paddw "#b", "#a" \n\t"\
- "paddw "#b", "#b" \n\t"\
- "psubw "#a", "#b" \n\t"
-
#define SBUTTERFLY(a,b,t,n,m)\
"mov" #m " " #a ", " #t " \n\t" /* abcd */\
"punpckl" #n " " #b ", " #a " \n\t" /* aebf */\
@@ -95,90 +77,6 @@ extern const double ff_pd_2[2];
SBUTTERFLY(a,c,d,dq,q) /* a=aeim d=bfjn */\
SBUTTERFLY(t,b,c,dq,q) /* t=cgko c=dhlp */
-static inline void transpose4x4(uint8_t *dst, uint8_t *src, x86_reg dst_stride, x86_reg src_stride){
- __asm__ volatile( //FIXME could save 1 instruction if done as 8x4 ...
- "movd (%1), %%mm0 \n\t"
- "add %3, %1 \n\t"
- "movd (%1), %%mm1 \n\t"
- "movd (%1,%3,1), %%mm2 \n\t"
- "movd (%1,%3,2), %%mm3 \n\t"
- "punpcklbw %%mm1, %%mm0 \n\t"
- "punpcklbw %%mm3, %%mm2 \n\t"
- "movq %%mm0, %%mm1 \n\t"
- "punpcklwd %%mm2, %%mm0 \n\t"
- "punpckhwd %%mm2, %%mm1 \n\t"
- "movd %%mm0, (%0) \n\t"
- "add %2, %0 \n\t"
- "punpckhdq %%mm0, %%mm0 \n\t"
- "movd %%mm0, (%0) \n\t"
- "movd %%mm1, (%0,%2,1) \n\t"
- "punpckhdq %%mm1, %%mm1 \n\t"
- "movd %%mm1, (%0,%2,2) \n\t"
-
- : "+&r" (dst),
- "+&r" (src)
- : "r" (dst_stride),
- "r" (src_stride)
- : "memory"
- );
-}
-
-// e,f,g,h can be memory
-// out: a,d,t,c
-#define TRANSPOSE8x4(a,b,c,d,e,f,g,h,t)\
- "punpcklbw " #e ", " #a " \n\t" /* a0 e0 a1 e1 a2 e2 a3 e3 */\
- "punpcklbw " #f ", " #b " \n\t" /* b0 f0 b1 f1 b2 f2 b3 f3 */\
- "punpcklbw " #g ", " #c " \n\t" /* c0 g0 c1 g1 c2 g2 d3 g3 */\
- "punpcklbw " #h ", " #d " \n\t" /* d0 h0 d1 h1 d2 h2 d3 h3 */\
- SBUTTERFLY(a, b, t, bw, q) /* a= a0 b0 e0 f0 a1 b1 e1 f1 */\
- /* t= a2 b2 e2 f2 a3 b3 e3 f3 */\
- SBUTTERFLY(c, d, b, bw, q) /* c= c0 d0 g0 h0 c1 d1 g1 h1 */\
- /* b= c2 d2 g2 h2 c3 d3 g3 h3 */\
- SBUTTERFLY(a, c, d, wd, q) /* a= a0 b0 c0 d0 e0 f0 g0 h0 */\
- /* d= a1 b1 c1 d1 e1 f1 g1 h1 */\
- SBUTTERFLY(t, b, c, wd, q) /* t= a2 b2 c2 d2 e2 f2 g2 h2 */\
- /* c= a3 b3 c3 d3 e3 f3 g3 h3 */
-
-#if ARCH_X86_64
-// permutes 01234567 -> 05736421
-#define TRANSPOSE8(a,b,c,d,e,f,g,h,t)\
- SBUTTERFLY(a,b,%%xmm8,wd,dqa)\
- SBUTTERFLY(c,d,b,wd,dqa)\
- SBUTTERFLY(e,f,d,wd,dqa)\
- SBUTTERFLY(g,h,f,wd,dqa)\
- SBUTTERFLY(a,c,h,dq,dqa)\
- SBUTTERFLY(%%xmm8,b,c,dq,dqa)\
- SBUTTERFLY(e,g,b,dq,dqa)\
- SBUTTERFLY(d,f,g,dq,dqa)\
- SBUTTERFLY(a,e,f,qdq,dqa)\
- SBUTTERFLY(%%xmm8,d,e,qdq,dqa)\
- SBUTTERFLY(h,b,d,qdq,dqa)\
- SBUTTERFLY(c,g,b,qdq,dqa)\
- "movdqa %%xmm8, "#g" \n\t"
-#else
-#define TRANSPOSE8(a,b,c,d,e,f,g,h,t)\
- "movdqa "#h", "#t" \n\t"\
- SBUTTERFLY(a,b,h,wd,dqa)\
- "movdqa "#h", 16"#t" \n\t"\
- "movdqa "#t", "#h" \n\t"\
- SBUTTERFLY(c,d,b,wd,dqa)\
- SBUTTERFLY(e,f,d,wd,dqa)\
- SBUTTERFLY(g,h,f,wd,dqa)\
- SBUTTERFLY(a,c,h,dq,dqa)\
- "movdqa "#h", "#t" \n\t"\
- "movdqa 16"#t", "#h" \n\t"\
- SBUTTERFLY(h,b,c,dq,dqa)\
- SBUTTERFLY(e,g,b,dq,dqa)\
- SBUTTERFLY(d,f,g,dq,dqa)\
- SBUTTERFLY(a,e,f,qdq,dqa)\
- SBUTTERFLY(h,d,e,qdq,dqa)\
- "movdqa "#h", 16"#t" \n\t"\
- "movdqa "#t", "#h" \n\t"\
- SBUTTERFLY(h,b,d,qdq,dqa)\
- SBUTTERFLY(c,g,b,qdq,dqa)\
- "movdqa 16"#t", "#g" \n\t"
-#endif
-
#define MOVQ_WONE(regd) \
__asm__ volatile ( \
"pcmpeqd %%" #regd ", %%" #regd " \n\t" \
@@ -199,6 +97,11 @@ void ff_avg_cavs_qpel16_mc00_mmx2(uint8_t *dst, uint8_t *src, int stride);
void ff_put_vc1_mspel_mc00_mmx(uint8_t *dst, const uint8_t *src, int stride, int rnd);
void ff_avg_vc1_mspel_mc00_mmx2(uint8_t *dst, const uint8_t *src, int stride, int rnd);
+void ff_put_rv40_qpel8_mc33_mmx(uint8_t *block, uint8_t *pixels, int line_size);
+void ff_put_rv40_qpel16_mc33_mmx(uint8_t *block, uint8_t *pixels, int line_size);
+void ff_avg_rv40_qpel8_mc33_mmx(uint8_t *block, uint8_t *pixels, int line_size);
+void ff_avg_rv40_qpel16_mc33_mmx(uint8_t *block, uint8_t *pixels, int line_size);
+
void ff_mmx_idct(DCTELEM *block);
void ff_mmxext_idct(DCTELEM *block);
diff --git a/libavcodec/x86/dsputil_yasm.asm b/libavcodec/x86/dsputil_yasm.asm
index 807c641..313e774 100644
--- a/libavcodec/x86/dsputil_yasm.asm
+++ b/libavcodec/x86/dsputil_yasm.asm
@@ -1130,6 +1130,85 @@ VECTOR_CLIP_INT32 6, 1, 0, 0
%endif
;-----------------------------------------------------------------------------
+; void vector_fmul_reverse(float *dst, const float *src0, const float *src1,
+; int len)
+;-----------------------------------------------------------------------------
+%macro VECTOR_FMUL_REVERSE 0
+cglobal vector_fmul_reverse, 4,4,2, dst, src0, src1, len
+ lea lenq, [lend*4 - 2*mmsize]
+ALIGN 16
+.loop
+%if cpuflag(avx)
+ vmovaps xmm0, [src1q + 16]
+ vinsertf128 m0, m0, [src1q], 1
+ vshufps m0, m0, m0, q0123
+ vmovaps xmm1, [src1q + mmsize + 16]
+ vinsertf128 m1, m1, [src1q + mmsize], 1
+ vshufps m1, m1, m1, q0123
+%else
+ mova m0, [src1q]
+ mova m1, [src1q + mmsize]
+ shufps m0, m0, q0123
+ shufps m1, m1, q0123
+%endif
+ mulps m0, m0, [src0q + lenq + mmsize]
+ mulps m1, m1, [src0q + lenq]
+ mova [dstq + lenq + mmsize], m0
+ mova [dstq + lenq], m1
+ add src1q, 2*mmsize
+ sub lenq, 2*mmsize
+ jge .loop
+%if mmsize == 32
+ vzeroupper
+ RET
+%else
+ REP_RET
+%endif
+%endmacro
+
+INIT_XMM sse
+VECTOR_FMUL_REVERSE
+%if HAVE_AVX
+INIT_YMM avx
+VECTOR_FMUL_REVERSE
+%endif
+
+;-----------------------------------------------------------------------------
+; vector_fmul_add(float *dst, const float *src0, const float *src1,
+; const float *src2, int len)
+;-----------------------------------------------------------------------------
+%macro VECTOR_FMUL_ADD 0
+cglobal vector_fmul_add, 5,5,2, dst, src0, src1, src2, len
+ lea lenq, [lend*4 - 2*mmsize]
+ALIGN 16
+.loop
+ mova m0, [src0q + lenq]
+ mova m1, [src0q + lenq + mmsize]
+ mulps m0, m0, [src1q + lenq]
+ mulps m1, m1, [src1q + lenq + mmsize]
+ addps m0, m0, [src2q + lenq]
+ addps m1, m1, [src2q + lenq + mmsize]
+ mova [dstq + lenq], m0
+ mova [dstq + lenq + mmsize], m1
+
+ sub lenq, 2*mmsize
+ jge .loop
+%if mmsize == 32
+ vzeroupper
+ RET
+%else
+ REP_RET
+%endif
+%endmacro
+
+INIT_XMM sse
+VECTOR_FMUL_ADD
+%if HAVE_AVX
+INIT_YMM avx
+VECTOR_FMUL_ADD
+%endif
+
+;-----------------------------------------------------------------------------
; void ff_butterflies_float_interleave(float *dst, const float *src0,
; const float *src1, int len);
;-----------------------------------------------------------------------------
@@ -1174,8 +1253,10 @@ cglobal butterflies_float_interleave, 4,4,3, dst, src0, src1, len
INIT_XMM sse
BUTTERFLIES_FLOAT_INTERLEAVE
+%if HAVE_AVX
INIT_YMM avx
BUTTERFLIES_FLOAT_INTERLEAVE
+%endif
INIT_XMM sse2
; %1 = aligned/unaligned
diff --git a/libavcodec/x86/dsputilenc_mmx.c b/libavcodec/x86/dsputilenc_mmx.c
index 2a403ba..47fa5ca 100644
--- a/libavcodec/x86/dsputilenc_mmx.c
+++ b/libavcodec/x86/dsputilenc_mmx.c
@@ -1127,8 +1127,8 @@ void ff_dsputilenc_init_mmx(DSPContext* c, AVCodecContext *avctx)
#endif
c->pix_norm1 = pix_norm1_mmx;
- c->sse[0] = (HAVE_YASM && mm_flags & AV_CPU_FLAG_SSE2) ? ff_sse16_sse2 : sse16_mmx;
- c->sse[1] = sse8_mmx;
+ c->sse[0] = sse16_mmx;
+ c->sse[1] = sse8_mmx;
c->vsad[4]= vsad_intra16_mmx;
c->nsse[0] = nsse16_mmx;
@@ -1146,11 +1146,11 @@ void ff_dsputilenc_init_mmx(DSPContext* c, AVCodecContext *avctx)
if (mm_flags & AV_CPU_FLAG_MMX2) {
- c->sum_abs_dctelem= sum_abs_dctelem_mmx2;
#if HAVE_YASM
c->hadamard8_diff[0]= ff_hadamard8_diff16_mmx2;
c->hadamard8_diff[1]= ff_hadamard8_diff_mmx2;
#endif
+ c->sum_abs_dctelem= sum_abs_dctelem_mmx2;
c->vsad[4]= vsad_intra16_mmx2;
if(!(avctx->flags & CODEC_FLAG_BITEXACT)){
@@ -1164,10 +1164,13 @@ void ff_dsputilenc_init_mmx(DSPContext* c, AVCodecContext *avctx)
if (bit_depth <= 8)
c->get_pixels = get_pixels_sse2;
c->sum_abs_dctelem= sum_abs_dctelem_sse2;
-#if HAVE_YASM && HAVE_ALIGNED_STACK
+#if HAVE_YASM
+ c->sse[0] = ff_sse16_sse2;
+#if HAVE_ALIGNED_STACK
c->hadamard8_diff[0]= ff_hadamard8_diff16_sse2;
c->hadamard8_diff[1]= ff_hadamard8_diff_sse2;
#endif
+#endif
}
#if HAVE_SSSE3
diff --git a/libavcodec/x86/fft.c b/libavcodec/x86/fft.c
index 3e0c42f..6349c23 100644
--- a/libavcodec/x86/fft.c
+++ b/libavcodec/x86/fft.c
@@ -25,30 +25,31 @@ av_cold void ff_fft_init_mmx(FFTContext *s)
{
#if HAVE_YASM
int has_vectors = av_get_cpu_flags();
- if (has_vectors & AV_CPU_FLAG_AVX && HAVE_AVX && s->nbits >= 5) {
- /* AVX for SB */
- s->imdct_calc = ff_imdct_calc_sse;
- s->imdct_half = ff_imdct_half_avx;
- s->fft_permute = ff_fft_permute_sse;
- s->fft_calc = ff_fft_calc_avx;
- s->fft_permutation = FF_FFT_PERM_AVX;
- } else if (has_vectors & AV_CPU_FLAG_SSE && HAVE_SSE) {
+ if (has_vectors & AV_CPU_FLAG_3DNOW && HAVE_AMD3DNOW) {
+ /* 3DNow! for K6-2/3 */
+ s->imdct_calc = ff_imdct_calc_3dnow;
+ s->imdct_half = ff_imdct_half_3dnow;
+ s->fft_calc = ff_fft_calc_3dnow;
+ }
+ if (has_vectors & AV_CPU_FLAG_3DNOWEXT && HAVE_AMD3DNOWEXT) {
+ /* 3DNowEx for K7 */
+ s->imdct_calc = ff_imdct_calc_3dnow2;
+ s->imdct_half = ff_imdct_half_3dnow2;
+ s->fft_calc = ff_fft_calc_3dnow2;
+ }
+ if (has_vectors & AV_CPU_FLAG_SSE && HAVE_SSE) {
/* SSE for P3/P4/K8 */
s->imdct_calc = ff_imdct_calc_sse;
s->imdct_half = ff_imdct_half_sse;
s->fft_permute = ff_fft_permute_sse;
s->fft_calc = ff_fft_calc_sse;
s->fft_permutation = FF_FFT_PERM_SWAP_LSBS;
- } else if (has_vectors & AV_CPU_FLAG_3DNOWEXT && HAVE_AMD3DNOWEXT) {
- /* 3DNowEx for K7 */
- s->imdct_calc = ff_imdct_calc_3dn2;
- s->imdct_half = ff_imdct_half_3dn2;
- s->fft_calc = ff_fft_calc_3dn2;
- } else if (has_vectors & AV_CPU_FLAG_3DNOW && HAVE_AMD3DNOW) {
- /* 3DNow! for K6-2/3 */
- s->imdct_calc = ff_imdct_calc_3dn;
- s->imdct_half = ff_imdct_half_3dn;
- s->fft_calc = ff_fft_calc_3dn;
+ }
+ if (has_vectors & AV_CPU_FLAG_AVX && HAVE_AVX && s->nbits >= 5) {
+ /* AVX for SB */
+ s->imdct_half = ff_imdct_half_avx;
+ s->fft_calc = ff_fft_calc_avx;
+ s->fft_permutation = FF_FFT_PERM_AVX;
}
#endif
}
@@ -58,12 +59,12 @@ av_cold void ff_dct_init_mmx(DCTContext *s)
{
#if HAVE_YASM
int has_vectors = av_get_cpu_flags();
+ if (has_vectors & AV_CPU_FLAG_SSE && HAVE_SSE)
+ s->dct32 = ff_dct32_float_sse;
+ if (has_vectors & AV_CPU_FLAG_SSE2 && HAVE_SSE)
+ s->dct32 = ff_dct32_float_sse2;
if (has_vectors & AV_CPU_FLAG_AVX && HAVE_AVX)
s->dct32 = ff_dct32_float_avx;
- else if (has_vectors & AV_CPU_FLAG_SSE2 && HAVE_SSE)
- s->dct32 = ff_dct32_float_sse2;
- else if (has_vectors & AV_CPU_FLAG_SSE && HAVE_SSE)
- s->dct32 = ff_dct32_float_sse;
#endif
}
#endif
diff --git a/libavcodec/x86/fft.h b/libavcodec/x86/fft.h
index 9d68d5b..1cefe7a 100644
--- a/libavcodec/x86/fft.h
+++ b/libavcodec/x86/fft.h
@@ -24,13 +24,13 @@
void ff_fft_permute_sse(FFTContext *s, FFTComplex *z);
void ff_fft_calc_avx(FFTContext *s, FFTComplex *z);
void ff_fft_calc_sse(FFTContext *s, FFTComplex *z);
-void ff_fft_calc_3dn(FFTContext *s, FFTComplex *z);
-void ff_fft_calc_3dn2(FFTContext *s, FFTComplex *z);
+void ff_fft_calc_3dnow(FFTContext *s, FFTComplex *z);
+void ff_fft_calc_3dnow2(FFTContext *s, FFTComplex *z);
-void ff_imdct_calc_3dn(FFTContext *s, FFTSample *output, const FFTSample *input);
-void ff_imdct_half_3dn(FFTContext *s, FFTSample *output, const FFTSample *input);
-void ff_imdct_calc_3dn2(FFTContext *s, FFTSample *output, const FFTSample *input);
-void ff_imdct_half_3dn2(FFTContext *s, FFTSample *output, const FFTSample *input);
+void ff_imdct_calc_3dnow(FFTContext *s, FFTSample *output, const FFTSample *input);
+void ff_imdct_half_3dnow(FFTContext *s, FFTSample *output, const FFTSample *input);
+void ff_imdct_calc_3dnow2(FFTContext *s, FFTSample *output, const FFTSample *input);
+void ff_imdct_half_3dnow2(FFTContext *s, FFTSample *output, const FFTSample *input);
void ff_imdct_calc_sse(FFTContext *s, FFTSample *output, const FFTSample *input);
void ff_imdct_half_sse(FFTContext *s, FFTSample *output, const FFTSample *input);
void ff_imdct_half_avx(FFTContext *s, FFTSample *output, const FFTSample *input);
diff --git a/libavcodec/x86/fft_3dn2.c b/libavcodec/x86/fft_3dn2.c
index ce3c9da..e684cc7 100644
--- a/libavcodec/x86/fft_3dn2.c
+++ b/libavcodec/x86/fft_3dn2.c
@@ -30,30 +30,30 @@ DECLARE_ALIGNED(8, static const unsigned int, m1m1)[2] = { 1U<<31, 1U<<31 };
"movq "#s","#d"\n"\
"psrlq $32,"#d"\n"\
"punpckldq "#s","#d"\n"
-#define ff_fft_calc_3dn2 ff_fft_calc_3dn
-#define ff_fft_dispatch_3dn2 ff_fft_dispatch_3dn
-#define ff_fft_dispatch_interleave_3dn2 ff_fft_dispatch_interleave_3dn
-#define ff_imdct_calc_3dn2 ff_imdct_calc_3dn
-#define ff_imdct_half_3dn2 ff_imdct_half_3dn
+#define ff_fft_calc_3dnow2 ff_fft_calc_3dnow
+#define ff_fft_dispatch_3dnow2 ff_fft_dispatch_3dnow
+#define ff_fft_dispatch_interleave_3dnow2 ff_fft_dispatch_interleave_3dnow
+#define ff_imdct_calc_3dnow2 ff_imdct_calc_3dnow
+#define ff_imdct_half_3dnow2 ff_imdct_half_3dnow
#else
#define PSWAPD(s,d) "pswapd "#s","#d"\n"
#endif
-void ff_fft_dispatch_3dn2(FFTComplex *z, int nbits);
-void ff_fft_dispatch_interleave_3dn2(FFTComplex *z, int nbits);
+void ff_fft_dispatch_3dnow2(FFTComplex *z, int nbits);
+void ff_fft_dispatch_interleave_3dnow2(FFTComplex *z, int nbits);
-void ff_fft_calc_3dn2(FFTContext *s, FFTComplex *z)
+void ff_fft_calc_3dnow2(FFTContext *s, FFTComplex *z)
{
int n = 1<<s->nbits;
int i;
- ff_fft_dispatch_interleave_3dn2(z, s->nbits);
+ ff_fft_dispatch_interleave_3dnow2(z, s->nbits);
__asm__ volatile("femms");
if(n <= 8)
for(i=0; i<n; i+=2)
FFSWAP(FFTSample, z[i].im, z[i+1].re);
}
-void ff_imdct_half_3dn2(FFTContext *s, FFTSample *output, const FFTSample *input)
+void ff_imdct_half_3dnow2(FFTContext *s, FFTSample *output, const FFTSample *input)
{
x86_reg j, k;
long n = s->mdct_size;
@@ -101,7 +101,7 @@ void ff_imdct_half_3dn2(FFTContext *s, FFTSample *output, const FFTSample *input
);
}
- ff_fft_dispatch_3dn2(z, s->nbits);
+ ff_fft_dispatch_3dnow2(z, s->nbits);
#define CMUL(j,mm0,mm1)\
"movq (%2,"#j",2), %%mm6 \n"\
@@ -144,13 +144,13 @@ void ff_imdct_half_3dn2(FFTContext *s, FFTSample *output, const FFTSample *input
__asm__ volatile("femms");
}
-void ff_imdct_calc_3dn2(FFTContext *s, FFTSample *output, const FFTSample *input)
+void ff_imdct_calc_3dnow2(FFTContext *s, FFTSample *output, const FFTSample *input)
{
x86_reg j, k;
long n = s->mdct_size;
long n4 = n >> 2;
- ff_imdct_half_3dn2(s, output+n4, input);
+ ff_imdct_half_3dnow2(s, output+n4, input);
j = -n;
k = n-8;
diff --git a/libavcodec/x86/fft_mmx.asm b/libavcodec/x86/fft_mmx.asm
index 225c666..1a430b9 100644
--- a/libavcodec/x86/fft_mmx.asm
+++ b/libavcodec/x86/fft_mmx.asm
@@ -45,6 +45,10 @@ struc FFTContext
.mdctbits: resd 1
.tcos: pointer 1
.tsin: pointer 1
+ .fftperm: pointer 1
+ .fftcalc: pointer 1
+ .imdctcalc:pointer 1
+ .imdcthalf:pointer 1
endstruc
SECTION_RODATA
@@ -65,6 +69,7 @@ perm1: dd 0x00, 0x02, 0x03, 0x01, 0x03, 0x00, 0x02, 0x01
perm2: dd 0x00, 0x01, 0x02, 0x03, 0x01, 0x00, 0x02, 0x03
ps_p1p1m1p1root2: dd 1.0, 1.0, -1.0, 1.0, M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, M_SQRT1_2
ps_m1m1p1m1p1m1m1m1: dd 1<<31, 1<<31, 0, 1<<31, 0, 1<<31, 1<<31, 1<<31
+ps_m1m1m1m1: times 4 dd 1<<31
ps_m1p1: dd 1<<31, 0
%assign i 16
@@ -297,7 +302,7 @@ IF%1 mova Z(1), m5
%define Z2(x) [r0+mmsize*x]
%define ZH(x) [r0+mmsize*x+mmsize/2]
-INIT_YMM
+INIT_YMM avx
%if HAVE_AVX
align 16
@@ -390,7 +395,7 @@ fft32_interleave_avx:
ret
%endif
-INIT_XMM
+INIT_XMM sse
%define movdqa movaps
align 16
@@ -439,11 +444,9 @@ fft16_sse:
ret
-INIT_MMX
-
-%macro FFT48_3DN 1
+%macro FFT48_3DN 0
align 16
-fft4%1:
+fft4 %+ SUFFIX:
T2_3DN m0, m1, Z(0), Z(1)
mova m2, Z(2)
mova m3, Z(3)
@@ -457,7 +460,7 @@ fft4%1:
ret
align 16
-fft8%1:
+fft8 %+ SUFFIX:
T2_3DN m0, m1, Z(0), Z(1)
mova m2, Z(2)
mova m3, Z(3)
@@ -495,7 +498,8 @@ fft8%1:
ret
%endmacro
-FFT48_3DN _3dn2
+INIT_MMX 3dnow2
+FFT48_3DN
%macro pswapd 2
%ifidn %1, %2
@@ -508,7 +512,8 @@ FFT48_3DN _3dn2
%endif
%endmacro
-FFT48_3DN _3dn
+INIT_MMX 3dnow
+FFT48_3DN
%define Z(x) [zq + o1q*(x&6) + mmsize*(x&1)]
@@ -532,7 +537,17 @@ DEFINE_ARGS z, w, n, o1, o3
rep ret
%endmacro
-INIT_YMM
+%macro FFT_DISPATCH 2; clobbers 5 GPRs, 8 XMMs
+ lea r2, [dispatch_tab%1]
+ mov r2, [r2 + (%2q-2)*gprsize]
+%ifdef PIC
+ lea r3, [$$]
+ add r2, r3
+%endif
+ call r2
+%endmacro ; FFT_DISPATCH
+
+INIT_YMM avx
%if HAVE_AVX
%macro INTERL_AVX 5
@@ -548,9 +563,17 @@ INIT_YMM
DECL_PASS pass_avx, PASS_BIG 1
DECL_PASS pass_interleave_avx, PASS_BIG 0
+
+cglobal fft_calc, 2,5,8
+ mov r3d, [r0 + FFTContext.nbits]
+ mov r0, r1
+ mov r1, r3
+ FFT_DISPATCH _interleave %+ SUFFIX, r1
+ REP_RET
+
%endif
-INIT_XMM
+INIT_XMM sse
%macro INTERL_SSE 5
mova %3, %2
@@ -565,16 +588,115 @@ INIT_XMM
DECL_PASS pass_sse, PASS_BIG 1
DECL_PASS pass_interleave_sse, PASS_BIG 0
-INIT_MMX
+cglobal fft_calc, 2,5,8
+ mov r3d, [r0 + FFTContext.nbits]
+ PUSH r1
+ PUSH r3
+ mov r0, r1
+ mov r1, r3
+ FFT_DISPATCH _interleave %+ SUFFIX, r1
+ POP rcx
+ POP r4
+ cmp rcx, 4
+ jg .end
+ mov r2, -1
+ add rcx, 3
+ shl r2, cl
+ sub r4, r2
+.loop
+ movaps xmm0, [r4 + r2]
+ movaps xmm1, xmm0
+ unpcklps xmm0, [r4 + r2 + 16]
+ unpckhps xmm1, [r4 + r2 + 16]
+ movaps [r4 + r2], xmm0
+ movaps [r4 + r2 + 16], xmm1
+ add r2, 32
+ jl .loop
+.end:
+ REP_RET
+
+cglobal fft_permute, 2,7,1
+ mov r4, [r0 + FFTContext.revtab]
+ mov r5, [r0 + FFTContext.tmpbuf]
+ mov ecx, [r0 + FFTContext.nbits]
+ mov r2, 1
+ shl r2, cl
+ xor r0, r0
+%if ARCH_X86_32
+ mov r1, r1m
+%endif
+.loop:
+ movaps xmm0, [r1 + 8*r0]
+ movzx r6, word [r4 + 2*r0]
+ movzx r3, word [r4 + 2*r0 + 2]
+ movlps [r5 + 8*r6], xmm0
+ movhps [r5 + 8*r3], xmm0
+ add r0, 2
+ cmp r0, r2
+ jl .loop
+ shl r2, 3
+ add r1, r2
+ add r5, r2
+ neg r2
+; nbits >= 2 (FFT4) and sizeof(FFTComplex)=8 => at least 32B
+.loopcopy:
+ movaps xmm0, [r5 + r2]
+ movaps xmm1, [r5 + r2 + 16]
+ movaps [r1 + r2], xmm0
+ movaps [r1 + r2 + 16], xmm1
+ add r2, 32
+ jl .loopcopy
+ REP_RET
+
+cglobal imdct_calc, 3,5,3
+ mov r3d, [r0 + FFTContext.mdctsize]
+ mov r4, [r0 + FFTContext.imdcthalf]
+ add r1, r3
+ PUSH r3
+ PUSH r1
+%if ARCH_X86_32
+ push r2
+ push r1
+ push r0
+%else
+ sub rsp, 8
+%endif
+ call r4
+%if ARCH_X86_32
+ add esp, 12
+%else
+ add rsp, 8
+%endif
+ POP r1
+ POP r3
+ lea r0, [r1 + 2*r3]
+ mov r2, r3
+ sub r3, 16
+ neg r2
+ movaps xmm2, [ps_m1m1m1m1]
+.loop:
+ movaps xmm0, [r1 + r3]
+ movaps xmm1, [r0 + r2]
+ shufps xmm0, xmm0, 0x1b
+ shufps xmm1, xmm1, 0x1b
+ xorps xmm0, xmm2
+ movaps [r0 + r3], xmm1
+ movaps [r1 + r2], xmm0
+ sub r3, 16
+ add r2, 16
+ jl .loop
+ REP_RET
+
+INIT_MMX 3dnow
%define mulps pfmul
%define addps pfadd
%define subps pfsub
%define unpcklps punpckldq
%define unpckhps punpckhdq
-DECL_PASS pass_3dn, PASS_SMALL 1, [wq], [wq+o1q]
-DECL_PASS pass_interleave_3dn, PASS_BIG 0
-%define pass_3dn2 pass_3dn
-%define pass_interleave_3dn2 pass_interleave_3dn
+DECL_PASS pass_3dnow, PASS_SMALL 1, [wq], [wq+o1q]
+DECL_PASS pass_interleave_3dnow, PASS_BIG 0
+%define pass_3dnow2 pass_3dnow
+%define pass_interleave_3dnow2 pass_interleave_3dnow
%ifdef PIC
%define SECTION_REL - $$
@@ -582,77 +704,73 @@ DECL_PASS pass_interleave_3dn, PASS_BIG 0
%define SECTION_REL
%endif
-%macro FFT_DISPATCH 2; clobbers 5 GPRs, 8 XMMs
- lea r2, [dispatch_tab%1]
- mov r2, [r2 + (%2q-2)*gprsize]
-%ifdef PIC
- lea r3, [$$]
- add r2, r3
+%macro DECL_FFT 1-2 ; nbits, suffix
+%ifidn %0, 1
+%xdefine fullsuffix SUFFIX
+%else
+%xdefine fullsuffix %2 %+ SUFFIX
%endif
- call r2
-%endmacro ; FFT_DISPATCH
-
-%macro DECL_FFT 2-3 ; nbits, cpu, suffix
-%xdefine list_of_fft fft4%2 SECTION_REL, fft8%2 SECTION_REL
+%xdefine list_of_fft fft4 %+ SUFFIX SECTION_REL, fft8 %+ SUFFIX SECTION_REL
%if %1>=5
-%xdefine list_of_fft list_of_fft, fft16%2 SECTION_REL
+%xdefine list_of_fft list_of_fft, fft16 %+ SUFFIX SECTION_REL
%endif
%if %1>=6
-%xdefine list_of_fft list_of_fft, fft32%3%2 SECTION_REL
+%xdefine list_of_fft list_of_fft, fft32 %+ fullsuffix SECTION_REL
%endif
%assign n 1<<%1
%rep 17-%1
%assign n2 n/2
%assign n4 n/4
-%xdefine list_of_fft list_of_fft, fft %+ n %+ %3%2 SECTION_REL
+%xdefine list_of_fft list_of_fft, fft %+ n %+ fullsuffix SECTION_REL
align 16
-fft %+ n %+ %3%2:
- call fft %+ n2 %+ %2
+fft %+ n %+ fullsuffix:
+ call fft %+ n2 %+ SUFFIX
add r0, n*4 - (n&(-2<<%1))
- call fft %+ n4 %+ %2
+ call fft %+ n4 %+ SUFFIX
add r0, n*2 - (n2&(-2<<%1))
- call fft %+ n4 %+ %2
+ call fft %+ n4 %+ SUFFIX
sub r0, n*6 + (n2&(-2<<%1))
lea r1, [cos_ %+ n]
mov r2d, n4/2
- jmp pass%3%2
+ jmp pass %+ fullsuffix
%assign n n*2
%endrep
%undef n
align 8
-dispatch_tab%3%2: pointer list_of_fft
+dispatch_tab %+ fullsuffix: pointer list_of_fft
section .text
; On x86_32, this function does the register saving and restoring for all of fft.
; The others pass args in registers and don't spill anything.
-cglobal fft_dispatch%3%2, 2,5,8, z, nbits
- FFT_DISPATCH %3%2, nbits
-%ifidn %2, _avx
+cglobal fft_dispatch%2, 2,5,8, z, nbits
+ FFT_DISPATCH fullsuffix, nbits
+%if mmsize == 32
vzeroupper
%endif
RET
%endmacro ; DECL_FFT
%if HAVE_AVX
-INIT_YMM
-DECL_FFT 6, _avx
-DECL_FFT 6, _avx, _interleave
+INIT_YMM avx
+DECL_FFT 6
+DECL_FFT 6, _interleave
%endif
-INIT_XMM
-DECL_FFT 5, _sse
-DECL_FFT 5, _sse, _interleave
-INIT_MMX
-DECL_FFT 4, _3dn
-DECL_FFT 4, _3dn, _interleave
-DECL_FFT 4, _3dn2
-DECL_FFT 4, _3dn2, _interleave
-
-INIT_XMM
+INIT_XMM sse
+DECL_FFT 5
+DECL_FFT 5, _interleave
+INIT_MMX 3dnow
+DECL_FFT 4
+DECL_FFT 4, _interleave
+INIT_MMX 3dnow2
+DECL_FFT 4
+DECL_FFT 4, _interleave
+
+INIT_XMM sse
%undef mulps
%undef addps
%undef subps
@@ -748,8 +866,8 @@ INIT_XMM
jl .post
%endmacro
-%macro DECL_IMDCT 2
-cglobal imdct_half%1, 3,12,8; FFTContext *s, FFTSample *output, const FFTSample *input
+%macro DECL_IMDCT 1
+cglobal imdct_half, 3,12,8; FFTContext *s, FFTSample *output, const FFTSample *input
%if ARCH_X86_64
%define rrevtab r7
%define rtcos r8
@@ -821,7 +939,7 @@ cglobal imdct_half%1, 3,12,8; FFTContext *s, FFTSample *output, const FFTSample
mov r0, r1
mov r1d, [r5+FFTContext.nbits]
- FFT_DISPATCH %1, r1
+ FFT_DISPATCH SUFFIX, r1
mov r0d, [r5+FFTContext.mdctsize]
add r6, r0
@@ -835,20 +953,20 @@ cglobal imdct_half%1, 3,12,8; FFTContext *s, FFTSample *output, const FFTSample
neg r0
mov r1, -mmsize
sub r1, r0
- %2 r0, r1, r6, rtcos, rtsin
+ %1 r0, r1, r6, rtcos, rtsin
%if ARCH_X86_64 == 0
add esp, 12
%endif
-%ifidn avx_enabled, 1
+%if mmsize == 32
vzeroupper
%endif
RET
%endmacro
-DECL_IMDCT _sse, POSROTATESHUF
+DECL_IMDCT POSROTATESHUF
-INIT_YMM
+INIT_YMM avx
%if HAVE_AVX
-DECL_IMDCT _avx, POSROTATESHUF_AVX
+DECL_IMDCT POSROTATESHUF_AVX
%endif
diff --git a/libavcodec/x86/fft_sse.c b/libavcodec/x86/fft_sse.c
deleted file mode 100644
index 13b992f..0000000
--- a/libavcodec/x86/fft_sse.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * FFT/MDCT transform with SSE optimizations
- * Copyright (c) 2008 Loren Merritt
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "libavutil/x86_cpu.h"
-#include "libavcodec/dsputil.h"
-#include "fft.h"
-#include "config.h"
-
-DECLARE_ASM_CONST(16, unsigned int, ff_m1m1m1m1)[4] =
- { 1U << 31, 1U << 31, 1U << 31, 1U << 31 };
-
-void ff_fft_dispatch_sse(FFTComplex *z, int nbits);
-void ff_fft_dispatch_interleave_sse(FFTComplex *z, int nbits);
-void ff_fft_dispatch_interleave_avx(FFTComplex *z, int nbits);
-
-#if HAVE_AVX
-void ff_fft_calc_avx(FFTContext *s, FFTComplex *z)
-{
- ff_fft_dispatch_interleave_avx(z, s->nbits);
-}
-#endif
-
-void ff_fft_calc_sse(FFTContext *s, FFTComplex *z)
-{
- int n = 1 << s->nbits;
-
- ff_fft_dispatch_interleave_sse(z, s->nbits);
-
- if(n <= 16) {
- x86_reg i = -8*n;
- __asm__ volatile(
- "1: \n"
- "movaps (%0,%1), %%xmm0 \n"
- "movaps %%xmm0, %%xmm1 \n"
- "unpcklps 16(%0,%1), %%xmm0 \n"
- "unpckhps 16(%0,%1), %%xmm1 \n"
- "movaps %%xmm0, (%0,%1) \n"
- "movaps %%xmm1, 16(%0,%1) \n"
- "add $32, %0 \n"
- "jl 1b \n"
- :"+r"(i)
- :"r"(z+n)
- :"memory"
- );
- }
-}
-
-void ff_fft_permute_sse(FFTContext *s, FFTComplex *z)
-{
- int n = 1 << s->nbits;
- int i;
- for(i=0; i<n; i+=2) {
- __asm__ volatile(
- "movaps %2, %%xmm0 \n"
- "movlps %%xmm0, %0 \n"
- "movhps %%xmm0, %1 \n"
- :"=m"(s->tmp_buf[s->revtab[i]]),
- "=m"(s->tmp_buf[s->revtab[i+1]])
- :"m"(z[i])
- );
- }
- memcpy(z, s->tmp_buf, n*sizeof(FFTComplex));
-}
-
-void ff_imdct_calc_sse(FFTContext *s, FFTSample *output, const FFTSample *input)
-{
- x86_reg j, k;
- long n = s->mdct_size;
- long n4 = n >> 2;
-
- s->imdct_half(s, output + n4, input);
-
- j = -n;
- k = n-16;
- __asm__ volatile(
- "movaps "MANGLE(ff_m1m1m1m1)", %%xmm7 \n"
- "1: \n"
- "movaps (%2,%1), %%xmm0 \n"
- "movaps (%3,%0), %%xmm1 \n"
- "shufps $0x1b, %%xmm0, %%xmm0 \n"
- "shufps $0x1b, %%xmm1, %%xmm1 \n"
- "xorps %%xmm7, %%xmm0 \n"
- "movaps %%xmm1, (%3,%1) \n"
- "movaps %%xmm0, (%2,%0) \n"
- "sub $16, %1 \n"
- "add $16, %0 \n"
- "jl 1b \n"
- :"+r"(j), "+r"(k)
- :"r"(output+n4), "r"(output+n4*3)
- XMM_CLOBBERS_ONLY("%xmm0", "%xmm1", "%xmm7")
- );
-}
diff --git a/libavcodec/x86/fmtconvert.asm b/libavcodec/x86/fmtconvert.asm
index 63befc9..4916e7a 100644
--- a/libavcodec/x86/fmtconvert.asm
+++ b/libavcodec/x86/fmtconvert.asm
@@ -115,6 +115,84 @@ FLOAT_TO_INT16 sse, 0
FLOAT_TO_INT16 3dnow, 0
%undef cvtps2pi
+;------------------------------------------------------------------------------
+; void ff_float_to_int16_step(int16_t *dst, const float *src, long len, long step);
+;------------------------------------------------------------------------------
+%macro FLOAT_TO_INT16_STEP 2
+cglobal float_to_int16_step_%1, 4,7,%2, dst, src, len, step, step3, v1, v2
+ add lenq, lenq
+ lea srcq, [srcq+2*lenq]
+ lea step3q, [stepq*3]
+ neg lenq
+.loop:
+%ifidn %1, sse2
+ cvtps2dq m0, [srcq+2*lenq ]
+ cvtps2dq m1, [srcq+2*lenq+16]
+ packssdw m0, m1
+ movd v1d, m0
+ psrldq m0, 4
+ movd v2d, m0
+ psrldq m0, 4
+ mov [dstq], v1w
+ mov [dstq+stepq*4], v2w
+ shr v1d, 16
+ shr v2d, 16
+ mov [dstq+stepq*2], v1w
+ mov [dstq+step3q*2], v2w
+ lea dstq, [dstq+stepq*8]
+ movd v1d, m0
+ psrldq m0, 4
+ movd v2d, m0
+ mov [dstq], v1w
+ mov [dstq+stepq*4], v2w
+ shr v1d, 16
+ shr v2d, 16
+ mov [dstq+stepq*2], v1w
+ mov [dstq+step3q*2], v2w
+ lea dstq, [dstq+stepq*8]
+%else
+ cvtps2pi m0, [srcq+2*lenq ]
+ cvtps2pi m1, [srcq+2*lenq+ 8]
+ cvtps2pi m2, [srcq+2*lenq+16]
+ cvtps2pi m3, [srcq+2*lenq+24]
+ packssdw m0, m1
+ packssdw m2, m3
+ movd v1d, m0
+ psrlq m0, 32
+ movd v2d, m0
+ mov [dstq], v1w
+ mov [dstq+stepq*4], v2w
+ shr v1d, 16
+ shr v2d, 16
+ mov [dstq+stepq*2], v1w
+ mov [dstq+step3q*2], v2w
+ lea dstq, [dstq+stepq*8]
+ movd v1d, m2
+ psrlq m2, 32
+ movd v2d, m2
+ mov [dstq], v1w
+ mov [dstq+stepq*4], v2w
+ shr v1d, 16
+ shr v2d, 16
+ mov [dstq+stepq*2], v1w
+ mov [dstq+step3q*2], v2w
+ lea dstq, [dstq+stepq*8]
+%endif
+ add lenq, 16
+ js .loop
+%ifnidn %1, sse2
+ emms
+%endif
+ REP_RET
+%endmacro
+
+INIT_XMM
+FLOAT_TO_INT16_STEP sse2, 2
+INIT_MMX
+FLOAT_TO_INT16_STEP sse, 0
+%define cvtps2pi pf2id
+FLOAT_TO_INT16_STEP 3dnow, 0
+%undef cvtps2pi
;-------------------------------------------------------------------------------
; void ff_float_to_int16_interleave2(int16_t *dst, const float **src, long len);
diff --git a/libavcodec/x86/fmtconvert_mmx.c b/libavcodec/x86/fmtconvert_mmx.c
index 42cb0bc..aaf634d 100644
--- a/libavcodec/x86/fmtconvert_mmx.c
+++ b/libavcodec/x86/fmtconvert_mmx.c
@@ -25,6 +25,7 @@
#include "libavutil/cpu.h"
#include "libavutil/x86_cpu.h"
#include "libavcodec/fmtconvert.h"
+#include "libavcodec/dsputil.h"
#if HAVE_YASM
@@ -35,6 +36,10 @@ void ff_float_to_int16_3dnow(int16_t *dst, const float *src, long len);
void ff_float_to_int16_sse (int16_t *dst, const float *src, long len);
void ff_float_to_int16_sse2 (int16_t *dst, const float *src, long len);
+void ff_float_to_int16_step_3dnow(int16_t *dst, const float *src, long len, long step);
+void ff_float_to_int16_step_sse (int16_t *dst, const float *src, long len, long step);
+void ff_float_to_int16_step_sse2 (int16_t *dst, const float *src, long len, long step);
+
void ff_float_to_int16_interleave2_3dnow(int16_t *dst, const float **src, long len);
void ff_float_to_int16_interleave2_sse (int16_t *dst, const float **src, long len);
void ff_float_to_int16_interleave2_sse2 (int16_t *dst, const float **src, long len);
@@ -48,12 +53,9 @@ void ff_float_to_int16_interleave6_3dn2(int16_t *dst, const float **src, int len
#define FLOAT_TO_INT16_INTERLEAVE(cpu) \
/* gcc pessimizes register allocation if this is in the same function as float_to_int16_interleave_sse2*/\
static av_noinline void float_to_int16_interleave_misc_##cpu(int16_t *dst, const float **src, long len, int channels){\
- DECLARE_ALIGNED(16, int16_t, tmp)[len];\
- int i,j,c;\
+ int c;\
for(c=0; c<channels; c++){\
- ff_float_to_int16_##cpu(tmp, src[c], len);\
- for(i=0, j=c; i<len; i++, j+=channels)\
- dst[j] = tmp[i];\
+ ff_float_to_int16_step_##cpu(dst+c, src[c], len, channels);\
}\
}\
\
diff --git a/libavcodec/x86/h264_i386.h b/libavcodec/x86/h264_i386.h
index 10ea32e..2daa40a 100644
--- a/libavcodec/x86/h264_i386.h
+++ b/libavcodec/x86/h264_i386.h
@@ -34,9 +34,12 @@
#include "libavcodec/cabac.h"
#include "cabac.h"
+#if HAVE_INLINE_ASM
+
//FIXME use some macros to avoid duplicating get_cabac (cannot be done yet
//as that would make optimization work hard)
#if HAVE_7REGS
+#define decode_significance decode_significance_x86
static int decode_significance_x86(CABACContext *c, int max_coeff,
uint8_t *significant_coeff_ctx_base,
int *index, x86_reg last_off){
@@ -105,6 +108,7 @@ static int decode_significance_x86(CABACContext *c, int max_coeff,
return coeff_count;
}
+#define decode_significance_8x8 decode_significance_8x8_x86
static int decode_significance_8x8_x86(CABACContext *c,
uint8_t *significant_coeff_ctx_base,
int *index, uint8_t *last_coeff_ctx_base, const uint8_t *sig_off){
@@ -185,4 +189,5 @@ static int decode_significance_8x8_x86(CABACContext *c,
}
#endif /* HAVE_7REGS && !defined(BROKEN_RELOCATIONS) */
+#endif /* HAVE_INLINE_ASM */
#endif /* AVCODEC_X86_H264_I386_H */
diff --git a/libavcodec/x86/h264_intrapred.asm b/libavcodec/x86/h264_intrapred.asm
index 3beb3b9..50a615b 100644
--- a/libavcodec/x86/h264_intrapred.asm
+++ b/libavcodec/x86/h264_intrapred.asm
@@ -87,31 +87,24 @@ cglobal pred16x16_vertical_sse, 2,3
; void pred16x16_horizontal(uint8_t *src, int stride)
;-----------------------------------------------------------------------------
-%macro PRED16x16_H 1
-cglobal pred16x16_horizontal_%1, 2,3
+%macro PRED16x16_H 0
+cglobal pred16x16_horizontal, 2,3
mov r2, 8
-%ifidn %1, ssse3
+%if cpuflag(ssse3)
mova m2, [pb_3]
%endif
.loop:
movd m0, [r0+r1*0-4]
movd m1, [r0+r1*1-4]
-%ifidn %1, ssse3
+%if cpuflag(ssse3)
pshufb m0, m2
pshufb m1, m2
%else
punpcklbw m0, m0
punpcklbw m1, m1
-%ifidn %1, mmxext
- pshufw m0, m0, 0xff
- pshufw m1, m1, 0xff
-%else
- punpckhwd m0, m0
- punpckhwd m1, m1
- punpckhdq m0, m0
- punpckhdq m1, m1
-%endif
+ SPLATW m0, m0, 3
+ SPLATW m1, m1, 3
mova [r0+r1*0+8], m0
mova [r0+r1*1+8], m1
%endif
@@ -124,18 +117,20 @@ cglobal pred16x16_horizontal_%1, 2,3
REP_RET
%endmacro
-INIT_MMX
-PRED16x16_H mmx
-PRED16x16_H mmxext
+INIT_MMX mmx
+PRED16x16_H
+INIT_MMX mmx2
+PRED16x16_H
+INIT_XMM ssse3
+PRED16x16_H
INIT_XMM
-PRED16x16_H ssse3
;-----------------------------------------------------------------------------
; void pred16x16_dc(uint8_t *src, int stride)
;-----------------------------------------------------------------------------
-%macro PRED16x16_DC 1
-cglobal pred16x16_dc_%1, 2,7
+%macro PRED16x16_DC 0
+cglobal pred16x16_dc, 2,7
mov r4, r0
sub r0, r1
pxor mm0, mm0
@@ -158,20 +153,10 @@ cglobal pred16x16_dc_%1, 2,7
add r5d, r6d
lea r2d, [r2+r5+16]
shr r2d, 5
-%ifidn %1, mmxext
- movd m0, r2d
- punpcklbw m0, m0
- pshufw m0, m0, 0
-%elifidn %1, sse2
- movd m0, r2d
- punpcklbw m0, m0
- pshuflw m0, m0, 0
- punpcklqdq m0, m0
-%elifidn %1, ssse3
+%if cpuflag(ssse3)
pxor m1, m1
- movd m0, r2d
- pshufb m0, m1
%endif
+ SPLATB_REG m0, r2, m1
%if mmsize==8
mov r3d, 8
@@ -195,18 +180,20 @@ cglobal pred16x16_dc_%1, 2,7
REP_RET
%endmacro
-INIT_MMX
-PRED16x16_DC mmxext
+INIT_MMX mmx2
+PRED16x16_DC
+INIT_XMM sse2
+PRED16x16_DC
+INIT_XMM ssse3
+PRED16x16_DC
INIT_XMM
-PRED16x16_DC sse2
-PRED16x16_DC ssse3
;-----------------------------------------------------------------------------
; void pred16x16_tm_vp8(uint8_t *src, int stride)
;-----------------------------------------------------------------------------
-%macro PRED16x16_TM_MMX 1
-cglobal pred16x16_tm_vp8_%1, 2,5
+%macro PRED16x16_TM_MMX 0
+cglobal pred16x16_tm_vp8, 2,5
sub r0, r1
pxor mm7, mm7
movq mm0, [r0+0]
@@ -223,12 +210,7 @@ cglobal pred16x16_tm_vp8_%1, 2,5
movzx r2d, byte [r0+r1-1]
sub r2d, r3d
movd mm4, r2d
-%ifidn %1, mmx
- punpcklwd mm4, mm4
- punpckldq mm4, mm4
-%else
- pshufw mm4, mm4, 0
-%endif
+ SPLATW mm4, mm4, 0
movq mm5, mm4
movq mm6, mm4
movq mm7, mm4
@@ -246,8 +228,11 @@ cglobal pred16x16_tm_vp8_%1, 2,5
REP_RET
%endmacro
-PRED16x16_TM_MMX mmx
-PRED16x16_TM_MMX mmxext
+INIT_MMX mmx
+PRED16x16_TM_MMX
+INIT_MMX mmx2
+PRED16x16_TM_MMX
+INIT_MMX
cglobal pred16x16_tm_vp8_sse2, 2,6,6
sub r0, r1
@@ -288,8 +273,8 @@ cglobal pred16x16_tm_vp8_sse2, 2,6,6
; void pred16x16_plane(uint8_t *src, int stride)
;-----------------------------------------------------------------------------
-%macro H264_PRED16x16_PLANE 3
-cglobal pred16x16_plane_%3_%1, 2, 9, %2
+%macro H264_PRED16x16_PLANE 1
+cglobal pred16x16_plane_%1, 2,9,7
mov r2, r1 ; +stride
neg r1 ; -stride
@@ -310,7 +295,10 @@ cglobal pred16x16_plane_%3_%1, 2, 9, %2
paddw m0, m2
paddw m1, m3
%else ; mmsize == 16
-%ifidn %1, sse2
+%if cpuflag(ssse3)
+ movhps m0, [r0+r1 +8]
+ pmaddubsw m0, [plane_shuf] ; H coefficients
+%else ; sse2
pxor m2, m2
movh m1, [r0+r1 +8]
punpcklbw m0, m2
@@ -318,29 +306,22 @@ cglobal pred16x16_plane_%3_%1, 2, 9, %2
pmullw m0, [pw_m8tom1]
pmullw m1, [pw_1to8]
paddw m0, m1
-%else ; ssse3
- movhps m0, [r0+r1 +8]
- pmaddubsw m0, [plane_shuf] ; H coefficients
%endif
movhlps m1, m0
%endif
paddw m0, m1
-%ifidn %1, mmx
+%if cpuflag(mmx2)
+ PSHUFLW m1, m0, 0xE
+%elif cpuflag(mmx)
mova m1, m0
psrlq m1, 32
-%elifidn %1, mmx2
- pshufw m1, m0, 0xE
-%else ; mmsize == 16
- pshuflw m1, m0, 0xE
%endif
paddw m0, m1
-%ifidn %1, mmx
+%if cpuflag(mmx2)
+ PSHUFLW m1, m0, 0x1
+%elif cpuflag(mmx)
mova m1, m0
psrlq m1, 16
-%elifidn %1, mmx2
- pshufw m1, m0, 0x1
-%else
- pshuflw m1, m0, 0x1
%endif
paddw m0, m1 ; sum of H coefficients
@@ -424,13 +405,13 @@ cglobal pred16x16_plane_%3_%1, 2, 9, %2
mov r0, r0m
%endif
-%ifidn %3, h264
+%ifidn %1, h264
lea r5, [r5*5+32]
sar r5, 6
-%elifidn %3, rv40
+%elifidn %1, rv40
lea r5, [r5*5]
sar r5, 6
-%elifidn %3, svq3
+%elifidn %1, svq3
test r5, r5
lea r6, [r5+3]
cmovs r5, r6
@@ -449,8 +430,8 @@ cglobal pred16x16_plane_%3_%1, 2, 9, %2
movd r1d, m0
movsx r1d, r1w
-%ifnidn %3, svq3
-%ifidn %3, h264
+%ifnidn %1, svq3
+%ifidn %1, h264
lea r1d, [r1d*5+32]
%else ; rv40
lea r1d, [r1d*5]
@@ -476,26 +457,10 @@ cglobal pred16x16_plane_%3_%1, 2, 9, %2
movd m1, r5d
movd m3, r3d
-%ifidn %1, mmx
- punpcklwd m0, m0
- punpcklwd m1, m1
- punpcklwd m3, m3
- punpckldq m0, m0
- punpckldq m1, m1
- punpckldq m3, m3
-%elifidn %1, mmx2
- pshufw m0, m0, 0x0
- pshufw m1, m1, 0x0
- pshufw m3, m3, 0x0
-%else
- pshuflw m0, m0, 0x0
- pshuflw m1, m1, 0x0
- pshuflw m3, m3, 0x0
- punpcklqdq m0, m0 ; splat H (words)
- punpcklqdq m1, m1 ; splat V (words)
- punpcklqdq m3, m3 ; splat a (words)
-%endif
-%ifidn %3, svq3
+ SPLATW m0, m0, 0 ; H
+ SPLATW m1, m1, 0 ; V
+ SPLATW m3, m3, 0 ; a
+%ifidn %1, svq3
SWAP 0, 1
%endif
mova m2, m0
@@ -568,27 +533,30 @@ cglobal pred16x16_plane_%3_%1, 2, 9, %2
REP_RET
%endmacro
-INIT_MMX
-H264_PRED16x16_PLANE mmx, 0, h264
-H264_PRED16x16_PLANE mmx, 0, rv40
-H264_PRED16x16_PLANE mmx, 0, svq3
-H264_PRED16x16_PLANE mmx2, 0, h264
-H264_PRED16x16_PLANE mmx2, 0, rv40
-H264_PRED16x16_PLANE mmx2, 0, svq3
+INIT_MMX mmx
+H264_PRED16x16_PLANE h264
+H264_PRED16x16_PLANE rv40
+H264_PRED16x16_PLANE svq3
+INIT_MMX mmx2
+H264_PRED16x16_PLANE h264
+H264_PRED16x16_PLANE rv40
+H264_PRED16x16_PLANE svq3
+INIT_XMM sse2
+H264_PRED16x16_PLANE h264
+H264_PRED16x16_PLANE rv40
+H264_PRED16x16_PLANE svq3
+INIT_XMM ssse3
+H264_PRED16x16_PLANE h264
+H264_PRED16x16_PLANE rv40
+H264_PRED16x16_PLANE svq3
INIT_XMM
-H264_PRED16x16_PLANE sse2, 8, h264
-H264_PRED16x16_PLANE sse2, 8, rv40
-H264_PRED16x16_PLANE sse2, 8, svq3
-H264_PRED16x16_PLANE ssse3, 8, h264
-H264_PRED16x16_PLANE ssse3, 8, rv40
-H264_PRED16x16_PLANE ssse3, 8, svq3
;-----------------------------------------------------------------------------
; void pred8x8_plane(uint8_t *src, int stride)
;-----------------------------------------------------------------------------
-%macro H264_PRED8x8_PLANE 2
-cglobal pred8x8_plane_%1, 2, 9, %2
+%macro H264_PRED8x8_PLANE 0
+cglobal pred8x8_plane, 2,9,7
mov r2, r1 ; +stride
neg r1 ; -stride
@@ -601,39 +569,35 @@ cglobal pred8x8_plane_%1, 2, 9, %2
pmullw m0, [pw_m4to4]
pmullw m1, [pw_m4to4+8]
%else ; mmsize == 16
-%ifidn %1, sse2
+%if cpuflag(ssse3)
+ movhps m0, [r0+r1 +4] ; this reads 4 bytes more than necessary
+ pmaddubsw m0, [plane8_shuf] ; H coefficients
+%else ; sse2
pxor m2, m2
movd m1, [r0+r1 +4]
punpckldq m0, m1
punpcklbw m0, m2
pmullw m0, [pw_m4to4]
-%else ; ssse3
- movhps m0, [r0+r1 +4] ; this reads 4 bytes more than necessary
- pmaddubsw m0, [plane8_shuf] ; H coefficients
%endif
movhlps m1, m0
%endif
paddw m0, m1
-%ifnidn %1, ssse3
-%ifidn %1, mmx
+%if notcpuflag(ssse3)
+%if cpuflag(mmx2)
+ PSHUFLW m1, m0, 0xE
+%elif cpuflag(mmx)
mova m1, m0
psrlq m1, 32
-%elifidn %1, mmx2
- pshufw m1, m0, 0xE
-%else ; mmsize == 16
- pshuflw m1, m0, 0xE
%endif
paddw m0, m1
%endif ; !ssse3
-%ifidn %1, mmx
+%if cpuflag(mmx2)
+ PSHUFLW m1, m0, 0x1
+%elif cpuflag(mmx)
mova m1, m0
psrlq m1, 16
-%elifidn %1, mmx2
- pshufw m1, m0, 0x1
-%else
- pshuflw m1, m0, 0x1
%endif
paddw m0, m1 ; sum of H coefficients
@@ -701,25 +665,9 @@ cglobal pred8x8_plane_%1, 2, 9, %2
movd m1, r5d
movd m3, r3d
-%ifidn %1, mmx
- punpcklwd m0, m0
- punpcklwd m1, m1
- punpcklwd m3, m3
- punpckldq m0, m0
- punpckldq m1, m1
- punpckldq m3, m3
-%elifidn %1, mmx2
- pshufw m0, m0, 0x0
- pshufw m1, m1, 0x0
- pshufw m3, m3, 0x0
-%else
- pshuflw m0, m0, 0x0
- pshuflw m1, m1, 0x0
- pshuflw m3, m3, 0x0
- punpcklqdq m0, m0 ; splat H (words)
- punpcklqdq m1, m1 ; splat V (words)
- punpcklqdq m3, m3 ; splat a (words)
-%endif
+ SPLATW m0, m0, 0 ; H
+ SPLATW m1, m1, 0 ; V
+ SPLATW m3, m3, 0 ; a
%if mmsize == 8
mova m2, m0
%endif
@@ -768,12 +716,15 @@ ALIGN 16
REP_RET
%endmacro
-INIT_MMX
-H264_PRED8x8_PLANE mmx, 0
-H264_PRED8x8_PLANE mmx2, 0
+INIT_MMX mmx
+H264_PRED8x8_PLANE
+INIT_MMX mmx2
+H264_PRED8x8_PLANE
+INIT_XMM sse2
+H264_PRED8x8_PLANE
+INIT_XMM ssse3
+H264_PRED8x8_PLANE
INIT_XMM
-H264_PRED8x8_PLANE sse2, 8
-H264_PRED8x8_PLANE ssse3, 8
;-----------------------------------------------------------------------------
; void pred8x8_vertical(uint8_t *src, int stride)
@@ -795,31 +746,15 @@ cglobal pred8x8_vertical_mmx, 2,2
; void pred8x8_horizontal(uint8_t *src, int stride)
;-----------------------------------------------------------------------------
-%macro PRED8x8_H 1
-cglobal pred8x8_horizontal_%1, 2,3
+%macro PRED8x8_H 0
+cglobal pred8x8_horizontal, 2,3
mov r2, 4
-%ifidn %1, ssse3
+%if cpuflag(ssse3)
mova m2, [pb_3]
%endif
.loop:
- movd m0, [r0+r1*0-4]
- movd m1, [r0+r1*1-4]
-%ifidn %1, ssse3
- pshufb m0, m2
- pshufb m1, m2
-%else
- punpcklbw m0, m0
- punpcklbw m1, m1
-%ifidn %1, mmxext
- pshufw m0, m0, 0xff
- pshufw m1, m1, 0xff
-%else
- punpckhwd m0, m0
- punpckhwd m1, m1
- punpckhdq m0, m0
- punpckhdq m1, m1
-%endif
-%endif
+ SPLATB_LOAD m0, r0+r1*0-1, m2
+ SPLATB_LOAD m1, r0+r1*1-1, m2
mova [r0+r1*0], m0
mova [r0+r1*1], m1
lea r0, [r0+r1*2]
@@ -828,10 +763,13 @@ cglobal pred8x8_horizontal_%1, 2,3
REP_RET
%endmacro
+INIT_MMX mmx
+PRED8x8_H
+INIT_MMX mmx2
+PRED8x8_H
+INIT_MMX ssse3
+PRED8x8_H
INIT_MMX
-PRED8x8_H mmx
-PRED8x8_H mmxext
-PRED8x8_H ssse3
;-----------------------------------------------------------------------------
; void pred8x8_top_dc_mmxext(uint8_t *src, int stride)
@@ -967,8 +905,8 @@ cglobal pred8x8_dc_rv40_mmxext, 2,7
; void pred8x8_tm_vp8(uint8_t *src, int stride)
;-----------------------------------------------------------------------------
-%macro PRED8x8_TM_MMX 1
-cglobal pred8x8_tm_vp8_%1, 2,6
+%macro PRED8x8_TM_MMX 0
+cglobal pred8x8_tm_vp8, 2,6
sub r0, r1
pxor mm7, mm7
movq mm0, [r0]
@@ -984,15 +922,8 @@ cglobal pred8x8_tm_vp8_%1, 2,6
sub r3d, r4d
movd mm2, r2d
movd mm4, r3d
-%ifidn %1, mmx
- punpcklwd mm2, mm2
- punpcklwd mm4, mm4
- punpckldq mm2, mm2
- punpckldq mm4, mm4
-%else
- pshufw mm2, mm2, 0
- pshufw mm4, mm4, 0
-%endif
+ SPLATW mm2, mm2, 0
+ SPLATW mm4, mm4, 0
movq mm3, mm2
movq mm5, mm4
paddw mm2, mm0
@@ -1009,8 +940,11 @@ cglobal pred8x8_tm_vp8_%1, 2,6
REP_RET
%endmacro
-PRED8x8_TM_MMX mmx
-PRED8x8_TM_MMX mmxext
+INIT_MMX mmx
+PRED8x8_TM_MMX
+INIT_MMX mmx2
+PRED8x8_TM_MMX
+INIT_MMX
cglobal pred8x8_tm_vp8_sse2, 2,6,4
sub r0, r1
@@ -2510,8 +2444,8 @@ cglobal pred4x4_dc_mmxext, 3,5
; void pred4x4_tm_vp8_mmxext(uint8_t *src, const uint8_t *topright, int stride)
;-----------------------------------------------------------------------------
-%macro PRED4x4_TM_MMX 1
-cglobal pred4x4_tm_vp8_%1, 3,6
+%macro PRED4x4_TM_MMX 0
+cglobal pred4x4_tm_vp8, 3,6
sub r0, r2
pxor mm7, mm7
movd mm0, [r0]
@@ -2525,14 +2459,14 @@ cglobal pred4x4_tm_vp8_%1, 3,6
sub r3d, r4d
movd mm2, r1d
movd mm4, r3d
-%ifidn %1, mmx
+%if cpuflag(mmx2)
+ pshufw mm2, mm2, 0
+ pshufw mm4, mm4, 0
+%else
punpcklwd mm2, mm2
punpcklwd mm4, mm4
punpckldq mm2, mm2
punpckldq mm4, mm4
-%else
- pshufw mm2, mm2, 0
- pshufw mm4, mm4, 0
%endif
paddw mm2, mm0
paddw mm4, mm0
@@ -2546,8 +2480,11 @@ cglobal pred4x4_tm_vp8_%1, 3,6
REP_RET
%endmacro
-PRED4x4_TM_MMX mmx
-PRED4x4_TM_MMX mmxext
+INIT_MMX mmx
+PRED4x4_TM_MMX
+INIT_MMX mmx2
+PRED4x4_TM_MMX
+INIT_MMX
cglobal pred4x4_tm_vp8_ssse3, 3,3
sub r0, r2
diff --git a/libavcodec/x86/h264_intrapred_init.c b/libavcodec/x86/h264_intrapred_init.c
index 41e611e..c6d4c70 100644
--- a/libavcodec/x86/h264_intrapred_init.c
+++ b/libavcodec/x86/h264_intrapred_init.c
@@ -96,9 +96,9 @@ PRED16x16(horizontal, 10, sse2)
void ff_pred16x16_vertical_mmx (uint8_t *src, int stride);
void ff_pred16x16_vertical_sse (uint8_t *src, int stride);
void ff_pred16x16_horizontal_mmx (uint8_t *src, int stride);
-void ff_pred16x16_horizontal_mmxext(uint8_t *src, int stride);
+void ff_pred16x16_horizontal_mmx2 (uint8_t *src, int stride);
void ff_pred16x16_horizontal_ssse3 (uint8_t *src, int stride);
-void ff_pred16x16_dc_mmxext (uint8_t *src, int stride);
+void ff_pred16x16_dc_mmx2 (uint8_t *src, int stride);
void ff_pred16x16_dc_sse2 (uint8_t *src, int stride);
void ff_pred16x16_dc_ssse3 (uint8_t *src, int stride);
void ff_pred16x16_plane_h264_mmx (uint8_t *src, int stride);
@@ -114,21 +114,21 @@ void ff_pred16x16_plane_svq3_mmx2 (uint8_t *src, int stride);
void ff_pred16x16_plane_svq3_sse2 (uint8_t *src, int stride);
void ff_pred16x16_plane_svq3_ssse3 (uint8_t *src, int stride);
void ff_pred16x16_tm_vp8_mmx (uint8_t *src, int stride);
-void ff_pred16x16_tm_vp8_mmxext (uint8_t *src, int stride);
+void ff_pred16x16_tm_vp8_mmx2 (uint8_t *src, int stride);
void ff_pred16x16_tm_vp8_sse2 (uint8_t *src, int stride);
void ff_pred8x8_top_dc_mmxext (uint8_t *src, int stride);
void ff_pred8x8_dc_rv40_mmxext (uint8_t *src, int stride);
void ff_pred8x8_dc_mmxext (uint8_t *src, int stride);
void ff_pred8x8_vertical_mmx (uint8_t *src, int stride);
void ff_pred8x8_horizontal_mmx (uint8_t *src, int stride);
-void ff_pred8x8_horizontal_mmxext (uint8_t *src, int stride);
+void ff_pred8x8_horizontal_mmx2 (uint8_t *src, int stride);
void ff_pred8x8_horizontal_ssse3 (uint8_t *src, int stride);
void ff_pred8x8_plane_mmx (uint8_t *src, int stride);
void ff_pred8x8_plane_mmx2 (uint8_t *src, int stride);
void ff_pred8x8_plane_sse2 (uint8_t *src, int stride);
void ff_pred8x8_plane_ssse3 (uint8_t *src, int stride);
void ff_pred8x8_tm_vp8_mmx (uint8_t *src, int stride);
-void ff_pred8x8_tm_vp8_mmxext (uint8_t *src, int stride);
+void ff_pred8x8_tm_vp8_mmx2 (uint8_t *src, int stride);
void ff_pred8x8_tm_vp8_sse2 (uint8_t *src, int stride);
void ff_pred8x8_tm_vp8_ssse3 (uint8_t *src, int stride);
void ff_pred8x8l_top_dc_mmxext (uint8_t *src, int has_topleft, int has_topright, int stride);
@@ -163,7 +163,7 @@ void ff_pred4x4_vertical_right_mmxext(uint8_t *src, const uint8_t *topright, int
void ff_pred4x4_horizontal_up_mmxext(uint8_t *src, const uint8_t *topright, int stride);
void ff_pred4x4_horizontal_down_mmxext(uint8_t *src, const uint8_t *topright, int stride);
void ff_pred4x4_tm_vp8_mmx (uint8_t *src, const uint8_t *topright, int stride);
-void ff_pred4x4_tm_vp8_mmxext (uint8_t *src, const uint8_t *topright, int stride);
+void ff_pred4x4_tm_vp8_mmx2 (uint8_t *src, const uint8_t *topright, int stride);
void ff_pred4x4_tm_vp8_ssse3 (uint8_t *src, const uint8_t *topright, int stride);
void ff_pred4x4_vertical_vp8_mmxext(uint8_t *src, const uint8_t *topright, int stride);
@@ -188,7 +188,8 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth
if (chroma_format_idc == 1)
h->pred8x8 [PLANE_PRED8x8] = ff_pred8x8_plane_mmx;
if (codec_id == CODEC_ID_SVQ3) {
- h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_svq3_mmx;
+ if (mm_flags & AV_CPU_FLAG_CMOV)
+ h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_svq3_mmx;
} else if (codec_id == CODEC_ID_RV40) {
h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_rv40_mmx;
} else {
@@ -198,10 +199,10 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth
}
if (mm_flags & AV_CPU_FLAG_MMX2) {
- h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_mmxext;
- h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_mmxext;
+ h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_mmx2;
+ h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_mmx2;
if (chroma_format_idc == 1)
- h->pred8x8[HOR_PRED8x8 ] = ff_pred8x8_horizontal_mmxext;
+ h->pred8x8[HOR_PRED8x8 ] = ff_pred8x8_horizontal_mmx2;
h->pred8x8l [TOP_DC_PRED ] = ff_pred8x8l_top_dc_mmxext;
h->pred8x8l [DC_PRED ] = ff_pred8x8l_dc_mmxext;
h->pred8x8l [HOR_PRED ] = ff_pred8x8l_horizontal_mmxext;
@@ -231,10 +232,10 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth
}
}
if (codec_id == CODEC_ID_VP8) {
- h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_tm_vp8_mmxext;
+ h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_tm_vp8_mmx2;
h->pred8x8 [DC_PRED8x8 ] = ff_pred8x8_dc_rv40_mmxext;
- h->pred8x8 [PLANE_PRED8x8 ] = ff_pred8x8_tm_vp8_mmxext;
- h->pred4x4 [TM_VP8_PRED ] = ff_pred4x4_tm_vp8_mmxext;
+ h->pred8x8 [PLANE_PRED8x8 ] = ff_pred8x8_tm_vp8_mmx2;
+ h->pred4x4 [TM_VP8_PRED ] = ff_pred4x4_tm_vp8_mmx2;
h->pred4x4 [VERT_PRED ] = ff_pred4x4_vertical_vp8_mmxext;
} else {
if (chroma_format_idc == 1)
diff --git a/libavcodec/x86/h264dsp_mmx.c b/libavcodec/x86/h264dsp_mmx.c
index dcd9180..c0a40c4 100644
--- a/libavcodec/x86/h264dsp_mmx.c
+++ b/libavcodec/x86/h264dsp_mmx.c
@@ -361,7 +361,8 @@ void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth, const int chrom
if (chroma_format_idc == 1)
c->h264_idct_add8 = ff_h264_idct_add8_8_mmx;
c->h264_idct_add16intra = ff_h264_idct_add16intra_8_mmx;
- c->h264_luma_dc_dequant_idct= ff_h264_luma_dc_dequant_idct_mmx;
+ if (mm_flags & AV_CPU_FLAG_CMOV)
+ c->h264_luma_dc_dequant_idct = ff_h264_luma_dc_dequant_idct_mmx;
if (mm_flags & AV_CPU_FLAG_MMX2) {
c->h264_idct_dc_add = ff_h264_idct_dc_add_8_mmx2;
diff --git a/libavcodec/x86/lpc_mmx.c b/libavcodec/x86/lpc_mmx.c
index d41c19b..27bebe8 100644
--- a/libavcodec/x86/lpc_mmx.c
+++ b/libavcodec/x86/lpc_mmx.c
@@ -23,6 +23,8 @@
#include "libavutil/cpu.h"
#include "libavcodec/lpc.h"
+#if HAVE_INLINE_ASM
+
static void lpc_apply_welch_window_sse2(const int32_t *data, int len,
double *w_data)
{
@@ -136,12 +138,16 @@ static void lpc_compute_autocorr_sse2(const double *data, int len, int lag,
}
}
+#endif /* HAVE_INLINE_ASM */
+
av_cold void ff_lpc_init_x86(LPCContext *c)
{
int mm_flags = av_get_cpu_flags();
+#if HAVE_INLINE_ASM
if (mm_flags & (AV_CPU_FLAG_SSE2|AV_CPU_FLAG_SSE2SLOW)) {
c->lpc_apply_welch_window = lpc_apply_welch_window_sse2;
c->lpc_compute_autocorr = lpc_compute_autocorr_sse2;
}
+#endif /* HAVE_INLINE_ASM */
}
diff --git a/libavcodec/x86/mathops.h b/libavcodec/x86/mathops.h
index 50b0283..e056eb0 100644
--- a/libavcodec/x86/mathops.h
+++ b/libavcodec/x86/mathops.h
@@ -25,6 +25,8 @@
#include "config.h"
#include "libavutil/common.h"
+#if HAVE_INLINE_ASM
+
#if ARCH_X86_32
#define MULL MULL
@@ -118,4 +120,5 @@ static inline uint32_t NEG_USR32(uint32_t a, int8_t s){
return a;
}
+#endif /* HAVE_INLINE_ASM */
#endif /* AVCODEC_X86_MATHOPS_H */
diff --git a/libavcodec/x86/rv40dsp.asm b/libavcodec/x86/rv40dsp.asm
index 721d3df..ae740c2 100644
--- a/libavcodec/x86/rv40dsp.asm
+++ b/libavcodec/x86/rv40dsp.asm
@@ -1,5 +1,7 @@
;******************************************************************************
;* MMX/SSE2-optimized functions for the RV40 decoder
+;* Copyright (c) 2010 Ronald S. Bultje <rsbultje at gmail.com>
+;* Copyright (c) 2010 Jason Garrett-Glaser <darkshikari at gmail.com>
;* Copyright (C) 2012 Christophe Gisquet <christophe.gisquet at gmail.com>
;*
;* This file is part of Libav.
@@ -25,11 +27,319 @@
SECTION_RODATA
align 16
-shift_round: times 8 dw 1 << (16 - 6)
-cextern pw_16
+pw_1024: times 8 dw 1 << (16 - 6) ; pw_1024
+
+sixtap_filter_hb_m: times 8 db 1, -5
+ times 8 db 52, 20
+ ; multiplied by 2 to have the same shift
+ times 8 db 2, -10
+ times 8 db 40, 40
+ ; back to normal
+ times 8 db 1, -5
+ times 8 db 20, 52
+
+sixtap_filter_v_m: times 8 dw 1
+ times 8 dw -5
+ times 8 dw 52
+ times 8 dw 20
+ ; multiplied by 2 to have the same shift
+ times 8 dw 2
+ times 8 dw -10
+ times 8 dw 40
+ times 8 dw 40
+ ; back to normal
+ times 8 dw 1
+ times 8 dw -5
+ times 8 dw 20
+ times 8 dw 52
+
+%ifdef PIC
+%define sixtap_filter_hw picregq
+%define sixtap_filter_hb picregq
+%define sixtap_filter_v picregq
+%define npicregs 1
+%else
+%define sixtap_filter_hw sixtap_filter_hw_m
+%define sixtap_filter_hb sixtap_filter_hb_m
+%define sixtap_filter_v sixtap_filter_v_m
+%define npicregs 0
+%endif
+
+filter_h6_shuf1: db 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8
+filter_h6_shuf2: db 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10
+filter_h6_shuf3: db 5, 4, 6, 5, 7, 6, 8, 7, 9, 8, 10, 9, 11, 10, 12, 11
+
+cextern pw_32
+cextern pw_16
+cextern pw_512
SECTION .text
+;-----------------------------------------------------------------------------
+; subpel MC functions:
+;
+; void [put|rv40]_rv40_qpel_[h|v]_<opt>(uint8_t *dst, int deststride,
+; uint8_t *src, int srcstride,
+; int len, int m);
+;----------------------------------------------------------------------
+%macro LOAD 2
+%if WIN64
+ movsxd %1q, %1d
+%endif
+%ifdef PIC
+ add %1q, picregq
+%else
+ add %1q, %2
+%endif
+%endmacro
+
+%macro STORE 3
+%ifidn %3, avg
+ movh %2, [dstq]
+%endif
+ packuswb %1, %1
+%ifidn %3, avg
+%if cpuflag(3dnow)
+ pavgusb %1, %2
+%else
+ pavgb %1, %2
+%endif
+%endif
+ movh [dstq], %1
+%endmacro
+
+%macro FILTER_V 1
+cglobal %1_rv40_qpel_v, 6,6+npicregs,12, dst, dststride, src, srcstride, height, my, picreg
+%ifdef PIC
+ lea picregq, [sixtap_filter_v_m]
+%endif
+ pxor m7, m7
+ LOAD my, sixtap_filter_v
+
+ ; read 5 lines
+ sub srcq, srcstrideq
+ sub srcq, srcstrideq
+ movh m0, [srcq]
+ movh m1, [srcq+srcstrideq]
+ movh m2, [srcq+srcstrideq*2]
+ lea srcq, [srcq+srcstrideq*2]
+ add srcq, srcstrideq
+ movh m3, [srcq]
+ movh m4, [srcq+srcstrideq]
+ punpcklbw m0, m7
+ punpcklbw m1, m7
+ punpcklbw m2, m7
+ punpcklbw m3, m7
+ punpcklbw m4, m7
+
+%ifdef m8
+ mova m8, [myq+ 0]
+ mova m9, [myq+16]
+ mova m10, [myq+32]
+ mova m11, [myq+48]
+%define COEFF05 m8
+%define COEFF14 m9
+%define COEFF2 m10
+%define COEFF3 m11
+%else
+%define COEFF05 [myq+ 0]
+%define COEFF14 [myq+16]
+%define COEFF2 [myq+32]
+%define COEFF3 [myq+48]
+%endif
+.nextrow:
+ mova m6, m1
+ movh m5, [srcq+2*srcstrideq] ; read new row
+ paddw m6, m4
+ punpcklbw m5, m7
+ pmullw m6, COEFF14
+ paddw m0, m5
+ pmullw m0, COEFF05
+ paddw m6, m0
+ mova m0, m1
+ paddw m6, [pw_32]
+ mova m1, m2
+ pmullw m2, COEFF2
+ paddw m6, m2
+ mova m2, m3
+ pmullw m3, COEFF3
+ paddw m6, m3
+
+ ; round/clip/store
+ mova m3, m4
+ psraw m6, 6
+ mova m4, m5
+ STORE m6, m5, %1
+
+ ; go to next line
+ add dstq, dststrideq
+ add srcq, srcstrideq
+ dec heightd ; next row
+ jg .nextrow
+ REP_RET
+%endmacro
+
+%macro FILTER_H 1
+cglobal %1_rv40_qpel_h, 6, 6+npicregs, 12, dst, dststride, src, srcstride, height, mx, picreg
+%ifdef PIC
+ lea picregq, [sixtap_filter_v_m]
+%endif
+ pxor m7, m7
+ LOAD mx, sixtap_filter_v
+ mova m6, [pw_32]
+%ifdef m8
+ mova m8, [mxq+ 0]
+ mova m9, [mxq+16]
+ mova m10, [mxq+32]
+ mova m11, [mxq+48]
+%define COEFF05 m8
+%define COEFF14 m9
+%define COEFF2 m10
+%define COEFF3 m11
+%else
+%define COEFF05 [mxq+ 0]
+%define COEFF14 [mxq+16]
+%define COEFF2 [mxq+32]
+%define COEFF3 [mxq+48]
+%endif
+.nextrow:
+ movq m0, [srcq-2]
+ movq m5, [srcq+3]
+ movq m1, [srcq-1]
+ movq m4, [srcq+2]
+ punpcklbw m0, m7
+ punpcklbw m5, m7
+ punpcklbw m1, m7
+ punpcklbw m4, m7
+ movq m2, [srcq-0]
+ movq m3, [srcq+1]
+ paddw m0, m5
+ paddw m1, m4
+ punpcklbw m2, m7
+ punpcklbw m3, m7
+ pmullw m0, COEFF05
+ pmullw m1, COEFF14
+ pmullw m2, COEFF2
+ pmullw m3, COEFF3
+ paddw m0, m6
+ paddw m1, m2
+ paddw m0, m3
+ paddw m0, m1
+ psraw m0, 6
+ STORE m0, m1, %1
+
+ ; go to next line
+ add dstq, dststrideq
+ add srcq, srcstrideq
+ dec heightd ; next row
+ jg .nextrow
+ REP_RET
+%endmacro
+
+%if ARCH_X86_32
+INIT_MMX mmx
+FILTER_V put
+FILTER_H put
+
+INIT_MMX mmx2
+FILTER_V avg
+FILTER_H avg
+
+INIT_MMX 3dnow
+FILTER_V avg
+FILTER_H avg
+%endif
+
+INIT_XMM sse2
+FILTER_H put
+FILTER_H avg
+FILTER_V put
+FILTER_V avg
+
+%macro FILTER_SSSE3 1
+cglobal %1_rv40_qpel_v, 6,6+npicregs,8, dst, dststride, src, srcstride, height, my, picreg
+%ifdef PIC
+ lea picregq, [sixtap_filter_hb_m]
+%endif
+
+ ; read 5 lines
+ sub srcq, srcstrideq
+ LOAD my, sixtap_filter_hb
+ sub srcq, srcstrideq
+ movh m0, [srcq]
+ movh m1, [srcq+srcstrideq]
+ movh m2, [srcq+srcstrideq*2]
+ lea srcq, [srcq+srcstrideq*2]
+ add srcq, srcstrideq
+ mova m5, [myq]
+ movh m3, [srcq]
+ movh m4, [srcq+srcstrideq]
+ lea srcq, [srcq+2*srcstrideq]
+
+.nextrow:
+ mova m6, m2
+ punpcklbw m0, m1
+ punpcklbw m6, m3
+ pmaddubsw m0, m5
+ pmaddubsw m6, [myq+16]
+ movh m7, [srcq] ; read new row
+ paddw m6, m0
+ mova m0, m1
+ mova m1, m2
+ mova m2, m3
+ mova m3, m4
+ mova m4, m7
+ punpcklbw m7, m3
+ pmaddubsw m7, m5
+ paddw m6, m7
+ pmulhrsw m6, [pw_512]
+ STORE m6, m7, %1
+
+ ; go to next line
+ add dstq, dststrideq
+ add srcq, srcstrideq
+ dec heightd ; next row
+ jg .nextrow
+ REP_RET
+
+cglobal %1_rv40_qpel_h, 6,6+npicregs,8, dst, dststride, src, srcstride, height, mx, picreg
+%ifdef PIC
+ lea picregq, [sixtap_filter_hb_m]
+%endif
+ mova m3, [filter_h6_shuf2]
+ mova m4, [filter_h6_shuf3]
+ LOAD mx, sixtap_filter_hb
+ mova m5, [mxq] ; set up 6tap filter in bytes
+ mova m6, [mxq+16]
+ mova m7, [filter_h6_shuf1]
+
+.nextrow:
+ movu m0, [srcq-2]
+ mova m1, m0
+ mova m2, m0
+ pshufb m0, m7
+ pshufb m1, m3
+ pshufb m2, m4
+ pmaddubsw m0, m5
+ pmaddubsw m1, m6
+ pmaddubsw m2, m5
+ paddw m0, m1
+ paddw m0, m2
+ pmulhrsw m0, [pw_512]
+ STORE m0, m1, %1
+
+ ; go to next line
+ add dstq, dststrideq
+ add srcq, srcstrideq
+ dec heightd ; next row
+ jg .nextrow
+ REP_RET
+%endmacro
+
+INIT_XMM ssse3
+FILTER_SSSE3 put
+FILTER_SSSE3 avg
+
; %1=5bits weights?, %2=dst %3=src1 %4=src3 %5=stride if sse2
%macro RV40_WCORE 4-5
movh m4, [%3 + r6 + 0]
@@ -143,7 +453,7 @@ SECTION .text
%macro RV40_WEIGHT 3
cglobal rv40_weight_func_%1_%2, 6, 7, 8
%if cpuflag(ssse3)
- mova m1, [shift_round]
+ mova m1, [pw_1024]
%else
mova m1, [pw_16]
%endif
@@ -177,7 +487,7 @@ cglobal rv40_weight_func_%1_%2, 6, 7, 8
REP_RET
%endmacro
-INIT_MMX mmx
+INIT_MMX mmx2
RV40_WEIGHT rnd, 8, 3
RV40_WEIGHT rnd, 16, 4
RV40_WEIGHT nornd, 8, 3
diff --git a/libavcodec/x86/rv40dsp_init.c b/libavcodec/x86/rv40dsp_init.c
index df468aa..e429cc3 100644
--- a/libavcodec/x86/rv40dsp_init.c
+++ b/libavcodec/x86/rv40dsp_init.c
@@ -22,9 +22,12 @@
/**
* @file
* RV40 decoder motion compensation functions x86-optimised
+ * 2,0 and 0,2 have h264 equivalents.
+ * 3,3 is bugged in the rv40 format and maps to _xy2 version
*/
#include "libavcodec/rv34dsp.h"
+#include "dsputil_mmx.h"
void ff_put_rv40_chroma_mc8_mmx (uint8_t *dst, uint8_t *src,
int stride, int h, int x, int y);
@@ -49,10 +52,136 @@ void ff_rv40_weight_func_nornd_16_##opt(uint8_t *dst, uint8_t *src1, uint8_t *sr
int w1, int w2, ptrdiff_t stride); \
void ff_rv40_weight_func_nornd_8_##opt (uint8_t *dst, uint8_t *src1, uint8_t *src2, \
int w1, int w2, ptrdiff_t stride);
-DECLARE_WEIGHT(mmx)
+DECLARE_WEIGHT(mmx2)
DECLARE_WEIGHT(sse2)
DECLARE_WEIGHT(ssse3)
+/** @{ */
+/**
+ * Define one qpel function.
+ * LOOPSIZE must be already set to the number of pixels processed per
+ * iteration in the inner loop of the called functions.
+ * COFF(x) must be already defined so as to provide the offset into any
+ * array of coeffs used by the called function for the qpel position x.
+ */
+#define QPEL_FUNC_DECL(OP, SIZE, PH, PV, OPT) \
+static void OP ## rv40_qpel ##SIZE ##_mc ##PH ##PV ##OPT(uint8_t *dst, \
+ uint8_t *src, \
+ int stride) \
+{ \
+ int i; \
+ if (PH && PV) { \
+ DECLARE_ALIGNED(16, uint8_t, tmp)[SIZE * (SIZE + 5)]; \
+ uint8_t *tmpptr = tmp + SIZE * 2; \
+ src -= stride * 2; \
+ \
+ for (i = 0; i < SIZE; i += LOOPSIZE) \
+ ff_put_rv40_qpel_h ##OPT(tmp + i, SIZE, src + i, stride, \
+ SIZE + 5, HCOFF(PH)); \
+ for (i = 0; i < SIZE; i += LOOPSIZE) \
+ ff_ ##OP ##rv40_qpel_v ##OPT(dst + i, stride, tmpptr + i, \
+ SIZE, SIZE, VCOFF(PV)); \
+ } else if (PV) { \
+ for (i = 0; i < SIZE; i += LOOPSIZE) \
+ ff_ ##OP ##rv40_qpel_v ## OPT(dst + i, stride, src + i, \
+ stride, SIZE, VCOFF(PV)); \
+ } else { \
+ for (i = 0; i < SIZE; i += LOOPSIZE) \
+ ff_ ##OP ##rv40_qpel_h ## OPT(dst + i, stride, src + i, \
+ stride, SIZE, HCOFF(PH)); \
+ } \
+};
+
+/** Declare functions for sizes 8 and 16 and given operations
+ * and qpel position. */
+#define QPEL_FUNCS_DECL(OP, PH, PV, OPT) \
+ QPEL_FUNC_DECL(OP, 8, PH, PV, OPT) \
+ QPEL_FUNC_DECL(OP, 16, PH, PV, OPT)
+
+/** Declare all functions for all sizes and qpel positions */
+#define QPEL_MC_DECL(OP, OPT) \
+void ff_ ##OP ##rv40_qpel_h ##OPT(uint8_t *dst, ptrdiff_t dstStride, \
+ const uint8_t *src, \
+ ptrdiff_t srcStride, \
+ int len, int m); \
+void ff_ ##OP ##rv40_qpel_v ##OPT(uint8_t *dst, ptrdiff_t dstStride, \
+ const uint8_t *src, \
+ ptrdiff_t srcStride, \
+ int len, int m); \
+QPEL_FUNCS_DECL(OP, 0, 1, OPT) \
+QPEL_FUNCS_DECL(OP, 0, 3, OPT) \
+QPEL_FUNCS_DECL(OP, 1, 0, OPT) \
+QPEL_FUNCS_DECL(OP, 1, 1, OPT) \
+QPEL_FUNCS_DECL(OP, 1, 2, OPT) \
+QPEL_FUNCS_DECL(OP, 1, 3, OPT) \
+QPEL_FUNCS_DECL(OP, 2, 1, OPT) \
+QPEL_FUNCS_DECL(OP, 2, 2, OPT) \
+QPEL_FUNCS_DECL(OP, 2, 3, OPT) \
+QPEL_FUNCS_DECL(OP, 3, 0, OPT) \
+QPEL_FUNCS_DECL(OP, 3, 1, OPT) \
+QPEL_FUNCS_DECL(OP, 3, 2, OPT)
+/** @} */
+
+#define LOOPSIZE 8
+#define HCOFF(x) (32 * (x - 1))
+#define VCOFF(x) (32 * (x - 1))
+QPEL_MC_DECL(put_, _ssse3)
+QPEL_MC_DECL(avg_, _ssse3)
+
+#undef LOOPSIZE
+#undef HCOFF
+#undef VCOFF
+#define LOOPSIZE 8
+#define HCOFF(x) (64 * (x - 1))
+#define VCOFF(x) (64 * (x - 1))
+QPEL_MC_DECL(put_, _sse2)
+QPEL_MC_DECL(avg_, _sse2)
+
+#if ARCH_X86_32
+#undef LOOPSIZE
+#undef HCOFF
+#undef VCOFF
+#define LOOPSIZE 4
+#define HCOFF(x) (64 * (x - 1))
+#define VCOFF(x) (64 * (x - 1))
+
+QPEL_MC_DECL(put_, _mmx)
+
+#define ff_put_rv40_qpel_h_mmx2 ff_put_rv40_qpel_h_mmx
+#define ff_put_rv40_qpel_v_mmx2 ff_put_rv40_qpel_v_mmx
+QPEL_MC_DECL(avg_, _mmx2)
+
+#define ff_put_rv40_qpel_h_3dnow ff_put_rv40_qpel_h_mmx
+#define ff_put_rv40_qpel_v_3dnow ff_put_rv40_qpel_v_mmx
+QPEL_MC_DECL(avg_, _3dnow)
+#endif
+
+/** @{ */
+/** Set one function */
+#define QPEL_FUNC_SET(OP, SIZE, PH, PV, OPT) \
+ c-> OP ## pixels_tab[2 - SIZE / 8][4 * PV + PH] = OP ## rv40_qpel ##SIZE ## _mc ##PH ##PV ##OPT;
+
+/** Set functions put and avg for sizes 8 and 16 and a given qpel position */
+#define QPEL_FUNCS_SET(OP, PH, PV, OPT) \
+ QPEL_FUNC_SET(OP, 8, PH, PV, OPT) \
+ QPEL_FUNC_SET(OP, 16, PH, PV, OPT)
+
+/** Set all functions for all sizes and qpel positions */
+#define QPEL_MC_SET(OP, OPT) \
+QPEL_FUNCS_SET (OP, 0, 1, OPT) \
+QPEL_FUNCS_SET (OP, 0, 3, OPT) \
+QPEL_FUNCS_SET (OP, 1, 0, OPT) \
+QPEL_FUNCS_SET (OP, 1, 1, OPT) \
+QPEL_FUNCS_SET (OP, 1, 2, OPT) \
+QPEL_FUNCS_SET (OP, 1, 3, OPT) \
+QPEL_FUNCS_SET (OP, 2, 1, OPT) \
+QPEL_FUNCS_SET (OP, 2, 2, OPT) \
+QPEL_FUNCS_SET (OP, 2, 3, OPT) \
+QPEL_FUNCS_SET (OP, 3, 0, OPT) \
+QPEL_FUNCS_SET (OP, 3, 1, OPT) \
+QPEL_FUNCS_SET (OP, 3, 2, OPT)
+/** @} */
+
void ff_rv40dsp_init_x86(RV34DSPContext *c, DSPContext *dsp)
{
#if HAVE_YASM
@@ -61,29 +190,46 @@ void ff_rv40dsp_init_x86(RV34DSPContext *c, DSPContext *dsp)
if (mm_flags & AV_CPU_FLAG_MMX) {
c->put_chroma_pixels_tab[0] = ff_put_rv40_chroma_mc8_mmx;
c->put_chroma_pixels_tab[1] = ff_put_rv40_chroma_mc4_mmx;
- c->rv40_weight_pixels_tab[0][0] = ff_rv40_weight_func_rnd_16_mmx;
- c->rv40_weight_pixels_tab[0][1] = ff_rv40_weight_func_rnd_8_mmx;
- c->rv40_weight_pixels_tab[1][0] = ff_rv40_weight_func_nornd_16_mmx;
- c->rv40_weight_pixels_tab[1][1] = ff_rv40_weight_func_nornd_8_mmx;
+ c->put_pixels_tab[0][15] = ff_put_rv40_qpel16_mc33_mmx;
+ c->put_pixels_tab[1][15] = ff_put_rv40_qpel8_mc33_mmx;
+ c->avg_pixels_tab[0][15] = ff_avg_rv40_qpel16_mc33_mmx;
+ c->avg_pixels_tab[1][15] = ff_avg_rv40_qpel8_mc33_mmx;
+#if ARCH_X86_32
+ QPEL_MC_SET(put_, _mmx)
+#endif
}
if (mm_flags & AV_CPU_FLAG_MMX2) {
c->avg_chroma_pixels_tab[0] = ff_avg_rv40_chroma_mc8_mmx2;
c->avg_chroma_pixels_tab[1] = ff_avg_rv40_chroma_mc4_mmx2;
+ c->rv40_weight_pixels_tab[0][0] = ff_rv40_weight_func_rnd_16_mmx2;
+ c->rv40_weight_pixels_tab[0][1] = ff_rv40_weight_func_rnd_8_mmx2;
+ c->rv40_weight_pixels_tab[1][0] = ff_rv40_weight_func_nornd_16_mmx2;
+ c->rv40_weight_pixels_tab[1][1] = ff_rv40_weight_func_nornd_8_mmx2;
+#if ARCH_X86_32
+ QPEL_MC_SET(avg_, _mmx2)
+#endif
} else if (mm_flags & AV_CPU_FLAG_3DNOW) {
c->avg_chroma_pixels_tab[0] = ff_avg_rv40_chroma_mc8_3dnow;
c->avg_chroma_pixels_tab[1] = ff_avg_rv40_chroma_mc4_3dnow;
+#if ARCH_X86_32
+ QPEL_MC_SET(avg_, _3dnow)
+#endif
}
if (mm_flags & AV_CPU_FLAG_SSE2) {
c->rv40_weight_pixels_tab[0][0] = ff_rv40_weight_func_rnd_16_sse2;
c->rv40_weight_pixels_tab[0][1] = ff_rv40_weight_func_rnd_8_sse2;
c->rv40_weight_pixels_tab[1][0] = ff_rv40_weight_func_nornd_16_sse2;
c->rv40_weight_pixels_tab[1][1] = ff_rv40_weight_func_nornd_8_sse2;
+ QPEL_MC_SET(put_, _sse2)
+ QPEL_MC_SET(avg_, _sse2)
}
if (mm_flags & AV_CPU_FLAG_SSSE3) {
c->rv40_weight_pixels_tab[0][0] = ff_rv40_weight_func_rnd_16_ssse3;
c->rv40_weight_pixels_tab[0][1] = ff_rv40_weight_func_rnd_8_ssse3;
c->rv40_weight_pixels_tab[1][0] = ff_rv40_weight_func_nornd_16_ssse3;
c->rv40_weight_pixels_tab[1][1] = ff_rv40_weight_func_nornd_8_ssse3;
+ QPEL_MC_SET(put_, _ssse3)
+ QPEL_MC_SET(avg_, _ssse3)
}
#endif
}
diff --git a/libavcodec/x86/snowdsp_mmx.c b/libavcodec/x86/snowdsp_mmx.c
index 3e6bc99..38f3246 100644
--- a/libavcodec/x86/snowdsp_mmx.c
+++ b/libavcodec/x86/snowdsp_mmx.c
@@ -26,9 +26,10 @@
#include "libavcodec/dwt.h"
#include "dsputil_mmx.h"
-static void ff_snow_horizontal_compose97i_sse2(IDWTELEM *b, int width){
+#if HAVE_INLINE_ASM
+
+static void ff_snow_horizontal_compose97i_sse2(IDWTELEM *b, IDWTELEM *temp, int width){
const int w2= (width+1)>>1;
- DECLARE_ALIGNED(16, IDWTELEM, temp)[width>>1];
const int w_l= (width>>1);
const int w_r= w2 - 1;
int i;
@@ -215,9 +216,8 @@ static void ff_snow_horizontal_compose97i_sse2(IDWTELEM *b, int width){
}
}
-static void ff_snow_horizontal_compose97i_mmx(IDWTELEM *b, int width){
+static void ff_snow_horizontal_compose97i_mmx(IDWTELEM *b, IDWTELEM *temp, int width){
const int w2= (width+1)>>1;
- IDWTELEM temp[width >> 1];
const int w_l= (width>>1);
const int w_r= w2 - 1;
int i;
@@ -675,14 +675,14 @@ static void ff_snow_vertical_compose97i_mmx(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM
#define snow_inner_add_yblock_sse2_end_8\
"sal $1, %%"REG_c" \n\t"\
- "add $"PTR_SIZE"*2, %1 \n\t"\
+ "addl $"PTR_SIZE"*2, %1 \n\t"\
snow_inner_add_yblock_sse2_end_common1\
"sar $1, %%"REG_c" \n\t"\
"sub $2, %2 \n\t"\
snow_inner_add_yblock_sse2_end_common2
#define snow_inner_add_yblock_sse2_end_16\
- "add $"PTR_SIZE"*1, %1 \n\t"\
+ "addl $"PTR_SIZE"*1, %1 \n\t"\
snow_inner_add_yblock_sse2_end_common1\
"dec %2 \n\t"\
snow_inner_add_yblock_sse2_end_common2
@@ -873,8 +873,11 @@ static void ff_snow_inner_add_yblock_mmx(const uint8_t *obmc, const int obmc_str
ff_snow_inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8);
}
+#endif /* HAVE_INLINE_ASM */
+
void ff_dwt_init_x86(DWTContext *c)
{
+#if HAVE_INLINE_ASM
int mm_flags = av_get_cpu_flags();
if (mm_flags & AV_CPU_FLAG_MMX) {
@@ -895,4 +898,5 @@ void ff_dwt_init_x86(DWTContext *c)
c->inner_add_yblock = ff_snow_inner_add_yblock_mmx;
}
}
+#endif /* HAVE_INLINE_ASM */
}
diff --git a/libavcodec/x86/vc1dsp_mmx.c b/libavcodec/x86/vc1dsp_mmx.c
index a525aee..717f74f 100644
--- a/libavcodec/x86/vc1dsp_mmx.c
+++ b/libavcodec/x86/vc1dsp_mmx.c
@@ -30,6 +30,8 @@
#include "dsputil_mmx.h"
#include "libavcodec/vc1dsp.h"
+#if HAVE_INLINE_ASM
+
#define OP_PUT(S,D)
#define OP_AVG(S,D) "pavgb " #S ", " #D " \n\t"
@@ -682,6 +684,8 @@ static void vc1_inv_trans_8x8_dc_mmx2(uint8_t *dest, int linesize, DCTELEM *bloc
);
}
+#endif /* HAVE_INLINE_ASM */
+
#define LOOP_FILTER(EXT) \
void ff_vc1_v_loop_filter4_ ## EXT(uint8_t *src, int stride, int pq); \
void ff_vc1_h_loop_filter4_ ## EXT(uint8_t *src, int stride, int pq); \
@@ -701,7 +705,6 @@ static void vc1_h_loop_filter16_ ## EXT(uint8_t *src, int stride, int pq) \
}
#if HAVE_YASM
-LOOP_FILTER(mmx)
LOOP_FILTER(mmx2)
LOOP_FILTER(sse2)
LOOP_FILTER(ssse3)
@@ -731,6 +734,7 @@ void ff_vc1dsp_init_mmx(VC1DSPContext *dsp)
{
int mm_flags = av_get_cpu_flags();
+#if HAVE_INLINE_ASM
if (mm_flags & AV_CPU_FLAG_MMX) {
dsp->put_vc1_mspel_pixels_tab[ 0] = ff_put_vc1_mspel_mc00_mmx;
dsp->put_vc1_mspel_pixels_tab[ 4] = put_vc1_mspel_mc01_mmx;
@@ -779,6 +783,7 @@ void ff_vc1dsp_init_mmx(VC1DSPContext *dsp)
dsp->vc1_inv_trans_8x4_dc = vc1_inv_trans_8x4_dc_mmx2;
dsp->vc1_inv_trans_4x4_dc = vc1_inv_trans_4x4_dc_mmx2;
}
+#endif /* HAVE_INLINE_ASM */
#define ASSIGN_LF(EXT) \
dsp->vc1_v_loop_filter4 = ff_vc1_v_loop_filter4_ ## EXT; \
@@ -790,10 +795,9 @@ void ff_vc1dsp_init_mmx(VC1DSPContext *dsp)
#if HAVE_YASM
if (mm_flags & AV_CPU_FLAG_MMX) {
- ASSIGN_LF(mmx);
dsp->put_no_rnd_vc1_chroma_pixels_tab[0]= ff_put_vc1_chroma_mc8_mmx_nornd;
}
- return;
+
if (mm_flags & AV_CPU_FLAG_MMX2) {
ASSIGN_LF(mmx2);
dsp->avg_no_rnd_vc1_chroma_pixels_tab[0]= ff_avg_vc1_chroma_mc8_mmx2_nornd;
diff --git a/libavcodec/x86/vc1dsp_yasm.asm b/libavcodec/x86/vc1dsp_yasm.asm
index 66f61db..ced2b5b 100644
--- a/libavcodec/x86/vc1dsp_yasm.asm
+++ b/libavcodec/x86/vc1dsp_yasm.asm
@@ -119,7 +119,9 @@ section .text
pand m2, m6
pand m3, m2 ; d final
- PSIGNW m3, m7
+ psraw m7, 15
+ pxor m3, m7
+ psubw m3, m7
psubw m0, m3
paddw m1, m3
packuswb m0, m0
@@ -227,13 +229,6 @@ section .text
imul r2, 0x01010101
%endmacro
-; I do not know why the sign extension is needed...
-%macro PSIGNW_SRA_MMX 2
- psraw %2, 15
- PSIGNW_MMX %1, %2
-%endmacro
-
-
%macro VC1_LF_MMX 1
INIT_MMX
cglobal vc1_v_loop_filter_internal_%1
@@ -274,10 +269,6 @@ cglobal vc1_h_loop_filter8_%1, 3,5,0
RET
%endmacro
-%define PABSW PABSW_MMX
-%define PSIGNW PSIGNW_SRA_MMX
-VC1_LF_MMX mmx
-
%define PABSW PABSW_MMX2
VC1_LF_MMX mmx2
@@ -295,7 +286,6 @@ cglobal vc1_h_loop_filter8_sse2, 3,6,8
RET
%define PABSW PABSW_SSSE3
-%define PSIGNW PSIGNW_SSSE3
INIT_MMX
; void ff_vc1_v_loop_filter4_ssse3(uint8_t *src, int stride, int pq)
diff --git a/libavcodec/x86/vp8dsp-init.c b/libavcodec/x86/vp8dsp-init.c
index d3f1456..589804f 100644
--- a/libavcodec/x86/vp8dsp-init.c
+++ b/libavcodec/x86/vp8dsp-init.c
@@ -389,11 +389,13 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c)
c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_sse2;
+#if ARCH_X86_64 || HAVE_ALIGNED_STACK
c->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16y_inner_sse2;
c->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_sse2;
c->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16y_mbedge_sse2;
c->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_mbedge_sse2;
+#endif
}
if (mm_flags & AV_CPU_FLAG_SSE2) {
@@ -401,11 +403,13 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c)
c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_sse2;
+#if ARCH_X86_64 || HAVE_ALIGNED_STACK
c->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16y_inner_sse2;
c->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_sse2;
c->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16y_mbedge_sse2;
c->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mbedge_sse2;
+#endif
}
if (mm_flags & AV_CPU_FLAG_SSSE3) {
@@ -419,6 +423,7 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c)
c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_ssse3;
c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_ssse3;
+#if ARCH_X86_64 || HAVE_ALIGNED_STACK
c->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16y_inner_ssse3;
c->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16y_inner_ssse3;
c->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_ssse3;
@@ -428,14 +433,17 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c)
c->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16y_mbedge_ssse3;
c->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_mbedge_ssse3;
c->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mbedge_ssse3;
+#endif
}
if (mm_flags & AV_CPU_FLAG_SSE4) {
c->vp8_idct_dc_add = ff_vp8_idct_dc_add_sse4;
c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_sse4;
+#if ARCH_X86_64 || HAVE_ALIGNED_STACK
c->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16y_mbedge_sse4;
c->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mbedge_sse4;
+#endif
}
#endif
}
diff --git a/libavcodec/x86/vp8dsp.asm b/libavcodec/x86/vp8dsp.asm
index 82f21fe..531b205 100644
--- a/libavcodec/x86/vp8dsp.asm
+++ b/libavcodec/x86/vp8dsp.asm
@@ -1465,27 +1465,6 @@ VP8_DC_WHT
%endif
%endmacro
-%macro SPLATB_REG 2-3
-%if cpuflag(ssse3)
- movd %1, %2d
- pshufb %1, %3
-%elif cpuflag(sse2)
- movd %1, %2d
- punpcklbw %1, %1
- pshuflw %1, %1, 0x0
- punpcklqdq %1, %1
-%elif cpuflag(mmx2)
- movd %1, %2d
- punpcklbw %1, %1
- pshufw %1, %1, 0x0
-%else
- movd %1, %2d
- punpcklbw %1, %1
- punpcklwd %1, %1
- punpckldq %1, %1
-%endif
-%endmacro
-
%macro SIMPLE_LOOPFILTER 2
cglobal vp8_%1_loop_filter_simple, 3, %2, 8, dst, stride, flim, cntr
%if mmsize == 8 ; mmx/mmxext
diff --git a/libavcodec/xvmc.h b/libavcodec/xvmc.h
index cdec161..1f77e4e 100644
--- a/libavcodec/xvmc.h
+++ b/libavcodec/xvmc.h
@@ -147,7 +147,7 @@ struct xvmc_pix_fmt {
*/
int filled_mv_blocks_num;
- /** Number of the the next free data block; one data block consists of
+ /** Number of the next free data block; one data block consists of
64 short values in the data_blocks array.
All blocks before this one have already been claimed by placing their
position into the corresponding block description structure field,
diff --git a/libavcodec/zerocodec.c b/libavcodec/zerocodec.c
index 6c57e05..487cb32 100644
--- a/libavcodec/zerocodec.c
+++ b/libavcodec/zerocodec.c
@@ -65,6 +65,10 @@ static int zerocodec_decode_frame(AVCodecContext *avctx, void *data,
pic->key_frame = 1;
pic->pict_type = AV_PICTURE_TYPE_I;
} else {
+ if (!prev) {
+ av_log(avctx, AV_LOG_ERROR, "Missing reference frame!\n");
+ return AVERROR_INVALIDDATA;
+ }
pic->key_frame = 0;
pic->pict_type = AV_PICTURE_TYPE_P;
}
diff --git a/libavdevice/Makefile b/libavdevice/Makefile
index 8226817..7f14217 100644
--- a/libavdevice/Makefile
+++ b/libavdevice/Makefile
@@ -1,9 +1,11 @@
NAME = avdevice
FFLIBS = avformat avcodec avutil
-HEADERS = avdevice.h
+HEADERS = avdevice.h \
+ version.h \
-OBJS = alldevices.o avdevice.o
+OBJS = alldevices.o \
+ avdevice.o \
# input/output devices
OBJS-$(CONFIG_ALSA_INDEV) += alsa-audio-common.o \
diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h
index c010af2..0efe2a7 100644
--- a/libavdevice/avdevice.h
+++ b/libavdevice/avdevice.h
@@ -19,6 +19,8 @@
#ifndef AVDEVICE_AVDEVICE_H
#define AVDEVICE_AVDEVICE_H
+#include "version.h"
+
/**
* @file
* @ingroup lavd
@@ -41,20 +43,6 @@
* @}
*/
-#include "libavutil/avutil.h"
-
-#define LIBAVDEVICE_VERSION_MAJOR 53
-#define LIBAVDEVICE_VERSION_MINOR 2
-#define LIBAVDEVICE_VERSION_MICRO 0
-
-#define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
- LIBAVDEVICE_VERSION_MINOR, \
- LIBAVDEVICE_VERSION_MICRO)
-#define LIBAVDEVICE_VERSION AV_VERSION(LIBAVDEVICE_VERSION_MAJOR, \
- LIBAVDEVICE_VERSION_MINOR, \
- LIBAVDEVICE_VERSION_MICRO)
-#define LIBAVDEVICE_BUILD LIBAVDEVICE_VERSION_INT
-
/**
* Return the LIBAVDEVICE_VERSION_INT constant.
*/
diff --git a/libavdevice/dv1394.c b/libavdevice/dv1394.c
index f48d2b1..2bb65b6 100644
--- a/libavdevice/dv1394.c
+++ b/libavdevice/dv1394.c
@@ -26,8 +26,6 @@
#include <poll.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
-#include <sys/time.h>
-#include <time.h>
#include "libavutil/log.h"
#include "libavutil/opt.h"
diff --git a/libavdevice/dv1394.h b/libavdevice/dv1394.h
index 5ccc68a..fc4df24 100644
--- a/libavdevice/dv1394.h
+++ b/libavdevice/dv1394.h
@@ -175,7 +175,8 @@
if(status.dropped_frames > 0) {
reset_dv1394();
} else {
- for(int i = 0; i < status.n_clear_frames; i++) {
+ int i;
+ for (i = 0; i < status.n_clear_frames; i++) {
copy_DV_frame();
}
}
diff --git a/libavdevice/fbdev.c b/libavdevice/fbdev.c
index f79893a..d789d41 100644
--- a/libavdevice/fbdev.c
+++ b/libavdevice/fbdev.c
@@ -32,7 +32,6 @@
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
-#include <sys/time.h>
#include <sys/mman.h>
#include <time.h>
#include <linux/fb.h>
diff --git a/libavdevice/jack_audio.c b/libavdevice/jack_audio.c
index 9f1bb23..85f9f09 100644
--- a/libavdevice/jack_audio.c
+++ b/libavdevice/jack_audio.c
@@ -91,7 +91,13 @@ static int process_callback(jack_nframes_t nframes, void *arg)
/* Copy and interleave audio data from the JACK buffer into the packet */
for (i = 0; i < self->nports; i++) {
+ #if HAVE_JACK_PORT_GET_LATENCY_RANGE
+ jack_latency_range_t range;
+ jack_port_get_latency_range(self->ports[i], JackCaptureLatency, &range);
+ latency += range.max;
+ #else
latency += jack_port_get_total_latency(self->client, self->ports[i]);
+ #endif
buffer = jack_port_get_buffer(self->ports[i], self->buffer_size);
for (j = 0; j < self->buffer_size; j++)
pkt_data[j * self->nports + i] = buffer[j];
diff --git a/libavdevice/oss_audio.c b/libavdevice/oss_audio.c
index e592c32..60432c5 100644
--- a/libavdevice/oss_audio.c
+++ b/libavdevice/oss_audio.c
@@ -33,8 +33,6 @@
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
-#include <sys/time.h>
-#include <sys/select.h>
#include "libavutil/log.h"
#include "libavutil/opt.h"
diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
index b9941d2..2154b63 100644
--- a/libavdevice/v4l2.c
+++ b/libavdevice/v4l2.c
@@ -42,7 +42,6 @@
#else
#include <linux/videodev2.h>
#endif
-#include <time.h>
#include "libavutil/imgutils.h"
#include "libavutil/log.h"
#include "libavutil/opt.h"
diff --git a/libavdevice/version.h b/libavdevice/version.h
new file mode 100644
index 0000000..52b47db
--- /dev/null
+++ b/libavdevice/version.h
@@ -0,0 +1,48 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVDEVICE_VERSION_H
+#define AVDEVICE_VERSION_H
+
+/**
+ * @file
+ * @ingroup lavd
+ * Libavdevice version macros
+ */
+
+#include "libavutil/avutil.h"
+
+#define LIBAVDEVICE_VERSION_MAJOR 53
+#define LIBAVDEVICE_VERSION_MINOR 2
+#define LIBAVDEVICE_VERSION_MICRO 0
+
+#define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
+ LIBAVDEVICE_VERSION_MINOR, \
+ LIBAVDEVICE_VERSION_MICRO)
+#define LIBAVDEVICE_VERSION AV_VERSION(LIBAVDEVICE_VERSION_MAJOR, \
+ LIBAVDEVICE_VERSION_MINOR, \
+ LIBAVDEVICE_VERSION_MICRO)
+#define LIBAVDEVICE_BUILD LIBAVDEVICE_VERSION_INT
+
+/**
+ * FF_API_* defines may be placed below to indicate public API that will be
+ * dropped at a future version bump. The defines themselves are not part of
+ * the public API and may change, break or disappear at any time.
+ */
+
+#endif /* AVDEVICE_VERSION_H */
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 6ee94e9..530aa57 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -1,20 +1,39 @@
NAME = avfilter
FFLIBS = avutil
+FFLIBS-$(CONFIG_ASYNCTS_FILTER) += avresample
FFLIBS-$(CONFIG_MOVIE_FILTER) += avformat avcodec
-FFLIBS-$(CONFIG_SCALE_FILTER) += swscale
+FFLIBS-$(CONFIG_RESAMPLE_FILTER) += avresample
+FFLIBS-$(CONFIG_SCALE_FILTER) += swscale
-HEADERS = avfilter.h avfiltergraph.h buffersrc.h version.h vsrc_buffer.h
+HEADERS = avfilter.h \
+ avfiltergraph.h \
+ buffersink.h \
+ buffersrc.h \
+ version.h \
OBJS = allfilters.o \
+ audio.o \
avfilter.o \
avfiltergraph.o \
- defaults.o \
+ buffer.o \
+ buffersink.o \
+ buffersrc.o \
drawutils.o \
formats.o \
graphparser.o \
- vsrc_buffer.o
+ vf_scale.o \
+ video.o \
+OBJS-$(CONFIG_AFIFO_FILTER) += fifo.o
+OBJS-$(CONFIG_AFORMAT_FILTER) += af_aformat.o
+OBJS-$(CONFIG_AMIX_FILTER) += af_amix.o
OBJS-$(CONFIG_ANULL_FILTER) += af_anull.o
+OBJS-$(CONFIG_ASPLIT_FILTER) += split.o
+OBJS-$(CONFIG_ASYNCTS_FILTER) += af_asyncts.o
+OBJS-$(CONFIG_CHANNELMAP_FILTER) += af_channelmap.o
+OBJS-$(CONFIG_CHANNELSPLIT_FILTER) += af_channelsplit.o
+OBJS-$(CONFIG_JOIN_FILTER) += af_join.o
+OBJS-$(CONFIG_RESAMPLE_FILTER) += af_resample.o
OBJS-$(CONFIG_ANULLSRC_FILTER) += asrc_anullsrc.o
@@ -30,8 +49,9 @@ OBJS-$(CONFIG_DRAWBOX_FILTER) += vf_drawbox.o
OBJS-$(CONFIG_DRAWTEXT_FILTER) += vf_drawtext.o
OBJS-$(CONFIG_FADE_FILTER) += vf_fade.o
OBJS-$(CONFIG_FIELDORDER_FILTER) += vf_fieldorder.o
-OBJS-$(CONFIG_FIFO_FILTER) += vf_fifo.o
+OBJS-$(CONFIG_FIFO_FILTER) += fifo.o
OBJS-$(CONFIG_FORMAT_FILTER) += vf_format.o
+OBJS-$(CONFIG_FPS_FILTER) += vf_fps.o
OBJS-$(CONFIG_FREI0R_FILTER) += vf_frei0r.o
OBJS-$(CONFIG_GRADFUN_FILTER) += vf_gradfun.o
OBJS-$(CONFIG_HFLIP_FILTER) += vf_hflip.o
@@ -54,7 +74,7 @@ OBJS-$(CONFIG_SETSAR_FILTER) += vf_aspect.o
OBJS-$(CONFIG_SETTB_FILTER) += vf_settb.o
OBJS-$(CONFIG_SHOWINFO_FILTER) += vf_showinfo.o
OBJS-$(CONFIG_SLICIFY_FILTER) += vf_slicify.o
-OBJS-$(CONFIG_SPLIT_FILTER) += vf_split.o
+OBJS-$(CONFIG_SPLIT_FILTER) += split.o
OBJS-$(CONFIG_TRANSPOSE_FILTER) += vf_transpose.o
OBJS-$(CONFIG_UNSHARP_FILTER) += vf_unsharp.o
OBJS-$(CONFIG_VFLIP_FILTER) += vf_vflip.o
@@ -69,4 +89,5 @@ OBJS-$(CONFIG_TESTSRC_FILTER) += vsrc_testsrc.o
OBJS-$(CONFIG_NULLSINK_FILTER) += vsink_nullsink.o
-TOOLS = graph2dot lavfi-showfiltfmts
+TOOLS = graph2dot
+TESTPROGS = filtfmts
diff --git a/libavfilter/af_aformat.c b/libavfilter/af_aformat.c
new file mode 100644
index 0000000..b355801
--- /dev/null
+++ b/libavfilter/af_aformat.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2011 Mina Nagy Zaki
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * format audio filter
+ */
+
+#include "libavutil/audioconvert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/opt.h"
+
+#include "audio.h"
+#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+
+typedef struct AFormatContext {
+ const AVClass *class;
+
+ AVFilterFormats *formats;
+ AVFilterFormats *sample_rates;
+ AVFilterChannelLayouts *channel_layouts;
+
+ char *formats_str;
+ char *sample_rates_str;
+ char *channel_layouts_str;
+} AFormatContext;
+
+#define OFFSET(x) offsetof(AFormatContext, x)
+#define A AV_OPT_FLAG_AUDIO_PARAM
+static const AVOption options[] = {
+ { "sample_fmts", "A comma-separated list of sample formats.", OFFSET(formats_str), AV_OPT_TYPE_STRING, .flags = A },
+ { "sample_rates", "A comma-separated list of sample rates.", OFFSET(sample_rates_str), AV_OPT_TYPE_STRING, .flags = A },
+ { "channel_layouts", "A comma-separated list of channel layouts.", OFFSET(channel_layouts_str), AV_OPT_TYPE_STRING, .flags = A },
+ { NULL },
+};
+
+static const AVClass aformat_class = {
+ .class_name = "aformat filter",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+#define PARSE_FORMATS(str, type, list, add_to_list, get_fmt, none, desc) \
+do { \
+ char *next, *cur = str; \
+ while (cur) { \
+ type fmt; \
+ next = strchr(cur, ','); \
+ if (next) \
+ *next++ = 0; \
+ \
+ if ((fmt = get_fmt(cur)) == none) { \
+ av_log(ctx, AV_LOG_ERROR, "Error parsing " desc ": %s.\n", cur);\
+ ret = AVERROR(EINVAL); \
+ goto fail; \
+ } \
+ add_to_list(&list, fmt); \
+ \
+ cur = next; \
+ } \
+} while (0)
+
+static int get_sample_rate(const char *samplerate)
+{
+ int ret = strtol(samplerate, NULL, 0);
+ return FFMAX(ret, 0);
+}
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+ AFormatContext *s = ctx->priv;
+ int ret;
+
+ if (!args) {
+ av_log(ctx, AV_LOG_ERROR, "No parameters supplied.\n");
+ return AVERROR(EINVAL);
+ }
+
+ s->class = &aformat_class;
+ av_opt_set_defaults(s);
+
+ if ((ret = av_set_options_string(s, args, "=", ":")) < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Error parsing options string '%s'.\n", args);
+ return ret;
+ }
+
+ PARSE_FORMATS(s->formats_str, enum AVSampleFormat, s->formats,
+ ff_add_format, av_get_sample_fmt, AV_SAMPLE_FMT_NONE, "sample format");
+ PARSE_FORMATS(s->sample_rates_str, int, s->sample_rates, ff_add_format,
+ get_sample_rate, 0, "sample rate");
+ PARSE_FORMATS(s->channel_layouts_str, uint64_t, s->channel_layouts,
+ ff_add_channel_layout, av_get_channel_layout, 0,
+ "channel layout");
+
+fail:
+ av_opt_free(s);
+ return ret;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+ AFormatContext *s = ctx->priv;
+
+ ff_set_common_formats(ctx, s->formats ? s->formats :
+ ff_all_formats(AVMEDIA_TYPE_AUDIO));
+ ff_set_common_samplerates(ctx, s->sample_rates ? s->sample_rates :
+ ff_all_samplerates());
+ ff_set_common_channel_layouts(ctx, s->channel_layouts ? s->channel_layouts :
+ ff_all_channel_layouts());
+
+ return 0;
+}
+
+AVFilter avfilter_af_aformat = {
+ .name = "aformat",
+ .description = NULL_IF_CONFIG_SMALL("Convert the input audio to one of the specified formats."),
+ .init = init,
+ .query_formats = query_formats,
+ .priv_size = sizeof(AFormatContext),
+
+ .inputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_AUDIO, },
+ { .name = NULL}},
+ .outputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_AUDIO},
+ { .name = NULL}},
+};
diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c
new file mode 100644
index 0000000..439231f
--- /dev/null
+++ b/libavfilter/af_amix.c
@@ -0,0 +1,560 @@
+/*
+ * Audio Mix Filter
+ * Copyright (c) 2012 Justin Ruggles <justin.ruggles at gmail.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Audio Mix Filter
+ *
+ * Mixes audio from multiple sources into a single output. The channel layout,
+ * sample rate, and sample format will be the same for all inputs and the
+ * output.
+ */
+
+#include "libavutil/audioconvert.h"
+#include "libavutil/audio_fifo.h"
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/float_dsp.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
+#include "libavutil/samplefmt.h"
+
+#include "audio.h"
+#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+
+#define INPUT_OFF 0 /**< input has reached EOF */
+#define INPUT_ON 1 /**< input is active */
+#define INPUT_INACTIVE 2 /**< input is on, but is currently inactive */
+
+#define DURATION_LONGEST 0
+#define DURATION_SHORTEST 1
+#define DURATION_FIRST 2
+
+
+typedef struct FrameInfo {
+ int nb_samples;
+ int64_t pts;
+ struct FrameInfo *next;
+} FrameInfo;
+
+/**
+ * Linked list used to store timestamps and frame sizes of all frames in the
+ * FIFO for the first input.
+ *
+ * This is needed to keep timestamps synchronized for the case where multiple
+ * input frames are pushed to the filter for processing before a frame is
+ * requested by the output link.
+ */
+typedef struct FrameList {
+ int nb_frames;
+ int nb_samples;
+ FrameInfo *list;
+ FrameInfo *end;
+} FrameList;
+
+static void frame_list_clear(FrameList *frame_list)
+{
+ if (frame_list) {
+ while (frame_list->list) {
+ FrameInfo *info = frame_list->list;
+ frame_list->list = info->next;
+ av_free(info);
+ }
+ frame_list->nb_frames = 0;
+ frame_list->nb_samples = 0;
+ frame_list->end = NULL;
+ }
+}
+
+static int frame_list_next_frame_size(FrameList *frame_list)
+{
+ if (!frame_list->list)
+ return 0;
+ return frame_list->list->nb_samples;
+}
+
+static int64_t frame_list_next_pts(FrameList *frame_list)
+{
+ if (!frame_list->list)
+ return AV_NOPTS_VALUE;
+ return frame_list->list->pts;
+}
+
+static void frame_list_remove_samples(FrameList *frame_list, int nb_samples)
+{
+ if (nb_samples >= frame_list->nb_samples) {
+ frame_list_clear(frame_list);
+ } else {
+ int samples = nb_samples;
+ while (samples > 0) {
+ FrameInfo *info = frame_list->list;
+ av_assert0(info != NULL);
+ if (info->nb_samples <= samples) {
+ samples -= info->nb_samples;
+ frame_list->list = info->next;
+ if (!frame_list->list)
+ frame_list->end = NULL;
+ frame_list->nb_frames--;
+ frame_list->nb_samples -= info->nb_samples;
+ av_free(info);
+ } else {
+ info->nb_samples -= samples;
+ info->pts += samples;
+ frame_list->nb_samples -= samples;
+ samples = 0;
+ }
+ }
+ }
+}
+
+static int frame_list_add_frame(FrameList *frame_list, int nb_samples, int64_t pts)
+{
+ FrameInfo *info = av_malloc(sizeof(*info));
+ if (!info)
+ return AVERROR(ENOMEM);
+ info->nb_samples = nb_samples;
+ info->pts = pts;
+ info->next = NULL;
+
+ if (!frame_list->list) {
+ frame_list->list = info;
+ frame_list->end = info;
+ } else {
+ av_assert0(frame_list->end != NULL);
+ frame_list->end->next = info;
+ frame_list->end = info;
+ }
+ frame_list->nb_frames++;
+ frame_list->nb_samples += nb_samples;
+
+ return 0;
+}
+
+
+typedef struct MixContext {
+ const AVClass *class; /**< class for AVOptions */
+ AVFloatDSPContext fdsp;
+
+ int nb_inputs; /**< number of inputs */
+ int active_inputs; /**< number of input currently active */
+ int duration_mode; /**< mode for determining duration */
+ float dropout_transition; /**< transition time when an input drops out */
+
+ int nb_channels; /**< number of channels */
+ int sample_rate; /**< sample rate */
+ int planar;
+ AVAudioFifo **fifos; /**< audio fifo for each input */
+ uint8_t *input_state; /**< current state of each input */
+ float *input_scale; /**< mixing scale factor for each input */
+ float scale_norm; /**< normalization factor for all inputs */
+ int64_t next_pts; /**< calculated pts for next output frame */
+ FrameList *frame_list; /**< list of frame info for the first input */
+} MixContext;
+
+#define OFFSET(x) offsetof(MixContext, x)
+#define A AV_OPT_FLAG_AUDIO_PARAM
+static const AVOption options[] = {
+ { "inputs", "Number of inputs.",
+ OFFSET(nb_inputs), AV_OPT_TYPE_INT, { 2 }, 1, 32, A },
+ { "duration", "How to determine the end-of-stream.",
+ OFFSET(duration_mode), AV_OPT_TYPE_INT, { DURATION_LONGEST }, 0, 2, A, "duration" },
+ { "longest", "Duration of longest input.", 0, AV_OPT_TYPE_CONST, { DURATION_LONGEST }, INT_MIN, INT_MAX, A, "duration" },
+ { "shortest", "Duration of shortest input.", 0, AV_OPT_TYPE_CONST, { DURATION_SHORTEST }, INT_MIN, INT_MAX, A, "duration" },
+ { "first", "Duration of first input.", 0, AV_OPT_TYPE_CONST, { DURATION_FIRST }, INT_MIN, INT_MAX, A, "duration" },
+ { "dropout_transition", "Transition time, in seconds, for volume "
+ "renormalization when an input stream ends.",
+ OFFSET(dropout_transition), AV_OPT_TYPE_FLOAT, { 2.0 }, 0, INT_MAX, A },
+ { NULL },
+};
+
+static const AVClass amix_class = {
+ .class_name = "amix filter",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+
+/**
+ * Update the scaling factors to apply to each input during mixing.
+ *
+ * This balances the full volume range between active inputs and handles
+ * volume transitions when EOF is encountered on an input but mixing continues
+ * with the remaining inputs.
+ */
+static void calculate_scales(MixContext *s, int nb_samples)
+{
+ int i;
+
+ if (s->scale_norm > s->active_inputs) {
+ s->scale_norm -= nb_samples / (s->dropout_transition * s->sample_rate);
+ s->scale_norm = FFMAX(s->scale_norm, s->active_inputs);
+ }
+
+ for (i = 0; i < s->nb_inputs; i++) {
+ if (s->input_state[i] == INPUT_ON)
+ s->input_scale[i] = 1.0f / s->scale_norm;
+ else
+ s->input_scale[i] = 0.0f;
+ }
+}
+
+static int config_output(AVFilterLink *outlink)
+{
+ AVFilterContext *ctx = outlink->src;
+ MixContext *s = ctx->priv;
+ int i;
+ char buf[64];
+
+ s->planar = av_sample_fmt_is_planar(outlink->format);
+ s->sample_rate = outlink->sample_rate;
+ outlink->time_base = (AVRational){ 1, outlink->sample_rate };
+ s->next_pts = AV_NOPTS_VALUE;
+
+ s->frame_list = av_mallocz(sizeof(*s->frame_list));
+ if (!s->frame_list)
+ return AVERROR(ENOMEM);
+
+ s->fifos = av_mallocz(s->nb_inputs * sizeof(*s->fifos));
+ if (!s->fifos)
+ return AVERROR(ENOMEM);
+
+ s->nb_channels = av_get_channel_layout_nb_channels(outlink->channel_layout);
+ for (i = 0; i < s->nb_inputs; i++) {
+ s->fifos[i] = av_audio_fifo_alloc(outlink->format, s->nb_channels, 1024);
+ if (!s->fifos[i])
+ return AVERROR(ENOMEM);
+ }
+
+ s->input_state = av_malloc(s->nb_inputs);
+ if (!s->input_state)
+ return AVERROR(ENOMEM);
+ memset(s->input_state, INPUT_ON, s->nb_inputs);
+ s->active_inputs = s->nb_inputs;
+
+ s->input_scale = av_mallocz(s->nb_inputs * sizeof(*s->input_scale));
+ if (!s->input_scale)
+ return AVERROR(ENOMEM);
+ s->scale_norm = s->active_inputs;
+ calculate_scales(s, 0);
+
+ av_get_channel_layout_string(buf, sizeof(buf), -1, outlink->channel_layout);
+
+ av_log(ctx, AV_LOG_VERBOSE,
+ "inputs:%d fmt:%s srate:%d cl:%s\n", s->nb_inputs,
+ av_get_sample_fmt_name(outlink->format), outlink->sample_rate, buf);
+
+ return 0;
+}
+
+/**
+ * Read samples from the input FIFOs, mix, and write to the output link.
+ */
+static int output_frame(AVFilterLink *outlink, int nb_samples)
+{
+ AVFilterContext *ctx = outlink->src;
+ MixContext *s = ctx->priv;
+ AVFilterBufferRef *out_buf, *in_buf;
+ int i;
+
+ calculate_scales(s, nb_samples);
+
+ out_buf = ff_get_audio_buffer(outlink, AV_PERM_WRITE, nb_samples);
+ if (!out_buf)
+ return AVERROR(ENOMEM);
+
+ in_buf = ff_get_audio_buffer(outlink, AV_PERM_WRITE, nb_samples);
+ if (!in_buf)
+ return AVERROR(ENOMEM);
+
+ for (i = 0; i < s->nb_inputs; i++) {
+ if (s->input_state[i] == INPUT_ON) {
+ int planes, plane_size, p;
+
+ av_audio_fifo_read(s->fifos[i], (void **)in_buf->extended_data,
+ nb_samples);
+
+ planes = s->planar ? s->nb_channels : 1;
+ plane_size = nb_samples * (s->planar ? 1 : s->nb_channels);
+ plane_size = FFALIGN(plane_size, 16);
+
+ for (p = 0; p < planes; p++) {
+ s->fdsp.vector_fmac_scalar((float *)out_buf->extended_data[p],
+ (float *) in_buf->extended_data[p],
+ s->input_scale[i], plane_size);
+ }
+ }
+ }
+ avfilter_unref_buffer(in_buf);
+
+ out_buf->pts = s->next_pts;
+ if (s->next_pts != AV_NOPTS_VALUE)
+ s->next_pts += nb_samples;
+
+ ff_filter_samples(outlink, out_buf);
+
+ return 0;
+}
+
+/**
+ * Returns the smallest number of samples available in the input FIFOs other
+ * than that of the first input.
+ */
+static int get_available_samples(MixContext *s)
+{
+ int i;
+ int available_samples = INT_MAX;
+
+ av_assert0(s->nb_inputs > 1);
+
+ for (i = 1; i < s->nb_inputs; i++) {
+ int nb_samples;
+ if (s->input_state[i] == INPUT_OFF)
+ continue;
+ nb_samples = av_audio_fifo_size(s->fifos[i]);
+ available_samples = FFMIN(available_samples, nb_samples);
+ }
+ if (available_samples == INT_MAX)
+ return 0;
+ return available_samples;
+}
+
+/**
+ * Requests a frame, if needed, from each input link other than the first.
+ */
+static int request_samples(AVFilterContext *ctx, int min_samples)
+{
+ MixContext *s = ctx->priv;
+ int i, ret;
+
+ av_assert0(s->nb_inputs > 1);
+
+ for (i = 1; i < s->nb_inputs; i++) {
+ ret = 0;
+ if (s->input_state[i] == INPUT_OFF)
+ continue;
+ while (!ret && av_audio_fifo_size(s->fifos[i]) < min_samples)
+ ret = ff_request_frame(ctx->inputs[i]);
+ if (ret == AVERROR_EOF) {
+ if (av_audio_fifo_size(s->fifos[i]) == 0) {
+ s->input_state[i] = INPUT_OFF;
+ continue;
+ }
+ } else if (ret < 0)
+ return ret;
+ }
+ return 0;
+}
+
+/**
+ * Calculates the number of active inputs and determines EOF based on the
+ * duration option.
+ *
+ * @return 0 if mixing should continue, or AVERROR_EOF if mixing should stop.
+ */
+static int calc_active_inputs(MixContext *s)
+{
+ int i;
+ int active_inputs = 0;
+ for (i = 0; i < s->nb_inputs; i++)
+ active_inputs += !!(s->input_state[i] != INPUT_OFF);
+ s->active_inputs = active_inputs;
+
+ if (!active_inputs ||
+ (s->duration_mode == DURATION_FIRST && s->input_state[0] == INPUT_OFF) ||
+ (s->duration_mode == DURATION_SHORTEST && active_inputs != s->nb_inputs))
+ return AVERROR_EOF;
+ return 0;
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+ AVFilterContext *ctx = outlink->src;
+ MixContext *s = ctx->priv;
+ int ret;
+ int wanted_samples, available_samples;
+
+ ret = calc_active_inputs(s);
+ if (ret < 0)
+ return ret;
+
+ if (s->input_state[0] == INPUT_OFF) {
+ ret = request_samples(ctx, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = calc_active_inputs(s);
+ if (ret < 0)
+ return ret;
+
+ available_samples = get_available_samples(s);
+ if (!available_samples)
+ return AVERROR(EAGAIN);
+
+ return output_frame(outlink, available_samples);
+ }
+
+ if (s->frame_list->nb_frames == 0) {
+ ret = ff_request_frame(ctx->inputs[0]);
+ if (ret == AVERROR_EOF) {
+ s->input_state[0] = INPUT_OFF;
+ if (s->nb_inputs == 1)
+ return AVERROR_EOF;
+ else
+ return AVERROR(EAGAIN);
+ } else if (ret < 0)
+ return ret;
+ }
+ av_assert0(s->frame_list->nb_frames > 0);
+
+ wanted_samples = frame_list_next_frame_size(s->frame_list);
+
+ if (s->active_inputs > 1) {
+ ret = request_samples(ctx, wanted_samples);
+ if (ret < 0)
+ return ret;
+
+ ret = calc_active_inputs(s);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (s->active_inputs > 1) {
+ available_samples = get_available_samples(s);
+ if (!available_samples)
+ return AVERROR(EAGAIN);
+ available_samples = FFMIN(available_samples, wanted_samples);
+ } else {
+ available_samples = wanted_samples;
+ }
+
+ s->next_pts = frame_list_next_pts(s->frame_list);
+ frame_list_remove_samples(s->frame_list, available_samples);
+
+ return output_frame(outlink, available_samples);
+}
+
+static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
+{
+ AVFilterContext *ctx = inlink->dst;
+ MixContext *s = ctx->priv;
+ AVFilterLink *outlink = ctx->outputs[0];
+ int i;
+
+ for (i = 0; i < ctx->nb_inputs; i++)
+ if (ctx->inputs[i] == inlink)
+ break;
+ if (i >= ctx->nb_inputs) {
+ av_log(ctx, AV_LOG_ERROR, "unknown input link\n");
+ return;
+ }
+
+ if (i == 0) {
+ int64_t pts = av_rescale_q(buf->pts, inlink->time_base,
+ outlink->time_base);
+ frame_list_add_frame(s->frame_list, buf->audio->nb_samples, pts);
+ }
+
+ av_audio_fifo_write(s->fifos[i], (void **)buf->extended_data,
+ buf->audio->nb_samples);
+
+ avfilter_unref_buffer(buf);
+}
+
+static int init(AVFilterContext *ctx, const char *args)
+{
+ MixContext *s = ctx->priv;
+ int i, ret;
+
+ s->class = &amix_class;
+ av_opt_set_defaults(s);
+
+ if ((ret = av_set_options_string(s, args, "=", ":")) < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Error parsing options string '%s'.\n", args);
+ return ret;
+ }
+ av_opt_free(s);
+
+ for (i = 0; i < s->nb_inputs; i++) {
+ char name[32];
+ AVFilterPad pad = { 0 };
+
+ snprintf(name, sizeof(name), "input%d", i);
+ pad.type = AVMEDIA_TYPE_AUDIO;
+ pad.name = av_strdup(name);
+ pad.filter_samples = filter_samples;
+
+ ff_insert_inpad(ctx, i, &pad);
+ }
+
+ avpriv_float_dsp_init(&s->fdsp, 0);
+
+ return 0;
+}
+
+static void uninit(AVFilterContext *ctx)
+{
+ int i;
+ MixContext *s = ctx->priv;
+
+ if (s->fifos) {
+ for (i = 0; i < s->nb_inputs; i++)
+ av_audio_fifo_free(s->fifos[i]);
+ av_freep(&s->fifos);
+ }
+ frame_list_clear(s->frame_list);
+ av_freep(&s->frame_list);
+ av_freep(&s->input_state);
+ av_freep(&s->input_scale);
+
+ for (i = 0; i < ctx->nb_inputs; i++)
+ av_freep(&ctx->input_pads[i].name);
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+ AVFilterFormats *formats = NULL;
+ ff_add_format(&formats, AV_SAMPLE_FMT_FLT);
+ ff_add_format(&formats, AV_SAMPLE_FMT_FLTP);
+ ff_set_common_formats(ctx, formats);
+ ff_set_common_channel_layouts(ctx, ff_all_channel_layouts());
+ ff_set_common_samplerates(ctx, ff_all_samplerates());
+ return 0;
+}
+
+AVFilter avfilter_af_amix = {
+ .name = "amix",
+ .description = NULL_IF_CONFIG_SMALL("Audio mixing."),
+ .priv_size = sizeof(MixContext),
+
+ .init = init,
+ .uninit = uninit,
+ .query_formats = query_formats,
+
+ .inputs = (const AVFilterPad[]) {{ .name = NULL}},
+ .outputs = (const AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .config_props = config_output,
+ .request_frame = request_frame },
+ { .name = NULL}},
+};
diff --git a/libavfilter/af_anull.c b/libavfilter/af_anull.c
index e2bed36..231fc8c 100644
--- a/libavfilter/af_anull.c
+++ b/libavfilter/af_anull.c
@@ -21,7 +21,9 @@
* null audio filter
*/
+#include "audio.h"
#include "avfilter.h"
+#include "internal.h"
AVFilter avfilter_af_anull = {
.name = "anull",
@@ -31,8 +33,7 @@ AVFilter avfilter_af_anull = {
.inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_AUDIO,
- .get_audio_buffer = avfilter_null_get_audio_buffer,
- .filter_samples = avfilter_null_filter_samples },
+ .get_audio_buffer = ff_null_get_audio_buffer, },
{ .name = NULL}},
.outputs = (AVFilterPad[]) {{ .name = "default",
diff --git a/libavfilter/af_asyncts.c b/libavfilter/af_asyncts.c
new file mode 100644
index 0000000..8402b26
--- /dev/null
+++ b/libavfilter/af_asyncts.c
@@ -0,0 +1,241 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavresample/avresample.h"
+#include "libavutil/audio_fifo.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
+#include "libavutil/samplefmt.h"
+
+#include "audio.h"
+#include "avfilter.h"
+#include "internal.h"
+
+typedef struct ASyncContext {
+ const AVClass *class;
+
+ AVAudioResampleContext *avr;
+ int64_t pts; ///< timestamp in samples of the first sample in fifo
+ int min_delta; ///< pad/trim min threshold in samples
+
+ /* options */
+ int resample;
+ float min_delta_sec;
+ int max_comp;
+} ASyncContext;
+
+#define OFFSET(x) offsetof(ASyncContext, x)
+#define A AV_OPT_FLAG_AUDIO_PARAM
+static const AVOption options[] = {
+ { "compensate", "Stretch/squeeze the data to make it match the timestamps", OFFSET(resample), AV_OPT_TYPE_INT, { 0 }, 0, 1, A },
+ { "min_delta", "Minimum difference between timestamps and audio data "
+ "(in seconds) to trigger padding/trimmin the data.", OFFSET(min_delta_sec), AV_OPT_TYPE_FLOAT, { 0.1 }, 0, INT_MAX, A },
+ { "max_comp", "Maximum compensation in samples per second.", OFFSET(max_comp), AV_OPT_TYPE_INT, { 500 }, 0, INT_MAX, A },
+ { NULL },
+};
+
+static const AVClass async_class = {
+ .class_name = "asyncts filter",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+static int init(AVFilterContext *ctx, const char *args)
+{
+ ASyncContext *s = ctx->priv;
+ int ret;
+
+ s->class = &async_class;
+ av_opt_set_defaults(s);
+
+ if ((ret = av_set_options_string(s, args, "=", ":")) < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Error parsing options string '%s'.\n", args);
+ return ret;
+ }
+ av_opt_free(s);
+
+ s->pts = AV_NOPTS_VALUE;
+
+ return 0;
+}
+
+static void uninit(AVFilterContext *ctx)
+{
+ ASyncContext *s = ctx->priv;
+
+ if (s->avr) {
+ avresample_close(s->avr);
+ avresample_free(&s->avr);
+ }
+}
+
+static int config_props(AVFilterLink *link)
+{
+ ASyncContext *s = link->src->priv;
+ int ret;
+
+ s->min_delta = s->min_delta_sec * link->sample_rate;
+ link->time_base = (AVRational){1, link->sample_rate};
+
+ s->avr = avresample_alloc_context();
+ if (!s->avr)
+ return AVERROR(ENOMEM);
+
+ av_opt_set_int(s->avr, "in_channel_layout", link->channel_layout, 0);
+ av_opt_set_int(s->avr, "out_channel_layout", link->channel_layout, 0);
+ av_opt_set_int(s->avr, "in_sample_fmt", link->format, 0);
+ av_opt_set_int(s->avr, "out_sample_fmt", link->format, 0);
+ av_opt_set_int(s->avr, "in_sample_rate", link->sample_rate, 0);
+ av_opt_set_int(s->avr, "out_sample_rate", link->sample_rate, 0);
+
+ if (s->resample)
+ av_opt_set_int(s->avr, "force_resampling", 1, 0);
+
+ if ((ret = avresample_open(s->avr)) < 0)
+ return ret;
+
+ return 0;
+}
+
+static int request_frame(AVFilterLink *link)
+{
+ AVFilterContext *ctx = link->src;
+ ASyncContext *s = ctx->priv;
+ int ret = ff_request_frame(ctx->inputs[0]);
+ int nb_samples;
+
+ /* flush the fifo */
+ if (ret == AVERROR_EOF && (nb_samples = avresample_get_delay(s->avr))) {
+ AVFilterBufferRef *buf = ff_get_audio_buffer(link, AV_PERM_WRITE,
+ nb_samples);
+ if (!buf)
+ return AVERROR(ENOMEM);
+ avresample_convert(s->avr, (void**)buf->extended_data, buf->linesize[0],
+ nb_samples, NULL, 0, 0);
+ buf->pts = s->pts;
+ ff_filter_samples(link, buf);
+ return 0;
+ }
+
+ return ret;
+}
+
+static void write_to_fifo(ASyncContext *s, AVFilterBufferRef *buf)
+{
+ avresample_convert(s->avr, NULL, 0, 0, (void**)buf->extended_data,
+ buf->linesize[0], buf->audio->nb_samples);
+ avfilter_unref_buffer(buf);
+}
+
+/* get amount of data currently buffered, in samples */
+static int64_t get_delay(ASyncContext *s)
+{
+ return avresample_available(s->avr) + avresample_get_delay(s->avr);
+}
+
+static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
+{
+ AVFilterContext *ctx = inlink->dst;
+ ASyncContext *s = ctx->priv;
+ AVFilterLink *outlink = ctx->outputs[0];
+ int nb_channels = av_get_channel_layout_nb_channels(buf->audio->channel_layout);
+ int64_t pts = (buf->pts == AV_NOPTS_VALUE) ? buf->pts :
+ av_rescale_q(buf->pts, inlink->time_base, outlink->time_base);
+ int out_size;
+ int64_t delta;
+
+ /* buffer data until we get the first timestamp */
+ if (s->pts == AV_NOPTS_VALUE) {
+ if (pts != AV_NOPTS_VALUE) {
+ s->pts = pts - get_delay(s);
+ }
+ write_to_fifo(s, buf);
+ return;
+ }
+
+ /* now wait for the next timestamp */
+ if (pts == AV_NOPTS_VALUE) {
+ write_to_fifo(s, buf);
+ return;
+ }
+
+ /* when we have two timestamps, compute how many samples would we have
+ * to add/remove to get proper sync between data and timestamps */
+ delta = pts - s->pts - get_delay(s);
+ out_size = avresample_available(s->avr);
+
+ if (labs(delta) > s->min_delta) {
+ av_log(ctx, AV_LOG_VERBOSE, "Discontinuity - %"PRId64" samples.\n", delta);
+ out_size += delta;
+ } else {
+ if (s->resample) {
+ int comp = av_clip(delta, -s->max_comp, s->max_comp);
+ av_log(ctx, AV_LOG_VERBOSE, "Compensating %d samples per second.\n", comp);
+ avresample_set_compensation(s->avr, delta, inlink->sample_rate);
+ }
+ delta = 0;
+ }
+
+ if (out_size > 0) {
+ AVFilterBufferRef *buf_out = ff_get_audio_buffer(outlink, AV_PERM_WRITE,
+ out_size);
+ if (!buf_out)
+ return;
+
+ avresample_read(s->avr, (void**)buf_out->extended_data, out_size);
+ buf_out->pts = s->pts;
+
+ if (delta > 0) {
+ av_samples_set_silence(buf_out->extended_data, out_size - delta,
+ delta, nb_channels, buf->format);
+ }
+ ff_filter_samples(outlink, buf_out);
+ } else {
+ av_log(ctx, AV_LOG_WARNING, "Non-monotonous timestamps, dropping "
+ "whole buffer.\n");
+ }
+
+ /* drain any remaining buffered data */
+ avresample_read(s->avr, NULL, avresample_available(s->avr));
+
+ s->pts = pts - avresample_get_delay(s->avr);
+ avresample_convert(s->avr, NULL, 0, 0, (void**)buf->extended_data,
+ buf->linesize[0], buf->audio->nb_samples);
+ avfilter_unref_buffer(buf);
+}
+
+AVFilter avfilter_af_asyncts = {
+ .name = "asyncts",
+ .description = NULL_IF_CONFIG_SMALL("Sync audio data to timestamps"),
+
+ .init = init,
+ .uninit = uninit,
+
+ .priv_size = sizeof(ASyncContext),
+
+ .inputs = (const AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .filter_samples = filter_samples },
+ { NULL }},
+ .outputs = (const AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .config_props = config_props,
+ .request_frame = request_frame },
+ { NULL }},
+};
diff --git a/libavfilter/af_channelmap.c b/libavfilter/af_channelmap.c
new file mode 100644
index 0000000..0dfffaa
--- /dev/null
+++ b/libavfilter/af_channelmap.c
@@ -0,0 +1,401 @@
+/*
+ * Copyright (c) 2012 Google, Inc.
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * audio channel mapping filter
+ */
+
+#include <ctype.h>
+
+#include "libavutil/audioconvert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
+#include "libavutil/samplefmt.h"
+
+#include "audio.h"
+#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+
+struct ChannelMap {
+ uint64_t in_channel;
+ uint64_t out_channel;
+ int in_channel_idx;
+ int out_channel_idx;
+};
+
+enum MappingMode {
+ MAP_NONE,
+ MAP_ONE_INT,
+ MAP_ONE_STR,
+ MAP_PAIR_INT_INT,
+ MAP_PAIR_INT_STR,
+ MAP_PAIR_STR_INT,
+ MAP_PAIR_STR_STR
+};
+
+#define MAX_CH 64
+typedef struct ChannelMapContext {
+ const AVClass *class;
+ AVFilterChannelLayouts *channel_layouts;
+ char *mapping_str;
+ char *channel_layout_str;
+ uint64_t output_layout;
+ struct ChannelMap map[MAX_CH];
+ int nch;
+ enum MappingMode mode;
+} ChannelMapContext;
+
+#define OFFSET(x) offsetof(ChannelMapContext, x)
+#define A AV_OPT_FLAG_AUDIO_PARAM
+static const AVOption options[] = {
+ { "map", "A comma-separated list of input channel numbers in output order.",
+ OFFSET(mapping_str), AV_OPT_TYPE_STRING, .flags = A },
+ { "channel_layout", "Output channel layout.",
+ OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, .flags = A },
+ { NULL },
+};
+
+static const AVClass channelmap_class = {
+ .class_name = "channel map filter",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+static char* split(char *message, char delim) {
+ char *next = strchr(message, delim);
+ if (next)
+ *next++ = '\0';
+ return next;
+}
+
+static int get_channel_idx(char **map, int *ch, char delim, int max_ch)
+{
+ char *next = split(*map, delim);
+ int len;
+ int n = 0;
+ if (!next && delim == '-')
+ return AVERROR(EINVAL);
+ len = strlen(*map);
+ sscanf(*map, "%d%n", ch, &n);
+ if (n != len)
+ return AVERROR(EINVAL);
+ if (*ch < 0 || *ch > max_ch)
+ return AVERROR(EINVAL);
+ *map = next;
+ return 0;
+}
+
+static int get_channel(char **map, uint64_t *ch, char delim)
+{
+ char *next = split(*map, delim);
+ if (!next && delim == '-')
+ return AVERROR(EINVAL);
+ *ch = av_get_channel_layout(*map);
+ if (av_get_channel_layout_nb_channels(*ch) != 1)
+ return AVERROR(EINVAL);
+ *map = next;
+ return 0;
+}
+
+static av_cold int channelmap_init(AVFilterContext *ctx, const char *args)
+{
+ ChannelMapContext *s = ctx->priv;
+ int ret;
+ char *mapping;
+ enum mode;
+ int map_entries = 0;
+ char buf[256];
+ enum MappingMode mode;
+ uint64_t out_ch_mask = 0;
+ int i;
+
+ if (!args) {
+ av_log(ctx, AV_LOG_ERROR, "No parameters supplied.\n");
+ return AVERROR(EINVAL);
+ }
+
+ s->class = &channelmap_class;
+ av_opt_set_defaults(s);
+
+ if ((ret = av_set_options_string(s, args, "=", ":")) < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Error parsing options string '%s'.\n", args);
+ return ret;
+ }
+
+ mapping = s->mapping_str;
+
+ if (!mapping) {
+ mode = MAP_NONE;
+ } else {
+ char *dash = strchr(mapping, '-');
+ if (!dash) { // short mapping
+ if (isdigit(*mapping))
+ mode = MAP_ONE_INT;
+ else
+ mode = MAP_ONE_STR;
+ } else if (isdigit(*mapping)) {
+ if (isdigit(*(dash+1)))
+ mode = MAP_PAIR_INT_INT;
+ else
+ mode = MAP_PAIR_INT_STR;
+ } else {
+ if (isdigit(*(dash+1)))
+ mode = MAP_PAIR_STR_INT;
+ else
+ mode = MAP_PAIR_STR_STR;
+ }
+ }
+
+ if (mode != MAP_NONE) {
+ char *comma = mapping;
+ map_entries = 1;
+ while ((comma = strchr(comma, ','))) {
+ if (*++comma) // Allow trailing comma
+ map_entries++;
+ }
+ }
+
+ if (map_entries > MAX_CH) {
+ av_log(ctx, AV_LOG_ERROR, "Too many channels mapped: '%d'.\n", map_entries);
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+
+ for (i = 0; i < map_entries; i++) {
+ int in_ch_idx = -1, out_ch_idx = -1;
+ uint64_t in_ch = 0, out_ch = 0;
+ static const char err[] = "Failed to parse channel map\n";
+ switch (mode) {
+ case MAP_ONE_INT:
+ if (get_channel_idx(&mapping, &in_ch_idx, ',', MAX_CH) < 0) {
+ ret = AVERROR(EINVAL);
+ av_log(ctx, AV_LOG_ERROR, err);
+ goto fail;
+ }
+ s->map[i].in_channel_idx = in_ch_idx;
+ s->map[i].out_channel_idx = i;
+ break;
+ case MAP_ONE_STR:
+ if (!get_channel(&mapping, &in_ch, ',')) {
+ av_log(ctx, AV_LOG_ERROR, err);
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ s->map[i].in_channel = in_ch;
+ s->map[i].out_channel_idx = i;
+ break;
+ case MAP_PAIR_INT_INT:
+ if (get_channel_idx(&mapping, &in_ch_idx, '-', MAX_CH) < 0 ||
+ get_channel_idx(&mapping, &out_ch_idx, ',', MAX_CH) < 0) {
+ av_log(ctx, AV_LOG_ERROR, err);
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ s->map[i].in_channel_idx = in_ch_idx;
+ s->map[i].out_channel_idx = out_ch_idx;
+ break;
+ case MAP_PAIR_INT_STR:
+ if (get_channel_idx(&mapping, &in_ch_idx, '-', MAX_CH) < 0 ||
+ get_channel(&mapping, &out_ch, ',') < 0 ||
+ out_ch & out_ch_mask) {
+ av_log(ctx, AV_LOG_ERROR, err);
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ s->map[i].in_channel_idx = in_ch_idx;
+ s->map[i].out_channel = out_ch;
+ out_ch_mask |= out_ch;
+ break;
+ case MAP_PAIR_STR_INT:
+ if (get_channel(&mapping, &in_ch, '-') < 0 ||
+ get_channel_idx(&mapping, &out_ch_idx, ',', MAX_CH) < 0) {
+ av_log(ctx, AV_LOG_ERROR, err);
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ s->map[i].in_channel = in_ch;
+ s->map[i].out_channel_idx = out_ch_idx;
+ break;
+ case MAP_PAIR_STR_STR:
+ if (get_channel(&mapping, &in_ch, '-') < 0 ||
+ get_channel(&mapping, &out_ch, ',') < 0 ||
+ out_ch & out_ch_mask) {
+ av_log(ctx, AV_LOG_ERROR, err);
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ s->map[i].in_channel = in_ch;
+ s->map[i].out_channel = out_ch;
+ out_ch_mask |= out_ch;
+ break;
+ }
+ }
+ s->mode = mode;
+ s->nch = map_entries;
+ s->output_layout = out_ch_mask ? out_ch_mask :
+ av_get_default_channel_layout(map_entries);
+
+ if (s->channel_layout_str) {
+ uint64_t fmt;
+ if ((fmt = av_get_channel_layout(s->channel_layout_str)) == 0) {
+ av_log(ctx, AV_LOG_ERROR, "Error parsing channel layout: '%s'.\n",
+ s->channel_layout_str);
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ if (mode == MAP_NONE) {
+ int i;
+ s->nch = av_get_channel_layout_nb_channels(fmt);
+ for (i = 0; i < s->nch; i++) {
+ s->map[i].in_channel_idx = i;
+ s->map[i].out_channel_idx = i;
+ }
+ } else if (out_ch_mask && out_ch_mask != fmt) {
+ av_get_channel_layout_string(buf, sizeof(buf), 0, out_ch_mask);
+ av_log(ctx, AV_LOG_ERROR,
+ "Output channel layout '%s' does not match the list of channel mapped: '%s'.\n",
+ s->channel_layout_str, buf);
+ ret = AVERROR(EINVAL);
+ goto fail;
+ } else if (s->nch != av_get_channel_layout_nb_channels(fmt)) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Output channel layout %s does not match the number of channels mapped %d.\n",
+ s->channel_layout_str, s->nch);
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ s->output_layout = fmt;
+ }
+ ff_add_channel_layout(&s->channel_layouts, s->output_layout);
+
+ if (mode == MAP_PAIR_INT_STR || mode == MAP_PAIR_STR_STR) {
+ for (i = 0; i < s->nch; i++) {
+ s->map[i].out_channel_idx = av_get_channel_layout_channel_index(
+ s->output_layout, s->map[i].out_channel);
+ }
+ }
+
+fail:
+ av_opt_free(s);
+ return ret;
+}
+
+static int channelmap_query_formats(AVFilterContext *ctx)
+{
+ ChannelMapContext *s = ctx->priv;
+
+ ff_set_common_formats(ctx, ff_planar_sample_fmts());
+ ff_set_common_samplerates(ctx, ff_all_samplerates());
+ ff_channel_layouts_ref(ff_all_channel_layouts(), &ctx->inputs[0]->out_channel_layouts);
+ ff_channel_layouts_ref(s->channel_layouts, &ctx->outputs[0]->in_channel_layouts);
+
+ return 0;
+}
+
+static void channelmap_filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
+{
+ AVFilterContext *ctx = inlink->dst;
+ AVFilterLink *outlink = ctx->outputs[0];
+ const ChannelMapContext *s = ctx->priv;
+ const int nch_in = av_get_channel_layout_nb_channels(inlink->channel_layout);
+ const int nch_out = s->nch;
+ int ch;
+ uint8_t *source_planes[MAX_CH];
+
+ memcpy(source_planes, buf->extended_data,
+ nch_in * sizeof(source_planes[0]));
+
+ if (nch_out > nch_in) {
+ if (nch_out > FF_ARRAY_ELEMS(buf->data)) {
+ uint8_t **new_extended_data =
+ av_mallocz(nch_out * sizeof(*buf->extended_data));
+ if (!new_extended_data)
+ return;
+ if (buf->extended_data == buf->data) {
+ buf->extended_data = new_extended_data;
+ } else {
+ buf->extended_data = new_extended_data;
+ av_free(buf->extended_data);
+ }
+ } else if (buf->extended_data != buf->data) {
+ av_free(buf->extended_data);
+ buf->extended_data = buf->data;
+ }
+ }
+
+ for (ch = 0; ch < nch_out; ch++) {
+ buf->extended_data[s->map[ch].out_channel_idx] =
+ source_planes[s->map[ch].in_channel_idx];
+ }
+
+ if (buf->data != buf->extended_data)
+ memcpy(buf->data, buf->extended_data,
+ FFMIN(FF_ARRAY_ELEMS(buf->data), nch_out) * sizeof(buf->data[0]));
+
+ ff_filter_samples(outlink, buf);
+}
+
+static int channelmap_config_input(AVFilterLink *inlink)
+{
+ AVFilterContext *ctx = inlink->dst;
+ ChannelMapContext *s = ctx->priv;
+ int i, err = 0;
+ const char *channel_name;
+ char layout_name[256];
+
+ if (s->mode == MAP_PAIR_STR_INT || s->mode == MAP_PAIR_STR_STR) {
+ for (i = 0; i < s->nch; i++) {
+ s->map[i].in_channel_idx = av_get_channel_layout_channel_index(
+ inlink->channel_layout, s->map[i].in_channel);
+ if (s->map[i].in_channel_idx < 0) {
+ channel_name = av_get_channel_name(s->map[i].in_channel);
+ av_get_channel_layout_string(layout_name, sizeof(layout_name),
+ 0, inlink->channel_layout);
+ av_log(ctx, AV_LOG_ERROR,
+ "input channel '%s' not available from input layout '%s'\n",
+ channel_name, layout_name);
+ err = AVERROR(EINVAL);
+ }
+ }
+ }
+
+ return err;
+}
+
+AVFilter avfilter_af_channelmap = {
+ .name = "channelmap",
+ .description = NULL_IF_CONFIG_SMALL("Remap audio channels."),
+ .init = channelmap_init,
+ .query_formats = channelmap_query_formats,
+ .priv_size = sizeof(ChannelMapContext),
+
+ .inputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .filter_samples = channelmap_filter_samples,
+ .config_props = channelmap_config_input },
+ { .name = NULL }},
+ .outputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_AUDIO },
+ { .name = NULL }},
+};
diff --git a/libavfilter/af_channelsplit.c b/libavfilter/af_channelsplit.c
new file mode 100644
index 0000000..ed134d2
--- /dev/null
+++ b/libavfilter/af_channelsplit.c
@@ -0,0 +1,146 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Channel split filter
+ *
+ * Split an audio stream into per-channel streams.
+ */
+
+#include "libavutil/audioconvert.h"
+#include "libavutil/opt.h"
+
+#include "audio.h"
+#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+
+typedef struct ChannelSplitContext {
+ const AVClass *class;
+
+ uint64_t channel_layout;
+ char *channel_layout_str;
+} ChannelSplitContext;
+
+#define OFFSET(x) offsetof(ChannelSplitContext, x)
+#define A AV_OPT_FLAG_AUDIO_PARAM
+static const AVOption options[] = {
+ { "channel_layout", "Input channel layout.", OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, { .str = "stereo" }, .flags = A },
+ { NULL },
+};
+
+static const AVClass channelsplit_class = {
+ .class_name = "channelsplit filter",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+static int init(AVFilterContext *ctx, const char *arg)
+{
+ ChannelSplitContext *s = ctx->priv;
+ int nb_channels;
+ int ret = 0, i;
+
+ s->class = &channelsplit_class;
+ av_opt_set_defaults(s);
+ if ((ret = av_set_options_string(s, arg, "=", ":")) < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Error parsing options string '%s'.\n", arg);
+ return ret;
+ }
+ if (!(s->channel_layout = av_get_channel_layout(s->channel_layout_str))) {
+ av_log(ctx, AV_LOG_ERROR, "Error parsing channel layout '%s'.\n",
+ s->channel_layout_str);
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+
+ nb_channels = av_get_channel_layout_nb_channels(s->channel_layout);
+ for (i = 0; i < nb_channels; i++) {
+ uint64_t channel = av_channel_layout_extract_channel(s->channel_layout, i);
+ AVFilterPad pad = { 0 };
+
+ pad.type = AVMEDIA_TYPE_AUDIO;
+ pad.name = av_get_channel_name(channel);
+
+ ff_insert_outpad(ctx, i, &pad);
+ }
+
+fail:
+ av_opt_free(s);
+ return ret;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+ ChannelSplitContext *s = ctx->priv;
+ AVFilterChannelLayouts *in_layouts = NULL;
+ int i;
+
+ ff_set_common_formats (ctx, ff_planar_sample_fmts());
+ ff_set_common_samplerates(ctx, ff_all_samplerates());
+
+ ff_add_channel_layout(&in_layouts, s->channel_layout);
+ ff_channel_layouts_ref(in_layouts, &ctx->inputs[0]->out_channel_layouts);
+
+ for (i = 0; i < ctx->nb_outputs; i++) {
+ AVFilterChannelLayouts *out_layouts = NULL;
+ uint64_t channel = av_channel_layout_extract_channel(s->channel_layout, i);
+
+ ff_add_channel_layout(&out_layouts, channel);
+ ff_channel_layouts_ref(out_layouts, &ctx->outputs[i]->in_channel_layouts);
+ }
+
+ return 0;
+}
+
+static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
+{
+ AVFilterContext *ctx = inlink->dst;
+ int i;
+
+ for (i = 0; i < ctx->nb_outputs; i++) {
+ AVFilterBufferRef *buf_out = avfilter_ref_buffer(buf, ~AV_PERM_WRITE);
+
+ if (!buf_out)
+ return;
+
+ buf_out->data[0] = buf_out->extended_data[0] = buf_out->extended_data[i];
+ buf_out->audio->channel_layout =
+ av_channel_layout_extract_channel(buf->audio->channel_layout, i);
+
+ ff_filter_samples(ctx->outputs[i], buf_out);
+ }
+ avfilter_unref_buffer(buf);
+}
+
+AVFilter avfilter_af_channelsplit = {
+ .name = "channelsplit",
+ .description = NULL_IF_CONFIG_SMALL("Split audio into per-channel streams"),
+ .priv_size = sizeof(ChannelSplitContext),
+
+ .init = init,
+ .query_formats = query_formats,
+
+ .inputs = (const AVFilterPad[]){{ .name = "default",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .filter_samples = filter_samples, },
+ { NULL }},
+ .outputs = (const AVFilterPad[]){{ NULL }},
+};
diff --git a/libavfilter/af_join.c b/libavfilter/af_join.c
new file mode 100644
index 0000000..e86c556
--- /dev/null
+++ b/libavfilter/af_join.c
@@ -0,0 +1,501 @@
+/*
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Audio join filter
+ *
+ * Join multiple audio inputs as different channels in
+ * a single output
+ */
+
+#include "libavutil/audioconvert.h"
+#include "libavutil/avassert.h"
+#include "libavutil/opt.h"
+
+#include "audio.h"
+#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+
+typedef struct ChannelMap {
+ int input; ///< input stream index
+ int in_channel_idx; ///< index of in_channel in the input stream data
+ uint64_t in_channel; ///< layout describing the input channel
+ uint64_t out_channel; ///< layout describing the output channel
+} ChannelMap;
+
+typedef struct JoinContext {
+ const AVClass *class;
+
+ int inputs;
+ char *map;
+ char *channel_layout_str;
+ uint64_t channel_layout;
+
+ int nb_channels;
+ ChannelMap *channels;
+
+ /**
+ * Temporary storage for input frames, until we get one on each input.
+ */
+ AVFilterBufferRef **input_frames;
+
+ /**
+ * Temporary storage for data pointers, for assembling the output buffer.
+ */
+ uint8_t **data;
+} JoinContext;
+
+/**
+ * To avoid copying the data from input buffers, this filter creates
+ * a custom output buffer that stores references to all inputs and
+ * unrefs them on free.
+ */
+typedef struct JoinBufferPriv {
+ AVFilterBufferRef **in_buffers;
+ int nb_in_buffers;
+} JoinBufferPriv;
+
+#define OFFSET(x) offsetof(JoinContext, x)
+#define A AV_OPT_FLAG_AUDIO_PARAM
+static const AVOption join_options[] = {
+ { "inputs", "Number of input streams.", OFFSET(inputs), AV_OPT_TYPE_INT, { 2 }, 1, INT_MAX, A },
+ { "channel_layout", "Channel layout of the "
+ "output stream.", OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, {.str = "stereo"}, 0, 0, A },
+ { "map", "A comma-separated list of channels maps in the format "
+ "'input_stream.input_channel-output_channel.",
+ OFFSET(map), AV_OPT_TYPE_STRING, .flags = A },
+ { NULL },
+};
+
+static const AVClass join_class = {
+ .class_name = "join filter",
+ .item_name = av_default_item_name,
+ .option = join_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+static void filter_samples(AVFilterLink *link, AVFilterBufferRef *buf)
+{
+ AVFilterContext *ctx = link->dst;
+ JoinContext *s = ctx->priv;
+ int i;
+
+ for (i = 0; i < ctx->nb_inputs; i++)
+ if (link == ctx->inputs[i])
+ break;
+ av_assert0(i < ctx->nb_inputs);
+ av_assert0(!s->input_frames[i]);
+ s->input_frames[i] = buf;
+}
+
+static int parse_maps(AVFilterContext *ctx)
+{
+ JoinContext *s = ctx->priv;
+ char *cur = s->map;
+
+ while (cur && *cur) {
+ char *sep, *next, *p;
+ uint64_t in_channel = 0, out_channel = 0;
+ int input_idx, out_ch_idx, in_ch_idx;
+
+ next = strchr(cur, ',');
+ if (next)
+ *next++ = 0;
+
+ /* split the map into input and output parts */
+ if (!(sep = strchr(cur, '-'))) {
+ av_log(ctx, AV_LOG_ERROR, "Missing separator '-' in channel "
+ "map '%s'\n", cur);
+ return AVERROR(EINVAL);
+ }
+ *sep++ = 0;
+
+#define PARSE_CHANNEL(str, var, inout) \
+ if (!(var = av_get_channel_layout(str))) { \
+ av_log(ctx, AV_LOG_ERROR, "Invalid " inout " channel: %s.\n", str);\
+ return AVERROR(EINVAL); \
+ } \
+ if (av_get_channel_layout_nb_channels(var) != 1) { \
+ av_log(ctx, AV_LOG_ERROR, "Channel map describes more than one " \
+ inout " channel.\n"); \
+ return AVERROR(EINVAL); \
+ }
+
+ /* parse output channel */
+ PARSE_CHANNEL(sep, out_channel, "output");
+ if (!(out_channel & s->channel_layout)) {
+ av_log(ctx, AV_LOG_ERROR, "Output channel '%s' is not present in "
+ "requested channel layout.\n", sep);
+ return AVERROR(EINVAL);
+ }
+
+ out_ch_idx = av_get_channel_layout_channel_index(s->channel_layout,
+ out_channel);
+ if (s->channels[out_ch_idx].input >= 0) {
+ av_log(ctx, AV_LOG_ERROR, "Multiple maps for output channel "
+ "'%s'.\n", sep);
+ return AVERROR(EINVAL);
+ }
+
+ /* parse input channel */
+ input_idx = strtol(cur, &cur, 0);
+ if (input_idx < 0 || input_idx >= s->inputs) {
+ av_log(ctx, AV_LOG_ERROR, "Invalid input stream index: %d.\n",
+ input_idx);
+ return AVERROR(EINVAL);
+ }
+
+ if (*cur)
+ cur++;
+
+ in_ch_idx = strtol(cur, &p, 0);
+ if (p == cur) {
+ /* channel specifier is not a number,
+ * try to parse as channel name */
+ PARSE_CHANNEL(cur, in_channel, "input");
+ }
+
+ s->channels[out_ch_idx].input = input_idx;
+ if (in_channel)
+ s->channels[out_ch_idx].in_channel = in_channel;
+ else
+ s->channels[out_ch_idx].in_channel_idx = in_ch_idx;
+
+ cur = next;
+ }
+ return 0;
+}
+
+static int join_init(AVFilterContext *ctx, const char *args)
+{
+ JoinContext *s = ctx->priv;
+ int ret, i;
+
+ s->class = &join_class;
+ av_opt_set_defaults(s);
+ if ((ret = av_set_options_string(s, args, "=", ":")) < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Error parsing options string '%s'.\n", args);
+ return ret;
+ }
+
+ if (!(s->channel_layout = av_get_channel_layout(s->channel_layout_str))) {
+ av_log(ctx, AV_LOG_ERROR, "Error parsing channel layout '%s'.\n",
+ s->channel_layout_str);
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+
+ s->nb_channels = av_get_channel_layout_nb_channels(s->channel_layout);
+ s->channels = av_mallocz(sizeof(*s->channels) * s->nb_channels);
+ s->data = av_mallocz(sizeof(*s->data) * s->nb_channels);
+ s->input_frames = av_mallocz(sizeof(*s->input_frames) * s->inputs);
+ if (!s->channels || !s->data || !s->input_frames) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ for (i = 0; i < s->nb_channels; i++) {
+ s->channels[i].out_channel = av_channel_layout_extract_channel(s->channel_layout, i);
+ s->channels[i].input = -1;
+ }
+
+ if ((ret = parse_maps(ctx)) < 0)
+ goto fail;
+
+ for (i = 0; i < s->inputs; i++) {
+ char name[32];
+ AVFilterPad pad = { 0 };
+
+ snprintf(name, sizeof(name), "input%d", i);
+ pad.type = AVMEDIA_TYPE_AUDIO;
+ pad.name = av_strdup(name);
+ pad.filter_samples = filter_samples;
+
+ pad.needs_fifo = 1;
+
+ ff_insert_inpad(ctx, i, &pad);
+ }
+
+fail:
+ av_opt_free(s);
+ return ret;
+}
+
+static void join_uninit(AVFilterContext *ctx)
+{
+ JoinContext *s = ctx->priv;
+ int i;
+
+ for (i = 0; i < ctx->nb_inputs; i++) {
+ av_freep(&ctx->input_pads[i].name);
+ avfilter_unref_buffer(s->input_frames[i]);
+ }
+
+ av_freep(&s->channels);
+ av_freep(&s->data);
+ av_freep(&s->input_frames);
+}
+
+static int join_query_formats(AVFilterContext *ctx)
+{
+ JoinContext *s = ctx->priv;
+ AVFilterChannelLayouts *layouts = NULL;
+ int i;
+
+ ff_add_channel_layout(&layouts, s->channel_layout);
+ ff_channel_layouts_ref(layouts, &ctx->outputs[0]->in_channel_layouts);
+
+ for (i = 0; i < ctx->nb_inputs; i++)
+ ff_channel_layouts_ref(ff_all_channel_layouts(),
+ &ctx->inputs[i]->out_channel_layouts);
+
+ ff_set_common_formats (ctx, ff_planar_sample_fmts());
+ ff_set_common_samplerates(ctx, ff_all_samplerates());
+
+ return 0;
+}
+
+static void guess_map_matching(AVFilterContext *ctx, ChannelMap *ch,
+ uint64_t *inputs)
+{
+ int i;
+
+ for (i = 0; i < ctx->nb_inputs; i++) {
+ AVFilterLink *link = ctx->inputs[i];
+
+ if (ch->out_channel & link->channel_layout &&
+ !(ch->out_channel & inputs[i])) {
+ ch->input = i;
+ ch->in_channel = ch->out_channel;
+ inputs[i] |= ch->out_channel;
+ return;
+ }
+ }
+}
+
+static void guess_map_any(AVFilterContext *ctx, ChannelMap *ch,
+ uint64_t *inputs)
+{
+ int i;
+
+ for (i = 0; i < ctx->nb_inputs; i++) {
+ AVFilterLink *link = ctx->inputs[i];
+
+ if ((inputs[i] & link->channel_layout) != link->channel_layout) {
+ uint64_t unused = link->channel_layout & ~inputs[i];
+
+ ch->input = i;
+ ch->in_channel = av_channel_layout_extract_channel(unused, 0);
+ inputs[i] |= ch->in_channel;
+ return;
+ }
+ }
+}
+
+static int join_config_output(AVFilterLink *outlink)
+{
+ AVFilterContext *ctx = outlink->src;
+ JoinContext *s = ctx->priv;
+ uint64_t *inputs; // nth element tracks which channels are used from nth input
+ int i, ret = 0;
+
+ /* initialize inputs to user-specified mappings */
+ if (!(inputs = av_mallocz(sizeof(*inputs) * ctx->nb_inputs)))
+ return AVERROR(ENOMEM);
+ for (i = 0; i < s->nb_channels; i++) {
+ ChannelMap *ch = &s->channels[i];
+ AVFilterLink *inlink;
+
+ if (ch->input < 0)
+ continue;
+
+ inlink = ctx->inputs[ch->input];
+
+ if (!ch->in_channel)
+ ch->in_channel = av_channel_layout_extract_channel(inlink->channel_layout,
+ ch->in_channel_idx);
+
+ if (!(ch->in_channel & inlink->channel_layout)) {
+ av_log(ctx, AV_LOG_ERROR, "Requested channel %s is not present in "
+ "input stream #%d.\n", av_get_channel_name(ch->in_channel),
+ ch->input);
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+
+ inputs[ch->input] |= ch->in_channel;
+ }
+
+ /* guess channel maps when not explicitly defined */
+ /* first try unused matching channels */
+ for (i = 0; i < s->nb_channels; i++) {
+ ChannelMap *ch = &s->channels[i];
+
+ if (ch->input < 0)
+ guess_map_matching(ctx, ch, inputs);
+ }
+
+ /* if the above failed, try to find _any_ unused input channel */
+ for (i = 0; i < s->nb_channels; i++) {
+ ChannelMap *ch = &s->channels[i];
+
+ if (ch->input < 0)
+ guess_map_any(ctx, ch, inputs);
+
+ if (ch->input < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Could not find input channel for "
+ "output channel '%s'.\n",
+ av_get_channel_name(ch->out_channel));
+ goto fail;
+ }
+
+ ch->in_channel_idx = av_get_channel_layout_channel_index(ctx->inputs[ch->input]->channel_layout,
+ ch->in_channel);
+ }
+
+ /* print mappings */
+ av_log(ctx, AV_LOG_VERBOSE, "mappings: ");
+ for (i = 0; i < s->nb_channels; i++) {
+ ChannelMap *ch = &s->channels[i];
+ av_log(ctx, AV_LOG_VERBOSE, "%d.%s => %s ", ch->input,
+ av_get_channel_name(ch->in_channel),
+ av_get_channel_name(ch->out_channel));
+ }
+ av_log(ctx, AV_LOG_VERBOSE, "\n");
+
+ for (i = 0; i < ctx->nb_inputs; i++) {
+ if (!inputs[i])
+ av_log(ctx, AV_LOG_WARNING, "No channels are used from input "
+ "stream %d.\n", i);
+ }
+
+fail:
+ av_freep(&inputs);
+ return ret;
+}
+
+static void join_free_buffer(AVFilterBuffer *buf)
+{
+ JoinBufferPriv *priv = buf->priv;
+
+ if (priv) {
+ int i;
+
+ for (i = 0; i < priv->nb_in_buffers; i++)
+ avfilter_unref_buffer(priv->in_buffers[i]);
+
+ av_freep(&priv->in_buffers);
+ av_freep(&buf->priv);
+ }
+
+ if (buf->extended_data != buf->data)
+ av_freep(&buf->extended_data);
+ av_freep(&buf);
+}
+
+static int join_request_frame(AVFilterLink *outlink)
+{
+ AVFilterContext *ctx = outlink->src;
+ JoinContext *s = ctx->priv;
+ AVFilterBufferRef *buf;
+ JoinBufferPriv *priv;
+ int linesize = INT_MAX;
+ int perms = ~0;
+ int nb_samples = 0;
+ int i, j, ret;
+
+ /* get a frame on each input */
+ for (i = 0; i < ctx->nb_inputs; i++) {
+ AVFilterLink *inlink = ctx->inputs[i];
+
+ if (!s->input_frames[i] &&
+ (ret = ff_request_frame(inlink)) < 0)
+ return ret;
+
+ /* request the same number of samples on all inputs */
+ if (i == 0) {
+ nb_samples = s->input_frames[0]->audio->nb_samples;
+
+ for (j = 1; !i && j < ctx->nb_inputs; j++)
+ ctx->inputs[j]->request_samples = nb_samples;
+ }
+ }
+
+ for (i = 0; i < s->nb_channels; i++) {
+ ChannelMap *ch = &s->channels[i];
+ AVFilterBufferRef *cur_buf = s->input_frames[ch->input];
+
+ s->data[i] = cur_buf->extended_data[ch->in_channel_idx];
+ linesize = FFMIN(linesize, cur_buf->linesize[0]);
+ perms &= cur_buf->perms;
+ }
+
+ av_assert0(nb_samples > 0);
+ buf = avfilter_get_audio_buffer_ref_from_arrays(s->data, linesize, perms,
+ nb_samples, outlink->format,
+ outlink->channel_layout);
+ if (!buf)
+ return AVERROR(ENOMEM);
+
+ buf->buf->free = join_free_buffer;
+ buf->pts = s->input_frames[0]->pts;
+
+ if (!(priv = av_mallocz(sizeof(*priv))))
+ goto fail;
+ if (!(priv->in_buffers = av_mallocz(sizeof(*priv->in_buffers) * ctx->nb_inputs)))
+ goto fail;
+
+ for (i = 0; i < ctx->nb_inputs; i++)
+ priv->in_buffers[i] = s->input_frames[i];
+ priv->nb_in_buffers = ctx->nb_inputs;
+ buf->buf->priv = priv;
+
+ ff_filter_samples(outlink, buf);
+
+ memset(s->input_frames, 0, sizeof(*s->input_frames) * ctx->nb_inputs);
+
+ return 0;
+
+fail:
+ avfilter_unref_buffer(buf);
+ if (priv)
+ av_freep(&priv->in_buffers);
+ av_freep(&priv);
+ return AVERROR(ENOMEM);
+}
+
+AVFilter avfilter_af_join = {
+ .name = "join",
+ .description = NULL_IF_CONFIG_SMALL("Join multiple audio streams into "
+ "multi-channel output"),
+ .priv_size = sizeof(JoinContext),
+
+ .init = join_init,
+ .uninit = join_uninit,
+ .query_formats = join_query_formats,
+
+ .inputs = (const AVFilterPad[]){{ NULL }},
+ .outputs = (const AVFilterPad[]){{ .name = "default",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .config_props = join_config_output,
+ .request_frame = join_request_frame, },
+ { NULL }},
+};
diff --git a/libavfilter/af_resample.c b/libavfilter/af_resample.c
new file mode 100644
index 0000000..8a02cfe
--- /dev/null
+++ b/libavfilter/af_resample.c
@@ -0,0 +1,236 @@
+/*
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * sample format and channel layout conversion audio filter
+ */
+
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
+
+#include "libavresample/avresample.h"
+
+#include "audio.h"
+#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+
+typedef struct ResampleContext {
+ AVAudioResampleContext *avr;
+
+ int64_t next_pts;
+} ResampleContext;
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+ ResampleContext *s = ctx->priv;
+
+ if (s->avr) {
+ avresample_close(s->avr);
+ avresample_free(&s->avr);
+ }
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+ AVFilterLink *inlink = ctx->inputs[0];
+ AVFilterLink *outlink = ctx->outputs[0];
+
+ AVFilterFormats *in_formats = ff_all_formats(AVMEDIA_TYPE_AUDIO);
+ AVFilterFormats *out_formats = ff_all_formats(AVMEDIA_TYPE_AUDIO);
+ AVFilterFormats *in_samplerates = ff_all_samplerates();
+ AVFilterFormats *out_samplerates = ff_all_samplerates();
+ AVFilterChannelLayouts *in_layouts = ff_all_channel_layouts();
+ AVFilterChannelLayouts *out_layouts = ff_all_channel_layouts();
+
+ ff_formats_ref(in_formats, &inlink->out_formats);
+ ff_formats_ref(out_formats, &outlink->in_formats);
+
+ ff_formats_ref(in_samplerates, &inlink->out_samplerates);
+ ff_formats_ref(out_samplerates, &outlink->in_samplerates);
+
+ ff_channel_layouts_ref(in_layouts, &inlink->out_channel_layouts);
+ ff_channel_layouts_ref(out_layouts, &outlink->in_channel_layouts);
+
+ return 0;
+}
+
+static int config_output(AVFilterLink *outlink)
+{
+ AVFilterContext *ctx = outlink->src;
+ AVFilterLink *inlink = ctx->inputs[0];
+ ResampleContext *s = ctx->priv;
+ char buf1[64], buf2[64];
+ int ret;
+
+ if (s->avr) {
+ avresample_close(s->avr);
+ avresample_free(&s->avr);
+ }
+
+ if (inlink->channel_layout == outlink->channel_layout &&
+ inlink->sample_rate == outlink->sample_rate &&
+ inlink->format == outlink->format)
+ return 0;
+
+ if (!(s->avr = avresample_alloc_context()))
+ return AVERROR(ENOMEM);
+
+ av_opt_set_int(s->avr, "in_channel_layout", inlink ->channel_layout, 0);
+ av_opt_set_int(s->avr, "out_channel_layout", outlink->channel_layout, 0);
+ av_opt_set_int(s->avr, "in_sample_fmt", inlink ->format, 0);
+ av_opt_set_int(s->avr, "out_sample_fmt", outlink->format, 0);
+ av_opt_set_int(s->avr, "in_sample_rate", inlink ->sample_rate, 0);
+ av_opt_set_int(s->avr, "out_sample_rate", outlink->sample_rate, 0);
+
+ /* if both the input and output formats are s16 or u8, use s16 as
+ the internal sample format */
+ if (av_get_bytes_per_sample(inlink->format) <= 2 &&
+ av_get_bytes_per_sample(outlink->format) <= 2)
+ av_opt_set_int(s->avr, "internal_sample_fmt", AV_SAMPLE_FMT_S16P, 0);
+
+ if ((ret = avresample_open(s->avr)) < 0)
+ return ret;
+
+ outlink->time_base = (AVRational){ 1, outlink->sample_rate };
+ s->next_pts = AV_NOPTS_VALUE;
+
+ av_get_channel_layout_string(buf1, sizeof(buf1),
+ -1, inlink ->channel_layout);
+ av_get_channel_layout_string(buf2, sizeof(buf2),
+ -1, outlink->channel_layout);
+ av_log(ctx, AV_LOG_VERBOSE,
+ "fmt:%s srate:%d cl:%s -> fmt:%s srate:%d cl:%s\n",
+ av_get_sample_fmt_name(inlink ->format), inlink ->sample_rate, buf1,
+ av_get_sample_fmt_name(outlink->format), outlink->sample_rate, buf2);
+
+ return 0;
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+ AVFilterContext *ctx = outlink->src;
+ ResampleContext *s = ctx->priv;
+ int ret = ff_request_frame(ctx->inputs[0]);
+
+ /* flush the lavr delay buffer */
+ if (ret == AVERROR_EOF && s->avr) {
+ AVFilterBufferRef *buf;
+ int nb_samples = av_rescale_rnd(avresample_get_delay(s->avr),
+ outlink->sample_rate,
+ ctx->inputs[0]->sample_rate,
+ AV_ROUND_UP);
+
+ if (!nb_samples)
+ return ret;
+
+ buf = ff_get_audio_buffer(outlink, AV_PERM_WRITE, nb_samples);
+ if (!buf)
+ return AVERROR(ENOMEM);
+
+ ret = avresample_convert(s->avr, (void**)buf->extended_data,
+ buf->linesize[0], nb_samples,
+ NULL, 0, 0);
+ if (ret <= 0) {
+ avfilter_unref_buffer(buf);
+ return (ret == 0) ? AVERROR_EOF : ret;
+ }
+
+ buf->pts = s->next_pts;
+ ff_filter_samples(outlink, buf);
+ return 0;
+ }
+ return ret;
+}
+
+static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
+{
+ AVFilterContext *ctx = inlink->dst;
+ ResampleContext *s = ctx->priv;
+ AVFilterLink *outlink = ctx->outputs[0];
+
+ if (s->avr) {
+ AVFilterBufferRef *buf_out;
+ int delay, nb_samples, ret;
+
+ /* maximum possible samples lavr can output */
+ delay = avresample_get_delay(s->avr);
+ nb_samples = av_rescale_rnd(buf->audio->nb_samples + delay,
+ outlink->sample_rate, inlink->sample_rate,
+ AV_ROUND_UP);
+
+ buf_out = ff_get_audio_buffer(outlink, AV_PERM_WRITE, nb_samples);
+ ret = avresample_convert(s->avr, (void**)buf_out->extended_data,
+ buf_out->linesize[0], nb_samples,
+ (void**)buf->extended_data, buf->linesize[0],
+ buf->audio->nb_samples);
+
+ av_assert0(!avresample_available(s->avr));
+
+ if (s->next_pts == AV_NOPTS_VALUE) {
+ if (buf->pts == AV_NOPTS_VALUE) {
+ av_log(ctx, AV_LOG_WARNING, "First timestamp is missing, "
+ "assuming 0.\n");
+ s->next_pts = 0;
+ } else
+ s->next_pts = av_rescale_q(buf->pts, inlink->time_base,
+ outlink->time_base);
+ }
+
+ if (ret > 0) {
+ buf_out->audio->nb_samples = ret;
+ if (buf->pts != AV_NOPTS_VALUE) {
+ buf_out->pts = av_rescale_q(buf->pts, inlink->time_base,
+ outlink->time_base) -
+ av_rescale(delay, outlink->sample_rate,
+ inlink->sample_rate);
+ } else
+ buf_out->pts = s->next_pts;
+
+ s->next_pts = buf_out->pts + buf_out->audio->nb_samples;
+
+ ff_filter_samples(outlink, buf_out);
+ }
+ avfilter_unref_buffer(buf);
+ } else
+ ff_filter_samples(outlink, buf);
+}
+
+AVFilter avfilter_af_resample = {
+ .name = "resample",
+ .description = NULL_IF_CONFIG_SMALL("Audio resampling and conversion."),
+ .priv_size = sizeof(ResampleContext),
+
+ .uninit = uninit,
+ .query_formats = query_formats,
+
+ .inputs = (const AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .filter_samples = filter_samples,
+ .min_perms = AV_PERM_READ },
+ { .name = NULL}},
+ .outputs = (const AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .config_props = config_output,
+ .request_frame = request_frame },
+ { .name = NULL}},
+};
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index ba66941..9c22b4f 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -34,7 +34,16 @@ void avfilter_register_all(void)
return;
initialized = 1;
+ REGISTER_FILTER (AFIFO, afifo, af);
+ REGISTER_FILTER (AFORMAT, aformat, af);
+ REGISTER_FILTER (AMIX, amix, af);
REGISTER_FILTER (ANULL, anull, af);
+ REGISTER_FILTER (ASPLIT, asplit, af);
+ REGISTER_FILTER (ASYNCTS, asyncts, af);
+ REGISTER_FILTER (CHANNELMAP, channelmap, af);
+ REGISTER_FILTER (CHANNELSPLIT,channelsplit,af);
+ REGISTER_FILTER (JOIN, join, af);
+ REGISTER_FILTER (RESAMPLE, resample, af);
REGISTER_FILTER (ANULLSRC, anullsrc, asrc);
@@ -52,6 +61,7 @@ void avfilter_register_all(void)
REGISTER_FILTER (FIELDORDER, fieldorder, vf);
REGISTER_FILTER (FIFO, fifo, vf);
REGISTER_FILTER (FORMAT, format, vf);
+ REGISTER_FILTER (FPS, fps, vf);
REGISTER_FILTER (FREI0R, frei0r, vf);
REGISTER_FILTER (GRADFUN, gradfun, vf);
REGISTER_FILTER (HFLIP, hflip, vf);
@@ -89,9 +99,22 @@ void avfilter_register_all(void)
REGISTER_FILTER (NULLSINK, nullsink, vsink);
- /* vsrc_buffer is a part of public API => registered unconditionally */
+ /* those filters are part of public or internal API => registered
+ * unconditionally */
{
extern AVFilter avfilter_vsrc_buffer;
avfilter_register(&avfilter_vsrc_buffer);
}
+ {
+ extern AVFilter avfilter_asrc_abuffer;
+ avfilter_register(&avfilter_asrc_abuffer);
+ }
+ {
+ extern AVFilter avfilter_vsink_buffer;
+ avfilter_register(&avfilter_vsink_buffer);
+ }
+ {
+ extern AVFilter avfilter_asink_abuffer;
+ avfilter_register(&avfilter_asink_abuffer);
+ }
}
diff --git a/libavfilter/asink_anullsink.c b/libavfilter/asink_anullsink.c
index 3a505e7..b527850 100644
--- a/libavfilter/asink_anullsink.c
+++ b/libavfilter/asink_anullsink.c
@@ -17,6 +17,7 @@
*/
#include "avfilter.h"
+#include "internal.h"
static void null_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref) { }
diff --git a/libavfilter/asrc_anullsrc.c b/libavfilter/asrc_anullsrc.c
index 8e99012..c4339e9 100644
--- a/libavfilter/asrc_anullsrc.c
+++ b/libavfilter/asrc_anullsrc.c
@@ -22,6 +22,7 @@
*/
#include "avfilter.h"
+#include "internal.h"
#include "libavutil/audioconvert.h"
typedef struct {
@@ -29,7 +30,7 @@ typedef struct {
int64_t sample_rate;
} ANullContext;
-static int init(AVFilterContext *ctx, const char *args, void *opaque)
+static int init(AVFilterContext *ctx, const char *args)
{
ANullContext *priv = ctx->priv;
char channel_layout_str[128] = "";
@@ -67,7 +68,7 @@ static int config_props(AVFilterLink *outlink)
chans_nb = av_get_channel_layout_nb_channels(priv->channel_layout);
av_get_channel_layout_string(buf, sizeof(buf), chans_nb, priv->channel_layout);
- av_log(outlink->src, AV_LOG_INFO,
+ av_log(outlink->src, AV_LOG_VERBOSE,
"sample_rate:%"PRId64 " channel_layout:%"PRId64 " channel_layout_description:'%s'\n",
priv->sample_rate, priv->channel_layout, buf);
diff --git a/libavfilter/audio.c b/libavfilter/audio.c
new file mode 100644
index 0000000..1489608
--- /dev/null
+++ b/libavfilter/audio.c
@@ -0,0 +1,190 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/audioconvert.h"
+
+#include "audio.h"
+#include "avfilter.h"
+#include "internal.h"
+
+AVFilterBufferRef *ff_null_get_audio_buffer(AVFilterLink *link, int perms,
+ int nb_samples)
+{
+ return ff_get_audio_buffer(link->dst->outputs[0], perms, nb_samples);
+}
+
+AVFilterBufferRef *ff_default_get_audio_buffer(AVFilterLink *link, int perms,
+ int nb_samples)
+{
+ AVFilterBufferRef *samplesref = NULL;
+ uint8_t **data;
+ int planar = av_sample_fmt_is_planar(link->format);
+ int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout);
+ int planes = planar ? nb_channels : 1;
+ int linesize;
+
+ if (!(data = av_mallocz(sizeof(*data) * planes)))
+ goto fail;
+
+ if (av_samples_alloc(data, &linesize, nb_channels, nb_samples, link->format, 0) < 0)
+ goto fail;
+
+ samplesref = avfilter_get_audio_buffer_ref_from_arrays(data, linesize, perms,
+ nb_samples, link->format,
+ link->channel_layout);
+ if (!samplesref)
+ goto fail;
+
+ av_freep(&data);
+
+fail:
+ if (data)
+ av_freep(&data[0]);
+ av_freep(&data);
+ return samplesref;
+}
+
+AVFilterBufferRef *ff_get_audio_buffer(AVFilterLink *link, int perms,
+ int nb_samples)
+{
+ AVFilterBufferRef *ret = NULL;
+
+ if (link->dstpad->get_audio_buffer)
+ ret = link->dstpad->get_audio_buffer(link, perms, nb_samples);
+
+ if (!ret)
+ ret = ff_default_get_audio_buffer(link, perms, nb_samples);
+
+ if (ret)
+ ret->type = AVMEDIA_TYPE_AUDIO;
+
+ return ret;
+}
+
+AVFilterBufferRef* avfilter_get_audio_buffer_ref_from_arrays(uint8_t **data,
+ int linesize,int perms,
+ int nb_samples,
+ enum AVSampleFormat sample_fmt,
+ uint64_t channel_layout)
+{
+ int planes;
+ AVFilterBuffer *samples = av_mallocz(sizeof(*samples));
+ AVFilterBufferRef *samplesref = av_mallocz(sizeof(*samplesref));
+
+ if (!samples || !samplesref)
+ goto fail;
+
+ samplesref->buf = samples;
+ samplesref->buf->free = ff_avfilter_default_free_buffer;
+ if (!(samplesref->audio = av_mallocz(sizeof(*samplesref->audio))))
+ goto fail;
+
+ samplesref->audio->nb_samples = nb_samples;
+ samplesref->audio->channel_layout = channel_layout;
+ samplesref->audio->planar = av_sample_fmt_is_planar(sample_fmt);
+
+ planes = samplesref->audio->planar ? av_get_channel_layout_nb_channels(channel_layout) : 1;
+
+ /* make sure the buffer gets read permission or it's useless for output */
+ samplesref->perms = perms | AV_PERM_READ;
+
+ samples->refcount = 1;
+ samplesref->type = AVMEDIA_TYPE_AUDIO;
+ samplesref->format = sample_fmt;
+
+ memcpy(samples->data, data,
+ FFMIN(FF_ARRAY_ELEMS(samples->data), planes)*sizeof(samples->data[0]));
+ memcpy(samplesref->data, samples->data, sizeof(samples->data));
+
+ samples->linesize[0] = samplesref->linesize[0] = linesize;
+
+ if (planes > FF_ARRAY_ELEMS(samples->data)) {
+ samples-> extended_data = av_mallocz(sizeof(*samples->extended_data) *
+ planes);
+ samplesref->extended_data = av_mallocz(sizeof(*samplesref->extended_data) *
+ planes);
+
+ if (!samples->extended_data || !samplesref->extended_data)
+ goto fail;
+
+ memcpy(samples-> extended_data, data, sizeof(*data)*planes);
+ memcpy(samplesref->extended_data, data, sizeof(*data)*planes);
+ } else {
+ samples->extended_data = samples->data;
+ samplesref->extended_data = samplesref->data;
+ }
+
+ samplesref->pts = AV_NOPTS_VALUE;
+
+ return samplesref;
+
+fail:
+ if (samples && samples->extended_data != samples->data)
+ av_freep(&samples->extended_data);
+ if (samplesref) {
+ av_freep(&samplesref->audio);
+ if (samplesref->extended_data != samplesref->data)
+ av_freep(&samplesref->extended_data);
+ }
+ av_freep(&samplesref);
+ av_freep(&samples);
+ return NULL;
+}
+
+static void default_filter_samples(AVFilterLink *link,
+ AVFilterBufferRef *samplesref)
+{
+ ff_filter_samples(link->dst->outputs[0], samplesref);
+}
+
+void ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
+{
+ void (*filter_samples)(AVFilterLink *, AVFilterBufferRef *);
+ AVFilterPad *dst = link->dstpad;
+ AVFilterBufferRef *buf_out;
+
+ FF_DPRINTF_START(NULL, filter_samples); ff_dlog_link(NULL, link, 1);
+
+ if (!(filter_samples = dst->filter_samples))
+ filter_samples = default_filter_samples;
+
+ /* prepare to copy the samples if the buffer has insufficient permissions */
+ if ((dst->min_perms & samplesref->perms) != dst->min_perms ||
+ dst->rej_perms & samplesref->perms) {
+ av_log(link->dst, AV_LOG_DEBUG,
+ "Copying audio data in avfilter (have perms %x, need %x, reject %x)\n",
+ samplesref->perms, link->dstpad->min_perms, link->dstpad->rej_perms);
+
+ buf_out = ff_default_get_audio_buffer(link, dst->min_perms,
+ samplesref->audio->nb_samples);
+ buf_out->pts = samplesref->pts;
+ buf_out->audio->sample_rate = samplesref->audio->sample_rate;
+
+ /* Copy actual data into new samples buffer */
+ av_samples_copy(buf_out->extended_data, samplesref->extended_data,
+ 0, 0, samplesref->audio->nb_samples,
+ av_get_channel_layout_nb_channels(link->channel_layout),
+ link->format);
+
+ avfilter_unref_buffer(samplesref);
+ } else
+ buf_out = samplesref;
+
+ filter_samples(link, buf_out);
+}
+
diff --git a/libavfilter/audio.h b/libavfilter/audio.h
new file mode 100644
index 0000000..9af44f8
--- /dev/null
+++ b/libavfilter/audio.h
@@ -0,0 +1,55 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVFILTER_AUDIO_H
+#define AVFILTER_AUDIO_H
+
+#include "avfilter.h"
+
+/** default handler for get_audio_buffer() for audio inputs */
+AVFilterBufferRef *ff_default_get_audio_buffer(AVFilterLink *link, int perms,
+ int nb_samples);
+
+/** get_audio_buffer() handler for filters which simply pass audio along */
+AVFilterBufferRef *ff_null_get_audio_buffer(AVFilterLink *link, int perms,
+ int nb_samples);
+
+/**
+ * Request an audio samples buffer with a specific set of permissions.
+ *
+ * @param link the output link to the filter from which the buffer will
+ * be requested
+ * @param perms the required access permissions
+ * @param nb_samples the number of samples per channel
+ * @return A reference to the samples. This must be unreferenced with
+ * avfilter_unref_buffer when you are finished with it.
+ */
+AVFilterBufferRef *ff_get_audio_buffer(AVFilterLink *link, int perms,
+ int nb_samples);
+
+/**
+ * Send a buffer of audio samples to the next filter.
+ *
+ * @param link the output link over which the audio samples are being sent
+ * @param samplesref a reference to the buffer of audio samples being sent. The
+ * receiving filter will free this reference when it no longer
+ * needs it or pass it on to the next filter.
+ */
+void ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref);
+
+#endif /* AVFILTER_AUDIO_H */
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index d426591..dc82815 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -24,9 +24,9 @@
#include "libavutil/pixdesc.h"
#include "libavutil/rational.h"
#include "libavutil/audioconvert.h"
-#include "libavutil/imgutils.h"
-#include "libavcodec/avcodec.h"
+
#include "avfilter.h"
+#include "formats.h"
#include "internal.h"
unsigned avfilter_version(void) {
@@ -44,46 +44,9 @@ const char *avfilter_license(void)
return LICENSE_PREFIX LIBAV_LICENSE + sizeof(LICENSE_PREFIX) - 1;
}
-AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask)
-{
- AVFilterBufferRef *ret = av_malloc(sizeof(AVFilterBufferRef));
- if (!ret)
- return NULL;
- *ret = *ref;
- if (ref->type == AVMEDIA_TYPE_VIDEO) {
- ret->video = av_malloc(sizeof(AVFilterBufferRefVideoProps));
- if (!ret->video) {
- av_free(ret);
- return NULL;
- }
- *ret->video = *ref->video;
- } else if (ref->type == AVMEDIA_TYPE_AUDIO) {
- ret->audio = av_malloc(sizeof(AVFilterBufferRefAudioProps));
- if (!ret->audio) {
- av_free(ret);
- return NULL;
- }
- *ret->audio = *ref->audio;
- }
- ret->perms &= pmask;
- ret->buf->refcount ++;
- return ret;
-}
-
-void avfilter_unref_buffer(AVFilterBufferRef *ref)
-{
- if (!ref)
- return;
- if (!(--ref->buf->refcount))
- ref->buf->free(ref->buf);
- av_free(ref->video);
- av_free(ref->audio);
- av_free(ref);
-}
-
-void avfilter_insert_pad(unsigned idx, unsigned *count, size_t padidx_off,
- AVFilterPad **pads, AVFilterLink ***links,
- AVFilterPad *newpad)
+void ff_insert_pad(unsigned idx, unsigned *count, size_t padidx_off,
+ AVFilterPad **pads, AVFilterLink ***links,
+ AVFilterPad *newpad)
{
unsigned i;
@@ -107,8 +70,8 @@ int avfilter_link(AVFilterContext *src, unsigned srcpad,
{
AVFilterLink *link;
- if (src->output_count <= srcpad || dst->input_count <= dstpad ||
- src->outputs[srcpad] || dst->inputs[dstpad])
+ if (src->nb_outputs <= srcpad || dst->nb_inputs <= dstpad ||
+ src->outputs[srcpad] || dst->inputs[dstpad])
return -1;
if (src->output_pads[srcpad].type != dst->input_pads[dstpad].type) {
@@ -138,7 +101,7 @@ int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
int ret;
unsigned dstpad_idx = link->dstpad - link->dst->input_pads;
- av_log(link->dst, AV_LOG_INFO, "auto-inserting filter '%s' "
+ av_log(link->dst, AV_LOG_VERBOSE, "auto-inserting filter '%s' "
"between the filter '%s' and the filter '%s'\n",
filt->name, link->src->name, link->dst->name);
@@ -157,8 +120,14 @@ int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
/* if any information on supported media formats already exists on the
* link, we need to preserve that */
if (link->out_formats)
- avfilter_formats_changeref(&link->out_formats,
+ ff_formats_changeref(&link->out_formats,
&filt->outputs[filt_dstpad_idx]->out_formats);
+ if (link->out_samplerates)
+ ff_formats_changeref(&link->out_samplerates,
+ &filt->outputs[filt_dstpad_idx]->out_samplerates);
+ if (link->out_channel_layouts)
+ ff_channel_layouts_changeref(&link->out_channel_layouts,
+ &filt->outputs[filt_dstpad_idx]->out_channel_layouts);
return 0;
}
@@ -169,7 +138,7 @@ int avfilter_config_links(AVFilterContext *filter)
unsigned i;
int ret;
- for (i = 0; i < filter->input_count; i ++) {
+ for (i = 0; i < filter->nb_inputs; i ++) {
AVFilterLink *link = filter->inputs[i];
if (!link) continue;
@@ -186,28 +155,50 @@ int avfilter_config_links(AVFilterContext *filter)
if ((ret = avfilter_config_links(link->src)) < 0)
return ret;
- if (!(config_link = link->srcpad->config_props))
- config_link = avfilter_default_config_output_link;
- if ((ret = config_link(link)) < 0)
+ if (!(config_link = link->srcpad->config_props)) {
+ if (link->src->nb_inputs != 1) {
+ av_log(link->src, AV_LOG_ERROR, "Source filters and filters "
+ "with more than one input "
+ "must set config_props() "
+ "callbacks on all outputs\n");
+ return AVERROR(EINVAL);
+ }
+ } else if ((ret = config_link(link)) < 0) {
+ av_log(link->src, AV_LOG_ERROR,
+ "Failed to configure output pad on %s\n",
+ link->src->name);
return ret;
+ }
if (link->time_base.num == 0 && link->time_base.den == 0)
- link->time_base = link->src && link->src->input_count ?
+ link->time_base = link->src && link->src->nb_inputs ?
link->src->inputs[0]->time_base : AV_TIME_BASE_Q;
- if (link->sample_aspect_ratio.num == 0 && link->sample_aspect_ratio.den == 0)
- link->sample_aspect_ratio = link->src->input_count ?
- link->src->inputs[0]->sample_aspect_ratio : (AVRational){1,1};
-
- if (link->sample_rate == 0 && link->src && link->src->input_count)
- link->sample_rate = link->src->inputs[0]->sample_rate;
-
- if (link->channel_layout == 0 && link->src && link->src->input_count)
- link->channel_layout = link->src->inputs[0]->channel_layout;
+ if (link->type == AVMEDIA_TYPE_VIDEO) {
+ if (!link->sample_aspect_ratio.num && !link->sample_aspect_ratio.den)
+ link->sample_aspect_ratio = link->src->nb_inputs ?
+ link->src->inputs[0]->sample_aspect_ratio : (AVRational){1,1};
+
+ if (link->src->nb_inputs) {
+ if (!link->w)
+ link->w = link->src->inputs[0]->w;
+ if (!link->h)
+ link->h = link->src->inputs[0]->h;
+ } else if (!link->w || !link->h) {
+ av_log(link->src, AV_LOG_ERROR,
+ "Video source filters must set their output link's "
+ "width and height\n");
+ return AVERROR(EINVAL);
+ }
+ }
if ((config_link = link->dstpad->config_props))
- if ((ret = config_link(link)) < 0)
+ if ((ret = config_link(link)) < 0) {
+ av_log(link->src, AV_LOG_ERROR,
+ "Failed to configure input pad on %s\n",
+ link->dst->name);
return ret;
+ }
link->init_state = AVLINK_INIT;
}
@@ -216,51 +207,7 @@ int avfilter_config_links(AVFilterContext *filter)
return 0;
}
-#ifdef DEBUG
-static char *ff_get_ref_perms_string(char *buf, size_t buf_size, int perms)
-{
- snprintf(buf, buf_size, "%s%s%s%s%s%s",
- perms & AV_PERM_READ ? "r" : "",
- perms & AV_PERM_WRITE ? "w" : "",
- perms & AV_PERM_PRESERVE ? "p" : "",
- perms & AV_PERM_REUSE ? "u" : "",
- perms & AV_PERM_REUSE2 ? "U" : "",
- perms & AV_PERM_NEG_LINESIZES ? "n" : "");
- return buf;
-}
-#endif
-
-static void ff_dlog_ref(void *ctx, AVFilterBufferRef *ref, int end)
-{
- av_unused char buf[16];
- av_dlog(ctx,
- "ref[%p buf:%p refcount:%d perms:%s data:%p linesize[%d, %d, %d, %d] pts:%"PRId64" pos:%"PRId64,
- ref, ref->buf, ref->buf->refcount, ff_get_ref_perms_string(buf, sizeof(buf), ref->perms), ref->data[0],
- ref->linesize[0], ref->linesize[1], ref->linesize[2], ref->linesize[3],
- ref->pts, ref->pos);
-
- if (ref->video) {
- av_dlog(ctx, " a:%d/%d s:%dx%d i:%c iskey:%d type:%c",
- ref->video->pixel_aspect.num, ref->video->pixel_aspect.den,
- ref->video->w, ref->video->h,
- !ref->video->interlaced ? 'P' : /* Progressive */
- ref->video->top_field_first ? 'T' : 'B', /* Top / Bottom */
- ref->video->key_frame,
- av_get_picture_type_char(ref->video->pict_type));
- }
- if (ref->audio) {
- av_dlog(ctx, " cl:%"PRId64"d sn:%d s:%d sr:%d p:%d",
- ref->audio->channel_layout,
- ref->audio->nb_samples,
- ref->audio->size,
- ref->audio->sample_rate,
- ref->audio->planar);
- }
-
- av_dlog(ctx, "]%s", end ? "\n" : "");
-}
-
-static void ff_dlog_link(void *ctx, AVFilterLink *link, int end)
+void ff_dlog_link(void *ctx, AVFilterLink *link, int end)
{
if (link->type == AVMEDIA_TYPE_VIDEO) {
av_dlog(ctx,
@@ -284,243 +231,35 @@ static void ff_dlog_link(void *ctx, AVFilterLink *link, int end)
}
}
-#define FF_DPRINTF_START(ctx, func) av_dlog(NULL, "%-16s: ", #func)
-
-AVFilterBufferRef *avfilter_get_video_buffer(AVFilterLink *link, int perms, int w, int h)
-{
- AVFilterBufferRef *ret = NULL;
-
- av_unused char buf[16];
- FF_DPRINTF_START(NULL, get_video_buffer); ff_dlog_link(NULL, link, 0);
- av_dlog(NULL, " perms:%s w:%d h:%d\n", ff_get_ref_perms_string(buf, sizeof(buf), perms), w, h);
-
- if (link->dstpad->get_video_buffer)
- ret = link->dstpad->get_video_buffer(link, perms, w, h);
-
- if (!ret)
- ret = avfilter_default_get_video_buffer(link, perms, w, h);
-
- if (ret)
- ret->type = AVMEDIA_TYPE_VIDEO;
-
- FF_DPRINTF_START(NULL, get_video_buffer); ff_dlog_link(NULL, link, 0); av_dlog(NULL, " returning "); ff_dlog_ref(NULL, ret, 1);
-
- return ret;
-}
-
-AVFilterBufferRef *
-avfilter_get_video_buffer_ref_from_arrays(uint8_t *data[4], int linesize[4], int perms,
- int w, int h, enum PixelFormat format)
-{
- AVFilterBuffer *pic = av_mallocz(sizeof(AVFilterBuffer));
- AVFilterBufferRef *picref = av_mallocz(sizeof(AVFilterBufferRef));
-
- if (!pic || !picref)
- goto fail;
-
- picref->buf = pic;
- picref->buf->free = ff_avfilter_default_free_buffer;
- if (!(picref->video = av_mallocz(sizeof(AVFilterBufferRefVideoProps))))
- goto fail;
-
- pic->w = picref->video->w = w;
- pic->h = picref->video->h = h;
-
- /* make sure the buffer gets read permission or it's useless for output */
- picref->perms = perms | AV_PERM_READ;
-
- pic->refcount = 1;
- picref->type = AVMEDIA_TYPE_VIDEO;
- pic->format = picref->format = format;
-
- memcpy(pic->data, data, 4*sizeof(data[0]));
- memcpy(pic->linesize, linesize, 4*sizeof(linesize[0]));
- memcpy(picref->data, pic->data, sizeof(picref->data));
- memcpy(picref->linesize, pic->linesize, sizeof(picref->linesize));
-
- return picref;
-
-fail:
- if (picref && picref->video)
- av_free(picref->video);
- av_free(picref);
- av_free(pic);
- return NULL;
-}
-
-AVFilterBufferRef *avfilter_get_audio_buffer(AVFilterLink *link, int perms,
- enum AVSampleFormat sample_fmt, int size,
- uint64_t channel_layout, int planar)
-{
- AVFilterBufferRef *ret = NULL;
-
- if (link->dstpad->get_audio_buffer)
- ret = link->dstpad->get_audio_buffer(link, perms, sample_fmt, size, channel_layout, planar);
-
- if (!ret)
- ret = avfilter_default_get_audio_buffer(link, perms, sample_fmt, size, channel_layout, planar);
-
- if (ret)
- ret->type = AVMEDIA_TYPE_AUDIO;
-
- return ret;
-}
-
-int avfilter_request_frame(AVFilterLink *link)
+int ff_request_frame(AVFilterLink *link)
{
FF_DPRINTF_START(NULL, request_frame); ff_dlog_link(NULL, link, 1);
if (link->srcpad->request_frame)
return link->srcpad->request_frame(link);
else if (link->src->inputs[0])
- return avfilter_request_frame(link->src->inputs[0]);
+ return ff_request_frame(link->src->inputs[0]);
else return -1;
}
-int avfilter_poll_frame(AVFilterLink *link)
+int ff_poll_frame(AVFilterLink *link)
{
int i, min = INT_MAX;
if (link->srcpad->poll_frame)
return link->srcpad->poll_frame(link);
- for (i = 0; i < link->src->input_count; i++) {
+ for (i = 0; i < link->src->nb_inputs; i++) {
int val;
if (!link->src->inputs[i])
return -1;
- val = avfilter_poll_frame(link->src->inputs[i]);
+ val = ff_poll_frame(link->src->inputs[i]);
min = FFMIN(min, val);
}
return min;
}
-/* XXX: should we do the duplicating of the picture ref here, instead of
- * forcing the source filter to do it? */
-void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
-{
- void (*start_frame)(AVFilterLink *, AVFilterBufferRef *);
- AVFilterPad *dst = link->dstpad;
- int perms = picref->perms;
-
- FF_DPRINTF_START(NULL, start_frame); ff_dlog_link(NULL, link, 0); av_dlog(NULL, " "); ff_dlog_ref(NULL, picref, 1);
-
- if (!(start_frame = dst->start_frame))
- start_frame = avfilter_default_start_frame;
-
- if (picref->linesize[0] < 0)
- perms |= AV_PERM_NEG_LINESIZES;
- /* prepare to copy the picture if it has insufficient permissions */
- if ((dst->min_perms & perms) != dst->min_perms || dst->rej_perms & perms) {
- av_log(link->dst, AV_LOG_DEBUG,
- "frame copy needed (have perms %x, need %x, reject %x)\n",
- picref->perms,
- link->dstpad->min_perms, link->dstpad->rej_perms);
-
- link->cur_buf = avfilter_get_video_buffer(link, dst->min_perms, link->w, link->h);
- link->src_buf = picref;
- avfilter_copy_buffer_ref_props(link->cur_buf, link->src_buf);
- }
- else
- link->cur_buf = picref;
-
- start_frame(link, link->cur_buf);
-}
-
-void avfilter_end_frame(AVFilterLink *link)
-{
- void (*end_frame)(AVFilterLink *);
-
- if (!(end_frame = link->dstpad->end_frame))
- end_frame = avfilter_default_end_frame;
-
- end_frame(link);
-
- /* unreference the source picture if we're feeding the destination filter
- * a copied version dues to permission issues */
- if (link->src_buf) {
- avfilter_unref_buffer(link->src_buf);
- link->src_buf = NULL;
- }
-}
-
-void avfilter_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
-{
- uint8_t *src[4], *dst[4];
- int i, j, vsub;
- void (*draw_slice)(AVFilterLink *, int, int, int);
-
- FF_DPRINTF_START(NULL, draw_slice); ff_dlog_link(NULL, link, 0); av_dlog(NULL, " y:%d h:%d dir:%d\n", y, h, slice_dir);
-
- /* copy the slice if needed for permission reasons */
- if (link->src_buf) {
- vsub = av_pix_fmt_descriptors[link->format].log2_chroma_h;
-
- for (i = 0; i < 4; i++) {
- if (link->src_buf->data[i]) {
- src[i] = link->src_buf-> data[i] +
- (y >> (i==1 || i==2 ? vsub : 0)) * link->src_buf-> linesize[i];
- dst[i] = link->cur_buf->data[i] +
- (y >> (i==1 || i==2 ? vsub : 0)) * link->cur_buf->linesize[i];
- } else
- src[i] = dst[i] = NULL;
- }
-
- for (i = 0; i < 4; i++) {
- int planew =
- av_image_get_linesize(link->format, link->cur_buf->video->w, i);
-
- if (!src[i]) continue;
-
- for (j = 0; j < h >> (i==1 || i==2 ? vsub : 0); j++) {
- memcpy(dst[i], src[i], planew);
- src[i] += link->src_buf->linesize[i];
- dst[i] += link->cur_buf->linesize[i];
- }
- }
- }
-
- if (!(draw_slice = link->dstpad->draw_slice))
- draw_slice = avfilter_default_draw_slice;
- draw_slice(link, y, h, slice_dir);
-}
-
-void avfilter_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
-{
- void (*filter_samples)(AVFilterLink *, AVFilterBufferRef *);
- AVFilterPad *dst = link->dstpad;
-
- FF_DPRINTF_START(NULL, filter_samples); ff_dlog_link(NULL, link, 1);
-
- if (!(filter_samples = dst->filter_samples))
- filter_samples = avfilter_default_filter_samples;
-
- /* prepare to copy the samples if the buffer has insufficient permissions */
- if ((dst->min_perms & samplesref->perms) != dst->min_perms ||
- dst->rej_perms & samplesref->perms) {
-
- av_log(link->dst, AV_LOG_DEBUG,
- "Copying audio data in avfilter (have perms %x, need %x, reject %x)\n",
- samplesref->perms, link->dstpad->min_perms, link->dstpad->rej_perms);
-
- link->cur_buf = avfilter_default_get_audio_buffer(link, dst->min_perms,
- samplesref->format,
- samplesref->audio->size,
- samplesref->audio->channel_layout,
- samplesref->audio->planar);
- link->cur_buf->pts = samplesref->pts;
- link->cur_buf->audio->sample_rate = samplesref->audio->sample_rate;
-
- /* Copy actual data into new samples buffer */
- memcpy(link->cur_buf->data[0], samplesref->data[0], samplesref->audio->size);
-
- avfilter_unref_buffer(samplesref);
- } else
- link->cur_buf = samplesref;
-
- filter_samples(link, link->cur_buf);
-}
-
#define MAX_REGISTERED_AVFILTERS_NB 64
static AVFilter *registered_avfilters[MAX_REGISTERED_AVFILTERS_NB + 1];
@@ -600,27 +339,31 @@ int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *in
goto err;
}
- ret->input_count = pad_count(filter->inputs);
- if (ret->input_count) {
- ret->input_pads = av_malloc(sizeof(AVFilterPad) * ret->input_count);
+ ret->nb_inputs = pad_count(filter->inputs);
+ if (ret->nb_inputs ) {
+ ret->input_pads = av_malloc(sizeof(AVFilterPad) * ret->nb_inputs);
if (!ret->input_pads)
goto err;
- memcpy(ret->input_pads, filter->inputs, sizeof(AVFilterPad) * ret->input_count);
- ret->inputs = av_mallocz(sizeof(AVFilterLink*) * ret->input_count);
+ memcpy(ret->input_pads, filter->inputs, sizeof(AVFilterPad) * ret->nb_inputs);
+ ret->inputs = av_mallocz(sizeof(AVFilterLink*) * ret->nb_inputs);
if (!ret->inputs)
goto err;
}
- ret->output_count = pad_count(filter->outputs);
- if (ret->output_count) {
- ret->output_pads = av_malloc(sizeof(AVFilterPad) * ret->output_count);
+ ret->nb_outputs = pad_count(filter->outputs);
+ if (ret->nb_outputs) {
+ ret->output_pads = av_malloc(sizeof(AVFilterPad) * ret->nb_outputs);
if (!ret->output_pads)
goto err;
- memcpy(ret->output_pads, filter->outputs, sizeof(AVFilterPad) * ret->output_count);
- ret->outputs = av_mallocz(sizeof(AVFilterLink*) * ret->output_count);
+ memcpy(ret->output_pads, filter->outputs, sizeof(AVFilterPad) * ret->nb_outputs);
+ ret->outputs = av_mallocz(sizeof(AVFilterLink*) * ret->nb_outputs);
if (!ret->outputs)
goto err;
}
+#if FF_API_FOO_COUNT
+ ret->output_count = ret->nb_outputs;
+ ret->input_count = ret->nb_inputs;
+#endif
*filter_ctx = ret;
return 0;
@@ -628,10 +371,10 @@ int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *in
err:
av_freep(&ret->inputs);
av_freep(&ret->input_pads);
- ret->input_count = 0;
+ ret->nb_inputs = 0;
av_freep(&ret->outputs);
av_freep(&ret->output_pads);
- ret->output_count = 0;
+ ret->nb_outputs = 0;
av_freep(&ret->priv);
av_free(ret);
return AVERROR(ENOMEM);
@@ -645,21 +388,29 @@ void avfilter_free(AVFilterContext *filter)
if (filter->filter->uninit)
filter->filter->uninit(filter);
- for (i = 0; i < filter->input_count; i++) {
+ for (i = 0; i < filter->nb_inputs; i++) {
if ((link = filter->inputs[i])) {
if (link->src)
link->src->outputs[link->srcpad - link->src->output_pads] = NULL;
- avfilter_formats_unref(&link->in_formats);
- avfilter_formats_unref(&link->out_formats);
+ ff_formats_unref(&link->in_formats);
+ ff_formats_unref(&link->out_formats);
+ ff_formats_unref(&link->in_samplerates);
+ ff_formats_unref(&link->out_samplerates);
+ ff_channel_layouts_unref(&link->in_channel_layouts);
+ ff_channel_layouts_unref(&link->out_channel_layouts);
}
av_freep(&link);
}
- for (i = 0; i < filter->output_count; i++) {
+ for (i = 0; i < filter->nb_outputs; i++) {
if ((link = filter->outputs[i])) {
if (link->dst)
link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL;
- avfilter_formats_unref(&link->in_formats);
- avfilter_formats_unref(&link->out_formats);
+ ff_formats_unref(&link->in_formats);
+ ff_formats_unref(&link->out_formats);
+ ff_formats_unref(&link->in_samplerates);
+ ff_formats_unref(&link->out_samplerates);
+ ff_channel_layouts_unref(&link->in_channel_layouts);
+ ff_channel_layouts_unref(&link->out_channel_layouts);
}
av_freep(&link);
}
@@ -678,25 +429,16 @@ int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque
int ret=0;
if (filter->filter->init)
- ret = filter->filter->init(filter, args, opaque);
+ ret = filter->filter->init(filter, args);
return ret;
}
-int avfilter_copy_frame_props(AVFilterBufferRef *dst, const AVFrame *src)
+const char *avfilter_pad_get_name(AVFilterPad *pads, int pad_idx)
{
- if (dst->type != AVMEDIA_TYPE_VIDEO)
- return AVERROR(EINVAL);
-
- dst->pts = src->pts;
- dst->format = src->format;
-
- dst->video->w = src->width;
- dst->video->h = src->height;
- dst->video->pixel_aspect = src->sample_aspect_ratio;
- dst->video->interlaced = src->interlaced_frame;
- dst->video->top_field_first = src->top_field_first;
- dst->video->key_frame = src->key_frame;
- dst->video->pict_type = src->pict_type;
+ return pads[pad_idx].name;
+}
- return 0;
+enum AVMediaType avfilter_pad_get_type(AVFilterPad *pads, int pad_idx)
+{
+ return pads[pad_idx].type;
}
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index 068c50b..aaf86e9 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -52,6 +52,7 @@ const char *avfilter_license(void);
typedef struct AVFilterContext AVFilterContext;
typedef struct AVFilterLink AVFilterLink;
typedef struct AVFilterPad AVFilterPad;
+typedef struct AVFilterFormats AVFilterFormats;
/**
* A reference-counted buffer data type used by the filter system. Filters
@@ -60,9 +61,23 @@ typedef struct AVFilterPad AVFilterPad;
*/
typedef struct AVFilterBuffer {
uint8_t *data[8]; ///< buffer data for each plane/channel
- int linesize[8]; ///< number of bytes per line
- unsigned refcount; ///< number of references to this buffer
+ /**
+ * pointers to the data planes/channels.
+ *
+ * For video, this should simply point to data[].
+ *
+ * For planar audio, each channel has a separate data pointer, and
+ * linesize[0] contains the size of each channel buffer.
+ * For packed audio, there is just one data pointer, and linesize[0]
+ * contains the total size of the buffer for all channels.
+ *
+ * Note: Both data and extended_data will always be set, but for planar
+ * audio with more channels that can fit in data, extended_data must be used
+ * in order to access all channels.
+ */
+ uint8_t **extended_data;
+ int linesize[8]; ///< number of bytes per line
/** private data to be used by a custom free function */
void *priv;
@@ -76,6 +91,7 @@ typedef struct AVFilterBuffer {
int format; ///< media format
int w, h; ///< width and height of the allocated buffer
+ unsigned refcount; ///< number of references to this buffer
} AVFilterBuffer;
#define AV_PERM_READ 0x01 ///< can read from the buffer
@@ -93,8 +109,7 @@ typedef struct AVFilterBuffer {
typedef struct AVFilterBufferRefAudioProps {
uint64_t channel_layout; ///< channel layout of audio buffer
int nb_samples; ///< number of audio samples
- int size; ///< audio buffer size
- uint32_t sample_rate; ///< audio buffer sample rate
+ int sample_rate; ///< audio buffer sample rate
int planar; ///< audio buffer - planar or packed
} AVFilterBufferRefAudioProps;
@@ -124,8 +139,25 @@ typedef struct AVFilterBufferRefVideoProps {
typedef struct AVFilterBufferRef {
AVFilterBuffer *buf; ///< the buffer that this is a reference to
uint8_t *data[8]; ///< picture/audio data for each plane
+ /**
+ * pointers to the data planes/channels.
+ *
+ * For video, this should simply point to data[].
+ *
+ * For planar audio, each channel has a separate data pointer, and
+ * linesize[0] contains the size of each channel buffer.
+ * For packed audio, there is just one data pointer, and linesize[0]
+ * contains the total size of the buffer for all channels.
+ *
+ * Note: Both data and extended_data will always be set, but for planar
+ * audio with more channels that can fit in data, extended_data must be used
+ * in order to access all channels.
+ */
+ uint8_t **extended_data;
int linesize[8]; ///< number of bytes per line
- int format; ///< media format
+
+ AVFilterBufferRefVideoProps *video; ///< video buffer specific properties
+ AVFilterBufferRefAudioProps *audio; ///< audio buffer specific properties
/**
* presentation timestamp. The time unit may change during
@@ -135,28 +167,17 @@ typedef struct AVFilterBufferRef {
int64_t pts;
int64_t pos; ///< byte position in stream, -1 if unknown
+ int format; ///< media format
+
int perms; ///< permissions, see the AV_PERM_* flags
enum AVMediaType type; ///< media type of buffer data
- AVFilterBufferRefVideoProps *video; ///< video buffer specific properties
- AVFilterBufferRefAudioProps *audio; ///< audio buffer specific properties
} AVFilterBufferRef;
/**
* Copy properties of src to dst, without copying the actual data
*/
-static inline void avfilter_copy_buffer_ref_props(AVFilterBufferRef *dst, AVFilterBufferRef *src)
-{
- // copy common properties
- dst->pts = src->pts;
- dst->pos = src->pos;
-
- switch (src->type) {
- case AVMEDIA_TYPE_VIDEO: *dst->video = *src->video; break;
- case AVMEDIA_TYPE_AUDIO: *dst->audio = *src->audio; break;
- default: break;
- }
-}
+void avfilter_copy_buffer_ref_props(AVFilterBufferRef *dst, AVFilterBufferRef *src);
/**
* Add a new reference to a buffer.
@@ -177,137 +198,14 @@ AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask);
*/
void avfilter_unref_buffer(AVFilterBufferRef *ref);
-/**
- * A list of supported formats for one end of a filter link. This is used
- * during the format negotiation process to try to pick the best format to
- * use to minimize the number of necessary conversions. Each filter gives a
- * list of the formats supported by each input and output pad. The list
- * given for each pad need not be distinct - they may be references to the
- * same list of formats, as is often the case when a filter supports multiple
- * formats, but will always output the same format as it is given in input.
- *
- * In this way, a list of possible input formats and a list of possible
- * output formats are associated with each link. When a set of formats is
- * negotiated over a link, the input and output lists are merged to form a
- * new list containing only the common elements of each list. In the case
- * that there were no common elements, a format conversion is necessary.
- * Otherwise, the lists are merged, and all other links which reference
- * either of the format lists involved in the merge are also affected.
- *
- * For example, consider the filter chain:
- * filter (a) --> (b) filter (b) --> (c) filter
- *
- * where the letters in parenthesis indicate a list of formats supported on
- * the input or output of the link. Suppose the lists are as follows:
- * (a) = {A, B}
- * (b) = {A, B, C}
- * (c) = {B, C}
- *
- * First, the first link's lists are merged, yielding:
- * filter (a) --> (a) filter (a) --> (c) filter
- *
- * Notice that format list (b) now refers to the same list as filter list (a).
- * Next, the lists for the second link are merged, yielding:
- * filter (a) --> (a) filter (a) --> (a) filter
- *
- * where (a) = {B}.
- *
- * Unfortunately, when the format lists at the two ends of a link are merged,
- * we must ensure that all links which reference either pre-merge format list
- * get updated as well. Therefore, we have the format list structure store a
- * pointer to each of the pointers to itself.
- */
-typedef struct AVFilterFormats {
- unsigned format_count; ///< number of formats
- int *formats; ///< list of media formats
-
- unsigned refcount; ///< number of references to this list
- struct AVFilterFormats ***refs; ///< references to this list
-} AVFilterFormats;
-
-/**
- * Create a list of supported formats. This is intended for use in
- * AVFilter->query_formats().
- *
- * @param fmts list of media formats, terminated by -1
- * @return the format list, with no existing references
- */
-AVFilterFormats *avfilter_make_format_list(const int *fmts);
-
-/**
- * Add fmt to the list of media formats contained in *avff.
- * If *avff is NULL the function allocates the filter formats struct
- * and puts its pointer in *avff.
- *
- * @return a non negative value in case of success, or a negative
- * value corresponding to an AVERROR code in case of error
- */
-int avfilter_add_format(AVFilterFormats **avff, int fmt);
-
-/**
- * Return a list of all formats supported by Libav for the given media type.
- */
-AVFilterFormats *avfilter_all_formats(enum AVMediaType type);
-
-/**
- * Return a format list which contains the intersection of the formats of
- * a and b. Also, all the references of a, all the references of b, and
- * a and b themselves will be deallocated.
- *
- * If a and b do not share any common formats, neither is modified, and NULL
- * is returned.
- */
-AVFilterFormats *avfilter_merge_formats(AVFilterFormats *a, AVFilterFormats *b);
-
-/**
- * Add *ref as a new reference to formats.
- * That is the pointers will point like in the ascii art below:
- * ________
- * |formats |<--------.
- * | ____ | ____|___________________
- * | |refs| | | __|_
- * | |* * | | | | | | AVFilterLink
- * | |* *--------->|*ref|
- * | |____| | | |____|
- * |________| |________________________
- */
-void avfilter_formats_ref(AVFilterFormats *formats, AVFilterFormats **ref);
-
-/**
- * If *ref is non-NULL, remove *ref as a reference to the format list
- * it currently points to, deallocates that list if this was the last
- * reference, and sets *ref to NULL.
- *
- * Before After
- * ________ ________ NULL
- * |formats |<--------. |formats | ^
- * | ____ | ____|________________ | ____ | ____|________________
- * | |refs| | | __|_ | |refs| | | __|_
- * | |* * | | | | | | AVFilterLink | |* * | | | | | | AVFilterLink
- * | |* *--------->|*ref| | |* | | | |*ref|
- * | |____| | | |____| | |____| | | |____|
- * |________| |_____________________ |________| |_____________________
- */
-void avfilter_formats_unref(AVFilterFormats **ref);
-
-/**
- *
- * Before After
- * ________ ________
- * |formats |<---------. |formats |<---------.
- * | ____ | ___|___ | ____ | ___|___
- * | |refs| | | | | | |refs| | | | | NULL
- * | |* *--------->|*oldref| | |* *--------->|*newref| ^
- * | |* * | | |_______| | |* * | | |_______| ___|___
- * | |____| | | |____| | | | |
- * |________| |________| |*oldref|
- * |_______|
- */
-void avfilter_formats_changeref(AVFilterFormats **oldref,
- AVFilterFormats **newref);
-
+#if FF_API_AVFILTERPAD_PUBLIC
/**
* A filter pad used for either input or output.
+ *
+ * @warning this struct will be removed from public API.
+ * users should call avfilter_pad_get_name() and avfilter_pad_get_type()
+ * to access the name and type fields; there should be no need to access
+ * any other fields from outside of libavfilter.
*/
struct AVFilterPad {
/**
@@ -318,8 +216,7 @@ struct AVFilterPad {
const char *name;
/**
- * AVFilterPad type. Only video supported now, hopefully someone will
- * add audio in the future.
+ * AVFilterPad type.
*/
enum AVMediaType type;
@@ -367,8 +264,7 @@ struct AVFilterPad {
* Input audio pads only.
*/
AVFilterBufferRef *(*get_audio_buffer)(AVFilterLink *link, int perms,
- enum AVSampleFormat sample_fmt, int size,
- uint64_t channel_layout, int planar);
+ int nb_samples);
/**
* Callback called after the slices of a frame are completely sent. If
@@ -402,7 +298,7 @@ struct AVFilterPad {
*
* Defaults to just calling the source poll_frame() method.
*
- * Output video pads only.
+ * Output pads only.
*/
int (*poll_frame)(AVFilterLink *link);
@@ -411,7 +307,7 @@ struct AVFilterPad {
* frame being output over the given link. This should return zero on
* success, and another value on error.
*
- * Output video pads only.
+ * Output pads only.
*/
int (*request_frame)(AVFilterLink *link);
@@ -430,65 +326,38 @@ struct AVFilterPad {
* and another value on error.
*/
int (*config_props)(AVFilterLink *link);
-};
-
-/** default handler for start_frame() for video inputs */
-void avfilter_default_start_frame(AVFilterLink *link, AVFilterBufferRef *picref);
-
-/** default handler for draw_slice() for video inputs */
-void avfilter_default_draw_slice(AVFilterLink *link, int y, int h, int slice_dir);
-
-/** default handler for end_frame() for video inputs */
-void avfilter_default_end_frame(AVFilterLink *link);
-/** default handler for filter_samples() for audio inputs */
-void avfilter_default_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref);
-
-/** default handler for config_props() for audio/video outputs */
-int avfilter_default_config_output_link(AVFilterLink *link);
-
-/** default handler for config_props() for audio/video inputs */
-int avfilter_default_config_input_link (AVFilterLink *link);
-
-/** default handler for get_video_buffer() for video inputs */
-AVFilterBufferRef *avfilter_default_get_video_buffer(AVFilterLink *link,
- int perms, int w, int h);
-
-/** default handler for get_audio_buffer() for audio inputs */
-AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int perms,
- enum AVSampleFormat sample_fmt, int size,
- uint64_t channel_layout, int planar);
+ /**
+ * The filter expects a fifo to be inserted on its input link,
+ * typically because it has a delay.
+ *
+ * input pads only.
+ */
+ int needs_fifo;
+};
+#endif
/**
- * A helper for query_formats() which sets all links to the same list of
- * formats. If there are no links hooked to this filter, the list of formats is
- * freed.
+ * Get the name of an AVFilterPad.
+ *
+ * @param pads an array of AVFilterPads
+ * @param pad_idx index of the pad in the array it; is the caller's
+ * responsibility to ensure the index is valid
+ *
+ * @return name of the pad_idx'th pad in pads
*/
-void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats);
-
-/** Default handler for query_formats() */
-int avfilter_default_query_formats(AVFilterContext *ctx);
-
-/** start_frame() handler for filters which simply pass video along */
-void avfilter_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref);
-
-/** draw_slice() handler for filters which simply pass video along */
-void avfilter_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir);
-
-/** end_frame() handler for filters which simply pass video along */
-void avfilter_null_end_frame(AVFilterLink *link);
-
-/** filter_samples() handler for filters which simply pass audio along */
-void avfilter_null_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref);
-
-/** get_video_buffer() handler for filters which simply pass video along */
-AVFilterBufferRef *avfilter_null_get_video_buffer(AVFilterLink *link,
- int perms, int w, int h);
+const char *avfilter_pad_get_name(AVFilterPad *pads, int pad_idx);
-/** get_audio_buffer() handler for filters which simply pass audio along */
-AVFilterBufferRef *avfilter_null_get_audio_buffer(AVFilterLink *link, int perms,
- enum AVSampleFormat sample_fmt, int size,
- uint64_t channel_layout, int planar);
+/**
+ * Get the type of an AVFilterPad.
+ *
+ * @param pads an array of AVFilterPads
+ * @param pad_idx index of the pad in the array; it is the caller's
+ * responsibility to ensure the index is valid
+ *
+ * @return type of the pad_idx'th pad in pads
+ */
+enum AVMediaType avfilter_pad_get_type(AVFilterPad *pads, int pad_idx);
/**
* Filter definition. This defines the pads a filter contains, and all the
@@ -497,15 +366,28 @@ AVFilterBufferRef *avfilter_null_get_audio_buffer(AVFilterLink *link, int perms,
typedef struct AVFilter {
const char *name; ///< filter name
- int priv_size; ///< size of private data to allocate for the filter
+ /**
+ * A description for the filter. You should use the
+ * NULL_IF_CONFIG_SMALL() macro to define it.
+ */
+ const char *description;
+
+ const AVFilterPad *inputs; ///< NULL terminated list of inputs. NULL if none
+ const AVFilterPad *outputs; ///< NULL terminated list of outputs. NULL if none
+
+ /*****************************************************************
+ * All fields below this line are not part of the public API. They
+ * may not be used outside of libavfilter and can be changed and
+ * removed at will.
+ * New public fields should be added right above.
+ *****************************************************************
+ */
/**
* Filter initialization function. Args contains the user-supplied
* parameters. FIXME: maybe an AVOption-based system would be better?
- * opaque is data provided by the code requesting creation of the filter,
- * and is used to pass data to the filter.
*/
- int (*init)(AVFilterContext *ctx, const char *args, void *opaque);
+ int (*init)(AVFilterContext *ctx, const char *args);
/**
* Filter uninitialization function. Should deallocate any memory held
@@ -524,14 +406,7 @@ typedef struct AVFilter {
*/
int (*query_formats)(AVFilterContext *);
- const AVFilterPad *inputs; ///< NULL terminated list of inputs. NULL if none
- const AVFilterPad *outputs; ///< NULL terminated list of outputs. NULL if none
-
- /**
- * A description for the filter. You should use the
- * NULL_IF_CONFIG_SMALL() macro to define it.
- */
- const char *description;
+ int priv_size; ///< size of private data to allocate for the filter
} AVFilter;
/** An instance of a filter */
@@ -542,13 +417,19 @@ struct AVFilterContext {
char *name; ///< name of this filter instance
- unsigned input_count; ///< number of input pads
AVFilterPad *input_pads; ///< array of input pads
AVFilterLink **inputs; ///< array of pointers to input links
+#if FF_API_FOO_COUNT
+ unsigned input_count; ///< @deprecated use nb_inputs
+#endif
+ unsigned nb_inputs; ///< number of input pads
- unsigned output_count; ///< number of output pads
AVFilterPad *output_pads; ///< array of output pads
AVFilterLink **outputs; ///< array of pointers to output links
+#if FF_API_FOO_COUNT
+ unsigned output_count; ///< @deprecated use nb_outputs
+#endif
+ unsigned nb_outputs; ///< number of output pads
void *priv; ///< private data for use by the filter
};
@@ -567,13 +448,6 @@ struct AVFilterLink {
AVFilterContext *dst; ///< dest filter
AVFilterPad *dstpad; ///< input pad on the dest filter
- /** stage of the initialization of the link properties (dimensions, etc) */
- enum {
- AVLINK_UNINIT = 0, ///< not started
- AVLINK_STARTINIT, ///< started, but incomplete
- AVLINK_INIT ///< complete
- } init_state;
-
enum AVMediaType type; ///< filter media type
/* These parameters apply only to video */
@@ -582,11 +456,27 @@ struct AVFilterLink {
AVRational sample_aspect_ratio; ///< agreed upon sample aspect ratio
/* These two parameters apply only to audio */
uint64_t channel_layout; ///< channel layout of current buffer (see libavutil/audioconvert.h)
- int64_t sample_rate; ///< samples per second
+ int sample_rate; ///< samples per second
int format; ///< agreed upon media format
/**
+ * Define the time base used by the PTS of the frames/samples
+ * which will pass through this link.
+ * During the configuration stage, each filter is supposed to
+ * change only the output timebase, while the timebase of the
+ * input link is assumed to be an unchangeable property.
+ */
+ AVRational time_base;
+
+ /*****************************************************************
+ * All fields below this line are not part of the public API. They
+ * may not be used outside of libavfilter and can be changed and
+ * removed at will.
+ * New public fields should be added right above.
+ *****************************************************************
+ */
+ /**
* Lists of formats supported by the input and output filters respectively.
* These lists are used for negotiating the format to actually be used,
* which will be loaded into the format member, above, when chosen.
@@ -595,6 +485,31 @@ struct AVFilterLink {
AVFilterFormats *out_formats;
/**
+ * Lists of channel layouts and sample rates used for automatic
+ * negotiation.
+ */
+ AVFilterFormats *in_samplerates;
+ AVFilterFormats *out_samplerates;
+ struct AVFilterChannelLayouts *in_channel_layouts;
+ struct AVFilterChannelLayouts *out_channel_layouts;
+
+ /**
+ * Audio only, the destination filter sets this to a non-zero value to
+ * request that buffers with the given number of samples should be sent to
+ * it. AVFilterPad.needs_fifo must also be set on the corresponding input
+ * pad.
+ * Last buffer before EOF will be padded with silence.
+ */
+ int request_samples;
+
+ /** stage of the initialization of the link properties (dimensions, etc) */
+ enum {
+ AVLINK_UNINIT = 0, ///< not started
+ AVLINK_STARTINIT, ///< started, but incomplete
+ AVLINK_INIT ///< complete
+ } init_state;
+
+ /**
* The buffer reference currently being sent across the link by the source
* filter. This is used internally by the filter system to allow
* automatic copying of buffers which do not have sufficient permissions
@@ -605,15 +520,6 @@ struct AVFilterLink {
AVFilterBufferRef *cur_buf;
AVFilterBufferRef *out_buf;
-
- /**
- * Define the time base used by the PTS of the frames/samples
- * which will pass through this link.
- * During the configuration stage, each filter is supposed to
- * change only the output timebase, while the timebase of the
- * input link is assumed to be an unchangeable property.
- */
- AVRational time_base;
};
/**
@@ -637,20 +543,6 @@ int avfilter_link(AVFilterContext *src, unsigned srcpad,
int avfilter_config_links(AVFilterContext *filter);
/**
- * Request a picture buffer with a specific set of permissions.
- *
- * @param link the output link to the filter from which the buffer will
- * be requested
- * @param perms the required access permissions
- * @param w the minimum width of the buffer to allocate
- * @param h the minimum height of the buffer to allocate
- * @return A reference to the buffer. This must be unreferenced with
- * avfilter_unref_buffer when you are finished with it.
- */
-AVFilterBufferRef *avfilter_get_video_buffer(AVFilterLink *link, int perms,
- int w, int h);
-
-/**
* Create a buffer reference wrapped around an already allocated image
* buffer.
*
@@ -666,83 +558,22 @@ avfilter_get_video_buffer_ref_from_arrays(uint8_t *data[4], int linesize[4], int
int w, int h, enum PixelFormat format);
/**
- * Request an audio samples buffer with a specific set of permissions.
+ * Create an audio buffer reference wrapped around an already
+ * allocated samples buffer.
*
- * @param link the output link to the filter from which the buffer will
- * be requested
+ * @param data pointers to the samples plane buffers
+ * @param linesize linesize for the samples plane buffers
* @param perms the required access permissions
+ * @param nb_samples number of samples per channel
* @param sample_fmt the format of each sample in the buffer to allocate
- * @param size the buffer size in bytes
- * @param channel_layout the number and type of channels per sample in the buffer to allocate
- * @param planar audio data layout - planar or packed
- * @return A reference to the samples. This must be unreferenced with
- * avfilter_unref_buffer when you are finished with it.
+ * @param channel_layout the channel layout of the buffer
*/
-AVFilterBufferRef *avfilter_get_audio_buffer(AVFilterLink *link, int perms,
- enum AVSampleFormat sample_fmt, int size,
- uint64_t channel_layout, int planar);
-
-/**
- * Request an input frame from the filter at the other end of the link.
- *
- * @param link the input link
- * @return zero on success
- */
-int avfilter_request_frame(AVFilterLink *link);
-
-/**
- * Poll a frame from the filter chain.
- *
- * @param link the input link
- * @return the number of immediately available frames, a negative
- * number in case of error
- */
-int avfilter_poll_frame(AVFilterLink *link);
-
-/**
- * Notify the next filter of the start of a frame.
- *
- * @param link the output link the frame will be sent over
- * @param picref A reference to the frame about to be sent. The data for this
- * frame need only be valid once draw_slice() is called for that
- * portion. The receiving filter will free this reference when
- * it no longer needs it.
- */
-void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref);
-
-/**
- * Notifie the next filter that the current frame has finished.
- *
- * @param link the output link the frame was sent over
- */
-void avfilter_end_frame(AVFilterLink *link);
-
-/**
- * Send a slice to the next filter.
- *
- * Slices have to be provided in sequential order, either in
- * top-bottom or bottom-top order. If slices are provided in
- * non-sequential order the behavior of the function is undefined.
- *
- * @param link the output link over which the frame is being sent
- * @param y offset in pixels from the top of the image for this slice
- * @param h height of this slice in pixels
- * @param slice_dir the assumed direction for sending slices,
- * from the top slice to the bottom slice if the value is 1,
- * from the bottom slice to the top slice if the value is -1,
- * for other values the behavior of the function is undefined.
- */
-void avfilter_draw_slice(AVFilterLink *link, int y, int h, int slice_dir);
-
-/**
- * Send a buffer of audio samples to the next filter.
- *
- * @param link the output link over which the audio samples are being sent
- * @param samplesref a reference to the buffer of audio samples being sent. The
- * receiving filter will free this reference when it no longer
- * needs it or pass it on to the next filter.
- */
-void avfilter_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref);
+AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_arrays(uint8_t **data,
+ int linesize,
+ int perms,
+ int nb_samples,
+ enum AVSampleFormat sample_fmt,
+ uint64_t channel_layout);
/** Initialize the filter system. Register all builtin filters. */
void avfilter_register_all(void);
@@ -822,44 +653,19 @@ int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
unsigned filt_srcpad_idx, unsigned filt_dstpad_idx);
/**
- * Insert a new pad.
+ * Copy the frame properties of src to dst, without copying the actual
+ * image data.
*
- * @param idx Insertion point. Pad is inserted at the end if this point
- * is beyond the end of the list of pads.
- * @param count Pointer to the number of pads in the list
- * @param padidx_off Offset within an AVFilterLink structure to the element
- * to increment when inserting a new pad causes link
- * numbering to change
- * @param pads Pointer to the pointer to the beginning of the list of pads
- * @param links Pointer to the pointer to the beginning of the list of links
- * @param newpad The new pad to add. A copy is made when adding.
+ * @return 0 on success, a negative number on error.
*/
-void avfilter_insert_pad(unsigned idx, unsigned *count, size_t padidx_off,
- AVFilterPad **pads, AVFilterLink ***links,
- AVFilterPad *newpad);
-
-/** Insert a new input pad for the filter. */
-static inline void avfilter_insert_inpad(AVFilterContext *f, unsigned index,
- AVFilterPad *p)
-{
- avfilter_insert_pad(index, &f->input_count, offsetof(AVFilterLink, dstpad),
- &f->input_pads, &f->inputs, p);
-}
-
-/** Insert a new output pad for the filter. */
-static inline void avfilter_insert_outpad(AVFilterContext *f, unsigned index,
- AVFilterPad *p)
-{
- avfilter_insert_pad(index, &f->output_count, offsetof(AVFilterLink, srcpad),
- &f->output_pads, &f->outputs, p);
-}
+int avfilter_copy_frame_props(AVFilterBufferRef *dst, const AVFrame *src);
/**
- * Copy the frame properties of src to dst, without copying the actual
- * image data.
+ * Copy the frame properties and data pointers of src to dst, without copying
+ * the actual data.
*
* @return 0 on success, a negative number on error.
*/
-int avfilter_copy_frame_props(AVFilterBufferRef *dst, const AVFrame *src);
+int avfilter_copy_buf_props(AVFrame *dst, const AVFilterBufferRef *src);
#endif /* AVFILTER_AVFILTER_H */
diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index 04d9027..c147c3b 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -25,8 +25,11 @@
#include "avfilter.h"
#include "avfiltergraph.h"
+#include "formats.h"
#include "internal.h"
+#include "libavutil/audioconvert.h"
+#include "libavutil/avassert.h"
#include "libavutil/log.h"
static const AVClass filtergraph_class = {
@@ -40,9 +43,7 @@ AVFilterGraph *avfilter_graph_alloc(void)
AVFilterGraph *ret = av_mallocz(sizeof(AVFilterGraph));
if (!ret)
return NULL;
-#if FF_API_GRAPH_AVCLASS
ret->av_class = &filtergraph_class;
-#endif
return ret;
}
@@ -91,7 +92,15 @@ fail:
return ret;
}
-int ff_avfilter_graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
+/**
+ * Check for the validity of graph.
+ *
+ * A graph is considered valid if all its input and output pads are
+ * connected.
+ *
+ * @return 0 in case of success, a negative value otherwise
+ */
+static int graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
{
AVFilterContext *filt;
int i, j;
@@ -99,7 +108,7 @@ int ff_avfilter_graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
for (i = 0; i < graph->filter_count; i++) {
filt = graph->filters[i];
- for (j = 0; j < filt->input_count; j++) {
+ for (j = 0; j < filt->nb_inputs; j++) {
if (!filt->inputs[j] || !filt->inputs[j]->src) {
av_log(log_ctx, AV_LOG_ERROR,
"Input pad \"%s\" for the filter \"%s\" of type \"%s\" not connected to any source\n",
@@ -108,7 +117,7 @@ int ff_avfilter_graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
}
}
- for (j = 0; j < filt->output_count; j++) {
+ for (j = 0; j < filt->nb_outputs; j++) {
if (!filt->outputs[j] || !filt->outputs[j]->dst) {
av_log(log_ctx, AV_LOG_ERROR,
"Output pad \"%s\" for the filter \"%s\" of type \"%s\" not connected to any destination\n",
@@ -121,7 +130,12 @@ int ff_avfilter_graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
return 0;
}
-int ff_avfilter_graph_config_links(AVFilterGraph *graph, AVClass *log_ctx)
+/**
+ * Configure all the links of graphctx.
+ *
+ * @return 0 in case of success, a negative value otherwise
+ */
+static int graph_config_links(AVFilterGraph *graph, AVClass *log_ctx)
{
AVFilterContext *filt;
int i, ret;
@@ -129,7 +143,7 @@ int ff_avfilter_graph_config_links(AVFilterGraph *graph, AVClass *log_ctx)
for (i=0; i < graph->filter_count; i++) {
filt = graph->filters[i];
- if (!filt->output_count) {
+ if (!filt->nb_outputs) {
if ((ret = avfilter_config_links(filt)))
return ret;
}
@@ -152,48 +166,110 @@ AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, char *name)
static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
{
int i, j, ret;
- int scaler_count = 0;
- char inst_name[30];
+ int scaler_count = 0, resampler_count = 0;
/* ask all the sub-filters for their supported media formats */
for (i = 0; i < graph->filter_count; i++) {
if (graph->filters[i]->filter->query_formats)
graph->filters[i]->filter->query_formats(graph->filters[i]);
else
- avfilter_default_query_formats(graph->filters[i]);
+ ff_default_query_formats(graph->filters[i]);
}
/* go through and merge as many format lists as possible */
for (i = 0; i < graph->filter_count; i++) {
AVFilterContext *filter = graph->filters[i];
- for (j = 0; j < filter->input_count; j++) {
+ for (j = 0; j < filter->nb_inputs; j++) {
AVFilterLink *link = filter->inputs[j];
- if (link && link->in_formats != link->out_formats) {
- if (!avfilter_merge_formats(link->in_formats,
- link->out_formats)) {
- AVFilterContext *scale;
- char scale_args[256];
- /* couldn't merge format lists. auto-insert scale filter */
+ int convert_needed = 0;
+
+ if (!link)
+ continue;
+
+ if (link->in_formats != link->out_formats &&
+ !ff_merge_formats(link->in_formats,
+ link->out_formats))
+ convert_needed = 1;
+ if (link->type == AVMEDIA_TYPE_AUDIO) {
+ if (link->in_channel_layouts != link->out_channel_layouts &&
+ !ff_merge_channel_layouts(link->in_channel_layouts,
+ link->out_channel_layouts))
+ convert_needed = 1;
+ if (link->in_samplerates != link->out_samplerates &&
+ !ff_merge_samplerates(link->in_samplerates,
+ link->out_samplerates))
+ convert_needed = 1;
+ }
+
+ if (convert_needed) {
+ AVFilterContext *convert;
+ AVFilter *filter;
+ AVFilterLink *inlink, *outlink;
+ char scale_args[256];
+ char inst_name[30];
+
+ /* couldn't merge format lists. auto-insert conversion filter */
+ switch (link->type) {
+ case AVMEDIA_TYPE_VIDEO:
+ if (!(filter = avfilter_get_by_name("scale"))) {
+ av_log(log_ctx, AV_LOG_ERROR, "'scale' filter "
+ "not present, cannot convert pixel formats.\n");
+ return AVERROR(EINVAL);
+ }
+
snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d",
scaler_count++);
snprintf(scale_args, sizeof(scale_args), "0:0:%s", graph->scale_sws_opts);
- if ((ret = avfilter_graph_create_filter(&scale, avfilter_get_by_name("scale"),
- inst_name, scale_args, NULL, graph)) < 0)
- return ret;
- if ((ret = avfilter_insert_filter(link, scale, 0, 0)) < 0)
+ if ((ret = avfilter_graph_create_filter(&convert, filter,
+ inst_name, scale_args, NULL,
+ graph)) < 0)
return ret;
-
- scale->filter->query_formats(scale);
- if (((link = scale-> inputs[0]) &&
- !avfilter_merge_formats(link->in_formats, link->out_formats)) ||
- ((link = scale->outputs[0]) &&
- !avfilter_merge_formats(link->in_formats, link->out_formats))) {
- av_log(log_ctx, AV_LOG_ERROR,
- "Impossible to convert between the formats supported by the filter "
- "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ if (!(filter = avfilter_get_by_name("resample"))) {
+ av_log(log_ctx, AV_LOG_ERROR, "'resample' filter "
+ "not present, cannot convert audio formats.\n");
return AVERROR(EINVAL);
}
+
+ snprintf(inst_name, sizeof(inst_name), "auto-inserted resampler %d",
+ resampler_count++);
+ if ((ret = avfilter_graph_create_filter(&convert, filter,
+ inst_name, NULL, NULL, graph)) < 0)
+ return ret;
+ break;
+ default:
+ return AVERROR(EINVAL);
+ }
+
+ if ((ret = avfilter_insert_filter(link, convert, 0, 0)) < 0)
+ return ret;
+
+ convert->filter->query_formats(convert);
+ inlink = convert->inputs[0];
+ outlink = convert->outputs[0];
+ if (!ff_merge_formats( inlink->in_formats, inlink->out_formats) ||
+ !ff_merge_formats(outlink->in_formats, outlink->out_formats))
+ ret |= AVERROR(ENOSYS);
+ if (inlink->type == AVMEDIA_TYPE_AUDIO &&
+ (!ff_merge_samplerates(inlink->in_samplerates,
+ inlink->out_samplerates) ||
+ !ff_merge_channel_layouts(inlink->in_channel_layouts,
+ inlink->out_channel_layouts)))
+ ret |= AVERROR(ENOSYS);
+ if (outlink->type == AVMEDIA_TYPE_AUDIO &&
+ (!ff_merge_samplerates(outlink->in_samplerates,
+ outlink->out_samplerates) ||
+ !ff_merge_channel_layouts(outlink->in_channel_layouts,
+ outlink->out_channel_layouts)))
+ ret |= AVERROR(ENOSYS);
+
+ if (ret < 0) {
+ av_log(log_ctx, AV_LOG_ERROR,
+ "Impossible to convert between the formats supported by the filter "
+ "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
+ return ret;
}
}
}
@@ -202,46 +278,90 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
return 0;
}
-static void pick_format(AVFilterLink *link)
+static int pick_format(AVFilterLink *link)
{
if (!link || !link->in_formats)
- return;
+ return 0;
link->in_formats->format_count = 1;
link->format = link->in_formats->formats[0];
- avfilter_formats_unref(&link->in_formats);
- avfilter_formats_unref(&link->out_formats);
+ if (link->type == AVMEDIA_TYPE_AUDIO) {
+ if (!link->in_samplerates->format_count) {
+ av_log(link->src, AV_LOG_ERROR, "Cannot select sample rate for"
+ " the link between filters %s and %s.\n", link->src->name,
+ link->dst->name);
+ return AVERROR(EINVAL);
+ }
+ link->in_samplerates->format_count = 1;
+ link->sample_rate = link->in_samplerates->formats[0];
+
+ if (!link->in_channel_layouts->nb_channel_layouts) {
+ av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for"
+ "the link between filters %s and %s.\n", link->src->name,
+ link->dst->name);
+ return AVERROR(EINVAL);
+ }
+ link->in_channel_layouts->nb_channel_layouts = 1;
+ link->channel_layout = link->in_channel_layouts->channel_layouts[0];
+ }
+
+ ff_formats_unref(&link->in_formats);
+ ff_formats_unref(&link->out_formats);
+ ff_formats_unref(&link->in_samplerates);
+ ff_formats_unref(&link->out_samplerates);
+ ff_channel_layouts_unref(&link->in_channel_layouts);
+ ff_channel_layouts_unref(&link->out_channel_layouts);
+
+ return 0;
}
+#define REDUCE_FORMATS(fmt_type, list_type, list, var, nb, add_format) \
+do { \
+ for (i = 0; i < filter->nb_inputs; i++) { \
+ AVFilterLink *link = filter->inputs[i]; \
+ fmt_type fmt; \
+ \
+ if (!link->out_ ## list || link->out_ ## list->nb != 1) \
+ continue; \
+ fmt = link->out_ ## list->var[0]; \
+ \
+ for (j = 0; j < filter->nb_outputs; j++) { \
+ AVFilterLink *out_link = filter->outputs[j]; \
+ list_type *fmts; \
+ \
+ if (link->type != out_link->type || \
+ out_link->in_ ## list->nb == 1) \
+ continue; \
+ fmts = out_link->in_ ## list; \
+ \
+ if (!out_link->in_ ## list->nb) { \
+ add_format(&out_link->in_ ##list, fmt); \
+ break; \
+ } \
+ \
+ for (k = 0; k < out_link->in_ ## list->nb; k++) \
+ if (fmts->var[k] == fmt) { \
+ fmts->var[0] = fmt; \
+ fmts->nb = 1; \
+ ret = 1; \
+ break; \
+ } \
+ } \
+ } \
+} while (0)
+
static int reduce_formats_on_filter(AVFilterContext *filter)
{
int i, j, k, ret = 0;
- for (i = 0; i < filter->input_count; i++) {
- AVFilterLink *link = filter->inputs[i];
- int format = link->out_formats->formats[0];
-
- if (link->out_formats->format_count != 1)
- continue;
-
- for (j = 0; j < filter->output_count; j++) {
- AVFilterLink *out_link = filter->outputs[j];
- AVFilterFormats *fmts = out_link->in_formats;
-
- if (link->type != out_link->type ||
- out_link->in_formats->format_count == 1)
- continue;
+ REDUCE_FORMATS(int, AVFilterFormats, formats, formats,
+ format_count, ff_add_format);
+ REDUCE_FORMATS(int, AVFilterFormats, samplerates, formats,
+ format_count, ff_add_format);
+ REDUCE_FORMATS(uint64_t, AVFilterChannelLayouts, channel_layouts,
+ channel_layouts, nb_channel_layouts, ff_add_channel_layout);
- for (k = 0; k < out_link->in_formats->format_count; k++)
- if (fmts->formats[k] == format) {
- fmts->formats[0] = format;
- fmts->format_count = 1;
- ret = 1;
- break;
- }
- }
- }
return ret;
}
@@ -257,21 +377,196 @@ static void reduce_formats(AVFilterGraph *graph)
} while (reduced);
}
-static void pick_formats(AVFilterGraph *graph)
+static void swap_samplerates_on_filter(AVFilterContext *filter)
{
+ AVFilterLink *link = NULL;
+ int sample_rate;
int i, j;
+ for (i = 0; i < filter->nb_inputs; i++) {
+ link = filter->inputs[i];
+
+ if (link->type == AVMEDIA_TYPE_AUDIO &&
+ link->out_samplerates->format_count == 1)
+ break;
+ }
+ if (i == filter->nb_inputs)
+ return;
+
+ sample_rate = link->out_samplerates->formats[0];
+
+ for (i = 0; i < filter->nb_outputs; i++) {
+ AVFilterLink *outlink = filter->outputs[i];
+ int best_idx, best_diff = INT_MAX;
+
+ if (outlink->type != AVMEDIA_TYPE_AUDIO ||
+ outlink->in_samplerates->format_count < 2)
+ continue;
+
+ for (j = 0; j < outlink->in_samplerates->format_count; j++) {
+ int diff = abs(sample_rate - outlink->in_samplerates->formats[j]);
+
+ if (diff < best_diff) {
+ best_diff = diff;
+ best_idx = j;
+ }
+ }
+ FFSWAP(int, outlink->in_samplerates->formats[0],
+ outlink->in_samplerates->formats[best_idx]);
+ }
+}
+
+static void swap_samplerates(AVFilterGraph *graph)
+{
+ int i;
+
+ for (i = 0; i < graph->filter_count; i++)
+ swap_samplerates_on_filter(graph->filters[i]);
+}
+
+static void swap_channel_layouts_on_filter(AVFilterContext *filter)
+{
+ AVFilterLink *link = NULL;
+ uint64_t chlayout;
+ int i, j;
+
+ for (i = 0; i < filter->nb_inputs; i++) {
+ link = filter->inputs[i];
+
+ if (link->type == AVMEDIA_TYPE_AUDIO &&
+ link->out_channel_layouts->nb_channel_layouts == 1)
+ break;
+ }
+ if (i == filter->nb_inputs)
+ return;
+
+ chlayout = link->out_channel_layouts->channel_layouts[0];
+
+ for (i = 0; i < filter->nb_outputs; i++) {
+ AVFilterLink *outlink = filter->outputs[i];
+ int best_idx, best_score = INT_MIN;
+
+ if (outlink->type != AVMEDIA_TYPE_AUDIO ||
+ outlink->in_channel_layouts->nb_channel_layouts < 2)
+ continue;
+
+ for (j = 0; j < outlink->in_channel_layouts->nb_channel_layouts; j++) {
+ uint64_t out_chlayout = outlink->in_channel_layouts->channel_layouts[j];
+ int matched_channels = av_get_channel_layout_nb_channels(chlayout &
+ out_chlayout);
+ int extra_channels = av_get_channel_layout_nb_channels(out_chlayout &
+ (~chlayout));
+ int score = matched_channels - extra_channels;
+
+ if (score > best_score) {
+ best_score = score;
+ best_idx = j;
+ }
+ }
+ FFSWAP(uint64_t, outlink->in_channel_layouts->channel_layouts[0],
+ outlink->in_channel_layouts->channel_layouts[best_idx]);
+ }
+
+}
+
+static void swap_channel_layouts(AVFilterGraph *graph)
+{
+ int i;
+
+ for (i = 0; i < graph->filter_count; i++)
+ swap_channel_layouts_on_filter(graph->filters[i]);
+}
+
+static void swap_sample_fmts_on_filter(AVFilterContext *filter)
+{
+ AVFilterLink *link = NULL;
+ int format, bps;
+ int i, j;
+
+ for (i = 0; i < filter->nb_inputs; i++) {
+ link = filter->inputs[i];
+
+ if (link->type == AVMEDIA_TYPE_AUDIO &&
+ link->out_formats->format_count == 1)
+ break;
+ }
+ if (i == filter->nb_inputs)
+ return;
+
+ format = link->out_formats->formats[0];
+ bps = av_get_bytes_per_sample(format);
+
+ for (i = 0; i < filter->nb_outputs; i++) {
+ AVFilterLink *outlink = filter->outputs[i];
+ int best_idx = -1, best_score = INT_MIN;
+
+ if (outlink->type != AVMEDIA_TYPE_AUDIO ||
+ outlink->in_formats->format_count < 2)
+ continue;
+
+ for (j = 0; j < outlink->in_formats->format_count; j++) {
+ int out_format = outlink->in_formats->formats[j];
+ int out_bps = av_get_bytes_per_sample(out_format);
+ int score;
+
+ if (av_get_packed_sample_fmt(out_format) == format ||
+ av_get_planar_sample_fmt(out_format) == format) {
+ best_idx = j;
+ break;
+ }
+
+ /* for s32 and float prefer double to prevent loss of information */
+ if (bps == 4 && out_bps == 8) {
+ best_idx = j;
+ break;
+ }
+
+ /* prefer closest higher or equal bps */
+ score = -abs(out_bps - bps);
+ if (out_bps >= bps)
+ score += INT_MAX/2;
+
+ if (score > best_score) {
+ best_score = score;
+ best_idx = j;
+ }
+ }
+ av_assert0(best_idx >= 0);
+ FFSWAP(int, outlink->in_formats->formats[0],
+ outlink->in_formats->formats[best_idx]);
+ }
+}
+
+static void swap_sample_fmts(AVFilterGraph *graph)
+{
+ int i;
+
+ for (i = 0; i < graph->filter_count; i++)
+ swap_sample_fmts_on_filter(graph->filters[i]);
+
+}
+
+static int pick_formats(AVFilterGraph *graph)
+{
+ int i, j, ret;
+
for (i = 0; i < graph->filter_count; i++) {
AVFilterContext *filter = graph->filters[i];
- for (j = 0; j < filter->input_count; j++)
- pick_format(filter->inputs[j]);
- for (j = 0; j < filter->output_count; j++)
- pick_format(filter->outputs[j]);
+ for (j = 0; j < filter->nb_inputs; j++)
+ if ((ret = pick_format(filter->inputs[j])) < 0)
+ return ret;
+ for (j = 0; j < filter->nb_outputs; j++)
+ if ((ret = pick_format(filter->outputs[j])) < 0)
+ return ret;
}
+ return 0;
}
-int ff_avfilter_graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx)
+/**
+ * Configure the formats of all the links in the graph.
+ */
+static int graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx)
{
int ret;
@@ -284,7 +579,52 @@ int ff_avfilter_graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx)
* of format conversion inside filters */
reduce_formats(graph);
- pick_formats(graph);
+ /* for audio filters, ensure the best format, sample rate and channel layout
+ * is selected */
+ swap_sample_fmts(graph);
+ swap_samplerates(graph);
+ swap_channel_layouts(graph);
+
+ if ((ret = pick_formats(graph)) < 0)
+ return ret;
+
+ return 0;
+}
+
+static int graph_insert_fifos(AVFilterGraph *graph, AVClass *log_ctx)
+{
+ AVFilterContext *f;
+ int i, j, ret;
+ int fifo_count = 0;
+
+ for (i = 0; i < graph->filter_count; i++) {
+ f = graph->filters[i];
+
+ for (j = 0; j < f->nb_inputs; j++) {
+ AVFilterLink *link = f->inputs[j];
+ AVFilterContext *fifo_ctx;
+ AVFilter *fifo;
+ char name[32];
+
+ if (!link->dstpad->needs_fifo)
+ continue;
+
+ fifo = f->inputs[j]->type == AVMEDIA_TYPE_VIDEO ?
+ avfilter_get_by_name("fifo") :
+ avfilter_get_by_name("afifo");
+
+ snprintf(name, sizeof(name), "auto-inserted fifo %d", fifo_count++);
+
+ ret = avfilter_graph_create_filter(&fifo_ctx, fifo, name, NULL,
+ NULL, graph);
+ if (ret < 0)
+ return ret;
+
+ ret = avfilter_insert_filter(link, fifo_ctx, 0, 0);
+ if (ret < 0)
+ return ret;
+ }
+ }
return 0;
}
@@ -293,11 +633,13 @@ int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)
{
int ret;
- if ((ret = ff_avfilter_graph_check_validity(graphctx, log_ctx)))
+ if ((ret = graph_check_validity(graphctx, log_ctx)))
+ return ret;
+ if ((ret = graph_insert_fifos(graphctx, log_ctx)) < 0)
return ret;
- if ((ret = ff_avfilter_graph_config_formats(graphctx, log_ctx)))
+ if ((ret = graph_config_formats(graphctx, log_ctx)))
return ret;
- if ((ret = ff_avfilter_graph_config_links(graphctx, log_ctx)))
+ if ((ret = graph_config_links(graphctx, log_ctx)))
return ret;
return 0;
diff --git a/libavfilter/avfiltergraph.h b/libavfilter/avfiltergraph.h
index 0d600b9..7c4672d 100644
--- a/libavfilter/avfiltergraph.h
+++ b/libavfilter/avfiltergraph.h
@@ -26,9 +26,7 @@
#include "libavutil/log.h"
typedef struct AVFilterGraph {
-#if FF_API_GRAPH_AVCLASS
const AVClass *av_class;
-#endif
unsigned filter_count;
AVFilterContext **filters;
diff --git a/libavfilter/buffer.c b/libavfilter/buffer.c
new file mode 100644
index 0000000..be0da26
--- /dev/null
+++ b/libavfilter/buffer.c
@@ -0,0 +1,168 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/audioconvert.h"
+#include "libavcodec/avcodec.h"
+
+#include "avfilter.h"
+#include "internal.h"
+
+/* TODO: buffer pool. see comment for avfilter_default_get_video_buffer() */
+void ff_avfilter_default_free_buffer(AVFilterBuffer *ptr)
+{
+ if (ptr->extended_data != ptr->data)
+ av_freep(&ptr->extended_data);
+ av_free(ptr->data[0]);
+ av_free(ptr);
+}
+
+AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask)
+{
+ AVFilterBufferRef *ret = av_malloc(sizeof(AVFilterBufferRef));
+ if (!ret)
+ return NULL;
+ *ret = *ref;
+ if (ref->type == AVMEDIA_TYPE_VIDEO) {
+ ret->video = av_malloc(sizeof(AVFilterBufferRefVideoProps));
+ if (!ret->video) {
+ av_free(ret);
+ return NULL;
+ }
+ *ret->video = *ref->video;
+ ret->extended_data = ret->data;
+ } else if (ref->type == AVMEDIA_TYPE_AUDIO) {
+ ret->audio = av_malloc(sizeof(AVFilterBufferRefAudioProps));
+ if (!ret->audio) {
+ av_free(ret);
+ return NULL;
+ }
+ *ret->audio = *ref->audio;
+
+ if (ref->extended_data != ref->data) {
+ int nb_channels = av_get_channel_layout_nb_channels(ref->audio->channel_layout);
+ if (!(ret->extended_data = av_malloc(sizeof(*ret->extended_data) *
+ nb_channels))) {
+ av_freep(&ret->audio);
+ av_freep(&ret);
+ return NULL;
+ }
+ memcpy(ret->extended_data, ref->extended_data,
+ sizeof(*ret->extended_data) * nb_channels);
+ } else
+ ret->extended_data = ret->data;
+ }
+ ret->perms &= pmask;
+ ret->buf->refcount ++;
+ return ret;
+}
+
+void avfilter_unref_buffer(AVFilterBufferRef *ref)
+{
+ if (!ref)
+ return;
+ if (!(--ref->buf->refcount))
+ ref->buf->free(ref->buf);
+ if (ref->extended_data != ref->data)
+ av_freep(&ref->extended_data);
+ av_free(ref->video);
+ av_free(ref->audio);
+ av_free(ref);
+}
+
+int avfilter_copy_frame_props(AVFilterBufferRef *dst, const AVFrame *src)
+{
+ dst->pts = src->pts;
+ dst->format = src->format;
+
+ switch (dst->type) {
+ case AVMEDIA_TYPE_VIDEO:
+ dst->video->w = src->width;
+ dst->video->h = src->height;
+ dst->video->pixel_aspect = src->sample_aspect_ratio;
+ dst->video->interlaced = src->interlaced_frame;
+ dst->video->top_field_first = src->top_field_first;
+ dst->video->key_frame = src->key_frame;
+ dst->video->pict_type = src->pict_type;
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ dst->audio->sample_rate = src->sample_rate;
+ dst->audio->channel_layout = src->channel_layout;
+ break;
+ default:
+ return AVERROR(EINVAL);
+ }
+
+ return 0;
+}
+
+int avfilter_copy_buf_props(AVFrame *dst, const AVFilterBufferRef *src)
+{
+ int planes, nb_channels;
+
+ memcpy(dst->data, src->data, sizeof(dst->data));
+ memcpy(dst->linesize, src->linesize, sizeof(dst->linesize));
+
+ dst->pts = src->pts;
+ dst->format = src->format;
+
+ switch (src->type) {
+ case AVMEDIA_TYPE_VIDEO:
+ dst->width = src->video->w;
+ dst->height = src->video->h;
+ dst->sample_aspect_ratio = src->video->pixel_aspect;
+ dst->interlaced_frame = src->video->interlaced;
+ dst->top_field_first = src->video->top_field_first;
+ dst->key_frame = src->video->key_frame;
+ dst->pict_type = src->video->pict_type;
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ nb_channels = av_get_channel_layout_nb_channels(src->audio->channel_layout);
+ planes = av_sample_fmt_is_planar(src->format) ? nb_channels : 1;
+
+ if (planes > FF_ARRAY_ELEMS(dst->data)) {
+ dst->extended_data = av_mallocz(planes * sizeof(*dst->extended_data));
+ if (!dst->extended_data)
+ return AVERROR(ENOMEM);
+ memcpy(dst->extended_data, src->extended_data,
+ planes * sizeof(dst->extended_data));
+ } else
+ dst->extended_data = dst->data;
+
+ dst->sample_rate = src->audio->sample_rate;
+ dst->channel_layout = src->audio->channel_layout;
+ dst->nb_samples = src->audio->nb_samples;
+ break;
+ default:
+ return AVERROR(EINVAL);
+ }
+
+ return 0;
+}
+
+void avfilter_copy_buffer_ref_props(AVFilterBufferRef *dst, AVFilterBufferRef *src)
+{
+ // copy common properties
+ dst->pts = src->pts;
+ dst->pos = src->pos;
+
+ switch (src->type) {
+ case AVMEDIA_TYPE_VIDEO: *dst->video = *src->video; break;
+ case AVMEDIA_TYPE_AUDIO: *dst->audio = *src->audio; break;
+ default: break;
+ }
+}
diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c
new file mode 100644
index 0000000..50d949b
--- /dev/null
+++ b/libavfilter/buffersink.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2011 Stefano Sabatini
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * buffer sink
+ */
+
+#include "libavutil/audio_fifo.h"
+#include "libavutil/audioconvert.h"
+#include "libavutil/avassert.h"
+#include "libavutil/mathematics.h"
+
+#include "audio.h"
+#include "avfilter.h"
+#include "buffersink.h"
+#include "internal.h"
+
+typedef struct {
+ AVFilterBufferRef *cur_buf; ///< last buffer delivered on the sink
+ AVAudioFifo *audio_fifo; ///< FIFO for audio samples
+ int64_t next_pts; ///< interpolating audio pts
+} BufferSinkContext;
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+ BufferSinkContext *sink = ctx->priv;
+
+ if (sink->audio_fifo)
+ av_audio_fifo_free(sink->audio_fifo);
+}
+
+static void start_frame(AVFilterLink *link, AVFilterBufferRef *buf)
+{
+ BufferSinkContext *s = link->dst->priv;
+
+ av_assert0(!s->cur_buf);
+ s->cur_buf = buf;
+ link->cur_buf = NULL;
+};
+
+int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf)
+{
+ BufferSinkContext *s = ctx->priv;
+ AVFilterLink *link = ctx->inputs[0];
+ int ret;
+
+ if (!buf)
+ return ff_poll_frame(ctx->inputs[0]);
+
+ if ((ret = ff_request_frame(link)) < 0)
+ return ret;
+
+ if (!s->cur_buf)
+ return AVERROR(EINVAL);
+
+ *buf = s->cur_buf;
+ s->cur_buf = NULL;
+
+ return 0;
+}
+
+static int read_from_fifo(AVFilterContext *ctx, AVFilterBufferRef **pbuf,
+ int nb_samples)
+{
+ BufferSinkContext *s = ctx->priv;
+ AVFilterLink *link = ctx->inputs[0];
+ AVFilterBufferRef *buf;
+
+ if (!(buf = ff_get_audio_buffer(link, AV_PERM_WRITE, nb_samples)))
+ return AVERROR(ENOMEM);
+ av_audio_fifo_read(s->audio_fifo, (void**)buf->extended_data, nb_samples);
+
+ buf->pts = s->next_pts;
+ s->next_pts += av_rescale_q(nb_samples, (AVRational){1, link->sample_rate},
+ link->time_base);
+
+ *pbuf = buf;
+ return 0;
+
+}
+
+int av_buffersink_read_samples(AVFilterContext *ctx, AVFilterBufferRef **pbuf,
+ int nb_samples)
+{
+ BufferSinkContext *s = ctx->priv;
+ AVFilterLink *link = ctx->inputs[0];
+ int ret = 0;
+
+ if (!s->audio_fifo) {
+ int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout);
+ if (!(s->audio_fifo = av_audio_fifo_alloc(link->format, nb_channels, nb_samples)))
+ return AVERROR(ENOMEM);
+ }
+
+ while (ret >= 0) {
+ AVFilterBufferRef *buf;
+
+ if (av_audio_fifo_size(s->audio_fifo) >= nb_samples)
+ return read_from_fifo(ctx, pbuf, nb_samples);
+
+ ret = av_buffersink_read(ctx, &buf);
+ if (ret == AVERROR_EOF && av_audio_fifo_size(s->audio_fifo))
+ return read_from_fifo(ctx, pbuf, av_audio_fifo_size(s->audio_fifo));
+ else if (ret < 0)
+ return ret;
+
+ if (buf->pts != AV_NOPTS_VALUE) {
+ s->next_pts = buf->pts -
+ av_rescale_q(av_audio_fifo_size(s->audio_fifo),
+ (AVRational){ 1, link->sample_rate },
+ link->time_base);
+ }
+
+ ret = av_audio_fifo_write(s->audio_fifo, (void**)buf->extended_data,
+ buf->audio->nb_samples);
+ avfilter_unref_buffer(buf);
+ }
+
+ return ret;
+}
+
+AVFilter avfilter_vsink_buffer = {
+ .name = "buffersink",
+ .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them available to the end of the filter graph."),
+ .priv_size = sizeof(BufferSinkContext),
+ .uninit = uninit,
+
+ .inputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .start_frame = start_frame,
+ .min_perms = AV_PERM_READ,
+ .needs_fifo = 1 },
+ { .name = NULL }},
+ .outputs = (AVFilterPad[]) {{ .name = NULL }},
+};
+
+AVFilter avfilter_asink_abuffer = {
+ .name = "abuffersink",
+ .description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them available to the end of the filter graph."),
+ .priv_size = sizeof(BufferSinkContext),
+ .uninit = uninit,
+
+ .inputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .filter_samples = start_frame,
+ .min_perms = AV_PERM_READ,
+ .needs_fifo = 1 },
+ { .name = NULL }},
+ .outputs = (AVFilterPad[]) {{ .name = NULL }},
+};
diff --git a/libavfilter/buffersink.h b/libavfilter/buffersink.h
new file mode 100644
index 0000000..8f94a9c
--- /dev/null
+++ b/libavfilter/buffersink.h
@@ -0,0 +1,62 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVFILTER_BUFFERSINK_H
+#define AVFILTER_BUFFERSINK_H
+
+/**
+ * @file
+ * memory buffer sink API
+ */
+
+#include "avfilter.h"
+
+/**
+ * Get a buffer with filtered data from sink and put it in buf.
+ *
+ * @param sink pointer to a context of a buffersink or abuffersink AVFilter.
+ * @param buf pointer to the buffer will be written here if buf is non-NULL. buf
+ * must be freed by the caller using avfilter_unref_buffer().
+ * Buf may also be NULL to query whether a buffer is ready to be
+ * output.
+ *
+ * @return >= 0 in case of success, a negative AVERROR code in case of
+ * failure.
+ */
+int av_buffersink_read(AVFilterContext *sink, AVFilterBufferRef **buf);
+
+/**
+ * Same as av_buffersink_read, but with the ability to specify the number of
+ * samples read. This function is less efficient than av_buffersink_read(),
+ * because it copies the data around.
+ *
+ * @param sink pointer to a context of the abuffersink AVFilter.
+ * @param buf pointer to the buffer will be written here if buf is non-NULL. buf
+ * must be freed by the caller using avfilter_unref_buffer(). buf
+ * will contain exactly nb_samples audio samples, except at the end
+ * of stream, when it can contain less than nb_samples.
+ * Buf may also be NULL to query whether a buffer is ready to be
+ * output.
+ *
+ * @warning do not mix this function with av_buffersink_read(). Use only one or
+ * the other with a single sink, not both.
+ */
+int av_buffersink_read_samples(AVFilterContext *ctx, AVFilterBufferRef **buf,
+ int nb_samples);
+
+#endif /* AVFILTER_BUFFERSINK_H */
diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c
new file mode 100644
index 0000000..0b9d5d0
--- /dev/null
+++ b/libavfilter/buffersrc.c
@@ -0,0 +1,384 @@
+/*
+ * Copyright (c) 2008 Vitor Sessak
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * memory buffer source filter
+ */
+
+#include "audio.h"
+#include "avfilter.h"
+#include "buffersrc.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
+
+#include "libavutil/audioconvert.h"
+#include "libavutil/fifo.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
+#include "libavutil/samplefmt.h"
+
+typedef struct {
+ const AVClass *class;
+ AVFifoBuffer *fifo;
+ AVRational time_base; ///< time_base to set in the output link
+
+ /* video only */
+ int h, w;
+ enum PixelFormat pix_fmt;
+ AVRational pixel_aspect;
+
+ /* audio only */
+ int sample_rate;
+ enum AVSampleFormat sample_fmt;
+ char *sample_fmt_str;
+ uint64_t channel_layout;
+ char *channel_layout_str;
+
+ int eof;
+} BufferSourceContext;
+
+#define CHECK_VIDEO_PARAM_CHANGE(s, c, width, height, format)\
+ if (c->w != width || c->h != height || c->pix_fmt != format) {\
+ av_log(s, AV_LOG_ERROR, "Changing frame properties on the fly is not supported.\n");\
+ return AVERROR(EINVAL);\
+ }
+
+#define CHECK_AUDIO_PARAM_CHANGE(s, c, srate, ch_layout, format)\
+ if (c->sample_fmt != format || c->sample_rate != srate ||\
+ c->channel_layout != ch_layout) {\
+ av_log(s, AV_LOG_ERROR, "Changing frame properties on the fly is not supported.\n");\
+ return AVERROR(EINVAL);\
+ }
+
+int av_buffersrc_write_frame(AVFilterContext *buffer_filter, AVFrame *frame)
+{
+ BufferSourceContext *c = buffer_filter->priv;
+ AVFilterBufferRef *buf;
+ int ret;
+
+ if (!frame) {
+ c->eof = 1;
+ return 0;
+ } else if (c->eof)
+ return AVERROR(EINVAL);
+
+ if (!av_fifo_space(c->fifo) &&
+ (ret = av_fifo_realloc2(c->fifo, av_fifo_size(c->fifo) +
+ sizeof(buf))) < 0)
+ return ret;
+
+ switch (buffer_filter->outputs[0]->type) {
+ case AVMEDIA_TYPE_VIDEO:
+ CHECK_VIDEO_PARAM_CHANGE(buffer_filter, c, frame->width, frame->height,
+ frame->format);
+ buf = ff_get_video_buffer(buffer_filter->outputs[0], AV_PERM_WRITE,
+ c->w, c->h);
+ av_image_copy(buf->data, buf->linesize, frame->data, frame->linesize,
+ c->pix_fmt, c->w, c->h);
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ CHECK_AUDIO_PARAM_CHANGE(buffer_filter, c, frame->sample_rate, frame->channel_layout,
+ frame->format);
+ buf = ff_get_audio_buffer(buffer_filter->outputs[0], AV_PERM_WRITE,
+ frame->nb_samples);
+ av_samples_copy(buf->extended_data, frame->extended_data,
+ 0, 0, frame->nb_samples,
+ av_get_channel_layout_nb_channels(frame->channel_layout),
+ frame->format);
+ break;
+ default:
+ return AVERROR(EINVAL);
+ }
+
+ avfilter_copy_frame_props(buf, frame);
+
+ if ((ret = av_fifo_generic_write(c->fifo, &buf, sizeof(buf), NULL)) < 0) {
+ avfilter_unref_buffer(buf);
+ return ret;
+ }
+
+ return 0;
+}
+
+int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf)
+{
+ BufferSourceContext *c = s->priv;
+ int ret;
+
+ if (!buf) {
+ c->eof = 1;
+ return 0;
+ } else if (c->eof)
+ return AVERROR(EINVAL);
+
+ if (!av_fifo_space(c->fifo) &&
+ (ret = av_fifo_realloc2(c->fifo, av_fifo_size(c->fifo) +
+ sizeof(buf))) < 0)
+ return ret;
+
+ switch (s->outputs[0]->type) {
+ case AVMEDIA_TYPE_VIDEO:
+ CHECK_VIDEO_PARAM_CHANGE(s, c, buf->video->w, buf->video->h, buf->format);
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ CHECK_AUDIO_PARAM_CHANGE(s, c, buf->audio->sample_rate, buf->audio->channel_layout,
+ buf->format);
+ break;
+ default:
+ return AVERROR(EINVAL);
+ }
+
+ if ((ret = av_fifo_generic_write(c->fifo, &buf, sizeof(buf), NULL)) < 0)
+ return ret;
+
+ return 0;
+}
+
+static av_cold int init_video(AVFilterContext *ctx, const char *args)
+{
+ BufferSourceContext *c = ctx->priv;
+ char pix_fmt_str[128];
+ int n = 0;
+
+ if (!args ||
+ (n = sscanf(args, "%d:%d:%127[^:]:%d:%d:%d:%d", &c->w, &c->h, pix_fmt_str,
+ &c->time_base.num, &c->time_base.den,
+ &c->pixel_aspect.num, &c->pixel_aspect.den)) != 7) {
+ av_log(ctx, AV_LOG_ERROR, "Expected 7 arguments, but %d found in '%s'\n", n, args);
+ return AVERROR(EINVAL);
+ }
+ if ((c->pix_fmt = av_get_pix_fmt(pix_fmt_str)) == PIX_FMT_NONE) {
+ char *tail;
+ c->pix_fmt = strtol(pix_fmt_str, &tail, 10);
+ if (*tail || c->pix_fmt < 0 || c->pix_fmt >= PIX_FMT_NB) {
+ av_log(ctx, AV_LOG_ERROR, "Invalid pixel format string '%s'\n", pix_fmt_str);
+ return AVERROR(EINVAL);
+ }
+ }
+
+ if (!(c->fifo = av_fifo_alloc(sizeof(AVFilterBufferRef*))))
+ return AVERROR(ENOMEM);
+
+ av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d pixfmt:%s\n", c->w, c->h, av_pix_fmt_descriptors[c->pix_fmt].name);
+ return 0;
+}
+
+#define OFFSET(x) offsetof(BufferSourceContext, x)
+#define A AV_OPT_FLAG_AUDIO_PARAM
+static const AVOption audio_options[] = {
+ { "time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, { 0 }, 0, INT_MAX, A },
+ { "sample_rate", NULL, OFFSET(sample_rate), AV_OPT_TYPE_INT, { 0 }, 0, INT_MAX, A },
+ { "sample_fmt", NULL, OFFSET(sample_fmt_str), AV_OPT_TYPE_STRING, .flags = A },
+ { "channel_layout", NULL, OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, .flags = A },
+ { NULL },
+};
+
+static const AVClass abuffer_class = {
+ .class_name = "abuffer source",
+ .item_name = av_default_item_name,
+ .option = audio_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+static av_cold int init_audio(AVFilterContext *ctx, const char *args)
+{
+ BufferSourceContext *s = ctx->priv;
+ int ret = 0;
+
+ s->class = &abuffer_class;
+ av_opt_set_defaults(s);
+
+ if ((ret = av_set_options_string(s, args, "=", ":")) < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Error parsing options string: %s.\n", args);
+ goto fail;
+ }
+
+ s->sample_fmt = av_get_sample_fmt(s->sample_fmt_str);
+ if (s->sample_fmt == AV_SAMPLE_FMT_NONE) {
+ av_log(ctx, AV_LOG_ERROR, "Invalid sample format %s.\n",
+ s->sample_fmt_str);
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+
+ s->channel_layout = av_get_channel_layout(s->channel_layout_str);
+ if (!s->channel_layout) {
+ av_log(ctx, AV_LOG_ERROR, "Invalid channel layout %s.\n",
+ s->channel_layout_str);
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+
+ if (!(s->fifo = av_fifo_alloc(sizeof(AVFilterBufferRef*)))) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ if (!s->time_base.num)
+ s->time_base = (AVRational){1, s->sample_rate};
+
+ av_log(ctx, AV_LOG_VERBOSE, "tb:%d/%d samplefmt:%s samplerate: %d "
+ "ch layout:%s\n", s->time_base.num, s->time_base.den, s->sample_fmt_str,
+ s->sample_rate, s->channel_layout_str);
+
+fail:
+ av_opt_free(s);
+ return ret;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+ BufferSourceContext *s = ctx->priv;
+ while (s->fifo && av_fifo_size(s->fifo)) {
+ AVFilterBufferRef *buf;
+ av_fifo_generic_read(s->fifo, &buf, sizeof(buf), NULL);
+ avfilter_unref_buffer(buf);
+ }
+ av_fifo_free(s->fifo);
+ s->fifo = NULL;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+ BufferSourceContext *c = ctx->priv;
+ AVFilterChannelLayouts *channel_layouts = NULL;
+ AVFilterFormats *formats = NULL;
+ AVFilterFormats *samplerates = NULL;
+
+ switch (ctx->outputs[0]->type) {
+ case AVMEDIA_TYPE_VIDEO:
+ ff_add_format(&formats, c->pix_fmt);
+ ff_set_common_formats(ctx, formats);
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ ff_add_format(&formats, c->sample_fmt);
+ ff_set_common_formats(ctx, formats);
+
+ ff_add_format(&samplerates, c->sample_rate);
+ ff_set_common_samplerates(ctx, samplerates);
+
+ ff_add_channel_layout(&channel_layouts, c->channel_layout);
+ ff_set_common_channel_layouts(ctx, channel_layouts);
+ break;
+ default:
+ return AVERROR(EINVAL);
+ }
+
+ return 0;
+}
+
+static int config_props(AVFilterLink *link)
+{
+ BufferSourceContext *c = link->src->priv;
+
+ switch (link->type) {
+ case AVMEDIA_TYPE_VIDEO:
+ link->w = c->w;
+ link->h = c->h;
+ link->sample_aspect_ratio = c->pixel_aspect;
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ link->channel_layout = c->channel_layout;
+ link->sample_rate = c->sample_rate;
+ break;
+ default:
+ return AVERROR(EINVAL);
+ }
+
+ link->time_base = c->time_base;
+ return 0;
+}
+
+static int request_frame(AVFilterLink *link)
+{
+ BufferSourceContext *c = link->src->priv;
+ AVFilterBufferRef *buf;
+
+ if (!av_fifo_size(c->fifo)) {
+ if (c->eof)
+ return AVERROR_EOF;
+ return AVERROR(EAGAIN);
+ }
+ av_fifo_generic_read(c->fifo, &buf, sizeof(buf), NULL);
+
+ switch (link->type) {
+ case AVMEDIA_TYPE_VIDEO:
+ ff_start_frame(link, avfilter_ref_buffer(buf, ~0));
+ ff_draw_slice(link, 0, link->h, 1);
+ ff_end_frame(link);
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ ff_filter_samples(link, avfilter_ref_buffer(buf, ~0));
+ break;
+ default:
+ return AVERROR(EINVAL);
+ }
+
+ avfilter_unref_buffer(buf);
+
+ return 0;
+}
+
+static int poll_frame(AVFilterLink *link)
+{
+ BufferSourceContext *c = link->src->priv;
+ int size = av_fifo_size(c->fifo);
+ if (!size && c->eof)
+ return AVERROR_EOF;
+ return size/sizeof(AVFilterBufferRef*);
+}
+
+AVFilter avfilter_vsrc_buffer = {
+ .name = "buffer",
+ .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them accessible to the filterchain."),
+ .priv_size = sizeof(BufferSourceContext),
+ .query_formats = query_formats,
+
+ .init = init_video,
+ .uninit = uninit,
+
+ .inputs = (AVFilterPad[]) {{ .name = NULL }},
+ .outputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .request_frame = request_frame,
+ .poll_frame = poll_frame,
+ .config_props = config_props, },
+ { .name = NULL}},
+};
+
+AVFilter avfilter_asrc_abuffer = {
+ .name = "abuffer",
+ .description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them accessible to the filterchain."),
+ .priv_size = sizeof(BufferSourceContext),
+ .query_formats = query_formats,
+
+ .init = init_audio,
+ .uninit = uninit,
+
+ .inputs = (AVFilterPad[]) {{ .name = NULL }},
+ .outputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .request_frame = request_frame,
+ .poll_frame = poll_frame,
+ .config_props = config_props, },
+ { .name = NULL}},
+};
diff --git a/libavfilter/buffersrc.h b/libavfilter/buffersrc.h
index 918a54f..ca82a75 100644
--- a/libavfilter/buffersrc.h
+++ b/libavfilter/buffersrc.h
@@ -36,4 +36,15 @@
*/
int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf);
+/**
+ * Add a frame to the buffer source.
+ *
+ * @param s an instance of the buffersrc filter.
+ * @param frame frame to be added.
+ *
+ * @warning frame data will be memcpy()ed, which may be a big performance
+ * hit. Use av_buffersrc_buffer() to avoid copying the data.
+ */
+int av_buffersrc_write_frame(AVFilterContext *s, AVFrame *frame);
+
#endif /* AVFILTER_BUFFERSRC_H */
diff --git a/libavfilter/defaults.c b/libavfilter/defaults.c
deleted file mode 100644
index 6d9003d..0000000
--- a/libavfilter/defaults.c
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Filter layer - default implementations
- * Copyright (c) 2007 Bobby Bingham
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "libavutil/audioconvert.h"
-#include "libavutil/imgutils.h"
-#include "libavutil/samplefmt.h"
-#include "avfilter.h"
-#include "internal.h"
-
-/* TODO: buffer pool. see comment for avfilter_default_get_video_buffer() */
-void ff_avfilter_default_free_buffer(AVFilterBuffer *ptr)
-{
- av_free(ptr->data[0]);
- av_free(ptr);
-}
-
-/* TODO: set the buffer's priv member to a context structure for the whole
- * filter chain. This will allow for a buffer pool instead of the constant
- * alloc & free cycle currently implemented. */
-AVFilterBufferRef *avfilter_default_get_video_buffer(AVFilterLink *link, int perms, int w, int h)
-{
- int linesize[4];
- uint8_t *data[4];
- AVFilterBufferRef *picref = NULL;
-
- // +2 is needed for swscaler, +16 to be SIMD-friendly
- if (av_image_alloc(data, linesize, w, h, link->format, 16) < 0)
- return NULL;
-
- picref = avfilter_get_video_buffer_ref_from_arrays(data, linesize,
- perms, w, h, link->format);
- if (!picref) {
- av_free(data[0]);
- return NULL;
- }
-
- return picref;
-}
-
-AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int perms,
- enum AVSampleFormat sample_fmt, int size,
- uint64_t channel_layout, int planar)
-{
- AVFilterBuffer *samples = av_mallocz(sizeof(AVFilterBuffer));
- AVFilterBufferRef *ref = NULL;
- int i, sample_size, chans_nb, bufsize, per_channel_size, step_size = 0;
- char *buf;
-
- if (!samples || !(ref = av_mallocz(sizeof(AVFilterBufferRef))))
- goto fail;
-
- ref->buf = samples;
- ref->format = sample_fmt;
-
- ref->audio = av_mallocz(sizeof(AVFilterBufferRefAudioProps));
- if (!ref->audio)
- goto fail;
-
- ref->audio->channel_layout = channel_layout;
- ref->audio->size = size;
- ref->audio->planar = planar;
-
- /* make sure the buffer gets read permission or it's useless for output */
- ref->perms = perms | AV_PERM_READ;
-
- samples->refcount = 1;
- samples->free = ff_avfilter_default_free_buffer;
-
- sample_size = av_get_bytes_per_sample(sample_fmt);
- chans_nb = av_get_channel_layout_nb_channels(channel_layout);
-
- per_channel_size = size/chans_nb;
- ref->audio->nb_samples = per_channel_size/sample_size;
-
- /* Set the number of bytes to traverse to reach next sample of a particular channel:
- * For planar, this is simply the sample size.
- * For packed, this is the number of samples * sample_size.
- */
- for (i = 0; i < chans_nb; i++)
- samples->linesize[i] = planar > 0 ? per_channel_size : sample_size;
- memset(&samples->linesize[chans_nb], 0, (8-chans_nb) * sizeof(samples->linesize[0]));
-
- /* Calculate total buffer size, round to multiple of 16 to be SIMD friendly */
- bufsize = (size + 15)&~15;
- buf = av_malloc(bufsize);
- if (!buf)
- goto fail;
-
- /* For planar, set the start point of each channel's data within the buffer
- * For packed, set the start point of the entire buffer only
- */
- samples->data[0] = buf;
- if (buf && planar) {
- for (i = 1; i < chans_nb; i++) {
- step_size += per_channel_size;
- samples->data[i] = buf + step_size;
- }
- } else {
- for (i = 1; i < chans_nb; i++)
- samples->data[i] = buf;
- }
-
- memset(&samples->data[chans_nb], 0, (8-chans_nb) * sizeof(samples->data[0]));
-
- memcpy(ref->data, samples->data, sizeof(ref->data));
- memcpy(ref->linesize, samples->linesize, sizeof(ref->linesize));
-
- return ref;
-
-fail:
- if (ref)
- av_free(ref->audio);
- av_free(ref);
- av_free(samples);
- return NULL;
-}
-
-void avfilter_default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
-{
- AVFilterLink *outlink = NULL;
-
- if (inlink->dst->output_count)
- outlink = inlink->dst->outputs[0];
-
- if (outlink) {
- outlink->out_buf = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
- avfilter_copy_buffer_ref_props(outlink->out_buf, picref);
- avfilter_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0));
- }
-}
-
-void avfilter_default_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
-{
- AVFilterLink *outlink = NULL;
-
- if (inlink->dst->output_count)
- outlink = inlink->dst->outputs[0];
-
- if (outlink)
- avfilter_draw_slice(outlink, y, h, slice_dir);
-}
-
-void avfilter_default_end_frame(AVFilterLink *inlink)
-{
- AVFilterLink *outlink = NULL;
-
- if (inlink->dst->output_count)
- outlink = inlink->dst->outputs[0];
-
- avfilter_unref_buffer(inlink->cur_buf);
- inlink->cur_buf = NULL;
-
- if (outlink) {
- if (outlink->out_buf) {
- avfilter_unref_buffer(outlink->out_buf);
- outlink->out_buf = NULL;
- }
- avfilter_end_frame(outlink);
- }
-}
-
-/* FIXME: samplesref is same as link->cur_buf. Need to consider removing the redundant parameter. */
-void avfilter_default_filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesref)
-{
- AVFilterLink *outlink = NULL;
-
- if (inlink->dst->output_count)
- outlink = inlink->dst->outputs[0];
-
- if (outlink) {
- outlink->out_buf = avfilter_default_get_audio_buffer(inlink, AV_PERM_WRITE, samplesref->format,
- samplesref->audio->size,
- samplesref->audio->channel_layout,
- samplesref->audio->planar);
- outlink->out_buf->pts = samplesref->pts;
- outlink->out_buf->audio->sample_rate = samplesref->audio->sample_rate;
- avfilter_filter_samples(outlink, avfilter_ref_buffer(outlink->out_buf, ~0));
- avfilter_unref_buffer(outlink->out_buf);
- outlink->out_buf = NULL;
- }
- avfilter_unref_buffer(samplesref);
- inlink->cur_buf = NULL;
-}
-
-/**
- * default config_link() implementation for output video links to simplify
- * the implementation of one input one output video filters */
-int avfilter_default_config_output_link(AVFilterLink *link)
-{
- if (link->src->input_count && link->src->inputs[0]) {
- if (link->type == AVMEDIA_TYPE_VIDEO) {
- link->w = link->src->inputs[0]->w;
- link->h = link->src->inputs[0]->h;
- link->time_base = link->src->inputs[0]->time_base;
- } else if (link->type == AVMEDIA_TYPE_AUDIO) {
- link->channel_layout = link->src->inputs[0]->channel_layout;
- link->sample_rate = link->src->inputs[0]->sample_rate;
- }
- } else {
- /* XXX: any non-simple filter which would cause this branch to be taken
- * really should implement its own config_props() for this link. */
- return -1;
- }
-
- return 0;
-}
-
-/**
- * A helper for query_formats() which sets all links to the same list of
- * formats. If there are no links hooked to this filter, the list of formats is
- * freed.
- *
- * FIXME: this will need changed for filters with a mix of pad types
- * (video + audio, etc)
- */
-void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
-{
- int count = 0, i;
-
- for (i = 0; i < ctx->input_count; i++) {
- if (ctx->inputs[i]) {
- avfilter_formats_ref(formats, &ctx->inputs[i]->out_formats);
- count++;
- }
- }
- for (i = 0; i < ctx->output_count; i++) {
- if (ctx->outputs[i]) {
- avfilter_formats_ref(formats, &ctx->outputs[i]->in_formats);
- count++;
- }
- }
-
- if (!count) {
- av_free(formats->formats);
- av_free(formats->refs);
- av_free(formats);
- }
-}
-
-int avfilter_default_query_formats(AVFilterContext *ctx)
-{
- enum AVMediaType type = ctx->inputs && ctx->inputs [0] ? ctx->inputs [0]->type :
- ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
- AVMEDIA_TYPE_VIDEO;
-
- avfilter_set_common_formats(ctx, avfilter_all_formats(type));
- return 0;
-}
-
-void avfilter_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
-{
- avfilter_start_frame(link->dst->outputs[0], picref);
-}
-
-void avfilter_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
-{
- avfilter_draw_slice(link->dst->outputs[0], y, h, slice_dir);
-}
-
-void avfilter_null_end_frame(AVFilterLink *link)
-{
- avfilter_end_frame(link->dst->outputs[0]);
-}
-
-void avfilter_null_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
-{
- avfilter_filter_samples(link->dst->outputs[0], samplesref);
-}
-
-AVFilterBufferRef *avfilter_null_get_video_buffer(AVFilterLink *link, int perms, int w, int h)
-{
- return avfilter_get_video_buffer(link->dst->outputs[0], perms, w, h);
-}
-
-AVFilterBufferRef *avfilter_null_get_audio_buffer(AVFilterLink *link, int perms,
- enum AVSampleFormat sample_fmt, int size,
- uint64_t channel_layout, int packed)
-{
- return avfilter_get_audio_buffer(link->dst->outputs[0], perms, sample_fmt,
- size, channel_layout, packed);
-}
diff --git a/libavfilter/fifo.c b/libavfilter/fifo.c
new file mode 100644
index 0000000..234df7f
--- /dev/null
+++ b/libavfilter/fifo.c
@@ -0,0 +1,294 @@
+/*
+ * Copyright (c) 2007 Bobby Bingham
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * FIFO buffering filter
+ */
+
+#include "libavutil/avassert.h"
+#include "libavutil/audioconvert.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/samplefmt.h"
+
+#include "audio.h"
+#include "avfilter.h"
+#include "internal.h"
+#include "video.h"
+
+typedef struct Buf {
+ AVFilterBufferRef *buf;
+ struct Buf *next;
+} Buf;
+
+typedef struct {
+ Buf root;
+ Buf *last; ///< last buffered frame
+
+ /**
+ * When a specific number of output samples is requested, the partial
+ * buffer is stored here
+ */
+ AVFilterBufferRef *buf_out;
+ int allocated_samples; ///< number of samples buf_out was allocated for
+} FifoContext;
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+ FifoContext *fifo = ctx->priv;
+ fifo->last = &fifo->root;
+
+ return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+ FifoContext *fifo = ctx->priv;
+ Buf *buf, *tmp;
+
+ for (buf = fifo->root.next; buf; buf = tmp) {
+ tmp = buf->next;
+ avfilter_unref_buffer(buf->buf);
+ av_free(buf);
+ }
+
+ avfilter_unref_buffer(fifo->buf_out);
+}
+
+static void add_to_queue(AVFilterLink *inlink, AVFilterBufferRef *buf)
+{
+ FifoContext *fifo = inlink->dst->priv;
+
+ fifo->last->next = av_mallocz(sizeof(Buf));
+ fifo->last = fifo->last->next;
+ fifo->last->buf = buf;
+}
+
+static void queue_pop(FifoContext *s)
+{
+ Buf *tmp = s->root.next->next;
+ if (s->last == s->root.next)
+ s->last = &s->root;
+ av_freep(&s->root.next);
+ s->root.next = tmp;
+}
+
+static void end_frame(AVFilterLink *inlink) { }
+
+static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { }
+
+/**
+ * Move data pointers and pts offset samples forward.
+ */
+static void buffer_offset(AVFilterLink *link, AVFilterBufferRef *buf,
+ int offset)
+{
+ int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout);
+ int planar = av_sample_fmt_is_planar(link->format);
+ int planes = planar ? nb_channels : 1;
+ int block_align = av_get_bytes_per_sample(link->format) * (planar ? 1 : nb_channels);
+ int i;
+
+ av_assert0(buf->audio->nb_samples > offset);
+
+ for (i = 0; i < planes; i++)
+ buf->extended_data[i] += block_align*offset;
+ if (buf->data != buf->extended_data)
+ memcpy(buf->data, buf->extended_data,
+ FFMIN(planes, FF_ARRAY_ELEMS(buf->data)) * sizeof(*buf->data));
+ buf->linesize[0] -= block_align*offset;
+ buf->audio->nb_samples -= offset;
+
+ if (buf->pts != AV_NOPTS_VALUE) {
+ buf->pts += av_rescale_q(offset, (AVRational){1, link->sample_rate},
+ link->time_base);
+ }
+}
+
+static int calc_ptr_alignment(AVFilterBufferRef *buf)
+{
+ int planes = av_sample_fmt_is_planar(buf->format) ?
+ av_get_channel_layout_nb_channels(buf->audio->channel_layout) : 1;
+ int min_align = 128;
+ int p;
+
+ for (p = 0; p < planes; p++) {
+ int cur_align = 128;
+ while ((intptr_t)buf->extended_data[p] % cur_align)
+ cur_align >>= 1;
+ if (cur_align < min_align)
+ min_align = cur_align;
+ }
+ return min_align;
+}
+
+static int return_audio_frame(AVFilterContext *ctx)
+{
+ AVFilterLink *link = ctx->outputs[0];
+ FifoContext *s = ctx->priv;
+ AVFilterBufferRef *head = s->root.next->buf;
+ AVFilterBufferRef *buf_out;
+ int ret;
+
+ if (!s->buf_out &&
+ head->audio->nb_samples >= link->request_samples &&
+ calc_ptr_alignment(head) >= 32) {
+ if (head->audio->nb_samples == link->request_samples) {
+ buf_out = head;
+ queue_pop(s);
+ } else {
+ buf_out = avfilter_ref_buffer(head, AV_PERM_READ);
+ buf_out->audio->nb_samples = link->request_samples;
+ buffer_offset(link, head, link->request_samples);
+ }
+ } else {
+ int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout);
+
+ if (!s->buf_out) {
+ s->buf_out = ff_get_audio_buffer(link, AV_PERM_WRITE,
+ link->request_samples);
+ if (!s->buf_out)
+ return AVERROR(ENOMEM);
+
+ s->buf_out->audio->nb_samples = 0;
+ s->buf_out->pts = head->pts;
+ s->allocated_samples = link->request_samples;
+ } else if (link->request_samples != s->allocated_samples) {
+ av_log(ctx, AV_LOG_ERROR, "request_samples changed before the "
+ "buffer was returned.\n");
+ return AVERROR(EINVAL);
+ }
+
+ while (s->buf_out->audio->nb_samples < s->allocated_samples) {
+ int len = FFMIN(s->allocated_samples - s->buf_out->audio->nb_samples,
+ head->audio->nb_samples);
+
+ av_samples_copy(s->buf_out->extended_data, head->extended_data,
+ s->buf_out->audio->nb_samples, 0, len, nb_channels,
+ link->format);
+ s->buf_out->audio->nb_samples += len;
+
+ if (len == head->audio->nb_samples) {
+ avfilter_unref_buffer(head);
+ queue_pop(s);
+
+ if (!s->root.next &&
+ (ret = ff_request_frame(ctx->inputs[0])) < 0) {
+ if (ret == AVERROR_EOF) {
+ av_samples_set_silence(s->buf_out->extended_data,
+ s->buf_out->audio->nb_samples,
+ s->allocated_samples -
+ s->buf_out->audio->nb_samples,
+ nb_channels, link->format);
+ s->buf_out->audio->nb_samples = s->allocated_samples;
+ break;
+ }
+ return ret;
+ }
+ head = s->root.next->buf;
+ } else {
+ buffer_offset(link, head, len);
+ }
+ }
+ buf_out = s->buf_out;
+ s->buf_out = NULL;
+ }
+ ff_filter_samples(link, buf_out);
+
+ return 0;
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+ FifoContext *fifo = outlink->src->priv;
+ int ret;
+
+ if (!fifo->root.next) {
+ if ((ret = ff_request_frame(outlink->src->inputs[0])) < 0)
+ return ret;
+ }
+
+ /* by doing this, we give ownership of the reference to the next filter,
+ * so we don't have to worry about dereferencing it ourselves. */
+ switch (outlink->type) {
+ case AVMEDIA_TYPE_VIDEO:
+ ff_start_frame(outlink, fifo->root.next->buf);
+ ff_draw_slice (outlink, 0, outlink->h, 1);
+ ff_end_frame (outlink);
+ queue_pop(fifo);
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ if (outlink->request_samples) {
+ return return_audio_frame(outlink->src);
+ } else {
+ ff_filter_samples(outlink, fifo->root.next->buf);
+ queue_pop(fifo);
+ }
+ break;
+ default:
+ return AVERROR(EINVAL);
+ }
+
+ return 0;
+}
+
+AVFilter avfilter_vf_fifo = {
+ .name = "fifo",
+ .description = NULL_IF_CONFIG_SMALL("Buffer input images and send them when they are requested."),
+
+ .init = init,
+ .uninit = uninit,
+
+ .priv_size = sizeof(FifoContext),
+
+ .inputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .get_video_buffer= ff_null_get_video_buffer,
+ .start_frame = add_to_queue,
+ .draw_slice = draw_slice,
+ .end_frame = end_frame,
+ .rej_perms = AV_PERM_REUSE2, },
+ { .name = NULL}},
+ .outputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .request_frame = request_frame, },
+ { .name = NULL}},
+};
+
+AVFilter avfilter_af_afifo = {
+ .name = "afifo",
+ .description = NULL_IF_CONFIG_SMALL("Buffer input frames and send them when they are requested."),
+
+ .init = init,
+ .uninit = uninit,
+
+ .priv_size = sizeof(FifoContext),
+
+ .inputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .get_audio_buffer = ff_null_get_audio_buffer,
+ .filter_samples = add_to_queue,
+ .rej_perms = AV_PERM_REUSE2, },
+ { .name = NULL}},
+ .outputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .request_frame = request_frame, },
+ { .name = NULL}},
+};
diff --git a/libavfilter/filtfmts.c b/libavfilter/filtfmts.c
new file mode 100644
index 0000000..8b23c7b
--- /dev/null
+++ b/libavfilter/filtfmts.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2009 Stefano Sabatini
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdio.h>
+
+#include "libavformat/avformat.h"
+#include "libavutil/pixdesc.h"
+#include "libavfilter/avfilter.h"
+#include "libavfilter/formats.h"
+
+#undef fprintf
+#undef printf
+
+int main(int argc, char **argv)
+{
+ AVFilter *filter;
+ AVFilterContext *filter_ctx;
+ const char *filter_name;
+ const char *filter_args = NULL;
+ int i, j;
+
+ av_log_set_level(AV_LOG_DEBUG);
+
+ if (!argv[1]) {
+ fprintf(stderr, "Missing filter name as argument\n");
+ return 1;
+ }
+
+ filter_name = argv[1];
+ if (argv[2])
+ filter_args = argv[2];
+
+ avfilter_register_all();
+
+ /* get a corresponding filter and open it */
+ if (!(filter = avfilter_get_by_name(filter_name))) {
+ fprintf(stderr, "Unrecognized filter with name '%s'\n", filter_name);
+ return 1;
+ }
+
+ if (avfilter_open(&filter_ctx, filter, NULL) < 0) {
+ fprintf(stderr, "Impossible to open filter with name '%s'\n",
+ filter_name);
+ return 1;
+ }
+ if (avfilter_init_filter(filter_ctx, filter_args, NULL) < 0) {
+ fprintf(stderr, "Impossible to init filter '%s' with arguments '%s'\n",
+ filter_name, filter_args);
+ return 1;
+ }
+
+ /* create a link for each of the input pads */
+ for (i = 0; i < filter_ctx->input_count; i++) {
+ AVFilterLink *link = av_mallocz(sizeof(AVFilterLink));
+ link->type = filter_ctx->filter->inputs[i].type;
+ filter_ctx->inputs[i] = link;
+ }
+ for (i = 0; i < filter_ctx->output_count; i++) {
+ AVFilterLink *link = av_mallocz(sizeof(AVFilterLink));
+ link->type = filter_ctx->filter->outputs[i].type;
+ filter_ctx->outputs[i] = link;
+ }
+
+ if (filter->query_formats)
+ filter->query_formats(filter_ctx);
+ else
+ ff_default_query_formats(filter_ctx);
+
+ /* print the supported formats in input */
+ for (i = 0; i < filter_ctx->input_count; i++) {
+ AVFilterFormats *fmts = filter_ctx->inputs[i]->out_formats;
+ for (j = 0; j < fmts->format_count; j++)
+ printf("INPUT[%d] %s: %s\n",
+ i, filter_ctx->filter->inputs[i].name,
+ av_pix_fmt_descriptors[fmts->formats[j]].name);
+ }
+
+ /* print the supported formats in output */
+ for (i = 0; i < filter_ctx->output_count; i++) {
+ AVFilterFormats *fmts = filter_ctx->outputs[i]->in_formats;
+ for (j = 0; j < fmts->format_count; j++)
+ printf("OUTPUT[%d] %s: %s\n",
+ i, filter_ctx->filter->outputs[i].name,
+ av_pix_fmt_descriptors[fmts->formats[j]].name);
+ }
+
+ avfilter_free(filter_ctx);
+ fflush(stdout);
+ return 0;
+}
diff --git a/libavfilter/formats.c b/libavfilter/formats.c
index 78b0277..3ec6839 100644
--- a/libavfilter/formats.c
+++ b/libavfilter/formats.c
@@ -22,55 +22,132 @@
#include "libavutil/pixdesc.h"
#include "avfilter.h"
#include "internal.h"
+#include "formats.h"
/**
* Add all refs from a to ret and destroy a.
*/
-static void merge_ref(AVFilterFormats *ret, AVFilterFormats *a)
+#define MERGE_REF(ret, a, fmts, type, fail) \
+do { \
+ type ***tmp; \
+ int i; \
+ \
+ if (!(tmp = av_realloc(ret->refs, \
+ sizeof(*tmp) * (ret->refcount + a->refcount)))) \
+ goto fail; \
+ ret->refs = tmp; \
+ \
+ for (i = 0; i < a->refcount; i ++) { \
+ ret->refs[ret->refcount] = a->refs[i]; \
+ *ret->refs[ret->refcount++] = ret; \
+ } \
+ \
+ av_freep(&a->refs); \
+ av_freep(&a->fmts); \
+ av_freep(&a); \
+} while (0)
+
+/**
+ * Add all formats common for a and b to ret, copy the refs and destroy
+ * a and b.
+ */
+#define MERGE_FORMATS(ret, a, b, fmts, nb, type, fail) \
+do { \
+ int i, j, k = 0, count = FFMIN(a->nb, b->nb); \
+ \
+ if (!(ret = av_mallocz(sizeof(*ret)))) \
+ goto fail; \
+ \
+ if (count) { \
+ if (!(ret->fmts = av_malloc(sizeof(*ret->fmts) * count))) \
+ goto fail; \
+ for (i = 0; i < a->nb; i++) \
+ for (j = 0; j < b->nb; j++) \
+ if (a->fmts[i] == b->fmts[j]) \
+ ret->fmts[k++] = a->fmts[i]; \
+ \
+ ret->nb = k; \
+ } \
+ /* check that there was at least one common format */ \
+ if (!ret->nb) \
+ goto fail; \
+ \
+ MERGE_REF(ret, a, fmts, type, fail); \
+ MERGE_REF(ret, b, fmts, type, fail); \
+} while (0)
+
+AVFilterFormats *ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b)
{
- int i;
+ AVFilterFormats *ret = NULL;
- for(i = 0; i < a->refcount; i ++) {
- ret->refs[ret->refcount] = a->refs[i];
- *ret->refs[ret->refcount++] = ret;
- }
+ if (a == b)
+ return a;
+
+ MERGE_FORMATS(ret, a, b, formats, format_count, AVFilterFormats, fail);
- av_free(a->refs);
- av_free(a->formats);
- av_free(a);
+ return ret;
+fail:
+ if (ret) {
+ av_freep(&ret->refs);
+ av_freep(&ret->formats);
+ }
+ av_freep(&ret);
+ return NULL;
}
-AVFilterFormats *avfilter_merge_formats(AVFilterFormats *a, AVFilterFormats *b)
+AVFilterFormats *ff_merge_samplerates(AVFilterFormats *a,
+ AVFilterFormats *b)
{
- AVFilterFormats *ret;
- unsigned i, j, k = 0, m_count;
-
- ret = av_mallocz(sizeof(AVFilterFormats));
+ AVFilterFormats *ret = NULL;
- /* merge list of formats */
- m_count = FFMIN(a->format_count, b->format_count);
- if (m_count) {
- ret->formats = av_malloc(sizeof(*ret->formats) * m_count);
- for(i = 0; i < a->format_count; i ++)
- for(j = 0; j < b->format_count; j ++)
- if(a->formats[i] == b->formats[j])
- ret->formats[k++] = a->formats[i];
+ if (a == b) return a;
- ret->format_count = k;
- }
- /* check that there was at least one common format */
- if(!ret->format_count) {
- av_free(ret->formats);
- av_free(ret);
- return NULL;
+ if (a->format_count && b->format_count) {
+ MERGE_FORMATS(ret, a, b, formats, format_count, AVFilterFormats, fail);
+ } else if (a->format_count) {
+ MERGE_REF(a, b, formats, AVFilterFormats, fail);
+ ret = a;
+ } else {
+ MERGE_REF(b, a, formats, AVFilterFormats, fail);
+ ret = b;
}
- ret->refs = av_malloc(sizeof(AVFilterFormats**)*(a->refcount+b->refcount));
+ return ret;
+fail:
+ if (ret) {
+ av_freep(&ret->refs);
+ av_freep(&ret->formats);
+ }
+ av_freep(&ret);
+ return NULL;
+}
- merge_ref(ret, a);
- merge_ref(ret, b);
+AVFilterChannelLayouts *ff_merge_channel_layouts(AVFilterChannelLayouts *a,
+ AVFilterChannelLayouts *b)
+{
+ AVFilterChannelLayouts *ret = NULL;
+
+ if (a == b) return a;
+
+ if (a->nb_channel_layouts && b->nb_channel_layouts) {
+ MERGE_FORMATS(ret, a, b, channel_layouts, nb_channel_layouts,
+ AVFilterChannelLayouts, fail);
+ } else if (a->nb_channel_layouts) {
+ MERGE_REF(a, b, channel_layouts, AVFilterChannelLayouts, fail);
+ ret = a;
+ } else {
+ MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, fail);
+ ret = b;
+ }
return ret;
+fail:
+ if (ret) {
+ av_freep(&ret->refs);
+ av_freep(&ret->channel_layouts);
+ }
+ av_freep(&ret);
+ return NULL;
}
int ff_fmt_is_in(int fmt, const int *fmts)
@@ -84,7 +161,7 @@ int ff_fmt_is_in(int fmt, const int *fmts)
return 0;
}
-AVFilterFormats *avfilter_make_format_list(const int *fmts)
+AVFilterFormats *ff_make_format_list(const int *fmts)
{
AVFilterFormats *formats;
int count;
@@ -92,7 +169,7 @@ AVFilterFormats *avfilter_make_format_list(const int *fmts)
for (count = 0; fmts[count] != -1; count++)
;
- formats = av_mallocz(sizeof(AVFilterFormats));
+ formats = av_mallocz(sizeof(*formats));
if (count)
formats->formats = av_malloc(sizeof(*formats->formats) * count);
formats->format_count = count;
@@ -101,24 +178,34 @@ AVFilterFormats *avfilter_make_format_list(const int *fmts)
return formats;
}
-int avfilter_add_format(AVFilterFormats **avff, int fmt)
+#define ADD_FORMAT(f, fmt, type, list, nb) \
+do { \
+ type *fmts; \
+ \
+ if (!(*f) && !(*f = av_mallocz(sizeof(**f)))) \
+ return AVERROR(ENOMEM); \
+ \
+ fmts = av_realloc((*f)->list, \
+ sizeof(*(*f)->list) * ((*f)->nb + 1));\
+ if (!fmts) \
+ return AVERROR(ENOMEM); \
+ \
+ (*f)->list = fmts; \
+ (*f)->list[(*f)->nb++] = fmt; \
+ return 0; \
+} while (0)
+
+int ff_add_format(AVFilterFormats **avff, int fmt)
{
- int *fmts;
-
- if (!(*avff) && !(*avff = av_mallocz(sizeof(AVFilterFormats))))
- return AVERROR(ENOMEM);
-
- fmts = av_realloc((*avff)->formats,
- sizeof(*(*avff)->formats) * ((*avff)->format_count+1));
- if (!fmts)
- return AVERROR(ENOMEM);
+ ADD_FORMAT(avff, fmt, int, formats, format_count);
+}
- (*avff)->formats = fmts;
- (*avff)->formats[(*avff)->format_count++] = fmt;
- return 0;
+int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout)
+{
+ ADD_FORMAT(l, channel_layout, uint64_t, channel_layouts, nb_channel_layouts);
}
-AVFilterFormats *avfilter_all_formats(enum AVMediaType type)
+AVFilterFormats *ff_all_formats(enum AVMediaType type)
{
AVFilterFormats *ret = NULL;
int fmt;
@@ -128,56 +215,177 @@ AVFilterFormats *avfilter_all_formats(enum AVMediaType type)
for (fmt = 0; fmt < num_formats; fmt++)
if ((type != AVMEDIA_TYPE_VIDEO) ||
(type == AVMEDIA_TYPE_VIDEO && !(av_pix_fmt_descriptors[fmt].flags & PIX_FMT_HWACCEL)))
- avfilter_add_format(&ret, fmt);
+ ff_add_format(&ret, fmt);
return ret;
}
-void avfilter_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
+AVFilterFormats *ff_planar_sample_fmts(void)
{
- *ref = f;
- f->refs = av_realloc(f->refs, sizeof(AVFilterFormats**) * ++f->refcount);
- f->refs[f->refcount-1] = ref;
+ AVFilterFormats *ret = NULL;
+ int fmt;
+
+ for (fmt = 0; fmt < AV_SAMPLE_FMT_NB; fmt++)
+ if (av_sample_fmt_is_planar(fmt))
+ ff_add_format(&ret, fmt);
+
+ return ret;
}
-static int find_ref_index(AVFilterFormats **ref)
+AVFilterFormats *ff_all_samplerates(void)
{
- int i;
- for(i = 0; i < (*ref)->refcount; i ++)
- if((*ref)->refs[i] == ref)
- return i;
- return -1;
+ AVFilterFormats *ret = av_mallocz(sizeof(*ret));
+ return ret;
}
-void avfilter_formats_unref(AVFilterFormats **ref)
+AVFilterChannelLayouts *ff_all_channel_layouts(void)
{
- int idx;
+ AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
+ return ret;
+}
- if (!*ref)
- return;
+#define FORMATS_REF(f, ref) \
+do { \
+ *ref = f; \
+ f->refs = av_realloc(f->refs, sizeof(*f->refs) * ++f->refcount); \
+ f->refs[f->refcount-1] = ref; \
+} while (0)
- idx = find_ref_index(ref);
+void ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
+{
+ FORMATS_REF(f, ref);
+}
- if(idx >= 0)
- memmove((*ref)->refs + idx, (*ref)->refs + idx+1,
- sizeof(AVFilterFormats**) * ((*ref)->refcount-idx-1));
+void ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
+{
+ FORMATS_REF(f, ref);
+}
- if(!--(*ref)->refcount) {
- av_free((*ref)->formats);
- av_free((*ref)->refs);
- av_free(*ref);
- }
- *ref = NULL;
+#define FIND_REF_INDEX(ref, idx) \
+do { \
+ int i; \
+ for (i = 0; i < (*ref)->refcount; i ++) \
+ if((*ref)->refs[i] == ref) { \
+ idx = i; \
+ break; \
+ } \
+} while (0)
+
+#define FORMATS_UNREF(ref, list) \
+do { \
+ int idx = -1; \
+ \
+ if (!*ref) \
+ return; \
+ \
+ FIND_REF_INDEX(ref, idx); \
+ \
+ if (idx >= 0) \
+ memmove((*ref)->refs + idx, (*ref)->refs + idx + 1, \
+ sizeof(*(*ref)->refs) * ((*ref)->refcount - idx - 1)); \
+ \
+ if(!--(*ref)->refcount) { \
+ av_free((*ref)->list); \
+ av_free((*ref)->refs); \
+ av_free(*ref); \
+ } \
+ *ref = NULL; \
+} while (0)
+
+void ff_formats_unref(AVFilterFormats **ref)
+{
+ FORMATS_UNREF(ref, formats);
}
-void avfilter_formats_changeref(AVFilterFormats **oldref,
- AVFilterFormats **newref)
+void ff_channel_layouts_unref(AVFilterChannelLayouts **ref)
{
- int idx = find_ref_index(oldref);
+ FORMATS_UNREF(ref, channel_layouts);
+}
+
+#define FORMATS_CHANGEREF(oldref, newref) \
+do { \
+ int idx = -1; \
+ \
+ FIND_REF_INDEX(oldref, idx); \
+ \
+ if (idx >= 0) { \
+ (*oldref)->refs[idx] = newref; \
+ *newref = *oldref; \
+ *oldref = NULL; \
+ } \
+} while (0)
+
+void ff_channel_layouts_changeref(AVFilterChannelLayouts **oldref,
+ AVFilterChannelLayouts **newref)
+{
+ FORMATS_CHANGEREF(oldref, newref);
+}
+
+void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
+{
+ FORMATS_CHANGEREF(oldref, newref);
+}
+
+#define SET_COMMON_FORMATS(ctx, fmts, in_fmts, out_fmts, ref, list) \
+{ \
+ int count = 0, i; \
+ \
+ for (i = 0; i < ctx->nb_inputs; i++) { \
+ if (ctx->inputs[i]) { \
+ ref(fmts, &ctx->inputs[i]->out_fmts); \
+ count++; \
+ } \
+ } \
+ for (i = 0; i < ctx->nb_outputs; i++) { \
+ if (ctx->outputs[i]) { \
+ ref(fmts, &ctx->outputs[i]->in_fmts); \
+ count++; \
+ } \
+ } \
+ \
+ if (!count) { \
+ av_freep(&fmts->list); \
+ av_freep(&fmts->refs); \
+ av_freep(&fmts); \
+ } \
+}
- if(idx >= 0) {
- (*oldref)->refs[idx] = newref;
- *newref = *oldref;
- *oldref = NULL;
+void ff_set_common_channel_layouts(AVFilterContext *ctx,
+ AVFilterChannelLayouts *layouts)
+{
+ SET_COMMON_FORMATS(ctx, layouts, in_channel_layouts, out_channel_layouts,
+ ff_channel_layouts_ref, channel_layouts);
+}
+
+void ff_set_common_samplerates(AVFilterContext *ctx,
+ AVFilterFormats *samplerates)
+{
+ SET_COMMON_FORMATS(ctx, samplerates, in_samplerates, out_samplerates,
+ ff_formats_ref, formats);
+}
+
+/**
+ * A helper for query_formats() which sets all links to the same list of
+ * formats. If there are no links hooked to this filter, the list of formats is
+ * freed.
+ */
+void ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
+{
+ SET_COMMON_FORMATS(ctx, formats, in_formats, out_formats,
+ ff_formats_ref, formats);
+}
+
+int ff_default_query_formats(AVFilterContext *ctx)
+{
+ enum AVMediaType type = ctx->inputs && ctx->inputs [0] ? ctx->inputs [0]->type :
+ ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
+ AVMEDIA_TYPE_VIDEO;
+
+ ff_set_common_formats(ctx, ff_all_formats(type));
+ if (type == AVMEDIA_TYPE_AUDIO) {
+ ff_set_common_channel_layouts(ctx, ff_all_channel_layouts());
+ ff_set_common_samplerates(ctx, ff_all_samplerates());
}
+
+ return 0;
}
diff --git a/libavfilter/formats.h b/libavfilter/formats.h
new file mode 100644
index 0000000..0e1628c
--- /dev/null
+++ b/libavfilter/formats.h
@@ -0,0 +1,221 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVFILTER_FORMATS_H
+#define AVFILTER_FORMATS_H
+
+#include "avfilter.h"
+
+/**
+ * A list of supported formats for one end of a filter link. This is used
+ * during the format negotiation process to try to pick the best format to
+ * use to minimize the number of necessary conversions. Each filter gives a
+ * list of the formats supported by each input and output pad. The list
+ * given for each pad need not be distinct - they may be references to the
+ * same list of formats, as is often the case when a filter supports multiple
+ * formats, but will always output the same format as it is given in input.
+ *
+ * In this way, a list of possible input formats and a list of possible
+ * output formats are associated with each link. When a set of formats is
+ * negotiated over a link, the input and output lists are merged to form a
+ * new list containing only the common elements of each list. In the case
+ * that there were no common elements, a format conversion is necessary.
+ * Otherwise, the lists are merged, and all other links which reference
+ * either of the format lists involved in the merge are also affected.
+ *
+ * For example, consider the filter chain:
+ * filter (a) --> (b) filter (b) --> (c) filter
+ *
+ * where the letters in parenthesis indicate a list of formats supported on
+ * the input or output of the link. Suppose the lists are as follows:
+ * (a) = {A, B}
+ * (b) = {A, B, C}
+ * (c) = {B, C}
+ *
+ * First, the first link's lists are merged, yielding:
+ * filter (a) --> (a) filter (a) --> (c) filter
+ *
+ * Notice that format list (b) now refers to the same list as filter list (a).
+ * Next, the lists for the second link are merged, yielding:
+ * filter (a) --> (a) filter (a) --> (a) filter
+ *
+ * where (a) = {B}.
+ *
+ * Unfortunately, when the format lists at the two ends of a link are merged,
+ * we must ensure that all links which reference either pre-merge format list
+ * get updated as well. Therefore, we have the format list structure store a
+ * pointer to each of the pointers to itself.
+ */
+struct AVFilterFormats {
+ unsigned format_count; ///< number of formats
+ int *formats; ///< list of media formats
+
+ unsigned refcount; ///< number of references to this list
+ struct AVFilterFormats ***refs; ///< references to this list
+};
+
+typedef struct AVFilterChannelLayouts {
+ uint64_t *channel_layouts; ///< list of channel layouts
+ int nb_channel_layouts; ///< number of channel layouts
+
+ unsigned refcount; ///< number of references to this list
+ struct AVFilterChannelLayouts ***refs; ///< references to this list
+} AVFilterChannelLayouts;
+
+/**
+ * Return a channel layouts/samplerates list which contains the intersection of
+ * the layouts/samplerates of a and b. Also, all the references of a, all the
+ * references of b, and a and b themselves will be deallocated.
+ *
+ * If a and b do not share any common elements, neither is modified, and NULL
+ * is returned.
+ */
+AVFilterChannelLayouts *ff_merge_channel_layouts(AVFilterChannelLayouts *a,
+ AVFilterChannelLayouts *b);
+AVFilterFormats *ff_merge_samplerates(AVFilterFormats *a,
+ AVFilterFormats *b);
+
+/**
+ * Construct an empty AVFilterChannelLayouts/AVFilterFormats struct --
+ * representing any channel layout/sample rate.
+ */
+AVFilterChannelLayouts *ff_all_channel_layouts(void);
+AVFilterFormats *ff_all_samplerates(void);
+
+/**
+ * A helper for query_formats() which sets all links to the same list of channel
+ * layouts/sample rates. If there are no links hooked to this filter, the list
+ * is freed.
+ */
+void ff_set_common_channel_layouts(AVFilterContext *ctx,
+ AVFilterChannelLayouts *layouts);
+void ff_set_common_samplerates(AVFilterContext *ctx,
+ AVFilterFormats *samplerates);
+
+/**
+ * A helper for query_formats() which sets all links to the same list of
+ * formats. If there are no links hooked to this filter, the list of formats is
+ * freed.
+ */
+void ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats);
+
+int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout);
+
+/**
+ * Add *ref as a new reference to f.
+ */
+void ff_channel_layouts_ref(AVFilterChannelLayouts *f,
+ AVFilterChannelLayouts **ref);
+
+/**
+ * Remove a reference to a channel layouts list.
+ */
+void ff_channel_layouts_unref(AVFilterChannelLayouts **ref);
+
+void ff_channel_layouts_changeref(AVFilterChannelLayouts **oldref,
+ AVFilterChannelLayouts **newref);
+
+int ff_default_query_formats(AVFilterContext *ctx);
+
+
+/**
+ * Create a list of supported formats. This is intended for use in
+ * AVFilter->query_formats().
+ *
+ * @param fmts list of media formats, terminated by -1
+ * @return the format list, with no existing references
+ */
+AVFilterFormats *ff_make_format_list(const int *fmts);
+
+/**
+ * Add fmt to the list of media formats contained in *avff.
+ * If *avff is NULL the function allocates the filter formats struct
+ * and puts its pointer in *avff.
+ *
+ * @return a non negative value in case of success, or a negative
+ * value corresponding to an AVERROR code in case of error
+ */
+int ff_add_format(AVFilterFormats **avff, int fmt);
+
+/**
+ * Return a list of all formats supported by Libav for the given media type.
+ */
+AVFilterFormats *ff_all_formats(enum AVMediaType type);
+
+/**
+ * Construct a formats list containing all planar sample formats.
+ */
+AVFilterFormats *ff_planar_sample_fmts(void);
+
+/**
+ * Return a format list which contains the intersection of the formats of
+ * a and b. Also, all the references of a, all the references of b, and
+ * a and b themselves will be deallocated.
+ *
+ * If a and b do not share any common formats, neither is modified, and NULL
+ * is returned.
+ */
+AVFilterFormats *ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b);
+
+/**
+ * Add *ref as a new reference to formats.
+ * That is the pointers will point like in the ascii art below:
+ * ________
+ * |formats |<--------.
+ * | ____ | ____|___________________
+ * | |refs| | | __|_
+ * | |* * | | | | | | AVFilterLink
+ * | |* *--------->|*ref|
+ * | |____| | | |____|
+ * |________| |________________________
+ */
+void ff_formats_ref(AVFilterFormats *formats, AVFilterFormats **ref);
+
+/**
+ * If *ref is non-NULL, remove *ref as a reference to the format list
+ * it currently points to, deallocates that list if this was the last
+ * reference, and sets *ref to NULL.
+ *
+ * Before After
+ * ________ ________ NULL
+ * |formats |<--------. |formats | ^
+ * | ____ | ____|________________ | ____ | ____|________________
+ * | |refs| | | __|_ | |refs| | | __|_
+ * | |* * | | | | | | AVFilterLink | |* * | | | | | | AVFilterLink
+ * | |* *--------->|*ref| | |* | | | |*ref|
+ * | |____| | | |____| | |____| | | |____|
+ * |________| |_____________________ |________| |_____________________
+ */
+void ff_formats_unref(AVFilterFormats **ref);
+
+/**
+ *
+ * Before After
+ * ________ ________
+ * |formats |<---------. |formats |<---------.
+ * | ____ | ___|___ | ____ | ___|___
+ * | |refs| | | | | | |refs| | | | | NULL
+ * | |* *--------->|*oldref| | |* *--------->|*newref| ^
+ * | |* * | | |_______| | |* * | | |_______| ___|___
+ * | |____| | | |____| | | | |
+ * |________| |________| |*oldref|
+ * |_______|
+ */
+void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref);
+
+#endif /* AVFILTER_FORMATS_H */
diff --git a/libavfilter/gradfun.h b/libavfilter/gradfun.h
index 6b192a3..5d01130 100644
--- a/libavfilter/gradfun.h
+++ b/libavfilter/gradfun.h
@@ -37,12 +37,9 @@ typedef struct {
void (*blur_line) (uint16_t *dc, uint16_t *buf, uint16_t *buf1, uint8_t *src, int src_linesize, int width);
} GradFunContext;
+void ff_gradfun_init_x86(GradFunContext *gf);
+
void ff_gradfun_filter_line_c(uint8_t *dst, uint8_t *src, uint16_t *dc, int width, int thresh, const uint16_t *dithers);
void ff_gradfun_blur_line_c(uint16_t *dc, uint16_t *buf, uint16_t *buf1, uint8_t *src, int src_linesize, int width);
-void ff_gradfun_filter_line_mmx2(uint8_t *dst, uint8_t *src, uint16_t *dc, int width, int thresh, const uint16_t *dithers);
-void ff_gradfun_filter_line_ssse3(uint8_t *dst, uint8_t *src, uint16_t *dc, int width, int thresh, const uint16_t *dithers);
-
-void ff_gradfun_blur_line_sse2(uint16_t *dc, uint16_t *buf, uint16_t *buf1, uint8_t *src, int src_linesize, int width);
-
#endif /* AVFILTER_GRADFUN_H */
diff --git a/libavfilter/graphparser.c b/libavfilter/graphparser.c
index b3f295f..4915529 100644
--- a/libavfilter/graphparser.c
+++ b/libavfilter/graphparser.c
@@ -226,7 +226,7 @@ static int link_filter_inouts(AVFilterContext *filt_ctx,
{
int pad, ret;
- for (pad = 0; pad < filt_ctx->input_count; pad++) {
+ for (pad = 0; pad < filt_ctx->nb_inputs; pad++) {
AVFilterInOut *p = *curr_inputs;
if (p) {
@@ -254,7 +254,7 @@ static int link_filter_inouts(AVFilterContext *filt_ctx,
return AVERROR(EINVAL);
}
- pad = filt_ctx->output_count;
+ pad = filt_ctx->nb_outputs;
while (pad--) {
AVFilterInOut *currlinkn = av_mallocz(sizeof(AVFilterInOut));
if (!currlinkn)
@@ -350,12 +350,6 @@ static int parse_outputs(const char **buf, AVFilterInOut **curr_inputs,
return pad;
}
-#if FF_API_GRAPH_AVCLASS
-#define log_ctx graph
-#else
-#define log_ctx NULL
-#endif
-
static int parse_sws_flags(const char **buf, AVFilterGraph *graph)
{
char *p = strchr(*buf, ';');
@@ -364,7 +358,7 @@ static int parse_sws_flags(const char **buf, AVFilterGraph *graph)
return 0;
if (!p) {
- av_log(log_ctx, AV_LOG_ERROR, "sws_flags not terminated with ';'.\n");
+ av_log(graph, AV_LOG_ERROR, "sws_flags not terminated with ';'.\n");
return AVERROR(EINVAL);
}
@@ -397,18 +391,18 @@ int avfilter_graph_parse2(AVFilterGraph *graph, const char *filters,
AVFilterContext *filter;
filters += strspn(filters, WHITESPACES);
- if ((ret = parse_inputs(&filters, &curr_inputs, &open_outputs, log_ctx)) < 0)
+ if ((ret = parse_inputs(&filters, &curr_inputs, &open_outputs, graph)) < 0)
goto fail;
- if ((ret = parse_filter(&filter, &filters, graph, index, log_ctx)) < 0)
+ if ((ret = parse_filter(&filter, &filters, graph, index, graph)) < 0)
goto fail;
- if ((ret = link_filter_inouts(filter, &curr_inputs, &open_inputs, log_ctx)) < 0)
+ if ((ret = link_filter_inouts(filter, &curr_inputs, &open_inputs, graph)) < 0)
goto fail;
if ((ret = parse_outputs(&filters, &curr_inputs, &open_inputs, &open_outputs,
- log_ctx)) < 0)
+ graph)) < 0)
goto fail;
filters += strspn(filters, WHITESPACES);
@@ -420,7 +414,7 @@ int avfilter_graph_parse2(AVFilterGraph *graph, const char *filters,
} while (chr == ',' || chr == ';');
if (chr) {
- av_log(log_ctx, AV_LOG_ERROR,
+ av_log(graph, AV_LOG_ERROR,
"Unable to parse graph description substring: \"%s\"\n",
filters - 1);
ret = AVERROR(EINVAL);
@@ -446,7 +440,6 @@ int avfilter_graph_parse2(AVFilterGraph *graph, const char *filters,
return ret;
}
-#undef log_ctx
int avfilter_graph_parse(AVFilterGraph *graph, const char *filters,
AVFilterInOut *open_inputs,
diff --git a/libavfilter/internal.h b/libavfilter/internal.h
index 0630e9b..954610e 100644
--- a/libavfilter/internal.h
+++ b/libavfilter/internal.h
@@ -25,29 +25,140 @@
*/
#include "avfilter.h"
-#include "avfiltergraph.h"
+#if !FF_API_AVFILTERPAD_PUBLIC
/**
- * Check for the validity of graph.
- *
- * A graph is considered valid if all its input and output pads are
- * connected.
- *
- * @return 0 in case of success, a negative value otherwise
+ * A filter pad used for either input or output.
*/
-int ff_avfilter_graph_check_validity(AVFilterGraph *graphctx, AVClass *log_ctx);
+struct AVFilterPad {
+ /**
+ * Pad name. The name is unique among inputs and among outputs, but an
+ * input may have the same name as an output. This may be NULL if this
+ * pad has no need to ever be referenced by name.
+ */
+ const char *name;
-/**
- * Configure all the links of graphctx.
- *
- * @return 0 in case of success, a negative value otherwise
- */
-int ff_avfilter_graph_config_links(AVFilterGraph *graphctx, AVClass *log_ctx);
+ /**
+ * AVFilterPad type.
+ */
+ enum AVMediaType type;
-/**
- * Configure the formats of all the links in the graph.
- */
-int ff_avfilter_graph_config_formats(AVFilterGraph *graphctx, AVClass *log_ctx);
+ /**
+ * Minimum required permissions on incoming buffers. Any buffer with
+ * insufficient permissions will be automatically copied by the filter
+ * system to a new buffer which provides the needed access permissions.
+ *
+ * Input pads only.
+ */
+ int min_perms;
+
+ /**
+ * Permissions which are not accepted on incoming buffers. Any buffer
+ * which has any of these permissions set will be automatically copied
+ * by the filter system to a new buffer which does not have those
+ * permissions. This can be used to easily disallow buffers with
+ * AV_PERM_REUSE.
+ *
+ * Input pads only.
+ */
+ int rej_perms;
+
+ /**
+ * Callback called before passing the first slice of a new frame. If
+ * NULL, the filter layer will default to storing a reference to the
+ * picture inside the link structure.
+ *
+ * Input video pads only.
+ */
+ void (*start_frame)(AVFilterLink *link, AVFilterBufferRef *picref);
+
+ /**
+ * Callback function to get a video buffer. If NULL, the filter system will
+ * use avfilter_default_get_video_buffer().
+ *
+ * Input video pads only.
+ */
+ AVFilterBufferRef *(*get_video_buffer)(AVFilterLink *link, int perms, int w, int h);
+
+ /**
+ * Callback function to get an audio buffer. If NULL, the filter system will
+ * use avfilter_default_get_audio_buffer().
+ *
+ * Input audio pads only.
+ */
+ AVFilterBufferRef *(*get_audio_buffer)(AVFilterLink *link, int perms,
+ int nb_samples);
+
+ /**
+ * Callback called after the slices of a frame are completely sent. If
+ * NULL, the filter layer will default to releasing the reference stored
+ * in the link structure during start_frame().
+ *
+ * Input video pads only.
+ */
+ void (*end_frame)(AVFilterLink *link);
+
+ /**
+ * Slice drawing callback. This is where a filter receives video data
+ * and should do its processing.
+ *
+ * Input video pads only.
+ */
+ void (*draw_slice)(AVFilterLink *link, int y, int height, int slice_dir);
+
+ /**
+ * Samples filtering callback. This is where a filter receives audio data
+ * and should do its processing.
+ *
+ * Input audio pads only.
+ */
+ void (*filter_samples)(AVFilterLink *link, AVFilterBufferRef *samplesref);
+
+ /**
+ * Frame poll callback. This returns the number of immediately available
+ * samples. It should return a positive value if the next request_frame()
+ * is guaranteed to return one frame (with no delay).
+ *
+ * Defaults to just calling the source poll_frame() method.
+ *
+ * Output pads only.
+ */
+ int (*poll_frame)(AVFilterLink *link);
+
+ /**
+ * Frame request callback. A call to this should result in at least one
+ * frame being output over the given link. This should return zero on
+ * success, and another value on error.
+ *
+ * Output pads only.
+ */
+ int (*request_frame)(AVFilterLink *link);
+
+ /**
+ * Link configuration callback.
+ *
+ * For output pads, this should set the link properties such as
+ * width/height. This should NOT set the format property - that is
+ * negotiated between filters by the filter system using the
+ * query_formats() callback before this function is called.
+ *
+ * For input pads, this should check the properties of the link, and update
+ * the filter's internal state as necessary.
+ *
+ * For both input and output filters, this should return zero on success,
+ * and another value on error.
+ */
+ int (*config_props)(AVFilterLink *link);
+
+ /**
+ * The filter expects a fifo to be inserted on its input link,
+ * typically because it has a delay.
+ *
+ * input pads only.
+ */
+ int needs_fifo;
+};
+#endif
/** default handler for freeing audio/video buffer when there are no references left */
void ff_avfilter_default_free_buffer(AVFilterBuffer *buf);
@@ -55,4 +166,64 @@ void ff_avfilter_default_free_buffer(AVFilterBuffer *buf);
/** Tell is a format is contained in the provided list terminated by -1. */
int ff_fmt_is_in(int fmt, const int *fmts);
+#define FF_DPRINTF_START(ctx, func) av_dlog(NULL, "%-16s: ", #func)
+
+void ff_dlog_link(void *ctx, AVFilterLink *link, int end);
+
+/**
+ * Insert a new pad.
+ *
+ * @param idx Insertion point. Pad is inserted at the end if this point
+ * is beyond the end of the list of pads.
+ * @param count Pointer to the number of pads in the list
+ * @param padidx_off Offset within an AVFilterLink structure to the element
+ * to increment when inserting a new pad causes link
+ * numbering to change
+ * @param pads Pointer to the pointer to the beginning of the list of pads
+ * @param links Pointer to the pointer to the beginning of the list of links
+ * @param newpad The new pad to add. A copy is made when adding.
+ */
+void ff_insert_pad(unsigned idx, unsigned *count, size_t padidx_off,
+ AVFilterPad **pads, AVFilterLink ***links,
+ AVFilterPad *newpad);
+
+/** Insert a new input pad for the filter. */
+static inline void ff_insert_inpad(AVFilterContext *f, unsigned index,
+ AVFilterPad *p)
+{
+ ff_insert_pad(index, &f->nb_inputs, offsetof(AVFilterLink, dstpad),
+ &f->input_pads, &f->inputs, p);
+#if FF_API_FOO_COUNT
+ f->input_count = f->nb_inputs;
+#endif
+}
+
+/** Insert a new output pad for the filter. */
+static inline void ff_insert_outpad(AVFilterContext *f, unsigned index,
+ AVFilterPad *p)
+{
+ ff_insert_pad(index, &f->nb_outputs, offsetof(AVFilterLink, srcpad),
+ &f->output_pads, &f->outputs, p);
+#if FF_API_FOO_COUNT
+ f->output_count = f->nb_outputs;
+#endif
+}
+
+/**
+ * Poll a frame from the filter chain.
+ *
+ * @param link the input link
+ * @return the number of immediately available frames, a negative
+ * number in case of error
+ */
+int ff_poll_frame(AVFilterLink *link);
+
+/**
+ * Request an input frame from the filter at the other end of the link.
+ *
+ * @param link the input link
+ * @return zero on success
+ */
+int ff_request_frame(AVFilterLink *link);
+
#endif /* AVFILTER_INTERNAL_H */
diff --git a/libavfilter/split.c b/libavfilter/split.c
new file mode 100644
index 0000000..f1c4b92
--- /dev/null
+++ b/libavfilter/split.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2007 Bobby Bingham
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * audio and video splitter
+ */
+
+#include "avfilter.h"
+#include "audio.h"
+#include "internal.h"
+#include "video.h"
+
+static int split_init(AVFilterContext *ctx, const char *args)
+{
+ int i, nb_outputs = 2;
+
+ if (args) {
+ nb_outputs = strtol(args, NULL, 0);
+ if (nb_outputs <= 0) {
+ av_log(ctx, AV_LOG_ERROR, "Invalid number of outputs specified: %d.\n",
+ nb_outputs);
+ return AVERROR(EINVAL);
+ }
+ }
+
+ for (i = 0; i < nb_outputs; i++) {
+ char name[32];
+ AVFilterPad pad = { 0 };
+
+ snprintf(name, sizeof(name), "output%d", i);
+ pad.type = ctx->filter->inputs[0].type;
+ pad.name = av_strdup(name);
+
+ ff_insert_outpad(ctx, i, &pad);
+ }
+
+ return 0;
+}
+
+static void split_uninit(AVFilterContext *ctx)
+{
+ int i;
+
+ for (i = 0; i < ctx->nb_outputs; i++)
+ av_freep(&ctx->output_pads[i].name);
+}
+
+static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
+{
+ AVFilterContext *ctx = inlink->dst;
+ int i;
+
+ for (i = 0; i < ctx->nb_outputs; i++)
+ ff_start_frame(ctx->outputs[i],
+ avfilter_ref_buffer(picref, ~AV_PERM_WRITE));
+}
+
+static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
+{
+ AVFilterContext *ctx = inlink->dst;
+ int i;
+
+ for (i = 0; i < ctx->nb_outputs; i++)
+ ff_draw_slice(ctx->outputs[i], y, h, slice_dir);
+}
+
+static void end_frame(AVFilterLink *inlink)
+{
+ AVFilterContext *ctx = inlink->dst;
+ int i;
+
+ for (i = 0; i < ctx->nb_outputs; i++)
+ ff_end_frame(ctx->outputs[i]);
+
+ avfilter_unref_buffer(inlink->cur_buf);
+}
+
+AVFilter avfilter_vf_split = {
+ .name = "split",
+ .description = NULL_IF_CONFIG_SMALL("Pass on the input to two outputs."),
+
+ .init = split_init,
+ .uninit = split_uninit,
+
+ .inputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .get_video_buffer= ff_null_get_video_buffer,
+ .start_frame = start_frame,
+ .draw_slice = draw_slice,
+ .end_frame = end_frame, },
+ { .name = NULL}},
+ .outputs = (AVFilterPad[]) {{ .name = NULL}},
+};
+
+static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesref)
+{
+ AVFilterContext *ctx = inlink->dst;
+ int i;
+
+ for (i = 0; i < ctx->nb_outputs; i++)
+ ff_filter_samples(inlink->dst->outputs[i],
+ avfilter_ref_buffer(samplesref, ~AV_PERM_WRITE));
+}
+
+AVFilter avfilter_af_asplit = {
+ .name = "asplit",
+ .description = NULL_IF_CONFIG_SMALL("Pass on the audio input to N audio outputs."),
+
+ .init = split_init,
+ .uninit = split_uninit,
+
+ .inputs = (const AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .get_audio_buffer = ff_null_get_audio_buffer,
+ .filter_samples = filter_samples },
+ { .name = NULL }},
+ .outputs = (const AVFilterPad[]) {{ .name = NULL }},
+};
diff --git a/libavfilter/version.h b/libavfilter/version.h
index 5d646e4..c1292bb 100644
--- a/libavfilter/version.h
+++ b/libavfilter/version.h
@@ -28,8 +28,8 @@
#include "libavutil/avutil.h"
-#define LIBAVFILTER_VERSION_MAJOR 2
-#define LIBAVFILTER_VERSION_MINOR 16
+#define LIBAVFILTER_VERSION_MAJOR 3
+#define LIBAVFILTER_VERSION_MINOR 0
#define LIBAVFILTER_VERSION_MICRO 0
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
@@ -41,11 +41,16 @@
#define LIBAVFILTER_BUILD LIBAVFILTER_VERSION_INT
/**
- * Those FF_API_* defines are not part of public API.
- * They may change, break or disappear at any time.
+ * FF_API_* defines may be placed below to indicate public API that will be
+ * dropped at a future version bump. The defines themselves are not part of
+ * the public API and may change, break or disappear at any time.
*/
-#ifndef FF_API_GRAPH_AVCLASS
-#define FF_API_GRAPH_AVCLASS (LIBAVFILTER_VERSION_MAJOR > 2)
+
+#ifndef FF_API_AVFILTERPAD_PUBLIC
+#define FF_API_AVFILTERPAD_PUBLIC (LIBAVFILTER_VERSION_MAJOR < 4)
+#endif
+#ifndef FF_API_FOO_COUNT
+#define FF_API_FOO_COUNT (LIBAVFILTER_VERSION_MAJOR < 4)
#endif
-#endif // AVFILTER_VERSION_H
+#endif /* AVFILTER_VERSION_H */
diff --git a/libavfilter/vf_aspect.c b/libavfilter/vf_aspect.c
index 9db29c7..4b58e5e 100644
--- a/libavfilter/vf_aspect.c
+++ b/libavfilter/vf_aspect.c
@@ -25,12 +25,14 @@
#include "libavutil/mathematics.h"
#include "avfilter.h"
+#include "internal.h"
+#include "video.h"
typedef struct {
AVRational aspect;
} AspectContext;
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
{
AspectContext *aspect = ctx->priv;
double ratio;
@@ -58,7 +60,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
if (aspect->aspect.den == 0)
aspect->aspect = (AVRational) {0, 1};
- av_log(ctx, AV_LOG_INFO, "a:%d/%d\n", aspect->aspect.num, aspect->aspect.den);
+ av_log(ctx, AV_LOG_VERBOSE, "a:%d/%d\n", aspect->aspect.num, aspect->aspect.den);
return 0;
}
@@ -67,7 +69,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
AspectContext *aspect = link->dst->priv;
picref->video->pixel_aspect = aspect->aspect;
- avfilter_start_frame(link->dst->outputs[0], picref);
+ ff_start_frame(link->dst->outputs[0], picref);
}
#if CONFIG_SETDAR_FILTER
@@ -81,7 +83,7 @@ static int setdar_config_props(AVFilterLink *inlink)
aspect->aspect.num * inlink->h,
aspect->aspect.den * inlink->w, 100);
- av_log(inlink->dst, AV_LOG_INFO, "w:%d h:%d -> dar:%d/%d sar:%d/%d\n",
+ av_log(inlink->dst, AV_LOG_VERBOSE, "w:%d h:%d -> dar:%d/%d sar:%d/%d\n",
inlink->w, inlink->h, dar.num, dar.den, aspect->aspect.num, aspect->aspect.den);
inlink->sample_aspect_ratio = aspect->aspect;
@@ -100,9 +102,9 @@ AVFilter avfilter_vf_setdar = {
.inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.config_props = setdar_config_props,
- .get_video_buffer = avfilter_null_get_video_buffer,
+ .get_video_buffer = ff_null_get_video_buffer,
.start_frame = start_frame,
- .end_frame = avfilter_null_end_frame },
+ .end_frame = ff_null_end_frame },
{ .name = NULL}},
.outputs = (AVFilterPad[]) {{ .name = "default",
@@ -133,9 +135,9 @@ AVFilter avfilter_vf_setsar = {
.inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.config_props = setsar_config_props,
- .get_video_buffer = avfilter_null_get_video_buffer,
+ .get_video_buffer = ff_null_get_video_buffer,
.start_frame = start_frame,
- .end_frame = avfilter_null_end_frame },
+ .end_frame = ff_null_end_frame },
{ .name = NULL}},
.outputs = (AVFilterPad[]) {{ .name = "default",
diff --git a/libavfilter/vf_blackframe.c b/libavfilter/vf_blackframe.c
index 770eec9..acf9f05 100644
--- a/libavfilter/vf_blackframe.c
+++ b/libavfilter/vf_blackframe.c
@@ -28,6 +28,9 @@
*/
#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
typedef struct {
unsigned int bamount; ///< black amount
@@ -44,11 +47,11 @@ static int query_formats(AVFilterContext *ctx)
PIX_FMT_NONE
};
- avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
return 0;
}
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
{
BlackFrameContext *blackframe = ctx->priv;
@@ -60,7 +63,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
if (args)
sscanf(args, "%u:%u", &blackframe->bamount, &blackframe->bthresh);
- av_log(ctx, AV_LOG_INFO, "bamount:%u bthresh:%u\n",
+ av_log(ctx, AV_LOG_VERBOSE, "bamount:%u bthresh:%u\n",
blackframe->bamount, blackframe->bthresh);
if (blackframe->bamount > 100 || blackframe->bthresh > 255) {
@@ -85,7 +88,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
p += picref->linesize[0];
}
- avfilter_draw_slice(ctx->outputs[0], y, h, slice_dir);
+ ff_draw_slice(ctx->outputs[0], y, h, slice_dir);
}
static void end_frame(AVFilterLink *inlink)
@@ -103,7 +106,7 @@ static void end_frame(AVFilterLink *inlink)
blackframe->frame++;
blackframe->nblack = 0;
- avfilter_end_frame(inlink->dst->outputs[0]);
+ ff_end_frame(inlink->dst->outputs[0]);
}
AVFilter avfilter_vf_blackframe = {
@@ -118,8 +121,8 @@ AVFilter avfilter_vf_blackframe = {
.inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.draw_slice = draw_slice,
- .get_video_buffer = avfilter_null_get_video_buffer,
- .start_frame = avfilter_null_start_frame,
+ .get_video_buffer = ff_null_get_video_buffer,
+ .start_frame = ff_null_start_frame,
.end_frame = end_frame, },
{ .name = NULL}},
diff --git a/libavfilter/vf_boxblur.c b/libavfilter/vf_boxblur.c
index fa739de..be4a832 100644
--- a/libavfilter/vf_boxblur.c
+++ b/libavfilter/vf_boxblur.c
@@ -29,6 +29,9 @@
#include "libavutil/eval.h"
#include "libavutil/pixdesc.h"
#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
static const char *const var_names[] = {
"w",
@@ -74,7 +77,7 @@ typedef struct {
#define V 2
#define A 3
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
{
BoxBlurContext *boxblur = ctx->priv;
int e;
@@ -129,7 +132,7 @@ static int query_formats(AVFilterContext *ctx)
PIX_FMT_NONE
};
- avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
return 0;
}
@@ -327,7 +330,7 @@ static void draw_slice(AVFilterLink *inlink, int y0, int h0, int slice_dir)
w[plane], h[plane], boxblur->radius[plane], boxblur->power[plane],
boxblur->temp);
- avfilter_draw_slice(outlink, y0, h0, slice_dir);
+ ff_draw_slice(outlink, y0, h0, slice_dir);
}
AVFilter avfilter_vf_boxblur = {
diff --git a/libavfilter/vf_copy.c b/libavfilter/vf_copy.c
index 705ad1e..9ceb2f8 100644
--- a/libavfilter/vf_copy.c
+++ b/libavfilter/vf_copy.c
@@ -22,6 +22,8 @@
*/
#include "avfilter.h"
+#include "internal.h"
+#include "video.h"
AVFilter avfilter_vf_copy = {
.name = "copy",
@@ -29,9 +31,9 @@ AVFilter avfilter_vf_copy = {
.inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
- .get_video_buffer = avfilter_null_get_video_buffer,
- .start_frame = avfilter_null_start_frame,
- .end_frame = avfilter_null_end_frame,
+ .get_video_buffer = ff_null_get_video_buffer,
+ .start_frame = ff_null_start_frame,
+ .end_frame = ff_null_end_frame,
.rej_perms = ~0 },
{ .name = NULL}},
.outputs = (AVFilterPad[]) {{ .name = "default",
diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c
index d3b5a09..6d124c1 100644
--- a/libavfilter/vf_crop.c
+++ b/libavfilter/vf_crop.c
@@ -26,6 +26,9 @@
/* #define DEBUG */
#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
#include "libavutil/eval.h"
#include "libavutil/avstring.h"
#include "libavutil/libm.h"
@@ -105,12 +108,12 @@ static int query_formats(AVFilterContext *ctx)
PIX_FMT_NONE
};
- avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
return 0;
}
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
{
CropContext *crop = ctx->priv;
@@ -204,7 +207,7 @@ static int config_input(AVFilterLink *link)
NULL, NULL, NULL, NULL, 0, ctx)) < 0)
return AVERROR(EINVAL);
- av_log(ctx, AV_LOG_INFO, "w:%d h:%d -> w:%d h:%d\n",
+ av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d -> w:%d h:%d\n",
link->w, link->h, crop->w, crop->h);
if (crop->w <= 0 || crop->h <= 0 ||
@@ -288,7 +291,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
ref2->data[3] += crop->x * crop->max_step[3];
}
- avfilter_start_frame(link->dst->outputs[0], ref2);
+ ff_start_frame(link->dst->outputs[0], ref2);
}
static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
@@ -306,7 +309,7 @@ static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
if (y + h > crop->y + crop->h)
h = crop->y + crop->h - y;
- avfilter_draw_slice(ctx->outputs[0], y - crop->y, h, slice_dir);
+ ff_draw_slice(ctx->outputs[0], y - crop->y, h, slice_dir);
}
static void end_frame(AVFilterLink *link)
@@ -315,7 +318,7 @@ static void end_frame(AVFilterLink *link)
crop->var_values[VAR_N] += 1.0;
avfilter_unref_buffer(link->cur_buf);
- avfilter_end_frame(link->dst->outputs[0]);
+ ff_end_frame(link->dst->outputs[0]);
}
AVFilter avfilter_vf_crop = {
@@ -333,7 +336,7 @@ AVFilter avfilter_vf_crop = {
.start_frame = start_frame,
.draw_slice = draw_slice,
.end_frame = end_frame,
- .get_video_buffer = avfilter_null_get_video_buffer,
+ .get_video_buffer = ff_null_get_video_buffer,
.config_props = config_input, },
{ .name = NULL}},
.outputs = (AVFilterPad[]) {{ .name = "default",
diff --git a/libavfilter/vf_cropdetect.c b/libavfilter/vf_cropdetect.c
index 34b5dc9..f2e9e93 100644
--- a/libavfilter/vf_cropdetect.c
+++ b/libavfilter/vf_cropdetect.c
@@ -25,6 +25,9 @@
#include "libavutil/imgutils.h"
#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
typedef struct {
int x1, y1, x2, y2;
@@ -46,7 +49,7 @@ static int query_formats(AVFilterContext *ctx)
PIX_FMT_NONE
};
- avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
return 0;
}
@@ -77,7 +80,7 @@ static int checkline(void *ctx, const unsigned char *src, int stride, int len, i
return total;
}
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
{
CropDetectContext *cd = ctx->priv;
@@ -89,7 +92,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
if (args)
sscanf(args, "%d:%d:%d", &cd->limit, &cd->round, &cd->reset_count);
- av_log(ctx, AV_LOG_INFO, "limit:%d round:%d reset_count:%d\n",
+ av_log(ctx, AV_LOG_VERBOSE, "limit:%d round:%d reset_count:%d\n",
cd->limit, cd->round, cd->reset_count);
return 0;
@@ -188,7 +191,7 @@ static void end_frame(AVFilterLink *inlink)
w, h, x, y);
}
- avfilter_end_frame(inlink->dst->outputs[0]);
+ ff_end_frame(inlink->dst->outputs[0]);
}
AVFilter avfilter_vf_cropdetect = {
@@ -203,8 +206,8 @@ AVFilter avfilter_vf_cropdetect = {
.inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.config_props = config_input,
- .get_video_buffer = avfilter_null_get_video_buffer,
- .start_frame = avfilter_null_start_frame,
+ .get_video_buffer = ff_null_get_video_buffer,
+ .start_frame = ff_null_start_frame,
.end_frame = end_frame, },
{ .name = NULL}},
diff --git a/libavfilter/vf_delogo.c b/libavfilter/vf_delogo.c
index ca31568..c248739 100644
--- a/libavfilter/vf_delogo.c
+++ b/libavfilter/vf_delogo.c
@@ -29,6 +29,9 @@
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
/**
* Apply a simple delogo algorithm to the image in dst and put the
@@ -164,11 +167,11 @@ static int query_formats(AVFilterContext *ctx)
PIX_FMT_NONE
};
- avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
return 0;
}
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
{
DelogoContext *delogo = ctx->priv;
int ret = 0;
@@ -217,8 +220,8 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
AVFilterBufferRef *outpicref;
if (inpicref->perms & AV_PERM_PRESERVE) {
- outpicref = avfilter_get_video_buffer(outlink, AV_PERM_WRITE,
- outlink->w, outlink->h);
+ outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE,
+ outlink->w, outlink->h);
avfilter_copy_buffer_ref_props(outpicref, inpicref);
outpicref->video->w = outlink->w;
outpicref->video->h = outlink->h;
@@ -226,7 +229,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
outpicref = inpicref;
outlink->out_buf = outpicref;
- avfilter_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0));
+ ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0));
}
static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { }
@@ -255,8 +258,8 @@ static void end_frame(AVFilterLink *inlink)
delogo->show, direct);
}
- avfilter_draw_slice(outlink, 0, inlink->h, 1);
- avfilter_end_frame(outlink);
+ ff_draw_slice(outlink, 0, inlink->h, 1);
+ ff_end_frame(outlink);
avfilter_unref_buffer(inpicref);
if (!direct)
avfilter_unref_buffer(outpicref);
@@ -271,7 +274,7 @@ AVFilter avfilter_vf_delogo = {
.inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
- .get_video_buffer = avfilter_null_get_video_buffer,
+ .get_video_buffer = ff_null_get_video_buffer,
.start_frame = start_frame,
.draw_slice = null_draw_slice,
.end_frame = end_frame,
diff --git a/libavfilter/vf_drawbox.c b/libavfilter/vf_drawbox.c
index ab5cb03..87c2ad7 100644
--- a/libavfilter/vf_drawbox.c
+++ b/libavfilter/vf_drawbox.c
@@ -28,6 +28,9 @@
#include "libavutil/pixdesc.h"
#include "libavutil/parseutils.h"
#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
enum { Y, U, V, A };
@@ -37,7 +40,7 @@ typedef struct {
int vsub, hsub; ///< chroma subsampling
} DrawBoxContext;
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
{
DrawBoxContext *drawbox= ctx->priv;
char color_str[1024] = "black";
@@ -70,7 +73,7 @@ static int query_formats(AVFilterContext *ctx)
PIX_FMT_NONE
};
- avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
return 0;
}
@@ -84,7 +87,7 @@ static int config_input(AVFilterLink *inlink)
if (drawbox->w == 0) drawbox->w = inlink->w;
if (drawbox->h == 0) drawbox->h = inlink->h;
- av_log(inlink->dst, AV_LOG_INFO, "x:%d y:%d w:%d h:%d color:0x%02X%02X%02X%02X\n",
+ av_log(inlink->dst, AV_LOG_VERBOSE, "x:%d y:%d w:%d h:%d color:0x%02X%02X%02X%02X\n",
drawbox->w, drawbox->y, drawbox->w, drawbox->h,
drawbox->yuv_color[Y], drawbox->yuv_color[U], drawbox->yuv_color[V], drawbox->yuv_color[A]);
@@ -117,7 +120,7 @@ static void draw_slice(AVFilterLink *inlink, int y0, int h, int slice_dir)
}
}
- avfilter_draw_slice(inlink->dst->outputs[0], y0, h, 1);
+ ff_draw_slice(inlink->dst->outputs[0], y0, h, 1);
}
AVFilter avfilter_vf_drawbox = {
@@ -130,10 +133,10 @@ AVFilter avfilter_vf_drawbox = {
.inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.config_props = config_input,
- .get_video_buffer = avfilter_null_get_video_buffer,
- .start_frame = avfilter_null_start_frame,
+ .get_video_buffer = ff_null_get_video_buffer,
+ .start_frame = ff_null_start_frame,
.draw_slice = draw_slice,
- .end_frame = avfilter_null_end_frame,
+ .end_frame = ff_null_end_frame,
.min_perms = AV_PERM_WRITE | AV_PERM_READ,
.rej_perms = AV_PERM_PRESERVE },
{ .name = NULL}},
diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c
index 4846716..22a9480 100644
--- a/libavfilter/vf_drawtext.c
+++ b/libavfilter/vf_drawtext.c
@@ -41,6 +41,9 @@
#include "libavutil/lfg.h"
#include "avfilter.h"
#include "drawutils.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
#undef time
@@ -277,7 +280,7 @@ error:
return ret;
}
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
{
int err;
DrawTextContext *dtext = ctx->priv;
@@ -395,7 +398,7 @@ static int query_formats(AVFilterContext *ctx)
PIX_FMT_NONE
};
- avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
return 0;
}
@@ -847,7 +850,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
(int)dtext->var_values[VAR_N], dtext->var_values[VAR_T],
dtext->x, dtext->y, dtext->x+dtext->w, dtext->y+dtext->h);
- avfilter_start_frame(inlink->dst->outputs[0], inpicref);
+ ff_start_frame(inlink->dst->outputs[0], inpicref);
}
static void end_frame(AVFilterLink *inlink)
@@ -861,8 +864,8 @@ static void end_frame(AVFilterLink *inlink)
dtext->var_values[VAR_N] += 1.0;
- avfilter_draw_slice(outlink, 0, picref->video->h, 1);
- avfilter_end_frame(outlink);
+ ff_draw_slice(outlink, 0, picref->video->h, 1);
+ ff_end_frame(outlink);
}
AVFilter avfilter_vf_drawtext = {
@@ -875,7 +878,7 @@ AVFilter avfilter_vf_drawtext = {
.inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
- .get_video_buffer = avfilter_null_get_video_buffer,
+ .get_video_buffer = ff_null_get_video_buffer,
.start_frame = start_frame,
.draw_slice = null_draw_slice,
.end_frame = end_frame,
diff --git a/libavfilter/vf_fade.c b/libavfilter/vf_fade.c
index 9f748b8..3e8b26c 100644
--- a/libavfilter/vf_fade.c
+++ b/libavfilter/vf_fade.c
@@ -27,6 +27,9 @@
#include "libavutil/pixdesc.h"
#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
typedef struct {
int factor, fade_per_frame;
@@ -34,7 +37,7 @@ typedef struct {
int hsub, vsub, bpp;
} FadeContext;
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
{
FadeContext *fade = ctx->priv;
unsigned int nb_frames;
@@ -61,7 +64,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
}
fade->stop_frame = fade->start_frame + nb_frames;
- av_log(ctx, AV_LOG_INFO,
+ av_log(ctx, AV_LOG_VERBOSE,
"type:%s start_frame:%d nb_frames:%d\n",
in_out, fade->start_frame, nb_frames);
return 0;
@@ -78,7 +81,7 @@ static int query_formats(AVFilterContext *ctx)
PIX_FMT_NONE
};
- avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
return 0;
}
@@ -131,14 +134,14 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
}
}
- avfilter_draw_slice(inlink->dst->outputs[0], y, h, slice_dir);
+ ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir);
}
static void end_frame(AVFilterLink *inlink)
{
FadeContext *fade = inlink->dst->priv;
- avfilter_end_frame(inlink->dst->outputs[0]);
+ ff_end_frame(inlink->dst->outputs[0]);
if (fade->frame_index >= fade->start_frame &&
fade->frame_index <= fade->stop_frame)
@@ -157,8 +160,8 @@ AVFilter avfilter_vf_fade = {
.inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.config_props = config_props,
- .get_video_buffer = avfilter_null_get_video_buffer,
- .start_frame = avfilter_null_start_frame,
+ .get_video_buffer = ff_null_get_video_buffer,
+ .start_frame = ff_null_start_frame,
.draw_slice = draw_slice,
.end_frame = end_frame,
.min_perms = AV_PERM_READ | AV_PERM_WRITE,
diff --git a/libavfilter/vf_fieldorder.c b/libavfilter/vf_fieldorder.c
index 444dffb..55e7238 100644
--- a/libavfilter/vf_fieldorder.c
+++ b/libavfilter/vf_fieldorder.c
@@ -28,6 +28,9 @@
#include "libavutil/imgutils.h"
#include "libavutil/pixdesc.h"
#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
typedef struct
{
@@ -35,7 +38,7 @@ typedef struct
int line_size[4]; ///< bytes of pixel data per line for each plane
} FieldOrderContext;
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
{
FieldOrderContext *fieldorder = ctx->priv;
@@ -55,7 +58,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
return AVERROR(EINVAL);
}
- av_log(ctx, AV_LOG_INFO, "output field order: %s\n",
+ av_log(ctx, AV_LOG_VERBOSE, "output field order: %s\n",
fieldorder->dst_tff ? tff : bff);
return 0;
@@ -76,12 +79,12 @@ static int query_formats(AVFilterContext *ctx)
|| av_pix_fmt_descriptors[pix_fmt].flags & PIX_FMT_BITSTREAM)
&& av_pix_fmt_descriptors[pix_fmt].nb_components
&& !av_pix_fmt_descriptors[pix_fmt].log2_chroma_h
- && (ret = avfilter_add_format(&formats, pix_fmt)) < 0) {
- avfilter_formats_unref(&formats);
+ && (ret = ff_add_format(&formats, pix_fmt)) < 0) {
+ ff_formats_unref(&formats);
return ret;
}
- avfilter_formats_ref(formats, &ctx->inputs[0]->out_formats);
- avfilter_formats_ref(formats, &ctx->outputs[0]->in_formats);
+ ff_formats_ref(formats, &ctx->inputs[0]->out_formats);
+ ff_formats_ref(formats, &ctx->outputs[0]->in_formats);
}
return 0;
@@ -110,7 +113,7 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *inlink, int perms, int
AVFilterContext *ctx = inlink->dst;
AVFilterLink *outlink = ctx->outputs[0];
- return avfilter_get_video_buffer(outlink, perms, w, h);
+ return ff_get_video_buffer(outlink, perms, w, h);
}
static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
@@ -123,7 +126,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
outpicref = avfilter_ref_buffer(inpicref, ~0);
outlink->out_buf = outpicref;
- avfilter_start_frame(outlink, outpicref);
+ ff_start_frame(outlink, outpicref);
}
static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
@@ -140,7 +143,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
* and that complexity will be added later */
if ( !inpicref->video->interlaced
|| inpicref->video->top_field_first == fieldorder->dst_tff) {
- avfilter_draw_slice(outlink, y, h, slice_dir);
+ ff_draw_slice(outlink, y, h, slice_dir);
}
}
@@ -202,13 +205,13 @@ static void end_frame(AVFilterLink *inlink)
}
}
outpicref->video->top_field_first = fieldorder->dst_tff;
- avfilter_draw_slice(outlink, 0, h, 1);
+ ff_draw_slice(outlink, 0, h, 1);
} else {
av_dlog(ctx,
"not interlaced or field order already correct\n");
}
- avfilter_end_frame(outlink);
+ ff_end_frame(outlink);
avfilter_unref_buffer(inpicref);
}
diff --git a/libavfilter/vf_fifo.c b/libavfilter/vf_fifo.c
deleted file mode 100644
index 836cce2..0000000
--- a/libavfilter/vf_fifo.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2007 Bobby Bingham
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * FIFO buffering video filter
- */
-
-#include "avfilter.h"
-
-typedef struct BufPic {
- AVFilterBufferRef *picref;
- struct BufPic *next;
-} BufPic;
-
-typedef struct {
- BufPic root;
- BufPic *last; ///< last buffered picture
-} FifoContext;
-
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
-{
- FifoContext *fifo = ctx->priv;
- fifo->last = &fifo->root;
-
- av_log(ctx, AV_LOG_INFO, "\n");
- return 0;
-}
-
-static av_cold void uninit(AVFilterContext *ctx)
-{
- FifoContext *fifo = ctx->priv;
- BufPic *pic, *tmp;
-
- for (pic = fifo->root.next; pic; pic = tmp) {
- tmp = pic->next;
- avfilter_unref_buffer(pic->picref);
- av_free(pic);
- }
-}
-
-static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
-{
- FifoContext *fifo = inlink->dst->priv;
-
- fifo->last->next = av_mallocz(sizeof(BufPic));
- fifo->last = fifo->last->next;
- fifo->last->picref = picref;
-}
-
-static void end_frame(AVFilterLink *inlink) { }
-
-static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { }
-
-static int request_frame(AVFilterLink *outlink)
-{
- FifoContext *fifo = outlink->src->priv;
- BufPic *tmp;
- int ret;
-
- if (!fifo->root.next) {
- if ((ret = avfilter_request_frame(outlink->src->inputs[0]) < 0))
- return ret;
- }
-
- /* by doing this, we give ownership of the reference to the next filter,
- * so we don't have to worry about dereferencing it ourselves. */
- avfilter_start_frame(outlink, fifo->root.next->picref);
- avfilter_draw_slice (outlink, 0, outlink->h, 1);
- avfilter_end_frame (outlink);
-
- if (fifo->last == fifo->root.next)
- fifo->last = &fifo->root;
- tmp = fifo->root.next->next;
- av_free(fifo->root.next);
- fifo->root.next = tmp;
-
- return 0;
-}
-
-AVFilter avfilter_vf_fifo = {
- .name = "fifo",
- .description = NULL_IF_CONFIG_SMALL("Buffer input images and send them when they are requested."),
-
- .init = init,
- .uninit = uninit,
-
- .priv_size = sizeof(FifoContext),
-
- .inputs = (AVFilterPad[]) {{ .name = "default",
- .type = AVMEDIA_TYPE_VIDEO,
- .get_video_buffer= avfilter_null_get_video_buffer,
- .start_frame = start_frame,
- .draw_slice = draw_slice,
- .end_frame = end_frame,
- .rej_perms = AV_PERM_REUSE2, },
- { .name = NULL}},
- .outputs = (AVFilterPad[]) {{ .name = "default",
- .type = AVMEDIA_TYPE_VIDEO,
- .request_frame = request_frame, },
- { .name = NULL}},
-};
diff --git a/libavfilter/vf_format.c b/libavfilter/vf_format.c
index 9c1e0d4..b9251a1 100644
--- a/libavfilter/vf_format.c
+++ b/libavfilter/vf_format.c
@@ -25,6 +25,9 @@
#include "libavutil/pixdesc.h"
#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
typedef struct {
/**
@@ -36,7 +39,7 @@ typedef struct {
#define PIX_FMT_NAME_MAXSIZE 32
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
{
FormatContext *format = ctx->priv;
const char *cur, *sep;
@@ -88,7 +91,7 @@ static AVFilterFormats *make_format_list(FormatContext *format, int flag)
#if CONFIG_FORMAT_FILTER
static int query_formats_format(AVFilterContext *ctx)
{
- avfilter_set_common_formats(ctx, make_format_list(ctx->priv, 1));
+ ff_set_common_formats(ctx, make_format_list(ctx->priv, 1));
return 0;
}
@@ -104,10 +107,10 @@ AVFilter avfilter_vf_format = {
.inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
- .get_video_buffer= avfilter_null_get_video_buffer,
- .start_frame = avfilter_null_start_frame,
- .draw_slice = avfilter_null_draw_slice,
- .end_frame = avfilter_null_end_frame, },
+ .get_video_buffer= ff_null_get_video_buffer,
+ .start_frame = ff_null_start_frame,
+ .draw_slice = ff_null_draw_slice,
+ .end_frame = ff_null_end_frame, },
{ .name = NULL}},
.outputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO },
@@ -118,7 +121,7 @@ AVFilter avfilter_vf_format = {
#if CONFIG_NOFORMAT_FILTER
static int query_formats_noformat(AVFilterContext *ctx)
{
- avfilter_set_common_formats(ctx, make_format_list(ctx->priv, 0));
+ ff_set_common_formats(ctx, make_format_list(ctx->priv, 0));
return 0;
}
@@ -134,10 +137,10 @@ AVFilter avfilter_vf_noformat = {
.inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
- .get_video_buffer= avfilter_null_get_video_buffer,
- .start_frame = avfilter_null_start_frame,
- .draw_slice = avfilter_null_draw_slice,
- .end_frame = avfilter_null_end_frame, },
+ .get_video_buffer= ff_null_get_video_buffer,
+ .start_frame = ff_null_start_frame,
+ .draw_slice = ff_null_draw_slice,
+ .end_frame = ff_null_end_frame, },
{ .name = NULL}},
.outputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO },
diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c
new file mode 100644
index 0000000..bcc6a69
--- /dev/null
+++ b/libavfilter/vf_fps.c
@@ -0,0 +1,273 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * a filter enforcing given constant framerate
+ */
+
+#include "libavutil/fifo.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
+
+#include "avfilter.h"
+#include "internal.h"
+#include "video.h"
+
+typedef struct FPSContext {
+ const AVClass *class;
+
+ AVFifoBuffer *fifo; ///< store frames until we get two successive timestamps
+
+ /* timestamps in input timebase */
+ int64_t first_pts; ///< pts of the first frame that arrived on this filter
+ int64_t pts; ///< pts of the first frame currently in the fifo
+
+ AVRational framerate; ///< target framerate
+ char *fps; ///< a string describing target framerate
+
+ /* statistics */
+ int frames_in; ///< number of frames on input
+ int frames_out; ///< number of frames on output
+ int dup; ///< number of frames duplicated
+ int drop; ///< number of framed dropped
+} FPSContext;
+
+#define OFFSET(x) offsetof(FPSContext, x)
+#define V AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption options[] = {
+ { "fps", "A string describing desired output framerate", OFFSET(fps), AV_OPT_TYPE_STRING, { .str = "25" }, .flags = V },
+ { NULL },
+};
+
+static const AVClass class = {
+ .class_name = "FPS filter",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+ FPSContext *s = ctx->priv;
+ int ret;
+
+ s->class = &class;
+ av_opt_set_defaults(s);
+
+ if ((ret = av_set_options_string(s, args, "=", ":")) < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Error parsing the options string %s.\n",
+ args);
+ return ret;
+ }
+
+ if ((ret = av_parse_video_rate(&s->framerate, s->fps)) < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Error parsing framerate %s.\n", s->fps);
+ return ret;
+ }
+ av_opt_free(s);
+
+ if (!(s->fifo = av_fifo_alloc(2*sizeof(AVFilterBufferRef*))))
+ return AVERROR(ENOMEM);
+
+ av_log(ctx, AV_LOG_VERBOSE, "fps=%d/%d\n", s->framerate.num, s->framerate.den);
+ return 0;
+}
+
+static void flush_fifo(AVFifoBuffer *fifo)
+{
+ while (av_fifo_size(fifo)) {
+ AVFilterBufferRef *tmp;
+ av_fifo_generic_read(fifo, &tmp, sizeof(tmp), NULL);
+ avfilter_unref_buffer(tmp);
+ }
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+ FPSContext *s = ctx->priv;
+ if (s->fifo) {
+ flush_fifo(s->fifo);
+ av_fifo_free(s->fifo);
+ }
+
+ av_log(ctx, AV_LOG_VERBOSE, "%d frames in, %d frames out; %d frames dropped, "
+ "%d frames duplicated.\n", s->frames_in, s->frames_out, s->drop, s->dup);
+}
+
+static int config_props(AVFilterLink* link)
+{
+ FPSContext *s = link->src->priv;
+
+ link->time_base = (AVRational){ s->framerate.den, s->framerate.num };
+ link->w = link->src->inputs[0]->w;
+ link->h = link->src->inputs[0]->h;
+ s->pts = AV_NOPTS_VALUE;
+
+ return 0;
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+ AVFilterContext *ctx = outlink->src;
+ FPSContext *s = ctx->priv;
+ int frames_out = s->frames_out;
+ int ret = 0;
+
+ while (ret >= 0 && s->frames_out == frames_out)
+ ret = ff_request_frame(ctx->inputs[0]);
+
+ /* flush the fifo */
+ if (ret == AVERROR_EOF && av_fifo_size(s->fifo)) {
+ int i;
+ for (i = 0; av_fifo_size(s->fifo); i++) {
+ AVFilterBufferRef *buf;
+
+ av_fifo_generic_read(s->fifo, &buf, sizeof(buf), NULL);
+ buf->pts = av_rescale_q(s->first_pts, ctx->inputs[0]->time_base,
+ outlink->time_base) + s->frames_out;
+
+ ff_start_frame(outlink, buf);
+ ff_draw_slice(outlink, 0, outlink->h, 1);
+ ff_end_frame(outlink);
+ s->frames_out++;
+ }
+ return 0;
+ }
+
+ return ret;
+}
+
+static int write_to_fifo(AVFifoBuffer *fifo, AVFilterBufferRef *buf)
+{
+ int ret;
+
+ if (!av_fifo_space(fifo) &&
+ (ret = av_fifo_realloc2(fifo, 2*av_fifo_size(fifo))))
+ return ret;
+
+ av_fifo_generic_write(fifo, &buf, sizeof(buf), NULL);
+ return 0;
+}
+
+static void end_frame(AVFilterLink *inlink)
+{
+ AVFilterContext *ctx = inlink->dst;
+ FPSContext *s = ctx->priv;
+ AVFilterLink *outlink = ctx->outputs[0];
+ AVFilterBufferRef *buf = inlink->cur_buf;
+ int64_t delta;
+ int i;
+
+ s->frames_in++;
+ /* discard frames until we get the first timestamp */
+ if (s->pts == AV_NOPTS_VALUE) {
+ if (buf->pts != AV_NOPTS_VALUE) {
+ write_to_fifo(s->fifo, buf);
+ s->first_pts = s->pts = buf->pts;
+ } else {
+ av_log(ctx, AV_LOG_WARNING, "Discarding initial frame(s) with no "
+ "timestamp.\n");
+ avfilter_unref_buffer(buf);
+ s->drop++;
+ }
+ return;
+ }
+
+ /* now wait for the next timestamp */
+ if (buf->pts == AV_NOPTS_VALUE) {
+ write_to_fifo(s->fifo, buf);
+ return;
+ }
+
+ /* number of output frames */
+ delta = av_rescale_q(buf->pts - s->pts, inlink->time_base,
+ outlink->time_base);
+
+ if (delta < 1) {
+ /* drop the frame and everything buffered except the first */
+ AVFilterBufferRef *tmp;
+ int drop = av_fifo_size(s->fifo)/sizeof(AVFilterBufferRef*);
+
+ av_log(ctx, AV_LOG_DEBUG, "Dropping %d frame(s).\n", drop);
+ s->drop += drop;
+
+ av_fifo_generic_read(s->fifo, &tmp, sizeof(tmp), NULL);
+ flush_fifo(s->fifo);
+ write_to_fifo(s->fifo, tmp);
+
+ avfilter_unref_buffer(buf);
+ return;
+ }
+
+ /* can output >= 1 frames */
+ for (i = 0; i < delta; i++) {
+ AVFilterBufferRef *buf_out;
+ av_fifo_generic_read(s->fifo, &buf_out, sizeof(buf_out), NULL);
+
+ /* duplicate the frame if needed */
+ if (!av_fifo_size(s->fifo) && i < delta - 1) {
+ av_log(ctx, AV_LOG_DEBUG, "Duplicating frame.\n");
+ write_to_fifo(s->fifo, avfilter_ref_buffer(buf_out, AV_PERM_READ));
+ s->dup++;
+ }
+
+ buf_out->pts = av_rescale_q(s->first_pts, inlink->time_base,
+ outlink->time_base) + s->frames_out;
+
+ ff_start_frame(outlink, buf_out);
+ ff_draw_slice(outlink, 0, outlink->h, 1);
+ ff_end_frame(outlink);
+ s->frames_out++;
+ }
+ flush_fifo(s->fifo);
+
+ write_to_fifo(s->fifo, buf);
+ s->pts = s->first_pts + av_rescale_q(s->frames_out, outlink->time_base, inlink->time_base);
+}
+
+static void null_start_frame(AVFilterLink *link, AVFilterBufferRef *buf)
+{
+}
+
+static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
+{
+}
+
+AVFilter avfilter_vf_fps = {
+ .name = "fps",
+ .description = NULL_IF_CONFIG_SMALL("Force constant framerate"),
+
+ .init = init,
+ .uninit = uninit,
+
+ .priv_size = sizeof(FPSContext),
+
+ .inputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .start_frame = null_start_frame,
+ .draw_slice = null_draw_slice,
+ .end_frame = end_frame, },
+ { .name = NULL}},
+ .outputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .request_frame = request_frame,
+ .config_props = config_props},
+ { .name = NULL}},
+};
diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c
index 455e24a..93ec92a 100644
--- a/libavfilter/vf_frei0r.c
+++ b/libavfilter/vf_frei0r.c
@@ -31,6 +31,9 @@
#include "libavutil/mathematics.h"
#include "libavutil/parseutils.h"
#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
typedef f0r_instance_t (*f0r_construct_f)(unsigned int width, unsigned int height);
typedef void (*f0r_destruct_f)(f0r_instance_t instance);
@@ -143,7 +146,7 @@ static int set_params(AVFilterContext *ctx, const char *params)
return ret;
}
- av_log(ctx, AV_LOG_INFO,
+ av_log(ctx, AV_LOG_VERBOSE,
"idx:%d name:'%s' type:%s explanation:'%s' ",
i, info.name,
info.type == F0R_PARAM_BOOL ? "bool" :
@@ -154,7 +157,7 @@ static int set_params(AVFilterContext *ctx, const char *params)
info.explanation);
#ifdef DEBUG
- av_log(ctx, AV_LOG_INFO, "value:");
+ av_log(ctx, AV_LOG_DEBUG, "value:");
switch (info.type) {
void *v;
double d;
@@ -165,31 +168,31 @@ static int set_params(AVFilterContext *ctx, const char *params)
case F0R_PARAM_BOOL:
v = &d;
frei0r->get_param_value(frei0r->instance, v, i);
- av_log(ctx, AV_LOG_INFO, "%s", d >= 0.5 && d <= 1.0 ? "y" : "n");
+ av_log(ctx, AV_LOG_DEBUG, "%s", d >= 0.5 && d <= 1.0 ? "y" : "n");
break;
case F0R_PARAM_DOUBLE:
v = &d;
frei0r->get_param_value(frei0r->instance, v, i);
- av_log(ctx, AV_LOG_INFO, "%f", d);
+ av_log(ctx, AV_LOG_DEBUG, "%f", d);
break;
case F0R_PARAM_COLOR:
v = &col;
frei0r->get_param_value(frei0r->instance, v, i);
- av_log(ctx, AV_LOG_INFO, "%f/%f/%f", col.r, col.g, col.b);
+ av_log(ctx, AV_LOG_DEBUG, "%f/%f/%f", col.r, col.g, col.b);
break;
case F0R_PARAM_POSITION:
v = &pos;
frei0r->get_param_value(frei0r->instance, v, i);
- av_log(ctx, AV_LOG_INFO, "%lf/%lf", pos.x, pos.y);
+ av_log(ctx, AV_LOG_DEBUG, "%lf/%lf", pos.x, pos.y);
break;
default: /* F0R_PARAM_STRING */
v = s;
frei0r->get_param_value(frei0r->instance, v, i);
- av_log(ctx, AV_LOG_INFO, "'%s'\n", s);
+ av_log(ctx, AV_LOG_DEBUG, "'%s'\n", s);
break;
}
#endif
- av_log(ctx, AV_LOG_INFO, "\n");
+ av_log(ctx, AV_LOG_VERBOSE, "\n");
}
return 0;
@@ -263,7 +266,7 @@ static av_cold int frei0r_init(AVFilterContext *ctx,
return AVERROR(EINVAL);
}
- av_log(ctx, AV_LOG_INFO,
+ av_log(ctx, AV_LOG_VERBOSE,
"name:%s author:'%s' explanation:'%s' color_model:%s "
"frei0r_version:%d version:%d.%d num_params:%d\n",
pi->name, pi->author, pi->explanation,
@@ -275,7 +278,7 @@ static av_cold int frei0r_init(AVFilterContext *ctx,
return 0;
}
-static av_cold int filter_init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int filter_init(AVFilterContext *ctx, const char *args)
{
Frei0rContext *frei0r = ctx->priv;
char dl_name[1024], c;
@@ -320,20 +323,20 @@ static int query_formats(AVFilterContext *ctx)
AVFilterFormats *formats = NULL;
if (frei0r->plugin_info.color_model == F0R_COLOR_MODEL_BGRA8888) {
- avfilter_add_format(&formats, PIX_FMT_BGRA);
+ ff_add_format(&formats, PIX_FMT_BGRA);
} else if (frei0r->plugin_info.color_model == F0R_COLOR_MODEL_RGBA8888) {
- avfilter_add_format(&formats, PIX_FMT_RGBA);
+ ff_add_format(&formats, PIX_FMT_RGBA);
} else { /* F0R_COLOR_MODEL_PACKED32 */
static const enum PixelFormat pix_fmts[] = {
PIX_FMT_BGRA, PIX_FMT_ARGB, PIX_FMT_ABGR, PIX_FMT_ARGB, PIX_FMT_NONE
};
- formats = avfilter_make_format_list(pix_fmts);
+ formats = ff_make_format_list(pix_fmts);
}
if (!formats)
return AVERROR(ENOMEM);
- avfilter_set_common_formats(ctx, formats);
+ ff_set_common_formats(ctx, formats);
return 0;
}
@@ -350,8 +353,8 @@ static void end_frame(AVFilterLink *inlink)
(const uint32_t *)inpicref->data[0],
(uint32_t *)outpicref->data[0]);
avfilter_unref_buffer(inpicref);
- avfilter_draw_slice(outlink, 0, outlink->h, 1);
- avfilter_end_frame(outlink);
+ ff_draw_slice(outlink, 0, outlink->h, 1);
+ ff_end_frame(outlink);
avfilter_unref_buffer(outpicref);
}
@@ -378,7 +381,7 @@ AVFilter avfilter_vf_frei0r = {
{ .name = NULL}},
};
-static av_cold int source_init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int source_init(AVFilterContext *ctx, const char *args)
{
Frei0rContext *frei0r = ctx->priv;
char dl_name[1024], c;
@@ -430,16 +433,16 @@ static int source_config_props(AVFilterLink *outlink)
static int source_request_frame(AVFilterLink *outlink)
{
Frei0rContext *frei0r = outlink->src->priv;
- AVFilterBufferRef *picref = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+ AVFilterBufferRef *picref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
picref->video->pixel_aspect = (AVRational) {1, 1};
picref->pts = frei0r->pts++;
picref->pos = -1;
- avfilter_start_frame(outlink, avfilter_ref_buffer(picref, ~0));
+ ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0));
frei0r->update(frei0r->instance, av_rescale_q(picref->pts, frei0r->time_base, (AVRational){1,1000}),
NULL, (uint32_t *)picref->data[0]);
- avfilter_draw_slice(outlink, 0, outlink->h, 1);
- avfilter_end_frame(outlink);
+ ff_draw_slice(outlink, 0, outlink->h, 1);
+ ff_end_frame(outlink);
avfilter_unref_buffer(picref);
return 0;
diff --git a/libavfilter/vf_gradfun.c b/libavfilter/vf_gradfun.c
index 9da9b20..71749fe 100644
--- a/libavfilter/vf_gradfun.c
+++ b/libavfilter/vf_gradfun.c
@@ -36,7 +36,10 @@
#include "libavutil/cpu.h"
#include "libavutil/pixdesc.h"
#include "avfilter.h"
+#include "formats.h"
#include "gradfun.h"
+#include "internal.h"
+#include "video.h"
DECLARE_ALIGNED(16, static const uint16_t, dither)[8][8] = {
{0x00,0x60,0x18,0x78,0x06,0x66,0x1E,0x7E},
@@ -115,12 +118,11 @@ static void filter(GradFunContext *ctx, uint8_t *dst, uint8_t *src, int width, i
}
}
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
{
GradFunContext *gf = ctx->priv;
float thresh = 1.2;
int radius = 16;
- int cpu_flags = av_get_cpu_flags();
if (args)
sscanf(args, "%f:%d", &thresh, &radius);
@@ -132,14 +134,10 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
gf->blur_line = ff_gradfun_blur_line_c;
gf->filter_line = ff_gradfun_filter_line_c;
- if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX2)
- gf->filter_line = ff_gradfun_filter_line_mmx2;
- if (HAVE_SSSE3 && cpu_flags & AV_CPU_FLAG_SSSE3)
- gf->filter_line = ff_gradfun_filter_line_ssse3;
- if (HAVE_SSE && cpu_flags & AV_CPU_FLAG_SSE2)
- gf->blur_line = ff_gradfun_blur_line_sse2;
+ if (HAVE_MMX)
+ ff_gradfun_init_x86(gf);
- av_log(ctx, AV_LOG_INFO, "threshold:%.2f radius:%d\n", thresh, gf->radius);
+ av_log(ctx, AV_LOG_VERBOSE, "threshold:%.2f radius:%d\n", thresh, gf->radius);
return 0;
}
@@ -160,7 +158,7 @@ static int query_formats(AVFilterContext *ctx)
PIX_FMT_NONE
};
- avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
return 0;
}
@@ -188,7 +186,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
AVFilterBufferRef *outpicref;
if (inpicref->perms & AV_PERM_PRESERVE) {
- outpicref = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+ outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
avfilter_copy_buffer_ref_props(outpicref, inpicref);
outpicref->video->w = outlink->w;
outpicref->video->h = outlink->h;
@@ -196,7 +194,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
outpicref = inpicref;
outlink->out_buf = outpicref;
- avfilter_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0));
+ ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0));
}
static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { }
@@ -225,8 +223,8 @@ static void end_frame(AVFilterLink *inlink)
av_image_copy_plane(outpic->data[p], outpic->linesize[p], inpic->data[p], inpic->linesize[p], w, h);
}
- avfilter_draw_slice(outlink, 0, inlink->h, 1);
- avfilter_end_frame(outlink);
+ ff_draw_slice(outlink, 0, inlink->h, 1);
+ ff_end_frame(outlink);
avfilter_unref_buffer(inpic);
if (outpic != inpic)
avfilter_unref_buffer(outpic);
diff --git a/libavfilter/vf_hflip.c b/libavfilter/vf_hflip.c
index c92296e..af167e1 100644
--- a/libavfilter/vf_hflip.c
+++ b/libavfilter/vf_hflip.c
@@ -25,6 +25,9 @@
*/
#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
#include "libavutil/pixdesc.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/imgutils.h"
@@ -62,7 +65,7 @@ static int query_formats(AVFilterContext *ctx)
PIX_FMT_NONE
};
- avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
return 0;
}
@@ -139,7 +142,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
}
}
- avfilter_draw_slice(inlink->dst->outputs[0], y, h, slice_dir);
+ ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir);
}
AVFilter avfilter_vf_hflip = {
diff --git a/libavfilter/vf_hqdn3d.c b/libavfilter/vf_hqdn3d.c
index 2e9a895..af69d41 100644
--- a/libavfilter/vf_hqdn3d.c
+++ b/libavfilter/vf_hqdn3d.c
@@ -27,6 +27,9 @@
#include "libavutil/pixdesc.h"
#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
typedef struct {
int Coefs[4][512*16];
@@ -194,7 +197,7 @@ static void PrecalcCoefs(int *Ct, double Dist25)
#define PARAM2_DEFAULT 3.0
#define PARAM3_DEFAULT 6.0
-static int init(AVFilterContext *ctx, const char *args, void *opaque)
+static int init(AVFilterContext *ctx, const char *args)
{
HQDN3DContext *hqdn3d = ctx->priv;
double LumSpac, LumTmp, ChromSpac, ChromTmp;
@@ -235,7 +238,7 @@ static int init(AVFilterContext *ctx, const char *args, void *opaque)
}
}
- av_log(ctx, AV_LOG_INFO, "ls:%lf cs:%lf lt:%lf ct:%lf\n",
+ av_log(ctx, AV_LOG_VERBOSE, "ls:%lf cs:%lf lt:%lf ct:%lf\n",
LumSpac, ChromSpac, LumTmp, ChromTmp);
if (LumSpac < 0 || ChromSpac < 0 || isnan(ChromTmp)) {
av_log(ctx, AV_LOG_ERROR,
@@ -268,7 +271,7 @@ static int query_formats(AVFilterContext *ctx)
PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_YUV411P, PIX_FMT_NONE
};
- avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
return 0;
}
@@ -317,8 +320,8 @@ static void end_frame(AVFilterLink *inlink)
hqdn3d->Coefs[2],
hqdn3d->Coefs[3]);
- avfilter_draw_slice(outlink, 0, inpic->video->h, 1);
- avfilter_end_frame(outlink);
+ ff_draw_slice(outlink, 0, inpic->video->h, 1);
+ ff_end_frame(outlink);
avfilter_unref_buffer(inpic);
avfilter_unref_buffer(outpic);
}
diff --git a/libavfilter/vf_libopencv.c b/libavfilter/vf_libopencv.c
index 6e343af..ac892d9 100644
--- a/libavfilter/vf_libopencv.c
+++ b/libavfilter/vf_libopencv.c
@@ -30,6 +30,8 @@
#include "libavutil/avstring.h"
#include "libavutil/file.h"
#include "avfilter.h"
+#include "formats.h"
+#include "video.h"
static void fill_iplimage_from_picref(IplImage *img, const AVFilterBufferRef *picref, enum PixelFormat pixfmt)
{
@@ -61,7 +63,7 @@ static int query_formats(AVFilterContext *ctx)
PIX_FMT_BGR24, PIX_FMT_BGRA, PIX_FMT_GRAY8, PIX_FMT_NONE
};
- avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
return 0;
}
@@ -69,7 +71,7 @@ static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { }
typedef struct {
const char *name;
- int (*init)(AVFilterContext *ctx, const char *args, void *opaque);
+ int (*init)(AVFilterContext *ctx, const char *args);
void (*uninit)(AVFilterContext *ctx);
void (*end_frame_filter)(AVFilterContext *ctx, IplImage *inimg, IplImage *outimg);
void *priv;
@@ -81,7 +83,7 @@ typedef struct {
double param3, param4;
} SmoothContext;
-static av_cold int smooth_init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int smooth_init(AVFilterContext *ctx, const char *args)
{
OCVContext *ocv = ctx->priv;
SmoothContext *smooth = ocv->priv;
@@ -119,7 +121,7 @@ static av_cold int smooth_init(AVFilterContext *ctx, const char *args, void *opa
return AVERROR(EINVAL);
}
- av_log(ctx, AV_LOG_INFO, "type:%s param1:%d param2:%d param3:%f param4:%f\n",
+ av_log(ctx, AV_LOG_VERBOSE, "type:%s param1:%d param2:%d param3:%f param4:%f\n",
type_str, smooth->param1, smooth->param2, smooth->param3, smooth->param4);
return 0;
}
@@ -237,7 +239,7 @@ static int parse_iplconvkernel(IplConvKernel **kernel, char *buf, void *log_ctx)
if (!*kernel)
return AVERROR(ENOMEM);
- av_log(log_ctx, AV_LOG_INFO, "Structuring element: w:%d h:%d x:%d y:%d shape:%s\n",
+ av_log(log_ctx, AV_LOG_VERBOSE, "Structuring element: w:%d h:%d x:%d y:%d shape:%s\n",
rows, cols, anchor_x, anchor_y, shape_str);
return 0;
}
@@ -247,7 +249,7 @@ typedef struct {
IplConvKernel *kernel;
} DilateContext;
-static av_cold int dilate_init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int dilate_init(AVFilterContext *ctx, const char *args)
{
OCVContext *ocv = ctx->priv;
DilateContext *dilate = ocv->priv;
@@ -267,7 +269,7 @@ static av_cold int dilate_init(AVFilterContext *ctx, const char *args, void *opa
av_free(kernel_str);
sscanf(buf, ":%d", &dilate->nb_iterations);
- av_log(ctx, AV_LOG_INFO, "iterations_nb:%d\n", dilate->nb_iterations);
+ av_log(ctx, AV_LOG_VERBOSE, "iterations_nb:%d\n", dilate->nb_iterations);
if (dilate->nb_iterations <= 0) {
av_log(ctx, AV_LOG_ERROR, "Invalid non-positive value '%d' for nb_iterations\n",
dilate->nb_iterations);
@@ -301,7 +303,7 @@ static void erode_end_frame_filter(AVFilterContext *ctx, IplImage *inimg, IplIma
typedef struct {
const char *name;
size_t priv_size;
- int (*init)(AVFilterContext *ctx, const char *args, void *opaque);
+ int (*init)(AVFilterContext *ctx, const char *args);
void (*uninit)(AVFilterContext *ctx);
void (*end_frame_filter)(AVFilterContext *ctx, IplImage *inimg, IplImage *outimg);
} OCVFilterEntry;
@@ -312,7 +314,7 @@ static OCVFilterEntry ocv_filter_entries[] = {
{ "smooth", sizeof(SmoothContext), smooth_init, NULL, smooth_end_frame_filter },
};
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
{
OCVContext *ocv = ctx->priv;
char name[128], priv_args[1024];
@@ -331,7 +333,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
if (!(ocv->priv = av_mallocz(entry->priv_size)))
return AVERROR(ENOMEM);
- return ocv->init(ctx, priv_args, opaque);
+ return ocv->init(ctx, priv_args);
}
}
@@ -364,8 +366,8 @@ static void end_frame(AVFilterLink *inlink)
fill_picref_from_iplimage(outpicref, &outimg, inlink->format);
avfilter_unref_buffer(inpicref);
- avfilter_draw_slice(outlink, 0, outlink->h, 1);
- avfilter_end_frame(outlink);
+ ff_draw_slice(outlink, 0, outlink->h, 1);
+ ff_end_frame(outlink);
avfilter_unref_buffer(outpicref);
}
diff --git a/libavfilter/vf_lut.c b/libavfilter/vf_lut.c
index b4950f4..8e96ed3 100644
--- a/libavfilter/vf_lut.c
+++ b/libavfilter/vf_lut.c
@@ -29,7 +29,9 @@
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "avfilter.h"
+#include "formats.h"
#include "internal.h"
+#include "video.h"
static const char *const var_names[] = {
"E",
@@ -108,7 +110,7 @@ static const AVClass lut_class = {
lut_options
};
-static int init(AVFilterContext *ctx, const char *args, void *opaque)
+static int init(AVFilterContext *ctx, const char *args)
{
LutContext *lut = ctx->priv;
int ret;
@@ -163,7 +165,7 @@ static int query_formats(AVFilterContext *ctx)
enum PixelFormat *pix_fmts = lut->is_rgb ? rgb_pix_fmts :
lut->is_yuv ? yuv_pix_fmts : all_pix_fmts;
- avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
return 0;
}
@@ -337,7 +339,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
}
}
- avfilter_draw_slice(outlink, y, h, slice_dir);
+ ff_draw_slice(outlink, y, h, slice_dir);
}
#define DEFINE_LUT_FILTER(name_, description_, init_) \
@@ -373,7 +375,7 @@ DEFINE_LUT_FILTER(lutrgb, "Compute and apply a lookup table to the RGB input vid
#if CONFIG_NEGATE_FILTER
-static int negate_init(AVFilterContext *ctx, const char *args, void *opaque)
+static int negate_init(AVFilterContext *ctx, const char *args)
{
LutContext *lut = ctx->priv;
char lut_params[64];
@@ -386,7 +388,7 @@ static int negate_init(AVFilterContext *ctx, const char *args, void *opaque)
snprintf(lut_params, sizeof(lut_params), "c0=negval:c1=negval:c2=negval:a=%s",
lut->negate_alpha ? "negval" : "val");
- return init(ctx, lut_params, opaque);
+ return init(ctx, lut_params);
}
DEFINE_LUT_FILTER(negate, "Negate input video.", negate_init);
diff --git a/libavfilter/vf_null.c b/libavfilter/vf_null.c
index 8414c5f..26545dc 100644
--- a/libavfilter/vf_null.c
+++ b/libavfilter/vf_null.c
@@ -22,6 +22,8 @@
*/
#include "avfilter.h"
+#include "internal.h"
+#include "video.h"
AVFilter avfilter_vf_null = {
.name = "null",
@@ -31,9 +33,9 @@ AVFilter avfilter_vf_null = {
.inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
- .get_video_buffer = avfilter_null_get_video_buffer,
- .start_frame = avfilter_null_start_frame,
- .end_frame = avfilter_null_end_frame },
+ .get_video_buffer = ff_null_get_video_buffer,
+ .start_frame = ff_null_start_frame,
+ .end_frame = ff_null_end_frame },
{ .name = NULL}},
.outputs = (AVFilterPad[]) {{ .name = "default",
diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c
index e8171e0..9852853 100644
--- a/libavfilter/vf_overlay.c
+++ b/libavfilter/vf_overlay.c
@@ -26,12 +26,14 @@
*/
#include "avfilter.h"
+#include "formats.h"
#include "libavutil/eval.h"
#include "libavutil/avstring.h"
#include "libavutil/pixdesc.h"
#include "libavutil/imgutils.h"
#include "libavutil/mathematics.h"
#include "internal.h"
+#include "video.h"
static const char *const var_names[] = {
"E",
@@ -69,7 +71,7 @@ typedef struct {
char x_expr[256], y_expr[256];
} OverlayContext;
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
{
OverlayContext *over = ctx->priv;
@@ -94,12 +96,12 @@ static int query_formats(AVFilterContext *ctx)
{
const enum PixelFormat inout_pix_fmts[] = { PIX_FMT_YUV420P, PIX_FMT_NONE };
const enum PixelFormat blend_pix_fmts[] = { PIX_FMT_YUVA420P, PIX_FMT_NONE };
- AVFilterFormats *inout_formats = avfilter_make_format_list(inout_pix_fmts);
- AVFilterFormats *blend_formats = avfilter_make_format_list(blend_pix_fmts);
+ AVFilterFormats *inout_formats = ff_make_format_list(inout_pix_fmts);
+ AVFilterFormats *blend_formats = ff_make_format_list(blend_pix_fmts);
- avfilter_formats_ref(inout_formats, &ctx->inputs [MAIN ]->out_formats);
- avfilter_formats_ref(blend_formats, &ctx->inputs [OVERLAY]->out_formats);
- avfilter_formats_ref(inout_formats, &ctx->outputs[MAIN ]->in_formats );
+ ff_formats_ref(inout_formats, &ctx->inputs [MAIN ]->out_formats);
+ ff_formats_ref(blend_formats, &ctx->inputs [OVERLAY]->out_formats);
+ ff_formats_ref(inout_formats, &ctx->outputs[MAIN ]->in_formats );
return 0;
}
@@ -149,7 +151,7 @@ static int config_input_overlay(AVFilterLink *inlink)
goto fail;
over->x = res;
- av_log(ctx, AV_LOG_INFO,
+ av_log(ctx, AV_LOG_VERBOSE,
"main w:%d h:%d fmt:%s overlay x:%d y:%d w:%d h:%d fmt:%s\n",
ctx->inputs[MAIN]->w, ctx->inputs[MAIN]->h,
av_pix_fmt_descriptors[ctx->inputs[MAIN]->format].name,
@@ -188,7 +190,7 @@ static int config_output(AVFilterLink *outlink)
av_gcd((int64_t)tb1.num * tb2.den,
(int64_t)tb2.num * tb1.den),
(int64_t)tb1.den * tb2.den, INT_MAX);
- av_log(ctx, AV_LOG_INFO,
+ av_log(ctx, AV_LOG_VERBOSE,
"main_tb:%d/%d overlay_tb:%d/%d -> tb:%d/%d exact:%d\n",
tb1.num, tb1.den, tb2.num, tb2.den, tb->num, tb->den, exact);
if (!exact)
@@ -203,7 +205,7 @@ static int config_output(AVFilterLink *outlink)
static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms, int w, int h)
{
- return avfilter_get_video_buffer(link->dst->outputs[0], perms, w, h);
+ return ff_get_video_buffer(link->dst->outputs[0], perms, w, h);
}
static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
@@ -219,7 +221,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
if (!over->overpicref || over->overpicref->pts < outpicref->pts) {
AVFilterBufferRef *old = over->overpicref;
over->overpicref = NULL;
- avfilter_request_frame(ctx->inputs[OVERLAY]);
+ ff_request_frame(ctx->inputs[OVERLAY]);
if (over->overpicref) {
if (old)
avfilter_unref_buffer(old);
@@ -227,7 +229,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
over->overpicref = old;
}
- avfilter_start_frame(inlink->dst->outputs[0], outpicref);
+ ff_start_frame(inlink->dst->outputs[0], outpicref);
}
static void start_frame_overlay(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
@@ -332,12 +334,12 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
over->overpicref->video->w, over->overpicref->video->h,
y, outpicref->video->w, h);
}
- avfilter_draw_slice(outlink, y, h, slice_dir);
+ ff_draw_slice(outlink, y, h, slice_dir);
}
static void end_frame(AVFilterLink *inlink)
{
- avfilter_end_frame(inlink->dst->outputs[0]);
+ ff_end_frame(inlink->dst->outputs[0]);
avfilter_unref_buffer(inlink->cur_buf);
}
@@ -349,12 +351,12 @@ static int poll_frame(AVFilterLink *link)
{
AVFilterContext *s = link->src;
OverlayContext *over = s->priv;
- int ret = avfilter_poll_frame(s->inputs[OVERLAY]);
+ int ret = ff_poll_frame(s->inputs[OVERLAY]);
if (ret == AVERROR_EOF)
ret = !!over->overpicref;
- return ret && avfilter_poll_frame(s->inputs[MAIN]);
+ return ret && ff_poll_frame(s->inputs[MAIN]);
}
AVFilter avfilter_vf_overlay = {
diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c
index fdadb1a..de7ae00 100644
--- a/libavfilter/vf_pad.c
+++ b/libavfilter/vf_pad.c
@@ -25,6 +25,9 @@
*/
#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
#include "libavutil/avstring.h"
#include "libavutil/eval.h"
#include "libavutil/pixdesc.h"
@@ -84,7 +87,7 @@ static int query_formats(AVFilterContext *ctx)
PIX_FMT_NONE
};
- avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
return 0;
}
@@ -105,7 +108,7 @@ typedef struct {
int needs_copy;
} PadContext;
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
{
PadContext *pad = ctx->priv;
char color_string[128] = "black";
@@ -217,7 +220,7 @@ static int config_input(AVFilterLink *inlink)
ff_fill_line_with_color(pad->line, pad->line_step, pad->w, pad->color,
inlink->format, rgba_color, &is_packed_rgba, NULL);
- av_log(ctx, AV_LOG_INFO, "w:%d h:%d -> w:%d h:%d x:%d y:%d color:0x%02X%02X%02X%02X[%s]\n",
+ av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d -> w:%d h:%d x:%d y:%d color:0x%02X%02X%02X%02X[%s]\n",
inlink->w, inlink->h, pad->w, pad->h, pad->x, pad->y,
pad->color[0], pad->color[1], pad->color[2], pad->color[3],
is_packed_rgba ? "rgba" : "yuva");
@@ -254,9 +257,9 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *inlink, int perms, int
{
PadContext *pad = inlink->dst->priv;
- AVFilterBufferRef *picref = avfilter_get_video_buffer(inlink->dst->outputs[0], perms,
- w + (pad->w - pad->in_w),
- h + (pad->h - pad->in_h));
+ AVFilterBufferRef *picref = ff_get_video_buffer(inlink->dst->outputs[0], perms,
+ w + (pad->w - pad->in_w),
+ h + (pad->h - pad->in_h));
int plane;
picref->video->w = w;
@@ -325,9 +328,9 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
if(pad->needs_copy){
av_log(inlink->dst, AV_LOG_DEBUG, "Direct padding impossible allocating new frame\n");
avfilter_unref_buffer(outpicref);
- outpicref = avfilter_get_video_buffer(inlink->dst->outputs[0], AV_PERM_WRITE | AV_PERM_NEG_LINESIZES,
- FFMAX(inlink->w, pad->w),
- FFMAX(inlink->h, pad->h));
+ outpicref = ff_get_video_buffer(inlink->dst->outputs[0], AV_PERM_WRITE | AV_PERM_NEG_LINESIZES,
+ FFMAX(inlink->w, pad->w),
+ FFMAX(inlink->h, pad->h));
avfilter_copy_buffer_ref_props(outpicref, inpicref);
}
@@ -336,12 +339,12 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
outpicref->video->w = pad->w;
outpicref->video->h = pad->h;
- avfilter_start_frame(inlink->dst->outputs[0], outpicref);
+ ff_start_frame(inlink->dst->outputs[0], outpicref);
}
static void end_frame(AVFilterLink *link)
{
- avfilter_end_frame(link->dst->outputs[0]);
+ ff_end_frame(link->dst->outputs[0]);
avfilter_unref_buffer(link->cur_buf);
}
@@ -365,7 +368,7 @@ static void draw_send_bar_slice(AVFilterLink *link, int y, int h, int slice_dir,
link->dst->outputs[0]->out_buf->linesize,
pad->line, pad->line_step, pad->hsub, pad->vsub,
0, bar_y, pad->w, bar_h);
- avfilter_draw_slice(link->dst->outputs[0], bar_y, bar_h, slice_dir);
+ ff_draw_slice(link->dst->outputs[0], bar_y, bar_h, slice_dir);
}
}
@@ -399,7 +402,7 @@ static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
ff_draw_rectangle(outpic->data, outpic->linesize,
pad->line, pad->line_step, pad->hsub, pad->vsub,
pad->x + pad->in_w, y, pad->w - pad->x - pad->in_w, h);
- avfilter_draw_slice(link->dst->outputs[0], y, h, slice_dir);
+ ff_draw_slice(link->dst->outputs[0], y, h, slice_dir);
draw_send_bar_slice(link, y, h, slice_dir, -1);
}
diff --git a/libavfilter/vf_pixdesctest.c b/libavfilter/vf_pixdesctest.c
index cf7dfed..37dbe2d 100644
--- a/libavfilter/vf_pixdesctest.c
+++ b/libavfilter/vf_pixdesctest.c
@@ -25,6 +25,8 @@
#include "libavutil/pixdesc.h"
#include "avfilter.h"
+#include "internal.h"
+#include "video.h"
typedef struct {
const AVPixFmtDescriptor *pix_desc;
@@ -56,8 +58,8 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
AVFilterBufferRef *outpicref;
int i;
- outlink->out_buf = avfilter_get_video_buffer(outlink, AV_PERM_WRITE,
- outlink->w, outlink->h);
+ outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE,
+ outlink->w, outlink->h);
outpicref = outlink->out_buf;
avfilter_copy_buffer_ref_props(outpicref, picref);
@@ -76,7 +78,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
priv->pix_desc->flags & PIX_FMT_PSEUDOPAL)
memcpy(outpicref->data[1], outpicref->data[1], 256*4);
- avfilter_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0));
+ ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0));
}
static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
@@ -106,7 +108,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
}
}
- avfilter_draw_slice(inlink->dst->outputs[0], y, h, slice_dir);
+ ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir);
}
AVFilter avfilter_vf_pixdesctest = {
diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
index 85095b7..2786993 100644
--- a/libavfilter/vf_scale.c
+++ b/libavfilter/vf_scale.c
@@ -24,6 +24,9 @@
*/
#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
#include "libavutil/avstring.h"
#include "libavutil/eval.h"
#include "libavutil/mathematics.h"
@@ -80,7 +83,7 @@ typedef struct {
char h_expr[256]; ///< height expression string
} ScaleContext;
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
{
ScaleContext *scale = ctx->priv;
const char *p;
@@ -123,21 +126,21 @@ static int query_formats(AVFilterContext *ctx)
formats = NULL;
for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++)
if ( sws_isSupportedInput(pix_fmt)
- && (ret = avfilter_add_format(&formats, pix_fmt)) < 0) {
- avfilter_formats_unref(&formats);
+ && (ret = ff_add_format(&formats, pix_fmt)) < 0) {
+ ff_formats_unref(&formats);
return ret;
}
- avfilter_formats_ref(formats, &ctx->inputs[0]->out_formats);
+ ff_formats_ref(formats, &ctx->inputs[0]->out_formats);
}
if (ctx->outputs[0]) {
formats = NULL;
for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++)
if ( sws_isSupportedOutput(pix_fmt)
- && (ret = avfilter_add_format(&formats, pix_fmt)) < 0) {
- avfilter_formats_unref(&formats);
+ && (ret = ff_add_format(&formats, pix_fmt)) < 0) {
+ ff_formats_unref(&formats);
return ret;
}
- avfilter_formats_ref(formats, &ctx->outputs[0]->in_formats);
+ ff_formats_ref(formats, &ctx->outputs[0]->in_formats);
}
return 0;
@@ -212,7 +215,7 @@ static int config_props(AVFilterLink *outlink)
outlink->h = h;
/* TODO: make algorithm configurable */
- av_log(ctx, AV_LOG_INFO, "w:%d h:%d fmt:%s -> w:%d h:%d fmt:%s flags:0x%0x\n",
+ av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d fmt:%s -> w:%d h:%d fmt:%s flags:0x%0x\n",
inlink ->w, inlink ->h, av_pix_fmt_descriptors[ inlink->format].name,
outlink->w, outlink->h, av_pix_fmt_descriptors[outlink->format].name,
scale->flags);
@@ -256,14 +259,14 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
AVFilterBufferRef *outpicref;
if (!scale->sws) {
- avfilter_start_frame(outlink, avfilter_ref_buffer(picref, ~0));
+ ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0));
return;
}
scale->hsub = av_pix_fmt_descriptors[link->format].log2_chroma_w;
scale->vsub = av_pix_fmt_descriptors[link->format].log2_chroma_h;
- outpicref = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+ outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
avfilter_copy_buffer_ref_props(outpicref, picref);
outpicref->video->w = outlink->w;
outpicref->video->h = outlink->h;
@@ -276,7 +279,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
INT_MAX);
scale->slice_y = 0;
- avfilter_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0));
+ ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0));
}
static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
@@ -287,7 +290,7 @@ static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
const uint8_t *data[4];
if (!scale->sws) {
- avfilter_draw_slice(link->dst->outputs[0], y, h, slice_dir);
+ ff_draw_slice(link->dst->outputs[0], y, h, slice_dir);
return;
}
@@ -307,7 +310,7 @@ static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
if (slice_dir == -1)
scale->slice_y -= out_h;
- avfilter_draw_slice(link->dst->outputs[0], scale->slice_y, out_h, slice_dir);
+ ff_draw_slice(link->dst->outputs[0], scale->slice_y, out_h, slice_dir);
if (slice_dir == 1)
scale->slice_y += out_h;
}
diff --git a/libavfilter/vf_select.c b/libavfilter/vf_select.c
index 13ec040..719885e 100644
--- a/libavfilter/vf_select.c
+++ b/libavfilter/vf_select.c
@@ -27,6 +27,8 @@
#include "libavutil/fifo.h"
#include "libavutil/mathematics.h"
#include "avfilter.h"
+#include "internal.h"
+#include "video.h"
static const char *const var_names[] = {
"E", ///< Euler number
@@ -120,7 +122,7 @@ typedef struct {
AVFifoBuffer *pending_frames; ///< FIFO buffer of video frames
} SelectContext;
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
{
SelectContext *select = ctx->priv;
int ret;
@@ -241,7 +243,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
sizeof(picref), NULL);
return;
}
- avfilter_start_frame(inlink->dst->outputs[0], avfilter_ref_buffer(picref, ~0));
+ ff_start_frame(inlink->dst->outputs[0], avfilter_ref_buffer(picref, ~0));
}
}
@@ -250,7 +252,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
SelectContext *select = inlink->dst->priv;
if (select->select && !select->cache_frames)
- avfilter_draw_slice(inlink->dst->outputs[0], y, h, slice_dir);
+ ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir);
}
static void end_frame(AVFilterLink *inlink)
@@ -261,7 +263,7 @@ static void end_frame(AVFilterLink *inlink)
if (select->select) {
if (select->cache_frames)
return;
- avfilter_end_frame(inlink->dst->outputs[0]);
+ ff_end_frame(inlink->dst->outputs[0]);
}
avfilter_unref_buffer(picref);
}
@@ -276,15 +278,15 @@ static int request_frame(AVFilterLink *outlink)
if (av_fifo_size(select->pending_frames)) {
AVFilterBufferRef *picref;
av_fifo_generic_read(select->pending_frames, &picref, sizeof(picref), NULL);
- avfilter_start_frame(outlink, avfilter_ref_buffer(picref, ~0));
- avfilter_draw_slice(outlink, 0, outlink->h, 1);
- avfilter_end_frame(outlink);
+ ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0));
+ ff_draw_slice(outlink, 0, outlink->h, 1);
+ ff_end_frame(outlink);
avfilter_unref_buffer(picref);
return 0;
}
while (!select->select) {
- int ret = avfilter_request_frame(inlink);
+ int ret = ff_request_frame(inlink);
if (ret < 0)
return ret;
}
@@ -299,12 +301,12 @@ static int poll_frame(AVFilterLink *outlink)
int count, ret;
if (!av_fifo_size(select->pending_frames)) {
- if ((count = avfilter_poll_frame(inlink)) <= 0)
+ if ((count = ff_poll_frame(inlink)) <= 0)
return count;
/* request frame from input, and apply select condition to it */
select->cache_frames = 1;
while (count-- && av_fifo_space(select->pending_frames)) {
- ret = avfilter_request_frame(inlink);
+ ret = ff_request_frame(inlink);
if (ret < 0)
break;
}
@@ -339,7 +341,7 @@ AVFilter avfilter_vf_select = {
.inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
- .get_video_buffer = avfilter_null_get_video_buffer,
+ .get_video_buffer = ff_null_get_video_buffer,
.config_props = config_input,
.start_frame = start_frame,
.draw_slice = draw_slice,
diff --git a/libavfilter/vf_setpts.c b/libavfilter/vf_setpts.c
index b49ca5e..ecffc0f 100644
--- a/libavfilter/vf_setpts.c
+++ b/libavfilter/vf_setpts.c
@@ -29,6 +29,8 @@
#include "libavutil/eval.h"
#include "libavutil/mathematics.h"
#include "avfilter.h"
+#include "internal.h"
+#include "video.h"
static const char *const var_names[] = {
"E", ///< Euler number
@@ -65,7 +67,7 @@ typedef struct {
double var_values[VAR_VARS_NB];
} SetPTSContext;
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
{
SetPTSContext *setpts = ctx->priv;
int ret;
@@ -92,7 +94,7 @@ static int config_input(AVFilterLink *inlink)
setpts->var_values[VAR_TB] = av_q2d(inlink->time_base);
- av_log(inlink->src, AV_LOG_INFO, "TB:%f\n", setpts->var_values[VAR_TB]);
+ av_log(inlink->src, AV_LOG_VERBOSE, "TB:%f\n", setpts->var_values[VAR_TB]);
return 0;
}
@@ -128,7 +130,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
setpts->var_values[VAR_N] += 1.0;
setpts->var_values[VAR_PREV_INPTS ] = TS2D(inpicref ->pts);
setpts->var_values[VAR_PREV_OUTPTS] = TS2D(outpicref->pts);
- avfilter_start_frame(inlink->dst->outputs[0], outpicref);
+ ff_start_frame(inlink->dst->outputs[0], outpicref);
}
static av_cold void uninit(AVFilterContext *ctx)
@@ -148,7 +150,7 @@ AVFilter avfilter_vf_setpts = {
.inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
- .get_video_buffer = avfilter_null_get_video_buffer,
+ .get_video_buffer = ff_null_get_video_buffer,
.config_props = config_input,
.start_frame = start_frame, },
{ .name = NULL }},
diff --git a/libavfilter/vf_settb.c b/libavfilter/vf_settb.c
index 49f7a57..62084bf 100644
--- a/libavfilter/vf_settb.c
+++ b/libavfilter/vf_settb.c
@@ -29,6 +29,7 @@
#include "libavutil/rational.h"
#include "avfilter.h"
#include "internal.h"
+#include "video.h"
static const char *const var_names[] = {
"E",
@@ -53,7 +54,7 @@ typedef struct {
double var_values[VAR_VARS_NB];
} SetTBContext;
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
{
SetTBContext *settb = ctx->priv;
av_strlcpy(settb->tb_expr, "intb", sizeof(settb->tb_expr));
@@ -96,7 +97,7 @@ static int config_output_props(AVFilterLink *outlink)
}
outlink->time_base = time_base;
- av_log(outlink->src, AV_LOG_INFO, "tb:%d/%d -> tb:%d/%d\n",
+ av_log(outlink->src, AV_LOG_VERBOSE, "tb:%d/%d -> tb:%d/%d\n",
inlink ->time_base.num, inlink ->time_base.den,
outlink->time_base.num, outlink->time_base.den);
@@ -118,7 +119,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
avfilter_unref_buffer(picref);
}
- avfilter_start_frame(outlink, picref2);
+ ff_start_frame(outlink, picref2);
}
AVFilter avfilter_vf_settb = {
@@ -130,9 +131,9 @@ AVFilter avfilter_vf_settb = {
.inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
- .get_video_buffer = avfilter_null_get_video_buffer,
+ .get_video_buffer = ff_null_get_video_buffer,
.start_frame = start_frame,
- .end_frame = avfilter_null_end_frame },
+ .end_frame = ff_null_end_frame },
{ .name = NULL }},
.outputs = (AVFilterPad[]) {{ .name = "default",
diff --git a/libavfilter/vf_showinfo.c b/libavfilter/vf_showinfo.c
index aa2a7f1..b8053b5 100644
--- a/libavfilter/vf_showinfo.c
+++ b/libavfilter/vf_showinfo.c
@@ -26,12 +26,14 @@
#include "libavutil/imgutils.h"
#include "libavutil/pixdesc.h"
#include "avfilter.h"
+#include "internal.h"
+#include "video.h"
typedef struct {
unsigned int frame;
} ShowInfoContext;
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
{
ShowInfoContext *showinfo = ctx->priv;
showinfo->frame = 0;
@@ -74,7 +76,7 @@ static void end_frame(AVFilterLink *inlink)
checksum, plane_checksum[0], plane_checksum[1], plane_checksum[2], plane_checksum[3]);
showinfo->frame++;
- avfilter_end_frame(inlink->dst->outputs[0]);
+ ff_end_frame(inlink->dst->outputs[0]);
}
AVFilter avfilter_vf_showinfo = {
@@ -86,8 +88,8 @@ AVFilter avfilter_vf_showinfo = {
.inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
- .get_video_buffer = avfilter_null_get_video_buffer,
- .start_frame = avfilter_null_start_frame,
+ .get_video_buffer = ff_null_get_video_buffer,
+ .start_frame = ff_null_start_frame,
.end_frame = end_frame,
.min_perms = AV_PERM_READ, },
{ .name = NULL}},
diff --git a/libavfilter/vf_slicify.c b/libavfilter/vf_slicify.c
index cc56fe8..e256c45 100644
--- a/libavfilter/vf_slicify.c
+++ b/libavfilter/vf_slicify.c
@@ -24,6 +24,8 @@
*/
#include "avfilter.h"
+#include "internal.h"
+#include "video.h"
#include "libavutil/pixdesc.h"
typedef struct {
@@ -33,7 +35,7 @@ typedef struct {
int use_random_h; ///< enable the use of random slice height values
} SliceContext;
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
{
SliceContext *slice = ctx->priv;
@@ -72,7 +74,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
av_log(link->dst, AV_LOG_DEBUG, "h:%d\n", slice->h);
- avfilter_start_frame(link->dst->outputs[0], picref);
+ ff_start_frame(link->dst->outputs[0], picref);
}
static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
@@ -82,16 +84,16 @@ static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
if (slice_dir == 1) {
for (y2 = y; y2 + slice->h <= y + h; y2 += slice->h)
- avfilter_draw_slice(link->dst->outputs[0], y2, slice->h, slice_dir);
+ ff_draw_slice(link->dst->outputs[0], y2, slice->h, slice_dir);
if (y2 < y + h)
- avfilter_draw_slice(link->dst->outputs[0], y2, y + h - y2, slice_dir);
+ ff_draw_slice(link->dst->outputs[0], y2, y + h - y2, slice_dir);
} else if (slice_dir == -1) {
for (y2 = y + h; y2 - slice->h >= y; y2 -= slice->h)
- avfilter_draw_slice(link->dst->outputs[0], y2 - slice->h, slice->h, slice_dir);
+ ff_draw_slice(link->dst->outputs[0], y2 - slice->h, slice->h, slice_dir);
if (y2 > y)
- avfilter_draw_slice(link->dst->outputs[0], y, y2 - y, slice_dir);
+ ff_draw_slice(link->dst->outputs[0], y, y2 - y, slice_dir);
}
}
@@ -105,11 +107,11 @@ AVFilter avfilter_vf_slicify = {
.inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
- .get_video_buffer = avfilter_null_get_video_buffer,
+ .get_video_buffer = ff_null_get_video_buffer,
.start_frame = start_frame,
.draw_slice = draw_slice,
.config_props = config_props,
- .end_frame = avfilter_null_end_frame, },
+ .end_frame = ff_null_end_frame, },
{ .name = NULL}},
.outputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO, },
diff --git a/libavfilter/vf_split.c b/libavfilter/vf_split.c
deleted file mode 100644
index 54fdd21..0000000
--- a/libavfilter/vf_split.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2007 Bobby Bingham
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * Video splitter
- */
-
-#include "avfilter.h"
-
-static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
-{
- avfilter_start_frame(inlink->dst->outputs[0],
- avfilter_ref_buffer(picref, ~AV_PERM_WRITE));
- avfilter_start_frame(inlink->dst->outputs[1],
- avfilter_ref_buffer(picref, ~AV_PERM_WRITE));
-}
-
-static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
-{
- avfilter_draw_slice(inlink->dst->outputs[0], y, h, slice_dir);
- avfilter_draw_slice(inlink->dst->outputs[1], y, h, slice_dir);
-}
-
-static void end_frame(AVFilterLink *inlink)
-{
- avfilter_end_frame(inlink->dst->outputs[0]);
- avfilter_end_frame(inlink->dst->outputs[1]);
-
- avfilter_unref_buffer(inlink->cur_buf);
-}
-
-AVFilter avfilter_vf_split = {
- .name = "split",
- .description = NULL_IF_CONFIG_SMALL("Pass on the input to two outputs."),
-
- .inputs = (AVFilterPad[]) {{ .name = "default",
- .type = AVMEDIA_TYPE_VIDEO,
- .get_video_buffer= avfilter_null_get_video_buffer,
- .start_frame = start_frame,
- .draw_slice = draw_slice,
- .end_frame = end_frame, },
- { .name = NULL}},
- .outputs = (AVFilterPad[]) {{ .name = "output1",
- .type = AVMEDIA_TYPE_VIDEO, },
- { .name = "output2",
- .type = AVMEDIA_TYPE_VIDEO, },
- { .name = NULL}},
-};
diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c
index a0ec67c..f78244e 100644
--- a/libavfilter/vf_transpose.c
+++ b/libavfilter/vf_transpose.c
@@ -29,6 +29,9 @@
#include "libavutil/pixdesc.h"
#include "libavutil/imgutils.h"
#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
typedef struct {
int hsub, vsub;
@@ -41,7 +44,7 @@ typedef struct {
int dir;
} TransContext;
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
{
TransContext *trans = ctx->priv;
trans->dir = 0;
@@ -83,7 +86,7 @@ static int query_formats(AVFilterContext *ctx)
PIX_FMT_NONE
};
- avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
return 0;
}
@@ -107,7 +110,7 @@ static int config_props_output(AVFilterLink *outlink)
} else
outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
- av_log(ctx, AV_LOG_INFO, "w:%d h:%d dir:%d -> w:%d h:%d rotation:%s vflip:%d\n",
+ av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d dir:%d -> w:%d h:%d rotation:%s vflip:%d\n",
inlink->w, inlink->h, trans->dir, outlink->w, outlink->h,
trans->dir == 1 || trans->dir == 3 ? "clockwise" : "counterclockwise",
trans->dir == 0 || trans->dir == 3);
@@ -118,8 +121,8 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
{
AVFilterLink *outlink = inlink->dst->outputs[0];
- outlink->out_buf = avfilter_get_video_buffer(outlink, AV_PERM_WRITE,
- outlink->w, outlink->h);
+ outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE,
+ outlink->w, outlink->h);
outlink->out_buf->pts = picref->pts;
if (picref->video->pixel_aspect.num == 0) {
@@ -129,7 +132,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
outlink->out_buf->video->pixel_aspect.den = picref->video->pixel_aspect.num;
}
- avfilter_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0));
+ ff_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0));
}
static void end_frame(AVFilterLink *inlink)
@@ -190,8 +193,8 @@ static void end_frame(AVFilterLink *inlink)
}
avfilter_unref_buffer(inpic);
- avfilter_draw_slice(outlink, 0, outpic->video->h, 1);
- avfilter_end_frame(outlink);
+ ff_draw_slice(outlink, 0, outpic->video->h, 1);
+ ff_end_frame(outlink);
avfilter_unref_buffer(outpic);
}
diff --git a/libavfilter/vf_unsharp.c b/libavfilter/vf_unsharp.c
index 7aca2cf..ddfbf2c 100644
--- a/libavfilter/vf_unsharp.c
+++ b/libavfilter/vf_unsharp.c
@@ -37,6 +37,9 @@
*/
#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
#include "libavutil/common.h"
#include "libavutil/mem.h"
#include "libavutil/pixdesc.h"
@@ -129,7 +132,7 @@ static void set_filter_param(FilterParam *fp, int msize_x, int msize_y, double a
fp->halfscale = 1 << (fp->scalebits - 1);
}
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
{
UnsharpContext *unsharp = ctx->priv;
int lmsize_x = 5, cmsize_x = 5;
@@ -162,7 +165,7 @@ static int query_formats(AVFilterContext *ctx)
PIX_FMT_YUVJ444P, PIX_FMT_YUVJ440P, PIX_FMT_NONE
};
- avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
return 0;
}
@@ -174,7 +177,7 @@ static void init_filter_param(AVFilterContext *ctx, FilterParam *fp, const char
effect = fp->amount == 0 ? "none" : fp->amount < 0 ? "blur" : "sharpen";
- av_log(ctx, AV_LOG_INFO, "effect:%s type:%s msize_x:%d msize_y:%d amount:%0.2f\n",
+ av_log(ctx, AV_LOG_VERBOSE, "effect:%s type:%s msize_x:%d msize_y:%d amount:%0.2f\n",
effect, effect_type, fp->msize_x, fp->msize_y, fp->amount / 65535.0);
for (z = 0; z < 2 * fp->steps_y; z++)
@@ -223,8 +226,8 @@ static void end_frame(AVFilterLink *link)
apply_unsharp(out->data[2], out->linesize[2], in->data[2], in->linesize[2], cw, ch, &unsharp->chroma);
avfilter_unref_buffer(in);
- avfilter_draw_slice(link->dst->outputs[0], 0, link->h, 1);
- avfilter_end_frame(link->dst->outputs[0]);
+ ff_draw_slice(link->dst->outputs[0], 0, link->h, 1);
+ ff_end_frame(link->dst->outputs[0]);
avfilter_unref_buffer(out);
}
diff --git a/libavfilter/vf_vflip.c b/libavfilter/vf_vflip.c
index 09ba303..0f528f1 100644
--- a/libavfilter/vf_vflip.c
+++ b/libavfilter/vf_vflip.c
@@ -25,6 +25,8 @@
#include "libavutil/pixdesc.h"
#include "avfilter.h"
+#include "internal.h"
+#include "video.h"
typedef struct {
int vsub; ///< vertical chroma subsampling
@@ -47,9 +49,9 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms,
int i;
if (!(perms & AV_PERM_NEG_LINESIZES))
- return avfilter_default_get_video_buffer(link, perms, w, h);
+ return ff_default_get_video_buffer(link, perms, w, h);
- picref = avfilter_get_video_buffer(link->dst->outputs[0], perms, w, h);
+ picref = ff_get_video_buffer(link->dst->outputs[0], perms, w, h);
for (i = 0; i < 4; i ++) {
int vsub = i == 1 || i == 2 ? flip->vsub : 0;
@@ -77,14 +79,14 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *inpicref)
}
}
- avfilter_start_frame(link->dst->outputs[0], outpicref);
+ ff_start_frame(link->dst->outputs[0], outpicref);
}
static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
{
AVFilterContext *ctx = link->dst;
- avfilter_draw_slice(ctx->outputs[0], link->h - (y+h), h, -1 * slice_dir);
+ ff_draw_slice(ctx->outputs[0], link->h - (y+h), h, -1 * slice_dir);
}
AVFilter avfilter_vf_vflip = {
diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c
index 12b3783..230e797 100644
--- a/libavfilter/vf_yadif.c
+++ b/libavfilter/vf_yadif.c
@@ -23,46 +23,14 @@
#include "libavutil/common.h"
#include "libavutil/pixdesc.h"
#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
#include "yadif.h"
#undef NDEBUG
#include <assert.h>
-typedef struct {
- /**
- * 0: send 1 frame for each frame
- * 1: send 1 frame for each field
- * 2: like 0 but skips spatial interlacing check
- * 3: like 1 but skips spatial interlacing check
- */
- int mode;
-
- /**
- * 0: top field first
- * 1: bottom field first
- * -1: auto-detection
- */
- int parity;
-
- int frame_pending;
-
- /**
- * 0: deinterlace all frames
- * 1: only deinterlace frames marked as interlaced
- */
- int auto_enable;
-
- AVFilterBufferRef *cur;
- AVFilterBufferRef *next;
- AVFilterBufferRef *prev;
- AVFilterBufferRef *out;
- void (*filter_line)(uint8_t *dst,
- uint8_t *prev, uint8_t *cur, uint8_t *next,
- int w, int prefs, int mrefs, int parity, int mode);
-
- const AVPixFmtDescriptor *csp;
-} YADIFContext;
-
#define CHECK(j)\
{ int score = FFABS(cur[mrefs-1+(j)] - cur[prefs-1-(j)])\
+ FFABS(cur[mrefs +(j)] - cur[prefs -(j)])\
@@ -179,7 +147,7 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms, int w,
int height= FFALIGN(h+2, 32);
int i;
- picref = avfilter_default_get_video_buffer(link, perms, width, height);
+ picref = ff_default_get_video_buffer(link, perms, width, height);
picref->video->w = w;
picref->video->h = h;
@@ -204,8 +172,8 @@ static void return_frame(AVFilterContext *ctx, int is_second)
}
if (is_second) {
- yadif->out = avfilter_get_video_buffer(link, AV_PERM_WRITE | AV_PERM_PRESERVE |
- AV_PERM_REUSE, link->w, link->h);
+ yadif->out = ff_get_video_buffer(link, AV_PERM_WRITE | AV_PERM_PRESERVE |
+ AV_PERM_REUSE, link->w, link->h);
avfilter_copy_buffer_ref_props(yadif->out, yadif->cur);
yadif->out->video->interlaced = 0;
}
@@ -218,18 +186,18 @@ static void return_frame(AVFilterContext *ctx, int is_second)
filter(ctx, yadif->out, tff ^ !is_second, tff);
if (is_second) {
- if (yadif->next->pts != AV_NOPTS_VALUE &&
- yadif->cur->pts != AV_NOPTS_VALUE) {
- yadif->out->pts =
- (yadif->next->pts&yadif->cur->pts) +
- ((yadif->next->pts^yadif->cur->pts)>>1);
+ int64_t cur_pts = yadif->cur->pts;
+ int64_t next_pts = yadif->next->pts;
+
+ if (next_pts != AV_NOPTS_VALUE && cur_pts != AV_NOPTS_VALUE) {
+ yadif->out->pts = cur_pts + next_pts;
} else {
yadif->out->pts = AV_NOPTS_VALUE;
}
- avfilter_start_frame(ctx->outputs[0], yadif->out);
+ ff_start_frame(ctx->outputs[0], yadif->out);
}
- avfilter_draw_slice(ctx->outputs[0], 0, link->h, 1);
- avfilter_end_frame(ctx->outputs[0]);
+ ff_draw_slice(ctx->outputs[0], 0, link->h, 1);
+ ff_end_frame(ctx->outputs[0]);
yadif->frame_pending = (yadif->mode&1) && !is_second;
}
@@ -255,19 +223,23 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
yadif->out = avfilter_ref_buffer(yadif->cur, AV_PERM_READ);
avfilter_unref_buffer(yadif->prev);
yadif->prev = NULL;
- avfilter_start_frame(ctx->outputs[0], yadif->out);
+ if (yadif->out->pts != AV_NOPTS_VALUE)
+ yadif->out->pts *= 2;
+ ff_start_frame(ctx->outputs[0], yadif->out);
return;
}
if (!yadif->prev)
yadif->prev = avfilter_ref_buffer(yadif->cur, AV_PERM_READ);
- yadif->out = avfilter_get_video_buffer(ctx->outputs[0], AV_PERM_WRITE | AV_PERM_PRESERVE |
- AV_PERM_REUSE, link->w, link->h);
+ yadif->out = ff_get_video_buffer(ctx->outputs[0], AV_PERM_WRITE | AV_PERM_PRESERVE |
+ AV_PERM_REUSE, link->w, link->h);
avfilter_copy_buffer_ref_props(yadif->out, yadif->cur);
yadif->out->video->interlaced = 0;
- avfilter_start_frame(ctx->outputs[0], yadif->out);
+ if (yadif->out->pts != AV_NOPTS_VALUE)
+ yadif->out->pts *= 2;
+ ff_start_frame(ctx->outputs[0], yadif->out);
}
static void end_frame(AVFilterLink *link)
@@ -279,8 +251,8 @@ static void end_frame(AVFilterLink *link)
return;
if (yadif->auto_enable && !yadif->cur->video->interlaced) {
- avfilter_draw_slice(ctx->outputs[0], 0, link->h, 1);
- avfilter_end_frame(ctx->outputs[0]);
+ ff_draw_slice(ctx->outputs[0], 0, link->h, 1);
+ ff_end_frame(ctx->outputs[0]);
return;
}
@@ -300,8 +272,21 @@ static int request_frame(AVFilterLink *link)
do {
int ret;
- if ((ret = avfilter_request_frame(link->src->inputs[0])))
+ if (yadif->eof)
+ return AVERROR_EOF;
+
+ ret = ff_request_frame(link->src->inputs[0]);
+
+ if (ret == AVERROR_EOF && yadif->next) {
+ AVFilterBufferRef *next = avfilter_ref_buffer(yadif->next, AV_PERM_READ);
+ next->pts = yadif->next->pts * 2 - yadif->cur->pts;
+
+ start_frame(link->src->inputs[0], next);
+ end_frame(link->src->inputs[0]);
+ yadif->eof = 1;
+ } else if (ret < 0) {
return ret;
+ }
} while (!yadif->cur);
return 0;
@@ -315,12 +300,16 @@ static int poll_frame(AVFilterLink *link)
if (yadif->frame_pending)
return 1;
- val = avfilter_poll_frame(link->src->inputs[0]);
+ val = ff_poll_frame(link->src->inputs[0]);
+ if (val <= 0)
+ return val;
if (val==1 && !yadif->next) { //FIXME change API to not requre this red tape
- if ((ret = avfilter_request_frame(link->src->inputs[0])) < 0)
+ if ((ret = ff_request_frame(link->src->inputs[0])) < 0)
return ret;
- val = avfilter_poll_frame(link->src->inputs[0]);
+ val = ff_poll_frame(link->src->inputs[0]);
+ if (val <= 0)
+ return val;
}
assert(yadif->next || !val);
@@ -364,15 +353,14 @@ static int query_formats(AVFilterContext *ctx)
PIX_FMT_NONE
};
- avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
return 0;
}
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
{
YADIFContext *yadif = ctx->priv;
- int cpu_flags = av_get_cpu_flags();
yadif->mode = 0;
yadif->parity = -1;
@@ -382,20 +370,27 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
if (args) sscanf(args, "%d:%d:%d", &yadif->mode, &yadif->parity, &yadif->auto_enable);
yadif->filter_line = filter_line_c;
- if (HAVE_SSSE3 && cpu_flags & AV_CPU_FLAG_SSSE3)
- yadif->filter_line = ff_yadif_filter_line_ssse3;
- else if (HAVE_SSE && cpu_flags & AV_CPU_FLAG_SSE2)
- yadif->filter_line = ff_yadif_filter_line_sse2;
- else if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX)
- yadif->filter_line = ff_yadif_filter_line_mmx;
- av_log(ctx, AV_LOG_INFO, "mode:%d parity:%d auto_enable:%d\n", yadif->mode, yadif->parity, yadif->auto_enable);
+ if (HAVE_MMX)
+ ff_yadif_init_x86(yadif);
+
+ av_log(ctx, AV_LOG_VERBOSE, "mode:%d parity:%d auto_enable:%d\n", yadif->mode, yadif->parity, yadif->auto_enable);
return 0;
}
static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { }
+static int config_props(AVFilterLink *link)
+{
+ link->time_base.num = link->src->inputs[0]->time_base.num;
+ link->time_base.den = link->src->inputs[0]->time_base.den * 2;
+ link->w = link->src->inputs[0]->w;
+ link->h = link->src->inputs[0]->h;
+
+ return 0;
+}
+
AVFilter avfilter_vf_yadif = {
.name = "yadif",
.description = NULL_IF_CONFIG_SMALL("Deinterlace the input image"),
@@ -416,6 +411,7 @@ AVFilter avfilter_vf_yadif = {
.outputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.poll_frame = poll_frame,
- .request_frame = request_frame, },
+ .request_frame = request_frame,
+ .config_props = config_props, },
{ .name = NULL}},
};
diff --git a/libavfilter/video.c b/libavfilter/video.c
new file mode 100644
index 0000000..feaaeba
--- /dev/null
+++ b/libavfilter/video.c
@@ -0,0 +1,310 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/imgutils.h"
+
+#include "avfilter.h"
+#include "internal.h"
+#include "video.h"
+
+#ifdef DEBUG
+static char *ff_get_ref_perms_string(char *buf, size_t buf_size, int perms)
+{
+ snprintf(buf, buf_size, "%s%s%s%s%s%s",
+ perms & AV_PERM_READ ? "r" : "",
+ perms & AV_PERM_WRITE ? "w" : "",
+ perms & AV_PERM_PRESERVE ? "p" : "",
+ perms & AV_PERM_REUSE ? "u" : "",
+ perms & AV_PERM_REUSE2 ? "U" : "",
+ perms & AV_PERM_NEG_LINESIZES ? "n" : "");
+ return buf;
+}
+#endif
+
+static void ff_dlog_ref(void *ctx, AVFilterBufferRef *ref, int end)
+{
+ av_unused char buf[16];
+ av_dlog(ctx,
+ "ref[%p buf:%p refcount:%d perms:%s data:%p linesize[%d, %d, %d, %d] pts:%"PRId64" pos:%"PRId64,
+ ref, ref->buf, ref->buf->refcount, ff_get_ref_perms_string(buf, sizeof(buf), ref->perms), ref->data[0],
+ ref->linesize[0], ref->linesize[1], ref->linesize[2], ref->linesize[3],
+ ref->pts, ref->pos);
+
+ if (ref->video) {
+ av_dlog(ctx, " a:%d/%d s:%dx%d i:%c iskey:%d type:%c",
+ ref->video->pixel_aspect.num, ref->video->pixel_aspect.den,
+ ref->video->w, ref->video->h,
+ !ref->video->interlaced ? 'P' : /* Progressive */
+ ref->video->top_field_first ? 'T' : 'B', /* Top / Bottom */
+ ref->video->key_frame,
+ av_get_picture_type_char(ref->video->pict_type));
+ }
+ if (ref->audio) {
+ av_dlog(ctx, " cl:%"PRId64"d n:%d r:%d p:%d",
+ ref->audio->channel_layout,
+ ref->audio->nb_samples,
+ ref->audio->sample_rate,
+ ref->audio->planar);
+ }
+
+ av_dlog(ctx, "]%s", end ? "\n" : "");
+}
+
+AVFilterBufferRef *ff_null_get_video_buffer(AVFilterLink *link, int perms, int w, int h)
+{
+ return ff_get_video_buffer(link->dst->outputs[0], perms, w, h);
+}
+
+/* TODO: set the buffer's priv member to a context structure for the whole
+ * filter chain. This will allow for a buffer pool instead of the constant
+ * alloc & free cycle currently implemented. */
+AVFilterBufferRef *ff_default_get_video_buffer(AVFilterLink *link, int perms, int w, int h)
+{
+ int linesize[4];
+ uint8_t *data[4];
+ AVFilterBufferRef *picref = NULL;
+
+ // +2 is needed for swscaler, +16 to be SIMD-friendly
+ if (av_image_alloc(data, linesize, w, h, link->format, 16) < 0)
+ return NULL;
+
+ picref = avfilter_get_video_buffer_ref_from_arrays(data, linesize,
+ perms, w, h, link->format);
+ if (!picref) {
+ av_free(data[0]);
+ return NULL;
+ }
+
+ return picref;
+}
+
+AVFilterBufferRef *
+avfilter_get_video_buffer_ref_from_arrays(uint8_t *data[4], int linesize[4], int perms,
+ int w, int h, enum PixelFormat format)
+{
+ AVFilterBuffer *pic = av_mallocz(sizeof(AVFilterBuffer));
+ AVFilterBufferRef *picref = av_mallocz(sizeof(AVFilterBufferRef));
+
+ if (!pic || !picref)
+ goto fail;
+
+ picref->buf = pic;
+ picref->buf->free = ff_avfilter_default_free_buffer;
+ if (!(picref->video = av_mallocz(sizeof(AVFilterBufferRefVideoProps))))
+ goto fail;
+
+ pic->w = picref->video->w = w;
+ pic->h = picref->video->h = h;
+
+ /* make sure the buffer gets read permission or it's useless for output */
+ picref->perms = perms | AV_PERM_READ;
+
+ pic->refcount = 1;
+ picref->type = AVMEDIA_TYPE_VIDEO;
+ pic->format = picref->format = format;
+
+ memcpy(pic->data, data, 4*sizeof(data[0]));
+ memcpy(pic->linesize, linesize, 4*sizeof(linesize[0]));
+ memcpy(picref->data, pic->data, sizeof(picref->data));
+ memcpy(picref->linesize, pic->linesize, sizeof(picref->linesize));
+
+ pic-> extended_data = pic->data;
+ picref->extended_data = picref->data;
+
+ picref->pts = AV_NOPTS_VALUE;
+
+ return picref;
+
+fail:
+ if (picref && picref->video)
+ av_free(picref->video);
+ av_free(picref);
+ av_free(pic);
+ return NULL;
+}
+
+AVFilterBufferRef *ff_get_video_buffer(AVFilterLink *link, int perms, int w, int h)
+{
+ AVFilterBufferRef *ret = NULL;
+
+ av_unused char buf[16];
+ FF_DPRINTF_START(NULL, get_video_buffer); ff_dlog_link(NULL, link, 0);
+ av_dlog(NULL, " perms:%s w:%d h:%d\n", ff_get_ref_perms_string(buf, sizeof(buf), perms), w, h);
+
+ if (link->dstpad->get_video_buffer)
+ ret = link->dstpad->get_video_buffer(link, perms, w, h);
+
+ if (!ret)
+ ret = ff_default_get_video_buffer(link, perms, w, h);
+
+ if (ret)
+ ret->type = AVMEDIA_TYPE_VIDEO;
+
+ FF_DPRINTF_START(NULL, get_video_buffer); ff_dlog_link(NULL, link, 0); av_dlog(NULL, " returning "); ff_dlog_ref(NULL, ret, 1);
+
+ return ret;
+}
+
+void ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
+{
+ ff_start_frame(link->dst->outputs[0], picref);
+}
+
+static void default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
+{
+ AVFilterLink *outlink = NULL;
+
+ if (inlink->dst->nb_outputs)
+ outlink = inlink->dst->outputs[0];
+
+ if (outlink) {
+ outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+ avfilter_copy_buffer_ref_props(outlink->out_buf, picref);
+ ff_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0));
+ }
+}
+
+/* XXX: should we do the duplicating of the picture ref here, instead of
+ * forcing the source filter to do it? */
+void ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
+{
+ void (*start_frame)(AVFilterLink *, AVFilterBufferRef *);
+ AVFilterPad *dst = link->dstpad;
+ int perms = picref->perms;
+
+ FF_DPRINTF_START(NULL, start_frame); ff_dlog_link(NULL, link, 0); av_dlog(NULL, " "); ff_dlog_ref(NULL, picref, 1);
+
+ if (!(start_frame = dst->start_frame))
+ start_frame = default_start_frame;
+
+ if (picref->linesize[0] < 0)
+ perms |= AV_PERM_NEG_LINESIZES;
+ /* prepare to copy the picture if it has insufficient permissions */
+ if ((dst->min_perms & perms) != dst->min_perms || dst->rej_perms & perms) {
+ av_log(link->dst, AV_LOG_DEBUG,
+ "frame copy needed (have perms %x, need %x, reject %x)\n",
+ picref->perms,
+ link->dstpad->min_perms, link->dstpad->rej_perms);
+
+ link->cur_buf = ff_get_video_buffer(link, dst->min_perms, link->w, link->h);
+ link->src_buf = picref;
+ avfilter_copy_buffer_ref_props(link->cur_buf, link->src_buf);
+ }
+ else
+ link->cur_buf = picref;
+
+ start_frame(link, link->cur_buf);
+}
+
+void ff_null_end_frame(AVFilterLink *link)
+{
+ ff_end_frame(link->dst->outputs[0]);
+}
+
+static void default_end_frame(AVFilterLink *inlink)
+{
+ AVFilterLink *outlink = NULL;
+
+ if (inlink->dst->nb_outputs)
+ outlink = inlink->dst->outputs[0];
+
+ avfilter_unref_buffer(inlink->cur_buf);
+ inlink->cur_buf = NULL;
+
+ if (outlink) {
+ if (outlink->out_buf) {
+ avfilter_unref_buffer(outlink->out_buf);
+ outlink->out_buf = NULL;
+ }
+ ff_end_frame(outlink);
+ }
+}
+
+void ff_end_frame(AVFilterLink *link)
+{
+ void (*end_frame)(AVFilterLink *);
+
+ if (!(end_frame = link->dstpad->end_frame))
+ end_frame = default_end_frame;
+
+ end_frame(link);
+
+ /* unreference the source picture if we're feeding the destination filter
+ * a copied version dues to permission issues */
+ if (link->src_buf) {
+ avfilter_unref_buffer(link->src_buf);
+ link->src_buf = NULL;
+ }
+}
+
+void ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
+{
+ ff_draw_slice(link->dst->outputs[0], y, h, slice_dir);
+}
+
+static void default_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
+{
+ AVFilterLink *outlink = NULL;
+
+ if (inlink->dst->nb_outputs)
+ outlink = inlink->dst->outputs[0];
+
+ if (outlink)
+ ff_draw_slice(outlink, y, h, slice_dir);
+}
+
+void ff_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
+{
+ uint8_t *src[4], *dst[4];
+ int i, j, vsub;
+ void (*draw_slice)(AVFilterLink *, int, int, int);
+
+ FF_DPRINTF_START(NULL, draw_slice); ff_dlog_link(NULL, link, 0); av_dlog(NULL, " y:%d h:%d dir:%d\n", y, h, slice_dir);
+
+ /* copy the slice if needed for permission reasons */
+ if (link->src_buf) {
+ vsub = av_pix_fmt_descriptors[link->format].log2_chroma_h;
+
+ for (i = 0; i < 4; i++) {
+ if (link->src_buf->data[i]) {
+ src[i] = link->src_buf-> data[i] +
+ (y >> (i==1 || i==2 ? vsub : 0)) * link->src_buf-> linesize[i];
+ dst[i] = link->cur_buf->data[i] +
+ (y >> (i==1 || i==2 ? vsub : 0)) * link->cur_buf->linesize[i];
+ } else
+ src[i] = dst[i] = NULL;
+ }
+
+ for (i = 0; i < 4; i++) {
+ int planew =
+ av_image_get_linesize(link->format, link->cur_buf->video->w, i);
+
+ if (!src[i]) continue;
+
+ for (j = 0; j < h >> (i==1 || i==2 ? vsub : 0); j++) {
+ memcpy(dst[i], src[i], planew);
+ src[i] += link->src_buf->linesize[i];
+ dst[i] += link->cur_buf->linesize[i];
+ }
+ }
+ }
+
+ if (!(draw_slice = link->dstpad->draw_slice))
+ draw_slice = default_draw_slice;
+ draw_slice(link, y, h, slice_dir);
+}
diff --git a/libavfilter/video.h b/libavfilter/video.h
new file mode 100644
index 0000000..ce4e9c2
--- /dev/null
+++ b/libavfilter/video.h
@@ -0,0 +1,81 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVFILTER_VIDEO_H
+#define AVFILTER_VIDEO_H
+
+#include "avfilter.h"
+
+AVFilterBufferRef *ff_default_get_video_buffer(AVFilterLink *link,
+ int perms, int w, int h);
+AVFilterBufferRef *ff_null_get_video_buffer(AVFilterLink *link, int perms, int w, int h);
+
+/**
+ * Request a picture buffer with a specific set of permissions.
+ *
+ * @param link the output link to the filter from which the buffer will
+ * be requested
+ * @param perms the required access permissions
+ * @param w the minimum width of the buffer to allocate
+ * @param h the minimum height of the buffer to allocate
+ * @return A reference to the buffer. This must be unreferenced with
+ * avfilter_unref_buffer when you are finished with it.
+ */
+AVFilterBufferRef *ff_get_video_buffer(AVFilterLink *link, int perms,
+ int w, int h);
+
+void ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref);
+void ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir);
+void ff_null_end_frame(AVFilterLink *link);
+
+/**
+ * Notify the next filter of the start of a frame.
+ *
+ * @param link the output link the frame will be sent over
+ * @param picref A reference to the frame about to be sent. The data for this
+ * frame need only be valid once draw_slice() is called for that
+ * portion. The receiving filter will free this reference when
+ * it no longer needs it.
+ */
+void ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref);
+
+/**
+ * Notify the next filter that the current frame has finished.
+ *
+ * @param link the output link the frame was sent over
+ */
+void ff_end_frame(AVFilterLink *link);
+
+/**
+ * Send a slice to the next filter.
+ *
+ * Slices have to be provided in sequential order, either in
+ * top-bottom or bottom-top order. If slices are provided in
+ * non-sequential order the behavior of the function is undefined.
+ *
+ * @param link the output link over which the frame is being sent
+ * @param y offset in pixels from the top of the image for this slice
+ * @param h height of this slice in pixels
+ * @param slice_dir the assumed direction for sending slices,
+ * from the top slice to the bottom slice if the value is 1,
+ * from the bottom slice to the top slice if the value is -1,
+ * for other values the behavior of the function is undefined.
+ */
+void ff_draw_slice(AVFilterLink *link, int y, int h, int slice_dir);
+
+#endif /* AVFILTER_VIDEO_H */
diff --git a/libavfilter/vsink_nullsink.c b/libavfilter/vsink_nullsink.c
index bdfcb8a..6f11158 100644
--- a/libavfilter/vsink_nullsink.c
+++ b/libavfilter/vsink_nullsink.c
@@ -17,6 +17,7 @@
*/
#include "avfilter.h"
+#include "internal.h"
static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
{
diff --git a/libavfilter/vsrc_buffer.c b/libavfilter/vsrc_buffer.c
deleted file mode 100644
index 742943a..0000000
--- a/libavfilter/vsrc_buffer.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (c) 2008 Vitor Sessak
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * memory buffer source filter
- */
-
-#include "avfilter.h"
-#include "buffersrc.h"
-#include "vsrc_buffer.h"
-#include "libavutil/fifo.h"
-#include "libavutil/imgutils.h"
-
-typedef struct {
- AVFifoBuffer *fifo;
- int h, w;
- enum PixelFormat pix_fmt;
- AVRational time_base; ///< time_base to set in the output link
- AVRational pixel_aspect;
- int eof;
-} BufferSourceContext;
-
-#define CHECK_PARAM_CHANGE(s, c, width, height, format)\
- if (c->w != width || c->h != height || c->pix_fmt != format) {\
- av_log(s, AV_LOG_ERROR, "Changing frame properties on the fly is not supported.\n");\
- return AVERROR(EINVAL);\
- }
-
-int av_vsrc_buffer_add_frame(AVFilterContext *buffer_filter, AVFrame *frame,
- int64_t pts, AVRational pixel_aspect)
-{
- BufferSourceContext *c = buffer_filter->priv;
- AVFilterBufferRef *buf;
- int ret;
-
- if (!frame) {
- c->eof = 1;
- return 0;
- } else if (c->eof)
- return AVERROR(EINVAL);
-
- if (!av_fifo_space(c->fifo) &&
- (ret = av_fifo_realloc2(c->fifo, av_fifo_size(c->fifo) +
- sizeof(buf))) < 0)
- return ret;
-
- CHECK_PARAM_CHANGE(buffer_filter, c, frame->width, frame->height, frame->format);
-
- buf = avfilter_get_video_buffer(buffer_filter->outputs[0], AV_PERM_WRITE,
- c->w, c->h);
- av_image_copy(buf->data, buf->linesize, frame->data, frame->linesize,
- c->pix_fmt, c->w, c->h);
-
- avfilter_copy_frame_props(buf, frame);
- buf->pts = pts;
- buf->video->pixel_aspect = pixel_aspect;
-
- if ((ret = av_fifo_generic_write(c->fifo, &buf, sizeof(buf), NULL)) < 0) {
- avfilter_unref_buffer(buf);
- return ret;
- }
-
- return 0;
-}
-
-int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf)
-{
- BufferSourceContext *c = s->priv;
- int ret;
-
- if (!buf) {
- c->eof = 1;
- return 0;
- } else if (c->eof)
- return AVERROR(EINVAL);
-
- if (!av_fifo_space(c->fifo) &&
- (ret = av_fifo_realloc2(c->fifo, av_fifo_size(c->fifo) +
- sizeof(buf))) < 0)
- return ret;
-
- CHECK_PARAM_CHANGE(s, c, buf->video->w, buf->video->h, buf->format);
-
- if ((ret = av_fifo_generic_write(c->fifo, &buf, sizeof(buf), NULL)) < 0)
- return ret;
-
- return 0;
-}
-
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
-{
- BufferSourceContext *c = ctx->priv;
- char pix_fmt_str[128];
- int n = 0;
-
- if (!args ||
- (n = sscanf(args, "%d:%d:%127[^:]:%d:%d:%d:%d", &c->w, &c->h, pix_fmt_str,
- &c->time_base.num, &c->time_base.den,
- &c->pixel_aspect.num, &c->pixel_aspect.den)) != 7) {
- av_log(ctx, AV_LOG_ERROR, "Expected 7 arguments, but %d found in '%s'\n", n, args);
- return AVERROR(EINVAL);
- }
- if ((c->pix_fmt = av_get_pix_fmt(pix_fmt_str)) == PIX_FMT_NONE) {
- char *tail;
- c->pix_fmt = strtol(pix_fmt_str, &tail, 10);
- if (*tail || c->pix_fmt < 0 || c->pix_fmt >= PIX_FMT_NB) {
- av_log(ctx, AV_LOG_ERROR, "Invalid pixel format string '%s'\n", pix_fmt_str);
- return AVERROR(EINVAL);
- }
- }
-
- if (!(c->fifo = av_fifo_alloc(sizeof(AVFilterBufferRef*))))
- return AVERROR(ENOMEM);
-
- av_log(ctx, AV_LOG_INFO, "w:%d h:%d pixfmt:%s\n", c->w, c->h, av_pix_fmt_descriptors[c->pix_fmt].name);
- return 0;
-}
-
-static av_cold void uninit(AVFilterContext *ctx)
-{
- BufferSourceContext *s = ctx->priv;
- while (av_fifo_size(s->fifo)) {
- AVFilterBufferRef *buf;
- av_fifo_generic_read(s->fifo, &buf, sizeof(buf), NULL);
- avfilter_unref_buffer(buf);
- }
- av_fifo_free(s->fifo);
- s->fifo = NULL;
-}
-
-static int query_formats(AVFilterContext *ctx)
-{
- BufferSourceContext *c = ctx->priv;
- enum PixelFormat pix_fmts[] = { c->pix_fmt, PIX_FMT_NONE };
-
- avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
- return 0;
-}
-
-static int config_props(AVFilterLink *link)
-{
- BufferSourceContext *c = link->src->priv;
-
- link->w = c->w;
- link->h = c->h;
- link->sample_aspect_ratio = c->pixel_aspect;
- link->time_base = c->time_base;
-
- return 0;
-}
-
-static int request_frame(AVFilterLink *link)
-{
- BufferSourceContext *c = link->src->priv;
- AVFilterBufferRef *buf;
-
- if (!av_fifo_size(c->fifo)) {
- if (c->eof)
- return AVERROR_EOF;
- av_log(link->src, AV_LOG_ERROR,
- "request_frame() called with no available frame!\n");
- return AVERROR(EINVAL);
- }
- av_fifo_generic_read(c->fifo, &buf, sizeof(buf), NULL);
-
- avfilter_start_frame(link, avfilter_ref_buffer(buf, ~0));
- avfilter_draw_slice(link, 0, link->h, 1);
- avfilter_end_frame(link);
- avfilter_unref_buffer(buf);
-
- return 0;
-}
-
-static int poll_frame(AVFilterLink *link)
-{
- BufferSourceContext *c = link->src->priv;
- int size = av_fifo_size(c->fifo);
- if (!size && c->eof)
- return AVERROR_EOF;
- return size/sizeof(AVFilterBufferRef*);
-}
-
-AVFilter avfilter_vsrc_buffer = {
- .name = "buffer",
- .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them accessible to the filterchain."),
- .priv_size = sizeof(BufferSourceContext),
- .query_formats = query_formats,
-
- .init = init,
- .uninit = uninit,
-
- .inputs = (AVFilterPad[]) {{ .name = NULL }},
- .outputs = (AVFilterPad[]) {{ .name = "default",
- .type = AVMEDIA_TYPE_VIDEO,
- .request_frame = request_frame,
- .poll_frame = poll_frame,
- .config_props = config_props, },
- { .name = NULL}},
-};
diff --git a/libavfilter/vsrc_buffer.h b/libavfilter/vsrc_buffer.h
deleted file mode 100644
index 13a209c..0000000
--- a/libavfilter/vsrc_buffer.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2008 Vitor Sessak
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef AVFILTER_VSRC_BUFFER_H
-#define AVFILTER_VSRC_BUFFER_H
-
-/**
- * @file
- * memory buffer source API for video
- */
-
-#include "libavcodec/avcodec.h" /* AVFrame */
-#include "avfilter.h"
-
-int av_vsrc_buffer_add_frame(AVFilterContext *buffer_filter, AVFrame *frame,
- int64_t pts, AVRational pixel_aspect);
-
-#endif /* AVFILTER_VSRC_BUFFER_H */
diff --git a/libavfilter/vsrc_color.c b/libavfilter/vsrc_color.c
index 94b5a29..2d361a1 100644
--- a/libavfilter/vsrc_color.c
+++ b/libavfilter/vsrc_color.c
@@ -24,6 +24,9 @@
*/
#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
#include "libavutil/pixdesc.h"
#include "libavutil/colorspace.h"
#include "libavutil/imgutils.h"
@@ -41,7 +44,7 @@ typedef struct {
uint64_t pts;
} ColorContext;
-static av_cold int color_init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int color_init(AVFilterContext *ctx, const char *args)
{
ColorContext *color = ctx->priv;
char color_string[128] = "black";
@@ -100,7 +103,7 @@ static int query_formats(AVFilterContext *ctx)
PIX_FMT_NONE
};
- avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
return 0;
}
@@ -124,7 +127,7 @@ static int color_config_props(AVFilterLink *inlink)
ff_fill_line_with_color(color->line, color->line_step, color->w, color->color,
inlink->format, rgba_color, &is_packed_rgba, NULL);
- av_log(ctx, AV_LOG_INFO, "w:%d h:%d r:%d/%d color:0x%02x%02x%02x%02x[%s]\n",
+ av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d r:%d/%d color:0x%02x%02x%02x%02x[%s]\n",
color->w, color->h, color->time_base.den, color->time_base.num,
color->color[0], color->color[1], color->color[2], color->color[3],
is_packed_rgba ? "rgba" : "yuva");
@@ -138,17 +141,17 @@ static int color_config_props(AVFilterLink *inlink)
static int color_request_frame(AVFilterLink *link)
{
ColorContext *color = link->src->priv;
- AVFilterBufferRef *picref = avfilter_get_video_buffer(link, AV_PERM_WRITE, color->w, color->h);
+ AVFilterBufferRef *picref = ff_get_video_buffer(link, AV_PERM_WRITE, color->w, color->h);
picref->video->pixel_aspect = (AVRational) {1, 1};
picref->pts = color->pts++;
picref->pos = -1;
- avfilter_start_frame(link, avfilter_ref_buffer(picref, ~0));
+ ff_start_frame(link, avfilter_ref_buffer(picref, ~0));
ff_draw_rectangle(picref->data, picref->linesize,
color->line, color->line_step, color->hsub, color->vsub,
0, 0, color->w, color->h);
- avfilter_draw_slice(link, 0, color->h, 1);
- avfilter_end_frame(link);
+ ff_draw_slice(link, 0, color->h, 1);
+ ff_end_frame(link);
avfilter_unref_buffer(picref);
return 0;
diff --git a/libavfilter/vsrc_movie.c b/libavfilter/vsrc_movie.c
index 4ac079c..512d929 100644
--- a/libavfilter/vsrc_movie.c
+++ b/libavfilter/vsrc_movie.c
@@ -36,6 +36,9 @@
#include "libavutil/imgutils.h"
#include "libavformat/avformat.h"
#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
typedef struct {
const AVClass *class;
@@ -152,14 +155,14 @@ static int movie_init(AVFilterContext *ctx)
movie->w = movie->codec_ctx->width;
movie->h = movie->codec_ctx->height;
- av_log(ctx, AV_LOG_INFO, "seek_point:%"PRIi64" format_name:%s file_name:%s stream_index:%d\n",
+ av_log(ctx, AV_LOG_VERBOSE, "seek_point:%"PRIi64" format_name:%s file_name:%s stream_index:%d\n",
movie->seek_point, movie->format_name, movie->file_name,
movie->stream_index);
return 0;
}
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
{
MovieContext *movie = ctx->priv;
int ret;
@@ -202,7 +205,7 @@ static int query_formats(AVFilterContext *ctx)
MovieContext *movie = ctx->priv;
enum PixelFormat pix_fmts[] = { movie->codec_ctx->pix_fmt, PIX_FMT_NONE };
- avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
return 0;
}
@@ -235,8 +238,8 @@ static int movie_get_frame(AVFilterLink *outlink)
if (frame_decoded) {
/* FIXME: avoid the memcpy */
- movie->picref = avfilter_get_video_buffer(outlink, AV_PERM_WRITE | AV_PERM_PRESERVE |
- AV_PERM_REUSE2, outlink->w, outlink->h);
+ movie->picref = ff_get_video_buffer(outlink, AV_PERM_WRITE | AV_PERM_PRESERVE |
+ AV_PERM_REUSE2, outlink->w, outlink->h);
av_image_copy(movie->picref->data, movie->picref->linesize,
movie->frame->data, movie->frame->linesize,
movie->picref->format, outlink->w, outlink->h);
@@ -286,9 +289,9 @@ static int request_frame(AVFilterLink *outlink)
return ret;
outpicref = avfilter_ref_buffer(movie->picref, ~0);
- avfilter_start_frame(outlink, outpicref);
- avfilter_draw_slice(outlink, 0, outlink->h, 1);
- avfilter_end_frame(outlink);
+ ff_start_frame(outlink, outpicref);
+ ff_draw_slice(outlink, 0, outlink->h, 1);
+ ff_end_frame(outlink);
avfilter_unref_buffer(movie->picref);
movie->picref = NULL;
diff --git a/libavfilter/vsrc_nullsrc.c b/libavfilter/vsrc_nullsrc.c
index 4f9dd79..089188d 100644
--- a/libavfilter/vsrc_nullsrc.c
+++ b/libavfilter/vsrc_nullsrc.c
@@ -26,6 +26,8 @@
#include "libavutil/mathematics.h"
#include "libavutil/parseutils.h"
#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
static const char *const var_names[] = {
"E",
@@ -49,7 +51,7 @@ typedef struct {
double var_values[VAR_VARS_NB];
} NullContext;
-static int init(AVFilterContext *ctx, const char *args, void *opaque)
+static int init(AVFilterContext *ctx, const char *args)
{
NullContext *priv = ctx->priv;
@@ -98,7 +100,7 @@ static int config_props(AVFilterLink *outlink)
outlink->h = priv->h;
outlink->time_base = tb;
- av_log(outlink->src, AV_LOG_INFO, "w:%d h:%d tb:%d/%d\n", priv->w, priv->h,
+ av_log(outlink->src, AV_LOG_VERBOSE, "w:%d h:%d tb:%d/%d\n", priv->w, priv->h,
tb.num, tb.den);
return 0;
diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c
index 0f5596b..c8e1aa6 100644
--- a/libavfilter/vsrc_testsrc.c
+++ b/libavfilter/vsrc_testsrc.c
@@ -37,6 +37,9 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/parseutils.h"
#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
typedef struct {
const AVClass *class;
@@ -67,7 +70,7 @@ static const AVOption testsrc_options[] = {
{ NULL },
};
-static av_cold int init_common(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init_common(AVFilterContext *ctx, const char *args)
{
TestSourceContext *test = ctx->priv;
AVRational frame_rate_q;
@@ -130,8 +133,7 @@ static int request_frame(AVFilterLink *outlink)
if (test->max_pts >= 0 && test->pts > test->max_pts)
return AVERROR_EOF;
- picref = avfilter_get_video_buffer(outlink, AV_PERM_WRITE,
- test->w, test->h);
+ picref = ff_get_video_buffer(outlink, AV_PERM_WRITE, test->w, test->h);
picref->pts = test->pts++;
picref->pos = -1;
picref->video->key_frame = 1;
@@ -141,9 +143,9 @@ static int request_frame(AVFilterLink *outlink)
test->nb_frame++;
test->fill_picture_fn(outlink->src, picref);
- avfilter_start_frame(outlink, avfilter_ref_buffer(picref, ~0));
- avfilter_draw_slice(outlink, 0, picref->video->h, 1);
- avfilter_end_frame(outlink);
+ ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0));
+ ff_draw_slice(outlink, 0, picref->video->h, 1);
+ ff_end_frame(outlink);
avfilter_unref_buffer(picref);
return 0;
@@ -334,13 +336,13 @@ static void test_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
}
}
-static av_cold int test_init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int test_init(AVFilterContext *ctx, const char *args)
{
TestSourceContext *test = ctx->priv;
test->class = &testsrc_class;
test->fill_picture_fn = test_fill_picture;
- return init_common(ctx, args, opaque);
+ return init_common(ctx, args);
}
static int test_query_formats(AVFilterContext *ctx)
@@ -348,7 +350,7 @@ static int test_query_formats(AVFilterContext *ctx)
static const enum PixelFormat pix_fmts[] = {
PIX_FMT_RGB24, PIX_FMT_NONE
};
- avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
return 0;
}
@@ -440,13 +442,13 @@ static void rgbtest_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref
}
}
-static av_cold int rgbtest_init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int rgbtest_init(AVFilterContext *ctx, const char *args)
{
TestSourceContext *test = ctx->priv;
test->class = &rgbtestsrc_class;
test->fill_picture_fn = rgbtest_fill_picture;
- return init_common(ctx, args, opaque);
+ return init_common(ctx, args);
}
static int rgbtest_query_formats(AVFilterContext *ctx)
@@ -459,7 +461,7 @@ static int rgbtest_query_formats(AVFilterContext *ctx)
PIX_FMT_RGB555, PIX_FMT_BGR555,
PIX_FMT_NONE
};
- avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
return 0;
}
diff --git a/libavfilter/x86/gradfun.c b/libavfilter/x86/gradfun.c
index ff3b19d..07569de 100644
--- a/libavfilter/x86/gradfun.c
+++ b/libavfilter/x86/gradfun.c
@@ -18,6 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/attributes.h"
#include "libavutil/cpu.h"
#include "libavutil/x86_cpu.h"
#include "libavfilter/gradfun.h"
@@ -25,9 +26,9 @@
DECLARE_ALIGNED(16, static const uint16_t, pw_7f)[8] = {0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F};
DECLARE_ALIGNED(16, static const uint16_t, pw_ff)[8] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
-void ff_gradfun_filter_line_mmx2(uint8_t *dst, uint8_t *src, uint16_t *dc, int width, int thresh, const uint16_t *dithers)
+#if HAVE_MMX2
+static void gradfun_filter_line_mmx2(uint8_t *dst, uint8_t *src, uint16_t *dc, int width, int thresh, const uint16_t *dithers)
{
-#if HAVE_MMX
intptr_t x;
if (width & 3) {
x = width & ~3;
@@ -70,12 +71,12 @@ void ff_gradfun_filter_line_mmx2(uint8_t *dst, uint8_t *src, uint16_t *dc, int w
"rm"(thresh), "m"(*dithers), "m"(*pw_7f)
:"memory"
);
-#endif
}
+#endif
-void ff_gradfun_filter_line_ssse3(uint8_t *dst, uint8_t *src, uint16_t *dc, int width, int thresh, const uint16_t *dithers)
-{
#if HAVE_SSSE3
+static void gradfun_filter_line_ssse3(uint8_t *dst, uint8_t *src, uint16_t *dc, int width, int thresh, const uint16_t *dithers)
+{
intptr_t x;
if (width & 7) {
// could be 10% faster if I somehow eliminated this
@@ -117,12 +118,12 @@ void ff_gradfun_filter_line_ssse3(uint8_t *dst, uint8_t *src, uint16_t *dc, int
"rm"(thresh), "m"(*dithers), "m"(*pw_7f)
:"memory"
);
-#endif // HAVE_SSSE3
}
+#endif // HAVE_SSSE3
-void ff_gradfun_blur_line_sse2(uint16_t *dc, uint16_t *buf, uint16_t *buf1, uint8_t *src, int src_linesize, int width)
-{
#if HAVE_SSE
+static void gradfun_blur_line_sse2(uint16_t *dc, uint16_t *buf, uint16_t *buf1, uint8_t *src, int src_linesize, int width)
+{
#define BLURV(load)\
intptr_t x = -2*width;\
__asm__ volatile(\
@@ -160,5 +161,23 @@ void ff_gradfun_blur_line_sse2(uint16_t *dc, uint16_t *buf, uint16_t *buf1, uint
} else {
BLURV("movdqa");
}
+}
#endif // HAVE_SSE
+
+av_cold void ff_gradfun_init_x86(GradFunContext *gf)
+{
+ int cpu_flags = av_get_cpu_flags();
+
+#if HAVE_MMX2
+ if (cpu_flags & AV_CPU_FLAG_MMX2)
+ gf->filter_line = gradfun_filter_line_mmx2;
+#endif
+#if HAVE_SSSE3
+ if (cpu_flags & AV_CPU_FLAG_SSSE3)
+ gf->filter_line = gradfun_filter_line_ssse3;
+#endif
+#if HAVE_SSE
+ if (cpu_flags & AV_CPU_FLAG_SSE2)
+ gf->blur_line = gradfun_blur_line_sse2;
+#endif
}
diff --git a/libavfilter/x86/yadif.c b/libavfilter/x86/yadif.c
index 7cd7e19..6d9f9b2 100644
--- a/libavfilter/x86/yadif.c
+++ b/libavfilter/x86/yadif.c
@@ -18,6 +18,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include "libavutil/attributes.h"
#include "libavutil/cpu.h"
#include "libavutil/x86_cpu.h"
#include "libavcodec/x86/dsputil_mmx.h"
@@ -47,3 +48,21 @@ DECLARE_ASM_CONST(16, const xmm_reg, pw_1) = {0x0001000100010001ULL, 0x000100010
#define RENAME(a) a ## _mmx
#include "yadif_template.c"
#endif
+
+av_cold void ff_yadif_init_x86(YADIFContext *yadif)
+{
+ int cpu_flags = av_get_cpu_flags();
+
+#if HAVE_MMX
+ if (cpu_flags & AV_CPU_FLAG_MMX)
+ yadif->filter_line = yadif_filter_line_mmx;
+#endif
+#if HAVE_SSE
+ if (cpu_flags & AV_CPU_FLAG_SSE2)
+ yadif->filter_line = yadif_filter_line_sse2;
+#endif
+#if HAVE_SSSE3
+ if (cpu_flags & AV_CPU_FLAG_SSSE3)
+ yadif->filter_line = yadif_filter_line_ssse3;
+#endif
+}
diff --git a/libavfilter/x86/yadif_template.c b/libavfilter/x86/yadif_template.c
index ffcc39e..1de0a58 100644
--- a/libavfilter/x86/yadif_template.c
+++ b/libavfilter/x86/yadif_template.c
@@ -103,9 +103,9 @@
"por "MM"5, "MM"3 \n\t"\
MOVQ" "MM"3, "MM"1 \n\t"
-void RENAME(ff_yadif_filter_line)(uint8_t *dst,
- uint8_t *prev, uint8_t *cur, uint8_t *next,
- int w, int prefs, int mrefs, int parity, int mode)
+static void RENAME(yadif_filter_line)(uint8_t *dst, uint8_t *prev, uint8_t *cur,
+ uint8_t *next, int w, int prefs,
+ int mrefs, int parity, int mode)
{
DECLARE_ALIGNED(16, uint8_t, tmp0)[16];
DECLARE_ALIGNED(16, uint8_t, tmp1)[16];
diff --git a/libavfilter/yadif.h b/libavfilter/yadif.h
index d658b68..9d23870 100644
--- a/libavfilter/yadif.h
+++ b/libavfilter/yadif.h
@@ -19,18 +19,45 @@
#ifndef AVFILTER_YADIF_H
#define AVFILTER_YADIF_H
+#include "libavutil/pixdesc.h"
#include "avfilter.h"
-void ff_yadif_filter_line_mmx(uint8_t *dst,
- uint8_t *prev, uint8_t *cur, uint8_t *next,
- int w, int prefs, int mrefs, int parity, int mode);
+typedef struct {
+ /**
+ * 0: send 1 frame for each frame
+ * 1: send 1 frame for each field
+ * 2: like 0 but skips spatial interlacing check
+ * 3: like 1 but skips spatial interlacing check
+ */
+ int mode;
-void ff_yadif_filter_line_sse2(uint8_t *dst,
- uint8_t *prev, uint8_t *cur, uint8_t *next,
- int w, int prefs, int mrefs, int parity, int mode);
+ /**
+ * 0: top field first
+ * 1: bottom field first
+ * -1: auto-detection
+ */
+ int parity;
-void ff_yadif_filter_line_ssse3(uint8_t *dst,
- uint8_t *prev, uint8_t *cur, uint8_t *next,
- int w, int prefs, int mrefs, int parity, int mode);
+ int frame_pending;
+
+ /**
+ * 0: deinterlace all frames
+ * 1: only deinterlace frames marked as interlaced
+ */
+ int auto_enable;
+
+ AVFilterBufferRef *cur;
+ AVFilterBufferRef *next;
+ AVFilterBufferRef *prev;
+ AVFilterBufferRef *out;
+ void (*filter_line)(uint8_t *dst,
+ uint8_t *prev, uint8_t *cur, uint8_t *next,
+ int w, int prefs, int mrefs, int parity, int mode);
+
+ const AVPixFmtDescriptor *csp;
+ int eof;
+} YADIFContext;
+
+void ff_yadif_init_x86(YADIFContext *yadif);
#endif /* AVFILTER_YADIF_H */
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 681ea1b..bf219c2 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -1,7 +1,9 @@
NAME = avformat
FFLIBS = avcodec avutil
-HEADERS = avformat.h avio.h version.h
+HEADERS = avformat.h \
+ avio.h \
+ version.h \
OBJS = allformats.o \
avio.o \
@@ -108,6 +110,8 @@ OBJS-$(CONFIG_H264_MUXER) += rawenc.o
OBJS-$(CONFIG_HLS_DEMUXER) += hls.o
OBJS-$(CONFIG_IDCIN_DEMUXER) += idcin.o
OBJS-$(CONFIG_IFF_DEMUXER) += iff.o
+OBJS-$(CONFIG_ILBC_DEMUXER) += ilbc.o
+OBJS-$(CONFIG_ILBC_MUXER) += ilbc.o
OBJS-$(CONFIG_IMAGE2_DEMUXER) += img2dec.o img2.o
OBJS-$(CONFIG_IMAGE2_MUXER) += img2enc.o img2.o
OBJS-$(CONFIG_IMAGE2PIPE_DEMUXER) += img2dec.o img2.o
@@ -146,7 +150,7 @@ OBJS-$(CONFIG_MP2_MUXER) += mp3enc.o rawenc.o
OBJS-$(CONFIG_MP3_DEMUXER) += mp3dec.o
OBJS-$(CONFIG_MP3_MUXER) += mp3enc.o rawenc.o id3v2enc.o
OBJS-$(CONFIG_MPC_DEMUXER) += mpc.o apetag.o
-OBJS-$(CONFIG_MPC8_DEMUXER) += mpc8.o
+OBJS-$(CONFIG_MPC8_DEMUXER) += mpc8.o apetag.o
OBJS-$(CONFIG_MPEG1SYSTEM_MUXER) += mpegenc.o
OBJS-$(CONFIG_MPEG1VCD_MUXER) += mpegenc.o
OBJS-$(CONFIG_MPEG2DVD_MUXER) += mpegenc.o
@@ -156,7 +160,7 @@ OBJS-$(CONFIG_MPEG1VIDEO_MUXER) += rawenc.o
OBJS-$(CONFIG_MPEG2VIDEO_MUXER) += rawenc.o
OBJS-$(CONFIG_MPEGPS_DEMUXER) += mpeg.o
OBJS-$(CONFIG_MPEGTS_DEMUXER) += mpegts.o isom.o
-OBJS-$(CONFIG_MPEGTS_MUXER) += mpegtsenc.o adtsenc.o
+OBJS-$(CONFIG_MPEGTS_MUXER) += mpegtsenc.o
OBJS-$(CONFIG_MPEGVIDEO_DEMUXER) += mpegvideodec.o rawdec.o
OBJS-$(CONFIG_MPJPEG_MUXER) += mpjpeg.o
OBJS-$(CONFIG_MSNWC_TCP_DEMUXER) += msnwc_tcp.o
@@ -260,6 +264,7 @@ OBJS-$(CONFIG_RTPDEC) += rdt.o \
rtpdec_h263.o \
rtpdec_h263_rfc2190.o \
rtpdec_h264.o \
+ rtpdec_ilbc.o \
rtpdec_latm.o \
rtpdec_mpeg4.o \
rtpdec_qcelp.o \
@@ -326,8 +331,6 @@ OBJS-$(CONFIG_YUV4MPEGPIPE_MUXER) += yuv4mpeg.o
OBJS-$(CONFIG_YUV4MPEGPIPE_DEMUXER) += yuv4mpeg.o
# external libraries
-OBJS-$(CONFIG_LIBNUT_DEMUXER) += libnut.o
-OBJS-$(CONFIG_LIBNUT_MUXER) += libnut.o
OBJS-$(CONFIG_LIBRTMP) += librtmp.o
# protocols I/O
@@ -345,15 +348,24 @@ OBJS-$(CONFIG_MMST_PROTOCOL) += mmst.o mms.o asf.o
OBJS-$(CONFIG_MD5_PROTOCOL) += md5proto.o
OBJS-$(CONFIG_PIPE_PROTOCOL) += file.o
OBJS-$(CONFIG_RTMP_PROTOCOL) += rtmpproto.o rtmppkt.o
+OBJS-$(CONFIG_RTMPHTTP_PROTOCOL) += rtmphttp.o
+OBJS-$(CONFIG_RTMPT_PROTOCOL) += rtmpproto.o rtmppkt.o
OBJS-$(CONFIG_RTP_PROTOCOL) += rtpproto.o
+OBJS-$(CONFIG_SCTP_PROTOCOL) += sctp.o
OBJS-$(CONFIG_TCP_PROTOCOL) += tcp.o
OBJS-$(CONFIG_TLS_PROTOCOL) += tls.o
OBJS-$(CONFIG_UDP_PROTOCOL) += udp.o
SKIPHEADERS-$(CONFIG_NETWORK) += network.h rtsp.h
-EXAMPLES = metadata output
+EXAMPLES = metadata \
+ output \
+
TESTPROGS = seek
-TOOLS = aviocat ismindex pktdumper probetest
+
+TOOLS = aviocat \
+ ismindex \
+ pktdumper \
+ probetest \
$(SUBDIR)output-example$(EXESUF): ELIBS = -lswscale
diff --git a/libavformat/ac3dec.c b/libavformat/ac3dec.c
index 60c3cf9..c2e3301 100644
--- a/libavformat/ac3dec.c
+++ b/libavformat/ac3dec.c
@@ -57,11 +57,31 @@ static int ac3_eac3_probe(AVProbeData *p, enum CodecID expected_codec_id)
if(codec_id != expected_codec_id) return 0;
// keep this in sync with mp3 probe, both need to avoid
// issues with MPEG-files!
- if (first_frames>=4) return AVPROBE_SCORE_MAX/2+1;
- else if(max_frames>500)return AVPROBE_SCORE_MAX/2;
- else if(max_frames>=4) return AVPROBE_SCORE_MAX/4;
- else if(max_frames>=1) return 1;
- else return 0;
+ if (first_frames >= 4) return AVPROBE_SCORE_MAX / 2 + 1;
+
+ if (max_frames) {
+ int pes = 0, i;
+ unsigned int code = -1;
+
+#define VIDEO_ID 0x000001e0
+#define AUDIO_ID 0x000001c0
+ /* do a search for mpegps headers to be able to properly bias
+ * towards mpegps if we detect this stream as both. */
+ for (i = 0; i<p->buf_size; i++) {
+ code = (code << 8) + p->buf[i];
+ if ((code & 0xffffff00) == 0x100) {
+ if ((code & 0x1f0) == VIDEO_ID) pes++;
+ else if((code & 0x1e0) == AUDIO_ID) pes++;
+ }
+ }
+
+ if (pes)
+ max_frames = (max_frames + pes - 1) / pes;
+ }
+ if (max_frames > 500) return AVPROBE_SCORE_MAX / 2;
+ else if (max_frames >= 4) return AVPROBE_SCORE_MAX / 4;
+ else if (max_frames >= 1) return 1;
+ else return 0;
}
#if CONFIG_AC3_DEMUXER
diff --git a/libavformat/adts.h b/libavformat/adts.h
deleted file mode 100644
index 78b42c7..0000000
--- a/libavformat/adts.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * ADTS muxer.
- * Copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier at smartjog.com>
- * Mans Rullgard <mans at mansr.com>
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef AVFORMAT_ADTS_H
-#define AVFORMAT_ADTS_H
-
-#include "avformat.h"
-#include "libavcodec/mpeg4audio.h"
-
-#define ADTS_HEADER_SIZE 7
-
-typedef struct {
- int write_adts;
- int objecttype;
- int sample_rate_index;
- int channel_conf;
- int pce_size;
- uint8_t pce_data[MAX_PCE_SIZE];
-} ADTSContext;
-
-int ff_adts_write_frame_header(ADTSContext *ctx, uint8_t *buf,
- int size, int pce_size);
-int ff_adts_decode_extradata(AVFormatContext *s, ADTSContext *adts,
- uint8_t *buf, int size);
-
-#endif /* AVFORMAT_ADTS_H */
diff --git a/libavformat/adtsenc.c b/libavformat/adtsenc.c
index ef3d8e2..1a9f879 100644
--- a/libavformat/adtsenc.c
+++ b/libavformat/adtsenc.c
@@ -25,11 +25,21 @@
#include "libavcodec/avcodec.h"
#include "libavcodec/mpeg4audio.h"
#include "avformat.h"
-#include "adts.h"
+
+#define ADTS_HEADER_SIZE 7
+
+typedef struct {
+ int write_adts;
+ int objecttype;
+ int sample_rate_index;
+ int channel_conf;
+ int pce_size;
+ uint8_t pce_data[MAX_PCE_SIZE];
+} ADTSContext;
#define ADTS_MAX_FRAME_BYTES ((1 << 13) - 1)
-int ff_adts_decode_extradata(AVFormatContext *s, ADTSContext *adts, uint8_t *buf, int size)
+static int adts_decode_extradata(AVFormatContext *s, ADTSContext *adts, uint8_t *buf, int size)
{
GetBitContext gb;
PutBitContext pb;
@@ -84,14 +94,14 @@ static int adts_write_header(AVFormatContext *s)
AVCodecContext *avc = s->streams[0]->codec;
if (avc->extradata_size > 0 &&
- ff_adts_decode_extradata(s, adts, avc->extradata, avc->extradata_size) < 0)
+ adts_decode_extradata(s, adts, avc->extradata, avc->extradata_size) < 0)
return -1;
return 0;
}
-int ff_adts_write_frame_header(ADTSContext *ctx,
- uint8_t *buf, int size, int pce_size)
+static int adts_write_frame_header(ADTSContext *ctx,
+ uint8_t *buf, int size, int pce_size)
{
PutBitContext pb;
@@ -137,7 +147,7 @@ static int adts_write_packet(AVFormatContext *s, AVPacket *pkt)
if (!pkt->size)
return 0;
if (adts->write_adts) {
- int err = ff_adts_write_frame_header(adts, buf, pkt->size,
+ int err = adts_write_frame_header(adts, buf, pkt->size,
adts->pce_size);
if (err < 0)
return err;
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index f5be7aa..8456398 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -108,6 +108,7 @@ void av_register_all(void)
REGISTER_DEMUXER (HLS, hls);
REGISTER_DEMUXER (IDCIN, idcin);
REGISTER_DEMUXER (IFF, iff);
+ REGISTER_MUXDEMUX (ILBC, ilbc);
REGISTER_MUXDEMUX (IMAGE2, image2);
REGISTER_MUXDEMUX (IMAGE2PIPE, image2pipe);
REGISTER_DEMUXER (INGENIENT, ingenient);
@@ -256,13 +257,15 @@ void av_register_all(void)
REGISTER_PROTOCOL (MD5, md5);
REGISTER_PROTOCOL (PIPE, pipe);
REGISTER_PROTOCOL (RTMP, rtmp);
+ REGISTER_PROTOCOL (RTMPHTTP, rtmphttp);
+ REGISTER_PROTOCOL (RTMPT, rtmpt);
REGISTER_PROTOCOL (RTP, rtp);
+ REGISTER_PROTOCOL (SCTP, sctp);
REGISTER_PROTOCOL (TCP, tcp);
REGISTER_PROTOCOL (TLS, tls);
REGISTER_PROTOCOL (UDP, udp);
/* external libraries */
- REGISTER_MUXDEMUX (LIBNUT, libnut);
REGISTER_PROTOCOL (LIBRTMP, librtmp);
REGISTER_PROTOCOL (LIBRTMPE, librtmpe);
REGISTER_PROTOCOL (LIBRTMPS, librtmps);
diff --git a/libavformat/amr.c b/libavformat/amr.c
index 96f559b..f20bc0a 100644
--- a/libavformat/amr.c
+++ b/libavformat/amr.c
@@ -28,27 +28,22 @@ Only mono files are supported.
#include "avformat.h"
#include "internal.h"
-static const char AMR_header [] = "#!AMR\n";
-static const char AMRWB_header [] = "#!AMR-WB\n";
+static const char AMR_header[] = "#!AMR\n";
+static const char AMRWB_header[] = "#!AMR-WB\n";
#if CONFIG_AMR_MUXER
static int amr_write_header(AVFormatContext *s)
{
- AVIOContext *pb = s->pb;
+ AVIOContext *pb = s->pb;
AVCodecContext *enc = s->streams[0]->codec;
s->priv_data = NULL;
- if (enc->codec_id == CODEC_ID_AMR_NB)
- {
+ if (enc->codec_id == CODEC_ID_AMR_NB) {
avio_write(pb, AMR_header, sizeof(AMR_header) - 1); /* magic number */
- }
- else if(enc->codec_id == CODEC_ID_AMR_WB)
- {
+ } else if (enc->codec_id == CODEC_ID_AMR_WB) {
avio_write(pb, AMRWB_header, sizeof(AMRWB_header) - 1); /* magic number */
- }
- else
- {
+ } else {
return -1;
}
avio_flush(pb);
@@ -65,11 +60,11 @@ static int amr_write_packet(AVFormatContext *s, AVPacket *pkt)
static int amr_probe(AVProbeData *p)
{
- //Only check for "#!AMR" which could be amr-wb, amr-nb.
- //This will also trigger multichannel files: "#!AMR_MC1.0\n" and
- //"#!AMR-WB_MC1.0\n" (not supported)
+ // Only check for "#!AMR" which could be amr-wb, amr-nb.
+ // This will also trigger multichannel files: "#!AMR_MC1.0\n" and
+ // "#!AMR-WB_MC1.0\n" (not supported)
- if(memcmp(p->buf,AMR_header,5)==0)
+ if (!memcmp(p->buf, AMR_header, 5))
return AVPROBE_SCORE_MAX;
else
return 0;
@@ -86,83 +81,71 @@ static int amr_read_header(AVFormatContext *s)
st = avformat_new_stream(s, NULL);
if (!st)
- {
return AVERROR(ENOMEM);
- }
- if(memcmp(header,AMR_header,6)!=0)
- {
- avio_read(pb, header+6, 3);
- if(memcmp(header,AMRWB_header,9)!=0)
- {
+ if (memcmp(header, AMR_header, 6)) {
+ avio_read(pb, header + 6, 3);
+ if (memcmp(header, AMRWB_header, 9)) {
return -1;
}
- st->codec->codec_tag = MKTAG('s', 'a', 'w', 'b');
- st->codec->codec_id = CODEC_ID_AMR_WB;
+ st->codec->codec_tag = MKTAG('s', 'a', 'w', 'b');
+ st->codec->codec_id = CODEC_ID_AMR_WB;
st->codec->sample_rate = 16000;
- }
- else
- {
- st->codec->codec_tag = MKTAG('s', 'a', 'm', 'r');
- st->codec->codec_id = CODEC_ID_AMR_NB;
+ } else {
+ st->codec->codec_tag = MKTAG('s', 'a', 'm', 'r');
+ st->codec->codec_id = CODEC_ID_AMR_NB;
st->codec->sample_rate = 8000;
}
- st->codec->channels = 1;
+ st->codec->channels = 1;
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
return 0;
}
-static int amr_read_packet(AVFormatContext *s,
- AVPacket *pkt)
+static int amr_read_packet(AVFormatContext *s, AVPacket *pkt)
{
AVCodecContext *enc = s->streams[0]->codec;
int read, size = 0, toc, mode;
int64_t pos = avio_tell(s->pb);
- if (s->pb->eof_reached)
- {
+ if (s->pb->eof_reached) {
return AVERROR(EIO);
}
-//FIXME this is wrong, this should rather be in a AVParset
- toc=avio_r8(s->pb);
+ // FIXME this is wrong, this should rather be in a AVParset
+ toc = avio_r8(s->pb);
mode = (toc >> 3) & 0x0F;
- if (enc->codec_id == CODEC_ID_AMR_NB)
- {
- static const uint8_t packed_size[16] = {12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0};
+ if (enc->codec_id == CODEC_ID_AMR_NB) {
+ static const uint8_t packed_size[16] = {
+ 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0
+ };
- size=packed_size[mode]+1;
- }
- else if(enc->codec_id == CODEC_ID_AMR_WB)
- {
- static uint8_t packed_size[16] = {18, 24, 33, 37, 41, 47, 51, 59, 61, 6, 6, 0, 0, 0, 1, 1};
+ size = packed_size[mode] + 1;
+ } else if (enc->codec_id == CODEC_ID_AMR_WB) {
+ static const uint8_t packed_size[16] = {
+ 18, 24, 33, 37, 41, 47, 51, 59, 61, 6, 6, 0, 0, 0, 1, 1
+ };
- size=packed_size[mode];
- }
- else
- {
+ size = packed_size[mode];
+ } else {
assert(0);
}
- if ( (size==0) || av_new_packet(pkt, size))
- {
+ if (!size || av_new_packet(pkt, size))
return AVERROR(EIO);
- }
/* Both AMR formats have 50 frames per second */
s->streams[0]->codec->bit_rate = size*8*50;
pkt->stream_index = 0;
- pkt->pos = pos;
- pkt->data[0]=toc;
- pkt->duration= enc->codec_id == CODEC_ID_AMR_NB ? 160 : 320;
- read = avio_read(s->pb, pkt->data+1, size-1);
+ pkt->pos = pos;
+ pkt->data[0] = toc;
+ pkt->duration = enc->codec_id == CODEC_ID_AMR_NB ? 160 : 320;
+ read = avio_read(s->pb, pkt->data + 1, size - 1);
- if (read != size-1)
- {
+ if (read != size - 1) {
av_free_packet(pkt);
return AVERROR(EIO);
}
diff --git a/libavformat/ape.c b/libavformat/ape.c
index b3fca23..76ad549 100644
--- a/libavformat/ape.c
+++ b/libavformat/ape.c
@@ -312,12 +312,6 @@ static int ape_read_header(AVFormatContext * s)
ape_dumpinfo(s, ape);
- /* try to read APE tags */
- if (pb->seekable) {
- ff_ape_parse_tag(s);
- avio_seek(pb, 0, SEEK_SET);
- }
-
av_log(s, AV_LOG_DEBUG, "Decoding file - v%d.%02d, compression level %"PRIu16"\n",
ape->fileversion / 1000, (ape->fileversion % 1000) / 10,
ape->compressiontype);
@@ -354,6 +348,12 @@ static int ape_read_header(AVFormatContext * s)
pts += ape->blocksperframe / MAC_SUBFRAME_SIZE;
}
+ /* try to read APE tags */
+ if (pb->seekable) {
+ ff_ape_parse_tag(s);
+ avio_seek(pb, 0, SEEK_SET);
+ }
+
return 0;
}
diff --git a/libavformat/apetag.c b/libavformat/apetag.c
index 68c987e..062f746 100644
--- a/libavformat/apetag.c
+++ b/libavformat/apetag.c
@@ -24,6 +24,7 @@
#include "libavutil/dict.h"
#include "avformat.h"
#include "apetag.h"
+#include "internal.h"
#define APE_TAG_VERSION 2000
#define APE_TAG_FOOTER_BYTES 32
@@ -56,20 +57,47 @@ static int ape_tag_read_field(AVFormatContext *s)
return -1;
if (flags & APE_TAG_FLAG_IS_BINARY) {
uint8_t filename[1024];
+ enum CodecID id;
AVStream *st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
- avio_get_str(pb, INT_MAX, filename, sizeof(filename));
- st->codec->extradata = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
- if (!st->codec->extradata)
- return AVERROR(ENOMEM);
- if (avio_read(pb, st->codec->extradata, size) != size) {
- av_freep(&st->codec->extradata);
- return AVERROR(EIO);
+
+ size -= avio_get_str(pb, size, filename, sizeof(filename));
+ if (size <= 0) {
+ av_log(s, AV_LOG_WARNING, "Skipping binary tag '%s'.\n", key);
+ return 0;
}
- st->codec->extradata_size = size;
+
av_dict_set(&st->metadata, key, filename, 0);
- st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT;
+
+ if ((id = ff_guess_image2_codec(filename)) != CODEC_ID_NONE) {
+ AVPacket pkt;
+ int ret;
+
+ ret = av_get_packet(s->pb, &pkt, size);
+ if (ret < 0) {
+ av_log(s, AV_LOG_ERROR, "Error reading cover art.\n");
+ return ret;
+ }
+
+ st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
+ st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ st->codec->codec_id = id;
+
+ st->attached_pic = pkt;
+ st->attached_pic.stream_index = st->index;
+ st->attached_pic.flags |= AV_PKT_FLAG_KEY;
+ } else {
+ st->codec->extradata = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!st->codec->extradata)
+ return AVERROR(ENOMEM);
+ if (avio_read(pb, st->codec->extradata, size) != size) {
+ av_freep(&st->codec->extradata);
+ return AVERROR(EIO);
+ }
+ st->codec->extradata_size = size;
+ st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT;
+ }
} else {
value = av_malloc(size+1);
if (!value)
diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c
index b39d2f2..91b0992 100644
--- a/libavformat/asfdec.c
+++ b/libavformat/asfdec.c
@@ -30,6 +30,7 @@
#include "avformat.h"
#include "internal.h"
#include "avio_internal.h"
+#include "id3v2.h"
#include "riff.h"
#include "asf.h"
#include "asfcrypt.h"
@@ -173,6 +174,101 @@ static int get_value(AVIOContext *pb, int type){
}
}
+/* MSDN claims that this should be "compatible with the ID3 frame, APIC",
+ * but in reality this is only loosely similar */
+static int asf_read_picture(AVFormatContext *s, int len)
+{
+ AVPacket pkt = { 0 };
+ const CodecMime *mime = ff_id3v2_mime_tags;
+ enum CodecID id = CODEC_ID_NONE;
+ char mimetype[64];
+ uint8_t *desc = NULL;
+ ASFStream *ast = NULL;
+ AVStream *st = NULL;
+ int ret, type, picsize, desc_len;
+
+ /* type + picsize + mime + desc */
+ if (len < 1 + 4 + 2 + 2) {
+ av_log(s, AV_LOG_ERROR, "Invalid attached picture size: %d.\n", len);
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* picture type */
+ type = avio_r8(s->pb);
+ len--;
+ if (type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types) || type < 0) {
+ av_log(s, AV_LOG_WARNING, "Unknown attached picture type: %d.\n", type);
+ type = 0;
+ }
+
+ /* picture data size */
+ picsize = avio_rl32(s->pb);
+ len -= 4;
+
+ /* picture MIME type */
+ len -= avio_get_str16le(s->pb, len, mimetype, sizeof(mimetype));
+ while (mime->id != CODEC_ID_NONE) {
+ if (!strncmp(mime->str, mimetype, sizeof(mimetype))) {
+ id = mime->id;
+ break;
+ }
+ mime++;
+ }
+ if (id == CODEC_ID_NONE) {
+ av_log(s, AV_LOG_ERROR, "Unknown attached picture mimetype: %s.\n",
+ mimetype);
+ return 0;
+ }
+
+ if (picsize >= len) {
+ av_log(s, AV_LOG_ERROR, "Invalid attached picture data size: %d >= %d.\n",
+ picsize, len);
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* picture description */
+ desc_len = (len - picsize) * 2 + 1;
+ desc = av_malloc(desc_len);
+ if (!desc)
+ return AVERROR(ENOMEM);
+ len -= avio_get_str16le(s->pb, len - picsize, desc, desc_len);
+
+ ret = av_get_packet(s->pb, &pkt, picsize);
+ if (ret < 0)
+ goto fail;
+
+ st = avformat_new_stream(s, NULL);
+ ast = av_mallocz(sizeof(*ast));
+ if (!st || !ast) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ st->priv_data = ast;
+
+ st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
+ st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ st->codec->codec_id = id;
+
+ st->attached_pic = pkt;
+ st->attached_pic.stream_index = st->index;
+ st->attached_pic.flags |= AV_PKT_FLAG_KEY;
+
+ if (*desc)
+ av_dict_set(&st->metadata, "title", desc, AV_DICT_DONT_STRDUP_VAL);
+ else
+ av_freep(&desc);
+
+ av_dict_set(&st->metadata, "comment", ff_id3v2_picture_types[type], 0);
+
+ return 0;
+
+fail:
+ av_freep(&ast);
+ av_freep(&desc);
+ av_free_packet(&pkt);
+ return ret;
+}
+
static void get_tag(AVFormatContext *s, const char *key, int type, int len)
{
char *value;
@@ -190,6 +286,9 @@ static void get_tag(AVFormatContext *s, const char *key, int type, int len)
} else if (type > 1 && type <= 5) { // boolean or DWORD or QWORD or WORD
uint64_t num = get_value(s->pb, type);
snprintf(value, len, "%"PRIu64, num);
+ } else if (type == 1 && !strcmp(key, "WM/Picture")) { // handle cover art
+ asf_read_picture(s, len);
+ goto finish;
} else {
av_log(s, AV_LOG_DEBUG, "Unsupported value type %d in tag %s.\n", type, key);
goto finish;
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 087b0b4..e292206 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -201,6 +201,10 @@
#include "avio.h"
#include "libavformat/version.h"
+#if FF_API_AV_GETTIME
+#include "libavutil/time.h"
+#endif
+
struct AVFormatContext;
@@ -351,6 +355,9 @@ typedef struct AVProbeData {
#define AVFMT_NOGENSEARCH 0x4000 /**< Format does not allow to fallback to generic search */
#define AVFMT_NO_BYTE_SEEK 0x8000 /**< Format does not allow seeking by bytes */
#define AVFMT_ALLOW_FLUSH 0x10000 /**< Format allows flushing. If not set, the muxer will not receive a NULL packet in the write_packet function. */
+#define AVFMT_TS_NONSTRICT 0x20000 /**< Format does not require strictly
+ increasing timestamps, but they must
+ still be monotonic */
/**
* @addtogroup lavf_encoding
@@ -373,7 +380,8 @@ typedef struct AVOutputFormat {
/**
* can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_RAWPICTURE,
* AVFMT_GLOBALHEADER, AVFMT_NOTIMESTAMPS, AVFMT_VARIABLE_FPS,
- * AVFMT_NODIMENSIONS, AVFMT_NOSTREAMS, AVFMT_ALLOW_FLUSH
+ * AVFMT_NODIMENSIONS, AVFMT_NOSTREAMS, AVFMT_ALLOW_FLUSH,
+ * AVFMT_TS_NONSTRICT
*/
int flags;
@@ -817,7 +825,7 @@ typedef struct AVFormatContext {
*/
void *priv_data;
- /*
+ /**
* I/O context.
*
* decoding: either set by the user before avformat_open_input() (then
@@ -1632,11 +1640,6 @@ void av_dump_format(AVFormatContext *ic,
int is_output);
/**
- * Get the current time in microseconds.
- */
-int64_t av_gettime(void);
-
-/**
* Return in 'buf' the path with '%d' replaced by a number.
*
* Also handles the '%0nd' format where 'n' is the total number
diff --git a/libavformat/avidec.c b/libavformat/avidec.c
index abfea2c..38f84f9 100644
--- a/libavformat/avidec.c
+++ b/libavformat/avidec.c
@@ -39,8 +39,8 @@ typedef struct AVIStream {
int remaining;
int packet_size;
- int scale;
- int rate;
+ uint32_t scale;
+ uint32_t rate;
int sample_size; /* size of one sample (or packet) (in the rate/scale sense) in bytes */
int64_t cum_len; /* temporary storage (used during seek) */
diff --git a/libavformat/avio.c b/libavformat/avio.c
index ba25abe..5acaf30 100644
--- a/libavformat/avio.c
+++ b/libavformat/avio.c
@@ -19,11 +19,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <unistd.h>
-
#include "libavutil/avstring.h"
#include "libavutil/dict.h"
#include "libavutil/opt.h"
+#include "libavutil/time.h"
#include "os_support.h"
#include "avformat.h"
#if CONFIG_NETWORK
@@ -237,7 +236,7 @@ static inline int retry_transfer_wrapper(URLContext *h, unsigned char *buf, int
if (fast_retries)
fast_retries--;
else
- usleep(1000);
+ av_usleep(1000);
} else if (ret < 1)
return ret < 0 ? ret : len;
if (ret)
@@ -345,6 +344,13 @@ int ffurl_get_file_handle(URLContext *h)
return h->prot->url_get_file_handle(h);
}
+int ffurl_shutdown(URLContext *h, int flags)
+{
+ if (!h->prot->url_shutdown)
+ return AVERROR(EINVAL);
+ return h->prot->url_shutdown(h, flags);
+}
+
int ff_check_interrupt(AVIOInterruptCB *cb)
{
int ret;
diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c
index 3b695a9..c4c523d 100644
--- a/libavformat/avisynth.c
+++ b/libavformat/avisynth.c
@@ -49,10 +49,15 @@ static int avisynth_read_header(AVFormatContext *s)
DWORD id;
AVStream *st;
AVISynthStream *stream;
+ wchar_t filename_wchar[1024] = { 0 };
+ char filename_char[1024] = { 0 };
AVIFileInit();
- res = AVIFileOpen(&avs->file, s->filename, OF_READ|OF_SHARE_DENY_WRITE, NULL);
+ /* avisynth can't accept UTF-8 filename */
+ MultiByteToWideChar(CP_UTF8, 0, s->filename, -1, filename_wchar, 1024);
+ WideCharToMultiByte(CP_THREAD_ACP, 0, filename_wchar, -1, filename_char, 1024, NULL, NULL);
+ res = AVIFileOpen(&avs->file, filename_char, OF_READ|OF_SHARE_DENY_WRITE, NULL);
if (res != S_OK)
{
av_log(s, AV_LOG_ERROR, "AVIFileOpen failed with error %ld", res);
diff --git a/libavformat/cafdec.c b/libavformat/cafdec.c
index e35026f..d5ee9be 100644
--- a/libavformat/cafdec.c
+++ b/libavformat/cafdec.c
@@ -394,5 +394,5 @@ AVInputFormat ff_caf_demuxer = {
.read_header = read_header,
.read_packet = read_packet,
.read_seek = read_seek,
- .codec_tag = (const AVCodecTag*[]){ ff_codec_caf_tags, 0 },
+ .codec_tag = (const AVCodecTag* const []){ ff_codec_caf_tags, 0 },
};
diff --git a/libavformat/dv.c b/libavformat/dv.c
index b96b3ba..e02fb53 100644
--- a/libavformat/dv.c
+++ b/libavformat/dv.c
@@ -31,6 +31,7 @@
#include <time.h>
#include "avformat.h"
#include "internal.h"
+#include "libavcodec/dv_profile.h"
#include "libavcodec/dvdata.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
diff --git a/libavformat/dvenc.c b/libavformat/dvenc.c
index 8ebdd7f..51eb16e 100644
--- a/libavformat/dvenc.c
+++ b/libavformat/dvenc.c
@@ -32,6 +32,7 @@
#include "avformat.h"
#include "internal.h"
+#include "libavcodec/dv_profile.h"
#include "libavcodec/dvdata.h"
#include "dv.h"
#include "libavutil/fifo.h"
diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c
index 47ef40f..b215547 100644
--- a/libavformat/electronicarts.c
+++ b/libavformat/electronicarts.c
@@ -487,12 +487,17 @@ static int ea_read_packet(AVFormatContext *s,
while (!packet_read) {
chunk_type = avio_rl32(pb);
- chunk_size = (ea->big_endian ? avio_rb32(pb) : avio_rl32(pb)) - 8;
+ chunk_size = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb);
+ if (chunk_size <= 8)
+ return AVERROR_INVALIDDATA;
+ chunk_size -= 8;
switch (chunk_type) {
/* audio data */
case ISNh_TAG:
/* header chunk also contains data; skip over the header portion*/
+ if (chunk_size < 32)
+ return AVERROR_INVALIDDATA;
avio_skip(pb, 32);
chunk_size -= 32;
case ISNd_TAG:
diff --git a/libavformat/file.c b/libavformat/file.c
index cca9ec1..0e3577d 100644
--- a/libavformat/file.c
+++ b/libavformat/file.c
@@ -22,10 +22,12 @@
#include "libavutil/avstring.h"
#include "avformat.h"
#include <fcntl.h>
-#if HAVE_SETMODE
+#if HAVE_IO_H
#include <io.h>
#endif
+#if HAVE_UNISTD_H
#include <unistd.h>
+#endif
#include <sys/stat.h>
#include <stdlib.h>
#include "os_support.h"
diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c
index 8981a56..f481c10 100644
--- a/libavformat/flacdec.c
+++ b/libavformat/flacdec.c
@@ -21,12 +21,127 @@
#include "libavcodec/flac.h"
#include "avformat.h"
+#include "id3v2.h"
#include "internal.h"
#include "rawdec.h"
#include "oggdec.h"
#include "vorbiscomment.h"
#include "libavcodec/bytestream.h"
+static int parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size)
+{
+ const CodecMime *mime = ff_id3v2_mime_tags;
+ enum CodecID id = CODEC_ID_NONE;
+ uint8_t mimetype[64], *desc = NULL, *data = NULL;
+ AVIOContext *pb = NULL;
+ AVStream *st;
+ int type, width, height;
+ int len, ret = 0;
+
+ st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+
+ pb = avio_alloc_context(buf, buf_size, 0, NULL, NULL, NULL, NULL);
+ if (!pb)
+ return AVERROR(ENOMEM);
+
+ /* read the picture type */
+ type = avio_rb32(pb);
+ if (type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types) || type < 0) {
+ av_log(s, AV_LOG_ERROR, "Invalid picture type: %d.\n", type);
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+
+ /* picture mimetype */
+ len = avio_rb32(pb);
+ if (len <= 0 ||
+ avio_read(pb, mimetype, FFMIN(len, sizeof(mimetype) - 1)) != len) {
+ av_log(s, AV_LOG_ERROR, "Could not read mimetype from an attached "
+ "picture.\n");
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+ mimetype[len] = 0;
+
+ while (mime->id != CODEC_ID_NONE) {
+ if (!strncmp(mime->str, mimetype, sizeof(mimetype))) {
+ id = mime->id;
+ break;
+ }
+ mime++;
+ }
+ if (id == CODEC_ID_NONE) {
+ av_log(s, AV_LOG_ERROR, "Unknown attached picture mimetype: %s.\n",
+ mimetype);
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+
+ /* picture description */
+ len = avio_rb32(pb);
+ if (len > 0) {
+ if (!(desc = av_malloc(len + 1))) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ if (avio_read(pb, desc, len) != len) {
+ ret = AVERROR(EIO);
+ goto fail;
+ }
+ desc[len] = 0;
+ }
+
+ /* picture metadata */
+ width = avio_rb32(pb);
+ height = avio_rb32(pb);
+ avio_skip(pb, 8);
+
+ /* picture data */
+ len = avio_rb32(pb);
+ if (len <= 0) {
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+ if (!(data = av_malloc(len))) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ if (avio_read(pb, data, len) != len) {
+ ret = AVERROR(EIO);
+ goto fail;
+ }
+
+ av_init_packet(&st->attached_pic);
+ st->attached_pic.data = data;
+ st->attached_pic.size = len;
+ st->attached_pic.destruct = av_destruct_packet;
+ st->attached_pic.stream_index = st->index;
+ st->attached_pic.flags |= AV_PKT_FLAG_KEY;
+
+ st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
+ st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ st->codec->codec_id = id;
+ st->codec->width = width;
+ st->codec->height = height;
+ av_dict_set(&st->metadata, "comment", ff_id3v2_picture_types[type], 0);
+ if (desc)
+ av_dict_set(&st->metadata, "title", desc, AV_DICT_DONT_STRDUP_VAL);
+
+ av_freep(&pb);
+
+ return 0;
+
+fail:
+ av_freep(&desc);
+ av_freep(&data);
+ av_freep(&pb);
+ return ret;
+
+}
+
static int flac_read_header(AVFormatContext *s)
{
int ret, metadata_last=0, metadata_type, metadata_size, found_streaminfo=0;
@@ -55,6 +170,7 @@ static int flac_read_header(AVFormatContext *s)
/* allocate and read metadata block for supported types */
case FLAC_METADATA_TYPE_STREAMINFO:
case FLAC_METADATA_TYPE_CUESHEET:
+ case FLAC_METADATA_TYPE_PICTURE:
case FLAC_METADATA_TYPE_VORBIS_COMMENT:
buffer = av_mallocz(metadata_size + FF_INPUT_BUFFER_PADDING_SIZE);
if (!buffer) {
@@ -121,6 +237,13 @@ static int flac_read_header(AVFormatContext *s)
offset += ti * 12;
avpriv_new_chapter(s, track, st->time_base, start, AV_NOPTS_VALUE, isrc);
}
+ } else if (metadata_type == FLAC_METADATA_TYPE_PICTURE) {
+ ret = parse_picture(s, buffer, metadata_size);
+ av_freep(&buffer);
+ if (ret < 0) {
+ av_log(s, AV_LOG_ERROR, "Error parsing attached picture.\n");
+ return ret;
+ }
} else {
/* STREAMINFO must be the first block */
if (!found_streaminfo) {
diff --git a/libavformat/flv.h b/libavformat/flv.h
index 6418b27..fe0fc90 100644
--- a/libavformat/flv.h
+++ b/libavformat/flv.h
@@ -82,6 +82,8 @@ enum {
FLV_CODECID_NELLYMOSER_16KHZ_MONO = 4 << FLV_AUDIO_CODECID_OFFSET,
FLV_CODECID_NELLYMOSER_8KHZ_MONO = 5 << FLV_AUDIO_CODECID_OFFSET,
FLV_CODECID_NELLYMOSER = 6 << FLV_AUDIO_CODECID_OFFSET,
+ FLV_CODECID_PCM_ALAW = 7 << FLV_AUDIO_CODECID_OFFSET,
+ FLV_CODECID_PCM_MULAW = 8 << FLV_AUDIO_CODECID_OFFSET,
FLV_CODECID_AAC = 10<< FLV_AUDIO_CODECID_OFFSET,
FLV_CODECID_SPEEX = 11<< FLV_AUDIO_CODECID_OFFSET,
};
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index 7c4b792..12c2504 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -26,6 +26,7 @@
#include "libavutil/avstring.h"
#include "libavutil/dict.h"
+#include "libavutil/opt.h"
#include "libavutil/intfloat.h"
#include "libavutil/mathematics.h"
#include "libavcodec/bytestream.h"
@@ -42,6 +43,8 @@
#define VALIDATE_INDEX_TS_THRESH 2500
typedef struct {
+ const AVClass *class; ///< Class for private options.
+ int trust_metadata; ///< configure streams according onMetaData
int wrong_dts; ///< wrong dts due to negative cts
uint8_t *new_extradata[2];
int new_extradata_size[2];
@@ -66,6 +69,66 @@ static int flv_probe(AVProbeData *p)
return 0;
}
+static AVStream *create_stream(AVFormatContext *s, int tag, int codec_type)
+{
+ AVStream *st = avformat_new_stream(s, NULL);
+ if (!st)
+ return NULL;
+ st->id = tag;
+ st->codec->codec_type = codec_type;
+ avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
+ return st;
+}
+static int flv_same_audio_codec(AVCodecContext *acodec, int flags)
+{
+ int bits_per_coded_sample = (flags & FLV_AUDIO_SAMPLESIZE_MASK) ? 16 : 8;
+ int flv_codecid = flags & FLV_AUDIO_CODECID_MASK;
+ int codec_id;
+
+ if (!acodec->codec_id && !acodec->codec_tag)
+ return 1;
+
+ if (acodec->bits_per_coded_sample != bits_per_coded_sample)
+ return 0;
+
+ switch(flv_codecid) {
+ //no distinction between S16 and S8 PCM codec flags
+ case FLV_CODECID_PCM:
+ codec_id = bits_per_coded_sample == 8 ? CODEC_ID_PCM_U8 :
+#if HAVE_BIGENDIAN
+ CODEC_ID_PCM_S16BE;
+#else
+ CODEC_ID_PCM_S16LE;
+#endif
+ return codec_id == acodec->codec_id;
+ case FLV_CODECID_PCM_LE:
+ codec_id = bits_per_coded_sample == 8 ? CODEC_ID_PCM_U8 : CODEC_ID_PCM_S16LE;
+ return codec_id == acodec->codec_id;
+ case FLV_CODECID_AAC:
+ return acodec->codec_id == CODEC_ID_AAC;
+ case FLV_CODECID_ADPCM:
+ return acodec->codec_id == CODEC_ID_ADPCM_SWF;
+ case FLV_CODECID_SPEEX:
+ return acodec->codec_id == CODEC_ID_SPEEX;
+ case FLV_CODECID_MP3:
+ return acodec->codec_id == CODEC_ID_MP3;
+ case FLV_CODECID_NELLYMOSER_8KHZ_MONO:
+ case FLV_CODECID_NELLYMOSER_16KHZ_MONO:
+ case FLV_CODECID_NELLYMOSER:
+ return acodec->codec_id == CODEC_ID_NELLYMOSER;
+ case FLV_CODECID_PCM_MULAW:
+ return acodec->sample_rate == 8000 &&
+ acodec->codec_id == CODEC_ID_PCM_MULAW;
+ case FLV_CODECID_PCM_ALAW:
+ return acodec->sample_rate = 8000 &&
+ acodec->codec_id == CODEC_ID_PCM_ALAW;
+ default:
+ return acodec->codec_tag == (flv_codecid >> FLV_AUDIO_CODECID_OFFSET);
+ }
+
+ return 0;
+}
+
static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream, AVCodecContext *acodec, int flv_codecid) {
switch(flv_codecid) {
//no distinction between S16 and S8 PCM codec flags
@@ -97,12 +160,47 @@ static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream, AVCodecCo
case FLV_CODECID_NELLYMOSER:
acodec->codec_id = CODEC_ID_NELLYMOSER;
break;
+ case FLV_CODECID_PCM_MULAW:
+ acodec->sample_rate = 8000;
+ acodec->codec_id = CODEC_ID_PCM_MULAW;
+ break;
+ case FLV_CODECID_PCM_ALAW:
+ acodec->sample_rate = 8000;
+ acodec->codec_id = CODEC_ID_PCM_ALAW;
+ break;
default:
av_log(s, AV_LOG_INFO, "Unsupported audio codec (%x)\n", flv_codecid >> FLV_AUDIO_CODECID_OFFSET);
acodec->codec_tag = flv_codecid >> FLV_AUDIO_CODECID_OFFSET;
}
}
+static int flv_same_video_codec(AVCodecContext *vcodec, int flags)
+{
+ int flv_codecid = flags & FLV_VIDEO_CODECID_MASK;
+
+ if (!vcodec->codec_id && !vcodec->codec_tag)
+ return 1;
+
+ switch (flv_codecid) {
+ case FLV_CODECID_H263:
+ return vcodec->codec_id == CODEC_ID_FLV1;
+ case FLV_CODECID_SCREEN:
+ return vcodec->codec_id == CODEC_ID_FLASHSV;
+ case FLV_CODECID_SCREEN2:
+ return vcodec->codec_id == CODEC_ID_FLASHSV2;
+ case FLV_CODECID_VP6:
+ return vcodec->codec_id == CODEC_ID_VP6F;
+ case FLV_CODECID_VP6A:
+ return vcodec->codec_id == CODEC_ID_VP6A;
+ case FLV_CODECID_H264:
+ return vcodec->codec_id == CODEC_ID_H264;
+ default:
+ return vcodec->codec_tag == flv_codecid;
+ }
+
+ return 0;
+}
+
static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream, int flv_codecid) {
AVCodecContext *vcodec = vstream->codec;
switch(flv_codecid) {
@@ -228,6 +326,7 @@ finish:
static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vstream, const char *key, int64_t max_pos, int depth) {
AVCodecContext *acodec, *vcodec;
+ FLVContext *flv = s->priv_data;
AVIOContext *ioc;
AMFDataType amf_type;
char str_val[256];
@@ -302,6 +401,28 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst
vcodec->bit_rate = num_val * 1024.0;
else if (!strcmp(key, "audiodatarate") && acodec && 0 <= (int)(num_val * 1024.0))
acodec->bit_rate = num_val * 1024.0;
+ else if (!strcmp(key, "datastream")) {
+ AVStream *st = create_stream(s, 2, AVMEDIA_TYPE_DATA);
+ if (!st)
+ return AVERROR(ENOMEM);
+ st->codec->codec_id = CODEC_ID_TEXT;
+ } else if (flv->trust_metadata) {
+ if (!strcmp(key, "videocodecid") && vcodec) {
+ flv_set_video_codec(s, vstream, num_val);
+ } else
+ if (!strcmp(key, "audiocodecid") && acodec) {
+ flv_set_audio_codec(s, astream, acodec, num_val);
+ } else
+ if (!strcmp(key, "audiosamplerate") && acodec) {
+ acodec->sample_rate = num_val;
+ } else
+ if (!strcmp(key, "width") && vcodec) {
+ vcodec->width = num_val;
+ } else
+ if (!strcmp(key, "height") && vcodec) {
+ vcodec->height = num_val;
+ }
+ }
}
if (!strcmp(key, "duration") ||
@@ -344,7 +465,14 @@ static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) {
//first object needs to be "onMetaData" string
type = avio_r8(ioc);
- if(type != AMF_DATA_TYPE_STRING || amf_get_string(ioc, buffer, sizeof(buffer)) < 0 || strcmp(buffer, "onMetaData"))
+ if (type != AMF_DATA_TYPE_STRING ||
+ amf_get_string(ioc, buffer, sizeof(buffer)) < 0)
+ return -1;
+
+ if (!strcmp(buffer, "onTextData"))
+ return 1;
+
+ if (strcmp(buffer, "onMetaData"))
return -1;
//find the streams now so that amf_parse_object doesn't need to do the lookup every time it is called.
@@ -361,16 +489,6 @@ static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) {
return 0;
}
-static AVStream *create_stream(AVFormatContext *s, int is_audio){
- AVStream *st = avformat_new_stream(s, NULL);
- if (!st)
- return NULL;
- st->id = is_audio;
- st->codec->codec_type = is_audio ? AVMEDIA_TYPE_AUDIO : AVMEDIA_TYPE_VIDEO;
- avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
- return st;
-}
-
static int flv_read_header(AVFormatContext *s)
{
int offset, flags;
@@ -389,11 +507,11 @@ static int flv_read_header(AVFormatContext *s)
s->ctx_flags |= AVFMTCTX_NOHEADER;
if(flags & FLV_HEADER_FLAG_HASVIDEO){
- if(!create_stream(s, 0))
+ if(!create_stream(s, 0, AVMEDIA_TYPE_VIDEO))
return AVERROR(ENOMEM);
}
if(flags & FLV_HEADER_FLAG_HASAUDIO){
- if(!create_stream(s, 1))
+ if(!create_stream(s, 1, AVMEDIA_TYPE_AUDIO))
return AVERROR(ENOMEM);
}
@@ -453,6 +571,65 @@ static void clear_index_entries(AVFormatContext *s, int64_t pos)
}
}
+
+static int flv_data_packet(AVFormatContext *s, AVPacket *pkt,
+ int64_t dts, int64_t next)
+{
+ int ret = AVERROR_INVALIDDATA, i;
+ AVIOContext *pb = s->pb;
+ AVStream *st = NULL;
+ AMFDataType type;
+ char buf[20];
+ int length;
+
+ type = avio_r8(pb);
+ if (type == AMF_DATA_TYPE_MIXEDARRAY)
+ avio_seek(pb, 4, SEEK_CUR);
+ else if (type != AMF_DATA_TYPE_OBJECT)
+ goto out;
+
+ amf_get_string(pb, buf, sizeof(buf));
+ if (strcmp(buf, "type") || avio_r8(pb) != AMF_DATA_TYPE_STRING)
+ goto out;
+
+ amf_get_string(pb, buf, sizeof(buf));
+ //FIXME parse it as codec_id
+ amf_get_string(pb, buf, sizeof(buf));
+ if (strcmp(buf, "text") || avio_r8(pb) != AMF_DATA_TYPE_STRING)
+ goto out;
+
+ length = avio_rb16(pb);
+ ret = av_get_packet(s->pb, pkt, length);
+ if (ret < 0) {
+ ret = AVERROR(EIO);
+ goto out;
+ }
+
+ for (i = 0; i < s->nb_streams; i++) {
+ st = s->streams[i];
+ if (st->codec->codec_type == AVMEDIA_TYPE_DATA)
+ break;
+ }
+
+ if (i == s->nb_streams) {
+ st = create_stream(s, 2, AVMEDIA_TYPE_DATA);
+ if (!st)
+ goto out;
+ st->codec->codec_id = CODEC_ID_TEXT;
+ }
+
+ pkt->dts = dts;
+ pkt->pts = dts;
+ pkt->size = ret;
+
+ pkt->stream_index = st->index;
+ pkt->flags |= AV_PKT_FLAG_KEY;
+
+ avio_seek(s->pb, next + 4, SEEK_SET);
+out:
+ return ret;
+}
+
static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
{
FLVContext *flv = s->priv_data;
@@ -507,7 +684,9 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
goto skip;
} else {
if (type == FLV_TAG_TYPE_META && size > 13+1+4)
- flv_read_metabody(s, next);
+ if (flv_read_metabody(s, next) > 0) {
+ return flv_data_packet(s, pkt, dts, next);
+ }
else /* skip packet */
av_log(s, AV_LOG_DEBUG, "skipping flv packet: type %d, size %d, flags %d\n", type, size, flags);
skip:
@@ -522,12 +701,20 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
/* now find stream */
for(i=0;i<s->nb_streams;i++) {
st = s->streams[i];
- if (st->id == is_audio)
- break;
+ if (is_audio && st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+ if (flv_same_audio_codec(st->codec, flags)) {
+ break;
+ }
+ } else
+ if (!is_audio && st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+ if (flv_same_video_codec(st->codec, flags)) {
+ break;
+ }
+ }
}
if(i == s->nb_streams){
- av_log(s, AV_LOG_ERROR, "invalid stream\n");
- st= create_stream(s, is_audio);
+ st = create_stream(s, is_audio,
+ is_audio ? AVMEDIA_TYPE_AUDIO : AVMEDIA_TYPE_VIDEO);
s->ctx_flags &= ~AVFMTCTX_NOHEADER;
}
av_dlog(s, "%d %X %d \n", is_audio, flags, st->discard);
@@ -571,8 +758,8 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
}
if(!st->codec->codec_id){
flv_set_audio_codec(s, st, st->codec, flags & FLV_AUDIO_CODECID_MASK);
- flv->last_sample_rate = st->codec->sample_rate;
- flv->last_channels = st->codec->channels;
+ flv->last_sample_rate = sample_rate = st->codec->sample_rate;
+ flv->last_channels = channels = st->codec->channels;
} else {
AVCodecContext ctx;
ctx.sample_rate = sample_rate;
@@ -673,32 +860,19 @@ static int flv_read_seek(AVFormatContext *s, int stream_index,
return avio_seek_time(s->pb, stream_index, ts, flags);
}
-#if 0 /* don't know enough to implement this */
-static int flv_read_seek2(AVFormatContext *s, int stream_index,
- int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
-{
- int ret = AVERROR(ENOSYS);
-
- if (ts - min_ts > (uint64_t)(max_ts - ts)) flags |= AVSEEK_FLAG_BACKWARD;
-
- if (!s->pb->seekable) {
- if (stream_index < 0) {
- stream_index = av_find_default_stream_index(s);
- if (stream_index < 0)
- return -1;
-
- /* timestamp for default must be expressed in AV_TIME_BASE units */
- ts = av_rescale_rnd(ts, 1000, AV_TIME_BASE,
- flags & AVSEEK_FLAG_BACKWARD ? AV_ROUND_DOWN : AV_ROUND_UP);
- }
- ret = avio_seek_time(s->pb, stream_index, ts, flags);
- }
+#define OFFSET(x) offsetof(FLVContext, x)
+#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
+static const AVOption options[] = {
+ { "flv_metadata", "Allocate streams according the onMetaData array", OFFSET(trust_metadata), AV_OPT_TYPE_INT, { 0 }, 0, 1, VD},
+ { NULL }
+};
- if (ret == AVERROR(ENOSYS))
- ret = av_seek_frame(s, stream_index, ts, flags);
- return ret;
-}
-#endif
+static const AVClass class = {
+ .class_name = "flvdec",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
AVInputFormat ff_flv_demuxer = {
.name = "flv",
@@ -708,9 +882,7 @@ AVInputFormat ff_flv_demuxer = {
.read_header = flv_read_header,
.read_packet = flv_read_packet,
.read_seek = flv_read_seek,
-#if 0
- .read_seek2 = flv_read_seek2,
-#endif
.read_close = flv_read_close,
.extensions = "flv",
+ .priv_class = &class,
};
diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c
index 42ecde1..d77507d 100644
--- a/libavformat/flvenc.c
+++ b/libavformat/flvenc.c
@@ -19,41 +19,43 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/dict.h"
#include "libavutil/intfloat.h"
+#include "avc.h"
#include "avformat.h"
#include "flv.h"
#include "internal.h"
-#include "avc.h"
#include "metadata.h"
-#include "libavutil/dict.h"
#undef NDEBUG
#include <assert.h>
static const AVCodecTag flv_video_codec_ids[] = {
- {CODEC_ID_FLV1, FLV_CODECID_H263 },
- {CODEC_ID_FLASHSV, FLV_CODECID_SCREEN},
- {CODEC_ID_FLASHSV2, FLV_CODECID_SCREEN2},
- {CODEC_ID_VP6F, FLV_CODECID_VP6 },
- {CODEC_ID_VP6, FLV_CODECID_VP6 },
- {CODEC_ID_H264, FLV_CODECID_H264 },
- {CODEC_ID_NONE, 0}
+ { CODEC_ID_FLV1, FLV_CODECID_H263 },
+ { CODEC_ID_FLASHSV, FLV_CODECID_SCREEN },
+ { CODEC_ID_FLASHSV2, FLV_CODECID_SCREEN2 },
+ { CODEC_ID_VP6F, FLV_CODECID_VP6 },
+ { CODEC_ID_VP6, FLV_CODECID_VP6 },
+ { CODEC_ID_H264, FLV_CODECID_H264 },
+ { CODEC_ID_NONE, 0 }
};
static const AVCodecTag flv_audio_codec_ids[] = {
- {CODEC_ID_MP3, FLV_CODECID_MP3 >> FLV_AUDIO_CODECID_OFFSET},
- {CODEC_ID_PCM_U8, FLV_CODECID_PCM >> FLV_AUDIO_CODECID_OFFSET},
- {CODEC_ID_PCM_S16BE, FLV_CODECID_PCM >> FLV_AUDIO_CODECID_OFFSET},
- {CODEC_ID_PCM_S16LE, FLV_CODECID_PCM_LE >> FLV_AUDIO_CODECID_OFFSET},
- {CODEC_ID_ADPCM_SWF, FLV_CODECID_ADPCM >> FLV_AUDIO_CODECID_OFFSET},
- {CODEC_ID_AAC, FLV_CODECID_AAC >> FLV_AUDIO_CODECID_OFFSET},
- {CODEC_ID_NELLYMOSER, FLV_CODECID_NELLYMOSER >> FLV_AUDIO_CODECID_OFFSET},
- {CODEC_ID_SPEEX, FLV_CODECID_SPEEX >> FLV_AUDIO_CODECID_OFFSET},
- {CODEC_ID_NONE, 0}
+ { CODEC_ID_MP3, FLV_CODECID_MP3 >> FLV_AUDIO_CODECID_OFFSET },
+ { CODEC_ID_PCM_U8, FLV_CODECID_PCM >> FLV_AUDIO_CODECID_OFFSET },
+ { CODEC_ID_PCM_S16BE, FLV_CODECID_PCM >> FLV_AUDIO_CODECID_OFFSET },
+ { CODEC_ID_PCM_S16LE, FLV_CODECID_PCM_LE >> FLV_AUDIO_CODECID_OFFSET },
+ { CODEC_ID_ADPCM_SWF, FLV_CODECID_ADPCM >> FLV_AUDIO_CODECID_OFFSET },
+ { CODEC_ID_AAC, FLV_CODECID_AAC >> FLV_AUDIO_CODECID_OFFSET },
+ { CODEC_ID_NELLYMOSER, FLV_CODECID_NELLYMOSER >> FLV_AUDIO_CODECID_OFFSET },
+ { CODEC_ID_PCM_MULAW, FLV_CODECID_PCM_MULAW >> FLV_AUDIO_CODECID_OFFSET },
+ { CODEC_ID_PCM_ALAW, FLV_CODECID_PCM_ALAW >> FLV_AUDIO_CODECID_OFFSET },
+ { CODEC_ID_SPEEX, FLV_CODECID_SPEEX >> FLV_AUDIO_CODECID_OFFSET },
+ { CODEC_ID_NONE, 0 }
};
typedef struct FLVContext {
- int reserved;
+ int reserved;
int64_t duration_offset;
int64_t filesize_offset;
int64_t duration;
@@ -64,50 +66,55 @@ typedef struct FLVStreamContext {
int64_t last_ts; ///< last timestamp for each stream
} FLVStreamContext;
-static int get_audio_flags(AVCodecContext *enc){
- int flags = (enc->bits_per_coded_sample == 16) ? FLV_SAMPLESSIZE_16BIT : FLV_SAMPLESSIZE_8BIT;
+static int get_audio_flags(AVFormatContext *s, AVCodecContext *enc)
+{
+ int flags = (enc->bits_per_coded_sample == 16) ? FLV_SAMPLESSIZE_16BIT
+ : FLV_SAMPLESSIZE_8BIT;
if (enc->codec_id == CODEC_ID_AAC) // specs force these parameters
- return FLV_CODECID_AAC | FLV_SAMPLERATE_44100HZ | FLV_SAMPLESSIZE_16BIT | FLV_STEREO;
+ return FLV_CODECID_AAC | FLV_SAMPLERATE_44100HZ |
+ FLV_SAMPLESSIZE_16BIT | FLV_STEREO;
else if (enc->codec_id == CODEC_ID_SPEEX) {
if (enc->sample_rate != 16000) {
- av_log(enc, AV_LOG_ERROR, "flv only supports wideband (16kHz) Speex audio\n");
+ av_log(s, AV_LOG_ERROR,
+ "flv only supports wideband (16kHz) Speex audio\n");
return -1;
}
if (enc->channels != 1) {
- av_log(enc, AV_LOG_ERROR, "flv only supports mono Speex audio\n");
+ av_log(s, AV_LOG_ERROR, "flv only supports mono Speex audio\n");
return -1;
}
return FLV_CODECID_SPEEX | FLV_SAMPLERATE_11025HZ | FLV_SAMPLESSIZE_16BIT;
} else {
- switch (enc->sample_rate) {
- case 44100:
+ switch (enc->sample_rate) {
+ case 44100:
flags |= FLV_SAMPLERATE_44100HZ;
break;
- case 22050:
+ case 22050:
flags |= FLV_SAMPLERATE_22050HZ;
break;
- case 11025:
+ case 11025:
flags |= FLV_SAMPLERATE_11025HZ;
break;
- case 16000: //nellymoser only
- case 8000: //nellymoser only
- case 5512: //not mp3
- if(enc->codec_id != CODEC_ID_MP3){
+ case 16000: // nellymoser only
+ case 8000: // nellymoser only
+ case 5512: // not MP3
+ if (enc->codec_id != CODEC_ID_MP3) {
flags |= FLV_SAMPLERATE_SPECIAL;
break;
}
default:
- av_log(enc, AV_LOG_ERROR, "flv does not support that sample rate, choose from (44100, 22050, 11025).\n");
+ av_log(s, AV_LOG_ERROR,
+ "flv does not support that sample rate, "
+ "choose from (44100, 22050, 11025).\n");
return -1;
- }
+ }
}
- if (enc->channels > 1) {
+ if (enc->channels > 1)
flags |= FLV_STEREO;
- }
- switch(enc->codec_id){
+ switch (enc->codec_id) {
case CODEC_ID_MP3:
flags |= FLV_CODECID_MP3 | FLV_SAMPLESSIZE_16BIT;
break;
@@ -121,22 +128,27 @@ static int get_audio_flags(AVCodecContext *enc){
flags |= FLV_CODECID_PCM_LE | FLV_SAMPLESSIZE_16BIT;
break;
case CODEC_ID_ADPCM_SWF:
- flags |= FLV_CODECID_ADPCM | FLV_SAMPLESSIZE_16BIT;
+ flags |= FLV_CODECID_ADPCM | FLV_SAMPLESSIZE_16BIT;
break;
case CODEC_ID_NELLYMOSER:
- if (enc->sample_rate == 8000) {
- flags |= FLV_CODECID_NELLYMOSER_8KHZ_MONO | FLV_SAMPLESSIZE_16BIT;
- } else if (enc->sample_rate == 16000) {
+ if (enc->sample_rate == 8000)
+ flags |= FLV_CODECID_NELLYMOSER_8KHZ_MONO | FLV_SAMPLESSIZE_16BIT;
+ else if (enc->sample_rate == 16000)
flags |= FLV_CODECID_NELLYMOSER_16KHZ_MONO | FLV_SAMPLESSIZE_16BIT;
- } else {
- flags |= FLV_CODECID_NELLYMOSER | FLV_SAMPLESSIZE_16BIT;
- }
+ else
+ flags |= FLV_CODECID_NELLYMOSER | FLV_SAMPLESSIZE_16BIT;
+ break;
+ case CODEC_ID_PCM_MULAW:
+ flags = FLV_CODECID_PCM_MULAW | FLV_SAMPLERATE_SPECIAL | FLV_SAMPLESSIZE_16BIT;
+ break;
+ case CODEC_ID_PCM_ALAW:
+ flags = FLV_CODECID_PCM_ALAW | FLV_SAMPLERATE_SPECIAL | FLV_SAMPLESSIZE_16BIT;
break;
case 0:
- flags |= enc->codec_tag<<4;
+ flags |= enc->codec_tag << 4;
break;
default:
- av_log(enc, AV_LOG_ERROR, "codec not compatible with flv\n");
+ av_log(s, AV_LOG_ERROR, "codec not compatible with flv\n");
return -1;
}
@@ -150,16 +162,17 @@ static void put_amf_string(AVIOContext *pb, const char *str)
avio_write(pb, str, len);
}
-static void put_avc_eos_tag(AVIOContext *pb, unsigned ts) {
+static void put_avc_eos_tag(AVIOContext *pb, unsigned ts)
+{
avio_w8(pb, FLV_TAG_TYPE_VIDEO);
- avio_wb24(pb, 5); /* Tag Data Size */
- avio_wb24(pb, ts); /* lower 24 bits of timestamp in ms*/
- avio_w8(pb, (ts >> 24) & 0x7F); /* MSB of ts in ms*/
- avio_wb24(pb, 0); /* StreamId = 0 */
- avio_w8(pb, 23); /* ub[4] FrameType = 1, ub[4] CodecId = 7 */
- avio_w8(pb, 2); /* AVC end of sequence */
- avio_wb24(pb, 0); /* Always 0 for AVC EOS. */
- avio_wb32(pb, 16); /* Size of FLV tag */
+ avio_wb24(pb, 5); /* Tag Data Size */
+ avio_wb24(pb, ts); /* lower 24 bits of timestamp in ms */
+ avio_w8(pb, (ts >> 24) & 0x7F); /* MSB of ts in ms */
+ avio_wb24(pb, 0); /* StreamId = 0 */
+ avio_w8(pb, 23); /* ub[4] FrameType = 1, ub[4] CodecId = 7 */
+ avio_w8(pb, 2); /* AVC end of sequence */
+ avio_wb24(pb, 0); /* Always 0 for AVC EOS. */
+ avio_wb32(pb, 16); /* Size of FLV tag */
}
static void put_amf_double(AVIOContext *pb, double d)
@@ -168,7 +181,8 @@ static void put_amf_double(AVIOContext *pb, double d)
avio_wb64(pb, av_double2int(d));
}
-static void put_amf_bool(AVIOContext *pb, int b) {
+static void put_amf_bool(AVIOContext *pb, int b)
+{
avio_w8(pb, AMF_DATA_TYPE_BOOL);
avio_w8(pb, !!b);
}
@@ -177,30 +191,44 @@ static int flv_write_header(AVFormatContext *s)
{
AVIOContext *pb = s->pb;
FLVContext *flv = s->priv_data;
- AVCodecContext *audio_enc = NULL, *video_enc = NULL;
+ AVCodecContext *audio_enc = NULL, *video_enc = NULL, *data_enc = NULL;
int i, metadata_count = 0;
double framerate = 0.0;
int64_t metadata_size_pos, data_size, metadata_count_pos;
AVDictionaryEntry *tag = NULL;
- for(i=0; i<s->nb_streams; i++){
+ for (i = 0; i < s->nb_streams; i++) {
AVCodecContext *enc = s->streams[i]->codec;
FLVStreamContext *sc;
- if (enc->codec_type == AVMEDIA_TYPE_VIDEO) {
- if (s->streams[i]->r_frame_rate.den && s->streams[i]->r_frame_rate.num) {
+ switch (enc->codec_type) {
+ case AVMEDIA_TYPE_VIDEO:
+ if (s->streams[i]->r_frame_rate.den &&
+ s->streams[i]->r_frame_rate.num) {
framerate = av_q2d(s->streams[i]->r_frame_rate);
} else {
- framerate = 1/av_q2d(s->streams[i]->codec->time_base);
+ framerate = 1 / av_q2d(s->streams[i]->codec->time_base);
}
video_enc = enc;
- if(enc->codec_tag == 0) {
- av_log(enc, AV_LOG_ERROR, "video codec not compatible with flv\n");
+ if (enc->codec_tag == 0) {
+ av_log(s, AV_LOG_ERROR, "video codec not compatible with flv\n");
return -1;
}
- } else {
+ break;
+ case AVMEDIA_TYPE_AUDIO:
audio_enc = enc;
- if(get_audio_flags(enc)<0)
- return -1;
+ if (get_audio_flags(s, enc) < 0)
+ return AVERROR_INVALIDDATA;
+ break;
+ case AVMEDIA_TYPE_DATA:
+ if (enc->codec_id != CODEC_ID_TEXT) {
+ av_log(s, AV_LOG_ERROR, "codec not compatible with flv\n");
+ return AVERROR_INVALIDDATA;
+ }
+ data_enc = enc;
+ break;
+ default:
+ av_log(s, AV_LOG_ERROR, "codec not compatible with flv\n");
+ return -1;
}
avpriv_set_pts_info(s->streams[i], 32, 1, 1000); /* 32 bit pts in ms */
@@ -210,32 +238,32 @@ static int flv_write_header(AVFormatContext *s)
s->streams[i]->priv_data = sc;
sc->last_ts = -1;
}
+
flv->delay = AV_NOPTS_VALUE;
avio_write(pb, "FLV", 3);
- avio_w8(pb,1);
- avio_w8(pb, FLV_HEADER_FLAG_HASAUDIO * !!audio_enc
- + FLV_HEADER_FLAG_HASVIDEO * !!video_enc);
- avio_wb32(pb,9);
- avio_wb32(pb,0);
-
- for(i=0; i<s->nb_streams; i++){
- if(s->streams[i]->codec->codec_tag == 5){
- avio_w8(pb,8); // message type
- avio_wb24(pb,0); // include flags
- avio_wb24(pb,0); // time stamp
- avio_wb32(pb,0); // reserved
- avio_wb32(pb,11); // size
- flv->reserved=5;
+ avio_w8(pb, 1);
+ avio_w8(pb, FLV_HEADER_FLAG_HASAUDIO * !!audio_enc +
+ FLV_HEADER_FLAG_HASVIDEO * !!video_enc);
+ avio_wb32(pb, 9);
+ avio_wb32(pb, 0);
+
+ for (i = 0; i < s->nb_streams; i++)
+ if (s->streams[i]->codec->codec_tag == 5) {
+ avio_w8(pb, 8); // message type
+ avio_wb24(pb, 0); // include flags
+ avio_wb24(pb, 0); // time stamp
+ avio_wb32(pb, 0); // reserved
+ avio_wb32(pb, 11); // size
+ flv->reserved = 5;
}
- }
/* write meta_tag */
- avio_w8(pb, 18); // tag type META
- metadata_size_pos= avio_tell(pb);
- avio_wb24(pb, 0); // size of data part (sum of all parts below)
- avio_wb24(pb, 0); // time stamp
- avio_wb32(pb, 0); // reserved
+ avio_w8(pb, 18); // tag type META
+ metadata_size_pos = avio_tell(pb);
+ avio_wb24(pb, 0); // size of data part (sum of all parts below)
+ avio_wb24(pb, 0); // timestamp
+ avio_wb32(pb, 0); // reserved
/* now data of data_size size */
@@ -246,14 +274,20 @@ static int flv_write_header(AVFormatContext *s)
/* mixed array (hash) with size and string/type/data tuples */
avio_w8(pb, AMF_DATA_TYPE_MIXEDARRAY);
metadata_count_pos = avio_tell(pb);
- metadata_count = 5*!!video_enc + 5*!!audio_enc + 2; // +2 for duration and file size
+ metadata_count = 5 * !!video_enc +
+ 5 * !!audio_enc +
+ 1 * !!data_enc +
+ 2; // +2 for duration and file size
+
avio_wb32(pb, metadata_count);
put_amf_string(pb, "duration");
flv->duration_offset= avio_tell(pb);
- put_amf_double(pb, s->duration / AV_TIME_BASE); // fill in the guessed duration, it'll be corrected later if incorrect
- if(video_enc){
+ // fill in the guessed duration, it'll be corrected later if incorrect
+ put_amf_double(pb, s->duration / AV_TIME_BASE);
+
+ if (video_enc) {
put_amf_string(pb, "width");
put_amf_double(pb, video_enc->width);
@@ -270,7 +304,7 @@ static int flv_write_header(AVFormatContext *s)
put_amf_double(pb, video_enc->codec_tag);
}
- if(audio_enc){
+ if (audio_enc) {
put_amf_string(pb, "audiodatarate");
put_amf_double(pb, audio_enc->bit_rate / 1024.0);
@@ -287,6 +321,11 @@ static int flv_write_header(AVFormatContext *s)
put_amf_double(pb, audio_enc->codec_tag);
}
+ if (data_enc) {
+ put_amf_string(pb, "datastream");
+ put_amf_double(pb, 0.0);
+ }
+
while ((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
put_amf_string(pb, tag->key);
avio_w8(pb, AMF_DATA_TYPE_STRING);
@@ -295,14 +334,14 @@ static int flv_write_header(AVFormatContext *s)
}
put_amf_string(pb, "filesize");
- flv->filesize_offset= avio_tell(pb);
+ flv->filesize_offset = avio_tell(pb);
put_amf_double(pb, 0); // delayed write
put_amf_string(pb, "");
avio_w8(pb, AMF_END_OF_OBJECT);
/* write total size of tag */
- data_size= avio_tell(pb) - metadata_size_pos - 10;
+ data_size = avio_tell(pb) - metadata_size_pos - 10;
avio_seek(pb, metadata_count_pos, SEEK_SET);
avio_wb32(pb, metadata_count);
@@ -317,14 +356,14 @@ static int flv_write_header(AVFormatContext *s)
if (enc->codec_id == CODEC_ID_AAC || enc->codec_id == CODEC_ID_H264) {
int64_t pos;
avio_w8(pb, enc->codec_type == AVMEDIA_TYPE_VIDEO ?
- FLV_TAG_TYPE_VIDEO : FLV_TAG_TYPE_AUDIO);
+ FLV_TAG_TYPE_VIDEO : FLV_TAG_TYPE_AUDIO);
avio_wb24(pb, 0); // size patched later
avio_wb24(pb, 0); // ts
- avio_w8(pb, 0); // ts ext
+ avio_w8(pb, 0); // ts ext
avio_wb24(pb, 0); // streamid
pos = avio_tell(pb);
if (enc->codec_id == CODEC_ID_AAC) {
- avio_w8(pb, get_audio_flags(enc));
+ avio_w8(pb, get_audio_flags(s, enc));
avio_w8(pb, 0); // AAC sequence header
avio_write(pb, enc->extradata, enc->extradata_size);
} else {
@@ -357,9 +396,8 @@ static int flv_write_trailer(AVFormatContext *s)
AVCodecContext *enc = s->streams[i]->codec;
FLVStreamContext *sc = s->streams[i]->priv_data;
if (enc->codec_type == AVMEDIA_TYPE_VIDEO &&
- enc->codec_id == CODEC_ID_H264) {
+ enc->codec_id == CODEC_ID_H264)
put_avc_eos_tag(pb, sc->last_ts);
- }
}
file_size = avio_tell(pb);
@@ -376,94 +414,127 @@ static int flv_write_trailer(AVFormatContext *s)
static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
{
- AVIOContext *pb = s->pb;
- AVCodecContext *enc = s->streams[pkt->stream_index]->codec;
- FLVContext *flv = s->priv_data;
+ AVIOContext *pb = s->pb;
+ AVCodecContext *enc = s->streams[pkt->stream_index]->codec;
+ FLVContext *flv = s->priv_data;
FLVStreamContext *sc = s->streams[pkt->stream_index]->priv_data;
unsigned ts;
- int size= pkt->size;
- uint8_t *data= NULL;
+ int size = pkt->size;
+ uint8_t *data = NULL;
int flags, flags_size;
-// av_log(s, AV_LOG_DEBUG, "type:%d pts: %"PRId64" size:%d\n", enc->codec_type, timestamp, size);
+ // av_log(s, AV_LOG_DEBUG, "type:%d pts: %"PRId64" size:%d\n",
+ // enc->codec_type, timestamp, size);
- if(enc->codec_id == CODEC_ID_VP6 || enc->codec_id == CODEC_ID_VP6F ||
- enc->codec_id == CODEC_ID_AAC)
- flags_size= 2;
- else if(enc->codec_id == CODEC_ID_H264)
- flags_size= 5;
+ if (enc->codec_id == CODEC_ID_VP6 || enc->codec_id == CODEC_ID_VP6F ||
+ enc->codec_id == CODEC_ID_AAC)
+ flags_size = 2;
+ else if (enc->codec_id == CODEC_ID_H264)
+ flags_size = 5;
else
- flags_size= 1;
+ flags_size = 1;
- if (enc->codec_type == AVMEDIA_TYPE_VIDEO) {
+ switch (enc->codec_type) {
+ case AVMEDIA_TYPE_VIDEO:
avio_w8(pb, FLV_TAG_TYPE_VIDEO);
flags = enc->codec_tag;
- if(flags == 0) {
- av_log(enc, AV_LOG_ERROR, "video codec %X not compatible with flv\n",enc->codec_id);
+ if (flags == 0) {
+ av_log(s, AV_LOG_ERROR,
+ "video codec %X not compatible with flv\n",
+ enc->codec_id);
return -1;
}
flags |= pkt->flags & AV_PKT_FLAG_KEY ? FLV_FRAME_KEY : FLV_FRAME_INTER;
- } else {
- assert(enc->codec_type == AVMEDIA_TYPE_AUDIO);
- flags = get_audio_flags(enc);
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ flags = get_audio_flags(s, enc);
assert(size);
avio_w8(pb, FLV_TAG_TYPE_AUDIO);
+ break;
+ case AVMEDIA_TYPE_DATA:
+ avio_w8(pb, FLV_TAG_TYPE_META);
+ break;
+ default:
+ return AVERROR(EINVAL);
}
- if (enc->codec_id == CODEC_ID_H264) {
+ if (enc->codec_id == CODEC_ID_H264)
/* check if extradata looks like MP4 */
- if (enc->extradata_size > 0 && *(uint8_t*)enc->extradata != 1) {
+ if (enc->extradata_size > 0 && *(uint8_t*)enc->extradata != 1)
if (ff_avc_parse_nal_units_buf(pkt->data, &data, &size) < 0)
return -1;
- }
- }
+
if (flv->delay == AV_NOPTS_VALUE)
flv->delay = -pkt->dts;
+
if (pkt->dts < -flv->delay) {
- av_log(s, AV_LOG_WARNING, "Packets are not in the proper order with "
- "respect to DTS\n");
+ av_log(s, AV_LOG_WARNING,
+ "Packets are not in the proper order with respect to DTS\n");
return AVERROR(EINVAL);
}
ts = pkt->dts + flv->delay; // add delay to force positive dts
/* check Speex packet duration */
- if (enc->codec_id == CODEC_ID_SPEEX && ts - sc->last_ts > 160) {
+ if (enc->codec_id == CODEC_ID_SPEEX && ts - sc->last_ts > 160)
av_log(s, AV_LOG_WARNING, "Warning: Speex stream has more than "
"8 frames per packet. Adobe Flash "
"Player cannot handle this!\n");
- }
if (sc->last_ts < ts)
sc->last_ts = ts;
- avio_wb24(pb,size + flags_size);
- avio_wb24(pb,ts);
- avio_w8(pb,(ts >> 24) & 0x7F); // timestamps are 32bits _signed_
- avio_wb24(pb,flv->reserved);
- avio_w8(pb,flags);
- if (enc->codec_id == CODEC_ID_VP6)
- avio_w8(pb,0);
- if (enc->codec_id == CODEC_ID_VP6F)
- avio_w8(pb, enc->extradata_size ? enc->extradata[0] : 0);
- else if (enc->codec_id == CODEC_ID_AAC)
- avio_w8(pb,1); // AAC raw
- else if (enc->codec_id == CODEC_ID_H264) {
- avio_w8(pb,1); // AVC NALU
- avio_wb24(pb,pkt->pts - pkt->dts);
- }
+ avio_wb24(pb, size + flags_size);
+ avio_wb24(pb, ts);
+ avio_w8(pb, (ts >> 24) & 0x7F); // timestamps are 32 bits _signed_
+ avio_wb24(pb, flv->reserved);
+
+ if (enc->codec_type == AVMEDIA_TYPE_DATA) {
+ int data_size;
+ int metadata_size_pos = avio_tell(pb);
+ avio_w8(pb, AMF_DATA_TYPE_STRING);
+ put_amf_string(pb, "onTextData");
+ avio_w8(pb, AMF_DATA_TYPE_MIXEDARRAY);
+ avio_wb32(pb, 2);
+ put_amf_string(pb, "type");
+ avio_w8(pb, AMF_DATA_TYPE_STRING);
+ put_amf_string(pb, "Text");
+ put_amf_string(pb, "text");
+ avio_w8(pb, AMF_DATA_TYPE_STRING);
+ put_amf_string(pb, pkt->data);
+ put_amf_string(pb, "");
+ avio_w8(pb, AMF_END_OF_OBJECT);
+ /* write total size of tag */
+ data_size = avio_tell(pb) - metadata_size_pos;
+ avio_seek(pb, metadata_size_pos - 10, SEEK_SET);
+ avio_wb24(pb, data_size);
+ avio_seek(pb, data_size + 10 - 3, SEEK_CUR);
+ avio_wb32(pb, data_size + 11);
+ } else {
+ avio_w8(pb,flags);
+ if (enc->codec_id == CODEC_ID_VP6)
+ avio_w8(pb, 0);
+ if (enc->codec_id == CODEC_ID_VP6F)
+ avio_w8(pb, enc->extradata_size ? enc->extradata[0] : 0);
+ else if (enc->codec_id == CODEC_ID_AAC)
+ avio_w8(pb, 1); // AAC raw
+ else if (enc->codec_id == CODEC_ID_H264) {
+ avio_w8(pb, 1); // AVC NALU
+ avio_wb24(pb, pkt->pts - pkt->dts);
+ }
- avio_write(pb, data ? data : pkt->data, size);
+ avio_write(pb, data ? data : pkt->data, size);
- avio_wb32(pb,size+flags_size+11); // previous tag size
- flv->duration = FFMAX(flv->duration, pkt->pts + flv->delay + pkt->duration);
+ avio_wb32(pb, size + flags_size + 11); // previous tag size
+ flv->duration = FFMAX(flv->duration,
+ pkt->pts + flv->delay + pkt->duration);
+ }
avio_flush(pb);
-
av_free(data);
return pb->error;
@@ -484,8 +555,9 @@ AVOutputFormat ff_flv_muxer = {
.write_header = flv_write_header,
.write_packet = flv_write_packet,
.write_trailer = flv_write_trailer,
- .codec_tag = (const AVCodecTag* const []){
- flv_video_codec_ids, flv_audio_codec_ids, 0
- },
- .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
+ .codec_tag = (const AVCodecTag* const []) {
+ flv_video_codec_ids, flv_audio_codec_ids, 0
+ },
+ .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS |
+ AVFMT_TS_NONSTRICT,
};
diff --git a/libavformat/framecrcenc.c b/libavformat/framecrcenc.c
index d1148f9..36dfd29 100644
--- a/libavformat/framecrcenc.c
+++ b/libavformat/framecrcenc.c
@@ -43,5 +43,5 @@ AVOutputFormat ff_framecrc_muxer = {
.video_codec = CODEC_ID_RAWVIDEO,
.write_header = ff_framehash_write_header,
.write_packet = framecrc_write_packet,
- .flags = AVFMT_VARIABLE_FPS,
+ .flags = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT,
};
diff --git a/libavformat/gxfenc.c b/libavformat/gxfenc.c
index 5069f2f..c11b77b 100644
--- a/libavformat/gxfenc.c
+++ b/libavformat/gxfenc.c
@@ -524,17 +524,6 @@ static int gxf_write_umf_media_audio(AVIOContext *pb, GXFStreamContext *sc)
return 32;
}
-#if 0
-static int gxf_write_umf_media_mjpeg(AVIOContext *pb, GXFStreamContext *sc)
-{
- avio_wb64(pb, 0); /* FIXME FLOAT max chroma quant level */
- avio_wb64(pb, 0); /* FIXME FLOAT max luma quant level */
- avio_wb64(pb, 0); /* FIXME FLOAT min chroma quant level */
- avio_wb64(pb, 0); /* FIXME FLOAT min luma quant level */
- return 32;
-}
-#endif
-
static int gxf_write_umf_media_description(AVFormatContext *s)
{
GXFContext *gxf = s->priv_data;
diff --git a/libavformat/hls.c b/libavformat/hls.c
index e876735..253463e 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -30,9 +30,9 @@
#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
#include "libavutil/dict.h"
+#include "libavutil/time.h"
#include "avformat.h"
#include "internal.h"
-#include <unistd.h>
#include "avio_internal.h"
#include "url.h"
@@ -407,7 +407,7 @@ reload:
while (av_gettime() - v->last_load_time < reload_interval) {
if (ff_check_interrupt(c->interrupt_callback))
return AVERROR_EXIT;
- usleep(100*1000);
+ av_usleep(100*1000);
}
/* Enough time has elapsed since the last reload */
goto reload;
diff --git a/libavformat/hlsproto.c b/libavformat/hlsproto.c
index 044b7ff..179bdf1 100644
--- a/libavformat/hlsproto.c
+++ b/libavformat/hlsproto.c
@@ -26,11 +26,11 @@
*/
#include "libavutil/avstring.h"
+#include "libavutil/time.h"
#include "avformat.h"
#include "internal.h"
#include "url.h"
#include "version.h"
-#include <unistd.h>
/*
* An apple http stream consists of a playlist with media segment files,
@@ -308,7 +308,7 @@ retry:
while (av_gettime() - s->last_load_time < reload_interval) {
if (ff_check_interrupt(&h->interrupt_callback))
return AVERROR_EXIT;
- usleep(100*1000);
+ av_usleep(100*1000);
}
goto retry;
}
diff --git a/libavformat/http.c b/libavformat/http.c
index c69e3f5..ce4a508 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -21,7 +21,6 @@
#include "libavutil/avstring.h"
#include "avformat.h"
-#include <unistd.h>
#include "internal.h"
#include "network.h"
#include "http.h"
@@ -51,6 +50,11 @@ typedef struct {
char *headers;
int willclose; /**< Set if the server correctly handles Connection: close and will close the connection after feeding us the content. */
int chunked_post;
+ int end_chunked_post; /**< A flag which indicates if the end of chunked encoding has been sent. */
+ int end_header; /**< A flag which indicates we have finished to read POST reply. */
+ int multiple_requests; /**< A flag which indicates if we use persistent connections. */
+ uint8_t *post_data;
+ int post_datalen;
} HTTPContext;
#define OFFSET(x) offsetof(HTTPContext, x)
@@ -59,6 +63,8 @@ typedef struct {
static const AVOption options[] = {
{"chunked_post", "use chunked transfer-encoding for posts", OFFSET(chunked_post), AV_OPT_TYPE_INT, {.dbl = 1}, 0, 1, E },
{"headers", "custom HTTP headers, can override built in default headers", OFFSET(headers), AV_OPT_TYPE_STRING, { 0 }, 0, 0, D|E },
+{"multiple_requests", "use persistent connections", OFFSET(multiple_requests), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 1, D|E },
+{"post_data", "custom HTTP post data", OFFSET(post_data), AV_OPT_TYPE_BINARY, .flags = D|E },
{NULL}
};
#define HTTP_CLASS(flavor)\
@@ -96,7 +102,6 @@ static int http_open_cnx(URLContext *h)
int port, use_proxy, err, location_changed = 0, redirects = 0, attempts = 0;
HTTPAuthType cur_auth_type, cur_proxy_auth_type;
HTTPContext *s = h->priv_data;
- URLContext *hd = NULL;
proxy_path = getenv("http_proxy");
use_proxy = (proxy_path != NULL) && !getenv("no_proxy") &&
@@ -135,12 +140,14 @@ static int http_open_cnx(URLContext *h)
}
ff_url_join(buf, sizeof(buf), lower_proto, NULL, hostname, port, NULL);
- err = ffurl_open(&hd, buf, AVIO_FLAG_READ_WRITE,
- &h->interrupt_callback, NULL);
- if (err < 0)
- goto fail;
- s->hd = hd;
+ if (!s->hd) {
+ err = ffurl_open(&s->hd, buf, AVIO_FLAG_READ_WRITE,
+ &h->interrupt_callback, NULL);
+ if (err < 0)
+ goto fail;
+ }
+
cur_auth_type = s->auth_state.auth_type;
cur_proxy_auth_type = s->auth_state.auth_type;
if (http_connect(h, path, local_path, hoststr, auth, proxyauth, &location_changed) < 0)
@@ -149,7 +156,8 @@ static int http_open_cnx(URLContext *h)
if (s->http_code == 401) {
if ((cur_auth_type == HTTP_AUTH_NONE || s->auth_state.stale) &&
s->auth_state.auth_type != HTTP_AUTH_NONE && attempts < 4) {
- ffurl_close(hd);
+ ffurl_close(s->hd);
+ s->hd = NULL;
goto redo;
} else
goto fail;
@@ -157,7 +165,8 @@ static int http_open_cnx(URLContext *h)
if (s->http_code == 407) {
if ((cur_proxy_auth_type == HTTP_AUTH_NONE || s->proxy_auth_state.stale) &&
s->proxy_auth_state.auth_type != HTTP_AUTH_NONE && attempts < 4) {
- ffurl_close(hd);
+ ffurl_close(s->hd);
+ s->hd = NULL;
goto redo;
} else
goto fail;
@@ -165,7 +174,8 @@ static int http_open_cnx(URLContext *h)
if ((s->http_code == 301 || s->http_code == 302 || s->http_code == 303 || s->http_code == 307)
&& location_changed == 1) {
/* url moved, get next */
- ffurl_close(hd);
+ ffurl_close(s->hd);
+ s->hd = NULL;
if (redirects++ >= MAX_REDIRECTS)
return AVERROR(EIO);
/* Restart the authentication process with the new target, which
@@ -177,12 +187,22 @@ static int http_open_cnx(URLContext *h)
}
return 0;
fail:
- if (hd)
- ffurl_close(hd);
+ if (s->hd)
+ ffurl_close(s->hd);
s->hd = NULL;
return AVERROR(EIO);
}
+int ff_http_do_new_request(URLContext *h, const char *uri)
+{
+ HTTPContext *s = h->priv_data;
+
+ s->off = 0;
+ av_strlcpy(s->location, uri, sizeof(s->location));
+
+ return http_open_cnx(h);
+}
+
static int http_open(URLContext *h, const char *uri, int flags)
{
HTTPContext *s = h->priv_data;
@@ -206,7 +226,7 @@ static int http_getc(HTTPContext *s)
if (s->buf_ptr >= s->buf_end) {
len = ffurl_read(s->hd, s->buffer, BUFFER_SIZE);
if (len < 0) {
- return AVERROR(EIO);
+ return len;
} else if (len == 0) {
return -1;
} else {
@@ -226,7 +246,7 @@ static int http_get_line(HTTPContext *s, char *line, int line_size)
for(;;) {
ch = http_getc(s);
if (ch < 0)
- return AVERROR(EIO);
+ return ch;
if (ch == '\n') {
/* process line */
if (q > line && q[-1] == '\r')
@@ -248,8 +268,10 @@ static int process_line(URLContext *h, char *line, int line_count,
char *tag, *p, *end;
/* end of header */
- if (line[0] == '\0')
+ if (line[0] == '\0') {
+ s->end_header = 1;
return 0;
+ }
p = line;
if (line_count == 0) {
@@ -286,15 +308,15 @@ static int process_line(URLContext *h, char *line, int line_count,
strcpy(s->location, p);
*new_location = 1;
} else if (!av_strcasecmp (tag, "Content-Length") && s->filesize == -1) {
- s->filesize = atoll(p);
+ s->filesize = strtoll(p, NULL, 10);
} else if (!av_strcasecmp (tag, "Content-Range")) {
/* "bytes $from-$to/$document_size" */
const char *slash;
if (!strncmp (p, "bytes ", 6)) {
p += 6;
- s->off = atoll(p);
+ s->off = strtoll(p, NULL, 10);
if ((slash = strchr(p, '/')) && strlen(slash) > 0)
- s->filesize = atoll(slash+1);
+ s->filesize = strtoll(slash+1, NULL, 10);
}
h->is_streamed = 0; /* we _can_ in fact seek */
} else if (!av_strcasecmp(tag, "Accept-Ranges") && !strncmp(p, "bytes", 5)) {
@@ -324,13 +346,37 @@ static inline int has_header(const char *str, const char *header)
return av_stristart(str, header + 2, NULL) || av_stristr(str, header);
}
+static int http_read_header(URLContext *h, int *new_location)
+{
+ HTTPContext *s = h->priv_data;
+ char line[1024];
+ int err = 0;
+
+ s->chunksize = -1;
+
+ for (;;) {
+ if ((err = http_get_line(s, line, sizeof(line))) < 0)
+ return err;
+
+ av_dlog(NULL, "header='%s'\n", line);
+
+ err = process_line(h, line, s->line_count, new_location);
+ if (err < 0)
+ return err;
+ if (err == 0)
+ break;
+ s->line_count++;
+ }
+
+ return err;
+}
+
static int http_connect(URLContext *h, const char *path, const char *local_path,
const char *hoststr, const char *auth,
const char *proxyauth, int *new_location)
{
HTTPContext *s = h->priv_data;
int post, err;
- char line[1024];
char headers[1024] = "";
char *authstr = NULL, *proxyauthstr = NULL;
int64_t off = s->off;
@@ -340,6 +386,14 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
/* send http header */
post = h->flags & AVIO_FLAG_WRITE;
+
+ if (s->post_data) {
+ /* force POST method and disable chunked encoding when
+ * custom HTTP post data is set */
+ post = 1;
+ s->chunked_post = 0;
+ }
+
method = post ? "POST" : "GET";
authstr = ff_http_auth_create_response(&s->auth_state, auth, local_path,
method);
@@ -356,12 +410,23 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
if (!has_header(s->headers, "\r\nRange: ") && !post)
len += av_strlcatf(headers + len, sizeof(headers) - len,
"Range: bytes=%"PRId64"-\r\n", s->off);
- if (!has_header(s->headers, "\r\nConnection: "))
- len += av_strlcpy(headers + len, "Connection: close\r\n",
- sizeof(headers)-len);
+
+ if (!has_header(s->headers, "\r\nConnection: ")) {
+ if (s->multiple_requests) {
+ len += av_strlcpy(headers + len, "Connection: keep-alive\r\n",
+ sizeof(headers) - len);
+ } else {
+ len += av_strlcpy(headers + len, "Connection: close\r\n",
+ sizeof(headers) - len);
+ }
+ }
+
if (!has_header(s->headers, "\r\nHost: "))
len += av_strlcatf(headers + len, sizeof(headers) - len,
"Host: %s\r\n", hoststr);
+ if (!has_header(s->headers, "\r\nContent-Length: ") && s->post_data)
+ len += av_strlcatf(headers + len, sizeof(headers) - len,
+ "Content-Length: %d\r\n", s->post_datalen);
/* now add in custom headers */
if (s->headers)
@@ -383,8 +448,12 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
av_freep(&authstr);
av_freep(&proxyauthstr);
- if (ffurl_write(s->hd, s->buffer, strlen(s->buffer)) < 0)
- return AVERROR(EIO);
+ if ((err = ffurl_write(s->hd, s->buffer, strlen(s->buffer))) < 0)
+ return err;
+
+ if (s->post_data)
+ if ((err = ffurl_write(s->hd, s->post_data, s->post_datalen)) < 0)
+ return err;
/* init input buffer */
s->buf_ptr = s->buffer;
@@ -393,29 +462,20 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
s->off = 0;
s->filesize = -1;
s->willclose = 0;
- if (post) {
+ s->end_chunked_post = 0;
+ s->end_header = 0;
+ if (post && !s->post_data) {
/* Pretend that it did work. We didn't read any header yet, since
* we've still to send the POST data, but the code calling this
* function will check http_code after we return. */
s->http_code = 200;
return 0;
}
- s->chunksize = -1;
/* wait for header */
- for(;;) {
- if (http_get_line(s, line, sizeof(line)) < 0)
- return AVERROR(EIO);
-
- av_dlog(NULL, "header='%s'\n", line);
-
- err = process_line(h, line, s->line_count, new_location);
- if (err < 0)
- return err;
- if (err == 0)
- break;
- s->line_count++;
- }
+ err = http_read_header(h, new_location);
+ if (err < 0)
+ return err;
return (off == s->off) ? 0 : -1;
}
@@ -448,6 +508,16 @@ static int http_buf_read(URLContext *h, uint8_t *buf, int size)
static int http_read(URLContext *h, uint8_t *buf, int size)
{
HTTPContext *s = h->priv_data;
+ int err, new_location;
+
+ if (!s->hd)
+ return AVERROR_EOF;
+
+ if (s->end_chunked_post && !s->end_header) {
+ err = http_read_header(h, &new_location);
+ if (err < 0)
+ return err;
+ }
if (s->chunksize >= 0) {
if (!s->chunksize) {
@@ -455,8 +525,8 @@ static int http_read(URLContext *h, uint8_t *buf, int size)
for(;;) {
do {
- if (http_get_line(s, line, sizeof(line)) < 0)
- return AVERROR(EIO);
+ if ((err = http_get_line(s, line, sizeof(line))) < 0)
+ return err;
} while (!*line); /* skip CR LF from last chunk */
s->chunksize = strtoll(line, NULL, 16);
@@ -500,16 +570,30 @@ static int http_write(URLContext *h, const uint8_t *buf, int size)
return size;
}
-static int http_close(URLContext *h)
+static int http_shutdown(URLContext *h, int flags)
{
int ret = 0;
char footer[] = "0\r\n\r\n";
HTTPContext *s = h->priv_data;
/* signal end of chunked encoding if used */
- if ((h->flags & AVIO_FLAG_WRITE) && s->chunked_post) {
+ if ((flags & AVIO_FLAG_WRITE) && s->chunked_post) {
ret = ffurl_write(s->hd, footer, sizeof(footer) - 1);
ret = ret > 0 ? 0 : ret;
+ s->end_chunked_post = 1;
+ }
+
+ return ret;
+}
+
+static int http_close(URLContext *h)
+{
+ int ret = 0;
+ HTTPContext *s = h->priv_data;
+
+ if (!s->end_chunked_post) {
+ /* Close the write direction by sending the end of chunked encoding. */
+ ret = http_shutdown(h, h->flags);
}
if (s->hd)
@@ -569,6 +653,7 @@ URLProtocol ff_http_protocol = {
.url_seek = http_seek,
.url_close = http_close,
.url_get_file_handle = http_get_file_handle,
+ .url_shutdown = http_shutdown,
.priv_data_size = sizeof(HTTPContext),
.priv_data_class = &http_context_class,
.flags = URL_PROTOCOL_FLAG_NETWORK,
@@ -583,6 +668,7 @@ URLProtocol ff_https_protocol = {
.url_seek = http_seek,
.url_close = http_close,
.url_get_file_handle = http_get_file_handle,
+ .url_shutdown = http_shutdown,
.priv_data_size = sizeof(HTTPContext),
.priv_data_class = &https_context_class,
.flags = URL_PROTOCOL_FLAG_NETWORK,
@@ -603,10 +689,11 @@ static int http_proxy_open(URLContext *h, const char *uri, int flags)
HTTPContext *s = h->priv_data;
char hostname[1024], hoststr[1024];
char auth[1024], pathbuf[1024], *path;
- char line[1024], lower_url[100];
+ char lower_url[100];
int port, ret = 0, attempts = 0;
HTTPAuthType cur_auth_type;
char *authstr;
+ int new_loc;
h->is_streamed = 1;
@@ -647,30 +734,19 @@ redo:
s->filesize = -1;
cur_auth_type = s->proxy_auth_state.auth_type;
- for (;;) {
- int new_loc;
- // Note: This uses buffering, potentially reading more than the
- // HTTP header. If tunneling a protocol where the server starts
- // the conversation, we might buffer part of that here, too.
- // Reading that requires using the proper ffurl_read() function
- // on this URLContext, not using the fd directly (as the tls
- // protocol does). This shouldn't be an issue for tls though,
- // since the client starts the conversation there, so there
- // is no extra data that we might buffer up here.
- if (http_get_line(s, line, sizeof(line)) < 0) {
- ret = AVERROR(EIO);
- goto fail;
- }
-
- av_dlog(h, "header='%s'\n", line);
+ /* Note: This uses buffering, potentially reading more than the
+ * HTTP header. If tunneling a protocol where the server starts
+ * the conversation, we might buffer part of that here, too.
+ * Reading that requires using the proper ffurl_read() function
+ * on this URLContext, not using the fd directly (as the tls
+ * protocol does). This shouldn't be an issue for tls though,
+ * since the client starts the conversation there, so there
+ * is no extra data that we might buffer up here.
+ */
+ ret = http_read_header(h, &new_loc);
+ if (ret < 0)
+ goto fail;
- ret = process_line(h, line, s->line_count, &new_loc);
- if (ret < 0)
- goto fail;
- if (ret == 0)
- break;
- s->line_count++;
- }
attempts++;
if (s->http_code == 407 &&
(cur_auth_type == HTTP_AUTH_NONE || s->proxy_auth_state.stale) &&
diff --git a/libavformat/http.h b/libavformat/http.h
index 8dfb192..3579ad7 100644
--- a/libavformat/http.h
+++ b/libavformat/http.h
@@ -35,4 +35,14 @@
*/
void ff_http_init_auth_state(URLContext *dest, const URLContext *src);
+/**
+ * Send a new HTTP request, reusing the old connection.
+ *
+ * @param h pointer to the ressource
+ * @param uri uri used to perform the request
+ * @return a negative value if an error condition occured, 0
+ * otherwise
+ */
+int ff_http_do_new_request(URLContext *h, const char *uri);
+
#endif /* AVFORMAT_HTTP_H */
diff --git a/libavformat/idroqdec.c b/libavformat/idroqdec.c
index 5c1528d..be3122e 100644
--- a/libavformat/idroqdec.c
+++ b/libavformat/idroqdec.c
@@ -217,7 +217,7 @@ static int roq_read_packet(AVFormatContext *s,
}
AVInputFormat ff_roq_demuxer = {
- .name = "RoQ",
+ .name = "roq",
.long_name = NULL_IF_CONFIG_SMALL("id RoQ format"),
.priv_data_size = sizeof(RoqDemuxContext),
.read_probe = roq_probe,
diff --git a/libavformat/idroqenc.c b/libavformat/idroqenc.c
index 266a731..394d16f 100644
--- a/libavformat/idroqenc.c
+++ b/libavformat/idroqenc.c
@@ -36,7 +36,7 @@ static int roq_write_header(struct AVFormatContext *s)
}
AVOutputFormat ff_roq_muxer = {
- .name = "RoQ",
+ .name = "roq",
.long_name = NULL_IF_CONFIG_SMALL("raw id RoQ format"),
.extensions = "roq",
.audio_codec = CODEC_ID_ROQ_DPCM,
diff --git a/libavformat/iff.c b/libavformat/iff.c
index 8ed6812..cde420e 100644
--- a/libavformat/iff.c
+++ b/libavformat/iff.c
@@ -281,7 +281,7 @@ static int iff_read_packet(AVFormatContext *s,
}
AVInputFormat ff_iff_demuxer = {
- .name = "IFF",
+ .name = "iff",
.long_name = NULL_IF_CONFIG_SMALL("Interchange File Format"),
.priv_data_size = sizeof(IffDemuxContext),
.read_probe = iff_probe,
diff --git a/libavformat/ilbc.c b/libavformat/ilbc.c
new file mode 100644
index 0000000..33aed77
--- /dev/null
+++ b/libavformat/ilbc.c
@@ -0,0 +1,141 @@
+/*
+ * iLBC storage file format
+ * Copyright (c) 2012 Martin Storsjo
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avformat.h"
+#include "internal.h"
+
+static const char mode20_header[] = "#!iLBC20\n";
+static const char mode30_header[] = "#!iLBC30\n";
+
+static int ilbc_write_header(AVFormatContext *s)
+{
+ AVIOContext *pb = s->pb;
+ AVCodecContext *enc;
+
+ if (s->nb_streams != 1) {
+ av_log(s, AV_LOG_ERROR, "Unsupported number of streams\n");
+ return AVERROR(EINVAL);
+ }
+ enc = s->streams[0]->codec;
+
+ if (enc->codec_id != CODEC_ID_ILBC) {
+ av_log(s, AV_LOG_ERROR, "Unsupported codec\n");
+ return AVERROR(EINVAL);
+ }
+
+ if (enc->block_align == 50) {
+ avio_write(pb, mode30_header, sizeof(mode30_header) - 1);
+ } else if (enc->block_align == 38) {
+ avio_write(pb, mode20_header, sizeof(mode20_header) - 1);
+ } else {
+ av_log(s, AV_LOG_ERROR, "Unsupported mode\n");
+ return AVERROR(EINVAL);
+ }
+ avio_flush(pb);
+ return 0;
+}
+
+static int ilbc_write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ avio_write(s->pb, pkt->data, pkt->size);
+ avio_flush(s->pb);
+ return 0;
+}
+
+static int ilbc_probe(AVProbeData *p)
+{
+ // Only check for "#!iLBC" which matches both formats
+ if (!memcmp(p->buf, mode20_header, 6))
+ return AVPROBE_SCORE_MAX;
+ else
+ return 0;
+}
+
+static int ilbc_read_header(AVFormatContext *s)
+{
+ AVIOContext *pb = s->pb;
+ AVStream *st;
+ uint8_t header[9];
+
+ avio_read(pb, header, 9);
+
+ st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+ st->codec->codec_id = CODEC_ID_ILBC;
+ st->codec->sample_rate = 8000;
+ st->codec->channels = 1;
+ st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->start_time = 0;
+ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+ if (!memcmp(header, mode20_header, sizeof(mode20_header) - 1)) {
+ st->codec->block_align = 38;
+ st->codec->bit_rate = 15200;
+ } else if (!memcmp(header, mode30_header, sizeof(mode30_header) - 1)) {
+ st->codec->block_align = 50;
+ st->codec->bit_rate = 13333;
+ } else {
+ av_log(s, AV_LOG_ERROR, "Unrecognized iLBC file header\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ return 0;
+}
+
+static int ilbc_read_packet(AVFormatContext *s,
+ AVPacket *pkt)
+{
+ AVCodecContext *enc = s->streams[0]->codec;
+ int ret;
+
+ if ((ret = av_new_packet(pkt, enc->block_align)) < 0)
+ return ret;
+
+ pkt->stream_index = 0;
+ pkt->pos = avio_tell(s->pb);
+ pkt->duration = enc->block_align == 38 ? 160 : 240;
+ if ((ret = avio_read(s->pb, pkt->data, enc->block_align)) != enc->block_align) {
+ av_free_packet(pkt);
+ return ret < 0 ? ret : AVERROR(EIO);
+ }
+
+ return 0;
+}
+
+AVInputFormat ff_ilbc_demuxer = {
+ .name = "ilbc",
+ .long_name = NULL_IF_CONFIG_SMALL("iLBC storage file format"),
+ .read_probe = ilbc_probe,
+ .read_header = ilbc_read_header,
+ .read_packet = ilbc_read_packet,
+ .flags = AVFMT_GENERIC_INDEX,
+};
+
+AVOutputFormat ff_ilbc_muxer = {
+ .name = "ilbc",
+ .long_name = NULL_IF_CONFIG_SMALL("iLBC storage file format"),
+ .mime_type = "audio/iLBC",
+ .extensions = "lbc",
+ .audio_codec = CODEC_ID_ILBC,
+ .write_header = ilbc_write_header,
+ .write_packet = ilbc_write_packet,
+ .flags = AVFMT_NOTIMESTAMPS,
+};
diff --git a/libavformat/img2dec.c b/libavformat/img2dec.c
index b4b9723..8f30cd5 100644
--- a/libavformat/img2dec.c
+++ b/libavformat/img2dec.c
@@ -40,6 +40,7 @@ typedef struct {
char *video_size; /**< Set by a private option. */
char *framerate; /**< Set by a private option. */
int loop;
+ int start_number;
} VideoDemuxData;
static const int sizes[][2] = {
@@ -70,13 +71,13 @@ static int infer_size(int *width_ptr, int *height_ptr, int size)
/* return -1 if no image found */
static int find_image_range(int *pfirst_index, int *plast_index,
- const char *path)
+ const char *path, int max_start)
{
char buf[1024];
int range, last_index, range1, first_index;
/* find the first image */
- for(first_index = 0; first_index < 5; first_index++) {
+ for (first_index = 0; first_index < max_start; first_index++) {
if (av_get_frame_filename(buf, sizeof(buf), path, first_index) < 0){
*pfirst_index =
*plast_index = 1;
@@ -182,7 +183,8 @@ static int read_header(AVFormatContext *s1)
}
if (!s->is_pipe) {
- if (find_image_range(&first_index, &last_index, s->path) < 0)
+ if (find_image_range(&first_index, &last_index, s->path,
+ FFMAX(s->start_number, 5)) < 0)
return AVERROR(ENOENT);
s->img_first = first_index;
s->img_last = last_index;
@@ -283,6 +285,7 @@ static const AVOption options[] = {
{ "video_size", "", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
{ "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC },
{ "loop", "", OFFSET(loop), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 1, DEC },
+ { "start_number", "first number in the sequence", OFFSET(start_number), AV_OPT_TYPE_INT, {.dbl = 1}, 1, INT_MAX, DEC },
{ NULL },
};
diff --git a/libavformat/img2enc.c b/libavformat/img2enc.c
index c825c2b..0f34857 100644
--- a/libavformat/img2enc.c
+++ b/libavformat/img2enc.c
@@ -26,8 +26,10 @@
#include "avformat.h"
#include "avio_internal.h"
#include "internal.h"
+#include "libavutil/opt.h"
typedef struct {
+ const AVClass *class; /**< Class for private options. */
int img_number;
int is_pipe;
char path[1024];
@@ -37,7 +39,6 @@ static int write_header(AVFormatContext *s)
{
VideoMuxData *img = s->priv_data;
- img->img_number = 1;
av_strlcpy(img->path, s->filename, sizeof(img->path));
/* find format */
@@ -124,7 +125,21 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
return 0;
}
+#define OFFSET(x) offsetof(VideoMuxData, x)
+#define ENC AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption muxoptions[] = {
+ { "start_number", "first number in the sequence", OFFSET(img_number), AV_OPT_TYPE_INT, {.dbl = 1}, 1, INT_MAX, ENC },
+ { NULL },
+};
+
#if CONFIG_IMAGE2_MUXER
+static const AVClass img2mux_class = {
+ .class_name = "image2 muxer",
+ .item_name = av_default_item_name,
+ .option = muxoptions,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVOutputFormat ff_image2_muxer = {
.name = "image2",
.long_name = NULL_IF_CONFIG_SMALL("image2 sequence"),
@@ -135,7 +150,8 @@ AVOutputFormat ff_image2_muxer = {
.video_codec = CODEC_ID_MJPEG,
.write_header = write_header,
.write_packet = write_packet,
- .flags = AVFMT_NOTIMESTAMPS | AVFMT_NODIMENSIONS | AVFMT_NOFILE
+ .flags = AVFMT_NOTIMESTAMPS | AVFMT_NODIMENSIONS | AVFMT_NOFILE,
+ .priv_class = &img2mux_class,
};
#endif
#if CONFIG_IMAGE2PIPE_MUXER
diff --git a/libavformat/isom.c b/libavformat/isom.c
index 3ea8ce1..e5cde5a 100644
--- a/libavformat/isom.c
+++ b/libavformat/isom.c
@@ -244,6 +244,7 @@ const AVCodecTag ff_codec_movaudio_tags[] = {
{ CODEC_ID_DVAUDIO, MKTAG('v', 'd', 'v', 'a') },
{ CODEC_ID_DVAUDIO, MKTAG('d', 'v', 'c', 'a') },
{ CODEC_ID_GSM, MKTAG('a', 'g', 's', 'm') },
+ { CODEC_ID_ILBC, MKTAG('i', 'l', 'b', 'c') },
{ CODEC_ID_MACE3, MKTAG('M', 'A', 'C', '3') },
{ CODEC_ID_MACE6, MKTAG('M', 'A', 'C', '6') },
{ CODEC_ID_MP1, MKTAG('.', 'm', 'p', '1') },
diff --git a/libavformat/iss.c b/libavformat/iss.c
index 8c297f8..b9848d3 100644
--- a/libavformat/iss.c
+++ b/libavformat/iss.c
@@ -123,7 +123,7 @@ static int iss_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_iss_demuxer = {
- .name = "ISS",
+ .name = "iss",
.long_name = NULL_IF_CONFIG_SMALL("Funcom ISS format"),
.priv_data_size = sizeof(IssDemuxContext),
.read_probe = iss_probe,
diff --git a/libavformat/ivfdec.c b/libavformat/ivfdec.c
index 9482fc2..b3555f4 100644
--- a/libavformat/ivfdec.c
+++ b/libavformat/ivfdec.c
@@ -87,5 +87,5 @@ AVInputFormat ff_ivf_demuxer = {
.read_header = read_header,
.read_packet = read_packet,
.flags = AVFMT_GENERIC_INDEX,
- .codec_tag = (const AVCodecTag*[]){ ff_codec_bmp_tags, 0 },
+ .codec_tag = (const AVCodecTag* const []){ ff_codec_bmp_tags, 0 },
};
diff --git a/libavformat/libnut.c b/libavformat/libnut.c
deleted file mode 100644
index 4295d67..0000000
--- a/libavformat/libnut.c
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * NUT (de)muxing via libnut
- * copyright (c) 2006 Oded Shimon <ods15 at ods15.dyndns.org>
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * NUT demuxing and muxing via libnut.
- * @author Oded Shimon <ods15 at ods15.dyndns.org>
- */
-
-#include "avformat.h"
-#include "internal.h"
-#include "riff.h"
-#include <libnut.h>
-
-#define ID_STRING "nut/multimedia container"
-#define ID_LENGTH (strlen(ID_STRING) + 1)
-
-typedef struct {
- nut_context_tt * nut;
- nut_stream_header_tt * s;
-} NUTContext;
-
-static const AVCodecTag nut_tags[] = {
- { CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') },
- { CODEC_ID_MP3, MKTAG('m', 'p', '3', ' ') },
- { CODEC_ID_VORBIS, MKTAG('v', 'r', 'b', 's') },
- { 0, 0 },
-};
-
-#if CONFIG_LIBNUT_MUXER
-static int av_write(void * h, size_t len, const uint8_t * buf) {
- AVIOContext * bc = h;
- avio_write(bc, buf, len);
- //avio_flush(bc);
- return len;
-}
-
-static int nut_write_header(AVFormatContext * avf) {
- NUTContext * priv = avf->priv_data;
- AVIOContext * bc = avf->pb;
- nut_muxer_opts_tt mopts = {
- .output = {
- .priv = bc,
- .write = av_write,
- },
- .alloc = { av_malloc, av_realloc, av_free },
- .write_index = 1,
- .realtime_stream = 0,
- .max_distance = 32768,
- .fti = NULL,
- };
- nut_stream_header_tt * s;
- int i;
-
- priv->s = s = av_mallocz((avf->nb_streams + 1) * sizeof*s);
-
- for (i = 0; i < avf->nb_streams; i++) {
- AVCodecContext * codec = avf->streams[i]->codec;
- int j;
- int fourcc = 0;
- int num, denom, ssize;
-
- s[i].type = codec->codec_type == AVMEDIA_TYPE_VIDEO ? NUT_VIDEO_CLASS : NUT_AUDIO_CLASS;
-
- if (codec->codec_tag) fourcc = codec->codec_tag;
- else fourcc = ff_codec_get_tag(nut_tags, codec->codec_id);
-
- if (!fourcc) {
- if (codec->codec_type == AVMEDIA_TYPE_VIDEO) fourcc = ff_codec_get_tag(ff_codec_bmp_tags, codec->codec_id);
- if (codec->codec_type == AVMEDIA_TYPE_AUDIO) fourcc = ff_codec_get_tag(ff_codec_wav_tags, codec->codec_id);
- }
-
- s[i].fourcc_len = 4;
- s[i].fourcc = av_malloc(s[i].fourcc_len);
- for (j = 0; j < s[i].fourcc_len; j++) s[i].fourcc[j] = (fourcc >> (j*8)) & 0xFF;
-
- ff_parse_specific_params(codec, &num, &ssize, &denom);
- avpriv_set_pts_info(avf->streams[i], 60, denom, num);
-
- s[i].time_base.num = denom;
- s[i].time_base.den = num;
-
- s[i].fixed_fps = 0;
- s[i].decode_delay = codec->has_b_frames;
- s[i].codec_specific_len = codec->extradata_size;
- s[i].codec_specific = codec->extradata;
-
- if (codec->codec_type == AVMEDIA_TYPE_VIDEO) {
- s[i].width = codec->width;
- s[i].height = codec->height;
- s[i].sample_width = 0;
- s[i].sample_height = 0;
- s[i].colorspace_type = 0;
- } else {
- s[i].samplerate_num = codec->sample_rate;
- s[i].samplerate_denom = 1;
- s[i].channel_count = codec->channels;
- }
- }
-
- s[avf->nb_streams].type = -1;
- priv->nut = nut_muxer_init(&mopts, s, NULL);
-
- return 0;
-}
-
-static int nut_write_packet(AVFormatContext * avf, AVPacket * pkt) {
- NUTContext * priv = avf->priv_data;
- nut_packet_tt p;
-
- p.len = pkt->size;
- p.stream = pkt->stream_index;
- p.pts = pkt->pts;
- p.flags = pkt->flags & AV_PKT_FLAG_KEY ? NUT_FLAG_KEY : 0;
- p.next_pts = 0;
-
- nut_write_frame_reorder(priv->nut, &p, pkt->data);
-
- return 0;
-}
-
-static int nut_write_trailer(AVFormatContext * avf) {
- AVIOContext * bc = avf->pb;
- NUTContext * priv = avf->priv_data;
- int i;
-
- nut_muxer_uninit_reorder(priv->nut);
- avio_flush(bc);
-
- for(i = 0; priv->s[i].type != -1; i++ ) av_freep(&priv->s[i].fourcc);
- av_freep(&priv->s);
-
- return 0;
-}
-
-AVOutputFormat ff_libnut_muxer = {
- .name = "libnut",
- .long_name = "nut format",
- .mime_type = "video/x-nut",
- .extensions = "nut",
- .priv_data_size = sizeof(NUTContext),
- .audio_codec = CODEC_ID_VORBIS,
- .video_codec = CODEC_ID_MPEG4,
- .write_header = nut_write_header,
- .write_packet = nut_write_packet,
- .write_trailer = nut_write_trailer,
- .flags = AVFMT_GLOBALHEADER,
-};
-#endif /* CONFIG_LIBNUT_MUXER */
-
-static int nut_probe(AVProbeData *p) {
- if (!memcmp(p->buf, ID_STRING, ID_LENGTH)) return AVPROBE_SCORE_MAX;
-
- return 0;
-}
-
-static size_t av_read(void * h, size_t len, uint8_t * buf) {
- AVIOContext * bc = h;
- return avio_read(bc, buf, len);
-}
-
-static off_t av_seek(void * h, long long pos, int whence) {
- AVIOContext * bc = h;
- if (whence == SEEK_END) {
- pos = avio_size(bc) + pos;
- whence = SEEK_SET;
- }
- return avio_seek(bc, pos, whence);
-}
-
-static int nut_read_header(AVFormatContext * avf) {
- NUTContext * priv = avf->priv_data;
- AVIOContext * bc = avf->pb;
- nut_demuxer_opts_tt dopts = {
- .input = {
- .priv = bc,
- .seek = av_seek,
- .read = av_read,
- .eof = NULL,
- .file_pos = 0,
- },
- .alloc = { av_malloc, av_realloc, av_free },
- .read_index = 1,
- .cache_syncpoints = 1,
- };
- nut_context_tt * nut = priv->nut = nut_demuxer_init(&dopts);
- nut_stream_header_tt * s;
- int ret, i;
-
- if ((ret = nut_read_headers(nut, &s, NULL))) {
- av_log(avf, AV_LOG_ERROR, " NUT error: %s\n", nut_error(ret));
- nut_demuxer_uninit(nut);
- return -1;
- }
-
- priv->s = s;
-
- for (i = 0; s[i].type != -1 && i < 2; i++) {
- AVStream * st = avformat_new_stream(avf, NULL);
- int j;
-
- for (j = 0; j < s[i].fourcc_len && j < 8; j++) st->codec->codec_tag |= s[i].fourcc[j]<<(j*8);
-
- st->codec->has_b_frames = s[i].decode_delay;
-
- st->codec->extradata_size = s[i].codec_specific_len;
- if (st->codec->extradata_size) {
- st->codec->extradata = av_mallocz(st->codec->extradata_size);
- memcpy(st->codec->extradata, s[i].codec_specific, st->codec->extradata_size);
- }
-
- avpriv_set_pts_info(avf->streams[i], 60, s[i].time_base.num, s[i].time_base.den);
- st->start_time = 0;
- st->duration = s[i].max_pts;
-
- st->codec->codec_id = ff_codec_get_id(nut_tags, st->codec->codec_tag);
-
- switch(s[i].type) {
- case NUT_AUDIO_CLASS:
- st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
- if (st->codec->codec_id == CODEC_ID_NONE) st->codec->codec_id = ff_codec_get_id(ff_codec_wav_tags, st->codec->codec_tag);
-
- st->codec->channels = s[i].channel_count;
- st->codec->sample_rate = s[i].samplerate_num / s[i].samplerate_denom;
- break;
- case NUT_VIDEO_CLASS:
- st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- if (st->codec->codec_id == CODEC_ID_NONE) st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, st->codec->codec_tag);
-
- st->codec->width = s[i].width;
- st->codec->height = s[i].height;
- st->sample_aspect_ratio.num = s[i].sample_width;
- st->sample_aspect_ratio.den = s[i].sample_height;
- break;
- }
- if (st->codec->codec_id == CODEC_ID_NONE) av_log(avf, AV_LOG_ERROR, "Unknown codec?!\n");
- }
-
- return 0;
-}
-
-static int nut_read_packet(AVFormatContext * avf, AVPacket * pkt) {
- NUTContext * priv = avf->priv_data;
- nut_packet_tt pd;
- int ret;
-
- ret = nut_read_next_packet(priv->nut, &pd);
-
- if (ret || av_new_packet(pkt, pd.len) < 0) {
- if (ret != NUT_ERR_EOF)
- av_log(avf, AV_LOG_ERROR, " NUT error: %s\n", nut_error(ret));
- return -1;
- }
-
- if (pd.flags & NUT_FLAG_KEY) pkt->flags |= AV_PKT_FLAG_KEY;
- pkt->pts = pd.pts;
- pkt->stream_index = pd.stream;
- pkt->pos = avio_tell(avf->pb);
-
- ret = nut_read_frame(priv->nut, &pd.len, pkt->data);
-
- return ret;
-}
-
-static int nut_read_seek(AVFormatContext * avf, int stream_index, int64_t target_ts, int flags) {
- NUTContext * priv = avf->priv_data;
- int active_streams[] = { stream_index, -1 };
- double time_pos = target_ts * priv->s[stream_index].time_base.num / (double)priv->s[stream_index].time_base.den;
-
- if (nut_seek(priv->nut, time_pos, 2*!(flags & AVSEEK_FLAG_BACKWARD), active_streams)) return -1;
-
- return 0;
-}
-
-static int nut_read_close(AVFormatContext *s) {
- NUTContext * priv = s->priv_data;
-
- nut_demuxer_uninit(priv->nut);
-
- return 0;
-}
-
-AVInputFormat ff_libnut_demuxer = {
- .name = "libnut",
- .long_name = NULL_IF_CONFIG_SMALL("NUT format"),
- .priv_data_size = sizeof(NUTContext),
- .read_probe = nut_probe,
- .read_header = nut_read_header,
- .read_packet = nut_read_packet,
- .read_close = nut_read_close,
- .read_seek = nut_read_seek,
- .extensions = "nut",
-};
diff --git a/libavformat/librtmp.c b/libavformat/librtmp.c
index 8883bbc..7133bd6 100644
--- a/libavformat/librtmp.c
+++ b/libavformat/librtmp.c
@@ -24,13 +24,22 @@
* RTMP protocol based on http://rtmpdump.mplayerhq.hu/ librtmp
*/
+#include "libavutil/avstring.h"
#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
#include "avformat.h"
#include "url.h"
#include <librtmp/rtmp.h>
#include <librtmp/log.h>
+typedef struct LibRTMPContext {
+ const AVClass *class;
+ RTMP rtmp;
+ char *app;
+ char *playpath;
+} LibRTMPContext;
+
static void rtmp_log(int level, const char *fmt, va_list args)
{
switch (level) {
@@ -49,7 +58,8 @@ static void rtmp_log(int level, const char *fmt, va_list args)
static int rtmp_close(URLContext *s)
{
- RTMP *r = s->priv_data;
+ LibRTMPContext *ctx = s->priv_data;
+ RTMP *r = &ctx->rtmp;
RTMP_Close(r);
return 0;
@@ -69,24 +79,45 @@ static int rtmp_close(URLContext *s)
*/
static int rtmp_open(URLContext *s, const char *uri, int flags)
{
- RTMP *r = s->priv_data;
- int rc;
+ LibRTMPContext *ctx = s->priv_data;
+ RTMP *r = &ctx->rtmp;
+ int rc = 0, level;
+ char *filename = s->filename;
switch (av_log_get_level()) {
default:
- case AV_LOG_FATAL: rc = RTMP_LOGCRIT; break;
- case AV_LOG_ERROR: rc = RTMP_LOGERROR; break;
- case AV_LOG_WARNING: rc = RTMP_LOGWARNING; break;
- case AV_LOG_INFO: rc = RTMP_LOGINFO; break;
- case AV_LOG_VERBOSE: rc = RTMP_LOGDEBUG; break;
- case AV_LOG_DEBUG: rc = RTMP_LOGDEBUG2; break;
+ case AV_LOG_FATAL: level = RTMP_LOGCRIT; break;
+ case AV_LOG_ERROR: level = RTMP_LOGERROR; break;
+ case AV_LOG_WARNING: level = RTMP_LOGWARNING; break;
+ case AV_LOG_INFO: level = RTMP_LOGINFO; break;
+ case AV_LOG_VERBOSE: level = RTMP_LOGDEBUG; break;
+ case AV_LOG_DEBUG: level = RTMP_LOGDEBUG2; break;
}
- RTMP_LogSetLevel(rc);
+ RTMP_LogSetLevel(level);
RTMP_LogSetCallback(rtmp_log);
+ if (ctx->app || ctx->playpath) {
+ int len = strlen(s->filename) + 1;
+ if (ctx->app) len += strlen(ctx->app) + sizeof(" app=");
+ if (ctx->playpath) len += strlen(ctx->playpath) + sizeof(" playpath=");
+
+ if (!(filename = av_malloc(len)))
+ return AVERROR(ENOMEM);
+
+ av_strlcpy(filename, s->filename, len);
+ if (ctx->app) {
+ av_strlcat(filename, " app=", len);
+ av_strlcat(filename, ctx->app, len);
+ }
+ if (ctx->playpath) {
+ av_strlcat(filename, " playpath=", len);
+ av_strlcat(filename, ctx->playpath, len);
+ }
+ }
+
RTMP_Init(r);
- if (!RTMP_SetupURL(r, s->filename)) {
- rc = -1;
+ if (!RTMP_SetupURL(r, filename)) {
+ rc = AVERROR_UNKNOWN;
goto fail;
}
@@ -94,43 +125,49 @@ static int rtmp_open(URLContext *s, const char *uri, int flags)
RTMP_EnableWrite(r);
if (!RTMP_Connect(r, NULL) || !RTMP_ConnectStream(r, 0)) {
- rc = -1;
+ rc = AVERROR_UNKNOWN;
goto fail;
}
s->is_streamed = 1;
- return 0;
+ rc = 0;
fail:
+ if (filename != s->filename)
+ av_freep(&filename);
return rc;
}
static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
{
- RTMP *r = s->priv_data;
+ LibRTMPContext *ctx = s->priv_data;
+ RTMP *r = &ctx->rtmp;
return RTMP_Write(r, buf, size);
}
static int rtmp_read(URLContext *s, uint8_t *buf, int size)
{
- RTMP *r = s->priv_data;
+ LibRTMPContext *ctx = s->priv_data;
+ RTMP *r = &ctx->rtmp;
return RTMP_Read(r, buf, size);
}
static int rtmp_read_pause(URLContext *s, int pause)
{
- RTMP *r = s->priv_data;
+ LibRTMPContext *ctx = s->priv_data;
+ RTMP *r = &ctx->rtmp;
if (!RTMP_Pause(r, pause))
- return -1;
+ return AVERROR_UNKNOWN;
return 0;
}
static int64_t rtmp_read_seek(URLContext *s, int stream_index,
int64_t timestamp, int flags)
{
- RTMP *r = s->priv_data;
+ LibRTMPContext *ctx = s->priv_data;
+ RTMP *r = &ctx->rtmp;
if (flags & AVSEEK_FLAG_BYTE)
return AVERROR(ENOSYS);
@@ -141,17 +178,36 @@ static int64_t rtmp_read_seek(URLContext *s, int stream_index,
flags & AVSEEK_FLAG_BACKWARD ? AV_ROUND_DOWN : AV_ROUND_UP);
if (!RTMP_SendSeek(r, timestamp))
- return -1;
+ return AVERROR_UNKNOWN;
return timestamp;
}
static int rtmp_get_file_handle(URLContext *s)
{
- RTMP *r = s->priv_data;
+ LibRTMPContext *ctx = s->priv_data;
+ RTMP *r = &ctx->rtmp;
return RTMP_Socket(r);
}
+#define OFFSET(x) offsetof(LibRTMPContext, x)
+#define DEC AV_OPT_FLAG_DECODING_PARAM
+#define ENC AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ {"rtmp_app", "Name of application to connect to on the RTMP server", OFFSET(app), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
+ {"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
+ { NULL },
+};
+
+#define RTMP_CLASS(flavor)\
+static const AVClass lib ## flavor ## _class = {\
+ .class_name = "lib" #flavor " protocol",\
+ .item_name = av_default_item_name,\
+ .option = options,\
+ .version = LIBAVUTIL_VERSION_INT,\
+};
+
+RTMP_CLASS(rtmp)
URLProtocol ff_librtmp_protocol = {
.name = "rtmp",
.url_open = rtmp_open,
@@ -161,10 +217,12 @@ URLProtocol ff_librtmp_protocol = {
.url_read_pause = rtmp_read_pause,
.url_read_seek = rtmp_read_seek,
.url_get_file_handle = rtmp_get_file_handle,
- .priv_data_size = sizeof(RTMP),
+ .priv_data_size = sizeof(LibRTMPContext),
+ .priv_data_class = &librtmp_class,
.flags = URL_PROTOCOL_FLAG_NETWORK,
};
+RTMP_CLASS(rtmpt)
URLProtocol ff_librtmpt_protocol = {
.name = "rtmpt",
.url_open = rtmp_open,
@@ -174,10 +232,12 @@ URLProtocol ff_librtmpt_protocol = {
.url_read_pause = rtmp_read_pause,
.url_read_seek = rtmp_read_seek,
.url_get_file_handle = rtmp_get_file_handle,
- .priv_data_size = sizeof(RTMP),
+ .priv_data_size = sizeof(LibRTMPContext),
+ .priv_data_class = &librtmpt_class,
.flags = URL_PROTOCOL_FLAG_NETWORK,
};
+RTMP_CLASS(rtmpe)
URLProtocol ff_librtmpe_protocol = {
.name = "rtmpe",
.url_open = rtmp_open,
@@ -187,10 +247,12 @@ URLProtocol ff_librtmpe_protocol = {
.url_read_pause = rtmp_read_pause,
.url_read_seek = rtmp_read_seek,
.url_get_file_handle = rtmp_get_file_handle,
- .priv_data_size = sizeof(RTMP),
+ .priv_data_size = sizeof(LibRTMPContext),
+ .priv_data_class = &librtmpe_class,
.flags = URL_PROTOCOL_FLAG_NETWORK,
};
+RTMP_CLASS(rtmpte)
URLProtocol ff_librtmpte_protocol = {
.name = "rtmpte",
.url_open = rtmp_open,
@@ -200,10 +262,12 @@ URLProtocol ff_librtmpte_protocol = {
.url_read_pause = rtmp_read_pause,
.url_read_seek = rtmp_read_seek,
.url_get_file_handle = rtmp_get_file_handle,
- .priv_data_size = sizeof(RTMP),
+ .priv_data_size = sizeof(LibRTMPContext),
+ .priv_data_class = &librtmpte_class,
.flags = URL_PROTOCOL_FLAG_NETWORK,
};
+RTMP_CLASS(rtmps)
URLProtocol ff_librtmps_protocol = {
.name = "rtmps",
.url_open = rtmp_open,
@@ -213,6 +277,7 @@ URLProtocol ff_librtmps_protocol = {
.url_read_pause = rtmp_read_pause,
.url_read_seek = rtmp_read_seek,
.url_get_file_handle = rtmp_get_file_handle,
- .priv_data_size = sizeof(RTMP),
+ .priv_data_size = sizeof(LibRTMPContext),
+ .priv_data_class = &librtmps_class,
.flags = URL_PROTOCOL_FLAG_NETWORK,
};
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index e45cfb0..3b78ae3 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -1717,7 +1717,7 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
if ((n = matroska_ebmlnum_uint(matroska, data, size, &num)) < 0) {
av_log(matroska->ctx, AV_LOG_ERROR, "EBML block data error\n");
- return res;
+ return n;
}
data += n;
size -= n;
@@ -2069,6 +2069,11 @@ static int matroska_read_packet(AVFormatContext *s, AVPacket *pkt)
ret = matroska_parse_cluster(matroska);
}
+ if (ret == AVERROR_INVALIDDATA) {
+ pkt->flags |= AV_PKT_FLAG_CORRUPT;
+ return 0;
+ }
+
return ret;
}
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index 9334b52..61a91d7 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -1305,7 +1305,8 @@ AVOutputFormat ff_matroska_muxer = {
.write_header = mkv_write_header,
.write_packet = mkv_write_packet,
.write_trailer = mkv_write_trailer,
- .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
+ .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS |
+ AVFMT_TS_NONSTRICT,
.codec_tag = (const AVCodecTag* const []){
ff_codec_bmp_tags, ff_codec_wav_tags, 0
},
@@ -1326,7 +1327,8 @@ AVOutputFormat ff_webm_muxer = {
.write_header = mkv_write_header,
.write_packet = mkv_write_packet,
.write_trailer = mkv_write_trailer,
- .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
+ .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS |
+ AVFMT_TS_NONSTRICT,
};
#endif
@@ -1346,7 +1348,7 @@ AVOutputFormat ff_matroska_audio_muxer = {
.write_header = mkv_write_header,
.write_packet = mkv_write_packet,
.write_trailer = mkv_write_trailer,
- .flags = AVFMT_GLOBALHEADER,
+ .flags = AVFMT_GLOBALHEADER | AVFMT_TS_NONSTRICT,
.codec_tag = (const AVCodecTag* const []){ ff_codec_wav_tags, 0 },
};
#endif
diff --git a/libavformat/md5enc.c b/libavformat/md5enc.c
index 3fd5450..4e8db3c 100644
--- a/libavformat/md5enc.c
+++ b/libavformat/md5enc.c
@@ -106,6 +106,6 @@ AVOutputFormat ff_framemd5_muxer = {
.video_codec = CODEC_ID_RAWVIDEO,
.write_header = ff_framehash_write_header,
.write_packet = framemd5_write_packet,
- .flags = AVFMT_VARIABLE_FPS,
+ .flags = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT,
};
#endif
diff --git a/libavformat/mmst.c b/libavformat/mmst.c
index 93ad073..4b96f5d 100644
--- a/libavformat/mmst.c
+++ b/libavformat/mmst.c
@@ -144,7 +144,7 @@ static int send_command_packet(MMSTContext *mmst)
av_log(NULL, AV_LOG_ERROR,
"Failed to write data of length %d: %d (%s)\n",
exact_length, write_result,
- write_result < 0 ? strerror(write_result) :
+ write_result < 0 ? strerror(AVUNERROR(write_result)) :
"The server closed the connection");
return AVERROR(EIO);
}
@@ -246,7 +246,7 @@ static MMSSCPacketType get_tcp_server_response(MMSTContext *mmst)
if(read_result < 0) {
av_log(NULL, AV_LOG_ERROR,
"Error reading packet header: %d (%s)\n",
- read_result, strerror(read_result));
+ read_result, strerror(AVUNERROR(read_result)));
packet_type = SC_PKT_CANCEL;
} else {
av_log(NULL, AV_LOG_ERROR,
@@ -266,7 +266,7 @@ static MMSSCPacketType get_tcp_server_response(MMSTContext *mmst)
av_log(NULL, AV_LOG_ERROR,
"Reading command packet length failed: %d (%s)\n",
read_result,
- read_result < 0 ? strerror(read_result) :
+ read_result < 0 ? strerror(AVUNERROR(read_result)) :
"The server closed the connection");
return read_result < 0 ? read_result : AVERROR(EIO);
}
@@ -287,7 +287,7 @@ static MMSSCPacketType get_tcp_server_response(MMSTContext *mmst)
av_log(NULL, AV_LOG_ERROR,
"Reading pkt data (length=%d) failed: %d (%s)\n",
length_remaining, read_result,
- read_result < 0 ? strerror(read_result) :
+ read_result < 0 ? strerror(AVUNERROR(read_result)) :
"The server closed the connection");
return read_result < 0 ? read_result : AVERROR(EIO);
}
@@ -324,7 +324,7 @@ static MMSSCPacketType get_tcp_server_response(MMSTContext *mmst)
av_log(NULL, AV_LOG_ERROR,
"Failed to read packet data of size %d: %d (%s)\n",
length_remaining, read_result,
- read_result < 0 ? strerror(read_result) :
+ read_result < 0 ? strerror(AVUNERROR(read_result)) :
"The server closed the connection");
return read_result < 0 ? read_result : AVERROR(EIO);
}
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 04deef6..647fd0e 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -25,6 +25,7 @@
//#define DEBUG
//#define MOV_EXPORT_ALL_METADATA
+#include "libavutil/attributes.h"
#include "libavutil/audioconvert.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/intfloat.h"
@@ -63,17 +64,18 @@ typedef struct MOVParseTableEntry {
int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
} MOVParseTableEntry;
-static const MOVParseTableEntry mov_default_parse_table[];
+static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
unsigned len, const char *key)
{
char buf[16];
- short current, total;
+ short current, total = 0;
avio_rb16(pb); // unknown
current = avio_rb16(pb);
- total = avio_rb16(pb);
+ if (len >= 6)
+ total = avio_rb16(pb);
if (!total)
snprintf(buf, sizeof(buf), "%d", current);
else
@@ -164,6 +166,48 @@ static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
return p - dst;
}
+static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
+{
+ AVPacket pkt;
+ AVStream *st;
+ MOVStreamContext *sc;
+ enum CodecID id;
+ int ret;
+
+ switch (type) {
+ case 0xd: id = CODEC_ID_MJPEG; break;
+ case 0xe: id = CODEC_ID_PNG; break;
+ case 0x1b: id = CODEC_ID_BMP; break;
+ default:
+ av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
+ avio_skip(pb, len);
+ return 0;
+ }
+
+ st = avformat_new_stream(c->fc, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+ sc = av_mallocz(sizeof(*sc));
+ if (!sc)
+ return AVERROR(ENOMEM);
+ st->priv_data = sc;
+
+ ret = av_get_packet(pb, &pkt, len);
+ if (ret < 0)
+ return ret;
+
+ st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
+
+ st->attached_pic = pkt;
+ st->attached_pic.stream_index = st->index;
+ st->attached_pic.flags |= AV_PKT_FLAG_KEY;
+
+ st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ st->codec->codec_id = id;
+
+ return 0;
+}
+
static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
#ifdef MOV_EXPORT_ALL_METADATA
@@ -171,8 +215,8 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
#endif
char str[1024], key2[16], language[4] = {0};
const char *key = NULL;
- uint16_t str_size, langcode = 0;
- uint32_t data_type = 0;
+ uint16_t langcode = 0;
+ uint32_t data_type = 0, str_size;
int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
switch (atom.type) {
@@ -222,6 +266,14 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
avio_rb32(pb); // unknown
str_size = data_size - 16;
atom.size -= 16;
+
+ if (atom.type == MKTAG('c', 'o', 'v', 'r')) {
+ int ret = mov_read_covr(c, pb, data_type, str_size);
+ if (ret < 0) {
+ av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
+ return ret;
+ }
+ }
} else return 0;
} else if (atom.size > 4 && key && !c->itunes_metadata) {
str_size = avio_rb16(pb); // string length
@@ -299,79 +351,6 @@ static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
}
-static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
-{
- int64_t total_size = 0;
- MOVAtom a;
- int i;
-
- if (atom.size < 0)
- atom.size = INT64_MAX;
- while (total_size + 8 < atom.size && !pb->eof_reached) {
- int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
- a.size = atom.size;
- a.type=0;
- if (atom.size >= 8) {
- a.size = avio_rb32(pb);
- a.type = avio_rl32(pb);
- }
- av_dlog(c->fc, "type: %08x '%.4s' parent:'%.4s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
- a.type, (char*)&a.type, (char*)&atom.type, a.size, total_size, atom.size);
- total_size += 8;
- if (a.size == 1) { /* 64 bit extended size */
- a.size = avio_rb64(pb) - 8;
- total_size += 8;
- }
- if (a.size == 0) {
- a.size = atom.size - total_size;
- if (a.size <= 8)
- break;
- }
- a.size -= 8;
- if (a.size < 0)
- break;
- a.size = FFMIN(a.size, atom.size - total_size);
-
- for (i = 0; mov_default_parse_table[i].type; i++)
- if (mov_default_parse_table[i].type == a.type) {
- parse = mov_default_parse_table[i].parse;
- break;
- }
-
- // container is user data
- if (!parse && (atom.type == MKTAG('u','d','t','a') ||
- atom.type == MKTAG('i','l','s','t')))
- parse = mov_read_udta_string;
-
- if (!parse) { /* skip leaf atoms data */
- avio_skip(pb, a.size);
- } else {
- int64_t start_pos = avio_tell(pb);
- int64_t left;
- int err = parse(c, pb, a);
- if (err < 0)
- return err;
- if (c->found_moov && c->found_mdat &&
- ((!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX) ||
- start_pos + a.size == avio_size(pb))) {
- if (!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX)
- c->next_root_atom = start_pos + a.size;
- return 0;
- }
- left = a.size - avio_tell(pb) + start_pos;
- if (left > 0) /* skip garbage at atom end */
- avio_skip(pb, left);
- }
-
- total_size += a.size;
- }
-
- if (total_size < atom.size && atom.size < 0x7ffff)
- avio_skip(pb, atom.size - total_size);
-
- return 0;
-}
-
static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
AVStream *st;
@@ -596,8 +575,9 @@ static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
AVStream *st;
- uint8_t version;
- uint32_t flags, layout_tag, bitmap, num_descr, label_mask;
+ uint8_t av_unused version;
+ uint32_t av_unused flags;
+ uint32_t layout_tag, bitmap, num_descr, label_mask;
int i;
if (c->fc->nb_streams < 1)
@@ -622,9 +602,9 @@ static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
label_mask = 0;
for (i = 0; i < num_descr; i++) {
- uint32_t label, cflags;
+ uint32_t label;
label = avio_rb32(pb); // mChannelLabel
- cflags = avio_rb32(pb); // mChannelFlags
+ avio_rb32(pb); // mChannelFlags
avio_rl32(pb); // mCoordinates[0]
avio_rl32(pb); // mCoordinates[1]
avio_rl32(pb); // mCoordinates[2]
@@ -992,7 +972,7 @@ static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return AVERROR_INVALIDDATA;
if (atom.size >= 10) {
- // Broken files created by legacy versions of Libav and FFmpeg will
+ // Broken files created by legacy versions of libavformat will
// wrap a whole fiel atom inside of a glbl atom.
unsigned size = avio_rb32(pb);
unsigned type = avio_rl32(pb);
@@ -1022,7 +1002,7 @@ static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return AVERROR_INVALIDDATA;
profile_level = avio_r8(pb);
- if (profile_level & 0xf0 != 0xc0)
+ if ((profile_level & 0xf0) != 0xc0)
return 0;
av_free(st->codec->extradata);
@@ -1454,6 +1434,7 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
case CODEC_ID_GSM:
case CODEC_ID_ADPCM_MS:
case CODEC_ID_ADPCM_IMA_WAV:
+ case CODEC_ID_ILBC:
st->codec->block_align = sc->bytes_per_frame;
break;
case CODEC_ID_ALAC:
@@ -1462,6 +1443,9 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
st->codec->sample_rate = AV_RB32(st->codec->extradata+32);
}
break;
+ case CODEC_ID_VC1:
+ st->need_parsing = AVSTREAM_PARSE_FULL;
+ break;
default:
break;
}
@@ -2049,9 +2033,6 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
#if CONFIG_H263_DECODER
case CODEC_ID_H263:
#endif
-#if CONFIG_H264_DECODER
- case CODEC_ID_H264:
-#endif
#if CONFIG_MPEG4_DECODER
case CODEC_ID_MPEG4:
#endif
@@ -2509,6 +2490,79 @@ static const MOVParseTableEntry mov_default_parse_table[] = {
{ 0, NULL }
};
+static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+ int64_t total_size = 0;
+ MOVAtom a;
+ int i;
+
+ if (atom.size < 0)
+ atom.size = INT64_MAX;
+ while (total_size + 8 < atom.size && !pb->eof_reached) {
+ int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
+ a.size = atom.size;
+ a.type=0;
+ if (atom.size >= 8) {
+ a.size = avio_rb32(pb);
+ a.type = avio_rl32(pb);
+ }
+ av_dlog(c->fc, "type: %08x '%.4s' parent:'%.4s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
+ a.type, (char*)&a.type, (char*)&atom.type, a.size, total_size, atom.size);
+ total_size += 8;
+ if (a.size == 1) { /* 64 bit extended size */
+ a.size = avio_rb64(pb) - 8;
+ total_size += 8;
+ }
+ if (a.size == 0) {
+ a.size = atom.size - total_size;
+ if (a.size <= 8)
+ break;
+ }
+ a.size -= 8;
+ if (a.size < 0)
+ break;
+ a.size = FFMIN(a.size, atom.size - total_size);
+
+ for (i = 0; mov_default_parse_table[i].type; i++)
+ if (mov_default_parse_table[i].type == a.type) {
+ parse = mov_default_parse_table[i].parse;
+ break;
+ }
+
+ // container is user data
+ if (!parse && (atom.type == MKTAG('u','d','t','a') ||
+ atom.type == MKTAG('i','l','s','t')))
+ parse = mov_read_udta_string;
+
+ if (!parse) { /* skip leaf atoms data */
+ avio_skip(pb, a.size);
+ } else {
+ int64_t start_pos = avio_tell(pb);
+ int64_t left;
+ int err = parse(c, pb, a);
+ if (err < 0)
+ return err;
+ if (c->found_moov && c->found_mdat &&
+ ((!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX) ||
+ start_pos + a.size == avio_size(pb))) {
+ if (!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX)
+ c->next_root_atom = start_pos + a.size;
+ return 0;
+ }
+ left = a.size - avio_tell(pb) + start_pos;
+ if (left > 0) /* skip garbage at atom end */
+ avio_skip(pb, left);
+ }
+
+ total_size += a.size;
+ }
+
+ if (total_size < atom.size && atom.size < 0x7ffff)
+ avio_skip(pb, atom.size - total_size);
+
+ return 0;
+}
+
static int mov_probe(AVProbeData *p)
{
unsigned int offset;
diff --git a/libavformat/mov_chan.c b/libavformat/mov_chan.c
index a0fbecc..edd5f6c 100644
--- a/libavformat/mov_chan.c
+++ b/libavformat/mov_chan.c
@@ -414,6 +414,20 @@ static const enum MovChannelLayoutTag mov_ch_layouts_alac[] = {
0,
};
+static const enum MovChannelLayoutTag mov_ch_layouts_wav[] = {
+ MOV_CH_LAYOUT_MONO,
+ MOV_CH_LAYOUT_STEREO,
+ MOV_CH_LAYOUT_MATRIXSTEREO,
+ MOV_CH_LAYOUT_MPEG_3_0_A,
+ MOV_CH_LAYOUT_QUADRAPHONIC,
+ MOV_CH_LAYOUT_MPEG_5_0_A,
+ MOV_CH_LAYOUT_MPEG_5_1_A,
+ MOV_CH_LAYOUT_MPEG_6_1_A,
+ MOV_CH_LAYOUT_MPEG_7_1_A,
+ MOV_CH_LAYOUT_MPEG_7_1_C,
+ MOV_CH_LAYOUT_SMPTE_DTV,
+};
+
static const struct {
enum CodecID codec_id;
const enum MovChannelLayoutTag *layouts;
@@ -421,6 +435,18 @@ static const struct {
{ CODEC_ID_AAC, mov_ch_layouts_aac },
{ CODEC_ID_AC3, mov_ch_layouts_ac3 },
{ CODEC_ID_ALAC, mov_ch_layouts_alac },
+ { CODEC_ID_PCM_U8, mov_ch_layouts_wav },
+ { CODEC_ID_PCM_S8, mov_ch_layouts_wav },
+ { CODEC_ID_PCM_S16LE, mov_ch_layouts_wav },
+ { CODEC_ID_PCM_S16BE, mov_ch_layouts_wav },
+ { CODEC_ID_PCM_S24LE, mov_ch_layouts_wav },
+ { CODEC_ID_PCM_S24BE, mov_ch_layouts_wav },
+ { CODEC_ID_PCM_S32LE, mov_ch_layouts_wav },
+ { CODEC_ID_PCM_S32BE, mov_ch_layouts_wav },
+ { CODEC_ID_PCM_F32LE, mov_ch_layouts_wav },
+ { CODEC_ID_PCM_F32BE, mov_ch_layouts_wav },
+ { CODEC_ID_PCM_F64LE, mov_ch_layouts_wav },
+ { CODEC_ID_PCM_F64BE, mov_ch_layouts_wav },
{ CODEC_ID_NONE, NULL },
};
@@ -492,7 +518,7 @@ uint32_t ff_mov_get_channel_layout_tag(enum CodecID codec_id,
/* find the layout tag for the specified channel layout */
for (i = 0; layouts[i] != 0; i++) {
- if (layouts[i] & 0xFFFF != channels)
+ if ((layouts[i] & 0xFFFF) != channels)
continue;
for (j = 0; layout_map[j].tag != 0; j++) {
if (layout_map[j].tag == layouts[i] &&
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 35c03dd..350ac95 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -264,14 +264,6 @@ static int mov_write_extradata_tag(AVIOContext *pb, MOVTrack *track)
return track->enc->extradata_size;
}
-static int mov_write_enda_tag(AVIOContext *pb)
-{
- avio_wb32(pb, 10);
- ffio_wfourcc(pb, "enda");
- avio_wb16(pb, 1); /* little endian */
- return 10;
-}
-
static void put_descr(AVIOContext *pb, int tag, unsigned int size)
{
int i = 3;
@@ -334,14 +326,6 @@ static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic
return update_size(pb, pos);
}
-static int mov_pcm_le_gt16(enum CodecID codec_id)
-{
- return codec_id == CODEC_ID_PCM_S24LE ||
- codec_id == CODEC_ID_PCM_S32LE ||
- codec_id == CODEC_ID_PCM_F32LE ||
- codec_id == CODEC_ID_PCM_F64LE;
-}
-
static int mov_write_ms_tag(AVIOContext *pb, MOVTrack *track)
{
int64_t pos = avio_tell(pb);
@@ -403,12 +387,9 @@ static int mov_write_wave_tag(AVIOContext *pb, MOVTrack *track)
ffio_wfourcc(pb, "mp4a");
avio_wb32(pb, 0);
mov_write_esds_tag(pb, track);
- } else if (mov_pcm_le_gt16(track->enc->codec_id)) {
- mov_write_enda_tag(pb);
} else if (track->enc->codec_id == CODEC_ID_AMR_NB) {
mov_write_amr_tag(pb, track);
} else if (track->enc->codec_id == CODEC_ID_AC3) {
- mov_write_chan_tag(pb, track);
mov_write_ac3_tag(pb, track);
} else if (track->enc->codec_id == CODEC_ID_ALAC) {
mov_write_extradata_tag(pb, track);
@@ -641,8 +622,7 @@ static int mov_write_audio_tag(AVIOContext *pb, MOVTrack *track)
track->enc->codec_id == CODEC_ID_AMR_NB ||
track->enc->codec_id == CODEC_ID_ALAC ||
track->enc->codec_id == CODEC_ID_ADPCM_MS ||
- track->enc->codec_id == CODEC_ID_ADPCM_IMA_WAV ||
- mov_pcm_le_gt16(track->enc->codec_id)))
+ track->enc->codec_id == CODEC_ID_ADPCM_IMA_WAV))
mov_write_wave_tag(pb, track);
else if(track->tag == MKTAG('m','p','4','a'))
mov_write_esds_tag(pb, track);
@@ -657,6 +637,9 @@ static int mov_write_audio_tag(AVIOContext *pb, MOVTrack *track)
else if (track->vos_len > 0)
mov_write_glbl_tag(pb, track);
+ if (track->mode == MODE_MOV && track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
+ mov_write_chan_tag(pb, track);
+
return update_size(pb, pos);
}
@@ -3112,7 +3095,8 @@ static int mov_write_header(AVFormatContext *s)
}else if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO){
track->timescale = st->codec->sample_rate;
/* set sample_size for PCM and ADPCM */
- if (av_get_bits_per_sample(st->codec->codec_id)) {
+ if (av_get_bits_per_sample(st->codec->codec_id) ||
+ st->codec->codec_id == CODEC_ID_ILBC) {
if (!st->codec->block_align) {
av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set\n", i);
goto error;
diff --git a/libavformat/movenchint.c b/libavformat/movenchint.c
index 579d040..5ef90f1 100644
--- a/libavformat/movenchint.c
+++ b/libavformat/movenchint.c
@@ -43,9 +43,9 @@ int ff_mov_init_hinting(AVFormatContext *s, int index, int src_index)
track->enc->codec_type = AVMEDIA_TYPE_DATA;
track->enc->codec_tag = track->tag;
- track->rtp_ctx = ff_rtp_chain_mux_open(s, src_st, NULL,
- RTP_MAX_PACKET_SIZE);
- if (!track->rtp_ctx)
+ ret = ff_rtp_chain_mux_open(&track->rtp_ctx, s, src_st, NULL,
+ RTP_MAX_PACKET_SIZE);
+ if (ret < 0)
goto fail;
/* Copy the RTP AVStream timebase back to the hint AVStream */
diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c
index d233209..3987520 100644
--- a/libavformat/mp3dec.c
+++ b/libavformat/mp3dec.c
@@ -63,11 +63,31 @@ static int mp3_read_probe(AVProbeData *p)
}
// keep this in sync with ac3 probe, both need to avoid
// issues with MPEG-files!
- if (first_frames>=4) return AVPROBE_SCORE_MAX/2+1;
- else if(max_frames>500)return AVPROBE_SCORE_MAX/2;
- else if(max_frames>=4) return AVPROBE_SCORE_MAX/4;
- else if(max_frames>=1) return 1;
- else return 0;
+ if (first_frames >= 4) return AVPROBE_SCORE_MAX / 2 + 1;
+
+ if (max_frames) {
+ int pes = 0, i;
+ unsigned int code = -1;
+
+#define VIDEO_ID 0x000001e0
+#define AUDIO_ID 0x000001c0
+ /* do a search for mpegps headers to be able to properly bias
+ * towards mpegps if we detect this stream as both. */
+ for (i = 0; i<p->buf_size; i++) {
+ code = (code << 8) + p->buf[i];
+ if ((code & 0xffffff00) == 0x100) {
+ if ((code & 0x1f0) == VIDEO_ID) pes++;
+ else if((code & 0x1e0) == AUDIO_ID) pes++;
+ }
+ }
+
+ if (pes)
+ max_frames = (max_frames + pes - 1) / pes;
+ }
+ if (max_frames > 500) return AVPROBE_SCORE_MAX / 2;
+ else if (max_frames >= 4) return AVPROBE_SCORE_MAX / 4;
+ else if (max_frames >= 1) return 1;
+ else return 0;
//mpegps_mp3_unrecognized_format.mpg has max_frames=3
}
diff --git a/libavformat/mpc8.c b/libavformat/mpc8.c
index 890404f..93848f4 100644
--- a/libavformat/mpc8.c
+++ b/libavformat/mpc8.c
@@ -21,6 +21,7 @@
#include "libavcodec/get_bits.h"
#include "libavcodec/unary.h"
+#include "apetag.h"
#include "avformat.h"
#include "internal.h"
#include "avio_internal.h"
@@ -240,6 +241,12 @@ static int mpc8_read_header(AVFormatContext *s)
st->duration = c->samples / (1152 << (st->codec->extradata[1]&3)*2);
size -= avio_tell(pb) - pos;
+ if (pb->seekable) {
+ int64_t pos = avio_tell(s->pb);
+ ff_ape_parse_tag(s);
+ avio_seek(s->pb, pos, SEEK_SET);
+ }
+
return 0;
}
diff --git a/libavformat/mpegenc.c b/libavformat/mpegenc.c
index bda8d83..7bcf289 100644
--- a/libavformat/mpegenc.c
+++ b/libavformat/mpegenc.c
@@ -832,6 +832,12 @@ static int flush_packet(AVFormatContext *ctx, int stream_index,
if (stuffing_size < 0)
stuffing_size = 0;
+
+ if (startcode == PRIVATE_STREAM_1 && id >= 0xa0) {
+ if (payload_size < av_fifo_size(stream->fifo))
+ stuffing_size += payload_size % stream->lpcm_align;
+ }
+
if (stuffing_size > 16) { /*<=16 for MPEG-1, <=32 for MPEG-2*/
pad_packet_bytes += stuffing_size;
packet_size -= stuffing_size;
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 2222f25..5b44c0e 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -19,8 +19,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-//#define USE_SYNCPOINT_SEARCH
-
#include "libavutil/crc.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/log.h"
@@ -534,6 +532,8 @@ static const StreamType HDMV_types[] = {
{ 0x82, AVMEDIA_TYPE_AUDIO, CODEC_ID_DTS },
{ 0x83, AVMEDIA_TYPE_AUDIO, CODEC_ID_TRUEHD },
{ 0x84, AVMEDIA_TYPE_AUDIO, CODEC_ID_EAC3 },
+ { 0x85, AVMEDIA_TYPE_AUDIO, CODEC_ID_DTS }, /* DTS HD */
+ { 0x86, AVMEDIA_TYPE_AUDIO, CODEC_ID_DTS }, /* DTS HD MASTER*/
{ 0x90, AVMEDIA_TYPE_SUBTITLE, CODEC_ID_HDMV_PGS_SUBTITLE },
{ 0 },
};
@@ -549,6 +549,10 @@ static const StreamType REGD_types[] = {
{ MKTAG('d','r','a','c'), AVMEDIA_TYPE_VIDEO, CODEC_ID_DIRAC },
{ MKTAG('A','C','-','3'), AVMEDIA_TYPE_AUDIO, CODEC_ID_AC3 },
{ MKTAG('B','S','S','D'), AVMEDIA_TYPE_AUDIO, CODEC_ID_S302M },
+ { MKTAG('D','T','S','1'), AVMEDIA_TYPE_AUDIO, CODEC_ID_DTS },
+ { MKTAG('D','T','S','2'), AVMEDIA_TYPE_AUDIO, CODEC_ID_DTS },
+ { MKTAG('D','T','S','3'), AVMEDIA_TYPE_AUDIO, CODEC_ID_DTS },
+ { MKTAG('V','C','-','1'), AVMEDIA_TYPE_VIDEO, CODEC_ID_VC1 },
{ 0 },
};
@@ -1819,7 +1823,6 @@ static int handle_packets(MpegTSContext *ts, int nb_packets)
static int mpegts_probe(AVProbeData *p)
{
-#if 1
const int size= p->buf_size;
int score, fec_score, dvhs_score;
int check_count= size / TS_FEC_PACKET_SIZE;
@@ -1838,13 +1841,6 @@ static int mpegts_probe(AVProbeData *p)
else if(dvhs_score > score && dvhs_score > fec_score && dvhs_score > 6) return AVPROBE_SCORE_MAX + dvhs_score - CHECK_COUNT;
else if( fec_score > 6) return AVPROBE_SCORE_MAX + fec_score - CHECK_COUNT;
else return -1;
-#else
- /* only use the extension for safer guess */
- if (av_match_ext(p->filename, "ts"))
- return AVPROBE_SCORE_MAX;
- else
- return 0;
-#endif
}
/* return the 90kHz PCR and the extension for the 27MHz PCR. return
@@ -2095,92 +2091,6 @@ static int64_t mpegts_get_pcr(AVFormatContext *s, int stream_index,
return timestamp;
}
-#ifdef USE_SYNCPOINT_SEARCH
-
-static int read_seek2(AVFormatContext *s,
- int stream_index,
- int64_t min_ts,
- int64_t target_ts,
- int64_t max_ts,
- int flags)
-{
- int64_t pos;
-
- int64_t ts_ret, ts_adj;
- int stream_index_gen_search;
- AVStream *st;
- AVParserState *backup;
-
- backup = ff_store_parser_state(s);
-
- // detect direction of seeking for search purposes
- flags |= (target_ts - min_ts > (uint64_t)(max_ts - target_ts)) ?
- AVSEEK_FLAG_BACKWARD : 0;
-
- if (flags & AVSEEK_FLAG_BYTE) {
- // use position directly, we will search starting from it
- pos = target_ts;
- } else {
- // search for some position with good timestamp match
- if (stream_index < 0) {
- stream_index_gen_search = av_find_default_stream_index(s);
- if (stream_index_gen_search < 0) {
- ff_restore_parser_state(s, backup);
- return -1;
- }
-
- st = s->streams[stream_index_gen_search];
- // timestamp for default must be expressed in AV_TIME_BASE units
- ts_adj = av_rescale(target_ts,
- st->time_base.den,
- AV_TIME_BASE * (int64_t)st->time_base.num);
- } else {
- ts_adj = target_ts;
- stream_index_gen_search = stream_index;
- }
- pos = ff_gen_search(s, stream_index_gen_search, ts_adj,
- 0, INT64_MAX, -1,
- AV_NOPTS_VALUE,
- AV_NOPTS_VALUE,
- flags, &ts_ret, mpegts_get_pcr);
- if (pos < 0) {
- ff_restore_parser_state(s, backup);
- return -1;
- }
- }
-
- // search for actual matching keyframe/starting position for all streams
- if (ff_gen_syncpoint_search(s, stream_index, pos,
- min_ts, target_ts, max_ts,
- flags) < 0) {
- ff_restore_parser_state(s, backup);
- return -1;
- }
-
- ff_free_parser_state(s, backup);
- return 0;
-}
-
-static int read_seek(AVFormatContext *s, int stream_index, int64_t target_ts, int flags)
-{
- int ret;
- if (flags & AVSEEK_FLAG_BACKWARD) {
- flags &= ~AVSEEK_FLAG_BACKWARD;
- ret = read_seek2(s, stream_index, INT64_MIN, target_ts, target_ts, flags);
- if (ret < 0)
- // for compatibility reasons, seek to the best-fitting timestamp
- ret = read_seek2(s, stream_index, INT64_MIN, target_ts, INT64_MAX, flags);
- } else {
- ret = read_seek2(s, stream_index, target_ts, target_ts, INT64_MAX, flags);
- if (ret < 0)
- // for compatibility reasons, seek to the best-fitting timestamp
- ret = read_seek2(s, stream_index, INT64_MIN, target_ts, INT64_MAX, flags);
- }
- return ret;
-}
-
-#else
-
static int read_seek(AVFormatContext *s, int stream_index, int64_t target_ts, int flags){
MpegTSContext *ts = s->priv_data;
uint8_t buf[TS_PACKET_SIZE];
@@ -2204,8 +2114,6 @@ static int read_seek(AVFormatContext *s, int stream_index, int64_t target_ts, in
return 0;
}
-#endif
-
/**************************************************************/
/* parsing functions - called from other demuxers such as RTP */
@@ -2270,9 +2178,6 @@ AVInputFormat ff_mpegts_demuxer = {
.read_seek = read_seek,
.read_timestamp = mpegts_get_pcr,
.flags = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT,
-#ifdef USE_SYNCPOINT_SEARCH
- .read_seek2 = read_seek2,
-#endif
};
AVInputFormat ff_mpegtsraw_demuxer = {
@@ -2285,8 +2190,5 @@ AVInputFormat ff_mpegtsraw_demuxer = {
.read_seek = read_seek,
.read_timestamp = mpegts_get_pcr,
.flags = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT,
-#ifdef USE_SYNCPOINT_SEARCH
- .read_seek2 = read_seek2,
-#endif
.priv_class = &mpegtsraw_class,
};
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index f60594a..7456931 100644
--- a/libavformat/mpegtsenc.c
+++ b/libavformat/mpegtsenc.c
@@ -28,7 +28,6 @@
#include "avformat.h"
#include "internal.h"
#include "mpegts.h"
-#include "adts.h"
#define PCR_TIME_BASE 27000000
@@ -77,7 +76,11 @@ typedef struct MpegTSWrite {
int pmt_start_pid;
int start_pid;
- int reemit_pat_pmt;
+ int reemit_pat_pmt; // backward compatibility
+
+#define MPEGTS_FLAG_REEMIT_PAT_PMT 0x01
+#define MPEGTS_FLAG_AAC_LATM 0x02
+ int flags;
} MpegTSWrite;
/* a PES packet header is generated every DEFAULT_PES_HEADER_FREQ packets */
@@ -98,6 +101,15 @@ static const AVOption options[] = {
{ "muxrate", NULL, offsetof(MpegTSWrite, mux_rate), AV_OPT_TYPE_INT, {1}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
{ "pes_payload_size", "Minimum PES packet payload in bytes",
offsetof(MpegTSWrite, pes_payload_size), AV_OPT_TYPE_INT, {DEFAULT_PES_PAYLOAD_SIZE}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
+ { "mpegts_flags", "MPEG-TS muxing flags", offsetof(MpegTSWrite, flags), AV_OPT_TYPE_FLAGS, {.dbl = 0}, 0, INT_MAX,
+ AV_OPT_FLAG_ENCODING_PARAM, "mpegts_flags" },
+ { "resend_headers", "Reemit PAT/PMT before writing the next packet",
+ 0, AV_OPT_TYPE_CONST, {.dbl = MPEGTS_FLAG_REEMIT_PAT_PMT}, 0, INT_MAX,
+ AV_OPT_FLAG_ENCODING_PARAM, "mpegts_flags"},
+ { "latm", "Use LATM packetization for AAC",
+ 0, AV_OPT_TYPE_CONST, {.dbl = MPEGTS_FLAG_AAC_LATM}, 0, INT_MAX,
+ AV_OPT_FLAG_ENCODING_PARAM, "mpegts_flags"},
+ // backward compatibility
{ "resend_headers", "Reemit PAT/PMT before writing the next packet",
offsetof(MpegTSWrite, reemit_pat_pmt), AV_OPT_TYPE_INT, {0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
{ NULL },
@@ -214,7 +226,7 @@ typedef struct MpegTSWriteStream {
int64_t payload_dts;
int payload_flags;
uint8_t *payload;
- ADTSContext *adts;
+ AVFormatContext *amux;
} MpegTSWriteStream;
static void mpegts_write_pat(AVFormatContext *s)
@@ -236,7 +248,7 @@ static void mpegts_write_pat(AVFormatContext *s)
static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
{
- // MpegTSWrite *ts = s->priv_data;
+ MpegTSWrite *ts = s->priv_data;
uint8_t data[1012], *q, *desc_length_ptr, *program_info_length_ptr;
int val, stream_type, i;
@@ -275,7 +287,7 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
stream_type = STREAM_TYPE_AUDIO_MPEG1;
break;
case CODEC_ID_AAC:
- stream_type = STREAM_TYPE_AUDIO_AAC;
+ stream_type = (ts->flags & MPEGTS_FLAG_AAC_LATM) ? STREAM_TYPE_AUDIO_AAC_LATM : STREAM_TYPE_AUDIO_AAC;
break;
case CODEC_ID_AAC_LATM:
stream_type = STREAM_TYPE_AUDIO_AAC_LATM;
@@ -459,6 +471,7 @@ static int mpegts_write_header(AVFormatContext *s)
const char *service_name;
const char *provider_name;
int *pids;
+ int ret;
if (s->max_delay < 0) /* Not set by the caller */
s->max_delay = 0;
@@ -499,12 +512,16 @@ static int mpegts_write_header(AVFormatContext *s)
st = s->streams[i];
avpriv_set_pts_info(st, 33, 1, 90000);
ts_st = av_mallocz(sizeof(MpegTSWriteStream));
- if (!ts_st)
+ if (!ts_st) {
+ ret = AVERROR(ENOMEM);
goto fail;
+ }
st->priv_data = ts_st;
ts_st->payload = av_mallocz(ts->pes_payload_size);
- if (!ts_st->payload)
+ if (!ts_st->payload) {
+ ret = AVERROR(ENOMEM);
goto fail;
+ }
ts_st->service = service;
/* MPEG pid values < 16 are reserved. Applications which set st->id in
* this range are assigned a calculated pid. */
@@ -514,15 +531,18 @@ static int mpegts_write_header(AVFormatContext *s)
ts_st->pid = st->id;
} else {
av_log(s, AV_LOG_ERROR, "Invalid stream id %d, must be less than 8191\n", st->id);
+ ret = AVERROR(EINVAL);
goto fail;
}
if (ts_st->pid == service->pmt.pid) {
av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", ts_st->pid);
+ ret = AVERROR(EINVAL);
goto fail;
}
for (j = 0; j < i; j++)
if (pids[j] == ts_st->pid) {
av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", ts_st->pid);
+ ret = AVERROR(EINVAL);
goto fail;
}
pids[i] = ts_st->pid;
@@ -537,12 +557,25 @@ static int mpegts_write_header(AVFormatContext *s)
pcr_st = st;
}
if (st->codec->codec_id == CODEC_ID_AAC &&
- st->codec->extradata_size > 0) {
- ts_st->adts = av_mallocz(sizeof(*ts_st->adts));
- if (!ts_st->adts)
+ st->codec->extradata_size > 0)
+ {
+ AVStream *ast;
+ ts_st->amux = avformat_alloc_context();
+ if (!ts_st->amux) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ ts_st->amux->oformat = av_guess_format((ts->flags & MPEGTS_FLAG_AAC_LATM) ? "latm" : "adts", NULL, NULL);
+ if (!ts_st->amux->oformat) {
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ ast = avformat_new_stream(ts_st->amux, NULL);
+ ret = avcodec_copy_context(ast->codec, st->codec);
+ if (ret != 0)
goto fail;
- if (ff_adts_decode_extradata(s, ts_st->adts, st->codec->extradata,
- st->codec->extradata_size) < 0)
+ ret = avformat_write_header(ts_st->amux, NULL);
+ if (ret < 0)
goto fail;
}
}
@@ -611,11 +644,14 @@ static int mpegts_write_header(AVFormatContext *s)
ts_st = st->priv_data;
if (ts_st) {
av_freep(&ts_st->payload);
- av_freep(&ts_st->adts);
+ if (ts_st->amux) {
+ avformat_free_context(ts_st->amux);
+ ts_st->amux = NULL;
+ }
}
av_freep(&st->priv_data);
}
- return -1;
+ return ret;
}
/* send SDT, PAT and PMT tables regulary */
@@ -947,9 +983,15 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
int64_t dts = AV_NOPTS_VALUE, pts = AV_NOPTS_VALUE;
if (ts->reemit_pat_pmt) {
+ av_log(s, AV_LOG_WARNING, "resend_headers option is deprecated, use -mpegts_flags resend_headers\n");
+ ts->reemit_pat_pmt = 0;
+ ts->flags |= MPEGTS_FLAG_REEMIT_PAT_PMT;
+ }
+
+ if (ts->flags & MPEGTS_FLAG_REEMIT_PAT_PMT) {
ts->pat_packet_count = ts->pat_packet_period - 1;
ts->sdt_packet_count = ts->sdt_packet_period - 1;
- ts->reemit_pat_pmt = 0;
+ ts->flags &= ~MPEGTS_FLAG_REEMIT_PAT_PMT;
}
if (pkt->pts != AV_NOPTS_VALUE)
@@ -959,7 +1001,7 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
if (ts_st->first_pts_check && pts == AV_NOPTS_VALUE) {
av_log(s, AV_LOG_ERROR, "first pts value must set\n");
- return -1;
+ return AVERROR(EINVAL);
}
ts_st->first_pts_check = 0;
@@ -970,7 +1012,7 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
if (pkt->size < 5 || AV_RB32(pkt->data) != 0x0000001) {
av_log(s, AV_LOG_ERROR, "H.264 bitstream malformed, "
"no startcode found, use -bsf h264_mp4toannexb\n");
- return -1;
+ return AVERROR(EINVAL);
}
do {
@@ -982,7 +1024,7 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
if ((state & 0x1f) != 9) { // AUD NAL
data = av_malloc(pkt->size+6);
if (!data)
- return -1;
+ return AVERROR(ENOMEM);
memcpy(data+6, pkt->data, pkt->size);
AV_WB32(data, 0x00000001);
data[4] = 0x09;
@@ -991,35 +1033,37 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
size = pkt->size+6;
}
} else if (st->codec->codec_id == CODEC_ID_AAC) {
- if (pkt->size < 2)
- return -1;
+ if (pkt->size < 2) {
+ av_log(s, AV_LOG_ERROR, "AAC packet too short\n");
+ return AVERROR(EINVAL);
+ }
if ((AV_RB16(pkt->data) & 0xfff0) != 0xfff0) {
- ADTSContext *adts = ts_st->adts;
- int new_size, err;
- if (!adts) {
- av_log(s, AV_LOG_ERROR, "aac bitstream not in adts format "
+ int ret;
+ AVPacket pkt2;
+
+ if (!ts_st->amux) {
+ av_log(s, AV_LOG_ERROR, "AAC bitstream not in ADTS format "
"and extradata missing\n");
- return -1;
+ return AVERROR(EINVAL);
}
- new_size = ADTS_HEADER_SIZE+adts->pce_size+pkt->size;
- if ((unsigned)new_size >= INT_MAX)
- return -1;
- data = av_malloc(new_size);
- if (!data)
+
+ av_init_packet(&pkt2);
+ pkt2.data = pkt->data;
+ pkt2.size = pkt->size;
+ ret = avio_open_dyn_buf(&ts_st->amux->pb);
+ if (ret < 0)
return AVERROR(ENOMEM);
- err = ff_adts_write_frame_header(adts, data, pkt->size,
- adts->pce_size);
- if (err < 0) {
+
+ ret = av_write_frame(ts_st->amux, &pkt2);
+ if (ret < 0) {
+ avio_close_dyn_buf(ts_st->amux->pb, &data);
+ ts_st->amux->pb = NULL;
av_free(data);
- return err;
+ return ret;
}
- if (adts->pce_size) {
- memcpy(data+ADTS_HEADER_SIZE, adts->pce_data, adts->pce_size);
- adts->pce_size = 0;
- }
- memcpy(data+ADTS_HEADER_SIZE+adts->pce_size, pkt->data, pkt->size);
+ size = avio_close_dyn_buf(ts_st->amux->pb, &data);
+ ts_st->amux->pb = NULL;
buf = data;
- size = new_size;
}
}
@@ -1099,7 +1143,10 @@ static int mpegts_write_end(AVFormatContext *s)
AVStream *st = s->streams[i];
MpegTSWriteStream *ts_st = st->priv_data;
av_freep(&ts_st->payload);
- av_freep(&ts_st->adts);
+ if (ts_st->amux) {
+ avformat_free_context(ts_st->amux);
+ ts_st->amux = NULL;
+ }
}
for(i = 0; i < ts->nb_services; i++) {
diff --git a/libavformat/mtv.c b/libavformat/mtv.c
index 2af9c2d..e917a19 100644
--- a/libavformat/mtv.c
+++ b/libavformat/mtv.c
@@ -130,7 +130,7 @@ static int mtv_read_header(AVFormatContext *s)
avpriv_set_pts_info(st, 64, 1, mtv->video_fps);
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = CODEC_ID_RAWVIDEO;
- st->codec->pix_fmt = PIX_FMT_RGB565;
+ st->codec->pix_fmt = PIX_FMT_RGB565BE;
st->codec->width = mtv->img_width;
st->codec->height = mtv->img_height;
st->codec->sample_rate = mtv->video_fps;
@@ -163,9 +163,6 @@ static int mtv_read_packet(AVFormatContext *s, AVPacket *pkt)
MTVDemuxContext *mtv = s->priv_data;
AVIOContext *pb = s->pb;
int ret;
-#if !HAVE_BIGENDIAN
- int i;
-#endif
if((avio_tell(pb) - s->data_offset + mtv->img_segment_size) % mtv->full_segment_size)
{
@@ -184,17 +181,6 @@ static int mtv_read_packet(AVFormatContext *s, AVPacket *pkt)
if(ret < 0)
return ret;
-#if !HAVE_BIGENDIAN
-
- /* pkt->data is GGGRRRR BBBBBGGG
- * and we need RRRRRGGG GGGBBBBB
- * for PIX_FMT_RGB565 so here we
- * just swap bytes as they come
- */
-
- for(i=0;i<mtv->img_segment_size/2;i++)
- *((uint16_t *)pkt->data+i) = av_bswap16(*((uint16_t *)pkt->data+i));
-#endif
pkt->stream_index = 0;
}
@@ -202,7 +188,7 @@ static int mtv_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_mtv_demuxer = {
- .name = "MTV",
+ .name = "mtv",
.long_name = NULL_IF_CONFIG_SMALL("MTV format"),
.priv_data_size = sizeof(MTVDemuxContext),
.read_probe = mtv_probe,
diff --git a/libavformat/network.c b/libavformat/network.c
index 432084f..c2f7a9b 100644
--- a/libavformat/network.c
+++ b/libavformat/network.c
@@ -164,6 +164,14 @@ int ff_neterrno(void)
return AVERROR(EAGAIN);
case WSAEINTR:
return AVERROR(EINTR);
+ case WSAEPROTONOSUPPORT:
+ return AVERROR(EPROTONOSUPPORT);
+ case WSAETIMEDOUT:
+ return AVERROR(ETIMEDOUT);
+ case WSAECONNREFUSED:
+ return AVERROR(ECONNREFUSED);
+ case WSAEINPROGRESS:
+ return AVERROR(EINPROGRESS);
}
return -err;
}
diff --git a/libavformat/network.h b/libavformat/network.h
index 72d01d2..793cfee 100644
--- a/libavformat/network.h
+++ b/libavformat/network.h
@@ -27,14 +27,29 @@
#include "libavutil/error.h"
#include "os_support.h"
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
#if HAVE_WINSOCK2_H
#include <winsock2.h>
#include <ws2tcpip.h>
+#ifndef EPROTONOSUPPORT
#define EPROTONOSUPPORT WSAEPROTONOSUPPORT
+#endif
+#ifndef ETIMEDOUT
#define ETIMEDOUT WSAETIMEDOUT
+#endif
+#ifndef ECONNREFUSED
#define ECONNREFUSED WSAECONNREFUSED
+#endif
+#ifndef EINPROGRESS
#define EINPROGRESS WSAEINPROGRESS
+#endif
+
+#define getsockopt(a, b, c, d, e) getsockopt(a, b, c, (char*) d, e)
+#define setsockopt(a, b, c, d, e) setsockopt(a, b, c, (const char*) d, e)
int ff_neterrno(void);
#else
diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c
index 1a160c5..24e823e 100644
--- a/libavformat/nsvdec.c
+++ b/libavformat/nsvdec.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/attributes.h"
#include "libavutil/mathematics.h"
#include "avformat.h"
#include "internal.h"
@@ -273,7 +274,7 @@ static int nsv_parse_NSVf_header(AVFormatContext *s)
{
NSVContext *nsv = s->priv_data;
AVIOContext *pb = s->pb;
- unsigned int file_size;
+ unsigned int av_unused file_size;
unsigned int size;
int64_t duration;
int strings_size;
@@ -595,7 +596,7 @@ null_chunk_retry:
av_dlog(s, "NSV CHUNK %d aux, %u bytes video, %d bytes audio\n", auxcount, vsize, asize);
/* skip aux stuff */
for (i = 0; i < auxcount; i++) {
- uint32_t auxtag;
+ uint32_t av_unused auxtag;
auxsize = avio_rl16(pb);
auxtag = avio_rl32(pb);
av_dlog(s, "NSV aux data: '%c%c%c%c', %d bytes\n",
diff --git a/libavformat/options_table.h b/libavformat/options_table.h
index 683596c..58f3dcf 100644
--- a/libavformat/options_table.h
+++ b/libavformat/options_table.h
@@ -19,6 +19,11 @@
#ifndef AVFORMAT_OPTIONS_TABLE
#define AVFORMAT_OPTIONS_TABLE
+#include <limits.h>
+
+#include "libavutil/opt.h"
+#include "avformat.h"
+
#define OFFSET(x) offsetof(AVFormatContext,x)
#define DEFAULT 0 //should be NAN but it does not work as it is not a constant in glibc as required by ANSI/ISO C
//these names are too long to be readable
diff --git a/libavformat/os_support.c b/libavformat/os_support.c
index 889a005..6d8c8ac 100644
--- a/libavformat/os_support.c
+++ b/libavformat/os_support.c
@@ -28,9 +28,11 @@
#include "os_support.h"
#if defined(_WIN32) && !defined(__MINGW32CE__)
+#undef open
+#include <fcntl.h>
+#include <io.h>
#include <windows.h>
-#undef open
int ff_win32_open(const char *filename_utf8, int oflag, int pmode)
{
int fd;
@@ -57,9 +59,10 @@ int ff_win32_open(const char *filename_utf8, int oflag, int pmode)
#if CONFIG_NETWORK
#include <fcntl.h>
-#include <unistd.h>
#if !HAVE_POLL_H
+#if HAVE_SYS_TIME_H
#include <sys/time.h>
+#endif
#if HAVE_WINSOCK2_H
#include <winsock2.h>
#elif HAVE_SYS_SELECT_H
@@ -252,7 +255,8 @@ const char *ff_gai_strerror(int ecode)
int ff_socket_nonblock(int socket, int enable)
{
#if HAVE_WINSOCK2_H
- return ioctlsocket(socket, FIONBIO, &enable);
+ u_long param = enable;
+ return ioctlsocket(socket, FIONBIO, ¶m);
#else
if (enable)
return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) | O_NONBLOCK);
@@ -262,7 +266,7 @@ int ff_socket_nonblock(int socket, int enable)
}
#if !HAVE_POLL_H
-int poll(struct pollfd *fds, nfds_t numfds, int timeout)
+int ff_poll(struct pollfd *fds, nfds_t numfds, int timeout)
{
fd_set read_set;
fd_set write_set;
@@ -282,7 +286,7 @@ int poll(struct pollfd *fds, nfds_t numfds, int timeout)
FD_ZERO(&write_set);
FD_ZERO(&exception_set);
- n = -1;
+ n = 0;
for(i = 0; i < numfds; i++) {
if (fds[i].fd < 0)
continue;
@@ -297,22 +301,22 @@ int poll(struct pollfd *fds, nfds_t numfds, int timeout)
if (fds[i].events & POLLOUT) FD_SET(fds[i].fd, &write_set);
if (fds[i].events & POLLERR) FD_SET(fds[i].fd, &exception_set);
- if (fds[i].fd > n)
- n = fds[i].fd;
+ if (fds[i].fd >= n)
+ n = fds[i].fd + 1;
};
- if (n == -1)
+ if (n == 0)
/* Hey!? Nothing to poll, in fact!!! */
return 0;
if (timeout < 0)
- rc = select(n+1, &read_set, &write_set, &exception_set, NULL);
+ rc = select(n, &read_set, &write_set, &exception_set, NULL);
else {
struct timeval tv;
tv.tv_sec = timeout / 1000;
tv.tv_usec = 1000 * (timeout % 1000);
- rc = select(n+1, &read_set, &write_set, &exception_set, &tv);
+ rc = select(n, &read_set, &write_set, &exception_set, &tv);
};
if (rc < 0)
diff --git a/libavformat/os_support.h b/libavformat/os_support.h
index 20c6d73..8e2eb83 100644
--- a/libavformat/os_support.h
+++ b/libavformat/os_support.h
@@ -29,6 +29,8 @@
#include "config.h"
+#include <sys/stat.h>
+
#if defined(__MINGW32__) && !defined(__MINGW32CE__)
# include <fcntl.h>
# define lseek(f,p,w) _lseeki64((f), (p), (w))
@@ -45,6 +47,25 @@ static inline int is_dos_path(const char *path)
return 0;
}
+#if defined(__OS2__)
+#define SHUT_RD 0
+#define SHUT_WR 1
+#define SHUT_RDWR 2
+#endif
+
+#if defined(_WIN32)
+#define SHUT_RD SD_RECEIVE
+#define SHUT_WR SD_SEND
+#define SHUT_RDWR SD_BOTH
+
+#ifndef S_IRUSR
+#define S_IRUSR S_IREAD
+#endif
+#ifndef S_IWUSR
+#define S_IWUSR S_IWRITE
+#endif
+#endif
+
#if defined(_WIN32) && !defined(__MINGW32CE__)
int ff_win32_open(const char *filename, int oflag, int pmode);
#define open ff_win32_open
@@ -63,6 +84,10 @@ typedef int socklen_t;
#if !HAVE_POLL_H
typedef unsigned long nfds_t;
+#if HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+#if !HAVE_STRUCT_POLLFD
struct pollfd {
int fd;
short events; /* events to look for */
@@ -82,9 +107,11 @@ struct pollfd {
#define POLLERR 0x0004 /* errors pending */
#define POLLHUP 0x0080 /* disconnected */
#define POLLNVAL 0x1000 /* invalid file descriptor */
+#endif
-int poll(struct pollfd *fds, nfds_t numfds, int timeout);
+int ff_poll(struct pollfd *fds, nfds_t numfds, int timeout);
+#define poll ff_poll
#endif /* HAVE_POLL_H */
#endif /* CONFIG_NETWORK */
diff --git a/libavformat/riff.c b/libavformat/riff.c
index 8a91345..0aef2d7 100644
--- a/libavformat/riff.c
+++ b/libavformat/riff.c
@@ -284,6 +284,8 @@ const AVCodecTag ff_codec_bmp_tags[] = {
{ CODEC_ID_VBLE, MKTAG('V', 'B', 'L', 'E') },
{ CODEC_ID_DXTORY, MKTAG('x', 't', 'o', 'r') },
{ CODEC_ID_ZEROCODEC, MKTAG('Z', 'E', 'C', 'O') },
+ { CODEC_ID_MSS1, MKTAG('M', 'S', 'S', '1') },
+ { CODEC_ID_MSA1, MKTAG('M', 'S', 'A', '1') },
{ CODEC_ID_NONE, 0 }
};
@@ -322,6 +324,7 @@ const AVCodecTag ff_codec_wav_tags[] = {
{ CODEC_ID_ATRAC3, 0x0270 },
{ CODEC_ID_ADPCM_G722, 0x028F },
{ CODEC_ID_IMC, 0x0401 },
+ { CODEC_ID_IAC, 0x0402 },
{ CODEC_ID_GSM_MS, 0x1500 },
{ CODEC_ID_TRUESPEECH, 0x1501 },
{ CODEC_ID_AAC, 0x1600 }, /* ADTS AAC */
diff --git a/libavformat/rtmphttp.c b/libavformat/rtmphttp.c
new file mode 100644
index 0000000..499341a
--- /dev/null
+++ b/libavformat/rtmphttp.c
@@ -0,0 +1,251 @@
+/*
+ * RTMP HTTP network protocol
+ * Copyright (c) 2012 Samuel Pitoiset
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * RTMP HTTP protocol
+ */
+
+#include "libavutil/avstring.h"
+#include "libavutil/intfloat.h"
+#include "libavutil/opt.h"
+#include "libavutil/time.h"
+#include "internal.h"
+#include "http.h"
+
+#define RTMPT_DEFAULT_PORT 80
+
+/* protocol handler context */
+typedef struct RTMP_HTTPContext {
+ URLContext *stream; ///< HTTP stream
+ char host[256]; ///< hostname of the server
+ int port; ///< port to connect (default is 80)
+ char client_id[64]; ///< client ID used for all requests except the first one
+ int seq; ///< sequence ID used for all requests
+ uint8_t *out_data; ///< output buffer
+ int out_size; ///< current output buffer size
+ int out_capacity; ///< current output buffer capacity
+ int initialized; ///< flag indicating when the http context is initialized
+ int finishing; ///< flag indicating when the client closes the connection
+ int nb_bytes_read; ///< number of bytes read since the last request
+} RTMP_HTTPContext;
+
+static int rtmp_http_send_cmd(URLContext *h, const char *cmd)
+{
+ RTMP_HTTPContext *rt = h->priv_data;
+ char uri[2048];
+ uint8_t c;
+ int ret;
+
+ ff_url_join(uri, sizeof(uri), "http", NULL, rt->host, rt->port,
+ "/%s/%s/%d", cmd, rt->client_id, rt->seq++);
+
+ av_opt_set_bin(rt->stream->priv_data, "post_data", rt->out_data,
+ rt->out_size, 0);
+
+ /* send a new request to the server */
+ if ((ret = ff_http_do_new_request(rt->stream, uri)) < 0)
+ return ret;
+
+ /* re-init output buffer */
+ rt->out_size = 0;
+
+ /* read the first byte which contains the polling interval */
+ if ((ret = ffurl_read(rt->stream, &c, 1)) < 0)
+ return ret;
+
+ /* re-init the number of bytes read */
+ rt->nb_bytes_read = 0;
+
+ return ret;
+}
+
+static int rtmp_http_write(URLContext *h, const uint8_t *buf, int size)
+{
+ RTMP_HTTPContext *rt = h->priv_data;
+ void *ptr;
+
+ if (rt->out_size + size > rt->out_capacity) {
+ rt->out_capacity = (rt->out_size + size) * 2;
+ ptr = av_realloc(rt->out_data, rt->out_capacity);
+ if (!ptr)
+ return AVERROR(ENOMEM);
+ rt->out_data = ptr;
+ }
+
+ memcpy(rt->out_data + rt->out_size, buf, size);
+ rt->out_size += size;
+
+ return size;
+}
+
+static int rtmp_http_read(URLContext *h, uint8_t *buf, int size)
+{
+ RTMP_HTTPContext *rt = h->priv_data;
+ int ret, off = 0;
+
+ /* try to read at least 1 byte of data */
+ do {
+ ret = ffurl_read(rt->stream, buf + off, size);
+ if (ret < 0 && ret != AVERROR_EOF)
+ return ret;
+
+ if (ret == AVERROR_EOF) {
+ if (rt->finishing) {
+ /* Do not send new requests when the client wants to
+ * close the connection. */
+ return AVERROR(EAGAIN);
+ }
+
+ /* When the client has reached end of file for the last request,
+ * we have to send a new request if we have buffered data.
+ * Otherwise, we have to send an idle POST. */
+ if (rt->out_size > 0) {
+ if ((ret = rtmp_http_send_cmd(h, "send")) < 0)
+ return ret;
+ } else {
+ if (rt->nb_bytes_read == 0) {
+ /* Wait 50ms before retrying to read a server reply in
+ * order to reduce the number of idle requets. */
+ av_usleep(50000);
+ }
+
+ if ((ret = rtmp_http_write(h, "", 1)) < 0)
+ return ret;
+
+ if ((ret = rtmp_http_send_cmd(h, "idle")) < 0)
+ return ret;
+ }
+
+ if (h->flags & AVIO_FLAG_NONBLOCK) {
+ /* no incoming data to handle in nonblocking mode */
+ return AVERROR(EAGAIN);
+ }
+ } else {
+ off += ret;
+ size -= ret;
+ rt->nb_bytes_read += ret;
+ }
+ } while (off <= 0);
+
+ return off;
+}
+
+static int rtmp_http_close(URLContext *h)
+{
+ RTMP_HTTPContext *rt = h->priv_data;
+ uint8_t tmp_buf[2048];
+ int ret = 0;
+
+ if (rt->initialized) {
+ /* client wants to close the connection */
+ rt->finishing = 1;
+
+ do {
+ ret = rtmp_http_read(h, tmp_buf, sizeof(tmp_buf));
+ } while (ret > 0);
+
+ /* re-init output buffer before sending the close command */
+ rt->out_size = 0;
+
+ if ((ret = rtmp_http_write(h, "", 1)) == 1)
+ ret = rtmp_http_send_cmd(h, "close");
+ }
+
+ av_freep(&rt->out_data);
+ ffurl_close(rt->stream);
+
+ return ret;
+}
+
+static int rtmp_http_open(URLContext *h, const char *uri, int flags)
+{
+ RTMP_HTTPContext *rt = h->priv_data;
+ char headers[1024], url[1024];
+ int ret, off = 0;
+
+ av_url_split(NULL, 0, NULL, 0, rt->host, sizeof(rt->host), &rt->port,
+ NULL, 0, uri);
+
+ if (rt->port < 0)
+ rt->port = RTMPT_DEFAULT_PORT;
+
+ /* This is the first request that is sent to the server in order to
+ * register a client on the server and start a new session. The server
+ * replies with a unique id (usually a number) that is used by the client
+ * for all future requests.
+ * Note: the reply doesn't contain a value for the polling interval.
+ * A successful connect resets the consecutive index that is used
+ * in the URLs. */
+ ff_url_join(url, sizeof(url), "http", NULL, rt->host, rt->port, "/open/1");
+
+ /* alloc the http context */
+ if ((ret = ffurl_alloc(&rt->stream, url, AVIO_FLAG_READ_WRITE, NULL)) < 0)
+ goto fail;
+
+ /* set options */
+ snprintf(headers, sizeof(headers),
+ "Cache-Control: no-cache\r\n"
+ "Content-type: application/x-fcs\r\n"
+ "User-Agent: Shockwave Flash\r\n");
+ av_opt_set(rt->stream->priv_data, "headers", headers, 0);
+ av_opt_set(rt->stream->priv_data, "multiple_requests", "1", 0);
+ av_opt_set_bin(rt->stream->priv_data, "post_data", "", 1, 0);
+
+ /* open the http context */
+ if ((ret = ffurl_connect(rt->stream, NULL)) < 0)
+ goto fail;
+
+ /* read the server reply which contains a unique ID */
+ for (;;) {
+ ret = ffurl_read(rt->stream, rt->client_id + off, sizeof(rt->client_id) - off);
+ if (ret == AVERROR_EOF)
+ break;
+ if (ret < 0)
+ goto fail;
+ off += ret;
+ if (off == sizeof(rt->client_id)) {
+ ret = AVERROR(EIO);
+ goto fail;
+ }
+ }
+ while (off > 0 && isspace(rt->client_id[off - 1]))
+ off--;
+ rt->client_id[off] = '\0';
+
+ /* http context is now initialized */
+ rt->initialized = 1;
+ return 0;
+
+fail:
+ rtmp_http_close(h);
+ return ret;
+}
+
+URLProtocol ff_rtmphttp_protocol = {
+ .name = "rtmphttp",
+ .url_open = rtmp_http_open,
+ .url_read = rtmp_http_read,
+ .url_write = rtmp_http_write,
+ .url_close = rtmp_http_close,
+ .priv_data_size = sizeof(RTMP_HTTPContext),
+ .flags = URL_PROTOCOL_FLAG_NETWORK,
+};
diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c
index 8c455a0..4ce238d 100644
--- a/libavformat/rtmppkt.c
+++ b/libavformat/rtmppkt.c
@@ -74,14 +74,25 @@ void ff_amf_write_object_end(uint8_t **dst)
int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p,
int chunk_size, RTMPPacket *prev_pkt)
{
- uint8_t hdr, t, buf[16];
+ uint8_t hdr;
+
+ if (ffurl_read(h, &hdr, 1) != 1)
+ return AVERROR(EIO);
+
+ return ff_rtmp_packet_read_internal(h, p, chunk_size, prev_pkt, hdr);
+}
+
+int ff_rtmp_packet_read_internal(URLContext *h, RTMPPacket *p, int chunk_size,
+ RTMPPacket *prev_pkt, uint8_t hdr)
+{
+
+ uint8_t t, buf[16];
int channel_id, timestamp, data_size, offset = 0;
uint32_t extra = 0;
enum RTMPPacketType type;
int size = 0;
+ int ret;
- if (ffurl_read(h, &hdr, 1) != 1)
- return AVERROR(EIO);
size++;
channel_id = hdr & 0x3F;
@@ -129,8 +140,9 @@ int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p,
if (hdr != RTMP_PS_TWELVEBYTES)
timestamp += prev_pkt[channel_id].timestamp;
- if (ff_rtmp_packet_create(p, channel_id, type, timestamp, data_size))
- return -1;
+ if ((ret = ff_rtmp_packet_create(p, channel_id, type, timestamp,
+ data_size)) < 0)
+ return ret;
p->extra = extra;
// save history
prev_pkt[channel_id].channel_id = channel_id;
@@ -149,7 +161,10 @@ int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p,
offset += chunk_size;
size += chunk_size;
if (data_size > 0) {
- ffurl_read_complete(h, &t, 1); //marker
+ if ((ret = ffurl_read_complete(h, &t, 1)) < 0) { // marker
+ ff_rtmp_packet_destroy(p);
+ return ret;
+ }
size++;
if (t != (0xC0 + channel_id))
return -1;
@@ -165,6 +180,7 @@ int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt,
int mode = RTMP_PS_TWELVEBYTES;
int off = 0;
int size = 0;
+ int ret;
pkt->ts_delta = pkt->timestamp - prev_pkt[pkt->channel_id].timestamp;
@@ -216,15 +232,18 @@ int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt,
}
prev_pkt[pkt->channel_id].extra = pkt->extra;
- ffurl_write(h, pkt_hdr, p-pkt_hdr);
+ if ((ret = ffurl_write(h, pkt_hdr, p - pkt_hdr)) < 0)
+ return ret;
size = p - pkt_hdr + pkt->data_size;
while (off < pkt->data_size) {
int towrite = FFMIN(chunk_size, pkt->data_size - off);
- ffurl_write(h, pkt->data + off, towrite);
+ if ((ret = ffurl_write(h, pkt->data + off, towrite)) < 0)
+ return ret;
off += towrite;
if (off < pkt->data_size) {
uint8_t marker = 0xC0 | pkt->channel_id;
- ffurl_write(h, &marker, 1);
+ if ((ret = ffurl_write(h, &marker, 1)) < 0)
+ return ret;
size++;
}
}
diff --git a/libavformat/rtmppkt.h b/libavformat/rtmppkt.h
index 8372484..a83d0fe 100644
--- a/libavformat/rtmppkt.h
+++ b/libavformat/rtmppkt.h
@@ -115,6 +115,19 @@ void ff_rtmp_packet_destroy(RTMPPacket *pkt);
*/
int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p,
int chunk_size, RTMPPacket *prev_pkt);
+/**
+ * Read internal RTMP packet sent by the server.
+ *
+ * @param h reader context
+ * @param p packet
+ * @param chunk_size current chunk size
+ * @param prev_pkt previously read packet headers for all channels
+ * (may be needed for restoring incomplete packet header)
+ * @param c the first byte already read
+ * @return number of bytes read on success, negative value otherwise
+ */
+int ff_rtmp_packet_read_internal(URLContext *h, RTMPPacket *p, int chunk_size,
+ RTMPPacket *prev_pkt, uint8_t c);
/**
* Send RTMP packet to the server.
diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
index 9cdb639..b48274b 100644
--- a/libavformat/rtmpproto.c
+++ b/libavformat/rtmpproto.c
@@ -44,6 +44,8 @@
#define APP_MAX_LENGTH 128
#define PLAYPATH_MAX_LENGTH 256
+#define TCURL_MAX_LENGTH 512
+#define FLASHVER_MAX_LENGTH 64
/** RTMP protocol handler state */
typedef enum {
@@ -66,12 +68,15 @@ typedef struct RTMPContext {
int chunk_size; ///< size of the chunks RTMP packets are divided into
int is_input; ///< input/output flag
char *playpath; ///< stream identifier to play (with possible "mp4:" prefix)
+ int live; ///< 0: recorded, -1: live, -2: both
char *app; ///< name of application
+ char *conn; ///< append arbitrary AMF data to the Connect message
ClientState state; ///< current state
int main_channel_id; ///< an additional channel ID which is used for some invocations
uint8_t* flv_data; ///< buffer with data for demuxer
int flv_size; ///< current buffer size
int flv_off; ///< number of bytes read from current buffer
+ int flv_nb_packets; ///< number of flv packets published
RTMPPacket out_pkt; ///< rtmp packet, created from flv a/v or metadata (for output)
uint32_t client_report_size; ///< number of bytes after which client should report to server
uint32_t bytes_read; ///< number of bytes read from server
@@ -81,6 +86,12 @@ typedef struct RTMPContext {
int flv_header_bytes; ///< number of initialized bytes in flv_header
int nb_invokes; ///< keeps track of invoke messages
int create_stream_invoke; ///< invoke id for the create stream command
+ char* tcurl; ///< url of the target stream
+ char* flashver; ///< version of the flash plugin
+ char* swfurl; ///< url of the swf player
+ int server_bw; ///< server bandwidth
+ int client_buffer_time; ///< client buffer time in ms
+ int flush_interval; ///< number of packets flushed in the same request (RTMPT only)
} RTMPContext;
#define PLAYER_KEY_OPEN_PART_LEN 30 ///< length of partial key used for first client digest signing
@@ -106,38 +117,104 @@ static const uint8_t rtmp_server_key[] = {
0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
};
+static int rtmp_write_amf_data(URLContext *s, char *param, uint8_t **p)
+{
+ char *field, *value;
+ char type;
+
+ /* The type must be B for Boolean, N for number, S for string, O for
+ * object, or Z for null. For Booleans the data must be either 0 or 1 for
+ * FALSE or TRUE, respectively. Likewise for Objects the data must be
+ * 0 or 1 to end or begin an object, respectively. Data items in subobjects
+ * may be named, by prefixing the type with 'N' and specifying the name
+ * before the value (ie. NB:myFlag:1). This option may be used multiple times
+ * to construct arbitrary AMF sequences. */
+ if (param[0] && param[1] == ':') {
+ type = param[0];
+ value = param + 2;
+ } else if (param[0] == 'N' && param[1] && param[2] == ':') {
+ type = param[1];
+ field = param + 3;
+ value = strchr(field, ':');
+ if (!value)
+ goto fail;
+ *value = '\0';
+ value++;
+
+ if (!field || !value)
+ goto fail;
+
+ ff_amf_write_field_name(p, field);
+ } else {
+ goto fail;
+ }
+
+ switch (type) {
+ case 'B':
+ ff_amf_write_bool(p, value[0] != '0');
+ break;
+ case 'S':
+ ff_amf_write_string(p, value);
+ break;
+ case 'N':
+ ff_amf_write_number(p, strtod(value, NULL));
+ break;
+ case 'Z':
+ ff_amf_write_null(p);
+ break;
+ case 'O':
+ if (value[0] != '0')
+ ff_amf_write_object_start(p);
+ else
+ ff_amf_write_object_end(p);
+ break;
+ default:
+ goto fail;
+ break;
+ }
+
+ return 0;
+
+fail:
+ av_log(s, AV_LOG_ERROR, "Invalid AMF parameter: %s\n", param);
+ return AVERROR(EINVAL);
+}
+
/**
* Generate 'connect' call and send it to the server.
*/
-static void gen_connect(URLContext *s, RTMPContext *rt, const char *proto,
- const char *host, int port)
+static int gen_connect(URLContext *s, RTMPContext *rt)
{
RTMPPacket pkt;
- uint8_t ver[64], *p;
- char tcurl[512];
+ uint8_t *p;
+ int ret;
+
+ if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
+ 0, 4096)) < 0)
+ return ret;
- ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0, 4096);
p = pkt.data;
- ff_url_join(tcurl, sizeof(tcurl), proto, NULL, host, port, "/%s", rt->app);
ff_amf_write_string(&p, "connect");
ff_amf_write_number(&p, ++rt->nb_invokes);
ff_amf_write_object_start(&p);
ff_amf_write_field_name(&p, "app");
ff_amf_write_string(&p, rt->app);
- if (rt->is_input) {
- snprintf(ver, sizeof(ver), "%s %d,%d,%d,%d", RTMP_CLIENT_PLATFORM, RTMP_CLIENT_VER1,
- RTMP_CLIENT_VER2, RTMP_CLIENT_VER3, RTMP_CLIENT_VER4);
- } else {
- snprintf(ver, sizeof(ver), "FMLE/3.0 (compatible; %s)", LIBAVFORMAT_IDENT);
+ if (!rt->is_input) {
ff_amf_write_field_name(&p, "type");
ff_amf_write_string(&p, "nonprivate");
}
ff_amf_write_field_name(&p, "flashVer");
- ff_amf_write_string(&p, ver);
+ ff_amf_write_string(&p, rt->flashver);
+
+ if (rt->swfurl) {
+ ff_amf_write_field_name(&p, "swfUrl");
+ ff_amf_write_string(&p, rt->swfurl);
+ }
+
ff_amf_write_field_name(&p, "tcUrl");
- ff_amf_write_string(&p, tcurl);
+ ff_amf_write_string(&p, rt->tcurl);
if (rt->is_input) {
ff_amf_write_field_name(&p, "fpad");
ff_amf_write_bool(&p, 0);
@@ -156,23 +233,53 @@ static void gen_connect(URLContext *s, RTMPContext *rt, const char *proto,
}
ff_amf_write_object_end(&p);
+ if (rt->conn) {
+ char *param = rt->conn;
+
+ // Write arbitrary AMF data to the Connect message.
+ while (param != NULL) {
+ char *sep;
+ param += strspn(param, " ");
+ if (!*param)
+ break;
+ sep = strchr(param, ' ');
+ if (sep)
+ *sep = '\0';
+ if ((ret = rtmp_write_amf_data(s, param, &p)) < 0) {
+ // Invalid AMF parameter.
+ ff_rtmp_packet_destroy(&pkt);
+ return ret;
+ }
+
+ if (sep)
+ param = sep + 1;
+ else
+ break;
+ }
+ }
+
pkt.data_size = p - pkt.data;
- ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
+ ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
+ rt->prev_pkt[1]);
ff_rtmp_packet_destroy(&pkt);
+
+ return ret;
}
/**
* Generate 'releaseStream' call and send it to the server. It should make
* the server release some channel for media streams.
*/
-static void gen_release_stream(URLContext *s, RTMPContext *rt)
+static int gen_release_stream(URLContext *s, RTMPContext *rt)
{
RTMPPacket pkt;
uint8_t *p;
+ int ret;
- ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0,
- 29 + strlen(rt->playpath));
+ if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
+ 0, 29 + strlen(rt->playpath))) < 0)
+ return ret;
av_log(s, AV_LOG_DEBUG, "Releasing stream...\n");
p = pkt.data;
@@ -181,21 +288,26 @@ static void gen_release_stream(URLContext *s, RTMPContext *rt)
ff_amf_write_null(&p);
ff_amf_write_string(&p, rt->playpath);
- ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
+ ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
+ rt->prev_pkt[1]);
ff_rtmp_packet_destroy(&pkt);
+
+ return ret;
}
/**
* Generate 'FCPublish' call and send it to the server. It should make
* the server preapare for receiving media streams.
*/
-static void gen_fcpublish_stream(URLContext *s, RTMPContext *rt)
+static int gen_fcpublish_stream(URLContext *s, RTMPContext *rt)
{
RTMPPacket pkt;
uint8_t *p;
+ int ret;
- ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0,
- 25 + strlen(rt->playpath));
+ if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
+ 0, 25 + strlen(rt->playpath))) < 0)
+ return ret;
av_log(s, AV_LOG_DEBUG, "FCPublish stream...\n");
p = pkt.data;
@@ -204,21 +316,26 @@ static void gen_fcpublish_stream(URLContext *s, RTMPContext *rt)
ff_amf_write_null(&p);
ff_amf_write_string(&p, rt->playpath);
- ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
+ ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
+ rt->prev_pkt[1]);
ff_rtmp_packet_destroy(&pkt);
+
+ return ret;
}
/**
* Generate 'FCUnpublish' call and send it to the server. It should make
* the server destroy stream.
*/
-static void gen_fcunpublish_stream(URLContext *s, RTMPContext *rt)
+static int gen_fcunpublish_stream(URLContext *s, RTMPContext *rt)
{
RTMPPacket pkt;
uint8_t *p;
+ int ret;
- ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0,
- 27 + strlen(rt->playpath));
+ if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
+ 0, 27 + strlen(rt->playpath))) < 0)
+ return ret;
av_log(s, AV_LOG_DEBUG, "UnPublishing stream...\n");
p = pkt.data;
@@ -227,21 +344,28 @@ static void gen_fcunpublish_stream(URLContext *s, RTMPContext *rt)
ff_amf_write_null(&p);
ff_amf_write_string(&p, rt->playpath);
- ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
+ ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
+ rt->prev_pkt[1]);
ff_rtmp_packet_destroy(&pkt);
+
+ return ret;
}
/**
* Generate 'createStream' call and send it to the server. It should make
* the server allocate some channel for media streams.
*/
-static void gen_create_stream(URLContext *s, RTMPContext *rt)
+static int gen_create_stream(URLContext *s, RTMPContext *rt)
{
RTMPPacket pkt;
uint8_t *p;
+ int ret;
av_log(s, AV_LOG_DEBUG, "Creating stream...\n");
- ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0, 25);
+
+ if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
+ 0, 25)) < 0)
+ return ret;
p = pkt.data;
ff_amf_write_string(&p, "createStream");
@@ -249,8 +373,11 @@ static void gen_create_stream(URLContext *s, RTMPContext *rt)
ff_amf_write_null(&p);
rt->create_stream_invoke = rt->nb_invokes;
- ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
+ ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
+ rt->prev_pkt[1]);
ff_rtmp_packet_destroy(&pkt);
+
+ return ret;
}
@@ -258,13 +385,17 @@ static void gen_create_stream(URLContext *s, RTMPContext *rt)
* Generate 'deleteStream' call and send it to the server. It should make
* the server remove some channel for media streams.
*/
-static void gen_delete_stream(URLContext *s, RTMPContext *rt)
+static int gen_delete_stream(URLContext *s, RTMPContext *rt)
{
RTMPPacket pkt;
uint8_t *p;
+ int ret;
av_log(s, AV_LOG_DEBUG, "Deleting stream...\n");
- ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0, 34);
+
+ if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
+ 0, 34)) < 0)
+ return ret;
p = pkt.data;
ff_amf_write_string(&p, "deleteStream");
@@ -272,22 +403,54 @@ static void gen_delete_stream(URLContext *s, RTMPContext *rt)
ff_amf_write_null(&p);
ff_amf_write_number(&p, rt->main_channel_id);
- ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
+ ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
+ rt->prev_pkt[1]);
+ ff_rtmp_packet_destroy(&pkt);
+
+ return ret;
+}
+
+/**
+ * Generate client buffer time and send it to the server.
+ */
+static int gen_buffer_time(URLContext *s, RTMPContext *rt)
+{
+ RTMPPacket pkt;
+ uint8_t *p;
+ int ret;
+
+ if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING,
+ 1, 10)) < 0)
+ return ret;
+
+ p = pkt.data;
+ bytestream_put_be16(&p, 3);
+ bytestream_put_be32(&p, rt->main_channel_id);
+ bytestream_put_be32(&p, rt->client_buffer_time);
+
+ ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
+ rt->prev_pkt[1]);
ff_rtmp_packet_destroy(&pkt);
+
+ return ret;
}
/**
* Generate 'play' call and send it to the server, then ping the server
* to start actual playing.
*/
-static void gen_play(URLContext *s, RTMPContext *rt)
+static int gen_play(URLContext *s, RTMPContext *rt)
{
RTMPPacket pkt;
uint8_t *p;
+ int ret;
av_log(s, AV_LOG_DEBUG, "Sending play command for '%s'\n", rt->playpath);
- ff_rtmp_packet_create(&pkt, RTMP_VIDEO_CHANNEL, RTMP_PT_INVOKE, 0,
- 20 + strlen(rt->playpath));
+
+ if ((ret = ff_rtmp_packet_create(&pkt, RTMP_VIDEO_CHANNEL, RTMP_PT_INVOKE,
+ 0, 29 + strlen(rt->playpath))) < 0)
+ return ret;
+
pkt.extra = rt->main_channel_id;
p = pkt.data;
@@ -295,33 +458,30 @@ static void gen_play(URLContext *s, RTMPContext *rt)
ff_amf_write_number(&p, ++rt->nb_invokes);
ff_amf_write_null(&p);
ff_amf_write_string(&p, rt->playpath);
+ ff_amf_write_number(&p, rt->live);
- ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
+ ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
+ rt->prev_pkt[1]);
ff_rtmp_packet_destroy(&pkt);
- // set client buffer time disguised in ping packet
- ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING, 1, 10);
-
- p = pkt.data;
- bytestream_put_be16(&p, 3);
- bytestream_put_be32(&p, 1);
- bytestream_put_be32(&p, 256); //TODO: what is a good value here?
-
- ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
- ff_rtmp_packet_destroy(&pkt);
+ return ret;
}
/**
* Generate 'publish' call and send it to the server.
*/
-static void gen_publish(URLContext *s, RTMPContext *rt)
+static int gen_publish(URLContext *s, RTMPContext *rt)
{
RTMPPacket pkt;
uint8_t *p;
+ int ret;
av_log(s, AV_LOG_DEBUG, "Sending publish command for '%s'\n", rt->playpath);
- ff_rtmp_packet_create(&pkt, RTMP_SOURCE_CHANNEL, RTMP_PT_INVOKE, 0,
- 30 + strlen(rt->playpath));
+
+ if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SOURCE_CHANNEL, RTMP_PT_INVOKE,
+ 0, 30 + strlen(rt->playpath))) < 0)
+ return ret;
+
pkt.extra = rt->main_channel_id;
p = pkt.data;
@@ -331,54 +491,103 @@ static void gen_publish(URLContext *s, RTMPContext *rt)
ff_amf_write_string(&p, rt->playpath);
ff_amf_write_string(&p, "live");
- ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
+ ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
+ rt->prev_pkt[1]);
ff_rtmp_packet_destroy(&pkt);
+
+ return ret;
}
/**
* Generate ping reply and send it to the server.
*/
-static void gen_pong(URLContext *s, RTMPContext *rt, RTMPPacket *ppkt)
+static int gen_pong(URLContext *s, RTMPContext *rt, RTMPPacket *ppkt)
{
RTMPPacket pkt;
uint8_t *p;
+ int ret;
+
+ if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING,
+ ppkt->timestamp + 1, 6)) < 0)
+ return ret;
- ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING, ppkt->timestamp + 1, 6);
p = pkt.data;
bytestream_put_be16(&p, 7);
bytestream_put_be32(&p, AV_RB32(ppkt->data+2));
- ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
+ ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
+ rt->prev_pkt[1]);
ff_rtmp_packet_destroy(&pkt);
+
+ return ret;
}
/**
* Generate server bandwidth message and send it to the server.
*/
-static void gen_server_bw(URLContext *s, RTMPContext *rt)
+static int gen_server_bw(URLContext *s, RTMPContext *rt)
+{
+ RTMPPacket pkt;
+ uint8_t *p;
+ int ret;
+
+ if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_SERVER_BW,
+ 0, 4)) < 0)
+ return ret;
+
+ p = pkt.data;
+ bytestream_put_be32(&p, rt->server_bw);
+ ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
+ rt->prev_pkt[1]);
+ ff_rtmp_packet_destroy(&pkt);
+
+ return ret;
+}
+
+/**
+ * Generate check bandwidth message and send it to the server.
+ */
+static int gen_check_bw(URLContext *s, RTMPContext *rt)
{
RTMPPacket pkt;
uint8_t *p;
+ int ret;
+
+ if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
+ 0, 21)) < 0)
+ return ret;
- ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_SERVER_BW, 0, 4);
p = pkt.data;
- bytestream_put_be32(&p, 2500000);
- ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
+ ff_amf_write_string(&p, "_checkbw");
+ ff_amf_write_number(&p, ++rt->nb_invokes);
+ ff_amf_write_null(&p);
+
+ ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
+ rt->prev_pkt[1]);
ff_rtmp_packet_destroy(&pkt);
+
+ return ret;
}
/**
* Generate report on bytes read so far and send it to the server.
*/
-static void gen_bytes_read(URLContext *s, RTMPContext *rt, uint32_t ts)
+static int gen_bytes_read(URLContext *s, RTMPContext *rt, uint32_t ts)
{
RTMPPacket pkt;
uint8_t *p;
+ int ret;
+
+ if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_BYTES_READ,
+ ts, 4)) < 0)
+ return ret;
- ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_BYTES_READ, ts, 4);
p = pkt.data;
bytestream_put_be32(&p, rt->bytes_read);
- ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
+ ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
+ rt->prev_pkt[1]);
ff_rtmp_packet_destroy(&pkt);
+
+ return ret;
}
//TODO: Move HMAC code somewhere. Eventually.
@@ -396,14 +605,16 @@ static void gen_bytes_read(URLContext *s, RTMPContext *rt, uint32_t ts)
* @param keylen digest key length
* @param dst buffer where calculated digest will be stored (32 bytes)
*/
-static void rtmp_calc_digest(const uint8_t *src, int len, int gap,
- const uint8_t *key, int keylen, uint8_t *dst)
+static int rtmp_calc_digest(const uint8_t *src, int len, int gap,
+ const uint8_t *key, int keylen, uint8_t *dst)
{
struct AVSHA *sha;
uint8_t hmac_buf[64+32] = {0};
int i;
sha = av_mallocz(av_sha_size);
+ if (!sha)
+ return AVERROR(ENOMEM);
if (keylen < 64) {
memcpy(hmac_buf, key, keylen);
@@ -432,6 +643,8 @@ static void rtmp_calc_digest(const uint8_t *src, int len, int gap,
av_sha_final(sha, dst);
av_free(sha);
+
+ return 0;
}
/**
@@ -444,14 +657,18 @@ static void rtmp_calc_digest(const uint8_t *src, int len, int gap,
static int rtmp_handshake_imprint_with_digest(uint8_t *buf)
{
int i, digest_pos = 0;
+ int ret;
for (i = 8; i < 12; i++)
digest_pos += buf[i];
digest_pos = (digest_pos % 728) + 12;
- rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
- rtmp_player_key, PLAYER_KEY_OPEN_PART_LEN,
- buf + digest_pos);
+ ret = rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
+ rtmp_player_key, PLAYER_KEY_OPEN_PART_LEN,
+ buf + digest_pos);
+ if (ret < 0)
+ return ret;
+
return digest_pos;
}
@@ -466,14 +683,18 @@ static int rtmp_validate_digest(uint8_t *buf, int off)
{
int i, digest_pos = 0;
uint8_t digest[32];
+ int ret;
for (i = 0; i < 4; i++)
digest_pos += buf[i + off];
digest_pos = (digest_pos % 728) + off + 4;
- rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
- rtmp_server_key, SERVER_KEY_OPEN_PART_LEN,
- digest);
+ ret = rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
+ rtmp_server_key, SERVER_KEY_OPEN_PART_LEN,
+ digest);
+ if (ret < 0)
+ return ret;
+
if (!memcmp(digest, buf + digest_pos, 32))
return digest_pos;
return 0;
@@ -501,6 +722,7 @@ static int rtmp_handshake(URLContext *s, RTMPContext *rt)
int i;
int server_pos, client_pos;
uint8_t digest[32];
+ int ret;
av_log(s, AV_LOG_DEBUG, "Handshaking...\n");
@@ -509,17 +731,25 @@ static int rtmp_handshake(URLContext *s, RTMPContext *rt)
for (i = 9; i <= RTMP_HANDSHAKE_PACKET_SIZE; i++)
tosend[i] = av_lfg_get(&rnd) >> 24;
client_pos = rtmp_handshake_imprint_with_digest(tosend + 1);
+ if (client_pos < 0)
+ return client_pos;
+
+ if ((ret = ffurl_write(rt->stream, tosend,
+ RTMP_HANDSHAKE_PACKET_SIZE + 1)) < 0) {
+ av_log(s, AV_LOG_ERROR, "Cannot write RTMP handshake request\n");
+ return ret;
+ }
- ffurl_write(rt->stream, tosend, RTMP_HANDSHAKE_PACKET_SIZE + 1);
- i = ffurl_read_complete(rt->stream, serverdata, RTMP_HANDSHAKE_PACKET_SIZE + 1);
- if (i != RTMP_HANDSHAKE_PACKET_SIZE + 1) {
+ if ((ret = ffurl_read_complete(rt->stream, serverdata,
+ RTMP_HANDSHAKE_PACKET_SIZE + 1)) < 0) {
av_log(s, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
- return -1;
+ return ret;
}
- i = ffurl_read_complete(rt->stream, clientdata, RTMP_HANDSHAKE_PACKET_SIZE);
- if (i != RTMP_HANDSHAKE_PACKET_SIZE) {
+
+ if ((ret = ffurl_read_complete(rt->stream, clientdata,
+ RTMP_HANDSHAKE_PACKET_SIZE)) < 0) {
av_log(s, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
- return -1;
+ return ret;
}
av_log(s, AV_LOG_DEBUG, "Server version %d.%d.%d.%d\n",
@@ -527,38 +757,57 @@ static int rtmp_handshake(URLContext *s, RTMPContext *rt)
if (rt->is_input && serverdata[5] >= 3) {
server_pos = rtmp_validate_digest(serverdata + 1, 772);
+ if (server_pos < 0)
+ return server_pos;
+
if (!server_pos) {
server_pos = rtmp_validate_digest(serverdata + 1, 8);
+ if (server_pos < 0)
+ return server_pos;
+
if (!server_pos) {
av_log(s, AV_LOG_ERROR, "Server response validating failed\n");
- return -1;
+ return AVERROR(EIO);
}
}
- rtmp_calc_digest(tosend + 1 + client_pos, 32, 0,
- rtmp_server_key, sizeof(rtmp_server_key),
- digest);
- rtmp_calc_digest(clientdata, RTMP_HANDSHAKE_PACKET_SIZE-32, 0,
- digest, 32,
- digest);
+ ret = rtmp_calc_digest(tosend + 1 + client_pos, 32, 0, rtmp_server_key,
+ sizeof(rtmp_server_key), digest);
+ if (ret < 0)
+ return ret;
+
+ ret = rtmp_calc_digest(clientdata, RTMP_HANDSHAKE_PACKET_SIZE - 32, 0,
+ digest, 32, digest);
+ if (ret < 0)
+ return ret;
+
if (memcmp(digest, clientdata + RTMP_HANDSHAKE_PACKET_SIZE - 32, 32)) {
av_log(s, AV_LOG_ERROR, "Signature mismatch\n");
- return -1;
+ return AVERROR(EIO);
}
for (i = 0; i < RTMP_HANDSHAKE_PACKET_SIZE; i++)
tosend[i] = av_lfg_get(&rnd) >> 24;
- rtmp_calc_digest(serverdata + 1 + server_pos, 32, 0,
- rtmp_player_key, sizeof(rtmp_player_key),
- digest);
- rtmp_calc_digest(tosend, RTMP_HANDSHAKE_PACKET_SIZE - 32, 0,
- digest, 32,
- tosend + RTMP_HANDSHAKE_PACKET_SIZE - 32);
+ ret = rtmp_calc_digest(serverdata + 1 + server_pos, 32, 0,
+ rtmp_player_key, sizeof(rtmp_player_key),
+ digest);
+ if (ret < 0)
+ return ret;
+
+ ret = rtmp_calc_digest(tosend, RTMP_HANDSHAKE_PACKET_SIZE - 32, 0,
+ digest, 32,
+ tosend + RTMP_HANDSHAKE_PACKET_SIZE - 32);
+ if (ret < 0)
+ return ret;
// write reply back to the server
- ffurl_write(rt->stream, tosend, RTMP_HANDSHAKE_PACKET_SIZE);
+ if ((ret = ffurl_write(rt->stream, tosend,
+ RTMP_HANDSHAKE_PACKET_SIZE)) < 0)
+ return ret;
} else {
- ffurl_write(rt->stream, serverdata+1, RTMP_HANDSHAKE_PACKET_SIZE);
+ if ((ret = ffurl_write(rt->stream, serverdata + 1,
+ RTMP_HANDSHAKE_PACKET_SIZE)) < 0)
+ return ret;
}
return 0;
@@ -574,6 +823,7 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)
{
int i, t;
const uint8_t *data_end = pkt->data + pkt->data_size;
+ int ret;
#ifdef DEBUG
ff_rtmp_packet_dump(s, pkt);
@@ -587,7 +837,9 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)
return -1;
}
if (!rt->is_input)
- ff_rtmp_packet_write(rt->stream, pkt, rt->chunk_size, rt->prev_pkt[1]);
+ if ((ret = ff_rtmp_packet_write(rt->stream, pkt, rt->chunk_size,
+ rt->prev_pkt[1])) < 0)
+ return ret;
rt->chunk_size = AV_RB32(pkt->data);
if (rt->chunk_size <= 0) {
av_log(s, AV_LOG_ERROR, "Incorrect chunk size %d\n", rt->chunk_size);
@@ -598,7 +850,8 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)
case RTMP_PT_PING:
t = AV_RB16(pkt->data);
if (t == 6)
- gen_pong(s, rt, pkt);
+ if ((ret = gen_pong(s, rt, pkt)) < 0)
+ return ret;
break;
case RTMP_PT_CLIENT_BW:
if (pkt->data_size < 4) {
@@ -610,6 +863,14 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)
av_log(s, AV_LOG_DEBUG, "Client bandwidth = %d\n", AV_RB32(pkt->data));
rt->client_report_size = AV_RB32(pkt->data) >> 1;
break;
+ case RTMP_PT_SERVER_BW:
+ rt->server_bw = AV_RB32(pkt->data);
+ if (rt->server_bw <= 0) {
+ av_log(s, AV_LOG_ERROR, "Incorrect server bandwidth %d\n", rt->server_bw);
+ return AVERROR(EINVAL);
+ }
+ av_log(s, AV_LOG_DEBUG, "Server bandwidth = %d\n", rt->server_bw);
+ break;
case RTMP_PT_INVOKE:
//TODO: check for the messages sent for wrong state?
if (!memcmp(pkt->data, "\002\000\006_error", 9)) {
@@ -623,14 +884,18 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)
switch (rt->state) {
case STATE_HANDSHAKED:
if (!rt->is_input) {
- gen_release_stream(s, rt);
- gen_fcpublish_stream(s, rt);
+ if ((ret = gen_release_stream(s, rt)) < 0)
+ return ret;
+ if ((ret = gen_fcpublish_stream(s, rt)) < 0)
+ return ret;
rt->state = STATE_RELEASING;
} else {
- gen_server_bw(s, rt);
+ if ((ret = gen_server_bw(s, rt)) < 0)
+ return ret;
rt->state = STATE_CONNECTING;
}
- gen_create_stream(s, rt);
+ if ((ret = gen_create_stream(s, rt)) < 0)
+ return ret;
break;
case STATE_FCPUBLISH:
rt->state = STATE_CONNECTING;
@@ -654,9 +919,13 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)
rt->main_channel_id = av_int2double(AV_RB64(pkt->data + 21));
}
if (rt->is_input) {
- gen_play(s, rt);
+ if ((ret = gen_play(s, rt)) < 0)
+ return ret;
+ if ((ret = gen_buffer_time(s, rt)) < 0)
+ return ret;
} else {
- gen_publish(s, rt);
+ if ((ret = gen_publish(s, rt)) < 0)
+ return ret;
}
rt->state = STATE_READY;
break;
@@ -685,8 +954,14 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)
if (!t && !strcmp(tmpstr, "NetStream.Play.Stop")) rt->state = STATE_STOPPED;
if (!t && !strcmp(tmpstr, "NetStream.Play.UnpublishNotify")) rt->state = STATE_STOPPED;
if (!t && !strcmp(tmpstr, "NetStream.Publish.Start")) rt->state = STATE_PUBLISHING;
+ } else if (!memcmp(pkt->data, "\002\000\010onBWDone", 11)) {
+ if ((ret = gen_check_bw(s, rt)) < 0)
+ return ret;
}
break;
+ default:
+ av_log(s, AV_LOG_VERBOSE, "Unknown packet type received 0x%02X\n", pkt->type);
+ break;
}
return 0;
}
@@ -727,14 +1002,15 @@ static int get_packet(URLContext *s, int for_header)
rt->bytes_read += ret;
if (rt->bytes_read > rt->last_bytes_read + rt->client_report_size) {
av_log(s, AV_LOG_DEBUG, "Sending bytes read report\n");
- gen_bytes_read(s, rt, rpkt.timestamp + 1);
+ if ((ret = gen_bytes_read(s, rt, rpkt.timestamp + 1)) < 0)
+ return ret;
rt->last_bytes_read = rt->bytes_read;
}
ret = rtmp_parse_result(s, rt, &rpkt);
if (ret < 0) {//serious error in current packet
ff_rtmp_packet_destroy(&rpkt);
- return -1;
+ return ret;
}
if (rt->state == STATE_STOPPED) {
ff_rtmp_packet_destroy(&rpkt);
@@ -798,20 +1074,21 @@ static int get_packet(URLContext *s, int for_header)
static int rtmp_close(URLContext *h)
{
RTMPContext *rt = h->priv_data;
+ int ret = 0;
if (!rt->is_input) {
rt->flv_data = NULL;
if (rt->out_pkt.data_size)
ff_rtmp_packet_destroy(&rt->out_pkt);
if (rt->state > STATE_FCPUBLISH)
- gen_fcunpublish_stream(h, rt);
+ ret = gen_fcunpublish_stream(h, rt);
}
if (rt->state > STATE_HANDSHAKED)
- gen_delete_stream(h, rt);
+ ret = gen_delete_stream(h, rt);
av_freep(&rt->flv_data);
ffurl_close(rt->stream);
- return 0;
+ return ret;
}
/**
@@ -837,18 +1114,24 @@ static int rtmp_open(URLContext *s, const char *uri, int flags)
av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port,
path, sizeof(path), s->filename);
- if (port < 0)
- port = RTMP_DEFAULT_PORT;
- ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);
+ if (!strcmp(proto, "rtmpt")) {
+ /* open the http tunneling connection */
+ ff_url_join(buf, sizeof(buf), "rtmphttp", NULL, hostname, port, NULL);
+ } else {
+ /* open the tcp connection */
+ if (port < 0)
+ port = RTMP_DEFAULT_PORT;
+ ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);
+ }
- if (ffurl_open(&rt->stream, buf, AVIO_FLAG_READ_WRITE,
- &s->interrupt_callback, NULL) < 0) {
+ if ((ret = ffurl_open(&rt->stream, buf, AVIO_FLAG_READ_WRITE,
+ &s->interrupt_callback, NULL)) < 0) {
av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf);
goto fail;
}
rt->state = STATE_START;
- if (rtmp_handshake(s, rt))
+ if ((ret = rtmp_handshake(s, rt)) < 0)
goto fail;
rt->chunk_size = 128;
@@ -859,8 +1142,8 @@ static int rtmp_open(URLContext *s, const char *uri, int flags)
rt->app = av_malloc(APP_MAX_LENGTH);
if (!rt->app) {
- rtmp_close(s);
- return AVERROR(ENOMEM);
+ ret = AVERROR(ENOMEM);
+ goto fail;
}
//extract "app" part from path
@@ -868,14 +1151,16 @@ static int rtmp_open(URLContext *s, const char *uri, int flags)
fname = path + 10;
memcpy(rt->app, "ondemand", 9);
} else {
- char *p = strchr(path + 1, '/');
+ char *next = *path ? path + 1 : path;
+ char *p = strchr(next, '/');
if (!p) {
- fname = path + 1;
+ fname = next;
rt->app[0] = '\0';
} else {
+ // make sure we do not mismatch a playpath for an application instance
char *c = strchr(p + 1, ':');
fname = strchr(p + 1, '/');
- if (!fname || c < fname) {
+ if (!fname || (c && c < fname)) {
fname = p + 1;
av_strlcpy(rt->app, path + 1, p - path);
} else {
@@ -892,29 +1177,61 @@ static int rtmp_open(URLContext *s, const char *uri, int flags)
}
if (!rt->playpath) {
+ int len = strlen(fname);
+
rt->playpath = av_malloc(PLAYPATH_MAX_LENGTH);
if (!rt->playpath) {
- rtmp_close(s);
- return AVERROR(ENOMEM);
+ ret = AVERROR(ENOMEM);
+ goto fail;
}
- if (!strchr(fname, ':') &&
- (!strcmp(fname + strlen(fname) - 4, ".f4v") ||
- !strcmp(fname + strlen(fname) - 4, ".mp4"))) {
+ if (!strchr(fname, ':') && len >= 4 &&
+ (!strcmp(fname + len - 4, ".f4v") ||
+ !strcmp(fname + len - 4, ".mp4"))) {
memcpy(rt->playpath, "mp4:", 5);
+ } else if (len >= 4 && !strcmp(fname + len - 4, ".flv")) {
+ fname[len - 4] = '\0';
} else {
rt->playpath[0] = 0;
}
strncat(rt->playpath, fname, PLAYPATH_MAX_LENGTH - 5);
}
+ if (!rt->tcurl) {
+ rt->tcurl = av_malloc(TCURL_MAX_LENGTH);
+ if (!rt->tcurl) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ ff_url_join(rt->tcurl, TCURL_MAX_LENGTH, proto, NULL, hostname,
+ port, "/%s", rt->app);
+ }
+
+ if (!rt->flashver) {
+ rt->flashver = av_malloc(FLASHVER_MAX_LENGTH);
+ if (!rt->flashver) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ if (rt->is_input) {
+ snprintf(rt->flashver, FLASHVER_MAX_LENGTH, "%s %d,%d,%d,%d",
+ RTMP_CLIENT_PLATFORM, RTMP_CLIENT_VER1, RTMP_CLIENT_VER2,
+ RTMP_CLIENT_VER3, RTMP_CLIENT_VER4);
+ } else {
+ snprintf(rt->flashver, FLASHVER_MAX_LENGTH,
+ "FMLE/3.0 (compatible; %s)", LIBAVFORMAT_IDENT);
+ }
+ }
+
rt->client_report_size = 1048576;
rt->bytes_read = 0;
rt->last_bytes_read = 0;
+ rt->server_bw = 2500000;
av_log(s, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n",
proto, path, rt->app, rt->playpath);
- gen_connect(s, rt, proto, hostname, port);
+ if ((ret = gen_connect(s, rt)) < 0)
+ goto fail;
do {
ret = get_packet(s, 1);
@@ -941,7 +1258,7 @@ static int rtmp_open(URLContext *s, const char *uri, int flags)
fail:
rtmp_close(s);
- return AVERROR(EIO);
+ return ret;
}
static int rtmp_read(URLContext *s, uint8_t *buf, int size)
@@ -978,6 +1295,8 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
int pktsize, pkttype;
uint32_t ts;
const uint8_t *buf_temp = buf;
+ uint8_t c;
+ int ret;
do {
if (rt->skip_bytes) {
@@ -1013,7 +1332,10 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
}
//this can be a big packet, it's better to send it right here
- ff_rtmp_packet_create(&rt->out_pkt, RTMP_SOURCE_CHANNEL, pkttype, ts, pktsize);
+ if ((ret = ff_rtmp_packet_create(&rt->out_pkt, RTMP_SOURCE_CHANNEL,
+ pkttype, ts, pktsize)) < 0)
+ return ret;
+
rt->out_pkt.extra = rt->main_channel_id;
rt->flv_data = rt->out_pkt.data;
@@ -1034,13 +1356,49 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
if (rt->flv_off == rt->flv_size) {
rt->skip_bytes = 4;
- ff_rtmp_packet_write(rt->stream, &rt->out_pkt, rt->chunk_size, rt->prev_pkt[1]);
+ if ((ret = ff_rtmp_packet_write(rt->stream, &rt->out_pkt,
+ rt->chunk_size, rt->prev_pkt[1])) < 0)
+ return ret;
ff_rtmp_packet_destroy(&rt->out_pkt);
rt->flv_size = 0;
rt->flv_off = 0;
rt->flv_header_bytes = 0;
+ rt->flv_nb_packets++;
}
} while (buf_temp - buf < size);
+
+ if (rt->flv_nb_packets < rt->flush_interval)
+ return size;
+ rt->flv_nb_packets = 0;
+
+ /* set stream into nonblocking mode */
+ rt->stream->flags |= AVIO_FLAG_NONBLOCK;
+
+ /* try to read one byte from the stream */
+ ret = ffurl_read(rt->stream, &c, 1);
+
+ /* switch the stream back into blocking mode */
+ rt->stream->flags &= ~AVIO_FLAG_NONBLOCK;
+
+ if (ret == AVERROR(EAGAIN)) {
+ /* no incoming data to handle */
+ return size;
+ } else if (ret < 0) {
+ return ret;
+ } else if (ret == 1) {
+ RTMPPacket rpkt = { 0 };
+
+ if ((ret = ff_rtmp_packet_read_internal(rt->stream, &rpkt,
+ rt->chunk_size,
+ rt->prev_pkt[0], c)) <= 0)
+ return ret;
+
+ if ((ret = rtmp_parse_result(s, rt, &rpkt)) < 0)
+ return ret;
+
+ ff_rtmp_packet_destroy(&rpkt);
+ }
+
return size;
}
@@ -1050,7 +1408,17 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
static const AVOption rtmp_options[] = {
{"rtmp_app", "Name of application to connect to on the RTMP server", OFFSET(app), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
+ {"rtmp_buffer", "Set buffer time in milliseconds. The default is 3000.", OFFSET(client_buffer_time), AV_OPT_TYPE_INT, {3000}, 0, INT_MAX, DEC|ENC},
+ {"rtmp_conn", "Append arbitrary AMF data to the Connect message", OFFSET(conn), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
+ {"rtmp_flashver", "Version of the Flash plugin used to run the SWF player.", OFFSET(flashver), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
+ {"rtmp_flush_interval", "Number of packets flushed in the same request (RTMPT only).", OFFSET(flush_interval), AV_OPT_TYPE_INT, {10}, 0, INT_MAX, ENC},
+ {"rtmp_live", "Specify that the media is a live stream.", OFFSET(live), AV_OPT_TYPE_INT, {-2}, INT_MIN, INT_MAX, DEC, "rtmp_live"},
+ {"any", "both", 0, AV_OPT_TYPE_CONST, {-2}, 0, 0, DEC, "rtmp_live"},
+ {"live", "live stream", 0, AV_OPT_TYPE_CONST, {-1}, 0, 0, DEC, "rtmp_live"},
+ {"recorded", "recorded stream", 0, AV_OPT_TYPE_CONST, {0}, 0, 0, DEC, "rtmp_live"},
{"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
+ {"rtmp_swfurl", "URL of the SWF player. By default no value will be sent", OFFSET(swfurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
+ {"rtmp_tcurl", "URL of the target stream. Defaults to rtmp://host[:port]/app.", OFFSET(tcurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
{ NULL },
};
@@ -1071,3 +1439,21 @@ URLProtocol ff_rtmp_protocol = {
.flags = URL_PROTOCOL_FLAG_NETWORK,
.priv_data_class= &rtmp_class,
};
+
+static const AVClass rtmpt_class = {
+ .class_name = "rtmpt",
+ .item_name = av_default_item_name,
+ .option = rtmp_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+URLProtocol ff_rtmpt_protocol = {
+ .name = "rtmpt",
+ .url_open = rtmp_open,
+ .url_read = rtmp_read,
+ .url_write = rtmp_write,
+ .url_close = rtmp_close,
+ .priv_data_size = sizeof(RTMPContext),
+ .flags = URL_PROTOCOL_FLAG_NETWORK,
+ .priv_data_class = &rtmpt_class,
+};
diff --git a/libavformat/rtp.h b/libavformat/rtp.h
index e9f8778..0ffe18f 100644
--- a/libavformat/rtp.h
+++ b/libavformat/rtp.h
@@ -77,7 +77,7 @@ enum CodecID ff_rtp_codec_id(const char *buf, enum AVMediaType codec_type);
#define RTCP_TX_RATIO_DEN 1000
/* An arbitrary id value for RTP Xiph streams - only relevant to indicate
- * the the configuration has changed within a stream (by changing the
+ * that the configuration has changed within a stream (by changing the
* ident value sent).
*/
#define RTP_XIPH_IDENT 0xfecdba
diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c
index 41e6eb4..87d9255 100644
--- a/libavformat/rtpdec.c
+++ b/libavformat/rtpdec.c
@@ -26,7 +26,6 @@
#include "mpegts.h"
#include "url.h"
-#include <unistd.h>
#include "network.h"
#include "rtpdec.h"
@@ -68,6 +67,7 @@ void av_register_rtp_dynamic_payload_handlers(void)
ff_register_dynamic_payload_handler(&ff_h263_2000_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_h263_rfc2190_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_h264_dynamic_handler);
+ ff_register_dynamic_payload_handler(&ff_ilbc_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_vorbis_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_theora_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_qdm2_dynamic_handler);
diff --git a/libavformat/rtpdec_formats.h b/libavformat/rtpdec_formats.h
index 60edecb..aaa1809 100644
--- a/libavformat/rtpdec_formats.h
+++ b/libavformat/rtpdec_formats.h
@@ -45,6 +45,7 @@ extern RTPDynamicProtocolHandler ff_h263_1998_dynamic_handler;
extern RTPDynamicProtocolHandler ff_h263_2000_dynamic_handler;
extern RTPDynamicProtocolHandler ff_h263_rfc2190_dynamic_handler;
extern RTPDynamicProtocolHandler ff_h264_dynamic_handler;
+extern RTPDynamicProtocolHandler ff_ilbc_dynamic_handler;
extern RTPDynamicProtocolHandler ff_mp4a_latm_dynamic_handler;
extern RTPDynamicProtocolHandler ff_mp4v_es_dynamic_handler;
extern RTPDynamicProtocolHandler ff_mpeg4_generic_dynamic_handler;
diff --git a/libavformat/rtpdec_h263_rfc2190.c b/libavformat/rtpdec_h263_rfc2190.c
index a3a4825..92102f3 100644
--- a/libavformat/rtpdec_h263_rfc2190.c
+++ b/libavformat/rtpdec_h263_rfc2190.c
@@ -132,7 +132,7 @@ static int h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
if (!data->buf) {
/* Check the picture start code, only start buffering a new frame
* if this is correct */
- if (!f && len > 4 && AV_RB32(buf) >> 10 == 0x20) {
+ if (len > 4 && AV_RB32(buf) >> 10 == 0x20) {
int ret = avio_open_dyn_buf(&data->buf);
if (ret < 0)
return ret;
diff --git a/libavformat/rtpdec_h264.c b/libavformat/rtpdec_h264.c
index 32a57d3..c192d97 100644
--- a/libavformat/rtpdec_h264.c
+++ b/libavformat/rtpdec_h264.c
@@ -20,7 +20,7 @@
*/
/**
-* @file
+ * @file
* @brief H.264 / RTP Code (RFC3984)
* @author Ryan Martell <rdm4 at martellventures.com>
*
@@ -29,11 +29,8 @@
* This currently supports packetization mode:
* Single Nal Unit Mode (0), or
* Non-Interleaved Mode (1). It currently does not support
- * Interleaved Mode (2). (This requires implementing STAP-B, MTAP16, MTAP24, FU-B packet types)
- *
- * @note TODO:
- * 1) RTCP sender reports for udp streams are required..
- *
+ * Interleaved Mode (2). (This requires implementing STAP-B, MTAP16, MTAP24,
+ * FU-B packet types)
*/
#include "libavutil/base64.h"
@@ -42,35 +39,33 @@
#include "avformat.h"
#include "mpegts.h"
-#include <unistd.h>
#include "network.h"
#include <assert.h>
#include "rtpdec.h"
#include "rtpdec_formats.h"
-/**
- RTP/H264 specific private data.
-*/
struct PayloadContext {
- unsigned long cookie; ///< sanity check, to make sure we get the pointer we're expecting.
-
- //sdp setup parameters
- uint8_t profile_idc; ///< from the sdp setup parameters.
- uint8_t profile_iop; ///< from the sdp setup parameters.
- uint8_t level_idc; ///< from the sdp setup parameters.
- int packetization_mode; ///< from the sdp setup parameters.
+ // sdp setup parameters
+ uint8_t profile_idc;
+ uint8_t profile_iop;
+ uint8_t level_idc;
+ int packetization_mode;
#ifdef DEBUG
int packet_types_received[32];
#endif
};
-#define MAGIC_COOKIE (0xdeadbeef) ///< Cookie for the extradata; to verify we are what we think we are, and that we haven't been freed.
-#define DEAD_COOKIE (0xdeaddead) ///< Cookie for the extradata; once it is freed.
+#ifdef DEBUG
+#define COUNT_NAL_TYPE(data, nal) data->packet_types_received[(nal) & 0x1f]++
+#else
+#define COUNT_NAL_TYPE(data, nal) do { } while (0)
+#endif
+
+static const uint8_t start_sequence[] = { 0, 0, 0, 1 };
-/* ---------------- private code */
-static int sdp_parse_fmtp_config_h264(AVStream * stream,
- PayloadContext * h264_data,
+static int sdp_parse_fmtp_config_h264(AVStream *stream,
+ PayloadContext *h264_data,
char *attr, char *value)
{
AVCodecContext *codec = stream->codec;
@@ -81,14 +76,15 @@ static int sdp_parse_fmtp_config_h264(AVStream * stream,
av_log(codec, AV_LOG_DEBUG, "RTP Packetization Mode: %d\n", atoi(value));
h264_data->packetization_mode = atoi(value);
/*
- Packetization Mode:
- 0 or not present: Single NAL mode (Only nals from 1-23 are allowed)
- 1: Non-interleaved Mode: 1-23, 24 (STAP-A), 28 (FU-A) are allowed.
- 2: Interleaved Mode: 25 (STAP-B), 26 (MTAP16), 27 (MTAP24), 28 (FU-A), and 29 (FU-B) are allowed.
+ * Packetization Mode:
+ * 0 or not present: Single NAL mode (Only nals from 1-23 are allowed)
+ * 1: Non-interleaved Mode: 1-23, 24 (STAP-A), 28 (FU-A) are allowed.
+ * 2: Interleaved Mode: 25 (STAP-B), 26 (MTAP16), 27 (MTAP24), 28 (FU-A),
+ * and 29 (FU-B) are allowed.
*/
if (h264_data->packetization_mode > 1)
av_log(codec, AV_LOG_ERROR,
- "Interleaved RTP mode is not supported yet.");
+ "Interleaved RTP mode is not supported yet.\n");
} else if (!strcmp(attr, "profile-level-id")) {
if (strlen(value) == 6) {
char buffer[3];
@@ -97,25 +93,27 @@ static int sdp_parse_fmtp_config_h264(AVStream * stream,
uint8_t profile_iop;
uint8_t level_idc;
- buffer[0] = value[0]; buffer[1] = value[1]; buffer[2] = '\0';
+ buffer[0] = value[0];
+ buffer[1] = value[1];
+ buffer[2] = '\0';
profile_idc = strtol(buffer, NULL, 16);
- buffer[0] = value[2]; buffer[1] = value[3];
+ buffer[0] = value[2];
+ buffer[1] = value[3];
profile_iop = strtol(buffer, NULL, 16);
- buffer[0] = value[4]; buffer[1] = value[5];
- level_idc = strtol(buffer, NULL, 16);
+ buffer[0] = value[4];
+ buffer[1] = value[5];
+ level_idc = strtol(buffer, NULL, 16);
- // set the parameters...
av_log(codec, AV_LOG_DEBUG,
"RTP Profile IDC: %x Profile IOP: %x Level: %x\n",
profile_idc, profile_iop, level_idc);
h264_data->profile_idc = profile_idc;
h264_data->profile_iop = profile_iop;
- h264_data->level_idc = level_idc;
+ h264_data->level_idc = level_idc;
}
- } else if (!strcmp(attr, "sprop-parameter-sets")) {
- uint8_t start_sequence[] = { 0, 0, 0, 1 };
- codec->extradata_size= 0;
- codec->extradata= NULL;
+ } else if (!strcmp(attr, "sprop-parameter-sets")) {
+ codec->extradata_size = 0;
+ av_freep(&codec->extradata);
while (*value) {
char base64packet[1024];
@@ -132,127 +130,126 @@ static int sdp_parse_fmtp_config_h264(AVStream * stream,
if (*value == ',')
value++;
- packet_size= av_base64_decode(decoded_packet, base64packet, sizeof(decoded_packet));
+ packet_size = av_base64_decode(decoded_packet, base64packet,
+ sizeof(decoded_packet));
if (packet_size > 0) {
uint8_t *dest = av_malloc(packet_size + sizeof(start_sequence) +
- codec->extradata_size +
- FF_INPUT_BUFFER_PADDING_SIZE);
- if(dest)
- {
- if(codec->extradata_size)
- {
- // av_realloc?
- memcpy(dest, codec->extradata, codec->extradata_size);
- av_free(codec->extradata);
- }
-
- memcpy(dest+codec->extradata_size, start_sequence, sizeof(start_sequence));
- memcpy(dest+codec->extradata_size+sizeof(start_sequence), decoded_packet, packet_size);
- memset(dest+codec->extradata_size+sizeof(start_sequence)+
- packet_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
-
- codec->extradata= dest;
- codec->extradata_size+= sizeof(start_sequence)+packet_size;
- } else {
- av_log(codec, AV_LOG_ERROR, "Unable to allocate memory for extradata!");
+ codec->extradata_size +
+ FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!dest) {
+ av_log(codec, AV_LOG_ERROR,
+ "Unable to allocate memory for extradata!\n");
return AVERROR(ENOMEM);
}
+ if (codec->extradata_size) {
+ memcpy(dest, codec->extradata, codec->extradata_size);
+ av_free(codec->extradata);
+ }
+
+ memcpy(dest + codec->extradata_size, start_sequence,
+ sizeof(start_sequence));
+ memcpy(dest + codec->extradata_size + sizeof(start_sequence),
+ decoded_packet, packet_size);
+ memset(dest + codec->extradata_size + sizeof(start_sequence) +
+ packet_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+
+ codec->extradata = dest;
+ codec->extradata_size += sizeof(start_sequence) + packet_size;
}
}
- av_log(codec, AV_LOG_DEBUG, "Extradata set to %p (size: %d)!", codec->extradata, codec->extradata_size);
+ av_log(codec, AV_LOG_DEBUG, "Extradata set to %p (size: %d)!\n",
+ codec->extradata, codec->extradata_size);
}
return 0;
}
-// return 0 on packet, no more left, 1 on packet, 1 on partial packet...
-static int h264_handle_packet(AVFormatContext *ctx,
- PayloadContext *data,
- AVStream *st,
- AVPacket * pkt,
- uint32_t * timestamp,
- const uint8_t * buf,
- int len, int flags)
+// return 0 on packet, no more left, 1 on packet, 1 on partial packet
+static int h264_handle_packet(AVFormatContext *ctx, PayloadContext *data,
+ AVStream *st, AVPacket *pkt, uint32_t *timestamp,
+ const uint8_t *buf, int len, int flags)
{
- uint8_t nal = buf[0];
- uint8_t type = (nal & 0x1f);
- int result= 0;
- uint8_t start_sequence[] = { 0, 0, 0, 1 };
+ uint8_t nal;
+ uint8_t type;
+ int result = 0;
+
+ if (!len) {
+ av_log(ctx, AV_LOG_ERROR, "Empty H264 RTP packet\n");
+ return AVERROR_INVALIDDATA;
+ }
+ nal = buf[0];
+ type = nal & 0x1f;
-#ifdef DEBUG
assert(data);
- assert(data->cookie == MAGIC_COOKIE);
-#endif
assert(buf);
+ /* Simplify the case (these are all the nal types used internally by
+ * the h264 codec). */
if (type >= 1 && type <= 23)
- type = 1; // simplify the case. (these are all the nal types used internally by the h264 codec)
+ type = 1;
switch (type) {
case 0: // undefined, but pass them through
case 1:
- av_new_packet(pkt, len+sizeof(start_sequence));
+ av_new_packet(pkt, len + sizeof(start_sequence));
memcpy(pkt->data, start_sequence, sizeof(start_sequence));
- memcpy(pkt->data+sizeof(start_sequence), buf, len);
-#ifdef DEBUG
- data->packet_types_received[nal & 0x1f]++;
-#endif
+ memcpy(pkt->data + sizeof(start_sequence), buf, len);
+ COUNT_NAL_TYPE(data, nal);
break;
case 24: // STAP-A (one packet, multiple nals)
// consume the STAP-A NAL
buf++;
len--;
- // first we are going to figure out the total size....
+ // first we are going to figure out the total size
{
- int pass= 0;
- int total_length= 0;
- uint8_t *dst= NULL;
+ int pass = 0;
+ int total_length = 0;
+ uint8_t *dst = NULL;
- for(pass= 0; pass<2; pass++) {
- const uint8_t *src= buf;
- int src_len= len;
+ for (pass = 0; pass < 2; pass++) {
+ const uint8_t *src = buf;
+ int src_len = len;
- do {
- uint16_t nal_size = AV_RB16(src); // this going to be a problem if unaligned (can it be?)
+ while (src_len > 2) {
+ uint16_t nal_size = AV_RB16(src);
- // consume the length of the aggregate...
- src += 2;
+ // consume the length of the aggregate
+ src += 2;
src_len -= 2;
if (nal_size <= src_len) {
- if(pass==0) {
- // counting...
- total_length+= sizeof(start_sequence)+nal_size;
+ if (pass == 0) {
+ // counting
+ total_length += sizeof(start_sequence) + nal_size;
} else {
// copying
assert(dst);
memcpy(dst, start_sequence, sizeof(start_sequence));
- dst+= sizeof(start_sequence);
+ dst += sizeof(start_sequence);
memcpy(dst, src, nal_size);
-#ifdef DEBUG
- data->packet_types_received[*src & 0x1f]++;
-#endif
- dst+= nal_size;
+ COUNT_NAL_TYPE(data, *src);
+ dst += nal_size;
}
} else {
av_log(ctx, AV_LOG_ERROR,
"nal size exceeds length: %d %d\n", nal_size, src_len);
}
- // eat what we handled...
- src += nal_size;
+ // eat what we handled
+ src += nal_size;
src_len -= nal_size;
if (src_len < 0)
av_log(ctx, AV_LOG_ERROR,
"Consumed more bytes than we got! (%d)\n", src_len);
- } while (src_len > 2); // because there could be rtp padding..
+ }
- if(pass==0) {
- // now we know the total size of the packet (with the start sequences added)
+ if (pass == 0) {
+ /* now we know the total size of the packet (with the
+ * start sequences added) */
av_new_packet(pkt, total_length);
- dst= pkt->data;
+ dst = pkt->data;
} else {
- assert(dst-pkt->data==total_length);
+ assert(dst - pkt->data == total_length);
}
}
}
@@ -265,51 +262,54 @@ static int h264_handle_packet(AVFormatContext *ctx,
av_log(ctx, AV_LOG_ERROR,
"Unhandled type (%d) (See RFC for implementation details\n",
type);
- result= -1;
+ result = AVERROR(ENOSYS);
break;
case 28: // FU-A (fragmented nal)
buf++;
- len--; // skip the fu_indicator
- {
- // these are the same as above, we just redo them here for clarity...
- uint8_t fu_indicator = nal;
- uint8_t fu_header = *buf; // read the fu_header.
- uint8_t start_bit = fu_header >> 7;
-// uint8_t end_bit = (fu_header & 0x40) >> 6;
- uint8_t nal_type = (fu_header & 0x1f);
+ len--; // skip the fu_indicator
+ if (len > 1) {
+ // these are the same as above, we just redo them here for clarity
+ uint8_t fu_indicator = nal;
+ uint8_t fu_header = *buf;
+ uint8_t start_bit = fu_header >> 7;
+ uint8_t av_unused end_bit = (fu_header & 0x40) >> 6;
+ uint8_t nal_type = fu_header & 0x1f;
uint8_t reconstructed_nal;
- // reconstruct this packet's true nal; only the data follows..
- reconstructed_nal = fu_indicator & (0xe0); // the original nal forbidden bit and NRI are stored in this packet's nal;
+ // Reconstruct this packet's true nal; only the data follows.
+ /* The original nal forbidden bit and NRI are stored in this
+ * packet's nal. */
+ reconstructed_nal = fu_indicator & 0xe0;
reconstructed_nal |= nal_type;
- // skip the fu_header...
+ // skip the fu_header
buf++;
len--;
-#ifdef DEBUG
if (start_bit)
- data->packet_types_received[nal_type]++;
-#endif
- if(start_bit) {
- // copy in the start sequence, and the reconstructed nal....
- av_new_packet(pkt, sizeof(start_sequence)+sizeof(nal)+len);
+ COUNT_NAL_TYPE(data, nal_type);
+ if (start_bit) {
+ /* copy in the start sequence, and the reconstructed nal */
+ av_new_packet(pkt, sizeof(start_sequence) + sizeof(nal) + len);
memcpy(pkt->data, start_sequence, sizeof(start_sequence));
- pkt->data[sizeof(start_sequence)]= reconstructed_nal;
- memcpy(pkt->data+sizeof(start_sequence)+sizeof(nal), buf, len);
+ pkt->data[sizeof(start_sequence)] = reconstructed_nal;
+ memcpy(pkt->data + sizeof(start_sequence) + sizeof(nal), buf, len);
} else {
av_new_packet(pkt, len);
memcpy(pkt->data, buf, len);
}
+ } else {
+ av_log(ctx, AV_LOG_ERROR, "Too short data for FU-A H264 RTP packet\n");
+ result = AVERROR_INVALIDDATA;
}
break;
case 30: // undefined
case 31: // undefined
default:
- av_log(ctx, AV_LOG_ERROR, "Undefined type (%d)", type);
- result= -1;
+ av_log(ctx, AV_LOG_ERROR, "Undefined type (%d)\n", type);
+ result = AVERROR_INVALIDDATA;
break;
}
@@ -318,18 +318,9 @@ static int h264_handle_packet(AVFormatContext *ctx,
return result;
}
-/* ---------------- public code */
static PayloadContext *h264_new_context(void)
{
- PayloadContext *data =
- av_mallocz(sizeof(PayloadContext) +
- FF_INPUT_BUFFER_PADDING_SIZE);
-
- if (data) {
- data->cookie = MAGIC_COOKIE;
- }
-
- return data;
+ return av_mallocz(sizeof(PayloadContext) + FF_INPUT_BUFFER_PADDING_SIZE);
}
static void h264_free_context(PayloadContext *data)
@@ -344,13 +335,6 @@ static void h264_free_context(PayloadContext *data)
}
#endif
- assert(data);
- assert(data->cookie == MAGIC_COOKIE);
-
- // avoid stale pointers (assert)
- data->cookie = DEAD_COOKIE;
-
- // and clear out this...
av_free(data);
}
@@ -365,26 +349,27 @@ static int parse_h264_sdp_line(AVFormatContext *s, int st_index,
return 0;
stream = s->streams[st_index];
- codec = stream->codec;
- assert(h264_data->cookie == MAGIC_COOKIE);
+ codec = stream->codec;
if (av_strstart(p, "framesize:", &p)) {
char buf1[50];
char *dst = buf1;
- // remove the protocol identifier..
- while (*p && *p == ' ') p++; // strip spaces.
- while (*p && *p != ' ') p++; // eat protocol identifier
- while (*p && *p == ' ') p++; // strip trailing spaces.
- while (*p && *p != '-' && (dst - buf1) < sizeof(buf1) - 1) {
+ // remove the protocol identifier
+ while (*p && *p == ' ')
+ p++; // strip spaces.
+ while (*p && *p != ' ')
+ p++; // eat protocol identifier
+ while (*p && *p == ' ')
+ p++; // strip trailing spaces.
+ while (*p && *p != '-' && (dst - buf1) < sizeof(buf1) - 1)
*dst++ = *p++;
- }
*dst = '\0';
// a='framesize:96 320-240'
- // set our parameters..
- codec->width = atoi(buf1);
- codec->height = atoi(p + 1); // skip the -
+ // set our parameters
+ codec->width = atoi(buf1);
+ codec->height = atoi(p + 1); // skip the -
codec->pix_fmt = PIX_FMT_YUV420P;
} else if (av_strstart(p, "fmtp:", &p)) {
return ff_parse_fmtp(stream, h264_data, p, sdp_parse_fmtp_config_h264);
@@ -392,12 +377,9 @@ static int parse_h264_sdp_line(AVFormatContext *s, int st_index,
// could use this if we wanted.
}
- return 0; // keep processing it the normal way...
+ return 0;
}
-/**
-This is the structure for expanding on the dynamic rtp protocols (makes everything static. yay!)
-*/
RTPDynamicProtocolHandler ff_h264_dynamic_handler = {
.enc_name = "H264",
.codec_type = AVMEDIA_TYPE_VIDEO,
diff --git a/libavformat/rtpdec_ilbc.c b/libavformat/rtpdec_ilbc.c
new file mode 100644
index 0000000..7159dcf
--- /dev/null
+++ b/libavformat/rtpdec_ilbc.c
@@ -0,0 +1,73 @@
+/*
+ * RTP iLBC Depacketizer, RFC 3952
+ * Copyright (c) 2012 Martin Storsjo
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avformat.h"
+#include "rtpdec_formats.h"
+#include "libavutil/avstring.h"
+
+static int ilbc_parse_fmtp(AVStream *stream, PayloadContext *data,
+ char *attr, char *value)
+{
+ if (!strcmp(attr, "mode")) {
+ int mode = atoi(value);
+ switch (mode) {
+ case 20:
+ stream->codec->block_align = 38;
+ break;
+ case 30:
+ stream->codec->block_align = 50;
+ break;
+ default:
+ av_log(NULL, AV_LOG_ERROR, "Unsupported iLBC mode %d\n", mode);
+ return AVERROR(EINVAL);
+ }
+ }
+ return 0;
+}
+
+static int ilbc_parse_sdp_line(AVFormatContext *s, int st_index,
+ PayloadContext *data, const char *line)
+{
+ const char *p;
+ AVStream *st;
+
+ if (st_index < 0)
+ return 0;
+ st = s->streams[st_index];
+
+ if (av_strstart(line, "fmtp:", &p)) {
+ int ret = ff_parse_fmtp(st, data, p, ilbc_parse_fmtp);
+ if (ret < 0)
+ return ret;
+ if (!st->codec->block_align) {
+ av_log(s, AV_LOG_ERROR, "No iLBC mode set\n");
+ return AVERROR(EINVAL);
+ }
+ }
+ return 0;
+}
+
+RTPDynamicProtocolHandler ff_ilbc_dynamic_handler = {
+ .enc_name = "iLBC",
+ .codec_type = AVMEDIA_TYPE_AUDIO,
+ .codec_id = CODEC_ID_ILBC,
+ .parse_sdp_a_line = ilbc_parse_sdp_line,
+};
diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c
index 29fc2f4..9cf1a16 100644
--- a/libavformat/rtpenc.c
+++ b/libavformat/rtpenc.c
@@ -33,6 +33,7 @@
static const AVOption options[] = {
FF_RTP_FLAG_OPTS(RTPMuxContext, flags)
{ "payload_type", "Specify RTP payload type", offsetof(RTPMuxContext, payload_type), AV_OPT_TYPE_INT, {.dbl = -1 }, -1, 127, AV_OPT_FLAG_ENCODING_PARAM },
+ { "ssrc", "Stream identifier", offsetof(RTPMuxContext, ssrc), AV_OPT_TYPE_INT, { 0 }, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
{ NULL },
};
@@ -73,6 +74,7 @@ static int is_supported(enum CodecID id)
case CODEC_ID_VP8:
case CODEC_ID_ADPCM_G722:
case CODEC_ID_ADPCM_G726:
+ case CODEC_ID_ILBC:
return 1;
default:
return 0;
@@ -101,7 +103,8 @@ static int rtp_write_header(AVFormatContext *s1)
s->base_timestamp = av_get_random_seed();
s->timestamp = s->base_timestamp;
s->cur_timestamp = 0;
- s->ssrc = av_get_random_seed();
+ if (!s->ssrc)
+ s->ssrc = av_get_random_seed();
s->first_packet = 1;
s->first_rtcp_ntp_time = ff_ntp_time();
if (s1->start_time_realtime)
@@ -185,6 +188,16 @@ static int rtp_write_header(AVFormatContext *s1)
* 8000, even if the sample rate is 16000. See RFC 3551. */
avpriv_set_pts_info(st, 32, 1, 8000);
break;
+ case CODEC_ID_ILBC:
+ if (st->codec->block_align != 38 && st->codec->block_align != 50) {
+ av_log(s1, AV_LOG_ERROR, "Incorrect iLBC block size specified\n");
+ goto fail;
+ }
+ if (!s->max_frames_per_packet)
+ s->max_frames_per_packet = 1;
+ s->max_frames_per_packet = FFMIN(s->max_frames_per_packet,
+ s->max_payload_size / st->codec->block_align);
+ goto defaultcase;
case CODEC_ID_AMR_NB:
case CODEC_ID_AMR_WB:
if (!s->max_frames_per_packet)
@@ -196,11 +209,11 @@ static int rtp_write_header(AVFormatContext *s1)
/* max_header_toc_size + the largest AMR payload must fit */
if (1 + s->max_frames_per_packet + n > s->max_payload_size) {
av_log(s1, AV_LOG_ERROR, "RTP max payload size too small for AMR\n");
- return -1;
+ goto fail;
}
if (st->codec->channels != 1) {
av_log(s1, AV_LOG_ERROR, "Only mono is supported\n");
- return -1;
+ goto fail;
}
case CODEC_ID_AAC:
s->num_frames = 0;
@@ -214,6 +227,10 @@ defaultcase:
}
return 0;
+
+fail:
+ av_freep(&s->buf);
+ return AVERROR(EINVAL);
}
/* send an rtcp sender report packet */
@@ -389,6 +406,36 @@ static void rtp_send_mpegts_raw(AVFormatContext *s1,
}
}
+static int rtp_send_ilbc(AVFormatContext *s1, const uint8_t *buf, int size)
+{
+ RTPMuxContext *s = s1->priv_data;
+ AVStream *st = s1->streams[0];
+ int frame_duration = av_get_audio_frame_duration(st->codec, 0);
+ int frame_size = st->codec->block_align;
+ int frames = size / frame_size;
+
+ while (frames > 0) {
+ int n = FFMIN(s->max_frames_per_packet - s->num_frames, frames);
+
+ if (!s->num_frames) {
+ s->buf_ptr = s->buf;
+ s->timestamp = s->cur_timestamp;
+ }
+ memcpy(s->buf_ptr, buf, n * frame_size);
+ frames -= n;
+ s->num_frames += n;
+ s->buf_ptr += n * frame_size;
+ buf += n * frame_size;
+ s->cur_timestamp += n * frame_duration;
+
+ if (s->num_frames == s->max_frames_per_packet) {
+ ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 1);
+ s->num_frames = 0;
+ }
+ }
+ return 0;
+}
+
static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
{
RTPMuxContext *s = s1->priv_data;
@@ -477,6 +524,9 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
case CODEC_ID_VP8:
ff_rtp_send_vp8(s1, pkt->data, size);
break;
+ case CODEC_ID_ILBC:
+ rtp_send_ilbc(s1, pkt->data, size);
+ break;
default:
/* better than nothing : send the codec raw data */
rtp_send_raw(s1, pkt->data, size);
diff --git a/libavformat/rtpenc.h b/libavformat/rtpenc.h
index b8a3fd1..f81cc7a 100644
--- a/libavformat/rtpenc.h
+++ b/libavformat/rtpenc.h
@@ -66,12 +66,14 @@ typedef struct RTPMuxContext RTPMuxContext;
#define FF_RTP_FLAG_MP4A_LATM 1
#define FF_RTP_FLAG_RFC2190 2
#define FF_RTP_FLAG_SKIP_RTCP 4
+#define FF_RTP_FLAG_H264_MODE0 8
#define FF_RTP_FLAG_OPTS(ctx, fieldname) \
{ "rtpflags", "RTP muxer flags", offsetof(ctx, fieldname), AV_OPT_TYPE_FLAGS, {.dbl = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, \
{ "latm", "Use MP4A-LATM packetization instead of MPEG4-GENERIC for AAC", 0, AV_OPT_TYPE_CONST, {.dbl = FF_RTP_FLAG_MP4A_LATM}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, \
{ "rfc2190", "Use RFC 2190 packetization instead of RFC 4629 for H.263", 0, AV_OPT_TYPE_CONST, {.dbl = FF_RTP_FLAG_RFC2190}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, \
{ "skip_rtcp", "Don't send RTCP sender reports", 0, AV_OPT_TYPE_CONST, {.dbl = FF_RTP_FLAG_SKIP_RTCP}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, \
+ { "h264_mode0", "Use mode 0 for H264 in RTP", 0, AV_OPT_TYPE_CONST, {.dbl = FF_RTP_FLAG_H264_MODE0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, \
void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m);
diff --git a/libavformat/rtpenc_chain.c b/libavformat/rtpenc_chain.c
index 16b38d6..3742099 100644
--- a/libavformat/rtpenc_chain.c
+++ b/libavformat/rtpenc_chain.c
@@ -25,27 +25,31 @@
#include "avio_internal.h"
#include "libavutil/opt.h"
-AVFormatContext *ff_rtp_chain_mux_open(AVFormatContext *s, AVStream *st,
- URLContext *handle, int packet_size)
+int ff_rtp_chain_mux_open(AVFormatContext **out, AVFormatContext *s,
+ AVStream *st, URLContext *handle, int packet_size)
{
- AVFormatContext *rtpctx;
+ AVFormatContext *rtpctx = NULL;
int ret;
AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL);
uint8_t *rtpflags;
AVDictionary *opts = NULL;
- if (!rtp_format)
- return NULL;
+ if (!rtp_format) {
+ ret = AVERROR(ENOSYS);
+ goto fail;
+ }
/* Allocate an AVFormatContext for each output stream */
rtpctx = avformat_alloc_context();
- if (!rtpctx)
- return NULL;
+ if (!rtpctx) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
rtpctx->oformat = rtp_format;
if (!avformat_new_stream(rtpctx, NULL)) {
- av_free(rtpctx);
- return NULL;
+ ret = AVERROR(ENOMEM);
+ goto fail;
}
/* Pass the interrupt callback on */
rtpctx->interrupt_callback = s->interrupt_callback;
@@ -78,8 +82,15 @@ AVFormatContext *ff_rtp_chain_mux_open(AVFormatContext *s, AVStream *st,
av_free(ptr);
}
avformat_free_context(rtpctx);
- return NULL;
+ return ret;
}
- return rtpctx;
+ *out = rtpctx;
+ return 0;
+
+fail:
+ av_free(rtpctx);
+ if (handle)
+ ffurl_close(handle);
+ return ret;
}
diff --git a/libavformat/rtpenc_chain.h b/libavformat/rtpenc_chain.h
index 6bdddcf..66b9e4c 100644
--- a/libavformat/rtpenc_chain.h
+++ b/libavformat/rtpenc_chain.h
@@ -25,7 +25,7 @@
#include "avformat.h"
#include "url.h"
-AVFormatContext *ff_rtp_chain_mux_open(AVFormatContext *s, AVStream *st,
- URLContext *handle, int packet_size);
+int ff_rtp_chain_mux_open(AVFormatContext **out, AVFormatContext *s,
+ AVStream *st, URLContext *handle, int packet_size);
#endif /* AVFORMAT_RTPENC_CHAIN_H */
diff --git a/libavformat/rtpenc_h264.c b/libavformat/rtpenc_h264.c
index 776da83..ac74074 100644
--- a/libavformat/rtpenc_h264.c
+++ b/libavformat/rtpenc_h264.c
@@ -55,6 +55,12 @@ static void nal_send(AVFormatContext *s1, const uint8_t *buf, int size, int last
uint8_t type = buf[0] & 0x1F;
uint8_t nri = buf[0] & 0x60;
+ if (s->flags & FF_RTP_FLAG_H264_MODE0) {
+ av_log(s1, AV_LOG_ERROR,
+ "NAL size %d > %d, try -slice-max-size %d\n", size,
+ s->max_payload_size, s->max_payload_size);
+ return;
+ }
av_log(s1, AV_LOG_DEBUG, "NAL size %d > %d\n", size, s->max_payload_size);
s->buf[0] = 28; /* FU Indicator; Type = 28 ---> FU-A */
s->buf[0] |= nri;
diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c
index c93de4a..e70b89e 100644
--- a/libavformat/rtpproto.c
+++ b/libavformat/rtpproto.c
@@ -31,7 +31,6 @@
#include "rtpdec.h"
#include "url.h"
-#include <unistd.h>
#include <stdarg.h>
#include "internal.h"
#include "network.h"
@@ -40,7 +39,6 @@
#if HAVE_POLL_H
#include <sys/poll.h>
#endif
-#include <sys/time.h>
#define RTP_TX_BUF_SIZE (64 * 1024)
#define RTP_RX_BUF_SIZE (128 * 1024)
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 9ee7a75..76b5df8 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -30,7 +30,6 @@
#include "avformat.h"
#include "avio_internal.h"
-#include <sys/time.h>
#if HAVE_POLL_H
#include <poll.h>
#endif
@@ -198,7 +197,14 @@ static int sdp_parse_rtpmap(AVFormatContext *s,
* particular servers ("RealServer Version 6.1.3.970", see issue 1658)
* have a trailing space. */
get_word_sep(buf, sizeof(buf), "/ ", &p);
- if (payload_type >= RTP_PT_PRIVATE) {
+ if (payload_type < RTP_PT_PRIVATE) {
+ /* We are in a standard case
+ * (from http://www.iana.org/assignments/rtp-parameters). */
+ /* search into AVRtpPayloadTypes[] */
+ codec->codec_id = ff_rtp_codec_id(buf, codec->codec_type);
+ }
+
+ if (codec->codec_id == CODEC_ID_NONE) {
RTPDynamicProtocolHandler *handler =
ff_rtp_handler_find_by_name(buf, codec->codec_type);
init_rtp_handler(handler, rtsp_st, codec);
@@ -208,11 +214,6 @@ static int sdp_parse_rtpmap(AVFormatContext *s,
* the format name from the rtpmap line never is passed into rtpdec. */
if (!rtsp_st->dynamic_handler)
codec->codec_id = ff_rtp_codec_id(buf, codec->codec_type);
- } else {
- /* We are in a standard case
- * (from http://www.iana.org/assignments/rtp-parameters). */
- /* search into AVRtpPayloadTypes[] */
- codec->codec_id = ff_rtp_codec_id(buf, codec->codec_type);
}
c = avcodec_find_decoder(codec->codec_id);
@@ -606,11 +607,13 @@ static int rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st)
s->ctx_flags |= AVFMTCTX_NOHEADER;
if (s->oformat && CONFIG_RTSP_MUXER) {
- rtsp_st->transport_priv = ff_rtp_chain_mux_open(s, st,
- rtsp_st->rtp_handle,
- RTSP_TCP_MAX_PACKET_SIZE);
+ int ret = ff_rtp_chain_mux_open(&rtsp_st->transport_priv, s, st,
+ rtsp_st->rtp_handle,
+ RTSP_TCP_MAX_PACKET_SIZE);
/* Ownership of rtp_handle is passed to the rtp mux context */
rtsp_st->rtp_handle = NULL;
+ if (ret < 0)
+ return ret;
} else if (rt->transport == RTSP_TRANSPORT_RDT && CONFIG_RTPDEC)
rtsp_st->transport_priv = ff_rdt_parse_open(s, st->index,
rtsp_st->dynamic_protocol_context,
@@ -637,16 +640,17 @@ static int rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st)
#if CONFIG_RTSP_DEMUXER || CONFIG_RTSP_MUXER
static void rtsp_parse_range(int *min_ptr, int *max_ptr, const char **pp)
{
- const char *p;
+ const char *q;
+ char *p;
int v;
- p = *pp;
- p += strspn(p, SPACE_CHARS);
- v = strtol(p, (char **)&p, 10);
+ q = *pp;
+ q += strspn(q, SPACE_CHARS);
+ v = strtol(q, &p, 10);
if (*p == '-') {
p++;
*min_ptr = v;
- v = strtol(p, (char **)&p, 10);
+ v = strtol(p, &p, 10);
*max_ptr = v;
} else {
*min_ptr = v;
@@ -869,6 +873,9 @@ void ff_rtsp_parse_line(RTSPMessageHeader *reply, const char *buf,
} else if (av_stristart(p, "x-Accept-Dynamic-Rate:", &p) && rt) {
p += strspn(p, SPACE_CHARS);
rt->accept_dynamic_rate = atoi(p);
+ } else if (av_stristart(p, "Content-Type:", &p)) {
+ p += strspn(p, SPACE_CHARS);
+ av_strlcpy(reply->content_type, p, sizeof(reply->content_type));
}
}
@@ -1276,7 +1283,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
"%s/UDP;multicast", trans_pref);
}
if (s->oformat) {
- av_strlcat(transport, ";mode=receive", sizeof(transport));
+ av_strlcat(transport, ";mode=record", sizeof(transport));
} else if (rt->server_type == RTSP_SERVER_REAL ||
rt->server_type == RTSP_SERVER_WMS)
av_strlcat(transport, ";mode=play", sizeof(transport));
diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h
index 6872a51..e512336 100644
--- a/libavformat/rtsp.h
+++ b/libavformat/rtsp.h
@@ -171,6 +171,11 @@ typedef struct RTSPMessageHeader {
* returned
*/
char reason[256];
+
+ /**
+ * Content type header
+ */
+ char content_type[64];
} RTSPMessageHeader;
/**
diff --git a/libavformat/rtspenc.c b/libavformat/rtspenc.c
index ad6e485..c7fb2fa 100644
--- a/libavformat/rtspenc.c
+++ b/libavformat/rtspenc.c
@@ -21,7 +21,6 @@
#include "avformat.h"
-#include <sys/time.h>
#if HAVE_POLL_H
#include <poll.h>
#endif
diff --git a/libavformat/sapdec.c b/libavformat/sapdec.c
index 46a4b96..e377cef 100644
--- a/libavformat/sapdec.c
+++ b/libavformat/sapdec.c
@@ -30,7 +30,6 @@
#if HAVE_POLL_H
#include <poll.h>
#endif
-#include <sys/time.h>
struct SAPState {
URLContext *ann_fd;
diff --git a/libavformat/sapenc.c b/libavformat/sapenc.c
index ca133f5..7e84a3f 100644
--- a/libavformat/sapenc.c
+++ b/libavformat/sapenc.c
@@ -150,8 +150,10 @@ static int sap_write_header(AVFormatContext *s)
ret = AVERROR(EIO);
goto fail;
}
- s->streams[i]->priv_data = contexts[i] =
- ff_rtp_chain_mux_open(s, s->streams[i], fd, 0);
+ ret = ff_rtp_chain_mux_open(&contexts[i], s, s->streams[i], fd, 0);
+ if (ret < 0)
+ goto fail;
+ s->streams[i]->priv_data = contexts[i];
av_strlcpy(contexts[i]->filename, url, sizeof(contexts[i]->filename));
}
@@ -209,7 +211,7 @@ static int sap_write_header(AVFormatContext *s)
pos += strlen(&sap->ann[pos]) + 1;
if (av_sdp_create(contexts, s->nb_streams, &sap->ann[pos],
- sap->ann_size - pos)) {
+ sap->ann_size - pos)) {
ret = AVERROR_INVALIDDATA;
goto fail;
}
diff --git a/libavformat/sctp.c b/libavformat/sctp.c
new file mode 100644
index 0000000..7bcb5ae
--- /dev/null
+++ b/libavformat/sctp.c
@@ -0,0 +1,326 @@
+/*
+ * SCTP protocol
+ * Copyright (c) 2012 Luca Barbato
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ *
+ * sctp url_protocol
+ *
+ * url syntax: sctp://host:port[?option=val...]
+ * option: 'listen' : listen for an incoming connection
+ * 'max_streams=n' : set the maximum number of streams
+ * 'reuse=1' : enable reusing the socket [TBD]
+ *
+ * by setting the maximum number of streams the protocol will use the
+ * first two bytes of the incoming/outgoing buffer to store the
+ * stream number of the packet being read/written.
+ * @see sctp_read
+ * @see sctp_write
+ */
+
+
+#include <netinet/in.h>
+#include <netinet/sctp.h>
+
+#include "config.h"
+
+#if HAVE_POLL_H
+#include <poll.h>
+#endif
+
+#include "libavutil/intreadwrite.h"
+#include "libavutil/parseutils.h"
+#include "avformat.h"
+#include "internal.h"
+#include "network.h"
+#include "os_support.h"
+#include "url.h"
+
+/*
+ * The sctp_recvmsg and sctp_sendmsg functions are part of the user
+ * library that offers support
+ * for the SCTP kernel Implementation. The main purpose of this
+ * code is to provide the SCTP Socket API mappings for user
+ * application to interface with the SCTP in kernel.
+ *
+ * This implementation is based on the Socket API Extensions for SCTP
+ * defined in <draft-ietf-tsvwg-sctpsocket-10.txt>
+ *
+ * Copyright (c) 2003 International Business Machines, Corp.
+ *
+ * Written or modified by:
+ * Ryan Layer <rmlayer at us.ibm.com>
+ */
+
+static int ff_sctp_recvmsg(int s, void *msg, size_t len, struct sockaddr *from,
+ socklen_t *fromlen, struct sctp_sndrcvinfo *sinfo,
+ int *msg_flags)
+{
+ int recvb;
+ struct iovec iov;
+ char incmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ struct msghdr inmsg = { 0 };
+ struct cmsghdr *cmsg = NULL;
+
+ iov.iov_base = msg;
+ iov.iov_len = len;
+
+ inmsg.msg_name = from;
+ inmsg.msg_namelen = fromlen ? *fromlen : 0;
+ inmsg.msg_iov = &iov;
+ inmsg.msg_iovlen = 1;
+ inmsg.msg_control = incmsg;
+ inmsg.msg_controllen = sizeof(incmsg);
+
+ if ((recvb = recvmsg(s, &inmsg, msg_flags ? *msg_flags : 0)) < 0)
+ return recvb;
+
+ if (fromlen)
+ *fromlen = inmsg.msg_namelen;
+ if (msg_flags)
+ *msg_flags = inmsg.msg_flags;
+
+ for (cmsg = CMSG_FIRSTHDR(&inmsg); cmsg != NULL;
+ cmsg = CMSG_NXTHDR(&inmsg, cmsg)) {
+ if ((IPPROTO_SCTP == cmsg->cmsg_level) &&
+ (SCTP_SNDRCV == cmsg->cmsg_type))
+ break;
+ }
+
+ /* Copy sinfo. */
+ if (cmsg)
+ memcpy(sinfo, CMSG_DATA(cmsg), sizeof(struct sctp_sndrcvinfo));
+
+ return recvb;
+}
+
+static int ff_sctp_send(int s, const void *msg, size_t len,
+ const struct sctp_sndrcvinfo *sinfo, int flags)
+{
+ struct msghdr outmsg;
+ struct iovec iov;
+
+ outmsg.msg_name = NULL;
+ outmsg.msg_namelen = 0;
+ outmsg.msg_iov = &iov;
+ iov.iov_base = msg;
+ iov.iov_len = len;
+ outmsg.msg_iovlen = 1;
+ outmsg.msg_controllen = 0;
+
+ if (sinfo) {
+ char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ struct cmsghdr *cmsg;
+
+ outmsg.msg_control = outcmsg;
+ outmsg.msg_controllen = sizeof(outcmsg);
+ outmsg.msg_flags = 0;
+
+ cmsg = CMSG_FIRSTHDR(&outmsg);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+
+ outmsg.msg_controllen = cmsg->cmsg_len;
+ memcpy(CMSG_DATA(cmsg), sinfo, sizeof(struct sctp_sndrcvinfo));
+ }
+
+ return sendmsg(s, &outmsg, flags);
+}
+
+typedef struct SCTPContext {
+ int fd;
+ int max_streams;
+ struct sockaddr_storage dest_addr;
+ socklen_t dest_addr_len;
+} SCTPContext;
+
+static int sctp_open(URLContext *h, const char *uri, int flags)
+{
+ struct addrinfo *ai, *cur_ai;
+ struct addrinfo hints = { 0 };
+ struct sctp_event_subscribe event = { 0 };
+ struct sctp_initmsg initparams = { 0 };
+ int port;
+ int fd = -1;
+ SCTPContext *s = h->priv_data;
+ const char *p;
+ char buf[256];
+ int ret, listen_socket = 0;
+ char hostname[1024], proto[1024], path[1024];
+ char portstr[10];
+
+ av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname),
+ &port, path, sizeof(path), uri);
+ if (strcmp(proto,"sctp") || port <= 0 || port >= 65536)
+ return AVERROR(EINVAL);
+
+ s->max_streams = 0;
+ p = strchr(uri, '?');
+ if (p) {
+ if (av_find_info_tag(buf, sizeof(buf), "listen", p))
+ listen_socket = 1;
+ if (av_find_info_tag(buf, sizeof(buf), "max_streams", p))
+ s->max_streams = strtol(buf, NULL, 10);
+ }
+
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ snprintf(portstr, sizeof(portstr), "%d", port);
+ ret = getaddrinfo(hostname, portstr, &hints, &ai);
+ if (ret) {
+ av_log(h, AV_LOG_ERROR, "Failed to resolve hostname %s: %s\n",
+ hostname, gai_strerror(ret));
+ return AVERROR(EIO);
+ }
+
+ cur_ai = ai;
+
+ fd = socket(cur_ai->ai_family, SOCK_STREAM, IPPROTO_SCTP);
+ if (fd < 0)
+ goto fail;
+
+ s->dest_addr_len = sizeof(s->dest_addr);
+
+ if (listen_socket) {
+ int fd1;
+ ret = bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
+ listen(fd, 100);
+ fd1 = accept(fd, NULL, NULL);
+ closesocket(fd);
+ fd = fd1;
+ } else
+ ret = connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
+
+ ff_socket_nonblock(fd, 1);
+
+ event.sctp_data_io_event = 1;
+ /* TODO: Subscribe to more event types and handle them */
+
+ if (setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event,
+ sizeof(event)) != 0) {
+ av_log(h, AV_LOG_ERROR,
+ "SCTP ERROR: Unable to subscribe to events\n");
+ goto fail;
+ }
+
+ if (s->max_streams) {
+ initparams.sinit_max_instreams = s->max_streams;
+ initparams.sinit_num_ostreams = s->max_streams;
+ if (setsockopt(fd, IPPROTO_SCTP, SCTP_INITMSG, &initparams,
+ sizeof(initparams)) < 0)
+ av_log(h, AV_LOG_ERROR,
+ "SCTP ERROR: Unable to initialize socket max streams %d\n",
+ s->max_streams);
+ }
+
+ h->priv_data = s;
+ h->is_streamed = 1;
+ s->fd = fd;
+ freeaddrinfo(ai);
+ return 0;
+
+fail:
+ ret = AVERROR(EIO);
+ freeaddrinfo(ai);
+ return ret;
+}
+
+static int sctp_wait_fd(int fd, int write)
+{
+ int ev = write ? POLLOUT : POLLIN;
+ struct pollfd p = { .fd = fd, .events = ev, .revents = 0 };
+ int ret;
+
+ ret = poll(&p, 1, 100);
+ return ret < 0 ? ff_neterrno() : p.revents & ev ? 0 : AVERROR(EAGAIN);
+}
+
+static int sctp_read(URLContext *h, uint8_t *buf, int size)
+{
+ SCTPContext *s = h->priv_data;
+ int ret;
+
+ if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
+ ret = sctp_wait_fd(s->fd, 0);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (s->max_streams) {
+ /*StreamId is introduced as a 2byte code into the stream*/
+ struct sctp_sndrcvinfo info = { 0 };
+ ret = ff_sctp_recvmsg(s->fd, buf + 2, size - 2, NULL, 0, &info, 0);
+ AV_WB16(buf, info.sinfo_stream);
+ ret = ret < 0 ? ret : ret + 2;
+ } else
+ ret = recv(s->fd, buf, size, 0);
+
+ return ret < 0 ? ff_neterrno() : ret;
+}
+
+static int sctp_write(URLContext *h, const uint8_t *buf, int size)
+{
+ SCTPContext *s = h->priv_data;
+ int ret;
+
+ if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
+ ret = sctp_wait_fd(s->fd, 1);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (s->max_streams) {
+ /*StreamId is introduced as a 2byte code into the stream*/
+ struct sctp_sndrcvinfo info = { 0 };
+ info.sinfo_stream = AV_RB16(buf);
+ if (info.sinfo_stream > s->max_streams)
+ abort();
+ ret = ff_sctp_send(s->fd, buf + 2, size - 2, &info, MSG_EOR);
+ } else
+ ret = send(s->fd, buf, size, 0);
+
+ return ret < 0 ? ff_neterrno() : ret;
+}
+
+static int sctp_close(URLContext *h)
+{
+ SCTPContext *s = h->priv_data;
+ closesocket(s->fd);
+ return 0;
+}
+
+static int sctp_get_file_handle(URLContext *h)
+{
+ SCTPContext *s = h->priv_data;
+ return s->fd;
+}
+
+URLProtocol ff_sctp_protocol = {
+ .name = "sctp",
+ .url_open = sctp_open,
+ .url_read = sctp_read,
+ .url_write = sctp_write,
+ .url_close = sctp_close,
+ .url_get_file_handle = sctp_get_file_handle,
+ .priv_data_size = sizeof(SCTPContext),
+ .flags = URL_PROTOCOL_FLAG_NETWORK,
+};
diff --git a/libavformat/sdp.c b/libavformat/sdp.c
index 9692aab..1867225 100644
--- a/libavformat/sdp.c
+++ b/libavformat/sdp.c
@@ -388,15 +388,20 @@ static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c,
char *config = NULL;
switch (c->codec_id) {
- case CODEC_ID_H264:
+ case CODEC_ID_H264: {
+ int mode = 1;
+ if (fmt && fmt->oformat->priv_class &&
+ av_opt_flag_is_set(fmt->priv_data, "rtpflags", "h264_mode0"))
+ mode = 0;
if (c->extradata_size) {
config = extradata2psets(c);
}
av_strlcatf(buff, size, "a=rtpmap:%d H264/90000\r\n"
- "a=fmtp:%d packetization-mode=1%s\r\n",
+ "a=fmtp:%d packetization-mode=%d%s\r\n",
payload_type,
- payload_type, config ? config : "");
+ payload_type, mode, config ? config : "");
break;
+ }
case CODEC_ID_H263:
case CODEC_ID_H263P:
/* a=framesize is required by 3GPP TS 26.234 (PSS). It
@@ -544,6 +549,12 @@ static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c,
c->sample_rate);
break;
}
+ case CODEC_ID_ILBC:
+ av_strlcatf(buff, size, "a=rtpmap:%d iLBC/%d\r\n"
+ "a=fmtp:%d mode=%d\r\n",
+ payload_type, c->sample_rate,
+ payload_type, c->block_align == 38 ? 20 : 30);
+ break;
default:
/* Nothing special to do here... */
break;
diff --git a/libavformat/segment.c b/libavformat/segment.c
index 8274792..8a0f136 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -19,7 +19,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <strings.h>
#include <float.h>
#include "avformat.h"
diff --git a/libavformat/smjpegenc.c b/libavformat/smjpegenc.c
index 45ba20b..e27b895 100644
--- a/libavformat/smjpegenc.c
+++ b/libavformat/smjpegenc.c
@@ -144,6 +144,6 @@ AVOutputFormat ff_smjpeg_muxer = {
.write_header = smjpeg_write_header,
.write_packet = smjpeg_write_packet,
.write_trailer = smjpeg_write_trailer,
- .flags = AVFMT_GLOBALHEADER,
+ .flags = AVFMT_GLOBALHEADER | AVFMT_TS_NONSTRICT,
.codec_tag = (const AVCodecTag *const []){ ff_codec_smjpeg_video_tags, ff_codec_smjpeg_audio_tags, 0 },
};
diff --git a/libavformat/swfenc.c b/libavformat/swfenc.c
index 82ec7ff..fb0fdc5 100644
--- a/libavformat/swfenc.c
+++ b/libavformat/swfenc.c
@@ -513,6 +513,7 @@ AVOutputFormat ff_swf_muxer = {
.write_header = swf_write_header,
.write_packet = swf_write_packet,
.write_trailer = swf_write_trailer,
+ .flags = AVFMT_TS_NONSTRICT,
};
#endif
#if CONFIG_AVM2_MUXER
@@ -526,5 +527,6 @@ AVOutputFormat ff_avm2_muxer = {
.write_header = swf_write_header,
.write_packet = swf_write_packet,
.write_trailer = swf_write_trailer,
+ .flags = AVFMT_TS_NONSTRICT,
};
#endif
diff --git a/libavformat/tcp.c b/libavformat/tcp.c
index 0ed11f3..6a65860 100644
--- a/libavformat/tcp.c
+++ b/libavformat/tcp.c
@@ -20,7 +20,6 @@
*/
#include "avformat.h"
#include "libavutil/parseutils.h"
-#include <unistd.h>
#include "internal.h"
#include "network.h"
#include "os_support.h"
@@ -28,7 +27,6 @@
#if HAVE_POLL_H
#include <poll.h>
#endif
-#include <sys/time.h>
typedef struct TCPContext {
int fd;
@@ -65,7 +63,12 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
snprintf(portstr, sizeof(portstr), "%d", port);
- ret = getaddrinfo(hostname, portstr, &hints, &ai);
+ if (listen_socket)
+ hints.ai_flags |= AI_PASSIVE;
+ if (!hostname[0])
+ ret = getaddrinfo(NULL, portstr, &hints, &ai);
+ else
+ ret = getaddrinfo(hostname, portstr, &hints, &ai);
if (ret) {
av_log(h, AV_LOG_ERROR,
"Failed to resolve hostname %s: %s\n",
@@ -83,9 +86,23 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
if (listen_socket) {
int fd1;
+ int reuse = 1;
+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
ret = bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
- listen(fd, 1);
+ if (ret) {
+ ret = ff_neterrno();
+ goto fail1;
+ }
+ ret = listen(fd, 1);
+ if (ret) {
+ ret = ff_neterrno();
+ goto fail1;
+ }
fd1 = accept(fd, NULL, NULL);
+ if (fd1 < 0) {
+ ret = ff_neterrno();
+ goto fail1;
+ }
closesocket(fd);
fd = fd1;
ff_socket_nonblock(fd, 1);
@@ -125,12 +142,15 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
}
/* test error */
optlen = sizeof(ret);
- getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen);
+ if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen))
+ ret = AVUNERROR(ff_neterrno());
if (ret != 0) {
+ char errbuf[100];
+ ret = AVERROR(ret);
+ av_strerror(ret, errbuf, sizeof(errbuf));
av_log(h, AV_LOG_ERROR,
"TCP connection to %s:%d failed: %s\n",
- hostname, port, strerror(ret));
- ret = AVERROR(ret);
+ hostname, port, errbuf);
goto fail;
}
}
@@ -182,6 +202,22 @@ static int tcp_write(URLContext *h, const uint8_t *buf, int size)
return ret < 0 ? ff_neterrno() : ret;
}
+static int tcp_shutdown(URLContext *h, int flags)
+{
+ TCPContext *s = h->priv_data;
+ int how;
+
+ if (flags & AVIO_FLAG_WRITE && flags & AVIO_FLAG_READ) {
+ how = SHUT_RDWR;
+ } else if (flags & AVIO_FLAG_WRITE) {
+ how = SHUT_WR;
+ } else {
+ how = SHUT_RD;
+ }
+
+ return shutdown(s->fd, how);
+}
+
static int tcp_close(URLContext *h)
{
TCPContext *s = h->priv_data;
@@ -202,6 +238,7 @@ URLProtocol ff_tcp_protocol = {
.url_write = tcp_write,
.url_close = tcp_close,
.url_get_file_handle = tcp_get_file_handle,
+ .url_shutdown = tcp_shutdown,
.priv_data_size = sizeof(TCPContext),
.flags = URL_PROTOCOL_FLAG_NETWORK,
};
diff --git a/libavformat/udp.c b/libavformat/udp.c
index 6571ab5..e848ecd 100644
--- a/libavformat/udp.c
+++ b/libavformat/udp.c
@@ -30,12 +30,10 @@
#include "avio_internal.h"
#include "libavutil/parseutils.h"
#include "libavutil/avstring.h"
-#include <unistd.h>
#include "internal.h"
#include "network.h"
#include "os_support.h"
#include "url.h"
-#include <sys/time.h>
#ifndef IPV6_ADD_MEMBERSHIP
#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
@@ -57,13 +55,20 @@ typedef struct {
#define UDP_TX_BUF_SIZE 32768
#define UDP_MAX_PKT_SIZE 65536
+static void log_net_error(void *ctx, int level, const char* prefix)
+{
+ char errbuf[100];
+ av_strerror(ff_neterrno(), errbuf, sizeof(errbuf));
+ av_log(ctx, level, "%s: %s\n", prefix, errbuf);
+}
+
static int udp_set_multicast_ttl(int sockfd, int mcastTTL,
struct sockaddr *addr)
{
#ifdef IP_MULTICAST_TTL
if (addr->sa_family == AF_INET) {
if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &mcastTTL, sizeof(mcastTTL)) < 0) {
- av_log(NULL, AV_LOG_ERROR, "setsockopt(IP_MULTICAST_TTL): %s\n", strerror(errno));
+ log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_MULTICAST_TTL)");
return -1;
}
}
@@ -71,7 +76,7 @@ static int udp_set_multicast_ttl(int sockfd, int mcastTTL,
#if defined(IPPROTO_IPV6) && defined(IPV6_MULTICAST_HOPS)
if (addr->sa_family == AF_INET6) {
if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &mcastTTL, sizeof(mcastTTL)) < 0) {
- av_log(NULL, AV_LOG_ERROR, "setsockopt(IPV6_MULTICAST_HOPS): %s\n", strerror(errno));
+ log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IPV6_MULTICAST_HOPS)");
return -1;
}
}
@@ -88,7 +93,7 @@ static int udp_join_multicast_group(int sockfd, struct sockaddr *addr)
mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
mreq.imr_interface.s_addr= INADDR_ANY;
if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) {
- av_log(NULL, AV_LOG_ERROR, "setsockopt(IP_ADD_MEMBERSHIP): %s\n", strerror(errno));
+ log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_ADD_MEMBERSHIP)");
return -1;
}
}
@@ -100,7 +105,7 @@ static int udp_join_multicast_group(int sockfd, struct sockaddr *addr)
memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr));
mreq6.ipv6mr_interface= 0;
if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) {
- av_log(NULL, AV_LOG_ERROR, "setsockopt(IPV6_ADD_MEMBERSHIP): %s\n", strerror(errno));
+ log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IPV6_ADD_MEMBERSHIP)");
return -1;
}
}
@@ -117,7 +122,7 @@ static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr)
mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
mreq.imr_interface.s_addr= INADDR_ANY;
if (setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) {
- av_log(NULL, AV_LOG_ERROR, "setsockopt(IP_DROP_MEMBERSHIP): %s\n", strerror(errno));
+ log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_DROP_MEMBERSHIP)");
return -1;
}
}
@@ -129,7 +134,7 @@ static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr)
memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr));
mreq6.ipv6mr_interface= 0;
if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) {
- av_log(NULL, AV_LOG_ERROR, "setsockopt(IPV6_DROP_MEMBERSHIP): %s\n", strerror(errno));
+ log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IPV6_DROP_MEMBERSHIP)");
return -1;
}
}
@@ -163,6 +168,79 @@ static struct addrinfo* udp_resolve_host(const char *hostname, int port,
return res;
}
+static int udp_set_multicast_sources(int sockfd, struct sockaddr *addr,
+ int addr_len, char **sources,
+ int nb_sources, int include)
+{
+#if HAVE_STRUCT_GROUP_SOURCE_REQ && defined(MCAST_BLOCK_SOURCE) && !defined(_WIN32)
+ /* These ones are available in the microsoft SDK, but don't seem to work
+ * as on linux, so just prefer the v4-only approach there for now. */
+ int i;
+ for (i = 0; i < nb_sources; i++) {
+ struct group_source_req mreqs;
+ int level = addr->sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
+ struct addrinfo *sourceaddr = udp_resolve_host(sources[i], 0,
+ SOCK_DGRAM, AF_UNSPEC,
+ AI_NUMERICHOST);
+ if (!sourceaddr)
+ return AVERROR(ENOENT);
+
+ mreqs.gsr_interface = 0;
+ memcpy(&mreqs.gsr_group, addr, addr_len);
+ memcpy(&mreqs.gsr_source, sourceaddr->ai_addr, sourceaddr->ai_addrlen);
+ freeaddrinfo(sourceaddr);
+
+ if (setsockopt(sockfd, level,
+ include ? MCAST_JOIN_SOURCE_GROUP : MCAST_BLOCK_SOURCE,
+ (const void *)&mreqs, sizeof(mreqs)) < 0) {
+ if (include)
+ log_net_error(NULL, AV_LOG_ERROR, "setsockopt(MCAST_JOIN_SOURCE_GROUP)");
+ else
+ log_net_error(NULL, AV_LOG_ERROR, "setsockopt(MCAST_BLOCK_SOURCE)");
+ return ff_neterrno();
+ }
+ }
+#elif HAVE_STRUCT_IP_MREQ_SOURCE && defined(IP_BLOCK_SOURCE)
+ int i;
+ if (addr->sa_family != AF_INET) {
+ av_log(NULL, AV_LOG_ERROR,
+ "Setting multicast sources only supported for IPv4\n");
+ return AVERROR(EINVAL);
+ }
+ for (i = 0; i < nb_sources; i++) {
+ struct ip_mreq_source mreqs;
+ struct addrinfo *sourceaddr = udp_resolve_host(sources[i], 0,
+ SOCK_DGRAM, AF_UNSPEC,
+ AI_NUMERICHOST);
+ if (!sourceaddr)
+ return AVERROR(ENOENT);
+ if (sourceaddr->ai_addr->sa_family != AF_INET) {
+ freeaddrinfo(sourceaddr);
+ av_log(NULL, AV_LOG_ERROR, "%s is of incorrect protocol family\n",
+ sources[i]);
+ return AVERROR(EINVAL);
+ }
+
+ mreqs.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
+ mreqs.imr_interface.s_addr = INADDR_ANY;
+ mreqs.imr_sourceaddr.s_addr = ((struct sockaddr_in *)sourceaddr->ai_addr)->sin_addr.s_addr;
+ freeaddrinfo(sourceaddr);
+
+ if (setsockopt(sockfd, IPPROTO_IP,
+ include ? IP_ADD_SOURCE_MEMBERSHIP : IP_BLOCK_SOURCE,
+ (const void *)&mreqs, sizeof(mreqs)) < 0) {
+ if (include)
+ log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_ADD_SOURCE_MEMBERSHIP)");
+ else
+ log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_BLOCK_SOURCE)");
+ return ff_neterrno();
+ }
+ }
+#else
+ return AVERROR(ENOSYS);
+#endif
+ return 0;
+}
static int udp_set_url(struct sockaddr_storage *addr,
const char *hostname, int port)
{
@@ -193,8 +271,8 @@ static int udp_socket_create(UDPContext *s, struct sockaddr_storage *addr,
goto fail;
for (res = res0; res; res=res->ai_next) {
udp_fd = socket(res->ai_family, SOCK_DGRAM, 0);
- if (udp_fd > 0) break;
- av_log(NULL, AV_LOG_ERROR, "socket: %s\n", strerror(errno));
+ if (udp_fd != -1) break;
+ log_net_error(NULL, AV_LOG_ERROR, "socket");
}
if (udp_fd < 0)
@@ -218,9 +296,10 @@ static int udp_socket_create(UDPContext *s, struct sockaddr_storage *addr,
static int udp_port(struct sockaddr_storage *addr, int addr_len)
{
char sbuf[sizeof(int)*3+1];
+ int error;
- if (getnameinfo((struct sockaddr *)addr, addr_len, NULL, 0, sbuf, sizeof(sbuf), NI_NUMERICSERV) != 0) {
- av_log(NULL, AV_LOG_ERROR, "getnameinfo: %s\n", strerror(errno));
+ if ((error = getnameinfo((struct sockaddr *)addr, addr_len, NULL, 0, sbuf, sizeof(sbuf), NI_NUMERICSERV)) != 0) {
+ av_log(NULL, AV_LOG_ERROR, "getnameinfo: %s\n", gai_strerror(error));
return -1;
}
@@ -267,7 +346,7 @@ int ff_udp_set_remote_url(URLContext *h, const char *uri)
if (connect(s->udp_fd, (struct sockaddr *) &s->dest_addr,
s->dest_addr_len)) {
s->is_connected = 0;
- av_log(h, AV_LOG_ERROR, "connect: %s\n", strerror(errno));
+ log_net_error(h, AV_LOG_ERROR, "connect");
return AVERROR(EIO);
}
}
@@ -312,6 +391,8 @@ static int udp_open(URLContext *h, const char *uri, int flags)
struct sockaddr_storage my_addr;
int len;
int reuse_specified = 0;
+ int i, include = 0, num_sources = 0;
+ char *sources[32];
h->is_streamed = 1;
h->max_packet_size = 1472;
@@ -349,6 +430,25 @@ static int udp_open(URLContext *h, const char *uri, int flags)
if (av_find_info_tag(buf, sizeof(buf), "localaddr", p)) {
av_strlcpy(localaddr, buf, sizeof(localaddr));
}
+ if (av_find_info_tag(buf, sizeof(buf), "sources", p))
+ include = 1;
+ if (include || av_find_info_tag(buf, sizeof(buf), "block", p)) {
+ char *source_start;
+
+ source_start = buf;
+ while (1) {
+ char *next = strchr(source_start, ',');
+ if (next)
+ *next = '\0';
+ sources[num_sources] = av_strdup(source_start);
+ if (!sources[num_sources])
+ goto fail;
+ source_start = next + 1;
+ num_sources++;
+ if (num_sources >= FF_ARRAY_ELEMS(sources) || !next)
+ break;
+ }
+ }
}
/* fill the dest addr */
@@ -390,7 +490,7 @@ static int udp_open(URLContext *h, const char *uri, int flags)
* bind failed */
/* the bind is needed to give a port to the socket now */
if (bind_ret < 0 && bind(udp_fd,(struct sockaddr *)&my_addr, len) < 0) {
- av_log(h, AV_LOG_ERROR, "bind failed: %s\n", strerror(errno));
+ log_net_error(h, AV_LOG_ERROR, "bind failed");
goto fail;
}
@@ -406,8 +506,21 @@ static int udp_open(URLContext *h, const char *uri, int flags)
}
if (h->flags & AVIO_FLAG_READ) {
/* input */
- if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr) < 0)
+ if (num_sources == 0 || !include) {
+ if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr) < 0)
+ goto fail;
+
+ if (num_sources) {
+ if (udp_set_multicast_sources(udp_fd, (struct sockaddr *)&s->dest_addr, s->dest_addr_len, sources, num_sources, 0) < 0)
+ goto fail;
+ }
+ } else if (include && num_sources) {
+ if (udp_set_multicast_sources(udp_fd, (struct sockaddr *)&s->dest_addr, s->dest_addr_len, sources, num_sources, 1) < 0)
+ goto fail;
+ } else {
+ av_log(NULL, AV_LOG_ERROR, "invalid udp settings: inclusive multicast but no sources given\n");
goto fail;
+ }
}
}
@@ -415,7 +528,7 @@ static int udp_open(URLContext *h, const char *uri, int flags)
/* limit the tx buf size to limit latency */
tmp = s->buffer_size;
if (setsockopt(udp_fd, SOL_SOCKET, SO_SNDBUF, &tmp, sizeof(tmp)) < 0) {
- av_log(h, AV_LOG_ERROR, "setsockopt(SO_SNDBUF): %s\n", strerror(errno));
+ log_net_error(h, AV_LOG_ERROR, "setsockopt(SO_SNDBUF)");
goto fail;
}
} else {
@@ -423,23 +536,28 @@ static int udp_open(URLContext *h, const char *uri, int flags)
* avoid losing data on OSes that set this too low by default. */
tmp = s->buffer_size;
if (setsockopt(udp_fd, SOL_SOCKET, SO_RCVBUF, &tmp, sizeof(tmp)) < 0) {
- av_log(h, AV_LOG_WARNING, "setsockopt(SO_RECVBUF): %s\n", strerror(errno));
+ log_net_error(h, AV_LOG_WARNING, "setsockopt(SO_RECVBUF)");
}
/* make the socket non-blocking */
ff_socket_nonblock(udp_fd, 1);
}
if (s->is_connected) {
if (connect(udp_fd, (struct sockaddr *) &s->dest_addr, s->dest_addr_len)) {
- av_log(h, AV_LOG_ERROR, "connect: %s\n", strerror(errno));
+ log_net_error(h, AV_LOG_ERROR, "connect");
goto fail;
}
}
+ for (i = 0; i < num_sources; i++)
+ av_free(sources[i]);
+
s->udp_fd = udp_fd;
return 0;
fail:
if (udp_fd >= 0)
closesocket(udp_fd);
+ for (i = 0; i < num_sources; i++)
+ av_free(sources[i]);
return AVERROR(EIO);
}
diff --git a/libavformat/url.h b/libavformat/url.h
index bf8b6ed..0f0de78 100644
--- a/libavformat/url.h
+++ b/libavformat/url.h
@@ -81,6 +81,7 @@ typedef struct URLProtocol {
int64_t (*url_read_seek)(URLContext *h, int stream_index,
int64_t timestamp, int flags);
int (*url_get_file_handle)(URLContext *h);
+ int (*url_shutdown)(URLContext *h, int flags);
int priv_data_size;
const AVClass *priv_data_class;
int flags;
@@ -201,6 +202,18 @@ int64_t ffurl_size(URLContext *h);
int ffurl_get_file_handle(URLContext *h);
/**
+ * Signal the URLContext that we are done reading or writing the stream.
+ *
+ * @param h pointer to the resource
+ * @param flags flags which control how the resource indicated by url
+ * is to be shutdown
+ *
+ * @return a negative value if an error condition occurred, 0
+ * otherwise
+ */
+int ffurl_shutdown(URLContext *h, int flags);
+
+/**
* Register the URLProtocol protocol.
*
* @param size the size of the URLProtocol struct referenced
diff --git a/libavformat/utils.c b/libavformat/utils.c
index b167e96..156c527 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -38,8 +38,6 @@
#include "riff.h"
#include "audiointerleave.h"
#include "url.h"
-#include <sys/time.h>
-#include <time.h>
#include <stdarg.h>
#if CONFIG_NETWORK
#include "network.h"
@@ -218,7 +216,7 @@ AVOutputFormat *av_guess_format(const char *short_name, const char *filename,
score_max = 0;
while ((fmt = av_oformat_next(fmt))) {
score = 0;
- if (fmt->name && short_name && !strcmp(fmt->name, short_name))
+ if (fmt->name && short_name && !av_strcasecmp(fmt->name, short_name))
score += 100;
if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
score += 10;
@@ -557,7 +555,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma
}
s->duration = s->start_time = AV_NOPTS_VALUE;
- av_strlcpy(s->filename, filename, sizeof(s->filename));
+ av_strlcpy(s->filename, filename ? filename : "", sizeof(s->filename));
/* allocate private data */
if (s->iformat->priv_data_size > 0) {
@@ -612,6 +610,34 @@ fail:
/*******************************************************/
+static void probe_codec(AVFormatContext *s, AVStream *st, const AVPacket *pkt)
+{
+ if(st->codec->codec_id == CODEC_ID_PROBE){
+ AVProbeData *pd = &st->probe_data;
+ av_log(s, AV_LOG_DEBUG, "probing stream %d\n", st->index);
+ --st->probe_packets;
+
+ if (pkt) {
+ pd->buf = av_realloc(pd->buf, pd->buf_size+pkt->size+AVPROBE_PADDING_SIZE);
+ memcpy(pd->buf+pd->buf_size, pkt->data, pkt->size);
+ pd->buf_size += pkt->size;
+ memset(pd->buf+pd->buf_size, 0, AVPROBE_PADDING_SIZE);
+ } else {
+ st->probe_packets = 0;
+ }
+
+ if (!st->probe_packets ||
+ av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)) {
+ set_codec_from_probe_data(s, st, pd, st->probe_packets > 0 ? AVPROBE_SCORE_MAX/4 : 0);
+ if(st->codec->codec_id != CODEC_ID_PROBE){
+ pd->buf_size=0;
+ av_freep(&pd->buf);
+ av_log(s, AV_LOG_DEBUG, "probed stream %d\n", st->index);
+ }
+ }
+ }
+}
+
int ff_read_packet(AVFormatContext *s, AVPacket *pkt)
{
int ret, i;
@@ -622,10 +648,14 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt)
if (pktl) {
*pkt = pktl->pkt;
- if(s->streams[pkt->stream_index]->codec->codec_id != CODEC_ID_PROBE ||
- !s->streams[pkt->stream_index]->probe_packets ||
- s->raw_packet_buffer_remaining_size < pkt->size){
- AVProbeData *pd = &s->streams[pkt->stream_index]->probe_data;
+ st = s->streams[pkt->stream_index];
+ if (st->codec->codec_id != CODEC_ID_PROBE || !st->probe_packets ||
+ s->raw_packet_buffer_remaining_size < pkt->size) {
+ AVProbeData *pd;
+ if (st->probe_packets) {
+ probe_codec(s, st, NULL);
+ }
+ pd = &st->probe_data;
av_freep(&pd->buf);
pd->buf_size = 0;
s->raw_packet_buffer = pktl->next;
@@ -640,8 +670,12 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt)
if (ret < 0) {
if (!pktl || ret == AVERROR(EAGAIN))
return ret;
- for (i = 0; i < s->nb_streams; i++)
- s->streams[i]->probe_packets = 0;
+ for (i = 0; i < s->nb_streams; i++) {
+ st = s->streams[i];
+ if (st->probe_packets) {
+ probe_codec(s, st, NULL);
+ }
+ }
continue;
}
@@ -675,26 +709,7 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt)
add_to_pktbuf(&s->raw_packet_buffer, pkt, &s->raw_packet_buffer_end);
s->raw_packet_buffer_remaining_size -= pkt->size;
- if(st->codec->codec_id == CODEC_ID_PROBE){
- AVProbeData *pd = &st->probe_data;
- av_log(s, AV_LOG_DEBUG, "probing stream %d\n", st->index);
- --st->probe_packets;
-
- pd->buf = av_realloc(pd->buf, pd->buf_size+pkt->size+AVPROBE_PADDING_SIZE);
- memcpy(pd->buf+pd->buf_size, pkt->data, pkt->size);
- pd->buf_size += pkt->size;
- memset(pd->buf+pd->buf_size, 0, AVPROBE_PADDING_SIZE);
-
- if(av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)){
- //FIXME we do not reduce score to 0 for the case of running out of buffer space in bytes
- set_codec_from_probe_data(s, st, pd, st->probe_packets > 0 ? AVPROBE_SCORE_MAX/4 : 0);
- if(st->codec->codec_id != CODEC_ID_PROBE){
- pd->buf_size=0;
- av_freep(&pd->buf);
- av_log(s, AV_LOG_DEBUG, "probed stream %d\n", st->index);
- }
- }
- }
+ probe_codec(s, st, pkt);
}
}
@@ -791,6 +806,7 @@ static int is_intra_only(AVCodecContext *enc){
case CODEC_ID_VCR1:
case CODEC_ID_DNXHD:
case CODEC_ID_JPEG2000:
+ case CODEC_ID_MDEC:
return 1;
default: break;
}
@@ -985,24 +1001,19 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
}
}
- if(pkt->pts != AV_NOPTS_VALUE && duration){
- int64_t old_diff= FFABS(st->cur_dts - duration - pkt->pts);
- int64_t new_diff= FFABS(st->cur_dts - pkt->pts);
- if(old_diff < new_diff && old_diff < (duration>>3)){
- pkt->pts += duration;
- // av_log(NULL, AV_LOG_DEBUG, "id:%d old:%"PRId64" new:%"PRId64" dur:%d cur:%"PRId64" size:%d\n", pkt->stream_index, old_diff, new_diff, pkt->duration, st->cur_dts, pkt->size);
- }
+ if (pkt->pts != AV_NOPTS_VALUE || pkt->dts != AV_NOPTS_VALUE ||
+ duration) {
+ /* presentation is not delayed : PTS and DTS are the same */
+ if (pkt->pts == AV_NOPTS_VALUE)
+ pkt->pts = pkt->dts;
+ update_initial_timestamps(s, pkt->stream_index, pkt->pts,
+ pkt->pts);
+ if (pkt->pts == AV_NOPTS_VALUE)
+ pkt->pts = st->cur_dts;
+ pkt->dts = pkt->pts;
+ if (pkt->pts != AV_NOPTS_VALUE)
+ st->cur_dts = pkt->pts + duration;
}
-
- /* presentation is not delayed : PTS and DTS are the same */
- if(pkt->pts == AV_NOPTS_VALUE)
- pkt->pts = pkt->dts;
- update_initial_timestamps(s, pkt->stream_index, pkt->pts, pkt->pts);
- if(pkt->pts == AV_NOPTS_VALUE)
- pkt->pts = st->cur_dts;
- pkt->dts = pkt->pts;
- if(pkt->pts != AV_NOPTS_VALUE)
- st->cur_dts = pkt->pts + duration;
}
}
@@ -2966,7 +2977,9 @@ static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt){
pkt->dts= st->pts_buffer[0];
}
- if(st->cur_dts && st->cur_dts != AV_NOPTS_VALUE && st->cur_dts >= pkt->dts){
+ if (st->cur_dts && st->cur_dts != AV_NOPTS_VALUE &&
+ ((!(s->oformat->flags & AVFMT_TS_NONSTRICT) &&
+ st->cur_dts >= pkt->dts) || st->cur_dts > pkt->dts)) {
av_log(s, AV_LOG_ERROR,
"Application provided invalid, non monotonically increasing dts to muxer in stream %d: %"PRId64" >= %"PRId64"\n",
st->index, st->cur_dts, pkt->dts);
@@ -3396,12 +3409,12 @@ void av_dump_format(AVFormatContext *ic,
av_free(printed);
}
-int64_t av_gettime(void)
+#if FF_API_AV_GETTIME && CONFIG_SHARED && HAVE_SYMVER
+FF_SYMVER(int64_t, av_gettime, (void), "LIBAVFORMAT_54")
{
- struct timeval tv;
- gettimeofday(&tv,NULL);
- return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
+ return av_gettime();
}
+#endif
uint64_t ff_ntp_time(void)
{
diff --git a/libavformat/version.h b/libavformat/version.h
index 91ddfd2..0017698 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -30,7 +30,7 @@
#include "libavutil/avutil.h"
#define LIBAVFORMAT_VERSION_MAJOR 54
-#define LIBAVFORMAT_VERSION_MINOR 2
+#define LIBAVFORMAT_VERSION_MINOR 6
#define LIBAVFORMAT_VERSION_MICRO 0
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
@@ -44,9 +44,11 @@
#define LIBAVFORMAT_IDENT "Lavf" AV_STRINGIFY(LIBAVFORMAT_VERSION)
/**
- * Those FF_API_* defines are not part of public API.
- * They may change, break or disappear at any time.
+ * FF_API_* defines may be placed below to indicate public API that will be
+ * dropped at a future version bump. The defines themselves are not part of
+ * the public API and may change, break or disappear at any time.
*/
+
#ifndef FF_API_CLOSE_INPUT_FILE
#define FF_API_CLOSE_INPUT_FILE (LIBAVFORMAT_VERSION_MAJOR < 55)
#endif
@@ -59,5 +61,8 @@
#ifndef FF_API_INTERLEAVE_PACKET
#define FF_API_INTERLEAVE_PACKET (LIBAVFORMAT_VERSION_MAJOR < 55)
#endif
+#ifndef FF_API_AV_GETTIME
+#define FF_API_AV_GETTIME (LIBAVFORMAT_VERSION_MAJOR < 55)
+#endif
#endif /* AVFORMAT_VERSION_H */
diff --git a/libavformat/wav.c b/libavformat/wav.c
index 85849c1..c01121f 100644
--- a/libavformat/wav.c
+++ b/libavformat/wav.c
@@ -216,6 +216,7 @@ AVOutputFormat ff_wav_muxer = {
.write_header = wav_write_header,
.write_packet = wav_write_packet,
.write_trailer = wav_write_trailer,
+ .flags = AVFMT_TS_NONSTRICT,
.codec_tag = (const AVCodecTag* const []){ ff_codec_wav_tags, 0 },
.priv_class = &wav_muxer_class,
};
diff --git a/libavformat/wtv.c b/libavformat/wtv.c
index 07549b2..83f1bc1 100644
--- a/libavformat/wtv.c
+++ b/libavformat/wtv.c
@@ -443,7 +443,11 @@ static int read_probe(AVProbeData *p)
static void filetime_to_iso8601(char *buf, int buf_size, int64_t value)
{
time_t t = (value / 10000000LL) - 11644473600LL;
- strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", gmtime(&t));
+ struct tm *tm = gmtime(&t);
+ if (tm)
+ strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", gmtime(&t));
+ else
+ buf[0] = '\0';
}
/**
@@ -452,7 +456,11 @@ static void filetime_to_iso8601(char *buf, int buf_size, int64_t value)
static void crazytime_to_iso8601(char *buf, int buf_size, int64_t value)
{
time_t t = (value / 10000000LL) - 719162LL*86400LL;
- strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", gmtime(&t));
+ struct tm *tm = gmtime(&t);
+ if (tm)
+ strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", gmtime(&t));
+ else
+ buf[0] = '\0';
}
/**
@@ -461,7 +469,11 @@ static void crazytime_to_iso8601(char *buf, int buf_size, int64_t value)
static void oledate_to_iso8601(char *buf, int buf_size, int64_t value)
{
time_t t = 631112400LL + 86400*av_int2double(value);
- strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", gmtime(&t));
+ struct tm *tm = gmtime(&t);
+ if (tm)
+ strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", gmtime(&t));
+ else
+ buf[0] = '\0';
}
static void get_attachment(AVFormatContext *s, AVIOContext *pb, int length)
diff --git a/libavresample/Makefile b/libavresample/Makefile
index ce3fe81..c0c20a9 100644
--- a/libavresample/Makefile
+++ b/libavresample/Makefile
@@ -2,7 +2,7 @@ NAME = avresample
FFLIBS = avutil
HEADERS = avresample.h \
- version.h
+ version.h \
OBJS = audio_convert.o \
audio_data.o \
@@ -10,6 +10,6 @@ OBJS = audio_convert.o \
audio_mix_matrix.o \
options.o \
resample.o \
- utils.o
+ utils.o \
TESTPROGS = avresample
diff --git a/libavresample/audio_mix.c b/libavresample/audio_mix.c
index 34252bf..9319222 100644
--- a/libavresample/audio_mix.c
+++ b/libavresample/audio_mix.c
@@ -27,7 +27,7 @@
#include "audio_data.h"
#include "audio_mix.h"
-static const char *coeff_type_names[] = { "q6", "q15", "flt" };
+static const char *coeff_type_names[] = { "q8", "q15", "flt" };
void ff_audio_mix_set_func(AudioMix *am, enum AVSampleFormat fmt,
enum AVMixCoeffType coeff_type, int in_channels,
@@ -89,7 +89,7 @@ static void MIX_FUNC_NAME(fmt, cfmt)(stype **samples, ctype **matrix, \
MIX_FUNC_GENERIC(FLTP, FLT, float, float, float, sum)
MIX_FUNC_GENERIC(S16P, FLT, int16_t, float, float, av_clip_int16(lrintf(sum)))
MIX_FUNC_GENERIC(S16P, Q15, int16_t, int32_t, int64_t, av_clip_int16(sum >> 15))
-MIX_FUNC_GENERIC(S16P, Q6, int16_t, int16_t, int32_t, av_clip_int16(sum >> 6))
+MIX_FUNC_GENERIC(S16P, Q8, int16_t, int16_t, int32_t, av_clip_int16(sum >> 8))
/* TODO: templatize the channel-specific C functions */
@@ -115,6 +115,50 @@ static void mix_2_to_1_fltp_flt_c(float **samples, float **matrix, int len,
}
}
+static void mix_2_to_1_s16p_flt_c(int16_t **samples, float **matrix, int len,
+ int out_ch, int in_ch)
+{
+ int16_t *src0 = samples[0];
+ int16_t *src1 = samples[1];
+ int16_t *dst = src0;
+ float m0 = matrix[0][0];
+ float m1 = matrix[0][1];
+
+ while (len > 4) {
+ *dst++ = av_clip_int16(lrintf(*src0++ * m0 + *src1++ * m1));
+ *dst++ = av_clip_int16(lrintf(*src0++ * m0 + *src1++ * m1));
+ *dst++ = av_clip_int16(lrintf(*src0++ * m0 + *src1++ * m1));
+ *dst++ = av_clip_int16(lrintf(*src0++ * m0 + *src1++ * m1));
+ len -= 4;
+ }
+ while (len > 0) {
+ *dst++ = av_clip_int16(lrintf(*src0++ * m0 + *src1++ * m1));
+ len--;
+ }
+}
+
+static void mix_2_to_1_s16p_q8_c(int16_t **samples, int16_t **matrix, int len,
+ int out_ch, int in_ch)
+{
+ int16_t *src0 = samples[0];
+ int16_t *src1 = samples[1];
+ int16_t *dst = src0;
+ int16_t m0 = matrix[0][0];
+ int16_t m1 = matrix[0][1];
+
+ while (len > 4) {
+ *dst++ = (*src0++ * m0 + *src1++ * m1) >> 8;
+ *dst++ = (*src0++ * m0 + *src1++ * m1) >> 8;
+ *dst++ = (*src0++ * m0 + *src1++ * m1) >> 8;
+ *dst++ = (*src0++ * m0 + *src1++ * m1) >> 8;
+ len -= 4;
+ }
+ while (len > 0) {
+ *dst++ = (*src0++ * m0 + *src1++ * m1) >> 8;
+ len--;
+ }
+}
+
static void mix_1_to_2_fltp_flt_c(float **samples, float **matrix, int len,
int out_ch, int in_ch)
{
@@ -221,14 +265,20 @@ static int mix_function_init(AudioMix *am)
ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_Q15,
0, 0, 1, 1, "C", MIX_FUNC_NAME(S16P, Q15));
- ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_Q6,
- 0, 0, 1, 1, "C", MIX_FUNC_NAME(S16P, Q6));
+ ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_Q8,
+ 0, 0, 1, 1, "C", MIX_FUNC_NAME(S16P, Q8));
/* channel-specific C versions */
ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
2, 1, 1, 1, "C", mix_2_to_1_fltp_flt_c);
+ ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,
+ 2, 1, 1, 1, "C", mix_2_to_1_s16p_flt_c);
+
+ ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_Q8,
+ 2, 1, 1, 1, "C", mix_2_to_1_s16p_q8_c);
+
ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
1, 2, 1, 1, "C", mix_1_to_2_fltp_flt_c);
@@ -270,7 +320,8 @@ int ff_audio_mix_init(AVAudioResampleContext *avr)
avr->center_mix_level,
avr->surround_mix_level,
avr->lfe_mix_level, 1, matrix_dbl,
- avr->in_channels);
+ avr->in_channels,
+ avr->matrix_encoding);
if (ret < 0) {
av_free(matrix_dbl);
return ret;
@@ -320,7 +371,7 @@ void ff_audio_mix_close(AudioMix *am)
av_free(am->matrix[0]);
am->matrix = NULL;
}
- memset(am->matrix_q6, 0, sizeof(am->matrix_q6 ));
+ memset(am->matrix_q8, 0, sizeof(am->matrix_q8 ));
memset(am->matrix_q15, 0, sizeof(am->matrix_q15));
memset(am->matrix_flt, 0, sizeof(am->matrix_flt));
}
diff --git a/libavresample/audio_mix.h b/libavresample/audio_mix.h
index ffa1b23..61db330 100644
--- a/libavresample/audio_mix.h
+++ b/libavresample/audio_mix.h
@@ -47,7 +47,7 @@ typedef struct AudioMix {
mix_func *mix;
mix_func *mix_generic;
- int16_t *matrix_q6[AVRESAMPLE_MAX_CHANNELS];
+ int16_t *matrix_q8[AVRESAMPLE_MAX_CHANNELS];
int32_t *matrix_q15[AVRESAMPLE_MAX_CHANNELS];
float *matrix_flt[AVRESAMPLE_MAX_CHANNELS];
void **matrix;
diff --git a/libavresample/audio_mix_matrix.c b/libavresample/audio_mix_matrix.c
index 96c49ef..f7121c8 100644
--- a/libavresample/audio_mix_matrix.c
+++ b/libavresample/audio_mix_matrix.c
@@ -54,6 +54,8 @@
#define SURROUND_DIRECT_LEFT 33
#define SURROUND_DIRECT_RIGHT 34
+#define SQRT3_2 1.22474487139158904909 /* sqrt(3/2) */
+
static av_always_inline int even(uint64_t layout)
{
return (!layout || (layout & (layout - 1)));
@@ -83,14 +85,21 @@ static int sane_layout(uint64_t layout)
int avresample_build_matrix(uint64_t in_layout, uint64_t out_layout,
double center_mix_level, double surround_mix_level,
double lfe_mix_level, int normalize,
- double *matrix_out, int stride)
+ double *matrix_out, int stride,
+ enum AVMatrixEncoding matrix_encoding)
{
int i, j, out_i, out_j;
double matrix[64][64] = {{0}};
- int64_t unaccounted = in_layout & ~out_layout;
+ int64_t unaccounted;
double maxcoef = 0;
int in_channels, out_channels;
+ if ((out_layout & AV_CH_LAYOUT_STEREO_DOWNMIX) == AV_CH_LAYOUT_STEREO_DOWNMIX) {
+ out_layout = AV_CH_LAYOUT_STEREO;
+ }
+
+ unaccounted = in_layout & ~out_layout;
+
in_channels = av_get_channel_layout_nb_channels( in_layout);
out_channels = av_get_channel_layout_nb_channels(out_layout);
@@ -140,8 +149,19 @@ int avresample_build_matrix(uint64_t in_layout, uint64_t out_layout,
matrix[SIDE_LEFT ][BACK_CENTER] += M_SQRT1_2;
matrix[SIDE_RIGHT][BACK_CENTER] += M_SQRT1_2;
} else if (out_layout & AV_CH_FRONT_LEFT) {
- matrix[FRONT_LEFT ][BACK_CENTER] += surround_mix_level * M_SQRT1_2;
- matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level * M_SQRT1_2;
+ if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY ||
+ matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
+ if (unaccounted & (AV_CH_BACK_LEFT | AV_CH_SIDE_LEFT)) {
+ matrix[FRONT_LEFT ][BACK_CENTER] -= surround_mix_level * M_SQRT1_2;
+ matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level * M_SQRT1_2;
+ } else {
+ matrix[FRONT_LEFT ][BACK_CENTER] -= surround_mix_level;
+ matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level;
+ }
+ } else {
+ matrix[FRONT_LEFT ][BACK_CENTER] += surround_mix_level * M_SQRT1_2;
+ matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level * M_SQRT1_2;
+ }
} else if (out_layout & AV_CH_FRONT_CENTER) {
matrix[FRONT_CENTER][BACK_CENTER] += surround_mix_level * M_SQRT1_2;
} else
@@ -163,8 +183,20 @@ int avresample_build_matrix(uint64_t in_layout, uint64_t out_layout,
matrix[SIDE_RIGHT][BACK_RIGHT] += 1.0;
}
} else if (out_layout & AV_CH_FRONT_LEFT) {
- matrix[FRONT_LEFT ][BACK_LEFT ] += surround_mix_level;
- matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level;
+ if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
+ matrix[FRONT_LEFT ][BACK_LEFT ] -= surround_mix_level * M_SQRT1_2;
+ matrix[FRONT_LEFT ][BACK_RIGHT] -= surround_mix_level * M_SQRT1_2;
+ matrix[FRONT_RIGHT][BACK_LEFT ] += surround_mix_level * M_SQRT1_2;
+ matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level * M_SQRT1_2;
+ } else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
+ matrix[FRONT_LEFT ][BACK_LEFT ] -= surround_mix_level * SQRT3_2;
+ matrix[FRONT_LEFT ][BACK_RIGHT] -= surround_mix_level * M_SQRT1_2;
+ matrix[FRONT_RIGHT][BACK_LEFT ] += surround_mix_level * M_SQRT1_2;
+ matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level * SQRT3_2;
+ } else {
+ matrix[FRONT_LEFT ][BACK_LEFT ] += surround_mix_level;
+ matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level;
+ }
} else if (out_layout & AV_CH_FRONT_CENTER) {
matrix[FRONT_CENTER][BACK_LEFT ] += surround_mix_level * M_SQRT1_2;
matrix[FRONT_CENTER][BACK_RIGHT] += surround_mix_level * M_SQRT1_2;
@@ -187,8 +219,20 @@ int avresample_build_matrix(uint64_t in_layout, uint64_t out_layout,
matrix[BACK_CENTER][SIDE_LEFT ] += M_SQRT1_2;
matrix[BACK_CENTER][SIDE_RIGHT] += M_SQRT1_2;
} else if (out_layout & AV_CH_FRONT_LEFT) {
- matrix[FRONT_LEFT ][SIDE_LEFT ] += surround_mix_level;
- matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level;
+ if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
+ matrix[FRONT_LEFT ][SIDE_LEFT ] -= surround_mix_level * M_SQRT1_2;
+ matrix[FRONT_LEFT ][SIDE_RIGHT] -= surround_mix_level * M_SQRT1_2;
+ matrix[FRONT_RIGHT][SIDE_LEFT ] += surround_mix_level * M_SQRT1_2;
+ matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level * M_SQRT1_2;
+ } else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
+ matrix[FRONT_LEFT ][SIDE_LEFT ] -= surround_mix_level * SQRT3_2;
+ matrix[FRONT_LEFT ][SIDE_RIGHT] -= surround_mix_level * M_SQRT1_2;
+ matrix[FRONT_RIGHT][SIDE_LEFT ] += surround_mix_level * M_SQRT1_2;
+ matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level * SQRT3_2;
+ } else {
+ matrix[FRONT_LEFT ][SIDE_LEFT ] += surround_mix_level;
+ matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level;
+ }
} else if (out_layout & AV_CH_FRONT_CENTER) {
matrix[FRONT_CENTER][SIDE_LEFT ] += surround_mix_level * M_SQRT1_2;
matrix[FRONT_CENTER][SIDE_RIGHT] += surround_mix_level * M_SQRT1_2;
@@ -257,14 +301,14 @@ int avresample_get_matrix(AVAudioResampleContext *avr, double *matrix,
}
switch (avr->mix_coeff_type) {
- case AV_MIX_COEFF_TYPE_Q6:
- if (!avr->am->matrix_q6[0]) {
+ case AV_MIX_COEFF_TYPE_Q8:
+ if (!avr->am->matrix_q8[0]) {
av_log(avr, AV_LOG_ERROR, "matrix is not set\n");
return AVERROR(EINVAL);
}
for (o = 0; o < out_channels; o++)
for (i = 0; i < in_channels; i++)
- matrix[o * stride + i] = avr->am->matrix_q6[o][i] / 64.0;
+ matrix[o * stride + i] = avr->am->matrix_q8[o][i] / 256.0;
break;
case AV_MIX_COEFF_TYPE_Q15:
if (!avr->am->matrix_q15[0]) {
@@ -325,8 +369,8 @@ int avresample_set_matrix(AVAudioResampleContext *avr, const double *matrix,
avr->am->matrix = (void **)avr->am->matrix_## type;
switch (avr->mix_coeff_type) {
- case AV_MIX_COEFF_TYPE_Q6:
- CONVERT_MATRIX(q6, av_clip_int16(lrint(64.0 * v)))
+ case AV_MIX_COEFF_TYPE_Q8:
+ CONVERT_MATRIX(q8, av_clip_int16(lrint(256.0 * v)))
break;
case AV_MIX_COEFF_TYPE_Q15:
CONVERT_MATRIX(q15, av_clipl_int32(llrint(32768.0 * v)))
diff --git a/libavresample/avresample.h b/libavresample/avresample.h
index 41688ed..002bec2 100644
--- a/libavresample/avresample.h
+++ b/libavresample/avresample.h
@@ -39,7 +39,7 @@ typedef struct AVAudioResampleContext AVAudioResampleContext;
/** Mixing Coefficient Types */
enum AVMixCoeffType {
- AV_MIX_COEFF_TYPE_Q6, /** 16-bit 10.6 fixed-point */
+ AV_MIX_COEFF_TYPE_Q8, /** 16-bit 8.8 fixed-point */
AV_MIX_COEFF_TYPE_Q15, /** 32-bit 17.15 fixed-point */
AV_MIX_COEFF_TYPE_FLT, /** floating-point */
AV_MIX_COEFF_TYPE_NB, /** Number of coeff types. Not part of ABI */
@@ -131,12 +131,13 @@ void avresample_free(AVAudioResampleContext **avr);
* the weight of input channel i in output channel o.
* @param stride distance between adjacent input channels in the
* matrix array
+ * @param matrix_encoding matrixed stereo downmix mode (e.g. dplii)
* @return 0 on success, negative AVERROR code on failure
*/
int avresample_build_matrix(uint64_t in_layout, uint64_t out_layout,
double center_mix_level, double surround_mix_level,
double lfe_mix_level, int normalize, double *matrix,
- int stride);
+ int stride, enum AVMatrixEncoding matrix_encoding);
/**
* Get the current channel mixing matrix.
@@ -274,7 +275,8 @@ int avresample_available(AVAudioResampleContext *avr);
* @see avresample_convert()
*
* @param avr audio resample context
- * @param output output data pointers
+ * @param output output data pointers. May be NULL, in which case
+ * nb_samples of data is discarded from output FIFO.
* @param nb_samples number of samples to read from the FIFO
* @return the number of samples written to output
*/
diff --git a/libavresample/internal.h b/libavresample/internal.h
index 49ea6a6..fa9499a 100644
--- a/libavresample/internal.h
+++ b/libavresample/internal.h
@@ -70,6 +70,7 @@ struct AVAudioResampleContext {
AudioConvert *ac_out; /**< output sample format conversion context */
ResampleContext *resample; /**< resampling context */
AudioMix *am; /**< channel mixing context */
+ enum AVMatrixEncoding matrix_encoding; /**< matrixed stereo encoding */
};
#endif /* AVRESAMPLE_INTERNAL_H */
diff --git a/libavresample/options.c b/libavresample/options.c
index 0be1a26..a1a0b0c 100644
--- a/libavresample/options.c
+++ b/libavresample/options.c
@@ -40,8 +40,8 @@ static const AVOption options[] = {
{ "out_sample_fmt", "Output Sample Format", OFFSET(out_sample_fmt), AV_OPT_TYPE_INT, { AV_SAMPLE_FMT_S16 }, AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_NB-1, PARAM },
{ "out_sample_rate", "Output Sample Rate", OFFSET(out_sample_rate), AV_OPT_TYPE_INT, { 48000 }, 1, INT_MAX, PARAM },
{ "internal_sample_fmt", "Internal Sample Format", OFFSET(internal_sample_fmt), AV_OPT_TYPE_INT, { AV_SAMPLE_FMT_FLTP }, AV_SAMPLE_FMT_NONE, AV_SAMPLE_FMT_NB-1, PARAM },
- { "mix_coeff_type", "Mixing Coefficient Type", OFFSET(mix_coeff_type), AV_OPT_TYPE_INT, { AV_MIX_COEFF_TYPE_FLT }, AV_MIX_COEFF_TYPE_Q6, AV_MIX_COEFF_TYPE_NB-1, PARAM, "mix_coeff_type" },
- { "q6", "16-bit 10.6 Fixed-Point", 0, AV_OPT_TYPE_CONST, { AV_MIX_COEFF_TYPE_Q6 }, INT_MIN, INT_MAX, PARAM, "mix_coeff_type" },
+ { "mix_coeff_type", "Mixing Coefficient Type", OFFSET(mix_coeff_type), AV_OPT_TYPE_INT, { AV_MIX_COEFF_TYPE_FLT }, AV_MIX_COEFF_TYPE_Q8, AV_MIX_COEFF_TYPE_NB-1, PARAM, "mix_coeff_type" },
+ { "q8", "16-bit 8.8 Fixed-Point", 0, AV_OPT_TYPE_CONST, { AV_MIX_COEFF_TYPE_Q8 }, INT_MIN, INT_MAX, PARAM, "mix_coeff_type" },
{ "q15", "32-bit 17.15 Fixed-Point", 0, AV_OPT_TYPE_CONST, { AV_MIX_COEFF_TYPE_Q15 }, INT_MIN, INT_MAX, PARAM, "mix_coeff_type" },
{ "flt", "Floating-Point", 0, AV_OPT_TYPE_CONST, { AV_MIX_COEFF_TYPE_FLT }, INT_MIN, INT_MAX, PARAM, "mix_coeff_type" },
{ "center_mix_level", "Center Mix Level", OFFSET(center_mix_level), AV_OPT_TYPE_DOUBLE, { M_SQRT1_2 }, -32.0, 32.0, PARAM },
@@ -52,6 +52,10 @@ static const AVOption options[] = {
{ "phase_shift", "Resampling Phase Shift", OFFSET(phase_shift), AV_OPT_TYPE_INT, { 10 }, 0, 30, /* ??? */ PARAM },
{ "linear_interp", "Use Linear Interpolation", OFFSET(linear_interp), AV_OPT_TYPE_INT, { 0 }, 0, 1, PARAM },
{ "cutoff", "Cutoff Frequency Ratio", OFFSET(cutoff), AV_OPT_TYPE_DOUBLE, { 0.8 }, 0.0, 1.0, PARAM },
+ { "matrix_encoding", "Matrixed Stereo Encoding", OFFSET(matrix_encoding), AV_OPT_TYPE_INT, { AV_MATRIX_ENCODING_NONE}, AV_MATRIX_ENCODING_NONE, AV_MATRIX_ENCODING_NB-1, PARAM, "matrix_encoding" },
+ { "none", "None", 0, AV_OPT_TYPE_CONST, { AV_MATRIX_ENCODING_NONE }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
+ { "dolby", "Dolby", 0, AV_OPT_TYPE_CONST, { AV_MATRIX_ENCODING_DOLBY }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
+ { "dplii", "Dolby Pro Logic II", 0, AV_OPT_TYPE_CONST, { AV_MATRIX_ENCODING_DPLII }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
{ NULL },
};
diff --git a/libavresample/utils.c b/libavresample/utils.c
index f54dcc6..6d4509d 100644
--- a/libavresample/utils.c
+++ b/libavresample/utils.c
@@ -375,7 +375,8 @@ int avresample_convert(AVAudioResampleContext *avr, void **output,
}
}
- return handle_buffered_output(avr, &output_buffer, current_buffer);
+ return handle_buffered_output(avr, output ? &output_buffer : NULL,
+ current_buffer);
}
int avresample_available(AVAudioResampleContext *avr)
@@ -385,6 +386,8 @@ int avresample_available(AVAudioResampleContext *avr)
int avresample_read(AVAudioResampleContext *avr, void **output, int nb_samples)
{
+ if (!output)
+ return av_audio_fifo_drain(avr->out_fifo, nb_samples);
return av_audio_fifo_read(avr->out_fifo, output, nb_samples);
}
diff --git a/libavresample/version.h b/libavresample/version.h
index 4113edc..c4741e4 100644
--- a/libavresample/version.h
+++ b/libavresample/version.h
@@ -21,7 +21,7 @@
#define LIBAVRESAMPLE_VERSION_MAJOR 0
#define LIBAVRESAMPLE_VERSION_MINOR 0
-#define LIBAVRESAMPLE_VERSION_MICRO 0
+#define LIBAVRESAMPLE_VERSION_MICRO 3
#define LIBAVRESAMPLE_VERSION_INT AV_VERSION_INT(LIBAVRESAMPLE_VERSION_MAJOR, \
LIBAVRESAMPLE_VERSION_MINOR, \
@@ -34,8 +34,9 @@
#define LIBAVRESAMPLE_IDENT "Lavr" AV_STRINGIFY(LIBAVRESAMPLE_VERSION)
/**
- * These FF_API_* defines are not part of public API.
- * They may change, break or disappear at any time.
+ * FF_API_* defines may be placed below to indicate public API that will be
+ * dropped at a future version bump. The defines themselves are not part of
+ * the public API and may change, break or disappear at any time.
*/
#endif /* AVRESAMPLE_VERSION_H */
diff --git a/libavresample/x86/Makefile b/libavresample/x86/Makefile
index 63697fa..65bed89 100644
--- a/libavresample/x86/Makefile
+++ b/libavresample/x86/Makefile
@@ -1,5 +1,5 @@
OBJS += x86/audio_convert_init.o \
- x86/audio_mix_init.o
+ x86/audio_mix_init.o \
YASM-OBJS += x86/audio_convert.o \
- x86/audio_mix.o
+ x86/audio_mix.o \
diff --git a/libavresample/x86/audio_convert.asm b/libavresample/x86/audio_convert.asm
index 809c5d1..7b3cc22 100644
--- a/libavresample/x86/audio_convert.asm
+++ b/libavresample/x86/audio_convert.asm
@@ -1,6 +1,7 @@
;******************************************************************************
;* x86 optimized Format Conversion Utils
;* Copyright (c) 2008 Loren Merritt
+;* Copyright (c) 2012 Justin Ruggles <justin.ruggles at gmail.com>
;*
;* This file is part of Libav.
;*
@@ -21,9 +22,217 @@
%include "x86inc.asm"
%include "x86util.asm"
+%include "util.asm"
+
+SECTION_RODATA 32
+
+pf_s32_inv_scale: times 8 dd 0x30000000
+pf_s32_scale: times 8 dd 0x4f000000
+pf_s16_inv_scale: times 4 dd 0x38000000
+pf_s16_scale: times 4 dd 0x47000000
SECTION_TEXT
+;------------------------------------------------------------------------------
+; void ff_conv_s16_to_s32(int32_t *dst, const int16_t *src, int len);
+;------------------------------------------------------------------------------
+
+INIT_XMM sse2
+cglobal conv_s16_to_s32, 3,3,3, dst, src, len
+ lea lenq, [2*lend]
+ lea dstq, [dstq+2*lenq]
+ add srcq, lenq
+ neg lenq
+.loop:
+ mova m2, [srcq+lenq]
+ pxor m0, m0
+ pxor m1, m1
+ punpcklwd m0, m2
+ punpckhwd m1, m2
+ mova [dstq+2*lenq ], m0
+ mova [dstq+2*lenq+mmsize], m1
+ add lenq, mmsize
+ jl .loop
+ REP_RET
+
+;------------------------------------------------------------------------------
+; void ff_conv_s16_to_flt(float *dst, const int16_t *src, int len);
+;------------------------------------------------------------------------------
+
+%macro CONV_S16_TO_FLT 0
+cglobal conv_s16_to_flt, 3,3,3, dst, src, len
+ lea lenq, [2*lend]
+ add srcq, lenq
+ lea dstq, [dstq + 2*lenq]
+ neg lenq
+ mova m2, [pf_s16_inv_scale]
+ ALIGN 16
+.loop:
+ mova m0, [srcq+lenq]
+ S16_TO_S32_SX 0, 1
+ cvtdq2ps m0, m0
+ cvtdq2ps m1, m1
+ mulps m0, m2
+ mulps m1, m2
+ mova [dstq+2*lenq ], m0
+ mova [dstq+2*lenq+mmsize], m1
+ add lenq, mmsize
+ jl .loop
+ REP_RET
+%endmacro
+
+INIT_XMM sse2
+CONV_S16_TO_FLT
+INIT_XMM sse4
+CONV_S16_TO_FLT
+
+;------------------------------------------------------------------------------
+; void ff_conv_s32_to_s16(int16_t *dst, const int32_t *src, int len);
+;------------------------------------------------------------------------------
+
+%macro CONV_S32_TO_S16 0
+cglobal conv_s32_to_s16, 3,3,4, dst, src, len
+ lea lenq, [2*lend]
+ lea srcq, [srcq+2*lenq]
+ add dstq, lenq
+ neg lenq
+.loop:
+ mova m0, [srcq+2*lenq ]
+ mova m1, [srcq+2*lenq+ mmsize]
+ mova m2, [srcq+2*lenq+2*mmsize]
+ mova m3, [srcq+2*lenq+3*mmsize]
+ psrad m0, 16
+ psrad m1, 16
+ psrad m2, 16
+ psrad m3, 16
+ packssdw m0, m1
+ packssdw m2, m3
+ mova [dstq+lenq ], m0
+ mova [dstq+lenq+mmsize], m2
+ add lenq, mmsize*2
+ jl .loop
+%if mmsize == 8
+ emms
+ RET
+%else
+ REP_RET
+%endif
+%endmacro
+
+INIT_MMX mmx
+CONV_S32_TO_S16
+INIT_XMM sse2
+CONV_S32_TO_S16
+
+;------------------------------------------------------------------------------
+; void ff_conv_s32_to_flt(float *dst, const int32_t *src, int len);
+;------------------------------------------------------------------------------
+
+%macro CONV_S32_TO_FLT 0
+cglobal conv_s32_to_flt, 3,3,3, dst, src, len
+ lea lenq, [4*lend]
+ add srcq, lenq
+ add dstq, lenq
+ neg lenq
+ mova m0, [pf_s32_inv_scale]
+ ALIGN 16
+.loop:
+ cvtdq2ps m1, [srcq+lenq ]
+ cvtdq2ps m2, [srcq+lenq+mmsize]
+ mulps m1, m1, m0
+ mulps m2, m2, m0
+ mova [dstq+lenq ], m1
+ mova [dstq+lenq+mmsize], m2
+ add lenq, mmsize*2
+ jl .loop
+%if mmsize == 32
+ vzeroupper
+ RET
+%else
+ REP_RET
+%endif
+%endmacro
+
+INIT_XMM sse2
+CONV_S32_TO_FLT
+%if HAVE_AVX
+INIT_YMM avx
+CONV_S32_TO_FLT
+%endif
+
+;------------------------------------------------------------------------------
+; void ff_conv_flt_to_s16(int16_t *dst, const float *src, int len);
+;------------------------------------------------------------------------------
+
+INIT_XMM sse2
+cglobal conv_flt_to_s16, 3,3,5, dst, src, len
+ lea lenq, [2*lend]
+ lea srcq, [srcq+2*lenq]
+ add dstq, lenq
+ neg lenq
+ mova m4, [pf_s16_scale]
+.loop:
+ mova m0, [srcq+2*lenq ]
+ mova m1, [srcq+2*lenq+1*mmsize]
+ mova m2, [srcq+2*lenq+2*mmsize]
+ mova m3, [srcq+2*lenq+3*mmsize]
+ mulps m0, m4
+ mulps m1, m4
+ mulps m2, m4
+ mulps m3, m4
+ cvtps2dq m0, m0
+ cvtps2dq m1, m1
+ cvtps2dq m2, m2
+ cvtps2dq m3, m3
+ packssdw m0, m1
+ packssdw m2, m3
+ mova [dstq+lenq ], m0
+ mova [dstq+lenq+mmsize], m2
+ add lenq, mmsize*2
+ jl .loop
+ REP_RET
+
+;------------------------------------------------------------------------------
+; void ff_conv_flt_to_s32(int32_t *dst, const float *src, int len);
+;------------------------------------------------------------------------------
+
+%macro CONV_FLT_TO_S32 0
+cglobal conv_flt_to_s32, 3,3,5, dst, src, len
+ lea lenq, [lend*4]
+ add srcq, lenq
+ add dstq, lenq
+ neg lenq
+ mova m4, [pf_s32_scale]
+.loop:
+ mulps m0, m4, [srcq+lenq ]
+ mulps m1, m4, [srcq+lenq+1*mmsize]
+ mulps m2, m4, [srcq+lenq+2*mmsize]
+ mulps m3, m4, [srcq+lenq+3*mmsize]
+ cvtps2dq m0, m0
+ cvtps2dq m1, m1
+ cvtps2dq m2, m2
+ cvtps2dq m3, m3
+ mova [dstq+lenq ], m0
+ mova [dstq+lenq+1*mmsize], m1
+ mova [dstq+lenq+2*mmsize], m2
+ mova [dstq+lenq+3*mmsize], m3
+ add lenq, mmsize*4
+ jl .loop
+%if mmsize == 32
+ vzeroupper
+ RET
+%else
+ REP_RET
+%endif
+%endmacro
+
+INIT_XMM sse2
+CONV_FLT_TO_S32
+%if HAVE_AVX
+INIT_YMM avx
+CONV_FLT_TO_S32
+%endif
+
;-----------------------------------------------------------------------------
; void ff_conv_fltp_to_flt_6ch(float *dst, float *const *src, int len,
; int channels);
@@ -54,26 +263,24 @@ cglobal conv_fltp_to_flt_6ch, 2,8,7, dst, src, src1, src2, src3, src4, src5, len
mova m3, [srcq+src3q]
mova m4, [srcq+src4q]
mova m5, [srcq+src5q]
-%if cpuflag(sse)
+%if cpuflag(sse4)
SBUTTERFLYPS 0, 1, 6
SBUTTERFLYPS 2, 3, 6
SBUTTERFLYPS 4, 5, 6
- movaps m6, m4
- shufps m4, m0, q3210
+ blendps m6, m4, m0, 1100b
movlhps m0, m2
- movhlps m6, m2
- movaps [dstq ], m0
- movaps [dstq+16], m4
- movaps [dstq+32], m6
-
- movaps m6, m5
- shufps m5, m1, q3210
+ movhlps m4, m2
+ blendps m2, m5, m1, 1100b
movlhps m1, m3
- movhlps m6, m3
+ movhlps m5, m3
+
+ movaps [dstq ], m0
+ movaps [dstq+16], m6
+ movaps [dstq+32], m4
movaps [dstq+48], m1
- movaps [dstq+64], m5
- movaps [dstq+80], m6
+ movaps [dstq+64], m2
+ movaps [dstq+80], m5
%else ; mmx
SBUTTERFLY dq, 0, 1, 6
SBUTTERFLY dq, 2, 3, 6
@@ -100,5 +307,9 @@ cglobal conv_fltp_to_flt_6ch, 2,8,7, dst, src, src1, src2, src3, src4, src5, len
INIT_MMX mmx
CONV_FLTP_TO_FLT_6CH
-INIT_XMM sse
+INIT_XMM sse4
+CONV_FLTP_TO_FLT_6CH
+%if HAVE_AVX
+INIT_XMM avx
CONV_FLTP_TO_FLT_6CH
+%endif
diff --git a/libavresample/x86/audio_convert_init.c b/libavresample/x86/audio_convert_init.c
index 6883f10..2de4970 100644
--- a/libavresample/x86/audio_convert_init.c
+++ b/libavresample/x86/audio_convert_init.c
@@ -22,8 +22,28 @@
#include "libavutil/cpu.h"
#include "libavresample/audio_convert.h"
-extern void ff_conv_fltp_to_flt_6ch_mmx(float *dst, float *const *src, int len);
-extern void ff_conv_fltp_to_flt_6ch_sse(float *dst, float *const *src, int len);
+extern void ff_conv_s16_to_s32_sse2(int16_t *dst, const int32_t *src, int len);
+
+extern void ff_conv_s16_to_flt_sse2(float *dst, const int16_t *src, int len);
+extern void ff_conv_s16_to_flt_sse4(float *dst, const int16_t *src, int len);
+
+extern void ff_conv_s32_to_s16_mmx (int16_t *dst, const int32_t *src, int len);
+extern void ff_conv_s32_to_s16_sse2(int16_t *dst, const int32_t *src, int len);
+
+extern void ff_conv_s32_to_flt_sse2(float *dst, const int32_t *src, int len);
+extern void ff_conv_s32_to_flt_avx (float *dst, const int32_t *src, int len);
+
+extern void ff_conv_flt_to_s16_sse2(int16_t *dst, const float *src, int len);
+
+extern void ff_conv_flt_to_s32_sse2(int32_t *dst, const float *src, int len);
+extern void ff_conv_flt_to_s32_avx (int32_t *dst, const float *src, int len);
+
+extern void ff_conv_fltp_to_flt_6ch_mmx (float *dst, float *const *src, int len,
+ int channels);
+extern void ff_conv_fltp_to_flt_6ch_sse4(float *dst, float *const *src, int len,
+ int channels);
+extern void ff_conv_fltp_to_flt_6ch_avx (float *dst, float *const *src, int len,
+ int channels);
av_cold void ff_audio_convert_init_x86(AudioConvert *ac)
{
@@ -31,12 +51,40 @@ av_cold void ff_audio_convert_init_x86(AudioConvert *ac)
int mm_flags = av_get_cpu_flags();
if (mm_flags & AV_CPU_FLAG_MMX && HAVE_MMX) {
+ ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32,
+ 0, 1, 8, "MMX", ff_conv_s32_to_s16_mmx);
ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP,
6, 1, 4, "MMX", ff_conv_fltp_to_flt_6ch_mmx);
}
- if (mm_flags & AV_CPU_FLAG_SSE && HAVE_SSE) {
+ if (mm_flags & AV_CPU_FLAG_SSE2 && HAVE_SSE) {
+ if (!(mm_flags & AV_CPU_FLAG_SSE2SLOW)) {
+ ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32,
+ 0, 16, 16, "SSE2", ff_conv_s32_to_s16_sse2);
+ }
+ ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16,
+ 0, 16, 8, "SSE2", ff_conv_s16_to_s32_sse2);
+ ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16,
+ 0, 16, 8, "SSE2", ff_conv_s16_to_flt_sse2);
+ ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32,
+ 0, 16, 8, "SSE2", ff_conv_s32_to_flt_sse2);
+ ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT,
+ 0, 16, 16, "SSE2", ff_conv_flt_to_s16_sse2);
+ ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT,
+ 0, 16, 16, "SSE2", ff_conv_flt_to_s32_sse2);
+ }
+ if (mm_flags & AV_CPU_FLAG_SSE4 && HAVE_SSE) {
+ ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16,
+ 0, 16, 8, "SSE4", ff_conv_s16_to_flt_sse4);
+ ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP,
+ 6, 16, 4, "SSE4", ff_conv_fltp_to_flt_6ch_sse4);
+ }
+ if (mm_flags & AV_CPU_FLAG_AVX && HAVE_AVX) {
+ ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32,
+ 0, 32, 16, "AVX", ff_conv_s32_to_flt_avx);
+ ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT,
+ 0, 32, 32, "AVX", ff_conv_flt_to_s32_avx);
ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP,
- 6, 16, 4, "SSE", ff_conv_fltp_to_flt_6ch_sse);
+ 6, 16, 4, "AVX", ff_conv_fltp_to_flt_6ch_avx);
}
#endif
}
diff --git a/libavresample/x86/audio_mix.asm b/libavresample/x86/audio_mix.asm
index ef30f02..4b0434d 100644
--- a/libavresample/x86/audio_mix.asm
+++ b/libavresample/x86/audio_mix.asm
@@ -21,6 +21,7 @@
%include "x86inc.asm"
%include "x86util.asm"
+%include "util.asm"
SECTION_TEXT
@@ -60,5 +61,173 @@ cglobal mix_2_to_1_fltp_flt, 3,4,6, src, matrix, len, src1
INIT_XMM sse
MIX_2_TO_1_FLTP_FLT
+%if HAVE_AVX
INIT_YMM avx
MIX_2_TO_1_FLTP_FLT
+%endif
+
+;-----------------------------------------------------------------------------
+; void ff_mix_2_to_1_s16p_flt(int16_t **src, float **matrix, int len,
+; int out_ch, int in_ch);
+;-----------------------------------------------------------------------------
+
+%macro MIX_2_TO_1_S16P_FLT 0
+cglobal mix_2_to_1_s16p_flt, 3,4,6, src, matrix, len, src1
+ mov src1q, [srcq+gprsize]
+ mov srcq, [srcq]
+ sub src1q, srcq
+ mov matrixq, [matrixq ]
+ VBROADCASTSS m4, [matrixq ]
+ VBROADCASTSS m5, [matrixq+4]
+ ALIGN 16
+.loop:
+ mova m0, [srcq ]
+ mova m2, [srcq+src1q]
+ S16_TO_S32_SX 0, 1
+ S16_TO_S32_SX 2, 3
+ cvtdq2ps m0, m0
+ cvtdq2ps m1, m1
+ cvtdq2ps m2, m2
+ cvtdq2ps m3, m3
+ mulps m0, m4
+ mulps m1, m4
+ mulps m2, m5
+ mulps m3, m5
+ addps m0, m2
+ addps m1, m3
+ cvtps2dq m0, m0
+ cvtps2dq m1, m1
+ packssdw m0, m1
+ mova [srcq], m0
+ add srcq, mmsize
+ sub lend, mmsize/2
+ jg .loop
+ REP_RET
+%endmacro
+
+INIT_XMM sse2
+MIX_2_TO_1_S16P_FLT
+INIT_XMM sse4
+MIX_2_TO_1_S16P_FLT
+
+;-----------------------------------------------------------------------------
+; void ff_mix_2_to_1_s16p_q8(int16_t **src, int16_t **matrix, int len,
+; int out_ch, int in_ch);
+;-----------------------------------------------------------------------------
+
+INIT_XMM sse2
+cglobal mix_2_to_1_s16p_q8, 3,4,6, src, matrix, len, src1
+ mov src1q, [srcq+gprsize]
+ mov srcq, [srcq]
+ sub src1q, srcq
+ mov matrixq, [matrixq]
+ movd m4, [matrixq]
+ movd m5, [matrixq]
+ SPLATW m4, m4, 0
+ SPLATW m5, m5, 1
+ pxor m0, m0
+ punpcklwd m4, m0
+ punpcklwd m5, m0
+ ALIGN 16
+.loop:
+ mova m0, [srcq ]
+ mova m2, [srcq+src1q]
+ punpckhwd m1, m0, m0
+ punpcklwd m0, m0
+ punpckhwd m3, m2, m2
+ punpcklwd m2, m2
+ pmaddwd m0, m4
+ pmaddwd m1, m4
+ pmaddwd m2, m5
+ pmaddwd m3, m5
+ paddd m0, m2
+ paddd m1, m3
+ psrad m0, 8
+ psrad m1, 8
+ packssdw m0, m1
+ mova [srcq], m0
+ add srcq, mmsize
+ sub lend, mmsize/2
+ jg .loop
+ REP_RET
+
+;-----------------------------------------------------------------------------
+; void ff_mix_1_to_2_fltp_flt(float **src, float **matrix, int len,
+; int out_ch, int in_ch);
+;-----------------------------------------------------------------------------
+
+%macro MIX_1_TO_2_FLTP_FLT 0
+cglobal mix_1_to_2_fltp_flt, 3,5,4, src0, matrix0, len, src1, matrix1
+ mov src1q, [src0q+gprsize]
+ mov src0q, [src0q]
+ sub src1q, src0q
+ mov matrix1q, [matrix0q+gprsize]
+ mov matrix0q, [matrix0q]
+ VBROADCASTSS m2, [matrix0q]
+ VBROADCASTSS m3, [matrix1q]
+ ALIGN 16
+.loop:
+ mova m0, [src0q]
+ mulps m1, m0, m3
+ mulps m0, m0, m2
+ mova [src0q ], m0
+ mova [src0q+src1q], m1
+ add src0q, mmsize
+ sub lend, mmsize/4
+ jg .loop
+ REP_RET
+%endmacro
+
+INIT_XMM sse
+MIX_1_TO_2_FLTP_FLT
+%if HAVE_AVX
+INIT_YMM avx
+MIX_1_TO_2_FLTP_FLT
+%endif
+
+;-----------------------------------------------------------------------------
+; void ff_mix_1_to_2_s16p_flt(int16_t **src, float **matrix, int len,
+; int out_ch, int in_ch);
+;-----------------------------------------------------------------------------
+
+%macro MIX_1_TO_2_S16P_FLT 0
+cglobal mix_1_to_2_s16p_flt, 3,5,6, src0, matrix0, len, src1, matrix1
+ mov src1q, [src0q+gprsize]
+ mov src0q, [src0q]
+ sub src1q, src0q
+ mov matrix1q, [matrix0q+gprsize]
+ mov matrix0q, [matrix0q]
+ VBROADCASTSS m4, [matrix0q]
+ VBROADCASTSS m5, [matrix1q]
+ ALIGN 16
+.loop:
+ mova m0, [src0q]
+ S16_TO_S32_SX 0, 2
+ cvtdq2ps m0, m0
+ cvtdq2ps m2, m2
+ mulps m1, m0, m5
+ mulps m0, m0, m4
+ mulps m3, m2, m5
+ mulps m2, m2, m4
+ cvtps2dq m0, m0
+ cvtps2dq m1, m1
+ cvtps2dq m2, m2
+ cvtps2dq m3, m3
+ packssdw m0, m2
+ packssdw m1, m3
+ mova [src0q ], m0
+ mova [src0q+src1q], m1
+ add src0q, mmsize
+ sub lend, mmsize/2
+ jg .loop
+ REP_RET
+%endmacro
+
+INIT_XMM sse2
+MIX_1_TO_2_S16P_FLT
+INIT_XMM sse4
+MIX_1_TO_2_S16P_FLT
+%if HAVE_AVX
+INIT_XMM avx
+MIX_1_TO_2_S16P_FLT
+%endif
diff --git a/libavresample/x86/audio_mix_init.c b/libavresample/x86/audio_mix_init.c
index 8f8930f..b8f3a90 100644
--- a/libavresample/x86/audio_mix_init.c
+++ b/libavresample/x86/audio_mix_init.c
@@ -27,6 +27,26 @@ extern void ff_mix_2_to_1_fltp_flt_sse(float **src, float **matrix, int len,
extern void ff_mix_2_to_1_fltp_flt_avx(float **src, float **matrix, int len,
int out_ch, int in_ch);
+extern void ff_mix_2_to_1_s16p_flt_sse2(int16_t **src, float **matrix, int len,
+ int out_ch, int in_ch);
+extern void ff_mix_2_to_1_s16p_flt_sse4(int16_t **src, float **matrix, int len,
+ int out_ch, int in_ch);
+
+extern void ff_mix_2_to_1_s16p_q8_sse2(int16_t **src, int16_t **matrix,
+ int len, int out_ch, int in_ch);
+
+extern void ff_mix_1_to_2_fltp_flt_sse(float **src, float **matrix, int len,
+ int out_ch, int in_ch);
+extern void ff_mix_1_to_2_fltp_flt_avx(float **src, float **matrix, int len,
+ int out_ch, int in_ch);
+
+extern void ff_mix_1_to_2_s16p_flt_sse2(int16_t **src, float **matrix, int len,
+ int out_ch, int in_ch);
+extern void ff_mix_1_to_2_s16p_flt_sse4(int16_t **src, float **matrix, int len,
+ int out_ch, int in_ch);
+extern void ff_mix_1_to_2_s16p_flt_avx (int16_t **src, float **matrix, int len,
+ int out_ch, int in_ch);
+
av_cold void ff_audio_mix_init_x86(AudioMix *am)
{
#if HAVE_YASM
@@ -35,10 +55,30 @@ av_cold void ff_audio_mix_init_x86(AudioMix *am)
if (mm_flags & AV_CPU_FLAG_SSE && HAVE_SSE) {
ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
2, 1, 16, 8, "SSE", ff_mix_2_to_1_fltp_flt_sse);
+ ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
+ 1, 2, 16, 4, "SSE", ff_mix_1_to_2_fltp_flt_sse);
+ }
+ if (mm_flags & AV_CPU_FLAG_SSE2 && HAVE_SSE) {
+ ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,
+ 2, 1, 16, 8, "SSE2", ff_mix_2_to_1_s16p_flt_sse2);
+ ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_Q8,
+ 2, 1, 16, 8, "SSE2", ff_mix_2_to_1_s16p_q8_sse2);
+ ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,
+ 1, 2, 16, 8, "SSE2", ff_mix_1_to_2_s16p_flt_sse2);
+ }
+ if (mm_flags & AV_CPU_FLAG_SSE4 && HAVE_SSE) {
+ ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,
+ 2, 1, 16, 8, "SSE4", ff_mix_2_to_1_s16p_flt_sse4);
+ ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,
+ 1, 2, 16, 8, "SSE4", ff_mix_1_to_2_s16p_flt_sse4);
}
if (mm_flags & AV_CPU_FLAG_AVX && HAVE_AVX) {
ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
2, 1, 32, 16, "AVX", ff_mix_2_to_1_fltp_flt_avx);
+ ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
+ 1, 2, 32, 8, "AVX", ff_mix_1_to_2_fltp_flt_avx);
+ ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,
+ 1, 2, 16, 8, "AVX", ff_mix_1_to_2_s16p_flt_avx);
}
#endif
}
diff --git a/libavresample/x86/util.asm b/libavresample/x86/util.asm
new file mode 100644
index 0000000..501f662
--- /dev/null
+++ b/libavresample/x86/util.asm
@@ -0,0 +1,34 @@
+;******************************************************************************
+;* x86 utility macros for libavresample
+;* Copyright (c) 2012 Justin Ruggles <justin.ruggles at gmail.com>
+;*
+;* This file is part of Libav.
+;*
+;* Libav is free software; you can redistribute it and/or
+;* modify it under the terms of the GNU Lesser General Public
+;* License as published by the Free Software Foundation; either
+;* version 2.1 of the License, or (at your option) any later version.
+;*
+;* Libav is distributed in the hope that it will be useful,
+;* but WITHOUT ANY WARRANTY; without even the implied warranty of
+;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;* Lesser General Public License for more details.
+;*
+;* You should have received a copy of the GNU Lesser General Public
+;* License along with Libav; if not, write to the Free Software
+;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+;******************************************************************************
+
+%macro S16_TO_S32_SX 2 ; src/low dst, high dst
+%if cpuflag(sse4)
+ pmovsxwd m%2, m%1
+ psrldq m%1, 8
+ pmovsxwd m%1, m%1
+ SWAP %1, %2
+%else
+ punpckhwd m%2, m%1
+ punpcklwd m%1, m%1
+ psrad m%2, 16
+ psrad m%1, 16
+%endif
+%endmacro
diff --git a/libavutil/Makefile b/libavutil/Makefile
index 69f2acd..48f872d 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -9,6 +9,7 @@ HEADERS = adler32.h \
avstring.h \
avutil.h \
base64.h \
+ blowfish.h \
bswap.h \
common.h \
cpu.h \
@@ -36,6 +37,14 @@ HEADERS = adler32.h \
rational.h \
samplefmt.h \
sha.h \
+ time.h \
+ version.h \
+ xtea.h \
+
+ARCH_HEADERS = bswap.h \
+ intmath.h \
+ intreadwrite.h \
+ timer.h \
BUILT_HEADERS = avconfig.h
@@ -45,6 +54,7 @@ OBJS = adler32.o \
audioconvert.o \
avstring.o \
base64.o \
+ blowfish.o \
cpu.o \
crc.o \
des.o \
@@ -52,6 +62,7 @@ OBJS = adler32.o \
eval.o \
fifo.o \
file.o \
+ float_dsp.o \
imgutils.o \
intfloat_readwrite.o \
inverse.o \
@@ -71,10 +82,26 @@ OBJS = adler32.o \
rc4.o \
samplefmt.o \
sha.o \
+ time.o \
tree.o \
utils.o \
+ xtea.o \
-TESTPROGS = adler32 aes avstring base64 cpu crc des eval fifo lfg lls \
- md5 opt parseutils sha tree
-
-ARCH_HEADERS = bswap.h intmath.h intreadwrite.h timer.h
+TESTPROGS = adler32 \
+ aes \
+ avstring \
+ base64 \
+ blowfish \
+ cpu \
+ crc \
+ des \
+ eval \
+ fifo \
+ lfg \
+ lls \
+ md5 \
+ opt \
+ parseutils \
+ sha \
+ tree \
+ xtea \
diff --git a/libavutil/arm/Makefile b/libavutil/arm/Makefile
index 246f73a..ac7eca6 100644
--- a/libavutil/arm/Makefile
+++ b/libavutil/arm/Makefile
@@ -1 +1,8 @@
-OBJS += arm/cpu.o
+OBJS += arm/cpu.o \
+ arm/float_dsp_init_arm.o \
+
+ARMVFP-OBJS += arm/float_dsp_init_vfp.o \
+ arm/float_dsp_vfp.o \
+
+NEON-OBJS += arm/float_dsp_init_neon.o \
+ arm/float_dsp_neon.o \
diff --git a/libavutil/arm/asm.S b/libavutil/arm/asm.S
new file mode 100644
index 0000000..1508180
--- /dev/null
+++ b/libavutil/arm/asm.S
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2008 Mans Rullgard <mans at mansr.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+
+#ifdef __ELF__
+# define ELF
+#else
+# define ELF @
+#endif
+
+#if CONFIG_THUMB
+# define A @
+# define T
+#else
+# define A
+# define T @
+#endif
+
+#if HAVE_NEON
+ .arch armv7-a
+#elif HAVE_ARMV6T2
+ .arch armv6t2
+#elif HAVE_ARMV6
+ .arch armv6
+#elif HAVE_ARMV5TE
+ .arch armv5te
+#endif
+
+#if HAVE_NEON
+ .fpu neon
+#elif HAVE_ARMVFP
+ .fpu vfp
+#endif
+
+ .syntax unified
+T .thumb
+
+.macro require8 val=1
+ELF .eabi_attribute 24, \val
+.endm
+
+.macro preserve8 val=1
+ELF .eabi_attribute 25, \val
+.endm
+
+.macro function name, export=0
+ .set .Lpic_idx, 0
+ .set .Lpic_gp, 0
+ .macro endfunc
+ .if .Lpic_idx
+ .altmacro
+ put_pic %(.Lpic_idx - 1)
+ .noaltmacro
+ .endif
+ELF .size \name, . - \name
+ .endfunc
+ .purgem endfunc
+ .endm
+ .text
+ .align 2
+ .if \export
+ .global EXTERN_ASM\name
+EXTERN_ASM\name:
+ .endif
+ELF .type \name, %function
+ .func \name
+\name:
+.endm
+
+.macro const name, align=2
+ .macro endconst
+ELF .size \name, . - \name
+ .purgem endconst
+ .endm
+ .section .rodata
+ .align \align
+\name:
+.endm
+
+#if !HAVE_ARMV6T2
+.macro movw rd, val
+ mov \rd, \val & 255
+ orr \rd, \val & ~255
+.endm
+#endif
+
+.macro mov32 rd, val
+#if HAVE_ARMV6T2
+ movw \rd, #(\val) & 0xffff
+ .if (\val) >> 16
+ movt \rd, #(\val) >> 16
+ .endif
+#else
+ ldr \rd, =\val
+#endif
+.endm
+
+.macro put_pic num
+ put_pic_\num
+.endm
+
+.macro do_def_pic num, val, label
+ .macro put_pic_\num
+ .if \num
+ .altmacro
+ put_pic %(\num - 1)
+ .noaltmacro
+ .endif
+\label: .word \val
+ .purgem put_pic_\num
+ .endm
+.endm
+
+.macro def_pic val, label
+ .altmacro
+ do_def_pic %.Lpic_idx, \val, \label
+ .noaltmacro
+ .set .Lpic_idx, .Lpic_idx + 1
+.endm
+
+.macro ldpic rd, val, indir=0
+ ldr \rd, .Lpicoff\@
+.Lpic\@:
+ .if \indir
+ ldr \rd, [pc, \rd]
+ .else
+ add \rd, pc, \rd
+ .endif
+ def_pic \val - (.Lpic\@ + (8 >> CONFIG_THUMB)), .Lpicoff\@
+.endm
+
+.macro movrel rd, val
+#if CONFIG_PIC
+ ldpic \rd, \val
+#elif HAVE_ARMV6T2 && !defined(__APPLE__)
+ movw \rd, #:lower16:\val
+ movt \rd, #:upper16:\val
+#else
+ ldr \rd, =\val
+#endif
+.endm
+
+.macro movrelx rd, val, gp
+#if CONFIG_PIC && defined(__ELF__)
+ .ifnb \gp
+ .if .Lpic_gp
+ .unreq gp
+ .endif
+ gp .req \gp
+ ldpic gp, _GLOBAL_OFFSET_TABLE_
+ .elseif !.Lpic_gp
+ gp .req r12
+ ldpic gp, _GLOBAL_OFFSET_TABLE_
+ .endif
+ .set .Lpic_gp, 1
+ ldr \rd, .Lpicoff\@
+ ldr \rd, [gp, \rd]
+ def_pic \val(GOT), .Lpicoff\@
+#elif CONFIG_PIC && defined(__APPLE__)
+ ldpic \rd, .Lpic\@, indir=1
+ .non_lazy_symbol_pointer
+.Lpic\@:
+ .indirect_symbol \val
+ .word 0
+ .text
+#else
+ movrel \rd, \val
+#endif
+.endm
+
+.macro ldr_pre rt, rn, rm:vararg
+A ldr \rt, [\rn, \rm]!
+T add \rn, \rn, \rm
+T ldr \rt, [\rn]
+.endm
+
+.macro ldr_dpre rt, rn, rm:vararg
+A ldr \rt, [\rn, -\rm]!
+T sub \rn, \rn, \rm
+T ldr \rt, [\rn]
+.endm
+
+.macro ldr_nreg rt, rn, rm:vararg
+A ldr \rt, [\rn, -\rm]
+T sub \rt, \rn, \rm
+T ldr \rt, [\rt]
+.endm
+
+.macro ldr_post rt, rn, rm:vararg
+A ldr \rt, [\rn], \rm
+T ldr \rt, [\rn]
+T add \rn, \rn, \rm
+.endm
+
+.macro ldrd_reg rt, rt2, rn, rm
+A ldrd \rt, \rt2, [\rn, \rm]
+T add \rt, \rn, \rm
+T ldrd \rt, \rt2, [\rt]
+.endm
+
+.macro ldrd_post rt, rt2, rn, rm
+A ldrd \rt, \rt2, [\rn], \rm
+T ldrd \rt, \rt2, [\rn]
+T add \rn, \rn, \rm
+.endm
+
+.macro ldrh_pre rt, rn, rm
+A ldrh \rt, [\rn, \rm]!
+T add \rn, \rn, \rm
+T ldrh \rt, [\rn]
+.endm
+
+.macro ldrh_dpre rt, rn, rm
+A ldrh \rt, [\rn, -\rm]!
+T sub \rn, \rn, \rm
+T ldrh \rt, [\rn]
+.endm
+
+.macro ldrh_post rt, rn, rm
+A ldrh \rt, [\rn], \rm
+T ldrh \rt, [\rn]
+T add \rn, \rn, \rm
+.endm
+
+.macro ldrb_post rt, rn, rm
+A ldrb \rt, [\rn], \rm
+T ldrb \rt, [\rn]
+T add \rn, \rn, \rm
+.endm
+
+.macro str_post rt, rn, rm:vararg
+A str \rt, [\rn], \rm
+T str \rt, [\rn]
+T add \rn, \rn, \rm
+.endm
+
+.macro strb_post rt, rn, rm:vararg
+A strb \rt, [\rn], \rm
+T strb \rt, [\rn]
+T add \rn, \rn, \rm
+.endm
+
+.macro strd_post rt, rt2, rn, rm
+A strd \rt, \rt2, [\rn], \rm
+T strd \rt, \rt2, [\rn]
+T add \rn, \rn, \rm
+.endm
+
+.macro strh_pre rt, rn, rm
+A strh \rt, [\rn, \rm]!
+T add \rn, \rn, \rm
+T strh \rt, [\rn]
+.endm
+
+.macro strh_dpre rt, rn, rm
+A strh \rt, [\rn, -\rm]!
+T sub \rn, \rn, \rm
+T strh \rt, [\rn]
+.endm
+
+.macro strh_post rt, rn, rm
+A strh \rt, [\rn], \rm
+T strh \rt, [\rn]
+T add \rn, \rn, \rm
+.endm
+
+.macro strh_dpost rt, rn, rm
+A strh \rt, [\rn], -\rm
+T strh \rt, [\rn]
+T sub \rn, \rn, \rm
+.endm
+
+#if HAVE_VFP_ARGS
+ .eabi_attribute 28, 1
+# define VFP
+# define NOVFP @
+#else
+# define VFP @
+# define NOVFP
+#endif
+
+#define GLUE(a, b) a ## b
+#define JOIN(a, b) GLUE(a, b)
+#define X(s) JOIN(EXTERN_ASM, s)
diff --git a/libavutil/arm/float_dsp_arm.h b/libavutil/arm/float_dsp_arm.h
new file mode 100644
index 0000000..81fad3e
--- /dev/null
+++ b/libavutil/arm/float_dsp_arm.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2009 Mans Rullgard <mans at mansr.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_ARM_FLOAT_DSP_ARM_H
+#define AVUTIL_ARM_FLOAT_DSP_ARM_H
+
+#include "libavutil/float_dsp.h"
+
+void ff_float_dsp_init_vfp (AVFloatDSPContext *fdsp);
+void ff_float_dsp_init_neon(AVFloatDSPContext *fdsp);
+
+#endif /* AVUTIL_ARM_FLOAT_DSP_ARM_H */
diff --git a/libavutil/arm/float_dsp_init_arm.c b/libavutil/arm/float_dsp_init_arm.c
new file mode 100644
index 0000000..b133d32
--- /dev/null
+++ b/libavutil/arm/float_dsp_init_arm.c
@@ -0,0 +1,33 @@
+/*
+ * ARM optimized DSP utils
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/float_dsp.h"
+#include "cpu.h"
+#include "float_dsp_arm.h"
+
+void ff_float_dsp_init_arm(AVFloatDSPContext *fdsp)
+{
+ int cpu_flags = av_get_cpu_flags();
+
+ if (have_vfp(cpu_flags))
+ ff_float_dsp_init_vfp(fdsp);
+ if (have_neon(cpu_flags))
+ ff_float_dsp_init_neon(fdsp);
+}
diff --git a/libavutil/arm/float_dsp_init_neon.c b/libavutil/arm/float_dsp_init_neon.c
new file mode 100644
index 0000000..3ca0288
--- /dev/null
+++ b/libavutil/arm/float_dsp_init_neon.c
@@ -0,0 +1,36 @@
+/*
+ * ARM NEON optimised Float DSP functions
+ * Copyright (c) 2008 Mans Rullgard <mans at mansr.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+
+#include "libavutil/float_dsp.h"
+#include "float_dsp_arm.h"
+
+void ff_vector_fmul_neon(float *dst, const float *src0, const float *src1, int len);
+
+void ff_vector_fmac_scalar_neon(float *dst, const float *src, float mul,
+ int len);
+
+void ff_float_dsp_init_neon(AVFloatDSPContext *fdsp)
+{
+ fdsp->vector_fmul = ff_vector_fmul_neon;
+ fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_neon;
+}
diff --git a/libavutil/arm/float_dsp_init_vfp.c b/libavutil/arm/float_dsp_init_vfp.c
new file mode 100644
index 0000000..ef808d8
--- /dev/null
+++ b/libavutil/arm/float_dsp_init_vfp.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2008 Siarhei Siamashka <ssvb at users.sourceforge.net>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/float_dsp.h"
+#include "cpu.h"
+#include "float_dsp_arm.h"
+
+void ff_vector_fmul_vfp(float *dst, const float *src0, const float *src1,
+ int len);
+
+void ff_float_dsp_init_vfp(AVFloatDSPContext *fdsp)
+{
+ int cpu_flags = av_get_cpu_flags();
+
+ if (!have_vfpv3(cpu_flags))
+ fdsp->vector_fmul = ff_vector_fmul_vfp;
+}
diff --git a/libavutil/arm/float_dsp_neon.S b/libavutil/arm/float_dsp_neon.S
new file mode 100644
index 0000000..03b1643
--- /dev/null
+++ b/libavutil/arm/float_dsp_neon.S
@@ -0,0 +1,112 @@
+/*
+ * ARM NEON optimised Float DSP functions
+ * Copyright (c) 2008 Mans Rullgard <mans at mansr.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "asm.S"
+
+ preserve8
+
+function ff_vector_fmul_neon, export=1
+ subs r3, r3, #8
+ vld1.32 {d0-d3}, [r1,:128]!
+ vld1.32 {d4-d7}, [r2,:128]!
+ vmul.f32 q8, q0, q2
+ vmul.f32 q9, q1, q3
+ beq 3f
+ bics ip, r3, #15
+ beq 2f
+1: subs ip, ip, #16
+ vld1.32 {d0-d1}, [r1,:128]!
+ vld1.32 {d4-d5}, [r2,:128]!
+ vmul.f32 q10, q0, q2
+ vld1.32 {d2-d3}, [r1,:128]!
+ vld1.32 {d6-d7}, [r2,:128]!
+ vmul.f32 q11, q1, q3
+ vst1.32 {d16-d19},[r0,:128]!
+ vld1.32 {d0-d1}, [r1,:128]!
+ vld1.32 {d4-d5}, [r2,:128]!
+ vmul.f32 q8, q0, q2
+ vld1.32 {d2-d3}, [r1,:128]!
+ vld1.32 {d6-d7}, [r2,:128]!
+ vmul.f32 q9, q1, q3
+ vst1.32 {d20-d23},[r0,:128]!
+ bne 1b
+ ands r3, r3, #15
+ beq 3f
+2: vld1.32 {d0-d1}, [r1,:128]!
+ vld1.32 {d4-d5}, [r2,:128]!
+ vst1.32 {d16-d17},[r0,:128]!
+ vmul.f32 q8, q0, q2
+ vld1.32 {d2-d3}, [r1,:128]!
+ vld1.32 {d6-d7}, [r2,:128]!
+ vst1.32 {d18-d19},[r0,:128]!
+ vmul.f32 q9, q1, q3
+3: vst1.32 {d16-d19},[r0,:128]!
+ bx lr
+endfunc
+
+function ff_vector_fmac_scalar_neon, export=1
+VFP len .req r2
+VFP acc .req r3
+NOVFP len .req r3
+NOVFP acc .req r2
+VFP vdup.32 q15, d0[0]
+NOVFP vdup.32 q15, r2
+ bics r12, len, #15
+ mov acc, r0
+ beq 3f
+ vld1.32 {q0}, [r1,:128]!
+ vld1.32 {q8}, [acc,:128]!
+ vld1.32 {q1}, [r1,:128]!
+ vld1.32 {q9}, [acc,:128]!
+1: vmla.f32 q8, q0, q15
+ vld1.32 {q2}, [r1,:128]!
+ vld1.32 {q10}, [acc,:128]!
+ vmla.f32 q9, q1, q15
+ vld1.32 {q3}, [r1,:128]!
+ vld1.32 {q11}, [acc,:128]!
+ vmla.f32 q10, q2, q15
+ vst1.32 {q8}, [r0,:128]!
+ vmla.f32 q11, q3, q15
+ vst1.32 {q9}, [r0,:128]!
+ subs r12, r12, #16
+ beq 2f
+ vld1.32 {q0}, [r1,:128]!
+ vld1.32 {q8}, [acc,:128]!
+ vst1.32 {q10}, [r0,:128]!
+ vld1.32 {q1}, [r1,:128]!
+ vld1.32 {q9}, [acc,:128]!
+ vst1.32 {q11}, [r0,:128]!
+ b 1b
+2: vst1.32 {q10}, [r0,:128]!
+ vst1.32 {q11}, [r0,:128]!
+ ands len, len, #15
+ it eq
+ bxeq lr
+3: vld1.32 {q0}, [r1,:128]!
+ vld1.32 {q8}, [acc,:128]!
+ vmla.f32 q8, q0, q15
+ vst1.32 {q8}, [r0,:128]!
+ subs len, len, #4
+ bgt 3b
+ bx lr
+ .unreq len
+endfunc
diff --git a/libavutil/arm/float_dsp_vfp.S b/libavutil/arm/float_dsp_vfp.S
new file mode 100644
index 0000000..3931828
--- /dev/null
+++ b/libavutil/arm/float_dsp_vfp.S
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2008 Siarhei Siamashka <ssvb at users.sourceforge.net>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "asm.S"
+
+/**
+ * Assume that len is a positive number and is multiple of 8
+ */
+@ void ff_vector_fmul_vfp(float *dst, const float *src0, const float *src1, int len)
+function ff_vector_fmul_vfp, export=1
+ vpush {d8-d15}
+ fmrx r12, fpscr
+ orr r12, r12, #(3 << 16) /* set vector size to 4 */
+ fmxr fpscr, r12
+
+ vldmia r1!, {s0-s3}
+ vldmia r2!, {s8-s11}
+ vldmia r1!, {s4-s7}
+ vldmia r2!, {s12-s15}
+ vmul.f32 s8, s0, s8
+1:
+ subs r3, r3, #16
+ vmul.f32 s12, s4, s12
+ itttt ge
+ vldmiage r1!, {s16-s19}
+ vldmiage r2!, {s24-s27}
+ vldmiage r1!, {s20-s23}
+ vldmiage r2!, {s28-s31}
+ it ge
+ vmulge.f32 s24, s16, s24
+ vstmia r0!, {s8-s11}
+ vstmia r0!, {s12-s15}
+ it ge
+ vmulge.f32 s28, s20, s28
+ itttt gt
+ vldmiagt r1!, {s0-s3}
+ vldmiagt r2!, {s8-s11}
+ vldmiagt r1!, {s4-s7}
+ vldmiagt r2!, {s12-s15}
+ ittt ge
+ vmulge.f32 s8, s0, s8
+ vstmiage r0!, {s24-s27}
+ vstmiage r0!, {s28-s31}
+ bgt 1b
+
+ bic r12, r12, #(7 << 16) /* set vector size back to 1 */
+ fmxr fpscr, r12
+ vpop {d8-d15}
+ bx lr
+endfunc
diff --git a/libavutil/arm/intreadwrite.h b/libavutil/arm/intreadwrite.h
index 613abe5..ed53330 100644
--- a/libavutil/arm/intreadwrite.h
+++ b/libavutil/arm/intreadwrite.h
@@ -21,14 +21,22 @@
#include <stdint.h>
#include "config.h"
+#include "libavutil/attributes.h"
-#if HAVE_FAST_UNALIGNED && HAVE_INLINE_ASM
+#if HAVE_FAST_UNALIGNED && HAVE_INLINE_ASM && !AV_GCC_VERSION_AT_LEAST(4,7)
#define AV_RN16 AV_RN16
static av_always_inline unsigned AV_RN16(const void *p)
{
+ const uint8_t *q = p;
unsigned v;
- __asm__ ("ldrh %0, %1" : "=r"(v) : "m"(*(const uint16_t *)p));
+#if !AV_GCC_VERSION_AT_LEAST(4,6)
+ __asm__ ("ldrh %0, %1" : "=r"(v) : "m"(*(const uint16_t *)q));
+#elif defined __thumb__
+ __asm__ ("ldrh %0, %1" : "=r"(v) : "m"(q[0]), "m"(q[1]));
+#else
+ __asm__ ("ldrh %0, %1" : "=r"(v) : "Uq"(q[0]), "m"(q[1]));
+#endif
return v;
}
@@ -41,8 +49,9 @@ static av_always_inline void AV_WN16(void *p, uint16_t v)
#define AV_RN32 AV_RN32
static av_always_inline uint32_t AV_RN32(const void *p)
{
+ const struct __attribute__((packed)) { uint32_t v; } *q = p;
uint32_t v;
- __asm__ ("ldr %0, %1" : "=r"(v) : "m"(*(const uint32_t *)p));
+ __asm__ ("ldr %0, %1" : "=r"(v) : "m"(*q));
return v;
}
@@ -55,11 +64,12 @@ static av_always_inline void AV_WN32(void *p, uint32_t v)
#define AV_RN64 AV_RN64
static av_always_inline uint64_t AV_RN64(const void *p)
{
+ const struct __attribute__((packed)) { uint32_t v; } *q = p;
uint64_t v;
__asm__ ("ldr %Q0, %1 \n\t"
"ldr %R0, %2 \n\t"
: "=&r"(v)
- : "m"(*(const uint32_t*)p), "m"(*((const uint32_t*)p+1)));
+ : "m"(q[0]), "m"(q[1]));
return v;
}
diff --git a/libavutil/attributes.h b/libavutil/attributes.h
index ef990a1..292a0a1 100644
--- a/libavutil/attributes.h
+++ b/libavutil/attributes.h
@@ -32,98 +32,78 @@
# define AV_GCC_VERSION_AT_LEAST(x,y) 0
#endif
-#ifndef av_always_inline
#if AV_GCC_VERSION_AT_LEAST(3,1)
# define av_always_inline __attribute__((always_inline)) inline
+#elif defined(_MSC_VER)
+# define av_always_inline __forceinline
#else
# define av_always_inline inline
#endif
-#endif
-#ifndef av_noinline
#if AV_GCC_VERSION_AT_LEAST(3,1)
# define av_noinline __attribute__((noinline))
#else
# define av_noinline
#endif
-#endif
-#ifndef av_pure
#if AV_GCC_VERSION_AT_LEAST(3,1)
# define av_pure __attribute__((pure))
#else
# define av_pure
#endif
-#endif
-#ifndef av_const
#if AV_GCC_VERSION_AT_LEAST(2,6)
# define av_const __attribute__((const))
#else
# define av_const
#endif
-#endif
-#ifndef av_cold
#if AV_GCC_VERSION_AT_LEAST(4,3)
# define av_cold __attribute__((cold))
#else
# define av_cold
#endif
-#endif
-#ifndef av_flatten
#if AV_GCC_VERSION_AT_LEAST(4,1)
# define av_flatten __attribute__((flatten))
#else
# define av_flatten
#endif
-#endif
-#ifndef attribute_deprecated
#if AV_GCC_VERSION_AT_LEAST(3,1)
# define attribute_deprecated __attribute__((deprecated))
#else
# define attribute_deprecated
#endif
-#endif
-#ifndef av_unused
#if defined(__GNUC__)
# define av_unused __attribute__((unused))
#else
# define av_unused
#endif
-#endif
/**
* Mark a variable as used and prevent the compiler from optimizing it
* away. This is useful for variables accessed only from inline
* assembler without the compiler being aware.
*/
-#ifndef av_used
#if AV_GCC_VERSION_AT_LEAST(3,1)
# define av_used __attribute__((used))
#else
# define av_used
#endif
-#endif
-#ifndef av_alias
#if AV_GCC_VERSION_AT_LEAST(3,3)
# define av_alias __attribute__((may_alias))
#else
# define av_alias
#endif
-#endif
-#ifndef av_uninit
#if defined(__GNUC__) && !defined(__ICC)
# define av_uninit(x) x=x
#else
# define av_uninit(x) x
#endif
-#endif
#ifdef __GNUC__
# define av_builtin_constant_p __builtin_constant_p
@@ -133,4 +113,10 @@
# define av_printf_format(fmtpos, attrpos)
#endif
+#if AV_GCC_VERSION_AT_LEAST(2,5)
+# define av_noreturn __attribute__((noreturn))
+#else
+# define av_noreturn
+#endif
+
#endif /* AVUTIL_ATTRIBUTES_H */
diff --git a/libavutil/audioconvert.c b/libavutil/audioconvert.c
index 2560127..1ac63a3 100644
--- a/libavutil/audioconvert.c
+++ b/libavutil/audioconvert.c
@@ -175,11 +175,7 @@ void av_get_channel_layout_string(char *buf, int buf_size,
int av_get_channel_layout_nb_channels(uint64_t channel_layout)
{
- int count;
- uint64_t x = channel_layout;
- for (count = 0; x; count++)
- x &= x-1; // unset lowest set bit
- return count;
+ return av_popcount64(channel_layout);
}
uint64_t av_get_default_channel_layout(int nb_channels)
@@ -196,3 +192,38 @@ uint64_t av_get_default_channel_layout(int nb_channels)
default: return 0;
}
}
+
+int av_get_channel_layout_channel_index(uint64_t channel_layout,
+ uint64_t channel)
+{
+ if (!(channel_layout & channel) ||
+ av_get_channel_layout_nb_channels(channel) != 1)
+ return AVERROR(EINVAL);
+ channel_layout &= channel - 1;
+ return av_get_channel_layout_nb_channels(channel_layout);
+}
+
+const char *av_get_channel_name(uint64_t channel)
+{
+ int i;
+ if (av_get_channel_layout_nb_channels(channel) != 1)
+ return NULL;
+ for (i = 0; i < 64; i++)
+ if ((1ULL<<i) & channel)
+ return get_channel_name(i);
+ return NULL;
+}
+
+uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index)
+{
+ int i;
+
+ if (av_get_channel_layout_nb_channels(channel_layout) <= index)
+ return 0;
+
+ for (i = 0; i < 64; i++) {
+ if ((1ULL << i) & channel_layout && !index--)
+ return 1ULL << i;
+ }
+ return 0;
+}
diff --git a/libavutil/audioconvert.h b/libavutil/audioconvert.h
index 35a1a08..7e79097 100644
--- a/libavutil/audioconvert.h
+++ b/libavutil/audioconvert.h
@@ -101,6 +101,13 @@
#define AV_CH_LAYOUT_OCTAGONAL (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_LEFT|AV_CH_BACK_CENTER|AV_CH_BACK_RIGHT)
#define AV_CH_LAYOUT_STEREO_DOWNMIX (AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT)
+enum AVMatrixEncoding {
+ AV_MATRIX_ENCODING_NONE,
+ AV_MATRIX_ENCODING_DOLBY,
+ AV_MATRIX_ENCODING_DPLII,
+ AV_MATRIX_ENCODING_NB
+};
+
/**
* @}
*/
@@ -144,6 +151,30 @@ int av_get_channel_layout_nb_channels(uint64_t channel_layout);
uint64_t av_get_default_channel_layout(int nb_channels);
/**
+ * Get the index of a channel in channel_layout.
+ *
+ * @param channel a channel layout describing exactly one channel which must be
+ * present in channel_layout.
+ *
+ * @return index of channel in channel_layout on success, a negative AVERROR
+ * on error.
+ */
+int av_get_channel_layout_channel_index(uint64_t channel_layout,
+ uint64_t channel);
+
+/**
+ * Get the channel with the given index in channel_layout.
+ */
+uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index);
+
+/**
+ * Get the name of a given channel.
+ *
+ * @return channel name on success, NULL on error.
+ */
+const char *av_get_channel_name(uint64_t channel);
+
+/**
* @}
*/
diff --git a/libavutil/avutil.h b/libavutil/avutil.h
index bf2f89a..6811ad5 100644
--- a/libavutil/avutil.h
+++ b/libavutil/avutil.h
@@ -142,56 +142,6 @@
/**
* @}
- *
- * @defgroup lavu_ver Version and Build diagnostics
- *
- * Macros and function useful to check at compiletime and at runtime
- * which version of libavutil is in use.
- *
- * @{
- */
-
-#define LIBAVUTIL_VERSION_MAJOR 51
-#define LIBAVUTIL_VERSION_MINOR 29
-#define LIBAVUTIL_VERSION_MICRO 0
-
-#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
- LIBAVUTIL_VERSION_MINOR, \
- LIBAVUTIL_VERSION_MICRO)
-#define LIBAVUTIL_VERSION AV_VERSION(LIBAVUTIL_VERSION_MAJOR, \
- LIBAVUTIL_VERSION_MINOR, \
- LIBAVUTIL_VERSION_MICRO)
-#define LIBAVUTIL_BUILD LIBAVUTIL_VERSION_INT
-
-#define LIBAVUTIL_IDENT "Lavu" AV_STRINGIFY(LIBAVUTIL_VERSION)
-
-/**
- * @}
- *
- * @defgroup depr_guards Deprecation guards
- * Those FF_API_* defines are not part of public API.
- * They may change, break or disappear at any time.
- *
- * They are used mostly internally to mark code that will be removed
- * on the next major version.
- *
- * @{
- */
-#ifndef FF_API_GET_BITS_PER_SAMPLE_FMT
-#define FF_API_GET_BITS_PER_SAMPLE_FMT (LIBAVUTIL_VERSION_MAJOR < 52)
-#endif
-#ifndef FF_API_FIND_OPT
-#define FF_API_FIND_OPT (LIBAVUTIL_VERSION_MAJOR < 52)
-#endif
-#ifndef FF_API_AV_FIFO_PEEK
-#define FF_API_AV_FIFO_PEEK (LIBAVUTIL_VERSION_MAJOR < 52)
-#endif
-#ifndef FF_API_OLD_AVOPTIONS
-#define FF_API_OLD_AVOPTIONS (LIBAVUTIL_VERSION_MAJOR < 52)
-#endif
-
-/**
- * @}
*/
/**
@@ -315,6 +265,7 @@ char av_get_picture_type_char(enum AVPictureType pict_type);
#include "common.h"
#include "error.h"
+#include "version.h"
/**
* @}
diff --git a/libavutil/blowfish.c b/libavutil/blowfish.c
new file mode 100644
index 0000000..5df3dfc
--- /dev/null
+++ b/libavutil/blowfish.c
@@ -0,0 +1,570 @@
+/*
+ * Blowfish algorithm
+ * Copyright (c) 2012 Samuel Pitoiset
+ *
+ * loosely based on Paul Kocher's implementation
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/intreadwrite.h"
+
+#include "avutil.h"
+#include "common.h"
+#include "blowfish.h"
+
+static const uint32_t orig_p[AV_BF_ROUNDS + 2] = {
+ 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344,
+ 0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89,
+ 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
+ 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917,
+ 0x9216D5D9, 0x8979FB1B
+};
+
+static const uint32_t orig_s[4][256] = {
+ { 0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7,
+ 0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99,
+ 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16,
+ 0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E,
+ 0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE,
+ 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013,
+ 0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF,
+ 0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E,
+ 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60,
+ 0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440,
+ 0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE,
+ 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A,
+ 0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E,
+ 0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677,
+ 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193,
+ 0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032,
+ 0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88,
+ 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239,
+ 0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E,
+ 0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0,
+ 0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3,
+ 0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98,
+ 0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88,
+ 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE,
+ 0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6,
+ 0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D,
+ 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B,
+ 0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7,
+ 0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA,
+ 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463,
+ 0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F,
+ 0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09,
+ 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3,
+ 0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB,
+ 0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279,
+ 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
+ 0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB,
+ 0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82,
+ 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB,
+ 0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573,
+ 0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0,
+ 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B,
+ 0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790,
+ 0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8,
+ 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4,
+ 0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0,
+ 0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7,
+ 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C,
+ 0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD,
+ 0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1,
+ 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299,
+ 0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9,
+ 0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477,
+ 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF,
+ 0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49,
+ 0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF,
+ 0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA,
+ 0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5,
+ 0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41,
+ 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915,
+ 0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400,
+ 0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915,
+ 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664,
+ 0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A },
+ { 0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623,
+ 0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266,
+ 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1,
+ 0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E,
+ 0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6,
+ 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1,
+ 0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E,
+ 0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1,
+ 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737,
+ 0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8,
+ 0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF,
+ 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD,
+ 0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701,
+ 0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7,
+ 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41,
+ 0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331,
+ 0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF,
+ 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF,
+ 0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E,
+ 0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87,
+ 0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C,
+ 0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2,
+ 0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16,
+ 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD,
+ 0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B,
+ 0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509,
+ 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E,
+ 0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3,
+ 0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F,
+ 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A,
+ 0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4,
+ 0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960,
+ 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66,
+ 0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28,
+ 0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802,
+ 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
+ 0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510,
+ 0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF,
+ 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14,
+ 0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E,
+ 0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50,
+ 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7,
+ 0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8,
+ 0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281,
+ 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99,
+ 0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696,
+ 0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128,
+ 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73,
+ 0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0,
+ 0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0,
+ 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105,
+ 0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250,
+ 0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3,
+ 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285,
+ 0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00,
+ 0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061,
+ 0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB,
+ 0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E,
+ 0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735,
+ 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC,
+ 0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9,
+ 0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340,
+ 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20,
+ 0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7 },
+ { 0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934,
+ 0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068,
+ 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF,
+ 0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840,
+ 0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45,
+ 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504,
+ 0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A,
+ 0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB,
+ 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE,
+ 0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6,
+ 0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42,
+ 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B,
+ 0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2,
+ 0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB,
+ 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527,
+ 0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B,
+ 0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33,
+ 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C,
+ 0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3,
+ 0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC,
+ 0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17,
+ 0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564,
+ 0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B,
+ 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115,
+ 0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922,
+ 0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728,
+ 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0,
+ 0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E,
+ 0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37,
+ 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D,
+ 0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804,
+ 0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B,
+ 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3,
+ 0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB,
+ 0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D,
+ 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
+ 0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350,
+ 0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9,
+ 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A,
+ 0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE,
+ 0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D,
+ 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC,
+ 0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F,
+ 0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61,
+ 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2,
+ 0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9,
+ 0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2,
+ 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C,
+ 0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E,
+ 0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633,
+ 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10,
+ 0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169,
+ 0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52,
+ 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027,
+ 0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5,
+ 0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62,
+ 0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634,
+ 0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76,
+ 0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24,
+ 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC,
+ 0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4,
+ 0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C,
+ 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837,
+ 0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0 },
+ { 0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B,
+ 0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE,
+ 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B,
+ 0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4,
+ 0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8,
+ 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6,
+ 0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304,
+ 0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22,
+ 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4,
+ 0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6,
+ 0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9,
+ 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59,
+ 0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593,
+ 0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51,
+ 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28,
+ 0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C,
+ 0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B,
+ 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28,
+ 0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C,
+ 0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD,
+ 0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A,
+ 0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319,
+ 0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB,
+ 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F,
+ 0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991,
+ 0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32,
+ 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680,
+ 0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166,
+ 0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE,
+ 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB,
+ 0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5,
+ 0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47,
+ 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370,
+ 0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D,
+ 0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84,
+ 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
+ 0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8,
+ 0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD,
+ 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9,
+ 0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7,
+ 0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38,
+ 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F,
+ 0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C,
+ 0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525,
+ 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1,
+ 0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442,
+ 0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964,
+ 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E,
+ 0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8,
+ 0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D,
+ 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F,
+ 0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299,
+ 0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02,
+ 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC,
+ 0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614,
+ 0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A,
+ 0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6,
+ 0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B,
+ 0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0,
+ 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060,
+ 0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E,
+ 0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9,
+ 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F,
+ 0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6 }
+};
+
+static void F(AVBlowfish *ctx, uint32_t *xl, uint32_t *xr, int i)
+{
+ uint32_t Xl, Xr;
+ uint32_t y;
+
+ Xl = *xl;
+ Xr = *xr;
+
+ Xl ^= ctx->p[i];
+ y = ctx->s[0][(Xl >> 24) & 0xFF];
+ y += ctx->s[1][(Xl >> 16) & 0xFF];
+ y ^= ctx->s[2][(Xl >> 8) & 0xFF];
+ y += ctx->s[3][ Xl & 0xFF];
+ Xr ^= y;
+
+ *xl = Xr;
+ *xr = Xl;
+}
+
+av_cold void av_blowfish_init(AVBlowfish *ctx, const uint8_t *key, int key_len)
+{
+ uint32_t data, data_l, data_r;
+ int i, j, k;
+
+ memcpy(ctx->s, orig_s, sizeof(orig_s));
+
+ j = 0;
+ for (i = 0; i < AV_BF_ROUNDS + 2; ++i) {
+ data = 0;
+ for (k = 0; k < 4; k++) {
+ data = (data << 8) | key[j];
+ if (++j >= key_len)
+ j = 0;
+ }
+ ctx->p[i] = orig_p[i] ^ data;
+ }
+
+ data_l = data_r = 0;
+
+ for (i = 0; i < AV_BF_ROUNDS + 2; i += 2) {
+ av_blowfish_crypt_ecb(ctx, &data_l, &data_r, 0);
+ ctx->p[i] = data_l;
+ ctx->p[i + 1] = data_r;
+ }
+
+ for (i = 0; i < 4; ++i) {
+ for (j = 0; j < 256; j += 2) {
+ av_blowfish_crypt_ecb(ctx, &data_l, &data_r, 0);
+ ctx->s[i][j] = data_l;
+ ctx->s[i][j + 1] = data_r;
+ }
+ }
+}
+
+void av_blowfish_crypt_ecb(AVBlowfish *ctx, uint32_t *xl, uint32_t *xr,
+ int decrypt)
+{
+ uint32_t Xl, Xr;
+ int i;
+
+ Xl = *xl;
+ Xr = *xr;
+
+ if (decrypt) {
+ for (i = AV_BF_ROUNDS + 1; i > 1; --i)
+ F(ctx, &Xl, &Xr, i);
+
+ Xl = Xl ^ ctx->p[1];
+ Xr = Xr ^ ctx->p[0];
+ } else {
+ for (i = 0; i < AV_BF_ROUNDS; ++i)
+ F(ctx, &Xl, &Xr, i);
+
+ Xl = Xl ^ ctx->p[AV_BF_ROUNDS];
+ Xr = Xr ^ ctx->p[AV_BF_ROUNDS + 1];
+ }
+
+ *xl = Xr;
+ *xr = Xl;
+}
+
+void av_blowfish_crypt(AVBlowfish *ctx, uint8_t *dst, const uint8_t *src,
+ int count, uint8_t *iv, int decrypt)
+{
+ uint32_t v0, v1;
+ int i;
+
+ if (decrypt) {
+ while (count--) {
+ v0 = AV_RB32(src);
+ v1 = AV_RB32(src + 4);
+
+ av_blowfish_crypt_ecb(ctx, &v0, &v1, decrypt);
+
+ AV_WB32(dst, v0);
+ AV_WB32(dst + 4, v1);
+
+ if (iv) {
+ for (i = 0; i < 8; i++)
+ dst[i] = dst[i] ^ iv[i];
+ memcpy(iv, src, 8);
+ }
+
+ src += 8;
+ dst += 8;
+ }
+ } else {
+ while (count--) {
+ if (iv) {
+ for (i = 0; i < 8; i++)
+ dst[i] = src[i] ^ iv[i];
+ v0 = AV_RB32(dst);
+ v1 = AV_RB32(dst + 4);
+ } else {
+ v0 = AV_RB32(src);
+ v1 = AV_RB32(src + 4);
+ }
+
+ av_blowfish_crypt_ecb(ctx, &v0, &v1, decrypt);
+
+ AV_WB32(dst, v0);
+ AV_WB32(dst + 4, v1);
+
+ if (iv)
+ memcpy(iv, dst, 8);
+
+ src += 8;
+ dst += 8;
+ }
+ }
+}
+
+#ifdef TEST
+#include <stdio.h>
+#undef printf
+
+#define NUM_VARIABLE_KEY_TESTS 34
+
+/* plaintext bytes -- left halves */
+static const uint32_t plaintext_l[NUM_VARIABLE_KEY_TESTS] = {
+ 0x00000000, 0xFFFFFFFF, 0x10000000, 0x11111111, 0x11111111,
+ 0x01234567, 0x00000000, 0x01234567, 0x01A1D6D0, 0x5CD54CA8,
+ 0x0248D438, 0x51454B58, 0x42FD4430, 0x059B5E08, 0x0756D8E0,
+ 0x762514B8, 0x3BDD1190, 0x26955F68, 0x164D5E40, 0x6B056E18,
+ 0x004BD6EF, 0x480D3900, 0x437540C8, 0x072D43A0, 0x02FE5577,
+ 0x1D9D5C50, 0x30553228, 0x01234567, 0x01234567, 0x01234567,
+ 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF
+};
+
+/* plaintext bytes -- right halves */
+static const uint32_t plaintext_r[NUM_VARIABLE_KEY_TESTS] = {
+ 0x00000000, 0xFFFFFFFF, 0x00000001, 0x11111111, 0x11111111,
+ 0x89ABCDEF, 0x00000000, 0x89ABCDEF, 0x39776742, 0x3DEF57DA,
+ 0x06F67172, 0x2DDF440A, 0x59577FA2, 0x51CF143A, 0x774761D2,
+ 0x29BF486A, 0x49372802, 0x35AF609A, 0x4F275232, 0x759F5CCA,
+ 0x09176062, 0x6EE762F2, 0x698F3CFA, 0x77075292, 0x8117F12A,
+ 0x18F728C2, 0x6D6F295A, 0x89ABCDEF, 0x89ABCDEF, 0x89ABCDEF,
+ 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF
+};
+
+/* key bytes for variable key tests */
+static const uint8_t variable_key[NUM_VARIABLE_KEY_TESTS][8] = {
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
+ { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 },
+ { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
+ { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 },
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 },
+ { 0x7C, 0xA1, 0x10, 0x45, 0x4A, 0x1A, 0x6E, 0x57 },
+ { 0x01, 0x31, 0xD9, 0x61, 0x9D, 0xC1, 0x37, 0x6E },
+ { 0x07, 0xA1, 0x13, 0x3E, 0x4A, 0x0B, 0x26, 0x86 },
+ { 0x38, 0x49, 0x67, 0x4C, 0x26, 0x02, 0x31, 0x9E },
+ { 0x04, 0xB9, 0x15, 0xBA, 0x43, 0xFE, 0xB5, 0xB6 },
+ { 0x01, 0x13, 0xB9, 0x70, 0xFD, 0x34, 0xF2, 0xCE },
+ { 0x01, 0x70, 0xF1, 0x75, 0x46, 0x8F, 0xB5, 0xE6 },
+ { 0x43, 0x29, 0x7F, 0xAD, 0x38, 0xE3, 0x73, 0xFE },
+ { 0x07, 0xA7, 0x13, 0x70, 0x45, 0xDA, 0x2A, 0x16 },
+ { 0x04, 0x68, 0x91, 0x04, 0xC2, 0xFD, 0x3B, 0x2F },
+ { 0x37, 0xD0, 0x6B, 0xB5, 0x16, 0xCB, 0x75, 0x46 },
+ { 0x1F, 0x08, 0x26, 0x0D, 0x1A, 0xC2, 0x46, 0x5E },
+ { 0x58, 0x40, 0x23, 0x64, 0x1A, 0xBA, 0x61, 0x76 },
+ { 0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xB0, 0x07 },
+ { 0x49, 0x79, 0x3E, 0xBC, 0x79, 0xB3, 0x25, 0x8F },
+ { 0x4F, 0xB0, 0x5E, 0x15, 0x15, 0xAB, 0x73, 0xA7 },
+ { 0x49, 0xE9, 0x5D, 0x6D, 0x4C, 0xA2, 0x29, 0xBF },
+ { 0x01, 0x83, 0x10, 0xDC, 0x40, 0x9B, 0x26, 0xD6 },
+ { 0x1C, 0x58, 0x7F, 0x1C, 0x13, 0x92, 0x4F, 0xEF },
+ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
+ { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
+ { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
+ { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
+ { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }
+};
+
+/* ciphertext bytes -- left halves */
+static const uint32_t ciphertext_l[NUM_VARIABLE_KEY_TESTS] = {
+ 0x4EF99745, 0x51866FD5, 0x7D856F9A, 0x2466DD87, 0x61F9C380,
+ 0x7D0CC630, 0x4EF99745, 0x0ACEAB0F, 0x59C68245, 0xB1B8CC0B,
+ 0x1730E577, 0xA25E7856, 0x353882B1, 0x48F4D088, 0x432193B7,
+ 0x13F04154, 0x2EEDDA93, 0xD887E039, 0x5F99D04F, 0x4A057A3B,
+ 0x452031C1, 0x7555AE39, 0x53C55F9C, 0x7A8E7BFA, 0xCF9C5D7A,
+ 0xD1ABB290, 0x55CB3774, 0xFA34EC48, 0xA7907951, 0xC39E072D,
+ 0x014933E0, 0xF21E9A77, 0x24594688, 0x6B5C5A9C
+};
+
+/* ciphertext bytes -- right halves */
+static const uint32_t ciphertext_r[NUM_VARIABLE_KEY_TESTS] = {
+ 0x6198DD78, 0xB85ECB8A, 0x613063F2, 0x8B963C9D, 0x2281B096,
+ 0xAFDA1EC7, 0x6198DD78, 0xC6A0A28D, 0xEB05282B, 0x250F09A0,
+ 0x8BEA1DA4, 0xCF2651EB, 0x09CE8F1A, 0x4C379918, 0x8951FC98,
+ 0xD69D1AE5, 0xFFD39C79, 0x3C2DA6E3, 0x5B163969, 0x24D3977B,
+ 0xE4FADA8E, 0xF59B87BD, 0xB49FC019, 0x937E89A3, 0x4986ADB5,
+ 0x658BC778, 0xD13EF201, 0x47B268B2, 0x08EA3CAE, 0x9FAC631D,
+ 0xCDAFF6E4, 0xB71C49BC, 0x5754369A, 0x5D9E0A5A
+};
+
+/* plaintext bytes */
+static const uint8_t plaintext[8] = "BLOWFISH";
+
+/* ciphertext bytes */
+static const uint8_t ciphertext[8] = {
+ 0x32, 0x4E, 0xD0, 0xFE, 0xF4, 0x13, 0xA2, 0x03
+};
+
+int main(void)
+{
+ AVBlowfish ctx;
+ uint32_t tmptext_l[NUM_VARIABLE_KEY_TESTS];
+ uint32_t tmptext_r[NUM_VARIABLE_KEY_TESTS];
+ uint8_t tmp[8];
+ int i;
+
+ av_blowfish_init(&ctx, "abcdefghijklmnopqrstuvwxyz", 26);
+
+ av_blowfish_crypt(&ctx, tmp, plaintext, 1, NULL, 0);
+ if (memcmp(tmp, ciphertext, 8)) {
+ printf("Test encryption failed.\n");
+ return 1;
+ }
+
+ av_blowfish_crypt(&ctx, tmp, ciphertext, 1, NULL, 1);
+ if (memcmp(tmp, plaintext, 8)) {
+ printf("Test decryption failed.\n");
+ return 1;
+ }
+
+ memcpy(tmptext_l, plaintext_l, sizeof(*plaintext_l) * NUM_VARIABLE_KEY_TESTS);
+ memcpy(tmptext_r, plaintext_r, sizeof(*plaintext_r) * NUM_VARIABLE_KEY_TESTS);
+
+ for (i = 0; i < NUM_VARIABLE_KEY_TESTS; i++) {
+ av_blowfish_init(&ctx, variable_key[i], 8);
+
+ av_blowfish_crypt_ecb(&ctx, &tmptext_l[i], &tmptext_r[i], 0);
+ if (tmptext_l[i] != ciphertext_l[i] || tmptext_r[i] != ciphertext_r[i]) {
+ printf("Test encryption failed.\n");
+ return 1;
+ }
+
+ av_blowfish_crypt_ecb(&ctx, &tmptext_l[i], &tmptext_r[i], 1);
+ if (tmptext_l[i] != plaintext_l[i] || tmptext_r[i] != plaintext_r[i]) {
+ printf("Test decryption failed.\n");
+ return 1;
+ }
+ }
+ printf("Test encryption/decryption success.\n");
+
+ return 0;
+}
+
+#endif
diff --git a/libavutil/blowfish.h b/libavutil/blowfish.h
new file mode 100644
index 0000000..8c29536
--- /dev/null
+++ b/libavutil/blowfish.h
@@ -0,0 +1,76 @@
+/*
+ * Blowfish algorithm
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_BLOWFISH_H
+#define AVUTIL_BLOWFISH_H
+
+#include <stdint.h>
+
+/**
+ * @defgroup lavu_blowfish Blowfish
+ * @ingroup lavu_crypto
+ * @{
+ */
+
+#define AV_BF_ROUNDS 16
+
+typedef struct AVBlowfish {
+ uint32_t p[AV_BF_ROUNDS + 2];
+ uint32_t s[4][256];
+} AVBlowfish;
+
+/**
+ * Initialize an AVBlowfish context.
+ *
+ * @param ctx an AVBlowfish context
+ * @param key a key
+ * @param key_len length of the key
+ */
+void av_blowfish_init(struct AVBlowfish *ctx, const uint8_t *key, int key_len);
+
+/**
+ * Encrypt or decrypt a buffer using a previously initialized context.
+ *
+ * @param ctx an AVBlowfish context
+ * @param xl left four bytes halves of input to be encrypted
+ * @param xr right four bytes halves of input to be encrypted
+ * @param decrypt 0 for encryption, 1 for decryption
+ */
+void av_blowfish_crypt_ecb(struct AVBlowfish *ctx, uint32_t *xl, uint32_t *xr,
+ int decrypt);
+
+/**
+ * Encrypt or decrypt a buffer using a previously initialized context.
+ *
+ * @param ctx an AVBlowfish context
+ * @param dst destination array, can be equal to src
+ * @param src source array, can be equal to dst
+ * @param count number of 8 byte blocks
+ * @param iv initialization vector for CBC mode, if NULL ECB will be used
+ * @param decrypt 0 for encryption, 1 for decryption
+ */
+void av_blowfish_crypt(struct AVBlowfish *ctx, uint8_t *dst, const uint8_t *src,
+ int count, uint8_t *iv, int decrypt);
+
+/**
+ * @}
+ */
+
+#endif /* AVUTIL_BLOWFISH_H */
diff --git a/libavutil/cpu.c b/libavutil/cpu.c
index 6532744..c641106 100644
--- a/libavutil/cpu.c
+++ b/libavutil/cpu.c
@@ -47,7 +47,7 @@ void av_set_cpu_flags_mask(int mask)
int av_parse_cpu_flags(const char *s)
{
-#define CPUFLAG_MMX2 (AV_CPU_FLAG_MMX | AV_CPU_FLAG_MMX2)
+#define CPUFLAG_MMX2 (AV_CPU_FLAG_MMX | AV_CPU_FLAG_MMX2 | AV_CPU_FLAG_CMOV)
#define CPUFLAG_3DNOW (AV_CPU_FLAG_3DNOW | AV_CPU_FLAG_MMX)
#define CPUFLAG_3DNOWEXT (AV_CPU_FLAG_3DNOWEXT | CPUFLAG_3DNOW)
#define CPUFLAG_SSE (AV_CPU_FLAG_SSE | CPUFLAG_MMX2)
@@ -82,6 +82,7 @@ int av_parse_cpu_flags(const char *s)
{ "fma4" , NULL, 0, AV_OPT_TYPE_CONST, { CPUFLAG_FMA4 }, .unit = "flags" },
{ "3dnow" , NULL, 0, AV_OPT_TYPE_CONST, { CPUFLAG_3DNOW }, .unit = "flags" },
{ "3dnowext", NULL, 0, AV_OPT_TYPE_CONST, { CPUFLAG_3DNOWEXT }, .unit = "flags" },
+ { "cmov", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_CMOV }, .unit = "flags" },
#elif ARCH_ARM
{ "armv5te", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_ARMV5TE }, .unit = "flags" },
{ "armv6", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_ARMV6 }, .unit = "flags" },
@@ -143,6 +144,7 @@ static const struct {
{ AV_CPU_FLAG_FMA4, "fma4" },
{ AV_CPU_FLAG_3DNOW, "3dnow" },
{ AV_CPU_FLAG_3DNOWEXT, "3dnowext" },
+ { AV_CPU_FLAG_CMOV, "cmov" },
#endif
{ 0 }
};
diff --git a/libavutil/cpu.h b/libavutil/cpu.h
index 15c0088..f477c83 100644
--- a/libavutil/cpu.h
+++ b/libavutil/cpu.h
@@ -40,6 +40,8 @@
#define AV_CPU_FLAG_AVX 0x4000 ///< AVX functions: requires OS support even if YMM registers aren't used
#define AV_CPU_FLAG_XOP 0x0400 ///< Bulldozer XOP functions
#define AV_CPU_FLAG_FMA4 0x0800 ///< Bulldozer FMA4 functions
+#define AV_CPU_FLAG_CMOV 0x1000 ///< i686 cmov
+
#define AV_CPU_FLAG_ALTIVEC 0x0001 ///< standard
#define AV_CPU_FLAG_ARMV5TE (1 << 0)
diff --git a/libavutil/des.c b/libavutil/des.c
index d65760e..c7c6f1d 100644
--- a/libavutil/des.c
+++ b/libavutil/des.c
@@ -342,7 +342,7 @@ void av_des_mac(AVDES *d, uint8_t *dst, const uint8_t *src, int count) {
#undef srand
#include <stdlib.h>
#include <stdio.h>
-#include <sys/time.h>
+#include "libavutil/time.h"
static uint64_t rand64(void) {
uint64_t r = rand();
r = (r << 32) | rand();
@@ -389,13 +389,11 @@ int main(void) {
#ifdef GENTABLES
int j;
#endif
- struct timeval tv;
uint64_t key[3];
uint64_t data;
uint64_t ct;
uint64_t roundkeys[16];
- gettimeofday(&tv, NULL);
- srand(tv.tv_sec * 1000 * 1000 + tv.tv_usec);
+ srand(av_gettime());
key[0] = AV_RB64(test_key);
data = AV_RB64(plain);
gen_roundkeys(roundkeys, key[0]);
diff --git a/libavutil/dict.h b/libavutil/dict.h
index fd53036..aa07626 100644
--- a/libavutil/dict.h
+++ b/libavutil/dict.h
@@ -118,4 +118,4 @@ void av_dict_free(AVDictionary **m);
* @}
*/
-#endif // AVUTIL_DICT_H
+#endif /* AVUTIL_DICT_H */
diff --git a/libavutil/eval.c b/libavutil/eval.c
index 4d8ebf4..f2d619f 100644
--- a/libavutil/eval.c
+++ b/libavutil/eval.c
@@ -29,6 +29,7 @@
#include "avutil.h"
#include "eval.h"
#include "log.h"
+#include "mathematics.h"
typedef struct Parser {
const AVClass *class;
@@ -119,7 +120,7 @@ static int strmatch(const char *s, const char *prefix)
struct AVExpr {
enum {
e_value, e_const, e_func0, e_func1, e_func2,
- e_squish, e_gauss, e_ld, e_isnan,
+ e_squish, e_gauss, e_ld, e_isnan, e_isinf,
e_mod, e_max, e_min, e_eq, e_gt, e_gte,
e_pow, e_mul, e_div, e_add,
e_last, e_st, e_while, e_floor, e_ceil, e_trunc,
@@ -147,6 +148,7 @@ static double eval_expr(Parser *p, AVExpr *e)
case e_gauss: { double d = eval_expr(p, e->param[0]); return exp(-d*d/2)/sqrt(2*M_PI); }
case e_ld: return e->value * p->var[av_clip(eval_expr(p, e->param[0]), 0, VARS-1)];
case e_isnan: return e->value * !!isnan(eval_expr(p, e->param[0]));
+ case e_isinf: return e->value * !!isinf(eval_expr(p, e->param[0]));
case e_floor: return e->value * floor(eval_expr(p, e->param[0]));
case e_ceil : return e->value * ceil (eval_expr(p, e->param[0]));
case e_trunc: return e->value * trunc(eval_expr(p, e->param[0]));
@@ -281,6 +283,7 @@ static int parse_primary(AVExpr **e, Parser *p)
else if (strmatch(next, "lt" )) { AVExpr *tmp = d->param[1]; d->param[1] = d->param[0]; d->param[0] = tmp; d->type = e_gte; }
else if (strmatch(next, "ld" )) d->type = e_ld;
else if (strmatch(next, "isnan" )) d->type = e_isnan;
+ else if (strmatch(next, "isinf" )) d->type = e_isinf;
else if (strmatch(next, "st" )) d->type = e_st;
else if (strmatch(next, "while" )) d->type = e_while;
else if (strmatch(next, "floor" )) d->type = e_floor;
@@ -452,6 +455,7 @@ static int verify_expr(AVExpr *e)
case e_ld:
case e_gauss:
case e_isnan:
+ case e_isinf:
case e_floor:
case e_ceil:
case e_trunc:
@@ -600,6 +604,10 @@ int main(int argc, char **argv)
"st(0, 1); while(lte(ld(0),100), st(1, ld(1)+ld(0)); st(0, ld(0)+1))",
"isnan(1)",
"isnan(NAN)",
+ "isnan(INF)",
+ "isinf(1)",
+ "isinf(NAN)",
+ "isinf(INF)",
"floor(NAN)",
"floor(123.123)",
"floor(-123.123)",
diff --git a/libavutil/file.c b/libavutil/file.c
index 77aaca0..e1d0831 100644
--- a/libavutil/file.c
+++ b/libavutil/file.c
@@ -20,7 +20,9 @@
#include "log.h"
#include <fcntl.h>
#include <sys/stat.h>
+#if HAVE_UNISTD_H
#include <unistd.h>
+#endif
#if HAVE_MMAP
#include <sys/mman.h>
#elif HAVE_MAPVIEWOFFILE
diff --git a/libavutil/float_dsp.c b/libavutil/float_dsp.c
new file mode 100644
index 0000000..2e90939
--- /dev/null
+++ b/libavutil/float_dsp.c
@@ -0,0 +1,51 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+
+#include "float_dsp.h"
+
+static void vector_fmul_c(float *dst, const float *src0, const float *src1,
+ int len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ dst[i] = src0[i] * src1[i];
+}
+
+static void vector_fmac_scalar_c(float *dst, const float *src, float mul,
+ int len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ dst[i] += src[i] * mul;
+}
+
+void avpriv_float_dsp_init(AVFloatDSPContext *fdsp, int bit_exact)
+{
+ fdsp->vector_fmul = vector_fmul_c;
+ fdsp->vector_fmac_scalar = vector_fmac_scalar_c;
+
+#if ARCH_ARM
+ ff_float_dsp_init_arm(fdsp);
+#elif ARCH_PPC
+ ff_float_dsp_init_ppc(fdsp, bit_exact);
+#elif ARCH_X86
+ ff_float_dsp_init_x86(fdsp);
+#endif
+}
diff --git a/libavutil/float_dsp.h b/libavutil/float_dsp.h
new file mode 100644
index 0000000..95cef62
--- /dev/null
+++ b/libavutil/float_dsp.h
@@ -0,0 +1,69 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_FLOAT_DSP_H
+#define AVUTIL_FLOAT_DSP_H
+
+typedef struct AVFloatDSPContext {
+ /**
+ * Calculate the product of two vectors of floats and store the result in
+ * a vector of floats.
+ *
+ * @param dst output vector
+ * constraints: 32-byte aligned
+ * @param src0 first input vector
+ * constraints: 32-byte aligned
+ * @param src1 second input vector
+ * constraints: 32-byte aligned
+ * @param len number of elements in the input
+ * constraints: multiple of 16
+ */
+ void (*vector_fmul)(float *dst, const float *src0, const float *src1,
+ int len);
+
+ /**
+ * Multiply a vector of floats by a scalar float and add to
+ * destination vector. Source and destination vectors must
+ * overlap exactly or not at all.
+ *
+ * @param dst result vector
+ * constraints: 32-byte aligned
+ * @param src input vector
+ * constraints: 32-byte aligned
+ * @param mul scalar value
+ * @param len length of vector
+ * constraints: multiple of 16
+ */
+ void (*vector_fmac_scalar)(float *dst, const float *src, float mul,
+ int len);
+} AVFloatDSPContext;
+
+/**
+ * Initialize a float DSP context.
+ *
+ * @param fdsp float DSP context
+ * @param strict setting to non-zero avoids using functions which may not be IEEE-754 compliant
+ */
+void avpriv_float_dsp_init(AVFloatDSPContext *fdsp, int strict);
+
+
+void ff_float_dsp_init_arm(AVFloatDSPContext *fdsp);
+void ff_float_dsp_init_ppc(AVFloatDSPContext *fdsp, int strict);
+void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp);
+
+#endif /* AVUTIL_FLOAT_DSP_H */
diff --git a/libavutil/internal.h b/libavutil/internal.h
index ae678d5..41e8a9a 100644
--- a/libavutil/internal.h
+++ b/libavutil/internal.h
@@ -110,7 +110,7 @@ struct AVDictionary {
/* math */
-#if ARCH_X86
+#if ARCH_X86 && HAVE_INLINE_ASM
#define MASK_ABS(mask, level)\
__asm__ volatile(\
"cltd \n\t"\
diff --git a/libavutil/intfloat.h b/libavutil/intfloat.h
index 9db624a..38d26ad 100644
--- a/libavutil/intfloat.h
+++ b/libavutil/intfloat.h
@@ -39,7 +39,8 @@ union av_intfloat64 {
*/
static av_always_inline float av_int2float(uint32_t i)
{
- union av_intfloat32 v = { .i = i };
+ union av_intfloat32 v;
+ v.i = i;
return v.f;
}
@@ -48,7 +49,8 @@ static av_always_inline float av_int2float(uint32_t i)
*/
static av_always_inline uint32_t av_float2int(float f)
{
- union av_intfloat32 v = { .f = f };
+ union av_intfloat32 v;
+ v.f = f;
return v.i;
}
@@ -57,7 +59,8 @@ static av_always_inline uint32_t av_float2int(float f)
*/
static av_always_inline double av_int2double(uint64_t i)
{
- union av_intfloat64 v = { .i = i };
+ union av_intfloat64 v;
+ v.i = i;
return v.f;
}
@@ -66,7 +69,8 @@ static av_always_inline double av_int2double(uint64_t i)
*/
static av_always_inline uint64_t av_double2int(double f)
{
- union av_intfloat64 v = { .f = f };
+ union av_intfloat64 v;
+ v.f = f;
return v.i;
}
diff --git a/libavutil/libavutil.v b/libavutil/libavutil.v
index ec52f2b..eb16ae1 100644
--- a/libavutil/libavutil.v
+++ b/libavutil/libavutil.v
@@ -1,4 +1,4 @@
LIBAVUTIL_$MAJOR {
- global: av_*; ff_*; avutil_*;
+ global: av*; ff_*;
local: *;
};
diff --git a/libavutil/libm.h b/libavutil/libm.h
index 783f3cd..b5821e8 100644
--- a/libavutil/libm.h
+++ b/libavutil/libm.h
@@ -27,6 +27,14 @@
#include <math.h>
#include "config.h"
#include "attributes.h"
+#include "intfloat.h"
+
+#if !HAVE_CBRTF
+static av_always_inline float cbrtf(float x)
+{
+ return x < 0 ? -powf(-x, 1.0 / 3.0) : powf(x, 1.0 / 3.0);
+}
+#endif
#if !HAVE_EXP2
#undef exp2
@@ -38,6 +46,26 @@
#define exp2f(x) ((float)exp2(x))
#endif /* HAVE_EXP2F */
+#if !HAVE_ISINF
+static av_always_inline av_const int isinf(float x)
+{
+ uint32_t v = av_float2int(x);
+ if ((v & 0x7f800000) != 0x7f800000)
+ return 0;
+ return !(v & 0x007fffff);
+}
+#endif /* HAVE_ISINF */
+
+#if !HAVE_ISNAN
+static av_always_inline av_const int isnan(float x)
+{
+ uint32_t v = av_float2int(x);
+ if ((v & 0x7f800000) != 0x7f800000)
+ return 0;
+ return v & 0x007fffff;
+}
+#endif /* HAVE_ISNAN */
+
#if !HAVE_LLRINT
#undef llrint
#define llrint(x) ((long long)rint(x))
diff --git a/libavutil/log.c b/libavutil/log.c
index 2969355..9f1d59a 100644
--- a/libavutil/log.c
+++ b/libavutil/log.c
@@ -24,7 +24,11 @@
* logging functions
*/
+#include "config.h"
+
+#if HAVE_UNISTD_H
#include <unistd.h>
+#endif
#include <stdlib.h>
#include "avstring.h"
#include "avutil.h"
@@ -35,13 +39,14 @@ static int flags;
#if defined(_WIN32) && !defined(__MINGW32CE__)
#include <windows.h>
-static const uint8_t color[] = { 12, 12, 12, 14, 7, 7, 7 };
+#include <io.h>
+static const uint8_t color[] = { 12, 12, 12, 14, 7, 10, 11 };
static int16_t background, attr_orig;
static HANDLE con;
#define set_color(x) SetConsoleTextAttribute(con, background | color[x])
#define reset_color() SetConsoleTextAttribute(con, attr_orig)
#else
-static const uint8_t color[] = { 0x41, 0x41, 0x11, 0x03, 9, 9, 9 };
+static const uint8_t color[] = { 0x41, 0x41, 0x11, 0x03, 9, 0x02, 0x06 };
#define set_color(x) fprintf(stderr, "\033[%d;3%dm", color[x] >> 4, color[x]&15)
#define reset_color() fprintf(stderr, "\033[0m")
#endif
diff --git a/libavutil/mathematics.h b/libavutil/mathematics.h
index ec27979..043dd0f 100644
--- a/libavutil/mathematics.h
+++ b/libavutil/mathematics.h
@@ -25,36 +25,19 @@
#include <math.h>
#include "attributes.h"
#include "rational.h"
+#include "intfloat.h"
-#ifndef M_E
-#define M_E 2.7182818284590452354 /* e */
-#endif
-#ifndef M_LN2
-#define M_LN2 0.69314718055994530942 /* log_e 2 */
-#endif
-#ifndef M_LN10
-#define M_LN10 2.30258509299404568402 /* log_e 10 */
-#endif
#ifndef M_LOG2_10
#define M_LOG2_10 3.32192809488736234787 /* log_2 10 */
#endif
#ifndef M_PHI
#define M_PHI 1.61803398874989484820 /* phi / golden ratio */
#endif
-#ifndef M_PI
-#define M_PI 3.14159265358979323846 /* pi */
-#endif
-#ifndef M_SQRT1_2
-#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
-#endif
-#ifndef M_SQRT2
-#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
-#endif
#ifndef NAN
-#define NAN (0.0/0.0)
+#define NAN av_int2float(0x7fc00000)
#endif
#ifndef INFINITY
-#define INFINITY (1.0/0.0)
+#define INFINITY av_int2float(0x7f800000)
#endif
/**
diff --git a/libavutil/mem.c b/libavutil/mem.c
index bf1a542..0fe9f54 100644
--- a/libavutil/mem.c
+++ b/libavutil/mem.c
@@ -84,6 +84,8 @@ void *av_malloc(size_t size)
#elif HAVE_POSIX_MEMALIGN
if (posix_memalign(&ptr,32,size))
ptr = NULL;
+#elif HAVE_ALIGNED_MALLOC
+ ptr = _aligned_malloc(size, 32);
#elif HAVE_MEMALIGN
ptr = memalign(32,size);
/* Why 64?
@@ -131,6 +133,8 @@ void *av_realloc(void *ptr, size_t size)
if(!ptr) return av_malloc(size);
diff= ((char*)ptr)[-1];
return (char*)realloc((char*)ptr - diff, size + diff) + diff;
+#elif HAVE_ALIGNED_MALLOC
+ return _aligned_realloc(ptr, size, 32);
#else
return realloc(ptr, size);
#endif
@@ -141,6 +145,8 @@ void av_free(void *ptr)
#if CONFIG_MEMALIGN_HACK
if (ptr)
free((char*)ptr - ((char*)ptr)[-1]);
+#elif HAVE_ALIGNED_MALLOC
+ _aligned_free(ptr);
#else
free(ptr);
#endif
diff --git a/libavutil/mips/intreadwrite.h b/libavutil/mips/intreadwrite.h
index 0e0cc06..4dabbe6 100644
--- a/libavutil/mips/intreadwrite.h
+++ b/libavutil/mips/intreadwrite.h
@@ -24,75 +24,23 @@
#include <stdint.h>
#include "config.h"
-#if HAVE_INLINE_ASM
+#if ARCH_MIPS64 && HAVE_INLINE_ASM
#define AV_RN32 AV_RN32
static av_always_inline uint32_t AV_RN32(const void *p)
{
+ struct __attribute__((packed)) u32 { uint32_t v; };
+ const uint8_t *q = p;
+ const struct u32 *pl = (const struct u32 *)(q + 3 * !HAVE_BIGENDIAN);
+ const struct u32 *pr = (const struct u32 *)(q + 3 * HAVE_BIGENDIAN);
uint32_t v;
__asm__ ("lwl %0, %1 \n\t"
"lwr %0, %2 \n\t"
: "=&r"(v)
- : "m"(*(const uint32_t *)((const uint8_t *)p+3*!HAVE_BIGENDIAN)),
- "m"(*(const uint32_t *)((const uint8_t *)p+3*HAVE_BIGENDIAN)));
+ : "m"(*pl), "m"(*pr));
return v;
}
-#define AV_WN32 AV_WN32
-static av_always_inline void AV_WN32(void *p, uint32_t v)
-{
- __asm__ ("swl %2, %0 \n\t"
- "swr %2, %1 \n\t"
- : "=m"(*(uint32_t *)((uint8_t *)p+3*!HAVE_BIGENDIAN)),
- "=m"(*(uint32_t *)((uint8_t *)p+3*HAVE_BIGENDIAN))
- : "r"(v));
-}
-
-#if ARCH_MIPS64
-
-#define AV_RN64 AV_RN64
-static av_always_inline uint64_t AV_RN64(const void *p)
-{
- uint64_t v;
- __asm__ ("ldl %0, %1 \n\t"
- "ldr %0, %2 \n\t"
- : "=&r"(v)
- : "m"(*(const uint64_t *)((const uint8_t *)p+7*!HAVE_BIGENDIAN)),
- "m"(*(const uint64_t *)((const uint8_t *)p+7*HAVE_BIGENDIAN)));
- return v;
-}
-
-#define AV_WN64 AV_WN64
-static av_always_inline void AV_WN64(void *p, uint64_t v)
-{
- __asm__ ("sdl %2, %0 \n\t"
- "sdr %2, %1 \n\t"
- : "=m"(*(uint64_t *)((uint8_t *)p+7*!HAVE_BIGENDIAN)),
- "=m"(*(uint64_t *)((uint8_t *)p+7*HAVE_BIGENDIAN))
- : "r"(v));
-}
-
-#else
-
-#define AV_RN64 AV_RN64
-static av_always_inline uint64_t AV_RN64(const void *p)
-{
- union { uint64_t v; uint32_t hl[2]; } v;
- v.hl[0] = AV_RN32(p);
- v.hl[1] = AV_RN32((const uint8_t *)p + 4);
- return v.v;
-}
-
-#define AV_WN64 AV_WN64
-static av_always_inline void AV_WN64(void *p, uint64_t v)
-{
- union { uint64_t v; uint32_t hl[2]; } vv = { v };
- AV_WN32(p, vv.hl[0]);
- AV_WN32((uint8_t *)p + 4, vv.hl[1]);
-}
-
-#endif /* ARCH_MIPS64 */
-
-#endif /* HAVE_INLINE_ASM */
+#endif /* ARCH_MIPS64 && HAVE_INLINE_ASM */
#endif /* AVUTIL_MIPS_INTREADWRITE_H */
diff --git a/libavutil/opt.c b/libavutil/opt.c
index 7c53024..b1e50f7 100644
--- a/libavutil/opt.c
+++ b/libavutil/opt.c
@@ -31,6 +31,7 @@
#include "eval.h"
#include "dict.h"
#include "log.h"
+#include "mathematics.h"
#if FF_API_FIND_OPT
//FIXME order them and do a bin search
@@ -80,7 +81,8 @@ static int read_number(const AVOption *o, void *dst, double *num, int *den, int6
static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum)
{
if (o->max*den < num*intnum || o->min*den > num*intnum) {
- av_log(obj, AV_LOG_ERROR, "Value %lf for parameter '%s' out of range\n", num, o->name);
+ av_log(obj, AV_LOG_ERROR, "Value %lf for parameter '%s' out of range\n",
+ num*intnum/den, o->name);
return AVERROR(ERANGE);
}
@@ -316,6 +318,35 @@ int av_opt_set_q(void *obj, const char *name, AVRational val, int search_flags)
return set_number(obj, name, val.num, val.den, 1, search_flags);
}
+int av_opt_set_bin(void *obj, const char *name, const uint8_t *val, int len, int search_flags)
+{
+ void *target_obj;
+ const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
+ uint8_t *ptr;
+ uint8_t **dst;
+ int *lendst;
+
+ if (!o || !target_obj)
+ return AVERROR_OPTION_NOT_FOUND;
+
+ if (o->type != AV_OPT_TYPE_BINARY)
+ return AVERROR(EINVAL);
+
+ ptr = av_malloc(len);
+ if (!ptr)
+ return AVERROR(ENOMEM);
+
+ dst = (uint8_t **)(((uint8_t *)target_obj) + o->offset);
+ lendst = (int *)(dst + 1);
+
+ av_free(*dst);
+ *dst = ptr;
+ *lendst = len;
+ memcpy(ptr, val, len);
+
+ return 0;
+}
+
#if FF_API_OLD_AVOPTIONS
/**
*
diff --git a/libavutil/opt.h b/libavutil/opt.h
index 1954940..8f800fc 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -560,6 +560,7 @@ int av_opt_set (void *obj, const char *name, const char *val, int search_f
int av_opt_set_int (void *obj, const char *name, int64_t val, int search_flags);
int av_opt_set_double(void *obj, const char *name, double val, int search_flags);
int av_opt_set_q (void *obj, const char *name, AVRational val, int search_flags);
+int av_opt_set_bin (void *obj, const char *name, const uint8_t *val, int size, int search_flags);
/**
* @}
*/
diff --git a/libavutil/parseutils.c b/libavutil/parseutils.c
index ed147ee..34f45eb 100644
--- a/libavutil/parseutils.c
+++ b/libavutil/parseutils.c
@@ -21,7 +21,6 @@
* misc parsing utilities
*/
-#include <sys/time.h>
#include <time.h>
#include "avstring.h"
diff --git a/libavutil/ppc/Makefile b/libavutil/ppc/Makefile
index 5b18b08..4fd8d6d 100644
--- a/libavutil/ppc/Makefile
+++ b/libavutil/ppc/Makefile
@@ -1 +1,4 @@
OBJS += ppc/cpu.o \
+ ppc/float_dsp_init.o \
+
+ALTIVEC-OBJS += ppc/float_dsp_altivec.o \
diff --git a/libavutil/ppc/float_dsp_altivec.c b/libavutil/ppc/float_dsp_altivec.c
new file mode 100644
index 0000000..55e3fbe
--- /dev/null
+++ b/libavutil/ppc/float_dsp_altivec.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2006 Luca Barbato <lu_zero at gentoo.org>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "util_altivec.h"
+#include "float_dsp_altivec.h"
+
+void ff_vector_fmul_altivec(float *dst, const float *src0, const float *src1,
+ int len)
+{
+ int i;
+ vector float d0, d1, s, zero = (vector float)vec_splat_u32(0);
+ for (i = 0; i < len - 7; i += 8) {
+ d0 = vec_ld( 0, src0 + i);
+ s = vec_ld( 0, src1 + i);
+ d1 = vec_ld(16, src0 + i);
+ d0 = vec_madd(d0, s, zero);
+ d1 = vec_madd(d1, vec_ld(16, src1 + i), zero);
+ vec_st(d0, 0, dst + i);
+ vec_st(d1, 16, dst + i);
+ }
+}
diff --git a/libavutil/ppc/float_dsp_altivec.h b/libavutil/ppc/float_dsp_altivec.h
new file mode 100644
index 0000000..0b9425b
--- /dev/null
+++ b/libavutil/ppc/float_dsp_altivec.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2006 Luca Barbato <lu_zero at gentoo.org>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_PPC_FLOAT_DSP_ALTIVEC_H
+#define AVUTIL_PPC_FLOAT_DSP_ALTIVEC_H
+
+extern void ff_vector_fmul_altivec(float *dst, const float *src0,
+ const float *src1, int len);
+
+#endif /* AVUTIL_PPC_FLOAT_DSP_ALTIVEC_H */
diff --git a/libavutil/ppc/float_dsp_init.c b/libavutil/ppc/float_dsp_init.c
new file mode 100644
index 0000000..2052764
--- /dev/null
+++ b/libavutil/ppc/float_dsp_init.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2006 Luca Barbato <lu_zero at gentoo.org>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "libavutil/cpu.h"
+#include "libavutil/float_dsp.h"
+#include "float_dsp_altivec.h"
+
+void ff_float_dsp_init_ppc(AVFloatDSPContext *fdsp, int bit_exact)
+{
+#if HAVE_ALTIVEC
+ int mm_flags = av_get_cpu_flags();
+
+ if (!(mm_flags & AV_CPU_FLAG_ALTIVEC))
+ return;
+
+ fdsp->vector_fmul = ff_vector_fmul_altivec;
+#endif
+}
diff --git a/libavutil/ppc/types_altivec.h b/libavutil/ppc/types_altivec.h
new file mode 100644
index 0000000..0a4eaf8
--- /dev/null
+++ b/libavutil/ppc/types_altivec.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2006 Guillaume Poirier <gpoirier at mplayerhq.hu>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_PPC_TYPES_ALTIVEC_H
+#define AVUTIL_PPC_TYPES_ALTIVEC_H
+
+/***********************************************************************
+ * Vector types
+ **********************************************************************/
+#define vec_u8 vector unsigned char
+#define vec_s8 vector signed char
+#define vec_u16 vector unsigned short
+#define vec_s16 vector signed short
+#define vec_u32 vector unsigned int
+#define vec_s32 vector signed int
+#define vec_f vector float
+
+/***********************************************************************
+ * Null vector
+ **********************************************************************/
+#define LOAD_ZERO const vec_u8 zerov = vec_splat_u8( 0 )
+
+#define zero_u8v (vec_u8) zerov
+#define zero_s8v (vec_s8) zerov
+#define zero_u16v (vec_u16) zerov
+#define zero_s16v (vec_s16) zerov
+#define zero_u32v (vec_u32) zerov
+#define zero_s32v (vec_s32) zerov
+
+#endif /* AVUTIL_PPC_TYPES_ALTIVEC_H */
diff --git a/libavutil/ppc/util_altivec.h b/libavutil/ppc/util_altivec.h
new file mode 100644
index 0000000..bdbf862
--- /dev/null
+++ b/libavutil/ppc/util_altivec.h
@@ -0,0 +1,118 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Contains misc utility macros and inline functions
+ */
+
+#ifndef AVUTIL_PPC_UTIL_ALTIVEC_H
+#define AVUTIL_PPC_UTIL_ALTIVEC_H
+
+#include <stdint.h>
+
+#include "config.h"
+
+#if HAVE_ALTIVEC_H
+#include <altivec.h>
+#endif
+
+#include "types_altivec.h"
+
+// used to build registers permutation vectors (vcprm)
+// the 's' are for words in the _s_econd vector
+#define WORD_0 0x00,0x01,0x02,0x03
+#define WORD_1 0x04,0x05,0x06,0x07
+#define WORD_2 0x08,0x09,0x0a,0x0b
+#define WORD_3 0x0c,0x0d,0x0e,0x0f
+#define WORD_s0 0x10,0x11,0x12,0x13
+#define WORD_s1 0x14,0x15,0x16,0x17
+#define WORD_s2 0x18,0x19,0x1a,0x1b
+#define WORD_s3 0x1c,0x1d,0x1e,0x1f
+
+#define vcprm(a,b,c,d) (const vector unsigned char){WORD_ ## a, WORD_ ## b, WORD_ ## c, WORD_ ## d}
+#define vcii(a,b,c,d) (const vector float){FLOAT_ ## a, FLOAT_ ## b, FLOAT_ ## c, FLOAT_ ## d}
+
+// vcprmle is used to keep the same index as in the SSE version.
+// it's the same as vcprm, with the index inversed
+// ('le' is Little Endian)
+#define vcprmle(a,b,c,d) vcprm(d,c,b,a)
+
+// used to build inverse/identity vectors (vcii)
+// n is _n_egative, p is _p_ositive
+#define FLOAT_n -1.
+#define FLOAT_p 1.
+
+
+// Transpose 8x8 matrix of 16-bit elements (in-place)
+#define TRANSPOSE8(a,b,c,d,e,f,g,h) \
+do { \
+ vector signed short A1, B1, C1, D1, E1, F1, G1, H1; \
+ vector signed short A2, B2, C2, D2, E2, F2, G2, H2; \
+ \
+ A1 = vec_mergeh (a, e); \
+ B1 = vec_mergel (a, e); \
+ C1 = vec_mergeh (b, f); \
+ D1 = vec_mergel (b, f); \
+ E1 = vec_mergeh (c, g); \
+ F1 = vec_mergel (c, g); \
+ G1 = vec_mergeh (d, h); \
+ H1 = vec_mergel (d, h); \
+ \
+ A2 = vec_mergeh (A1, E1); \
+ B2 = vec_mergel (A1, E1); \
+ C2 = vec_mergeh (B1, F1); \
+ D2 = vec_mergel (B1, F1); \
+ E2 = vec_mergeh (C1, G1); \
+ F2 = vec_mergel (C1, G1); \
+ G2 = vec_mergeh (D1, H1); \
+ H2 = vec_mergel (D1, H1); \
+ \
+ a = vec_mergeh (A2, E2); \
+ b = vec_mergel (A2, E2); \
+ c = vec_mergeh (B2, F2); \
+ d = vec_mergel (B2, F2); \
+ e = vec_mergeh (C2, G2); \
+ f = vec_mergel (C2, G2); \
+ g = vec_mergeh (D2, H2); \
+ h = vec_mergel (D2, H2); \
+} while (0)
+
+
+/** @brief loads unaligned vector @a *src with offset @a offset
+ and returns it */
+static inline vector unsigned char unaligned_load(int offset, uint8_t *src)
+{
+ register vector unsigned char first = vec_ld(offset, src);
+ register vector unsigned char second = vec_ld(offset+15, src);
+ register vector unsigned char mask = vec_lvsl(offset, src);
+ return vec_perm(first, second, mask);
+}
+
+/**
+ * loads vector known misalignment
+ * @param perm_vec the align permute vector to combine the two loads from lvsl
+ */
+static inline vec_u8 load_with_perm_vec(int offset, uint8_t *src, vec_u8 perm_vec)
+{
+ vec_u8 a = vec_ld(offset, src);
+ vec_u8 b = vec_ld(offset+15, src);
+ return vec_perm(a, b, perm_vec);
+}
+
+#endif /* AVUTIL_PPC_UTIL_ALTIVEC_H */
diff --git a/libavutil/random_seed.c b/libavutil/random_seed.c
index 51ca99b..8ee4cb7 100644
--- a/libavutil/random_seed.c
+++ b/libavutil/random_seed.c
@@ -18,7 +18,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "config.h"
+
+#if HAVE_UNISTD_H
#include <unistd.h>
+#endif
#include <fcntl.h>
#include <math.h>
#include <time.h>
@@ -27,6 +31,7 @@
static int read_random(uint32_t *dst, const char *file)
{
+#if HAVE_UNISTD_H
int fd = open(file, O_RDONLY);
int err = -1;
@@ -36,6 +41,9 @@ static int read_random(uint32_t *dst, const char *file)
close(fd);
return err;
+#else
+ return -1;
+#endif
}
static uint32_t get_generic_seed(void)
diff --git a/libavutil/samplefmt.c b/libavutil/samplefmt.c
index 0a2ffa0..b6e785c 100644
--- a/libavutil/samplefmt.c
+++ b/libavutil/samplefmt.c
@@ -143,7 +143,7 @@ int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples,
}
int av_samples_fill_arrays(uint8_t **audio_data, int *linesize,
- uint8_t *buf, int nb_channels, int nb_samples,
+ const uint8_t *buf, int nb_channels, int nb_samples,
enum AVSampleFormat sample_fmt, int align)
{
int ch, planar, buf_size, line_size;
@@ -185,3 +185,41 @@ int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels,
}
return 0;
}
+
+int av_samples_copy(uint8_t **dst, uint8_t * const *src, int dst_offset,
+ int src_offset, int nb_samples, int nb_channels,
+ enum AVSampleFormat sample_fmt)
+{
+ int planar = av_sample_fmt_is_planar(sample_fmt);
+ int planes = planar ? nb_channels : 1;
+ int block_align = av_get_bytes_per_sample(sample_fmt) * (planar ? 1 : nb_channels);
+ int data_size = nb_samples * block_align;
+ int i;
+
+ dst_offset *= block_align;
+ src_offset *= block_align;
+
+ for (i = 0; i < planes; i++)
+ memcpy(dst[i] + dst_offset, src[i] + src_offset, data_size);
+
+ return 0;
+}
+
+int av_samples_set_silence(uint8_t **audio_data, int offset, int nb_samples,
+ int nb_channels, enum AVSampleFormat sample_fmt)
+{
+ int planar = av_sample_fmt_is_planar(sample_fmt);
+ int planes = planar ? nb_channels : 1;
+ int block_align = av_get_bytes_per_sample(sample_fmt) * (planar ? 1 : nb_channels);
+ int data_size = nb_samples * block_align;
+ int fill_char = (sample_fmt == AV_SAMPLE_FMT_U8 ||
+ sample_fmt == AV_SAMPLE_FMT_U8P) ? 0x80 : 0x00;
+ int i;
+
+ offset *= block_align;
+
+ for (i = 0; i < planes; i++)
+ memset(audio_data[i] + offset, fill_char, data_size);
+
+ return 0;
+}
diff --git a/libavutil/samplefmt.h b/libavutil/samplefmt.h
index bb5ba59..e3aa6a9 100644
--- a/libavutil/samplefmt.h
+++ b/libavutil/samplefmt.h
@@ -170,7 +170,8 @@ int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples,
* @param align buffer size alignment (0 = default, 1 = no alignment)
* @return 0 on success or a negative error code on failure
*/
-int av_samples_fill_arrays(uint8_t **audio_data, int *linesize, uint8_t *buf,
+int av_samples_fill_arrays(uint8_t **audio_data, int *linesize,
+ const uint8_t *buf,
int nb_channels, int nb_samples,
enum AVSampleFormat sample_fmt, int align);
@@ -193,4 +194,31 @@ int av_samples_fill_arrays(uint8_t **audio_data, int *linesize, uint8_t *buf,
int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels,
int nb_samples, enum AVSampleFormat sample_fmt, int align);
+/**
+ * Copy samples from src to dst.
+ *
+ * @param dst destination array of pointers to data planes
+ * @param src source array of pointers to data planes
+ * @param dst_offset offset in samples at which the data will be written to dst
+ * @param src_offset offset in samples at which the data will be read from src
+ * @param nb_samples number of samples to be copied
+ * @param nb_channels number of audio channels
+ * @param sample_fmt audio sample format
+ */
+int av_samples_copy(uint8_t **dst, uint8_t * const *src, int dst_offset,
+ int src_offset, int nb_samples, int nb_channels,
+ enum AVSampleFormat sample_fmt);
+
+/**
+ * Fill an audio buffer with silence.
+ *
+ * @param audio_data array of pointers to data planes
+ * @param offset offset in samples at which to start filling
+ * @param nb_samples number of samples to fill
+ * @param nb_channels number of audio channels
+ * @param sample_fmt audio sample format
+ */
+int av_samples_set_silence(uint8_t **audio_data, int offset, int nb_samples,
+ int nb_channels, enum AVSampleFormat sample_fmt);
+
#endif /* AVUTIL_SAMPLEFMT_H */
diff --git a/libavutil/time.c b/libavutil/time.c
new file mode 100644
index 0000000..51779c5
--- /dev/null
+++ b/libavutil/time.c
@@ -0,0 +1,68 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <time.h>
+#if HAVE_GETTIMEOFDAY
+#include <sys/time.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+
+#include "libavutil/time.h"
+#include "error.h"
+
+int64_t av_gettime(void)
+{
+#if HAVE_GETTIMEOFDAY
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
+#elif HAVE_GETSYSTEMTIMEASFILETIME
+ FILETIME ft;
+ int64_t t;
+ GetSystemTimeAsFileTime(&ft);
+ t = (int64_t)ft.dwHighDateTime << 32 | ft.dwLowDateTime;
+ return t / 10 - 11644473600000000; /* Jan 1, 1601 */
+#else
+ return -1;
+#endif
+}
+
+int av_usleep(unsigned usec)
+{
+#if HAVE_NANOSLEEP
+ struct timespec ts = { usec / 1000000, usec % 1000000 * 1000 };
+ while (nanosleep(&ts, &ts) < 0 && errno == EINTR);
+ return 0;
+#elif HAVE_USLEEP
+ return usleep(usec);
+#elif HAVE_SLEEP
+ Sleep(usec / 1000);
+ return 0;
+#else
+ return AVERROR(ENOSYS);
+#endif
+}
diff --git a/libavutil/time.h b/libavutil/time.h
new file mode 100644
index 0000000..b01a97d
--- /dev/null
+++ b/libavutil/time.h
@@ -0,0 +1,39 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_TIME_H
+#define AVUTIL_TIME_H
+
+#include <stdint.h>
+
+/**
+ * Get the current time in microseconds.
+ */
+int64_t av_gettime(void);
+
+/**
+ * Sleep for a period of time. Although the duration is expressed in
+ * microseconds, the actual delay may be rounded to the precision of the
+ * system timer.
+ *
+ * @param usec Number of microseconds to sleep.
+ * @return zero on success or (negative) error code.
+ */
+int av_usleep(unsigned usec);
+
+#endif /* AVUTIL_TIME_H */
diff --git a/libavutil/version.h b/libavutil/version.h
new file mode 100644
index 0000000..c42c6b0
--- /dev/null
+++ b/libavutil/version.h
@@ -0,0 +1,81 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_VERSION_H
+#define AVUTIL_VERSION_H
+
+#include "avutil.h"
+
+/**
+ * @file
+ * @ingroup lavu
+ * Libavutil version macros
+ */
+
+/**
+ * @defgroup lavu_ver Version and Build diagnostics
+ *
+ * Macros and function useful to check at compiletime and at runtime
+ * which version of libavutil is in use.
+ *
+ * @{
+ */
+
+#define LIBAVUTIL_VERSION_MAJOR 51
+#define LIBAVUTIL_VERSION_MINOR 36
+#define LIBAVUTIL_VERSION_MICRO 0
+
+#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
+ LIBAVUTIL_VERSION_MINOR, \
+ LIBAVUTIL_VERSION_MICRO)
+#define LIBAVUTIL_VERSION AV_VERSION(LIBAVUTIL_VERSION_MAJOR, \
+ LIBAVUTIL_VERSION_MINOR, \
+ LIBAVUTIL_VERSION_MICRO)
+#define LIBAVUTIL_BUILD LIBAVUTIL_VERSION_INT
+
+#define LIBAVUTIL_IDENT "Lavu" AV_STRINGIFY(LIBAVUTIL_VERSION)
+
+/**
+ * @}
+ *
+ * @defgroup depr_guards Deprecation guards
+ * FF_API_* defines may be placed below to indicate public API that will be
+ * dropped at a future version bump. The defines themselves are not part of
+ * the public API and may change, break or disappear at any time.
+ *
+ * @{
+ */
+
+#ifndef FF_API_GET_BITS_PER_SAMPLE_FMT
+#define FF_API_GET_BITS_PER_SAMPLE_FMT (LIBAVUTIL_VERSION_MAJOR < 52)
+#endif
+#ifndef FF_API_FIND_OPT
+#define FF_API_FIND_OPT (LIBAVUTIL_VERSION_MAJOR < 52)
+#endif
+#ifndef FF_API_AV_FIFO_PEEK
+#define FF_API_AV_FIFO_PEEK (LIBAVUTIL_VERSION_MAJOR < 52)
+#endif
+#ifndef FF_API_OLD_AVOPTIONS
+#define FF_API_OLD_AVOPTIONS (LIBAVUTIL_VERSION_MAJOR < 52)
+#endif
+
+/**
+ * @}
+ */
+
+#endif /* AVUTIL_VERSION_H */
diff --git a/libavutil/x86/Makefile b/libavutil/x86/Makefile
index de8a341..4546353 100644
--- a/libavutil/x86/Makefile
+++ b/libavutil/x86/Makefile
@@ -1 +1,4 @@
OBJS += x86/cpu.o \
+ x86/float_dsp_init.o \
+
+YASM-OBJS += x86/float_dsp.o \
diff --git a/libavutil/x86/bswap.h b/libavutil/x86/bswap.h
index c6cf007..c73be9a 100644
--- a/libavutil/x86/bswap.h
+++ b/libavutil/x86/bswap.h
@@ -28,6 +28,8 @@
#include "config.h"
#include "libavutil/attributes.h"
+#if HAVE_INLINE_ASM
+
#if !AV_GCC_VERSION_AT_LEAST(4,1)
#define av_bswap16 av_bswap16
static av_always_inline av_const unsigned av_bswap16(unsigned x)
@@ -55,4 +57,5 @@ static inline uint64_t av_const av_bswap64(uint64_t x)
#endif
#endif /* !AV_GCC_VERSION_AT_LEAST(4,5) */
+#endif /* HAVE_INLINE_ASM */
#endif /* AVUTIL_X86_BSWAP_H */
diff --git a/libavutil/x86/cpu.c b/libavutil/x86/cpu.c
index 2424fe4..5d77b0c 100644
--- a/libavutil/x86/cpu.c
+++ b/libavutil/x86/cpu.c
@@ -26,49 +26,44 @@
#include "libavutil/cpu.h"
/* ebx saving is necessary for PIC. gcc seems unable to see it alone */
-#define cpuid(index,eax,ebx,ecx,edx)\
- __asm__ volatile\
- ("mov %%"REG_b", %%"REG_S"\n\t"\
- "cpuid\n\t"\
- "xchg %%"REG_b", %%"REG_S\
- : "=a" (eax), "=S" (ebx),\
- "=c" (ecx), "=d" (edx)\
- : "0" (index));
-
-#define xgetbv(index,eax,edx) \
+#define cpuid(index, eax, ebx, ecx, edx) \
+ __asm__ volatile ( \
+ "mov %%"REG_b", %%"REG_S" \n\t" \
+ "cpuid \n\t" \
+ "xchg %%"REG_b", %%"REG_S \
+ : "=a" (eax), "=S" (ebx), "=c" (ecx), "=d" (edx) \
+ : "0" (index))
+
+#define xgetbv(index, eax, edx) \
__asm__ (".byte 0x0f, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c" (index))
+#define get_eflags(x) \
+ __asm__ volatile ("pushfl \n" \
+ "pop %0 \n" \
+ : "=r"(x))
+
+#define set_eflags(x) \
+ __asm__ volatile ("push %0 \n" \
+ "popfl \n" \
+ :: "r"(x))
+
/* Function to test if multimedia instructions are supported... */
int ff_get_cpu_flags_x86(void)
{
int rval = 0;
int eax, ebx, ecx, edx;
- int max_std_level, max_ext_level, std_caps=0, ext_caps=0;
- int family=0, model=0;
+ int max_std_level, max_ext_level, std_caps = 0, ext_caps = 0;
+ int family = 0, model = 0;
union { int i[3]; char c[12]; } vendor;
#if ARCH_X86_32
x86_reg a, c;
- __asm__ volatile (
- /* See if CPUID instruction is supported ... */
- /* ... Get copies of EFLAGS into eax and ecx */
- "pushfl\n\t"
- "pop %0\n\t"
- "mov %0, %1\n\t"
-
- /* ... Toggle the ID bit in one copy and store */
- /* to the EFLAGS reg */
- "xor $0x200000, %0\n\t"
- "push %0\n\t"
- "popfl\n\t"
-
- /* ... Get the (hopefully modified) EFLAGS */
- "pushfl\n\t"
- "pop %0\n\t"
- : "=a" (a), "=c" (c)
- :
- : "cc"
- );
+
+ /* Check if CPUID is supported by attempting to toggle the ID bit in
+ * the EFLAGS register. */
+ get_eflags(a);
+ set_eflags(a ^ 0x200000);
+ get_eflags(c);
if (a == c)
return 0; /* CPUID not supported */
@@ -79,17 +74,20 @@ int ff_get_cpu_flags_x86(void)
vendor.i[1] = edx;
vendor.i[2] = ecx;
- if(max_std_level >= 1){
+ if (max_std_level >= 1) {
cpuid(1, eax, ebx, ecx, std_caps);
- family = ((eax>>8)&0xf) + ((eax>>20)&0xff);
- model = ((eax>>4)&0xf) + ((eax>>12)&0xf0);
- if (std_caps & (1<<23))
+ family = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff);
+ model = ((eax >> 4) & 0xf) + ((eax >> 12) & 0xf0);
+ if (std_caps & (1 << 15))
+ rval |= AV_CPU_FLAG_CMOV;
+ if (std_caps & (1 << 23))
rval |= AV_CPU_FLAG_MMX;
- if (std_caps & (1<<25))
- rval |= AV_CPU_FLAG_MMX2
+ if (std_caps & (1 << 25))
+ rval |= AV_CPU_FLAG_MMX2;
#if HAVE_SSE
- | AV_CPU_FLAG_SSE;
- if (std_caps & (1<<26))
+ if (std_caps & (1 << 25))
+ rval |= AV_CPU_FLAG_SSE;
+ if (std_caps & (1 << 26))
rval |= AV_CPU_FLAG_SSE2;
if (ecx & 1)
rval |= AV_CPU_FLAG_SSE3;
@@ -109,20 +107,19 @@ int ff_get_cpu_flags_x86(void)
}
#endif
#endif
- ;
}
cpuid(0x80000000, max_ext_level, ebx, ecx, edx);
- if(max_ext_level >= 0x80000001){
+ if (max_ext_level >= 0x80000001) {
cpuid(0x80000001, eax, ebx, ecx, ext_caps);
- if (ext_caps & (1U<<31))
+ if (ext_caps & (1U << 31))
rval |= AV_CPU_FLAG_3DNOW;
- if (ext_caps & (1<<30))
+ if (ext_caps & (1 << 30))
rval |= AV_CPU_FLAG_3DNOWEXT;
- if (ext_caps & (1<<23))
+ if (ext_caps & (1 << 23))
rval |= AV_CPU_FLAG_MMX;
- if (ext_caps & (1<<22))
+ if (ext_caps & (1 << 22))
rval |= AV_CPU_FLAG_MMX2;
/* Allow for selectively disabling SSE2 functions on AMD processors
@@ -149,14 +146,17 @@ int ff_get_cpu_flags_x86(void)
if (!strncmp(vendor.c, "GenuineIntel", 12)) {
if (family == 6 && (model == 9 || model == 13 || model == 14)) {
- /* 6/9 (pentium-m "banias"), 6/13 (pentium-m "dothan"), and 6/14 (core1 "yonah")
- * theoretically support sse2, but it's usually slower than mmx,
- * so let's just pretend they don't. AV_CPU_FLAG_SSE2 is disabled and
- * AV_CPU_FLAG_SSE2SLOW is enabled so that SSE2 is not used unless
- * explicitly enabled by checking AV_CPU_FLAG_SSE2SLOW. The same
- * situation applies for AV_CPU_FLAG_SSE3 and AV_CPU_FLAG_SSE3SLOW. */
- if (rval & AV_CPU_FLAG_SSE2) rval ^= AV_CPU_FLAG_SSE2SLOW|AV_CPU_FLAG_SSE2;
- if (rval & AV_CPU_FLAG_SSE3) rval ^= AV_CPU_FLAG_SSE3SLOW|AV_CPU_FLAG_SSE3;
+ /* 6/9 (pentium-m "banias"), 6/13 (pentium-m "dothan"), and
+ * 6/14 (core1 "yonah") theoretically support sse2, but it's
+ * usually slower than mmx, so let's just pretend they don't.
+ * AV_CPU_FLAG_SSE2 is disabled and AV_CPU_FLAG_SSE2SLOW is
+ * enabled so that SSE2 is not used unless explicitly enabled
+ * by checking AV_CPU_FLAG_SSE2SLOW. The same situation
+ * applies for AV_CPU_FLAG_SSE3 and AV_CPU_FLAG_SSE3SLOW. */
+ if (rval & AV_CPU_FLAG_SSE2)
+ rval ^= AV_CPU_FLAG_SSE2SLOW | AV_CPU_FLAG_SSE2;
+ if (rval & AV_CPU_FLAG_SSE3)
+ rval ^= AV_CPU_FLAG_SSE3SLOW | AV_CPU_FLAG_SSE3;
}
/* The Atom processor has SSSE3 support, which is useful in many cases,
* but sometimes the SSSE3 version is slower than the SSE2 equivalent
diff --git a/libavutil/x86/float_dsp.asm b/libavutil/x86/float_dsp.asm
new file mode 100644
index 0000000..66ef093
--- /dev/null
+++ b/libavutil/x86/float_dsp.asm
@@ -0,0 +1,102 @@
+;*****************************************************************************
+;* x86-optimized Float DSP functions
+;*
+;* This file is part of Libav.
+;*
+;* Libav is free software; you can redistribute it and/or
+;* modify it under the terms of the GNU Lesser General Public
+;* License as published by the Free Software Foundation; either
+;* version 2.1 of the License, or (at your option) any later version.
+;*
+;* Libav is distributed in the hope that it will be useful,
+;* but WITHOUT ANY WARRANTY; without even the implied warranty of
+;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;* Lesser General Public License for more details.
+;*
+;* You should have received a copy of the GNU Lesser General Public
+;* License along with Libav; if not, write to the Free Software
+;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+;******************************************************************************
+
+%include "x86inc.asm"
+%include "x86util.asm"
+
+SECTION .text
+
+;-----------------------------------------------------------------------------
+; void vector_fmul(float *dst, const float *src0, const float *src1, int len)
+;-----------------------------------------------------------------------------
+%macro VECTOR_FMUL 0
+cglobal vector_fmul, 4,4,2, dst, src0, src1, len
+ lea lenq, [lend*4 - 2*mmsize]
+ALIGN 16
+.loop
+ mova m0, [src0q + lenq]
+ mova m1, [src0q + lenq + mmsize]
+ mulps m0, m0, [src1q + lenq]
+ mulps m1, m1, [src1q + lenq + mmsize]
+ mova [dstq + lenq], m0
+ mova [dstq + lenq + mmsize], m1
+
+ sub lenq, 2*mmsize
+ jge .loop
+%if mmsize == 32
+ vzeroupper
+ RET
+%else
+ REP_RET
+%endif
+%endmacro
+
+INIT_XMM sse
+VECTOR_FMUL
+%if HAVE_AVX
+INIT_YMM avx
+VECTOR_FMUL
+%endif
+
+;------------------------------------------------------------------------------
+; void ff_vector_fmac_scalar(float *dst, const float *src, float mul, int len)
+;------------------------------------------------------------------------------
+
+%macro VECTOR_FMAC_SCALAR 0
+%if UNIX64
+cglobal vector_fmac_scalar, 3,3,3, dst, src, len
+%else
+cglobal vector_fmac_scalar, 4,4,3, dst, src, mul, len
+%endif
+%if WIN64
+ SWAP 0, 2
+%endif
+%if ARCH_X86_32
+ VBROADCASTSS m0, mulm
+%else
+ shufps xmm0, xmm0, 0
+%if cpuflag(avx)
+ vinsertf128 m0, m0, xmm0, 1
+%endif
+%endif
+ lea lenq, [lend*4-2*mmsize]
+.loop
+ mulps m1, m0, [srcq+lenq ]
+ mulps m2, m0, [srcq+lenq+mmsize]
+ addps m1, m1, [dstq+lenq ]
+ addps m2, m2, [dstq+lenq+mmsize]
+ mova [dstq+lenq ], m1
+ mova [dstq+lenq+mmsize], m2
+ sub lenq, 2*mmsize
+ jge .loop
+%if mmsize == 32
+ vzeroupper
+ RET
+%else
+ REP_RET
+%endif
+%endmacro
+
+INIT_XMM sse
+VECTOR_FMAC_SCALAR
+%if HAVE_AVX
+INIT_YMM avx
+VECTOR_FMAC_SCALAR
+%endif
diff --git a/libavutil/x86/float_dsp_init.c b/libavutil/x86/float_dsp_init.c
new file mode 100644
index 0000000..d259a36
--- /dev/null
+++ b/libavutil/x86/float_dsp_init.c
@@ -0,0 +1,48 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+
+#include "libavutil/cpu.h"
+#include "libavutil/float_dsp.h"
+
+extern void ff_vector_fmul_sse(float *dst, const float *src0, const float *src1,
+ int len);
+extern void ff_vector_fmul_avx(float *dst, const float *src0, const float *src1,
+ int len);
+
+extern void ff_vector_fmac_scalar_sse(float *dst, const float *src, float mul,
+ int len);
+extern void ff_vector_fmac_scalar_avx(float *dst, const float *src, float mul,
+ int len);
+
+void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp)
+{
+#if HAVE_YASM
+ int mm_flags = av_get_cpu_flags();
+
+ if (mm_flags & AV_CPU_FLAG_SSE && HAVE_SSE) {
+ fdsp->vector_fmul = ff_vector_fmul_sse;
+ fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_sse;
+ }
+ if (mm_flags & AV_CPU_FLAG_AVX && HAVE_AVX) {
+ fdsp->vector_fmul = ff_vector_fmul_avx;
+ fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_avx;
+ }
+#endif
+}
diff --git a/libavutil/x86/intmath.h b/libavutil/x86/intmath.h
index a7e82b1..b23c0f1 100644
--- a/libavutil/x86/intmath.h
+++ b/libavutil/x86/intmath.h
@@ -21,6 +21,7 @@
#ifndef AVUTIL_X86_INTMATH_H
#define AVUTIL_X86_INTMATH_H
+#if HAVE_INLINE_ASM
#define FASTDIV(a,b) \
({\
int ret, dmy;\
@@ -31,5 +32,6 @@
);\
ret;\
})
+#endif
#endif /* AVUTIL_X86_INTMATH_H */
diff --git a/libavutil/x86/x86inc.asm b/libavutil/x86/x86inc.asm
index c167057..42ba97a 100644
--- a/libavutil/x86/x86inc.asm
+++ b/libavutil/x86/x86inc.asm
@@ -571,6 +571,7 @@ SECTION .note.GNU-stack noalloc noexec nowrite progbits
; All subsequent functions (up to the next INIT_CPUFLAGS) is built for the specified cpu.
; You shouldn't need to invoke this macro directly, it's a subroutine for INIT_MMX &co.
%macro INIT_CPUFLAGS 0-2
+ CPU amdnop
%if %0 >= 1
%xdefine cpuname %1
%assign cpuflags cpuflags_%1
@@ -592,6 +593,9 @@ SECTION .note.GNU-stack noalloc noexec nowrite progbits
%elifidn %1, sse3
%define movu lddqu
%endif
+ %if notcpuflag(mmx2)
+ CPU basicnop
+ %endif
%else
%xdefine SUFFIX
%undef cpuname
diff --git a/libavutil/x86/x86util.asm b/libavutil/x86/x86util.asm
index 55f4a93..941ec76 100644
--- a/libavutil/x86/x86util.asm
+++ b/libavutil/x86/x86util.asm
@@ -42,10 +42,9 @@
%endmacro
%macro SBUTTERFLYPS 3
- movaps m%3, m%1
- unpcklps m%1, m%2
- unpckhps m%3, m%2
- SWAP %2, %3
+ unpcklps m%3, m%1, m%2
+ unpckhps m%1, m%1, m%2
+ SWAP %1, %3, %2
%endmacro
%macro TRANSPOSE4x4B 5
@@ -85,13 +84,12 @@
%macro TRANSPOSE4x4PS 5
SBUTTERFLYPS %1, %2, %5
SBUTTERFLYPS %3, %4, %5
- movaps m%5, m%1
- movlhps m%1, m%3
- movhlps m%3, m%5
- movaps m%5, m%2
- movlhps m%2, m%4
- movhlps m%4, m%5
- SWAP %2, %3
+ movlhps m%5, m%1, m%3
+ movhlps m%3, m%1
+ SWAP %5, %1
+ movlhps m%5, m%2, m%4
+ movhlps m%4, m%2
+ SWAP %5, %2, %3
%endmacro
%macro TRANSPOSE8x8W 9-11
@@ -258,15 +256,26 @@
%define ABSB ABSB_MMX
%define ABSB2 ABSB2_MMX
-%macro SPLATB_MMX 3
+%macro SPLATB_LOAD 3
+%if cpuflag(ssse3)
+ movd %1, [%2-3]
+ pshufb %1, %3
+%else
movd %1, [%2-3] ;to avoid crossing a cacheline
punpcklbw %1, %1
SPLATW %1, %1, 3
+%endif
%endmacro
-%macro SPLATB_SSSE3 3
- movd %1, [%2-3]
+%macro SPLATB_REG 3
+%if cpuflag(ssse3)
+ movd %1, %2d
pshufb %1, %3
+%else
+ movd %1, %2d
+ punpcklbw %1, %1
+ SPLATW %1, %1, 0
+%endif
%endmacro
%macro PALIGNR_MMX 4-5 ; [dst,] src1, src2, imm, tmp
@@ -298,6 +307,14 @@
%endif
%endmacro
+%macro PSHUFLW 1+
+ %if mmsize == 8
+ pshufw %1
+ %else
+ pshuflw %1
+ %endif
+%endmacro
+
%macro DEINTB 5 ; mask, reg1, mask, reg2, optional src to fill masks from
%ifnum %5
pand m%3, m%5, m%4 ; src .. y6 .. y4
@@ -523,8 +540,22 @@
%if mmsize == 16
pshuflw %1, %2, (%3)*0x55
punpcklqdq %1, %1
-%else
+%elif cpuflag(mmx2)
pshufw %1, %2, (%3)*0x55
+%else
+ %ifnidn %1, %2
+ mova %1, %2
+ %endif
+ %if %3 & 2
+ punpckhwd %1, %1
+ %else
+ punpcklwd %1, %1
+ %endif
+ %if %3 & 1
+ punpckhwd %1, %1
+ %else
+ punpcklwd %1, %1
+ %endif
%endif
%endmacro
diff --git a/libavutil/xtea.c b/libavutil/xtea.c
new file mode 100644
index 0000000..7c3a14c
--- /dev/null
+++ b/libavutil/xtea.c
@@ -0,0 +1,168 @@
+/*
+ * A 32-bit implementation of the XTEA algorithm
+ * Copyright (c) 2012 Samuel Pitoiset
+ *
+ * loosely based on the implementation of David Wheeler and Roger Needham
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/intreadwrite.h"
+
+#include "avutil.h"
+#include "common.h"
+#include "xtea.h"
+
+void av_xtea_init(AVXTEA *ctx, const uint8_t key[16])
+{
+ int i;
+
+ for (i = 0; i < 4; i++)
+ ctx->key[i] = AV_RB32(key + (i << 2));
+}
+
+static void xtea_crypt_ecb(AVXTEA *ctx, uint8_t *dst, const uint8_t *src,
+ int decrypt)
+{
+ uint32_t v0, v1;
+ int i;
+
+ v0 = AV_RB32(src);
+ v1 = AV_RB32(src + 4);
+
+ if (decrypt) {
+ uint32_t delta = 0x9E3779B9, sum = delta * 32;
+
+ for (i = 0; i < 32; i++) {
+ v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]);
+ sum -= delta;
+ v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]);
+ }
+ } else {
+ uint32_t sum = 0, delta = 0x9E3779B9;
+
+ for (i = 0; i < 32; i++) {
+ v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]);
+ sum += delta;
+ v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]);
+ }
+ }
+
+ AV_WB32(dst, v0);
+ AV_WB32(dst + 4, v1);
+}
+
+void av_xtea_crypt(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, int count,
+ uint8_t *iv, int decrypt)
+{
+ int i;
+
+ if (decrypt) {
+ while (count--) {
+ xtea_crypt_ecb(ctx, dst, src, decrypt);
+
+ if (iv) {
+ for (i = 0; i < 8; i++)
+ dst[i] = dst[i] ^ iv[i];
+ memcpy(iv, src, 8);
+ }
+
+ src += 8;
+ dst += 8;
+ }
+ } else {
+ while (count--) {
+ if (iv) {
+ for (i = 0; i < 8; i++)
+ dst[i] = src[i] ^ iv[i];
+ xtea_crypt_ecb(ctx, dst, dst, decrypt);
+ memcpy(iv, dst, 8);
+ } else {
+ xtea_crypt_ecb(ctx, dst, src, decrypt);
+ }
+ src += 8;
+ dst += 8;
+ }
+ }
+}
+
+#ifdef TEST
+#include <stdio.h>
+#undef printf
+
+#define XTEA_NUM_TESTS 6
+
+static const uint8_t xtea_test_key[XTEA_NUM_TESTS][16] = {
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+};
+
+static const uint8_t xtea_test_pt[XTEA_NUM_TESTS][8] = {
+ { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
+ { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
+ { 0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f },
+ { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
+ { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
+ { 0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55 }
+};
+
+static const uint8_t xtea_test_ct[XTEA_NUM_TESTS][8] = {
+ { 0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5 },
+ { 0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8 },
+ { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
+ { 0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5 },
+ { 0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d },
+ { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }
+};
+
+int main(void)
+{
+ AVXTEA ctx;
+ uint8_t buf[8];
+ int i;
+
+ for (i = 0; i < XTEA_NUM_TESTS; i++) {
+ av_xtea_init(&ctx, xtea_test_key[i]);
+
+ av_xtea_crypt(&ctx, buf, xtea_test_pt[i], 1, NULL, 0);
+ if (memcmp(buf, xtea_test_ct[i], 8)) {
+ printf("Test encryption failed.\n");
+ return 1;
+ }
+
+ av_xtea_crypt(&ctx, buf, xtea_test_ct[i], 1, NULL, 1);
+ if (memcmp(buf, xtea_test_pt[i], 8)) {
+ printf("Test decryption failed.\n");
+ return 1;
+ }
+ }
+ printf("Test encryption/decryption success.\n");
+
+ return 0;
+}
+
+#endif
diff --git a/libavutil/xtea.h b/libavutil/xtea.h
new file mode 100644
index 0000000..cf305c6
--- /dev/null
+++ b/libavutil/xtea.h
@@ -0,0 +1,61 @@
+/*
+ * A 32-bit implementation of the XTEA algorithm
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_XTEA_H
+#define AVUTIL_XTEA_H
+
+#include <stdint.h>
+
+/**
+ * @defgroup lavu_xtea XTEA
+ * @ingroup lavu_crypto
+ * @{
+ */
+
+typedef struct AVXTEA {
+ uint32_t key[16];
+} AVXTEA;
+
+/**
+ * Initialize an AVXTEA context.
+ *
+ * @param x an AVXTEA context
+ * @param key a key of 16 bytes used for encryption/decryption
+ */
+void av_xtea_init(struct AVXTEA *ctx, const uint8_t key[16]);
+
+/**
+ * Encrypt or decrypt a buffer using a previously initialized context.
+ *
+ * @param x an AVXTEA context
+ * @param dst destination array, can be equal to src
+ * @param src source array, can be equal to dst
+ * @param count number of 8 byte blocks
+ * @param iv initialization vector for CBC mode, if NULL then ECB will be used
+ * @param decrypt 0 for encryption, 1 for decryption
+ */
+void av_xtea_crypt(struct AVXTEA *ctx, uint8_t *dst, const uint8_t *src,
+ int count, uint8_t *iv, int decrypt);
+
+/**
+ * @}
+ */
+
+#endif /* AVUTIL_XTEA_H */
diff --git a/libswscale/Makefile b/libswscale/Makefile
index 29f3f12..0799b45 100644
--- a/libswscale/Makefile
+++ b/libswscale/Makefile
@@ -1,7 +1,8 @@
NAME = swscale
FFLIBS = avutil
-HEADERS = swscale.h
+HEADERS = swscale.h \
+ version.h \
OBJS = input.o \
options.o \
@@ -12,4 +13,5 @@ OBJS = input.o \
utils.o \
yuv2rgb.o \
-TESTPROGS = colorspace swscale
+TESTPROGS = colorspace \
+ swscale \
diff --git a/libswscale/bfin/swscale_bfin.c b/libswscale/bfin/swscale_bfin.c
index f9eba1e..f2fe871 100644
--- a/libswscale/bfin/swscale_bfin.c
+++ b/libswscale/bfin/swscale_bfin.c
@@ -20,16 +20,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <inttypes.h>
-#include <assert.h>
-#include "config.h"
-#include <unistd.h>
+#include <stdint.h>
-#include "libswscale/rgb2rgb.h"
-#include "libswscale/swscale.h"
+#include "config.h"
#include "libswscale/swscale_internal.h"
#if defined (__FDPIC__) && CONFIG_SRAM
@@ -46,14 +39,14 @@ int ff_bfin_yuyvtoyv12(const uint8_t *src, uint8_t *ydst, uint8_t *udst,
uint8_t *vdst, int width, int height,
int lumStride, int chromStride, int srcStride) L1CODE;
-static int uyvytoyv12_unscaled(SwsContext *c, uint8_t *src[], int srcStride[],
- int srcSliceY, int srcSliceH, uint8_t *dst[],
- int dstStride[])
+static int uyvytoyv12_unscaled(SwsContext *c, const uint8_t *src[],
+ int srcStride[], int srcSliceY, int srcSliceH,
+ uint8_t *dst[], int dstStride[])
{
uint8_t *dsty = dst[0] + dstStride[0] * srcSliceY;
uint8_t *dstu = dst[1] + dstStride[1] * srcSliceY / 2;
uint8_t *dstv = dst[2] + dstStride[2] * srcSliceY / 2;
- uint8_t *ip = src[0] + srcStride[0] * srcSliceY;
+ const uint8_t *ip = src[0] + srcStride[0] * srcSliceY;
int w = dstStride[0];
ff_bfin_uyvytoyv12(ip, dsty, dstu, dstv, w, srcSliceH,
@@ -62,14 +55,14 @@ static int uyvytoyv12_unscaled(SwsContext *c, uint8_t *src[], int srcStride[],
return srcSliceH;
}
-static int yuyvtoyv12_unscaled(SwsContext *c, uint8_t *src[], int srcStride[],
- int srcSliceY, int srcSliceH, uint8_t *dst[],
- int dstStride[])
+static int yuyvtoyv12_unscaled(SwsContext *c, const uint8_t *src[],
+ int srcStride[], int srcSliceY, int srcSliceH,
+ uint8_t *dst[], int dstStride[])
{
uint8_t *dsty = dst[0] + dstStride[0] * srcSliceY;
uint8_t *dstu = dst[1] + dstStride[1] * srcSliceY / 2;
uint8_t *dstv = dst[2] + dstStride[2] * srcSliceY / 2;
- uint8_t *ip = src[0] + srcStride[0] * srcSliceY;
+ const uint8_t *ip = src[0] + srcStride[0] * srcSliceY;
int w = dstStride[0];
ff_bfin_yuyvtoyv12(ip, dsty, dstu, dstv, w, srcSliceH,
diff --git a/libswscale/bfin/yuv2rgb_bfin.c b/libswscale/bfin/yuv2rgb_bfin.c
index 91a7aee..4078a18 100644
--- a/libswscale/bfin/yuv2rgb_bfin.c
+++ b/libswscale/bfin/yuv2rgb_bfin.c
@@ -21,16 +21,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <inttypes.h>
-#include <assert.h>
-#include <unistd.h>
+#include <stdint.h>
#include "config.h"
-#include "libswscale/rgb2rgb.h"
-#include "libswscale/swscale.h"
#include "libswscale/swscale_internal.h"
#if defined(__FDPIC__) && CONFIG_SRAM
@@ -39,17 +32,20 @@
#define L1CODE
#endif
-void ff_bfin_yuv2rgb555_line(uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out,
+void ff_bfin_yuv2rgb555_line(const uint8_t *Y, const uint8_t *U,
+ const uint8_t *V, uint8_t *out,
int w, uint32_t *coeffs) L1CODE;
-void ff_bfin_yuv2rgb565_line(uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out,
+void ff_bfin_yuv2rgb565_line(const uint8_t *Y, const uint8_t *U,
+ const uint8_t *V, uint8_t *out,
int w, uint32_t *coeffs) L1CODE;
-void ff_bfin_yuv2rgb24_line(uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out,
+void ff_bfin_yuv2rgb24_line(const uint8_t *Y, const uint8_t *U,
+ const uint8_t *V, uint8_t *out,
int w, uint32_t *coeffs) L1CODE;
-typedef void (*ltransform)(uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out,
- int w, uint32_t *coeffs);
+typedef void (*ltransform)(const uint8_t *Y, const uint8_t *U, const uint8_t *V,
+ uint8_t *out, int w, uint32_t *coeffs);
static void bfin_prepare_coefficients(SwsContext *c, int rgb, int masks)
{
@@ -87,12 +83,13 @@ static void bfin_prepare_coefficients(SwsContext *c, int rgb, int masks)
}
}
-static int core_yuv420_rgb(SwsContext *c, uint8_t **in, int *instrides,
+static int core_yuv420_rgb(SwsContext *c, const uint8_t **in, int *instrides,
int srcSliceY, int srcSliceH, uint8_t **oplanes,
int *outstrides, ltransform lcscf,
int rgb, int masks)
{
- uint8_t *py, *pu, *pv, *op;
+ const uint8_t *py, *pu, *pv;
+ uint8_t *op;
int w = instrides[0];
int h2 = srcSliceH >> 1;
int i;
@@ -122,7 +119,7 @@ static int core_yuv420_rgb(SwsContext *c, uint8_t **in, int *instrides,
return srcSliceH;
}
-static int bfin_yuv420_rgb555(SwsContext *c, uint8_t **in, int *instrides,
+static int bfin_yuv420_rgb555(SwsContext *c, const uint8_t **in, int *instrides,
int srcSliceY, int srcSliceH,
uint8_t **oplanes, int *outstrides)
{
@@ -130,7 +127,7 @@ static int bfin_yuv420_rgb555(SwsContext *c, uint8_t **in, int *instrides,
outstrides, ff_bfin_yuv2rgb555_line, 1, 555);
}
-static int bfin_yuv420_bgr555(SwsContext *c, uint8_t **in, int *instrides,
+static int bfin_yuv420_bgr555(SwsContext *c, const uint8_t **in, int *instrides,
int srcSliceY, int srcSliceH,
uint8_t **oplanes, int *outstrides)
{
@@ -138,7 +135,7 @@ static int bfin_yuv420_bgr555(SwsContext *c, uint8_t **in, int *instrides,
outstrides, ff_bfin_yuv2rgb555_line, 0, 555);
}
-static int bfin_yuv420_rgb24(SwsContext *c, uint8_t **in, int *instrides,
+static int bfin_yuv420_rgb24(SwsContext *c, const uint8_t **in, int *instrides,
int srcSliceY, int srcSliceH,
uint8_t **oplanes, int *outstrides)
{
@@ -146,7 +143,7 @@ static int bfin_yuv420_rgb24(SwsContext *c, uint8_t **in, int *instrides,
outstrides, ff_bfin_yuv2rgb24_line, 1, 888);
}
-static int bfin_yuv420_bgr24(SwsContext *c, uint8_t **in, int *instrides,
+static int bfin_yuv420_bgr24(SwsContext *c, const uint8_t **in, int *instrides,
int srcSliceY, int srcSliceH,
uint8_t **oplanes, int *outstrides)
{
@@ -154,7 +151,7 @@ static int bfin_yuv420_bgr24(SwsContext *c, uint8_t **in, int *instrides,
outstrides, ff_bfin_yuv2rgb24_line, 0, 888);
}
-static int bfin_yuv420_rgb565(SwsContext *c, uint8_t **in, int *instrides,
+static int bfin_yuv420_rgb565(SwsContext *c, const uint8_t **in, int *instrides,
int srcSliceY, int srcSliceH,
uint8_t **oplanes, int *outstrides)
{
@@ -162,7 +159,7 @@ static int bfin_yuv420_rgb565(SwsContext *c, uint8_t **in, int *instrides,
outstrides, ff_bfin_yuv2rgb565_line, 1, 565);
}
-static int bfin_yuv420_bgr565(SwsContext *c, uint8_t **in, int *instrides,
+static int bfin_yuv420_bgr565(SwsContext *c, const uint8_t **in, int *instrides,
int srcSliceY, int srcSliceH,
uint8_t **oplanes, int *outstrides)
{
diff --git a/libswscale/input.c b/libswscale/input.c
index afc5156..40ed122 100644
--- a/libswscale/input.c
+++ b/libswscale/input.c
@@ -553,80 +553,120 @@ static void planar_rgb_to_y(uint8_t *dst, const uint8_t *src[4], int width)
}
}
-static void planar_rgb16le_to_y(uint8_t *_dst, const uint8_t *_src[4], int width)
+static void planar_rgb_to_uv(uint8_t *dstU, uint8_t *dstV, const uint8_t *src[4], int width)
{
int i;
- const uint16_t **src = (const uint16_t **)_src;
- uint16_t *dst = (uint16_t *)_dst;
for (i = 0; i < width; i++) {
- int g = AV_RL16(src[0] + i);
- int b = AV_RL16(src[1] + i);
- int r = AV_RL16(src[2] + i);
+ int g = src[0][i];
+ int b = src[1][i];
+ int r = src[2][i];
- dst[i] = ((RY * r + GY * g + BY * b + (33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
+ dstU[i] = (RU * r + GU * g + BU * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT;
+ dstV[i] = (RV * r + GV * g + BV * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT;
}
}
-static void planar_rgb16be_to_y(uint8_t *_dst, const uint8_t *_src[4], int width)
+#define rdpx(src) \
+ is_be ? AV_RB16(src) : AV_RL16(src)
+static av_always_inline void planar_rgb16_to_y(uint8_t *_dst, const uint8_t *_src[4],
+ int width, int bpc, int is_be)
{
int i;
const uint16_t **src = (const uint16_t **)_src;
uint16_t *dst = (uint16_t *)_dst;
for (i = 0; i < width; i++) {
- int g = AV_RB16(src[0] + i);
- int b = AV_RB16(src[1] + i);
- int r = AV_RB16(src[2] + i);
+ int g = rdpx(src[0] + i);
+ int b = rdpx(src[1] + i);
+ int r = rdpx(src[2] + i);
- dst[i] = ((RY * r + GY * g + BY * b + (33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
+ dst[i] = ((RY * r + GY * g + BY * b + (33 << (RGB2YUV_SHIFT + bpc - 9))) >> RGB2YUV_SHIFT);
}
}
-static void planar_rgb_to_uv(uint8_t *dstU, uint8_t *dstV, const uint8_t *src[4], int width)
+static void planar_rgb9le_to_y(uint8_t *dst, const uint8_t *src[4], int w)
{
- int i;
- for (i = 0; i < width; i++) {
- int g = src[0][i];
- int b = src[1][i];
- int r = src[2][i];
+ planar_rgb16_to_y(dst, src, w, 9, 0);
+}
- dstU[i] = (RU * r + GU * g + BU * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1);
- dstV[i] = (RV * r + GV * g + BV * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1);
- }
+static void planar_rgb9be_to_y(uint8_t *dst, const uint8_t *src[4], int w)
+{
+ planar_rgb16_to_y(dst, src, w, 9, 1);
}
-static void planar_rgb16le_to_uv(uint8_t *_dstU, uint8_t *_dstV,
- const uint8_t *_src[4], int width)
+static void planar_rgb10le_to_y(uint8_t *dst, const uint8_t *src[4], int w)
{
- int i;
- const uint16_t **src = (const uint16_t **)_src;
- uint16_t *dstU = (uint16_t *)_dstU;
- uint16_t *dstV = (uint16_t *)_dstV;
- for (i = 0; i < width; i++) {
- int g = AV_RL16(src[0] + i);
- int b = AV_RL16(src[1] + i);
- int r = AV_RL16(src[2] + i);
+ planar_rgb16_to_y(dst, src, w, 10, 0);
+}
- dstU[i] = (RU * r + GU * g + BU * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1);
- dstV[i] = (RV * r + GV * g + BV * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1);
- }
+static void planar_rgb10be_to_y(uint8_t *dst, const uint8_t *src[4], int w)
+{
+ planar_rgb16_to_y(dst, src, w, 10, 1);
}
-static void planar_rgb16be_to_uv(uint8_t *_dstU, uint8_t *_dstV,
- const uint8_t *_src[4], int width)
+static void planar_rgb16le_to_y(uint8_t *dst, const uint8_t *src[4], int w)
+{
+ planar_rgb16_to_y(dst, src, w, 16, 0);
+}
+
+static void planar_rgb16be_to_y(uint8_t *dst, const uint8_t *src[4], int w)
+{
+ planar_rgb16_to_y(dst, src, w, 16, 1);
+}
+
+static av_always_inline void planar_rgb16_to_uv(uint8_t *_dstU, uint8_t *_dstV,
+ const uint8_t *_src[4], int width,
+ int bpc, int is_be)
{
int i;
const uint16_t **src = (const uint16_t **)_src;
uint16_t *dstU = (uint16_t *)_dstU;
uint16_t *dstV = (uint16_t *)_dstV;
for (i = 0; i < width; i++) {
- int g = AV_RB16(src[0] + i);
- int b = AV_RB16(src[1] + i);
- int r = AV_RB16(src[2] + i);
+ int g = rdpx(src[0] + i);
+ int b = rdpx(src[1] + i);
+ int r = rdpx(src[2] + i);
- dstU[i] = (RU * r + GU * g + BU * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1);
- dstV[i] = (RV * r + GV * g + BV * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1);
+ dstU[i] = (RU * r + GU * g + BU * b + (257 << (RGB2YUV_SHIFT + bpc - 9))) >> RGB2YUV_SHIFT;
+ dstV[i] = (RV * r + GV * g + BV * b + (257 << (RGB2YUV_SHIFT + bpc - 9))) >> RGB2YUV_SHIFT;
}
}
+#undef rdpx
+
+static void planar_rgb9le_to_uv(uint8_t *dstU, uint8_t *dstV,
+ const uint8_t *src[4], int w)
+{
+ planar_rgb16_to_uv(dstU, dstV, src, w, 9, 0);
+}
+
+static void planar_rgb9be_to_uv(uint8_t *dstU, uint8_t *dstV,
+ const uint8_t *src[4], int w)
+{
+ planar_rgb16_to_uv(dstU, dstV, src, w, 9, 1);
+}
+
+static void planar_rgb10le_to_uv(uint8_t *dstU, uint8_t *dstV,
+ const uint8_t *src[4], int w)
+{
+ planar_rgb16_to_uv(dstU, dstV, src, w, 10, 0);
+}
+
+static void planar_rgb10be_to_uv(uint8_t *dstU, uint8_t *dstV,
+ const uint8_t *src[4], int w)
+{
+ planar_rgb16_to_uv(dstU, dstV, src, w, 10, 1);
+}
+
+static void planar_rgb16le_to_uv(uint8_t *dstU, uint8_t *dstV,
+ const uint8_t *src[4], int w)
+{
+ planar_rgb16_to_uv(dstU, dstV, src, w, 16, 0);
+}
+
+static void planar_rgb16be_to_uv(uint8_t *dstU, uint8_t *dstV,
+ const uint8_t *src[4], int w)
+{
+ planar_rgb16_to_uv(dstU, dstV, src, w, 16, 1);
+}
av_cold void ff_sws_init_input_funcs(SwsContext *c)
{
@@ -654,12 +694,20 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c)
c->chrToYV12 = palToUV_c;
break;
case PIX_FMT_GBRP9LE:
+ c->readChrPlanar = planar_rgb9le_to_uv;
+ break;
case PIX_FMT_GBRP10LE:
+ c->readChrPlanar = planar_rgb10le_to_uv;
+ break;
case PIX_FMT_GBRP16LE:
c->readChrPlanar = planar_rgb16le_to_uv;
break;
case PIX_FMT_GBRP9BE:
+ c->readChrPlanar = planar_rgb9be_to_uv;
+ break;
case PIX_FMT_GBRP10BE:
+ c->readChrPlanar = planar_rgb10be_to_uv;
+ break;
case PIX_FMT_GBRP16BE:
c->readChrPlanar = planar_rgb16be_to_uv;
break;
@@ -836,12 +884,20 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c)
c->alpToYV12 = NULL;
switch (srcFormat) {
case PIX_FMT_GBRP9LE:
+ c->readLumPlanar = planar_rgb9le_to_y;
+ break;
case PIX_FMT_GBRP10LE:
+ c->readLumPlanar = planar_rgb10le_to_y;
+ break;
case PIX_FMT_GBRP16LE:
c->readLumPlanar = planar_rgb16le_to_y;
break;
case PIX_FMT_GBRP9BE:
+ c->readLumPlanar = planar_rgb9be_to_y;
+ break;
case PIX_FMT_GBRP10BE:
+ c->readLumPlanar = planar_rgb10be_to_y;
+ break;
case PIX_FMT_GBRP16BE:
c->readLumPlanar = planar_rgb16be_to_y;
break;
diff --git a/libswscale/swscale.h b/libswscale/swscale.h
index b5a6a57..30c87be 100644
--- a/libswscale/swscale.h
+++ b/libswscale/swscale.h
@@ -30,31 +30,7 @@
#include "libavutil/avutil.h"
#include "libavutil/log.h"
#include "libavutil/pixfmt.h"
-
-#define LIBSWSCALE_VERSION_MAJOR 2
-#define LIBSWSCALE_VERSION_MINOR 1
-#define LIBSWSCALE_VERSION_MICRO 0
-
-#define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \
- LIBSWSCALE_VERSION_MINOR, \
- LIBSWSCALE_VERSION_MICRO)
-#define LIBSWSCALE_VERSION AV_VERSION(LIBSWSCALE_VERSION_MAJOR, \
- LIBSWSCALE_VERSION_MINOR, \
- LIBSWSCALE_VERSION_MICRO)
-#define LIBSWSCALE_BUILD LIBSWSCALE_VERSION_INT
-
-#define LIBSWSCALE_IDENT "SwS" AV_STRINGIFY(LIBSWSCALE_VERSION)
-
-/**
- * Those FF_API_* defines are not part of public API.
- * They may change, break or disappear at any time.
- */
-#ifndef FF_API_SWS_GETCONTEXT
-#define FF_API_SWS_GETCONTEXT (LIBSWSCALE_VERSION_MAJOR < 3)
-#endif
-#ifndef FF_API_SWS_CPU_CAPS
-#define FF_API_SWS_CPU_CAPS (LIBSWSCALE_VERSION_MAJOR < 3)
-#endif
+#include "version.h"
/**
* Return the LIBSWSCALE_VERSION_INT constant.
diff --git a/libswscale/version.h b/libswscale/version.h
new file mode 100644
index 0000000..32bb2f5
--- /dev/null
+++ b/libswscale/version.h
@@ -0,0 +1,56 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef SWSCALE_VERSION_H
+#define SWSCALE_VERSION_H
+
+/**
+ * @file
+ * swscale version macros
+ */
+
+#include "libavutil/avutil.h"
+
+#define LIBSWSCALE_VERSION_MAJOR 2
+#define LIBSWSCALE_VERSION_MINOR 1
+#define LIBSWSCALE_VERSION_MICRO 0
+
+#define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \
+ LIBSWSCALE_VERSION_MINOR, \
+ LIBSWSCALE_VERSION_MICRO)
+#define LIBSWSCALE_VERSION AV_VERSION(LIBSWSCALE_VERSION_MAJOR, \
+ LIBSWSCALE_VERSION_MINOR, \
+ LIBSWSCALE_VERSION_MICRO)
+#define LIBSWSCALE_BUILD LIBSWSCALE_VERSION_INT
+
+#define LIBSWSCALE_IDENT "SwS" AV_STRINGIFY(LIBSWSCALE_VERSION)
+
+/**
+ * FF_API_* defines may be placed below to indicate public API that will be
+ * dropped at a future version bump. The defines themselves are not part of
+ * the public API and may change, break or disappear at any time.
+ */
+
+#ifndef FF_API_SWS_GETCONTEXT
+#define FF_API_SWS_GETCONTEXT (LIBSWSCALE_VERSION_MAJOR < 3)
+#endif
+#ifndef FF_API_SWS_CPU_CAPS
+#define FF_API_SWS_CPU_CAPS (LIBSWSCALE_VERSION_MAJOR < 3)
+#endif
+
+#endif /* SWSCALE_VERSION_H */
diff --git a/libswscale/x86/swscale_mmx.c b/libswscale/x86/swscale_mmx.c
index 99b3262..37d786a 100644
--- a/libswscale/x86/swscale_mmx.c
+++ b/libswscale/x86/swscale_mmx.c
@@ -329,12 +329,12 @@ void ff_sws_init_swScale_mmx(SwsContext *c)
case 8: ASSIGN_SCALE_FUNC2(hscalefn, 8, opt1, opt2); break; \
default: ASSIGN_SCALE_FUNC2(hscalefn, X, opt1, opt2); break; \
}
-#define ASSIGN_VSCALEX_FUNC(vscalefn, opt, do_16_case) \
+#define ASSIGN_VSCALEX_FUNC(vscalefn, opt, do_16_case, condition_8bit) \
switch(c->dstBpc){ \
case 16: do_16_case; break; \
case 10: if (!isBE(c->dstFormat)) vscalefn = ff_yuv2planeX_10_ ## opt; break; \
case 9: if (!isBE(c->dstFormat)) vscalefn = ff_yuv2planeX_9_ ## opt; break; \
- default: vscalefn = ff_yuv2planeX_8_ ## opt; break; \
+ default: if (condition_8bit) vscalefn = ff_yuv2planeX_8_ ## opt; break; \
}
#define ASSIGN_VSCALE_FUNC(vscalefn, opt1, opt2, opt2chk) \
switch(c->dstBpc){ \
@@ -386,7 +386,7 @@ switch(c->dstBpc){ \
}
}
if (cpu_flags & AV_CPU_FLAG_MMX2) {
- ASSIGN_VSCALEX_FUNC(c->yuv2planeX, mmx2,);
+ ASSIGN_VSCALEX_FUNC(c->yuv2planeX, mmx2, , 1);
}
#endif
#define ASSIGN_SSE_SCALE_FUNC(hscalefn, filtersize, opt1, opt2) \
@@ -400,7 +400,8 @@ switch(c->dstBpc){ \
if (cpu_flags & AV_CPU_FLAG_SSE2) {
ASSIGN_SSE_SCALE_FUNC(c->hyScale, c->hLumFilterSize, sse2, sse2);
ASSIGN_SSE_SCALE_FUNC(c->hcScale, c->hChrFilterSize, sse2, sse2);
- ASSIGN_VSCALEX_FUNC(c->yuv2planeX, sse2,);
+ ASSIGN_VSCALEX_FUNC(c->yuv2planeX, sse2, ,
+ HAVE_ALIGNED_STACK || ARCH_X86_64);
ASSIGN_VSCALE_FUNC(c->yuv2plane1, sse2, sse2, 1);
switch (c->srcFormat) {
@@ -448,13 +449,15 @@ switch(c->dstBpc){ \
ASSIGN_SSE_SCALE_FUNC(c->hyScale, c->hLumFilterSize, sse4, ssse3);
ASSIGN_SSE_SCALE_FUNC(c->hcScale, c->hChrFilterSize, sse4, ssse3);
ASSIGN_VSCALEX_FUNC(c->yuv2planeX, sse4,
- if (!isBE(c->dstFormat)) c->yuv2planeX = ff_yuv2planeX_16_sse4);
+ if (!isBE(c->dstFormat)) c->yuv2planeX = ff_yuv2planeX_16_sse4,
+ HAVE_ALIGNED_STACK || ARCH_X86_64);
if (c->dstBpc == 16 && !isBE(c->dstFormat))
c->yuv2plane1 = ff_yuv2plane1_16_sse4;
}
if (cpu_flags & AV_CPU_FLAG_AVX) {
- ASSIGN_VSCALEX_FUNC(c->yuv2planeX, avx,);
+ ASSIGN_VSCALEX_FUNC(c->yuv2planeX, avx, ,
+ HAVE_ALIGNED_STACK || ARCH_X86_64);
ASSIGN_VSCALE_FUNC(c->yuv2plane1, avx, avx, 1);
switch (c->srcFormat) {
diff --git a/tests/Makefile b/tests/Makefile
index 19fbe11..91f2d49 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -1,25 +1,30 @@
-AREF = fate-acodec-aref
-VREF = fate-vsynth1-vref fate-vsynth2-vref
-REFS = $(AREF) $(VREF)
+VREF = tests/vsynth1/00.pgm
+AREF = tests/data/asynth1.sw
-$(VREF): avconv$(EXESUF) tests/vsynth1/00.pgm tests/vsynth2/00.pgm
-$(AREF): avconv$(EXESUF) tests/data/asynth1.sw
+OBJDIRS += tests/data tests/vsynth1
-OBJDIRS += tests/data tests/vsynth1 tests/vsynth2
+# Required due to missing automatic dependency tracking for HOSTOBJS.
+tests/rotozoom.o tests/videogen.o: tests/utils.c
tests/vsynth1/00.pgm: tests/videogen$(HOSTEXESUF) | tests/vsynth1
$(M)./$< 'tests/vsynth1/'
-tests/vsynth2/00.pgm: tests/rotozoom$(HOSTEXESUF) | tests/vsynth2
- $(M)./$< 'tests/vsynth2/' $(SRC_PATH)/tests/lena.pnm
-
tests/data/asynth1.sw: tests/audiogen$(HOSTEXESUF) | tests/data
$(M)./$< $@
tests/data/asynth-%.wav: tests/audiogen$(HOSTEXESUF) | tests/data
$(M)./$< $@ $(subst -, ,$*)
-tests/data/asynth% tests/vsynth%/00.pgm: TAG = GEN
+tests/data/vsynth1.yuv: tests/videogen$(HOSTEXESUF) | tests/data
+ $(M)$< $@
+
+tests/data/vsynth2.yuv: tests/rotozoom$(HOSTEXESUF) | tests/data
+ $(M)$< $(SRC_PATH)/tests/lena.pnm $@
+
+tests/data/asynth% tests/data/vsynth%.yuv tests/vsynth%/00.pgm: TAG = GEN
+
+include $(SRC_PATH)/tests/fate/acodec.mak
+include $(SRC_PATH)/tests/fate/vcodec.mak
include $(SRC_PATH)/tests/fate/aac.mak
include $(SRC_PATH)/tests/fate/ac3.mak
@@ -31,11 +36,13 @@ include $(SRC_PATH)/tests/fate/atrac.mak
include $(SRC_PATH)/tests/fate/audio.mak
include $(SRC_PATH)/tests/fate/bmp.mak
include $(SRC_PATH)/tests/fate/cdxl.mak
+include $(SRC_PATH)/tests/fate/cover-art.mak
include $(SRC_PATH)/tests/fate/dct.mak
include $(SRC_PATH)/tests/fate/demux.mak
include $(SRC_PATH)/tests/fate/dfa.mak
include $(SRC_PATH)/tests/fate/dpcm.mak
include $(SRC_PATH)/tests/fate/ea.mak
+include $(SRC_PATH)/tests/fate/flac.mak
include $(SRC_PATH)/tests/fate/fft.mak
include $(SRC_PATH)/tests/fate/h264.mak
include $(SRC_PATH)/tests/fate/image.mak
@@ -48,6 +55,7 @@ include $(SRC_PATH)/tests/fate/microsoft.mak
include $(SRC_PATH)/tests/fate/mp3.mak
include $(SRC_PATH)/tests/fate/mpc.mak
include $(SRC_PATH)/tests/fate/pcm.mak
+include $(SRC_PATH)/tests/fate/probe.mak
include $(SRC_PATH)/tests/fate/prores.mak
include $(SRC_PATH)/tests/fate/qt.mak
include $(SRC_PATH)/tests/fate/qtrle.mak
@@ -62,62 +70,57 @@ include $(SRC_PATH)/tests/fate/vqf.mak
include $(SRC_PATH)/tests/fate/wavpack.mak
include $(SRC_PATH)/tests/fate/wma.mak
-FATE_ACODEC = $(ACODEC_TESTS:%=fate-acodec-%)
-FATE_VSYNTH1 = $(VCODEC_TESTS:%=fate-vsynth1-%)
-FATE_VSYNTH2 = $(VCODEC_TESTS:%=fate-vsynth2-%)
-FATE_VCODEC = $(FATE_VSYNTH1) $(FATE_VSYNTH2)
FATE_LAVF = $(LAVF_TESTS:%=fate-lavf-%)
FATE_LAVFI = $(LAVFI_TESTS:%=fate-lavfi-%)
FATE_SEEK = $(SEEK_TESTS:seek_%=fate-seek-%)
-FATE = $(FATE_ACODEC) \
- $(FATE_VCODEC) \
- $(FATE_LAVF) \
- $(FATE_SEEK) \
+FATE_AVCONV += $(FATE_LAVF) \
+ $(FATE_LAVFI) \
+ $(FATE_SEEK) \
-FATE-$(CONFIG_AVFILTER) += $(FATE_LAVFI)
+FATE_AVCONV += $(FATE_AVCONV-yes)
+FATE-$(CONFIG_AVCONV) += $(FATE_AVCONV)
+
+FATE-$(CONFIG_AVCODEC) += $(FATE_LIBAVCODEC)
+
+FATE_SAMPLES-$(CONFIG_AVCONV) += $(FATE_SAMPLES_AVCONV)
+FATE_SAMPLES += $(FATE_SAMPLES-yes)
FATE += $(FATE-yes)
+FATE += $(FATE_LIBAVUTIL)
+
+$(FATE_AVCONV) $(FATE_SAMPLES_AVCONV): avconv$(EXESUF)
-$(filter-out %-aref,$(FATE_ACODEC)): $(AREF)
-$(filter-out %-vref,$(FATE_VSYNTH1)): fate-vsynth1-vref
-$(filter-out %-vref,$(FATE_VSYNTH2)): fate-vsynth2-vref
-$(FATE_LAVF): $(REFS)
-$(FATE_LAVFI): $(REFS) tools/lavfi-showfiltfmts$(EXESUF)
-$(FATE_SEEK): fate-codec fate-lavf libavformat/seek-test$(EXESUF)
+$(FATE_LAVF): $(AREF) $(VREF)
+$(FATE_LAVFI): $(VREF) libavfilter/filtfmts-test$(EXESUF)
+$(FATE_SEEK): fate-acodec fate-vsynth2 fate-lavf libavformat/seek-test$(EXESUF)
-$(FATE_ACODEC): CMD = codectest acodec
-$(FATE_VSYNTH1): CMD = codectest vsynth1
-$(FATE_VSYNTH2): CMD = codectest vsynth2
$(FATE_LAVF): CMD = lavftest
$(FATE_LAVFI): CMD = lavfitest
$(FATE_SEEK): CMD = seektest
-fate-codec: fate-acodec fate-vcodec
-fate-acodec: $(FATE_ACODEC)
-fate-vcodec: $(FATE_VCODEC)
fate-lavf: $(FATE_LAVF)
fate-lavfi: $(FATE_LAVFI)
fate-seek: $(FATE_SEEK)
ifdef SAMPLES
-FATE += $(FATE_TESTS) $(FATE_TESTS-yes)
+FATE += $(FATE_SAMPLES)
fate-rsync:
rsync -vaLW rsync://fate-suite.libav.org/fate-suite/ $(SAMPLES)
else
fate-rsync:
@echo "use 'make fate-rsync SAMPLES=/path/to/samples' to sync the fate suite"
-$(FATE_TESTS):
- @echo "SAMPLES not specified, cannot run FATE"
+$(FATE_SAMPLES):
+ @echo "$@ requires external samples and SAMPLES not specified"; false
endif
FATE_UTILS = base64 tiny_psnr
fate: $(FATE)
-$(FATE): avconv$(EXESUF) $(FATE_UTILS:%=tests/%$(HOSTEXESUF))
+$(FATE): $(FATE_UTILS:%=tests/%$(HOSTEXESUF))
@echo "TEST $(@:fate-%=%)"
- $(Q)$(SRC_PATH)/tests/fate-run.sh $@ "$(SAMPLES)" "$(TARGET_EXEC)" "$(TARGET_PATH)" '$(CMD)' '$(CMP)' '$(REF)' '$(FUZZ)' '$(THREADS)' '$(THREAD_TYPE)' '$(CPUFLAGS)' '$(CMP_SHIFT)' '$(CMP_TARGET)' '$(SIZE_TOLERANCE)'
+ $(Q)$(SRC_PATH)/tests/fate-run.sh $@ "$(SAMPLES)" "$(TARGET_EXEC)" "$(TARGET_PATH)" '$(CMD)' '$(CMP)' '$(REF)' '$(FUZZ)' '$(THREADS)' '$(THREAD_TYPE)' '$(CPUFLAGS)' '$(CMP_SHIFT)' '$(CMP_TARGET)' '$(SIZE_TOLERANCE)' '$(CMP_UNIT)'
fate-list:
@printf '%s\n' $(sort $(FATE))
@@ -125,7 +128,7 @@ fate-list:
clean:: testclean
testclean:
- $(RM) -r tests/vsynth1 tests/vsynth2 tests/data
+ $(RM) -r tests/vsynth1 tests/data
$(RM) $(CLEANSUFFIXES:%=tests/%)
$(RM) $(TESTTOOLS:%=tests/%$(HOSTEXESUF))
diff --git a/tests/codec-regression.sh b/tests/codec-regression.sh
deleted file mode 100755
index 80dd269..0000000
--- a/tests/codec-regression.sh
+++ /dev/null
@@ -1,421 +0,0 @@
-#!/bin/sh
-#
-# automatic regression test for avconv
-#
-#
-#set -x
-
-set -e
-
-. $(dirname $0)/regression-funcs.sh
-
-eval do_$test=y
-
-# generate reference for quality check
-if [ -n "$do_vref" ]; then
-do_avconv $raw_ref -f image2 -vcodec pgmyuv -i $raw_src -an -f rawvideo
-fi
-if [ -n "$do_aref" ]; then
-do_avconv $pcm_ref -b 128k -ac 2 -ar 44100 -f s16le -i $pcm_src -f wav
-fi
-
-if [ -n "$do_cljr" ] ; then
-do_video_encoding cljr.avi "-an -vcodec cljr"
-do_video_decoding
-fi
-
-if [ -n "$do_mpeg" ] ; then
-# mpeg1
-do_video_encoding mpeg1.mpg "-qscale 10 -f mpeg1video"
-do_video_decoding
-fi
-
-if [ -n "$do_mpeg2" ] ; then
-# mpeg2
-do_video_encoding mpeg2.mpg "-qscale 10 -vcodec mpeg2video -f mpeg1video"
-do_video_decoding
-fi
-
-if [ -n "$do_mpeg2_ivlc_qprd" ]; then
-# mpeg2 encoding intra vlc qprd
-do_video_encoding mpeg2ivlc-qprd.mpg "-vb 500k -bf 2 -trellis 1 -flags +mv0 -mpv_flags +qp_rd -intra_vlc 1 -cmp 2 -subcmp 2 -mbd rd -vcodec mpeg2video -f mpeg2video"
-do_video_decoding
-fi
-
-if [ -n "$do_mpeg2_422" ]; then
-#mpeg2 4:2:2 encoding
-do_video_encoding mpeg2_422.mpg "-vb 1000k -bf 2 -trellis 1 -flags +mv0+ildct+ilme -mpv_flags +qp_rd -intra_vlc 1 -mbd rd -vcodec mpeg2video -pix_fmt yuv422p -f mpeg2video"
-do_video_decoding
-fi
-
-if [ -n "$do_mpeg2_idct_int" ]; then
-# mpeg2
-do_video_encoding mpeg2_idct_int.mpg "-qscale 10 -vcodec mpeg2video -idct int -dct int -f mpeg1video"
-do_video_decoding "-idct int"
-fi
-
-if [ -n "$do_mpeg2_ilace" ]; then
-# mpeg2 encoding interlaced
-do_video_encoding mpeg2i.mpg "-qscale 10 -vcodec mpeg2video -f mpeg1video -flags +ildct+ilme"
-do_video_decoding
-fi
-
-if [ -n "$do_mpeg2thread" ] ; then
-# mpeg2 encoding interlaced
-do_video_encoding mpeg2thread.mpg "-qscale 10 -vcodec mpeg2video -f mpeg1video -bf 2 -flags +ildct+ilme -threads 2 -slices 2"
-do_video_decoding
-fi
-
-if [ -n "$do_mpeg2thread_ilace" ]; then
-# mpeg2 encoding interlaced using intra vlc
-do_video_encoding mpeg2threadivlc.mpg "-qscale 10 -vcodec mpeg2video -f mpeg1video -bf 2 -flags +ildct+ilme -intra_vlc 1 -threads 2 -slices 2"
-do_video_decoding
-fi
-
-if [ -n "$do_msmpeg4v2" ] ; then
-do_video_encoding msmpeg4v2.avi "-qscale 10 -an -vcodec msmpeg4v2"
-do_video_decoding
-fi
-
-if [ -n "$do_msmpeg4" ] ; then
-do_video_encoding msmpeg4.avi "-qscale 10 -an -vcodec msmpeg4"
-do_video_decoding
-fi
-
-if [ -n "$do_wmv1" ] ; then
-do_video_encoding wmv1.avi "-qscale 10 -an -vcodec wmv1"
-do_video_decoding
-fi
-
-if [ -n "$do_wmv2" ] ; then
-do_video_encoding wmv2.avi "-qscale 10 -an -vcodec wmv2"
-do_video_decoding
-fi
-
-if [ -n "$do_h261" ] ; then
-do_video_encoding h261.avi "-qscale 11 -s 352x288 -an -vcodec h261"
-do_video_decoding
-fi
-
-if [ -n "$do_h263" ] ; then
-do_video_encoding h263.avi "-qscale 10 -s 352x288 -an -vcodec h263"
-do_video_decoding
-fi
-
-if [ -n "$do_h263p" ] ; then
-do_video_encoding h263p.avi "-qscale 2 -flags +aic -umv 1 -aiv 1 -s 352x288 -an -vcodec h263p -ps 300"
-do_video_decoding
-fi
-
-if [ -n "$do_mpeg4" ] ; then
-do_video_encoding odivx.mp4 "-flags +mv4 -mbd bits -qscale 10 -an -vcodec mpeg4"
-do_video_decoding
-fi
-
-if [ -n "$do_huffyuv" ] ; then
-do_video_encoding huffyuv.avi "-an -vcodec huffyuv -pix_fmt yuv422p -sws_flags neighbor+bitexact"
-do_video_decoding "" "-strict -2 -pix_fmt yuv420p -sws_flags neighbor+bitexact"
-fi
-
-if [ -n "$do_rc" ] ; then
-do_video_encoding mpeg4-rc.avi "-b 400k -bf 2 -an -vcodec mpeg4"
-do_video_decoding
-fi
-
-if [ -n "$do_mpeg4adv" ] ; then
-do_video_encoding mpeg4-adv.avi "-qscale 9 -flags +mv4+aic -data_partitioning 1 -trellis 1 -mbd bits -ps 200 -an -vcodec mpeg4"
-do_video_decoding
-fi
-
-if [ -n "$do_mpeg4_qprd" ]; then
-do_video_encoding mpeg4-qprd.avi "-b 450k -bf 2 -trellis 1 -flags +mv4+mv0 -mpv_flags +qp_rd -cmp 2 -subcmp 2 -mbd rd -an -vcodec mpeg4"
-do_video_decoding
-fi
-
-if [ -n "$do_mpeg4_adap" ]; then
-do_video_encoding mpeg4-adap.avi "-b 550k -bf 2 -flags +mv4+mv0 -trellis 1 -cmp 1 -subcmp 2 -mbd rd -scplx_mask 0.3 -an -vcodec mpeg4"
-do_video_decoding
-fi
-
-if [ -n "$do_mpeg4_qpel" ]; then
-do_video_encoding mpeg4-Q.avi "-qscale 7 -flags +mv4+qpel -mbd 2 -bf 2 -cmp 1 -subcmp 2 -an -vcodec mpeg4"
-do_video_decoding
-fi
-
-if [ -n "$do_mpeg4thread" ] ; then
-do_video_encoding mpeg4-thread.avi "-b 500k -flags +mv4+aic -data_partitioning 1 -trellis 1 -mbd bits -ps 200 -bf 2 -an -vcodec mpeg4 -threads 2 -slices 2"
-do_video_decoding
-fi
-
-if [ -n "$do_error" ] ; then
-do_video_encoding error-mpeg4-adv.avi "-qscale 7 -flags +mv4+aic -data_partitioning 1 -mbd rd -ps 250 -error 10 -an -vcodec mpeg4"
-do_video_decoding
-fi
-
-if [ -n "$do_mpeg4nr" ] ; then
-do_video_encoding mpeg4-nr.avi "-qscale 8 -flags +mv4 -mbd rd -nr 200 -an -vcodec mpeg4"
-do_video_decoding
-fi
-
-if [ -n "$do_mpeg1b" ] ; then
-do_video_encoding mpeg1b.mpg "-qscale 8 -bf 3 -ps 200 -an -vcodec mpeg1video -f mpeg1video"
-do_video_decoding
-fi
-
-if [ -n "$do_mjpeg" ] ; then
-do_video_encoding mjpeg.avi "-qscale 9 -an -vcodec mjpeg -pix_fmt yuvj420p"
-do_video_decoding "" "-pix_fmt yuv420p"
-fi
-
-if [ -n "$do_ljpeg" ] ; then
-do_video_encoding ljpeg.avi "-an -vcodec ljpeg -strict -1"
-do_video_decoding
-fi
-
-if [ -n "$do_jpegls" ] ; then
-do_video_encoding jpegls.avi "-an -vcodec jpegls -vtag MJPG -sws_flags neighbor+full_chroma_int+accurate_rnd+bitexact"
-do_video_decoding "" "-pix_fmt yuv420p -sws_flags area+bitexact"
-fi
-
-if [ -n "$do_rv10" ] ; then
-do_video_encoding rv10.rm "-qscale 10 -an"
-do_video_decoding
-fi
-
-if [ -n "$do_rv20" ] ; then
-do_video_encoding rv20.rm "-qscale 10 -vcodec rv20 -an"
-do_video_decoding
-fi
-
-if [ -n "$do_asv1" ] ; then
-do_video_encoding asv1.avi "-qscale 10 -an -vcodec asv1"
-do_video_decoding
-fi
-
-if [ -n "$do_asv2" ] ; then
-do_video_encoding asv2.avi "-qscale 10 -an -vcodec asv2"
-do_video_decoding
-fi
-
-if [ -n "$do_flv" ] ; then
-do_video_encoding flv.flv "-qscale 10 -an -vcodec flv"
-do_video_decoding
-fi
-
-if [ -n "$do_ffv1" ] ; then
-do_video_encoding ffv1.avi "-strict -2 -an -vcodec ffv1"
-do_video_decoding
-fi
-
-if [ -n "$do_ffvhuff" ] ; then
-do_video_encoding ffvhuff.avi "-an -vcodec ffvhuff"
-do_video_decoding ""
-fi
-
-if [ -n "$do_snow" ] ; then
-do_video_encoding snow.avi "-strict -2 -an -vcodec snow -qscale 2 -flags +qpel -me_method iter -dia_size 2 -cmp 12 -subcmp 12 -s 128x64"
-do_video_decoding "" "-s 352x288"
-fi
-
-if [ -n "$do_snowll" ] ; then
-do_video_encoding snow53.avi "-strict -2 -an -vcodec snow -qscale .001 -pred 1 -flags +mv4+qpel"
-do_video_decoding
-fi
-
-if [ -n "$do_dv" ] ; then
-do_video_encoding dv.dv "-dct int -s pal -an"
-do_video_decoding "" "-s cif"
-fi
-
-if [ -n "$do_dv_411" ]; then
-do_video_encoding dv411.dv "-dct int -s pal -an -pix_fmt yuv411p -sws_flags area+accurate_rnd+bitexact"
-do_video_decoding "" "-s cif -sws_flags area+accurate_rnd+bitexact"
-fi
-
-if [ -n "$do_dv50" ] ; then
-do_video_encoding dv50.dv "-dct int -s pal -pix_fmt yuv422p -an -sws_flags neighbor+bitexact"
-do_video_decoding "" "-s cif -pix_fmt yuv420p -sws_flags neighbor+bitexact"
-fi
-
-if [ -n "$do_dnxhd_1080i" ] ; then
-# FIXME: interlaced raw DNxHD decoding is broken
-do_video_encoding dnxhd-1080i.mov "-vcodec dnxhd -flags +ildct -s hd1080 -b 120M -pix_fmt yuv422p -vframes 5 -an"
-do_video_decoding "" "-s cif -pix_fmt yuv420p"
-fi
-
-if [ -n "$do_dnxhd_720p" ] ; then
-do_video_encoding dnxhd-720p.dnxhd "-s hd720 -b 90M -pix_fmt yuv422p -vframes 5 -an"
-do_video_decoding "" "-s cif -pix_fmt yuv420p"
-fi
-
-if [ -n "$do_dnxhd_720p_rd" ] ; then
-do_video_encoding dnxhd-720p-rd.dnxhd "-threads 4 -mbd rd -s hd720 -b 90M -pix_fmt yuv422p -vframes 5 -an"
-do_video_decoding "" "-s cif -pix_fmt yuv420p"
-fi
-
-if [ -n "$do_dnxhd_720p_10bit" ] ; then
-do_video_encoding dnxhd-720p-10bit.dnxhd "-s hd720 -b 90M -pix_fmt yuv422p10 -vframes 5 -an"
-do_video_decoding "" "-s cif -pix_fmt yuv420p"
-fi
-
-if [ -n "$do_prores" ] ; then
-do_video_encoding prores.mov "-vcodec prores -profile hq"
-do_video_decoding "" "-pix_fmt yuv420p"
-fi
-
-if [ -n "$do_svq1" ] ; then
-do_video_encoding svq1.mov "-an -vcodec svq1 -qscale 3 -pix_fmt yuv410p"
-do_video_decoding "" "-pix_fmt yuv420p"
-fi
-
-if [ -n "$do_flashsv" ] ; then
-do_video_encoding flashsv.flv "-an -vcodec flashsv -sws_flags neighbor+full_chroma_int+accurate_rnd+bitexact"
-do_video_decoding "" "-pix_fmt yuv420p -sws_flags area+accurate_rnd+bitexact"
-fi
-
-if [ -n "$do_roq" ] ; then
-do_video_encoding roqav.roq "-vframes 5"
-do_video_decoding "" "-pix_fmt yuv420p"
-fi
-
-if [ -n "$do_qtrle" ] ; then
-do_video_encoding qtrle.mov "-an -vcodec qtrle"
-do_video_decoding "" "-pix_fmt yuv420p"
-fi
-
-if [ -n "$do_rgb" ] ; then
-do_video_encoding rgb.avi "-an -vcodec rawvideo -pix_fmt bgr24"
-do_video_decoding "" "-pix_fmt yuv420p"
-fi
-
-if [ -n "$do_v210" ] ; then
-do_video_encoding v210.avi "-an -c:v v210"
-do_video_decoding "" "-pix_fmt yuv420p"
-fi
-
-if [ -n "$do_yuv" ] ; then
-do_video_encoding yuv.avi "-an -vcodec rawvideo -pix_fmt yuv420p"
-do_video_decoding "" "-pix_fmt yuv420p"
-fi
-
-if [ -n "$do_mp2" ] ; then
-do_audio_encoding mp2.mp2
-do_audio_decoding
-$tiny_psnr $pcm_dst $pcm_ref 2 1924
-fi
-
-if [ -n "$do_ac3_fixed" ] ; then
-do_audio_encoding ac3.ac3 "-vn -acodec ac3_fixed"
-# binaries configured with --disable-sse decode ac3 differently
-#do_audio_decoding
-#$tiny_psnr $pcm_dst $pcm_ref 2 1024
-fi
-
-if [ -n "$do_adpcm_adx" ] ; then
-do_audio_encoding adpcm_adx.adx "-acodec adpcm_adx"
-do_audio_decoding
-fi
-
-if [ -n "$do_adpcm_ima_wav" ] ; then
-do_audio_encoding adpcm_ima.wav "-acodec adpcm_ima_wav"
-do_audio_decoding
-fi
-
-if [ -n "$do_adpcm_ima_qt" ] ; then
-do_audio_encoding adpcm_qt.aiff "-acodec adpcm_ima_qt"
-do_audio_decoding
-fi
-
-if [ -n "$do_adpcm_ms" ] ; then
-do_audio_encoding adpcm_ms.wav "-acodec adpcm_ms"
-do_audio_decoding
-fi
-
-if [ -n "$do_adpcm_yam" ] ; then
-do_audio_encoding adpcm_yam.wav "-acodec adpcm_yamaha"
-do_audio_decoding
-fi
-
-if [ -n "$do_adpcm_swf" ] ; then
-do_audio_encoding adpcm_swf.flv "-acodec adpcm_swf"
-do_audio_decoding
-fi
-
-if [ -n "$do_alac" ] ; then
-do_audio_encoding alac.m4a "-acodec alac -compression_level 1"
-do_audio_decoding
-fi
-
-if [ -n "$do_flac" ] ; then
-do_audio_encoding flac.flac "-acodec flac -compression_level 2"
-do_audio_decoding
-fi
-
-#if [ -n "$do_vorbis" ] ; then
-# vorbis
-#disabled because it is broken
-#do_audio_encoding vorbis.asf "-acodec vorbis"
-#do_audio_decoding
-#fi
-
-do_audio_enc_dec() {
- do_audio_encoding $3.$1 "$4 -sample_fmt $2 -acodec $3"
- do_audio_decoding
-}
-
-if [ -n "$do_pcm_alaw" ] ; then
-do_audio_enc_dec wav s16 pcm_alaw
-fi
-if [ -n "$do_pcm_mulaw" ] ; then
-do_audio_enc_dec wav s16 pcm_mulaw
-fi
-if [ -n "$do_pcm_s8" ] ; then
-do_audio_enc_dec mov u8 pcm_s8
-fi
-if [ -n "$do_pcm_u8" ] ; then
-do_audio_enc_dec wav u8 pcm_u8
-fi
-if [ -n "$do_pcm_s16be" ] ; then
-do_audio_enc_dec mov s16 pcm_s16be
-fi
-if [ -n "$do_pcm_s16le" ] ; then
-do_audio_enc_dec wav s16 pcm_s16le
-fi
-if [ -n "$do_pcm_s24be" ] ; then
-do_audio_enc_dec mov s32 pcm_s24be
-fi
-if [ -n "$do_pcm_s24le" ] ; then
-do_audio_enc_dec wav s32 pcm_s24le
-fi
-# no compatible muxer or demuxer
-# if [ -n "$do_pcm_u24be" ] ; then
-# do_audio_enc_dec ??? u32 pcm_u24be
-# fi
-# if [ -n "$do_pcm_u24le" ] ; then
-# do_audio_enc_dec ??? u32 pcm_u24le
-# fi
-if [ -n "$do_pcm_s32be" ] ; then
-do_audio_enc_dec mov s32 pcm_s32be
-fi
-if [ -n "$do_pcm_s32le" ] ; then
-do_audio_enc_dec wav s32 pcm_s32le
-fi
-# no compatible muxer or demuxer
-# if [ -n "$do_pcm_u32be" ] ; then
-# do_audio_enc_dec ??? u32 pcm_u32be
-# fi
-# if [ -n "$do_pcm_u32le" ] ; then
-# do_audio_enc_dec ??? u32 pcm_u32le
-# fi
-if [ -n "$do_pcm_f32be" ] ; then
-do_audio_enc_dec au flt pcm_f32be
-fi
-if [ -n "$do_pcm_f32le" ] ; then
-do_audio_enc_dec wav flt pcm_f32le
-fi
-if [ -n "$do_pcm_f64be" ] ; then
-do_audio_enc_dec au dbl pcm_f64be
-fi
-if [ -n "$do_pcm_f64le" ] ; then
-do_audio_enc_dec wav dbl pcm_f64le
-fi
diff --git a/tests/fate-run.sh b/tests/fate-run.sh
index f7a7aba..5d3ba4d 100755
--- a/tests/fate-run.sh
+++ b/tests/fate-run.sh
@@ -21,6 +21,7 @@ cpuflags=${11:-all}
cmp_shift=${12:-0}
cmp_target=${13:-0}
size_tolerance=${14:-0}
+cmp_unit=${15:-2}
outdir="tests/data/fate"
outfile="${outdir}/${test}"
@@ -40,7 +41,7 @@ compare(){
}
do_tiny_psnr(){
- psnr=$(tests/tiny_psnr "$1" "$2" 2 $cmp_shift 0)
+ psnr=$(tests/tiny_psnr "$1" "$2" $cmp_unit $cmp_shift 0)
val=$(expr "$psnr" : ".*$3: *\([0-9.]*\)")
size1=$(expr "$psnr" : '.*bytes: *\([0-9]*\)')
size2=$(expr "$psnr" : '.*bytes:[ 0-9]*/ *\([0-9]*\)')
@@ -60,11 +61,19 @@ stddev(){
do_tiny_psnr "$1" "$2" stddev
}
+oneline(){
+ printf '%s\n' "$1" | diff -u -b - "$2"
+}
+
run(){
test "${V:-0}" -gt 0 && echo "$target_exec" $target_path/"$@" >&3
$target_exec $target_path/"$@"
}
+probefmt(){
+ run avprobe -show_format_entry format_name -v 0 "$@"
+}
+
avconv(){
run avconv -nostats -threads $threads -thread_type $thread_type -cpuflags $cpuflags "$@"
}
@@ -102,16 +111,40 @@ enc_dec_pcm(){
avconv -f $out_fmt -i ${encfile} -c:a pcm_${pcm_fmt} -f ${dec_fmt} -
}
+FLAGS="-flags +bitexact -sws_flags +accurate_rnd+bitexact"
+DEC_OPTS="-threads $threads -idct simple $FLAGS"
+ENC_OPTS="-threads 1 -idct simple -dct fastint"
+
+enc_dec(){
+ src_fmt=$1
+ srcfile=$2
+ enc_fmt=$3
+ enc_opt=$4
+ dec_fmt=$5
+ dec_opt=$6
+ encfile="${outdir}/${test}.${enc_fmt}"
+ decfile="${outdir}/${test}.out.${dec_fmt}"
+ cleanfiles="$cleanfiles $decfile"
+ test "$7" = -keep || cleanfiles="$cleanfiles $encfile"
+ tsrcfile=$(target_path $srcfile)
+ tencfile=$(target_path $encfile)
+ tdecfile=$(target_path $decfile)
+ avconv -f $src_fmt $DEC_OPTS -i $tsrcfile $ENC_OPTS $enc_opt $FLAGS \
+ -f $enc_fmt -y $tencfile || return
+ do_md5sum $encfile
+ echo $(wc -c $encfile)
+ avconv $DEC_OPTS -i $tencfile $ENC_OPTS $dec_opt $FLAGS \
+ -f $dec_fmt -y $tdecfile || return
+ do_md5sum $decfile
+ tests/tiny_psnr $srcfile $decfile $cmp_unit $cmp_shift
+}
+
regtest(){
t="${test#$2-}"
ref=${base}/ref/$2/$t
${base}/${1}-regression.sh $t $2 $3 "$target_exec" "$target_path" "$threads" "$thread_type" "$cpuflags"
}
-codectest(){
- regtest codec $1 tests/$1
-}
-
lavftest(){
regtest lavf lavf tests/vsynth1
}
@@ -127,10 +160,10 @@ seektest(){
case $t in
image_*) file="tests/data/images/${t#image_}/%02d.${t#image_}" ;;
*) file=$(echo $t | tr _ '?')
- for d in acodec vsynth2 lavf; do
- test -f tests/data/$d/$file && break
+ for d in fate/acodec- fate/vsynth2- lavf/; do
+ test -f tests/data/$d$file && break
done
- file=$(echo tests/data/$d/$file)
+ file=$(echo tests/data/$d$file)
;;
esac
run libavformat/seek-test $target_path/$file
@@ -139,7 +172,7 @@ seektest(){
mkdir -p "$outdir"
exec 3>&2
-$command > "$outfile" 2>$errfile
+eval $command >"$outfile" 2>$errfile
err=$?
if [ $err -gt 128 ]; then
@@ -147,11 +180,12 @@ if [ $err -gt 128 ]; then
test "${sig}" = "${sig%[!A-Za-z]*}" || unset sig
fi
-if test -e "$ref"; then
+if test -e "$ref" || test $cmp = "oneline" ; then
case $cmp in
- diff) diff -u -w "$ref" "$outfile" >$cmpfile ;;
+ diff) diff -u -b "$ref" "$outfile" >$cmpfile ;;
oneoff) oneoff "$ref" "$outfile" >$cmpfile ;;
stddev) stddev "$ref" "$outfile" >$cmpfile ;;
+ oneline)oneline "$ref" "$outfile" >$cmpfile ;;
null) cat "$outfile" >$cmpfile ;;
esac
cmperr=$?
diff --git a/tests/fate/aac.mak b/tests/fate/aac.mak
index 1975e9e..9d52dae 100644
--- a/tests/fate/aac.mak
+++ b/tests/fate/aac.mak
@@ -71,7 +71,7 @@ FATE_AAC_CT = sbr_bc-ps_i.3gp \
FATE_AAC += $(FATE_AAC_CT:%=fate-aac-ct-%)
-FATE_TESTS += $(FATE_AAC)
+FATE_SAMPLES_AVCONV += $(FATE_AAC)
fate-aac: $(FATE_AAC)
$(FATE_AAC): CMP = oneoff
$(FATE_AAC): FUZZ = 2
diff --git a/tests/fate/ac3.mak b/tests/fate/ac3.mak
index ca0704d..6abda80 100644
--- a/tests/fate/ac3.mak
+++ b/tests/fate/ac3.mak
@@ -35,6 +35,7 @@ fate-ac3-encode: REF = $(SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav
fate-ac3-encode: CMP_SHIFT = -1024
fate-ac3-encode: CMP_TARGET = 399.62
fate-ac3-encode: SIZE_TOLERANCE = 488
+fate-ac3-encode: FUZZ = 3
FATE_AC3 += fate-eac3-encode
fate-eac3-encode: CMD = enc_dec_pcm eac3 wav s16le $(REF) -c:a eac3 -b:a 128k
@@ -43,6 +44,14 @@ fate-eac3-encode: REF = $(SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav
fate-eac3-encode: CMP_SHIFT = -1024
fate-eac3-encode: CMP_TARGET = 514.02
fate-eac3-encode: SIZE_TOLERANCE = 488
+fate-eac3-encode: FUZZ = 3
-FATE_TESTS += $(FATE_AC3)
+FATE_AC3 += fate-ac3-fixed-encode
+fate-ac3-fixed-encode: tests/data/asynth-44100-2.wav
+fate-ac3-fixed-encode: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav
+fate-ac3-fixed-encode: CMD = md5 -i $(SRC) -c ac3_fixed -b 128k -f ac3 -flags bitexact
+fate-ac3-fixed-encode: CMP = oneline
+fate-ac3-fixed-encode: REF = a1d1fc116463b771abf5aef7ed37d7b1
+
+FATE_SAMPLES_AVCONV += $(FATE_AC3)
fate-ac3: $(FATE_AC3)
diff --git a/tests/fate/acodec.mak b/tests/fate/acodec.mak
new file mode 100644
index 0000000..b4d0cea
--- /dev/null
+++ b/tests/fate/acodec.mak
@@ -0,0 +1,50 @@
+fate-acodec-%: CODEC = $(@:fate-acodec-%=%)
+fate-acodec-%: SRC = tests/data/asynth-44100-2.wav
+fate-acodec-%: CMD = enc_dec wav $(SRC) $(FMT) "-b 128k -c $(CODEC)" wav "-c pcm_s16le" -keep
+fate-acodec-%: CMP_UNIT = 2
+
+FATE_ACODEC_PCM = alaw mulaw \
+ s8 u8 \
+ s16be s16le \
+ s24be s24le \
+ s32be s32le \
+ f32be f32le \
+ f64be f64le
+
+FATE_ACODEC += $(FATE_ACODEC_PCM:%=fate-acodec-pcm-%)
+
+fate-acodec-pcm-%: FMT = wav
+fate-acodec-pcm-%: CODEC = pcm_$(@:fate-acodec-pcm-%=%)
+
+fate-acodec-pcm-s8: FMT = mov
+fate-acodec-pcm-s%be: FMT = mov
+fate-acodec-pcm-f%be: FMT = au
+
+FATE_ACODEC_ADPCM = adx ima_qt ima_wav ms swf yamaha
+FATE_ACODEC += $(FATE_ACODEC_ADPCM:%=fate-acodec-adpcm-%)
+
+fate-acodec-adpcm-%: CODEC = adpcm_$(@:fate-acodec-adpcm-%=%)
+
+fate-acodec-adpcm-adx: FMT = adx
+fate-acodec-adpcm-ima_qt: FMT = aiff
+fate-acodec-adpcm-ima_wav: FMT = wav
+fate-acodec-adpcm-ms: FMT = wav
+fate-acodec-adpcm-swf: FMT = flv
+fate-acodec-adpcm-yamaha: FMT = wav
+
+FATE_ACODEC += fate-acodec-mp2
+fate-acodec-mp2: FMT = mp2
+fate-acodec-mp2: CMP_SHIFT = -1924
+
+FATE_ACODEC += fate-acodec-alac
+fate-acodec-alac: FMT = mov
+fate-acodec-alac: CODEC = alac -compression_level 1
+
+FATE_ACODEC += fate-acodec-flac
+fate-acodec-flac: FMT = flac
+fate-acodec-flac: CODEC = flac -compression_level 2
+
+$(FATE_ACODEC): tests/data/asynth-44100-2.wav
+
+FATE_AVCONV += $(FATE_ACODEC)
+fate-acodec: $(FATE_ACODEC)
diff --git a/tests/fate/adpcm.mak b/tests/fate/adpcm.mak
index 5e41d6e..4205168 100644
--- a/tests/fate/adpcm.mak
+++ b/tests/fate/adpcm.mak
@@ -16,14 +16,23 @@ fate-adpcm-creative-8-2.6bit: CMD = md5 -i $(SAMPLES)/creative/BBC_3BIT.VOC -f s
FATE_ADPCM += fate-adpcm-creative-8-4bit
fate-adpcm-creative-8-4bit: CMD = md5 -i $(SAMPLES)/creative/BBC_4BIT.VOC -f s16le
-FATE_ADPCM += fate-adpcm-ea-mad-ea-r1
-fate-adpcm-ea-mad-ea-r1: CMD = framecrc -i $(SAMPLES)/ea-mad/NFS6LogoE.mad
+FATE_ADPCM += fate-adpcm-ea-1
+fate-adpcm-ea-1: CMD = framecrc -i $(SAMPLES)/ea-wve/networkBackbone-partial.wve -frames:a 26 -vn
+
+FATE_ADPCM += fate-adpcm-ea-2
+fate-adpcm-ea-2: CMD = framecrc -i $(SAMPLES)/ea-dct/NFS2Esprit-partial.dct -vn
FATE_ADPCM += fate-adpcm-ea-maxis-xa
fate-adpcm-ea-maxis-xa: CMD = framecrc -i $(SAMPLES)/maxis-xa/SC2KBUG.XA -frames:a 30
-FATE_ADPCM += fate-adpcm-ea-tqi
-fate-adpcm-ea-tqi: CMD = framecrc -i $(SAMPLES)/ea-wve/networkBackbone-partial.wve -frames:v 26
+FATE_ADPCM += fate-adpcm-ea-r1
+fate-adpcm-ea-r1: CMD = framecrc -i $(SAMPLES)/ea-mad/NFS6LogoE.mad -vn
+
+FATE_ADPCM += fate-adpcm-ima-amv
+fate-adpcm-ima-amv: CMD = framecrc -i $(SAMPLES)/amv/MTV_high_res_320x240_sample_Penguin_Joke_MTV_from_WMV.amv -t 10 -vn
+
+FATE_ADPCM += fate-adpcm-ima-apc
+fate-adpcm-ima-apc: CMD = md5 -i $(SAMPLES)/cryo-apc/cine007.APC -f s16le
FATE_ADPCM += fate-adpcm-ima-dk3
fate-adpcm-ima-dk3: CMD = md5 -i $(SAMPLES)/duck/sop-audio-only.avi -f s16le
@@ -31,17 +40,35 @@ fate-adpcm-ima-dk3: CMD = md5 -i $(SAMPLES)/duck/sop-audio-only.avi -f s16le
FATE_ADPCM += fate-adpcm-ima-dk4
fate-adpcm-ima-dk4: CMD = md5 -i $(SAMPLES)/duck/salsa-audio-only.avi -f s16le
+FATE_ADPCM += fate-adpcm-ima-ea-eacs
+fate-adpcm-ima-ea-eacs: CMD = framecrc -i $(SAMPLES)/ea-tgv/INTRO8K-partial.TGV -vn
+
+FATE_ADPCM += fate-adpcm-ima-ea-sead
+fate-adpcm-ima-ea-sead: CMD = framecrc -i $(SAMPLES)/ea-tgv/INTEL_S.TGV -vn
+
+FATE_ADPCM += fate-adpcm-ima-iss
+fate-adpcm-ima-iss: CMD = md5 -i $(SAMPLES)/funcom-iss/0004010100.iss -f s16le
+
+FATE_ADPCM += fate-adpcm-ima-smjpeg
+fate-adpcm-ima-smjpeg: CMD = framecrc -i $(SAMPLES)/smjpeg/scenwin.mjpg -vn
+
FATE_ADPCM += fate-adpcm-ima_wav-stereo
fate-adpcm-ima_wav-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-L-ms11.mov -f s16le
-FATE_ADPCM += fate-adpcm-psx-str-v3
-fate-adpcm-psx-str-v3: CMD = framecrc -i $(SAMPLES)/psx-str/abc000_cut.str -vn
+FATE_ADPCM += fate-adpcm-ima-ws
+fate-adpcm-ima-ws: CMD = framecrc -i $(SAMPLES)/vqa/cc-demo1-partial.vqa -vn
+
+FATE_ADPCM += fate-adpcm-ms-mono
+fate-adpcm-ms-mono: CMD = framecrc -i $(SAMPLES)/dxa/meetsquid.dxa -t 2 -vn
FATE_ADPCM += fate-adpcm-thp
-fate-adpcm-thp: CMD = framecrc -idct simple -i $(SAMPLES)/thp/pikmin2-opening1-partial.thp
+fate-adpcm-thp: CMD = framecrc -i $(SAMPLES)/thp/pikmin2-opening1-partial.thp -vn
+
+FATE_ADPCM += fate-adpcm-xa
+fate-adpcm-xa: CMD = framecrc -i $(SAMPLES)/psx-str/abc000_cut.str -vn
FATE_ADPCM += fate-adpcm_ms-stereo
fate-adpcm_ms-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-L-ms02.mov -f s16le
-FATE_TESTS += $(FATE_ADPCM)
+FATE_SAMPLES_AVCONV += $(FATE_ADPCM)
fate-adpcm: $(FATE_ADPCM)
diff --git a/tests/fate/als.mak b/tests/fate/als.mak
index 2674034..ab3e1c0 100644
--- a/tests/fate/als.mak
+++ b/tests/fate/als.mak
@@ -7,5 +7,5 @@ endef
$(foreach N,$(ALS_SUITE),$(eval $(call FATE_ALS_SUITE,$(N))))
-FATE_TESTS += $(FATE_ALS)
+FATE_SAMPLES_AVCONV += $(FATE_ALS)
fate-als: $(FATE_ALS)
diff --git a/tests/fate/amrnb.mak b/tests/fate/amrnb.mak
index 3545ba8..1fe1381 100644
--- a/tests/fate/amrnb.mak
+++ b/tests/fate/amrnb.mak
@@ -46,5 +46,5 @@ fate-amrnb-12k2: CMP = stddev
fate-amrnb-12k2: REF = $(SAMPLES)/amrnb/12.2k.pcm
fate-amrnb-12k2: FUZZ = 1
-FATE_TESTS += $(FATE_AMRNB)
+FATE_SAMPLES_AVCONV += $(FATE_AMRNB)
fate-amrnb: $(FATE_AMRNB)
diff --git a/tests/fate/amrwb.mak b/tests/fate/amrwb.mak
index 8fc7928..571fac0 100644
--- a/tests/fate/amrwb.mak
+++ b/tests/fate/amrwb.mak
@@ -58,5 +58,5 @@ fate-amrwb-23k85-2: CMP = stddev
fate-amrwb-23k85-2: REF = $(SAMPLES)/amrwb/deus-23k85.pcm
fate-amrwb-23k85-2: FUZZ = 1
-FATE_TESTS += $(FATE_AMRWB)
+FATE_SAMPLES_AVCONV += $(FATE_AMRWB)
fate-amrwb: $(FATE_AMRWB)
diff --git a/tests/fate/atrac.mak b/tests/fate/atrac.mak
index efb1727..3897311 100644
--- a/tests/fate/atrac.mak
+++ b/tests/fate/atrac.mak
@@ -18,5 +18,5 @@ fate-atrac3-3: CMD = pcm -i $(SAMPLES)/atrac3/mc_sich_at3_132_small.wav
fate-atrac3-3: CMP = oneoff
fate-atrac3-3: REF = $(SAMPLES)/atrac3/mc_sich_at3_132_small.pcm
-FATE_TESTS += $(FATE_ATRAC)
+FATE_SAMPLES_AVCONV += $(FATE_ATRAC)
fate-atrac: $(FATE_ATRAC)
diff --git a/tests/fate/audio.mak b/tests/fate/audio.mak
index 32bf757..3109adc 100644
--- a/tests/fate/audio.mak
+++ b/tests/fate/audio.mak
@@ -10,23 +10,35 @@ fate-binkaudio-rdft: CMP = oneoff
fate-binkaudio-rdft: REF = $(SAMPLES)/bink/binkaudio_rdft.pcm
fate-binkaudio-rdft: FUZZ = 2
-FATE_TESTS += $(FATE_BINKAUDIO)
+FATE_SAMPLES_AVCONV += $(FATE_BINKAUDIO)
fate-binkaudio: $(FATE_BINKAUDIO)
-FATE_TESTS += fate-dts
+FATE_SAMPLES_AVCONV += fate-bmv-audio
+fate-bmv-audio: CMD = framecrc -i $(SAMPLES)/bmv/SURFING-partial.BMV -vn
+
+FATE_SAMPLES_AVCONV += fate-delphine-cin-audio
+fate-delphine-cin-audio: CMD = framecrc -i $(SAMPLES)/delphine-cin/LOGO-partial.CIN -vn
+
+FATE_SAMPLES_AVCONV += fate-dts
fate-dts: CMD = pcm -i $(SAMPLES)/dts/dts.ts
fate-dts: CMP = oneoff
fate-dts: REF = $(SAMPLES)/dts/dts.pcm
-FATE_TESTS += fate-imc
+FATE_SAMPLES_AVCONV += fate-imc
fate-imc: CMD = pcm -i $(SAMPLES)/imc/imc.avi
fate-imc: CMP = oneoff
fate-imc: REF = $(SAMPLES)/imc/imc.pcm
-FATE_TESTS += fate-nellymoser
+FATE_SAMPLES_AVCONV += fate-nellymoser
fate-nellymoser: CMD = pcm -i $(SAMPLES)/nellymoser/nellymoser.flv
fate-nellymoser: CMP = oneoff
fate-nellymoser: REF = $(SAMPLES)/nellymoser/nellymoser.pcm
-FATE_TESTS += fate-ws_snd
+FATE_SAMPLES_AVCONV += fate-sierra-vmd-audio
+fate-sierra-vmd-audio: CMD = framecrc -i $(SAMPLES)/vmd/12.vmd -vn
+
+FATE_SAMPLES_AVCONV += fate-smacker-audio
+fate-smacker-audio: CMD = framecrc -i $(SAMPLES)/smacker/wetlogo.smk -vn
+
+FATE_SAMPLES_AVCONV += fate-ws_snd
fate-ws_snd: CMD = md5 -i $(SAMPLES)/vqa/ws_snd.vqa -f s16le
diff --git a/tests/fate/bmp.mak b/tests/fate/bmp.mak
index 56b5059..c660190 100644
--- a/tests/fate/bmp.mak
+++ b/tests/fate/bmp.mak
@@ -37,5 +37,5 @@ fate-bmp-rle4: CMD = framecrc -i $(SAMPLES)/bmp/testcompress4.bmp -pix_fmt rgb24
FATE_BMP += fate-bmp-rle8
fate-bmp-rle8: CMD = framecrc -i $(SAMPLES)/bmp/testcompress8.bmp -pix_fmt rgb24
-FATE_TESTS += $(FATE_BMP)
+FATE_SAMPLES_AVCONV += $(FATE_BMP)
fate-bmp: $(FATE_BMP)
diff --git a/tests/fate/cdxl.mak b/tests/fate/cdxl.mak
index 3a46c5c..86eaa09 100644
--- a/tests/fate/cdxl.mak
+++ b/tests/fate/cdxl.mak
@@ -13,5 +13,5 @@ fate-cdxl-pal8-small: CMD = framecrc -i $(SAMPLES)/cdxl/fruit.cdxl -an -pix_fmt
FATE_CDXL += fate-cdxl-bitline-ham6
fate-cdxl-bitline-ham6: CMD = framecrc -i $(SAMPLES)/cdxl/bitline.cdxl -frames:v 10
-FATE_TESTS += $(FATE_CDXL)
+FATE_SAMPLES_AVCONV += $(FATE_CDXL)
fate-cdxl: $(FATE_CDXL)
diff --git a/tests/fate/cover-art.mak b/tests/fate/cover-art.mak
new file mode 100644
index 0000000..f35e9bb
--- /dev/null
+++ b/tests/fate/cover-art.mak
@@ -0,0 +1,19 @@
+FATE_COVER_ART += fate-cover-art-ape
+fate-cover-art-ape: CMD = md5 -i $(SAMPLES)/cover_art/luckynight_cover.ape -an -c:v copy -f rawvideo
+fate-cover-art-ape: REF = 45333c983c45af54449dff10af144317
+
+FATE_COVER_ART += fate-cover-art-m4a
+fate-cover-art-m4a: CMD = md5 -i $(SAMPLES)/cover_art/Owner-iTunes_9.0.3.15.m4a -an -c:v copy -f rawvideo
+fate-cover-art-m4a: REF = 08ba70a3b594ff6345a93965e96a9d3e
+
+FATE_COVER_ART += fate-cover-art-wma
+fate-cover-art-wma: CMD = md5 -i $(SAMPLES)/cover_art/Californication_cover.wma -an -c:v copy -f rawvideo
+fate-cover-art-wma: REF = 0808bd0e1b61542a16e1906812dd924b
+
+FATE_COVER_ART += fate-cover-art-wv
+fate-cover-art-wv: CMD = md5 -i $(SAMPLES)/cover_art/luckynight_cover.wv -an -c:v copy -f rawvideo
+fate-cover-art-wv: REF = 45333c983c45af54449dff10af144317
+
+$(FATE_COVER_ART): CMP = oneline
+FATE_SAMPLES_AVCONV += $(FATE_COVER_ART)
+fate-cover-art: $(FATE_COVER_ART)
diff --git a/tests/fate/dct.mak b/tests/fate/dct.mak
index 8f2ab7a..d79cb91 100644
--- a/tests/fate/dct.mak
+++ b/tests/fate/dct.mak
@@ -1,4 +1,4 @@
-FATE_TESTS += fate-idct8x8
+FATE-yes += fate-idct8x8
fate-idct8x8: libavcodec/dct-test$(EXESUF)
fate-idct8x8: CMD = run libavcodec/dct-test -i
fate-idct8x8: REF = /dev/null
diff --git a/tests/fate/demux.mak b/tests/fate/demux.mak
index 0f83c8d..d9fe629 100644
--- a/tests/fate/demux.mak
+++ b/tests/fate/demux.mak
@@ -1,92 +1,71 @@
-FATE_TESTS += fate-adts-demux
+FATE_SAMPLES_AVCONV += fate-adts-demux
fate-adts-demux: CMD = crc -i $(SAMPLES)/aac/ct_faac-adts.aac -acodec copy
-FATE_TESTS += fate-aea-demux
+FATE_SAMPLES_AVCONV += fate-aea-demux
fate-aea-demux: CMD = crc -i $(SAMPLES)/aea/chirp.aea -acodec copy
-FATE_TESTS += fate-bink-demux
+FATE_SAMPLES_AVCONV += fate-bink-demux
fate-bink-demux: CMD = crc -i $(SAMPLES)/bink/Snd0a7d9b58.dee -vn -acodec copy
-FATE_TESTS += fate-bmv
-fate-bmv: CMD = framecrc -i $(SAMPLES)/bmv/SURFING-partial.BMV -pix_fmt rgb24
+FATE_SAMPLES_AVCONV += fate-caf
+fate-caf: CMD = crc -i $(SAMPLES)/caf/caf-pcm16.caf -c copy
-FATE_TESTS += fate-caf
-fate-caf: CMD = crc -i $(SAMPLES)/caf/caf-pcm16.caf
-
-FATE_TESTS += fate-cdxl-demux
+FATE_SAMPLES_AVCONV += fate-cdxl-demux
fate-cdxl-demux: CMD = framecrc -i $(SAMPLES)/cdxl/mirage.cdxl -vcodec copy -acodec copy
-FATE_TESTS += fate-cryo-apc
-fate-cryo-apc: CMD = md5 -i $(SAMPLES)/cryo-apc/cine007.APC -f s16le
-
-FATE_TESTS += fate-d-cinema-demux
-fate-d-cinema-demux: CMD = framecrc -i $(SAMPLES)/d-cinema/THX_Science_FLT_1920-partial.302 -acodec copy -pix_fmt rgb24
-
-FATE_TESTS += fate-funcom-iss
-fate-funcom-iss: CMD = md5 -i $(SAMPLES)/funcom-iss/0004010100.iss -f s16le
-
-FATE_TESTS += fate-interplay-mve-16bit
-fate-interplay-mve-16bit: CMD = framecrc -i $(SAMPLES)/interplay-mve/descent3-level5-16bit-partial.mve -pix_fmt rgb24
+FATE_SAMPLES_AVCONV += fate-d-cinema-demux
+fate-d-cinema-demux: CMD = framecrc -i $(SAMPLES)/d-cinema/THX_Science_FLT_1920-partial.302 -acodec copy
-FATE_TESTS += fate-interplay-mve-8bit
-fate-interplay-mve-8bit: CMD = framecrc -i $(SAMPLES)/interplay-mve/interplay-logo-2MB.mve -pix_fmt rgb24
-
-FATE_TESTS += fate-iv8-demux
+FATE_SAMPLES_AVCONV += fate-iv8-demux
fate-iv8-demux: CMD = framecrc -i $(SAMPLES)/iv8/zzz-partial.mpg -vcodec copy
-FATE_TESTS += fate-lmlm4-demux
+FATE_SAMPLES_AVCONV += fate-lmlm4-demux
fate-lmlm4-demux: CMD = framecrc -i $(SAMPLES)/lmlm4/LMLM4_CIFat30fps.divx -t 3 -acodec copy -vcodec copy
-FATE_TESTS += fate-maxis-xa
+FATE_SAMPLES_AVCONV += fate-maxis-xa
fate-maxis-xa: CMD = framecrc -i $(SAMPLES)/maxis-xa/SC2KBUG.XA -frames:a 30 -c:a copy
-FATE_TESTS += fate-mtv
-fate-mtv: CMD = framecrc -i $(SAMPLES)/mtv/comedian_auto-partial.mtv -acodec copy -pix_fmt rgb24
+FATE_SAMPLES_AVCONV += fate-mtv
+fate-mtv: CMD = framecrc -i $(SAMPLES)/mtv/comedian_auto-partial.mtv -c copy
-FATE_TESTS += fate-mxf-demux
+FATE_SAMPLES_AVCONV += fate-mxf-demux
fate-mxf-demux: CMD = framecrc -i $(SAMPLES)/mxf/C0023S01.mxf -acodec copy -vcodec copy
-FATE_TESTS += fate-nc-demux
+FATE_SAMPLES_AVCONV += fate-nc-demux
fate-nc-demux: CMD = framecrc -i $(SAMPLES)/nc-camera/nc-sample-partial -vcodec copy
-FATE_TESTS += fate-nsv-demux
+FATE_SAMPLES_AVCONV += fate-nsv-demux
fate-nsv-demux: CMD = framecrc -i $(SAMPLES)/nsv/witchblade-51kbps.nsv -t 6 -vcodec copy -acodec copy
-FATE_TESTS += fate-oma-demux
+FATE_SAMPLES_AVCONV += fate-oma-demux
fate-oma-demux: CMD = crc -i $(SAMPLES)/oma/01-Untitled-partial.oma -acodec copy
-FATE_TESTS += fate-psx-str
-fate-psx-str: CMD = framecrc -i $(SAMPLES)/psx-str/descent-partial.str
-
-FATE_TESTS += fate-psx-str-v3-mdec
-fate-psx-str-v3-mdec: CMD = framecrc -i $(SAMPLES)/psx-str/abc000_cut.str -an
+FATE_SAMPLES_AVCONV += fate-psx-str-demux
+fate-psx-str-demux: CMD = framecrc -i $(SAMPLES)/psx-str/descent-partial.str -c copy
-FATE_TESTS += fate-pva-demux
+FATE_SAMPLES_AVCONV += fate-pva-demux
fate-pva-demux: CMD = framecrc -idct simple -i $(SAMPLES)/pva/PVA_test-partial.pva -t 0.6 -acodec copy -vn
-FATE_TESTS += fate-qcp-demux
+FATE_SAMPLES_AVCONV += fate-qcp-demux
fate-qcp-demux: CMD = crc -i $(SAMPLES)/qcp/0036580847.QCP -acodec copy
-FATE_TESTS += fate-redcode-demux
+FATE_SAMPLES_AVCONV += fate-redcode-demux
fate-redcode-demux: CMD = framecrc -i $(SAMPLES)/r3d/4MB-sample.r3d -vcodec copy -acodec copy
-FATE_TESTS += fate-sierra-vmd
-fate-sierra-vmd: CMD = framecrc -i $(SAMPLES)/vmd/12.vmd -pix_fmt rgb24
-
-FATE_TESTS += fate-siff
+FATE_SAMPLES_AVCONV += fate-siff
fate-siff: CMD = framecrc -i $(SAMPLES)/SIFF/INTRO_B.VB -t 3 -pix_fmt rgb24
-FATE_TESTS += fate-smjpeg
-fate-smjpeg: CMD = framecrc -i $(SAMPLES)/smjpeg/scenwin.mjpg -vcodec copy
+FATE_SAMPLES_AVCONV += fate-smjpeg-demux
+fate-smjpeg-demux: CMD = framecrc -i $(SAMPLES)/smjpeg/scenwin.mjpg -c copy
-FATE_TESTS += fate-westwood-aud
-fate-westwood-aud: CMD = md5 -i $(SAMPLES)/westwood-aud/excellent.aud -f s16le
+FATE_SAMPLES_AVCONV += fate-westwood-aud
+fate-westwood-aud: CMD = framecrc -i $(SAMPLES)/westwood-aud/excellent.aud -c copy
-FATE_TESTS += fate-wtv-demux
+FATE_SAMPLES_AVCONV += fate-wtv-demux
fate-wtv-demux: CMD = framecrc -i $(SAMPLES)/wtv/law-and-order-partial.wtv -vcodec copy -acodec copy
-FATE_TESTS += fate-xmv-demux
+FATE_SAMPLES_AVCONV += fate-xmv-demux
fate-xmv-demux: CMD = framecrc -i $(SAMPLES)/xmv/logos1p.fmv -vcodec copy -acodec copy
-FATE_TESTS += fate-xwma-demux
+FATE_SAMPLES_AVCONV += fate-xwma-demux
fate-xwma-demux: CMD = crc -i $(SAMPLES)/xwma/ergon.xwma -acodec copy
diff --git a/tests/fate/dfa.mak b/tests/fate/dfa.mak
index 6220c07..56f7bfe 100644
--- a/tests/fate/dfa.mak
+++ b/tests/fate/dfa.mak
@@ -31,5 +31,5 @@ fate-dfa10: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0009.dfa -pix_fmt rgb2
FATE_DFA += fate-dfa11
fate-dfa11: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0010.dfa -pix_fmt rgb24
-FATE_TESTS += $(FATE_DFA)
+FATE_SAMPLES_AVCONV += $(FATE_DFA)
fate-dfa: $(FATE_DFA)
diff --git a/tests/fate/dpcm.mak b/tests/fate/dpcm.mak
index a8b8b3d..14e77a2 100644
--- a/tests/fate/dpcm.mak
+++ b/tests/fate/dpcm.mak
@@ -1,5 +1,8 @@
FATE_DPCM += fate-dpcm-idroq
-fate-dpcm-idroq: CMD = framecrc -i $(SAMPLES)/idroq/idlogo.roq
+fate-dpcm-idroq: CMD = framecrc -i $(SAMPLES)/idroq/idlogo.roq -vn
+
+FATE_DPCM += fate-dpcm-interplay
+fate-dpcm-interplay: CMD = framecrc -i $(SAMPLES)/interplay-mve/interplay-logo-2MB.mve -vn
FATE_DPCM += fate-dpcm-sierra
fate-dpcm-sierra: CMD = md5 -i $(SAMPLES)/sol/lsl7sample.sol -f s16le
@@ -7,5 +10,5 @@ fate-dpcm-sierra: CMD = md5 -i $(SAMPLES)/sol/lsl7sample.sol -f s16le
FATE_DPCM += fate-dpcm-xan
fate-dpcm-xan: CMD = md5 -i $(SAMPLES)/wc4-xan/wc4_2.avi -vn -f s16le
-FATE_TESTS += $(FATE_DPCM)
+FATE_SAMPLES_AVCONV += $(FATE_DPCM)
fate-dpcm: $(FATE_DPCM)
diff --git a/tests/fate/ea.mak b/tests/fate/ea.mak
index 0c91de5..59745fa 100644
--- a/tests/fate/ea.mak
+++ b/tests/fate/ea.mak
@@ -1,17 +1,20 @@
-FATE_TESTS += fate-ea-cdata
+FATE_SAMPLES_AVCONV += fate-ea-cdata
fate-ea-cdata: CMD = md5 -i $(SAMPLES)/ea-cdata/166b084d.46410f77.0009b440.24be960c.cdata -f s16le
-FATE_TESTS += fate-ea-cmv
+FATE_SAMPLES_AVCONV += fate-ea-cmv
fate-ea-cmv: CMD = framecrc -i $(SAMPLES)/ea-cmv/TITLE.CMV -pix_fmt rgb24
-FATE_TESTS += fate-ea-dct
-fate-ea-dct: CMD = framecrc -idct simple -i $(SAMPLES)/ea-dct/NFS2Esprit-partial.dct
-
-FATE_TESTS += fate-ea-tgq
+FATE_SAMPLES_AVCONV += fate-ea-tgq
fate-ea-tgq: CMD = framecrc -i $(SAMPLES)/ea-tgq/v27.tgq -an
-FATE_TESTS += fate-ea-tgv-ima-ea-eacs
-fate-ea-tgv-ima-ea-eacs: CMD = framecrc -i $(SAMPLES)/ea-tgv/INTRO8K-partial.TGV -pix_fmt rgb24
+FATE_SAMPLES_AVCONV += fate-ea-tqi
+fate-ea-tqi: CMD = framecrc -i $(SAMPLES)/ea-wve/networkBackbone-partial.wve -frames:v 26 -an
+
+FATE_SAMPLES_AVCONV += fate-ea-mad
+fate-ea-mad: CMD = framecrc -i $(SAMPLES)/ea-mad/NFS6LogoE.mad -an
+
+FATE_SAMPLES_AVCONV += fate-ea-tgv-1
+fate-ea-tgv-1: CMD = framecrc -i $(SAMPLES)/ea-tgv/INTRO8K-partial.TGV -pix_fmt rgb24 -an
-FATE_TESTS += fate-ea-tgv-ima-ea-sead
-fate-ea-tgv-ima-ea-sead: CMD = framecrc -i $(SAMPLES)/ea-tgv/INTEL_S.TGV -pix_fmt rgb24
+FATE_SAMPLES_AVCONV += fate-ea-tgv-2
+fate-ea-tgv-2: CMD = framecrc -i $(SAMPLES)/ea-tgv/INTEL_S.TGV -pix_fmt rgb24 -an
diff --git a/tests/fate/fft.mak b/tests/fate/fft.mak
index d419938..d3889cc 100644
--- a/tests/fate/fft.mak
+++ b/tests/fate/fft.mak
@@ -38,5 +38,5 @@ $(FATE_FFT_FIXED): libavcodec/fft-fixed-test$(EXESUF)
$(FATE_FFT_FIXED): CMD = run libavcodec/fft-fixed-test $(CPUFLAGS:%=-c%) $(ARGS)
$(FATE_FFT_FIXED): REF = /dev/null
-FATE_TESTS += $(FATE_FFT) $(FATE_FFT_FIXED)
+FATE-$(CONFIG_FFT) += $(FATE_FFT) $(FATE_FFT_FIXED)
fate-fft: $(FATE_FFT) $(FATE_FFT_FIXED)
diff --git a/tests/fate/flac.mak b/tests/fate/flac.mak
new file mode 100644
index 0000000..c534059
--- /dev/null
+++ b/tests/fate/flac.mak
@@ -0,0 +1,19 @@
+FATE_FLAC += fate-flac-chmode-indep \
+ fate-flac-chmode-left_side \
+ fate-flac-chmode-mid_side \
+ fate-flac-chmode-right_side \
+ fate-flac-fixed \
+ fate-flac-lpc-cholesky \
+ fate-flac-lpc-levinson \
+
+fate-flac-chmode-%: OPTS = -ch_mode $(@:fate-flac-chmode-%=%)
+fate-flac-fixed: OPTS = -lpc_type fixed
+fate-flac-lpc-%: OPTS = -lpc_type $(@:fate-flac-lpc-%=%)
+
+fate-flac-%: REF = $(SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav
+fate-flac-%: CMD = enc_dec_pcm flac wav s16le $(REF) -c flac $(OPTS)
+fate-flac-%: CMP = oneoff
+fate-flac-%: FUZZ = 0
+
+FATE_AVCONV += $(FATE_FLAC)
+fate-flac: $(FATE_FLAC)
diff --git a/tests/fate/h264.mak b/tests/fate/h264.mak
index 4d77617..8f27995 100644
--- a/tests/fate/h264.mak
+++ b/tests/fate/h264.mak
@@ -177,7 +177,7 @@ FATE_H264 := $(FATE_H264:%=fate-h264-conformance-%) \
fate-h264-extreme-plane-pred \
fate-h264-bsf-mp4toannexb \
-FATE_TESTS += $(FATE_H264)
+FATE_SAMPLES_AVCONV += $(FATE_H264)
fate-h264: $(FATE_H264)
fate-h264-conformance-aud_mw_e: CMD = framecrc -i $(SAMPLES)/h264-conformance/AUD_MW_E.264
diff --git a/tests/fate/image.mak b/tests/fate/image.mak
index dc78302..a6768a0 100644
--- a/tests/fate/image.mak
+++ b/tests/fate/image.mak
@@ -1,10 +1,10 @@
-FATE_TESTS += fate-dpx
+FATE_SAMPLES_AVCONV += fate-dpx
fate-dpx: CMD = framecrc -i $(SAMPLES)/dpx/lighthouse_rgb48.dpx
-FATE_TESTS += fate-pictor
+FATE_SAMPLES_AVCONV += fate-pictor
fate-pictor: CMD = framecrc -i $(SAMPLES)/pictor/MFISH.PIC -pix_fmt rgb24
-FATE_TESTS += fate-ptx
+FATE_SAMPLES_AVCONV += fate-ptx
fate-ptx: CMD = framecrc -i $(SAMPLES)/ptx/_113kw_pic.ptx -pix_fmt rgb24
FATE_SUNRASTER += fate-sunraster-1bit-raw
@@ -28,7 +28,7 @@ fate-sunraster-24bit-raw: CMD = framecrc -i $(SAMPLES)/sunraster/lena-24bit-raw.
FATE_SUNRASTER += fate-sunraster-24bit-rle
fate-sunraster-24bit-rle: CMD = framecrc -i $(SAMPLES)/sunraster/lena-24bit-rle.sun
-FATE_TESTS += $(FATE_SUNRASTER)
+FATE_SAMPLES_AVCONV += $(FATE_SUNRASTER)
fate-sunraster: $(FATE_SUNRASTER)
FATE_TARGA = CBW8 \
@@ -45,7 +45,7 @@ FATE_TARGA = CBW8 \
FATE_TARGA := $(FATE_TARGA:%=fate-targa-conformance-%) \
fate-targa-top-to-bottom
-FATE_TESTS += $(FATE_TARGA)
+FATE_SAMPLES_AVCONV += $(FATE_TARGA)
fate-targa: $(FATE_TARGA)
fate-targa-conformance-CBW8: CMD = framecrc -i $(SAMPLES)/targa-conformance/CBW8.TGA
@@ -67,5 +67,5 @@ fate-tiff-fax-g3: CMD = framecrc -i $(SAMPLES)/CCITT_fax/G31D.TIF
FATE_TIFF += fate-tiff-fax-g3s
fate-tiff-fax-g3s: CMD = framecrc -i $(SAMPLES)/CCITT_fax/G31DS.TIF
-FATE_TESTS += $(FATE_TIFF)
+FATE_SAMPLES_AVCONV += $(FATE_TIFF)
fate-tiff: $(FATE_TIFF)
diff --git a/tests/fate/indeo.mak b/tests/fate/indeo.mak
index cf1625c..783af5d 100644
--- a/tests/fate/indeo.mak
+++ b/tests/fate/indeo.mak
@@ -10,5 +10,5 @@ fate-indeo4: CMD = framecrc -i $(SAMPLES)/iv41/indeo41-partial.avi -an
FATE_INDEO += fate-indeo5
fate-indeo5: CMD = framecrc -i $(SAMPLES)/iv50/Educ_Movie_DeadlyForce.avi -an
-FATE_TESTS += $(FATE_INDEO)
+FATE_SAMPLES_AVCONV += $(FATE_INDEO)
fate-indeo: $(FATE_INDEO)
diff --git a/tests/fate/libavcodec.mak b/tests/fate/libavcodec.mak
index ec4012e..2aa9596 100644
--- a/tests/fate/libavcodec.mak
+++ b/tests/fate/libavcodec.mak
@@ -1,8 +1,10 @@
-FATE_TESTS += fate-golomb
+FATE_LIBAVCODEC += fate-golomb
fate-golomb: libavcodec/golomb-test$(EXESUF)
fate-golomb: CMD = run libavcodec/golomb-test
fate-golomb: REF = /dev/null
-FATE_TESTS += fate-iirfilter
+FATE_LIBAVCODEC += fate-iirfilter
fate-iirfilter: libavcodec/iirfilter-test$(EXESUF)
fate-iirfilter: CMD = run libavcodec/iirfilter-test
+
+fate-libavcodec: $(FATE_LIBAVCODEC)
diff --git a/tests/fate/libavutil.mak b/tests/fate/libavutil.mak
index a65b724..1052b1d 100644
--- a/tests/fate/libavutil.mak
+++ b/tests/fate/libavutil.mak
@@ -1,38 +1,48 @@
-FATE_TESTS += fate-adler32
+FATE_LIBAVUTIL += fate-adler32
fate-adler32: libavutil/adler32-test$(EXESUF)
fate-adler32: CMD = run libavutil/adler32-test
fate-adler32: REF = /dev/null
-FATE_TESTS += fate-aes
+FATE_LIBAVUTIL += fate-aes
fate-aes: libavutil/aes-test$(EXESUF)
fate-aes: CMD = run libavutil/aes-test
fate-aes: REF = /dev/null
-FATE_TESTS += fate-base64
+FATE_LIBAVUTIL += fate-base64
fate-base64: libavutil/base64-test$(EXESUF)
fate-base64: CMD = run libavutil/base64-test
-FATE_TESTS += fate-crc
+FATE_LIBAVUTIL += fate-blowfish
+fate-blowfish: libavutil/blowfish-test$(EXESUF)
+fate-blowfish: CMD = run libavutil/blowfish-test
+
+FATE_LIBAVUTIL += fate-crc
fate-crc: libavutil/crc-test$(EXESUF)
fate-crc: CMD = run libavutil/crc-test
-FATE_TESTS += fate-des
+FATE_LIBAVUTIL += fate-des
fate-des: libavutil/des-test$(EXESUF)
fate-des: CMD = run libavutil/des-test
fate-des: REF = /dev/null
-FATE_TESTS += fate-eval
+FATE_LIBAVUTIL += fate-eval
fate-eval: libavutil/eval-test$(EXESUF)
fate-eval: CMD = run libavutil/eval-test
-FATE_TESTS += fate-fifo
+FATE_LIBAVUTIL += fate-fifo
fate-fifo: libavutil/fifo-test$(EXESUF)
fate-fifo: CMD = run libavutil/fifo-test
-FATE_TESTS += fate-md5
+FATE_LIBAVUTIL += fate-md5
fate-md5: libavutil/md5-test$(EXESUF)
fate-md5: CMD = run libavutil/md5-test
-FATE_TESTS += fate-sha
+FATE_LIBAVUTIL += fate-sha
fate-sha: libavutil/sha-test$(EXESUF)
fate-sha: CMD = run libavutil/sha-test
+
+FATE_LIBAVUTIL += fate-xtea
+fate-xtea: libavutil/xtea-test$(EXESUF)
+fate-xtea: CMD = run libavutil/xtea-test
+
+fate-libavutil: $(FATE_LIBAVUTIL)
diff --git a/tests/fate/lossless-audio.mak b/tests/fate/lossless-audio.mak
index 44d6f09..f0ff496 100644
--- a/tests/fate/lossless-audio.mak
+++ b/tests/fate/lossless-audio.mak
@@ -1,17 +1,17 @@
-FATE_TESTS += fate-lossless-alac
+FATE_SAMPLES_AVCONV += fate-lossless-alac
fate-lossless-alac: CMD = md5 -i $(SAMPLES)/lossless-audio/inside.m4a -f s16le
-FATE_TESTS += fate-lossless-meridianaudio
+FATE_SAMPLES_AVCONV += fate-lossless-meridianaudio
fate-lossless-meridianaudio: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.mlp -f s16le
-FATE_TESTS += fate-lossless-monkeysaudio
+FATE_SAMPLES_AVCONV += fate-lossless-monkeysaudio
fate-lossless-monkeysaudio: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.ape -f s16le
-FATE_TESTS += fate-lossless-shorten
+FATE_SAMPLES_AVCONV += fate-lossless-shorten
fate-lossless-shorten: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.shn -f s16le
-FATE_TESTS += fate-lossless-tta
+FATE_SAMPLES_AVCONV += fate-lossless-tta
fate-lossless-tta: CMD = crc -i $(SAMPLES)/lossless-audio/inside.tta
-FATE_TESTS += fate-lossless-wma
+FATE_SAMPLES_AVCONV += fate-lossless-wma
fate-lossless-wma: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.wma -f s16le
diff --git a/tests/fate/lossless-video.mak b/tests/fate/lossless-video.mak
index e0f097e..4871296 100644
--- a/tests/fate/lossless-video.mak
+++ b/tests/fate/lossless-video.mak
@@ -4,20 +4,20 @@ fate-loco-rgb: CMD = framecrc -i $(SAMPLES)/loco/pig-loco-rgb.avi
FATE_LOCO += fate-loco-yuy2
fate-loco-yuy2: CMD = framecrc -i $(SAMPLES)/loco/pig-loco-0.avi
-FATE_TESTS += $(FATE_LOCO)
+FATE_SAMPLES_AVCONV += $(FATE_LOCO)
fate-loco: $(FATE_LOCO)
-FATE_TESTS += fate-msrle-8bit
+FATE_SAMPLES_AVCONV += fate-msrle-8bit
fate-msrle-8bit: CMD = framecrc -i $(SAMPLES)/msrle/Search-RLE.avi -pix_fmt rgb24
-FATE_TESTS += fate-mszh
+FATE_SAMPLES_AVCONV += fate-mszh
fate-mszh: CMD = framecrc -i $(SAMPLES)/lcl/mszh-1frame.avi
-FATE_TESTS += fate-vble
+FATE_SAMPLES_AVCONV += fate-vble
fate-vble: CMD = framecrc -i $(SAMPLES)/vble/flowers-partial-2MB.avi
-FATE_TESTS += fate-zlib
+FATE_SAMPLES_AVCONV += fate-zlib
fate-zlib: CMD = framecrc -i $(SAMPLES)/lcl/zlib-1frame.avi
-FATE_TESTS += fate-zerocodec
+FATE_SAMPLES_AVCONV += fate-zerocodec
fate-zerocodec: CMD = framecrc -i $(SAMPLES)/zerocodec/sample-zeco.avi
diff --git a/tests/fate/microsoft.mak b/tests/fate/microsoft.mak
index 5bc27b8..515f6ab 100644
--- a/tests/fate/microsoft.mak
+++ b/tests/fate/microsoft.mak
@@ -1,4 +1,4 @@
-FATE_TESTS += fate-msmpeg4v1
+FATE_SAMPLES_AVCONV += fate-msmpeg4v1
fate-msmpeg4v1: CMD = framecrc -flags +bitexact -dct fastint -idct simple -i $(SAMPLES)/msmpeg4v1/mpg4.avi -an
FATE_MSVIDEO1 += fate-msvideo1-16bit
@@ -7,7 +7,7 @@ fate-msvideo1-16bit: CMD = framecrc -i $(SAMPLES)/cram/clock-cram16.avi -pix_fmt
FATE_MSVIDEO1 += fate-msvideo1-8bit
fate-msvideo1-8bit: CMD = framecrc -i $(SAMPLES)/cram/skating.avi -t 1 -pix_fmt rgb24
-FATE_TESTS += $(FATE_MSVIDEO1)
+FATE_SAMPLES_AVCONV += $(FATE_MSVIDEO1)
fate-msvideo1: $(FATE_MSVIDEO1)
FATE_WMV8_DRM += fate-wmv8-drm
@@ -17,7 +17,7 @@ fate-wmv8-drm: CMD = framecrc -cryptokey 137381538c84c068111902a59c5cf6c340247c3
FATE_WMV8_DRM += fate-wmv8-drm-nodec
fate-wmv8-drm-nodec: CMD = framecrc -cryptokey 137381538c84c068111902a59c5cf6c340247c39 -i $(SAMPLES)/wmv8/wmv_drm.wmv -acodec copy -vcodec copy
-FATE_TESTS += $(FATE_WMV8_DRM)
+FATE_SAMPLES_AVCONV += $(FATE_WMV8_DRM)
fate-wmv8_drm: $(FATE_WMV8_DRM)
FATE_VC1 += fate-vc1_sa00040
@@ -35,5 +35,5 @@ fate-vc1_sa20021: CMD = framecrc -i $(SAMPLES)/vc1/SA20021.vc1
FATE_VC1 += fate-vc1-ism
fate-vc1-ism: CMD = framecrc -i $(SAMPLES)/isom/vc1-wmapro.ism -an
-FATE_TESTS += $(FATE_VC1)
+FATE_SAMPLES_AVCONV += $(FATE_VC1)
fate-vc1: $(FATE_VC1)
diff --git a/tests/fate/mp3.mak b/tests/fate/mp3.mak
index 4c16cb8..d3ddea9 100644
--- a/tests/fate/mp3.mak
+++ b/tests/fate/mp3.mak
@@ -38,7 +38,7 @@ fate-mp3-float-extra_overread: CMD = pcm -c:a mp3float -i $(SAMPLES)/mpegaudio/e
fate-mp3-float-extra_overread: CMP = stddev
fate-mp3-float-extra_overread: REF = $(SAMPLES)/mpegaudio/extra_overread.pcm
-FATE_TESTS += $(FATE_MP3)
+FATE_SAMPLES_AVCONV += $(FATE_MP3)
fate-mp3: $(FATE_MP3)
$(FATE_MP3): CMP = stddev
$(FATE_MP3): FUZZ = 0.07
diff --git a/tests/fate/mpc.mak b/tests/fate/mpc.mak
index 2b263ce..6f429d3 100644
--- a/tests/fate/mpc.mak
+++ b/tests/fate/mpc.mak
@@ -10,5 +10,5 @@ fate-musepack7: CMP = oneoff
fate-musepack7: REF = $(SAMPLES)/musepack/inside-mp7.pcm
fate-musepack7: FUZZ = 1
-FATE_TESTS += $(FATE_MPC)
+FATE_SAMPLES_AVCONV += $(FATE_MPC)
fate-mpc: $(FATE_MPC)
diff --git a/tests/fate/pcm.mak b/tests/fate/pcm.mak
index 4b27134..c84de9e 100644
--- a/tests/fate/pcm.mak
+++ b/tests/fate/pcm.mak
@@ -1,28 +1,25 @@
-FATE_PCM += fate-ea-mad-pcm-planar
-fate-ea-mad-pcm-planar: CMD = framecrc -i $(SAMPLES)/ea-mad/xeasport.mad
-
-FATE_PCM += fate-film-cvid-pcm-stereo-8bit
-fate-film-cvid-pcm-stereo-8bit: CMD = framecrc -i $(SAMPLES)/film/logo-capcom.cpk
-
-FATE_PCM += fate-iff-pcm
+FATE_SAMPLES_PCM += fate-iff-pcm
fate-iff-pcm: CMD = md5 -i $(SAMPLES)/iff/Bells -f s16le
-FATE_PCM += fate-pcm_dvd
+FATE_SAMPLES_PCM += fate-pcm_dvd
fate-pcm_dvd: CMD = framecrc -i $(SAMPLES)/pcm-dvd/coolitnow-partial.vob -vn
-FATE_PCM += fate-pcm_s16be-stereo
+FATE_SAMPLES_PCM += fate-pcm-planar
+fate-pcm-planar: CMD = framecrc -i $(SAMPLES)/ea-mad/xeasport.mad -vn
+
+FATE_SAMPLES_PCM += fate-pcm_s16be-stereo
fate-pcm_s16be-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-B-twos.mov -f s16le
-FATE_PCM += fate-pcm_s16le-stereo
+FATE_SAMPLES_PCM += fate-pcm_s16le-stereo
fate-pcm_s16le-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-L-sowt.mov -f s16le
-FATE_PCM += fate-pcm_u8-mono
+FATE_SAMPLES_PCM += fate-pcm_u8-mono
fate-pcm_u8-mono: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-8-raw.mov -f s16le
-FATE_PCM += fate-pcm_u8-stereo
+FATE_SAMPLES_PCM += fate-pcm_u8-stereo
fate-pcm_u8-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-8-raw.mov -f s16le
-FATE_PCM += fate-w64
+FATE_SAMPLES_PCM += fate-w64
fate-w64: CMD = crc -i $(SAMPLES)/w64/w64-pcm16.w64
FATE_PCM += fate-dcinema-encode
@@ -30,5 +27,6 @@ fate-dcinema-encode: tests/data/asynth-96000-6.wav
fate-dcinema-encode: SRC = tests/data/asynth-96000-6.wav
fate-dcinema-encode: CMD = enc_dec_pcm daud md5 s16le $(SRC) -c:a pcm_s24daud
-FATE_TESTS += $(FATE_PCM)
-fate-pcm: $(FATE_PCM)
+FATE_AVCONV += $(FATE_PCM)
+FATE_SAMPLES_AVCONV += $(FATE_SAMPLES_PCM)
+fate-pcm: $(FATE_PCM) $(FATE_SAMPLES_PCM)
diff --git a/tests/fate/probe.mak b/tests/fate/probe.mak
new file mode 100644
index 0000000..73bc5cb
--- /dev/null
+++ b/tests/fate/probe.mak
@@ -0,0 +1,18 @@
+FATE_PROBE_FORMAT += fate-probe-format-roundup997
+fate-probe-format-roundup997: REF = mpeg
+
+FATE_PROBE_FORMAT += fate-probe-format-roundup1383
+fate-probe-format-roundup1383: REF = mp3
+
+FATE_PROBE_FORMAT += fate-probe-format-roundup1414
+fate-probe-format-roundup1414: REF = mpeg
+
+FATE_PROBE_FORMAT += fate-probe-format-roundup2015
+fate-probe-format-roundup2015: REF = dv
+
+FATE_SAMPLES-$(CONFIG_AVPROBE) += $(FATE_PROBE_FORMAT)
+fate-probe-format: $(FATE_PROBE_FORMAT)
+
+$(FATE_PROBE_FORMAT): avprobe$(EXESUF)
+$(FATE_PROBE_FORMAT): CMP = oneline
+fate-probe-format-%: CMD = probefmt $(SAMPLES)/probe-format/$(@:fate-probe-format-%=%)
diff --git a/tests/fate/prores.mak b/tests/fate/prores.mak
index fb6f6cb..1d76fff 100644
--- a/tests/fate/prores.mak
+++ b/tests/fate/prores.mak
@@ -4,7 +4,7 @@ FATE_PRORES = fate-prores-422 \
fate-prores-422_proxy \
fate-prores-alpha \
-FATE_TESTS += $(FATE_PRORES)
+FATE_SAMPLES_AVCONV += $(FATE_PRORES)
fate-prores: $(FATE_PRORES)
fate-prores-422: CMD = framecrc -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_422.mov -pix_fmt yuv422p10le
diff --git a/tests/fate/qt.mak b/tests/fate/qt.mak
index 9b25306..b2b9500 100644
--- a/tests/fate/qt.mak
+++ b/tests/fate/qt.mak
@@ -1,50 +1,50 @@
-FATE_TESTS += fate-8bps
+FATE_SAMPLES_AVCONV += fate-8bps
fate-8bps: CMD = framecrc -i $(SAMPLES)/8bps/full9iron-partial.mov -pix_fmt rgb24
-FATE_TESTS += fate-qdm2
+FATE_SAMPLES_AVCONV += fate-qdm2
fate-qdm2: CMD = pcm -i $(SAMPLES)/qt-surge-suite/surge-2-16-B-QDM2.mov
fate-qdm2: CMP = oneoff
fate-qdm2: REF = $(SAMPLES)/qt-surge-suite/surge-2-16-B-QDM2.pcm
fate-qdm2: FUZZ = 2
-FATE_TESTS += fate-qt-alaw-mono
+FATE_SAMPLES_AVCONV += fate-qt-alaw-mono
fate-qt-alaw-mono: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-16-B-alaw.mov -f s16le
-FATE_TESTS += fate-qt-alaw-stereo
+FATE_SAMPLES_AVCONV += fate-qt-alaw-stereo
fate-qt-alaw-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-B-alaw.mov -f s16le
-FATE_TESTS += fate-qt-ima4-mono
+FATE_SAMPLES_AVCONV += fate-qt-ima4-mono
fate-qt-ima4-mono: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-16-B-ima4.mov -f s16le
-FATE_TESTS += fate-qt-ima4-stereo
+FATE_SAMPLES_AVCONV += fate-qt-ima4-stereo
fate-qt-ima4-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-B-ima4.mov -f s16le
-FATE_TESTS += fate-qt-mac3-mono
+FATE_SAMPLES_AVCONV += fate-qt-mac3-mono
fate-qt-mac3-mono: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-8-MAC3.mov -f s16le
-FATE_TESTS += fate-qt-mac3-stereo
+FATE_SAMPLES_AVCONV += fate-qt-mac3-stereo
fate-qt-mac3-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-8-MAC3.mov -f s16le
-FATE_TESTS += fate-qt-mac6-mono
+FATE_SAMPLES_AVCONV += fate-qt-mac6-mono
fate-qt-mac6-mono: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-8-MAC6.mov -f s16le
-FATE_TESTS += fate-qt-mac6-stereo
+FATE_SAMPLES_AVCONV += fate-qt-mac6-stereo
fate-qt-mac6-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-8-MAC6.mov -f s16le
-FATE_TESTS += fate-qt-ulaw-mono
+FATE_SAMPLES_AVCONV += fate-qt-ulaw-mono
fate-qt-ulaw-mono: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-16-B-ulaw.mov -f s16le
-FATE_TESTS += fate-qt-ulaw-stereo
+FATE_SAMPLES_AVCONV += fate-qt-ulaw-stereo
fate-qt-ulaw-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-B-ulaw.mov -f s16le
-FATE_TESTS += fate-quickdraw
+FATE_SAMPLES_AVCONV += fate-quickdraw
fate-quickdraw: CMD = framecrc -i $(SAMPLES)/quickdraw/Airplane.mov -pix_fmt rgb24
-FATE_TESTS += fate-rpza
+FATE_SAMPLES_AVCONV += fate-rpza
fate-rpza: CMD = framecrc -i $(SAMPLES)/rpza/rpza2.mov -t 2 -pix_fmt rgb24
-FATE_TESTS += fate-svq1
+FATE_SAMPLES_AVCONV += fate-svq1
fate-svq1: CMD = framecrc -i $(SAMPLES)/svq1/marymary-shackles.mov -an -t 10
-FATE_TESTS += fate-svq3
+FATE_SAMPLES_AVCONV += fate-svq3
fate-svq3: CMD = framecrc -i $(SAMPLES)/svq3/Vertical400kbit.sorenson3.mov -t 6 -an
diff --git a/tests/fate/qtrle.mak b/tests/fate/qtrle.mak
index 0d1e3fc..3850a80 100644
--- a/tests/fate/qtrle.mak
+++ b/tests/fate/qtrle.mak
@@ -1,8 +1,8 @@
FATE_QTRLE += fate-qtrle-1bit
-fate-qtrle-1bit: CMD = framecrc -i $(SAMPLES)/qtrle/Animation-Monochrome.mov
+fate-qtrle-1bit: CMD = framecrc -i $(SAMPLES)/qtrle/Animation-Monochrome.mov -an
FATE_QTRLE += fate-qtrle-2bit
-fate-qtrle-2bit: CMD = framecrc -i $(SAMPLES)/qtrle/Animation-4Greys.mov -pix_fmt rgb24
+fate-qtrle-2bit: CMD = framecrc -i $(SAMPLES)/qtrle/Animation-4Greys.mov -pix_fmt rgb24 -an
FATE_QTRLE += fate-qtrle-4bit
fate-qtrle-4bit: CMD = framecrc -i $(SAMPLES)/qtrle/Animation-16Greys.mov -pix_fmt rgb24 -an
@@ -19,5 +19,5 @@ fate-qtrle-24bit: CMD = framecrc -i $(SAMPLES)/qtrle/aletrek-rle.mov
FATE_QTRLE += fate-qtrle-32bit
fate-qtrle-32bit: CMD = framecrc -i $(SAMPLES)/qtrle/ultra_demo_720_480_32bpp_rle.mov -pix_fmt rgb24
-FATE_TESTS += $(FATE_QTRLE)
+FATE_SAMPLES_AVCONV += $(FATE_QTRLE)
fate-qtrle: $(FATE_QTRLE)
diff --git a/tests/fate/real.mak b/tests/fate/real.mak
index 64b9c80..2d450c3 100644
--- a/tests/fate/real.mak
+++ b/tests/fate/real.mak
@@ -1,25 +1,25 @@
-FATE_TESTS += fate-real-14_4
-fate-real-14_4: CMD = md5 -i $(SAMPLES)/real/ra3_in_rm_file.rm -f s16le
+FATE_SAMPLES_AVCONV += fate-ra-144
+fate-ra-144: CMD = md5 -i $(SAMPLES)/real/ra3_in_rm_file.rm -f s16le
-FATE_TESTS += fate-ra-288
+FATE_SAMPLES_AVCONV += fate-ra-288
fate-ra-288: CMD = pcm -i $(SAMPLES)/real/ra_288.rm
fate-ra-288: CMP = oneoff
fate-ra-288: REF = $(SAMPLES)/real/ra_288.pcm
fate-ra-288: FUZZ = 2
-FATE_TESTS += fate-ra-cook
+FATE_SAMPLES_AVCONV += fate-ra-cook
fate-ra-cook: CMD = pcm -i $(SAMPLES)/real/ra_cook.rm
fate-ra-cook: CMP = oneoff
fate-ra-cook: REF = $(SAMPLES)/real/ra_cook.pcm
-FATE_TESTS += fate-ralf
+FATE_SAMPLES_AVCONV += fate-ralf
fate-ralf: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.rmvb -vn -f s16le
-FATE_TESTS += fate-rv30
+FATE_SAMPLES_AVCONV += fate-rv30
fate-rv30: CMD = framecrc -flags +bitexact -dct fastint -idct simple -i $(SAMPLES)/real/rv30.rm -an
-FATE_TESTS += fate-real-rv40
-fate-real-rv40: CMD = framecrc -i $(SAMPLES)/real/spygames-2MB.rmvb -t 10 -an -vsync 0
+FATE_SAMPLES_AVCONV += fate-rv40
+fate-rv40: CMD = framecrc -i $(SAMPLES)/real/spygames-2MB.rmvb -t 10 -an -vsync 0
FATE_SIPR += fate-sipr-5k0
fate-sipr-5k0: CMD = pcm -i $(SAMPLES)/sipr/sipr_5k0.rm
@@ -41,5 +41,5 @@ fate-sipr-16k: CMD = pcm -i $(SAMPLES)/sipr/sipr_16k.rm
fate-sipr-16k: CMP = oneoff
fate-sipr-16k: REF = $(SAMPLES)/sipr/sipr_16k.pcm
-FATE_TESTS += $(FATE_SIPR)
+FATE_SAMPLES_AVCONV += $(FATE_SIPR)
fate-sipr: $(FATE_SIPR)
diff --git a/tests/fate/screen.mak b/tests/fate/screen.mak
index e6762ab..8ae7e90 100644
--- a/tests/fate/screen.mak
+++ b/tests/fate/screen.mak
@@ -1,8 +1,8 @@
# FIXME dropped frames in this test because of coarse timebase
-FATE_TESTS += fate-cscd
+FATE_SAMPLES_AVCONV += fate-cscd
fate-cscd: CMD = framecrc -i $(SAMPLES)/CSCD/sample_video.avi -an -pix_fmt rgb24
-FATE_TESTS += fate-dxtory
+FATE_SAMPLES_AVCONV += fate-dxtory
fate-dxtory: CMD = framecrc -i $(SAMPLES)/dxtory/dxtory_mic.avi
FATE_FRAPS += fate-fraps-v0
@@ -23,7 +23,7 @@ fate-fraps-v4: CMD = framecrc -i $(SAMPLES)/fraps/WoW_2006-11-03_14-58-17-19-nos
FATE_FRAPS += fate-fraps-v5
fate-fraps-v5: CMD = framecrc -i $(SAMPLES)/fraps/fraps-v5-bouncing-balls-partial.avi
-FATE_TESTS += $(FATE_FRAPS)
+FATE_SAMPLES_AVCONV += $(FATE_FRAPS)
fate-fraps: $(FATE_FRAPS)
FATE_TSCC += fate-tscc-15bit
@@ -32,7 +32,7 @@ fate-tscc-15bit: CMD = framecrc -i $(SAMPLES)/tscc/oneminute.avi -t 15 -pix_fmt
FATE_TSCC += fate-tscc-32bit
fate-tscc-32bit: CMD = framecrc -i $(SAMPLES)/tscc/2004-12-17-uebung9-partial.avi -pix_fmt rgb24 -an
-FATE_TESTS += $(FATE_TSCC)
+FATE_SAMPLES_AVCONV += $(FATE_TSCC)
fate-tscc: $(FATE_TSCC)
FATE_VMNC += fate-vmnc-16bit
@@ -41,7 +41,7 @@ fate-vmnc-16bit: CMD = framecrc -i $(SAMPLES)/VMnc/test.avi -pix_fmt rgb24
FATE_VMNC += fate-vmnc-32bit
fate-vmnc-32bit: CMD = framecrc -i $(SAMPLES)/VMnc/VS2k5DebugDemo-01-partial.avi -pix_fmt rgb24
-FATE_TESTS += $(FATE_VMNC)
+FATE_SAMPLES_AVCONV += $(FATE_VMNC)
fate-vmnc: $(FATE_VMNC)
FATE_ZMBV += fate-zmbv-8bit
@@ -56,5 +56,5 @@ fate-zmbv-16bit: CMD = framecrc -i $(SAMPLES)/zmbv/zmbv_16bit.avi -pix_fmt rgb24
FATE_ZMBV += fate-zmbv-32bit
fate-zmbv-32bit: CMD = framecrc -i $(SAMPLES)/zmbv/zmbv_32bit.avi -pix_fmt rgb24 -t 25
-FATE_TESTS += $(FATE_ZMBV)
+FATE_SAMPLES_AVCONV += $(FATE_ZMBV)
fate-zmbv: $(FATE_ZMBV)
diff --git a/tests/fate/utvideo.mak b/tests/fate/utvideo.mak
index 7cf6237..4e350f7 100644
--- a/tests/fate/utvideo.mak
+++ b/tests/fate/utvideo.mak
@@ -22,5 +22,5 @@ fate-utvideo_yuv422_left: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_yuv422_le
FATE_UTVIDEO += fate-utvideo_yuv422_median
fate-utvideo_yuv422_median: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_yuv422_median.avi
-FATE_TESTS += $(FATE_UTVIDEO)
+FATE_SAMPLES_AVCONV += $(FATE_UTVIDEO)
fate-utvideo: $(FATE_UTVIDEO)
diff --git a/tests/fate/vcodec.mak b/tests/fate/vcodec.mak
new file mode 100644
index 0000000..e9a9ad6
--- /dev/null
+++ b/tests/fate/vcodec.mak
@@ -0,0 +1,248 @@
+fate-vsynth1-%: SRC = tests/data/vsynth1.yuv
+fate-vsynth2-%: SRC = tests/data/vsynth2.yuv
+fate-vsynth%: CODEC = $(word 3, $(subst -, ,$(@)))
+fate-vsynth%: FMT = avi
+fate-vsynth%: CMD = enc_dec "rawvideo -s 352x288 -pix_fmt yuv420p" $(SRC) $(FMT) "-c $(CODEC) $(ENCOPTS)" rawvideo "-s 352x288 -pix_fmt yuv420p $(DECOPTS)" -keep
+fate-vsynth%: CMP_UNIT = 1
+
+FATE_VCODEC += asv1
+fate-vsynth%-asv1: ENCOPTS = -qscale 10
+
+FATE_VCODEC += asv2
+fate-vsynth%-asv2: ENCOPTS = -qscale 10
+
+FATE_VCODEC += cljr
+
+FATE_VCODEC += dnxhd-720p
+fate-vsynth%-dnxhd-720p: ENCOPTS = -s hd720 -b 90M \
+ -pix_fmt yuv422p -frames 5
+fate-vsynth%-dnxhd-720p: FMT = dnxhd
+
+FATE_VCODEC += dnxhd-720p-rd
+fate-vsynth%-dnxhd-720p-rd: ENCOPTS = -s hd720 -b 90M -threads 4 -mbd rd \
+ -pix_fmt yuv422p -frames 5
+fate-vsynth%-dnxhd-720p-rd: FMT = dnxhd
+
+FATE_VCODEC += dnxhd-720p-10bit
+fate-vsynth%-dnxhd-720p-10bit: ENCOPTS = -s hd720 -b 90M \
+ -pix_fmt yuv422p10 -frames 5
+fate-vsynth%-dnxhd-720p-10bit: FMT = dnxhd
+
+FATE_VCODEC += dnxhd-1080i
+fate-vsynth%-dnxhd-1080i: ENCOPTS = -s hd1080 -b 120M -flags +ildct \
+ -pix_fmt yuv422p -frames 5
+fate-vsynth%-dnxhd-1080i: FMT = mov
+
+FATE_VCODEC += dv
+fate-vsynth%-dv: CODEC = dvvideo
+fate-vsynth%-dv: ENCOPTS = -dct int -s pal
+fate-vsynth%-dv: FMT = dv
+
+FATE_VCODEC += dv-411
+fate-vsynth%-dv-411: CODEC = dvvideo
+fate-vsynth%-dv-411: ENCOPTS = -dct int -s pal -pix_fmt yuv411p \
+ -sws_flags area
+fate-vsynth%-dv-411: DECOPTS = -sws_flags area
+fate-vsynth%-dv-411: FMT = dv
+
+FATE_VCODEC += dv-50
+fate-vsynth%-dv-50: CODEC = dvvideo
+fate-vsynth%-dv-50: ENCOPTS = -dct int -s pal -pix_fmt yuv422p \
+ -sws_flags neighbor
+fate-vsynth%-dv-50: DECOPTS = -sws_flags neighbor
+fate-vsynth%-dv-50: FMT = dv
+
+FATE_VCODEC += ffv1
+fate-vsynth%-ffv1: ENCOPTS = -strict -2
+
+FATE_VCODEC += ffvhuff
+
+FATE_VCODEC += flashsv
+fate-vsynth%-flashsv: ENCOPTS = -sws_flags neighbor+full_chroma_int
+fate-vsynth%-flashsv: DECOPTS = -sws_flags area
+fate-vsynth%-flashsv: FMT = flv
+
+FATE_VCODEC += flv
+fate-vsynth%-flv: ENCOPTS = -qscale 10
+fate-vsynth%-flv: FMT = flv
+
+FATE_VCODEC += h261
+fate-vsynth%-h261: ENCOPTS = -qscale 11
+
+FATE_VCODEC += h263
+fate-vsynth%-h263: ENCOPTS = -qscale 10
+
+FATE_VCODEC += h263p
+fate-vsynth%-h263p: ENCOPTS = -qscale 2 -flags +aic -umv 1 -aiv 1 -ps 300
+
+FATE_VCODEC += huffyuv
+fate-vsynth%-huffyuv: ENCOPTS = -pix_fmt yuv422p -sws_flags neighbor
+fate-vsynth%-huffyuv: DECOPTS = -strict -2 -sws_flags neighbor
+
+FATE_VCODEC += jpegls
+fate-vsynth%-jpegls: ENCOPTS = -sws_flags neighbor+full_chroma_int
+fate-vsynth%-jpegls: DECOPTS = -sws_flags area
+
+FATE_VCODEC += ljpeg
+fate-vsynth%-ljpeg: ENCOPTS = -strict -1
+
+FATE_VCODEC += mjpeg
+fate-vsynth%-mjpeg: ENCOPTS = -qscale 9 -pix_fmt yuvj420p
+
+FATE_VCODEC += mpeg1
+fate-vsynth%-mpeg1: FMT = mpeg1video
+fate-vsynth%-mpeg1: CODEC = mpeg1video
+fate-vsynth%-mpeg1: ENCOPTS = -qscale 10
+
+FATE_VCODEC += mpeg1b
+fate-vsynth%-mpeg1b: CODEC = mpeg1video
+fate-vsynth%-mpeg1b: ENCOPTS = -qscale 8 -bf 3 -ps 200
+fate-vsynth%-mpeg1b: FMT = mpeg1video
+
+FATE_MPEG2 = mpeg2 \
+ mpeg2-422 \
+ mpeg2-idct-int \
+ mpeg2-ilace \
+ mpeg2-ivlc-qprd \
+ mpeg2-thread \
+ mpeg2-thread-ivlc
+
+FATE_VCODEC += $(FATE_MPEG2)
+
+$(FATE_MPEG2:%=fate-vsynth\%-%): FMT = mpeg2video
+$(FATE_MPEG2:%=fate-vsynth\%-%): CODEC = mpeg2video
+
+fate-vsynth%-mpeg2: ENCOPTS = -qscale 10
+fate-vsynth%-mpeg2-422: ENCOPTS = -vb 1000k \
+ -bf 2 \
+ -trellis 1 \
+ -flags +mv0+ildct+ilme \
+ -mpv_flags +qp_rd \
+ -intra_vlc 1 \
+ -mbd rd \
+ -pix_fmt yuv422p
+fate-vsynth%-mpeg2-idct-int: ENCOPTS = -qscale 10 -idct int -dct int
+fate-vsynth%-mpeg2-ilace: ENCOPTS = -qscale 10 -flags +ildct+ilme
+fate-vsynth%-mpeg2-ivlc-qprd: ENCOPTS = -vb 500k \
+ -bf 2 \
+ -trellis 1 \
+ -flags +mv0 \
+ -mpv_flags +qp_rd \
+ -intra_vlc 1 \
+ -cmp 2 -subcmp 2 \
+ -mbd rd
+fate-vsynth%-mpeg2-thread: ENCOPTS = -qscale 10 -bf 2 -flags +ildct+ilme \
+ -threads 2 -slices 2
+fate-vsynth%-mpeg2-thread-ivlc: ENCOPTS = -qscale 10 -bf 2 -flags +ildct+ilme \
+ -intra_vlc 1 -threads 2 -slices 2
+
+FATE_VCODEC += mpeg4
+fate-vsynth%-mpeg4: ENCOPTS = -qscale 10 -flags +mv4 -mbd bits
+fate-vsynth%-mpeg4: FMT = mp4
+
+FATE_VCODEC += mpeg4-rc
+fate-vsynth%-mpeg4-rc: ENCOPTS = -b 400k -bf 2
+
+FATE_VCODEC += mpeg4-adv
+fate-vsynth%-mpeg4-adv: ENCOPTS = -qscale 9 -flags +mv4+aic \
+ -data_partitioning 1 -trellis 1 \
+ -mbd bits -ps 200
+
+FATE_VCODEC += mpeg4-qprd
+fate-vsynth%-mpeg4-qprd: ENCOPTS = -b 450k -bf 2 -trellis 1 \
+ -flags +mv4+mv0 -mpv_flags +qp_rd \
+ -cmp 2 -subcmp 2 -mbd rd
+
+FATE_VCODEC += mpeg4-adap
+fate-vsynth%-mpeg4-adap: ENCOPTS = -b 550k -bf 2 -flags +mv4+mv0 \
+ -trellis 1 -cmp 1 -subcmp 2 \
+ -mbd rd -scplx_mask 0.3
+
+FATE_VCODEC += mpeg4-qpel
+fate-vsynth%-mpeg4-qpel: ENCOPTS = -qscale 7 -flags +mv4+qpel -mbd 2 \
+ -bf 2 -cmp 1 -subcmp 2
+
+FATE_VCODEC += mpeg4-thread
+fate-vsynth%-mpeg4-thread: ENCOPTS = -b 500k -flags +mv4+aic \
+ -data_partitioning 1 -trellis 1 \
+ -mbd bits -ps 200 -bf 2 \
+ -threads 2 -slices 2
+
+FATE_VCODEC += mpeg4-error
+fate-vsynth%-mpeg4-error: ENCOPTS = -qscale 7 -flags +mv4+aic \
+ -data_partitioning 1 -mbd rd \
+ -ps 250 -error 10
+
+FATE_VCODEC += mpeg4-nr
+fate-vsynth%-mpeg4-nr: ENCOPTS = -qscale 8 -flags +mv4 -mbd rd -nr 200
+
+FATE_VCODEC += msmpeg4
+fate-vsynth%-msmpeg4: ENCOPTS = -qscale 10
+
+FATE_VCODEC += msmpeg4v2
+fate-vsynth%-msmpeg4v2: ENCOPTS = -qscale 10
+
+FATE_VCODEC += prores
+fate-vsynth%-prores: ENCOPTS = -profile hq
+fate-vsynth%-prores: FMT = mov
+
+FATE_VCODEC += qtrle
+fate-vsynth%-qtrle: FMT = mov
+
+FATE_VCODEC += rgb
+fate-vsynth%-rgb: CODEC = rawvideo
+fate-vsynth%-rgb: ENCOPTS = -pix_fmt bgr24
+
+FATE_VCODEC += roqvideo
+fate-vsynth%-roqvideo: CODEC = roqvideo
+fate-vsynth%-roqvideo: ENCOPTS = -frames 5
+fate-vsynth%-roqvideo: FMT = roq
+
+FATE_VCODEC += rv10
+fate-vsynth%-rv10: ENCOPTS = -qscale 10
+fate-vsynth%-rv10: FMT = rm
+
+FATE_VCODEC += rv20
+fate-vsynth%-rv20: ENCOPTS = -qscale 10
+fate-vsynth%-rv20: FMT = rm
+
+FATE_VCODEC += snow
+fate-vsynth%-snow: ENCOPTS = -strict -2 -qscale 2 -flags +qpel \
+ -me_method iter -dia_size 2 \
+ -cmp 12 -subcmp 12 -s 128x64
+
+FATE_VCODEC += snow-hpel
+fate-vsynth%-snow-hpel: ENCOPTS = -strict -2 -qscale 2 \
+ -me_method iter -dia_size 2 \
+ -cmp 12 -subcmp 12 -s 128x64
+
+FATE_VCODEC += snow-ll
+fate-vsynth%-snow-ll: ENCOPTS = -strict -2 -qscale .001 -pred 1 \
+ -flags +mv4+qpel
+
+FATE_VCODEC += svq1
+fate-vsynth%-svq1: ENCOPTS = -qscale 3 -pix_fmt yuv410p
+fate-vsynth%-svq1: FMT = mov
+
+FATE_VCODEC += v210
+
+FATE_VCODEC += wmv1
+fate-vsynth%-wmv1: ENCOPTS = -qscale 10
+
+FATE_VCODEC += wmv2
+fate-vsynth%-wmv2: ENCOPTS = -qscale 10
+
+FATE_VCODEC += yuv
+fate-vsynth%-yuv: CODEC = rawvideo
+
+FATE_VSYNTH1 = $(FATE_VCODEC:%=fate-vsynth1-%)
+FATE_VSYNTH2 = $(FATE_VCODEC:%=fate-vsynth2-%)
+
+$(FATE_VSYNTH1): tests/data/vsynth1.yuv
+$(FATE_VSYNTH2): tests/data/vsynth2.yuv
+
+FATE_AVCONV += $(FATE_VSYNTH1) $(FATE_VSYNTH2)
+
+fate-vsynth1: $(FATE_VSYNTH1)
+fate-vsynth2: $(FATE_VSYNTH2)
+fate-vcodec: fate-vsynth1 fate-vsynth2
diff --git a/tests/fate/video.mak b/tests/fate/video.mak
index a676cd1..e173c4a 100644
--- a/tests/fate/video.mak
+++ b/tests/fate/video.mak
@@ -4,49 +4,52 @@ fate-4xm-1: CMD = framecrc -i $(SAMPLES)/4xm/version1.4xm -pix_fmt rgb24 -an
FATE_4XM += fate-4xm-2
fate-4xm-2: CMD = framecrc -i $(SAMPLES)/4xm/version2.4xm -pix_fmt rgb24 -an
-FATE_TESTS += $(FATE_4XM)
+FATE_SAMPLES_AVCONV += $(FATE_4XM)
fate-4xm: $(FATE_4XM)
-FATE_TESTS += fate-aasc
+FATE_SAMPLES_AVCONV += fate-aasc
fate-aasc: CMD = framecrc -i $(SAMPLES)/aasc/AASC-1.5MB.AVI -pix_fmt rgb24
-FATE_TESTS += fate-alg-mm
+FATE_SAMPLES_AVCONV += fate-alg-mm
fate-alg-mm: CMD = framecrc -i $(SAMPLES)/alg-mm/ibmlogo.mm -an -pix_fmt rgb24
-FATE_TESTS += fate-amv
-fate-amv: CMD = framecrc -idct simple -i $(SAMPLES)/amv/MTV_high_res_320x240_sample_Penguin_Joke_MTV_from_WMV.amv -t 10
+FATE_SAMPLES_AVCONV += fate-amv
+fate-amv: CMD = framecrc -idct simple -i $(SAMPLES)/amv/MTV_high_res_320x240_sample_Penguin_Joke_MTV_from_WMV.amv -t 10 -an
-FATE_TESTS += fate-ansi
+FATE_SAMPLES_AVCONV += fate-ansi
fate-ansi: CMD = framecrc -chars_per_frame 44100 -i $(SAMPLES)/ansi/TRE-IOM5.ANS -pix_fmt rgb24
-FATE_TESTS += fate-armovie-escape124
+FATE_SAMPLES_AVCONV += fate-armovie-escape124
fate-armovie-escape124: CMD = framecrc -i $(SAMPLES)/rpl/ESCAPE.RPL -pix_fmt rgb24
-FATE_TESTS += fate-auravision-v1
+FATE_SAMPLES_AVCONV += fate-auravision-v1
fate-auravision-v1: CMD = framecrc -i $(SAMPLES)/auravision/SOUVIDEO.AVI -an
-FATE_TESTS += fate-auravision-v2
+FATE_SAMPLES_AVCONV += fate-auravision-v2
fate-auravision-v2: CMD = framecrc -i $(SAMPLES)/auravision/salma-hayek-in-ugly-betty-partial-avi -an
-FATE_TESTS += fate-bethsoft-vid
+FATE_SAMPLES_AVCONV += fate-bethsoft-vid
fate-bethsoft-vid: CMD = framecrc -i $(SAMPLES)/bethsoft-vid/ANIM0001.VID -t 5 -pix_fmt rgb24
-FATE_TESTS += fate-bfi
+FATE_SAMPLES_AVCONV += fate-bfi
fate-bfi: CMD = framecrc -i $(SAMPLES)/bfi/2287.bfi -pix_fmt rgb24
-FATE_TESTS += fate-bink-video
+FATE_SAMPLES_AVCONV += fate-bink-video
fate-bink-video: CMD = framecrc -i $(SAMPLES)/bink/hol2br.bik
-FATE_TESTS += fate-cdgraphics
+FATE_SAMPLES_AVCONV += fate-bmv-video
+fate-bmv-video: CMD = framecrc -i $(SAMPLES)/bmv/SURFING-partial.BMV -pix_fmt rgb24 -an
+
+FATE_SAMPLES_AVCONV += fate-cdgraphics
fate-cdgraphics: CMD = framecrc -i $(SAMPLES)/cdgraphics/BrotherJohn.cdg -pix_fmt rgb24 -t 1
-FATE_TESTS += fate-cljr
+FATE_SAMPLES_AVCONV += fate-cljr
fate-cljr: CMD = framecrc -i $(SAMPLES)/cljr/testcljr-partial.avi
-FATE_TESTS += fate-corepng
+FATE_SAMPLES_AVCONV += fate-corepng
fate-corepng: CMD = framecrc -i $(SAMPLES)/png1/corepng-partial.avi
-FATE_TESTS += fate-creatureshock-avs
+FATE_SAMPLES_AVCONV += fate-creatureshock-avs
fate-creatureshock-avs: CMD = framecrc -i $(SAMPLES)/creatureshock-avs/OUTATIME.AVS -pix_fmt rgb24
FATE_CVID += fate-cvid-partial
@@ -58,42 +61,45 @@ fate-cvid-palette: CMD = framecrc -i $(SAMPLES)/cvid/catfight-cvid-pal8-partial.
FATE_CVID += fate-cvid-grayscale
fate-cvid-grayscale: CMD = framecrc -i $(SAMPLES)/cvid/pcitva15.avi -an
-FATE_TESTS += $(FATE_CVID)
+FATE_SAMPLES_AVCONV += $(FATE_CVID)
fate-cvid: $(FATE_CVID)
-FATE_TESTS += fate-cyberia-c93
+FATE_SAMPLES_AVCONV += fate-cyberia-c93
fate-cyberia-c93: CMD = framecrc -i $(SAMPLES)/cyberia-c93/intro1.c93 -t 3 -pix_fmt rgb24
-FATE_TESTS += fate-cyuv
+FATE_SAMPLES_AVCONV += fate-cyuv
fate-cyuv: CMD = framecrc -i $(SAMPLES)/cyuv/cyuv.avi
-FATE_TESTS += fate-delphine-cin
-fate-delphine-cin: CMD = framecrc -i $(SAMPLES)/delphine-cin/LOGO-partial.CIN -pix_fmt rgb24
+FATE_SAMPLES_AVCONV += fate-delphine-cin-video
+fate-delphine-cin-video: CMD = framecrc -i $(SAMPLES)/delphine-cin/LOGO-partial.CIN -pix_fmt rgb24 -an
-FATE_TESTS += fate-deluxepaint-anm
+FATE_SAMPLES_AVCONV += fate-deluxepaint-anm
fate-deluxepaint-anm: CMD = framecrc -i $(SAMPLES)/deluxepaint-anm/INTRO1.ANM -pix_fmt rgb24
FATE_TRUEMOTION1 += fate-truemotion1-15
-fate-truemotion1-15: CMD = framecrc -i $(SAMPLES)/duck/phant2-940.duk -pix_fmt rgb24
+fate-truemotion1-15: CMD = framecrc -i $(SAMPLES)/duck/phant2-940.duk -pix_fmt rgb24 -an
FATE_TRUEMOTION1 += fate-truemotion1-24
-fate-truemotion1-24: CMD = framecrc -i $(SAMPLES)/duck/sonic3dblast_intro-partial.avi -pix_fmt rgb24
+fate-truemotion1-24: CMD = framecrc -i $(SAMPLES)/duck/sonic3dblast_intro-partial.avi -pix_fmt rgb24 -an
-FATE_TESTS += $(FATE_TRUEMOTION1)
+FATE_SAMPLES_AVCONV += $(FATE_TRUEMOTION1)
fate-truemotion1: $(FATE_TRUEMOTION1)
-FATE_TESTS += fate-truemotion2
+FATE_SAMPLES_AVCONV += fate-truemotion2
fate-truemotion2: CMD = framecrc -i $(SAMPLES)/duck/tm20.avi
FATE_DXA += fate-dxa-feeble
-fate-dxa-feeble: CMD = framecrc -i $(SAMPLES)/dxa/meetsquid.dxa -t 2 -pix_fmt rgb24
+fate-dxa-feeble: CMD = framecrc -i $(SAMPLES)/dxa/meetsquid.dxa -t 2 -pix_fmt rgb24 -an
FATE_DXA += fate-dxa-scummvm
fate-dxa-scummvm: CMD = framecrc -i $(SAMPLES)/dxa/scummvm.dxa -pix_fmt rgb24
-FATE_TESTS += $(FATE_DXA)
+FATE_SAMPLES_AVCONV += $(FATE_DXA)
fate-dxa: $(FATE_DXA)
+FATE_SAMPLES_AVCONV += fate-film-cvid
+fate-film-cvid: CMD = framecrc -i $(SAMPLES)/film/logo-capcom.cpk -an
+
FATE_FLIC += fate-flic-af11-palette-change
fate-flic-af11-palette-change: CMD = framecrc -i $(SAMPLES)/fli/fli-engines.fli -t 3.3 -pix_fmt rgb24
@@ -103,17 +109,17 @@ fate-flic-af12: CMD = framecrc -i $(SAMPLES)/fli/jj00c2.fli -pix_fmt rgb24
FATE_FLIC += fate-flic-magiccarpet
fate-flic-magiccarpet: CMD = framecrc -i $(SAMPLES)/fli/intel.dat -pix_fmt rgb24
-FATE_TESTS += $(FATE_FLIC)
+FATE_SAMPLES_AVCONV += $(FATE_FLIC)
fate-flic: $(FATE_FLIC)
-FATE_TESTS += fate-frwu
+FATE_SAMPLES_AVCONV += fate-frwu
fate-frwu: CMD = framecrc -i $(SAMPLES)/frwu/frwu.avi
-FATE_TESTS += fate-id-cin-video
+FATE_SAMPLES_AVCONV += fate-id-cin-video
fate-id-cin-video: CMD = framecrc -i $(SAMPLES)/idcin/idlog-2MB.cin -pix_fmt rgb24
-FATE_TESTS-$(CONFIG_AVFILTER) += fate-idroq-video-encode
-fate-idroq-video-encode: CMD = md5 -f image2 -vcodec pgmyuv -i $(SAMPLES)/ffmpeg-synthetic/vsynth1/%02d.pgm -sws_flags +bitexact -vf pad=512:512:80:112 -f RoQ -t 0.2
+FATE_SAMPLES_AVCONV += fate-idroq-video-encode
+fate-idroq-video-encode: CMD = md5 -f image2 -vcodec pgmyuv -i $(SAMPLES)/ffmpeg-synthetic/vsynth1/%02d.pgm -sws_flags +bitexact -vf pad=512:512:80:112 -f roq -t 0.2
FATE_IFF += fate-iff-byterun1
fate-iff-byterun1: CMD = framecrc -i $(SAMPLES)/iff/ASH.LBM -pix_fmt rgb24
@@ -124,56 +130,77 @@ fate-iff-fibonacci: CMD = md5 -i $(SAMPLES)/iff/dasboot-in-compressed -f s16le
FATE_IFF += fate-iff-ilbm
fate-iff-ilbm: CMD = framecrc -i $(SAMPLES)/iff/lms-matriks.ilbm -pix_fmt rgb24
-FATE_TESTS += $(FATE_IFF)
+FATE_SAMPLES_AVCONV += $(FATE_IFF)
fate-iff: $(FATE_IFF)
-FATE_TESTS += fate-kgv1
+FATE_SAMPLES_AVCONV += fate-interplay-mve-8bit
+fate-interplay-mve-8bit: CMD = framecrc -i $(SAMPLES)/interplay-mve/interplay-logo-2MB.mve -pix_fmt rgb24 -an
+
+FATE_SAMPLES_AVCONV += fate-interplay-mve-16bit
+fate-interplay-mve-16bit: CMD = framecrc -i $(SAMPLES)/interplay-mve/descent3-level5-16bit-partial.mve -pix_fmt rgb24 -an
+
+FATE_SAMPLES_AVCONV += fate-kgv1
fate-kgv1: CMD = framecrc -i $(SAMPLES)/kega/kgv1.avi -pix_fmt rgb555le -an
-FATE_TESTS += fate-kmvc
+FATE_SAMPLES_AVCONV += fate-kmvc
fate-kmvc: CMD = framecrc -i $(SAMPLES)/KMVC/LOGO1.AVI -an -t 3 -pix_fmt rgb24
-FATE_TESTS += fate-mimic
+FATE_SAMPLES_AVCONV += fate-mdec
+fate-mdec: CMD = framecrc -idct simple -i $(SAMPLES)/ea-dct/NFS2Esprit-partial.dct -an
+
+FATE_SAMPLES_AVCONV += fate-mdec-v3
+fate-mdec-v3: CMD = framecrc -idct simple -i $(SAMPLES)/psx-str/abc000_cut.str -an
+
+FATE_SAMPLES_AVCONV += fate-mimic
fate-mimic: CMD = framecrc -idct simple -i $(SAMPLES)/mimic/mimic2-womanloveffmpeg.cam
-FATE_TESTS += fate-mjpegb
+FATE_SAMPLES_AVCONV += fate-mjpegb
fate-mjpegb: CMD = framecrc -idct simple -flags +bitexact -i $(SAMPLES)/mjpegb/mjpegb_part.mov -an
-FATE_TESTS += fate-motionpixels
+FATE_SAMPLES_AVCONV += fate-motionpixels
fate-motionpixels: CMD = framecrc -i $(SAMPLES)/motion-pixels/INTRO-partial.MVI -an -pix_fmt rgb24 -vframes 111
-FATE_TESTS += fate-mpeg2-field-enc
+FATE_SAMPLES_AVCONV += fate-mpeg2-field-enc
fate-mpeg2-field-enc: CMD = framecrc -flags +bitexact -dct fastint -idct simple -i $(SAMPLES)/mpeg2/mpeg2_field_encoding.ts -an
# FIXME dropped frames in this test because of coarse timebase
-FATE_TESTS += fate-nuv
+FATE_SAMPLES_AVCONV += fate-nuv
fate-nuv: CMD = framecrc -idct simple -i $(SAMPLES)/nuv/Today.nuv -an
-FATE_TESTS += fate-qpeg
+FATE_SAMPLES_AVCONV += fate-qpeg
fate-qpeg: CMD = framecrc -i $(SAMPLES)/qpeg/Clock.avi -an -pix_fmt rgb24
-FATE_TESTS += fate-r210
+FATE_SAMPLES_AVCONV += fate-r210
fate-r210: CMD = framecrc -i $(SAMPLES)/r210/r210.avi -pix_fmt rgb48le
-FATE_TESTS += fate-rl2
+FATE_SAMPLES_AVCONV += fate-rl2
fate-rl2: CMD = framecrc -i $(SAMPLES)/rl2/Z4915300.RL2 -pix_fmt rgb24 -an
-FATE_TESTS += fate-smacker
-fate-smacker: CMD = framecrc -i $(SAMPLES)/smacker/wetlogo.smk -pix_fmt rgb24
+FATE_SAMPLES_AVCONV += fate-roqvideo
+fate-roqvideo: CMD = framecrc -i $(SAMPLES)/idroq/idlogo.roq -an
+
+FATE_SAMPLES_AVCONV += fate-sierra-vmd-video
+fate-sierra-vmd-video: CMD = framecrc -i $(SAMPLES)/vmd/12.vmd -pix_fmt rgb24 -an
-FATE_TESTS += fate-smc
+FATE_SAMPLES_AVCONV += fate-smacker-video
+fate-smacker-video: CMD = framecrc -i $(SAMPLES)/smacker/wetlogo.smk -pix_fmt rgb24 -an
+
+FATE_SAMPLES_AVCONV += fate-smc
fate-smc: CMD = framecrc -i $(SAMPLES)/smc/cass_schi.qt -pix_fmt rgb24
-FATE_TESTS += fate-sp5x
+FATE_SAMPLES_AVCONV += fate-sp5x
fate-sp5x: CMD = framecrc -idct simple -i $(SAMPLES)/sp5x/sp5x_problem.avi
-FATE_TESTS += fate-sub-srt
+FATE_SAMPLES_AVCONV += fate-sub-srt
fate-sub-srt: CMD = md5 -i $(SAMPLES)/sub/SubRip_capability_tester.srt -f ass
-FATE_TESTS += fate-tiertex-seq
+FATE_SAMPLES_AVCONV += fate-thp
+fate-thp: CMD = framecrc -idct simple -i $(SAMPLES)/thp/pikmin2-opening1-partial.thp -an
+
+FATE_SAMPLES_AVCONV += fate-tiertex-seq
fate-tiertex-seq: CMD = framecrc -i $(SAMPLES)/tiertex-seq/Gameover.seq -pix_fmt rgb24
-FATE_TESTS += fate-tmv
+FATE_SAMPLES_AVCONV += fate-tmv
fate-tmv: CMD = framecrc -i $(SAMPLES)/tmv/pop-partial.tmv -pix_fmt rgb24
FATE_TXD += fate-txd-16bpp
@@ -182,39 +209,39 @@ fate-txd-16bpp: CMD = framecrc -i $(SAMPLES)/txd/misc.txd -pix_fmt bgra -an
FATE_TXD += fate-txd-pal8
fate-txd-pal8: CMD = framecrc -i $(SAMPLES)/txd/outro.txd -pix_fmt rgb24 -an
-FATE_TESTS += $(FATE_TXD)
+FATE_SAMPLES_AVCONV += $(FATE_TXD)
fate-txd: $(FATE_TXD)
-FATE_TESTS += fate-ulti
+FATE_SAMPLES_AVCONV += fate-ulti
fate-ulti: CMD = framecrc -i $(SAMPLES)/ulti/hit12w.avi -an
-FATE_TESTS += fate-v210
+FATE_SAMPLES_AVCONV += fate-v210
fate-v210: CMD = framecrc -i $(SAMPLES)/v210/v210_720p-partial.avi -pix_fmt yuv422p16be -an
-FATE_TESTS += fate-v410dec
+FATE_SAMPLES_AVCONV += fate-v410dec
fate-v410dec: CMD = framecrc -i $(SAMPLES)/v410/lenav410.mov -pix_fmt yuv444p10le
-FATE_TESTS += fate-v410enc
+FATE_SAMPLES_AVCONV += fate-v410enc
fate-v410enc: tests/vsynth1/00.pgm
fate-v410enc: CMD = md5 -f image2 -vcodec pgmyuv -i $(TARGET_PATH)/tests/vsynth1/%02d.pgm -flags +bitexact -vcodec v410 -f avi
-FATE_TESTS += fate-vcr1
+FATE_SAMPLES_AVCONV += fate-vcr1
fate-vcr1: CMD = framecrc -i $(SAMPLES)/vcr1/VCR1test.avi -an
-FATE_TESTS += fate-videoxl
+FATE_SAMPLES_AVCONV += fate-videoxl
fate-videoxl: CMD = framecrc -i $(SAMPLES)/vixl/pig-vixl.avi
-FATE_TESTS += fate-vqa-cc
-fate-vqa-cc: CMD = framecrc -i $(SAMPLES)/vqa/cc-demo1-partial.vqa -pix_fmt rgb24
+FATE_SAMPLES_AVCONV += fate-vqa-cc
+fate-vqa-cc: CMD = framecrc -i $(SAMPLES)/vqa/cc-demo1-partial.vqa -pix_fmt rgb24 -an
-FATE_TESTS += fate-wc3movie-xan
+FATE_SAMPLES_AVCONV += fate-wc3movie-xan
fate-wc3movie-xan: CMD = framecrc -i $(SAMPLES)/wc3movie/SC_32-part.MVE -pix_fmt rgb24
-FATE_TESTS += fate-wnv1
+FATE_SAMPLES_AVCONV += fate-wnv1
fate-wnv1: CMD = framecrc -i $(SAMPLES)/wnv1/wnv1-codec.avi -an
-FATE_TESTS += fate-yop
+FATE_SAMPLES_AVCONV += fate-yop
fate-yop: CMD = framecrc -i $(SAMPLES)/yop/test1.yop -pix_fmt rgb24 -an
-FATE_TESTS += fate-xxan-wc4
+FATE_SAMPLES_AVCONV += fate-xxan-wc4
fate-xxan-wc4: CMD = framecrc -i $(SAMPLES)/wc4-xan/wc4trailer-partial.avi -an
diff --git a/tests/fate/voice.mak b/tests/fate/voice.mak
index 73534af..fc0e530 100644
--- a/tests/fate/voice.mak
+++ b/tests/fate/voice.mak
@@ -6,7 +6,7 @@ fate-g722-encode: tests/data/asynth-16000-1.wav
fate-g722-encode: SRC = tests/data/asynth-16000-1.wav
fate-g722-encode: CMD = enc_dec_pcm wav md5 s16le $(SRC) -c:a g722
-FATE_TESTS += $(FATE_G722)
+FATE_SAMPLES_AVCONV += $(FATE_G722)
fate-g722: $(FATE_G722)
FATE_G726 += fate-g726-encode-2bit
@@ -29,7 +29,7 @@ fate-g726-encode-5bit: tests/data/asynth-8000-1.wav
fate-g726-encode-5bit: SRC = tests/data/asynth-8000-1.wav
fate-g726-encode-5bit: CMD = enc_dec_pcm wav md5 s16le $(SRC) -c:a g726 -b:a 40k
-FATE_TESTS += $(FATE_G726)
+FATE_SAMPLES_AVCONV += $(FATE_G726)
fate-g726: $(FATE_G726)
FATE_GSM += fate-gsm-ms
@@ -38,15 +38,15 @@ fate-gsm-ms: CMD = framecrc -i $(SAMPLES)/gsm/ciao.wav
FATE_GSM += fate-gsm-toast
fate-gsm-toast: CMD = framecrc -i $(SAMPLES)/gsm/sample-gsm-8000.mov -t 10
-FATE_TESTS += $(FATE_GSM)
+FATE_SAMPLES_AVCONV += $(FATE_GSM)
fate-gsm: $(FATE_GSM)
-FATE_TESTS += fate-qcelp
+FATE_SAMPLES_AVCONV += fate-qcelp
fate-qcelp: CMD = pcm -i $(SAMPLES)/qcp/0036580847.QCP
fate-qcelp: CMP = oneoff
fate-qcelp: REF = $(SAMPLES)/qcp/0036580847.pcm
-FATE_TESTS += fate-truespeech
+FATE_SAMPLES_AVCONV += fate-truespeech
fate-truespeech: CMD = pcm -i $(SAMPLES)/truespeech/a6.wav
fate-truespeech: CMP = oneoff
fate-truespeech: REF = $(SAMPLES)/truespeech/a6.pcm
diff --git a/tests/fate/vorbis.mak b/tests/fate/vorbis.mak
index 5452b74..774cb35 100644
--- a/tests/fate/vorbis.mak
+++ b/tests/fate/vorbis.mak
@@ -49,6 +49,7 @@ fate-vorbis-12: REF = $(SAMPLES)/vorbis/mono_small.pcm
FATE_VORBIS += fate-vorbis-13
fate-vorbis-13: CMD = pcm -i $(SAMPLES)/vorbis/moog_small.ogg
fate-vorbis-13: REF = $(SAMPLES)/vorbis/moog_small.pcm
+fate-vorbis-13: FUZZ = 2
FATE_VORBIS += fate-vorbis-14
fate-vorbis-14: CMD = pcm -i $(SAMPLES)/vorbis/rc1-test_small.ogg
@@ -75,6 +76,10 @@ FATE_VORBIS += fate-vorbis-19
fate-vorbis-19: CMD = pcm -i $(SAMPLES)/vorbis/test-short2_small.ogg
fate-vorbis-19: REF = $(SAMPLES)/vorbis/test-short2_small.pcm
-FATE_TESTS += $(FATE_VORBIS)
+FATE_VORBIS += fate-vorbis-20
+fate-vorbis-20: CMD = pcm -i $(SAMPLES)/vorbis/6.ogg
+fate-vorbis-20: REF = $(SAMPLES)/vorbis/6.pcm
+
+FATE_SAMPLES_AVCONV += $(FATE_VORBIS)
fate-vorbis: $(FATE_VORBIS)
$(FATE_VORBIS): CMP = oneoff
diff --git a/tests/fate/vpx.mak b/tests/fate/vpx.mak
index d7b2f22..4c1ed0d 100644
--- a/tests/fate/vpx.mak
+++ b/tests/fate/vpx.mak
@@ -1,27 +1,30 @@
-FATE_TESTS += fate-ea-vp60
-fate-ea-vp60: CMD = framecrc -i $(SAMPLES)/ea-vp6/g36.vp6
-
-FATE_TESTS += fate-ea-vp61
-fate-ea-vp61: CMD = framecrc -i $(SAMPLES)/ea-vp6/MovieSkirmishGondor.vp6 -t 4
-
FATE_VP3 += fate-vp31
fate-vp31: CMD = framecrc -i $(SAMPLES)/vp3/vp31.avi
FATE_VP3 += fate-vp3-coeff-level64
fate-vp3-coeff-level64: CMD = framecrc -i $(SAMPLES)/vp3/coeff_level64.mkv
-FATE_TESTS += $(FATE_VP3)
+FATE_SAMPLES_AVCONV += $(FATE_VP3)
fate-vp3: $(FATE_VP3)
-FATE_TESTS += fate-vp5
+FATE_SAMPLES_AVCONV += fate-vp5
fate-vp5: CMD = framecrc -i $(SAMPLES)/vp5/potter512-400-partial.avi -an
-FATE_TESTS += fate-vp6a
+FATE_VP6 += fate-vp60
+fate-vp60: CMD = framecrc -i $(SAMPLES)/ea-vp6/g36.vp6
+
+FATE_VP6 += fate-vp61
+fate-vp61: CMD = framecrc -i $(SAMPLES)/ea-vp6/MovieSkirmishGondor.vp6 -t 4
+
+FATE_VP6 += fate-vp6a
fate-vp6a: CMD = framecrc -i $(SAMPLES)/flash-vp6/300x180-Scr-f8-056alpha.flv
-FATE_TESTS += fate-vp6f
+FATE_VP6 += fate-vp6f
fate-vp6f: CMD = framecrc -i $(SAMPLES)/flash-vp6/clip1024.flv
+FATE_SAMPLES_AVCONV += $(FATE_VP6)
+fate-vp6: $(FATE_VP6)
+
VP8_SUITE = 001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017
define FATE_VP8_SUITE
@@ -46,5 +49,5 @@ endef
$(eval $(call FATE_VP8_FULL))
$(eval $(call FATE_VP8_FULL,-emu-edge,-flags +emu_edge))
-FATE_TESTS += $(FATE_VP8)
+FATE_SAMPLES_AVCONV += $(FATE_VP8)
fate-vp8: $(FATE_VP8)
diff --git a/tests/fate/vqf.mak b/tests/fate/vqf.mak
index 846b140..1867635 100644
--- a/tests/fate/vqf.mak
+++ b/tests/fate/vqf.mak
@@ -1,7 +1,7 @@
-FATE_TESTS += fate-twinvq
+FATE_SAMPLES_AVCONV += fate-twinvq
fate-twinvq: CMD = pcm -i $(SAMPLES)/vqf/achterba.vqf
fate-twinvq: CMP = oneoff
fate-twinvq: REF = $(SAMPLES)/vqf/achterba.pcm
-FATE_TESTS += fate-vqf-demux
+FATE_SAMPLES_AVCONV += fate-vqf-demux
fate-vqf-demux: CMD = md5 -i $(SAMPLES)/vqf/achterba.vqf -acodec copy -f framecrc
diff --git a/tests/fate/wavpack.mak b/tests/fate/wavpack.mak
index bf18954..b615c9e 100644
--- a/tests/fate/wavpack.mak
+++ b/tests/fate/wavpack.mak
@@ -1,4 +1,4 @@
-# Lossless
+# lossless
FATE_WAVPACK += fate-wavpack-lossless-float
fate-wavpack-lossless-float: CMD = md5 -i $(SAMPLES)/wavpack/lossless/32bit_float-partial.wv -f f32le
@@ -18,7 +18,7 @@ fate-wavpack-lossless-24bit: CMD = md5 -i $(SAMPLES)/wavpack/lossless/24bit-part
FATE_WAVPACK += fate-wavpack-lossless-32bit
fate-wavpack-lossless-32bit: CMD = md5 -i $(SAMPLES)/wavpack/lossless/32bit_int-partial.wv -f s32le
-# Lossy
+# lossy
FATE_WAVPACK += fate-wavpack-lossy-float
fate-wavpack-lossy-float: CMD = md5 -i $(SAMPLES)/wavpack/lossy/2.0_32-bit_float.wv -f f32le
@@ -35,7 +35,7 @@ fate-wavpack-lossy-24bit: CMD = md5 -i $(SAMPLES)/wavpack/lossy/4.0_24-bit.wv -f
FATE_WAVPACK += fate-wavpack-lossy-32bit
fate-wavpack-lossy-32bit: CMD = md5 -i $(SAMPLES)/wavpack/lossy/4.0_32-bit_int.wv -f s32le
-# Channel configurations
+# channel configurations
FATE_WAVPACK += fate-wavpack-channels-monofloat
fate-wavpack-channels-monofloat: CMD = md5 -i $(SAMPLES)/wavpack/num_channels/mono_float-partial.wv -f f32le
@@ -55,7 +55,7 @@ fate-wavpack-channels-6.1: CMD = md5 -i $(SAMPLES)/wavpack/num_channels/eva_2.22
FATE_WAVPACK += fate-wavpack-channels-7.1
fate-wavpack-channels-7.1: CMD = md5 -i $(SAMPLES)/wavpack/num_channels/panslab_sample_7.1_16bit-partial.wv -f s16le
-# Speed modes
+# speed modes
FATE_WAVPACK += fate-wavpack-speed-default
fate-wavpack-speed-default: CMD = md5 -i $(SAMPLES)/wavpack/speed_modes/default-partial.wv -f s16le
@@ -69,7 +69,7 @@ fate-wavpack-speed-high: CMD = md5 -i $(SAMPLES)/wavpack/speed_modes/high-partia
FATE_WAVPACK += fate-wavpack-speed-vhigh
fate-wavpack-speed-vhigh: CMD = md5 -i $(SAMPLES)/wavpack/speed_modes/vhigh-partial.wv -f s16le
-# Special Cases
+# special cases
FATE_WAVPACK += fate-wavpack-cuesheet
fate-wavpack-cuesheet: CMD = md5 -i $(SAMPLES)/wavpack/special/cue_sheet.wv -f s16le
@@ -86,5 +86,5 @@ fate-wavpack-falsestereo: CMD = md5 -i $(SAMPLES)/wavpack/special/false_stereo.w
FATE_WAVPACK += fate-wavpack-matroskamode
fate-wavpack-matroskamode: CMD = md5 -i $(SAMPLES)/wavpack/special/matroska_mode.mka -f s16le
-FATE_TESTS += $(FATE_WAVPACK)
+FATE_SAMPLES_AVCONV += $(FATE_WAVPACK)
fate-wavpack: $(FATE_WAVPACK)
diff --git a/tests/fate/wma.mak b/tests/fate/wma.mak
index 6fd4b38..ba52b31 100644
--- a/tests/fate/wma.mak
+++ b/tests/fate/wma.mak
@@ -13,7 +13,7 @@ fate-wmapro-ism: CMD = pcm -i $(SAMPLES)/isom/vc1-wmapro.ism -vn
fate-wmapro-ism: CMP = oneoff
fate-wmapro-ism: REF = $(SAMPLES)/isom/vc1-wmapro.pcm
-FATE_TESTS += $(FATE_WMAPRO)
+FATE_SAMPLES_AVCONV += $(FATE_WMAPRO)
fate-wmapro: $(FATE_WMAPRO)
FATE_WMAVOICE += fate-wmavoice-7k
@@ -34,7 +34,7 @@ fate-wmavoice-19k: CMP = stddev
fate-wmavoice-19k: REF = $(SAMPLES)/wmavoice/streaming_CBR-19K.pcm
fate-wmavoice-19k: FUZZ = 3
-FATE_TESTS += $(FATE_WMAVOICE)
+FATE_SAMPLES_AVCONV += $(FATE_WMAVOICE)
fate-wmavoice: $(FATE_WMAVOICE)
FATE_WMA_ENCODE += fate-wmav1-encode
@@ -53,5 +53,5 @@ fate-wmav2-encode: CMP_SHIFT = -8192
fate-wmav2-encode: CMP_TARGET = 258.32
fate-wmav2-encode: SIZE_TOLERANCE = 4632
-FATE_TESTS += $(FATE_WMA_ENCODE)
+FATE_SAMPLES_AVCONV += $(FATE_WMA_ENCODE)
fate-wma-encode: $(FATE_WMA_ENCODE)
diff --git a/tests/lavf-regression.sh b/tests/lavf-regression.sh
index ab8064d..a198306 100755
--- a/tests/lavf-regression.sh
+++ b/tests/lavf-regression.sh
@@ -33,7 +33,7 @@ do_image_formats()
run_avconv $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $2 $ENC_OPTS $3 -t 0.5 -y -qscale 10 $target_path/$file
do_md5sum ${outfile}02.$1
do_avconv_crc $file $DEC_OPTS $3 -i $target_path/$file
- wc -c ${outfile}02.$1
+ echo $(wc -c ${outfile}02.$1)
}
do_audio_only()
@@ -67,7 +67,7 @@ do_lavf mxf "-ar 48000" "-bf 2 -timecode_frame_start 264363"
fi
if [ -n "$do_mxf_d10" ]; then
-do_lavf mxf_d10 "-ar 48000 -ac 2" "-r 25 -s 720x576 -vf pad=720:608:0:32 -vcodec mpeg2video -g 0 -flags +ildct+low_delay -dc 10 -non_linear_quant 1 -intra_vlc 1 -qscale 1 -ps 1 -qmin 1 -rc_max_vbv_use 1 -rc_min_vbv_use 1 -pix_fmt yuv422p -minrate 30000k -maxrate 30000k -b 30000k -bufsize 1200000 -top 1 -rc_init_occupancy 1200000 -qmax 12 -f mxf_d10"
+do_lavf mxf_d10 "-ar 48000 -ac 2" "-r 25 -vf scale=720:576,pad=720:608:0:32 -vcodec mpeg2video -g 0 -flags +ildct+low_delay -dc 10 -non_linear_quant 1 -intra_vlc 1 -qscale 1 -ps 1 -qmin 1 -rc_max_vbv_use 1 -rc_min_vbv_use 1 -pix_fmt yuv422p -minrate 30000k -maxrate 30000k -b 30000k -bufsize 1200000 -top 1 -rc_init_occupancy 1200000 -qmax 12 -f mxf_d10"
fi
if [ -n "$do_ts" ] ; then
diff --git a/tests/lavfi-regression.sh b/tests/lavfi-regression.sh
index f8c0c4e..a315e72 100755
--- a/tests/lavfi-regression.sh
+++ b/tests/lavfi-regression.sh
@@ -44,7 +44,7 @@ do_lavfi_pixfmts(){
filter=$1
filter_args=$2
- showfiltfmts="$target_exec $target_path/tools/lavfi-showfiltfmts"
+ showfiltfmts="$target_exec $target_path/libavfilter/filtfmts-test"
exclude_fmts=${outfile}${1}_exclude_fmts
out_fmts=${outfile}${1}_out_fmts
diff --git a/tests/md5.sh b/tests/md5.sh
index 16b0281..4b95127 100644
--- a/tests/md5.sh
+++ b/tests/md5.sh
@@ -2,8 +2,8 @@
if [ X"$(echo | md5sum 2> /dev/null)" != X ]; then
do_md5sum() { md5sum -b $1; }
-elif [ X"$(echo | md5 2> /dev/null)" != X ]; then
- do_md5sum() { md5 $1 | sed 's#MD5 (\(.*\)) = \(.*\)#\2 *\1#'; }
+elif [ X"$(echo | command md5 2> /dev/null)" != X ]; then
+ do_md5sum() { command md5 $1 | sed 's#MD5 (\(.*\)) = \(.*\)#\2 *\1#'; }
elif [ -x /sbin/md5 ]; then
do_md5sum() { /sbin/md5 -r $1 | sed 's# \**\./# *./#'; }
elif openssl version >/dev/null 2>&1; then
diff --git a/tests/ref/acodec/ac3_fixed b/tests/ref/acodec/ac3_fixed
deleted file mode 100644
index 0c2f9b7..0000000
--- a/tests/ref/acodec/ac3_fixed
+++ /dev/null
@@ -1,2 +0,0 @@
-a1d1fc116463b771abf5aef7ed37d7b1 *./tests/data/acodec/ac3.ac3
-96408 ./tests/data/acodec/ac3.ac3
diff --git a/tests/ref/acodec/adpcm_adx b/tests/ref/acodec/adpcm_adx
deleted file mode 100644
index 8d86698..0000000
--- a/tests/ref/acodec/adpcm_adx
+++ /dev/null
@@ -1,4 +0,0 @@
-0a30509d9296b857e134b762b76dbc31 *./tests/data/acodec/adpcm_adx.adx
-297720 ./tests/data/acodec/adpcm_adx.adx
-2dbc601ed5259f4d74dc48ccd8da7eaf *./tests/data/adpcm_adx.acodec.out.wav
-stddev: 6989.46 PSNR: 19.44 MAXDIFF:65398 bytes: 1058432/ 1058400
diff --git a/tests/ref/acodec/adpcm_ima_qt b/tests/ref/acodec/adpcm_ima_qt
deleted file mode 100644
index c1db43f..0000000
--- a/tests/ref/acodec/adpcm_ima_qt
+++ /dev/null
@@ -1,4 +0,0 @@
-057d27978b35888776512e4e9669a63b *./tests/data/acodec/adpcm_qt.aiff
-281252 ./tests/data/acodec/adpcm_qt.aiff
-169c40435c68d50112c9c61fc67e446d *./tests/data/adpcm_ima_qt.acodec.out.wav
-stddev: 918.61 PSNR: 37.07 MAXDIFF:34029 bytes: 1058560/ 1058400
diff --git a/tests/ref/acodec/adpcm_ima_wav b/tests/ref/acodec/adpcm_ima_wav
deleted file mode 100644
index f83dbad..0000000
--- a/tests/ref/acodec/adpcm_ima_wav
+++ /dev/null
@@ -1,4 +0,0 @@
-56b75c3a6dacedcf2ce7b0586aa33594 *./tests/data/acodec/adpcm_ima.wav
-267324 ./tests/data/acodec/adpcm_ima.wav
-ddddfa47302da540abf19224202bef57 *./tests/data/adpcm_ima_wav.acodec.out.wav
-stddev: 903.51 PSNR: 37.21 MAXDIFF:34026 bytes: 1061748/ 1058400
diff --git a/tests/ref/acodec/adpcm_ms b/tests/ref/acodec/adpcm_ms
deleted file mode 100644
index 301bc80..0000000
--- a/tests/ref/acodec/adpcm_ms
+++ /dev/null
@@ -1,4 +0,0 @@
-a407b87daeef5b25dfb6c5b3f519e9c1 *./tests/data/acodec/adpcm_ms.wav
-268378 ./tests/data/acodec/adpcm_ms.wav
-22863fb278c4e0ebe9c34cb15db5dd6b *./tests/data/adpcm_ms.acodec.out.wav
-stddev: 1050.01 PSNR: 35.91 MAXDIFF:29806 bytes: 1060576/ 1058400
diff --git a/tests/ref/acodec/adpcm_swf b/tests/ref/acodec/adpcm_swf
deleted file mode 100644
index 5306dc4..0000000
--- a/tests/ref/acodec/adpcm_swf
+++ /dev/null
@@ -1,4 +0,0 @@
-42d4639866ed4d692eaf126228a4fa2a *./tests/data/acodec/adpcm_swf.flv
-269166 ./tests/data/acodec/adpcm_swf.flv
-f7df69d3fe708303820f2a9d00140a5b *./tests/data/adpcm_swf.acodec.out.wav
-stddev: 933.58 PSNR: 36.93 MAXDIFF:51119 bytes: 1064960/ 1058400
diff --git a/tests/ref/acodec/adpcm_yam b/tests/ref/acodec/adpcm_yam
deleted file mode 100644
index f7c9f75..0000000
--- a/tests/ref/acodec/adpcm_yam
+++ /dev/null
@@ -1,4 +0,0 @@
-e9c14f701d25947317db9367b9dc772d *./tests/data/acodec/adpcm_yam.wav
-265274 ./tests/data/acodec/adpcm_yam.wav
-1488b5974fa040a65f0d407fc0224c6a *./tests/data/adpcm_yam.acodec.out.wav
-stddev: 1247.60 PSNR: 34.41 MAXDIFF:39895 bytes: 1060864/ 1058400
diff --git a/tests/ref/acodec/alac b/tests/ref/acodec/alac
deleted file mode 100644
index 02752cf..0000000
--- a/tests/ref/acodec/alac
+++ /dev/null
@@ -1,4 +0,0 @@
-b9e78aa8b8774a63d187380a47201a37 *./tests/data/acodec/alac.m4a
-389154 ./tests/data/acodec/alac.m4a
-64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/alac.acodec.out.wav
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/aref b/tests/ref/acodec/aref
deleted file mode 100644
index cd89a63..0000000
--- a/tests/ref/acodec/aref
+++ /dev/null
@@ -1,2 +0,0 @@
-64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/acodec.ref.wav
-1058446 ./tests/data/acodec.ref.wav
diff --git a/tests/ref/acodec/flac b/tests/ref/acodec/flac
deleted file mode 100644
index cc5c173..0000000
--- a/tests/ref/acodec/flac
+++ /dev/null
@@ -1,4 +0,0 @@
-f582b59cc68adfcb3342dcfd7e020b71 *./tests/data/acodec/flac.flac
-361581 ./tests/data/acodec/flac.flac
-64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/flac.acodec.out.wav
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/mp2 b/tests/ref/acodec/mp2
deleted file mode 100644
index 3be6c58..0000000
--- a/tests/ref/acodec/mp2
+++ /dev/null
@@ -1,5 +0,0 @@
-f6eb0a205350bbd7fb1028a01c7ae8aa *./tests/data/acodec/mp2.mp2
-96130 ./tests/data/acodec/mp2.mp2
-5a669ca7321adc6ab66a3eade4035909 *./tests/data/mp2.acodec.out.wav
-stddev: 9315.99 PSNR: 16.94 MAXDIFF:65388 bytes: 1059840/ 1058400
-stddev: 4384.33 PSNR: 23.49 MAXDIFF:52631 bytes: 1057916/ 1058400
diff --git a/tests/ref/acodec/pcm_alaw b/tests/ref/acodec/pcm_alaw
deleted file mode 100644
index 4943831..0000000
--- a/tests/ref/acodec/pcm_alaw
+++ /dev/null
@@ -1,4 +0,0 @@
-ede2da07839a00c255a43129922f2c7b *./tests/data/acodec/pcm_alaw.wav
-529258 ./tests/data/acodec/pcm_alaw.wav
-f323f7551ffad91de8613f44dcb198b6 *./tests/data/pcm_alaw.acodec.out.wav
-stddev: 101.67 PSNR: 56.19 MAXDIFF: 515 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/pcm_f32be b/tests/ref/acodec/pcm_f32be
deleted file mode 100644
index 5f067c2..0000000
--- a/tests/ref/acodec/pcm_f32be
+++ /dev/null
@@ -1,4 +0,0 @@
-118ff3dc83c62ce9ce669eef57e55bb2 *./tests/data/acodec/pcm_f32be.au
-2116824 ./tests/data/acodec/pcm_f32be.au
-64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/pcm_f32be.acodec.out.wav
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/pcm_f32le b/tests/ref/acodec/pcm_f32le
deleted file mode 100644
index eb6ea93..0000000
--- a/tests/ref/acodec/pcm_f32le
+++ /dev/null
@@ -1,4 +0,0 @@
-653d82a64b7bd96ac193e105e9f92d4c *./tests/data/acodec/pcm_f32le.wav
-2116880 ./tests/data/acodec/pcm_f32le.wav
-64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/pcm_f32le.acodec.out.wav
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/pcm_f64be b/tests/ref/acodec/pcm_f64be
deleted file mode 100644
index 9abdabc..0000000
--- a/tests/ref/acodec/pcm_f64be
+++ /dev/null
@@ -1,4 +0,0 @@
-8112296b1ed94f72f20d04b1a54850a7 *./tests/data/acodec/pcm_f64be.au
-4233624 ./tests/data/acodec/pcm_f64be.au
-64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/pcm_f64be.acodec.out.wav
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/pcm_f64le b/tests/ref/acodec/pcm_f64le
deleted file mode 100644
index 2f0576b..0000000
--- a/tests/ref/acodec/pcm_f64le
+++ /dev/null
@@ -1,4 +0,0 @@
-48b4cd378f47a50dc902aa03cc8280ed *./tests/data/acodec/pcm_f64le.wav
-4233680 ./tests/data/acodec/pcm_f64le.wav
-64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/pcm_f64le.acodec.out.wav
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/pcm_mulaw b/tests/ref/acodec/pcm_mulaw
deleted file mode 100644
index cefd76b..0000000
--- a/tests/ref/acodec/pcm_mulaw
+++ /dev/null
@@ -1,4 +0,0 @@
-0c2a55850fb46ad5385a69b15b271f10 *./tests/data/acodec/pcm_mulaw.wav
-529258 ./tests/data/acodec/pcm_mulaw.wav
-7ae8c3fc804bd574006fd547fe28980c *./tests/data/pcm_mulaw.acodec.out.wav
-stddev: 103.38 PSNR: 56.04 MAXDIFF: 644 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/pcm_s16be b/tests/ref/acodec/pcm_s16be
deleted file mode 100644
index f766666..0000000
--- a/tests/ref/acodec/pcm_s16be
+++ /dev/null
@@ -1,4 +0,0 @@
-53c9eb319c778e7ce137667f62384994 *./tests/data/acodec/pcm_s16be.mov
-1060073 ./tests/data/acodec/pcm_s16be.mov
-64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/pcm_s16be.acodec.out.wav
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/pcm_s16le b/tests/ref/acodec/pcm_s16le
deleted file mode 100644
index c7b5de7..0000000
--- a/tests/ref/acodec/pcm_s16le
+++ /dev/null
@@ -1,4 +0,0 @@
-64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/acodec/pcm_s16le.wav
-1058446 ./tests/data/acodec/pcm_s16le.wav
-64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/pcm_s16le.acodec.out.wav
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/pcm_s24be b/tests/ref/acodec/pcm_s24be
deleted file mode 100644
index b9fada7..0000000
--- a/tests/ref/acodec/pcm_s24be
+++ /dev/null
@@ -1,4 +0,0 @@
-af8acd2f08e4bbebe7f4bea4d6f59dd6 *./tests/data/acodec/pcm_s24be.mov
-1589273 ./tests/data/acodec/pcm_s24be.mov
-64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/pcm_s24be.acodec.out.wav
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/pcm_s24le b/tests/ref/acodec/pcm_s24le
deleted file mode 100644
index 0d86d1e..0000000
--- a/tests/ref/acodec/pcm_s24le
+++ /dev/null
@@ -1,4 +0,0 @@
-18ea73985dbdf59e23f5aba66145e6fe *./tests/data/acodec/pcm_s24le.wav
-1587668 ./tests/data/acodec/pcm_s24le.wav
-64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/pcm_s24le.acodec.out.wav
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/pcm_s32be b/tests/ref/acodec/pcm_s32be
deleted file mode 100644
index d6e5205..0000000
--- a/tests/ref/acodec/pcm_s32be
+++ /dev/null
@@ -1,4 +0,0 @@
-63f0e22b4f7c5d61d75047d85f140d52 *./tests/data/acodec/pcm_s32be.mov
-2118473 ./tests/data/acodec/pcm_s32be.mov
-64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/pcm_s32be.acodec.out.wav
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/pcm_s32le b/tests/ref/acodec/pcm_s32le
deleted file mode 100644
index 2b81c29..0000000
--- a/tests/ref/acodec/pcm_s32le
+++ /dev/null
@@ -1,4 +0,0 @@
-8d8849fa5c5d91b9cb74f5c74e937faf *./tests/data/acodec/pcm_s32le.wav
-2116868 ./tests/data/acodec/pcm_s32le.wav
-64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/pcm_s32le.acodec.out.wav
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/pcm_s8 b/tests/ref/acodec/pcm_s8
deleted file mode 100644
index 3b550d2..0000000
--- a/tests/ref/acodec/pcm_s8
+++ /dev/null
@@ -1,4 +0,0 @@
-4b3013a3f3c328ecdb617cd88b3fe836 *./tests/data/acodec/pcm_s8.mov
-530873 ./tests/data/acodec/pcm_s8.mov
-651d4eb8d98dfcdda96ae6c43d8f156b *./tests/data/pcm_s8.acodec.out.wav
-stddev: 147.89 PSNR: 52.93 MAXDIFF: 255 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/pcm_u8 b/tests/ref/acodec/pcm_u8
deleted file mode 100644
index e8d70c9..0000000
--- a/tests/ref/acodec/pcm_u8
+++ /dev/null
@@ -1,4 +0,0 @@
-70fecbae732f81143a560c7315eda49a *./tests/data/acodec/pcm_u8.wav
-529246 ./tests/data/acodec/pcm_u8.wav
-651d4eb8d98dfcdda96ae6c43d8f156b *./tests/data/pcm_u8.acodec.out.wav
-stddev: 147.89 PSNR: 52.93 MAXDIFF: 255 bytes: 1058400/ 1058400
diff --git a/tests/ref/fate/acodec-adpcm-adx b/tests/ref/fate/acodec-adpcm-adx
new file mode 100644
index 0000000..2bc49ab
--- /dev/null
+++ b/tests/ref/fate/acodec-adpcm-adx
@@ -0,0 +1,4 @@
+0a30509d9296b857e134b762b76dbc31 *tests/data/fate/acodec-adpcm-adx.adx
+297720 tests/data/fate/acodec-adpcm-adx.adx
+2dbc601ed5259f4d74dc48ccd8da7eaf *tests/data/fate/acodec-adpcm-adx.out.wav
+stddev: 6989.46 PSNR: 19.44 MAXDIFF:65398 bytes: 1058400/ 1058432
diff --git a/tests/ref/fate/acodec-adpcm-ima_qt b/tests/ref/fate/acodec-adpcm-ima_qt
new file mode 100644
index 0000000..79b8c60
--- /dev/null
+++ b/tests/ref/fate/acodec-adpcm-ima_qt
@@ -0,0 +1,4 @@
+057d27978b35888776512e4e9669a63b *tests/data/fate/acodec-adpcm-ima_qt.aiff
+281252 tests/data/fate/acodec-adpcm-ima_qt.aiff
+169c40435c68d50112c9c61fc67e446d *tests/data/fate/acodec-adpcm-ima_qt.out.wav
+stddev: 918.61 PSNR: 37.07 MAXDIFF:34029 bytes: 1058400/ 1058560
diff --git a/tests/ref/fate/acodec-adpcm-ima_wav b/tests/ref/fate/acodec-adpcm-ima_wav
new file mode 100644
index 0000000..6d83fd5
--- /dev/null
+++ b/tests/ref/fate/acodec-adpcm-ima_wav
@@ -0,0 +1,4 @@
+56b75c3a6dacedcf2ce7b0586aa33594 *tests/data/fate/acodec-adpcm-ima_wav.wav
+267324 tests/data/fate/acodec-adpcm-ima_wav.wav
+ddddfa47302da540abf19224202bef57 *tests/data/fate/acodec-adpcm-ima_wav.out.wav
+stddev: 903.51 PSNR: 37.21 MAXDIFF:34026 bytes: 1058400/ 1061748
diff --git a/tests/ref/fate/acodec-adpcm-ms b/tests/ref/fate/acodec-adpcm-ms
new file mode 100644
index 0000000..eb8515d
--- /dev/null
+++ b/tests/ref/fate/acodec-adpcm-ms
@@ -0,0 +1,4 @@
+a407b87daeef5b25dfb6c5b3f519e9c1 *tests/data/fate/acodec-adpcm-ms.wav
+268378 tests/data/fate/acodec-adpcm-ms.wav
+22863fb278c4e0ebe9c34cb15db5dd6b *tests/data/fate/acodec-adpcm-ms.out.wav
+stddev: 1050.01 PSNR: 35.91 MAXDIFF:29806 bytes: 1058400/ 1060576
diff --git a/tests/ref/fate/acodec-adpcm-swf b/tests/ref/fate/acodec-adpcm-swf
new file mode 100644
index 0000000..fddb771
--- /dev/null
+++ b/tests/ref/fate/acodec-adpcm-swf
@@ -0,0 +1,4 @@
+42d4639866ed4d692eaf126228a4fa2a *tests/data/fate/acodec-adpcm-swf.flv
+269166 tests/data/fate/acodec-adpcm-swf.flv
+f7df69d3fe708303820f2a9d00140a5b *tests/data/fate/acodec-adpcm-swf.out.wav
+stddev: 933.58 PSNR: 36.93 MAXDIFF:51119 bytes: 1058400/ 1064960
diff --git a/tests/ref/fate/acodec-adpcm-yamaha b/tests/ref/fate/acodec-adpcm-yamaha
new file mode 100644
index 0000000..da60f44
--- /dev/null
+++ b/tests/ref/fate/acodec-adpcm-yamaha
@@ -0,0 +1,4 @@
+e9c14f701d25947317db9367b9dc772d *tests/data/fate/acodec-adpcm-yamaha.wav
+265274 tests/data/fate/acodec-adpcm-yamaha.wav
+1488b5974fa040a65f0d407fc0224c6a *tests/data/fate/acodec-adpcm-yamaha.out.wav
+stddev: 1247.60 PSNR: 34.41 MAXDIFF:39895 bytes: 1058400/ 1060864
diff --git a/tests/ref/fate/acodec-alac b/tests/ref/fate/acodec-alac
new file mode 100644
index 0000000..bb7a202
--- /dev/null
+++ b/tests/ref/fate/acodec-alac
@@ -0,0 +1,4 @@
+8ad790d3a0bbda81cd23c15ab8ba760d *tests/data/fate/acodec-alac.mov
+389258 tests/data/fate/acodec-alac.mov
+64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-alac.out.wav
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/fate/acodec-flac b/tests/ref/fate/acodec-flac
new file mode 100644
index 0000000..3ef32c2
--- /dev/null
+++ b/tests/ref/fate/acodec-flac
@@ -0,0 +1,4 @@
+f582b59cc68adfcb3342dcfd7e020b71 *tests/data/fate/acodec-flac.flac
+361581 tests/data/fate/acodec-flac.flac
+64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-flac.out.wav
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/fate/acodec-mp2 b/tests/ref/fate/acodec-mp2
new file mode 100644
index 0000000..42381b4
--- /dev/null
+++ b/tests/ref/fate/acodec-mp2
@@ -0,0 +1,4 @@
+f6eb0a205350bbd7fb1028a01c7ae8aa *tests/data/fate/acodec-mp2.mp2
+96130 tests/data/fate/acodec-mp2.mp2
+5a669ca7321adc6ab66a3eade4035909 *tests/data/fate/acodec-mp2.out.wav
+stddev: 4384.33 PSNR: 23.49 MAXDIFF:52631 bytes: 1058400/ 1057916
diff --git a/tests/ref/fate/acodec-pcm-alaw b/tests/ref/fate/acodec-pcm-alaw
new file mode 100644
index 0000000..28ce960
--- /dev/null
+++ b/tests/ref/fate/acodec-pcm-alaw
@@ -0,0 +1,4 @@
+a2dd6a934ec6d5ec901a211652e85227 *tests/data/fate/acodec-pcm-alaw.wav
+529258 tests/data/fate/acodec-pcm-alaw.wav
+f323f7551ffad91de8613f44dcb198b6 *tests/data/fate/acodec-pcm-alaw.out.wav
+stddev: 101.67 PSNR: 56.19 MAXDIFF: 515 bytes: 1058400/ 1058400
diff --git a/tests/ref/fate/acodec-pcm-f32be b/tests/ref/fate/acodec-pcm-f32be
new file mode 100644
index 0000000..5b0f498
--- /dev/null
+++ b/tests/ref/fate/acodec-pcm-f32be
@@ -0,0 +1,4 @@
+118ff3dc83c62ce9ce669eef57e55bb2 *tests/data/fate/acodec-pcm-f32be.au
+2116824 tests/data/fate/acodec-pcm-f32be.au
+64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-pcm-f32be.out.wav
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/fate/acodec-pcm-f32le b/tests/ref/fate/acodec-pcm-f32le
new file mode 100644
index 0000000..681f083
--- /dev/null
+++ b/tests/ref/fate/acodec-pcm-f32le
@@ -0,0 +1,4 @@
+653d82a64b7bd96ac193e105e9f92d4c *tests/data/fate/acodec-pcm-f32le.wav
+2116880 tests/data/fate/acodec-pcm-f32le.wav
+64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-pcm-f32le.out.wav
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/fate/acodec-pcm-f64be b/tests/ref/fate/acodec-pcm-f64be
new file mode 100644
index 0000000..dd882d3
--- /dev/null
+++ b/tests/ref/fate/acodec-pcm-f64be
@@ -0,0 +1,4 @@
+8112296b1ed94f72f20d04b1a54850a7 *tests/data/fate/acodec-pcm-f64be.au
+4233624 tests/data/fate/acodec-pcm-f64be.au
+64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-pcm-f64be.out.wav
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/fate/acodec-pcm-f64le b/tests/ref/fate/acodec-pcm-f64le
new file mode 100644
index 0000000..c6cb027
--- /dev/null
+++ b/tests/ref/fate/acodec-pcm-f64le
@@ -0,0 +1,4 @@
+48b4cd378f47a50dc902aa03cc8280ed *tests/data/fate/acodec-pcm-f64le.wav
+4233680 tests/data/fate/acodec-pcm-f64le.wav
+64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-pcm-f64le.out.wav
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/fate/acodec-pcm-mulaw b/tests/ref/fate/acodec-pcm-mulaw
new file mode 100644
index 0000000..bd2a1e8
--- /dev/null
+++ b/tests/ref/fate/acodec-pcm-mulaw
@@ -0,0 +1,4 @@
+fd10ee54bd298fc29fd6fc70baa71414 *tests/data/fate/acodec-pcm-mulaw.wav
+529258 tests/data/fate/acodec-pcm-mulaw.wav
+7ae8c3fc804bd574006fd547fe28980c *tests/data/fate/acodec-pcm-mulaw.out.wav
+stddev: 103.38 PSNR: 56.04 MAXDIFF: 644 bytes: 1058400/ 1058400
diff --git a/tests/ref/fate/acodec-pcm-s16be b/tests/ref/fate/acodec-pcm-s16be
new file mode 100644
index 0000000..39c3838
--- /dev/null
+++ b/tests/ref/fate/acodec-pcm-s16be
@@ -0,0 +1,4 @@
+009a446579dd4cba793723b5e2b93c39 *tests/data/fate/acodec-pcm-s16be.mov
+1060097 tests/data/fate/acodec-pcm-s16be.mov
+64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-pcm-s16be.out.wav
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/fate/acodec-pcm-s16le b/tests/ref/fate/acodec-pcm-s16le
new file mode 100644
index 0000000..51366ad
--- /dev/null
+++ b/tests/ref/fate/acodec-pcm-s16le
@@ -0,0 +1,4 @@
+64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-pcm-s16le.wav
+1058446 tests/data/fate/acodec-pcm-s16le.wav
+64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-pcm-s16le.out.wav
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/fate/acodec-pcm-s24be b/tests/ref/fate/acodec-pcm-s24be
new file mode 100644
index 0000000..20bc4e0
--- /dev/null
+++ b/tests/ref/fate/acodec-pcm-s24be
@@ -0,0 +1,4 @@
+de27dae0dff0359d8f39449b17d5607f *tests/data/fate/acodec-pcm-s24be.mov
+1589297 tests/data/fate/acodec-pcm-s24be.mov
+64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-pcm-s24be.out.wav
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/fate/acodec-pcm-s24le b/tests/ref/fate/acodec-pcm-s24le
new file mode 100644
index 0000000..a7e77e2
--- /dev/null
+++ b/tests/ref/fate/acodec-pcm-s24le
@@ -0,0 +1,4 @@
+18ea73985dbdf59e23f5aba66145e6fe *tests/data/fate/acodec-pcm-s24le.wav
+1587668 tests/data/fate/acodec-pcm-s24le.wav
+64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-pcm-s24le.out.wav
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/fate/acodec-pcm-s32be b/tests/ref/fate/acodec-pcm-s32be
new file mode 100644
index 0000000..302bc1a
--- /dev/null
+++ b/tests/ref/fate/acodec-pcm-s32be
@@ -0,0 +1,4 @@
+2db1e7fe92d4006103691a4b59064dc6 *tests/data/fate/acodec-pcm-s32be.mov
+2118497 tests/data/fate/acodec-pcm-s32be.mov
+64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-pcm-s32be.out.wav
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/fate/acodec-pcm-s32le b/tests/ref/fate/acodec-pcm-s32le
new file mode 100644
index 0000000..1c3e412
--- /dev/null
+++ b/tests/ref/fate/acodec-pcm-s32le
@@ -0,0 +1,4 @@
+8d8849fa5c5d91b9cb74f5c74e937faf *tests/data/fate/acodec-pcm-s32le.wav
+2116868 tests/data/fate/acodec-pcm-s32le.wav
+64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-pcm-s32le.out.wav
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/fate/acodec-pcm-s8 b/tests/ref/fate/acodec-pcm-s8
new file mode 100644
index 0000000..f830d2f
--- /dev/null
+++ b/tests/ref/fate/acodec-pcm-s8
@@ -0,0 +1,4 @@
+9ee95a7fff38831a1cad3b49c33e6ed9 *tests/data/fate/acodec-pcm-s8.mov
+530897 tests/data/fate/acodec-pcm-s8.mov
+651d4eb8d98dfcdda96ae6c43d8f156b *tests/data/fate/acodec-pcm-s8.out.wav
+stddev: 147.89 PSNR: 52.93 MAXDIFF: 255 bytes: 1058400/ 1058400
diff --git a/tests/ref/fate/acodec-pcm-u8 b/tests/ref/fate/acodec-pcm-u8
new file mode 100644
index 0000000..80e70ea
--- /dev/null
+++ b/tests/ref/fate/acodec-pcm-u8
@@ -0,0 +1,4 @@
+70fecbae732f81143a560c7315eda49a *tests/data/fate/acodec-pcm-u8.wav
+529246 tests/data/fate/acodec-pcm-u8.wav
+651d4eb8d98dfcdda96ae6c43d8f156b *tests/data/fate/acodec-pcm-u8.out.wav
+stddev: 147.89 PSNR: 52.93 MAXDIFF: 255 bytes: 1058400/ 1058400
diff --git a/tests/ref/fate/adpcm-ea-1 b/tests/ref/fate/adpcm-ea-1
new file mode 100644
index 0000000..f5a33df
--- /dev/null
+++ b/tests/ref/fate/adpcm-ea-1
@@ -0,0 +1,26 @@
+#tb 0: 1/22050
+0, 0, 0, 1484, 5936, 0x00000000
+0, 1484, 1484, 1456, 5824, 0x00000000
+0, 2940, 2940, 1484, 5936, 0x00000000
+0, 4424, 4424, 1456, 5824, 0x00000000
+0, 5880, 5880, 1484, 5936, 0x00000000
+0, 7364, 7364, 1456, 5824, 0x00000000
+0, 8820, 8820, 1484, 5936, 0x00000000
+0, 10304, 10304, 1456, 5824, 0x0f06f5bb
+0, 11760, 11760, 1484, 5936, 0xb0dbfc46
+0, 13244, 13244, 1456, 5824, 0x9daa9f9c
+0, 14700, 14700, 1484, 5936, 0x61400d2f
+0, 16184, 16184, 1456, 5824, 0x34a5b0e3
+0, 17640, 17640, 1484, 5936, 0x6e546f72
+0, 19124, 19124, 1456, 5824, 0x4f093b35
+0, 20580, 20580, 1484, 5936, 0x95b5b599
+0, 22064, 22064, 1456, 5824, 0x75e15e60
+0, 23520, 23520, 1484, 5936, 0xd1077d39
+0, 25004, 25004, 1456, 5824, 0x956e21ca
+0, 26460, 26460, 1484, 5936, 0x33bac234
+0, 27944, 27944, 1456, 5824, 0x5df37824
+0, 29400, 29400, 1484, 5936, 0xc174af24
+0, 30884, 30884, 1456, 5824, 0xe5dc2159
+0, 32340, 32340, 1484, 5936, 0x63ffc8b1
+0, 33824, 33824, 1456, 5824, 0xefe4c365
+0, 35280, 35280, 1484, 5936, 0x2174304d
diff --git a/tests/ref/fate/adpcm-ea-2 b/tests/ref/fate/adpcm-ea-2
new file mode 100644
index 0000000..f58d9a0
--- /dev/null
+++ b/tests/ref/fate/adpcm-ea-2
@@ -0,0 +1,134 @@
+#tb 0: 1/22050
+0, 0, 0, 1484, 5936, 0xea261a29
+0, 1484, 1484, 1456, 5824, 0x253df061
+0, 2940, 2940, 1484, 5936, 0x603a5bd7
+0, 4424, 4424, 1456, 5824, 0x9d283f59
+0, 5880, 5880, 1484, 5936, 0x49323497
+0, 7364, 7364, 1456, 5824, 0x7c299939
+0, 8820, 8820, 1484, 5936, 0x9f918e9a
+0, 10304, 10304, 1456, 5824, 0x1226b534
+0, 11760, 11760, 1484, 5936, 0xdd159326
+0, 13244, 13244, 1456, 5824, 0x361ad10f
+0, 14700, 14700, 1484, 5936, 0x6ccac9e3
+0, 16184, 16184, 1456, 5824, 0x1861efef
+0, 17640, 17640, 1484, 5936, 0x5f718eb9
+0, 19124, 19124, 1456, 5824, 0xd4ca72ba
+0, 20580, 20580, 1484, 5936, 0xbf2b27e6
+0, 22064, 22064, 1456, 5824, 0xcb6f024e
+0, 23520, 23520, 1484, 5936, 0x7dfb7e05
+0, 25004, 25004, 1456, 5824, 0x80e16f13
+0, 26460, 26460, 1484, 5936, 0x0fb59227
+0, 27944, 27944, 1456, 5824, 0x4d6f1fdb
+0, 29400, 29400, 1484, 5936, 0x505a5103
+0, 30884, 30884, 1456, 5824, 0x47ef4c13
+0, 32340, 32340, 1484, 5936, 0xbe4795fb
+0, 33824, 33824, 1456, 5824, 0xb82cc4ff
+0, 35280, 35280, 1484, 5936, 0xf7c6ab8d
+0, 36764, 36764, 1456, 5824, 0x1442f5e0
+0, 38220, 38220, 1484, 5936, 0x64659389
+0, 39704, 39704, 1456, 5824, 0xdd81725c
+0, 41160, 41160, 1484, 5936, 0x7f7c604f
+0, 42644, 42644, 1456, 5824, 0xafc77beb
+0, 44100, 44100, 1484, 5936, 0x24f88e4d
+0, 45584, 45584, 1456, 5824, 0xa31956ca
+0, 47040, 47040, 1484, 5936, 0x958e02b9
+0, 48524, 48524, 1456, 5824, 0xcfc79890
+0, 49980, 49980, 1484, 5936, 0xc7e788ae
+0, 51464, 51464, 1456, 5824, 0x4b6b1acc
+0, 52920, 52920, 1484, 5936, 0xa74496dc
+0, 54404, 54404, 1456, 5824, 0x719e6171
+0, 55860, 55860, 1484, 5936, 0x9346222d
+0, 57344, 57344, 1456, 5824, 0x9e2a876e
+0, 58800, 58800, 1484, 5936, 0xeca6ea64
+0, 60284, 60284, 1456, 5824, 0x07d8174f
+0, 61740, 61740, 1484, 5936, 0x2df5aa6b
+0, 63224, 63224, 1456, 5824, 0x314e7034
+0, 64680, 64680, 1484, 5936, 0x5a328768
+0, 66164, 66164, 1456, 5824, 0x32b92446
+0, 67620, 67620, 1484, 5936, 0x20ecbc9b
+0, 69104, 69104, 1456, 5824, 0x76019c14
+0, 70560, 70560, 1484, 5936, 0x8c3ef8a6
+0, 72044, 72044, 1456, 5824, 0xcdaab50b
+0, 73500, 73500, 1484, 5936, 0xb2f87f4f
+0, 74984, 74984, 1456, 5824, 0x70c26379
+0, 76440, 76440, 1484, 5936, 0x5691ecfd
+0, 77924, 77924, 1456, 5824, 0x61e208fe
+0, 79380, 79380, 1484, 5936, 0x87d1a5e0
+0, 80864, 80864, 1456, 5824, 0x02054cfd
+0, 82320, 82320, 1484, 5936, 0x22ff1c4b
+0, 83804, 83804, 1456, 5824, 0xc6d87fef
+0, 85260, 85260, 1484, 5936, 0x9028bb3b
+0, 86744, 86744, 1456, 5824, 0xbadde406
+0, 88200, 88200, 1484, 5936, 0x6e88ddf1
+0, 89684, 89684, 1456, 5824, 0x5bb8be6e
+0, 91140, 91140, 1484, 5936, 0xe1f8d7fc
+0, 92624, 92624, 1456, 5824, 0xc824e388
+0, 94080, 94080, 1484, 5936, 0x654371a9
+0, 95564, 95564, 1456, 5824, 0xae6ee9ec
+0, 97020, 97020, 1484, 5936, 0x9aa4550d
+0, 98504, 98504, 1456, 5824, 0xdce210ac
+0, 99960, 99960, 1484, 5936, 0xb12641c8
+0, 101444, 101444, 1456, 5824, 0x277e014b
+0, 102900, 102900, 1484, 5936, 0xb0d262de
+0, 104384, 104384, 1456, 5824, 0xf94d6f49
+0, 105840, 105840, 1484, 5936, 0x3d7848cb
+0, 107324, 107324, 1456, 5824, 0xe67fc08e
+0, 108780, 108780, 1484, 5936, 0x0475e0d6
+0, 110264, 110264, 1456, 5824, 0x8a9a4a2e
+0, 111720, 111720, 1484, 5936, 0x82576204
+0, 113204, 113204, 1456, 5824, 0x3017b648
+0, 114660, 114660, 1484, 5936, 0xca4c3e04
+0, 116144, 116144, 1456, 5824, 0x340077d1
+0, 117600, 117600, 1484, 5936, 0x805bea6e
+0, 119084, 119084, 1456, 5824, 0x2cf6c87b
+0, 120540, 120540, 1484, 5936, 0x3635bc5f
+0, 122024, 122024, 1456, 5824, 0x0d7a81c7
+0, 123480, 123480, 1484, 5936, 0x26179764
+0, 124964, 124964, 1456, 5824, 0xa0b2454f
+0, 126420, 126420, 1484, 5936, 0x91d24608
+0, 127904, 127904, 1456, 5824, 0x6509b3e1
+0, 129360, 129360, 1484, 5936, 0xa0e3c9fc
+0, 130844, 130844, 1456, 5824, 0x18682a2f
+0, 132300, 132300, 1484, 5936, 0x89cea4ff
+0, 133784, 133784, 1456, 5824, 0x7dd22b85
+0, 135240, 135240, 1484, 5936, 0x8b2eeb8d
+0, 136724, 136724, 1456, 5824, 0x0c21af82
+0, 138180, 138180, 1484, 5936, 0x9c5a748d
+0, 139664, 139664, 1456, 5824, 0x1dc72c5c
+0, 141120, 141120, 1484, 5936, 0xe6129383
+0, 142604, 142604, 1456, 5824, 0x0a44312a
+0, 144060, 144060, 1484, 5936, 0x7ed30640
+0, 145544, 145544, 1456, 5824, 0xede15f25
+0, 147000, 147000, 1484, 5936, 0x0096d0f3
+0, 148484, 148484, 1456, 5824, 0x13764b4b
+0, 149940, 149940, 1484, 5936, 0xd4608756
+0, 151424, 151424, 1456, 5824, 0x254b5f2a
+0, 152880, 152880, 1484, 5936, 0x7705b830
+0, 154364, 154364, 1456, 5824, 0x64a63d78
+0, 155820, 155820, 1484, 5936, 0xc02d81a6
+0, 157304, 157304, 1456, 5824, 0xd239e55e
+0, 158760, 158760, 1484, 5936, 0x8018cd3a
+0, 160244, 160244, 1456, 5824, 0xf86b8a98
+0, 161700, 161700, 1484, 5936, 0x2a0078bc
+0, 163184, 163184, 1456, 5824, 0x058d4e1b
+0, 164640, 164640, 1484, 5936, 0xbc718309
+0, 166124, 166124, 1456, 5824, 0xaf6c29e5
+0, 167580, 167580, 1484, 5936, 0x80df004d
+0, 169064, 169064, 1456, 5824, 0xeca5aa57
+0, 170520, 170520, 1484, 5936, 0xb793a8f8
+0, 172004, 172004, 1456, 5824, 0x70fa6aff
+0, 173460, 173460, 1484, 5936, 0xda8d4cc6
+0, 174944, 174944, 1456, 5824, 0xa70088eb
+0, 176400, 176400, 1484, 5936, 0x1c0b0aab
+0, 177884, 177884, 1456, 5824, 0x234d2436
+0, 179340, 179340, 1484, 5936, 0xf79d731e
+0, 180824, 180824, 1456, 5824, 0x5a4e454a
+0, 182280, 182280, 1484, 5936, 0xccf6d042
+0, 183764, 183764, 1456, 5824, 0x4e524d14
+0, 185220, 185220, 1484, 5936, 0xf8f2fcc3
+0, 186704, 186704, 1456, 5824, 0x08f12491
+0, 188160, 188160, 1484, 5936, 0x506e0a42
+0, 189644, 189644, 1456, 5824, 0x7cf05049
+0, 191100, 191100, 1484, 5936, 0xdeb9d295
+0, 192584, 192584, 1456, 5824, 0x758ef642
+0, 194040, 194040, 1484, 5936, 0x91903980
diff --git a/tests/ref/fate/adpcm-ea-mad-ea-r1 b/tests/ref/fate/adpcm-ea-mad-ea-r1
deleted file mode 100644
index 7e8a995..0000000
--- a/tests/ref/fate/adpcm-ea-mad-ea-r1
+++ /dev/null
@@ -1,193 +0,0 @@
-#tb 0: 1/90000
-#tb 1: 1/48000
-0, 0, 0, 0, 535680, 0x889c32cf
-1, 0, 0, 1624, 6496, 0x00000000
-0, 2970, 2970, 0, 535680, 0x0b1ef044
-1, 1624, 1624, 1596, 6384, 0x00000000
-0, 5940, 5940, 0, 535680, 0xa7d0818b
-1, 3220, 3220, 1596, 6384, 0x00000000
-0, 8910, 8910, 0, 535680, 0xf392e4e1
-1, 4816, 4816, 1596, 6384, 0x00000000
-0, 11880, 11880, 0, 535680, 0x08480c69
-1, 6412, 6412, 1596, 6384, 0x00000000
-0, 14850, 14850, 0, 535680, 0x2b8af1ed
-1, 8008, 8008, 1624, 6496, 0xe2034d04
-0, 17820, 17820, 0, 535680, 0x0d58e062
-1, 9632, 9632, 1596, 6384, 0x089c9157
-0, 20790, 20790, 0, 535680, 0xd140ced0
-1, 11228, 11228, 1596, 6384, 0xeed5743c
-0, 23760, 23760, 0, 535680, 0xbd0e6652
-1, 12824, 12824, 1596, 6384, 0x71de6b34
-0, 26730, 26730, 0, 535680, 0xdc2f2a6b
-1, 14420, 14420, 1596, 6384, 0xc0d67710
-0, 29700, 29700, 0, 535680, 0x97c31a38
-1, 16016, 16016, 1624, 6496, 0x35786490
-0, 32670, 32670, 0, 535680, 0x1a2bdf38
-1, 17640, 17640, 1596, 6384, 0xdf1c99a2
-0, 35640, 35640, 0, 535680, 0xb3af3ac4
-1, 19236, 19236, 1596, 6384, 0xca9591ad
-0, 38610, 38610, 0, 535680, 0x07a52577
-1, 20832, 20832, 1596, 6384, 0x6f0d9c3d
-0, 41580, 41580, 0, 535680, 0x78407368
-1, 22428, 22428, 1596, 6384, 0xfacbbaee
-0, 44550, 44550, 0, 535680, 0xd2a9efc3
-1, 24024, 24024, 1624, 6496, 0x927fb136
-0, 47520, 47520, 0, 535680, 0x36df2f29
-1, 25648, 25648, 1596, 6384, 0x9d4f2572
-0, 50490, 50490, 0, 535680, 0x9821d8f7
-1, 27244, 27244, 1596, 6384, 0x2a3c6d08
-0, 53460, 53460, 0, 535680, 0xf64321aa
-1, 28840, 28840, 1596, 6384, 0x4282b1e0
-0, 56430, 56430, 0, 535680, 0x53e4d9aa
-1, 30436, 30436, 1596, 6384, 0xc4a77b9f
-0, 59400, 59400, 0, 535680, 0xdbd6f853
-1, 32032, 32032, 1624, 6496, 0x2af6a14f
-0, 62370, 62370, 0, 535680, 0x5d40cf8b
-1, 33656, 33656, 1596, 6384, 0x4d734169
-0, 65340, 65340, 0, 535680, 0xe624af9d
-1, 35252, 35252, 1596, 6384, 0xb91b5865
-0, 68310, 68310, 0, 535680, 0xd9dbb4cd
-1, 36848, 36848, 1596, 6384, 0x9dce2417
-0, 71280, 71280, 0, 535680, 0xf14e72ec
-1, 38444, 38444, 1596, 6384, 0xb7c4e1ce
-0, 74250, 74250, 0, 535680, 0xb35c18f6
-1, 40040, 40040, 1624, 6496, 0xef0dc07a
-0, 77220, 77220, 0, 535680, 0xc96d7757
-1, 41664, 41664, 1596, 6384, 0x4ad21d10
-0, 80190, 80190, 0, 535680, 0xdfb937df
-1, 43260, 43260, 1596, 6384, 0xcfe14682
-0, 83160, 83160, 0, 535680, 0x40cd71d7
-1, 44856, 44856, 1596, 6384, 0x07be48eb
-0, 86130, 86130, 0, 535680, 0x15e176d6
-1, 46452, 46452, 1596, 6384, 0x09de3498
-0, 89100, 89100, 0, 535680, 0x7f891b24
-1, 48048, 48048, 1624, 6496, 0xab2e9686
-0, 92070, 92070, 0, 535680, 0xb87a8c32
-1, 49672, 49672, 1596, 6384, 0x3aba3ccc
-0, 95040, 95040, 0, 535680, 0x0c01541f
-1, 51268, 51268, 1596, 6384, 0x0a905ec3
-0, 98010, 98010, 0, 535680, 0x9eee99b3
-1, 52864, 52864, 1596, 6384, 0x76a93ce4
-0, 100980, 100980, 0, 535680, 0xd65eb689
-1, 54460, 54460, 1596, 6384, 0xa99063a4
-0, 103950, 103950, 0, 535680, 0x6e733cfa
-1, 56056, 56056, 1624, 6496, 0xc16bb88d
-0, 106920, 106920, 0, 535680, 0xac536670
-1, 57680, 57680, 1596, 6384, 0x650379bf
-0, 109890, 109890, 0, 535680, 0x002275b8
-1, 59276, 59276, 1596, 6384, 0x4e0749fe
-0, 112860, 112860, 0, 535680, 0x6a5385cb
-1, 60872, 60872, 1596, 6384, 0x778e8d12
-0, 115830, 115830, 0, 535680, 0xd129ade3
-1, 62468, 62468, 1596, 6384, 0x9fa8c494
-0, 118800, 118800, 0, 535680, 0x32cab5d7
-1, 64064, 64064, 1624, 6496, 0x61d5bead
-0, 121770, 121770, 0, 535680, 0x08be1c8f
-1, 65688, 65688, 1596, 6384, 0x4da9bc3c
-0, 124740, 124740, 0, 535680, 0x59e1fba0
-1, 67284, 67284, 1596, 6384, 0xa72b6f93
-0, 127710, 127710, 0, 535680, 0x138aee3a
-1, 68880, 68880, 1596, 6384, 0x811f5f77
-0, 130680, 130680, 0, 535680, 0x4cfbcd5e
-1, 70476, 70476, 1596, 6384, 0x83ea5e3d
-0, 133650, 133650, 0, 535680, 0xf6cf0fb4
-1, 72072, 72072, 1624, 6496, 0x78bab460
-0, 136620, 136620, 0, 535680, 0xb13a06de
-1, 73696, 73696, 1596, 6384, 0xc9a07432
-0, 139590, 139590, 0, 535680, 0x59176f00
-1, 75292, 75292, 1596, 6384, 0x4b4f2a34
-0, 142560, 142560, 0, 535680, 0xf84b4ca3
-1, 76888, 76888, 1596, 6384, 0x4d707a53
-0, 145530, 145530, 0, 535680, 0x7fd09f73
-1, 78484, 78484, 1596, 6384, 0x703efb60
-0, 148500, 148500, 0, 535680, 0x3be383b8
-1, 80080, 80080, 1624, 6496, 0x319a77bb
-0, 151470, 151470, 0, 535680, 0xa7118e51
-1, 81704, 81704, 1596, 6384, 0xbdfd82ec
-0, 154440, 154440, 0, 535680, 0xbd83120c
-1, 83300, 83300, 1596, 6384, 0x413c3503
-0, 157410, 157410, 0, 535680, 0x3bc9d256
-1, 84896, 84896, 1596, 6384, 0xe6e666b3
-0, 160380, 160380, 0, 535680, 0xb6c87f87
-1, 86492, 86492, 1596, 6384, 0xa09c7342
-0, 163350, 163350, 0, 535680, 0xe80d110a
-1, 88088, 88088, 1624, 6496, 0x60cba846
-0, 166320, 166320, 0, 535680, 0xb3a83362
-1, 89712, 89712, 1596, 6384, 0x0ba34308
-0, 169290, 169290, 0, 535680, 0xfb39eb52
-1, 91308, 91308, 1596, 6384, 0xdc3a65f0
-0, 172260, 172260, 0, 535680, 0xbf6e1220
-1, 92904, 92904, 1596, 6384, 0x1ebf9dc4
-0, 175230, 175230, 0, 535680, 0x9ecdfbae
-1, 94500, 94500, 1596, 6384, 0xbbcb1449
-0, 178200, 178200, 0, 535680, 0x069a65f5
-1, 96096, 96096, 1624, 6496, 0x926574eb
-0, 181170, 181170, 0, 535680, 0x206e372c
-1, 97720, 97720, 1596, 6384, 0xb4da92f1
-0, 184140, 184140, 0, 535680, 0x58c83dd4
-1, 99316, 99316, 1596, 6384, 0xdbbd21e0
-0, 187110, 187110, 0, 535680, 0xc3562b03
-1, 100912, 100912, 1596, 6384, 0x08510eff
-0, 190080, 190080, 0, 535680, 0xd1ed85a0
-1, 102508, 102508, 1596, 6384, 0x9534b7ca
-0, 193050, 193050, 0, 535680, 0xb6205f4b
-1, 104104, 104104, 1624, 6496, 0x50a5ed30
-0, 196020, 196020, 0, 535680, 0xaedf8bfa
-1, 105728, 105728, 1596, 6384, 0xf5ac2f7c
-0, 198990, 198990, 0, 535680, 0xa48d5dea
-1, 107324, 107324, 1596, 6384, 0x4fe1fa55
-0, 201960, 201960, 0, 535680, 0xff82e7c1
-1, 108920, 108920, 1596, 6384, 0xd61c4c05
-0, 204930, 204930, 0, 535680, 0xc9560222
-1, 110516, 110516, 1596, 6384, 0x56d11b45
-0, 207900, 207900, 0, 535680, 0x0fafa549
-1, 112112, 112112, 1624, 6496, 0x3906084b
-0, 210870, 210870, 0, 535680, 0x8d556ccb
-1, 113736, 113736, 1596, 6384, 0x1ef31fed
-0, 213840, 213840, 0, 535680, 0x802aac1f
-1, 115332, 115332, 1596, 6384, 0x58ed82f5
-0, 216810, 216810, 0, 535680, 0x7d0fa168
-1, 116928, 116928, 1596, 6384, 0xb31ccd1f
-0, 219780, 219780, 0, 535680, 0x1a9255c9
-1, 118524, 118524, 1596, 6384, 0xfb648285
-0, 222750, 222750, 0, 535680, 0xb4ec7e35
-1, 120120, 120120, 1624, 6496, 0xfae2950b
-0, 225720, 225720, 0, 535680, 0x48fac072
-1, 121744, 121744, 1596, 6384, 0xe28c8357
-0, 228690, 228690, 0, 535680, 0x1e260135
-1, 123340, 123340, 1596, 6384, 0xda718e60
-0, 231660, 231660, 0, 535680, 0xce4d5079
-1, 124936, 124936, 1596, 6384, 0x27516999
-0, 234630, 234630, 0, 535680, 0x13e5e4ed
-1, 126532, 126532, 1596, 6384, 0x0ba07921
-0, 237600, 237600, 0, 535680, 0x592305ec
-1, 128128, 128128, 1624, 6496, 0xcfbecfab
-0, 240570, 240570, 0, 535680, 0x9e227508
-1, 129752, 129752, 1596, 6384, 0xae4cedcd
-0, 243540, 243540, 0, 535680, 0x1d37e5ea
-1, 131348, 131348, 1596, 6384, 0x917b4707
-0, 246510, 246510, 0, 535680, 0x7eae7692
-1, 132944, 132944, 1596, 6384, 0x8671b28e
-0, 249480, 249480, 0, 535680, 0xf452e4b9
-1, 134540, 134540, 1596, 6384, 0x9a1238fa
-0, 252450, 252450, 0, 535680, 0x1460e7e9
-1, 136136, 136136, 1624, 6496, 0x23b8f8ca
-0, 255420, 255420, 0, 535680, 0xc6d8a638
-1, 137760, 137760, 1596, 6384, 0x3903bcd6
-0, 258390, 258390, 0, 535680, 0x854f5fb0
-1, 139356, 139356, 1596, 6384, 0x0532b267
-0, 261360, 261360, 0, 535680, 0x854f5fb0
-1, 140952, 140952, 1596, 6384, 0xde931220
-0, 264330, 264330, 0, 535680, 0x70a02d87
-1, 142548, 142548, 1596, 6384, 0x4ed70a80
-0, 267300, 267300, 0, 535680, 0x9a4ad464
-0, 270270, 270270, 0, 535680, 0x9a4ad464
-1, 144144, 144144, 1624, 6496, 0x4a52d5a1
-0, 273240, 273240, 0, 535680, 0x9a4ad464
-1, 145768, 145768, 1596, 6384, 0xc1be5760
-0, 276210, 276210, 0, 535680, 0x9a4ad464
-1, 147364, 147364, 1596, 6384, 0x790d69ba
-0, 279180, 279180, 0, 535680, 0x9a4ad464
-1, 148960, 148960, 1596, 6384, 0x9d73e6cf
-0, 282150, 282150, 0, 535680, 0x9a4ad464
-1, 150556, 150556, 1568, 6272, 0xbc0fc725
diff --git a/tests/ref/fate/adpcm-ea-r1 b/tests/ref/fate/adpcm-ea-r1
new file mode 100644
index 0000000..74d15c6
--- /dev/null
+++ b/tests/ref/fate/adpcm-ea-r1
@@ -0,0 +1,96 @@
+#tb 0: 1/48000
+0, 0, 0, 1624, 6496, 0x00000000
+0, 1624, 1624, 1596, 6384, 0x00000000
+0, 3220, 3220, 1596, 6384, 0x00000000
+0, 4816, 4816, 1596, 6384, 0x00000000
+0, 6412, 6412, 1596, 6384, 0x00000000
+0, 8008, 8008, 1624, 6496, 0xe2034d04
+0, 9632, 9632, 1596, 6384, 0x089c9157
+0, 11228, 11228, 1596, 6384, 0xeed5743c
+0, 12824, 12824, 1596, 6384, 0x71de6b34
+0, 14420, 14420, 1596, 6384, 0xc0d67710
+0, 16016, 16016, 1624, 6496, 0x35786490
+0, 17640, 17640, 1596, 6384, 0xdf1c99a2
+0, 19236, 19236, 1596, 6384, 0xca9591ad
+0, 20832, 20832, 1596, 6384, 0x6f0d9c3d
+0, 22428, 22428, 1596, 6384, 0xfacbbaee
+0, 24024, 24024, 1624, 6496, 0x927fb136
+0, 25648, 25648, 1596, 6384, 0x9d4f2572
+0, 27244, 27244, 1596, 6384, 0x2a3c6d08
+0, 28840, 28840, 1596, 6384, 0x4282b1e0
+0, 30436, 30436, 1596, 6384, 0xc4a77b9f
+0, 32032, 32032, 1624, 6496, 0x2af6a14f
+0, 33656, 33656, 1596, 6384, 0x4d734169
+0, 35252, 35252, 1596, 6384, 0xb91b5865
+0, 36848, 36848, 1596, 6384, 0x9dce2417
+0, 38444, 38444, 1596, 6384, 0xb7c4e1ce
+0, 40040, 40040, 1624, 6496, 0xef0dc07a
+0, 41664, 41664, 1596, 6384, 0x4ad21d10
+0, 43260, 43260, 1596, 6384, 0xcfe14682
+0, 44856, 44856, 1596, 6384, 0x07be48eb
+0, 46452, 46452, 1596, 6384, 0x09de3498
+0, 48048, 48048, 1624, 6496, 0xab2e9686
+0, 49672, 49672, 1596, 6384, 0x3aba3ccc
+0, 51268, 51268, 1596, 6384, 0x0a905ec3
+0, 52864, 52864, 1596, 6384, 0x76a93ce4
+0, 54460, 54460, 1596, 6384, 0xa99063a4
+0, 56056, 56056, 1624, 6496, 0xc16bb88d
+0, 57680, 57680, 1596, 6384, 0x650379bf
+0, 59276, 59276, 1596, 6384, 0x4e0749fe
+0, 60872, 60872, 1596, 6384, 0x778e8d12
+0, 62468, 62468, 1596, 6384, 0x9fa8c494
+0, 64064, 64064, 1624, 6496, 0x61d5bead
+0, 65688, 65688, 1596, 6384, 0x4da9bc3c
+0, 67284, 67284, 1596, 6384, 0xa72b6f93
+0, 68880, 68880, 1596, 6384, 0x811f5f77
+0, 70476, 70476, 1596, 6384, 0x83ea5e3d
+0, 72072, 72072, 1624, 6496, 0x78bab460
+0, 73696, 73696, 1596, 6384, 0xc9a07432
+0, 75292, 75292, 1596, 6384, 0x4b4f2a34
+0, 76888, 76888, 1596, 6384, 0x4d707a53
+0, 78484, 78484, 1596, 6384, 0x703efb60
+0, 80080, 80080, 1624, 6496, 0x319a77bb
+0, 81704, 81704, 1596, 6384, 0xbdfd82ec
+0, 83300, 83300, 1596, 6384, 0x413c3503
+0, 84896, 84896, 1596, 6384, 0xe6e666b3
+0, 86492, 86492, 1596, 6384, 0xa09c7342
+0, 88088, 88088, 1624, 6496, 0x60cba846
+0, 89712, 89712, 1596, 6384, 0x0ba34308
+0, 91308, 91308, 1596, 6384, 0xdc3a65f0
+0, 92904, 92904, 1596, 6384, 0x1ebf9dc4
+0, 94500, 94500, 1596, 6384, 0xbbcb1449
+0, 96096, 96096, 1624, 6496, 0x926574eb
+0, 97720, 97720, 1596, 6384, 0xb4da92f1
+0, 99316, 99316, 1596, 6384, 0xdbbd21e0
+0, 100912, 100912, 1596, 6384, 0x08510eff
+0, 102508, 102508, 1596, 6384, 0x9534b7ca
+0, 104104, 104104, 1624, 6496, 0x50a5ed30
+0, 105728, 105728, 1596, 6384, 0xf5ac2f7c
+0, 107324, 107324, 1596, 6384, 0x4fe1fa55
+0, 108920, 108920, 1596, 6384, 0xd61c4c05
+0, 110516, 110516, 1596, 6384, 0x56d11b45
+0, 112112, 112112, 1624, 6496, 0x3906084b
+0, 113736, 113736, 1596, 6384, 0x1ef31fed
+0, 115332, 115332, 1596, 6384, 0x58ed82f5
+0, 116928, 116928, 1596, 6384, 0xb31ccd1f
+0, 118524, 118524, 1596, 6384, 0xfb648285
+0, 120120, 120120, 1624, 6496, 0xfae2950b
+0, 121744, 121744, 1596, 6384, 0xe28c8357
+0, 123340, 123340, 1596, 6384, 0xda718e60
+0, 124936, 124936, 1596, 6384, 0x27516999
+0, 126532, 126532, 1596, 6384, 0x0ba07921
+0, 128128, 128128, 1624, 6496, 0xcfbecfab
+0, 129752, 129752, 1596, 6384, 0xae4cedcd
+0, 131348, 131348, 1596, 6384, 0x917b4707
+0, 132944, 132944, 1596, 6384, 0x8671b28e
+0, 134540, 134540, 1596, 6384, 0x9a1238fa
+0, 136136, 136136, 1624, 6496, 0x23b8f8ca
+0, 137760, 137760, 1596, 6384, 0x3903bcd6
+0, 139356, 139356, 1596, 6384, 0x0532b267
+0, 140952, 140952, 1596, 6384, 0xde931220
+0, 142548, 142548, 1596, 6384, 0x4ed70a80
+0, 144144, 144144, 1624, 6496, 0x4a52d5a1
+0, 145768, 145768, 1596, 6384, 0xc1be5760
+0, 147364, 147364, 1596, 6384, 0x790d69ba
+0, 148960, 148960, 1596, 6384, 0x9d73e6cf
+0, 150556, 150556, 1568, 6272, 0xbc0fc725
diff --git a/tests/ref/fate/adpcm-ea-tqi b/tests/ref/fate/adpcm-ea-tqi
deleted file mode 100644
index 9f09003..0000000
--- a/tests/ref/fate/adpcm-ea-tqi
+++ /dev/null
@@ -1,53 +0,0 @@
-#tb 0: 1/90000
-#tb 1: 1/22050
-0, 0, 0, 0, 115200, 0x375ec573
-1, 0, 0, 1484, 5936, 0x00000000
-0, 6000, 6000, 0, 115200, 0x375ec573
-1, 1484, 1484, 1456, 5824, 0x00000000
-0, 12000, 12000, 0, 115200, 0x375ec573
-1, 2940, 2940, 1484, 5936, 0x00000000
-0, 18000, 18000, 0, 115200, 0x375ec573
-1, 4424, 4424, 1456, 5824, 0x00000000
-0, 24000, 24000, 0, 115200, 0x375ec573
-1, 5880, 5880, 1484, 5936, 0x00000000
-0, 30000, 30000, 0, 115200, 0x375ec573
-1, 7364, 7364, 1456, 5824, 0x00000000
-0, 36000, 36000, 0, 115200, 0x375ec573
-1, 8820, 8820, 1484, 5936, 0x00000000
-0, 42000, 42000, 0, 115200, 0x375ec573
-1, 10304, 10304, 1456, 5824, 0x0f06f5bb
-0, 48000, 48000, 0, 115200, 0x0b4d31bf
-1, 11760, 11760, 1484, 5936, 0xb0dbfc46
-0, 54000, 54000, 0, 115200, 0xdd724598
-1, 13244, 13244, 1456, 5824, 0x9daa9f9c
-0, 60000, 60000, 0, 115200, 0xc3077e75
-1, 14700, 14700, 1484, 5936, 0x61400d2f
-0, 66000, 66000, 0, 115200, 0xbf70778a
-1, 16184, 16184, 1456, 5824, 0x34a5b0e3
-0, 72000, 72000, 0, 115200, 0x117eb766
-1, 17640, 17640, 1484, 5936, 0x6e546f72
-0, 78000, 78000, 0, 115200, 0x4617fbad
-1, 19124, 19124, 1456, 5824, 0x4f093b35
-0, 84000, 84000, 0, 115200, 0x5f5b02d2
-1, 20580, 20580, 1484, 5936, 0x95b5b599
-0, 90000, 90000, 0, 115200, 0x2a9c5325
-1, 22064, 22064, 1456, 5824, 0x75e15e60
-0, 96000, 96000, 0, 115200, 0x14a89e2a
-1, 23520, 23520, 1484, 5936, 0xd1077d39
-0, 102000, 102000, 0, 115200, 0xe69aa994
-1, 25004, 25004, 1456, 5824, 0x956e21ca
-0, 108000, 108000, 0, 115200, 0xfbacf589
-1, 26460, 26460, 1484, 5936, 0x33bac234
-0, 114000, 114000, 0, 115200, 0x1d714c6e
-1, 27944, 27944, 1456, 5824, 0x5df37824
-0, 120000, 120000, 0, 115200, 0x6eff66cb
-1, 29400, 29400, 1484, 5936, 0xc174af24
-0, 126000, 126000, 0, 115200, 0xee21c1cb
-1, 30884, 30884, 1456, 5824, 0xe5dc2159
-0, 132000, 132000, 0, 115200, 0xce714ada
-1, 32340, 32340, 1484, 5936, 0x63ffc8b1
-0, 138000, 138000, 0, 115200, 0xf89d56c3
-1, 33824, 33824, 1456, 5824, 0xefe4c365
-0, 144000, 144000, 0, 115200, 0x65fd5e60
-1, 35280, 35280, 1484, 5936, 0x2174304d
-0, 150000, 150000, 0, 115200, 0x0c256424
diff --git a/tests/ref/fate/adpcm-ima-amv b/tests/ref/fate/adpcm-ima-amv
new file mode 100644
index 0000000..6c2fa32
--- /dev/null
+++ b/tests/ref/fate/adpcm-ima-amv
@@ -0,0 +1,161 @@
+#tb 0: 1/22050
+0, 0, 0, 1378, 2756, 0x0af35034
+0, 1378, 1378, 1378, 2756, 0x8462443f
+0, 2756, 2756, 1378, 2756, 0x9f493ba6
+0, 4134, 4134, 1378, 2756, 0x634e5f06
+0, 5513, 5513, 1380, 2760, 0x51f35cd4
+0, 6891, 6891, 1378, 2756, 0x011c51e5
+0, 8269, 8269, 1378, 2756, 0x8c2c198c
+0, 9647, 9647, 1378, 2756, 0x2b4a3397
+0, 11025, 11025, 1378, 2756, 0x63794f22
+0, 12403, 12403, 1378, 2756, 0xfc363898
+0, 13781, 13781, 1378, 2756, 0x0da5486e
+0, 15159, 15159, 1378, 2756, 0xbae17a5f
+0, 16538, 16538, 1380, 2760, 0xba266e1b
+0, 17916, 17916, 1378, 2756, 0xdfb61002
+0, 19294, 19294, 1378, 2756, 0x15d029da
+0, 20672, 20672, 1378, 2756, 0x7bc82012
+0, 22050, 22050, 1378, 2756, 0x002e6999
+0, 23428, 23428, 1378, 2756, 0x96346ba6
+0, 24806, 24806, 1378, 2756, 0x3d54543b
+0, 26184, 26184, 1380, 2760, 0x601786e1
+0, 27563, 27563, 1378, 2756, 0xf22a5793
+0, 28941, 28941, 1378, 2756, 0x21f54d49
+0, 30319, 30319, 1378, 2756, 0x0c6d4399
+0, 31697, 31697, 1378, 2756, 0x17282f8e
+0, 33075, 33075, 1378, 2756, 0xeb698f75
+0, 34453, 34453, 1378, 2756, 0x935e1de2
+0, 35831, 35831, 1380, 2760, 0xb6fb4293
+0, 37209, 37209, 1378, 2756, 0x485053dc
+0, 38588, 38588, 1378, 2756, 0x24c35027
+0, 39966, 39966, 1378, 2756, 0x09f323ee
+0, 41344, 41344, 1378, 2756, 0xbc7d58d5
+0, 42722, 42722, 1378, 2756, 0xaefd487c
+0, 44100, 44100, 1378, 2756, 0xaca16cc0
+0, 45478, 45478, 1380, 2760, 0x98a76091
+0, 46856, 46856, 1378, 2756, 0x5d357141
+0, 48234, 48234, 1378, 2756, 0x65ea2657
+0, 49613, 49613, 1378, 2756, 0xb5e1334a
+0, 50991, 50991, 1378, 2756, 0x32cd5d91
+0, 52369, 52369, 1378, 2756, 0xdc23722b
+0, 53747, 53747, 1378, 2756, 0x2ba34684
+0, 55125, 55125, 1378, 2756, 0xf9755ba8
+0, 56503, 56503, 1380, 2760, 0x24221ddb
+0, 57881, 57881, 1378, 2756, 0xef843aa4
+0, 59259, 59259, 1378, 2756, 0x420442fe
+0, 60638, 60638, 1378, 2756, 0x5a0933cb
+0, 62016, 62016, 1378, 2756, 0xef5f6d61
+0, 63394, 63394, 1378, 2756, 0xe57e6dc0
+0, 64772, 64772, 1378, 2756, 0xc0f0495a
+0, 66150, 66150, 1380, 2760, 0x2c3b55df
+0, 67528, 67528, 1378, 2756, 0x39c2586c
+0, 68906, 68906, 1378, 2756, 0x7ffc46e5
+0, 70284, 70284, 1378, 2756, 0xa2766664
+0, 71663, 71663, 1378, 2756, 0xacb50c6c
+0, 73041, 73041, 1378, 2756, 0x7f659084
+0, 74419, 74419, 1378, 2756, 0xc72e6a12
+0, 75797, 75797, 1380, 2760, 0xdb6944df
+0, 77175, 77175, 1378, 2756, 0x954f45c1
+0, 78553, 78553, 1378, 2756, 0xa9484240
+0, 79931, 79931, 1378, 2756, 0x1d595349
+0, 81309, 81309, 1378, 2756, 0xcf2a565e
+0, 82688, 82688, 1378, 2756, 0x391028d5
+0, 84066, 84066, 1378, 2756, 0x348db7ad
+0, 85444, 85444, 1380, 2760, 0xb69b5e3a
+0, 86822, 86822, 1378, 2756, 0xe3635fbe
+0, 88200, 88200, 1378, 2756, 0xdcad3654
+0, 89578, 89578, 1378, 2756, 0x5c17abef
+0, 90956, 90956, 1378, 2756, 0xb3235184
+0, 92334, 92334, 1378, 2756, 0xdabb64a6
+0, 93713, 93713, 1378, 2756, 0xa95dc58d
+0, 95091, 95091, 1380, 2760, 0x8e7ac9eb
+0, 96469, 96469, 1378, 2756, 0x492b658e
+0, 97847, 97847, 1378, 2756, 0x377483ab
+0, 99225, 99225, 1378, 2756, 0x2c250279
+0, 100603, 100603, 1378, 2756, 0x704dbdb3
+0, 101981, 101981, 1378, 2756, 0x800d7da2
+0, 103359, 103359, 1378, 2756, 0x872aa32e
+0, 104738, 104738, 1378, 2756, 0x2d4837fe
+0, 106116, 106116, 1380, 2760, 0xc89ea57e
+0, 107494, 107494, 1378, 2756, 0x6447d7ef
+0, 108872, 108872, 1378, 2756, 0x144f59cc
+0, 110250, 110250, 1378, 2756, 0xc667154e
+0, 111628, 111628, 1378, 2756, 0xf0de66ae
+0, 113006, 113006, 1378, 2756, 0xeabf3c32
+0, 114384, 114384, 1378, 2756, 0xe98e81d1
+0, 115763, 115763, 1380, 2760, 0x56aa5889
+0, 117141, 117141, 1378, 2756, 0x4fd34c0e
+0, 118519, 118519, 1378, 2756, 0x67cf6912
+0, 119897, 119897, 1378, 2756, 0xfa944def
+0, 121275, 121275, 1378, 2756, 0xc12f23b2
+0, 122653, 122653, 1378, 2756, 0x5ea325a2
+0, 124031, 124031, 1378, 2756, 0x2b245824
+0, 125409, 125409, 1380, 2760, 0x90ac533e
+0, 126788, 126788, 1378, 2756, 0xcca34d26
+0, 128166, 128166, 1378, 2756, 0xb5f820d0
+0, 129544, 129544, 1378, 2756, 0x27f24335
+0, 130922, 130922, 1378, 2756, 0x4a9e87b7
+0, 132300, 132300, 1378, 2756, 0xbd076129
+0, 133678, 133678, 1378, 2756, 0x2e0e3f2e
+0, 135056, 135056, 1380, 2760, 0xdf534478
+0, 136434, 136434, 1378, 2756, 0xca000a2e
+0, 137813, 137813, 1378, 2756, 0x87472df3
+0, 139191, 139191, 1378, 2756, 0x16733810
+0, 140569, 140569, 1378, 2756, 0xfa0734b4
+0, 141947, 141947, 1378, 2756, 0x5eff3fc4
+0, 143325, 143325, 1378, 2756, 0xf35346bd
+0, 144703, 144703, 1378, 2756, 0xac6411c5
+0, 146081, 146081, 1380, 2760, 0x478c3c56
+0, 147459, 147459, 1378, 2756, 0xebd30bdd
+0, 148838, 148838, 1378, 2756, 0xaef95a31
+0, 150216, 150216, 1378, 2756, 0x8aad29d1
+0, 151594, 151594, 1378, 2756, 0x626863f0
+0, 152972, 152972, 1378, 2756, 0x68c05707
+0, 154350, 154350, 1378, 2756, 0x437c5e8d
+0, 155728, 155728, 1380, 2760, 0x8eca4bdb
+0, 157106, 157106, 1378, 2756, 0x62bd4162
+0, 158484, 158484, 1378, 2756, 0x9f744aa4
+0, 159863, 159863, 1378, 2756, 0x0f3f6409
+0, 161241, 161241, 1378, 2756, 0x3fee827a
+0, 162619, 162619, 1378, 2756, 0x48a0ac19
+0, 163997, 163997, 1378, 2756, 0x8e4ce0d0
+0, 165375, 165375, 1380, 2760, 0xcda82236
+0, 166753, 166753, 1378, 2756, 0x0e523255
+0, 168131, 168131, 1378, 2756, 0x84103d30
+0, 169509, 169509, 1378, 2756, 0x13941cde
+0, 170888, 170888, 1378, 2756, 0x9fc834c5
+0, 172266, 172266, 1378, 2756, 0xc0217a77
+0, 173644, 173644, 1378, 2756, 0x3f643659
+0, 175022, 175022, 1380, 2760, 0x9dbd6002
+0, 176400, 176400, 1378, 2756, 0x94f046fb
+0, 177778, 177778, 1378, 2756, 0xab01fb12
+0, 179156, 179156, 1378, 2756, 0x04cffe5c
+0, 180534, 180534, 1378, 2756, 0xef661c5e
+0, 181913, 181913, 1378, 2756, 0x094c5fc5
+0, 183291, 183291, 1378, 2756, 0xe0c1486a
+0, 184669, 184669, 1380, 2760, 0x8c3535b7
+0, 186047, 186047, 1378, 2756, 0x594934aa
+0, 187425, 187425, 1378, 2756, 0x74007238
+0, 188803, 188803, 1378, 2756, 0x61f1394d
+0, 190181, 190181, 1378, 2756, 0x72584f07
+0, 191559, 191559, 1378, 2756, 0xced9acf9
+0, 192938, 192938, 1378, 2756, 0x7d2e3ea1
+0, 194316, 194316, 1378, 2756, 0x56c06897
+0, 195694, 195694, 1380, 2760, 0x19983bbf
+0, 197072, 197072, 1378, 2756, 0x4f884f27
+0, 198450, 198450, 1378, 2756, 0x81ab2f63
+0, 199828, 199828, 1378, 2756, 0x448e681d
+0, 201206, 201206, 1378, 2756, 0x0ba9826e
+0, 202584, 202584, 1378, 2756, 0x049f36fa
+0, 203963, 203963, 1378, 2756, 0x096a2b62
+0, 205341, 205341, 1380, 2760, 0x579e2035
+0, 206719, 206719, 1378, 2756, 0xd13e30e1
+0, 208097, 208097, 1378, 2756, 0x30b6412b
+0, 209475, 209475, 1378, 2756, 0xbb1c3268
+0, 210853, 210853, 1378, 2756, 0xbc175b6a
+0, 212231, 212231, 1378, 2756, 0xf8d160e2
+0, 213609, 213609, 1378, 2756, 0xc1048154
+0, 214988, 214988, 1380, 2760, 0xb83548f4
+0, 216366, 216366, 1378, 2756, 0x22647962
+0, 217744, 217744, 1378, 2756, 0x14ca54d3
+0, 219122, 219122, 1378, 2756, 0x58754b3a
diff --git a/tests/ref/fate/cryo-apc b/tests/ref/fate/adpcm-ima-apc
similarity index 100%
rename from tests/ref/fate/cryo-apc
rename to tests/ref/fate/adpcm-ima-apc
diff --git a/tests/ref/fate/adpcm-ima-ea-eacs b/tests/ref/fate/adpcm-ima-ea-eacs
new file mode 100644
index 0000000..9887296
--- /dev/null
+++ b/tests/ref/fate/adpcm-ima-ea-eacs
@@ -0,0 +1,48 @@
+#tb 0: 1/22050
+0, 0, 0, 1468, 5872, 0x00000000
+0, 1468, 1468, 1468, 5872, 0x00000000
+0, 2936, 2936, 1468, 5872, 0x00000000
+0, 4404, 4404, 1468, 5872, 0x00000000
+0, 5872, 5872, 1468, 5872, 0x00000000
+0, 7340, 7340, 1468, 5872, 0x00000000
+0, 8808, 8808, 1468, 5872, 0x00000000
+0, 10276, 10276, 1468, 5872, 0x00000000
+0, 11744, 11744, 1468, 5872, 0x00000000
+0, 13212, 13212, 1468, 5872, 0x00000000
+0, 14680, 14680, 1468, 5872, 0x00000000
+0, 16148, 16148, 1468, 5872, 0x00000000
+0, 17616, 17616, 1468, 5872, 0x00000000
+0, 19084, 19084, 1468, 5872, 0x00000000
+0, 20552, 20552, 1468, 5872, 0x00000000
+0, 22020, 22020, 1468, 5872, 0xc6f64777
+0, 23488, 23488, 1468, 5872, 0x7c9e60e8
+0, 24956, 24956, 1468, 5872, 0x46525c54
+0, 26424, 26424, 1468, 5872, 0x842796bb
+0, 27892, 27892, 1468, 5872, 0xb1f6cbd5
+0, 29360, 29360, 1468, 5872, 0x0261a74b
+0, 30828, 30828, 1468, 5872, 0x8218b1f9
+0, 32296, 32296, 1468, 5872, 0xd7a2cae6
+0, 33764, 33764, 1468, 5872, 0x69d34562
+0, 35232, 35232, 1468, 5872, 0x9303ec65
+0, 36700, 36700, 1468, 5872, 0xd5d963a1
+0, 38168, 38168, 1468, 5872, 0x0557e06f
+0, 39636, 39636, 1468, 5872, 0x1eb48b41
+0, 41104, 41104, 1468, 5872, 0x70f5ca3f
+0, 42572, 42572, 1468, 5872, 0xd39e5c5e
+0, 44040, 44040, 1468, 5872, 0x29c59140
+0, 45508, 45508, 1468, 5872, 0x7d95e643
+0, 46976, 46976, 1468, 5872, 0x45353fd8
+0, 48444, 48444, 1468, 5872, 0xad7b1b27
+0, 49912, 49912, 1468, 5872, 0x1f0377b3
+0, 51380, 51380, 1468, 5872, 0x6074541e
+0, 52848, 52848, 1468, 5872, 0xa4f5e892
+0, 54316, 54316, 1468, 5872, 0x084bc696
+0, 55784, 55784, 1468, 5872, 0x67fdafce
+0, 57252, 57252, 1468, 5872, 0x8dfd249d
+0, 58720, 58720, 1468, 5872, 0x514184ee
+0, 60188, 60188, 1468, 5872, 0xc0090b0d
+0, 61656, 61656, 1468, 5872, 0xc1171cc8
+0, 63124, 63124, 1468, 5872, 0x7d7dd07e
+0, 64592, 64592, 1468, 5872, 0xe6aa619c
+0, 66060, 66060, 1468, 5872, 0xd5aac0df
+0, 67528, 67528, 1468, 5872, 0x3b68b390
diff --git a/tests/ref/fate/adpcm-ima-ea-sead b/tests/ref/fate/adpcm-ima-ea-sead
new file mode 100644
index 0000000..17c1087
--- /dev/null
+++ b/tests/ref/fate/adpcm-ima-ea-sead
@@ -0,0 +1,50 @@
+#tb 0: 1/22050
+0, 0, 0, 736, 2944, 0x00000000
+0, 736, 736, 1472, 5888, 0x5ae3c2a4
+0, 2208, 2208, 1472, 5888, 0x158fbcb4
+0, 3680, 3680, 1472, 5888, 0x3fc85d35
+0, 5152, 5152, 1472, 5888, 0x4667ec2b
+0, 6624, 6624, 1472, 5888, 0x82744494
+0, 8096, 8096, 1472, 5888, 0x3b0cb86f
+0, 9568, 9568, 1472, 5888, 0x29493fbb
+0, 11040, 11040, 1472, 5888, 0xaa2d8595
+0, 12512, 12512, 1472, 5888, 0x2e563de6
+0, 13984, 13984, 1472, 5888, 0x225cca99
+0, 15456, 15456, 1472, 5888, 0x2b577599
+0, 16928, 16928, 1472, 5888, 0x3d967f32
+0, 18400, 18400, 1472, 5888, 0x16639a84
+0, 19872, 19872, 1472, 5888, 0x90549ba0
+0, 21344, 21344, 1472, 5888, 0xf46e6644
+0, 22816, 22816, 1472, 5888, 0x39a073ec
+0, 24288, 24288, 1472, 5888, 0xb1d7a93a
+0, 25760, 25760, 1472, 5888, 0x25e9795b
+0, 27232, 27232, 1472, 5888, 0xbbc07644
+0, 28704, 28704, 1472, 5888, 0x323f6a1b
+0, 30176, 30176, 1472, 5888, 0x7cae130b
+0, 31648, 31648, 1472, 5888, 0xd23bf9c6
+0, 33120, 33120, 1472, 5888, 0x5f73ef35
+0, 34592, 34592, 1472, 5888, 0xc66026be
+0, 36064, 36064, 1472, 5888, 0xc8fdb539
+0, 37536, 37536, 1472, 5888, 0x94c6bfbd
+0, 39008, 39008, 1472, 5888, 0xb77e1b83
+0, 40480, 40480, 1472, 5888, 0x6c6d6693
+0, 41952, 41952, 1472, 5888, 0xd9f064d4
+0, 43424, 43424, 1472, 5888, 0x85dd990d
+0, 44896, 44896, 1472, 5888, 0x385e021b
+0, 46368, 46368, 1472, 5888, 0xac09fd02
+0, 47840, 47840, 1472, 5888, 0xc6dcdff2
+0, 49312, 49312, 1472, 5888, 0x86a6944d
+0, 50784, 50784, 1472, 5888, 0x8587b964
+0, 52256, 52256, 1472, 5888, 0x2b0355ff
+0, 53728, 53728, 1472, 5888, 0xe4148a85
+0, 55200, 55200, 1472, 5888, 0xdf02ed4f
+0, 56672, 56672, 1472, 5888, 0x87a54b15
+0, 58144, 58144, 1472, 5888, 0x3ad2be45
+0, 59616, 59616, 1472, 5888, 0x3a49c2c3
+0, 61088, 61088, 1472, 5888, 0xc2b66404
+0, 62560, 62560, 1472, 5888, 0xac3e234a
+0, 64032, 64032, 1472, 5888, 0x5dcf523b
+0, 65504, 65504, 1472, 5888, 0x2034b5d6
+0, 66976, 66976, 1472, 5888, 0x96882832
+0, 68448, 68448, 1472, 5888, 0x2be3d534
+0, 69920, 69920, 1472, 5888, 0xa841a49d
diff --git a/tests/ref/fate/funcom-iss b/tests/ref/fate/adpcm-ima-iss
similarity index 100%
rename from tests/ref/fate/funcom-iss
rename to tests/ref/fate/adpcm-ima-iss
diff --git a/tests/ref/fate/adpcm-ima-smjpeg b/tests/ref/fate/adpcm-ima-smjpeg
new file mode 100644
index 0000000..45cb97b
--- /dev/null
+++ b/tests/ref/fate/adpcm-ima-smjpeg
@@ -0,0 +1,351 @@
+#tb 0: 1/22050
+0, 0, 0, 512, 1024, 0x00000000
+0, 507, 507, 512, 1024, 0x00000000
+0, 1014, 1014, 512, 1024, 0xd89a448e
+0, 1521, 1521, 512, 1024, 0x695b369c
+0, 2029, 2029, 512, 1024, 0xc8ba5707
+0, 2558, 2558, 512, 1024, 0xdf241fc6
+0, 3065, 3065, 512, 1024, 0x61cf4166
+0, 3572, 3572, 512, 1024, 0x97cbc386
+0, 4079, 4079, 512, 1024, 0x44899d04
+0, 4586, 4586, 512, 1024, 0xa7cbaa62
+0, 5116, 5116, 512, 1024, 0xa7aea60c
+0, 5623, 5623, 512, 1024, 0xd7b18a89
+0, 6130, 6130, 512, 1024, 0x268e81f6
+0, 6637, 6637, 512, 1024, 0x9cf83a2f
+0, 7166, 7166, 512, 1024, 0x5559b508
+0, 7673, 7673, 512, 1024, 0xe1b9e71c
+0, 8181, 8181, 512, 1024, 0xdcee733e
+0, 8688, 8688, 512, 1024, 0xe5918f60
+0, 9195, 9195, 512, 1024, 0x29dbd209
+0, 9724, 9724, 512, 1024, 0x9bcbcf16
+0, 10231, 10231, 512, 1024, 0x86f5f458
+0, 10738, 10738, 512, 1024, 0xabcbda86
+0, 11246, 11246, 512, 1024, 0xc51f77b9
+0, 11775, 11775, 512, 1024, 0xf6b3a504
+0, 12282, 12282, 512, 1024, 0x1af3e40e
+0, 12789, 12789, 512, 1024, 0x3866b03b
+0, 13296, 13296, 512, 1024, 0xbc005403
+0, 13803, 13803, 512, 1024, 0xe9dfcc51
+0, 14333, 14333, 512, 1024, 0x83c837cb
+0, 14840, 14840, 512, 1024, 0xfa649580
+0, 15347, 15347, 512, 1024, 0x519452ea
+0, 15854, 15854, 512, 1024, 0xd4978774
+0, 16383, 16383, 512, 1024, 0xe2a3b1cd
+0, 16890, 16890, 512, 1024, 0x9a9472ad
+0, 17397, 17397, 512, 1024, 0xa12d4060
+0, 17905, 17905, 512, 1024, 0x31fb0646
+0, 18412, 18412, 512, 1024, 0xfc44343f
+0, 18941, 18941, 512, 1024, 0x0847751a
+0, 19448, 19448, 512, 1024, 0x227968a2
+0, 19955, 19955, 512, 1024, 0x7cce9f1c
+0, 20462, 20462, 512, 1024, 0xb8356713
+0, 20992, 20992, 512, 1024, 0xb29f6e6f
+0, 21499, 21499, 512, 1024, 0x9e1430ab
+0, 22006, 22006, 512, 1024, 0x26d85423
+0, 22513, 22513, 512, 1024, 0x6496547d
+0, 23020, 23020, 512, 1024, 0x316b1a86
+0, 23549, 23549, 512, 1024, 0x3cd83afc
+0, 24057, 24057, 512, 1024, 0x993ff633
+0, 24564, 24564, 512, 1024, 0x0708d1a2
+0, 25071, 25071, 512, 1024, 0xd7230db9
+0, 25578, 25578, 512, 1024, 0xbb0779ca
+0, 26107, 26107, 512, 1024, 0xc6094e1b
+0, 26614, 26614, 512, 1024, 0x15a8b039
+0, 27122, 27122, 512, 1024, 0xd6dbe88c
+0, 27629, 27629, 512, 1024, 0x7e8d1140
+0, 28158, 28158, 512, 1024, 0xef88e525
+0, 28665, 28665, 512, 1024, 0x44e21149
+0, 29172, 29172, 512, 1024, 0x65b0f5f4
+0, 29679, 29679, 512, 1024, 0xb955f687
+0, 30186, 30186, 512, 1024, 0xc85fba9c
+0, 30716, 30716, 512, 1024, 0xf59655ad
+0, 31223, 31223, 512, 1024, 0x6de80bf1
+0, 31730, 31730, 512, 1024, 0x2dcf6e41
+0, 32237, 32237, 512, 1024, 0xd0ddcf8a
+0, 32766, 32766, 512, 1024, 0x00135c2d
+0, 33273, 33273, 512, 1024, 0x697f8efd
+0, 33781, 33781, 512, 1024, 0x7a9bada5
+0, 34288, 34288, 512, 1024, 0x0d22783c
+0, 34795, 34795, 512, 1024, 0x7726d07d
+0, 35324, 35324, 512, 1024, 0xa2f14f67
+0, 35831, 35831, 512, 1024, 0x7f51060d
+0, 36338, 36338, 512, 1024, 0xc4ec6aea
+0, 36846, 36846, 512, 1024, 0x9bb37ca4
+0, 37375, 37375, 512, 1024, 0x9b085577
+0, 37882, 37882, 512, 1024, 0x8812f8af
+0, 38389, 38389, 512, 1024, 0x788f5221
+0, 38896, 38896, 512, 1024, 0x3a2ce642
+0, 39403, 39403, 512, 1024, 0x72415692
+0, 39933, 39933, 512, 1024, 0xe3dcc105
+0, 40440, 40440, 512, 1024, 0xb26c0599
+0, 40947, 40947, 512, 1024, 0x5c9e55eb
+0, 41454, 41454, 512, 1024, 0x8fe88707
+0, 41983, 41983, 512, 1024, 0xc5d7beb6
+0, 42490, 42490, 512, 1024, 0xe1d3a3b4
+0, 42998, 42998, 512, 1024, 0x012da0c6
+0, 43505, 43505, 512, 1024, 0x8d010922
+0, 44012, 44012, 512, 1024, 0x3366eb0d
+0, 44541, 44541, 512, 1024, 0xc9381a27
+0, 45048, 45048, 512, 1024, 0x0774f685
+0, 45555, 45555, 512, 1024, 0xc5cae0a5
+0, 46062, 46062, 512, 1024, 0xa6f4737c
+0, 46592, 46592, 512, 1024, 0x8fb6d0d1
+0, 47099, 47099, 512, 1024, 0x05f579c2
+0, 47606, 47606, 512, 1024, 0x56905d99
+0, 48113, 48113, 512, 1024, 0x002ee18d
+0, 48620, 48620, 512, 1024, 0xeb37ef51
+0, 49149, 49149, 512, 1024, 0x38025635
+0, 49657, 49657, 512, 1024, 0x4fe643c8
+0, 50164, 50164, 512, 1024, 0x11d66ab1
+0, 50671, 50671, 512, 1024, 0xcc3051e9
+0, 51178, 51178, 512, 1024, 0xcd93e854
+0, 51707, 51707, 512, 1024, 0x38f1196d
+0, 52214, 52214, 512, 1024, 0x657a15fc
+0, 52722, 52722, 512, 1024, 0x669ce2a9
+0, 53229, 53229, 512, 1024, 0x95862dda
+0, 53758, 53758, 512, 1024, 0x1726a7b2
+0, 54265, 54265, 512, 1024, 0xd6ece2a1
+0, 54772, 54772, 512, 1024, 0x33ab9553
+0, 55279, 55279, 512, 1024, 0xd50c73a6
+0, 55787, 55787, 512, 1024, 0xfe25b63a
+0, 56316, 56316, 512, 1024, 0x7e2959e3
+0, 56823, 56823, 512, 1024, 0xa4c07b34
+0, 57330, 57330, 512, 1024, 0xd6d8f15c
+0, 57837, 57837, 512, 1024, 0x1eccddd7
+0, 58366, 58366, 512, 1024, 0x2b69f9cb
+0, 58874, 58874, 512, 1024, 0x667b775f
+0, 59381, 59381, 512, 1024, 0xad3b84e9
+0, 59888, 59888, 512, 1024, 0x4f29fc67
+0, 60395, 60395, 512, 1024, 0x8d611ab7
+0, 60924, 60924, 512, 1024, 0x278966ea
+0, 61431, 61431, 512, 1024, 0xaf33812b
+0, 61938, 61938, 512, 1024, 0xa55f4265
+0, 62446, 62446, 512, 1024, 0x023cb51c
+0, 62975, 62975, 512, 1024, 0x1d1f1005
+0, 63482, 63482, 512, 1024, 0x874cccf7
+0, 63989, 63989, 512, 1024, 0xda705428
+0, 64496, 64496, 512, 1024, 0x48d9b440
+0, 65003, 65003, 512, 1024, 0xa14e0712
+0, 65533, 65533, 512, 1024, 0x7efbad1f
+0, 66040, 66040, 512, 1024, 0xdb82c17f
+0, 66547, 66547, 512, 1024, 0xcbe87613
+0, 67054, 67054, 512, 1024, 0x3a63df1d
+0, 67583, 67583, 512, 1024, 0xd5636bba
+0, 68090, 68090, 512, 1024, 0x9397af23
+0, 68598, 68598, 512, 1024, 0x32a07c98
+0, 69105, 69105, 512, 1024, 0x202ca667
+0, 69612, 69612, 512, 1024, 0xdf969011
+0, 70141, 70141, 512, 1024, 0xc434d238
+0, 70648, 70648, 512, 1024, 0xe9ad7562
+0, 71155, 71155, 512, 1024, 0xb51b6b50
+0, 71663, 71663, 512, 1024, 0xe70aecd3
+0, 72192, 72192, 512, 1024, 0x03c816b2
+0, 72699, 72699, 512, 1024, 0x869fdf25
+0, 73206, 73206, 512, 1024, 0xd40a0a62
+0, 73713, 73713, 512, 1024, 0x5af7dd35
+0, 74220, 74220, 512, 1024, 0x891ffc72
+0, 74750, 74750, 512, 1024, 0x1ff68a08
+0, 75257, 75257, 512, 1024, 0x5a7517a9
+0, 75764, 75764, 512, 1024, 0x0f959f74
+0, 76271, 76271, 512, 1024, 0xe92a12a2
+0, 76778, 76778, 512, 1024, 0x38000e55
+0, 77307, 77307, 512, 1024, 0x39fbdd70
+0, 77814, 77814, 512, 1024, 0xca3d9184
+0, 78322, 78322, 512, 1024, 0x66c8995b
+0, 78829, 78829, 512, 1024, 0xac25acea
+0, 79358, 79358, 512, 1024, 0x3cd1046c
+0, 79865, 79865, 512, 1024, 0x6a1df31c
+0, 80372, 80372, 512, 1024, 0x21ca10a1
+0, 80879, 80879, 512, 1024, 0x1aeccedc
+0, 81387, 81387, 512, 1024, 0xddea1335
+0, 81916, 81916, 512, 1024, 0x19f5ca9f
+0, 82423, 82423, 512, 1024, 0x88e95e43
+0, 82930, 82930, 512, 1024, 0x726284fe
+0, 83437, 83437, 512, 1024, 0x6b85b40e
+0, 83966, 83966, 512, 1024, 0x111fee2a
+0, 84474, 84474, 512, 1024, 0x3656b588
+0, 84981, 84981, 512, 1024, 0xa5a2b552
+0, 85488, 85488, 512, 1024, 0x38fb2467
+0, 85995, 85995, 512, 1024, 0xaa919ccc
+0, 86524, 86524, 512, 1024, 0x15993dbc
+0, 87031, 87031, 512, 1024, 0xbe01a7b9
+0, 87539, 87539, 512, 1024, 0xefe93c09
+0, 88046, 88046, 512, 1024, 0x1bb566e5
+0, 88575, 88575, 512, 1024, 0x15ce6237
+0, 89082, 89082, 512, 1024, 0xa8552e66
+0, 89589, 89589, 512, 1024, 0x9d80187e
+0, 90096, 90096, 512, 1024, 0x5df3fc30
+0, 90603, 90603, 512, 1024, 0x1a312aa5
+0, 91133, 91133, 512, 1024, 0x6bb8e302
+0, 91640, 91640, 512, 1024, 0xbd9684bb
+0, 92147, 92147, 512, 1024, 0x78b0b166
+0, 92654, 92654, 512, 1024, 0xd9af5eae
+0, 93183, 93183, 512, 1024, 0xdb90fe82
+0, 93690, 93690, 512, 1024, 0x327614e9
+0, 94198, 94198, 512, 1024, 0x1f19b7fe
+0, 94705, 94705, 512, 1024, 0x46c53f96
+0, 95212, 95212, 512, 1024, 0x921b2189
+0, 95741, 95741, 512, 1024, 0xa8fbc85a
+0, 96248, 96248, 512, 1024, 0xabfdaaae
+0, 96755, 96755, 512, 1024, 0x6acc7387
+0, 97263, 97263, 512, 1024, 0x0d9c27b5
+0, 97792, 97792, 512, 1024, 0xba4dd809
+0, 98299, 98299, 512, 1024, 0x2a2ad521
+0, 98806, 98806, 512, 1024, 0x892de38a
+0, 99313, 99313, 512, 1024, 0xdc97a2eb
+0, 99820, 99820, 512, 1024, 0x4f614ca4
+0, 100350, 100350, 512, 1024, 0x9c8a77ea
+0, 100857, 100857, 512, 1024, 0x2d30e646
+0, 101364, 101364, 512, 1024, 0x74e800a7
+0, 101871, 101871, 512, 1024, 0x1e01fb02
+0, 102378, 102378, 512, 1024, 0x4ed2c1d8
+0, 102907, 102907, 512, 1024, 0xf2fdbe63
+0, 103415, 103415, 512, 1024, 0x8d6f63a1
+0, 103922, 103922, 512, 1024, 0xded468d9
+0, 104429, 104429, 512, 1024, 0xccad839e
+0, 104958, 104958, 512, 1024, 0xdde7c082
+0, 105465, 105465, 512, 1024, 0x548613c5
+0, 105972, 105972, 512, 1024, 0x383909bd
+0, 106479, 106479, 512, 1024, 0xfd37627b
+0, 106987, 106987, 512, 1024, 0x6d95a481
+0, 107516, 107516, 512, 1024, 0x56aa87fa
+0, 108023, 108023, 512, 1024, 0x7b67258c
+0, 108530, 108530, 512, 1024, 0x7dd99a92
+0, 109037, 109037, 512, 1024, 0x4a66d102
+0, 109566, 109566, 512, 1024, 0x7b3fce51
+0, 110074, 110074, 512, 1024, 0xbbd968aa
+0, 110581, 110581, 512, 1024, 0x8283ec36
+0, 111088, 111088, 512, 1024, 0x3c96493d
+0, 111595, 111595, 512, 1024, 0xfa4f8cf8
+0, 112124, 112124, 512, 1024, 0xe2cf872d
+0, 112631, 112631, 512, 1024, 0x0a9e7aa6
+0, 113139, 113139, 512, 1024, 0x6e7a0550
+0, 113646, 113646, 512, 1024, 0x3acfea2f
+0, 114175, 114175, 512, 1024, 0x7111d0fa
+0, 114682, 114682, 512, 1024, 0xe9a1eca9
+0, 115189, 115189, 512, 1024, 0x24da6c46
+0, 115696, 115696, 512, 1024, 0x117cff37
+0, 116204, 116204, 512, 1024, 0x0f27cab6
+0, 116733, 116733, 512, 1024, 0x69b6b4e6
+0, 117240, 117240, 512, 1024, 0x1e6cc841
+0, 117747, 117747, 512, 1024, 0xb01e2365
+0, 118254, 118254, 512, 1024, 0x14e200d3
+0, 118783, 118783, 512, 1024, 0xd1184c98
+0, 119291, 119291, 512, 1024, 0xef9140e9
+0, 119798, 119798, 512, 1024, 0x4cbb645e
+0, 120305, 120305, 512, 1024, 0xe7fe2f06
+0, 120812, 120812, 512, 1024, 0xf8c45028
+0, 121341, 121341, 512, 1024, 0x561358f4
+0, 121848, 121848, 512, 1024, 0xd0129b77
+0, 122355, 122355, 512, 1024, 0xcc636e88
+0, 122863, 122863, 512, 1024, 0xe9406321
+0, 123392, 123392, 512, 1024, 0x9f16a041
+0, 123899, 123899, 512, 1024, 0x468bf409
+0, 124406, 124406, 512, 1024, 0x3df70f7b
+0, 124913, 124913, 512, 1024, 0xa880b11b
+0, 125420, 125420, 512, 1024, 0x3286c489
+0, 125950, 125950, 512, 1024, 0x39fe9ebc
+0, 126457, 126457, 512, 1024, 0xc533d83b
+0, 126964, 126964, 512, 1024, 0x153b195d
+0, 127471, 127471, 512, 1024, 0xd84786a1
+0, 127978, 127978, 512, 1024, 0xdc295aaa
+0, 128507, 128507, 512, 1024, 0xfb764d8c
+0, 129015, 129015, 512, 1024, 0xeebc9db9
+0, 129522, 129522, 512, 1024, 0x7ba9403e
+0, 130029, 130029, 512, 1024, 0x4e5571ec
+0, 130558, 130558, 512, 1024, 0xd965fad4
+0, 131065, 131065, 512, 1024, 0x87e259f2
+0, 131572, 131572, 512, 1024, 0xae7e533b
+0, 132080, 132080, 512, 1024, 0x313cf4d6
+0, 132587, 132587, 512, 1024, 0xe1844c90
+0, 133116, 133116, 512, 1024, 0xbb057b44
+0, 133623, 133623, 512, 1024, 0xa5099687
+0, 134130, 134130, 512, 1024, 0xbff10707
+0, 134637, 134637, 512, 1024, 0x37c4ffc0
+0, 135167, 135167, 512, 1024, 0xf9fb6caa
+0, 135674, 135674, 512, 1024, 0x3b6a3a1f
+0, 136181, 136181, 512, 1024, 0x83431edb
+0, 136688, 136688, 512, 1024, 0x1eb713cf
+0, 137195, 137195, 512, 1024, 0xd7b07a6d
+0, 137724, 137724, 512, 1024, 0x81ae3391
+0, 138231, 138231, 512, 1024, 0xf150130a
+0, 138739, 138739, 512, 1024, 0x09678eaa
+0, 139246, 139246, 512, 1024, 0xb94e06f1
+0, 139775, 139775, 512, 1024, 0x67b1dbc9
+0, 140282, 140282, 512, 1024, 0xd6edc235
+0, 140789, 140789, 512, 1024, 0x34e4c499
+0, 141296, 141296, 512, 1024, 0xeefd89c0
+0, 141804, 141804, 512, 1024, 0x38afdaf1
+0, 142333, 142333, 512, 1024, 0x29a60d76
+0, 142840, 142840, 512, 1024, 0xe28a4372
+0, 143347, 143347, 512, 1024, 0x7089454d
+0, 143854, 143854, 512, 1024, 0x0c01bb7b
+0, 144383, 144383, 512, 1024, 0xbd776a72
+0, 144891, 144891, 512, 1024, 0x86776fd0
+0, 145398, 145398, 512, 1024, 0xb37c88f7
+0, 145905, 145905, 512, 1024, 0x5f90aaf8
+0, 146412, 146412, 512, 1024, 0x203d4222
+0, 146941, 146941, 512, 1024, 0x382692a6
+0, 147448, 147448, 512, 1024, 0xf37c95fd
+0, 147956, 147956, 512, 1024, 0x6c0b8877
+0, 148463, 148463, 512, 1024, 0x2e54a8b6
+0, 148992, 148992, 512, 1024, 0x7f266488
+0, 149499, 149499, 512, 1024, 0xfbf20f9a
+0, 150006, 150006, 512, 1024, 0xf2985cc0
+0, 150513, 150513, 512, 1024, 0xc7075340
+0, 151020, 151020, 512, 1024, 0xe4585695
+0, 151550, 151550, 512, 1024, 0xbdffa380
+0, 152057, 152057, 512, 1024, 0x2422a8a9
+0, 152564, 152564, 512, 1024, 0x59cbd75f
+0, 153071, 153071, 512, 1024, 0x04ad1a8c
+0, 153578, 153578, 512, 1024, 0x33c09191
+0, 154107, 154107, 512, 1024, 0x55efa6fd
+0, 154615, 154615, 512, 1024, 0xf73d0e5d
+0, 155122, 155122, 512, 1024, 0x6141ebae
+0, 155629, 155629, 512, 1024, 0x7db17a68
+0, 156158, 156158, 512, 1024, 0xa6c690b6
+0, 156665, 156665, 512, 1024, 0xa6fd6725
+0, 157172, 157172, 512, 1024, 0x50a90b9b
+0, 157680, 157680, 512, 1024, 0xef990dc8
+0, 158187, 158187, 512, 1024, 0x75adf6b5
+0, 158716, 158716, 512, 1024, 0x61eac43e
+0, 159223, 159223, 512, 1024, 0x67797a19
+0, 159730, 159730, 512, 1024, 0xf325277a
+0, 160237, 160237, 512, 1024, 0x18bf254a
+0, 160767, 160767, 512, 1024, 0x2ce6bee3
+0, 161274, 161274, 512, 1024, 0x8d320860
+0, 161781, 161781, 512, 1024, 0xc979b6e8
+0, 162288, 162288, 512, 1024, 0xdb644b41
+0, 162795, 162795, 512, 1024, 0xe1b368ba
+0, 163324, 163324, 512, 1024, 0xacc53d15
+0, 163832, 163832, 512, 1024, 0x42ea8c18
+0, 164339, 164339, 512, 1024, 0xe52c99a4
+0, 164846, 164846, 512, 1024, 0xd7db54a6
+0, 165375, 165375, 512, 1024, 0x7f27a7e3
+0, 165882, 165882, 512, 1024, 0xf7ffeaa9
+0, 166389, 166389, 512, 1024, 0x792b6088
+0, 166896, 166896, 512, 1024, 0x61d99724
+0, 167404, 167404, 512, 1024, 0x5213720e
+0, 167933, 167933, 512, 1024, 0xac09dd30
+0, 168440, 168440, 512, 1024, 0x960bf6bb
+0, 168947, 168947, 512, 1024, 0xc90168e1
+0, 169454, 169454, 512, 1024, 0x43b45768
+0, 169983, 169983, 512, 1024, 0x935d60a1
+0, 170491, 170491, 512, 1024, 0x9a342ef2
+0, 170998, 170998, 512, 1024, 0xc894709f
+0, 171505, 171505, 512, 1024, 0x59b43b07
+0, 172012, 172012, 512, 1024, 0x36a1a98d
+0, 172541, 172541, 512, 1024, 0x9e1a121c
+0, 173048, 173048, 512, 1024, 0x02208b78
+0, 173556, 173556, 512, 1024, 0xd1d7b274
+0, 174063, 174063, 512, 1024, 0xdacd5096
+0, 174592, 174592, 512, 1024, 0x51b71ead
+0, 175099, 175099, 512, 1024, 0xd009a7ca
+0, 175606, 175606, 512, 1024, 0xb6d5a938
+0, 176113, 176113, 512, 1024, 0xf3d45e47
+0, 176621, 176621, 512, 1024, 0xea8e04fc
+0, 177150, 177150, 512, 1024, 0x0b928bd8
+0, 177657, 177657, 512, 1024, 0x0f02caec
+0, 178164, 178164, 512, 1024, 0xe2b137a8
+0, 178671, 178671, 512, 1024, 0xd5f94892
diff --git a/tests/ref/fate/adpcm-ima-ws b/tests/ref/fate/adpcm-ima-ws
new file mode 100644
index 0000000..61e0def
--- /dev/null
+++ b/tests/ref/fate/adpcm-ima-ws
@@ -0,0 +1,41 @@
+#tb 0: 1/22050
+0, 0, 0, 11024, 22048, 0x0665d7f4
+0, 11024, 11024, 1470, 2940, 0x0f3c64cb
+0, 12494, 12494, 1470, 2940, 0xc90b9e78
+0, 13964, 13964, 1470, 2940, 0x146246a3
+0, 15434, 15434, 1470, 2940, 0xd22c714e
+0, 16904, 16904, 1470, 2940, 0xd86b681e
+0, 18374, 18374, 1470, 2940, 0x12ec8186
+0, 19844, 19844, 1470, 2940, 0x69aa85b6
+0, 21314, 21314, 1470, 2940, 0xb24d33b0
+0, 22784, 22784, 1470, 2940, 0x3f7b0f0d
+0, 24254, 24254, 1470, 2940, 0x64f10f7e
+0, 25724, 25724, 1470, 2940, 0xd6ea379a
+0, 27194, 27194, 1470, 2940, 0x7c38e830
+0, 28664, 28664, 1470, 2940, 0xc28ff132
+0, 30134, 30134, 1470, 2940, 0xe7b11629
+0, 31604, 31604, 1470, 2940, 0xeb86fdcb
+0, 33074, 33074, 1470, 2940, 0x5508f586
+0, 34544, 34544, 1470, 2940, 0xf4fa1f1b
+0, 36014, 36014, 1470, 2940, 0x9e5ff976
+0, 37484, 37484, 1470, 2940, 0xcfc4e08f
+0, 38954, 38954, 1470, 2940, 0x74bde7ed
+0, 40424, 40424, 1470, 2940, 0x3e4ae245
+0, 41894, 41894, 1470, 2940, 0x4c6a8e56
+0, 43364, 43364, 1470, 2940, 0xa09d86ab
+0, 44834, 44834, 1470, 2940, 0xc8531912
+0, 46304, 46304, 1470, 2940, 0xa5f266aa
+0, 47774, 47774, 1470, 2940, 0x587a4187
+0, 49244, 49244, 1470, 2940, 0x14752d45
+0, 50714, 50714, 1470, 2940, 0x558cde10
+0, 52184, 52184, 1470, 2940, 0x735fee38
+0, 53654, 53654, 1470, 2940, 0xac8bb6c8
+0, 55124, 55124, 1470, 2940, 0xa503c73b
+0, 56594, 56594, 1470, 2940, 0x7cd588a3
+0, 58064, 58064, 1470, 2940, 0xa6974b04
+0, 59534, 59534, 1470, 2940, 0xbf448241
+0, 61004, 61004, 1470, 2940, 0x2a5c2759
+0, 62474, 62474, 1470, 2940, 0xd0de5ce0
+0, 63944, 63944, 1470, 2940, 0xc0486649
+0, 65414, 65414, 1470, 2940, 0x48b040af
+0, 66884, 66884, 1470, 2940, 0x82a338a9
diff --git a/tests/ref/fate/adpcm-ms-mono b/tests/ref/fate/adpcm-ms-mono
new file mode 100644
index 0000000..3bf44f8
--- /dev/null
+++ b/tests/ref/fate/adpcm-ms-mono
@@ -0,0 +1,46 @@
+#tb 0: 1/11025
+0, 0, 0, 500, 1000, 0x64cd9403
+0, 500, 500, 500, 1000, 0xa4ef8a9d
+0, 1000, 1000, 500, 1000, 0x75c19868
+0, 1500, 1500, 500, 1000, 0x93db6f79
+0, 2000, 2000, 500, 1000, 0x6835625d
+0, 2500, 2500, 500, 1000, 0xb3affa8f
+0, 3000, 3000, 500, 1000, 0x159fdcc8
+0, 3500, 3500, 500, 1000, 0x79f9f7f1
+0, 4000, 4000, 500, 1000, 0xd7d1131e
+0, 4500, 4500, 500, 1000, 0x52a6f797
+0, 5000, 5000, 500, 1000, 0x748202ca
+0, 5500, 5500, 500, 1000, 0x0ef92449
+0, 6000, 6000, 500, 1000, 0x6a3760ab
+0, 6500, 6500, 500, 1000, 0xce5c5abf
+0, 7000, 7000, 500, 1000, 0x23396792
+0, 7500, 7500, 500, 1000, 0xa5276238
+0, 8000, 8000, 500, 1000, 0x288adf1b
+0, 8500, 8500, 500, 1000, 0xe7de6fb2
+0, 9000, 9000, 500, 1000, 0x2c2c707f
+0, 9500, 9500, 500, 1000, 0xd66d6daf
+0, 10000, 10000, 500, 1000, 0xbcea7d64
+0, 10500, 10500, 500, 1000, 0x766feea5
+0, 11000, 11000, 500, 1000, 0xd2e1d63a
+0, 11500, 11500, 500, 1000, 0x2f7ef4ed
+0, 12000, 12000, 500, 1000, 0xb655cba4
+0, 12500, 12500, 500, 1000, 0x4507d37b
+0, 13000, 13000, 500, 1000, 0x0c57f794
+0, 13500, 13500, 500, 1000, 0x0ecbe5cc
+0, 14000, 14000, 500, 1000, 0x9bf6e345
+0, 14500, 14500, 500, 1000, 0xc461443c
+0, 15000, 15000, 500, 1000, 0xad9657bf
+0, 15500, 15500, 500, 1000, 0x466fe91c
+0, 16000, 16000, 500, 1000, 0x9ee377fe
+0, 16500, 16500, 500, 1000, 0x09956428
+0, 17000, 17000, 500, 1000, 0x9b285f0a
+0, 17500, 17500, 500, 1000, 0x0a3e61a6
+0, 18000, 18000, 500, 1000, 0xacc25d6b
+0, 18500, 18500, 500, 1000, 0x377be319
+0, 19000, 19000, 500, 1000, 0xe4890504
+0, 19500, 19500, 500, 1000, 0xe90a6497
+0, 20000, 20000, 500, 1000, 0xd00fe950
+0, 20500, 20500, 500, 1000, 0xf195eb44
+0, 21000, 21000, 500, 1000, 0xa491f3ef
+0, 21500, 21500, 500, 1000, 0x2c036e18
+0, 22000, 22000, 500, 1000, 0x52d65e2a
diff --git a/tests/ref/fate/adpcm-thp b/tests/ref/fate/adpcm-thp
index 135de54..72aff61 100644
--- a/tests/ref/fate/adpcm-thp
+++ b/tests/ref/fate/adpcm-thp
@@ -1,145 +1,72 @@
-#tb 0: 524288/15712911
-#tb 1: 1/32000
-0, 0, 0, 1, 291840, 0xbd7e0b22
-1, 0, 0, 1078, 4312, 0x469714f6
-0, 1, 1, 1, 291840, 0xf6e12ca5
-1, 1078, 1078, 1064, 4256, 0xe03dd882
-0, 2, 2, 1, 291840, 0x528c7049
-1, 2142, 2142, 1078, 4312, 0x46b901f7
-0, 3, 3, 1, 291840, 0x93055de9
-1, 3220, 3220, 1064, 4256, 0x8d4a54e4
-0, 4, 4, 1, 291840, 0xf95a51c1
-1, 4284, 4284, 1064, 4256, 0xfd616b67
-0, 5, 5, 1, 291840, 0x6ad3a65a
-1, 5348, 5348, 1078, 4312, 0xefe62302
-0, 6, 6, 1, 291840, 0x494684a7
-1, 6426, 6426, 1064, 4256, 0xab11684e
-0, 7, 7, 1, 291840, 0x74c14eb1
-1, 7490, 7490, 1064, 4256, 0xb4b3feb8
-0, 8, 8, 1, 291840, 0x149fcb7e
-1, 8554, 8554, 1078, 4312, 0x71db6461
-0, 9, 9, 1, 291840, 0x25649761
-1, 9632, 9632, 1064, 4256, 0x090e5efa
-0, 10, 10, 1, 291840, 0xbc3f9052
-1, 10696, 10696, 1064, 4256, 0x36f49c28
-0, 11, 11, 1, 291840, 0x080edfff
-1, 11760, 11760, 1078, 4312, 0x0fe3d262
-0, 12, 12, 1, 291840, 0x6d7ad684
-1, 12838, 12838, 1064, 4256, 0x199ce269
-0, 13, 13, 1, 291840, 0x6d53844d
-1, 13902, 13902, 1064, 4256, 0x98342d05
-0, 14, 14, 1, 291840, 0xf7ad5385
-1, 14966, 14966, 1078, 4312, 0xb6fb7ebe
-0, 15, 15, 1, 291840, 0x0241b56a
-1, 16044, 16044, 1064, 4256, 0x033dd562
-0, 16, 16, 1, 291840, 0x120122c8
-1, 17108, 17108, 1064, 4256, 0xc2cc17e0
-0, 17, 17, 1, 291840, 0x31b0f32a
-1, 18172, 18172, 1078, 4312, 0x4bb3ff50
-0, 18, 18, 1, 291840, 0x14068b98
-1, 19250, 19250, 1064, 4256, 0x6f2671ef
-0, 19, 19, 1, 291840, 0xeeec658b
-1, 20314, 20314, 1064, 4256, 0x5a337bf4
-0, 20, 20, 1, 291840, 0x9376374c
-1, 21378, 21378, 1078, 4312, 0xa71f6967
-0, 21, 21, 1, 291840, 0x091e8c6e
-1, 22456, 22456, 1064, 4256, 0x48084aa9
-0, 22, 22, 1, 291840, 0x744ad07f
-1, 23520, 23520, 1064, 4256, 0x3cce4218
-0, 23, 23, 1, 291840, 0xf99c554e
-1, 24584, 24584, 1078, 4312, 0xcbb8f73d
-0, 24, 24, 1, 291840, 0xc84bd677
-1, 25662, 25662, 1064, 4256, 0x36825021
-0, 25, 25, 1, 291840, 0x3898d474
-1, 26726, 26726, 1064, 4256, 0xeae036c6
-0, 26, 26, 1, 291840, 0x1e2910c8
-1, 27790, 27790, 1078, 4312, 0x0d650ac6
-0, 27, 27, 1, 291840, 0xb11f58bc
-1, 28868, 28868, 1064, 4256, 0xfba4f58c
-0, 28, 28, 1, 291840, 0xf89170ee
-1, 29932, 29932, 1064, 4256, 0x54311f9b
-0, 29, 29, 1, 291840, 0x8f239dc3
-1, 30996, 30996, 1078, 4312, 0x286386b3
-0, 30, 30, 1, 291840, 0x8538c76c
-1, 32074, 32074, 1064, 4256, 0x871896de
-0, 31, 31, 1, 291840, 0x162ee66f
-1, 33138, 33138, 1064, 4256, 0x9ef9f970
-0, 32, 32, 1, 291840, 0x5f8708a5
-1, 34202, 34202, 1078, 4312, 0xf9ae97f1
-0, 33, 33, 1, 291840, 0x95802dfb
-1, 35280, 35280, 1064, 4256, 0x0ad0d765
-0, 34, 34, 1, 291840, 0xc424630d
-1, 36344, 36344, 1064, 4256, 0x8e6aa9b5
-0, 35, 35, 1, 291840, 0xfb8a8667
-1, 37408, 37408, 1078, 4312, 0x8362787b
-0, 36, 36, 1, 291840, 0xbad79af5
-1, 38486, 38486, 1064, 4256, 0x9b6a5d9c
-0, 37, 37, 1, 291840, 0xc733b325
-1, 39550, 39550, 1064, 4256, 0xfb715d8f
-0, 38, 38, 1, 291840, 0x4bfbcd70
-1, 40614, 40614, 1078, 4312, 0x02bd8075
-0, 39, 39, 1, 291840, 0x502cd950
-1, 41692, 41692, 1064, 4256, 0x428eb932
-0, 40, 40, 1, 291840, 0x8461ca2c
-1, 42756, 42756, 1064, 4256, 0x17ea8c94
-0, 41, 41, 1, 291840, 0x00219b0d
-1, 43820, 43820, 1078, 4312, 0xb3e761d7
-0, 42, 42, 1, 291840, 0xa4de45e1
-1, 44898, 44898, 1064, 4256, 0x0919755a
-0, 43, 43, 1, 291840, 0xacd3f4df
-1, 45962, 45962, 1064, 4256, 0x5e520edd
-0, 44, 44, 1, 291840, 0x2203a369
-1, 47026, 47026, 1078, 4312, 0x69aa070e
-0, 45, 45, 1, 291840, 0x0a66effa
-1, 48104, 48104, 1064, 4256, 0xf8192f7d
-0, 46, 46, 1, 291840, 0x7ac1fd91
-1, 49168, 49168, 1064, 4256, 0xaad4475c
-0, 47, 47, 1, 291840, 0x84970aa7
-1, 50232, 50232, 1078, 4312, 0x0cabcfcb
-0, 48, 48, 1, 291840, 0x569d145f
-1, 51310, 51310, 1064, 4256, 0x952f0f96
-0, 49, 49, 1, 291840, 0xe51efe1b
-1, 52374, 52374, 1064, 4256, 0x1b805a0c
-0, 50, 50, 1, 291840, 0x38e2cd78
-1, 53438, 53438, 1078, 4312, 0x93043d2a
-0, 51, 51, 1, 291840, 0x93428ea2
-1, 54516, 54516, 1064, 4256, 0x38b99e44
-0, 52, 52, 1, 291840, 0x3d3f5b17
-1, 55580, 55580, 1064, 4256, 0x60cc52ff
-0, 53, 53, 1, 291840, 0x9546127d
-1, 56644, 56644, 1078, 4312, 0x6a875849
-0, 54, 54, 1, 291840, 0x4178be54
-1, 57722, 57722, 1064, 4256, 0xd08d6d0e
-0, 55, 55, 1, 291840, 0x0d0f8036
-1, 58786, 58786, 1064, 4256, 0x36bfe48e
-0, 56, 56, 1, 291840, 0xc20557b9
-1, 59850, 59850, 1078, 4312, 0x795c6134
-0, 57, 57, 1, 291840, 0x6d4b2d64
-1, 60928, 60928, 1064, 4256, 0x4fd79583
-0, 58, 58, 1, 291840, 0xa750125d
-1, 61992, 61992, 1064, 4256, 0x65e2ab9f
-0, 59, 59, 1, 291840, 0x04623ce3
-1, 63056, 63056, 1078, 4312, 0xedeede4a
-0, 60, 60, 1, 291840, 0xc7f2bbc7
-1, 64134, 64134, 1064, 4256, 0x097e0d09
-0, 61, 61, 1, 291840, 0x6e271336
-1, 65198, 65198, 1064, 4256, 0x58afa133
-0, 62, 62, 1, 291840, 0xcfbd4246
-1, 66262, 66262, 1078, 4312, 0x442525b5
-0, 63, 63, 1, 291840, 0xe1493be9
-1, 67340, 67340, 1064, 4256, 0x6645c591
-0, 64, 64, 1, 291840, 0x6c731194
-1, 68404, 68404, 1064, 4256, 0xb0dd948a
-0, 65, 65, 1, 291840, 0x0fc30cc2
-1, 69468, 69468, 1078, 4312, 0x12684e69
-0, 66, 66, 1, 291840, 0x967427f3
-1, 70546, 70546, 1064, 4256, 0xb45098e3
-0, 67, 67, 1, 291840, 0x55ae3b00
-1, 71610, 71610, 1064, 4256, 0xb6d3c61c
-0, 68, 68, 1, 291840, 0xbe4f200c
-1, 72674, 72674, 1078, 4312, 0xb46b5b22
-0, 69, 69, 1, 291840, 0xc515e443
-1, 73752, 73752, 1064, 4256, 0x9a556830
-0, 70, 70, 1, 291840, 0xd738bd69
-1, 74816, 74816, 1064, 4256, 0x67ca2b35
-0, 71, 71, 1, 291840, 0xa8e0ab69
+#tb 0: 1/32000
+0, 0, 0, 1078, 4312, 0x469714f6
+0, 1078, 1078, 1064, 4256, 0xe03dd882
+0, 2142, 2142, 1078, 4312, 0x46b901f7
+0, 3220, 3220, 1064, 4256, 0x8d4a54e4
+0, 4284, 4284, 1064, 4256, 0xfd616b67
+0, 5348, 5348, 1078, 4312, 0xefe62302
+0, 6426, 6426, 1064, 4256, 0xab11684e
+0, 7490, 7490, 1064, 4256, 0xb4b3feb8
+0, 8554, 8554, 1078, 4312, 0x71db6461
+0, 9632, 9632, 1064, 4256, 0x090e5efa
+0, 10696, 10696, 1064, 4256, 0x36f49c28
+0, 11760, 11760, 1078, 4312, 0x0fe3d262
+0, 12838, 12838, 1064, 4256, 0x199ce269
+0, 13902, 13902, 1064, 4256, 0x98342d05
+0, 14966, 14966, 1078, 4312, 0xb6fb7ebe
+0, 16044, 16044, 1064, 4256, 0x033dd562
+0, 17108, 17108, 1064, 4256, 0xc2cc17e0
+0, 18172, 18172, 1078, 4312, 0x4bb3ff50
+0, 19250, 19250, 1064, 4256, 0x6f2671ef
+0, 20314, 20314, 1064, 4256, 0x5a337bf4
+0, 21378, 21378, 1078, 4312, 0xa71f6967
+0, 22456, 22456, 1064, 4256, 0x48084aa9
+0, 23520, 23520, 1064, 4256, 0x3cce4218
+0, 24584, 24584, 1078, 4312, 0xcbb8f73d
+0, 25662, 25662, 1064, 4256, 0x36825021
+0, 26726, 26726, 1064, 4256, 0xeae036c6
+0, 27790, 27790, 1078, 4312, 0x0d650ac6
+0, 28868, 28868, 1064, 4256, 0xfba4f58c
+0, 29932, 29932, 1064, 4256, 0x54311f9b
+0, 30996, 30996, 1078, 4312, 0x286386b3
+0, 32074, 32074, 1064, 4256, 0x871896de
+0, 33138, 33138, 1064, 4256, 0x9ef9f970
+0, 34202, 34202, 1078, 4312, 0xf9ae97f1
+0, 35280, 35280, 1064, 4256, 0x0ad0d765
+0, 36344, 36344, 1064, 4256, 0x8e6aa9b5
+0, 37408, 37408, 1078, 4312, 0x8362787b
+0, 38486, 38486, 1064, 4256, 0x9b6a5d9c
+0, 39550, 39550, 1064, 4256, 0xfb715d8f
+0, 40614, 40614, 1078, 4312, 0x02bd8075
+0, 41692, 41692, 1064, 4256, 0x428eb932
+0, 42756, 42756, 1064, 4256, 0x17ea8c94
+0, 43820, 43820, 1078, 4312, 0xb3e761d7
+0, 44898, 44898, 1064, 4256, 0x0919755a
+0, 45962, 45962, 1064, 4256, 0x5e520edd
+0, 47026, 47026, 1078, 4312, 0x69aa070e
+0, 48104, 48104, 1064, 4256, 0xf8192f7d
+0, 49168, 49168, 1064, 4256, 0xaad4475c
+0, 50232, 50232, 1078, 4312, 0x0cabcfcb
+0, 51310, 51310, 1064, 4256, 0x952f0f96
+0, 52374, 52374, 1064, 4256, 0x1b805a0c
+0, 53438, 53438, 1078, 4312, 0x93043d2a
+0, 54516, 54516, 1064, 4256, 0x38b99e44
+0, 55580, 55580, 1064, 4256, 0x60cc52ff
+0, 56644, 56644, 1078, 4312, 0x6a875849
+0, 57722, 57722, 1064, 4256, 0xd08d6d0e
+0, 58786, 58786, 1064, 4256, 0x36bfe48e
+0, 59850, 59850, 1078, 4312, 0x795c6134
+0, 60928, 60928, 1064, 4256, 0x4fd79583
+0, 61992, 61992, 1064, 4256, 0x65e2ab9f
+0, 63056, 63056, 1078, 4312, 0xedeede4a
+0, 64134, 64134, 1064, 4256, 0x097e0d09
+0, 65198, 65198, 1064, 4256, 0x58afa133
+0, 66262, 66262, 1078, 4312, 0x442525b5
+0, 67340, 67340, 1064, 4256, 0x6645c591
+0, 68404, 68404, 1064, 4256, 0xb0dd948a
+0, 69468, 69468, 1078, 4312, 0x12684e69
+0, 70546, 70546, 1064, 4256, 0xb45098e3
+0, 71610, 71610, 1064, 4256, 0xb6d3c61c
+0, 72674, 72674, 1078, 4312, 0xb46b5b22
+0, 73752, 73752, 1064, 4256, 0x9a556830
+0, 74816, 74816, 1064, 4256, 0x67ca2b35
diff --git a/tests/ref/fate/adpcm-psx-str-v3 b/tests/ref/fate/adpcm-xa
similarity index 100%
rename from tests/ref/fate/adpcm-psx-str-v3
rename to tests/ref/fate/adpcm-xa
diff --git a/tests/ref/fate/amv b/tests/ref/fate/amv
index 768ddaf..407f077 100644
--- a/tests/ref/fate/amv
+++ b/tests/ref/fate/amv
@@ -1,322 +1,161 @@
#tb 0: 1/16
-#tb 1: 1/22050
0, 0, 0, 1, 28800, 0x026058a9
-1, 0, 0, 1378, 2756, 0x0af35034
-1, 1378, 1378, 1378, 2756, 0x8462443f
0, 1, 1, 1, 28800, 0x5dc728de
-1, 2756, 2756, 1378, 2756, 0x9f493ba6
0, 2, 2, 1, 28800, 0x83e19a2c
-1, 4134, 4134, 1378, 2756, 0x634e5f06
0, 3, 3, 1, 28800, 0xb029f94a
-1, 5512, 5512, 1380, 2760, 0x51f35cd4
0, 4, 4, 1, 28800, 0x735a6b15
0, 5, 5, 1, 28800, 0xf7e9dc8b
-1, 6891, 6891, 1378, 2756, 0x011c51e5
0, 6, 6, 1, 28800, 0xa108b0cf
-1, 8269, 8269, 1378, 2756, 0x8c2c198c
0, 7, 7, 1, 28800, 0x3d11c138
-1, 9647, 9647, 1378, 2756, 0x2b4a3397
0, 8, 8, 1, 28800, 0xed23afda
-1, 11025, 11025, 1378, 2756, 0x63794f22
-1, 12403, 12403, 1378, 2756, 0xfc363898
0, 9, 9, 1, 28800, 0x713bb2dc
-1, 13781, 13781, 1378, 2756, 0x0da5486e
0, 10, 10, 1, 28800, 0x551ad51e
-1, 15159, 15159, 1378, 2756, 0xbae17a5f
0, 11, 11, 1, 28800, 0x49dfcf2d
0, 12, 12, 1, 28800, 0x6399d5b3
-1, 16538, 16538, 1380, 2760, 0xba266e1b
0, 13, 13, 1, 28800, 0x520ad812
-1, 17916, 17916, 1378, 2756, 0xdfb61002
0, 14, 14, 1, 28800, 0xc46ad9da
-1, 19294, 19294, 1378, 2756, 0x15d029da
0, 15, 15, 1, 28800, 0xe79edb9e
-1, 20672, 20672, 1378, 2756, 0x7bc82012
0, 16, 16, 1, 28800, 0xdb1acb30
-1, 22050, 22050, 1378, 2756, 0x002e6999
-1, 23428, 23428, 1378, 2756, 0x96346ba6
0, 17, 17, 1, 28800, 0x050fb669
-1, 24806, 24806, 1378, 2756, 0x3d54543b
0, 18, 18, 1, 28800, 0x096ca687
-1, 26184, 26184, 1380, 2760, 0x601786e1
0, 19, 19, 1, 28800, 0x0054a6bd
-1, 27562, 27562, 1378, 2756, 0xf22a5793
0, 20, 20, 1, 28800, 0x6d7daad2
0, 21, 21, 1, 28800, 0x9c10a9dc
-1, 28941, 28941, 1378, 2756, 0x21f54d49
0, 22, 22, 1, 28800, 0x89b1a623
-1, 30319, 30319, 1378, 2756, 0x0c6d4399
0, 23, 23, 1, 28800, 0xa0a19c3f
-1, 31697, 31697, 1378, 2756, 0x17282f8e
0, 24, 24, 1, 28800, 0x26c898ad
-1, 33075, 33075, 1378, 2756, 0xeb698f75
-1, 34453, 34453, 1378, 2756, 0x935e1de2
0, 25, 25, 1, 28800, 0x6f639dae
-1, 35831, 35831, 1380, 2760, 0xb6fb4293
0, 26, 26, 1, 28800, 0xa173a9b5
-1, 37209, 37209, 1378, 2756, 0x485053dc
0, 27, 27, 1, 28800, 0xa309aa08
0, 28, 28, 1, 28800, 0x2059b6c4
-1, 38588, 38588, 1378, 2756, 0x24c35027
0, 29, 29, 1, 28800, 0x5ae8c761
-1, 39966, 39966, 1378, 2756, 0x09f323ee
0, 30, 30, 1, 28800, 0xb780c9c5
-1, 41344, 41344, 1378, 2756, 0xbc7d58d5
0, 31, 31, 1, 28800, 0xf58ac8fe
-1, 42722, 42722, 1378, 2756, 0xaefd487c
0, 32, 32, 1, 28800, 0x9bb307e7
-1, 44100, 44100, 1378, 2756, 0xaca16cc0
-1, 45478, 45478, 1380, 2760, 0x98a76091
0, 33, 33, 1, 28800, 0xd32c3e81
-1, 46856, 46856, 1378, 2756, 0x5d357141
0, 34, 34, 1, 28800, 0x4edd51d2
-1, 48234, 48234, 1378, 2756, 0x65ea2657
0, 35, 35, 1, 28800, 0x5a88684d
-1, 49612, 49612, 1378, 2756, 0xb5e1334a
0, 36, 36, 1, 28800, 0x5bd97f0e
0, 37, 37, 1, 28800, 0x36d67843
-1, 50991, 50991, 1378, 2756, 0x32cd5d91
0, 38, 38, 1, 28800, 0x0e18781d
-1, 52369, 52369, 1378, 2756, 0xdc23722b
0, 39, 39, 1, 28800, 0xa3168807
-1, 53747, 53747, 1378, 2756, 0x2ba34684
0, 40, 40, 1, 28800, 0xa7c575b8
-1, 55125, 55125, 1378, 2756, 0xf9755ba8
-1, 56503, 56503, 1380, 2760, 0x24221ddb
0, 41, 41, 1, 28800, 0x86367c37
-1, 57881, 57881, 1378, 2756, 0xef843aa4
0, 42, 42, 1, 28800, 0xb0f79180
-1, 59259, 59259, 1378, 2756, 0x420442fe
0, 43, 43, 1, 28800, 0x61da8c0f
0, 44, 44, 1, 28800, 0x9b11948a
-1, 60638, 60638, 1378, 2756, 0x5a0933cb
0, 45, 45, 1, 28800, 0xc53d9b44
-1, 62016, 62016, 1378, 2756, 0xef5f6d61
0, 46, 46, 1, 28800, 0xdc699185
-1, 63394, 63394, 1378, 2756, 0xe57e6dc0
0, 47, 47, 1, 28800, 0x7b4f92b5
-1, 64772, 64772, 1378, 2756, 0xc0f0495a
0, 48, 48, 1, 28800, 0x40469065
-1, 66150, 66150, 1380, 2760, 0x2c3b55df
-1, 67528, 67528, 1378, 2756, 0x39c2586c
0, 49, 49, 1, 28800, 0x737ea07e
-1, 68906, 68906, 1378, 2756, 0x7ffc46e5
0, 50, 50, 1, 28800, 0x0db49c8b
-1, 70284, 70284, 1378, 2756, 0xa2766664
0, 51, 51, 1, 28800, 0x39249f10
-1, 71662, 71662, 1378, 2756, 0xacb50c6c
0, 52, 52, 1, 28800, 0xc182ab99
0, 53, 53, 1, 28800, 0xd8f7a7c9
-1, 73041, 73041, 1378, 2756, 0x7f659084
0, 54, 54, 1, 28800, 0x46789caa
-1, 74419, 74419, 1378, 2756, 0xc72e6a12
0, 55, 55, 1, 28800, 0x4759a374
-1, 75797, 75797, 1380, 2760, 0xdb6944df
0, 56, 56, 1, 28800, 0xe621b16a
-1, 77175, 77175, 1378, 2756, 0x954f45c1
-1, 78553, 78553, 1378, 2756, 0xa9484240
0, 57, 57, 1, 28800, 0xcf47a999
-1, 79931, 79931, 1378, 2756, 0x1d595349
0, 58, 58, 1, 28800, 0x801dacd4
-1, 81309, 81309, 1378, 2756, 0xcf2a565e
0, 59, 59, 1, 28800, 0xe580af51
0, 60, 60, 1, 28800, 0x03d7a887
-1, 82688, 82688, 1378, 2756, 0x391028d5
0, 61, 61, 1, 28800, 0xa67ea51d
-1, 84066, 84066, 1378, 2756, 0x348db7ad
0, 62, 62, 1, 28800, 0x9fee0ec8
-1, 85444, 85444, 1380, 2760, 0xb69b5e3a
0, 63, 63, 1, 28800, 0x7f602a5e
-1, 86822, 86822, 1378, 2756, 0xe3635fbe
0, 64, 64, 1, 28800, 0x100d432a
-1, 88200, 88200, 1378, 2756, 0xdcad3654
-1, 89578, 89578, 1378, 2756, 0x5c17abef
0, 65, 65, 1, 28800, 0x42164dfb
-1, 90956, 90956, 1378, 2756, 0xb3235184
0, 66, 66, 1, 28800, 0x86c05196
-1, 92334, 92334, 1378, 2756, 0xdabb64a6
0, 67, 67, 1, 28800, 0xfc225938
-1, 93712, 93712, 1378, 2756, 0xa95dc58d
0, 68, 68, 1, 28800, 0x81085e87
0, 69, 69, 1, 28800, 0xaa8f5d0a
-1, 95091, 95091, 1380, 2760, 0x8e7ac9eb
0, 70, 70, 1, 28800, 0x605a5f9f
-1, 96469, 96469, 1378, 2756, 0x492b658e
0, 71, 71, 1, 28800, 0x68dc64b2
-1, 97847, 97847, 1378, 2756, 0x377483ab
0, 72, 72, 1, 28800, 0xd08e710b
-1, 99225, 99225, 1378, 2756, 0x2c250279
-1, 100603, 100603, 1378, 2756, 0x704dbdb3
0, 73, 73, 1, 28800, 0xf8567939
-1, 101981, 101981, 1378, 2756, 0x800d7da2
0, 74, 74, 1, 28800, 0x8dad7a4f
-1, 103359, 103359, 1378, 2756, 0x872aa32e
0, 75, 75, 1, 28800, 0x1a19813c
0, 76, 76, 1, 28800, 0x8a157f0e
-1, 104738, 104738, 1378, 2756, 0x2d4837fe
0, 77, 77, 1, 28800, 0xa4fa7b9d
-1, 106116, 106116, 1380, 2760, 0xc89ea57e
0, 78, 78, 1, 28800, 0x093b7b36
-1, 107494, 107494, 1378, 2756, 0x6447d7ef
0, 79, 79, 1, 28800, 0xa925755b
-1, 108872, 108872, 1378, 2756, 0x144f59cc
0, 80, 80, 1, 28800, 0xa5968138
-1, 110250, 110250, 1378, 2756, 0xc667154e
-1, 111628, 111628, 1378, 2756, 0xf0de66ae
0, 81, 81, 1, 28800, 0xe00877ac
-1, 113006, 113006, 1378, 2756, 0xeabf3c32
0, 82, 82, 1, 28800, 0xd736183e
-1, 114384, 114384, 1378, 2756, 0xe98e81d1
0, 83, 83, 1, 28800, 0x356f2068
-1, 115762, 115762, 1380, 2760, 0x56aa5889
0, 84, 84, 1, 28800, 0xf9a50f22
0, 85, 85, 1, 28800, 0x92df2ae8
-1, 117141, 117141, 1378, 2756, 0x4fd34c0e
0, 86, 86, 1, 28800, 0x67a43dc8
-1, 118519, 118519, 1378, 2756, 0x67cf6912
0, 87, 87, 1, 28800, 0xf8ce2ead
-1, 119897, 119897, 1378, 2756, 0xfa944def
0, 88, 88, 1, 28800, 0xf42f37ee
-1, 121275, 121275, 1378, 2756, 0xc12f23b2
-1, 122653, 122653, 1378, 2756, 0x5ea325a2
0, 89, 89, 1, 28800, 0x03611f37
-1, 124031, 124031, 1378, 2756, 0x2b245824
0, 90, 90, 1, 28800, 0xddda2327
-1, 125409, 125409, 1380, 2760, 0x90ac533e
0, 91, 91, 1, 28800, 0xdf073d85
0, 92, 92, 1, 28800, 0xa8331fee
-1, 126788, 126788, 1378, 2756, 0xcca34d26
0, 93, 93, 1, 28800, 0x59d3490a
-1, 128166, 128166, 1378, 2756, 0xb5f820d0
0, 94, 94, 1, 28800, 0xa8335be6
-1, 129544, 129544, 1378, 2756, 0x27f24335
0, 95, 95, 1, 28800, 0xd5483b43
-1, 130922, 130922, 1378, 2756, 0x4a9e87b7
0, 96, 96, 1, 28800, 0x23422dc9
-1, 132300, 132300, 1378, 2756, 0xbd076129
-1, 133678, 133678, 1378, 2756, 0x2e0e3f2e
0, 97, 97, 1, 28800, 0xc04e4689
-1, 135056, 135056, 1380, 2760, 0xdf534478
0, 98, 98, 1, 28800, 0xd4d96372
-1, 136434, 136434, 1378, 2756, 0xca000a2e
0, 99, 99, 1, 28800, 0x9c814e96
-1, 137812, 137812, 1378, 2756, 0x87472df3
0, 100, 100, 1, 28800, 0x7c4b5d3b
0, 101, 101, 1, 28800, 0x6bf66c04
-1, 139191, 139191, 1378, 2756, 0x16733810
0, 102, 102, 1, 28800, 0x6e8d4bb6
-1, 140569, 140569, 1378, 2756, 0xfa0734b4
0, 103, 103, 1, 28800, 0xad964d00
-1, 141947, 141947, 1378, 2756, 0x5eff3fc4
0, 104, 104, 1, 28800, 0x1ff36bd1
-1, 143325, 143325, 1378, 2756, 0xf35346bd
-1, 144703, 144703, 1378, 2756, 0xac6411c5
0, 105, 105, 1, 28800, 0xa4664c76
-1, 146081, 146081, 1380, 2760, 0x478c3c56
0, 106, 106, 1, 28800, 0x50626d82
-1, 147459, 147459, 1378, 2756, 0xebd30bdd
0, 107, 107, 1, 28800, 0x81906c5c
0, 108, 108, 1, 28800, 0x5060543f
-1, 148838, 148838, 1378, 2756, 0xaef95a31
0, 109, 109, 1, 28800, 0x231c5a86
-1, 150216, 150216, 1378, 2756, 0x8aad29d1
0, 110, 110, 1, 28800, 0x79775d48
-1, 151594, 151594, 1378, 2756, 0x626863f0
0, 111, 111, 1, 28800, 0xbb893571
-1, 152972, 152972, 1378, 2756, 0x68c05707
0, 112, 112, 1, 28800, 0x794c49ed
-1, 154350, 154350, 1378, 2756, 0x437c5e8d
-1, 155728, 155728, 1380, 2760, 0x8eca4bdb
0, 113, 113, 1, 28800, 0x70464bac
-1, 157106, 157106, 1378, 2756, 0x62bd4162
0, 114, 114, 1, 28800, 0xe79549ce
-1, 158484, 158484, 1378, 2756, 0x9f744aa4
0, 115, 115, 1, 28800, 0xa6565555
-1, 159862, 159862, 1378, 2756, 0x0f3f6409
0, 116, 116, 1, 28800, 0x2ef1ad6d
0, 117, 117, 1, 28800, 0xdd22b9aa
-1, 161241, 161241, 1378, 2756, 0x3fee827a
0, 118, 118, 1, 28800, 0x26ebaa97
-1, 162619, 162619, 1378, 2756, 0x48a0ac19
0, 119, 119, 1, 28800, 0x32bd979e
-1, 163997, 163997, 1378, 2756, 0x8e4ce0d0
0, 120, 120, 1, 28800, 0x4c167c9a
-1, 165375, 165375, 1380, 2760, 0xcda82236
-1, 166753, 166753, 1378, 2756, 0x0e523255
0, 121, 121, 1, 28800, 0xfdf76051
-1, 168131, 168131, 1378, 2756, 0x84103d30
0, 122, 122, 1, 28800, 0x966938a8
-1, 169509, 169509, 1378, 2756, 0x13941cde
0, 123, 123, 1, 28800, 0xcea3fbde
0, 124, 124, 1, 28800, 0x29a0c213
-1, 170888, 170888, 1378, 2756, 0x9fc834c5
0, 125, 125, 1, 28800, 0x5633a1c2
-1, 172266, 172266, 1378, 2756, 0xc0217a77
0, 126, 126, 1, 28800, 0xdc0b9af8
-1, 173644, 173644, 1378, 2756, 0x3f643659
0, 127, 127, 1, 28800, 0x92138848
-1, 175022, 175022, 1380, 2760, 0x9dbd6002
0, 128, 128, 1, 28800, 0xd7308da5
-1, 176400, 176400, 1378, 2756, 0x94f046fb
-1, 177778, 177778, 1378, 2756, 0xab01fb12
0, 129, 129, 1, 28800, 0x0c8f9b3f
-1, 179156, 179156, 1378, 2756, 0x04cffe5c
0, 130, 130, 1, 28800, 0xd059b5d1
-1, 180534, 180534, 1378, 2756, 0xef661c5e
0, 131, 131, 1, 28800, 0xba6ed9cd
-1, 181912, 181912, 1378, 2756, 0x094c5fc5
0, 132, 132, 1, 28800, 0x896c1064
0, 133, 133, 1, 28800, 0x986e2fc9
-1, 183291, 183291, 1378, 2756, 0xe0c1486a
0, 134, 134, 1, 28800, 0xcba94e4b
-1, 184669, 184669, 1380, 2760, 0x8c3535b7
0, 135, 135, 1, 28800, 0xf3e778ed
-1, 186047, 186047, 1378, 2756, 0x594934aa
0, 136, 136, 1, 28800, 0xc6cd7d48
-1, 187425, 187425, 1378, 2756, 0x74007238
-1, 188803, 188803, 1378, 2756, 0x61f1394d
0, 137, 137, 1, 28800, 0xd9bd84d8
-1, 190181, 190181, 1378, 2756, 0x72584f07
0, 138, 138, 1, 28800, 0x391197b4
-1, 191559, 191559, 1378, 2756, 0xced9acf9
0, 139, 139, 1, 28800, 0xf361a1d9
0, 140, 140, 1, 28800, 0x9a1ea54e
-1, 192938, 192938, 1378, 2756, 0x7d2e3ea1
0, 141, 141, 1, 28800, 0x551aab57
-1, 194316, 194316, 1378, 2756, 0x56c06897
0, 142, 142, 1, 28800, 0x3af8577d
-1, 195694, 195694, 1380, 2760, 0x19983bbf
0, 143, 143, 1, 28800, 0x10f76ed0
-1, 197072, 197072, 1378, 2756, 0x4f884f27
0, 144, 144, 1, 28800, 0x026a7fde
-1, 198450, 198450, 1378, 2756, 0x81ab2f63
-1, 199828, 199828, 1378, 2756, 0x448e681d
0, 145, 145, 1, 28800, 0x3e0e8db8
-1, 201206, 201206, 1378, 2756, 0x0ba9826e
0, 146, 146, 1, 28800, 0x22998d2d
-1, 202584, 202584, 1378, 2756, 0x049f36fa
0, 147, 147, 1, 28800, 0x05978b12
-1, 203962, 203962, 1378, 2756, 0x096a2b62
0, 148, 148, 1, 28800, 0x38b88294
0, 149, 149, 1, 28800, 0x2ef677d6
-1, 205341, 205341, 1380, 2760, 0x579e2035
0, 150, 150, 1, 28800, 0x0b9a8894
-1, 206719, 206719, 1378, 2756, 0xd13e30e1
0, 151, 151, 1, 28800, 0x2dcb6718
-1, 208097, 208097, 1378, 2756, 0x30b6412b
0, 152, 152, 1, 28800, 0xa31b6679
-1, 209475, 209475, 1378, 2756, 0xbb1c3268
-1, 210853, 210853, 1378, 2756, 0xbc175b6a
0, 153, 153, 1, 28800, 0x262d6a50
-1, 212231, 212231, 1378, 2756, 0xf8d160e2
0, 154, 154, 1, 28800, 0xff3d6d0d
-1, 213609, 213609, 1378, 2756, 0xc1048154
0, 155, 155, 1, 28800, 0x159d7045
0, 156, 156, 1, 28800, 0xf0df7800
-1, 214988, 214988, 1380, 2760, 0xb83548f4
0, 157, 157, 1, 28800, 0xbe825ea5
-1, 216366, 216366, 1378, 2756, 0x22647962
0, 158, 158, 1, 28800, 0x80e25d5a
-1, 217744, 217744, 1378, 2756, 0x14ca54d3
0, 159, 159, 1, 28800, 0x8cbe263f
-1, 219122, 219122, 1378, 2756, 0x58754b3a
diff --git a/tests/ref/fate/blowfish b/tests/ref/fate/blowfish
new file mode 100644
index 0000000..fed0b4d
--- /dev/null
+++ b/tests/ref/fate/blowfish
@@ -0,0 +1 @@
+Test encryption/decryption success.
diff --git a/tests/ref/fate/bmv b/tests/ref/fate/bmv
deleted file mode 100644
index 2ea4862..0000000
--- a/tests/ref/fate/bmv
+++ /dev/null
@@ -1,44 +0,0 @@
-#tb 0: 1/12
-#tb 1: 1/22050
-0, 0, 0, 1, 823680, 0xddb8a306
-1, 0, 0, 1856, 7424, 0x18540b36
-0, 1, 1, 1, 823680, 0xa95375c8
-1, 1856, 1856, 1824, 7296, 0x5acd2484
-0, 2, 2, 1, 823680, 0xa95375c8
-1, 3680, 3680, 1856, 7424, 0xa1bc5c5a
-0, 3, 3, 1, 823680, 0xb6f78afe
-1, 5536, 5536, 1824, 7296, 0x71a02ad1
-0, 4, 4, 1, 823680, 0xb6f78afe
-1, 7360, 7360, 1856, 7424, 0x09cc32f2
-0, 5, 5, 1, 823680, 0x45b9c8f0
-1, 9216, 9216, 1824, 7296, 0xa3451726
-0, 6, 6, 1, 823680, 0x45b9c8f0
-1, 11040, 11040, 1824, 7296, 0x1eb40a18
-0, 7, 7, 1, 823680, 0x7653d8e9
-1, 12864, 12864, 1856, 7424, 0xc55a2acf
-0, 8, 8, 1, 823680, 0x7653d8e9
-1, 14720, 14720, 1824, 7296, 0x5b9fad3f
-0, 9, 9, 1, 823680, 0xf1e2fd73
-1, 16544, 16544, 1856, 7424, 0xea651ae7
-0, 10, 10, 1, 823680, 0xf1e2fd73
-1, 18400, 18400, 1824, 7296, 0x2bd5ddb6
-0, 11, 11, 1, 823680, 0x6d2deab3
-1, 20224, 20224, 1856, 7424, 0xde4243b4
-0, 12, 12, 1, 823680, 0x6d2deab3
-1, 22080, 22080, 1824, 7296, 0x358806d3
-0, 13, 13, 1, 823680, 0x37fd33ce
-1, 23904, 23904, 1824, 7296, 0x511a144e
-0, 14, 14, 1, 823680, 0x37fd33ce
-1, 25728, 25728, 1856, 7424, 0x887a3e84
-0, 15, 15, 1, 823680, 0x0a8e0ab9
-1, 27584, 27584, 1824, 7296, 0xfeae2a0c
-0, 16, 16, 1, 823680, 0x0a8e0ab9
-1, 29408, 29408, 1856, 7424, 0xa4ea5d22
-0, 17, 17, 1, 823680, 0x991bb2b0
-1, 31264, 31264, 1824, 7296, 0xb3adf7fa
-0, 18, 18, 1, 823680, 0x991bb2b0
-1, 33088, 33088, 1856, 7424, 0xce995dcc
-0, 19, 19, 1, 823680, 0xb8397c8c
-1, 34944, 34944, 1824, 7296, 0x5b4cf574
-0, 20, 20, 1, 823680, 0xb8397c8c
-1, 36768, 36768, 1824, 7296, 0x8a70eaf0
diff --git a/tests/ref/fate/bmv-audio b/tests/ref/fate/bmv-audio
new file mode 100644
index 0000000..746bb0c
--- /dev/null
+++ b/tests/ref/fate/bmv-audio
@@ -0,0 +1,22 @@
+#tb 0: 1/22050
+0, 0, 0, 1856, 7424, 0x18540b36
+0, 1856, 1856, 1824, 7296, 0x5acd2484
+0, 3680, 3680, 1856, 7424, 0xa1bc5c5a
+0, 5536, 5536, 1824, 7296, 0x71a02ad1
+0, 7360, 7360, 1856, 7424, 0x09cc32f2
+0, 9216, 9216, 1824, 7296, 0xa3451726
+0, 11040, 11040, 1824, 7296, 0x1eb40a18
+0, 12864, 12864, 1856, 7424, 0xc55a2acf
+0, 14720, 14720, 1824, 7296, 0x5b9fad3f
+0, 16544, 16544, 1856, 7424, 0xea651ae7
+0, 18400, 18400, 1824, 7296, 0x2bd5ddb6
+0, 20224, 20224, 1856, 7424, 0xde4243b4
+0, 22080, 22080, 1824, 7296, 0x358806d3
+0, 23904, 23904, 1824, 7296, 0x511a144e
+0, 25728, 25728, 1856, 7424, 0x887a3e84
+0, 27584, 27584, 1824, 7296, 0xfeae2a0c
+0, 29408, 29408, 1856, 7424, 0xa4ea5d22
+0, 31264, 31264, 1824, 7296, 0xb3adf7fa
+0, 33088, 33088, 1856, 7424, 0xce995dcc
+0, 34944, 34944, 1824, 7296, 0x5b4cf574
+0, 36768, 36768, 1824, 7296, 0x8a70eaf0
diff --git a/tests/ref/fate/bmv-video b/tests/ref/fate/bmv-video
new file mode 100644
index 0000000..f19cd45
--- /dev/null
+++ b/tests/ref/fate/bmv-video
@@ -0,0 +1,22 @@
+#tb 0: 1/12
+0, 0, 0, 1, 823680, 0xddb8a306
+0, 1, 1, 1, 823680, 0xa95375c8
+0, 2, 2, 1, 823680, 0xa95375c8
+0, 3, 3, 1, 823680, 0xb6f78afe
+0, 4, 4, 1, 823680, 0xb6f78afe
+0, 5, 5, 1, 823680, 0x45b9c8f0
+0, 6, 6, 1, 823680, 0x45b9c8f0
+0, 7, 7, 1, 823680, 0x7653d8e9
+0, 8, 8, 1, 823680, 0x7653d8e9
+0, 9, 9, 1, 823680, 0xf1e2fd73
+0, 10, 10, 1, 823680, 0xf1e2fd73
+0, 11, 11, 1, 823680, 0x6d2deab3
+0, 12, 12, 1, 823680, 0x6d2deab3
+0, 13, 13, 1, 823680, 0x37fd33ce
+0, 14, 14, 1, 823680, 0x37fd33ce
+0, 15, 15, 1, 823680, 0x0a8e0ab9
+0, 16, 16, 1, 823680, 0x0a8e0ab9
+0, 17, 17, 1, 823680, 0x991bb2b0
+0, 18, 18, 1, 823680, 0x991bb2b0
+0, 19, 19, 1, 823680, 0xb8397c8c
+0, 20, 20, 1, 823680, 0xb8397c8c
diff --git a/tests/ref/fate/caf b/tests/ref/fate/caf
index a400501..00de78c 100644
--- a/tests/ref/fate/caf
+++ b/tests/ref/fate/caf
@@ -1 +1 @@
-CRC=0x5b74195c
+CRC=0xd0d7195c
diff --git a/tests/ref/fate/crc b/tests/ref/fate/crc
index 4a82680..1c24aea 100644
--- a/tests/ref/fate/crc
+++ b/tests/ref/fate/crc
@@ -1,4 +1,4 @@
-crc EDB88320 =3D5CDD04
-crc 04C11DB7 =E0BAF5C0
-crc 00008005 =BB1F
-crc 00000007 =E3
+crc EDB88320 = 3D5CDD04
+crc 04C11DB7 = E0BAF5C0
+crc 00008005 = BB1F
+crc 00000007 = E3
diff --git a/tests/ref/fate/delphine-cin b/tests/ref/fate/delphine-cin
deleted file mode 100644
index 7803444..0000000
--- a/tests/ref/fate/delphine-cin
+++ /dev/null
@@ -1,185 +0,0 @@
-#tb 0: 1/12
-#tb 1: 1/22050
-0, 0, 0, 1, 153600, 0x00000000
-1, 0, 0, 88224, 176448, 0x541ddc55
-0, 1, 1, 1, 153600, 0x9c77862c
-0, 2, 2, 1, 153600, 0xd487c33c
-0, 3, 3, 1, 153600, 0x5c00c01c
-0, 4, 4, 1, 153600, 0x5496c2a2
-0, 5, 5, 1, 153600, 0x858ac5c0
-0, 6, 6, 1, 153600, 0xe32fc7d9
-0, 7, 7, 1, 153600, 0xabffc965
-0, 8, 8, 1, 153600, 0x4171c8e7
-0, 9, 9, 1, 153600, 0xaec4ca90
-0, 10, 10, 1, 153600, 0x3cb4cb5d
-0, 11, 11, 1, 153600, 0x3aedcdc0
-0, 12, 12, 1, 153600, 0x0fa4cf55
-0, 13, 13, 1, 153600, 0x66a1d146
-0, 14, 14, 1, 153600, 0x3828d3ad
-0, 15, 15, 1, 153600, 0x73ccd7a4
-0, 16, 16, 1, 153600, 0xb815d983
-0, 17, 17, 1, 153600, 0x11a5a54f
-0, 18, 18, 1, 153600, 0x337d8bff
-0, 19, 19, 1, 153600, 0x0a1c8e5c
-0, 20, 20, 1, 153600, 0x09648a57
-0, 21, 21, 1, 153600, 0xf7398ba4
-0, 22, 22, 1, 153600, 0x836d8aaf
-0, 23, 23, 1, 153600, 0x4ee385bf
-0, 24, 24, 1, 153600, 0xacf2c4d6
-0, 25, 25, 1, 153600, 0x0610f426
-0, 26, 26, 1, 153600, 0xb798e4a1
-0, 27, 27, 1, 153600, 0xdaabe17e
-0, 28, 28, 1, 153600, 0x7b82def5
-0, 29, 29, 1, 153600, 0x56afe483
-0, 30, 30, 1, 153600, 0x4640acef
-0, 31, 31, 1, 153600, 0x4415f46c
-0, 32, 32, 1, 153600, 0x258d01d0
-0, 33, 33, 1, 153600, 0x18a55ba1
-0, 34, 34, 1, 153600, 0x165a7173
-0, 35, 35, 1, 153600, 0xfa8a438b
-0, 36, 36, 1, 153600, 0x57083a34
-0, 37, 37, 1, 153600, 0xb39923cd
-0, 38, 38, 1, 153600, 0x3e32fd70
-0, 39, 39, 1, 153600, 0xa7e9eb7f
-0, 40, 40, 1, 153600, 0x8c20ed88
-0, 41, 41, 1, 153600, 0x8c9bed27
-0, 42, 42, 1, 153600, 0xc79af188
-0, 43, 43, 1, 153600, 0x3bda00c8
-0, 44, 44, 1, 153600, 0x03f837a7
-0, 45, 45, 1, 153600, 0x550b83e3
-0, 46, 46, 1, 153600, 0xc0bc6080
-0, 47, 47, 1, 153600, 0xb8d968ed
-0, 48, 48, 1, 153600, 0x893e2348
-1, 88224, 88224, 1838, 3676, 0xaf455081
-0, 49, 49, 1, 153600, 0x6cd01834
-1, 90062, 90062, 1838, 3676, 0x27ef4e91
-0, 50, 50, 1, 153600, 0x9e6926c5
-1, 91900, 91900, 1838, 3676, 0xd1d986a3
-0, 51, 51, 1, 153600, 0x4b57a4ea
-1, 93738, 93738, 1838, 3676, 0xaaa2b589
-0, 52, 52, 1, 153600, 0xaab2cfcd
-1, 95576, 95576, 1838, 3676, 0x6e794ff9
-0, 53, 53, 1, 153600, 0xffbb334d
-1, 97414, 97414, 1838, 3676, 0x266351f1
-0, 54, 54, 1, 153600, 0x4b37e5a9
-1, 99252, 99252, 1838, 3676, 0xdeae50b2
-0, 55, 55, 1, 153600, 0x3486dee0
-1, 101090, 101090, 1838, 3676, 0x90f1f96a
-0, 56, 56, 1, 153600, 0xa7185454
-1, 102928, 102928, 1838, 3676, 0xea07adf9
-0, 57, 57, 1, 153600, 0xec29b8c2
-1, 104766, 104766, 1838, 3676, 0xb80a8925
-0, 58, 58, 1, 153600, 0x01e562ba
-1, 106604, 106604, 1838, 3676, 0xc392a1da
-0, 59, 59, 1, 153600, 0xe695cda3
-1, 108442, 108442, 1838, 3676, 0xa076bdda
-0, 60, 60, 1, 153600, 0xf6b59dac
-1, 110280, 110280, 1838, 3676, 0x8f40b4cc
-0, 61, 61, 1, 153600, 0xb308206b
-1, 112118, 112118, 1838, 3676, 0x4227fe30
-0, 62, 62, 1, 153600, 0xcc6ede4a
-1, 113956, 113956, 1838, 3676, 0x82b31ec8
-0, 63, 63, 1, 153600, 0xd9f8071c
-1, 115794, 115794, 1838, 3676, 0x3ba04042
-0, 64, 64, 1, 153600, 0xfb434821
-1, 117632, 117632, 1838, 3676, 0x6fe7440a
-0, 65, 65, 1, 153600, 0x84c97077
-1, 119470, 119470, 1838, 3676, 0x23e33177
-0, 66, 66, 1, 153600, 0x82dc5217
-1, 121308, 121308, 1838, 3676, 0x1f14242c
-0, 67, 67, 1, 153600, 0xdbfd0ba8
-1, 123146, 123146, 1838, 3676, 0x72931fb0
-0, 68, 68, 1, 153600, 0x3d71058e
-1, 124984, 124984, 1838, 3676, 0x2b1351c2
-0, 69, 69, 1, 153600, 0x3027b928
-1, 126822, 126822, 1838, 3676, 0x6aee7070
-0, 70, 70, 1, 153600, 0x792ae3bd
-1, 128660, 128660, 1838, 3676, 0x237658fa
-0, 71, 71, 1, 153600, 0x36db00a7
-1, 130498, 130498, 1838, 3676, 0xac001143
-0, 72, 72, 1, 153600, 0x4484e720
-1, 132336, 132336, 1838, 3676, 0x1921ee21
-0, 73, 73, 1, 153600, 0xfaa76cdc
-1, 134174, 134174, 1838, 3676, 0x80186091
-0, 74, 74, 1, 153600, 0x9f1e4c7e
-1, 136012, 136012, 1838, 3676, 0xb7f37ede
-0, 75, 75, 1, 153600, 0x4b545d88
-1, 137850, 137850, 1838, 3676, 0x355227ef
-0, 76, 76, 1, 153600, 0xa11cfd15
-1, 139688, 139688, 1838, 3676, 0xb0411f35
-0, 77, 77, 1, 153600, 0x9f5d49c4
-1, 141526, 141526, 1838, 3676, 0xe7c4fe0e
-0, 78, 78, 1, 153600, 0x7a496740
-1, 143364, 143364, 1838, 3676, 0x0425984d
-0, 79, 79, 1, 153600, 0x98477803
-1, 145202, 145202, 1838, 3676, 0xfd59dea1
-0, 80, 80, 1, 153600, 0xa5fc20f8
-1, 147040, 147040, 1838, 3676, 0xa53d5aab
-0, 81, 81, 1, 153600, 0x344ff96e
-1, 148878, 148878, 1838, 3676, 0x8bc403c2
-0, 82, 82, 1, 153600, 0x20c91746
-1, 150716, 150716, 1838, 3676, 0x7dd638c2
-0, 83, 83, 1, 153600, 0x7c59b379
-1, 152554, 152554, 1838, 3676, 0x284913eb
-0, 84, 84, 1, 153600, 0x38e3b86d
-1, 154392, 154392, 1838, 3676, 0xec17e83c
-0, 85, 85, 1, 153600, 0xff25a440
-1, 156230, 156230, 1838, 3676, 0x40543463
-0, 86, 86, 1, 153600, 0xa1f66533
-1, 158068, 158068, 1838, 3676, 0x92d81bf8
-0, 87, 87, 1, 153600, 0xe136260a
-1, 159906, 159906, 1838, 3676, 0x44ef161d
-0, 88, 88, 1, 153600, 0x048ccf56
-1, 161744, 161744, 1838, 3676, 0x499df3d5
-0, 89, 89, 1, 153600, 0x65f68a24
-1, 163582, 163582, 1838, 3676, 0xf98f4d75
-0, 90, 90, 1, 153600, 0xf32b385a
-1, 165420, 165420, 1838, 3676, 0x8ffe2681
-0, 91, 91, 1, 153600, 0x3e930a8f
-1, 167258, 167258, 1838, 3676, 0x84093bfd
-1, 169096, 169096, 1838, 3676, 0x5f9c2e32
-1, 170934, 170934, 1838, 3676, 0x8f93c29b
-1, 172772, 172772, 1838, 3676, 0xf0ada687
-1, 174610, 174610, 1838, 3676, 0x30019db2
-1, 176448, 176448, 1838, 3676, 0x06ebace3
-1, 178286, 178286, 1838, 3676, 0xc293d944
-1, 180124, 180124, 1838, 3676, 0x789ff65e
-1, 181962, 181962, 1838, 3676, 0xa2ae13c1
-1, 183800, 183800, 1838, 3676, 0xb64f1cd9
-1, 185638, 185638, 1838, 3676, 0x18f4e36a
-1, 187476, 187476, 1838, 3676, 0xe9ccd0f0
-1, 189314, 189314, 1838, 3676, 0xc215b4ab
-1, 191152, 191152, 1838, 3676, 0x45b5c410
-1, 192990, 192990, 1838, 3676, 0xf84a9939
-1, 194828, 194828, 1838, 3676, 0xc8aff71e
-1, 196666, 196666, 1838, 3676, 0x76cc3afc
-1, 198504, 198504, 1838, 3676, 0x524e1dd6
-1, 200342, 200342, 1838, 3676, 0x115a3f10
-1, 202180, 202180, 1838, 3676, 0xd2bb51d1
-1, 204018, 204018, 1838, 3676, 0xe1dbfca5
-1, 205856, 205856, 1838, 3676, 0xc428f070
-1, 207694, 207694, 1838, 3676, 0x6aa4dddf
-1, 209532, 209532, 1838, 3676, 0xa0428f08
-1, 211370, 211370, 1838, 3676, 0x8fd7e256
-1, 213208, 213208, 1838, 3676, 0x41cb1787
-1, 215046, 215046, 1838, 3676, 0xe348568e
-1, 216884, 216884, 1838, 3676, 0x79091a0c
-1, 218722, 218722, 1838, 3676, 0x592f6f2e
-1, 220560, 220560, 1838, 3676, 0xa151448f
-1, 222398, 222398, 1838, 3676, 0xb3402e7a
-1, 224236, 224236, 1838, 3676, 0x74112e27
-1, 226074, 226074, 1838, 3676, 0xba090659
-1, 227912, 227912, 1838, 3676, 0xa0451f81
-1, 229750, 229750, 1838, 3676, 0x09c7393a
-1, 231588, 231588, 1838, 3676, 0xceb4e340
-1, 233426, 233426, 1838, 3676, 0x0440291a
-1, 235264, 235264, 1838, 3676, 0xb7b930c4
-1, 237102, 237102, 1838, 3676, 0x1a2afa4a
-1, 238940, 238940, 1838, 3676, 0x414fee56
-1, 240778, 240778, 1838, 3676, 0x5e26bc97
-1, 242616, 242616, 1838, 3676, 0x780e0481
-1, 244454, 244454, 1838, 3676, 0xb6dfb9c5
-1, 246292, 246292, 1838, 3676, 0x447b36ca
-1, 248130, 248130, 1838, 3676, 0x601c3067
-1, 249968, 249968, 1838, 3676, 0x199f2f8d
-1, 251806, 251806, 1838, 3676, 0x98645b08
diff --git a/tests/ref/fate/delphine-cin-audio b/tests/ref/fate/delphine-cin-audio
new file mode 100644
index 0000000..1a94a6b
--- /dev/null
+++ b/tests/ref/fate/delphine-cin-audio
@@ -0,0 +1,92 @@
+#tb 0: 1/22050
+0, 0, 0, 88224, 176448, 0x541ddc55
+0, 88224, 88224, 1838, 3676, 0xaf455081
+0, 90062, 90062, 1838, 3676, 0x27ef4e91
+0, 91900, 91900, 1838, 3676, 0xd1d986a3
+0, 93738, 93738, 1838, 3676, 0xaaa2b589
+0, 95576, 95576, 1838, 3676, 0x6e794ff9
+0, 97414, 97414, 1838, 3676, 0x266351f1
+0, 99252, 99252, 1838, 3676, 0xdeae50b2
+0, 101090, 101090, 1838, 3676, 0x90f1f96a
+0, 102928, 102928, 1838, 3676, 0xea07adf9
+0, 104766, 104766, 1838, 3676, 0xb80a8925
+0, 106604, 106604, 1838, 3676, 0xc392a1da
+0, 108442, 108442, 1838, 3676, 0xa076bdda
+0, 110280, 110280, 1838, 3676, 0x8f40b4cc
+0, 112118, 112118, 1838, 3676, 0x4227fe30
+0, 113956, 113956, 1838, 3676, 0x82b31ec8
+0, 115794, 115794, 1838, 3676, 0x3ba04042
+0, 117632, 117632, 1838, 3676, 0x6fe7440a
+0, 119470, 119470, 1838, 3676, 0x23e33177
+0, 121308, 121308, 1838, 3676, 0x1f14242c
+0, 123146, 123146, 1838, 3676, 0x72931fb0
+0, 124984, 124984, 1838, 3676, 0x2b1351c2
+0, 126822, 126822, 1838, 3676, 0x6aee7070
+0, 128660, 128660, 1838, 3676, 0x237658fa
+0, 130498, 130498, 1838, 3676, 0xac001143
+0, 132336, 132336, 1838, 3676, 0x1921ee21
+0, 134174, 134174, 1838, 3676, 0x80186091
+0, 136012, 136012, 1838, 3676, 0xb7f37ede
+0, 137850, 137850, 1838, 3676, 0x355227ef
+0, 139688, 139688, 1838, 3676, 0xb0411f35
+0, 141526, 141526, 1838, 3676, 0xe7c4fe0e
+0, 143364, 143364, 1838, 3676, 0x0425984d
+0, 145202, 145202, 1838, 3676, 0xfd59dea1
+0, 147040, 147040, 1838, 3676, 0xa53d5aab
+0, 148878, 148878, 1838, 3676, 0x8bc403c2
+0, 150716, 150716, 1838, 3676, 0x7dd638c2
+0, 152554, 152554, 1838, 3676, 0x284913eb
+0, 154392, 154392, 1838, 3676, 0xec17e83c
+0, 156230, 156230, 1838, 3676, 0x40543463
+0, 158068, 158068, 1838, 3676, 0x92d81bf8
+0, 159906, 159906, 1838, 3676, 0x44ef161d
+0, 161744, 161744, 1838, 3676, 0x499df3d5
+0, 163582, 163582, 1838, 3676, 0xf98f4d75
+0, 165420, 165420, 1838, 3676, 0x8ffe2681
+0, 167258, 167258, 1838, 3676, 0x84093bfd
+0, 169096, 169096, 1838, 3676, 0x5f9c2e32
+0, 170934, 170934, 1838, 3676, 0x8f93c29b
+0, 172772, 172772, 1838, 3676, 0xf0ada687
+0, 174610, 174610, 1838, 3676, 0x30019db2
+0, 176448, 176448, 1838, 3676, 0x06ebace3
+0, 178286, 178286, 1838, 3676, 0xc293d944
+0, 180124, 180124, 1838, 3676, 0x789ff65e
+0, 181962, 181962, 1838, 3676, 0xa2ae13c1
+0, 183800, 183800, 1838, 3676, 0xb64f1cd9
+0, 185638, 185638, 1838, 3676, 0x18f4e36a
+0, 187476, 187476, 1838, 3676, 0xe9ccd0f0
+0, 189314, 189314, 1838, 3676, 0xc215b4ab
+0, 191152, 191152, 1838, 3676, 0x45b5c410
+0, 192990, 192990, 1838, 3676, 0xf84a9939
+0, 194828, 194828, 1838, 3676, 0xc8aff71e
+0, 196666, 196666, 1838, 3676, 0x76cc3afc
+0, 198504, 198504, 1838, 3676, 0x524e1dd6
+0, 200342, 200342, 1838, 3676, 0x115a3f10
+0, 202180, 202180, 1838, 3676, 0xd2bb51d1
+0, 204018, 204018, 1838, 3676, 0xe1dbfca5
+0, 205856, 205856, 1838, 3676, 0xc428f070
+0, 207694, 207694, 1838, 3676, 0x6aa4dddf
+0, 209532, 209532, 1838, 3676, 0xa0428f08
+0, 211370, 211370, 1838, 3676, 0x8fd7e256
+0, 213208, 213208, 1838, 3676, 0x41cb1787
+0, 215046, 215046, 1838, 3676, 0xe348568e
+0, 216884, 216884, 1838, 3676, 0x79091a0c
+0, 218722, 218722, 1838, 3676, 0x592f6f2e
+0, 220560, 220560, 1838, 3676, 0xa151448f
+0, 222398, 222398, 1838, 3676, 0xb3402e7a
+0, 224236, 224236, 1838, 3676, 0x74112e27
+0, 226074, 226074, 1838, 3676, 0xba090659
+0, 227912, 227912, 1838, 3676, 0xa0451f81
+0, 229750, 229750, 1838, 3676, 0x09c7393a
+0, 231588, 231588, 1838, 3676, 0xceb4e340
+0, 233426, 233426, 1838, 3676, 0x0440291a
+0, 235264, 235264, 1838, 3676, 0xb7b930c4
+0, 237102, 237102, 1838, 3676, 0x1a2afa4a
+0, 238940, 238940, 1838, 3676, 0x414fee56
+0, 240778, 240778, 1838, 3676, 0x5e26bc97
+0, 242616, 242616, 1838, 3676, 0x780e0481
+0, 244454, 244454, 1838, 3676, 0xb6dfb9c5
+0, 246292, 246292, 1838, 3676, 0x447b36ca
+0, 248130, 248130, 1838, 3676, 0x601c3067
+0, 249968, 249968, 1838, 3676, 0x199f2f8d
+0, 251806, 251806, 1838, 3676, 0x98645b08
diff --git a/tests/ref/fate/delphine-cin-video b/tests/ref/fate/delphine-cin-video
new file mode 100644
index 0000000..feaea26
--- /dev/null
+++ b/tests/ref/fate/delphine-cin-video
@@ -0,0 +1,93 @@
+#tb 0: 1/12
+0, 0, 0, 1, 153600, 0x00000000
+0, 1, 1, 1, 153600, 0x9c77862c
+0, 2, 2, 1, 153600, 0xd487c33c
+0, 3, 3, 1, 153600, 0x5c00c01c
+0, 4, 4, 1, 153600, 0x5496c2a2
+0, 5, 5, 1, 153600, 0x858ac5c0
+0, 6, 6, 1, 153600, 0xe32fc7d9
+0, 7, 7, 1, 153600, 0xabffc965
+0, 8, 8, 1, 153600, 0x4171c8e7
+0, 9, 9, 1, 153600, 0xaec4ca90
+0, 10, 10, 1, 153600, 0x3cb4cb5d
+0, 11, 11, 1, 153600, 0x3aedcdc0
+0, 12, 12, 1, 153600, 0x0fa4cf55
+0, 13, 13, 1, 153600, 0x66a1d146
+0, 14, 14, 1, 153600, 0x3828d3ad
+0, 15, 15, 1, 153600, 0x73ccd7a4
+0, 16, 16, 1, 153600, 0xb815d983
+0, 17, 17, 1, 153600, 0x11a5a54f
+0, 18, 18, 1, 153600, 0x337d8bff
+0, 19, 19, 1, 153600, 0x0a1c8e5c
+0, 20, 20, 1, 153600, 0x09648a57
+0, 21, 21, 1, 153600, 0xf7398ba4
+0, 22, 22, 1, 153600, 0x836d8aaf
+0, 23, 23, 1, 153600, 0x4ee385bf
+0, 24, 24, 1, 153600, 0xacf2c4d6
+0, 25, 25, 1, 153600, 0x0610f426
+0, 26, 26, 1, 153600, 0xb798e4a1
+0, 27, 27, 1, 153600, 0xdaabe17e
+0, 28, 28, 1, 153600, 0x7b82def5
+0, 29, 29, 1, 153600, 0x56afe483
+0, 30, 30, 1, 153600, 0x4640acef
+0, 31, 31, 1, 153600, 0x4415f46c
+0, 32, 32, 1, 153600, 0x258d01d0
+0, 33, 33, 1, 153600, 0x18a55ba1
+0, 34, 34, 1, 153600, 0x165a7173
+0, 35, 35, 1, 153600, 0xfa8a438b
+0, 36, 36, 1, 153600, 0x57083a34
+0, 37, 37, 1, 153600, 0xb39923cd
+0, 38, 38, 1, 153600, 0x3e32fd70
+0, 39, 39, 1, 153600, 0xa7e9eb7f
+0, 40, 40, 1, 153600, 0x8c20ed88
+0, 41, 41, 1, 153600, 0x8c9bed27
+0, 42, 42, 1, 153600, 0xc79af188
+0, 43, 43, 1, 153600, 0x3bda00c8
+0, 44, 44, 1, 153600, 0x03f837a7
+0, 45, 45, 1, 153600, 0x550b83e3
+0, 46, 46, 1, 153600, 0xc0bc6080
+0, 47, 47, 1, 153600, 0xb8d968ed
+0, 48, 48, 1, 153600, 0x893e2348
+0, 49, 49, 1, 153600, 0x6cd01834
+0, 50, 50, 1, 153600, 0x9e6926c5
+0, 51, 51, 1, 153600, 0x4b57a4ea
+0, 52, 52, 1, 153600, 0xaab2cfcd
+0, 53, 53, 1, 153600, 0xffbb334d
+0, 54, 54, 1, 153600, 0x4b37e5a9
+0, 55, 55, 1, 153600, 0x3486dee0
+0, 56, 56, 1, 153600, 0xa7185454
+0, 57, 57, 1, 153600, 0xec29b8c2
+0, 58, 58, 1, 153600, 0x01e562ba
+0, 59, 59, 1, 153600, 0xe695cda3
+0, 60, 60, 1, 153600, 0xf6b59dac
+0, 61, 61, 1, 153600, 0xb308206b
+0, 62, 62, 1, 153600, 0xcc6ede4a
+0, 63, 63, 1, 153600, 0xd9f8071c
+0, 64, 64, 1, 153600, 0xfb434821
+0, 65, 65, 1, 153600, 0x84c97077
+0, 66, 66, 1, 153600, 0x82dc5217
+0, 67, 67, 1, 153600, 0xdbfd0ba8
+0, 68, 68, 1, 153600, 0x3d71058e
+0, 69, 69, 1, 153600, 0x3027b928
+0, 70, 70, 1, 153600, 0x792ae3bd
+0, 71, 71, 1, 153600, 0x36db00a7
+0, 72, 72, 1, 153600, 0x4484e720
+0, 73, 73, 1, 153600, 0xfaa76cdc
+0, 74, 74, 1, 153600, 0x9f1e4c7e
+0, 75, 75, 1, 153600, 0x4b545d88
+0, 76, 76, 1, 153600, 0xa11cfd15
+0, 77, 77, 1, 153600, 0x9f5d49c4
+0, 78, 78, 1, 153600, 0x7a496740
+0, 79, 79, 1, 153600, 0x98477803
+0, 80, 80, 1, 153600, 0xa5fc20f8
+0, 81, 81, 1, 153600, 0x344ff96e
+0, 82, 82, 1, 153600, 0x20c91746
+0, 83, 83, 1, 153600, 0x7c59b379
+0, 84, 84, 1, 153600, 0x38e3b86d
+0, 85, 85, 1, 153600, 0xff25a440
+0, 86, 86, 1, 153600, 0xa1f66533
+0, 87, 87, 1, 153600, 0xe136260a
+0, 88, 88, 1, 153600, 0x048ccf56
+0, 89, 89, 1, 153600, 0x65f68a24
+0, 90, 90, 1, 153600, 0xf32b385a
+0, 91, 91, 1, 153600, 0x3e930a8f
diff --git a/tests/ref/fate/dpcm-idroq b/tests/ref/fate/dpcm-idroq
index 0865343..85e8efb 100644
--- a/tests/ref/fate/dpcm-idroq
+++ b/tests/ref/fate/dpcm-idroq
@@ -1,379 +1,168 @@
-#tb 0: 1/30
-#tb 1: 1/22050
-0, 0, 0, 1, 393216, 0x56995aac
-1, 0, 0, 7456, 29824, 0x77e265b7
-0, 1, 1, 1, 393216, 0xf9ed5d6c
-0, 2, 2, 1, 393216, 0xd3285d75
-0, 3, 3, 1, 393216, 0x82d15d62
-0, 4, 4, 1, 393216, 0x893e5d6f
-0, 5, 5, 1, 393216, 0x82d15d62
-0, 6, 6, 1, 393216, 0x893e5d6f
-0, 7, 7, 1, 393216, 0x82d15d62
-0, 8, 8, 1, 393216, 0x893e5d6f
-0, 9, 9, 1, 393216, 0x82d15d62
-0, 10, 10, 1, 393216, 0x893e5d6f
-1, 7456, 7456, 736, 2944, 0x8dcdf50b
-0, 11, 11, 1, 393216, 0x82d15d62
-1, 8192, 8192, 736, 2944, 0xb135cd2a
-0, 12, 12, 1, 393216, 0x893e5d6f
-1, 8928, 8928, 736, 2944, 0x54a6e73f
-0, 13, 13, 1, 393216, 0x82d15d62
-1, 9664, 9664, 736, 2944, 0x050ccd4e
-0, 14, 14, 1, 393216, 0x893e5d6f
-1, 10400, 10400, 736, 2944, 0x6b68db44
-0, 15, 15, 1, 393216, 0x82d15d62
-1, 11136, 11136, 736, 2944, 0x55d1f308
-0, 16, 16, 1, 393216, 0x2ae39eca
-1, 11872, 11872, 736, 2944, 0x7e92f50b
-0, 17, 17, 1, 393216, 0x9254be70
-1, 12608, 12608, 736, 2944, 0xe9e91eed
-0, 18, 18, 1, 393216, 0x4b2ed384
-1, 13344, 13344, 736, 2944, 0x80af2ce0
-0, 19, 19, 1, 393216, 0xbbd9d8f7
-1, 14080, 14080, 736, 2944, 0xc67ffb07
-0, 20, 20, 1, 393216, 0x1f2be0c3
-1, 14816, 14816, 736, 2944, 0x7aaded27
-0, 21, 21, 1, 393216, 0x2434eb25
-1, 15552, 15552, 736, 2944, 0x14a024fd
-0, 22, 22, 1, 393216, 0xa6cced4e
-1, 16288, 16288, 736, 2944, 0x26e8df1f
-0, 23, 23, 1, 393216, 0xd116f38b
-1, 17024, 17024, 736, 2944, 0x2688df44
-0, 24, 24, 1, 393216, 0x6b86f380
-1, 17760, 17760, 736, 2944, 0x4b9cdd33
-0, 25, 25, 1, 393216, 0xc1b3f8e9
-1, 18496, 18496, 736, 2944, 0x10c2f11c
-0, 26, 26, 1, 393216, 0x2993fd5d
-1, 19232, 19232, 736, 2944, 0xc4e3ad6d
-0, 27, 27, 1, 393216, 0xf489fe18
-1, 19968, 19968, 736, 2944, 0xbeb1a78e
-0, 28, 28, 1, 393216, 0x9ef10501
-1, 20704, 20704, 736, 2944, 0x283d4e7f
-0, 29, 29, 1, 393216, 0x8faf0512
-1, 21440, 21440, 736, 2944, 0x4acf65e0
-0, 30, 30, 1, 393216, 0xa54d0736
-1, 22176, 22176, 736, 2944, 0x0ca29b8c
-0, 31, 31, 1, 393216, 0xf4ef01e0
-1, 22912, 22912, 736, 2944, 0x003fae34
-0, 32, 32, 1, 393216, 0xe241ef51
-1, 23648, 23648, 736, 2944, 0x2acfec7e
-0, 33, 33, 1, 393216, 0xcc38e51f
-1, 24384, 24384, 736, 2944, 0xea6fc6fe
-0, 34, 34, 1, 393216, 0xb1345876
-1, 25120, 25120, 736, 2944, 0xf5daec2f
-0, 35, 35, 1, 393216, 0xf9b0968b
-1, 25856, 25856, 736, 2944, 0x8d33ed7a
-0, 36, 36, 1, 393216, 0x6bb1523f
-1, 26592, 26592, 736, 2944, 0xc328f984
-0, 37, 37, 1, 393216, 0x83469a05
-1, 27328, 27328, 736, 2944, 0x6e0b58d3
-0, 38, 38, 1, 393216, 0x73e30882
-1, 28064, 28064, 736, 2944, 0xe282dc3f
-0, 39, 39, 1, 393216, 0x8673da66
-1, 28800, 28800, 736, 2944, 0xbf9bf3e6
-0, 40, 40, 1, 393216, 0xb67596d3
-1, 29536, 29536, 736, 2944, 0xd7b7d7e3
-0, 41, 41, 1, 393216, 0xf7638710
-1, 30272, 30272, 736, 2944, 0x4e87b6ab
-0, 42, 42, 1, 393216, 0x813a8f47
-1, 31008, 31008, 736, 2944, 0x7b8ce8d6
-0, 43, 43, 1, 393216, 0xb3526555
-1, 31744, 31744, 736, 2944, 0xd42991a5
-0, 44, 44, 1, 393216, 0x1b167be3
-1, 32480, 32480, 736, 2944, 0x452c98ca
-0, 45, 45, 1, 393216, 0x99114562
-1, 33216, 33216, 736, 2944, 0x6d27832d
-0, 46, 46, 1, 393216, 0xfafb0693
-1, 33952, 33952, 736, 2944, 0xa558720e
-0, 47, 47, 1, 393216, 0x121d96c8
-1, 34688, 34688, 736, 2944, 0x0a31bec0
-0, 48, 48, 1, 393216, 0xb3c68c5d
-1, 35424, 35424, 736, 2944, 0x28431384
-0, 49, 49, 1, 393216, 0x2035b97f
-1, 36160, 36160, 736, 2944, 0xd5e9fb3d
-0, 50, 50, 1, 393216, 0xfbcaeb62
-1, 36896, 36896, 736, 2944, 0x34f0e9f8
-0, 51, 51, 1, 393216, 0xfd5aea5d
-1, 37632, 37632, 736, 2944, 0x979432df
-0, 52, 52, 1, 393216, 0x66efbddd
-1, 38368, 38368, 736, 2944, 0xb00acd4d
-0, 53, 53, 1, 393216, 0xf1e17862
-1, 39104, 39104, 736, 2944, 0x726bffd6
-0, 54, 54, 1, 393216, 0x27fa584d
-1, 39840, 39840, 736, 2944, 0xa1f39a6d
-0, 55, 55, 1, 393216, 0xe644ec5f
-1, 40576, 40576, 736, 2944, 0xf6a8e30e
-0, 56, 56, 1, 393216, 0x7e3067ba
-1, 41312, 41312, 736, 2944, 0x608e9e06
-0, 57, 57, 1, 393216, 0x1b6ba6fd
-1, 42048, 42048, 736, 2944, 0x4ec58bc3
-0, 58, 58, 1, 393216, 0x55bdba34
-1, 42784, 42784, 736, 2944, 0x6d5c8458
-0, 59, 59, 1, 393216, 0xc67db2e4
-1, 43520, 43520, 736, 2944, 0x76a0abbd
-0, 60, 60, 1, 393216, 0x359de8a2
-1, 44256, 44256, 736, 2944, 0xf830e8a6
-0, 61, 61, 1, 393216, 0x7b7a32ef
-1, 44992, 44992, 736, 2944, 0x1bdd7bec
-0, 62, 62, 1, 393216, 0xbe512a66
-1, 45728, 45728, 736, 2944, 0x3c1bd187
-0, 63, 63, 1, 393216, 0x681d82bf
-1, 46464, 46464, 736, 2944, 0xf52cf697
-0, 64, 64, 1, 393216, 0xa2320ec5
-1, 47200, 47200, 736, 2944, 0x8f65b773
-0, 65, 65, 1, 393216, 0xcfbd9954
-1, 47936, 47936, 736, 2944, 0xf8b5b598
-0, 66, 66, 1, 393216, 0x7fee9854
-1, 48672, 48672, 736, 2944, 0xcd87d5ed
-0, 67, 67, 1, 393216, 0x70eec155
-1, 49408, 49408, 736, 2944, 0x672ac02a
-0, 68, 68, 1, 393216, 0x114f684e
-1, 50144, 50144, 736, 2944, 0x1d5d13ed
-0, 69, 69, 1, 393216, 0xe27f034f
-1, 50880, 50880, 736, 2944, 0xe298e3d4
-0, 70, 70, 1, 393216, 0xfbbd89b4
-1, 51616, 51616, 736, 2944, 0x3d2e9c32
-0, 71, 71, 1, 393216, 0xcef4c58a
-1, 52352, 52352, 736, 2944, 0xf3a39259
-0, 72, 72, 1, 393216, 0x9eea88e9
-1, 53088, 53088, 736, 2944, 0x930ae8f8
-0, 73, 73, 1, 393216, 0x911cea42
-1, 53824, 53824, 736, 2944, 0x8562aff7
-0, 74, 74, 1, 393216, 0xec5727ea
-1, 54560, 54560, 736, 2944, 0x9cd6c6a7
-0, 75, 75, 1, 393216, 0xda998c33
-1, 55296, 55296, 736, 2944, 0x2709dc5c
-0, 76, 76, 1, 393216, 0xc82140ed
-1, 56032, 56032, 736, 2944, 0xcbe31816
-0, 77, 77, 1, 393216, 0x4caa8591
-1, 56768, 56768, 736, 2944, 0xd7876ec4
-0, 78, 78, 1, 393216, 0x4944206c
-1, 57504, 57504, 736, 2944, 0xc2468b6a
-0, 79, 79, 1, 393216, 0xd4676a94
-1, 58240, 58240, 736, 2944, 0x76043e84
-0, 80, 80, 1, 393216, 0x9e0340b3
-1, 58976, 58976, 736, 2944, 0xd2c35bf0
-0, 81, 81, 1, 393216, 0xbdef7f94
-1, 59712, 59712, 736, 2944, 0x63de6061
-0, 82, 82, 1, 393216, 0xfac05cb0
-1, 60448, 60448, 736, 2944, 0xd8f6ed1d
-0, 83, 83, 1, 393216, 0xfef5a369
-1, 61184, 61184, 736, 2944, 0xe034928a
-0, 84, 84, 1, 393216, 0x9fcb3711
-1, 61920, 61920, 736, 2944, 0xa044da74
-0, 85, 85, 1, 393216, 0x6d93f761
-1, 62656, 62656, 736, 2944, 0xee410dba
-0, 86, 86, 1, 393216, 0xe95dc1ae
-1, 63392, 63392, 736, 2944, 0x8e020c7c
-0, 87, 87, 1, 393216, 0x3e561557
-1, 64128, 64128, 736, 2944, 0x73057ddb
-0, 88, 88, 1, 393216, 0x0fa7a049
-1, 64864, 64864, 736, 2944, 0xdee5cc18
-0, 89, 89, 1, 393216, 0xf16afb95
-1, 65600, 65600, 736, 2944, 0xf4d31dec
-0, 90, 90, 1, 393216, 0xe53a2064
-1, 66336, 66336, 736, 2944, 0xe8131e1c
-0, 91, 91, 1, 393216, 0x57f046a4
-1, 67072, 67072, 736, 2944, 0x8ae69c95
-0, 92, 92, 1, 393216, 0xf6f16a0c
-1, 67808, 67808, 736, 2944, 0x791c0bf4
-0, 93, 93, 1, 393216, 0xcba0c8b0
-1, 68544, 68544, 736, 2944, 0xd45a10db
-0, 94, 94, 1, 393216, 0x5bdbe522
-1, 69280, 69280, 736, 2944, 0x3a72b010
-0, 95, 95, 1, 393216, 0x0fed0151
-1, 70016, 70016, 736, 2944, 0x6a4a0411
-0, 96, 96, 1, 393216, 0xbf86faf8
-1, 70752, 70752, 736, 2944, 0xd77ab7f5
-0, 97, 97, 1, 393216, 0x39854c5f
-1, 71488, 71488, 736, 2944, 0xe3bf4fe5
-0, 98, 98, 1, 393216, 0xd9b7760a
-1, 72224, 72224, 736, 2944, 0x12db1be8
-0, 99, 99, 1, 393216, 0x8edcc1d9
-1, 72960, 72960, 736, 2944, 0x345210b0
-0, 100, 100, 1, 393216, 0x44ae1435
-1, 73696, 73696, 736, 2944, 0xcfc1f892
-0, 101, 101, 1, 393216, 0xbc3d6d73
-1, 74432, 74432, 736, 2944, 0x5b0a80bb
-0, 102, 102, 1, 393216, 0xedd82647
-1, 75168, 75168, 736, 2944, 0x31ab1168
-0, 103, 103, 1, 393216, 0x1c2e5ce3
-1, 75904, 75904, 736, 2944, 0xd4a4bb0a
-0, 104, 104, 1, 393216, 0x04e29afe
-1, 76640, 76640, 736, 2944, 0x8e211c8f
-0, 105, 105, 1, 393216, 0xb191578e
-1, 77376, 77376, 736, 2944, 0xcf464d50
-0, 106, 106, 1, 393216, 0x31d75a06
-1, 78112, 78112, 736, 2944, 0xe74ff3d6
-0, 107, 107, 1, 393216, 0xfdb6c56e
-1, 78848, 78848, 736, 2944, 0x6274635f
-0, 108, 108, 1, 393216, 0xf528f484
-1, 79584, 79584, 736, 2944, 0xc34c9f64
-0, 109, 109, 1, 393216, 0x87af758e
-1, 80320, 80320, 736, 2944, 0xbb997537
-0, 110, 110, 1, 393216, 0xc8bdafb7
-1, 81056, 81056, 736, 2944, 0x3600da72
-0, 111, 111, 1, 393216, 0x573afe93
-1, 81792, 81792, 736, 2944, 0x343e15f4
-0, 112, 112, 1, 393216, 0xb03cb8f5
-1, 82528, 82528, 736, 2944, 0x17bc58a8
-0, 113, 113, 1, 393216, 0x6e03ac71
-1, 83264, 83264, 736, 2944, 0x3dcbd3ff
-0, 114, 114, 1, 393216, 0xf919164e
-1, 84000, 84000, 736, 2944, 0x1d422371
-0, 115, 115, 1, 393216, 0x80059f3c
-1, 84736, 84736, 736, 2944, 0xe2b83d9d
-0, 116, 116, 1, 393216, 0xf4ea0b1a
-1, 85472, 85472, 736, 2944, 0x65388409
-0, 117, 117, 1, 393216, 0xe7720ffb
-1, 86208, 86208, 736, 2944, 0xafbca269
-0, 118, 118, 1, 393216, 0x1ec0cd56
-1, 86944, 86944, 736, 2944, 0x2d00c0fb
-0, 119, 119, 1, 393216, 0x2bc8cf18
-1, 87680, 87680, 736, 2944, 0xbac9c503
-0, 120, 120, 1, 393216, 0xe0bf17b5
-1, 88416, 88416, 736, 2944, 0x9990768d
-0, 121, 121, 1, 393216, 0x660247e1
-1, 89152, 89152, 736, 2944, 0x8ba978be
-0, 122, 122, 1, 393216, 0xcf66f2a9
-1, 89888, 89888, 736, 2944, 0x5a44a2f5
-0, 123, 123, 1, 393216, 0x5494d5ab
-1, 90624, 90624, 736, 2944, 0xa4b6f3b8
-0, 124, 124, 1, 393216, 0x2c02f2c4
-1, 91360, 91360, 736, 2944, 0x631b6b9f
-0, 125, 125, 1, 393216, 0x93fa3783
-1, 92096, 92096, 736, 2944, 0x4c840923
-0, 126, 126, 1, 393216, 0x4cc50633
-1, 92832, 92832, 736, 2944, 0x7c105df3
-0, 127, 127, 1, 393216, 0x3f179386
-1, 93568, 93568, 736, 2944, 0x01bcb213
-0, 128, 128, 1, 393216, 0x2bca9e1b
-1, 94304, 94304, 736, 2944, 0x95cffbf7
-0, 129, 129, 1, 393216, 0x3e4af867
-1, 95040, 95040, 736, 2944, 0x170a9c3a
-0, 130, 130, 1, 393216, 0x7e7df93c
-1, 95776, 95776, 736, 2944, 0x59e09d61
-0, 131, 131, 1, 393216, 0x577e4fb0
-1, 96512, 96512, 736, 2944, 0x3ea0f205
-0, 132, 132, 1, 393216, 0x34487f0a
-1, 97248, 97248, 736, 2944, 0xd9ea1a3a
-0, 133, 133, 1, 393216, 0x0937bcfc
-1, 97984, 97984, 736, 2944, 0xaf32d704
-0, 134, 134, 1, 393216, 0xa9e75a5e
-1, 98720, 98720, 736, 2944, 0x2d473392
-0, 135, 135, 1, 393216, 0xf7bc0c89
-1, 99456, 99456, 736, 2944, 0x2a8ec544
-0, 136, 136, 1, 393216, 0x06dacca6
-1, 100192, 100192, 736, 2944, 0x883c8838
-0, 137, 137, 1, 393216, 0x7baaa4bd
-1, 100928, 100928, 736, 2944, 0xfaf4d789
-0, 138, 138, 1, 393216, 0x95477f5f
-1, 101664, 101664, 736, 2944, 0xcb315b65
-0, 139, 139, 1, 393216, 0x51117526
-1, 102400, 102400, 736, 2944, 0x980c93b0
-0, 140, 140, 1, 393216, 0x69656d03
-1, 103136, 103136, 736, 2944, 0x0819583b
-0, 141, 141, 1, 393216, 0xcbd061bb
-1, 103872, 103872, 736, 2944, 0xf126e5b5
-0, 142, 142, 1, 393216, 0x8d1d5be2
-1, 104608, 104608, 736, 2944, 0x88836255
-0, 143, 143, 1, 393216, 0x43e55930
-1, 105344, 105344, 736, 2944, 0xc8ae8ca8
-0, 144, 144, 1, 393216, 0xb56f5872
-1, 106080, 106080, 736, 2944, 0xf0750551
-0, 145, 145, 1, 393216, 0x09a255e9
-1, 106816, 106816, 736, 2944, 0x3dfe13a3
-0, 146, 146, 1, 393216, 0xcaaa5456
-1, 107552, 107552, 736, 2944, 0xf2aa957b
-0, 147, 147, 1, 393216, 0xd267501f
-1, 108288, 108288, 736, 2944, 0xa77b79a3
-0, 148, 148, 1, 393216, 0x7bef4eca
-1, 109024, 109024, 736, 2944, 0xb1038284
-0, 149, 149, 1, 393216, 0x9aa94af3
-1, 109760, 109760, 736, 2944, 0xf96be3ba
-0, 150, 150, 1, 393216, 0xd39d4a29
-1, 110496, 110496, 736, 2944, 0x1ae6e293
-0, 151, 151, 1, 393216, 0x7a754960
-1, 111232, 111232, 736, 2944, 0x2059d020
-0, 152, 152, 1, 393216, 0x3f004921
-1, 111968, 111968, 736, 2944, 0x7e6c9996
-0, 153, 153, 1, 393216, 0x0f784ca8
-1, 112704, 112704, 736, 2944, 0x3108b540
-0, 154, 154, 1, 393216, 0x2a062c70
-1, 113440, 113440, 736, 2944, 0x75133155
-0, 155, 155, 1, 393216, 0x114ef770
-1, 114176, 114176, 736, 2944, 0x59a19226
-0, 156, 156, 1, 393216, 0xfb7673bf
-1, 114912, 114912, 736, 2944, 0x3140c138
-0, 157, 157, 1, 393216, 0xbaea88f7
-1, 115648, 115648, 736, 2944, 0x7570d3be
-0, 158, 158, 1, 393216, 0x6fdfe2ec
-1, 116384, 116384, 736, 2944, 0x54fd4ff6
-0, 159, 159, 1, 393216, 0xb7b2b398
-1, 117120, 117120, 736, 2944, 0x23bcf6dc
-0, 160, 160, 1, 393216, 0x14ba127e
-1, 117856, 117856, 736, 2944, 0x2d26489b
-0, 161, 161, 1, 393216, 0x660b3041
-1, 118592, 118592, 736, 2944, 0x4b37bf13
-0, 162, 162, 1, 393216, 0xe3f3302a
-1, 119328, 119328, 736, 2944, 0x12812ec9
-0, 163, 163, 1, 393216, 0x34c7f1c9
-1, 120064, 120064, 736, 2944, 0xc4a609dd
-0, 164, 164, 1, 393216, 0xa8257bf4
-1, 120800, 120800, 736, 2944, 0x5a8c5b20
-0, 165, 165, 1, 393216, 0xd63fc649
-1, 121536, 121536, 736, 2944, 0xd05d110f
-0, 166, 166, 1, 393216, 0xf8e5b79c
-1, 122272, 122272, 736, 2944, 0xceea6f1f
-0, 167, 167, 1, 393216, 0xa67b52ab
-1, 123008, 123008, 736, 2944, 0x4033b0a5
-0, 168, 168, 1, 393216, 0xef8f9c74
-1, 123744, 123744, 736, 2944, 0x101895ce
-0, 169, 169, 1, 393216, 0x6d3aa6b6
-1, 124480, 124480, 736, 2944, 0xd6c6809f
-0, 170, 170, 1, 393216, 0x8c174ee6
-1, 125216, 125216, 736, 2944, 0x197bda7e
-0, 171, 171, 1, 393216, 0x2dfbc524
-1, 125952, 125952, 736, 2944, 0x96fb3e4b
-0, 172, 172, 1, 393216, 0x7d0808b6
-1, 126688, 126688, 736, 2944, 0x12a6e3de
-0, 173, 173, 1, 393216, 0x6cbdf6f5
-1, 127424, 127424, 736, 2944, 0xfb80e466
-0, 174, 174, 1, 393216, 0xfe39bc53
-1, 128160, 128160, 736, 2944, 0xedb8c2fc
-0, 175, 175, 1, 393216, 0xa3d869b0
-1, 128896, 128896, 254, 1016, 0x30e56ca5
-0, 176, 176, 1, 393216, 0x09f00057
-0, 177, 177, 1, 393216, 0x6ba56343
-0, 178, 178, 1, 393216, 0xb696ca3e
-0, 179, 179, 1, 393216, 0x4eba0225
-0, 180, 180, 1, 393216, 0xdd45464b
-0, 181, 181, 1, 393216, 0x2909a9ea
-0, 182, 182, 1, 393216, 0x12aa3f85
-0, 183, 183, 1, 393216, 0x59421352
-0, 184, 184, 1, 393216, 0x57ea0313
-0, 185, 185, 1, 393216, 0x4e5f3a38
-0, 186, 186, 1, 393216, 0x55bc932d
-0, 187, 187, 1, 393216, 0x666ee55d
-0, 188, 188, 1, 393216, 0xb0f84a69
-0, 189, 189, 1, 393216, 0xad3ae63f
-0, 190, 190, 1, 393216, 0x970fd47d
-0, 191, 191, 1, 393216, 0x86c418e0
-0, 192, 192, 1, 393216, 0x52c9ce50
-0, 193, 193, 1, 393216, 0xd54c98c8
-0, 194, 194, 1, 393216, 0xb40e5fea
-0, 195, 195, 1, 393216, 0x2aa74875
-0, 196, 196, 1, 393216, 0x305b251e
-0, 197, 197, 1, 393216, 0xab8c0780
-0, 198, 198, 1, 393216, 0x0101dd0e
-0, 199, 199, 1, 393216, 0x23739cab
-0, 200, 200, 1, 393216, 0xf05196a0
-0, 201, 201, 1, 393216, 0x932d1e00
-0, 202, 202, 1, 393216, 0x932d1e00
-0, 203, 203, 1, 393216, 0x932d1e00
-0, 204, 204, 1, 393216, 0x932d1e00
-0, 205, 205, 1, 393216, 0x932d1e00
-0, 206, 206, 1, 393216, 0x932d1e00
-0, 207, 207, 1, 393216, 0x932d1e00
-0, 208, 208, 1, 393216, 0x932d1e00
-0, 209, 209, 1, 393216, 0x932d1e00
+#tb 0: 1/22050
+0, 0, 0, 7456, 29824, 0x77e265b7
+0, 7456, 7456, 736, 2944, 0x8dcdf50b
+0, 8192, 8192, 736, 2944, 0xb135cd2a
+0, 8928, 8928, 736, 2944, 0x54a6e73f
+0, 9664, 9664, 736, 2944, 0x050ccd4e
+0, 10400, 10400, 736, 2944, 0x6b68db44
+0, 11136, 11136, 736, 2944, 0x55d1f308
+0, 11872, 11872, 736, 2944, 0x7e92f50b
+0, 12608, 12608, 736, 2944, 0xe9e91eed
+0, 13344, 13344, 736, 2944, 0x80af2ce0
+0, 14080, 14080, 736, 2944, 0xc67ffb07
+0, 14816, 14816, 736, 2944, 0x7aaded27
+0, 15552, 15552, 736, 2944, 0x14a024fd
+0, 16288, 16288, 736, 2944, 0x26e8df1f
+0, 17024, 17024, 736, 2944, 0x2688df44
+0, 17760, 17760, 736, 2944, 0x4b9cdd33
+0, 18496, 18496, 736, 2944, 0x10c2f11c
+0, 19232, 19232, 736, 2944, 0xc4e3ad6d
+0, 19968, 19968, 736, 2944, 0xbeb1a78e
+0, 20704, 20704, 736, 2944, 0x283d4e7f
+0, 21440, 21440, 736, 2944, 0x4acf65e0
+0, 22176, 22176, 736, 2944, 0x0ca29b8c
+0, 22912, 22912, 736, 2944, 0x003fae34
+0, 23648, 23648, 736, 2944, 0x2acfec7e
+0, 24384, 24384, 736, 2944, 0xea6fc6fe
+0, 25120, 25120, 736, 2944, 0xf5daec2f
+0, 25856, 25856, 736, 2944, 0x8d33ed7a
+0, 26592, 26592, 736, 2944, 0xc328f984
+0, 27328, 27328, 736, 2944, 0x6e0b58d3
+0, 28064, 28064, 736, 2944, 0xe282dc3f
+0, 28800, 28800, 736, 2944, 0xbf9bf3e6
+0, 29536, 29536, 736, 2944, 0xd7b7d7e3
+0, 30272, 30272, 736, 2944, 0x4e87b6ab
+0, 31008, 31008, 736, 2944, 0x7b8ce8d6
+0, 31744, 31744, 736, 2944, 0xd42991a5
+0, 32480, 32480, 736, 2944, 0x452c98ca
+0, 33216, 33216, 736, 2944, 0x6d27832d
+0, 33952, 33952, 736, 2944, 0xa558720e
+0, 34688, 34688, 736, 2944, 0x0a31bec0
+0, 35424, 35424, 736, 2944, 0x28431384
+0, 36160, 36160, 736, 2944, 0xd5e9fb3d
+0, 36896, 36896, 736, 2944, 0x34f0e9f8
+0, 37632, 37632, 736, 2944, 0x979432df
+0, 38368, 38368, 736, 2944, 0xb00acd4d
+0, 39104, 39104, 736, 2944, 0x726bffd6
+0, 39840, 39840, 736, 2944, 0xa1f39a6d
+0, 40576, 40576, 736, 2944, 0xf6a8e30e
+0, 41312, 41312, 736, 2944, 0x608e9e06
+0, 42048, 42048, 736, 2944, 0x4ec58bc3
+0, 42784, 42784, 736, 2944, 0x6d5c8458
+0, 43520, 43520, 736, 2944, 0x76a0abbd
+0, 44256, 44256, 736, 2944, 0xf830e8a6
+0, 44992, 44992, 736, 2944, 0x1bdd7bec
+0, 45728, 45728, 736, 2944, 0x3c1bd187
+0, 46464, 46464, 736, 2944, 0xf52cf697
+0, 47200, 47200, 736, 2944, 0x8f65b773
+0, 47936, 47936, 736, 2944, 0xf8b5b598
+0, 48672, 48672, 736, 2944, 0xcd87d5ed
+0, 49408, 49408, 736, 2944, 0x672ac02a
+0, 50144, 50144, 736, 2944, 0x1d5d13ed
+0, 50880, 50880, 736, 2944, 0xe298e3d4
+0, 51616, 51616, 736, 2944, 0x3d2e9c32
+0, 52352, 52352, 736, 2944, 0xf3a39259
+0, 53088, 53088, 736, 2944, 0x930ae8f8
+0, 53824, 53824, 736, 2944, 0x8562aff7
+0, 54560, 54560, 736, 2944, 0x9cd6c6a7
+0, 55296, 55296, 736, 2944, 0x2709dc5c
+0, 56032, 56032, 736, 2944, 0xcbe31816
+0, 56768, 56768, 736, 2944, 0xd7876ec4
+0, 57504, 57504, 736, 2944, 0xc2468b6a
+0, 58240, 58240, 736, 2944, 0x76043e84
+0, 58976, 58976, 736, 2944, 0xd2c35bf0
+0, 59712, 59712, 736, 2944, 0x63de6061
+0, 60448, 60448, 736, 2944, 0xd8f6ed1d
+0, 61184, 61184, 736, 2944, 0xe034928a
+0, 61920, 61920, 736, 2944, 0xa044da74
+0, 62656, 62656, 736, 2944, 0xee410dba
+0, 63392, 63392, 736, 2944, 0x8e020c7c
+0, 64128, 64128, 736, 2944, 0x73057ddb
+0, 64864, 64864, 736, 2944, 0xdee5cc18
+0, 65600, 65600, 736, 2944, 0xf4d31dec
+0, 66336, 66336, 736, 2944, 0xe8131e1c
+0, 67072, 67072, 736, 2944, 0x8ae69c95
+0, 67808, 67808, 736, 2944, 0x791c0bf4
+0, 68544, 68544, 736, 2944, 0xd45a10db
+0, 69280, 69280, 736, 2944, 0x3a72b010
+0, 70016, 70016, 736, 2944, 0x6a4a0411
+0, 70752, 70752, 736, 2944, 0xd77ab7f5
+0, 71488, 71488, 736, 2944, 0xe3bf4fe5
+0, 72224, 72224, 736, 2944, 0x12db1be8
+0, 72960, 72960, 736, 2944, 0x345210b0
+0, 73696, 73696, 736, 2944, 0xcfc1f892
+0, 74432, 74432, 736, 2944, 0x5b0a80bb
+0, 75168, 75168, 736, 2944, 0x31ab1168
+0, 75904, 75904, 736, 2944, 0xd4a4bb0a
+0, 76640, 76640, 736, 2944, 0x8e211c8f
+0, 77376, 77376, 736, 2944, 0xcf464d50
+0, 78112, 78112, 736, 2944, 0xe74ff3d6
+0, 78848, 78848, 736, 2944, 0x6274635f
+0, 79584, 79584, 736, 2944, 0xc34c9f64
+0, 80320, 80320, 736, 2944, 0xbb997537
+0, 81056, 81056, 736, 2944, 0x3600da72
+0, 81792, 81792, 736, 2944, 0x343e15f4
+0, 82528, 82528, 736, 2944, 0x17bc58a8
+0, 83264, 83264, 736, 2944, 0x3dcbd3ff
+0, 84000, 84000, 736, 2944, 0x1d422371
+0, 84736, 84736, 736, 2944, 0xe2b83d9d
+0, 85472, 85472, 736, 2944, 0x65388409
+0, 86208, 86208, 736, 2944, 0xafbca269
+0, 86944, 86944, 736, 2944, 0x2d00c0fb
+0, 87680, 87680, 736, 2944, 0xbac9c503
+0, 88416, 88416, 736, 2944, 0x9990768d
+0, 89152, 89152, 736, 2944, 0x8ba978be
+0, 89888, 89888, 736, 2944, 0x5a44a2f5
+0, 90624, 90624, 736, 2944, 0xa4b6f3b8
+0, 91360, 91360, 736, 2944, 0x631b6b9f
+0, 92096, 92096, 736, 2944, 0x4c840923
+0, 92832, 92832, 736, 2944, 0x7c105df3
+0, 93568, 93568, 736, 2944, 0x01bcb213
+0, 94304, 94304, 736, 2944, 0x95cffbf7
+0, 95040, 95040, 736, 2944, 0x170a9c3a
+0, 95776, 95776, 736, 2944, 0x59e09d61
+0, 96512, 96512, 736, 2944, 0x3ea0f205
+0, 97248, 97248, 736, 2944, 0xd9ea1a3a
+0, 97984, 97984, 736, 2944, 0xaf32d704
+0, 98720, 98720, 736, 2944, 0x2d473392
+0, 99456, 99456, 736, 2944, 0x2a8ec544
+0, 100192, 100192, 736, 2944, 0x883c8838
+0, 100928, 100928, 736, 2944, 0xfaf4d789
+0, 101664, 101664, 736, 2944, 0xcb315b65
+0, 102400, 102400, 736, 2944, 0x980c93b0
+0, 103136, 103136, 736, 2944, 0x0819583b
+0, 103872, 103872, 736, 2944, 0xf126e5b5
+0, 104608, 104608, 736, 2944, 0x88836255
+0, 105344, 105344, 736, 2944, 0xc8ae8ca8
+0, 106080, 106080, 736, 2944, 0xf0750551
+0, 106816, 106816, 736, 2944, 0x3dfe13a3
+0, 107552, 107552, 736, 2944, 0xf2aa957b
+0, 108288, 108288, 736, 2944, 0xa77b79a3
+0, 109024, 109024, 736, 2944, 0xb1038284
+0, 109760, 109760, 736, 2944, 0xf96be3ba
+0, 110496, 110496, 736, 2944, 0x1ae6e293
+0, 111232, 111232, 736, 2944, 0x2059d020
+0, 111968, 111968, 736, 2944, 0x7e6c9996
+0, 112704, 112704, 736, 2944, 0x3108b540
+0, 113440, 113440, 736, 2944, 0x75133155
+0, 114176, 114176, 736, 2944, 0x59a19226
+0, 114912, 114912, 736, 2944, 0x3140c138
+0, 115648, 115648, 736, 2944, 0x7570d3be
+0, 116384, 116384, 736, 2944, 0x54fd4ff6
+0, 117120, 117120, 736, 2944, 0x23bcf6dc
+0, 117856, 117856, 736, 2944, 0x2d26489b
+0, 118592, 118592, 736, 2944, 0x4b37bf13
+0, 119328, 119328, 736, 2944, 0x12812ec9
+0, 120064, 120064, 736, 2944, 0xc4a609dd
+0, 120800, 120800, 736, 2944, 0x5a8c5b20
+0, 121536, 121536, 736, 2944, 0xd05d110f
+0, 122272, 122272, 736, 2944, 0xceea6f1f
+0, 123008, 123008, 736, 2944, 0x4033b0a5
+0, 123744, 123744, 736, 2944, 0x101895ce
+0, 124480, 124480, 736, 2944, 0xd6c6809f
+0, 125216, 125216, 736, 2944, 0x197bda7e
+0, 125952, 125952, 736, 2944, 0x96fb3e4b
+0, 126688, 126688, 736, 2944, 0x12a6e3de
+0, 127424, 127424, 736, 2944, 0xfb80e466
+0, 128160, 128160, 736, 2944, 0xedb8c2fc
+0, 128896, 128896, 254, 1016, 0x30e56ca5
diff --git a/tests/ref/fate/dpcm-interplay b/tests/ref/fate/dpcm-interplay
new file mode 100644
index 0000000..bda8a8f
--- /dev/null
+++ b/tests/ref/fate/dpcm-interplay
@@ -0,0 +1,125 @@
+#tb 0: 1/22050
+0, 0, 0, 1462, 5848, 0xea04292b
+0, 1462, 1462, 1472, 5888, 0x0e59e942
+0, 2934, 2934, 1472, 5888, 0x56d480f6
+0, 4406, 4406, 1472, 5888, 0xcb560b22
+0, 5878, 5878, 1472, 5888, 0xca26865b
+0, 7350, 7350, 1472, 5888, 0xa434392f
+0, 8822, 8822, 1472, 5888, 0xa0615fe4
+0, 10294, 10294, 1472, 5888, 0x85b241cd
+0, 11766, 11766, 1472, 5888, 0x2c417a43
+0, 13238, 13238, 1472, 5888, 0x2d5ed665
+0, 14710, 14710, 1472, 5888, 0x37267a2d
+0, 16182, 16182, 1472, 5888, 0x1f803c67
+0, 17654, 17654, 1472, 5888, 0xfb7940ef
+0, 19126, 19126, 1472, 5888, 0x1a5371e8
+0, 20598, 20598, 1472, 5888, 0x37e29b21
+0, 22070, 22070, 1462, 5848, 0x70065769
+0, 23532, 23532, 1472, 5888, 0xaf624f3d
+0, 25004, 25004, 1472, 5888, 0x8f5e5b57
+0, 26476, 26476, 1472, 5888, 0x93545968
+0, 27948, 27948, 1472, 5888, 0x915f268f
+0, 29420, 29420, 1472, 5888, 0x9cd48ac4
+0, 30892, 30892, 1472, 5888, 0x812c8e13
+0, 32364, 32364, 1472, 5888, 0xe794a2a7
+0, 33836, 33836, 1472, 5888, 0x4a056e4b
+0, 35308, 35308, 1472, 5888, 0xa3589992
+0, 36780, 36780, 1472, 5888, 0x19ea7ec5
+0, 38252, 38252, 1472, 5888, 0x422d5097
+0, 39724, 39724, 1472, 5888, 0xc9fd963f
+0, 41196, 41196, 1472, 5888, 0xc556a5ea
+0, 42668, 42668, 1472, 5888, 0x51557e0f
+0, 44140, 44140, 1462, 5848, 0x4903ad21
+0, 45602, 45602, 1472, 5888, 0xb1c85e85
+0, 47074, 47074, 1472, 5888, 0x68963d65
+0, 48546, 48546, 1472, 5888, 0x62a3124e
+0, 50018, 50018, 1472, 5888, 0x4ff1878f
+0, 51490, 51490, 1472, 5888, 0x8b09ac18
+0, 52962, 52962, 1472, 5888, 0x67d85338
+0, 54434, 54434, 1472, 5888, 0x82eca0a6
+0, 55906, 55906, 1472, 5888, 0x81a17eb8
+0, 57378, 57378, 1472, 5888, 0x7108478c
+0, 58850, 58850, 1472, 5888, 0xbfc18b09
+0, 60322, 60322, 1472, 5888, 0xad93711f
+0, 61794, 61794, 1472, 5888, 0xf8d25e39
+0, 63266, 63266, 1472, 5888, 0x41edd04e
+0, 64738, 64738, 1472, 5888, 0xa6557ee2
+0, 66210, 66210, 1462, 5848, 0xc14d5456
+0, 67672, 67672, 1472, 5888, 0x20a7821f
+0, 69144, 69144, 1472, 5888, 0x9f1a8f9d
+0, 70616, 70616, 1472, 5888, 0x2f3c6cc8
+0, 72088, 72088, 1472, 5888, 0x757c894a
+0, 73560, 73560, 1472, 5888, 0x483e98bb
+0, 75032, 75032, 1472, 5888, 0x84289c75
+0, 76504, 76504, 1472, 5888, 0xf79d5a91
+0, 77976, 77976, 1472, 5888, 0x395b5228
+0, 79448, 79448, 1472, 5888, 0x9c937a14
+0, 80920, 80920, 1472, 5888, 0x40c169cf
+0, 82392, 82392, 1472, 5888, 0x3e7f99b0
+0, 83864, 83864, 1472, 5888, 0xd4de993e
+0, 85336, 85336, 1472, 5888, 0xae856b09
+0, 86808, 86808, 1472, 5888, 0xa2369c95
+0, 88280, 88280, 1462, 5848, 0x992d516b
+0, 89742, 89742, 1472, 5888, 0xcd785ba9
+0, 91214, 91214, 1472, 5888, 0x55ea3bce
+0, 92686, 92686, 1472, 5888, 0xf06d4bbf
+0, 94158, 94158, 1472, 5888, 0x2a9d4c1a
+0, 95630, 95630, 1472, 5888, 0xd5e348a3
+0, 97102, 97102, 1472, 5888, 0x6431a24c
+0, 98574, 98574, 1472, 5888, 0x41f9908c
+0, 100046, 100046, 1472, 5888, 0x0ed99656
+0, 101518, 101518, 1472, 5888, 0x635a6392
+0, 102990, 102990, 1472, 5888, 0x690c750c
+0, 104462, 104462, 1472, 5888, 0xf9d97b23
+0, 105934, 105934, 1472, 5888, 0x75e1606b
+0, 107406, 107406, 1472, 5888, 0x1bcb43b0
+0, 108878, 108878, 1472, 5888, 0x48c295cb
+0, 110350, 110350, 1462, 5848, 0xe47f7b5d
+0, 111812, 111812, 1472, 5888, 0x20be7f3e
+0, 113284, 113284, 1472, 5888, 0x8c2428c4
+0, 114756, 114756, 1472, 5888, 0x851379af
+0, 116228, 116228, 1472, 5888, 0x5916647d
+0, 117700, 117700, 1472, 5888, 0xef9c6281
+0, 119172, 119172, 1472, 5888, 0x49660d32
+0, 120644, 120644, 1472, 5888, 0x62cf36a1
+0, 122116, 122116, 1472, 5888, 0x56dff39c
+0, 123588, 123588, 1472, 5888, 0x4e6b5b02
+0, 125060, 125060, 1472, 5888, 0xb8697067
+0, 126532, 126532, 1472, 5888, 0xcb4e2706
+0, 128004, 128004, 1472, 5888, 0x6eaa9669
+0, 129476, 129476, 1472, 5888, 0xfd9d7dba
+0, 130948, 130948, 1472, 5888, 0xfe137923
+0, 132420, 132420, 1462, 5848, 0x1931296f
+0, 133882, 133882, 1472, 5888, 0xa09a7c03
+0, 135354, 135354, 1472, 5888, 0xded9802d
+0, 136826, 136826, 1472, 5888, 0x9f6723b7
+0, 138298, 138298, 1472, 5888, 0x3ad02476
+0, 139770, 139770, 1472, 5888, 0xa1647e32
+0, 141242, 141242, 1472, 5888, 0x728672da
+0, 142714, 142714, 1472, 5888, 0x9c098090
+0, 144186, 144186, 1472, 5888, 0x32a65ea3
+0, 145658, 145658, 1472, 5888, 0xdde141d5
+0, 147130, 147130, 1472, 5888, 0x816c5fb4
+0, 148602, 148602, 1472, 5888, 0x75e17581
+0, 150074, 150074, 1472, 5888, 0x59035469
+0, 151546, 151546, 1472, 5888, 0x20d340cd
+0, 153018, 153018, 1472, 5888, 0xa89a8790
+0, 154490, 154490, 1462, 5848, 0x12b74c34
+0, 155952, 155952, 1472, 5888, 0xcd3b3bef
+0, 157424, 157424, 1472, 5888, 0xe5c44bf3
+0, 158896, 158896, 1472, 5888, 0xb82c4fa4
+0, 160368, 160368, 1472, 5888, 0x05b2443a
+0, 161840, 161840, 1472, 5888, 0x78028172
+0, 163312, 163312, 1472, 5888, 0xdfcac19a
+0, 164784, 164784, 1472, 5888, 0x0761a0b9
+0, 166256, 166256, 1472, 5888, 0x77d88607
+0, 167728, 167728, 1472, 5888, 0xdd7f4d77
+0, 169200, 169200, 1472, 5888, 0x366bf58a
+0, 170672, 170672, 1472, 5888, 0x9a3d59b5
+0, 172144, 172144, 1472, 5888, 0x16cb777f
+0, 173616, 173616, 1472, 5888, 0x1d4afe64
+0, 175088, 175088, 1472, 5888, 0xc0fe1e73
+0, 176560, 176560, 1462, 5848, 0xcceb69c8
+0, 178022, 178022, 1472, 5888, 0x89449643
+0, 179494, 179494, 1472, 5888, 0x5fe595b7
+0, 180966, 180966, 1472, 5888, 0x400a8c77
diff --git a/tests/ref/fate/dxa-feeble b/tests/ref/fate/dxa-feeble
index 6aaea29..74b43dc 100644
--- a/tests/ref/fate/dxa-feeble
+++ b/tests/ref/fate/dxa-feeble
@@ -1,67 +1,21 @@
#tb 0: 1/10
-#tb 1: 1/11025
0, 0, 0, 1, 921600, 0x0d03844f
-1, 0, 0, 500, 1000, 0x64cd9403
-1, 500, 500, 500, 1000, 0xa4ef8a9d
-1, 1000, 1000, 500, 1000, 0x75c19868
0, 1, 1, 1, 921600, 0x0d03844f
-1, 1500, 1500, 500, 1000, 0x93db6f79
-1, 2000, 2000, 500, 1000, 0x6835625d
0, 2, 2, 1, 921600, 0x649cdcea
-1, 2500, 2500, 500, 1000, 0xb3affa8f
-1, 3000, 3000, 500, 1000, 0x159fdcc8
0, 3, 3, 1, 921600, 0x649cdcea
-1, 3500, 3500, 500, 1000, 0x79f9f7f1
-1, 4000, 4000, 500, 1000, 0xd7d1131e
0, 4, 4, 1, 921600, 0x9c7f22e8
-1, 4500, 4500, 500, 1000, 0x52a6f797
-1, 5000, 5000, 500, 1000, 0x748202ca
-1, 5500, 5500, 500, 1000, 0x0ef92449
0, 5, 5, 1, 921600, 0x9c7f22e8
-1, 6000, 6000, 500, 1000, 0x6a3760ab
-1, 6500, 6500, 500, 1000, 0xce5c5abf
0, 6, 6, 1, 921600, 0x3451514a
-1, 7000, 7000, 500, 1000, 0x23396792
-1, 7500, 7500, 500, 1000, 0xa5276238
0, 7, 7, 1, 921600, 0x3451514a
-1, 8000, 8000, 500, 1000, 0x288adf1b
-1, 8500, 8500, 500, 1000, 0xe7de6fb2
0, 8, 8, 1, 921600, 0x8f19f600
-1, 9000, 9000, 500, 1000, 0x2c2c707f
-1, 9500, 9500, 500, 1000, 0xd66d6daf
0, 9, 9, 1, 921600, 0x8f19f600
-1, 10000, 10000, 500, 1000, 0xbcea7d64
-1, 10500, 10500, 500, 1000, 0x766feea5
-1, 11000, 11000, 500, 1000, 0xd2e1d63a
0, 10, 10, 1, 921600, 0x07e7445b
-1, 11500, 11500, 500, 1000, 0x2f7ef4ed
-1, 12000, 12000, 500, 1000, 0xb655cba4
0, 11, 11, 1, 921600, 0x07e7445b
-1, 12500, 12500, 500, 1000, 0x4507d37b
-1, 13000, 13000, 500, 1000, 0x0c57f794
0, 12, 12, 1, 921600, 0x873d1227
-1, 13500, 13500, 500, 1000, 0x0ecbe5cc
-1, 14000, 14000, 500, 1000, 0x9bf6e345
0, 13, 13, 1, 921600, 0x873d1227
-1, 14500, 14500, 500, 1000, 0xc461443c
-1, 15000, 15000, 500, 1000, 0xad9657bf
0, 14, 14, 1, 921600, 0xbef62d86
-1, 15500, 15500, 500, 1000, 0x466fe91c
-1, 16000, 16000, 500, 1000, 0x9ee377fe
-1, 16500, 16500, 500, 1000, 0x09956428
0, 15, 15, 1, 921600, 0xbef62d86
-1, 17000, 17000, 500, 1000, 0x9b285f0a
-1, 17500, 17500, 500, 1000, 0x0a3e61a6
0, 16, 16, 1, 921600, 0xcf84fee4
-1, 18000, 18000, 500, 1000, 0xacc25d6b
-1, 18500, 18500, 500, 1000, 0x377be319
0, 17, 17, 1, 921600, 0xcf84fee4
-1, 19000, 19000, 500, 1000, 0xe4890504
-1, 19500, 19500, 500, 1000, 0xe90a6497
0, 18, 18, 1, 921600, 0x5639e670
-1, 20000, 20000, 500, 1000, 0xd00fe950
-1, 20500, 20500, 500, 1000, 0xf195eb44
0, 19, 19, 1, 921600, 0x5639e670
-1, 21000, 21000, 500, 1000, 0xa491f3ef
-1, 21500, 21500, 500, 1000, 0x2c036e18
-1, 22000, 22000, 500, 1000, 0x52d65e2a
diff --git a/tests/ref/fate/ea-dct b/tests/ref/fate/ea-dct
deleted file mode 100644
index 071be8a..0000000
--- a/tests/ref/fate/ea-dct
+++ /dev/null
@@ -1,269 +0,0 @@
-#tb 0: 1/15
-#tb 1: 1/22050
-0, 0, 0, 1, 102144, 0x6edc83de
-1, 0, 0, 1484, 5936, 0xea261a29
-0, 1, 1, 1, 102144, 0xd0534fda
-1, 1484, 1484, 1456, 5824, 0x253df061
-0, 2, 2, 1, 102144, 0x6447911f
-1, 2940, 2940, 1484, 5936, 0x603a5bd7
-0, 3, 3, 1, 102144, 0xf21f3b46
-1, 4424, 4424, 1456, 5824, 0x9d283f59
-0, 4, 4, 1, 102144, 0x0975077a
-1, 5880, 5880, 1484, 5936, 0x49323497
-0, 5, 5, 1, 102144, 0xb9a12d8e
-1, 7364, 7364, 1456, 5824, 0x7c299939
-0, 6, 6, 1, 102144, 0x17413513
-1, 8820, 8820, 1484, 5936, 0x9f918e9a
-0, 7, 7, 1, 102144, 0x1e622a04
-1, 10304, 10304, 1456, 5824, 0x1226b534
-0, 8, 8, 1, 102144, 0x7489224e
-1, 11760, 11760, 1484, 5936, 0xdd159326
-0, 9, 9, 1, 102144, 0xae14956e
-1, 13244, 13244, 1456, 5824, 0x361ad10f
-0, 10, 10, 1, 102144, 0x104fd3a0
-1, 14700, 14700, 1484, 5936, 0x6ccac9e3
-0, 11, 11, 1, 102144, 0xea63a940
-1, 16184, 16184, 1456, 5824, 0x1861efef
-0, 12, 12, 1, 102144, 0x0cf81588
-1, 17640, 17640, 1484, 5936, 0x5f718eb9
-0, 13, 13, 1, 102144, 0xe4a5b2fd
-1, 19124, 19124, 1456, 5824, 0xd4ca72ba
-0, 14, 14, 1, 102144, 0x0c9aaf77
-1, 20580, 20580, 1484, 5936, 0xbf2b27e6
-0, 15, 15, 1, 102144, 0x065007d7
-1, 22064, 22064, 1456, 5824, 0xcb6f024e
-0, 16, 16, 1, 102144, 0x54c0c29b
-1, 23520, 23520, 1484, 5936, 0x7dfb7e05
-0, 17, 17, 1, 102144, 0x1114cb8e
-1, 25004, 25004, 1456, 5824, 0x80e16f13
-0, 18, 18, 1, 102144, 0xe4270462
-1, 26460, 26460, 1484, 5936, 0x0fb59227
-0, 19, 19, 1, 102144, 0x61e5b7fd
-1, 27944, 27944, 1456, 5824, 0x4d6f1fdb
-0, 20, 20, 1, 102144, 0x7cbeaca6
-1, 29400, 29400, 1484, 5936, 0x505a5103
-0, 21, 21, 1, 102144, 0xed92daa4
-1, 30884, 30884, 1456, 5824, 0x47ef4c13
-0, 22, 22, 1, 102144, 0xd8654d0d
-1, 32340, 32340, 1484, 5936, 0xbe4795fb
-0, 23, 23, 1, 102144, 0x854e842b
-1, 33824, 33824, 1456, 5824, 0xb82cc4ff
-0, 24, 24, 1, 102144, 0x56407c3a
-1, 35280, 35280, 1484, 5936, 0xf7c6ab8d
-0, 25, 25, 1, 102144, 0x17db3f90
-1, 36764, 36764, 1456, 5824, 0x1442f5e0
-0, 26, 26, 1, 102144, 0x8b133b9a
-1, 38220, 38220, 1484, 5936, 0x64659389
-0, 27, 27, 1, 102144, 0xe4899db9
-1, 39704, 39704, 1456, 5824, 0xdd81725c
-0, 28, 28, 1, 102144, 0x579cf092
-1, 41160, 41160, 1484, 5936, 0x7f7c604f
-0, 29, 29, 1, 102144, 0x19fa5062
-1, 42644, 42644, 1456, 5824, 0xafc77beb
-0, 30, 30, 1, 102144, 0x71339792
-1, 44100, 44100, 1484, 5936, 0x24f88e4d
-0, 31, 31, 1, 102144, 0x970e5c0c
-1, 45584, 45584, 1456, 5824, 0xa31956ca
-0, 32, 32, 1, 102144, 0x84ee616a
-1, 47040, 47040, 1484, 5936, 0x958e02b9
-0, 33, 33, 1, 102144, 0x1d6f9a23
-1, 48524, 48524, 1456, 5824, 0xcfc79890
-0, 34, 34, 1, 102144, 0xc28e19db
-1, 49980, 49980, 1484, 5936, 0xc7e788ae
-0, 35, 35, 1, 102144, 0x0e898967
-1, 51464, 51464, 1456, 5824, 0x4b6b1acc
-0, 36, 36, 1, 102144, 0x52a8b671
-1, 52920, 52920, 1484, 5936, 0xa74496dc
-0, 37, 37, 1, 102144, 0x3f45ea83
-1, 54404, 54404, 1456, 5824, 0x719e6171
-0, 38, 38, 1, 102144, 0x7b0fc603
-1, 55860, 55860, 1484, 5936, 0x9346222d
-0, 39, 39, 1, 102144, 0x14f94469
-1, 57344, 57344, 1456, 5824, 0x9e2a876e
-0, 40, 40, 1, 102144, 0x5b9f37cc
-1, 58800, 58800, 1484, 5936, 0xeca6ea64
-0, 41, 41, 1, 102144, 0xf902b7c7
-1, 60284, 60284, 1456, 5824, 0x07d8174f
-0, 42, 42, 1, 102144, 0x326836e0
-1, 61740, 61740, 1484, 5936, 0x2df5aa6b
-0, 43, 43, 1, 102144, 0x2e4aebba
-1, 63224, 63224, 1456, 5824, 0x314e7034
-0, 44, 44, 1, 102144, 0xd10ae58c
-1, 64680, 64680, 1484, 5936, 0x5a328768
-0, 45, 45, 1, 102144, 0xbd084ecf
-1, 66164, 66164, 1456, 5824, 0x32b92446
-0, 46, 46, 1, 102144, 0xb2157c0a
-1, 67620, 67620, 1484, 5936, 0x20ecbc9b
-0, 47, 47, 1, 102144, 0xd7f158d4
-1, 69104, 69104, 1456, 5824, 0x76019c14
-0, 48, 48, 1, 102144, 0x3cf86462
-1, 70560, 70560, 1484, 5936, 0x8c3ef8a6
-0, 49, 49, 1, 102144, 0x53ecddab
-1, 72044, 72044, 1456, 5824, 0xcdaab50b
-0, 50, 50, 1, 102144, 0xcdaba8ef
-1, 73500, 73500, 1484, 5936, 0xb2f87f4f
-0, 51, 51, 1, 102144, 0xab9ede18
-1, 74984, 74984, 1456, 5824, 0x70c26379
-0, 52, 52, 1, 102144, 0xb6706e79
-1, 76440, 76440, 1484, 5936, 0x5691ecfd
-0, 53, 53, 1, 102144, 0x76371069
-1, 77924, 77924, 1456, 5824, 0x61e208fe
-0, 54, 54, 1, 102144, 0x3a365016
-1, 79380, 79380, 1484, 5936, 0x87d1a5e0
-0, 55, 55, 1, 102144, 0x52177c09
-1, 80864, 80864, 1456, 5824, 0x02054cfd
-0, 56, 56, 1, 102144, 0xc33eb4fb
-1, 82320, 82320, 1484, 5936, 0x22ff1c4b
-0, 57, 57, 1, 102144, 0x16098436
-1, 83804, 83804, 1456, 5824, 0xc6d87fef
-0, 58, 58, 1, 102144, 0x715d6a2b
-1, 85260, 85260, 1484, 5936, 0x9028bb3b
-0, 59, 59, 1, 102144, 0xd3abc960
-1, 86744, 86744, 1456, 5824, 0xbadde406
-0, 60, 60, 1, 102144, 0x7f34b0d4
-1, 88200, 88200, 1484, 5936, 0x6e88ddf1
-0, 61, 61, 1, 102144, 0xe3219b9c
-1, 89684, 89684, 1456, 5824, 0x5bb8be6e
-0, 62, 62, 1, 102144, 0x5fa54f54
-1, 91140, 91140, 1484, 5936, 0xe1f8d7fc
-0, 63, 63, 1, 102144, 0x0fb746cb
-1, 92624, 92624, 1456, 5824, 0xc824e388
-0, 64, 64, 1, 102144, 0xa6bd2da2
-1, 94080, 94080, 1484, 5936, 0x654371a9
-0, 65, 65, 1, 102144, 0x04579119
-1, 95564, 95564, 1456, 5824, 0xae6ee9ec
-0, 66, 66, 1, 102144, 0xda818691
-1, 97020, 97020, 1484, 5936, 0x9aa4550d
-0, 67, 67, 1, 102144, 0xe9d44445
-1, 98504, 98504, 1456, 5824, 0xdce210ac
-0, 68, 68, 1, 102144, 0x94868dc9
-1, 99960, 99960, 1484, 5936, 0xb12641c8
-0, 69, 69, 1, 102144, 0x3ca52ce6
-1, 101444, 101444, 1456, 5824, 0x277e014b
-0, 70, 70, 1, 102144, 0xd7eb4c4f
-1, 102900, 102900, 1484, 5936, 0xb0d262de
-0, 71, 71, 1, 102144, 0xfcdfafca
-1, 104384, 104384, 1456, 5824, 0xf94d6f49
-0, 72, 72, 1, 102144, 0x473a4a5a
-1, 105840, 105840, 1484, 5936, 0x3d7848cb
-0, 73, 73, 1, 102144, 0xe5a5f3cb
-1, 107324, 107324, 1456, 5824, 0xe67fc08e
-0, 74, 74, 1, 102144, 0x34070219
-1, 108780, 108780, 1484, 5936, 0x0475e0d6
-0, 75, 75, 1, 102144, 0x0faa965a
-1, 110264, 110264, 1456, 5824, 0x8a9a4a2e
-0, 76, 76, 1, 102144, 0xe2c6acda
-1, 111720, 111720, 1484, 5936, 0x82576204
-0, 77, 77, 1, 102144, 0xe22776d5
-1, 113204, 113204, 1456, 5824, 0x3017b648
-0, 78, 78, 1, 102144, 0x80d85602
-1, 114660, 114660, 1484, 5936, 0xca4c3e04
-0, 79, 79, 1, 102144, 0x2f3fa190
-1, 116144, 116144, 1456, 5824, 0x340077d1
-0, 80, 80, 1, 102144, 0x70b461b1
-1, 117600, 117600, 1484, 5936, 0x805bea6e
-0, 81, 81, 1, 102144, 0x366c8b27
-1, 119084, 119084, 1456, 5824, 0x2cf6c87b
-0, 82, 82, 1, 102144, 0x65cc0866
-1, 120540, 120540, 1484, 5936, 0x3635bc5f
-0, 83, 83, 1, 102144, 0x903beb14
-1, 122024, 122024, 1456, 5824, 0x0d7a81c7
-0, 84, 84, 1, 102144, 0xb6c5f5c7
-1, 123480, 123480, 1484, 5936, 0x26179764
-0, 85, 85, 1, 102144, 0xaa813725
-1, 124964, 124964, 1456, 5824, 0xa0b2454f
-0, 86, 86, 1, 102144, 0x014a84a0
-1, 126420, 126420, 1484, 5936, 0x91d24608
-0, 87, 87, 1, 102144, 0xd286ece1
-1, 127904, 127904, 1456, 5824, 0x6509b3e1
-0, 88, 88, 1, 102144, 0x48b1c27d
-1, 129360, 129360, 1484, 5936, 0xa0e3c9fc
-0, 89, 89, 1, 102144, 0xa611ef42
-1, 130844, 130844, 1456, 5824, 0x18682a2f
-0, 90, 90, 1, 102144, 0x98627584
-1, 132300, 132300, 1484, 5936, 0x89cea4ff
-0, 91, 91, 1, 102144, 0x43de7c75
-1, 133784, 133784, 1456, 5824, 0x7dd22b85
-0, 92, 92, 1, 102144, 0xa9e22c68
-1, 135240, 135240, 1484, 5936, 0x8b2eeb8d
-0, 93, 93, 1, 102144, 0x84ac34d4
-1, 136724, 136724, 1456, 5824, 0x0c21af82
-0, 94, 94, 1, 102144, 0x6abd00ba
-1, 138180, 138180, 1484, 5936, 0x9c5a748d
-0, 95, 95, 1, 102144, 0x5d11066e
-1, 139664, 139664, 1456, 5824, 0x1dc72c5c
-0, 96, 96, 1, 102144, 0xb6b083aa
-1, 141120, 141120, 1484, 5936, 0xe6129383
-0, 97, 97, 1, 102144, 0x5d152a11
-1, 142604, 142604, 1456, 5824, 0x0a44312a
-0, 98, 98, 1, 102144, 0x0c0aec67
-1, 144060, 144060, 1484, 5936, 0x7ed30640
-0, 99, 99, 1, 102144, 0xa248bd10
-1, 145544, 145544, 1456, 5824, 0xede15f25
-0, 100, 100, 1, 102144, 0x4e6c12cc
-1, 147000, 147000, 1484, 5936, 0x0096d0f3
-0, 101, 101, 1, 102144, 0xca1d6753
-1, 148484, 148484, 1456, 5824, 0x13764b4b
-0, 102, 102, 1, 102144, 0x116310c3
-1, 149940, 149940, 1484, 5936, 0xd4608756
-0, 103, 103, 1, 102144, 0x16903cd0
-1, 151424, 151424, 1456, 5824, 0x254b5f2a
-0, 104, 104, 1, 102144, 0x239adfed
-1, 152880, 152880, 1484, 5936, 0x7705b830
-0, 105, 105, 1, 102144, 0x0970ce49
-1, 154364, 154364, 1456, 5824, 0x64a63d78
-0, 106, 106, 1, 102144, 0xb628adc1
-1, 155820, 155820, 1484, 5936, 0xc02d81a6
-0, 107, 107, 1, 102144, 0x473613f7
-1, 157304, 157304, 1456, 5824, 0xd239e55e
-0, 108, 108, 1, 102144, 0x3eef3987
-1, 158760, 158760, 1484, 5936, 0x8018cd3a
-0, 109, 109, 1, 102144, 0x935b99ca
-1, 160244, 160244, 1456, 5824, 0xf86b8a98
-0, 110, 110, 1, 102144, 0xb9f4d6ee
-1, 161700, 161700, 1484, 5936, 0x2a0078bc
-0, 111, 111, 1, 102144, 0xac811656
-1, 163184, 163184, 1456, 5824, 0x058d4e1b
-0, 112, 112, 1, 102144, 0xd1f84af0
-1, 164640, 164640, 1484, 5936, 0xbc718309
-0, 113, 113, 1, 102144, 0xf2fd25f4
-1, 166124, 166124, 1456, 5824, 0xaf6c29e5
-0, 114, 114, 1, 102144, 0x935bbed9
-1, 167580, 167580, 1484, 5936, 0x80df004d
-0, 115, 115, 1, 102144, 0x8c8c3e53
-1, 169064, 169064, 1456, 5824, 0xeca5aa57
-0, 116, 116, 1, 102144, 0x24afc20f
-1, 170520, 170520, 1484, 5936, 0xb793a8f8
-0, 117, 117, 1, 102144, 0xad20a451
-1, 172004, 172004, 1456, 5824, 0x70fa6aff
-0, 118, 118, 1, 102144, 0xd1a0df13
-1, 173460, 173460, 1484, 5936, 0xda8d4cc6
-0, 119, 119, 1, 102144, 0xb0ee53f8
-1, 174944, 174944, 1456, 5824, 0xa70088eb
-0, 120, 120, 1, 102144, 0x08cdb591
-1, 176400, 176400, 1484, 5936, 0x1c0b0aab
-0, 121, 121, 1, 102144, 0x89b985b0
-1, 177884, 177884, 1456, 5824, 0x234d2436
-0, 122, 122, 1, 102144, 0xdd27d51f
-1, 179340, 179340, 1484, 5936, 0xf79d731e
-0, 123, 123, 1, 102144, 0xa783fce0
-1, 180824, 180824, 1456, 5824, 0x5a4e454a
-0, 124, 124, 1, 102144, 0xfe5602e8
-1, 182280, 182280, 1484, 5936, 0xccf6d042
-0, 125, 125, 1, 102144, 0xfb989934
-1, 183764, 183764, 1456, 5824, 0x4e524d14
-0, 126, 126, 1, 102144, 0xf857eb2b
-1, 185220, 185220, 1484, 5936, 0xf8f2fcc3
-0, 127, 127, 1, 102144, 0x987a7098
-1, 186704, 186704, 1456, 5824, 0x08f12491
-0, 128, 128, 1, 102144, 0xbc749f42
-1, 188160, 188160, 1484, 5936, 0x506e0a42
-0, 129, 129, 1, 102144, 0x221e48a6
-1, 189644, 189644, 1456, 5824, 0x7cf05049
-0, 130, 130, 1, 102144, 0x4c4b5da2
-1, 191100, 191100, 1484, 5936, 0xdeb9d295
-0, 131, 131, 1, 102144, 0x32140027
-1, 192584, 192584, 1456, 5824, 0x758ef642
-0, 132, 132, 1, 102144, 0xbeb4bf18
-1, 194040, 194040, 1484, 5936, 0x91903980
-0, 133, 133, 1, 102144, 0x523012e5
diff --git a/tests/ref/fate/ea-mad b/tests/ref/fate/ea-mad
new file mode 100644
index 0000000..ce1df4a
--- /dev/null
+++ b/tests/ref/fate/ea-mad
@@ -0,0 +1,97 @@
+#tb 0: 1/90000
+0, 0, 0, 0, 535680, 0x889c32cf
+0, 2970, 2970, 0, 535680, 0x0b1ef044
+0, 5940, 5940, 0, 535680, 0xa7d0818b
+0, 8910, 8910, 0, 535680, 0xf392e4e1
+0, 11880, 11880, 0, 535680, 0x08480c69
+0, 14850, 14850, 0, 535680, 0x2b8af1ed
+0, 17820, 17820, 0, 535680, 0x0d58e062
+0, 20790, 20790, 0, 535680, 0xd140ced0
+0, 23760, 23760, 0, 535680, 0xbd0e6652
+0, 26730, 26730, 0, 535680, 0xdc2f2a6b
+0, 29700, 29700, 0, 535680, 0x97c31a38
+0, 32670, 32670, 0, 535680, 0x1a2bdf38
+0, 35640, 35640, 0, 535680, 0xb3af3ac4
+0, 38610, 38610, 0, 535680, 0x07a52577
+0, 41580, 41580, 0, 535680, 0x78407368
+0, 44550, 44550, 0, 535680, 0xd2a9efc3
+0, 47520, 47520, 0, 535680, 0x36df2f29
+0, 50490, 50490, 0, 535680, 0x9821d8f7
+0, 53460, 53460, 0, 535680, 0xf64321aa
+0, 56430, 56430, 0, 535680, 0x53e4d9aa
+0, 59400, 59400, 0, 535680, 0xdbd6f853
+0, 62370, 62370, 0, 535680, 0x5d40cf8b
+0, 65340, 65340, 0, 535680, 0xe624af9d
+0, 68310, 68310, 0, 535680, 0xd9dbb4cd
+0, 71280, 71280, 0, 535680, 0xf14e72ec
+0, 74250, 74250, 0, 535680, 0xb35c18f6
+0, 77220, 77220, 0, 535680, 0xc96d7757
+0, 80190, 80190, 0, 535680, 0xdfb937df
+0, 83160, 83160, 0, 535680, 0x40cd71d7
+0, 86130, 86130, 0, 535680, 0x15e176d6
+0, 89100, 89100, 0, 535680, 0x7f891b24
+0, 92070, 92070, 0, 535680, 0xb87a8c32
+0, 95040, 95040, 0, 535680, 0x0c01541f
+0, 98010, 98010, 0, 535680, 0x9eee99b3
+0, 100980, 100980, 0, 535680, 0xd65eb689
+0, 103950, 103950, 0, 535680, 0x6e733cfa
+0, 106920, 106920, 0, 535680, 0xac536670
+0, 109890, 109890, 0, 535680, 0x002275b8
+0, 112860, 112860, 0, 535680, 0x6a5385cb
+0, 115830, 115830, 0, 535680, 0xd129ade3
+0, 118800, 118800, 0, 535680, 0x32cab5d7
+0, 121770, 121770, 0, 535680, 0x08be1c8f
+0, 124740, 124740, 0, 535680, 0x59e1fba0
+0, 127710, 127710, 0, 535680, 0x138aee3a
+0, 130680, 130680, 0, 535680, 0x4cfbcd5e
+0, 133650, 133650, 0, 535680, 0xf6cf0fb4
+0, 136620, 136620, 0, 535680, 0xb13a06de
+0, 139590, 139590, 0, 535680, 0x59176f00
+0, 142560, 142560, 0, 535680, 0xf84b4ca3
+0, 145530, 145530, 0, 535680, 0x7fd09f73
+0, 148500, 148500, 0, 535680, 0x3be383b8
+0, 151470, 151470, 0, 535680, 0xa7118e51
+0, 154440, 154440, 0, 535680, 0xbd83120c
+0, 157410, 157410, 0, 535680, 0x3bc9d256
+0, 160380, 160380, 0, 535680, 0xb6c87f87
+0, 163350, 163350, 0, 535680, 0xe80d110a
+0, 166320, 166320, 0, 535680, 0xb3a83362
+0, 169290, 169290, 0, 535680, 0xfb39eb52
+0, 172260, 172260, 0, 535680, 0xbf6e1220
+0, 175230, 175230, 0, 535680, 0x9ecdfbae
+0, 178200, 178200, 0, 535680, 0x069a65f5
+0, 181170, 181170, 0, 535680, 0x206e372c
+0, 184140, 184140, 0, 535680, 0x58c83dd4
+0, 187110, 187110, 0, 535680, 0xc3562b03
+0, 190080, 190080, 0, 535680, 0xd1ed85a0
+0, 193050, 193050, 0, 535680, 0xb6205f4b
+0, 196020, 196020, 0, 535680, 0xaedf8bfa
+0, 198990, 198990, 0, 535680, 0xa48d5dea
+0, 201960, 201960, 0, 535680, 0xff82e7c1
+0, 204930, 204930, 0, 535680, 0xc9560222
+0, 207900, 207900, 0, 535680, 0x0fafa549
+0, 210870, 210870, 0, 535680, 0x8d556ccb
+0, 213840, 213840, 0, 535680, 0x802aac1f
+0, 216810, 216810, 0, 535680, 0x7d0fa168
+0, 219780, 219780, 0, 535680, 0x1a9255c9
+0, 222750, 222750, 0, 535680, 0xb4ec7e35
+0, 225720, 225720, 0, 535680, 0x48fac072
+0, 228690, 228690, 0, 535680, 0x1e260135
+0, 231660, 231660, 0, 535680, 0xce4d5079
+0, 234630, 234630, 0, 535680, 0x13e5e4ed
+0, 237600, 237600, 0, 535680, 0x592305ec
+0, 240570, 240570, 0, 535680, 0x9e227508
+0, 243540, 243540, 0, 535680, 0x1d37e5ea
+0, 246510, 246510, 0, 535680, 0x7eae7692
+0, 249480, 249480, 0, 535680, 0xf452e4b9
+0, 252450, 252450, 0, 535680, 0x1460e7e9
+0, 255420, 255420, 0, 535680, 0xc6d8a638
+0, 258390, 258390, 0, 535680, 0x854f5fb0
+0, 261360, 261360, 0, 535680, 0x854f5fb0
+0, 264330, 264330, 0, 535680, 0x70a02d87
+0, 267300, 267300, 0, 535680, 0x9a4ad464
+0, 270270, 270270, 0, 535680, 0x9a4ad464
+0, 273240, 273240, 0, 535680, 0x9a4ad464
+0, 276210, 276210, 0, 535680, 0x9a4ad464
+0, 279180, 279180, 0, 535680, 0x9a4ad464
+0, 282150, 282150, 0, 535680, 0x9a4ad464
diff --git a/tests/ref/fate/ea-mad-pcm-planar b/tests/ref/fate/ea-mad-pcm-planar
deleted file mode 100644
index 3c767fa..0000000
--- a/tests/ref/fate/ea-mad-pcm-planar
+++ /dev/null
@@ -1,294 +0,0 @@
-#tb 0: 1/90000
-#tb 1: 1/44100
-0, 0, 0, 0, 196608, 0x75d22292
-1, 0, 0, 1471, 5884, 0x00000000
-0, 2970, 2970, 0, 196608, 0x75d22292
-1, 1471, 1471, 1471, 5884, 0x00000000
-0, 5940, 5940, 0, 196608, 0x75d22292
-1, 2942, 2942, 1472, 5888, 0x00000000
-0, 8910, 8910, 0, 196608, 0x75d22292
-1, 4414, 4414, 1471, 5884, 0x00000000
-0, 11880, 11880, 0, 196608, 0x75d22292
-1, 5885, 5885, 1472, 5888, 0x00000000
-0, 14850, 14850, 0, 196608, 0x75d22292
-1, 7357, 7357, 1471, 5884, 0x00000000
-0, 17820, 17820, 0, 196608, 0x75d22292
-1, 8828, 8828, 1472, 5888, 0x00000000
-0, 20790, 20790, 0, 196608, 0x75d22292
-1, 10300, 10300, 1471, 5884, 0x00000000
-0, 23760, 23760, 0, 196608, 0x75d22292
-1, 11771, 11771, 1472, 5888, 0x00000000
-0, 26730, 26730, 0, 196608, 0xd3f66981
-1, 13243, 13243, 1471, 5884, 0x00000000
-0, 29700, 29700, 0, 196608, 0xed37c4c3
-1, 14714, 14714, 1472, 5888, 0x174b2bd4
-0, 32670, 32670, 0, 196608, 0x6ce01dc4
-1, 16186, 16186, 1471, 5884, 0xfab9563d
-0, 35640, 35640, 0, 196608, 0x2874fc9a
-1, 17657, 17657, 1472, 5888, 0x0129a4f5
-0, 38610, 38610, 0, 196608, 0x9b65bbc8
-1, 19129, 19129, 1471, 5884, 0xf12b15dd
-0, 41580, 41580, 0, 196608, 0x8f9af811
-1, 20600, 20600, 1472, 5888, 0x60c8c922
-0, 44550, 44550, 0, 196608, 0x04aeb0b0
-1, 22072, 22072, 1471, 5884, 0x85693c81
-0, 47520, 47520, 0, 196608, 0x0df037a1
-1, 23543, 23543, 1472, 5888, 0xcefcf0e0
-0, 50490, 50490, 0, 196608, 0xa32c5515
-1, 25015, 25015, 1471, 5884, 0x243974ff
-0, 53460, 53460, 0, 196608, 0xf3b11a1b
-1, 26486, 26486, 1471, 5884, 0x9101b901
-0, 56430, 56430, 0, 196608, 0xaf945190
-1, 27957, 27957, 1472, 5888, 0xe3c68cb9
-0, 59400, 59400, 0, 196608, 0xabee8b24
-1, 29429, 29429, 1471, 5884, 0x80f2ff5f
-0, 62370, 62370, 0, 196608, 0x1d7b3df0
-1, 30900, 30900, 1472, 5888, 0xfc2d19dc
-0, 65340, 65340, 0, 196608, 0x1347d787
-1, 32372, 32372, 1471, 5884, 0xb6e0af21
-0, 68310, 68310, 0, 196608, 0x654c4a9b
-1, 33843, 33843, 1472, 5888, 0x476e74ff
-0, 71280, 71280, 0, 196608, 0xa2a6596a
-1, 35315, 35315, 1471, 5884, 0x3921bc7f
-0, 74250, 74250, 0, 196608, 0x50d04d8e
-1, 36786, 36786, 1472, 5888, 0x44180a3f
-0, 77220, 77220, 0, 196608, 0x4f9f9352
-1, 38258, 38258, 1471, 5884, 0x01b5a119
-0, 80190, 80190, 0, 196608, 0xbb358281
-1, 39729, 39729, 1472, 5888, 0xdd7ad621
-0, 83160, 83160, 0, 196608, 0xcd91a50a
-1, 41201, 41201, 1471, 5884, 0xadabe898
-0, 86130, 86130, 0, 196608, 0xb665bb76
-1, 42672, 42672, 1472, 5888, 0x2141ff8e
-0, 89100, 89100, 0, 196608, 0xec924ee7
-1, 44144, 44144, 1471, 5884, 0xfb5118fb
-0, 92070, 92070, 0, 196608, 0x9c4aa4ad
-1, 45615, 45615, 1472, 5888, 0x06d31461
-0, 95040, 95040, 0, 196608, 0x27ccdf86
-1, 47087, 47087, 1471, 5884, 0x80ce34c1
-0, 98010, 98010, 0, 196608, 0x93778cc8
-1, 48558, 48558, 1472, 5888, 0x72bf392f
-0, 100980, 100980, 0, 196608, 0x3d68e826
-1, 50030, 50030, 1471, 5884, 0x9d9237cf
-0, 103950, 103950, 0, 196608, 0x9240b751
-1, 51501, 51501, 1471, 5884, 0xf5c9ce23
-0, 106920, 106920, 0, 196608, 0xd77ec46b
-1, 52972, 52972, 1472, 5888, 0x12a05dc5
-0, 109890, 109890, 0, 196608, 0x4a303ef1
-1, 54444, 54444, 1471, 5884, 0xd3ed5d4b
-0, 112860, 112860, 0, 196608, 0x2508bacf
-1, 55915, 55915, 1472, 5888, 0x06557401
-0, 115830, 115830, 0, 196608, 0xb74cb5bf
-1, 57387, 57387, 1471, 5884, 0x53d81662
-0, 118800, 118800, 0, 196608, 0x9c4a9719
-1, 58858, 58858, 1472, 5888, 0xd7e0d98d
-0, 121770, 121770, 0, 196608, 0xc34a7924
-1, 60330, 60330, 1471, 5884, 0xdf00752e
-0, 124740, 124740, 0, 196608, 0x9d8428bd
-1, 61801, 61801, 1472, 5888, 0x82f1d7a9
-0, 127710, 127710, 0, 196608, 0x019eebf7
-1, 63273, 63273, 1471, 5884, 0x9cb3aba9
-0, 130680, 130680, 0, 196608, 0x36e58d6b
-1, 64744, 64744, 1472, 5888, 0xd6f98e91
-0, 133650, 133650, 0, 196608, 0xc7038ceb
-1, 66216, 66216, 1471, 5884, 0xaa7f7c09
-0, 136620, 136620, 0, 196608, 0xb041fd50
-1, 67687, 67687, 1472, 5888, 0xb97a82a7
-0, 139590, 139590, 0, 196608, 0x76934674
-1, 69159, 69159, 1471, 5884, 0x375a3d53
-0, 142560, 142560, 0, 196608, 0x22afa88b
-1, 70630, 70630, 1472, 5888, 0xa0a460cb
-0, 145530, 145530, 0, 196608, 0x22158960
-1, 72102, 72102, 1471, 5884, 0xe05efbab
-0, 148500, 148500, 0, 196608, 0x75ab0895
-1, 73573, 73573, 1472, 5888, 0x95e151f0
-0, 151470, 151470, 0, 196608, 0xcaab6c6d
-1, 75045, 75045, 1471, 5884, 0x44ac688d
-0, 154440, 154440, 0, 196608, 0xe64d8b91
-1, 76516, 76516, 1471, 5884, 0xfc6d929f
-0, 157410, 157410, 0, 196608, 0x1e8aa17a
-1, 77987, 77987, 1472, 5888, 0x6406c5f1
-0, 160380, 160380, 0, 196608, 0x7dd94fdb
-1, 79459, 79459, 1471, 5884, 0x4ee9e48c
-0, 163350, 163350, 0, 196608, 0xab74566c
-1, 80930, 80930, 1472, 5888, 0xd55d43d0
-0, 166320, 166320, 0, 196608, 0xec962966
-1, 82402, 82402, 1471, 5884, 0xcae69baf
-0, 169290, 169290, 0, 196608, 0xf5bfd751
-1, 83873, 83873, 1472, 5888, 0x4c01f1f5
-0, 172260, 172260, 0, 196608, 0xc7f46e0e
-1, 85345, 85345, 1471, 5884, 0xf7d6dab6
-0, 175230, 175230, 0, 196608, 0xe641f676
-1, 86816, 86816, 1472, 5888, 0x1affdeb5
-0, 178200, 178200, 0, 196608, 0xea7c7b75
-1, 88288, 88288, 1471, 5884, 0x6db72487
-0, 181170, 181170, 0, 196608, 0x69120371
-1, 89759, 89759, 1472, 5888, 0x4f344e49
-0, 184140, 184140, 0, 196608, 0xb2319175
-1, 91231, 91231, 1471, 5884, 0x2df3827b
-0, 187110, 187110, 0, 196608, 0xd2d73b56
-1, 92702, 92702, 1472, 5888, 0x1d1fc283
-0, 190080, 190080, 0, 196608, 0x74aafac0
-1, 94174, 94174, 1471, 5884, 0x22eb1dd5
-0, 193050, 193050, 0, 196608, 0x15e8ddbc
-1, 95645, 95645, 1472, 5888, 0x734e7093
-0, 196020, 196020, 0, 196608, 0xd4e2c90c
-1, 97117, 97117, 1471, 5884, 0x357c9531
-0, 198990, 198990, 0, 196608, 0x86eaf31c
-1, 98588, 98588, 1472, 5888, 0x108c102d
-0, 201960, 201960, 0, 196608, 0x8004291b
-1, 100060, 100060, 1471, 5884, 0x96ad26c6
-0, 204930, 204930, 0, 196608, 0xbbf6954a
-1, 101531, 101531, 1472, 5888, 0x7bea1996
-0, 207900, 207900, 0, 196608, 0x2f24f0e1
-1, 103003, 103003, 1471, 5884, 0x124a1f8e
-0, 210870, 210870, 0, 196608, 0x59d56dfb
-1, 104474, 104474, 1471, 5884, 0x08d272fb
-0, 213840, 213840, 0, 196608, 0x1377c9cb
-1, 105945, 105945, 1472, 5888, 0x88832c6b
-0, 216810, 216810, 0, 196608, 0x07582cc3
-1, 107417, 107417, 1471, 5884, 0xedf41493
-0, 219780, 219780, 0, 196608, 0xa5a853fc
-1, 108888, 108888, 1472, 5888, 0xc4f226d7
-0, 222750, 222750, 0, 196608, 0x3b01856a
-1, 110360, 110360, 1471, 5884, 0x97730397
-0, 225720, 225720, 0, 196608, 0x64927496
-1, 111831, 111831, 1472, 5888, 0xbc3540e9
-0, 228690, 228690, 0, 196608, 0xf24c6f8a
-1, 113303, 113303, 1471, 5884, 0x8adfa135
-0, 231660, 231660, 0, 196608, 0xc92c3c46
-1, 114774, 114774, 1472, 5888, 0x6d4be121
-0, 234630, 234630, 0, 196608, 0xa50d07fb
-1, 116246, 116246, 1471, 5884, 0xc3daea85
-0, 237600, 237600, 0, 196608, 0xb1d4a092
-1, 117717, 117717, 1472, 5888, 0x5498e9f0
-0, 240570, 240570, 0, 196608, 0x20c5526b
-1, 119189, 119189, 1471, 5884, 0xa0eb691f
-0, 243540, 243540, 0, 196608, 0x6127fbbd
-1, 120660, 120660, 1472, 5888, 0x775c7c59
-0, 246510, 246510, 0, 196608, 0xc168a747
-1, 122132, 122132, 1471, 5884, 0x9f108fd1
-0, 249480, 249480, 0, 196608, 0x9c0d3241
-1, 123603, 123603, 1472, 5888, 0x72d53062
-0, 252450, 252450, 0, 196608, 0x5466dd21
-1, 125075, 125075, 1471, 5884, 0x13a93faa
-0, 255420, 255420, 0, 196608, 0x5bba67cc
-1, 126546, 126546, 1472, 5888, 0x64773c8e
-0, 258390, 258390, 0, 196608, 0x4c1a1c18
-1, 128018, 128018, 1471, 5884, 0xaf696999
-0, 261360, 261360, 0, 196608, 0x22c0a537
-1, 129489, 129489, 1471, 5884, 0xf45e7e81
-0, 264330, 264330, 0, 196608, 0x4ffc5ea6
-1, 130960, 130960, 1472, 5888, 0x00000000
-0, 267300, 267300, 0, 196608, 0x7e8e2395
-1, 132432, 132432, 1471, 5884, 0x00000000
-0, 270270, 270270, 0, 196608, 0xa3b6f198
-0, 273240, 273240, 0, 196608, 0xf6aac4d1
-1, 133903, 133903, 1472, 5888, 0x00000000
-0, 276210, 276210, 0, 196608, 0x1a6ea9ee
-1, 135375, 135375, 1471, 5884, 0x00000000
-0, 279180, 279180, 0, 196608, 0xfd729443
-1, 136846, 136846, 1472, 5888, 0x00000000
-0, 282150, 282150, 0, 196608, 0xc6a69012
-1, 138318, 138318, 1471, 5884, 0x00000000
-0, 285120, 285120, 0, 196608, 0x576f9270
-1, 139789, 139789, 1472, 5888, 0x00000000
-0, 288090, 288090, 0, 196608, 0x0d539fe5
-1, 141261, 141261, 1471, 5884, 0x00000000
-0, 291060, 291060, 0, 196608, 0x191db7d6
-1, 142732, 142732, 1472, 5888, 0x00000000
-0, 294030, 294030, 0, 196608, 0x80cddedd
-1, 144204, 144204, 1471, 5884, 0x00000000
-0, 297000, 297000, 0, 196608, 0xccf5fd39
-1, 145675, 145675, 1472, 5888, 0x00000000
-0, 299970, 299970, 0, 196608, 0x521d33b6
-1, 147147, 147147, 1471, 5884, 0x00000000
-0, 302940, 302940, 0, 196608, 0xb75e59ee
-1, 148618, 148618, 1472, 5888, 0x00000000
-0, 305910, 305910, 0, 196608, 0xbba68972
-1, 150090, 150090, 1471, 5884, 0x00000000
-0, 308880, 308880, 0, 196608, 0x368fb86a
-1, 151561, 151561, 1472, 5888, 0x00000000
-0, 311850, 311850, 0, 196608, 0x99e6e94a
-1, 153033, 153033, 1471, 5884, 0x00000000
-0, 314820, 314820, 0, 196608, 0xe4021296
-1, 154504, 154504, 1471, 5884, 0x00000000
-0, 317790, 317790, 0, 196608, 0xbc993b10
-1, 155975, 155975, 1472, 5888, 0x00000000
-0, 320760, 320760, 0, 196608, 0xf2765d22
-1, 157447, 157447, 1471, 5884, 0x00000000
-0, 323730, 323730, 0, 196608, 0xc6257db5
-1, 158918, 158918, 1472, 5888, 0x00000000
-0, 326700, 326700, 0, 196608, 0xa832782f
-1, 160390, 160390, 1471, 5884, 0x00000000
-0, 329670, 329670, 0, 196608, 0xa832782f
-1, 161861, 161861, 1472, 5888, 0x00000000
-0, 332640, 332640, 0, 196608, 0xa832782f
-1, 163333, 163333, 1471, 5884, 0x00000000
-0, 335610, 335610, 0, 196608, 0xa832782f
-1, 164804, 164804, 1472, 5888, 0x00000000
-0, 338580, 338580, 0, 196608, 0xa832782f
-1, 166276, 166276, 1471, 5884, 0x00000000
-0, 341550, 341550, 0, 196608, 0xa832782f
-1, 167747, 167747, 1472, 5888, 0x00000000
-0, 344520, 344520, 0, 196608, 0xa832782f
-1, 169219, 169219, 1471, 5884, 0x00000000
-0, 347490, 347490, 0, 196608, 0xa832782f
-1, 170690, 170690, 1472, 5888, 0x00000000
-0, 350460, 350460, 0, 196608, 0xa832782f
-1, 172162, 172162, 1471, 5884, 0xfe4b2bd4
-0, 353430, 353430, 0, 196608, 0xa832782f
-1, 173633, 173633, 1472, 5888, 0x00000000
-0, 356400, 356400, 0, 196608, 0xa832782f
-1, 175105, 175105, 1471, 5884, 0x00000000
-0, 359370, 359370, 0, 196608, 0xa832782f
-1, 176576, 176576, 1472, 5888, 0x00000000
-0, 362340, 362340, 0, 196608, 0xa832782f
-1, 178048, 178048, 1471, 5884, 0x00000000
-0, 365310, 365310, 0, 196608, 0xa832782f
-1, 179519, 179519, 1471, 5884, 0x00000000
-0, 368280, 368280, 0, 196608, 0xa832782f
-1, 180990, 180990, 1472, 5888, 0x00000000
-0, 371250, 371250, 0, 196608, 0xa832782f
-1, 182462, 182462, 1471, 5884, 0x00000000
-0, 374220, 374220, 0, 196608, 0xa832782f
-1, 183933, 183933, 1472, 5888, 0x00000000
-0, 377190, 377190, 0, 196608, 0xa832782f
-1, 185405, 185405, 1471, 5884, 0x00000000
-0, 380160, 380160, 0, 196608, 0xa832782f
-1, 186876, 186876, 1472, 5888, 0x00000000
-0, 383130, 383130, 0, 196608, 0xa832782f
-1, 188348, 188348, 1471, 5884, 0x00000000
-0, 386100, 386100, 0, 196608, 0xa832782f
-1, 189819, 189819, 1472, 5888, 0x00000000
-0, 389070, 389070, 0, 196608, 0xa832782f
-1, 191291, 191291, 1471, 5884, 0x00000000
-0, 392040, 392040, 0, 196608, 0xa832782f
-1, 192762, 192762, 1472, 5888, 0x00000000
-0, 395010, 395010, 0, 196608, 0xa832782f
-1, 194234, 194234, 1471, 5884, 0x00000000
-0, 397980, 397980, 0, 196608, 0xa832782f
-1, 195705, 195705, 1472, 5888, 0x00000000
-0, 400950, 400950, 0, 196608, 0xa832782f
-1, 197177, 197177, 1471, 5884, 0x00000000
-0, 403920, 403920, 0, 196608, 0xa832782f
-1, 198648, 198648, 1472, 5888, 0x00000000
-0, 406890, 406890, 0, 196608, 0xa832782f
-1, 200120, 200120, 1471, 5884, 0x00000000
-0, 409860, 409860, 0, 196608, 0xa832782f
-1, 201591, 201591, 1472, 5888, 0x00000000
-0, 412830, 412830, 0, 196608, 0xa832782f
-1, 203063, 203063, 1471, 5884, 0x00000000
-0, 415800, 415800, 0, 196608, 0xa832782f
-1, 204534, 204534, 1472, 5888, 0x00000000
-0, 418770, 418770, 0, 196608, 0xa832782f
-1, 206006, 206006, 1471, 5884, 0x00000000
-0, 421740, 421740, 0, 196608, 0xa832782f
-1, 207477, 207477, 1262, 5048, 0x00000000
-0, 424710, 424710, 0, 196608, 0xa832782f
-0, 427680, 427680, 0, 196608, 0xa832782f
-0, 430650, 430650, 0, 196608, 0xa832782f
-0, 433620, 433620, 0, 196608, 0xa832782f
-0, 436590, 436590, 0, 196608, 0xa832782f
-0, 439560, 439560, 0, 196608, 0xa832782f
-0, 442530, 442530, 0, 196608, 0xa832782f
diff --git a/tests/ref/fate/ea-tgv-1 b/tests/ref/fate/ea-tgv-1
new file mode 100644
index 0000000..fc92181
--- /dev/null
+++ b/tests/ref/fate/ea-tgv-1
@@ -0,0 +1,48 @@
+#tb 0: 1/15
+0, 0, 0, 1, 230400, 0xfbf2581e
+0, 1, 1, 1, 230400, 0xfbf2581e
+0, 2, 2, 1, 230400, 0xfbf2581e
+0, 3, 3, 1, 230400, 0xfbf2581e
+0, 4, 4, 1, 230400, 0xfbf2581e
+0, 5, 5, 1, 230400, 0xfbf2581e
+0, 6, 6, 1, 230400, 0xfbf2581e
+0, 7, 7, 1, 230400, 0xfbf2581e
+0, 8, 8, 1, 230400, 0xfbf2581e
+0, 9, 9, 1, 230400, 0xfbf2581e
+0, 10, 10, 1, 230400, 0xfbf2581e
+0, 11, 11, 1, 230400, 0xfbf2581e
+0, 12, 12, 1, 230400, 0xfbf2581e
+0, 13, 13, 1, 230400, 0xfbf2581e
+0, 14, 14, 1, 230400, 0xfbf2581e
+0, 15, 15, 1, 230400, 0xf5a0a21d
+0, 16, 16, 1, 230400, 0x909cc039
+0, 17, 17, 1, 230400, 0x14d899dd
+0, 18, 18, 1, 230400, 0x0d246edf
+0, 19, 19, 1, 230400, 0x5345fe0d
+0, 20, 20, 1, 230400, 0x5abdff9a
+0, 21, 21, 1, 230400, 0x1730d973
+0, 22, 22, 1, 230400, 0xec881be9
+0, 23, 23, 1, 230400, 0xf4216895
+0, 24, 24, 1, 230400, 0x529d7a52
+0, 25, 25, 1, 230400, 0x93b4c7b9
+0, 26, 26, 1, 230400, 0xedc65bcd
+0, 27, 27, 1, 230400, 0xf0fb54ae
+0, 28, 28, 1, 230400, 0x27864ce9
+0, 29, 29, 1, 230400, 0xcd05012d
+0, 30, 30, 1, 230400, 0x019b6d84
+0, 31, 31, 1, 230400, 0xcc05d416
+0, 32, 32, 1, 230400, 0xb04c0248
+0, 33, 33, 1, 230400, 0x6806eb92
+0, 34, 34, 1, 230400, 0x60e9c001
+0, 35, 35, 1, 230400, 0x9b040261
+0, 36, 36, 1, 230400, 0x6961fb90
+0, 37, 37, 1, 230400, 0xbf67ad24
+0, 38, 38, 1, 230400, 0x2270f328
+0, 39, 39, 1, 230400, 0xd0c345f6
+0, 40, 40, 1, 230400, 0xfd159212
+0, 41, 41, 1, 230400, 0x085578ff
+0, 42, 42, 1, 230400, 0xcca8afa6
+0, 43, 43, 1, 230400, 0x901ec91c
+0, 44, 44, 1, 230400, 0xf1cb99f3
+0, 45, 45, 1, 230400, 0x86d98f0c
+0, 46, 46, 1, 230400, 0x52970700
diff --git a/tests/ref/fate/ea-tgv-2 b/tests/ref/fate/ea-tgv-2
new file mode 100644
index 0000000..5e9de02
--- /dev/null
+++ b/tests/ref/fate/ea-tgv-2
@@ -0,0 +1,39 @@
+#tb 0: 1/15
+0, 0, 0, 1, 192000, 0xdfc2f225
+0, 1, 1, 1, 192000, 0x059b57bd
+0, 2, 2, 1, 192000, 0x766cb086
+0, 3, 3, 1, 192000, 0x459e3bac
+0, 4, 4, 1, 192000, 0x5293e622
+0, 5, 5, 1, 192000, 0x898b03f4
+0, 6, 6, 1, 192000, 0xb184a627
+0, 7, 7, 1, 192000, 0xa3fc650a
+0, 8, 8, 1, 192000, 0xea448589
+0, 9, 9, 1, 192000, 0x700e2b76
+0, 10, 10, 1, 192000, 0xa1a1d66d
+0, 11, 11, 1, 192000, 0xd63bc8a1
+0, 12, 12, 1, 192000, 0x5f08c023
+0, 13, 13, 1, 192000, 0x8b75ec3b
+0, 14, 14, 1, 192000, 0x62728ce4
+0, 15, 15, 1, 192000, 0xaa007941
+0, 16, 16, 1, 192000, 0x55dc5b3b
+0, 17, 17, 1, 192000, 0x72d836c2
+0, 18, 18, 1, 192000, 0x1f2de2fc
+0, 19, 19, 1, 192000, 0xb295dfdb
+0, 20, 20, 1, 192000, 0xe5c5f634
+0, 21, 21, 1, 192000, 0x455a0464
+0, 22, 22, 1, 192000, 0x3bf2340d
+0, 23, 23, 1, 192000, 0xe368f0fc
+0, 24, 24, 1, 192000, 0xfa7549c0
+0, 25, 25, 1, 192000, 0x4dd76f3d
+0, 26, 26, 1, 192000, 0x50a49f6c
+0, 27, 27, 1, 192000, 0xb6072f65
+0, 28, 28, 1, 192000, 0x093ce1a8
+0, 29, 29, 1, 192000, 0x55afe3db
+0, 30, 30, 1, 192000, 0x81c3bfab
+0, 31, 31, 1, 192000, 0x583ebd3d
+0, 32, 32, 1, 192000, 0x2504f003
+0, 33, 33, 1, 192000, 0x44ade2af
+0, 34, 34, 1, 192000, 0x77cbcfd8
+0, 35, 35, 1, 192000, 0xac7ddfa1
+0, 36, 36, 1, 192000, 0x79f7cfe8
+0, 37, 37, 1, 192000, 0xdf2898fd
diff --git a/tests/ref/fate/ea-tgv-ima-ea-eacs b/tests/ref/fate/ea-tgv-ima-ea-eacs
deleted file mode 100644
index 1814e3c..0000000
--- a/tests/ref/fate/ea-tgv-ima-ea-eacs
+++ /dev/null
@@ -1,96 +0,0 @@
-#tb 0: 1/15
-#tb 1: 1/22050
-0, 0, 0, 1, 230400, 0xfbf2581e
-1, 0, 0, 1468, 5872, 0x00000000
-1, 1468, 1468, 1468, 5872, 0x00000000
-0, 1, 1, 1, 230400, 0xfbf2581e
-1, 2936, 2936, 1468, 5872, 0x00000000
-0, 2, 2, 1, 230400, 0xfbf2581e
-1, 4404, 4404, 1468, 5872, 0x00000000
-0, 3, 3, 1, 230400, 0xfbf2581e
-1, 5872, 5872, 1468, 5872, 0x00000000
-0, 4, 4, 1, 230400, 0xfbf2581e
-1, 7340, 7340, 1468, 5872, 0x00000000
-0, 5, 5, 1, 230400, 0xfbf2581e
-1, 8808, 8808, 1468, 5872, 0x00000000
-0, 6, 6, 1, 230400, 0xfbf2581e
-1, 10276, 10276, 1468, 5872, 0x00000000
-0, 7, 7, 1, 230400, 0xfbf2581e
-1, 11744, 11744, 1468, 5872, 0x00000000
-0, 8, 8, 1, 230400, 0xfbf2581e
-1, 13212, 13212, 1468, 5872, 0x00000000
-0, 9, 9, 1, 230400, 0xfbf2581e
-1, 14680, 14680, 1468, 5872, 0x00000000
-0, 10, 10, 1, 230400, 0xfbf2581e
-1, 16148, 16148, 1468, 5872, 0x00000000
-0, 11, 11, 1, 230400, 0xfbf2581e
-1, 17616, 17616, 1468, 5872, 0x00000000
-0, 12, 12, 1, 230400, 0xfbf2581e
-1, 19084, 19084, 1468, 5872, 0x00000000
-0, 13, 13, 1, 230400, 0xfbf2581e
-1, 20552, 20552, 1468, 5872, 0x00000000
-0, 14, 14, 1, 230400, 0xfbf2581e
-1, 22020, 22020, 1468, 5872, 0xc6f64777
-0, 15, 15, 1, 230400, 0xf5a0a21d
-1, 23488, 23488, 1468, 5872, 0x7c9e60e8
-0, 16, 16, 1, 230400, 0x909cc039
-1, 24956, 24956, 1468, 5872, 0x46525c54
-0, 17, 17, 1, 230400, 0x14d899dd
-1, 26424, 26424, 1468, 5872, 0x842796bb
-0, 18, 18, 1, 230400, 0x0d246edf
-1, 27892, 27892, 1468, 5872, 0xb1f6cbd5
-0, 19, 19, 1, 230400, 0x5345fe0d
-1, 29360, 29360, 1468, 5872, 0x0261a74b
-0, 20, 20, 1, 230400, 0x5abdff9a
-1, 30828, 30828, 1468, 5872, 0x8218b1f9
-0, 21, 21, 1, 230400, 0x1730d973
-1, 32296, 32296, 1468, 5872, 0xd7a2cae6
-0, 22, 22, 1, 230400, 0xec881be9
-1, 33764, 33764, 1468, 5872, 0x69d34562
-0, 23, 23, 1, 230400, 0xf4216895
-1, 35232, 35232, 1468, 5872, 0x9303ec65
-0, 24, 24, 1, 230400, 0x529d7a52
-1, 36700, 36700, 1468, 5872, 0xd5d963a1
-0, 25, 25, 1, 230400, 0x93b4c7b9
-1, 38168, 38168, 1468, 5872, 0x0557e06f
-0, 26, 26, 1, 230400, 0xedc65bcd
-1, 39636, 39636, 1468, 5872, 0x1eb48b41
-0, 27, 27, 1, 230400, 0xf0fb54ae
-1, 41104, 41104, 1468, 5872, 0x70f5ca3f
-0, 28, 28, 1, 230400, 0x27864ce9
-1, 42572, 42572, 1468, 5872, 0xd39e5c5e
-0, 29, 29, 1, 230400, 0xcd05012d
-1, 44040, 44040, 1468, 5872, 0x29c59140
-0, 30, 30, 1, 230400, 0x019b6d84
-1, 45508, 45508, 1468, 5872, 0x7d95e643
-0, 31, 31, 1, 230400, 0xcc05d416
-1, 46976, 46976, 1468, 5872, 0x45353fd8
-0, 32, 32, 1, 230400, 0xb04c0248
-1, 48444, 48444, 1468, 5872, 0xad7b1b27
-0, 33, 33, 1, 230400, 0x6806eb92
-1, 49912, 49912, 1468, 5872, 0x1f0377b3
-0, 34, 34, 1, 230400, 0x60e9c001
-1, 51380, 51380, 1468, 5872, 0x6074541e
-0, 35, 35, 1, 230400, 0x9b040261
-1, 52848, 52848, 1468, 5872, 0xa4f5e892
-0, 36, 36, 1, 230400, 0x6961fb90
-1, 54316, 54316, 1468, 5872, 0x084bc696
-0, 37, 37, 1, 230400, 0xbf67ad24
-1, 55784, 55784, 1468, 5872, 0x67fdafce
-0, 38, 38, 1, 230400, 0x2270f328
-1, 57252, 57252, 1468, 5872, 0x8dfd249d
-0, 39, 39, 1, 230400, 0xd0c345f6
-1, 58720, 58720, 1468, 5872, 0x514184ee
-0, 40, 40, 1, 230400, 0xfd159212
-1, 60188, 60188, 1468, 5872, 0xc0090b0d
-0, 41, 41, 1, 230400, 0x085578ff
-1, 61656, 61656, 1468, 5872, 0xc1171cc8
-0, 42, 42, 1, 230400, 0xcca8afa6
-1, 63124, 63124, 1468, 5872, 0x7d7dd07e
-0, 43, 43, 1, 230400, 0x901ec91c
-1, 64592, 64592, 1468, 5872, 0xe6aa619c
-0, 44, 44, 1, 230400, 0xf1cb99f3
-1, 66060, 66060, 1468, 5872, 0xd5aac0df
-0, 45, 45, 1, 230400, 0x86d98f0c
-1, 67528, 67528, 1468, 5872, 0x3b68b390
-0, 46, 46, 1, 230400, 0x52970700
diff --git a/tests/ref/fate/ea-tgv-ima-ea-sead b/tests/ref/fate/ea-tgv-ima-ea-sead
deleted file mode 100644
index bfc9cb5..0000000
--- a/tests/ref/fate/ea-tgv-ima-ea-sead
+++ /dev/null
@@ -1,89 +0,0 @@
-#tb 0: 1/15
-#tb 1: 1/22050
-0, 0, 0, 1, 192000, 0xdfc2f225
-1, 0, 0, 736, 2944, 0x00000000
-1, 736, 736, 1472, 5888, 0x5ae3c2a4
-0, 1, 1, 1, 192000, 0x059b57bd
-1, 2208, 2208, 1472, 5888, 0x158fbcb4
-0, 2, 2, 1, 192000, 0x766cb086
-1, 3680, 3680, 1472, 5888, 0x3fc85d35
-0, 3, 3, 1, 192000, 0x459e3bac
-1, 5152, 5152, 1472, 5888, 0x4667ec2b
-0, 4, 4, 1, 192000, 0x5293e622
-1, 6624, 6624, 1472, 5888, 0x82744494
-0, 5, 5, 1, 192000, 0x898b03f4
-1, 8096, 8096, 1472, 5888, 0x3b0cb86f
-0, 6, 6, 1, 192000, 0xb184a627
-1, 9568, 9568, 1472, 5888, 0x29493fbb
-0, 7, 7, 1, 192000, 0xa3fc650a
-1, 11040, 11040, 1472, 5888, 0xaa2d8595
-0, 8, 8, 1, 192000, 0xea448589
-1, 12512, 12512, 1472, 5888, 0x2e563de6
-0, 9, 9, 1, 192000, 0x700e2b76
-1, 13984, 13984, 1472, 5888, 0x225cca99
-0, 10, 10, 1, 192000, 0xa1a1d66d
-1, 15456, 15456, 1472, 5888, 0x2b577599
-0, 11, 11, 1, 192000, 0xd63bc8a1
-1, 16928, 16928, 1472, 5888, 0x3d967f32
-0, 12, 12, 1, 192000, 0x5f08c023
-1, 18400, 18400, 1472, 5888, 0x16639a84
-0, 13, 13, 1, 192000, 0x8b75ec3b
-1, 19872, 19872, 1472, 5888, 0x90549ba0
-0, 14, 14, 1, 192000, 0x62728ce4
-1, 21344, 21344, 1472, 5888, 0xf46e6644
-0, 15, 15, 1, 192000, 0xaa007941
-1, 22816, 22816, 1472, 5888, 0x39a073ec
-0, 16, 16, 1, 192000, 0x55dc5b3b
-1, 24288, 24288, 1472, 5888, 0xb1d7a93a
-0, 17, 17, 1, 192000, 0x72d836c2
-1, 25760, 25760, 1472, 5888, 0x25e9795b
-0, 18, 18, 1, 192000, 0x1f2de2fc
-1, 27232, 27232, 1472, 5888, 0xbbc07644
-0, 19, 19, 1, 192000, 0xb295dfdb
-1, 28704, 28704, 1472, 5888, 0x323f6a1b
-0, 20, 20, 1, 192000, 0xe5c5f634
-1, 30176, 30176, 1472, 5888, 0x7cae130b
-0, 21, 21, 1, 192000, 0x455a0464
-1, 31648, 31648, 1472, 5888, 0xd23bf9c6
-0, 22, 22, 1, 192000, 0x3bf2340d
-1, 33120, 33120, 1472, 5888, 0x5f73ef35
-0, 23, 23, 1, 192000, 0xe368f0fc
-1, 34592, 34592, 1472, 5888, 0xc66026be
-0, 24, 24, 1, 192000, 0xfa7549c0
-1, 36064, 36064, 1472, 5888, 0xc8fdb539
-0, 25, 25, 1, 192000, 0x4dd76f3d
-1, 37536, 37536, 1472, 5888, 0x94c6bfbd
-0, 26, 26, 1, 192000, 0x50a49f6c
-1, 39008, 39008, 1472, 5888, 0xb77e1b83
-0, 27, 27, 1, 192000, 0xb6072f65
-1, 40480, 40480, 1472, 5888, 0x6c6d6693
-0, 28, 28, 1, 192000, 0x093ce1a8
-1, 41952, 41952, 1472, 5888, 0xd9f064d4
-0, 29, 29, 1, 192000, 0x55afe3db
-1, 43424, 43424, 1472, 5888, 0x85dd990d
-0, 30, 30, 1, 192000, 0x81c3bfab
-1, 44896, 44896, 1472, 5888, 0x385e021b
-0, 31, 31, 1, 192000, 0x583ebd3d
-1, 46368, 46368, 1472, 5888, 0xac09fd02
-0, 32, 32, 1, 192000, 0x2504f003
-1, 47840, 47840, 1472, 5888, 0xc6dcdff2
-0, 33, 33, 1, 192000, 0x44ade2af
-1, 49312, 49312, 1472, 5888, 0x86a6944d
-0, 34, 34, 1, 192000, 0x77cbcfd8
-1, 50784, 50784, 1472, 5888, 0x8587b964
-0, 35, 35, 1, 192000, 0xac7ddfa1
-1, 52256, 52256, 1472, 5888, 0x2b0355ff
-0, 36, 36, 1, 192000, 0x79f7cfe8
-1, 53728, 53728, 1472, 5888, 0xe4148a85
-0, 37, 37, 1, 192000, 0xdf2898fd
-1, 55200, 55200, 1472, 5888, 0xdf02ed4f
-1, 56672, 56672, 1472, 5888, 0x87a54b15
-1, 58144, 58144, 1472, 5888, 0x3ad2be45
-1, 59616, 59616, 1472, 5888, 0x3a49c2c3
-1, 61088, 61088, 1472, 5888, 0xc2b66404
-1, 62560, 62560, 1472, 5888, 0xac3e234a
-1, 64032, 64032, 1472, 5888, 0x5dcf523b
-1, 65504, 65504, 1472, 5888, 0x2034b5d6
-1, 66976, 66976, 1472, 5888, 0x96882832
-1, 68448, 68448, 1472, 5888, 0x2be3d534
-1, 69920, 69920, 1472, 5888, 0xa841a49d
diff --git a/tests/ref/fate/ea-tqi b/tests/ref/fate/ea-tqi
new file mode 100644
index 0000000..ba0073b
--- /dev/null
+++ b/tests/ref/fate/ea-tqi
@@ -0,0 +1,27 @@
+#tb 0: 1/90000
+0, 0, 0, 0, 115200, 0x375ec573
+0, 6000, 6000, 0, 115200, 0x375ec573
+0, 12000, 12000, 0, 115200, 0x375ec573
+0, 18000, 18000, 0, 115200, 0x375ec573
+0, 24000, 24000, 0, 115200, 0x375ec573
+0, 30000, 30000, 0, 115200, 0x375ec573
+0, 36000, 36000, 0, 115200, 0x375ec573
+0, 42000, 42000, 0, 115200, 0x375ec573
+0, 48000, 48000, 0, 115200, 0x0b4d31bf
+0, 54000, 54000, 0, 115200, 0xdd724598
+0, 60000, 60000, 0, 115200, 0xc3077e75
+0, 66000, 66000, 0, 115200, 0xbf70778a
+0, 72000, 72000, 0, 115200, 0x117eb766
+0, 78000, 78000, 0, 115200, 0x4617fbad
+0, 84000, 84000, 0, 115200, 0x5f5b02d2
+0, 90000, 90000, 0, 115200, 0x2a9c5325
+0, 96000, 96000, 0, 115200, 0x14a89e2a
+0, 102000, 102000, 0, 115200, 0xe69aa994
+0, 108000, 108000, 0, 115200, 0xfbacf589
+0, 114000, 114000, 0, 115200, 0x1d714c6e
+0, 120000, 120000, 0, 115200, 0x6eff66cb
+0, 126000, 126000, 0, 115200, 0xee21c1cb
+0, 132000, 132000, 0, 115200, 0xce714ada
+0, 138000, 138000, 0, 115200, 0xf89d56c3
+0, 144000, 144000, 0, 115200, 0x65fd5e60
+0, 150000, 150000, 0, 115200, 0x0c256424
diff --git a/tests/ref/fate/eval b/tests/ref/fate/eval
index ef50292..b6ca0fa 100644
--- a/tests/ref/fate/eval
+++ b/tests/ref/fate/eval
@@ -112,6 +112,18 @@ Evaluating 'isnan(1)'
Evaluating 'isnan(NAN)'
'isnan(NAN)' -> 1.000000
+Evaluating 'isnan(INF)'
+'isnan(INF)' -> 0.000000
+
+Evaluating 'isinf(1)'
+'isinf(1)' -> 0.000000
+
+Evaluating 'isinf(NAN)'
+'isinf(NAN)' -> 0.000000
+
+Evaluating 'isinf(INF)'
+'isinf(INF)' -> 1.000000
+
Evaluating 'floor(NAN)'
'floor(NAN)' -> nan
diff --git a/tests/ref/fate/film-cvid b/tests/ref/fate/film-cvid
new file mode 100644
index 0000000..12b1f1c
--- /dev/null
+++ b/tests/ref/fate/film-cvid
@@ -0,0 +1,111 @@
+#tb 0: 1/30
+0, 0, 0, 1, 107520, 0xa6c9fdd2
+0, 2, 2, 1, 107520, 0x61eb28c1
+0, 4, 4, 1, 107520, 0x45e20af7
+0, 6, 6, 1, 107520, 0x366970fc
+0, 8, 8, 1, 107520, 0xa392bcb3
+0, 10, 10, 1, 107520, 0xcf7bac98
+0, 12, 12, 1, 107520, 0x222eba53
+0, 14, 14, 1, 107520, 0x74e255a1
+0, 16, 16, 1, 107520, 0xc19eec6f
+0, 18, 18, 1, 107520, 0xa3880681
+0, 20, 20, 1, 107520, 0x957878db
+0, 22, 22, 1, 107520, 0x18340692
+0, 24, 24, 1, 107520, 0x9970f24d
+0, 26, 26, 1, 107520, 0xf08618aa
+0, 28, 28, 1, 107520, 0xee7324f0
+0, 30, 30, 1, 107520, 0xe15025b3
+0, 32, 32, 1, 107520, 0x8afa312e
+0, 34, 34, 1, 107520, 0x717a7d0f
+0, 36, 36, 1, 107520, 0x355c6e23
+0, 38, 38, 1, 107520, 0x7015a50f
+0, 40, 40, 1, 107520, 0xcdfc1a16
+0, 42, 42, 1, 107520, 0x38d929e7
+0, 44, 44, 1, 107520, 0x52913423
+0, 46, 46, 1, 107520, 0xe2c91c10
+0, 48, 48, 1, 107520, 0x85516e9c
+0, 50, 50, 1, 107520, 0xd1626030
+0, 52, 52, 1, 107520, 0xea7b16de
+0, 54, 54, 1, 107520, 0xa33eaa0d
+0, 56, 56, 1, 107520, 0x8e3be6a6
+0, 58, 58, 1, 107520, 0x14147bd6
+0, 60, 60, 1, 107520, 0x07d54bec
+0, 62, 62, 1, 107520, 0xe287a0a7
+0, 64, 64, 1, 107520, 0xc023a14d
+0, 66, 66, 1, 107520, 0x2437085d
+0, 68, 68, 1, 107520, 0x63823918
+0, 70, 70, 1, 107520, 0xbc17e198
+0, 72, 72, 1, 107520, 0x9d99bc81
+0, 74, 74, 1, 107520, 0x7e4ec71e
+0, 76, 76, 1, 107520, 0x55b98376
+0, 78, 78, 1, 107520, 0x356d8e9e
+0, 80, 80, 1, 107520, 0xf77e8a61
+0, 82, 82, 1, 107520, 0x5ae7c8c7
+0, 84, 84, 1, 107520, 0x8acf9322
+0, 86, 86, 1, 107520, 0x40a9177e
+0, 88, 88, 1, 107520, 0x3e0e4d8d
+0, 90, 90, 1, 107520, 0xd268865b
+0, 92, 92, 1, 107520, 0x89a4efeb
+0, 94, 94, 1, 107520, 0x70ca2478
+0, 96, 96, 1, 107520, 0xcc9ec981
+0, 98, 98, 1, 107520, 0xf0648459
+0, 100, 100, 1, 107520, 0x7e4a4cca
+0, 102, 102, 1, 107520, 0xb315dc65
+0, 104, 104, 1, 107520, 0x2aecc7b4
+0, 106, 106, 1, 107520, 0x81742f51
+0, 108, 108, 1, 107520, 0x3a1d7571
+0, 110, 110, 1, 107520, 0x3a1d7571
+0, 112, 112, 1, 107520, 0x3a1d7571
+0, 114, 114, 1, 107520, 0x3a1d7571
+0, 116, 116, 1, 107520, 0x3a1d7571
+0, 118, 118, 1, 107520, 0x3a1d7571
+0, 120, 120, 1, 107520, 0x3a1d7571
+0, 122, 122, 1, 107520, 0xe974733e
+0, 124, 124, 1, 107520, 0x999c6fbf
+0, 126, 126, 1, 107520, 0x26b56b6e
+0, 128, 128, 1, 107520, 0xc9f9647b
+0, 130, 130, 1, 107520, 0x6d025d00
+0, 132, 132, 1, 107520, 0xf9c056c1
+0, 134, 134, 1, 107520, 0xa5cc4d0b
+0, 136, 136, 1, 107520, 0x1a4c4236
+0, 138, 138, 1, 107520, 0xa9d538b6
+0, 140, 140, 1, 107520, 0x14682d00
+0, 142, 142, 1, 107520, 0x6236204f
+0, 144, 144, 1, 107520, 0x303e14aa
+0, 146, 146, 1, 107520, 0x943b0837
+0, 148, 148, 1, 107520, 0xfce5fd07
+0, 150, 150, 1, 107520, 0xd993f193
+0, 152, 152, 1, 107520, 0x4d48e7b4
+0, 154, 154, 1, 107520, 0x61ccdf83
+0, 156, 156, 1, 107520, 0xfb4fd608
+0, 158, 158, 1, 107520, 0x5efdcdb3
+0, 160, 160, 1, 107520, 0xb03ec886
+0, 162, 162, 1, 107520, 0xf464c343
+0, 164, 164, 1, 107520, 0xf464c343
+0, 166, 166, 1, 107520, 0xf464c343
+0, 168, 168, 1, 107520, 0xf464c343
+0, 170, 170, 1, 107520, 0xf464c343
+0, 172, 172, 1, 107520, 0xf464c343
+0, 174, 174, 1, 107520, 0xf464c343
+0, 176, 176, 1, 107520, 0xf464c343
+0, 178, 178, 1, 107520, 0xf464c343
+0, 180, 180, 1, 107520, 0xf464c343
+0, 182, 182, 1, 107520, 0xf464c343
+0, 184, 184, 1, 107520, 0xf2b2c712
+0, 186, 186, 1, 107520, 0xf2b2c712
+0, 188, 188, 1, 107520, 0xf2b2c712
+0, 190, 190, 1, 107520, 0xf2b2c712
+0, 192, 192, 1, 107520, 0xb95e6bc8
+0, 194, 194, 1, 107520, 0x33feee37
+0, 196, 196, 1, 107520, 0x36ee3cd5
+0, 198, 198, 1, 107520, 0x59096471
+0, 200, 200, 1, 107520, 0x53b470c6
+0, 202, 202, 1, 107520, 0xdb7c64ff
+0, 204, 204, 1, 107520, 0xe5a1596a
+0, 206, 206, 1, 107520, 0x8c8942eb
+0, 208, 208, 1, 107520, 0x5ecc379e
+0, 210, 210, 1, 107520, 0xea09432a
+0, 212, 212, 1, 107520, 0xe01e6b73
+0, 214, 214, 1, 107520, 0x1d13bba8
+0, 216, 216, 1, 107520, 0x3a993a6c
+0, 218, 218, 1, 107520, 0x2ede041a
diff --git a/tests/ref/fate/film-cvid-pcm-stereo-8bit b/tests/ref/fate/film-cvid-pcm-stereo-8bit
deleted file mode 100644
index 40851e2..0000000
--- a/tests/ref/fate/film-cvid-pcm-stereo-8bit
+++ /dev/null
@@ -1,141 +0,0 @@
-#tb 0: 1/30
-#tb 1: 1/44100
-0, 0, 0, 1, 107520, 0xa6c9fdd2
-1, 0, 0, 22048, 88192, 0x23bb50ae
-0, 2, 2, 1, 107520, 0x61eb28c1
-0, 4, 4, 1, 107520, 0x45e20af7
-0, 6, 6, 1, 107520, 0x366970fc
-0, 8, 8, 1, 107520, 0xa392bcb3
-0, 10, 10, 1, 107520, 0xcf7bac98
-0, 12, 12, 1, 107520, 0x222eba53
-0, 14, 14, 1, 107520, 0x74e255a1
-1, 22048, 22048, 11028, 44112, 0x79600f01
-0, 16, 16, 1, 107520, 0xc19eec6f
-0, 18, 18, 1, 107520, 0xa3880681
-0, 20, 20, 1, 107520, 0x957878db
-0, 22, 22, 1, 107520, 0x18340692
-1, 33076, 33076, 11024, 44096, 0x09dbf7aa
-0, 24, 24, 1, 107520, 0x9970f24d
-0, 26, 26, 1, 107520, 0xf08618aa
-0, 28, 28, 1, 107520, 0xee7324f0
-0, 30, 30, 1, 107520, 0xe15025b3
-1, 44100, 44100, 11028, 44112, 0x18fed048
-0, 32, 32, 1, 107520, 0x8afa312e
-0, 34, 34, 1, 107520, 0x717a7d0f
-0, 36, 36, 1, 107520, 0x355c6e23
-1, 55128, 55128, 11028, 44112, 0x030d35ef
-0, 38, 38, 1, 107520, 0x7015a50f
-0, 40, 40, 1, 107520, 0xcdfc1a16
-0, 42, 42, 1, 107520, 0x38d929e7
-0, 44, 44, 1, 107520, 0x52913423
-1, 66156, 66156, 11028, 44112, 0xc23154d5
-0, 46, 46, 1, 107520, 0xe2c91c10
-0, 48, 48, 1, 107520, 0x85516e9c
-0, 50, 50, 1, 107520, 0xd1626030
-0, 52, 52, 1, 107520, 0xea7b16de
-1, 77184, 77184, 11016, 44064, 0xe4713ee7
-0, 54, 54, 1, 107520, 0xa33eaa0d
-0, 56, 56, 1, 107520, 0x8e3be6a6
-0, 58, 58, 1, 107520, 0x14147bd6
-0, 60, 60, 1, 107520, 0x07d54bec
-1, 88200, 88200, 11028, 44112, 0xddc19d91
-0, 62, 62, 1, 107520, 0xe287a0a7
-0, 64, 64, 1, 107520, 0xc023a14d
-0, 66, 66, 1, 107520, 0x2437085d
-1, 99228, 99228, 11028, 44112, 0x9591522d
-0, 68, 68, 1, 107520, 0x63823918
-0, 70, 70, 1, 107520, 0xbc17e198
-0, 72, 72, 1, 107520, 0x9d99bc81
-0, 74, 74, 1, 107520, 0x7e4ec71e
-1, 110256, 110256, 11028, 44112, 0x90deb013
-0, 76, 76, 1, 107520, 0x55b98376
-0, 78, 78, 1, 107520, 0x356d8e9e
-0, 80, 80, 1, 107520, 0xf77e8a61
-0, 82, 82, 1, 107520, 0x5ae7c8c7
-1, 121284, 121284, 11016, 44064, 0x3842d420
-0, 84, 84, 1, 107520, 0x8acf9322
-0, 86, 86, 1, 107520, 0x40a9177e
-0, 88, 88, 1, 107520, 0x3e0e4d8d
-0, 90, 90, 1, 107520, 0xd268865b
-1, 132300, 132300, 11028, 44112, 0x99c8c3d9
-0, 92, 92, 1, 107520, 0x89a4efeb
-0, 94, 94, 1, 107520, 0x70ca2478
-0, 96, 96, 1, 107520, 0xcc9ec981
-1, 143328, 143328, 11028, 44112, 0xffaf3824
-0, 98, 98, 1, 107520, 0xf0648459
-0, 100, 100, 1, 107520, 0x7e4a4cca
-0, 102, 102, 1, 107520, 0xb315dc65
-0, 104, 104, 1, 107520, 0x2aecc7b4
-1, 154356, 154356, 11028, 44112, 0x3dbe1aef
-0, 106, 106, 1, 107520, 0x81742f51
-0, 108, 108, 1, 107520, 0x3a1d7571
-0, 110, 110, 1, 107520, 0x3a1d7571
-0, 112, 112, 1, 107520, 0x3a1d7571
-1, 165384, 165384, 11016, 44064, 0xed2c7dfb
-0, 114, 114, 1, 107520, 0x3a1d7571
-0, 116, 116, 1, 107520, 0x3a1d7571
-0, 118, 118, 1, 107520, 0x3a1d7571
-0, 120, 120, 1, 107520, 0x3a1d7571
-1, 176400, 176400, 11028, 44112, 0x9e475274
-0, 122, 122, 1, 107520, 0xe974733e
-0, 124, 124, 1, 107520, 0x999c6fbf
-0, 126, 126, 1, 107520, 0x26b56b6e
-1, 187428, 187428, 11028, 44112, 0x541f05d4
-0, 128, 128, 1, 107520, 0xc9f9647b
-0, 130, 130, 1, 107520, 0x6d025d00
-0, 132, 132, 1, 107520, 0xf9c056c1
-0, 134, 134, 1, 107520, 0xa5cc4d0b
-1, 198456, 198456, 11028, 44112, 0x09e39025
-0, 136, 136, 1, 107520, 0x1a4c4236
-0, 138, 138, 1, 107520, 0xa9d538b6
-0, 140, 140, 1, 107520, 0x14682d00
-0, 142, 142, 1, 107520, 0x6236204f
-1, 209484, 209484, 11016, 44064, 0xdc111087
-0, 144, 144, 1, 107520, 0x303e14aa
-0, 146, 146, 1, 107520, 0x943b0837
-0, 148, 148, 1, 107520, 0xfce5fd07
-0, 150, 150, 1, 107520, 0xd993f193
-1, 220500, 220500, 11028, 44112, 0xb8f86e48
-0, 152, 152, 1, 107520, 0x4d48e7b4
-0, 154, 154, 1, 107520, 0x61ccdf83
-0, 156, 156, 1, 107520, 0xfb4fd608
-1, 231528, 231528, 11028, 44112, 0xa1e0c75c
-0, 158, 158, 1, 107520, 0x5efdcdb3
-0, 160, 160, 1, 107520, 0xb03ec886
-0, 162, 162, 1, 107520, 0xf464c343
-0, 164, 164, 1, 107520, 0xf464c343
-1, 242556, 242556, 11028, 44112, 0x0654dcb0
-0, 166, 166, 1, 107520, 0xf464c343
-0, 168, 168, 1, 107520, 0xf464c343
-0, 170, 170, 1, 107520, 0xf464c343
-0, 172, 172, 1, 107520, 0xf464c343
-1, 253584, 253584, 11016, 44064, 0xb921e11a
-0, 174, 174, 1, 107520, 0xf464c343
-0, 176, 176, 1, 107520, 0xf464c343
-0, 178, 178, 1, 107520, 0xf464c343
-0, 180, 180, 1, 107520, 0xf464c343
-1, 264600, 264600, 11028, 44112, 0xe0ac619f
-0, 182, 182, 1, 107520, 0xf464c343
-0, 184, 184, 1, 107520, 0xf2b2c712
-0, 186, 186, 1, 107520, 0xf2b2c712
-1, 275628, 275628, 11028, 44112, 0xb07aa65c
-0, 188, 188, 1, 107520, 0xf2b2c712
-0, 190, 190, 1, 107520, 0xf2b2c712
-0, 192, 192, 1, 107520, 0xb95e6bc8
-0, 194, 194, 1, 107520, 0x33feee37
-1, 286656, 286656, 11028, 44112, 0x24610ff0
-0, 196, 196, 1, 107520, 0x36ee3cd5
-0, 198, 198, 1, 107520, 0x59096471
-0, 200, 200, 1, 107520, 0x53b470c6
-0, 202, 202, 1, 107520, 0xdb7c64ff
-1, 297684, 297684, 11016, 44064, 0x00000000
-0, 204, 204, 1, 107520, 0xe5a1596a
-0, 206, 206, 1, 107520, 0x8c8942eb
-0, 208, 208, 1, 107520, 0x5ecc379e
-0, 210, 210, 1, 107520, 0xea09432a
-1, 308700, 308700, 11028, 44112, 0x00000000
-0, 212, 212, 1, 107520, 0xe01e6b73
-0, 214, 214, 1, 107520, 0x1d13bba8
-0, 216, 216, 1, 107520, 0x3a993a6c
-1, 319728, 319728, 2200, 8800, 0x00000000
-0, 218, 218, 1, 107520, 0x2ede041a
diff --git a/tests/ref/fate/h264-conformance-cabac_mot_fld0_full b/tests/ref/fate/h264-conformance-cabac_mot_fld0_full
index d1093c1..b131cda 100644
--- a/tests/ref/fate/h264-conformance-cabac_mot_fld0_full
+++ b/tests/ref/fate/h264-conformance-cabac_mot_fld0_full
@@ -1,31 +1,31 @@
#tb 0: 1/25
-0, 2, 2, 1, 518400, 0xbf168f4e
-0, 4, 4, 1, 518400, 0xeda5e54f
-0, 6, 6, 1, 518400, 0xef496d43
-0, 8, 8, 1, 518400, 0x6b68dad5
-0, 10, 10, 1, 518400, 0x9a40a7de
-0, 12, 12, 1, 518400, 0x0c21c018
-0, 14, 14, 1, 518400, 0x4ac5a846
-0, 16, 16, 1, 518400, 0x3a1aa817
-0, 18, 18, 1, 518400, 0xcc4eb434
-0, 20, 20, 1, 518400, 0x4368a3c2
-0, 22, 22, 1, 518400, 0xb923682f
-0, 24, 24, 1, 518400, 0xd95460a8
-0, 26, 26, 1, 518400, 0x8e8518aa
-0, 28, 28, 1, 518400, 0x292a1a80
-0, 30, 30, 1, 518400, 0xbada388e
-0, 32, 32, 1, 518400, 0xa67f63c9
-0, 34, 34, 1, 518400, 0x9fc77e21
-0, 36, 36, 1, 518400, 0xe99dc2ac
-0, 38, 38, 1, 518400, 0x17d7d080
-0, 40, 40, 1, 518400, 0x41760c0b
-0, 42, 42, 1, 518400, 0x3c70f34d
-0, 44, 44, 1, 518400, 0x0d640285
-0, 46, 46, 1, 518400, 0x448893e8
-0, 48, 48, 1, 518400, 0x08194490
-0, 50, 50, 1, 518400, 0xcf227031
-0, 52, 52, 1, 518400, 0x8d94587d
-0, 54, 54, 1, 518400, 0x696fca01
-0, 56, 56, 1, 518400, 0xe0ab234b
-0, 58, 58, 1, 518400, 0x0620153b
-0, 59, 59, 1, 518400, 0xb78c146c
+0, 0, 0, 1, 518400, 0xbf168f4e
+0, 1, 1, 1, 518400, 0xeda5e54f
+0, 2, 2, 1, 518400, 0xef496d43
+0, 3, 3, 1, 518400, 0x6b68dad5
+0, 4, 4, 1, 518400, 0x9a40a7de
+0, 5, 5, 1, 518400, 0x0c21c018
+0, 6, 6, 1, 518400, 0x4ac5a846
+0, 7, 7, 1, 518400, 0x3a1aa817
+0, 8, 8, 1, 518400, 0xcc4eb434
+0, 9, 9, 1, 518400, 0x4368a3c2
+0, 10, 10, 1, 518400, 0xb923682f
+0, 11, 11, 1, 518400, 0xd95460a8
+0, 12, 12, 1, 518400, 0x8e8518aa
+0, 13, 13, 1, 518400, 0x292a1a80
+0, 14, 14, 1, 518400, 0xbada388e
+0, 15, 15, 1, 518400, 0xa67f63c9
+0, 16, 16, 1, 518400, 0x9fc77e21
+0, 17, 17, 1, 518400, 0xe99dc2ac
+0, 18, 18, 1, 518400, 0x17d7d080
+0, 19, 19, 1, 518400, 0x41760c0b
+0, 20, 20, 1, 518400, 0x3c70f34d
+0, 21, 21, 1, 518400, 0x0d640285
+0, 22, 22, 1, 518400, 0x448893e8
+0, 23, 23, 1, 518400, 0x08194490
+0, 24, 24, 1, 518400, 0xcf227031
+0, 25, 25, 1, 518400, 0x8d94587d
+0, 26, 26, 1, 518400, 0x696fca01
+0, 27, 27, 1, 518400, 0xe0ab234b
+0, 28, 28, 1, 518400, 0x0620153b
+0, 29, 29, 1, 518400, 0xb78c146c
diff --git a/tests/ref/fate/h264-conformance-cabac_mot_picaff0_full b/tests/ref/fate/h264-conformance-cabac_mot_picaff0_full
index 32210af..484025e 100644
--- a/tests/ref/fate/h264-conformance-cabac_mot_picaff0_full
+++ b/tests/ref/fate/h264-conformance-cabac_mot_picaff0_full
@@ -1,31 +1,31 @@
#tb 0: 1/25
-0, 1, 1, 1, 518400, 0xd8b58a23
-0, 3, 3, 1, 518400, 0xe53b4aba
-0, 4, 4, 1, 518400, 0x6cbca47a
-0, 5, 5, 1, 518400, 0xceb51253
-0, 6, 6, 1, 518400, 0x60cb3cdd
-0, 8, 8, 1, 518400, 0x7b633553
-0, 10, 10, 1, 518400, 0x10c012c9
-0, 12, 12, 1, 518400, 0xa340ee20
-0, 13, 13, 1, 518400, 0x574c22c2
-0, 14, 14, 1, 518400, 0xbcdb1bf7
-0, 15, 15, 1, 518400, 0x57811e9a
-0, 17, 17, 1, 518400, 0xdd4af748
-0, 19, 19, 1, 518400, 0xb931a637
-0, 21, 21, 1, 518400, 0xcef6ce95
-0, 22, 22, 1, 518400, 0xd28c7085
-0, 23, 23, 1, 518400, 0xae9daf53
-0, 24, 24, 1, 518400, 0xca29d819
-0, 26, 26, 1, 518400, 0x3c4bd7eb
-0, 28, 28, 1, 518400, 0x912ee227
-0, 30, 30, 1, 518400, 0xb67d0e27
-0, 31, 31, 1, 518400, 0x8cf7309d
-0, 32, 32, 1, 518400, 0x358ad344
-0, 33, 33, 1, 518400, 0x4462c642
-0, 35, 35, 1, 518400, 0x3bb43428
-0, 37, 37, 1, 518400, 0x12d6f8ca
-0, 39, 39, 1, 518400, 0x003f13aa
-0, 40, 40, 1, 518400, 0x6cd8c432
-0, 41, 41, 1, 518400, 0xee5ff01b
-0, 43, 43, 1, 518400, 0xba0616ee
-0, 44, 44, 1, 518400, 0x37fa7891
+0, 0, 0, 1, 518400, 0xd8b58a23
+0, 1, 1, 1, 518400, 0xe53b4aba
+0, 2, 2, 1, 518400, 0x6cbca47a
+0, 3, 3, 1, 518400, 0xceb51253
+0, 4, 4, 1, 518400, 0x60cb3cdd
+0, 5, 5, 1, 518400, 0x7b633553
+0, 6, 6, 1, 518400, 0x10c012c9
+0, 7, 7, 1, 518400, 0xa340ee20
+0, 8, 8, 1, 518400, 0x574c22c2
+0, 9, 9, 1, 518400, 0xbcdb1bf7
+0, 10, 10, 1, 518400, 0x57811e9a
+0, 11, 11, 1, 518400, 0xdd4af748
+0, 12, 12, 1, 518400, 0xb931a637
+0, 13, 13, 1, 518400, 0xcef6ce95
+0, 14, 14, 1, 518400, 0xd28c7085
+0, 15, 15, 1, 518400, 0xae9daf53
+0, 16, 16, 1, 518400, 0xca29d819
+0, 17, 17, 1, 518400, 0x3c4bd7eb
+0, 18, 18, 1, 518400, 0x912ee227
+0, 19, 19, 1, 518400, 0xb67d0e27
+0, 20, 20, 1, 518400, 0x8cf7309d
+0, 21, 21, 1, 518400, 0x358ad344
+0, 22, 22, 1, 518400, 0x4462c642
+0, 23, 23, 1, 518400, 0x3bb43428
+0, 24, 24, 1, 518400, 0x12d6f8ca
+0, 25, 25, 1, 518400, 0x003f13aa
+0, 26, 26, 1, 518400, 0x6cd8c432
+0, 27, 27, 1, 518400, 0xee5ff01b
+0, 28, 28, 1, 518400, 0xba0616ee
+0, 29, 29, 1, 518400, 0x37fa7891
diff --git a/tests/ref/fate/h264-conformance-cabref3_sand_d b/tests/ref/fate/h264-conformance-cabref3_sand_d
index 247ac2e..9e555f6 100644
--- a/tests/ref/fate/h264-conformance-cabref3_sand_d
+++ b/tests/ref/fate/h264-conformance-cabref3_sand_d
@@ -1,51 +1,51 @@
#tb 0: 1/25
-0, 2, 2, 1, 152064, 0x2061bbd0
-0, 4, 4, 1, 152064, 0x41adb750
-0, 6, 6, 1, 152064, 0x6e889e90
-0, 8, 8, 1, 152064, 0xbb5e60f5
-0, 10, 10, 1, 152064, 0x5a32eca7
-0, 12, 12, 1, 152064, 0x5cb05e88
-0, 14, 14, 1, 152064, 0x2fff3e6c
-0, 16, 16, 1, 152064, 0xd917c85e
-0, 18, 18, 1, 152064, 0x6eac446f
-0, 20, 20, 1, 152064, 0x238b24b0
-0, 22, 22, 1, 152064, 0x3f3bd44c
-0, 24, 24, 1, 152064, 0x73982bc5
-0, 26, 26, 1, 152064, 0xf6188a82
-0, 28, 28, 1, 152064, 0x818c5b41
-0, 30, 30, 1, 152064, 0x000d1012
-0, 32, 32, 1, 152064, 0xc4a8750e
-0, 34, 34, 1, 152064, 0x1689bb77
-0, 36, 36, 1, 152064, 0x8f52f338
-0, 38, 38, 1, 152064, 0xbf5ee06b
-0, 40, 40, 1, 152064, 0x89508ad7
-0, 42, 42, 1, 152064, 0x2b1986a6
-0, 44, 44, 1, 152064, 0xe6fd6b0e
-0, 46, 46, 1, 152064, 0x883e2e4e
-0, 48, 48, 1, 152064, 0xd133db07
-0, 50, 50, 1, 152064, 0x39b3bb22
-0, 52, 52, 1, 152064, 0x8447410a
-0, 54, 54, 1, 152064, 0x9c66c6e5
-0, 56, 56, 1, 152064, 0x514de9cc
-0, 58, 58, 1, 152064, 0x08d9f1da
-0, 60, 60, 1, 152064, 0x8f10f536
-0, 62, 62, 1, 152064, 0x57d4b27b
-0, 64, 64, 1, 152064, 0x46f56d3c
-0, 66, 66, 1, 152064, 0x5d260230
-0, 68, 68, 1, 152064, 0x4a72aeac
-0, 70, 70, 1, 152064, 0x5cfe187f
-0, 72, 72, 1, 152064, 0x08e55cb2
-0, 74, 74, 1, 152064, 0x4727f34f
-0, 76, 76, 1, 152064, 0xd6a26f1c
-0, 78, 78, 1, 152064, 0xcc1fcf9c
-0, 80, 80, 1, 152064, 0x3681b775
-0, 82, 82, 1, 152064, 0xf580c7d9
-0, 84, 84, 1, 152064, 0xaa6747fb
-0, 86, 86, 1, 152064, 0x2e22f9f9
-0, 88, 88, 1, 152064, 0xb3ee6d81
-0, 90, 90, 1, 152064, 0x930b0145
-0, 92, 92, 1, 152064, 0xae36af99
-0, 94, 94, 1, 152064, 0xeb58fd26
-0, 96, 96, 1, 152064, 0xb9004da3
-0, 98, 98, 1, 152064, 0x2b25e444
-0, 99, 99, 1, 152064, 0xb36927de
+0, 0, 0, 1, 152064, 0x2061bbd0
+0, 1, 1, 1, 152064, 0x41adb750
+0, 2, 2, 1, 152064, 0x6e889e90
+0, 3, 3, 1, 152064, 0xbb5e60f5
+0, 4, 4, 1, 152064, 0x5a32eca7
+0, 5, 5, 1, 152064, 0x5cb05e88
+0, 6, 6, 1, 152064, 0x2fff3e6c
+0, 7, 7, 1, 152064, 0xd917c85e
+0, 8, 8, 1, 152064, 0x6eac446f
+0, 9, 9, 1, 152064, 0x238b24b0
+0, 10, 10, 1, 152064, 0x3f3bd44c
+0, 11, 11, 1, 152064, 0x73982bc5
+0, 12, 12, 1, 152064, 0xf6188a82
+0, 13, 13, 1, 152064, 0x818c5b41
+0, 14, 14, 1, 152064, 0x000d1012
+0, 15, 15, 1, 152064, 0xc4a8750e
+0, 16, 16, 1, 152064, 0x1689bb77
+0, 17, 17, 1, 152064, 0x8f52f338
+0, 18, 18, 1, 152064, 0xbf5ee06b
+0, 19, 19, 1, 152064, 0x89508ad7
+0, 20, 20, 1, 152064, 0x2b1986a6
+0, 21, 21, 1, 152064, 0xe6fd6b0e
+0, 22, 22, 1, 152064, 0x883e2e4e
+0, 23, 23, 1, 152064, 0xd133db07
+0, 24, 24, 1, 152064, 0x39b3bb22
+0, 25, 25, 1, 152064, 0x8447410a
+0, 26, 26, 1, 152064, 0x9c66c6e5
+0, 27, 27, 1, 152064, 0x514de9cc
+0, 28, 28, 1, 152064, 0x08d9f1da
+0, 29, 29, 1, 152064, 0x8f10f536
+0, 30, 30, 1, 152064, 0x57d4b27b
+0, 31, 31, 1, 152064, 0x46f56d3c
+0, 32, 32, 1, 152064, 0x5d260230
+0, 33, 33, 1, 152064, 0x4a72aeac
+0, 34, 34, 1, 152064, 0x5cfe187f
+0, 35, 35, 1, 152064, 0x08e55cb2
+0, 36, 36, 1, 152064, 0x4727f34f
+0, 37, 37, 1, 152064, 0xd6a26f1c
+0, 38, 38, 1, 152064, 0xcc1fcf9c
+0, 39, 39, 1, 152064, 0x3681b775
+0, 40, 40, 1, 152064, 0xf580c7d9
+0, 41, 41, 1, 152064, 0xaa6747fb
+0, 42, 42, 1, 152064, 0x2e22f9f9
+0, 43, 43, 1, 152064, 0xb3ee6d81
+0, 44, 44, 1, 152064, 0x930b0145
+0, 45, 45, 1, 152064, 0xae36af99
+0, 46, 46, 1, 152064, 0xeb58fd26
+0, 47, 47, 1, 152064, 0xb9004da3
+0, 48, 48, 1, 152064, 0x2b25e444
+0, 49, 49, 1, 152064, 0xb36927de
diff --git a/tests/ref/fate/h264-conformance-cafi1_sva_c b/tests/ref/fate/h264-conformance-cafi1_sva_c
index 4be282c..180adf1 100644
--- a/tests/ref/fate/h264-conformance-cafi1_sva_c
+++ b/tests/ref/fate/h264-conformance-cafi1_sva_c
@@ -1,34 +1,34 @@
#tb 0: 1/25
-0, 2, 2, 1, 518400, 0x47bd73fa
-0, 4, 4, 1, 518400, 0xfe3ea7cc
-0, 6, 6, 1, 518400, 0x9bc549ae
-0, 8, 8, 1, 518400, 0x7bb7f0a1
-0, 10, 10, 1, 518400, 0x328903d4
-0, 12, 12, 1, 518400, 0x96ab366b
-0, 14, 14, 1, 518400, 0xa923eed3
-0, 16, 16, 1, 518400, 0x162b08f6
-0, 18, 18, 1, 518400, 0xe711bd8b
-0, 20, 20, 1, 518400, 0x55e2d4ed
-0, 22, 22, 1, 518400, 0x7dd3107b
-0, 24, 24, 1, 518400, 0x0ed20bcf
-0, 26, 26, 1, 518400, 0x352f5743
-0, 28, 28, 1, 518400, 0x0a3aeb5e
-0, 30, 30, 1, 518400, 0xc458eda3
-0, 32, 32, 1, 518400, 0xe8d5fec5
-0, 34, 34, 1, 518400, 0x18fc6c37
-0, 36, 36, 1, 518400, 0x448add76
-0, 38, 38, 1, 518400, 0x8741ead7
-0, 40, 40, 1, 518400, 0x7008a751
-0, 42, 42, 1, 518400, 0x4ca0633d
-0, 44, 44, 1, 518400, 0x021ab800
-0, 46, 46, 1, 518400, 0xfb91ba57
-0, 48, 48, 1, 518400, 0x90e71dd0
-0, 50, 50, 1, 518400, 0xac859de5
-0, 52, 52, 1, 518400, 0xce9790bd
-0, 54, 54, 1, 518400, 0x010ade8b
-0, 56, 56, 1, 518400, 0xd0b3a399
-0, 58, 58, 1, 518400, 0x6cafcff3
-0, 60, 60, 1, 518400, 0xc32284c0
-0, 62, 62, 1, 518400, 0x1af8f73e
-0, 64, 64, 1, 518400, 0x3babd71e
-0, 65, 65, 1, 518400, 0xd77cb86b
+0, 0, 0, 1, 518400, 0x47bd73fa
+0, 1, 1, 1, 518400, 0xfe3ea7cc
+0, 2, 2, 1, 518400, 0x9bc549ae
+0, 3, 3, 1, 518400, 0x7bb7f0a1
+0, 4, 4, 1, 518400, 0x328903d4
+0, 5, 5, 1, 518400, 0x96ab366b
+0, 6, 6, 1, 518400, 0xa923eed3
+0, 7, 7, 1, 518400, 0x162b08f6
+0, 8, 8, 1, 518400, 0xe711bd8b
+0, 9, 9, 1, 518400, 0x55e2d4ed
+0, 10, 10, 1, 518400, 0x7dd3107b
+0, 11, 11, 1, 518400, 0x0ed20bcf
+0, 12, 12, 1, 518400, 0x352f5743
+0, 13, 13, 1, 518400, 0x0a3aeb5e
+0, 14, 14, 1, 518400, 0xc458eda3
+0, 15, 15, 1, 518400, 0xe8d5fec5
+0, 16, 16, 1, 518400, 0x18fc6c37
+0, 17, 17, 1, 518400, 0x448add76
+0, 18, 18, 1, 518400, 0x8741ead7
+0, 19, 19, 1, 518400, 0x7008a751
+0, 20, 20, 1, 518400, 0x4ca0633d
+0, 21, 21, 1, 518400, 0x021ab800
+0, 22, 22, 1, 518400, 0xfb91ba57
+0, 23, 23, 1, 518400, 0x90e71dd0
+0, 24, 24, 1, 518400, 0xac859de5
+0, 25, 25, 1, 518400, 0xce9790bd
+0, 26, 26, 1, 518400, 0x010ade8b
+0, 27, 27, 1, 518400, 0xd0b3a399
+0, 28, 28, 1, 518400, 0x6cafcff3
+0, 29, 29, 1, 518400, 0xc32284c0
+0, 30, 30, 1, 518400, 0x1af8f73e
+0, 31, 31, 1, 518400, 0x3babd71e
+0, 32, 32, 1, 518400, 0xd77cb86b
diff --git a/tests/ref/fate/h264-conformance-cama1_vtc_c b/tests/ref/fate/h264-conformance-cama1_vtc_c
index b4cc76e..eeb66b0 100644
--- a/tests/ref/fate/h264-conformance-cama1_vtc_c
+++ b/tests/ref/fate/h264-conformance-cama1_vtc_c
@@ -1,5 +1,5 @@
#tb 0: 1/25
-0, 1, 1, 1, 518400, 0x41c2ce17
-0, 2, 2, 1, 518400, 0x39f217da
-0, 3, 3, 1, 518400, 0x5a108db9
-0, 4, 4, 1, 518400, 0x20cb214c
+0, 0, 0, 1, 518400, 0x41c2ce17
+0, 1, 1, 1, 518400, 0x39f217da
+0, 2, 2, 1, 518400, 0x5a108db9
+0, 3, 3, 1, 518400, 0x20cb214c
diff --git a/tests/ref/fate/h264-conformance-cama2_vtc_b b/tests/ref/fate/h264-conformance-cama2_vtc_b
index 911f144..0dfe6a9 100644
--- a/tests/ref/fate/h264-conformance-cama2_vtc_b
+++ b/tests/ref/fate/h264-conformance-cama2_vtc_b
@@ -1,5 +1,5 @@
#tb 0: 1/25
-0, 1, 1, 1, 622080, 0x004bb93f
-0, 2, 2, 1, 622080, 0xe70e193c
-0, 3, 3, 1, 622080, 0xd394cf17
-0, 4, 4, 1, 622080, 0x9e4cc924
+0, 0, 0, 1, 622080, 0x004bb93f
+0, 1, 1, 1, 622080, 0xe70e193c
+0, 2, 2, 1, 622080, 0xd394cf17
+0, 3, 3, 1, 622080, 0x9e4cc924
diff --git a/tests/ref/fate/h264-conformance-cama3_vtc_b b/tests/ref/fate/h264-conformance-cama3_vtc_b
index 3d912bd..46821c1 100644
--- a/tests/ref/fate/h264-conformance-cama3_vtc_b
+++ b/tests/ref/fate/h264-conformance-cama3_vtc_b
@@ -1,5 +1,5 @@
#tb 0: 1/25
-0, 1, 1, 1, 622080, 0xf3f0bf86
-0, 2, 2, 1, 622080, 0x6aaf3d42
-0, 3, 3, 1, 622080, 0xe53bcd5d
-0, 4, 4, 1, 622080, 0x8dabca9d
+0, 0, 0, 1, 622080, 0xf3f0bf86
+0, 1, 1, 1, 622080, 0x6aaf3d42
+0, 2, 2, 1, 622080, 0xe53bcd5d
+0, 3, 3, 1, 622080, 0x8dabca9d
diff --git a/tests/ref/fate/h264-conformance-capa1_toshiba_b b/tests/ref/fate/h264-conformance-capa1_toshiba_b
index 0d721ac..a0336f8 100644
--- a/tests/ref/fate/h264-conformance-capa1_toshiba_b
+++ b/tests/ref/fate/h264-conformance-capa1_toshiba_b
@@ -1,91 +1,91 @@
#tb 0: 1/25
-0, 2, 2, 1, 152064, 0x4040d2fc
-0, 3, 3, 1, 152064, 0x0d8f9897
-0, 5, 5, 1, 152064, 0xc23321cd
-0, 7, 7, 1, 152064, 0x3c9225eb
-0, 9, 9, 1, 152064, 0x8927006f
-0, 11, 11, 1, 152064, 0xf706a302
-0, 13, 13, 1, 152064, 0x8219c106
-0, 14, 14, 1, 152064, 0x06c990ea
-0, 15, 15, 1, 152064, 0x3a0f1135
-0, 16, 16, 1, 152064, 0x4cff21d3
-0, 17, 17, 1, 152064, 0x6be0e050
-0, 18, 18, 1, 152064, 0x718b6c7b
-0, 19, 19, 1, 152064, 0x24b38713
-0, 20, 20, 1, 152064, 0x500553fb
-0, 22, 22, 1, 152064, 0x531ae610
-0, 23, 23, 1, 152064, 0x46f4ff1b
-0, 25, 25, 1, 152064, 0xe5abe5ff
-0, 26, 26, 1, 152064, 0x97daa351
-0, 28, 28, 1, 152064, 0xfbef0a8f
-0, 30, 30, 1, 152064, 0xbe76134f
-0, 31, 31, 1, 152064, 0xa4bf10ea
-0, 33, 33, 1, 152064, 0xb2fb32af
-0, 35, 35, 1, 152064, 0xd33027a5
-0, 36, 36, 1, 152064, 0x78e20c2b
-0, 38, 38, 1, 152064, 0xefda2d6f
-0, 40, 40, 1, 152064, 0xb99126f0
-0, 41, 41, 1, 152064, 0x89d7e465
-0, 42, 42, 1, 152064, 0x6150ff97
-0, 44, 44, 1, 152064, 0xde03d937
-0, 45, 45, 1, 152064, 0xd90ca874
-0, 47, 47, 1, 152064, 0xb120b294
-0, 48, 48, 1, 152064, 0x644eade4
-0, 50, 50, 1, 152064, 0xd1bb004f
-0, 51, 51, 1, 152064, 0x99806a8b
-0, 52, 52, 1, 152064, 0x8c6b635f
-0, 53, 53, 1, 152064, 0xa269fa8b
-0, 55, 55, 1, 152064, 0xc11c0e64
-0, 56, 56, 1, 152064, 0xac13f5eb
-0, 57, 57, 1, 152064, 0x895799cf
-0, 59, 59, 1, 152064, 0x95a9bea1
-0, 60, 60, 1, 152064, 0xe998dfba
-0, 61, 61, 1, 152064, 0xc72d8460
-0, 63, 63, 1, 152064, 0xd1cb9b9a
-0, 64, 64, 1, 152064, 0xb49aadd3
-0, 65, 65, 1, 152064, 0x8bc38547
-0, 66, 66, 1, 152064, 0x3485984b
-0, 68, 68, 1, 152064, 0xdf305c0a
-0, 69, 69, 1, 152064, 0x6a1ec990
-0, 71, 71, 1, 152064, 0x595e0de4
-0, 73, 73, 1, 152064, 0xe1baf7c4
-0, 74, 74, 1, 152064, 0xf08b9b47
-0, 75, 75, 1, 152064, 0x6532ba6f
-0, 76, 76, 1, 152064, 0x3de67da6
-0, 77, 77, 1, 152064, 0x439ffd04
-0, 78, 78, 1, 152064, 0x6e6c1e97
-0, 79, 79, 1, 152064, 0x8e5aee7a
-0, 81, 81, 1, 152064, 0xd634999a
-0, 83, 83, 1, 152064, 0xadfa9e8b
-0, 84, 84, 1, 152064, 0x1b9090f5
-0, 86, 86, 1, 152064, 0x29094dfc
-0, 88, 88, 1, 152064, 0x56748851
-0, 90, 90, 1, 152064, 0x2316719d
-0, 92, 92, 1, 152064, 0x2ee0060b
-0, 94, 94, 1, 152064, 0x3edb36d4
-0, 96, 96, 1, 152064, 0x9ef437a3
-0, 98, 98, 1, 152064, 0x8d9af72e
-0, 100, 100, 1, 152064, 0xab86389c
-0, 102, 102, 1, 152064, 0xd3b34576
-0, 103, 103, 1, 152064, 0x9e5b04f4
-0, 105, 105, 1, 152064, 0x6a164c17
-0, 106, 106, 1, 152064, 0xcecf20ab
-0, 108, 108, 1, 152064, 0x07c8e273
-0, 110, 110, 1, 152064, 0x9b46fe6a
-0, 112, 112, 1, 152064, 0xc1e8002b
-0, 113, 113, 1, 152064, 0xdebdbe53
-0, 114, 114, 1, 152064, 0x0d2dfd99
-0, 116, 116, 1, 152064, 0xe8ae925f
-0, 117, 117, 1, 152064, 0xe1fe6272
-0, 118, 118, 1, 152064, 0xbb74d5e6
-0, 120, 120, 1, 152064, 0xc7b5d949
-0, 122, 122, 1, 152064, 0x9b15b020
-0, 124, 124, 1, 152064, 0xc8201f44
-0, 126, 126, 1, 152064, 0x30d03303
-0, 128, 128, 1, 152064, 0x9f66fbc2
-0, 130, 130, 1, 152064, 0x482b71ec
-0, 131, 131, 1, 152064, 0x1c9e50bf
-0, 133, 133, 1, 152064, 0x89f247e4
-0, 135, 135, 1, 152064, 0xaa5f9141
-0, 136, 136, 1, 152064, 0xb816aa8c
-0, 137, 137, 1, 152064, 0x3112a619
+0, 0, 0, 1, 152064, 0x4040d2fc
+0, 1, 1, 1, 152064, 0x0d8f9897
+0, 2, 2, 1, 152064, 0xc23321cd
+0, 3, 3, 1, 152064, 0x3c9225eb
+0, 4, 4, 1, 152064, 0x8927006f
+0, 5, 5, 1, 152064, 0xf706a302
+0, 6, 6, 1, 152064, 0x8219c106
+0, 7, 7, 1, 152064, 0x06c990ea
+0, 8, 8, 1, 152064, 0x3a0f1135
+0, 9, 9, 1, 152064, 0x4cff21d3
+0, 10, 10, 1, 152064, 0x6be0e050
+0, 11, 11, 1, 152064, 0x718b6c7b
+0, 12, 12, 1, 152064, 0x24b38713
+0, 13, 13, 1, 152064, 0x500553fb
+0, 14, 14, 1, 152064, 0x531ae610
+0, 15, 15, 1, 152064, 0x46f4ff1b
+0, 16, 16, 1, 152064, 0xe5abe5ff
+0, 17, 17, 1, 152064, 0x97daa351
+0, 18, 18, 1, 152064, 0xfbef0a8f
+0, 19, 19, 1, 152064, 0xbe76134f
+0, 20, 20, 1, 152064, 0xa4bf10ea
+0, 21, 21, 1, 152064, 0xb2fb32af
+0, 22, 22, 1, 152064, 0xd33027a5
+0, 23, 23, 1, 152064, 0x78e20c2b
+0, 24, 24, 1, 152064, 0xefda2d6f
+0, 25, 25, 1, 152064, 0xb99126f0
+0, 26, 26, 1, 152064, 0x89d7e465
+0, 27, 27, 1, 152064, 0x6150ff97
+0, 28, 28, 1, 152064, 0xde03d937
+0, 29, 29, 1, 152064, 0xd90ca874
+0, 30, 30, 1, 152064, 0xb120b294
+0, 31, 31, 1, 152064, 0x644eade4
+0, 32, 32, 1, 152064, 0xd1bb004f
+0, 33, 33, 1, 152064, 0x99806a8b
+0, 34, 34, 1, 152064, 0x8c6b635f
+0, 35, 35, 1, 152064, 0xa269fa8b
+0, 36, 36, 1, 152064, 0xc11c0e64
+0, 37, 37, 1, 152064, 0xac13f5eb
+0, 38, 38, 1, 152064, 0x895799cf
+0, 39, 39, 1, 152064, 0x95a9bea1
+0, 40, 40, 1, 152064, 0xe998dfba
+0, 41, 41, 1, 152064, 0xc72d8460
+0, 42, 42, 1, 152064, 0xd1cb9b9a
+0, 43, 43, 1, 152064, 0xb49aadd3
+0, 44, 44, 1, 152064, 0x8bc38547
+0, 45, 45, 1, 152064, 0x3485984b
+0, 46, 46, 1, 152064, 0xdf305c0a
+0, 47, 47, 1, 152064, 0x6a1ec990
+0, 48, 48, 1, 152064, 0x595e0de4
+0, 49, 49, 1, 152064, 0xe1baf7c4
+0, 50, 50, 1, 152064, 0xf08b9b47
+0, 51, 51, 1, 152064, 0x6532ba6f
+0, 52, 52, 1, 152064, 0x3de67da6
+0, 53, 53, 1, 152064, 0x439ffd04
+0, 54, 54, 1, 152064, 0x6e6c1e97
+0, 55, 55, 1, 152064, 0x8e5aee7a
+0, 56, 56, 1, 152064, 0xd634999a
+0, 57, 57, 1, 152064, 0xadfa9e8b
+0, 58, 58, 1, 152064, 0x1b9090f5
+0, 59, 59, 1, 152064, 0x29094dfc
+0, 60, 60, 1, 152064, 0x56748851
+0, 61, 61, 1, 152064, 0x2316719d
+0, 62, 62, 1, 152064, 0x2ee0060b
+0, 63, 63, 1, 152064, 0x3edb36d4
+0, 64, 64, 1, 152064, 0x9ef437a3
+0, 65, 65, 1, 152064, 0x8d9af72e
+0, 66, 66, 1, 152064, 0xab86389c
+0, 67, 67, 1, 152064, 0xd3b34576
+0, 68, 68, 1, 152064, 0x9e5b04f4
+0, 69, 69, 1, 152064, 0x6a164c17
+0, 70, 70, 1, 152064, 0xcecf20ab
+0, 71, 71, 1, 152064, 0x07c8e273
+0, 72, 72, 1, 152064, 0x9b46fe6a
+0, 73, 73, 1, 152064, 0xc1e8002b
+0, 74, 74, 1, 152064, 0xdebdbe53
+0, 75, 75, 1, 152064, 0x0d2dfd99
+0, 76, 76, 1, 152064, 0xe8ae925f
+0, 77, 77, 1, 152064, 0xe1fe6272
+0, 78, 78, 1, 152064, 0xbb74d5e6
+0, 79, 79, 1, 152064, 0xc7b5d949
+0, 80, 80, 1, 152064, 0x9b15b020
+0, 81, 81, 1, 152064, 0xc8201f44
+0, 82, 82, 1, 152064, 0x30d03303
+0, 83, 83, 1, 152064, 0x9f66fbc2
+0, 84, 84, 1, 152064, 0x482b71ec
+0, 85, 85, 1, 152064, 0x1c9e50bf
+0, 86, 86, 1, 152064, 0x89f247e4
+0, 87, 87, 1, 152064, 0xaa5f9141
+0, 88, 88, 1, 152064, 0xb816aa8c
+0, 89, 89, 1, 152064, 0x3112a619
diff --git a/tests/ref/fate/h264-conformance-capama3_sand_f b/tests/ref/fate/h264-conformance-capama3_sand_f
index 5a84688..b621b81 100644
--- a/tests/ref/fate/h264-conformance-capama3_sand_f
+++ b/tests/ref/fate/h264-conformance-capama3_sand_f
@@ -1,51 +1,51 @@
#tb 0: 1/25
-0, 1, 1, 1, 152064, 0xf772f152
-0, 2, 2, 1, 152064, 0xc416d300
-0, 4, 4, 1, 152064, 0xc2275c94
-0, 6, 6, 1, 152064, 0x1bd35645
-0, 7, 7, 1, 152064, 0x60327bf5
-0, 9, 9, 1, 152064, 0x7f5541bd
-0, 11, 11, 1, 152064, 0x52e5ebad
-0, 12, 12, 1, 152064, 0xb8e5c1f3
-0, 13, 13, 1, 152064, 0x2b4e3653
-0, 14, 14, 1, 152064, 0x9a8f8499
-0, 15, 15, 1, 152064, 0x32d4e9fb
-0, 17, 17, 1, 152064, 0x0bc73d7a
-0, 19, 19, 1, 152064, 0xb58a8b87
-0, 21, 21, 1, 152064, 0xddbc5468
-0, 23, 23, 1, 152064, 0xcfa30b64
-0, 24, 24, 1, 152064, 0xad411f36
-0, 26, 26, 1, 152064, 0x2f8c4d9b
-0, 28, 28, 1, 152064, 0xc8523359
-0, 29, 29, 1, 152064, 0x86be9861
-0, 30, 30, 1, 152064, 0x7518d731
-0, 32, 32, 1, 152064, 0x425fbfab
-0, 34, 34, 1, 152064, 0x4f00250d
-0, 36, 36, 1, 152064, 0x12b40617
-0, 38, 38, 1, 152064, 0x65ff925d
-0, 40, 40, 1, 152064, 0xc76a94c9
-0, 41, 41, 1, 152064, 0x640170d5
-0, 43, 43, 1, 152064, 0xd338a090
-0, 44, 44, 1, 152064, 0xce715174
-0, 46, 46, 1, 152064, 0x7bded195
-0, 48, 48, 1, 152064, 0x09e7d3b9
-0, 50, 50, 1, 152064, 0x651e1518
-0, 51, 51, 1, 152064, 0x03cadc5f
-0, 52, 52, 1, 152064, 0x08906919
-0, 54, 54, 1, 152064, 0x3303ebe0
-0, 56, 56, 1, 152064, 0xa28676c5
-0, 58, 58, 1, 152064, 0x3900ecaf
-0, 60, 60, 1, 152064, 0xeb795a05
-0, 61, 61, 1, 152064, 0x870034df
-0, 63, 63, 1, 152064, 0x69b0527a
-0, 64, 64, 1, 152064, 0xb2b314f9
-0, 66, 66, 1, 152064, 0x1a44ea1a
-0, 67, 67, 1, 152064, 0xe6eaec87
-0, 68, 68, 1, 152064, 0xd9ad818e
-0, 69, 69, 1, 152064, 0x9c7ff76e
-0, 70, 70, 1, 152064, 0x74c45abb
-0, 71, 71, 1, 152064, 0x2f4fa5c6
-0, 73, 73, 1, 152064, 0x19620702
-0, 75, 75, 1, 152064, 0xfc9601f3
-0, 77, 77, 1, 152064, 0x33e0d8e7
-0, 78, 78, 1, 152064, 0xdf7f2a80
+0, 0, 0, 1, 152064, 0xf772f152
+0, 1, 1, 1, 152064, 0xc416d300
+0, 2, 2, 1, 152064, 0xc2275c94
+0, 3, 3, 1, 152064, 0x1bd35645
+0, 4, 4, 1, 152064, 0x60327bf5
+0, 5, 5, 1, 152064, 0x7f5541bd
+0, 6, 6, 1, 152064, 0x52e5ebad
+0, 7, 7, 1, 152064, 0xb8e5c1f3
+0, 8, 8, 1, 152064, 0x2b4e3653
+0, 9, 9, 1, 152064, 0x9a8f8499
+0, 10, 10, 1, 152064, 0x32d4e9fb
+0, 11, 11, 1, 152064, 0x0bc73d7a
+0, 12, 12, 1, 152064, 0xb58a8b87
+0, 13, 13, 1, 152064, 0xddbc5468
+0, 14, 14, 1, 152064, 0xcfa30b64
+0, 15, 15, 1, 152064, 0xad411f36
+0, 16, 16, 1, 152064, 0x2f8c4d9b
+0, 17, 17, 1, 152064, 0xc8523359
+0, 18, 18, 1, 152064, 0x86be9861
+0, 19, 19, 1, 152064, 0x7518d731
+0, 20, 20, 1, 152064, 0x425fbfab
+0, 21, 21, 1, 152064, 0x4f00250d
+0, 22, 22, 1, 152064, 0x12b40617
+0, 23, 23, 1, 152064, 0x65ff925d
+0, 24, 24, 1, 152064, 0xc76a94c9
+0, 25, 25, 1, 152064, 0x640170d5
+0, 26, 26, 1, 152064, 0xd338a090
+0, 27, 27, 1, 152064, 0xce715174
+0, 28, 28, 1, 152064, 0x7bded195
+0, 29, 29, 1, 152064, 0x09e7d3b9
+0, 30, 30, 1, 152064, 0x651e1518
+0, 31, 31, 1, 152064, 0x03cadc5f
+0, 32, 32, 1, 152064, 0x08906919
+0, 33, 33, 1, 152064, 0x3303ebe0
+0, 34, 34, 1, 152064, 0xa28676c5
+0, 35, 35, 1, 152064, 0x3900ecaf
+0, 36, 36, 1, 152064, 0xeb795a05
+0, 37, 37, 1, 152064, 0x870034df
+0, 38, 38, 1, 152064, 0x69b0527a
+0, 39, 39, 1, 152064, 0xb2b314f9
+0, 40, 40, 1, 152064, 0x1a44ea1a
+0, 41, 41, 1, 152064, 0xe6eaec87
+0, 42, 42, 1, 152064, 0xd9ad818e
+0, 43, 43, 1, 152064, 0x9c7ff76e
+0, 44, 44, 1, 152064, 0x74c45abb
+0, 45, 45, 1, 152064, 0x2f4fa5c6
+0, 46, 46, 1, 152064, 0x19620702
+0, 47, 47, 1, 152064, 0xfc9601f3
+0, 48, 48, 1, 152064, 0x33e0d8e7
+0, 49, 49, 1, 152064, 0xdf7f2a80
diff --git a/tests/ref/fate/h264-conformance-cavlc_mot_fld0_full_b b/tests/ref/fate/h264-conformance-cavlc_mot_fld0_full_b
index 71020d9..f80c3be 100644
--- a/tests/ref/fate/h264-conformance-cavlc_mot_fld0_full_b
+++ b/tests/ref/fate/h264-conformance-cavlc_mot_fld0_full_b
@@ -1,31 +1,31 @@
#tb 0: 1/25
-0, 2, 2, 1, 518400, 0x99d0df36
-0, 4, 4, 1, 518400, 0xa8601c1a
-0, 6, 6, 1, 518400, 0x4a17d235
-0, 8, 8, 1, 518400, 0x75f23abf
-0, 10, 10, 1, 518400, 0x746aad53
-0, 12, 12, 1, 518400, 0xb0b8913e
-0, 14, 14, 1, 518400, 0x60a27f57
-0, 16, 16, 1, 518400, 0xfa227f3e
-0, 18, 18, 1, 518400, 0x7a1e57c2
-0, 20, 20, 1, 518400, 0xcbbaa84f
-0, 22, 22, 1, 518400, 0xf9c1bd13
-0, 24, 24, 1, 518400, 0x9e80caaf
-0, 26, 26, 1, 518400, 0x14cc6928
-0, 28, 28, 1, 518400, 0xca0353ef
-0, 30, 30, 1, 518400, 0xcad65e5f
-0, 32, 32, 1, 518400, 0xd5bc47b3
-0, 34, 34, 1, 518400, 0xa9893d36
-0, 36, 36, 1, 518400, 0x69bd9085
-0, 38, 38, 1, 518400, 0xff33c476
-0, 40, 40, 1, 518400, 0x9538adf7
-0, 42, 42, 1, 518400, 0xd4ff3b62
-0, 44, 44, 1, 518400, 0x021a11fd
-0, 46, 46, 1, 518400, 0x293e6f9f
-0, 48, 48, 1, 518400, 0x5d38e4c3
-0, 50, 50, 1, 518400, 0xd1f4ad49
-0, 52, 52, 1, 518400, 0xf13dd946
-0, 54, 54, 1, 518400, 0x0359e9ff
-0, 56, 56, 1, 518400, 0xb61098ad
-0, 58, 58, 1, 518400, 0xa855b11c
-0, 59, 59, 1, 518400, 0x7fcf9343
+0, 0, 0, 1, 518400, 0x99d0df36
+0, 1, 1, 1, 518400, 0xa8601c1a
+0, 2, 2, 1, 518400, 0x4a17d235
+0, 3, 3, 1, 518400, 0x75f23abf
+0, 4, 4, 1, 518400, 0x746aad53
+0, 5, 5, 1, 518400, 0xb0b8913e
+0, 6, 6, 1, 518400, 0x60a27f57
+0, 7, 7, 1, 518400, 0xfa227f3e
+0, 8, 8, 1, 518400, 0x7a1e57c2
+0, 9, 9, 1, 518400, 0xcbbaa84f
+0, 10, 10, 1, 518400, 0xf9c1bd13
+0, 11, 11, 1, 518400, 0x9e80caaf
+0, 12, 12, 1, 518400, 0x14cc6928
+0, 13, 13, 1, 518400, 0xca0353ef
+0, 14, 14, 1, 518400, 0xcad65e5f
+0, 15, 15, 1, 518400, 0xd5bc47b3
+0, 16, 16, 1, 518400, 0xa9893d36
+0, 17, 17, 1, 518400, 0x69bd9085
+0, 18, 18, 1, 518400, 0xff33c476
+0, 19, 19, 1, 518400, 0x9538adf7
+0, 20, 20, 1, 518400, 0xd4ff3b62
+0, 21, 21, 1, 518400, 0x021a11fd
+0, 22, 22, 1, 518400, 0x293e6f9f
+0, 23, 23, 1, 518400, 0x5d38e4c3
+0, 24, 24, 1, 518400, 0xd1f4ad49
+0, 25, 25, 1, 518400, 0xf13dd946
+0, 26, 26, 1, 518400, 0x0359e9ff
+0, 27, 27, 1, 518400, 0xb61098ad
+0, 28, 28, 1, 518400, 0xa855b11c
+0, 29, 29, 1, 518400, 0x7fcf9343
diff --git a/tests/ref/fate/h264-conformance-cavlc_mot_picaff0_full_b b/tests/ref/fate/h264-conformance-cavlc_mot_picaff0_full_b
index 98b2461..ed5e02e 100644
--- a/tests/ref/fate/h264-conformance-cavlc_mot_picaff0_full_b
+++ b/tests/ref/fate/h264-conformance-cavlc_mot_picaff0_full_b
@@ -1,31 +1,31 @@
#tb 0: 1/25
-0, 1, 1, 1, 518400, 0xf6b83a0e
-0, 3, 3, 1, 518400, 0xc5e8b8ee
-0, 4, 4, 1, 518400, 0xb3bc6e43
-0, 5, 5, 1, 518400, 0x5b08dc73
-0, 6, 6, 1, 518400, 0x4a7f7690
-0, 8, 8, 1, 518400, 0x8a9f4275
-0, 10, 10, 1, 518400, 0xc7cb92fd
-0, 12, 12, 1, 518400, 0xc721e231
-0, 13, 13, 1, 518400, 0xfb31371b
-0, 14, 14, 1, 518400, 0xac57f5d9
-0, 15, 15, 1, 518400, 0x92b7debc
-0, 17, 17, 1, 518400, 0xfe3e533e
-0, 19, 19, 1, 518400, 0x1b3a7a72
-0, 21, 21, 1, 518400, 0x98df2d81
-0, 22, 22, 1, 518400, 0xe0ce9c52
-0, 23, 23, 1, 518400, 0x6a31166d
-0, 24, 24, 1, 518400, 0x64ffd4d2
-0, 26, 26, 1, 518400, 0x3ec062ef
-0, 28, 28, 1, 518400, 0x3480fae1
-0, 30, 30, 1, 518400, 0xa87ae4b7
-0, 31, 31, 1, 518400, 0xd301319f
-0, 32, 32, 1, 518400, 0xa9284989
-0, 33, 33, 1, 518400, 0x3de73b50
-0, 35, 35, 1, 518400, 0x30a79f84
-0, 37, 37, 1, 518400, 0x7d5152d4
-0, 39, 39, 1, 518400, 0x25514095
-0, 40, 40, 1, 518400, 0x1749a05f
-0, 41, 41, 1, 518400, 0x598139a7
-0, 43, 43, 1, 518400, 0x3cece862
-0, 44, 44, 1, 518400, 0xe1c27efe
+0, 0, 0, 1, 518400, 0xf6b83a0e
+0, 1, 1, 1, 518400, 0xc5e8b8ee
+0, 2, 2, 1, 518400, 0xb3bc6e43
+0, 3, 3, 1, 518400, 0x5b08dc73
+0, 4, 4, 1, 518400, 0x4a7f7690
+0, 5, 5, 1, 518400, 0x8a9f4275
+0, 6, 6, 1, 518400, 0xc7cb92fd
+0, 7, 7, 1, 518400, 0xc721e231
+0, 8, 8, 1, 518400, 0xfb31371b
+0, 9, 9, 1, 518400, 0xac57f5d9
+0, 10, 10, 1, 518400, 0x92b7debc
+0, 11, 11, 1, 518400, 0xfe3e533e
+0, 12, 12, 1, 518400, 0x1b3a7a72
+0, 13, 13, 1, 518400, 0x98df2d81
+0, 14, 14, 1, 518400, 0xe0ce9c52
+0, 15, 15, 1, 518400, 0x6a31166d
+0, 16, 16, 1, 518400, 0x64ffd4d2
+0, 17, 17, 1, 518400, 0x3ec062ef
+0, 18, 18, 1, 518400, 0x3480fae1
+0, 19, 19, 1, 518400, 0xa87ae4b7
+0, 20, 20, 1, 518400, 0xd301319f
+0, 21, 21, 1, 518400, 0xa9284989
+0, 22, 22, 1, 518400, 0x3de73b50
+0, 23, 23, 1, 518400, 0x30a79f84
+0, 24, 24, 1, 518400, 0x7d5152d4
+0, 25, 25, 1, 518400, 0x25514095
+0, 26, 26, 1, 518400, 0x1749a05f
+0, 27, 27, 1, 518400, 0x598139a7
+0, 28, 28, 1, 518400, 0x3cece862
+0, 29, 29, 1, 518400, 0xe1c27efe
diff --git a/tests/ref/fate/h264-conformance-cvfi1_sony_d b/tests/ref/fate/h264-conformance-cvfi1_sony_d
index 0c82f32..195c7d6 100644
--- a/tests/ref/fate/h264-conformance-cvfi1_sony_d
+++ b/tests/ref/fate/h264-conformance-cvfi1_sony_d
@@ -1,18 +1,18 @@
#tb 0: 1/25
-0, 1, 1, 1, 518400, 0xd9444d71
-0, 3, 3, 1, 518400, 0x5d8928cd
-0, 5, 5, 1, 518400, 0xea5bc08b
-0, 7, 7, 1, 518400, 0xb4465d31
-0, 9, 9, 1, 518400, 0x983b5dbb
-0, 11, 11, 1, 518400, 0x54936746
-0, 13, 13, 1, 518400, 0x7ae38b02
-0, 15, 15, 1, 518400, 0xc2a0dd83
-0, 17, 17, 1, 518400, 0x61cac7a6
-0, 19, 19, 1, 518400, 0xb0038443
-0, 21, 21, 1, 518400, 0x16514296
-0, 23, 23, 1, 518400, 0xa68dd470
-0, 25, 25, 1, 518400, 0x2572f868
-0, 27, 27, 1, 518400, 0x770a3239
-0, 29, 29, 1, 518400, 0xdd04f6d2
-0, 31, 31, 1, 518400, 0xa5e5d01e
-0, 33, 33, 1, 518400, 0x5fe25c86
+0, 0, 0, 1, 518400, 0xd9444d71
+0, 1, 1, 1, 518400, 0x5d8928cd
+0, 2, 2, 1, 518400, 0xea5bc08b
+0, 3, 3, 1, 518400, 0xb4465d31
+0, 4, 4, 1, 518400, 0x983b5dbb
+0, 5, 5, 1, 518400, 0x54936746
+0, 6, 6, 1, 518400, 0x7ae38b02
+0, 7, 7, 1, 518400, 0xc2a0dd83
+0, 8, 8, 1, 518400, 0x61cac7a6
+0, 9, 9, 1, 518400, 0xb0038443
+0, 10, 10, 1, 518400, 0x16514296
+0, 11, 11, 1, 518400, 0xa68dd470
+0, 12, 12, 1, 518400, 0x2572f868
+0, 13, 13, 1, 518400, 0x770a3239
+0, 14, 14, 1, 518400, 0xdd04f6d2
+0, 15, 15, 1, 518400, 0xa5e5d01e
+0, 16, 16, 1, 518400, 0x5fe25c86
diff --git a/tests/ref/fate/h264-conformance-cvfi1_sva_c b/tests/ref/fate/h264-conformance-cvfi1_sva_c
index aa792f7..c19bc0d 100644
--- a/tests/ref/fate/h264-conformance-cvfi1_sva_c
+++ b/tests/ref/fate/h264-conformance-cvfi1_sva_c
@@ -1,8 +1,8 @@
#tb 0: 1/25
-0, 1, 1, 1, 518400, 0x8f022263
-0, 3, 3, 1, 518400, 0x02692654
-0, 5, 5, 1, 518400, 0x55eff579
-0, 7, 7, 1, 518400, 0x6c1bdf1d
-0, 9, 9, 1, 518400, 0xbbedf5e4
-0, 11, 11, 1, 518400, 0xb90d740d
-0, 13, 13, 1, 518400, 0x81300adb
+0, 0, 0, 1, 518400, 0x8f022263
+0, 1, 1, 1, 518400, 0x02692654
+0, 2, 2, 1, 518400, 0x55eff579
+0, 3, 3, 1, 518400, 0x6c1bdf1d
+0, 4, 4, 1, 518400, 0xbbedf5e4
+0, 5, 5, 1, 518400, 0xb90d740d
+0, 6, 6, 1, 518400, 0x81300adb
diff --git a/tests/ref/fate/h264-conformance-cvfi2_sony_h b/tests/ref/fate/h264-conformance-cvfi2_sony_h
index db78369..0914e22 100644
--- a/tests/ref/fate/h264-conformance-cvfi2_sony_h
+++ b/tests/ref/fate/h264-conformance-cvfi2_sony_h
@@ -1,18 +1,18 @@
#tb 0: 1/25
-0, 3, 3, 1, 518400, 0xd9444d71
-0, 5, 5, 1, 518400, 0x491faf75
-0, 7, 7, 1, 518400, 0xf8b4d15c
-0, 9, 9, 1, 518400, 0x99d9f60c
-0, 11, 11, 1, 518400, 0x46c17a6d
-0, 13, 13, 1, 518400, 0x30b9447d
-0, 15, 15, 1, 518400, 0x135d0c76
-0, 17, 17, 1, 518400, 0x1b831a3c
-0, 19, 19, 1, 518400, 0x5910def8
-0, 21, 21, 1, 518400, 0x8db90147
-0, 23, 23, 1, 518400, 0x6a2b79c7
-0, 25, 25, 1, 518400, 0xc8d302e5
-0, 27, 27, 1, 518400, 0x515bb024
-0, 29, 29, 1, 518400, 0xedf7836c
-0, 31, 31, 1, 518400, 0x7e247b9d
-0, 32, 32, 1, 518400, 0x10c9bb10
-0, 33, 33, 1, 518400, 0xe38e2807
+0, 0, 0, 1, 518400, 0xd9444d71
+0, 1, 1, 1, 518400, 0x491faf75
+0, 2, 2, 1, 518400, 0xf8b4d15c
+0, 3, 3, 1, 518400, 0x99d9f60c
+0, 4, 4, 1, 518400, 0x46c17a6d
+0, 5, 5, 1, 518400, 0x30b9447d
+0, 6, 6, 1, 518400, 0x135d0c76
+0, 7, 7, 1, 518400, 0x1b831a3c
+0, 8, 8, 1, 518400, 0x5910def8
+0, 9, 9, 1, 518400, 0x8db90147
+0, 10, 10, 1, 518400, 0x6a2b79c7
+0, 11, 11, 1, 518400, 0xc8d302e5
+0, 12, 12, 1, 518400, 0x515bb024
+0, 13, 13, 1, 518400, 0xedf7836c
+0, 14, 14, 1, 518400, 0x7e247b9d
+0, 15, 15, 1, 518400, 0x10c9bb10
+0, 16, 16, 1, 518400, 0xe38e2807
diff --git a/tests/ref/fate/h264-conformance-cvfi2_sva_c b/tests/ref/fate/h264-conformance-cvfi2_sva_c
index 063ec13..7c3162a 100644
--- a/tests/ref/fate/h264-conformance-cvfi2_sva_c
+++ b/tests/ref/fate/h264-conformance-cvfi2_sva_c
@@ -1,14 +1,14 @@
#tb 0: 1/25
-0, 2, 2, 1, 518400, 0x4073cc0b
-0, 4, 4, 1, 518400, 0x5f599a48
-0, 6, 6, 1, 518400, 0xc6fe555a
-0, 8, 8, 1, 518400, 0xe63ac345
-0, 10, 10, 1, 518400, 0x9b4f0c5c
-0, 12, 12, 1, 518400, 0x98aaba2d
-0, 14, 14, 1, 518400, 0xd629bd09
-0, 16, 16, 1, 518400, 0xe9796c37
-0, 18, 18, 1, 518400, 0xba54d16e
-0, 20, 20, 1, 518400, 0xe396c3eb
-0, 22, 22, 1, 518400, 0x63ee4b81
-0, 24, 24, 1, 518400, 0x68ac6986
-0, 25, 25, 1, 518400, 0xe0d53000
+0, 0, 0, 1, 518400, 0x4073cc0b
+0, 1, 1, 1, 518400, 0x5f599a48
+0, 2, 2, 1, 518400, 0xc6fe555a
+0, 3, 3, 1, 518400, 0xe63ac345
+0, 4, 4, 1, 518400, 0x9b4f0c5c
+0, 5, 5, 1, 518400, 0x98aaba2d
+0, 6, 6, 1, 518400, 0xd629bd09
+0, 7, 7, 1, 518400, 0xe9796c37
+0, 8, 8, 1, 518400, 0xba54d16e
+0, 9, 9, 1, 518400, 0xe396c3eb
+0, 10, 10, 1, 518400, 0x63ee4b81
+0, 11, 11, 1, 518400, 0x68ac6986
+0, 12, 12, 1, 518400, 0xe0d53000
diff --git a/tests/ref/fate/h264-conformance-cvmapaqp3_sony_e b/tests/ref/fate/h264-conformance-cvmapaqp3_sony_e
index bf28356..094fc98 100644
--- a/tests/ref/fate/h264-conformance-cvmapaqp3_sony_e
+++ b/tests/ref/fate/h264-conformance-cvmapaqp3_sony_e
@@ -1,9 +1,9 @@
#tb 0: 1/25
-0, 2, 2, 1, 518400, 0x80dffda2
-0, 4, 4, 1, 518400, 0x9450183b
-0, 6, 6, 1, 518400, 0x85d429a7
-0, 7, 7, 1, 518400, 0xe1f3b686
-0, 9, 9, 1, 518400, 0x2180c761
-0, 11, 11, 1, 518400, 0x30269c7c
-0, 12, 12, 1, 518400, 0xe9aa575a
-0, 13, 13, 1, 518400, 0x7b815a0a
+0, 0, 0, 1, 518400, 0x80dffda2
+0, 1, 1, 1, 518400, 0x9450183b
+0, 2, 2, 1, 518400, 0x85d429a7
+0, 3, 3, 1, 518400, 0xe1f3b686
+0, 4, 4, 1, 518400, 0x2180c761
+0, 5, 5, 1, 518400, 0x30269c7c
+0, 6, 6, 1, 518400, 0xe9aa575a
+0, 7, 7, 1, 518400, 0x7b815a0a
diff --git a/tests/ref/fate/h264-conformance-cvmp_mot_fld_l30_b b/tests/ref/fate/h264-conformance-cvmp_mot_fld_l30_b
index 0670058..57fa2f7 100644
--- a/tests/ref/fate/h264-conformance-cvmp_mot_fld_l30_b
+++ b/tests/ref/fate/h264-conformance-cvmp_mot_fld_l30_b
@@ -1,31 +1,31 @@
#tb 0: 1/25
-0, 2, 2, 1, 518400, 0xe9c7643e
-0, 4, 4, 1, 518400, 0xba7456ec
-0, 6, 6, 1, 518400, 0xdeb96749
-0, 8, 8, 1, 518400, 0xa101a986
-0, 10, 10, 1, 518400, 0x3db7baa5
-0, 12, 12, 1, 518400, 0xf3dfcec7
-0, 14, 14, 1, 518400, 0x79b4f537
-0, 16, 16, 1, 518400, 0x9e64fe68
-0, 18, 18, 1, 518400, 0x0e810b53
-0, 20, 20, 1, 518400, 0x20baf3b8
-0, 22, 22, 1, 518400, 0x0a49d341
-0, 24, 24, 1, 518400, 0xa8304ab5
-0, 26, 26, 1, 518400, 0x2600e98f
-0, 28, 28, 1, 518400, 0x9253e3e8
-0, 30, 30, 1, 518400, 0xd6e12783
-0, 32, 32, 1, 518400, 0x6894fc79
-0, 34, 34, 1, 518400, 0xfb60d3e3
-0, 36, 36, 1, 518400, 0x523602be
-0, 38, 38, 1, 518400, 0x4979f409
-0, 40, 40, 1, 518400, 0x50d4e2ab
-0, 42, 42, 1, 518400, 0xa8c2140a
-0, 44, 44, 1, 518400, 0x45c0bc15
-0, 46, 46, 1, 518400, 0xaef78cab
-0, 48, 48, 1, 518400, 0xec539d02
-0, 50, 50, 1, 518400, 0x602585ea
-0, 52, 52, 1, 518400, 0xda263463
-0, 54, 54, 1, 518400, 0xa03d8922
-0, 56, 56, 1, 518400, 0x43ea1c1d
-0, 58, 58, 1, 518400, 0xb1e055a6
-0, 59, 59, 1, 518400, 0x6fff9398
+0, 0, 0, 1, 518400, 0xe9c7643e
+0, 1, 1, 1, 518400, 0xba7456ec
+0, 2, 2, 1, 518400, 0xdeb96749
+0, 3, 3, 1, 518400, 0xa101a986
+0, 4, 4, 1, 518400, 0x3db7baa5
+0, 5, 5, 1, 518400, 0xf3dfcec7
+0, 6, 6, 1, 518400, 0x79b4f537
+0, 7, 7, 1, 518400, 0x9e64fe68
+0, 8, 8, 1, 518400, 0x0e810b53
+0, 9, 9, 1, 518400, 0x20baf3b8
+0, 10, 10, 1, 518400, 0x0a49d341
+0, 11, 11, 1, 518400, 0xa8304ab5
+0, 12, 12, 1, 518400, 0x2600e98f
+0, 13, 13, 1, 518400, 0x9253e3e8
+0, 14, 14, 1, 518400, 0xd6e12783
+0, 15, 15, 1, 518400, 0x6894fc79
+0, 16, 16, 1, 518400, 0xfb60d3e3
+0, 17, 17, 1, 518400, 0x523602be
+0, 18, 18, 1, 518400, 0x4979f409
+0, 19, 19, 1, 518400, 0x50d4e2ab
+0, 20, 20, 1, 518400, 0xa8c2140a
+0, 21, 21, 1, 518400, 0x45c0bc15
+0, 22, 22, 1, 518400, 0xaef78cab
+0, 23, 23, 1, 518400, 0xec539d02
+0, 24, 24, 1, 518400, 0x602585ea
+0, 25, 25, 1, 518400, 0xda263463
+0, 26, 26, 1, 518400, 0xa03d8922
+0, 27, 27, 1, 518400, 0x43ea1c1d
+0, 28, 28, 1, 518400, 0xb1e055a6
+0, 29, 29, 1, 518400, 0x6fff9398
diff --git a/tests/ref/fate/h264-conformance-cvmp_mot_frm_l31_b b/tests/ref/fate/h264-conformance-cvmp_mot_frm_l31_b
index 7f66ba0..bc7e81e 100644
--- a/tests/ref/fate/h264-conformance-cvmp_mot_frm_l31_b
+++ b/tests/ref/fate/h264-conformance-cvmp_mot_frm_l31_b
@@ -1,31 +1,31 @@
#tb 0: 1/25
-0, 2, 2, 1, 518400, 0x7b2475e3
-0, 4, 4, 1, 518400, 0xda786a87
-0, 6, 6, 1, 518400, 0xb1dd8108
-0, 8, 8, 1, 518400, 0x760ed65d
-0, 10, 10, 1, 518400, 0x8632d20c
-0, 12, 12, 1, 518400, 0xdd81e625
-0, 14, 14, 1, 518400, 0x853f1c41
-0, 16, 16, 1, 518400, 0x20191585
-0, 18, 18, 1, 518400, 0x0367e357
-0, 20, 20, 1, 518400, 0x60521167
-0, 22, 22, 1, 518400, 0xa887d4cc
-0, 24, 24, 1, 518400, 0x9a450f9e
-0, 26, 26, 1, 518400, 0xe9620841
-0, 28, 28, 1, 518400, 0xb482fb0e
-0, 30, 30, 1, 518400, 0x7b79f670
-0, 32, 32, 1, 518400, 0x9d37f1d1
-0, 34, 34, 1, 518400, 0xe358d323
-0, 36, 36, 1, 518400, 0x62ade59c
-0, 38, 38, 1, 518400, 0xdd78da66
-0, 40, 40, 1, 518400, 0xd97b867b
-0, 42, 42, 1, 518400, 0x8a90cf8c
-0, 44, 44, 1, 518400, 0x9d386610
-0, 46, 46, 1, 518400, 0x2c590f46
-0, 48, 48, 1, 518400, 0x92662861
-0, 50, 50, 1, 518400, 0x6979f563
-0, 52, 52, 1, 518400, 0xdd0fa1b2
-0, 54, 54, 1, 518400, 0xccbf1c1c
-0, 56, 56, 1, 518400, 0x7e358112
-0, 58, 58, 1, 518400, 0xb7c0d89d
-0, 59, 59, 1, 518400, 0xc6b03973
+0, 0, 0, 1, 518400, 0x7b2475e3
+0, 1, 1, 1, 518400, 0xda786a87
+0, 2, 2, 1, 518400, 0xb1dd8108
+0, 3, 3, 1, 518400, 0x760ed65d
+0, 4, 4, 1, 518400, 0x8632d20c
+0, 5, 5, 1, 518400, 0xdd81e625
+0, 6, 6, 1, 518400, 0x853f1c41
+0, 7, 7, 1, 518400, 0x20191585
+0, 8, 8, 1, 518400, 0x0367e357
+0, 9, 9, 1, 518400, 0x60521167
+0, 10, 10, 1, 518400, 0xa887d4cc
+0, 11, 11, 1, 518400, 0x9a450f9e
+0, 12, 12, 1, 518400, 0xe9620841
+0, 13, 13, 1, 518400, 0xb482fb0e
+0, 14, 14, 1, 518400, 0x7b79f670
+0, 15, 15, 1, 518400, 0x9d37f1d1
+0, 16, 16, 1, 518400, 0xe358d323
+0, 17, 17, 1, 518400, 0x62ade59c
+0, 18, 18, 1, 518400, 0xdd78da66
+0, 19, 19, 1, 518400, 0xd97b867b
+0, 20, 20, 1, 518400, 0x8a90cf8c
+0, 21, 21, 1, 518400, 0x9d386610
+0, 22, 22, 1, 518400, 0x2c590f46
+0, 23, 23, 1, 518400, 0x92662861
+0, 24, 24, 1, 518400, 0x6979f563
+0, 25, 25, 1, 518400, 0xdd0fa1b2
+0, 26, 26, 1, 518400, 0xccbf1c1c
+0, 27, 27, 1, 518400, 0x7e358112
+0, 28, 28, 1, 518400, 0xb7c0d89d
+0, 29, 29, 1, 518400, 0xc6b03973
diff --git a/tests/ref/fate/h264-conformance-cvnlfi1_sony_c b/tests/ref/fate/h264-conformance-cvnlfi1_sony_c
index d2a1e13..aa3c220 100644
--- a/tests/ref/fate/h264-conformance-cvnlfi1_sony_c
+++ b/tests/ref/fate/h264-conformance-cvnlfi1_sony_c
@@ -1,18 +1,18 @@
#tb 0: 1/25
-0, 1, 1, 1, 518400, 0x0fbb4e71
-0, 3, 3, 1, 518400, 0x4b816734
-0, 5, 5, 1, 518400, 0x0c350f19
-0, 7, 7, 1, 518400, 0xda049cb6
-0, 9, 9, 1, 518400, 0x1f3e7bb9
-0, 11, 11, 1, 518400, 0x995cbe66
-0, 13, 13, 1, 518400, 0x07f7e65c
-0, 15, 15, 1, 518400, 0xfcb7487f
-0, 17, 17, 1, 518400, 0xb080f48a
-0, 19, 19, 1, 518400, 0x3ef5b7e4
-0, 21, 21, 1, 518400, 0xa1518e1c
-0, 23, 23, 1, 518400, 0xb36f1cc9
-0, 25, 25, 1, 518400, 0x86ea48af
-0, 27, 27, 1, 518400, 0xe42373b7
-0, 29, 29, 1, 518400, 0xa8435828
-0, 31, 31, 1, 518400, 0xc942ea0e
-0, 33, 33, 1, 518400, 0xcc597514
+0, 0, 0, 1, 518400, 0x0fbb4e71
+0, 1, 1, 1, 518400, 0x4b816734
+0, 2, 2, 1, 518400, 0x0c350f19
+0, 3, 3, 1, 518400, 0xda049cb6
+0, 4, 4, 1, 518400, 0x1f3e7bb9
+0, 5, 5, 1, 518400, 0x995cbe66
+0, 6, 6, 1, 518400, 0x07f7e65c
+0, 7, 7, 1, 518400, 0xfcb7487f
+0, 8, 8, 1, 518400, 0xb080f48a
+0, 9, 9, 1, 518400, 0x3ef5b7e4
+0, 10, 10, 1, 518400, 0xa1518e1c
+0, 11, 11, 1, 518400, 0xb36f1cc9
+0, 12, 12, 1, 518400, 0x86ea48af
+0, 13, 13, 1, 518400, 0xe42373b7
+0, 14, 14, 1, 518400, 0xa8435828
+0, 15, 15, 1, 518400, 0xc942ea0e
+0, 16, 16, 1, 518400, 0xcc597514
diff --git a/tests/ref/fate/h264-conformance-cvnlfi2_sony_h b/tests/ref/fate/h264-conformance-cvnlfi2_sony_h
index 5c4022d..fe2e4d1 100644
--- a/tests/ref/fate/h264-conformance-cvnlfi2_sony_h
+++ b/tests/ref/fate/h264-conformance-cvnlfi2_sony_h
@@ -1,18 +1,18 @@
#tb 0: 1/25
-0, 3, 3, 1, 518400, 0x0fbb4e71
-0, 5, 5, 1, 518400, 0xc46bec04
-0, 7, 7, 1, 518400, 0xc50ffc1d
-0, 9, 9, 1, 518400, 0x684b07b7
-0, 11, 11, 1, 518400, 0xde799af0
-0, 13, 13, 1, 518400, 0xed497b27
-0, 15, 15, 1, 518400, 0x3e9d1e3a
-0, 17, 17, 1, 518400, 0x154d3c5c
-0, 19, 19, 1, 518400, 0x5257e37c
-0, 21, 21, 1, 518400, 0x6e15139a
-0, 23, 23, 1, 518400, 0x5dc39c59
-0, 25, 25, 1, 518400, 0xe1803100
-0, 27, 27, 1, 518400, 0xb4d4d535
-0, 29, 29, 1, 518400, 0x7a97a25d
-0, 31, 31, 1, 518400, 0xf86b8923
-0, 32, 32, 1, 518400, 0x3355be98
-0, 33, 33, 1, 518400, 0x8f555830
+0, 0, 0, 1, 518400, 0x0fbb4e71
+0, 1, 1, 1, 518400, 0xc46bec04
+0, 2, 2, 1, 518400, 0xc50ffc1d
+0, 3, 3, 1, 518400, 0x684b07b7
+0, 4, 4, 1, 518400, 0xde799af0
+0, 5, 5, 1, 518400, 0xed497b27
+0, 6, 6, 1, 518400, 0x3e9d1e3a
+0, 7, 7, 1, 518400, 0x154d3c5c
+0, 8, 8, 1, 518400, 0x5257e37c
+0, 9, 9, 1, 518400, 0x6e15139a
+0, 10, 10, 1, 518400, 0x5dc39c59
+0, 11, 11, 1, 518400, 0xe1803100
+0, 12, 12, 1, 518400, 0xb4d4d535
+0, 13, 13, 1, 518400, 0x7a97a25d
+0, 14, 14, 1, 518400, 0xf86b8923
+0, 15, 15, 1, 518400, 0x3355be98
+0, 16, 16, 1, 518400, 0x8f555830
diff --git a/tests/ref/fate/h264-conformance-cvpa1_toshiba_b b/tests/ref/fate/h264-conformance-cvpa1_toshiba_b
index 0253e1a..fd0911b 100644
--- a/tests/ref/fate/h264-conformance-cvpa1_toshiba_b
+++ b/tests/ref/fate/h264-conformance-cvpa1_toshiba_b
@@ -1,91 +1,91 @@
#tb 0: 1/25
-0, 2, 2, 1, 152064, 0x128cd77a
-0, 3, 3, 1, 152064, 0x565b9fc1
-0, 5, 5, 1, 152064, 0xbe322679
-0, 7, 7, 1, 152064, 0x0ea4238f
-0, 9, 9, 1, 152064, 0x1e08fb3c
-0, 11, 11, 1, 152064, 0x6da3a93c
-0, 13, 13, 1, 152064, 0x75e5b181
-0, 14, 14, 1, 152064, 0xa0b39334
-0, 15, 15, 1, 152064, 0xa0d10d6d
-0, 16, 16, 1, 152064, 0x33842bcb
-0, 17, 17, 1, 152064, 0x9a74e1e4
-0, 18, 18, 1, 152064, 0xc2037244
-0, 19, 19, 1, 152064, 0x364b8ae4
-0, 20, 20, 1, 152064, 0x18c04971
-0, 22, 22, 1, 152064, 0x7234ecb5
-0, 23, 23, 1, 152064, 0x3719f8bc
-0, 25, 25, 1, 152064, 0x1285ead1
-0, 26, 26, 1, 152064, 0xd3bfab18
-0, 28, 28, 1, 152064, 0x898111e2
-0, 30, 30, 1, 152064, 0x681c15fc
-0, 31, 31, 1, 152064, 0x8e501572
-0, 33, 33, 1, 152064, 0xd7c838be
-0, 35, 35, 1, 152064, 0xede424b2
-0, 36, 36, 1, 152064, 0xcfc20240
-0, 38, 38, 1, 152064, 0x13992e86
-0, 40, 40, 1, 152064, 0x56fb251a
-0, 41, 41, 1, 152064, 0xee9be320
-0, 42, 42, 1, 152064, 0xea650153
-0, 44, 44, 1, 152064, 0x2cb6dabe
-0, 45, 45, 1, 152064, 0xf44fa4b5
-0, 47, 47, 1, 152064, 0xdac2adff
-0, 48, 48, 1, 152064, 0x9e15a1dc
-0, 50, 50, 1, 152064, 0x28d00970
-0, 51, 51, 1, 152064, 0xe4277347
-0, 52, 52, 1, 152064, 0xebd25ad1
-0, 53, 53, 1, 152064, 0x029402da
-0, 55, 55, 1, 152064, 0x1a2311ef
-0, 56, 56, 1, 152064, 0xb86bf96a
-0, 57, 57, 1, 152064, 0x67d7a5b0
-0, 59, 59, 1, 152064, 0x573abc2d
-0, 60, 60, 1, 152064, 0xbe97dec0
-0, 61, 61, 1, 152064, 0x592b91a4
-0, 63, 63, 1, 152064, 0x9adda65e
-0, 64, 64, 1, 152064, 0x0354b2cb
-0, 65, 65, 1, 152064, 0x91e27ff9
-0, 66, 66, 1, 152064, 0x389f8625
-0, 68, 68, 1, 152064, 0x90175850
-0, 69, 69, 1, 152064, 0x2d36c427
-0, 71, 71, 1, 152064, 0xc0dd14ab
-0, 73, 73, 1, 152064, 0xd49bf131
-0, 74, 74, 1, 152064, 0x0d4a9b92
-0, 75, 75, 1, 152064, 0xae9bb2f1
-0, 76, 76, 1, 152064, 0x36847ade
-0, 77, 77, 1, 152064, 0x74810382
-0, 78, 78, 1, 152064, 0xc56d1d9f
-0, 79, 79, 1, 152064, 0xcfefe3ae
-0, 81, 81, 1, 152064, 0xeaa39353
-0, 83, 83, 1, 152064, 0x14289aef
-0, 84, 84, 1, 152064, 0x74ba8f3b
-0, 86, 86, 1, 152064, 0xdcaa518d
-0, 88, 88, 1, 152064, 0x6e4881c2
-0, 90, 90, 1, 152064, 0xa4db767d
-0, 92, 92, 1, 152064, 0x239b0b19
-0, 94, 94, 1, 152064, 0x5d054236
-0, 96, 96, 1, 152064, 0x6f392d7c
-0, 98, 98, 1, 152064, 0x5c2af146
-0, 100, 100, 1, 152064, 0x26b439af
-0, 102, 102, 1, 152064, 0xba7043ab
-0, 103, 103, 1, 152064, 0x0816000c
-0, 105, 105, 1, 152064, 0x3a713c05
-0, 106, 106, 1, 152064, 0xb3111f6d
-0, 108, 108, 1, 152064, 0xdbf8dae2
-0, 110, 110, 1, 152064, 0x09ddf22e
-0, 112, 112, 1, 152064, 0x8871fa7e
-0, 113, 113, 1, 152064, 0x9f5db7a1
-0, 114, 114, 1, 152064, 0xcc38f225
-0, 116, 116, 1, 152064, 0xa1d18df9
-0, 117, 117, 1, 152064, 0x9b1c5d6a
-0, 118, 118, 1, 152064, 0x9f2bc696
-0, 120, 120, 1, 152064, 0xc39bd11a
-0, 122, 122, 1, 152064, 0x4ceca7d0
-0, 124, 124, 1, 152064, 0x63a60f1d
-0, 126, 126, 1, 152064, 0x4cd31f28
-0, 128, 128, 1, 152064, 0x9c9af5d1
-0, 130, 130, 1, 152064, 0x6def65fc
-0, 131, 131, 1, 152064, 0x1011466d
-0, 133, 133, 1, 152064, 0xfeca406d
-0, 135, 135, 1, 152064, 0xd1ca8a1e
-0, 136, 136, 1, 152064, 0x30caa195
-0, 137, 137, 1, 152064, 0x31a09a48
+0, 0, 0, 1, 152064, 0x128cd77a
+0, 1, 1, 1, 152064, 0x565b9fc1
+0, 2, 2, 1, 152064, 0xbe322679
+0, 3, 3, 1, 152064, 0x0ea4238f
+0, 4, 4, 1, 152064, 0x1e08fb3c
+0, 5, 5, 1, 152064, 0x6da3a93c
+0, 6, 6, 1, 152064, 0x75e5b181
+0, 7, 7, 1, 152064, 0xa0b39334
+0, 8, 8, 1, 152064, 0xa0d10d6d
+0, 9, 9, 1, 152064, 0x33842bcb
+0, 10, 10, 1, 152064, 0x9a74e1e4
+0, 11, 11, 1, 152064, 0xc2037244
+0, 12, 12, 1, 152064, 0x364b8ae4
+0, 13, 13, 1, 152064, 0x18c04971
+0, 14, 14, 1, 152064, 0x7234ecb5
+0, 15, 15, 1, 152064, 0x3719f8bc
+0, 16, 16, 1, 152064, 0x1285ead1
+0, 17, 17, 1, 152064, 0xd3bfab18
+0, 18, 18, 1, 152064, 0x898111e2
+0, 19, 19, 1, 152064, 0x681c15fc
+0, 20, 20, 1, 152064, 0x8e501572
+0, 21, 21, 1, 152064, 0xd7c838be
+0, 22, 22, 1, 152064, 0xede424b2
+0, 23, 23, 1, 152064, 0xcfc20240
+0, 24, 24, 1, 152064, 0x13992e86
+0, 25, 25, 1, 152064, 0x56fb251a
+0, 26, 26, 1, 152064, 0xee9be320
+0, 27, 27, 1, 152064, 0xea650153
+0, 28, 28, 1, 152064, 0x2cb6dabe
+0, 29, 29, 1, 152064, 0xf44fa4b5
+0, 30, 30, 1, 152064, 0xdac2adff
+0, 31, 31, 1, 152064, 0x9e15a1dc
+0, 32, 32, 1, 152064, 0x28d00970
+0, 33, 33, 1, 152064, 0xe4277347
+0, 34, 34, 1, 152064, 0xebd25ad1
+0, 35, 35, 1, 152064, 0x029402da
+0, 36, 36, 1, 152064, 0x1a2311ef
+0, 37, 37, 1, 152064, 0xb86bf96a
+0, 38, 38, 1, 152064, 0x67d7a5b0
+0, 39, 39, 1, 152064, 0x573abc2d
+0, 40, 40, 1, 152064, 0xbe97dec0
+0, 41, 41, 1, 152064, 0x592b91a4
+0, 42, 42, 1, 152064, 0x9adda65e
+0, 43, 43, 1, 152064, 0x0354b2cb
+0, 44, 44, 1, 152064, 0x91e27ff9
+0, 45, 45, 1, 152064, 0x389f8625
+0, 46, 46, 1, 152064, 0x90175850
+0, 47, 47, 1, 152064, 0x2d36c427
+0, 48, 48, 1, 152064, 0xc0dd14ab
+0, 49, 49, 1, 152064, 0xd49bf131
+0, 50, 50, 1, 152064, 0x0d4a9b92
+0, 51, 51, 1, 152064, 0xae9bb2f1
+0, 52, 52, 1, 152064, 0x36847ade
+0, 53, 53, 1, 152064, 0x74810382
+0, 54, 54, 1, 152064, 0xc56d1d9f
+0, 55, 55, 1, 152064, 0xcfefe3ae
+0, 56, 56, 1, 152064, 0xeaa39353
+0, 57, 57, 1, 152064, 0x14289aef
+0, 58, 58, 1, 152064, 0x74ba8f3b
+0, 59, 59, 1, 152064, 0xdcaa518d
+0, 60, 60, 1, 152064, 0x6e4881c2
+0, 61, 61, 1, 152064, 0xa4db767d
+0, 62, 62, 1, 152064, 0x239b0b19
+0, 63, 63, 1, 152064, 0x5d054236
+0, 64, 64, 1, 152064, 0x6f392d7c
+0, 65, 65, 1, 152064, 0x5c2af146
+0, 66, 66, 1, 152064, 0x26b439af
+0, 67, 67, 1, 152064, 0xba7043ab
+0, 68, 68, 1, 152064, 0x0816000c
+0, 69, 69, 1, 152064, 0x3a713c05
+0, 70, 70, 1, 152064, 0xb3111f6d
+0, 71, 71, 1, 152064, 0xdbf8dae2
+0, 72, 72, 1, 152064, 0x09ddf22e
+0, 73, 73, 1, 152064, 0x8871fa7e
+0, 74, 74, 1, 152064, 0x9f5db7a1
+0, 75, 75, 1, 152064, 0xcc38f225
+0, 76, 76, 1, 152064, 0xa1d18df9
+0, 77, 77, 1, 152064, 0x9b1c5d6a
+0, 78, 78, 1, 152064, 0x9f2bc696
+0, 79, 79, 1, 152064, 0xc39bd11a
+0, 80, 80, 1, 152064, 0x4ceca7d0
+0, 81, 81, 1, 152064, 0x63a60f1d
+0, 82, 82, 1, 152064, 0x4cd31f28
+0, 83, 83, 1, 152064, 0x9c9af5d1
+0, 84, 84, 1, 152064, 0x6def65fc
+0, 85, 85, 1, 152064, 0x1011466d
+0, 86, 86, 1, 152064, 0xfeca406d
+0, 87, 87, 1, 152064, 0xd1ca8a1e
+0, 88, 88, 1, 152064, 0x30caa195
+0, 89, 89, 1, 152064, 0x31a09a48
diff --git a/tests/ref/fate/h264-conformance-fi1_sony_e b/tests/ref/fate/h264-conformance-fi1_sony_e
index 2e675b9..6b5e0db 100644
--- a/tests/ref/fate/h264-conformance-fi1_sony_e
+++ b/tests/ref/fate/h264-conformance-fi1_sony_e
@@ -1,18 +1,18 @@
#tb 0: 1/25
-0, 1, 1, 1, 36864, 0x3d54d3e3
-0, 3, 3, 1, 36864, 0xa9573ef0
-0, 5, 5, 1, 36864, 0x0ea5f263
-0, 7, 7, 1, 36864, 0x5a849fb9
-0, 9, 9, 1, 36864, 0x7ddb1eff
-0, 11, 11, 1, 36864, 0x5e73e3b7
-0, 13, 13, 1, 36864, 0x7d50d329
-0, 15, 15, 1, 36864, 0xf2c2cd27
-0, 17, 17, 1, 36864, 0xdf4f4628
-0, 19, 19, 1, 36864, 0xddd6d5be
-0, 21, 21, 1, 36864, 0xb530e1aa
-0, 23, 23, 1, 36864, 0xeca42470
-0, 25, 25, 1, 36864, 0xa5701caf
-0, 27, 27, 1, 36864, 0x6f5d28fc
-0, 29, 29, 1, 36864, 0xd4ab4ab2
-0, 31, 31, 1, 36864, 0xf2dfcc22
-0, 33, 33, 1, 36864, 0xcaa87e79
+0, 0, 0, 1, 36864, 0x3d54d3e3
+0, 1, 1, 1, 36864, 0xa9573ef0
+0, 2, 2, 1, 36864, 0x0ea5f263
+0, 3, 3, 1, 36864, 0x5a849fb9
+0, 4, 4, 1, 36864, 0x7ddb1eff
+0, 5, 5, 1, 36864, 0x5e73e3b7
+0, 6, 6, 1, 36864, 0x7d50d329
+0, 7, 7, 1, 36864, 0xf2c2cd27
+0, 8, 8, 1, 36864, 0xdf4f4628
+0, 9, 9, 1, 36864, 0xddd6d5be
+0, 10, 10, 1, 36864, 0xb530e1aa
+0, 11, 11, 1, 36864, 0xeca42470
+0, 12, 12, 1, 36864, 0xa5701caf
+0, 13, 13, 1, 36864, 0x6f5d28fc
+0, 14, 14, 1, 36864, 0xd4ab4ab2
+0, 15, 15, 1, 36864, 0xf2dfcc22
+0, 16, 16, 1, 36864, 0xcaa87e79
diff --git a/tests/ref/fate/h264-conformance-frext-bcrm_freh10 b/tests/ref/fate/h264-conformance-frext-bcrm_freh10
index 351d2b7..272a4aa 100644
--- a/tests/ref/fate/h264-conformance-frext-bcrm_freh10
+++ b/tests/ref/fate/h264-conformance-frext-bcrm_freh10
@@ -1,101 +1,101 @@
#tb 0: 1/25
-0, 2, 2, 1, 152064, 0xbdc2b880
-0, 4, 4, 1, 152064, 0x4ebf93fe
-0, 6, 6, 1, 152064, 0xe30d6871
-0, 8, 8, 1, 152064, 0x04f46b9b
-0, 10, 10, 1, 152064, 0xd7dd219a
-0, 12, 12, 1, 152064, 0x02fc6511
-0, 14, 14, 1, 152064, 0x98868faa
-0, 16, 16, 1, 152064, 0x54b94f92
-0, 18, 18, 1, 152064, 0xe3b6be4b
-0, 20, 20, 1, 152064, 0xf148cf10
-0, 22, 22, 1, 152064, 0xda3239b8
-0, 24, 24, 1, 152064, 0x6c5d7331
-0, 26, 26, 1, 152064, 0x825f1fea
-0, 28, 28, 1, 152064, 0x47791056
-0, 30, 30, 1, 152064, 0xc08e8a58
-0, 32, 32, 1, 152064, 0x020299f3
-0, 34, 34, 1, 152064, 0x0dfd4457
-0, 36, 36, 1, 152064, 0xcf005e68
-0, 38, 38, 1, 152064, 0x1f9e2c32
-0, 40, 40, 1, 152064, 0xa8359324
-0, 42, 42, 1, 152064, 0x4b03752d
-0, 44, 44, 1, 152064, 0xd6281621
-0, 46, 46, 1, 152064, 0xc97ac928
-0, 48, 48, 1, 152064, 0xded90dcd
-0, 50, 50, 1, 152064, 0xd6883255
-0, 52, 52, 1, 152064, 0x6edb4d4f
-0, 54, 54, 1, 152064, 0xd6f93a80
-0, 56, 56, 1, 152064, 0x163d6153
-0, 58, 58, 1, 152064, 0x04b90c06
-0, 60, 60, 1, 152064, 0xee8730c1
-0, 62, 62, 1, 152064, 0xd5f5c669
-0, 64, 64, 1, 152064, 0xcc600b1f
-0, 66, 66, 1, 152064, 0x15ddde03
-0, 68, 68, 1, 152064, 0xd0388dd0
-0, 70, 70, 1, 152064, 0xa292ab7d
-0, 72, 72, 1, 152064, 0xacf584e9
-0, 74, 74, 1, 152064, 0xcef42714
-0, 76, 76, 1, 152064, 0xeb162f35
-0, 78, 78, 1, 152064, 0x0a07de7b
-0, 80, 80, 1, 152064, 0x7ae76c81
-0, 82, 82, 1, 152064, 0x139c8fda
-0, 84, 84, 1, 152064, 0x43724411
-0, 86, 86, 1, 152064, 0x07b2ddea
-0, 88, 88, 1, 152064, 0x831a1cc7
-0, 90, 90, 1, 152064, 0x092f5073
-0, 92, 92, 1, 152064, 0xe5b6d380
-0, 94, 94, 1, 152064, 0xdd30d69e
-0, 96, 96, 1, 152064, 0x887020b2
-0, 98, 98, 1, 152064, 0x84436510
-0, 100, 100, 1, 152064, 0x49f63606
-0, 102, 102, 1, 152064, 0x6b96e959
-0, 104, 104, 1, 152064, 0xc6247cc7
-0, 106, 106, 1, 152064, 0x7a67c532
-0, 108, 108, 1, 152064, 0x93f4c476
-0, 110, 110, 1, 152064, 0x3c119654
-0, 112, 112, 1, 152064, 0xa45f7c72
-0, 114, 114, 1, 152064, 0x2ac50cb0
-0, 116, 116, 1, 152064, 0x9bf16d06
-0, 118, 118, 1, 152064, 0xfa0750d9
-0, 120, 120, 1, 152064, 0x02197630
-0, 122, 122, 1, 152064, 0x6d44f9b5
-0, 124, 124, 1, 152064, 0x86b211f5
-0, 126, 126, 1, 152064, 0xf4fda5d0
-0, 128, 128, 1, 152064, 0x36f840a7
-0, 130, 130, 1, 152064, 0x42412992
-0, 132, 132, 1, 152064, 0xd0c9ba37
-0, 134, 134, 1, 152064, 0xc40eba62
-0, 136, 136, 1, 152064, 0x2d093b53
-0, 138, 138, 1, 152064, 0xee39c69c
-0, 140, 140, 1, 152064, 0xcbbf8968
-0, 142, 142, 1, 152064, 0xfddc1704
-0, 144, 144, 1, 152064, 0x8dc47c61
-0, 146, 146, 1, 152064, 0xf15580bf
-0, 148, 148, 1, 152064, 0x9c71a8b0
-0, 150, 150, 1, 152064, 0x19b90b9f
-0, 152, 152, 1, 152064, 0xb65ae287
-0, 154, 154, 1, 152064, 0xf265693d
-0, 156, 156, 1, 152064, 0x721714a1
-0, 158, 158, 1, 152064, 0x383e8ac5
-0, 160, 160, 1, 152064, 0x02558677
-0, 162, 162, 1, 152064, 0xdaab3cdf
-0, 164, 164, 1, 152064, 0xc939a2f6
-0, 166, 166, 1, 152064, 0x977afa7f
-0, 168, 168, 1, 152064, 0xe5e65f35
-0, 170, 170, 1, 152064, 0x247546fa
-0, 172, 172, 1, 152064, 0x49ff2094
-0, 174, 174, 1, 152064, 0x9fd58cda
-0, 176, 176, 1, 152064, 0x3e31b6e3
-0, 178, 178, 1, 152064, 0x75c6d796
-0, 180, 180, 1, 152064, 0x4ab3e7bb
-0, 182, 182, 1, 152064, 0x393935ea
-0, 184, 184, 1, 152064, 0xc8e62905
-0, 186, 186, 1, 152064, 0xbb149e61
-0, 188, 188, 1, 152064, 0x2553c4c5
-0, 190, 190, 1, 152064, 0x7f82a8b4
-0, 192, 192, 1, 152064, 0x26ef31e6
-0, 194, 194, 1, 152064, 0xf029744a
-0, 196, 196, 1, 152064, 0x0a6f191a
-0, 198, 198, 1, 152064, 0x55808643
-0, 199, 199, 1, 152064, 0x27576172
+0, 0, 0, 1, 152064, 0xbdc2b880
+0, 1, 1, 1, 152064, 0x4ebf93fe
+0, 2, 2, 1, 152064, 0xe30d6871
+0, 3, 3, 1, 152064, 0x04f46b9b
+0, 4, 4, 1, 152064, 0xd7dd219a
+0, 5, 5, 1, 152064, 0x02fc6511
+0, 6, 6, 1, 152064, 0x98868faa
+0, 7, 7, 1, 152064, 0x54b94f92
+0, 8, 8, 1, 152064, 0xe3b6be4b
+0, 9, 9, 1, 152064, 0xf148cf10
+0, 10, 10, 1, 152064, 0xda3239b8
+0, 11, 11, 1, 152064, 0x6c5d7331
+0, 12, 12, 1, 152064, 0x825f1fea
+0, 13, 13, 1, 152064, 0x47791056
+0, 14, 14, 1, 152064, 0xc08e8a58
+0, 15, 15, 1, 152064, 0x020299f3
+0, 16, 16, 1, 152064, 0x0dfd4457
+0, 17, 17, 1, 152064, 0xcf005e68
+0, 18, 18, 1, 152064, 0x1f9e2c32
+0, 19, 19, 1, 152064, 0xa8359324
+0, 20, 20, 1, 152064, 0x4b03752d
+0, 21, 21, 1, 152064, 0xd6281621
+0, 22, 22, 1, 152064, 0xc97ac928
+0, 23, 23, 1, 152064, 0xded90dcd
+0, 24, 24, 1, 152064, 0xd6883255
+0, 25, 25, 1, 152064, 0x6edb4d4f
+0, 26, 26, 1, 152064, 0xd6f93a80
+0, 27, 27, 1, 152064, 0x163d6153
+0, 28, 28, 1, 152064, 0x04b90c06
+0, 29, 29, 1, 152064, 0xee8730c1
+0, 30, 30, 1, 152064, 0xd5f5c669
+0, 31, 31, 1, 152064, 0xcc600b1f
+0, 32, 32, 1, 152064, 0x15ddde03
+0, 33, 33, 1, 152064, 0xd0388dd0
+0, 34, 34, 1, 152064, 0xa292ab7d
+0, 35, 35, 1, 152064, 0xacf584e9
+0, 36, 36, 1, 152064, 0xcef42714
+0, 37, 37, 1, 152064, 0xeb162f35
+0, 38, 38, 1, 152064, 0x0a07de7b
+0, 39, 39, 1, 152064, 0x7ae76c81
+0, 40, 40, 1, 152064, 0x139c8fda
+0, 41, 41, 1, 152064, 0x43724411
+0, 42, 42, 1, 152064, 0x07b2ddea
+0, 43, 43, 1, 152064, 0x831a1cc7
+0, 44, 44, 1, 152064, 0x092f5073
+0, 45, 45, 1, 152064, 0xe5b6d380
+0, 46, 46, 1, 152064, 0xdd30d69e
+0, 47, 47, 1, 152064, 0x887020b2
+0, 48, 48, 1, 152064, 0x84436510
+0, 49, 49, 1, 152064, 0x49f63606
+0, 50, 50, 1, 152064, 0x6b96e959
+0, 51, 51, 1, 152064, 0xc6247cc7
+0, 52, 52, 1, 152064, 0x7a67c532
+0, 53, 53, 1, 152064, 0x93f4c476
+0, 54, 54, 1, 152064, 0x3c119654
+0, 55, 55, 1, 152064, 0xa45f7c72
+0, 56, 56, 1, 152064, 0x2ac50cb0
+0, 57, 57, 1, 152064, 0x9bf16d06
+0, 58, 58, 1, 152064, 0xfa0750d9
+0, 59, 59, 1, 152064, 0x02197630
+0, 60, 60, 1, 152064, 0x6d44f9b5
+0, 61, 61, 1, 152064, 0x86b211f5
+0, 62, 62, 1, 152064, 0xf4fda5d0
+0, 63, 63, 1, 152064, 0x36f840a7
+0, 64, 64, 1, 152064, 0x42412992
+0, 65, 65, 1, 152064, 0xd0c9ba37
+0, 66, 66, 1, 152064, 0xc40eba62
+0, 67, 67, 1, 152064, 0x2d093b53
+0, 68, 68, 1, 152064, 0xee39c69c
+0, 69, 69, 1, 152064, 0xcbbf8968
+0, 70, 70, 1, 152064, 0xfddc1704
+0, 71, 71, 1, 152064, 0x8dc47c61
+0, 72, 72, 1, 152064, 0xf15580bf
+0, 73, 73, 1, 152064, 0x9c71a8b0
+0, 74, 74, 1, 152064, 0x19b90b9f
+0, 75, 75, 1, 152064, 0xb65ae287
+0, 76, 76, 1, 152064, 0xf265693d
+0, 77, 77, 1, 152064, 0x721714a1
+0, 78, 78, 1, 152064, 0x383e8ac5
+0, 79, 79, 1, 152064, 0x02558677
+0, 80, 80, 1, 152064, 0xdaab3cdf
+0, 81, 81, 1, 152064, 0xc939a2f6
+0, 82, 82, 1, 152064, 0x977afa7f
+0, 83, 83, 1, 152064, 0xe5e65f35
+0, 84, 84, 1, 152064, 0x247546fa
+0, 85, 85, 1, 152064, 0x49ff2094
+0, 86, 86, 1, 152064, 0x9fd58cda
+0, 87, 87, 1, 152064, 0x3e31b6e3
+0, 88, 88, 1, 152064, 0x75c6d796
+0, 89, 89, 1, 152064, 0x4ab3e7bb
+0, 90, 90, 1, 152064, 0x393935ea
+0, 91, 91, 1, 152064, 0xc8e62905
+0, 92, 92, 1, 152064, 0xbb149e61
+0, 93, 93, 1, 152064, 0x2553c4c5
+0, 94, 94, 1, 152064, 0x7f82a8b4
+0, 95, 95, 1, 152064, 0x26ef31e6
+0, 96, 96, 1, 152064, 0xf029744a
+0, 97, 97, 1, 152064, 0x0a6f191a
+0, 98, 98, 1, 152064, 0x55808643
+0, 99, 99, 1, 152064, 0x27576172
diff --git a/tests/ref/fate/h264-conformance-frext-brcm_freh11 b/tests/ref/fate/h264-conformance-frext-brcm_freh11
index c3c2975..3183c4d 100644
--- a/tests/ref/fate/h264-conformance-frext-brcm_freh11
+++ b/tests/ref/fate/h264-conformance-frext-brcm_freh11
@@ -1,101 +1,101 @@
#tb 0: 1/25
-0, 2, 2, 1, 152064, 0x9744ac59
-0, 4, 4, 1, 152064, 0x3eba88bf
-0, 6, 6, 1, 152064, 0xd4105c5a
-0, 8, 8, 1, 152064, 0x452966a3
-0, 10, 10, 1, 152064, 0x30071add
-0, 12, 12, 1, 152064, 0x0eb75245
-0, 14, 14, 1, 152064, 0x4daa80fa
-0, 16, 16, 1, 152064, 0xf53a43a1
-0, 18, 18, 1, 152064, 0xa55ab43d
-0, 20, 20, 1, 152064, 0x915ec82e
-0, 22, 22, 1, 152064, 0xadce2f9a
-0, 24, 24, 1, 152064, 0xf7a25715
-0, 26, 26, 1, 152064, 0x90c91c7d
-0, 28, 28, 1, 152064, 0x4f0df4ef
-0, 30, 30, 1, 152064, 0xf6e0783c
-0, 32, 32, 1, 152064, 0x417c8ca8
-0, 34, 34, 1, 152064, 0xd33d29d8
-0, 36, 36, 1, 152064, 0xc9723fa3
-0, 38, 38, 1, 152064, 0x3e4f22f4
-0, 40, 40, 1, 152064, 0xd5aa7bd8
-0, 42, 42, 1, 152064, 0x2a425b54
-0, 44, 44, 1, 152064, 0x2d400788
-0, 46, 46, 1, 152064, 0x12fab3a4
-0, 48, 48, 1, 152064, 0x5544f881
-0, 50, 50, 1, 152064, 0xd0612cc5
-0, 52, 52, 1, 152064, 0x157b3654
-0, 54, 54, 1, 152064, 0x04b61fe0
-0, 56, 56, 1, 152064, 0x897d600a
-0, 58, 58, 1, 152064, 0x0d94fa29
-0, 60, 60, 1, 152064, 0xc0fe249d
-0, 62, 62, 1, 152064, 0x65abc1d6
-0, 64, 64, 1, 152064, 0x2bd5f09d
-0, 66, 66, 1, 152064, 0xd3eebd28
-0, 68, 68, 1, 152064, 0x93458649
-0, 70, 70, 1, 152064, 0x55e793a6
-0, 72, 72, 1, 152064, 0x9fc378ce
-0, 74, 74, 1, 152064, 0x24c32731
-0, 76, 76, 1, 152064, 0x3c321c50
-0, 78, 78, 1, 152064, 0xcef3ca8b
-0, 80, 80, 1, 152064, 0x97116676
-0, 82, 82, 1, 152064, 0x73ae78f6
-0, 84, 84, 1, 152064, 0xdeec219e
-0, 86, 86, 1, 152064, 0xc061d584
-0, 88, 88, 1, 152064, 0xcf47f6c9
-0, 90, 90, 1, 152064, 0x280d3a2d
-0, 92, 92, 1, 152064, 0xb660c846
-0, 94, 94, 1, 152064, 0xe167c588
-0, 96, 96, 1, 152064, 0x08f808de
-0, 98, 98, 1, 152064, 0x9de65c0b
-0, 100, 100, 1, 152064, 0xc52a1937
-0, 102, 102, 1, 152064, 0xf5a4d86f
-0, 104, 104, 1, 152064, 0xbef86d37
-0, 106, 106, 1, 152064, 0xa227b21b
-0, 108, 108, 1, 152064, 0x0601ad35
-0, 110, 110, 1, 152064, 0x15198730
-0, 112, 112, 1, 152064, 0x9af764c6
-0, 114, 114, 1, 152064, 0x1a95e99a
-0, 116, 116, 1, 152064, 0x6bef5aa8
-0, 118, 118, 1, 152064, 0x92f03267
-0, 120, 120, 1, 152064, 0x0a3d56cb
-0, 122, 122, 1, 152064, 0xd9c9f62e
-0, 124, 124, 1, 152064, 0xcd81ea16
-0, 126, 126, 1, 152064, 0x8ed789c0
-0, 128, 128, 1, 152064, 0x5a5e356f
-0, 130, 130, 1, 152064, 0x2f260ebf
-0, 132, 132, 1, 152064, 0xa0379c89
-0, 134, 134, 1, 152064, 0x100cb40c
-0, 136, 136, 1, 152064, 0xaad2220a
-0, 138, 138, 1, 152064, 0xec82aa8d
-0, 140, 140, 1, 152064, 0x91088303
-0, 142, 142, 1, 152064, 0x0cce0e9e
-0, 144, 144, 1, 152064, 0xf3bc716a
-0, 146, 146, 1, 152064, 0x989879c5
-0, 148, 148, 1, 152064, 0x491297a0
-0, 150, 150, 1, 152064, 0xdc16f30d
-0, 152, 152, 1, 152064, 0xb9bfdd57
-0, 154, 154, 1, 152064, 0x5fba59c2
-0, 156, 156, 1, 152064, 0x89c40529
-0, 158, 158, 1, 152064, 0x1b3e7b54
-0, 160, 160, 1, 152064, 0x5d0d7903
-0, 162, 162, 1, 152064, 0x2e3434e1
-0, 164, 164, 1, 152064, 0x1f47a276
-0, 166, 166, 1, 152064, 0xa22de2b1
-0, 168, 168, 1, 152064, 0x77344844
-0, 170, 170, 1, 152064, 0x6a6b3fce
-0, 172, 172, 1, 152064, 0x82660651
-0, 174, 174, 1, 152064, 0x51e67cc9
-0, 176, 176, 1, 152064, 0xb790ae51
-0, 178, 178, 1, 152064, 0x906bc6b6
-0, 180, 180, 1, 152064, 0x55c5dc21
-0, 182, 182, 1, 152064, 0xb51f3004
-0, 184, 184, 1, 152064, 0x68500a25
-0, 186, 186, 1, 152064, 0x5dbc812e
-0, 188, 188, 1, 152064, 0x895eb6ed
-0, 190, 190, 1, 152064, 0x2f5594fc
-0, 192, 192, 1, 152064, 0x04a222a9
-0, 194, 194, 1, 152064, 0x90036f6a
-0, 196, 196, 1, 152064, 0x8b8b064c
-0, 198, 198, 1, 152064, 0xd47c7334
-0, 199, 199, 1, 152064, 0x13f06213
+0, 0, 0, 1, 152064, 0x9744ac59
+0, 1, 1, 1, 152064, 0x3eba88bf
+0, 2, 2, 1, 152064, 0xd4105c5a
+0, 3, 3, 1, 152064, 0x452966a3
+0, 4, 4, 1, 152064, 0x30071add
+0, 5, 5, 1, 152064, 0x0eb75245
+0, 6, 6, 1, 152064, 0x4daa80fa
+0, 7, 7, 1, 152064, 0xf53a43a1
+0, 8, 8, 1, 152064, 0xa55ab43d
+0, 9, 9, 1, 152064, 0x915ec82e
+0, 10, 10, 1, 152064, 0xadce2f9a
+0, 11, 11, 1, 152064, 0xf7a25715
+0, 12, 12, 1, 152064, 0x90c91c7d
+0, 13, 13, 1, 152064, 0x4f0df4ef
+0, 14, 14, 1, 152064, 0xf6e0783c
+0, 15, 15, 1, 152064, 0x417c8ca8
+0, 16, 16, 1, 152064, 0xd33d29d8
+0, 17, 17, 1, 152064, 0xc9723fa3
+0, 18, 18, 1, 152064, 0x3e4f22f4
+0, 19, 19, 1, 152064, 0xd5aa7bd8
+0, 20, 20, 1, 152064, 0x2a425b54
+0, 21, 21, 1, 152064, 0x2d400788
+0, 22, 22, 1, 152064, 0x12fab3a4
+0, 23, 23, 1, 152064, 0x5544f881
+0, 24, 24, 1, 152064, 0xd0612cc5
+0, 25, 25, 1, 152064, 0x157b3654
+0, 26, 26, 1, 152064, 0x04b61fe0
+0, 27, 27, 1, 152064, 0x897d600a
+0, 28, 28, 1, 152064, 0x0d94fa29
+0, 29, 29, 1, 152064, 0xc0fe249d
+0, 30, 30, 1, 152064, 0x65abc1d6
+0, 31, 31, 1, 152064, 0x2bd5f09d
+0, 32, 32, 1, 152064, 0xd3eebd28
+0, 33, 33, 1, 152064, 0x93458649
+0, 34, 34, 1, 152064, 0x55e793a6
+0, 35, 35, 1, 152064, 0x9fc378ce
+0, 36, 36, 1, 152064, 0x24c32731
+0, 37, 37, 1, 152064, 0x3c321c50
+0, 38, 38, 1, 152064, 0xcef3ca8b
+0, 39, 39, 1, 152064, 0x97116676
+0, 40, 40, 1, 152064, 0x73ae78f6
+0, 41, 41, 1, 152064, 0xdeec219e
+0, 42, 42, 1, 152064, 0xc061d584
+0, 43, 43, 1, 152064, 0xcf47f6c9
+0, 44, 44, 1, 152064, 0x280d3a2d
+0, 45, 45, 1, 152064, 0xb660c846
+0, 46, 46, 1, 152064, 0xe167c588
+0, 47, 47, 1, 152064, 0x08f808de
+0, 48, 48, 1, 152064, 0x9de65c0b
+0, 49, 49, 1, 152064, 0xc52a1937
+0, 50, 50, 1, 152064, 0xf5a4d86f
+0, 51, 51, 1, 152064, 0xbef86d37
+0, 52, 52, 1, 152064, 0xa227b21b
+0, 53, 53, 1, 152064, 0x0601ad35
+0, 54, 54, 1, 152064, 0x15198730
+0, 55, 55, 1, 152064, 0x9af764c6
+0, 56, 56, 1, 152064, 0x1a95e99a
+0, 57, 57, 1, 152064, 0x6bef5aa8
+0, 58, 58, 1, 152064, 0x92f03267
+0, 59, 59, 1, 152064, 0x0a3d56cb
+0, 60, 60, 1, 152064, 0xd9c9f62e
+0, 61, 61, 1, 152064, 0xcd81ea16
+0, 62, 62, 1, 152064, 0x8ed789c0
+0, 63, 63, 1, 152064, 0x5a5e356f
+0, 64, 64, 1, 152064, 0x2f260ebf
+0, 65, 65, 1, 152064, 0xa0379c89
+0, 66, 66, 1, 152064, 0x100cb40c
+0, 67, 67, 1, 152064, 0xaad2220a
+0, 68, 68, 1, 152064, 0xec82aa8d
+0, 69, 69, 1, 152064, 0x91088303
+0, 70, 70, 1, 152064, 0x0cce0e9e
+0, 71, 71, 1, 152064, 0xf3bc716a
+0, 72, 72, 1, 152064, 0x989879c5
+0, 73, 73, 1, 152064, 0x491297a0
+0, 74, 74, 1, 152064, 0xdc16f30d
+0, 75, 75, 1, 152064, 0xb9bfdd57
+0, 76, 76, 1, 152064, 0x5fba59c2
+0, 77, 77, 1, 152064, 0x89c40529
+0, 78, 78, 1, 152064, 0x1b3e7b54
+0, 79, 79, 1, 152064, 0x5d0d7903
+0, 80, 80, 1, 152064, 0x2e3434e1
+0, 81, 81, 1, 152064, 0x1f47a276
+0, 82, 82, 1, 152064, 0xa22de2b1
+0, 83, 83, 1, 152064, 0x77344844
+0, 84, 84, 1, 152064, 0x6a6b3fce
+0, 85, 85, 1, 152064, 0x82660651
+0, 86, 86, 1, 152064, 0x51e67cc9
+0, 87, 87, 1, 152064, 0xb790ae51
+0, 88, 88, 1, 152064, 0x906bc6b6
+0, 89, 89, 1, 152064, 0x55c5dc21
+0, 90, 90, 1, 152064, 0xb51f3004
+0, 91, 91, 1, 152064, 0x68500a25
+0, 92, 92, 1, 152064, 0x5dbc812e
+0, 93, 93, 1, 152064, 0x895eb6ed
+0, 94, 94, 1, 152064, 0x2f5594fc
+0, 95, 95, 1, 152064, 0x04a222a9
+0, 96, 96, 1, 152064, 0x90036f6a
+0, 97, 97, 1, 152064, 0x8b8b064c
+0, 98, 98, 1, 152064, 0xd47c7334
+0, 99, 99, 1, 152064, 0x13f06213
diff --git a/tests/ref/fate/h264-conformance-frext-brcm_freh4 b/tests/ref/fate/h264-conformance-frext-brcm_freh4
index 04c05ac..ad3a3ec 100644
--- a/tests/ref/fate/h264-conformance-frext-brcm_freh4
+++ b/tests/ref/fate/h264-conformance-frext-brcm_freh4
@@ -1,101 +1,101 @@
#tb 0: 1/25
-0, 2, 2, 1, 152064, 0x9744ac59
-0, 4, 4, 1, 152064, 0xe1c69d97
-0, 6, 6, 1, 152064, 0x9ae85f93
-0, 8, 8, 1, 152064, 0x452966a3
-0, 10, 10, 1, 152064, 0xe8192823
-0, 12, 12, 1, 152064, 0x58b764eb
-0, 14, 14, 1, 152064, 0x51b686b1
-0, 16, 16, 1, 152064, 0x4bca5822
-0, 18, 18, 1, 152064, 0x29abc41c
-0, 20, 20, 1, 152064, 0x850ec94f
-0, 22, 22, 1, 152064, 0xac2c34f8
-0, 24, 24, 1, 152064, 0x080c6e67
-0, 26, 26, 1, 152064, 0x5e4e14d2
-0, 28, 28, 1, 152064, 0x978b054c
-0, 30, 30, 1, 152064, 0x861d8c3c
-0, 32, 32, 1, 152064, 0xe0818918
-0, 34, 34, 1, 152064, 0x8b834511
-0, 36, 36, 1, 152064, 0x223f567c
-0, 38, 38, 1, 152064, 0x6d61298d
-0, 40, 40, 1, 152064, 0xfe30826e
-0, 42, 42, 1, 152064, 0x4bad4f98
-0, 44, 44, 1, 152064, 0x69d5fdca
-0, 46, 46, 1, 152064, 0xe45bba1b
-0, 48, 48, 1, 152064, 0xa6d81298
-0, 50, 50, 1, 152064, 0x7f3f2c91
-0, 52, 52, 1, 152064, 0x658754b9
-0, 54, 54, 1, 152064, 0x2c6d3eba
-0, 56, 56, 1, 152064, 0x4500600c
-0, 58, 58, 1, 152064, 0xa745f74b
-0, 60, 60, 1, 152064, 0x2bf21fca
-0, 62, 62, 1, 152064, 0x08b8bdb3
-0, 64, 64, 1, 152064, 0x5a9d0a8b
-0, 66, 66, 1, 152064, 0x3a57d523
-0, 68, 68, 1, 152064, 0x3606826e
-0, 70, 70, 1, 152064, 0x3b91a8fb
-0, 72, 72, 1, 152064, 0x37c28959
-0, 74, 74, 1, 152064, 0xb51d1e75
-0, 76, 76, 1, 152064, 0x13be3f58
-0, 78, 78, 1, 152064, 0x0ed0e7cf
-0, 80, 80, 1, 152064, 0x298560d4
-0, 82, 82, 1, 152064, 0x62b68373
-0, 84, 84, 1, 152064, 0xf8bb4520
-0, 86, 86, 1, 152064, 0x90dfd6af
-0, 88, 88, 1, 152064, 0xf4770d20
-0, 90, 90, 1, 152064, 0x0d9549a0
-0, 92, 92, 1, 152064, 0x004eccb1
-0, 94, 94, 1, 152064, 0x3146d46b
-0, 96, 96, 1, 152064, 0x078d1808
-0, 98, 98, 1, 152064, 0x5d8d60cd
-0, 100, 100, 1, 152064, 0x8ff52dd8
-0, 102, 102, 1, 152064, 0x5aa3ccf7
-0, 104, 104, 1, 152064, 0x5bec6c39
-0, 106, 106, 1, 152064, 0xd44cae9d
-0, 108, 108, 1, 152064, 0xa1b0a151
-0, 110, 110, 1, 152064, 0xe3be7bb2
-0, 112, 112, 1, 152064, 0x50096775
-0, 114, 114, 1, 152064, 0xdffff851
-0, 116, 116, 1, 152064, 0x1d7250eb
-0, 118, 118, 1, 152064, 0x69663ca7
-0, 120, 120, 1, 152064, 0x62f77fc7
-0, 122, 122, 1, 152064, 0xbab8f471
-0, 124, 124, 1, 152064, 0x6af31785
-0, 126, 126, 1, 152064, 0xcbb2a9aa
-0, 128, 128, 1, 152064, 0xc57c32b9
-0, 130, 130, 1, 152064, 0xecbe2ce0
-0, 132, 132, 1, 152064, 0x2fbebf81
-0, 134, 134, 1, 152064, 0xa168af68
-0, 136, 136, 1, 152064, 0x1e5631ac
-0, 138, 138, 1, 152064, 0xe69fc927
-0, 140, 140, 1, 152064, 0x8e5c81d8
-0, 142, 142, 1, 152064, 0x42402010
-0, 144, 144, 1, 152064, 0xd7267482
-0, 146, 146, 1, 152064, 0x64b280df
-0, 148, 148, 1, 152064, 0xc4cbafcc
-0, 150, 150, 1, 152064, 0xcf2f1e8b
-0, 152, 152, 1, 152064, 0x4d6fdb3f
-0, 154, 154, 1, 152064, 0xf22d6fed
-0, 156, 156, 1, 152064, 0x625b167c
-0, 158, 158, 1, 152064, 0x41348089
-0, 160, 160, 1, 152064, 0x6db2779b
-0, 162, 162, 1, 152064, 0xe87030a8
-0, 164, 164, 1, 152064, 0x91b29cdd
-0, 166, 166, 1, 152064, 0xe824f242
-0, 168, 168, 1, 152064, 0xac995380
-0, 170, 170, 1, 152064, 0x7efe361b
-0, 172, 172, 1, 152064, 0xe10c0c26
-0, 174, 174, 1, 152064, 0x93108260
-0, 176, 176, 1, 152064, 0xbf4caed7
-0, 178, 178, 1, 152064, 0xb6a4d826
-0, 180, 180, 1, 152064, 0x78beea4e
-0, 182, 182, 1, 152064, 0xdf612df9
-0, 184, 184, 1, 152064, 0xa9ef2830
-0, 186, 186, 1, 152064, 0x06448895
-0, 188, 188, 1, 152064, 0x332eb6d5
-0, 190, 190, 1, 152064, 0x935ba2c5
-0, 192, 192, 1, 152064, 0x62a22656
-0, 194, 194, 1, 152064, 0x06a670a7
-0, 196, 196, 1, 152064, 0xf60b1af0
-0, 198, 198, 1, 152064, 0x85177c10
-0, 199, 199, 1, 152064, 0x5e4e5c4b
+0, 0, 0, 1, 152064, 0x9744ac59
+0, 1, 1, 1, 152064, 0xe1c69d97
+0, 2, 2, 1, 152064, 0x9ae85f93
+0, 3, 3, 1, 152064, 0x452966a3
+0, 4, 4, 1, 152064, 0xe8192823
+0, 5, 5, 1, 152064, 0x58b764eb
+0, 6, 6, 1, 152064, 0x51b686b1
+0, 7, 7, 1, 152064, 0x4bca5822
+0, 8, 8, 1, 152064, 0x29abc41c
+0, 9, 9, 1, 152064, 0x850ec94f
+0, 10, 10, 1, 152064, 0xac2c34f8
+0, 11, 11, 1, 152064, 0x080c6e67
+0, 12, 12, 1, 152064, 0x5e4e14d2
+0, 13, 13, 1, 152064, 0x978b054c
+0, 14, 14, 1, 152064, 0x861d8c3c
+0, 15, 15, 1, 152064, 0xe0818918
+0, 16, 16, 1, 152064, 0x8b834511
+0, 17, 17, 1, 152064, 0x223f567c
+0, 18, 18, 1, 152064, 0x6d61298d
+0, 19, 19, 1, 152064, 0xfe30826e
+0, 20, 20, 1, 152064, 0x4bad4f98
+0, 21, 21, 1, 152064, 0x69d5fdca
+0, 22, 22, 1, 152064, 0xe45bba1b
+0, 23, 23, 1, 152064, 0xa6d81298
+0, 24, 24, 1, 152064, 0x7f3f2c91
+0, 25, 25, 1, 152064, 0x658754b9
+0, 26, 26, 1, 152064, 0x2c6d3eba
+0, 27, 27, 1, 152064, 0x4500600c
+0, 28, 28, 1, 152064, 0xa745f74b
+0, 29, 29, 1, 152064, 0x2bf21fca
+0, 30, 30, 1, 152064, 0x08b8bdb3
+0, 31, 31, 1, 152064, 0x5a9d0a8b
+0, 32, 32, 1, 152064, 0x3a57d523
+0, 33, 33, 1, 152064, 0x3606826e
+0, 34, 34, 1, 152064, 0x3b91a8fb
+0, 35, 35, 1, 152064, 0x37c28959
+0, 36, 36, 1, 152064, 0xb51d1e75
+0, 37, 37, 1, 152064, 0x13be3f58
+0, 38, 38, 1, 152064, 0x0ed0e7cf
+0, 39, 39, 1, 152064, 0x298560d4
+0, 40, 40, 1, 152064, 0x62b68373
+0, 41, 41, 1, 152064, 0xf8bb4520
+0, 42, 42, 1, 152064, 0x90dfd6af
+0, 43, 43, 1, 152064, 0xf4770d20
+0, 44, 44, 1, 152064, 0x0d9549a0
+0, 45, 45, 1, 152064, 0x004eccb1
+0, 46, 46, 1, 152064, 0x3146d46b
+0, 47, 47, 1, 152064, 0x078d1808
+0, 48, 48, 1, 152064, 0x5d8d60cd
+0, 49, 49, 1, 152064, 0x8ff52dd8
+0, 50, 50, 1, 152064, 0x5aa3ccf7
+0, 51, 51, 1, 152064, 0x5bec6c39
+0, 52, 52, 1, 152064, 0xd44cae9d
+0, 53, 53, 1, 152064, 0xa1b0a151
+0, 54, 54, 1, 152064, 0xe3be7bb2
+0, 55, 55, 1, 152064, 0x50096775
+0, 56, 56, 1, 152064, 0xdffff851
+0, 57, 57, 1, 152064, 0x1d7250eb
+0, 58, 58, 1, 152064, 0x69663ca7
+0, 59, 59, 1, 152064, 0x62f77fc7
+0, 60, 60, 1, 152064, 0xbab8f471
+0, 61, 61, 1, 152064, 0x6af31785
+0, 62, 62, 1, 152064, 0xcbb2a9aa
+0, 63, 63, 1, 152064, 0xc57c32b9
+0, 64, 64, 1, 152064, 0xecbe2ce0
+0, 65, 65, 1, 152064, 0x2fbebf81
+0, 66, 66, 1, 152064, 0xa168af68
+0, 67, 67, 1, 152064, 0x1e5631ac
+0, 68, 68, 1, 152064, 0xe69fc927
+0, 69, 69, 1, 152064, 0x8e5c81d8
+0, 70, 70, 1, 152064, 0x42402010
+0, 71, 71, 1, 152064, 0xd7267482
+0, 72, 72, 1, 152064, 0x64b280df
+0, 73, 73, 1, 152064, 0xc4cbafcc
+0, 74, 74, 1, 152064, 0xcf2f1e8b
+0, 75, 75, 1, 152064, 0x4d6fdb3f
+0, 76, 76, 1, 152064, 0xf22d6fed
+0, 77, 77, 1, 152064, 0x625b167c
+0, 78, 78, 1, 152064, 0x41348089
+0, 79, 79, 1, 152064, 0x6db2779b
+0, 80, 80, 1, 152064, 0xe87030a8
+0, 81, 81, 1, 152064, 0x91b29cdd
+0, 82, 82, 1, 152064, 0xe824f242
+0, 83, 83, 1, 152064, 0xac995380
+0, 84, 84, 1, 152064, 0x7efe361b
+0, 85, 85, 1, 152064, 0xe10c0c26
+0, 86, 86, 1, 152064, 0x93108260
+0, 87, 87, 1, 152064, 0xbf4caed7
+0, 88, 88, 1, 152064, 0xb6a4d826
+0, 89, 89, 1, 152064, 0x78beea4e
+0, 90, 90, 1, 152064, 0xdf612df9
+0, 91, 91, 1, 152064, 0xa9ef2830
+0, 92, 92, 1, 152064, 0x06448895
+0, 93, 93, 1, 152064, 0x332eb6d5
+0, 94, 94, 1, 152064, 0x935ba2c5
+0, 95, 95, 1, 152064, 0x62a22656
+0, 96, 96, 1, 152064, 0x06a670a7
+0, 97, 97, 1, 152064, 0xf60b1af0
+0, 98, 98, 1, 152064, 0x85177c10
+0, 99, 99, 1, 152064, 0x5e4e5c4b
diff --git a/tests/ref/fate/h264-conformance-frext-freh6 b/tests/ref/fate/h264-conformance-frext-freh6
index 2fb085e..c769038 100644
--- a/tests/ref/fate/h264-conformance-frext-freh6
+++ b/tests/ref/fate/h264-conformance-frext-freh6
@@ -1,101 +1,101 @@
#tb 0: 1/25
-0, 2, 2, 1, 152064, 0x3b21d6cd
-0, 4, 4, 1, 152064, 0xc32088c6
-0, 6, 6, 1, 152064, 0x65a64cee
-0, 8, 8, 1, 152064, 0x0bd45a5b
-0, 10, 10, 1, 152064, 0xb2210d4d
-0, 12, 12, 1, 152064, 0xf5b15527
-0, 14, 14, 1, 152064, 0x806572ad
-0, 16, 16, 1, 152064, 0x6ecb1fc8
-0, 18, 18, 1, 152064, 0xc25e96d5
-0, 20, 20, 1, 152064, 0x5593b825
-0, 22, 22, 1, 152064, 0xf3be1cff
-0, 24, 24, 1, 152064, 0xa9155072
-0, 26, 26, 1, 152064, 0xd5552e26
-0, 28, 28, 1, 152064, 0x7bf0dbee
-0, 30, 30, 1, 152064, 0x998b4911
-0, 32, 32, 1, 152064, 0xcc71bbe0
-0, 34, 34, 1, 152064, 0x602415b8
-0, 36, 36, 1, 152064, 0xcfff37cf
-0, 38, 38, 1, 152064, 0x7cf824a8
-0, 40, 40, 1, 152064, 0x34816ee5
-0, 42, 42, 1, 152064, 0x1480540c
-0, 44, 44, 1, 152064, 0xc2351aaf
-0, 46, 46, 1, 152064, 0x3b8eac9f
-0, 48, 48, 1, 152064, 0x92a8faf8
-0, 50, 50, 1, 152064, 0x7b6121c8
-0, 52, 52, 1, 152064, 0xe73a3bac
-0, 54, 54, 1, 152064, 0xcd6e1e36
-0, 56, 56, 1, 152064, 0xb24660b1
-0, 58, 58, 1, 152064, 0xa290ec25
-0, 60, 60, 1, 152064, 0x308915ff
-0, 62, 62, 1, 152064, 0x1e8dd4db
-0, 64, 64, 1, 152064, 0x1372f2e0
-0, 66, 66, 1, 152064, 0xa07cc1d0
-0, 68, 68, 1, 152064, 0x34bb872c
-0, 70, 70, 1, 152064, 0x59e6a565
-0, 72, 72, 1, 152064, 0x9a097932
-0, 74, 74, 1, 152064, 0x938f2e20
-0, 76, 76, 1, 152064, 0x59a8157d
-0, 78, 78, 1, 152064, 0x5cacd404
-0, 80, 80, 1, 152064, 0xdad068f5
-0, 82, 82, 1, 152064, 0x7ba67d47
-0, 84, 84, 1, 152064, 0xc2a11e2d
-0, 86, 86, 1, 152064, 0xd37fdef7
-0, 88, 88, 1, 152064, 0x19a3f80a
-0, 90, 90, 1, 152064, 0x7ec7426a
-0, 92, 92, 1, 152064, 0x8ffedb61
-0, 94, 94, 1, 152064, 0x82aebdd0
-0, 96, 96, 1, 152064, 0xdfc920cc
-0, 98, 98, 1, 152064, 0x2a467698
-0, 100, 100, 1, 152064, 0xd08a37d5
-0, 102, 102, 1, 152064, 0xe606e66a
-0, 104, 104, 1, 152064, 0x0e7b8bd8
-0, 106, 106, 1, 152064, 0xf983c732
-0, 108, 108, 1, 152064, 0x9b82c2e7
-0, 110, 110, 1, 152064, 0xa990a47e
-0, 112, 112, 1, 152064, 0x2d5679f1
-0, 114, 114, 1, 152064, 0x7f1c0201
-0, 116, 116, 1, 152064, 0xc38b709d
-0, 118, 118, 1, 152064, 0x040246d8
-0, 120, 120, 1, 152064, 0xbc856021
-0, 122, 122, 1, 152064, 0x81e01a78
-0, 124, 124, 1, 152064, 0xaff1e7f1
-0, 126, 126, 1, 152064, 0x1fee7715
-0, 128, 128, 1, 152064, 0x65053711
-0, 130, 130, 1, 152064, 0x238a0118
-0, 132, 132, 1, 152064, 0x563491b4
-0, 134, 134, 1, 152064, 0x5974a6cc
-0, 136, 136, 1, 152064, 0xd8682c35
-0, 138, 138, 1, 152064, 0x85c49e96
-0, 140, 140, 1, 152064, 0x29486faa
-0, 142, 142, 1, 152064, 0x1a4f0579
-0, 144, 144, 1, 152064, 0x6ab86c2f
-0, 146, 146, 1, 152064, 0x36a36d2b
-0, 148, 148, 1, 152064, 0x3bd77543
-0, 150, 150, 1, 152064, 0x8fbddc41
-0, 152, 152, 1, 152064, 0xccc6e0a5
-0, 154, 154, 1, 152064, 0x00a9539e
-0, 156, 156, 1, 152064, 0x07ba0714
-0, 158, 158, 1, 152064, 0xbab2735d
-0, 160, 160, 1, 152064, 0x79cb5ba0
-0, 162, 162, 1, 152064, 0xdbcc1c92
-0, 164, 164, 1, 152064, 0xffec952c
-0, 166, 166, 1, 152064, 0xc31ac68e
-0, 168, 168, 1, 152064, 0x24293eb9
-0, 170, 170, 1, 152064, 0x7b9b2cb4
-0, 172, 172, 1, 152064, 0x9dd4fe95
-0, 174, 174, 1, 152064, 0xb62e8baf
-0, 176, 176, 1, 152064, 0x9fefc174
-0, 178, 178, 1, 152064, 0xe027c24e
-0, 180, 180, 1, 152064, 0xe38adc70
-0, 182, 182, 1, 152064, 0xc7bf536f
-0, 184, 184, 1, 152064, 0x4448f330
-0, 186, 186, 1, 152064, 0x4dad5339
-0, 188, 188, 1, 152064, 0x48fbab15
-0, 190, 190, 1, 152064, 0xe6c97b2c
-0, 192, 192, 1, 152064, 0x3c3829ee
-0, 194, 194, 1, 152064, 0x927772c0
-0, 196, 196, 1, 152064, 0xbb0f0ef4
-0, 198, 198, 1, 152064, 0xe65780a7
-0, 199, 199, 1, 152064, 0xaf8f6d72
+0, 0, 0, 1, 152064, 0x3b21d6cd
+0, 1, 1, 1, 152064, 0xc32088c6
+0, 2, 2, 1, 152064, 0x65a64cee
+0, 3, 3, 1, 152064, 0x0bd45a5b
+0, 4, 4, 1, 152064, 0xb2210d4d
+0, 5, 5, 1, 152064, 0xf5b15527
+0, 6, 6, 1, 152064, 0x806572ad
+0, 7, 7, 1, 152064, 0x6ecb1fc8
+0, 8, 8, 1, 152064, 0xc25e96d5
+0, 9, 9, 1, 152064, 0x5593b825
+0, 10, 10, 1, 152064, 0xf3be1cff
+0, 11, 11, 1, 152064, 0xa9155072
+0, 12, 12, 1, 152064, 0xd5552e26
+0, 13, 13, 1, 152064, 0x7bf0dbee
+0, 14, 14, 1, 152064, 0x998b4911
+0, 15, 15, 1, 152064, 0xcc71bbe0
+0, 16, 16, 1, 152064, 0x602415b8
+0, 17, 17, 1, 152064, 0xcfff37cf
+0, 18, 18, 1, 152064, 0x7cf824a8
+0, 19, 19, 1, 152064, 0x34816ee5
+0, 20, 20, 1, 152064, 0x1480540c
+0, 21, 21, 1, 152064, 0xc2351aaf
+0, 22, 22, 1, 152064, 0x3b8eac9f
+0, 23, 23, 1, 152064, 0x92a8faf8
+0, 24, 24, 1, 152064, 0x7b6121c8
+0, 25, 25, 1, 152064, 0xe73a3bac
+0, 26, 26, 1, 152064, 0xcd6e1e36
+0, 27, 27, 1, 152064, 0xb24660b1
+0, 28, 28, 1, 152064, 0xa290ec25
+0, 29, 29, 1, 152064, 0x308915ff
+0, 30, 30, 1, 152064, 0x1e8dd4db
+0, 31, 31, 1, 152064, 0x1372f2e0
+0, 32, 32, 1, 152064, 0xa07cc1d0
+0, 33, 33, 1, 152064, 0x34bb872c
+0, 34, 34, 1, 152064, 0x59e6a565
+0, 35, 35, 1, 152064, 0x9a097932
+0, 36, 36, 1, 152064, 0x938f2e20
+0, 37, 37, 1, 152064, 0x59a8157d
+0, 38, 38, 1, 152064, 0x5cacd404
+0, 39, 39, 1, 152064, 0xdad068f5
+0, 40, 40, 1, 152064, 0x7ba67d47
+0, 41, 41, 1, 152064, 0xc2a11e2d
+0, 42, 42, 1, 152064, 0xd37fdef7
+0, 43, 43, 1, 152064, 0x19a3f80a
+0, 44, 44, 1, 152064, 0x7ec7426a
+0, 45, 45, 1, 152064, 0x8ffedb61
+0, 46, 46, 1, 152064, 0x82aebdd0
+0, 47, 47, 1, 152064, 0xdfc920cc
+0, 48, 48, 1, 152064, 0x2a467698
+0, 49, 49, 1, 152064, 0xd08a37d5
+0, 50, 50, 1, 152064, 0xe606e66a
+0, 51, 51, 1, 152064, 0x0e7b8bd8
+0, 52, 52, 1, 152064, 0xf983c732
+0, 53, 53, 1, 152064, 0x9b82c2e7
+0, 54, 54, 1, 152064, 0xa990a47e
+0, 55, 55, 1, 152064, 0x2d5679f1
+0, 56, 56, 1, 152064, 0x7f1c0201
+0, 57, 57, 1, 152064, 0xc38b709d
+0, 58, 58, 1, 152064, 0x040246d8
+0, 59, 59, 1, 152064, 0xbc856021
+0, 60, 60, 1, 152064, 0x81e01a78
+0, 61, 61, 1, 152064, 0xaff1e7f1
+0, 62, 62, 1, 152064, 0x1fee7715
+0, 63, 63, 1, 152064, 0x65053711
+0, 64, 64, 1, 152064, 0x238a0118
+0, 65, 65, 1, 152064, 0x563491b4
+0, 66, 66, 1, 152064, 0x5974a6cc
+0, 67, 67, 1, 152064, 0xd8682c35
+0, 68, 68, 1, 152064, 0x85c49e96
+0, 69, 69, 1, 152064, 0x29486faa
+0, 70, 70, 1, 152064, 0x1a4f0579
+0, 71, 71, 1, 152064, 0x6ab86c2f
+0, 72, 72, 1, 152064, 0x36a36d2b
+0, 73, 73, 1, 152064, 0x3bd77543
+0, 74, 74, 1, 152064, 0x8fbddc41
+0, 75, 75, 1, 152064, 0xccc6e0a5
+0, 76, 76, 1, 152064, 0x00a9539e
+0, 77, 77, 1, 152064, 0x07ba0714
+0, 78, 78, 1, 152064, 0xbab2735d
+0, 79, 79, 1, 152064, 0x79cb5ba0
+0, 80, 80, 1, 152064, 0xdbcc1c92
+0, 81, 81, 1, 152064, 0xffec952c
+0, 82, 82, 1, 152064, 0xc31ac68e
+0, 83, 83, 1, 152064, 0x24293eb9
+0, 84, 84, 1, 152064, 0x7b9b2cb4
+0, 85, 85, 1, 152064, 0x9dd4fe95
+0, 86, 86, 1, 152064, 0xb62e8baf
+0, 87, 87, 1, 152064, 0x9fefc174
+0, 88, 88, 1, 152064, 0xe027c24e
+0, 89, 89, 1, 152064, 0xe38adc70
+0, 90, 90, 1, 152064, 0xc7bf536f
+0, 91, 91, 1, 152064, 0x4448f330
+0, 92, 92, 1, 152064, 0x4dad5339
+0, 93, 93, 1, 152064, 0x48fbab15
+0, 94, 94, 1, 152064, 0xe6c97b2c
+0, 95, 95, 1, 152064, 0x3c3829ee
+0, 96, 96, 1, 152064, 0x927772c0
+0, 97, 97, 1, 152064, 0xbb0f0ef4
+0, 98, 98, 1, 152064, 0xe65780a7
+0, 99, 99, 1, 152064, 0xaf8f6d72
diff --git a/tests/ref/fate/h264-conformance-frext-freh7_b b/tests/ref/fate/h264-conformance-frext-freh7_b
index 9b23f78..519c346 100644
--- a/tests/ref/fate/h264-conformance-frext-freh7_b
+++ b/tests/ref/fate/h264-conformance-frext-freh7_b
@@ -1,101 +1,101 @@
#tb 0: 1/25
-0, 2, 2, 1, 152064, 0x89f2e8d5
-0, 4, 4, 1, 152064, 0x35b99397
-0, 6, 6, 1, 152064, 0x6ef46744
-0, 8, 8, 1, 152064, 0xec4d6c1c
-0, 10, 10, 1, 152064, 0xad6e0c70
-0, 12, 12, 1, 152064, 0x2db534b3
-0, 14, 14, 1, 152064, 0xcbd25ddd
-0, 16, 16, 1, 152064, 0xd90708b4
-0, 18, 18, 1, 152064, 0xc2aa52df
-0, 20, 20, 1, 152064, 0xbcfc84dc
-0, 22, 22, 1, 152064, 0xa5a6d269
-0, 24, 24, 1, 152064, 0x27220ce9
-0, 26, 26, 1, 152064, 0xf075ee6d
-0, 28, 28, 1, 152064, 0x9fd3c2ac
-0, 30, 30, 1, 152064, 0xcba24c2d
-0, 32, 32, 1, 152064, 0x41cd9441
-0, 34, 34, 1, 152064, 0x0126efa3
-0, 36, 36, 1, 152064, 0xf62112af
-0, 38, 38, 1, 152064, 0x35aff50f
-0, 40, 40, 1, 152064, 0xcb0b276f
-0, 42, 42, 1, 152064, 0xc7ef0214
-0, 44, 44, 1, 152064, 0x7f78d387
-0, 46, 46, 1, 152064, 0x266c673d
-0, 48, 48, 1, 152064, 0x1d39c073
-0, 50, 50, 1, 152064, 0x6a3ae455
-0, 52, 52, 1, 152064, 0xe4ce0230
-0, 54, 54, 1, 152064, 0x7f95e87b
-0, 56, 56, 1, 152064, 0x7c552236
-0, 58, 58, 1, 152064, 0x24c799b9
-0, 60, 60, 1, 152064, 0x5042d974
-0, 62, 62, 1, 152064, 0xe934a5b8
-0, 64, 64, 1, 152064, 0x6d59c884
-0, 66, 66, 1, 152064, 0xd00f7fdb
-0, 68, 68, 1, 152064, 0x62ac3ebd
-0, 70, 70, 1, 152064, 0xb40a6c25
-0, 72, 72, 1, 152064, 0x8706188c
-0, 74, 74, 1, 152064, 0x7682e339
-0, 76, 76, 1, 152064, 0x1061d943
-0, 78, 78, 1, 152064, 0x50fa684a
-0, 80, 80, 1, 152064, 0xab4b1975
-0, 82, 82, 1, 152064, 0x2d043acb
-0, 84, 84, 1, 152064, 0xe3c2ec0a
-0, 86, 86, 1, 152064, 0xb9bc99dc
-0, 88, 88, 1, 152064, 0x051fb857
-0, 90, 90, 1, 152064, 0x71d1fe52
-0, 92, 92, 1, 152064, 0x4230c694
-0, 94, 94, 1, 152064, 0xb412a137
-0, 96, 96, 1, 152064, 0x2f50f90d
-0, 98, 98, 1, 152064, 0x68a1466f
-0, 100, 100, 1, 152064, 0x77e3f47b
-0, 102, 102, 1, 152064, 0x4d08de2b
-0, 104, 104, 1, 152064, 0x1fc663be
-0, 106, 106, 1, 152064, 0x2c8ba712
-0, 108, 108, 1, 152064, 0xd50d85b9
-0, 110, 110, 1, 152064, 0xe8483437
-0, 112, 112, 1, 152064, 0x4e331e4c
-0, 114, 114, 1, 152064, 0x0f64a7a0
-0, 116, 116, 1, 152064, 0x797b0b8c
-0, 118, 118, 1, 152064, 0x1b91e6d8
-0, 120, 120, 1, 152064, 0xf3a1f3b6
-0, 122, 122, 1, 152064, 0x2b94bd52
-0, 124, 124, 1, 152064, 0x1f30962e
-0, 126, 126, 1, 152064, 0x853321cf
-0, 128, 128, 1, 152064, 0x8266c0ac
-0, 130, 130, 1, 152064, 0x25498be0
-0, 132, 132, 1, 152064, 0x0f653af9
-0, 134, 134, 1, 152064, 0x0a025f7e
-0, 136, 136, 1, 152064, 0x1cfbae04
-0, 138, 138, 1, 152064, 0x3a874757
-0, 140, 140, 1, 152064, 0x2c67006e
-0, 142, 142, 1, 152064, 0x1d409bce
-0, 144, 144, 1, 152064, 0xfe43121f
-0, 146, 146, 1, 152064, 0x43411830
-0, 148, 148, 1, 152064, 0x536d26ca
-0, 150, 150, 1, 152064, 0x9eb873ea
-0, 152, 152, 1, 152064, 0x093f93ec
-0, 154, 154, 1, 152064, 0xdf6f0381
-0, 156, 156, 1, 152064, 0xa9f4b5e5
-0, 158, 158, 1, 152064, 0x08f71ef8
-0, 160, 160, 1, 152064, 0x7a68f820
-0, 162, 162, 1, 152064, 0xae0c73e7
-0, 164, 164, 1, 152064, 0x886ae6c7
-0, 166, 166, 1, 152064, 0x9357f433
-0, 168, 168, 1, 152064, 0xcc335068
-0, 170, 170, 1, 152064, 0x2ea108ab
-0, 172, 172, 1, 152064, 0x06d7dcb0
-0, 174, 174, 1, 152064, 0x81dc81bc
-0, 176, 176, 1, 152064, 0xfb32b626
-0, 178, 178, 1, 152064, 0x2787d1c7
-0, 180, 180, 1, 152064, 0x69e51118
-0, 182, 182, 1, 152064, 0xba15d94d
-0, 184, 184, 1, 152064, 0xc41c09cf
-0, 186, 186, 1, 152064, 0x7e50e12f
-0, 188, 188, 1, 152064, 0x0763ddbe
-0, 190, 190, 1, 152064, 0x8a09bb88
-0, 192, 192, 1, 152064, 0x530752b7
-0, 194, 194, 1, 152064, 0x9b159923
-0, 196, 196, 1, 152064, 0xcbb83ed3
-0, 198, 198, 1, 152064, 0xdeb5ac0e
-0, 199, 199, 1, 152064, 0x189299d4
+0, 0, 0, 1, 152064, 0x89f2e8d5
+0, 1, 1, 1, 152064, 0x35b99397
+0, 2, 2, 1, 152064, 0x6ef46744
+0, 3, 3, 1, 152064, 0xec4d6c1c
+0, 4, 4, 1, 152064, 0xad6e0c70
+0, 5, 5, 1, 152064, 0x2db534b3
+0, 6, 6, 1, 152064, 0xcbd25ddd
+0, 7, 7, 1, 152064, 0xd90708b4
+0, 8, 8, 1, 152064, 0xc2aa52df
+0, 9, 9, 1, 152064, 0xbcfc84dc
+0, 10, 10, 1, 152064, 0xa5a6d269
+0, 11, 11, 1, 152064, 0x27220ce9
+0, 12, 12, 1, 152064, 0xf075ee6d
+0, 13, 13, 1, 152064, 0x9fd3c2ac
+0, 14, 14, 1, 152064, 0xcba24c2d
+0, 15, 15, 1, 152064, 0x41cd9441
+0, 16, 16, 1, 152064, 0x0126efa3
+0, 17, 17, 1, 152064, 0xf62112af
+0, 18, 18, 1, 152064, 0x35aff50f
+0, 19, 19, 1, 152064, 0xcb0b276f
+0, 20, 20, 1, 152064, 0xc7ef0214
+0, 21, 21, 1, 152064, 0x7f78d387
+0, 22, 22, 1, 152064, 0x266c673d
+0, 23, 23, 1, 152064, 0x1d39c073
+0, 24, 24, 1, 152064, 0x6a3ae455
+0, 25, 25, 1, 152064, 0xe4ce0230
+0, 26, 26, 1, 152064, 0x7f95e87b
+0, 27, 27, 1, 152064, 0x7c552236
+0, 28, 28, 1, 152064, 0x24c799b9
+0, 29, 29, 1, 152064, 0x5042d974
+0, 30, 30, 1, 152064, 0xe934a5b8
+0, 31, 31, 1, 152064, 0x6d59c884
+0, 32, 32, 1, 152064, 0xd00f7fdb
+0, 33, 33, 1, 152064, 0x62ac3ebd
+0, 34, 34, 1, 152064, 0xb40a6c25
+0, 35, 35, 1, 152064, 0x8706188c
+0, 36, 36, 1, 152064, 0x7682e339
+0, 37, 37, 1, 152064, 0x1061d943
+0, 38, 38, 1, 152064, 0x50fa684a
+0, 39, 39, 1, 152064, 0xab4b1975
+0, 40, 40, 1, 152064, 0x2d043acb
+0, 41, 41, 1, 152064, 0xe3c2ec0a
+0, 42, 42, 1, 152064, 0xb9bc99dc
+0, 43, 43, 1, 152064, 0x051fb857
+0, 44, 44, 1, 152064, 0x71d1fe52
+0, 45, 45, 1, 152064, 0x4230c694
+0, 46, 46, 1, 152064, 0xb412a137
+0, 47, 47, 1, 152064, 0x2f50f90d
+0, 48, 48, 1, 152064, 0x68a1466f
+0, 49, 49, 1, 152064, 0x77e3f47b
+0, 50, 50, 1, 152064, 0x4d08de2b
+0, 51, 51, 1, 152064, 0x1fc663be
+0, 52, 52, 1, 152064, 0x2c8ba712
+0, 53, 53, 1, 152064, 0xd50d85b9
+0, 54, 54, 1, 152064, 0xe8483437
+0, 55, 55, 1, 152064, 0x4e331e4c
+0, 56, 56, 1, 152064, 0x0f64a7a0
+0, 57, 57, 1, 152064, 0x797b0b8c
+0, 58, 58, 1, 152064, 0x1b91e6d8
+0, 59, 59, 1, 152064, 0xf3a1f3b6
+0, 60, 60, 1, 152064, 0x2b94bd52
+0, 61, 61, 1, 152064, 0x1f30962e
+0, 62, 62, 1, 152064, 0x853321cf
+0, 63, 63, 1, 152064, 0x8266c0ac
+0, 64, 64, 1, 152064, 0x25498be0
+0, 65, 65, 1, 152064, 0x0f653af9
+0, 66, 66, 1, 152064, 0x0a025f7e
+0, 67, 67, 1, 152064, 0x1cfbae04
+0, 68, 68, 1, 152064, 0x3a874757
+0, 69, 69, 1, 152064, 0x2c67006e
+0, 70, 70, 1, 152064, 0x1d409bce
+0, 71, 71, 1, 152064, 0xfe43121f
+0, 72, 72, 1, 152064, 0x43411830
+0, 73, 73, 1, 152064, 0x536d26ca
+0, 74, 74, 1, 152064, 0x9eb873ea
+0, 75, 75, 1, 152064, 0x093f93ec
+0, 76, 76, 1, 152064, 0xdf6f0381
+0, 77, 77, 1, 152064, 0xa9f4b5e5
+0, 78, 78, 1, 152064, 0x08f71ef8
+0, 79, 79, 1, 152064, 0x7a68f820
+0, 80, 80, 1, 152064, 0xae0c73e7
+0, 81, 81, 1, 152064, 0x886ae6c7
+0, 82, 82, 1, 152064, 0x9357f433
+0, 83, 83, 1, 152064, 0xcc335068
+0, 84, 84, 1, 152064, 0x2ea108ab
+0, 85, 85, 1, 152064, 0x06d7dcb0
+0, 86, 86, 1, 152064, 0x81dc81bc
+0, 87, 87, 1, 152064, 0xfb32b626
+0, 88, 88, 1, 152064, 0x2787d1c7
+0, 89, 89, 1, 152064, 0x69e51118
+0, 90, 90, 1, 152064, 0xba15d94d
+0, 91, 91, 1, 152064, 0xc41c09cf
+0, 92, 92, 1, 152064, 0x7e50e12f
+0, 93, 93, 1, 152064, 0x0763ddbe
+0, 94, 94, 1, 152064, 0x8a09bb88
+0, 95, 95, 1, 152064, 0x530752b7
+0, 96, 96, 1, 152064, 0x9b159923
+0, 97, 97, 1, 152064, 0xcbb83ed3
+0, 98, 98, 1, 152064, 0xdeb5ac0e
+0, 99, 99, 1, 152064, 0x189299d4
diff --git a/tests/ref/fate/h264-conformance-frext-frext2_panasonic_b b/tests/ref/fate/h264-conformance-frext-frext2_panasonic_b
index 75005ec..7c53b5c 100644
--- a/tests/ref/fate/h264-conformance-frext-frext2_panasonic_b
+++ b/tests/ref/fate/h264-conformance-frext-frext2_panasonic_b
@@ -1,16 +1,16 @@
#tb 0: 1/25
-0, 2, 2, 1, 152064, 0x0147a2a9
-0, 3, 3, 1, 152064, 0xe2365351
-0, 4, 4, 1, 152064, 0xb5f9daee
-0, 5, 5, 1, 152064, 0xd60818b2
-0, 7, 7, 1, 152064, 0x21b528e5
-0, 8, 8, 1, 152064, 0x9c9dda18
-0, 9, 9, 1, 152064, 0x387fe7de
-0, 11, 11, 1, 152064, 0x8f0c5a1e
-0, 12, 12, 1, 152064, 0x02409694
-0, 14, 14, 1, 152064, 0x2b36a7a7
-0, 15, 15, 1, 152064, 0x3c6d3863
-0, 17, 17, 1, 152064, 0xaa7835e1
-0, 18, 18, 1, 152064, 0x6d105fe7
-0, 20, 20, 1, 152064, 0x9a348732
-0, 21, 21, 1, 152064, 0x96a3af13
+0, 0, 0, 1, 152064, 0x0147a2a9
+0, 1, 1, 1, 152064, 0xe2365351
+0, 2, 2, 1, 152064, 0xb5f9daee
+0, 3, 3, 1, 152064, 0xd60818b2
+0, 4, 4, 1, 152064, 0x21b528e5
+0, 5, 5, 1, 152064, 0x9c9dda18
+0, 6, 6, 1, 152064, 0x387fe7de
+0, 7, 7, 1, 152064, 0x8f0c5a1e
+0, 8, 8, 1, 152064, 0x02409694
+0, 9, 9, 1, 152064, 0x2b36a7a7
+0, 10, 10, 1, 152064, 0x3c6d3863
+0, 11, 11, 1, 152064, 0xaa7835e1
+0, 12, 12, 1, 152064, 0x6d105fe7
+0, 13, 13, 1, 152064, 0x9a348732
+0, 14, 14, 1, 152064, 0x96a3af13
diff --git a/tests/ref/fate/h264-conformance-frext-frext4_panasonic_a b/tests/ref/fate/h264-conformance-frext-frext4_panasonic_a
index 0efe2ab..c0886e4 100644
--- a/tests/ref/fate/h264-conformance-frext-frext4_panasonic_a
+++ b/tests/ref/fate/h264-conformance-frext-frext4_panasonic_a
@@ -1,11 +1,11 @@
#tb 0: 1/25
-0, 1, 1, 1, 152064, 0xd604d440
-0, 3, 3, 1, 152064, 0x08ef262c
-0, 4, 4, 1, 152064, 0x992fca8e
-0, 5, 5, 1, 152064, 0x5a02ee15
-0, 7, 7, 1, 152064, 0xf15d5c66
-0, 9, 9, 1, 152064, 0x360dda12
-0, 10, 10, 1, 152064, 0x18b54985
-0, 12, 12, 1, 152064, 0xf12b6cde
-0, 13, 13, 1, 152064, 0x3b2e63f7
-0, 14, 14, 1, 152064, 0x140abcfd
+0, 0, 0, 1, 152064, 0xd604d440
+0, 1, 1, 1, 152064, 0x08ef262c
+0, 2, 2, 1, 152064, 0x992fca8e
+0, 3, 3, 1, 152064, 0x5a02ee15
+0, 4, 4, 1, 152064, 0xf15d5c66
+0, 5, 5, 1, 152064, 0x360dda12
+0, 6, 6, 1, 152064, 0x18b54985
+0, 7, 7, 1, 152064, 0xf12b6cde
+0, 8, 8, 1, 152064, 0x3b2e63f7
+0, 9, 9, 1, 152064, 0x140abcfd
diff --git a/tests/ref/fate/h264-conformance-frext-hcaff1_hhi_b b/tests/ref/fate/h264-conformance-frext-hcaff1_hhi_b
index e5fc739..eb41d46 100644
--- a/tests/ref/fate/h264-conformance-frext-hcaff1_hhi_b
+++ b/tests/ref/fate/h264-conformance-frext-hcaff1_hhi_b
@@ -1,11 +1,11 @@
#tb 0: 1/25
-0, 2, 2, 1, 152064, 0xb055a9bd
-0, 4, 4, 1, 152064, 0x9e1eadb6
-0, 5, 5, 1, 152064, 0x48f117d2
-0, 6, 6, 1, 152064, 0x3e3ff049
-0, 7, 7, 1, 152064, 0x2ff80943
-0, 9, 9, 1, 152064, 0xc5ee16a6
-0, 10, 10, 1, 152064, 0x38c33f28
-0, 11, 11, 1, 152064, 0x3e8444c7
-0, 12, 12, 1, 152064, 0x14ca4ab2
-0, 13, 13, 1, 152064, 0xe20e78f7
+0, 0, 0, 1, 152064, 0xb055a9bd
+0, 1, 1, 1, 152064, 0x9e1eadb6
+0, 2, 2, 1, 152064, 0x48f117d2
+0, 3, 3, 1, 152064, 0x3e3ff049
+0, 4, 4, 1, 152064, 0x2ff80943
+0, 5, 5, 1, 152064, 0xc5ee16a6
+0, 6, 6, 1, 152064, 0x38c33f28
+0, 7, 7, 1, 152064, 0x3e8444c7
+0, 8, 8, 1, 152064, 0x14ca4ab2
+0, 9, 9, 1, 152064, 0xe20e78f7
diff --git a/tests/ref/fate/h264-conformance-frext-hpcafl_bcrm_c b/tests/ref/fate/h264-conformance-frext-hpcafl_bcrm_c
index b208184..dbfec43 100644
--- a/tests/ref/fate/h264-conformance-frext-hpcafl_bcrm_c
+++ b/tests/ref/fate/h264-conformance-frext-hpcafl_bcrm_c
@@ -1,301 +1,301 @@
#tb 0: 1/25
-0, 2, 2, 1, 152064, 0x502ec077
-0, 4, 4, 1, 152064, 0x84807243
-0, 6, 6, 1, 152064, 0xd7474a6e
-0, 8, 8, 1, 152064, 0x793469bb
-0, 10, 10, 1, 152064, 0xb7a0faf7
-0, 12, 12, 1, 152064, 0x1d3d3cba
-0, 14, 14, 1, 152064, 0xb62583de
-0, 16, 16, 1, 152064, 0xc8422fb1
-0, 18, 18, 1, 152064, 0x321dc699
-0, 20, 20, 1, 152064, 0x7a34d350
-0, 22, 22, 1, 152064, 0xaa4c302d
-0, 24, 24, 1, 152064, 0x45fa7ab0
-0, 26, 26, 1, 152064, 0xc7262e41
-0, 28, 28, 1, 152064, 0x3550000c
-0, 30, 30, 1, 152064, 0xf4bab54b
-0, 32, 32, 1, 152064, 0xaccf9c1a
-0, 34, 34, 1, 152064, 0x9bee20e9
-0, 36, 36, 1, 152064, 0x47fb7720
-0, 38, 38, 1, 152064, 0x12c63ffb
-0, 40, 40, 1, 152064, 0xfa2b8b4d
-0, 42, 42, 1, 152064, 0x279964bd
-0, 44, 44, 1, 152064, 0xb8b01c7e
-0, 46, 46, 1, 152064, 0x816fa010
-0, 48, 48, 1, 152064, 0x59fe1c8c
-0, 50, 50, 1, 152064, 0x13393fad
-0, 52, 52, 1, 152064, 0x991a50a4
-0, 54, 54, 1, 152064, 0x57df3eb7
-0, 56, 56, 1, 152064, 0x744371df
-0, 58, 58, 1, 152064, 0xe9f6d3ff
-0, 60, 60, 1, 152064, 0xc506fba0
-0, 62, 62, 1, 152064, 0x6295b90e
-0, 64, 64, 1, 152064, 0xa19cee2d
-0, 66, 66, 1, 152064, 0xf8c1b3ca
-0, 68, 68, 1, 152064, 0x69f68ce0
-0, 70, 70, 1, 152064, 0x80558bb6
-0, 72, 72, 1, 152064, 0x27824fa5
-0, 74, 74, 1, 152064, 0x27c929a1
-0, 76, 76, 1, 152064, 0xc0fe06d1
-0, 78, 78, 1, 152064, 0xc52bc58c
-0, 80, 80, 1, 152064, 0x0a5363c7
-0, 82, 82, 1, 152064, 0xd0f45a0d
-0, 84, 84, 1, 152064, 0x274710f9
-0, 86, 86, 1, 152064, 0x89d2d390
-0, 88, 88, 1, 152064, 0x12a9bfb0
-0, 90, 90, 1, 152064, 0x04501a93
-0, 92, 92, 1, 152064, 0xf92cbbf4
-0, 94, 94, 1, 152064, 0xf6d1b27d
-0, 96, 96, 1, 152064, 0xe3e904c3
-0, 98, 98, 1, 152064, 0x58f8516d
-0, 100, 100, 1, 152064, 0x70370c2b
-0, 102, 102, 1, 152064, 0xfeebc88c
-0, 104, 104, 1, 152064, 0x974c6ed6
-0, 106, 106, 1, 152064, 0x401bdcf2
-0, 108, 108, 1, 152064, 0xfe61e278
-0, 110, 110, 1, 152064, 0x96ba8bb9
-0, 112, 112, 1, 152064, 0x988492fd
-0, 114, 114, 1, 152064, 0xd1d913a9
-0, 116, 116, 1, 152064, 0x6bc46f0e
-0, 118, 118, 1, 152064, 0x695ef706
-0, 120, 120, 1, 152064, 0x142045c9
-0, 122, 122, 1, 152064, 0xb390ed87
-0, 124, 124, 1, 152064, 0xb9e6d2e5
-0, 126, 126, 1, 152064, 0xe348797f
-0, 128, 128, 1, 152064, 0x1cbd29d6
-0, 130, 130, 1, 152064, 0xbd7dd694
-0, 132, 132, 1, 152064, 0x516873c3
-0, 134, 134, 1, 152064, 0x27bba182
-0, 136, 136, 1, 152064, 0x7541f920
-0, 138, 138, 1, 152064, 0xfdf67042
-0, 140, 140, 1, 152064, 0x6c3c7896
-0, 142, 142, 1, 152064, 0xed86c467
-0, 144, 144, 1, 152064, 0x4ea83ca2
-0, 146, 146, 1, 152064, 0xa3e6725b
-0, 148, 148, 1, 152064, 0x917f5f16
-0, 150, 150, 1, 152064, 0x8cf2d2e1
-0, 152, 152, 1, 152064, 0x57a8d116
-0, 154, 154, 1, 152064, 0x0db267d4
-0, 156, 156, 1, 152064, 0xce782ac5
-0, 158, 158, 1, 152064, 0x1c9d8518
-0, 160, 160, 1, 152064, 0x47598ac7
-0, 162, 162, 1, 152064, 0xc5033d97
-0, 164, 164, 1, 152064, 0xd7aaa3a4
-0, 166, 166, 1, 152064, 0x078afc96
-0, 168, 168, 1, 152064, 0xc9fe673d
-0, 170, 170, 1, 152064, 0xe9284066
-0, 172, 172, 1, 152064, 0xbc570982
-0, 174, 174, 1, 152064, 0x0aac8574
-0, 176, 176, 1, 152064, 0x098cbeee
-0, 178, 178, 1, 152064, 0x19c36a9d
-0, 180, 180, 1, 152064, 0x8fe4a893
-0, 182, 182, 1, 152064, 0x0b652f17
-0, 184, 184, 1, 152064, 0x10f2e6bf
-0, 186, 186, 1, 152064, 0x7ce5634e
-0, 188, 188, 1, 152064, 0x8fe4ac6c
-0, 190, 190, 1, 152064, 0xcaba749e
-0, 192, 192, 1, 152064, 0x5f8a0d5c
-0, 194, 194, 1, 152064, 0xcaa66bbc
-0, 196, 196, 1, 152064, 0xc87ae617
-0, 198, 198, 1, 152064, 0xe8ef4dd7
-0, 200, 200, 1, 152064, 0xdfca5a07
-0, 202, 202, 1, 152064, 0x5f7eab7d
-0, 204, 204, 1, 152064, 0x8a65ebbb
-0, 206, 206, 1, 152064, 0x4beab4a0
-0, 208, 208, 1, 152064, 0xb5e6ab30
-0, 210, 210, 1, 152064, 0x8fe4f4d4
-0, 212, 212, 1, 152064, 0x95bde1ca
-0, 214, 214, 1, 152064, 0xcc5e3a53
-0, 216, 216, 1, 152064, 0xf09f1dd7
-0, 218, 218, 1, 152064, 0x10179672
-0, 220, 220, 1, 152064, 0x4ad16184
-0, 222, 222, 1, 152064, 0x9efa0e23
-0, 224, 224, 1, 152064, 0x22f59522
-0, 226, 226, 1, 152064, 0x4d38f09d
-0, 228, 228, 1, 152064, 0x4c5ebf56
-0, 230, 230, 1, 152064, 0xb19d5077
-0, 232, 232, 1, 152064, 0xa98576b9
-0, 234, 234, 1, 152064, 0x65324239
-0, 236, 236, 1, 152064, 0x709e4031
-0, 238, 238, 1, 152064, 0xf8e81681
-0, 240, 240, 1, 152064, 0x058514e5
-0, 242, 242, 1, 152064, 0xd1d1c806
-0, 244, 244, 1, 152064, 0x0e4dde57
-0, 246, 246, 1, 152064, 0x49e9c2bb
-0, 248, 248, 1, 152064, 0x01417ce6
-0, 250, 250, 1, 152064, 0xda7ebbf1
-0, 252, 252, 1, 152064, 0xa22906b7
-0, 254, 254, 1, 152064, 0x32e2df87
-0, 256, 256, 1, 152064, 0x69917c8f
-0, 258, 258, 1, 152064, 0xea8ed2cc
-0, 260, 260, 1, 152064, 0x0b8d57f1
-0, 262, 262, 1, 152064, 0x5f683bcd
-0, 264, 264, 1, 152064, 0x5162fe2f
-0, 266, 266, 1, 152064, 0x49c052f8
-0, 268, 268, 1, 152064, 0x990b69ba
-0, 270, 270, 1, 152064, 0xa6d4f99f
-0, 272, 272, 1, 152064, 0xe79ef4da
-0, 274, 274, 1, 152064, 0x5e8a3847
-0, 276, 276, 1, 152064, 0x38b1e75f
-0, 278, 278, 1, 152064, 0xf5c91bed
-0, 280, 280, 1, 152064, 0xd59a6d26
-0, 282, 282, 1, 152064, 0xc361de06
-0, 284, 284, 1, 152064, 0x63ed2229
-0, 286, 286, 1, 152064, 0xb8229205
-0, 288, 288, 1, 152064, 0x7c6619af
-0, 290, 290, 1, 152064, 0x4126b02f
-0, 292, 292, 1, 152064, 0x9250b99b
-0, 294, 294, 1, 152064, 0x589778f9
-0, 296, 296, 1, 152064, 0xed1fa45b
-0, 298, 298, 1, 152064, 0x700b6f32
-0, 300, 300, 1, 152064, 0x0590df55
-0, 302, 302, 1, 152064, 0x3e9c4018
-0, 304, 304, 1, 152064, 0x957b8860
-0, 306, 306, 1, 152064, 0x56161560
-0, 308, 308, 1, 152064, 0xbc43bc3b
-0, 310, 310, 1, 152064, 0x508d8632
-0, 312, 312, 1, 152064, 0xbc5736d8
-0, 314, 314, 1, 152064, 0xed7d3aef
-0, 316, 316, 1, 152064, 0x1dcdda9f
-0, 318, 318, 1, 152064, 0x8ef6d5c9
-0, 320, 320, 1, 152064, 0x15466acc
-0, 322, 322, 1, 152064, 0x45d4cf67
-0, 324, 324, 1, 152064, 0x8c900b9d
-0, 326, 326, 1, 152064, 0x747006e0
-0, 328, 328, 1, 152064, 0xac920a0c
-0, 330, 330, 1, 152064, 0xb8210c27
-0, 332, 332, 1, 152064, 0x7dbb873a
-0, 334, 334, 1, 152064, 0x0d4d7584
-0, 336, 336, 1, 152064, 0xefb3fe60
-0, 338, 338, 1, 152064, 0x905e2644
-0, 340, 340, 1, 152064, 0x7c04e534
-0, 342, 342, 1, 152064, 0x8889972a
-0, 344, 344, 1, 152064, 0x21c7d8ad
-0, 346, 346, 1, 152064, 0x1c641176
-0, 348, 348, 1, 152064, 0xf71489a4
-0, 350, 350, 1, 152064, 0xd7ac5555
-0, 352, 352, 1, 152064, 0xb4609c6d
-0, 354, 354, 1, 152064, 0xf5b2bd5e
-0, 356, 356, 1, 152064, 0x9f43ce57
-0, 358, 358, 1, 152064, 0x77642dd3
-0, 360, 360, 1, 152064, 0x3e79565c
-0, 362, 362, 1, 152064, 0x95f40b8e
-0, 364, 364, 1, 152064, 0x3c8ca4d4
-0, 366, 366, 1, 152064, 0xa02ac497
-0, 368, 368, 1, 152064, 0x4c93b377
-0, 370, 370, 1, 152064, 0x55f5ac68
-0, 372, 372, 1, 152064, 0xf8652eca
-0, 374, 374, 1, 152064, 0x56e94574
-0, 376, 376, 1, 152064, 0x6d8302e1
-0, 378, 378, 1, 152064, 0x29a57061
-0, 380, 380, 1, 152064, 0x24e4cfdc
-0, 382, 382, 1, 152064, 0xf5a5d62a
-0, 384, 384, 1, 152064, 0x998870c1
-0, 386, 386, 1, 152064, 0xa15b1f4e
-0, 388, 388, 1, 152064, 0xb0ccb51f
-0, 390, 390, 1, 152064, 0xeaaf59ab
-0, 392, 392, 1, 152064, 0x7e2b4fe6
-0, 394, 394, 1, 152064, 0x72299fea
-0, 396, 396, 1, 152064, 0x769da8b2
-0, 398, 398, 1, 152064, 0xefad7ef8
-0, 400, 400, 1, 152064, 0x24819983
-0, 402, 402, 1, 152064, 0x2aad32ab
-0, 404, 404, 1, 152064, 0xc80cac79
-0, 406, 406, 1, 152064, 0x1659d628
-0, 408, 408, 1, 152064, 0xef941f66
-0, 410, 410, 1, 152064, 0x0d7fcdb5
-0, 412, 412, 1, 152064, 0x7c1853fa
-0, 414, 414, 1, 152064, 0xb94c4d3c
-0, 416, 416, 1, 152064, 0xc47adfc2
-0, 418, 418, 1, 152064, 0x366a6729
-0, 420, 420, 1, 152064, 0x7eb37b70
-0, 422, 422, 1, 152064, 0xafd54c27
-0, 424, 424, 1, 152064, 0x67b18636
-0, 426, 426, 1, 152064, 0x93b22dcf
-0, 428, 428, 1, 152064, 0xa64991f1
-0, 430, 430, 1, 152064, 0xd32a7102
-0, 432, 432, 1, 152064, 0xff665d1c
-0, 434, 434, 1, 152064, 0xf107cc31
-0, 436, 436, 1, 152064, 0xf5b25652
-0, 438, 438, 1, 152064, 0x8caf783d
-0, 440, 440, 1, 152064, 0x72f3eb00
-0, 442, 442, 1, 152064, 0xb5aea5f8
-0, 444, 444, 1, 152064, 0xee70e870
-0, 446, 446, 1, 152064, 0x7c3a0156
-0, 448, 448, 1, 152064, 0x871b6383
-0, 450, 450, 1, 152064, 0x48d831ff
-0, 452, 452, 1, 152064, 0xca233913
-0, 454, 454, 1, 152064, 0xe14bc5eb
-0, 456, 456, 1, 152064, 0x9b1d27e7
-0, 458, 458, 1, 152064, 0xfb9637f7
-0, 460, 460, 1, 152064, 0x0c022157
-0, 462, 462, 1, 152064, 0x16d35fc9
-0, 464, 464, 1, 152064, 0x6d935f71
-0, 466, 466, 1, 152064, 0xae4066fa
-0, 468, 468, 1, 152064, 0xcef94fdc
-0, 470, 470, 1, 152064, 0xc234edb9
-0, 472, 472, 1, 152064, 0x26a4f2e2
-0, 474, 474, 1, 152064, 0xd29ac23e
-0, 476, 476, 1, 152064, 0xb7604395
-0, 478, 478, 1, 152064, 0x408084f6
-0, 480, 480, 1, 152064, 0x0a02026c
-0, 482, 482, 1, 152064, 0x78b33c7c
-0, 484, 484, 1, 152064, 0xcb02b874
-0, 486, 486, 1, 152064, 0xf566513b
-0, 488, 488, 1, 152064, 0xb34e52b1
-0, 490, 490, 1, 152064, 0xf55ff493
-0, 492, 492, 1, 152064, 0xb0e8282a
-0, 494, 494, 1, 152064, 0xe9510bbe
-0, 496, 496, 1, 152064, 0x292e8c5a
-0, 498, 498, 1, 152064, 0x62b9d2b0
-0, 500, 500, 1, 152064, 0x3a8cc827
-0, 502, 502, 1, 152064, 0x25cc465e
-0, 504, 504, 1, 152064, 0xf2bc32e2
-0, 506, 506, 1, 152064, 0x6141f914
-0, 508, 508, 1, 152064, 0x1171256f
-0, 510, 510, 1, 152064, 0x13cb2ded
-0, 512, 512, 1, 152064, 0x3d4ca557
-0, 514, 514, 1, 152064, 0xf2b9e72e
-0, 516, 516, 1, 152064, 0x03f7547a
-0, 518, 518, 1, 152064, 0xc7302955
-0, 520, 520, 1, 152064, 0xe78a46d3
-0, 522, 522, 1, 152064, 0x3726a270
-0, 524, 524, 1, 152064, 0x2f65722a
-0, 526, 526, 1, 152064, 0x55acce40
-0, 528, 528, 1, 152064, 0xf6fa9db2
-0, 530, 530, 1, 152064, 0x70a36937
-0, 532, 532, 1, 152064, 0x9313742d
-0, 534, 534, 1, 152064, 0x2eb14e53
-0, 536, 536, 1, 152064, 0x3d47c9c3
-0, 538, 538, 1, 152064, 0xd0a90348
-0, 540, 540, 1, 152064, 0x6ad48088
-0, 542, 542, 1, 152064, 0x68e64738
-0, 544, 544, 1, 152064, 0x04c3735a
-0, 546, 546, 1, 152064, 0x51d0593f
-0, 548, 548, 1, 152064, 0x42cf2b48
-0, 550, 550, 1, 152064, 0xa5496a0c
-0, 552, 552, 1, 152064, 0x84c25549
-0, 554, 554, 1, 152064, 0x96691600
-0, 556, 556, 1, 152064, 0x423135db
-0, 558, 558, 1, 152064, 0x8d2e08b6
-0, 560, 560, 1, 152064, 0xaeb4c840
-0, 562, 562, 1, 152064, 0xf3e71780
-0, 564, 564, 1, 152064, 0x8858228b
-0, 566, 566, 1, 152064, 0xf28613f8
-0, 568, 568, 1, 152064, 0xb5327882
-0, 570, 570, 1, 152064, 0xbb60bb85
-0, 572, 572, 1, 152064, 0x345ab1c9
-0, 574, 574, 1, 152064, 0x8aac2cba
-0, 576, 576, 1, 152064, 0x7ce15b4c
-0, 578, 578, 1, 152064, 0xc09c55c0
-0, 580, 580, 1, 152064, 0x8482ddd6
-0, 582, 582, 1, 152064, 0xab222a13
-0, 584, 584, 1, 152064, 0xd39b0dea
-0, 586, 586, 1, 152064, 0x6dab6e06
-0, 588, 588, 1, 152064, 0xec0891bd
-0, 590, 590, 1, 152064, 0x88bd9701
-0, 592, 592, 1, 152064, 0xdf13072a
-0, 594, 594, 1, 152064, 0x23b33081
-0, 596, 596, 1, 152064, 0x63943137
-0, 598, 598, 1, 152064, 0xab6a9052
-0, 599, 599, 1, 152064, 0x05485494
+0, 0, 0, 1, 152064, 0x502ec077
+0, 1, 1, 1, 152064, 0x84807243
+0, 2, 2, 1, 152064, 0xd7474a6e
+0, 3, 3, 1, 152064, 0x793469bb
+0, 4, 4, 1, 152064, 0xb7a0faf7
+0, 5, 5, 1, 152064, 0x1d3d3cba
+0, 6, 6, 1, 152064, 0xb62583de
+0, 7, 7, 1, 152064, 0xc8422fb1
+0, 8, 8, 1, 152064, 0x321dc699
+0, 9, 9, 1, 152064, 0x7a34d350
+0, 10, 10, 1, 152064, 0xaa4c302d
+0, 11, 11, 1, 152064, 0x45fa7ab0
+0, 12, 12, 1, 152064, 0xc7262e41
+0, 13, 13, 1, 152064, 0x3550000c
+0, 14, 14, 1, 152064, 0xf4bab54b
+0, 15, 15, 1, 152064, 0xaccf9c1a
+0, 16, 16, 1, 152064, 0x9bee20e9
+0, 17, 17, 1, 152064, 0x47fb7720
+0, 18, 18, 1, 152064, 0x12c63ffb
+0, 19, 19, 1, 152064, 0xfa2b8b4d
+0, 20, 20, 1, 152064, 0x279964bd
+0, 21, 21, 1, 152064, 0xb8b01c7e
+0, 22, 22, 1, 152064, 0x816fa010
+0, 23, 23, 1, 152064, 0x59fe1c8c
+0, 24, 24, 1, 152064, 0x13393fad
+0, 25, 25, 1, 152064, 0x991a50a4
+0, 26, 26, 1, 152064, 0x57df3eb7
+0, 27, 27, 1, 152064, 0x744371df
+0, 28, 28, 1, 152064, 0xe9f6d3ff
+0, 29, 29, 1, 152064, 0xc506fba0
+0, 30, 30, 1, 152064, 0x6295b90e
+0, 31, 31, 1, 152064, 0xa19cee2d
+0, 32, 32, 1, 152064, 0xf8c1b3ca
+0, 33, 33, 1, 152064, 0x69f68ce0
+0, 34, 34, 1, 152064, 0x80558bb6
+0, 35, 35, 1, 152064, 0x27824fa5
+0, 36, 36, 1, 152064, 0x27c929a1
+0, 37, 37, 1, 152064, 0xc0fe06d1
+0, 38, 38, 1, 152064, 0xc52bc58c
+0, 39, 39, 1, 152064, 0x0a5363c7
+0, 40, 40, 1, 152064, 0xd0f45a0d
+0, 41, 41, 1, 152064, 0x274710f9
+0, 42, 42, 1, 152064, 0x89d2d390
+0, 43, 43, 1, 152064, 0x12a9bfb0
+0, 44, 44, 1, 152064, 0x04501a93
+0, 45, 45, 1, 152064, 0xf92cbbf4
+0, 46, 46, 1, 152064, 0xf6d1b27d
+0, 47, 47, 1, 152064, 0xe3e904c3
+0, 48, 48, 1, 152064, 0x58f8516d
+0, 49, 49, 1, 152064, 0x70370c2b
+0, 50, 50, 1, 152064, 0xfeebc88c
+0, 51, 51, 1, 152064, 0x974c6ed6
+0, 52, 52, 1, 152064, 0x401bdcf2
+0, 53, 53, 1, 152064, 0xfe61e278
+0, 54, 54, 1, 152064, 0x96ba8bb9
+0, 55, 55, 1, 152064, 0x988492fd
+0, 56, 56, 1, 152064, 0xd1d913a9
+0, 57, 57, 1, 152064, 0x6bc46f0e
+0, 58, 58, 1, 152064, 0x695ef706
+0, 59, 59, 1, 152064, 0x142045c9
+0, 60, 60, 1, 152064, 0xb390ed87
+0, 61, 61, 1, 152064, 0xb9e6d2e5
+0, 62, 62, 1, 152064, 0xe348797f
+0, 63, 63, 1, 152064, 0x1cbd29d6
+0, 64, 64, 1, 152064, 0xbd7dd694
+0, 65, 65, 1, 152064, 0x516873c3
+0, 66, 66, 1, 152064, 0x27bba182
+0, 67, 67, 1, 152064, 0x7541f920
+0, 68, 68, 1, 152064, 0xfdf67042
+0, 69, 69, 1, 152064, 0x6c3c7896
+0, 70, 70, 1, 152064, 0xed86c467
+0, 71, 71, 1, 152064, 0x4ea83ca2
+0, 72, 72, 1, 152064, 0xa3e6725b
+0, 73, 73, 1, 152064, 0x917f5f16
+0, 74, 74, 1, 152064, 0x8cf2d2e1
+0, 75, 75, 1, 152064, 0x57a8d116
+0, 76, 76, 1, 152064, 0x0db267d4
+0, 77, 77, 1, 152064, 0xce782ac5
+0, 78, 78, 1, 152064, 0x1c9d8518
+0, 79, 79, 1, 152064, 0x47598ac7
+0, 80, 80, 1, 152064, 0xc5033d97
+0, 81, 81, 1, 152064, 0xd7aaa3a4
+0, 82, 82, 1, 152064, 0x078afc96
+0, 83, 83, 1, 152064, 0xc9fe673d
+0, 84, 84, 1, 152064, 0xe9284066
+0, 85, 85, 1, 152064, 0xbc570982
+0, 86, 86, 1, 152064, 0x0aac8574
+0, 87, 87, 1, 152064, 0x098cbeee
+0, 88, 88, 1, 152064, 0x19c36a9d
+0, 89, 89, 1, 152064, 0x8fe4a893
+0, 90, 90, 1, 152064, 0x0b652f17
+0, 91, 91, 1, 152064, 0x10f2e6bf
+0, 92, 92, 1, 152064, 0x7ce5634e
+0, 93, 93, 1, 152064, 0x8fe4ac6c
+0, 94, 94, 1, 152064, 0xcaba749e
+0, 95, 95, 1, 152064, 0x5f8a0d5c
+0, 96, 96, 1, 152064, 0xcaa66bbc
+0, 97, 97, 1, 152064, 0xc87ae617
+0, 98, 98, 1, 152064, 0xe8ef4dd7
+0, 99, 99, 1, 152064, 0xdfca5a07
+0, 100, 100, 1, 152064, 0x5f7eab7d
+0, 101, 101, 1, 152064, 0x8a65ebbb
+0, 102, 102, 1, 152064, 0x4beab4a0
+0, 103, 103, 1, 152064, 0xb5e6ab30
+0, 104, 104, 1, 152064, 0x8fe4f4d4
+0, 105, 105, 1, 152064, 0x95bde1ca
+0, 106, 106, 1, 152064, 0xcc5e3a53
+0, 107, 107, 1, 152064, 0xf09f1dd7
+0, 108, 108, 1, 152064, 0x10179672
+0, 109, 109, 1, 152064, 0x4ad16184
+0, 110, 110, 1, 152064, 0x9efa0e23
+0, 111, 111, 1, 152064, 0x22f59522
+0, 112, 112, 1, 152064, 0x4d38f09d
+0, 113, 113, 1, 152064, 0x4c5ebf56
+0, 114, 114, 1, 152064, 0xb19d5077
+0, 115, 115, 1, 152064, 0xa98576b9
+0, 116, 116, 1, 152064, 0x65324239
+0, 117, 117, 1, 152064, 0x709e4031
+0, 118, 118, 1, 152064, 0xf8e81681
+0, 119, 119, 1, 152064, 0x058514e5
+0, 120, 120, 1, 152064, 0xd1d1c806
+0, 121, 121, 1, 152064, 0x0e4dde57
+0, 122, 122, 1, 152064, 0x49e9c2bb
+0, 123, 123, 1, 152064, 0x01417ce6
+0, 124, 124, 1, 152064, 0xda7ebbf1
+0, 125, 125, 1, 152064, 0xa22906b7
+0, 126, 126, 1, 152064, 0x32e2df87
+0, 127, 127, 1, 152064, 0x69917c8f
+0, 128, 128, 1, 152064, 0xea8ed2cc
+0, 129, 129, 1, 152064, 0x0b8d57f1
+0, 130, 130, 1, 152064, 0x5f683bcd
+0, 131, 131, 1, 152064, 0x5162fe2f
+0, 132, 132, 1, 152064, 0x49c052f8
+0, 133, 133, 1, 152064, 0x990b69ba
+0, 134, 134, 1, 152064, 0xa6d4f99f
+0, 135, 135, 1, 152064, 0xe79ef4da
+0, 136, 136, 1, 152064, 0x5e8a3847
+0, 137, 137, 1, 152064, 0x38b1e75f
+0, 138, 138, 1, 152064, 0xf5c91bed
+0, 139, 139, 1, 152064, 0xd59a6d26
+0, 140, 140, 1, 152064, 0xc361de06
+0, 141, 141, 1, 152064, 0x63ed2229
+0, 142, 142, 1, 152064, 0xb8229205
+0, 143, 143, 1, 152064, 0x7c6619af
+0, 144, 144, 1, 152064, 0x4126b02f
+0, 145, 145, 1, 152064, 0x9250b99b
+0, 146, 146, 1, 152064, 0x589778f9
+0, 147, 147, 1, 152064, 0xed1fa45b
+0, 148, 148, 1, 152064, 0x700b6f32
+0, 149, 149, 1, 152064, 0x0590df55
+0, 150, 150, 1, 152064, 0x3e9c4018
+0, 151, 151, 1, 152064, 0x957b8860
+0, 152, 152, 1, 152064, 0x56161560
+0, 153, 153, 1, 152064, 0xbc43bc3b
+0, 154, 154, 1, 152064, 0x508d8632
+0, 155, 155, 1, 152064, 0xbc5736d8
+0, 156, 156, 1, 152064, 0xed7d3aef
+0, 157, 157, 1, 152064, 0x1dcdda9f
+0, 158, 158, 1, 152064, 0x8ef6d5c9
+0, 159, 159, 1, 152064, 0x15466acc
+0, 160, 160, 1, 152064, 0x45d4cf67
+0, 161, 161, 1, 152064, 0x8c900b9d
+0, 162, 162, 1, 152064, 0x747006e0
+0, 163, 163, 1, 152064, 0xac920a0c
+0, 164, 164, 1, 152064, 0xb8210c27
+0, 165, 165, 1, 152064, 0x7dbb873a
+0, 166, 166, 1, 152064, 0x0d4d7584
+0, 167, 167, 1, 152064, 0xefb3fe60
+0, 168, 168, 1, 152064, 0x905e2644
+0, 169, 169, 1, 152064, 0x7c04e534
+0, 170, 170, 1, 152064, 0x8889972a
+0, 171, 171, 1, 152064, 0x21c7d8ad
+0, 172, 172, 1, 152064, 0x1c641176
+0, 173, 173, 1, 152064, 0xf71489a4
+0, 174, 174, 1, 152064, 0xd7ac5555
+0, 175, 175, 1, 152064, 0xb4609c6d
+0, 176, 176, 1, 152064, 0xf5b2bd5e
+0, 177, 177, 1, 152064, 0x9f43ce57
+0, 178, 178, 1, 152064, 0x77642dd3
+0, 179, 179, 1, 152064, 0x3e79565c
+0, 180, 180, 1, 152064, 0x95f40b8e
+0, 181, 181, 1, 152064, 0x3c8ca4d4
+0, 182, 182, 1, 152064, 0xa02ac497
+0, 183, 183, 1, 152064, 0x4c93b377
+0, 184, 184, 1, 152064, 0x55f5ac68
+0, 185, 185, 1, 152064, 0xf8652eca
+0, 186, 186, 1, 152064, 0x56e94574
+0, 187, 187, 1, 152064, 0x6d8302e1
+0, 188, 188, 1, 152064, 0x29a57061
+0, 189, 189, 1, 152064, 0x24e4cfdc
+0, 190, 190, 1, 152064, 0xf5a5d62a
+0, 191, 191, 1, 152064, 0x998870c1
+0, 192, 192, 1, 152064, 0xa15b1f4e
+0, 193, 193, 1, 152064, 0xb0ccb51f
+0, 194, 194, 1, 152064, 0xeaaf59ab
+0, 195, 195, 1, 152064, 0x7e2b4fe6
+0, 196, 196, 1, 152064, 0x72299fea
+0, 197, 197, 1, 152064, 0x769da8b2
+0, 198, 198, 1, 152064, 0xefad7ef8
+0, 199, 199, 1, 152064, 0x24819983
+0, 200, 200, 1, 152064, 0x2aad32ab
+0, 201, 201, 1, 152064, 0xc80cac79
+0, 202, 202, 1, 152064, 0x1659d628
+0, 203, 203, 1, 152064, 0xef941f66
+0, 204, 204, 1, 152064, 0x0d7fcdb5
+0, 205, 205, 1, 152064, 0x7c1853fa
+0, 206, 206, 1, 152064, 0xb94c4d3c
+0, 207, 207, 1, 152064, 0xc47adfc2
+0, 208, 208, 1, 152064, 0x366a6729
+0, 209, 209, 1, 152064, 0x7eb37b70
+0, 210, 210, 1, 152064, 0xafd54c27
+0, 211, 211, 1, 152064, 0x67b18636
+0, 212, 212, 1, 152064, 0x93b22dcf
+0, 213, 213, 1, 152064, 0xa64991f1
+0, 214, 214, 1, 152064, 0xd32a7102
+0, 215, 215, 1, 152064, 0xff665d1c
+0, 216, 216, 1, 152064, 0xf107cc31
+0, 217, 217, 1, 152064, 0xf5b25652
+0, 218, 218, 1, 152064, 0x8caf783d
+0, 219, 219, 1, 152064, 0x72f3eb00
+0, 220, 220, 1, 152064, 0xb5aea5f8
+0, 221, 221, 1, 152064, 0xee70e870
+0, 222, 222, 1, 152064, 0x7c3a0156
+0, 223, 223, 1, 152064, 0x871b6383
+0, 224, 224, 1, 152064, 0x48d831ff
+0, 225, 225, 1, 152064, 0xca233913
+0, 226, 226, 1, 152064, 0xe14bc5eb
+0, 227, 227, 1, 152064, 0x9b1d27e7
+0, 228, 228, 1, 152064, 0xfb9637f7
+0, 229, 229, 1, 152064, 0x0c022157
+0, 230, 230, 1, 152064, 0x16d35fc9
+0, 231, 231, 1, 152064, 0x6d935f71
+0, 232, 232, 1, 152064, 0xae4066fa
+0, 233, 233, 1, 152064, 0xcef94fdc
+0, 234, 234, 1, 152064, 0xc234edb9
+0, 235, 235, 1, 152064, 0x26a4f2e2
+0, 236, 236, 1, 152064, 0xd29ac23e
+0, 237, 237, 1, 152064, 0xb7604395
+0, 238, 238, 1, 152064, 0x408084f6
+0, 239, 239, 1, 152064, 0x0a02026c
+0, 240, 240, 1, 152064, 0x78b33c7c
+0, 241, 241, 1, 152064, 0xcb02b874
+0, 242, 242, 1, 152064, 0xf566513b
+0, 243, 243, 1, 152064, 0xb34e52b1
+0, 244, 244, 1, 152064, 0xf55ff493
+0, 245, 245, 1, 152064, 0xb0e8282a
+0, 246, 246, 1, 152064, 0xe9510bbe
+0, 247, 247, 1, 152064, 0x292e8c5a
+0, 248, 248, 1, 152064, 0x62b9d2b0
+0, 249, 249, 1, 152064, 0x3a8cc827
+0, 250, 250, 1, 152064, 0x25cc465e
+0, 251, 251, 1, 152064, 0xf2bc32e2
+0, 252, 252, 1, 152064, 0x6141f914
+0, 253, 253, 1, 152064, 0x1171256f
+0, 254, 254, 1, 152064, 0x13cb2ded
+0, 255, 255, 1, 152064, 0x3d4ca557
+0, 256, 256, 1, 152064, 0xf2b9e72e
+0, 257, 257, 1, 152064, 0x03f7547a
+0, 258, 258, 1, 152064, 0xc7302955
+0, 259, 259, 1, 152064, 0xe78a46d3
+0, 260, 260, 1, 152064, 0x3726a270
+0, 261, 261, 1, 152064, 0x2f65722a
+0, 262, 262, 1, 152064, 0x55acce40
+0, 263, 263, 1, 152064, 0xf6fa9db2
+0, 264, 264, 1, 152064, 0x70a36937
+0, 265, 265, 1, 152064, 0x9313742d
+0, 266, 266, 1, 152064, 0x2eb14e53
+0, 267, 267, 1, 152064, 0x3d47c9c3
+0, 268, 268, 1, 152064, 0xd0a90348
+0, 269, 269, 1, 152064, 0x6ad48088
+0, 270, 270, 1, 152064, 0x68e64738
+0, 271, 271, 1, 152064, 0x04c3735a
+0, 272, 272, 1, 152064, 0x51d0593f
+0, 273, 273, 1, 152064, 0x42cf2b48
+0, 274, 274, 1, 152064, 0xa5496a0c
+0, 275, 275, 1, 152064, 0x84c25549
+0, 276, 276, 1, 152064, 0x96691600
+0, 277, 277, 1, 152064, 0x423135db
+0, 278, 278, 1, 152064, 0x8d2e08b6
+0, 279, 279, 1, 152064, 0xaeb4c840
+0, 280, 280, 1, 152064, 0xf3e71780
+0, 281, 281, 1, 152064, 0x8858228b
+0, 282, 282, 1, 152064, 0xf28613f8
+0, 283, 283, 1, 152064, 0xb5327882
+0, 284, 284, 1, 152064, 0xbb60bb85
+0, 285, 285, 1, 152064, 0x345ab1c9
+0, 286, 286, 1, 152064, 0x8aac2cba
+0, 287, 287, 1, 152064, 0x7ce15b4c
+0, 288, 288, 1, 152064, 0xc09c55c0
+0, 289, 289, 1, 152064, 0x8482ddd6
+0, 290, 290, 1, 152064, 0xab222a13
+0, 291, 291, 1, 152064, 0xd39b0dea
+0, 292, 292, 1, 152064, 0x6dab6e06
+0, 293, 293, 1, 152064, 0xec0891bd
+0, 294, 294, 1, 152064, 0x88bd9701
+0, 295, 295, 1, 152064, 0xdf13072a
+0, 296, 296, 1, 152064, 0x23b33081
+0, 297, 297, 1, 152064, 0x63943137
+0, 298, 298, 1, 152064, 0xab6a9052
+0, 299, 299, 1, 152064, 0x05485494
diff --git a/tests/ref/fate/h264-conformance-frext-hpcaflnl_bcrm_c b/tests/ref/fate/h264-conformance-frext-hpcaflnl_bcrm_c
index aafb2d4..65a366e 100644
--- a/tests/ref/fate/h264-conformance-frext-hpcaflnl_bcrm_c
+++ b/tests/ref/fate/h264-conformance-frext-hpcaflnl_bcrm_c
@@ -1,301 +1,301 @@
#tb 0: 1/25
-0, 2, 2, 1, 152064, 0x3e39c08b
-0, 4, 4, 1, 152064, 0xabc67990
-0, 6, 6, 1, 152064, 0x19614e74
-0, 8, 8, 1, 152064, 0xa3776beb
-0, 10, 10, 1, 152064, 0xcce6ffdf
-0, 12, 12, 1, 152064, 0xb0e94746
-0, 14, 14, 1, 152064, 0xdb1a84ef
-0, 16, 16, 1, 152064, 0xb2624509
-0, 18, 18, 1, 152064, 0x32e2d826
-0, 20, 20, 1, 152064, 0xb3bddf0b
-0, 22, 22, 1, 152064, 0x2e273ce3
-0, 24, 24, 1, 152064, 0x67af7e4d
-0, 26, 26, 1, 152064, 0x505c3261
-0, 28, 28, 1, 152064, 0xa43d015e
-0, 30, 30, 1, 152064, 0xad41c1f6
-0, 32, 32, 1, 152064, 0x633ba55f
-0, 34, 34, 1, 152064, 0xe80634f0
-0, 36, 36, 1, 152064, 0x80a07dc9
-0, 38, 38, 1, 152064, 0x0e7a3bbf
-0, 40, 40, 1, 152064, 0xcb099196
-0, 42, 42, 1, 152064, 0x57c96db5
-0, 44, 44, 1, 152064, 0xccd422fa
-0, 46, 46, 1, 152064, 0x0850b7a7
-0, 48, 48, 1, 152064, 0x30e33156
-0, 50, 50, 1, 152064, 0x34e13f9a
-0, 52, 52, 1, 152064, 0x03d36000
-0, 54, 54, 1, 152064, 0xbf7d49da
-0, 56, 56, 1, 152064, 0x77336d09
-0, 58, 58, 1, 152064, 0xca8be5a9
-0, 60, 60, 1, 152064, 0xe57c0b08
-0, 62, 62, 1, 152064, 0xbe77c093
-0, 64, 64, 1, 152064, 0x6bf1ff05
-0, 66, 66, 1, 152064, 0x9142babf
-0, 68, 68, 1, 152064, 0x08db8e67
-0, 70, 70, 1, 152064, 0x69ac8cb6
-0, 72, 72, 1, 152064, 0xaa3b5c88
-0, 74, 74, 1, 152064, 0x9bd32638
-0, 76, 76, 1, 152064, 0x7972115a
-0, 78, 78, 1, 152064, 0x5c1dd47b
-0, 80, 80, 1, 152064, 0x8a196e02
-0, 82, 82, 1, 152064, 0xa89672bc
-0, 84, 84, 1, 152064, 0x27b220e4
-0, 86, 86, 1, 152064, 0xfa38dc4a
-0, 88, 88, 1, 152064, 0x4784c639
-0, 90, 90, 1, 152064, 0xa5e4229a
-0, 92, 92, 1, 152064, 0xa986bdfc
-0, 94, 94, 1, 152064, 0x2951b47b
-0, 96, 96, 1, 152064, 0x4df404a6
-0, 98, 98, 1, 152064, 0xc75155e8
-0, 100, 100, 1, 152064, 0xfc05248c
-0, 102, 102, 1, 152064, 0x5d53da10
-0, 104, 104, 1, 152064, 0x284376ec
-0, 106, 106, 1, 152064, 0x19fce380
-0, 108, 108, 1, 152064, 0x876be6c9
-0, 110, 110, 1, 152064, 0x39eb8ff9
-0, 112, 112, 1, 152064, 0x289c9543
-0, 114, 114, 1, 152064, 0x24dd2356
-0, 116, 116, 1, 152064, 0x1dc17d3c
-0, 118, 118, 1, 152064, 0xd17c00ac
-0, 120, 120, 1, 152064, 0xc2ad54de
-0, 122, 122, 1, 152064, 0xbe11ee2f
-0, 124, 124, 1, 152064, 0x3db9dc89
-0, 126, 126, 1, 152064, 0xac0d7bc2
-0, 128, 128, 1, 152064, 0x8dab2dde
-0, 130, 130, 1, 152064, 0x566ad225
-0, 132, 132, 1, 152064, 0x587c7853
-0, 134, 134, 1, 152064, 0x601c9c80
-0, 136, 136, 1, 152064, 0x2afaf751
-0, 138, 138, 1, 152064, 0x1c9f7e3a
-0, 140, 140, 1, 152064, 0x899475bf
-0, 142, 142, 1, 152064, 0x0d65c7d9
-0, 144, 144, 1, 152064, 0xafd63d12
-0, 146, 146, 1, 152064, 0x162e62b9
-0, 148, 148, 1, 152064, 0x5c9554be
-0, 150, 150, 1, 152064, 0x35fbdaa2
-0, 152, 152, 1, 152064, 0x6438cbd8
-0, 154, 154, 1, 152064, 0xde0772c9
-0, 156, 156, 1, 152064, 0x79f82854
-0, 158, 158, 1, 152064, 0x86957840
-0, 160, 160, 1, 152064, 0xd9468cbf
-0, 162, 162, 1, 152064, 0x23e74609
-0, 164, 164, 1, 152064, 0x3919a146
-0, 166, 166, 1, 152064, 0xd641078b
-0, 168, 168, 1, 152064, 0x24397220
-0, 170, 170, 1, 152064, 0xe7fc3a7c
-0, 172, 172, 1, 152064, 0x3997154a
-0, 174, 174, 1, 152064, 0x2af3952c
-0, 176, 176, 1, 152064, 0x274ac07a
-0, 178, 178, 1, 152064, 0x288f7b09
-0, 180, 180, 1, 152064, 0xe6f9b022
-0, 182, 182, 1, 152064, 0xf09e2fbb
-0, 184, 184, 1, 152064, 0x7244e477
-0, 186, 186, 1, 152064, 0x0dfc72eb
-0, 188, 188, 1, 152064, 0x0322b21f
-0, 190, 190, 1, 152064, 0x18b08205
-0, 192, 192, 1, 152064, 0x6606153e
-0, 194, 194, 1, 152064, 0x85186272
-0, 196, 196, 1, 152064, 0x3369f064
-0, 198, 198, 1, 152064, 0xbe0d5a44
-0, 200, 200, 1, 152064, 0x320258bb
-0, 202, 202, 1, 152064, 0x4d6fb091
-0, 204, 204, 1, 152064, 0xc9bbf5e7
-0, 206, 206, 1, 152064, 0x0aa1b69b
-0, 208, 208, 1, 152064, 0x85b9ac11
-0, 210, 210, 1, 152064, 0xb25ff818
-0, 212, 212, 1, 152064, 0xa155dc25
-0, 214, 214, 1, 152064, 0xa8e03bfd
-0, 216, 216, 1, 152064, 0x0a862956
-0, 218, 218, 1, 152064, 0x11b49264
-0, 220, 220, 1, 152064, 0xa94e664e
-0, 222, 222, 1, 152064, 0x330e0fa2
-0, 224, 224, 1, 152064, 0xaf3d9518
-0, 226, 226, 1, 152064, 0x0836f2e8
-0, 228, 228, 1, 152064, 0xbf6dc578
-0, 230, 230, 1, 152064, 0x7b524d20
-0, 232, 232, 1, 152064, 0x9ef7677f
-0, 234, 234, 1, 152064, 0xeacf3f34
-0, 236, 236, 1, 152064, 0xfb4e3dbe
-0, 238, 238, 1, 152064, 0xb46e25cb
-0, 240, 240, 1, 152064, 0x363c1603
-0, 242, 242, 1, 152064, 0x263fc542
-0, 244, 244, 1, 152064, 0xf106e548
-0, 246, 246, 1, 152064, 0xde43c56a
-0, 248, 248, 1, 152064, 0xc2c4770a
-0, 250, 250, 1, 152064, 0x122fce19
-0, 252, 252, 1, 152064, 0x3ba01434
-0, 254, 254, 1, 152064, 0x0e8ce5ee
-0, 256, 256, 1, 152064, 0x6ceb82e1
-0, 258, 258, 1, 152064, 0xa23ee21c
-0, 260, 260, 1, 152064, 0xc6d960f9
-0, 262, 262, 1, 152064, 0x0de15258
-0, 264, 264, 1, 152064, 0x187b0333
-0, 266, 266, 1, 152064, 0x92e6582f
-0, 268, 268, 1, 152064, 0xb9586ce0
-0, 270, 270, 1, 152064, 0xefd803b5
-0, 272, 272, 1, 152064, 0x24eafb29
-0, 274, 274, 1, 152064, 0x20c73b14
-0, 276, 276, 1, 152064, 0xbd7ceaaa
-0, 278, 278, 1, 152064, 0x775216c8
-0, 280, 280, 1, 152064, 0xa08971c7
-0, 282, 282, 1, 152064, 0xef0ee865
-0, 284, 284, 1, 152064, 0x9ac61c2f
-0, 286, 286, 1, 152064, 0x52ae8ea9
-0, 288, 288, 1, 152064, 0x06571c14
-0, 290, 290, 1, 152064, 0x6e78ad33
-0, 292, 292, 1, 152064, 0xad01c627
-0, 294, 294, 1, 152064, 0xbfe074d3
-0, 296, 296, 1, 152064, 0x9357a183
-0, 298, 298, 1, 152064, 0x8de7767f
-0, 300, 300, 1, 152064, 0xa5e6e76e
-0, 302, 302, 1, 152064, 0xa6f646fe
-0, 304, 304, 1, 152064, 0x132e99f8
-0, 306, 306, 1, 152064, 0xb79f27de
-0, 308, 308, 1, 152064, 0x36d3cdcf
-0, 310, 310, 1, 152064, 0xdc938336
-0, 312, 312, 1, 152064, 0xacaa3a7f
-0, 314, 314, 1, 152064, 0xc61a37fd
-0, 316, 316, 1, 152064, 0x4fe1ddf0
-0, 318, 318, 1, 152064, 0xc0f7d660
-0, 320, 320, 1, 152064, 0xd72458ea
-0, 322, 322, 1, 152064, 0x6978d123
-0, 324, 324, 1, 152064, 0x64e60ccf
-0, 326, 326, 1, 152064, 0xaa07004c
-0, 328, 328, 1, 152064, 0x07cd1064
-0, 330, 330, 1, 152064, 0xa82320e5
-0, 332, 332, 1, 152064, 0xaedd8d30
-0, 334, 334, 1, 152064, 0x79b082ea
-0, 336, 336, 1, 152064, 0x9ed800ab
-0, 338, 338, 1, 152064, 0xde592bb4
-0, 340, 340, 1, 152064, 0xd966df88
-0, 342, 342, 1, 152064, 0xf921988a
-0, 344, 344, 1, 152064, 0x557ad9ae
-0, 346, 346, 1, 152064, 0xc3f31a9a
-0, 348, 348, 1, 152064, 0x65248561
-0, 350, 350, 1, 152064, 0x63df4aa6
-0, 352, 352, 1, 152064, 0x618da0a9
-0, 354, 354, 1, 152064, 0xe6f1c435
-0, 356, 356, 1, 152064, 0x9f90c38f
-0, 358, 358, 1, 152064, 0xd2853e14
-0, 360, 360, 1, 152064, 0x6e0268a9
-0, 362, 362, 1, 152064, 0x393712d1
-0, 364, 364, 1, 152064, 0x470da25f
-0, 366, 366, 1, 152064, 0xaf55cb3d
-0, 368, 368, 1, 152064, 0x6935b8b9
-0, 370, 370, 1, 152064, 0x5409a15f
-0, 372, 372, 1, 152064, 0x09073fee
-0, 374, 374, 1, 152064, 0xfb274e82
-0, 376, 376, 1, 152064, 0x1a770581
-0, 378, 378, 1, 152064, 0x17277d0d
-0, 380, 380, 1, 152064, 0xd4dcd982
-0, 382, 382, 1, 152064, 0x6b04eaf3
-0, 384, 384, 1, 152064, 0x8a3d822e
-0, 386, 386, 1, 152064, 0x1b971ec9
-0, 388, 388, 1, 152064, 0x14e0c0f6
-0, 390, 390, 1, 152064, 0x00667450
-0, 392, 392, 1, 152064, 0xd2385902
-0, 394, 394, 1, 152064, 0x905da6ab
-0, 396, 396, 1, 152064, 0xa3ffb18b
-0, 398, 398, 1, 152064, 0x10d48b19
-0, 400, 400, 1, 152064, 0xb2c7a3bd
-0, 402, 402, 1, 152064, 0x45593e96
-0, 404, 404, 1, 152064, 0x47a0b60c
-0, 406, 406, 1, 152064, 0x68c6d1b9
-0, 408, 408, 1, 152064, 0xbc881fcc
-0, 410, 410, 1, 152064, 0x422cc6f2
-0, 412, 412, 1, 152064, 0x9b686410
-0, 414, 414, 1, 152064, 0x35dc5e86
-0, 416, 416, 1, 152064, 0x247bedaa
-0, 418, 418, 1, 152064, 0x22b76fd1
-0, 420, 420, 1, 152064, 0x67cc7a75
-0, 422, 422, 1, 152064, 0xa197521e
-0, 424, 424, 1, 152064, 0x428c8662
-0, 426, 426, 1, 152064, 0x33dc2c73
-0, 428, 428, 1, 152064, 0x5b538903
-0, 430, 430, 1, 152064, 0x3c4176b6
-0, 432, 432, 1, 152064, 0x774364ba
-0, 434, 434, 1, 152064, 0xf237d03e
-0, 436, 436, 1, 152064, 0xac8746fb
-0, 438, 438, 1, 152064, 0x6b306a84
-0, 440, 440, 1, 152064, 0xa2ace513
-0, 442, 442, 1, 152064, 0x709c9be7
-0, 444, 444, 1, 152064, 0x2403f373
-0, 446, 446, 1, 152064, 0x147bf717
-0, 448, 448, 1, 152064, 0xe58964c8
-0, 450, 450, 1, 152064, 0xa0da36fc
-0, 452, 452, 1, 152064, 0x1ac1355c
-0, 454, 454, 1, 152064, 0x8a31c9f2
-0, 456, 456, 1, 152064, 0x42ba205c
-0, 458, 458, 1, 152064, 0xa11b3575
-0, 460, 460, 1, 152064, 0xcb35207c
-0, 462, 462, 1, 152064, 0x528f6189
-0, 464, 464, 1, 152064, 0x34f05bd7
-0, 466, 466, 1, 152064, 0x72317356
-0, 468, 468, 1, 152064, 0xaabd5028
-0, 470, 470, 1, 152064, 0x13dbeb7b
-0, 472, 472, 1, 152064, 0x62f1e8a8
-0, 474, 474, 1, 152064, 0x1723bfcd
-0, 476, 476, 1, 152064, 0x5c083c00
-0, 478, 478, 1, 152064, 0x52137894
-0, 480, 480, 1, 152064, 0xef1e082c
-0, 482, 482, 1, 152064, 0x664b3d53
-0, 484, 484, 1, 152064, 0x2eb9b296
-0, 486, 486, 1, 152064, 0xd0ca511e
-0, 488, 488, 1, 152064, 0x012d4724
-0, 490, 490, 1, 152064, 0xa847f5af
-0, 492, 492, 1, 152064, 0x483a2fde
-0, 494, 494, 1, 152064, 0xd1ab0257
-0, 496, 496, 1, 152064, 0x414692c7
-0, 498, 498, 1, 152064, 0x0b79df88
-0, 500, 500, 1, 152064, 0xdaa2c4a3
-0, 502, 502, 1, 152064, 0xd1b44500
-0, 504, 504, 1, 152064, 0xfd3d2cf3
-0, 506, 506, 1, 152064, 0xfdc0f748
-0, 508, 508, 1, 152064, 0xce762a2a
-0, 510, 510, 1, 152064, 0x08b63572
-0, 512, 512, 1, 152064, 0x5a46a38d
-0, 514, 514, 1, 152064, 0x03cee9c0
-0, 516, 516, 1, 152064, 0x9ee45473
-0, 518, 518, 1, 152064, 0x5a432386
-0, 520, 520, 1, 152064, 0x54c83d87
-0, 522, 522, 1, 152064, 0xc9caa1de
-0, 524, 524, 1, 152064, 0xa28367f1
-0, 526, 526, 1, 152064, 0x2607cdf1
-0, 528, 528, 1, 152064, 0x06baa8de
-0, 530, 530, 1, 152064, 0xf5346e32
-0, 532, 532, 1, 152064, 0x6d3e732b
-0, 534, 534, 1, 152064, 0x798c584b
-0, 536, 536, 1, 152064, 0x4076c948
-0, 538, 538, 1, 152064, 0x868cf63a
-0, 540, 540, 1, 152064, 0x23107ac5
-0, 542, 542, 1, 152064, 0x306f3fe2
-0, 544, 544, 1, 152064, 0xbd1d71d6
-0, 546, 546, 1, 152064, 0x1429545f
-0, 548, 548, 1, 152064, 0xaded29aa
-0, 550, 550, 1, 152064, 0x9b455a94
-0, 552, 552, 1, 152064, 0xb3774ce7
-0, 554, 554, 1, 152064, 0x92580986
-0, 556, 556, 1, 152064, 0x0eae2f95
-0, 558, 558, 1, 152064, 0x599208b2
-0, 560, 560, 1, 152064, 0x4804c04c
-0, 562, 562, 1, 152064, 0x5f730e8f
-0, 564, 564, 1, 152064, 0x3e501d1e
-0, 566, 566, 1, 152064, 0x32100740
-0, 568, 568, 1, 152064, 0x62226ff8
-0, 570, 570, 1, 152064, 0x7683b622
-0, 572, 572, 1, 152064, 0xc3e0aec1
-0, 574, 574, 1, 152064, 0xfac12608
-0, 576, 576, 1, 152064, 0xb21a5781
-0, 578, 578, 1, 152064, 0x8f1e4964
-0, 580, 580, 1, 152064, 0x0f62dd6e
-0, 582, 582, 1, 152064, 0xac062ac4
-0, 584, 584, 1, 152064, 0x1b320f7a
-0, 586, 586, 1, 152064, 0x346e7211
-0, 588, 588, 1, 152064, 0xe47592f3
-0, 590, 590, 1, 152064, 0xa3a7919c
-0, 592, 592, 1, 152064, 0xa3580fa6
-0, 594, 594, 1, 152064, 0xc73430c1
-0, 596, 596, 1, 152064, 0x994a2c18
-0, 598, 598, 1, 152064, 0x0b5d8d45
-0, 599, 599, 1, 152064, 0x9eed5109
+0, 0, 0, 1, 152064, 0x3e39c08b
+0, 1, 1, 1, 152064, 0xabc67990
+0, 2, 2, 1, 152064, 0x19614e74
+0, 3, 3, 1, 152064, 0xa3776beb
+0, 4, 4, 1, 152064, 0xcce6ffdf
+0, 5, 5, 1, 152064, 0xb0e94746
+0, 6, 6, 1, 152064, 0xdb1a84ef
+0, 7, 7, 1, 152064, 0xb2624509
+0, 8, 8, 1, 152064, 0x32e2d826
+0, 9, 9, 1, 152064, 0xb3bddf0b
+0, 10, 10, 1, 152064, 0x2e273ce3
+0, 11, 11, 1, 152064, 0x67af7e4d
+0, 12, 12, 1, 152064, 0x505c3261
+0, 13, 13, 1, 152064, 0xa43d015e
+0, 14, 14, 1, 152064, 0xad41c1f6
+0, 15, 15, 1, 152064, 0x633ba55f
+0, 16, 16, 1, 152064, 0xe80634f0
+0, 17, 17, 1, 152064, 0x80a07dc9
+0, 18, 18, 1, 152064, 0x0e7a3bbf
+0, 19, 19, 1, 152064, 0xcb099196
+0, 20, 20, 1, 152064, 0x57c96db5
+0, 21, 21, 1, 152064, 0xccd422fa
+0, 22, 22, 1, 152064, 0x0850b7a7
+0, 23, 23, 1, 152064, 0x30e33156
+0, 24, 24, 1, 152064, 0x34e13f9a
+0, 25, 25, 1, 152064, 0x03d36000
+0, 26, 26, 1, 152064, 0xbf7d49da
+0, 27, 27, 1, 152064, 0x77336d09
+0, 28, 28, 1, 152064, 0xca8be5a9
+0, 29, 29, 1, 152064, 0xe57c0b08
+0, 30, 30, 1, 152064, 0xbe77c093
+0, 31, 31, 1, 152064, 0x6bf1ff05
+0, 32, 32, 1, 152064, 0x9142babf
+0, 33, 33, 1, 152064, 0x08db8e67
+0, 34, 34, 1, 152064, 0x69ac8cb6
+0, 35, 35, 1, 152064, 0xaa3b5c88
+0, 36, 36, 1, 152064, 0x9bd32638
+0, 37, 37, 1, 152064, 0x7972115a
+0, 38, 38, 1, 152064, 0x5c1dd47b
+0, 39, 39, 1, 152064, 0x8a196e02
+0, 40, 40, 1, 152064, 0xa89672bc
+0, 41, 41, 1, 152064, 0x27b220e4
+0, 42, 42, 1, 152064, 0xfa38dc4a
+0, 43, 43, 1, 152064, 0x4784c639
+0, 44, 44, 1, 152064, 0xa5e4229a
+0, 45, 45, 1, 152064, 0xa986bdfc
+0, 46, 46, 1, 152064, 0x2951b47b
+0, 47, 47, 1, 152064, 0x4df404a6
+0, 48, 48, 1, 152064, 0xc75155e8
+0, 49, 49, 1, 152064, 0xfc05248c
+0, 50, 50, 1, 152064, 0x5d53da10
+0, 51, 51, 1, 152064, 0x284376ec
+0, 52, 52, 1, 152064, 0x19fce380
+0, 53, 53, 1, 152064, 0x876be6c9
+0, 54, 54, 1, 152064, 0x39eb8ff9
+0, 55, 55, 1, 152064, 0x289c9543
+0, 56, 56, 1, 152064, 0x24dd2356
+0, 57, 57, 1, 152064, 0x1dc17d3c
+0, 58, 58, 1, 152064, 0xd17c00ac
+0, 59, 59, 1, 152064, 0xc2ad54de
+0, 60, 60, 1, 152064, 0xbe11ee2f
+0, 61, 61, 1, 152064, 0x3db9dc89
+0, 62, 62, 1, 152064, 0xac0d7bc2
+0, 63, 63, 1, 152064, 0x8dab2dde
+0, 64, 64, 1, 152064, 0x566ad225
+0, 65, 65, 1, 152064, 0x587c7853
+0, 66, 66, 1, 152064, 0x601c9c80
+0, 67, 67, 1, 152064, 0x2afaf751
+0, 68, 68, 1, 152064, 0x1c9f7e3a
+0, 69, 69, 1, 152064, 0x899475bf
+0, 70, 70, 1, 152064, 0x0d65c7d9
+0, 71, 71, 1, 152064, 0xafd63d12
+0, 72, 72, 1, 152064, 0x162e62b9
+0, 73, 73, 1, 152064, 0x5c9554be
+0, 74, 74, 1, 152064, 0x35fbdaa2
+0, 75, 75, 1, 152064, 0x6438cbd8
+0, 76, 76, 1, 152064, 0xde0772c9
+0, 77, 77, 1, 152064, 0x79f82854
+0, 78, 78, 1, 152064, 0x86957840
+0, 79, 79, 1, 152064, 0xd9468cbf
+0, 80, 80, 1, 152064, 0x23e74609
+0, 81, 81, 1, 152064, 0x3919a146
+0, 82, 82, 1, 152064, 0xd641078b
+0, 83, 83, 1, 152064, 0x24397220
+0, 84, 84, 1, 152064, 0xe7fc3a7c
+0, 85, 85, 1, 152064, 0x3997154a
+0, 86, 86, 1, 152064, 0x2af3952c
+0, 87, 87, 1, 152064, 0x274ac07a
+0, 88, 88, 1, 152064, 0x288f7b09
+0, 89, 89, 1, 152064, 0xe6f9b022
+0, 90, 90, 1, 152064, 0xf09e2fbb
+0, 91, 91, 1, 152064, 0x7244e477
+0, 92, 92, 1, 152064, 0x0dfc72eb
+0, 93, 93, 1, 152064, 0x0322b21f
+0, 94, 94, 1, 152064, 0x18b08205
+0, 95, 95, 1, 152064, 0x6606153e
+0, 96, 96, 1, 152064, 0x85186272
+0, 97, 97, 1, 152064, 0x3369f064
+0, 98, 98, 1, 152064, 0xbe0d5a44
+0, 99, 99, 1, 152064, 0x320258bb
+0, 100, 100, 1, 152064, 0x4d6fb091
+0, 101, 101, 1, 152064, 0xc9bbf5e7
+0, 102, 102, 1, 152064, 0x0aa1b69b
+0, 103, 103, 1, 152064, 0x85b9ac11
+0, 104, 104, 1, 152064, 0xb25ff818
+0, 105, 105, 1, 152064, 0xa155dc25
+0, 106, 106, 1, 152064, 0xa8e03bfd
+0, 107, 107, 1, 152064, 0x0a862956
+0, 108, 108, 1, 152064, 0x11b49264
+0, 109, 109, 1, 152064, 0xa94e664e
+0, 110, 110, 1, 152064, 0x330e0fa2
+0, 111, 111, 1, 152064, 0xaf3d9518
+0, 112, 112, 1, 152064, 0x0836f2e8
+0, 113, 113, 1, 152064, 0xbf6dc578
+0, 114, 114, 1, 152064, 0x7b524d20
+0, 115, 115, 1, 152064, 0x9ef7677f
+0, 116, 116, 1, 152064, 0xeacf3f34
+0, 117, 117, 1, 152064, 0xfb4e3dbe
+0, 118, 118, 1, 152064, 0xb46e25cb
+0, 119, 119, 1, 152064, 0x363c1603
+0, 120, 120, 1, 152064, 0x263fc542
+0, 121, 121, 1, 152064, 0xf106e548
+0, 122, 122, 1, 152064, 0xde43c56a
+0, 123, 123, 1, 152064, 0xc2c4770a
+0, 124, 124, 1, 152064, 0x122fce19
+0, 125, 125, 1, 152064, 0x3ba01434
+0, 126, 126, 1, 152064, 0x0e8ce5ee
+0, 127, 127, 1, 152064, 0x6ceb82e1
+0, 128, 128, 1, 152064, 0xa23ee21c
+0, 129, 129, 1, 152064, 0xc6d960f9
+0, 130, 130, 1, 152064, 0x0de15258
+0, 131, 131, 1, 152064, 0x187b0333
+0, 132, 132, 1, 152064, 0x92e6582f
+0, 133, 133, 1, 152064, 0xb9586ce0
+0, 134, 134, 1, 152064, 0xefd803b5
+0, 135, 135, 1, 152064, 0x24eafb29
+0, 136, 136, 1, 152064, 0x20c73b14
+0, 137, 137, 1, 152064, 0xbd7ceaaa
+0, 138, 138, 1, 152064, 0x775216c8
+0, 139, 139, 1, 152064, 0xa08971c7
+0, 140, 140, 1, 152064, 0xef0ee865
+0, 141, 141, 1, 152064, 0x9ac61c2f
+0, 142, 142, 1, 152064, 0x52ae8ea9
+0, 143, 143, 1, 152064, 0x06571c14
+0, 144, 144, 1, 152064, 0x6e78ad33
+0, 145, 145, 1, 152064, 0xad01c627
+0, 146, 146, 1, 152064, 0xbfe074d3
+0, 147, 147, 1, 152064, 0x9357a183
+0, 148, 148, 1, 152064, 0x8de7767f
+0, 149, 149, 1, 152064, 0xa5e6e76e
+0, 150, 150, 1, 152064, 0xa6f646fe
+0, 151, 151, 1, 152064, 0x132e99f8
+0, 152, 152, 1, 152064, 0xb79f27de
+0, 153, 153, 1, 152064, 0x36d3cdcf
+0, 154, 154, 1, 152064, 0xdc938336
+0, 155, 155, 1, 152064, 0xacaa3a7f
+0, 156, 156, 1, 152064, 0xc61a37fd
+0, 157, 157, 1, 152064, 0x4fe1ddf0
+0, 158, 158, 1, 152064, 0xc0f7d660
+0, 159, 159, 1, 152064, 0xd72458ea
+0, 160, 160, 1, 152064, 0x6978d123
+0, 161, 161, 1, 152064, 0x64e60ccf
+0, 162, 162, 1, 152064, 0xaa07004c
+0, 163, 163, 1, 152064, 0x07cd1064
+0, 164, 164, 1, 152064, 0xa82320e5
+0, 165, 165, 1, 152064, 0xaedd8d30
+0, 166, 166, 1, 152064, 0x79b082ea
+0, 167, 167, 1, 152064, 0x9ed800ab
+0, 168, 168, 1, 152064, 0xde592bb4
+0, 169, 169, 1, 152064, 0xd966df88
+0, 170, 170, 1, 152064, 0xf921988a
+0, 171, 171, 1, 152064, 0x557ad9ae
+0, 172, 172, 1, 152064, 0xc3f31a9a
+0, 173, 173, 1, 152064, 0x65248561
+0, 174, 174, 1, 152064, 0x63df4aa6
+0, 175, 175, 1, 152064, 0x618da0a9
+0, 176, 176, 1, 152064, 0xe6f1c435
+0, 177, 177, 1, 152064, 0x9f90c38f
+0, 178, 178, 1, 152064, 0xd2853e14
+0, 179, 179, 1, 152064, 0x6e0268a9
+0, 180, 180, 1, 152064, 0x393712d1
+0, 181, 181, 1, 152064, 0x470da25f
+0, 182, 182, 1, 152064, 0xaf55cb3d
+0, 183, 183, 1, 152064, 0x6935b8b9
+0, 184, 184, 1, 152064, 0x5409a15f
+0, 185, 185, 1, 152064, 0x09073fee
+0, 186, 186, 1, 152064, 0xfb274e82
+0, 187, 187, 1, 152064, 0x1a770581
+0, 188, 188, 1, 152064, 0x17277d0d
+0, 189, 189, 1, 152064, 0xd4dcd982
+0, 190, 190, 1, 152064, 0x6b04eaf3
+0, 191, 191, 1, 152064, 0x8a3d822e
+0, 192, 192, 1, 152064, 0x1b971ec9
+0, 193, 193, 1, 152064, 0x14e0c0f6
+0, 194, 194, 1, 152064, 0x00667450
+0, 195, 195, 1, 152064, 0xd2385902
+0, 196, 196, 1, 152064, 0x905da6ab
+0, 197, 197, 1, 152064, 0xa3ffb18b
+0, 198, 198, 1, 152064, 0x10d48b19
+0, 199, 199, 1, 152064, 0xb2c7a3bd
+0, 200, 200, 1, 152064, 0x45593e96
+0, 201, 201, 1, 152064, 0x47a0b60c
+0, 202, 202, 1, 152064, 0x68c6d1b9
+0, 203, 203, 1, 152064, 0xbc881fcc
+0, 204, 204, 1, 152064, 0x422cc6f2
+0, 205, 205, 1, 152064, 0x9b686410
+0, 206, 206, 1, 152064, 0x35dc5e86
+0, 207, 207, 1, 152064, 0x247bedaa
+0, 208, 208, 1, 152064, 0x22b76fd1
+0, 209, 209, 1, 152064, 0x67cc7a75
+0, 210, 210, 1, 152064, 0xa197521e
+0, 211, 211, 1, 152064, 0x428c8662
+0, 212, 212, 1, 152064, 0x33dc2c73
+0, 213, 213, 1, 152064, 0x5b538903
+0, 214, 214, 1, 152064, 0x3c4176b6
+0, 215, 215, 1, 152064, 0x774364ba
+0, 216, 216, 1, 152064, 0xf237d03e
+0, 217, 217, 1, 152064, 0xac8746fb
+0, 218, 218, 1, 152064, 0x6b306a84
+0, 219, 219, 1, 152064, 0xa2ace513
+0, 220, 220, 1, 152064, 0x709c9be7
+0, 221, 221, 1, 152064, 0x2403f373
+0, 222, 222, 1, 152064, 0x147bf717
+0, 223, 223, 1, 152064, 0xe58964c8
+0, 224, 224, 1, 152064, 0xa0da36fc
+0, 225, 225, 1, 152064, 0x1ac1355c
+0, 226, 226, 1, 152064, 0x8a31c9f2
+0, 227, 227, 1, 152064, 0x42ba205c
+0, 228, 228, 1, 152064, 0xa11b3575
+0, 229, 229, 1, 152064, 0xcb35207c
+0, 230, 230, 1, 152064, 0x528f6189
+0, 231, 231, 1, 152064, 0x34f05bd7
+0, 232, 232, 1, 152064, 0x72317356
+0, 233, 233, 1, 152064, 0xaabd5028
+0, 234, 234, 1, 152064, 0x13dbeb7b
+0, 235, 235, 1, 152064, 0x62f1e8a8
+0, 236, 236, 1, 152064, 0x1723bfcd
+0, 237, 237, 1, 152064, 0x5c083c00
+0, 238, 238, 1, 152064, 0x52137894
+0, 239, 239, 1, 152064, 0xef1e082c
+0, 240, 240, 1, 152064, 0x664b3d53
+0, 241, 241, 1, 152064, 0x2eb9b296
+0, 242, 242, 1, 152064, 0xd0ca511e
+0, 243, 243, 1, 152064, 0x012d4724
+0, 244, 244, 1, 152064, 0xa847f5af
+0, 245, 245, 1, 152064, 0x483a2fde
+0, 246, 246, 1, 152064, 0xd1ab0257
+0, 247, 247, 1, 152064, 0x414692c7
+0, 248, 248, 1, 152064, 0x0b79df88
+0, 249, 249, 1, 152064, 0xdaa2c4a3
+0, 250, 250, 1, 152064, 0xd1b44500
+0, 251, 251, 1, 152064, 0xfd3d2cf3
+0, 252, 252, 1, 152064, 0xfdc0f748
+0, 253, 253, 1, 152064, 0xce762a2a
+0, 254, 254, 1, 152064, 0x08b63572
+0, 255, 255, 1, 152064, 0x5a46a38d
+0, 256, 256, 1, 152064, 0x03cee9c0
+0, 257, 257, 1, 152064, 0x9ee45473
+0, 258, 258, 1, 152064, 0x5a432386
+0, 259, 259, 1, 152064, 0x54c83d87
+0, 260, 260, 1, 152064, 0xc9caa1de
+0, 261, 261, 1, 152064, 0xa28367f1
+0, 262, 262, 1, 152064, 0x2607cdf1
+0, 263, 263, 1, 152064, 0x06baa8de
+0, 264, 264, 1, 152064, 0xf5346e32
+0, 265, 265, 1, 152064, 0x6d3e732b
+0, 266, 266, 1, 152064, 0x798c584b
+0, 267, 267, 1, 152064, 0x4076c948
+0, 268, 268, 1, 152064, 0x868cf63a
+0, 269, 269, 1, 152064, 0x23107ac5
+0, 270, 270, 1, 152064, 0x306f3fe2
+0, 271, 271, 1, 152064, 0xbd1d71d6
+0, 272, 272, 1, 152064, 0x1429545f
+0, 273, 273, 1, 152064, 0xaded29aa
+0, 274, 274, 1, 152064, 0x9b455a94
+0, 275, 275, 1, 152064, 0xb3774ce7
+0, 276, 276, 1, 152064, 0x92580986
+0, 277, 277, 1, 152064, 0x0eae2f95
+0, 278, 278, 1, 152064, 0x599208b2
+0, 279, 279, 1, 152064, 0x4804c04c
+0, 280, 280, 1, 152064, 0x5f730e8f
+0, 281, 281, 1, 152064, 0x3e501d1e
+0, 282, 282, 1, 152064, 0x32100740
+0, 283, 283, 1, 152064, 0x62226ff8
+0, 284, 284, 1, 152064, 0x7683b622
+0, 285, 285, 1, 152064, 0xc3e0aec1
+0, 286, 286, 1, 152064, 0xfac12608
+0, 287, 287, 1, 152064, 0xb21a5781
+0, 288, 288, 1, 152064, 0x8f1e4964
+0, 289, 289, 1, 152064, 0x0f62dd6e
+0, 290, 290, 1, 152064, 0xac062ac4
+0, 291, 291, 1, 152064, 0x1b320f7a
+0, 292, 292, 1, 152064, 0x346e7211
+0, 293, 293, 1, 152064, 0xe47592f3
+0, 294, 294, 1, 152064, 0xa3a7919c
+0, 295, 295, 1, 152064, 0xa3580fa6
+0, 296, 296, 1, 152064, 0xc73430c1
+0, 297, 297, 1, 152064, 0x994a2c18
+0, 298, 298, 1, 152064, 0x0b5d8d45
+0, 299, 299, 1, 152064, 0x9eed5109
diff --git a/tests/ref/fate/h264-conformance-frext-hpcamapalq_bcrm_b b/tests/ref/fate/h264-conformance-frext-hpcamapalq_bcrm_b
index 494fafa..a81e91f 100644
--- a/tests/ref/fate/h264-conformance-frext-hpcamapalq_bcrm_b
+++ b/tests/ref/fate/h264-conformance-frext-hpcamapalq_bcrm_b
@@ -1,301 +1,301 @@
#tb 0: 1/25
-0, 1, 1, 1, 152064, 0xf8248ceb
-0, 3, 3, 1, 152064, 0xb6204c81
-0, 4, 4, 1, 152064, 0x22fb1737
-0, 5, 5, 1, 152064, 0xce8c3fd7
-0, 7, 7, 1, 152064, 0xee88cedc
-0, 8, 8, 1, 152064, 0x1d4209ca
-0, 10, 10, 1, 152064, 0x6fb15238
-0, 12, 12, 1, 152064, 0x505200c2
-0, 13, 13, 1, 152064, 0xb73574ba
-0, 14, 14, 1, 152064, 0x0586a097
-0, 16, 16, 1, 152064, 0xed50fe02
-0, 17, 17, 1, 152064, 0x222221ab
-0, 18, 18, 1, 152064, 0x8afefd46
-0, 20, 20, 1, 152064, 0x6832c5cc
-0, 22, 22, 1, 152064, 0xba4c8110
-0, 23, 23, 1, 152064, 0x95c07e1e
-0, 24, 24, 1, 152064, 0xc5d6fde9
-0, 26, 26, 1, 152064, 0xe75a4921
-0, 28, 28, 1, 152064, 0x53b61688
-0, 29, 29, 1, 152064, 0x0335424b
-0, 31, 31, 1, 152064, 0x621742c7
-0, 33, 33, 1, 152064, 0x4f69f41b
-0, 34, 34, 1, 152064, 0x6b3f65d7
-0, 36, 36, 1, 152064, 0x8dfde04f
-0, 37, 37, 1, 152064, 0x30750ff5
-0, 39, 39, 1, 152064, 0xe3d70f3c
-0, 40, 40, 1, 152064, 0x0c1af825
-0, 42, 42, 1, 152064, 0x58a53935
-0, 43, 43, 1, 152064, 0xc63d9e98
-0, 45, 45, 1, 152064, 0xa85fdc48
-0, 46, 46, 1, 152064, 0x01bb9784
-0, 48, 48, 1, 152064, 0xdd5cb509
-0, 49, 49, 1, 152064, 0x29ae7d2b
-0, 51, 51, 1, 152064, 0xdb08593e
-0, 53, 53, 1, 152064, 0x372d5d4e
-0, 55, 55, 1, 152064, 0x31522664
-0, 57, 57, 1, 152064, 0x3f13f335
-0, 58, 58, 1, 152064, 0xfd10c19a
-0, 60, 60, 1, 152064, 0xef728975
-0, 62, 62, 1, 152064, 0x8e79234d
-0, 64, 64, 1, 152064, 0x47022791
-0, 65, 65, 1, 152064, 0x1ef9d297
-0, 66, 66, 1, 152064, 0x77bf9738
-0, 67, 67, 1, 152064, 0xd6bc8f03
-0, 69, 69, 1, 152064, 0x283ded4a
-0, 71, 71, 1, 152064, 0xd87098d1
-0, 72, 72, 1, 152064, 0x300077a2
-0, 73, 73, 1, 152064, 0x30ffbea4
-0, 75, 75, 1, 152064, 0x5dc5356b
-0, 76, 76, 1, 152064, 0x31cce185
-0, 77, 77, 1, 152064, 0x47fc9148
-0, 79, 79, 1, 152064, 0x1641491e
-0, 80, 80, 1, 152064, 0x2184937d
-0, 82, 82, 1, 152064, 0x126eb74a
-0, 83, 83, 1, 152064, 0x25c07593
-0, 84, 84, 1, 152064, 0xb1294e7e
-0, 86, 86, 1, 152064, 0x8b35f45d
-0, 88, 88, 1, 152064, 0x54765025
-0, 89, 89, 1, 152064, 0x1d17e901
-0, 91, 91, 1, 152064, 0xaeab358d
-0, 93, 93, 1, 152064, 0xf682c91f
-0, 94, 94, 1, 152064, 0x0b4c9b06
-0, 95, 95, 1, 152064, 0x45f326dc
-0, 97, 97, 1, 152064, 0x132eeda3
-0, 98, 98, 1, 152064, 0x3c9b8e16
-0, 99, 99, 1, 152064, 0x1be133c1
-0, 100, 100, 1, 152064, 0xfa876720
-0, 102, 102, 1, 152064, 0x1666cdb8
-0, 103, 103, 1, 152064, 0x362f418f
-0, 104, 104, 1, 152064, 0x926b4a96
-0, 105, 105, 1, 152064, 0xee3da1df
-0, 107, 107, 1, 152064, 0xc11f025d
-0, 108, 108, 1, 152064, 0x9ba62c19
-0, 109, 109, 1, 152064, 0x0d66194f
-0, 110, 110, 1, 152064, 0x2fd09340
-0, 111, 111, 1, 152064, 0x3dfb9e4d
-0, 112, 112, 1, 152064, 0xa3192ce6
-0, 113, 113, 1, 152064, 0x6bfce0e1
-0, 114, 114, 1, 152064, 0x3b7c5286
-0, 116, 116, 1, 152064, 0xb52f4bf5
-0, 118, 118, 1, 152064, 0x30870027
-0, 119, 119, 1, 152064, 0x6f8e71c3
-0, 120, 120, 1, 152064, 0x8d41b09a
-0, 121, 121, 1, 152064, 0xc1ff1d05
-0, 122, 122, 1, 152064, 0xca54125c
-0, 123, 123, 1, 152064, 0x3342d823
-0, 125, 125, 1, 152064, 0xcc4a7542
-0, 127, 127, 1, 152064, 0x21fc9a9d
-0, 128, 128, 1, 152064, 0x91587574
-0, 129, 129, 1, 152064, 0x30929cc2
-0, 130, 130, 1, 152064, 0xf07606b7
-0, 132, 132, 1, 152064, 0x0476b876
-0, 134, 134, 1, 152064, 0x213333dc
-0, 135, 135, 1, 152064, 0x87c67597
-0, 137, 137, 1, 152064, 0x05434641
-0, 139, 139, 1, 152064, 0x959eeffc
-0, 140, 140, 1, 152064, 0x92a130b4
-0, 142, 142, 1, 152064, 0x53d0b544
-0, 144, 144, 1, 152064, 0xaf8c233e
-0, 146, 146, 1, 152064, 0xd3d4259a
-0, 148, 148, 1, 152064, 0xa0287753
-0, 149, 149, 1, 152064, 0xfa23972a
-0, 150, 150, 1, 152064, 0xacae756d
-0, 152, 152, 1, 152064, 0xd8b58b5c
-0, 153, 153, 1, 152064, 0x7db2c755
-0, 155, 155, 1, 152064, 0x31e7b79a
-0, 157, 157, 1, 152064, 0xd8660d98
-0, 158, 158, 1, 152064, 0xdcf0d10d
-0, 159, 159, 1, 152064, 0x3e6567e6
-0, 161, 161, 1, 152064, 0xec3530fd
-0, 162, 162, 1, 152064, 0xf686c61a
-0, 163, 163, 1, 152064, 0x6e706804
-0, 165, 165, 1, 152064, 0x5fd4a1a3
-0, 167, 167, 1, 152064, 0xbb3384f7
-0, 168, 168, 1, 152064, 0x8ffb14dd
-0, 170, 170, 1, 152064, 0x01253a73
-0, 172, 172, 1, 152064, 0xf89c15df
-0, 173, 173, 1, 152064, 0xda2b0b4c
-0, 175, 175, 1, 152064, 0xfc9dfcc1
-0, 177, 177, 1, 152064, 0xfef4f0fa
-0, 178, 178, 1, 152064, 0x91669bea
-0, 180, 180, 1, 152064, 0x3664a565
-0, 181, 181, 1, 152064, 0x32dd7923
-0, 182, 182, 1, 152064, 0x26825231
-0, 183, 183, 1, 152064, 0x5f81896e
-0, 185, 185, 1, 152064, 0x0c64ca2f
-0, 186, 186, 1, 152064, 0x488bb665
-0, 188, 188, 1, 152064, 0x4d183a0f
-0, 189, 189, 1, 152064, 0xed169321
-0, 190, 190, 1, 152064, 0xcec22917
-0, 191, 191, 1, 152064, 0xbe04ea6c
-0, 193, 193, 1, 152064, 0x32b8bf9f
-0, 195, 195, 1, 152064, 0x9c7c2e13
-0, 197, 197, 1, 152064, 0x232e3016
-0, 199, 199, 1, 152064, 0x1b76c08e
-0, 201, 201, 1, 152064, 0x7425d821
-0, 202, 202, 1, 152064, 0x0818ff3c
-0, 203, 203, 1, 152064, 0xb4f2c42b
-0, 204, 204, 1, 152064, 0xe029f979
-0, 206, 206, 1, 152064, 0x97c54c2f
-0, 208, 208, 1, 152064, 0xd101c3b5
-0, 209, 209, 1, 152064, 0x5ed1f5d4
-0, 211, 211, 1, 152064, 0xc28264d1
-0, 212, 212, 1, 152064, 0xa162dd31
-0, 213, 213, 1, 152064, 0x2ee872ce
-0, 215, 215, 1, 152064, 0x809a8fce
-0, 216, 216, 1, 152064, 0xcfcc3ef9
-0, 218, 218, 1, 152064, 0xa5be6ce3
-0, 219, 219, 1, 152064, 0xd75930a0
-0, 221, 221, 1, 152064, 0x28acb80f
-0, 223, 223, 1, 152064, 0x223f2152
-0, 225, 225, 1, 152064, 0x0cf070cb
-0, 226, 226, 1, 152064, 0xcc7d011e
-0, 228, 228, 1, 152064, 0xb2c2a63c
-0, 229, 229, 1, 152064, 0x15514caa
-0, 231, 231, 1, 152064, 0x0c6d18ee
-0, 232, 232, 1, 152064, 0x33b4265d
-0, 233, 233, 1, 152064, 0xb4abaaaf
-0, 235, 235, 1, 152064, 0x26a7a856
-0, 236, 236, 1, 152064, 0xc75249cc
-0, 238, 238, 1, 152064, 0x59ccb0e1
-0, 240, 240, 1, 152064, 0xc613f202
-0, 242, 242, 1, 152064, 0xd1c0e171
-0, 243, 243, 1, 152064, 0xa195da2b
-0, 244, 244, 1, 152064, 0xbc7ed475
-0, 245, 245, 1, 152064, 0x99206e2c
-0, 247, 247, 1, 152064, 0x0ef04e03
-0, 249, 249, 1, 152064, 0x68cbc6a1
-0, 250, 250, 1, 152064, 0x2a5304b1
-0, 251, 251, 1, 152064, 0xf017978b
-0, 252, 252, 1, 152064, 0x94f5641a
-0, 254, 254, 1, 152064, 0xd681bd8f
-0, 255, 255, 1, 152064, 0x16e1e3a3
-0, 257, 257, 1, 152064, 0xe4486c7e
-0, 259, 259, 1, 152064, 0xa1bd394e
-0, 260, 260, 1, 152064, 0x49ad5959
-0, 262, 262, 1, 152064, 0x82219b70
-0, 264, 264, 1, 152064, 0x64e2abcf
-0, 266, 266, 1, 152064, 0x6d7d05d8
-0, 268, 268, 1, 152064, 0xd9ac2251
-0, 269, 269, 1, 152064, 0xf477eee5
-0, 271, 271, 1, 152064, 0xb9826a78
-0, 272, 272, 1, 152064, 0x97828a37
-0, 274, 274, 1, 152064, 0x12099b1f
-0, 275, 275, 1, 152064, 0x1ec45fa7
-0, 277, 277, 1, 152064, 0xfd5501c9
-0, 278, 278, 1, 152064, 0x6a8b26a3
-0, 280, 280, 1, 152064, 0xae58ff40
-0, 282, 282, 1, 152064, 0xc0f47aa1
-0, 283, 283, 1, 152064, 0x08bfa548
-0, 284, 284, 1, 152064, 0x7f2ff5ef
-0, 286, 286, 1, 152064, 0x5efa94a3
-0, 288, 288, 1, 152064, 0xf786f970
-0, 290, 290, 1, 152064, 0xab6bc712
-0, 291, 291, 1, 152064, 0x25647bee
-0, 293, 293, 1, 152064, 0x54333ad5
-0, 295, 295, 1, 152064, 0xb3a99413
-0, 296, 296, 1, 152064, 0xe7a78a0d
-0, 298, 298, 1, 152064, 0xa5054abc
-0, 300, 300, 1, 152064, 0xb94896ea
-0, 301, 301, 1, 152064, 0x9f641bca
-0, 303, 303, 1, 152064, 0x7363901c
-0, 304, 304, 1, 152064, 0xd340a000
-0, 305, 305, 1, 152064, 0x0217f413
-0, 306, 306, 1, 152064, 0xbbdba6e6
-0, 307, 307, 1, 152064, 0xabc42617
-0, 309, 309, 1, 152064, 0xa3442925
-0, 311, 311, 1, 152064, 0x7d06c7e9
-0, 312, 312, 1, 152064, 0xa45e32df
-0, 313, 313, 1, 152064, 0xf5ed407f
-0, 315, 315, 1, 152064, 0x5ec235d5
-0, 317, 317, 1, 152064, 0xa5706635
-0, 319, 319, 1, 152064, 0xa44a209b
-0, 321, 321, 1, 152064, 0xf2137e37
-0, 323, 323, 1, 152064, 0x5220508f
-0, 324, 324, 1, 152064, 0xae6b37da
-0, 326, 326, 1, 152064, 0xdf09b6cd
-0, 327, 327, 1, 152064, 0x2d39e1c0
-0, 329, 329, 1, 152064, 0xc8284a76
-0, 331, 331, 1, 152064, 0x7d7bbe76
-0, 332, 332, 1, 152064, 0xcfed7416
-0, 333, 333, 1, 152064, 0x81caaedd
-0, 334, 334, 1, 152064, 0x9dcdd771
-0, 336, 336, 1, 152064, 0x46c1331b
-0, 338, 338, 1, 152064, 0xace60efa
-0, 339, 339, 1, 152064, 0x9e0909f7
-0, 341, 341, 1, 152064, 0x72f5a321
-0, 342, 342, 1, 152064, 0x68f8cdcc
-0, 343, 343, 1, 152064, 0xcc59fdd9
-0, 345, 345, 1, 152064, 0xc0a700c6
-0, 347, 347, 1, 152064, 0xf4254dcf
-0, 348, 348, 1, 152064, 0xc59b46d1
-0, 350, 350, 1, 152064, 0x2e5b2524
-0, 352, 352, 1, 152064, 0x46051293
-0, 353, 353, 1, 152064, 0x3cbcd1cd
-0, 354, 354, 1, 152064, 0x9f308587
-0, 356, 356, 1, 152064, 0x6b91633f
-0, 357, 357, 1, 152064, 0xb7191012
-0, 359, 359, 1, 152064, 0xd2fd030f
-0, 361, 361, 1, 152064, 0x15a0ae2e
-0, 363, 363, 1, 152064, 0xac3920d0
-0, 364, 364, 1, 152064, 0x0eef80aa
-0, 365, 365, 1, 152064, 0x319008f1
-0, 367, 367, 1, 152064, 0x7734450c
-0, 368, 368, 1, 152064, 0xf112df62
-0, 369, 369, 1, 152064, 0x1dd8ffae
-0, 371, 371, 1, 152064, 0x655ef429
-0, 372, 372, 1, 152064, 0x27026213
-0, 374, 374, 1, 152064, 0x5c14b015
-0, 376, 376, 1, 152064, 0x9512abeb
-0, 378, 378, 1, 152064, 0x961812b2
-0, 379, 379, 1, 152064, 0xb8890aea
-0, 380, 380, 1, 152064, 0x4519db9a
-0, 381, 381, 1, 152064, 0xf358034a
-0, 383, 383, 1, 152064, 0x45d9f2ab
-0, 384, 384, 1, 152064, 0xebd47e7d
-0, 385, 385, 1, 152064, 0x15578be9
-0, 387, 387, 1, 152064, 0x1b373b2d
-0, 388, 388, 1, 152064, 0xbbe707e5
-0, 389, 389, 1, 152064, 0x5bf62385
-0, 391, 391, 1, 152064, 0x832e6ef5
-0, 393, 393, 1, 152064, 0x761e5968
-0, 394, 394, 1, 152064, 0x251f984d
-0, 396, 396, 1, 152064, 0xbda48899
-0, 397, 397, 1, 152064, 0x3fd843b9
-0, 399, 399, 1, 152064, 0x00485425
-0, 401, 401, 1, 152064, 0x4e282b39
-0, 403, 403, 1, 152064, 0x2630a8ea
-0, 405, 405, 1, 152064, 0x5ea5c973
-0, 407, 407, 1, 152064, 0xfc436d21
-0, 409, 409, 1, 152064, 0x69852ef5
-0, 411, 411, 1, 152064, 0x44cb5589
-0, 413, 413, 1, 152064, 0x32f32725
-0, 415, 415, 1, 152064, 0x54d50aca
-0, 417, 417, 1, 152064, 0xe7a639bb
-0, 419, 419, 1, 152064, 0x01be2ad5
-0, 421, 421, 1, 152064, 0x5c63eca4
-0, 423, 423, 1, 152064, 0x94e91116
-0, 424, 424, 1, 152064, 0x9a8be637
-0, 425, 425, 1, 152064, 0x165d9a12
-0, 427, 427, 1, 152064, 0x8c25ca0a
-0, 429, 429, 1, 152064, 0x4ee2ed32
-0, 431, 431, 1, 152064, 0x4b2fe0c6
-0, 433, 433, 1, 152064, 0x521e434e
-0, 435, 435, 1, 152064, 0x97679d7e
-0, 437, 437, 1, 152064, 0x886b9506
-0, 438, 438, 1, 152064, 0x4283eda8
-0, 440, 440, 1, 152064, 0xef793c49
-0, 441, 441, 1, 152064, 0x68ac2afe
-0, 443, 443, 1, 152064, 0x3d1ab510
-0, 444, 444, 1, 152064, 0x98d3ec95
-0, 445, 445, 1, 152064, 0x09f7e512
-0, 447, 447, 1, 152064, 0x801355dd
-0, 449, 449, 1, 152064, 0xf2e87a11
-0, 450, 450, 1, 152064, 0x16757601
-0, 451, 451, 1, 152064, 0x3074d74a
-0, 453, 453, 1, 152064, 0xec8c1290
-0, 455, 455, 1, 152064, 0x46fb1877
-0, 456, 456, 1, 152064, 0xf0b662c4
-0, 457, 457, 1, 152064, 0xf8683940
+0, 0, 0, 1, 152064, 0xf8248ceb
+0, 1, 1, 1, 152064, 0xb6204c81
+0, 2, 2, 1, 152064, 0x22fb1737
+0, 3, 3, 1, 152064, 0xce8c3fd7
+0, 4, 4, 1, 152064, 0xee88cedc
+0, 5, 5, 1, 152064, 0x1d4209ca
+0, 6, 6, 1, 152064, 0x6fb15238
+0, 7, 7, 1, 152064, 0x505200c2
+0, 8, 8, 1, 152064, 0xb73574ba
+0, 9, 9, 1, 152064, 0x0586a097
+0, 10, 10, 1, 152064, 0xed50fe02
+0, 11, 11, 1, 152064, 0x222221ab
+0, 12, 12, 1, 152064, 0x8afefd46
+0, 13, 13, 1, 152064, 0x6832c5cc
+0, 14, 14, 1, 152064, 0xba4c8110
+0, 15, 15, 1, 152064, 0x95c07e1e
+0, 16, 16, 1, 152064, 0xc5d6fde9
+0, 17, 17, 1, 152064, 0xe75a4921
+0, 18, 18, 1, 152064, 0x53b61688
+0, 19, 19, 1, 152064, 0x0335424b
+0, 20, 20, 1, 152064, 0x621742c7
+0, 21, 21, 1, 152064, 0x4f69f41b
+0, 22, 22, 1, 152064, 0x6b3f65d7
+0, 23, 23, 1, 152064, 0x8dfde04f
+0, 24, 24, 1, 152064, 0x30750ff5
+0, 25, 25, 1, 152064, 0xe3d70f3c
+0, 26, 26, 1, 152064, 0x0c1af825
+0, 27, 27, 1, 152064, 0x58a53935
+0, 28, 28, 1, 152064, 0xc63d9e98
+0, 29, 29, 1, 152064, 0xa85fdc48
+0, 30, 30, 1, 152064, 0x01bb9784
+0, 31, 31, 1, 152064, 0xdd5cb509
+0, 32, 32, 1, 152064, 0x29ae7d2b
+0, 33, 33, 1, 152064, 0xdb08593e
+0, 34, 34, 1, 152064, 0x372d5d4e
+0, 35, 35, 1, 152064, 0x31522664
+0, 36, 36, 1, 152064, 0x3f13f335
+0, 37, 37, 1, 152064, 0xfd10c19a
+0, 38, 38, 1, 152064, 0xef728975
+0, 39, 39, 1, 152064, 0x8e79234d
+0, 40, 40, 1, 152064, 0x47022791
+0, 41, 41, 1, 152064, 0x1ef9d297
+0, 42, 42, 1, 152064, 0x77bf9738
+0, 43, 43, 1, 152064, 0xd6bc8f03
+0, 44, 44, 1, 152064, 0x283ded4a
+0, 45, 45, 1, 152064, 0xd87098d1
+0, 46, 46, 1, 152064, 0x300077a2
+0, 47, 47, 1, 152064, 0x30ffbea4
+0, 48, 48, 1, 152064, 0x5dc5356b
+0, 49, 49, 1, 152064, 0x31cce185
+0, 50, 50, 1, 152064, 0x47fc9148
+0, 51, 51, 1, 152064, 0x1641491e
+0, 52, 52, 1, 152064, 0x2184937d
+0, 53, 53, 1, 152064, 0x126eb74a
+0, 54, 54, 1, 152064, 0x25c07593
+0, 55, 55, 1, 152064, 0xb1294e7e
+0, 56, 56, 1, 152064, 0x8b35f45d
+0, 57, 57, 1, 152064, 0x54765025
+0, 58, 58, 1, 152064, 0x1d17e901
+0, 59, 59, 1, 152064, 0xaeab358d
+0, 60, 60, 1, 152064, 0xf682c91f
+0, 61, 61, 1, 152064, 0x0b4c9b06
+0, 62, 62, 1, 152064, 0x45f326dc
+0, 63, 63, 1, 152064, 0x132eeda3
+0, 64, 64, 1, 152064, 0x3c9b8e16
+0, 65, 65, 1, 152064, 0x1be133c1
+0, 66, 66, 1, 152064, 0xfa876720
+0, 67, 67, 1, 152064, 0x1666cdb8
+0, 68, 68, 1, 152064, 0x362f418f
+0, 69, 69, 1, 152064, 0x926b4a96
+0, 70, 70, 1, 152064, 0xee3da1df
+0, 71, 71, 1, 152064, 0xc11f025d
+0, 72, 72, 1, 152064, 0x9ba62c19
+0, 73, 73, 1, 152064, 0x0d66194f
+0, 74, 74, 1, 152064, 0x2fd09340
+0, 75, 75, 1, 152064, 0x3dfb9e4d
+0, 76, 76, 1, 152064, 0xa3192ce6
+0, 77, 77, 1, 152064, 0x6bfce0e1
+0, 78, 78, 1, 152064, 0x3b7c5286
+0, 79, 79, 1, 152064, 0xb52f4bf5
+0, 80, 80, 1, 152064, 0x30870027
+0, 81, 81, 1, 152064, 0x6f8e71c3
+0, 82, 82, 1, 152064, 0x8d41b09a
+0, 83, 83, 1, 152064, 0xc1ff1d05
+0, 84, 84, 1, 152064, 0xca54125c
+0, 85, 85, 1, 152064, 0x3342d823
+0, 86, 86, 1, 152064, 0xcc4a7542
+0, 87, 87, 1, 152064, 0x21fc9a9d
+0, 88, 88, 1, 152064, 0x91587574
+0, 89, 89, 1, 152064, 0x30929cc2
+0, 90, 90, 1, 152064, 0xf07606b7
+0, 91, 91, 1, 152064, 0x0476b876
+0, 92, 92, 1, 152064, 0x213333dc
+0, 93, 93, 1, 152064, 0x87c67597
+0, 94, 94, 1, 152064, 0x05434641
+0, 95, 95, 1, 152064, 0x959eeffc
+0, 96, 96, 1, 152064, 0x92a130b4
+0, 97, 97, 1, 152064, 0x53d0b544
+0, 98, 98, 1, 152064, 0xaf8c233e
+0, 99, 99, 1, 152064, 0xd3d4259a
+0, 100, 100, 1, 152064, 0xa0287753
+0, 101, 101, 1, 152064, 0xfa23972a
+0, 102, 102, 1, 152064, 0xacae756d
+0, 103, 103, 1, 152064, 0xd8b58b5c
+0, 104, 104, 1, 152064, 0x7db2c755
+0, 105, 105, 1, 152064, 0x31e7b79a
+0, 106, 106, 1, 152064, 0xd8660d98
+0, 107, 107, 1, 152064, 0xdcf0d10d
+0, 108, 108, 1, 152064, 0x3e6567e6
+0, 109, 109, 1, 152064, 0xec3530fd
+0, 110, 110, 1, 152064, 0xf686c61a
+0, 111, 111, 1, 152064, 0x6e706804
+0, 112, 112, 1, 152064, 0x5fd4a1a3
+0, 113, 113, 1, 152064, 0xbb3384f7
+0, 114, 114, 1, 152064, 0x8ffb14dd
+0, 115, 115, 1, 152064, 0x01253a73
+0, 116, 116, 1, 152064, 0xf89c15df
+0, 117, 117, 1, 152064, 0xda2b0b4c
+0, 118, 118, 1, 152064, 0xfc9dfcc1
+0, 119, 119, 1, 152064, 0xfef4f0fa
+0, 120, 120, 1, 152064, 0x91669bea
+0, 121, 121, 1, 152064, 0x3664a565
+0, 122, 122, 1, 152064, 0x32dd7923
+0, 123, 123, 1, 152064, 0x26825231
+0, 124, 124, 1, 152064, 0x5f81896e
+0, 125, 125, 1, 152064, 0x0c64ca2f
+0, 126, 126, 1, 152064, 0x488bb665
+0, 127, 127, 1, 152064, 0x4d183a0f
+0, 128, 128, 1, 152064, 0xed169321
+0, 129, 129, 1, 152064, 0xcec22917
+0, 130, 130, 1, 152064, 0xbe04ea6c
+0, 131, 131, 1, 152064, 0x32b8bf9f
+0, 132, 132, 1, 152064, 0x9c7c2e13
+0, 133, 133, 1, 152064, 0x232e3016
+0, 134, 134, 1, 152064, 0x1b76c08e
+0, 135, 135, 1, 152064, 0x7425d821
+0, 136, 136, 1, 152064, 0x0818ff3c
+0, 137, 137, 1, 152064, 0xb4f2c42b
+0, 138, 138, 1, 152064, 0xe029f979
+0, 139, 139, 1, 152064, 0x97c54c2f
+0, 140, 140, 1, 152064, 0xd101c3b5
+0, 141, 141, 1, 152064, 0x5ed1f5d4
+0, 142, 142, 1, 152064, 0xc28264d1
+0, 143, 143, 1, 152064, 0xa162dd31
+0, 144, 144, 1, 152064, 0x2ee872ce
+0, 145, 145, 1, 152064, 0x809a8fce
+0, 146, 146, 1, 152064, 0xcfcc3ef9
+0, 147, 147, 1, 152064, 0xa5be6ce3
+0, 148, 148, 1, 152064, 0xd75930a0
+0, 149, 149, 1, 152064, 0x28acb80f
+0, 150, 150, 1, 152064, 0x223f2152
+0, 151, 151, 1, 152064, 0x0cf070cb
+0, 152, 152, 1, 152064, 0xcc7d011e
+0, 153, 153, 1, 152064, 0xb2c2a63c
+0, 154, 154, 1, 152064, 0x15514caa
+0, 155, 155, 1, 152064, 0x0c6d18ee
+0, 156, 156, 1, 152064, 0x33b4265d
+0, 157, 157, 1, 152064, 0xb4abaaaf
+0, 158, 158, 1, 152064, 0x26a7a856
+0, 159, 159, 1, 152064, 0xc75249cc
+0, 160, 160, 1, 152064, 0x59ccb0e1
+0, 161, 161, 1, 152064, 0xc613f202
+0, 162, 162, 1, 152064, 0xd1c0e171
+0, 163, 163, 1, 152064, 0xa195da2b
+0, 164, 164, 1, 152064, 0xbc7ed475
+0, 165, 165, 1, 152064, 0x99206e2c
+0, 166, 166, 1, 152064, 0x0ef04e03
+0, 167, 167, 1, 152064, 0x68cbc6a1
+0, 168, 168, 1, 152064, 0x2a5304b1
+0, 169, 169, 1, 152064, 0xf017978b
+0, 170, 170, 1, 152064, 0x94f5641a
+0, 171, 171, 1, 152064, 0xd681bd8f
+0, 172, 172, 1, 152064, 0x16e1e3a3
+0, 173, 173, 1, 152064, 0xe4486c7e
+0, 174, 174, 1, 152064, 0xa1bd394e
+0, 175, 175, 1, 152064, 0x49ad5959
+0, 176, 176, 1, 152064, 0x82219b70
+0, 177, 177, 1, 152064, 0x64e2abcf
+0, 178, 178, 1, 152064, 0x6d7d05d8
+0, 179, 179, 1, 152064, 0xd9ac2251
+0, 180, 180, 1, 152064, 0xf477eee5
+0, 181, 181, 1, 152064, 0xb9826a78
+0, 182, 182, 1, 152064, 0x97828a37
+0, 183, 183, 1, 152064, 0x12099b1f
+0, 184, 184, 1, 152064, 0x1ec45fa7
+0, 185, 185, 1, 152064, 0xfd5501c9
+0, 186, 186, 1, 152064, 0x6a8b26a3
+0, 187, 187, 1, 152064, 0xae58ff40
+0, 188, 188, 1, 152064, 0xc0f47aa1
+0, 189, 189, 1, 152064, 0x08bfa548
+0, 190, 190, 1, 152064, 0x7f2ff5ef
+0, 191, 191, 1, 152064, 0x5efa94a3
+0, 192, 192, 1, 152064, 0xf786f970
+0, 193, 193, 1, 152064, 0xab6bc712
+0, 194, 194, 1, 152064, 0x25647bee
+0, 195, 195, 1, 152064, 0x54333ad5
+0, 196, 196, 1, 152064, 0xb3a99413
+0, 197, 197, 1, 152064, 0xe7a78a0d
+0, 198, 198, 1, 152064, 0xa5054abc
+0, 199, 199, 1, 152064, 0xb94896ea
+0, 200, 200, 1, 152064, 0x9f641bca
+0, 201, 201, 1, 152064, 0x7363901c
+0, 202, 202, 1, 152064, 0xd340a000
+0, 203, 203, 1, 152064, 0x0217f413
+0, 204, 204, 1, 152064, 0xbbdba6e6
+0, 205, 205, 1, 152064, 0xabc42617
+0, 206, 206, 1, 152064, 0xa3442925
+0, 207, 207, 1, 152064, 0x7d06c7e9
+0, 208, 208, 1, 152064, 0xa45e32df
+0, 209, 209, 1, 152064, 0xf5ed407f
+0, 210, 210, 1, 152064, 0x5ec235d5
+0, 211, 211, 1, 152064, 0xa5706635
+0, 212, 212, 1, 152064, 0xa44a209b
+0, 213, 213, 1, 152064, 0xf2137e37
+0, 214, 214, 1, 152064, 0x5220508f
+0, 215, 215, 1, 152064, 0xae6b37da
+0, 216, 216, 1, 152064, 0xdf09b6cd
+0, 217, 217, 1, 152064, 0x2d39e1c0
+0, 218, 218, 1, 152064, 0xc8284a76
+0, 219, 219, 1, 152064, 0x7d7bbe76
+0, 220, 220, 1, 152064, 0xcfed7416
+0, 221, 221, 1, 152064, 0x81caaedd
+0, 222, 222, 1, 152064, 0x9dcdd771
+0, 223, 223, 1, 152064, 0x46c1331b
+0, 224, 224, 1, 152064, 0xace60efa
+0, 225, 225, 1, 152064, 0x9e0909f7
+0, 226, 226, 1, 152064, 0x72f5a321
+0, 227, 227, 1, 152064, 0x68f8cdcc
+0, 228, 228, 1, 152064, 0xcc59fdd9
+0, 229, 229, 1, 152064, 0xc0a700c6
+0, 230, 230, 1, 152064, 0xf4254dcf
+0, 231, 231, 1, 152064, 0xc59b46d1
+0, 232, 232, 1, 152064, 0x2e5b2524
+0, 233, 233, 1, 152064, 0x46051293
+0, 234, 234, 1, 152064, 0x3cbcd1cd
+0, 235, 235, 1, 152064, 0x9f308587
+0, 236, 236, 1, 152064, 0x6b91633f
+0, 237, 237, 1, 152064, 0xb7191012
+0, 238, 238, 1, 152064, 0xd2fd030f
+0, 239, 239, 1, 152064, 0x15a0ae2e
+0, 240, 240, 1, 152064, 0xac3920d0
+0, 241, 241, 1, 152064, 0x0eef80aa
+0, 242, 242, 1, 152064, 0x319008f1
+0, 243, 243, 1, 152064, 0x7734450c
+0, 244, 244, 1, 152064, 0xf112df62
+0, 245, 245, 1, 152064, 0x1dd8ffae
+0, 246, 246, 1, 152064, 0x655ef429
+0, 247, 247, 1, 152064, 0x27026213
+0, 248, 248, 1, 152064, 0x5c14b015
+0, 249, 249, 1, 152064, 0x9512abeb
+0, 250, 250, 1, 152064, 0x961812b2
+0, 251, 251, 1, 152064, 0xb8890aea
+0, 252, 252, 1, 152064, 0x4519db9a
+0, 253, 253, 1, 152064, 0xf358034a
+0, 254, 254, 1, 152064, 0x45d9f2ab
+0, 255, 255, 1, 152064, 0xebd47e7d
+0, 256, 256, 1, 152064, 0x15578be9
+0, 257, 257, 1, 152064, 0x1b373b2d
+0, 258, 258, 1, 152064, 0xbbe707e5
+0, 259, 259, 1, 152064, 0x5bf62385
+0, 260, 260, 1, 152064, 0x832e6ef5
+0, 261, 261, 1, 152064, 0x761e5968
+0, 262, 262, 1, 152064, 0x251f984d
+0, 263, 263, 1, 152064, 0xbda48899
+0, 264, 264, 1, 152064, 0x3fd843b9
+0, 265, 265, 1, 152064, 0x00485425
+0, 266, 266, 1, 152064, 0x4e282b39
+0, 267, 267, 1, 152064, 0x2630a8ea
+0, 268, 268, 1, 152064, 0x5ea5c973
+0, 269, 269, 1, 152064, 0xfc436d21
+0, 270, 270, 1, 152064, 0x69852ef5
+0, 271, 271, 1, 152064, 0x44cb5589
+0, 272, 272, 1, 152064, 0x32f32725
+0, 273, 273, 1, 152064, 0x54d50aca
+0, 274, 274, 1, 152064, 0xe7a639bb
+0, 275, 275, 1, 152064, 0x01be2ad5
+0, 276, 276, 1, 152064, 0x5c63eca4
+0, 277, 277, 1, 152064, 0x94e91116
+0, 278, 278, 1, 152064, 0x9a8be637
+0, 279, 279, 1, 152064, 0x165d9a12
+0, 280, 280, 1, 152064, 0x8c25ca0a
+0, 281, 281, 1, 152064, 0x4ee2ed32
+0, 282, 282, 1, 152064, 0x4b2fe0c6
+0, 283, 283, 1, 152064, 0x521e434e
+0, 284, 284, 1, 152064, 0x97679d7e
+0, 285, 285, 1, 152064, 0x886b9506
+0, 286, 286, 1, 152064, 0x4283eda8
+0, 287, 287, 1, 152064, 0xef793c49
+0, 288, 288, 1, 152064, 0x68ac2afe
+0, 289, 289, 1, 152064, 0x3d1ab510
+0, 290, 290, 1, 152064, 0x98d3ec95
+0, 291, 291, 1, 152064, 0x09f7e512
+0, 292, 292, 1, 152064, 0x801355dd
+0, 293, 293, 1, 152064, 0xf2e87a11
+0, 294, 294, 1, 152064, 0x16757601
+0, 295, 295, 1, 152064, 0x3074d74a
+0, 296, 296, 1, 152064, 0xec8c1290
+0, 297, 297, 1, 152064, 0x46fb1877
+0, 298, 298, 1, 152064, 0xf0b662c4
+0, 299, 299, 1, 152064, 0xf8683940
diff --git a/tests/ref/fate/h264-conformance-frext-hpcvfl_bcrm_a b/tests/ref/fate/h264-conformance-frext-hpcvfl_bcrm_a
index b208184..dbfec43 100644
--- a/tests/ref/fate/h264-conformance-frext-hpcvfl_bcrm_a
+++ b/tests/ref/fate/h264-conformance-frext-hpcvfl_bcrm_a
@@ -1,301 +1,301 @@
#tb 0: 1/25
-0, 2, 2, 1, 152064, 0x502ec077
-0, 4, 4, 1, 152064, 0x84807243
-0, 6, 6, 1, 152064, 0xd7474a6e
-0, 8, 8, 1, 152064, 0x793469bb
-0, 10, 10, 1, 152064, 0xb7a0faf7
-0, 12, 12, 1, 152064, 0x1d3d3cba
-0, 14, 14, 1, 152064, 0xb62583de
-0, 16, 16, 1, 152064, 0xc8422fb1
-0, 18, 18, 1, 152064, 0x321dc699
-0, 20, 20, 1, 152064, 0x7a34d350
-0, 22, 22, 1, 152064, 0xaa4c302d
-0, 24, 24, 1, 152064, 0x45fa7ab0
-0, 26, 26, 1, 152064, 0xc7262e41
-0, 28, 28, 1, 152064, 0x3550000c
-0, 30, 30, 1, 152064, 0xf4bab54b
-0, 32, 32, 1, 152064, 0xaccf9c1a
-0, 34, 34, 1, 152064, 0x9bee20e9
-0, 36, 36, 1, 152064, 0x47fb7720
-0, 38, 38, 1, 152064, 0x12c63ffb
-0, 40, 40, 1, 152064, 0xfa2b8b4d
-0, 42, 42, 1, 152064, 0x279964bd
-0, 44, 44, 1, 152064, 0xb8b01c7e
-0, 46, 46, 1, 152064, 0x816fa010
-0, 48, 48, 1, 152064, 0x59fe1c8c
-0, 50, 50, 1, 152064, 0x13393fad
-0, 52, 52, 1, 152064, 0x991a50a4
-0, 54, 54, 1, 152064, 0x57df3eb7
-0, 56, 56, 1, 152064, 0x744371df
-0, 58, 58, 1, 152064, 0xe9f6d3ff
-0, 60, 60, 1, 152064, 0xc506fba0
-0, 62, 62, 1, 152064, 0x6295b90e
-0, 64, 64, 1, 152064, 0xa19cee2d
-0, 66, 66, 1, 152064, 0xf8c1b3ca
-0, 68, 68, 1, 152064, 0x69f68ce0
-0, 70, 70, 1, 152064, 0x80558bb6
-0, 72, 72, 1, 152064, 0x27824fa5
-0, 74, 74, 1, 152064, 0x27c929a1
-0, 76, 76, 1, 152064, 0xc0fe06d1
-0, 78, 78, 1, 152064, 0xc52bc58c
-0, 80, 80, 1, 152064, 0x0a5363c7
-0, 82, 82, 1, 152064, 0xd0f45a0d
-0, 84, 84, 1, 152064, 0x274710f9
-0, 86, 86, 1, 152064, 0x89d2d390
-0, 88, 88, 1, 152064, 0x12a9bfb0
-0, 90, 90, 1, 152064, 0x04501a93
-0, 92, 92, 1, 152064, 0xf92cbbf4
-0, 94, 94, 1, 152064, 0xf6d1b27d
-0, 96, 96, 1, 152064, 0xe3e904c3
-0, 98, 98, 1, 152064, 0x58f8516d
-0, 100, 100, 1, 152064, 0x70370c2b
-0, 102, 102, 1, 152064, 0xfeebc88c
-0, 104, 104, 1, 152064, 0x974c6ed6
-0, 106, 106, 1, 152064, 0x401bdcf2
-0, 108, 108, 1, 152064, 0xfe61e278
-0, 110, 110, 1, 152064, 0x96ba8bb9
-0, 112, 112, 1, 152064, 0x988492fd
-0, 114, 114, 1, 152064, 0xd1d913a9
-0, 116, 116, 1, 152064, 0x6bc46f0e
-0, 118, 118, 1, 152064, 0x695ef706
-0, 120, 120, 1, 152064, 0x142045c9
-0, 122, 122, 1, 152064, 0xb390ed87
-0, 124, 124, 1, 152064, 0xb9e6d2e5
-0, 126, 126, 1, 152064, 0xe348797f
-0, 128, 128, 1, 152064, 0x1cbd29d6
-0, 130, 130, 1, 152064, 0xbd7dd694
-0, 132, 132, 1, 152064, 0x516873c3
-0, 134, 134, 1, 152064, 0x27bba182
-0, 136, 136, 1, 152064, 0x7541f920
-0, 138, 138, 1, 152064, 0xfdf67042
-0, 140, 140, 1, 152064, 0x6c3c7896
-0, 142, 142, 1, 152064, 0xed86c467
-0, 144, 144, 1, 152064, 0x4ea83ca2
-0, 146, 146, 1, 152064, 0xa3e6725b
-0, 148, 148, 1, 152064, 0x917f5f16
-0, 150, 150, 1, 152064, 0x8cf2d2e1
-0, 152, 152, 1, 152064, 0x57a8d116
-0, 154, 154, 1, 152064, 0x0db267d4
-0, 156, 156, 1, 152064, 0xce782ac5
-0, 158, 158, 1, 152064, 0x1c9d8518
-0, 160, 160, 1, 152064, 0x47598ac7
-0, 162, 162, 1, 152064, 0xc5033d97
-0, 164, 164, 1, 152064, 0xd7aaa3a4
-0, 166, 166, 1, 152064, 0x078afc96
-0, 168, 168, 1, 152064, 0xc9fe673d
-0, 170, 170, 1, 152064, 0xe9284066
-0, 172, 172, 1, 152064, 0xbc570982
-0, 174, 174, 1, 152064, 0x0aac8574
-0, 176, 176, 1, 152064, 0x098cbeee
-0, 178, 178, 1, 152064, 0x19c36a9d
-0, 180, 180, 1, 152064, 0x8fe4a893
-0, 182, 182, 1, 152064, 0x0b652f17
-0, 184, 184, 1, 152064, 0x10f2e6bf
-0, 186, 186, 1, 152064, 0x7ce5634e
-0, 188, 188, 1, 152064, 0x8fe4ac6c
-0, 190, 190, 1, 152064, 0xcaba749e
-0, 192, 192, 1, 152064, 0x5f8a0d5c
-0, 194, 194, 1, 152064, 0xcaa66bbc
-0, 196, 196, 1, 152064, 0xc87ae617
-0, 198, 198, 1, 152064, 0xe8ef4dd7
-0, 200, 200, 1, 152064, 0xdfca5a07
-0, 202, 202, 1, 152064, 0x5f7eab7d
-0, 204, 204, 1, 152064, 0x8a65ebbb
-0, 206, 206, 1, 152064, 0x4beab4a0
-0, 208, 208, 1, 152064, 0xb5e6ab30
-0, 210, 210, 1, 152064, 0x8fe4f4d4
-0, 212, 212, 1, 152064, 0x95bde1ca
-0, 214, 214, 1, 152064, 0xcc5e3a53
-0, 216, 216, 1, 152064, 0xf09f1dd7
-0, 218, 218, 1, 152064, 0x10179672
-0, 220, 220, 1, 152064, 0x4ad16184
-0, 222, 222, 1, 152064, 0x9efa0e23
-0, 224, 224, 1, 152064, 0x22f59522
-0, 226, 226, 1, 152064, 0x4d38f09d
-0, 228, 228, 1, 152064, 0x4c5ebf56
-0, 230, 230, 1, 152064, 0xb19d5077
-0, 232, 232, 1, 152064, 0xa98576b9
-0, 234, 234, 1, 152064, 0x65324239
-0, 236, 236, 1, 152064, 0x709e4031
-0, 238, 238, 1, 152064, 0xf8e81681
-0, 240, 240, 1, 152064, 0x058514e5
-0, 242, 242, 1, 152064, 0xd1d1c806
-0, 244, 244, 1, 152064, 0x0e4dde57
-0, 246, 246, 1, 152064, 0x49e9c2bb
-0, 248, 248, 1, 152064, 0x01417ce6
-0, 250, 250, 1, 152064, 0xda7ebbf1
-0, 252, 252, 1, 152064, 0xa22906b7
-0, 254, 254, 1, 152064, 0x32e2df87
-0, 256, 256, 1, 152064, 0x69917c8f
-0, 258, 258, 1, 152064, 0xea8ed2cc
-0, 260, 260, 1, 152064, 0x0b8d57f1
-0, 262, 262, 1, 152064, 0x5f683bcd
-0, 264, 264, 1, 152064, 0x5162fe2f
-0, 266, 266, 1, 152064, 0x49c052f8
-0, 268, 268, 1, 152064, 0x990b69ba
-0, 270, 270, 1, 152064, 0xa6d4f99f
-0, 272, 272, 1, 152064, 0xe79ef4da
-0, 274, 274, 1, 152064, 0x5e8a3847
-0, 276, 276, 1, 152064, 0x38b1e75f
-0, 278, 278, 1, 152064, 0xf5c91bed
-0, 280, 280, 1, 152064, 0xd59a6d26
-0, 282, 282, 1, 152064, 0xc361de06
-0, 284, 284, 1, 152064, 0x63ed2229
-0, 286, 286, 1, 152064, 0xb8229205
-0, 288, 288, 1, 152064, 0x7c6619af
-0, 290, 290, 1, 152064, 0x4126b02f
-0, 292, 292, 1, 152064, 0x9250b99b
-0, 294, 294, 1, 152064, 0x589778f9
-0, 296, 296, 1, 152064, 0xed1fa45b
-0, 298, 298, 1, 152064, 0x700b6f32
-0, 300, 300, 1, 152064, 0x0590df55
-0, 302, 302, 1, 152064, 0x3e9c4018
-0, 304, 304, 1, 152064, 0x957b8860
-0, 306, 306, 1, 152064, 0x56161560
-0, 308, 308, 1, 152064, 0xbc43bc3b
-0, 310, 310, 1, 152064, 0x508d8632
-0, 312, 312, 1, 152064, 0xbc5736d8
-0, 314, 314, 1, 152064, 0xed7d3aef
-0, 316, 316, 1, 152064, 0x1dcdda9f
-0, 318, 318, 1, 152064, 0x8ef6d5c9
-0, 320, 320, 1, 152064, 0x15466acc
-0, 322, 322, 1, 152064, 0x45d4cf67
-0, 324, 324, 1, 152064, 0x8c900b9d
-0, 326, 326, 1, 152064, 0x747006e0
-0, 328, 328, 1, 152064, 0xac920a0c
-0, 330, 330, 1, 152064, 0xb8210c27
-0, 332, 332, 1, 152064, 0x7dbb873a
-0, 334, 334, 1, 152064, 0x0d4d7584
-0, 336, 336, 1, 152064, 0xefb3fe60
-0, 338, 338, 1, 152064, 0x905e2644
-0, 340, 340, 1, 152064, 0x7c04e534
-0, 342, 342, 1, 152064, 0x8889972a
-0, 344, 344, 1, 152064, 0x21c7d8ad
-0, 346, 346, 1, 152064, 0x1c641176
-0, 348, 348, 1, 152064, 0xf71489a4
-0, 350, 350, 1, 152064, 0xd7ac5555
-0, 352, 352, 1, 152064, 0xb4609c6d
-0, 354, 354, 1, 152064, 0xf5b2bd5e
-0, 356, 356, 1, 152064, 0x9f43ce57
-0, 358, 358, 1, 152064, 0x77642dd3
-0, 360, 360, 1, 152064, 0x3e79565c
-0, 362, 362, 1, 152064, 0x95f40b8e
-0, 364, 364, 1, 152064, 0x3c8ca4d4
-0, 366, 366, 1, 152064, 0xa02ac497
-0, 368, 368, 1, 152064, 0x4c93b377
-0, 370, 370, 1, 152064, 0x55f5ac68
-0, 372, 372, 1, 152064, 0xf8652eca
-0, 374, 374, 1, 152064, 0x56e94574
-0, 376, 376, 1, 152064, 0x6d8302e1
-0, 378, 378, 1, 152064, 0x29a57061
-0, 380, 380, 1, 152064, 0x24e4cfdc
-0, 382, 382, 1, 152064, 0xf5a5d62a
-0, 384, 384, 1, 152064, 0x998870c1
-0, 386, 386, 1, 152064, 0xa15b1f4e
-0, 388, 388, 1, 152064, 0xb0ccb51f
-0, 390, 390, 1, 152064, 0xeaaf59ab
-0, 392, 392, 1, 152064, 0x7e2b4fe6
-0, 394, 394, 1, 152064, 0x72299fea
-0, 396, 396, 1, 152064, 0x769da8b2
-0, 398, 398, 1, 152064, 0xefad7ef8
-0, 400, 400, 1, 152064, 0x24819983
-0, 402, 402, 1, 152064, 0x2aad32ab
-0, 404, 404, 1, 152064, 0xc80cac79
-0, 406, 406, 1, 152064, 0x1659d628
-0, 408, 408, 1, 152064, 0xef941f66
-0, 410, 410, 1, 152064, 0x0d7fcdb5
-0, 412, 412, 1, 152064, 0x7c1853fa
-0, 414, 414, 1, 152064, 0xb94c4d3c
-0, 416, 416, 1, 152064, 0xc47adfc2
-0, 418, 418, 1, 152064, 0x366a6729
-0, 420, 420, 1, 152064, 0x7eb37b70
-0, 422, 422, 1, 152064, 0xafd54c27
-0, 424, 424, 1, 152064, 0x67b18636
-0, 426, 426, 1, 152064, 0x93b22dcf
-0, 428, 428, 1, 152064, 0xa64991f1
-0, 430, 430, 1, 152064, 0xd32a7102
-0, 432, 432, 1, 152064, 0xff665d1c
-0, 434, 434, 1, 152064, 0xf107cc31
-0, 436, 436, 1, 152064, 0xf5b25652
-0, 438, 438, 1, 152064, 0x8caf783d
-0, 440, 440, 1, 152064, 0x72f3eb00
-0, 442, 442, 1, 152064, 0xb5aea5f8
-0, 444, 444, 1, 152064, 0xee70e870
-0, 446, 446, 1, 152064, 0x7c3a0156
-0, 448, 448, 1, 152064, 0x871b6383
-0, 450, 450, 1, 152064, 0x48d831ff
-0, 452, 452, 1, 152064, 0xca233913
-0, 454, 454, 1, 152064, 0xe14bc5eb
-0, 456, 456, 1, 152064, 0x9b1d27e7
-0, 458, 458, 1, 152064, 0xfb9637f7
-0, 460, 460, 1, 152064, 0x0c022157
-0, 462, 462, 1, 152064, 0x16d35fc9
-0, 464, 464, 1, 152064, 0x6d935f71
-0, 466, 466, 1, 152064, 0xae4066fa
-0, 468, 468, 1, 152064, 0xcef94fdc
-0, 470, 470, 1, 152064, 0xc234edb9
-0, 472, 472, 1, 152064, 0x26a4f2e2
-0, 474, 474, 1, 152064, 0xd29ac23e
-0, 476, 476, 1, 152064, 0xb7604395
-0, 478, 478, 1, 152064, 0x408084f6
-0, 480, 480, 1, 152064, 0x0a02026c
-0, 482, 482, 1, 152064, 0x78b33c7c
-0, 484, 484, 1, 152064, 0xcb02b874
-0, 486, 486, 1, 152064, 0xf566513b
-0, 488, 488, 1, 152064, 0xb34e52b1
-0, 490, 490, 1, 152064, 0xf55ff493
-0, 492, 492, 1, 152064, 0xb0e8282a
-0, 494, 494, 1, 152064, 0xe9510bbe
-0, 496, 496, 1, 152064, 0x292e8c5a
-0, 498, 498, 1, 152064, 0x62b9d2b0
-0, 500, 500, 1, 152064, 0x3a8cc827
-0, 502, 502, 1, 152064, 0x25cc465e
-0, 504, 504, 1, 152064, 0xf2bc32e2
-0, 506, 506, 1, 152064, 0x6141f914
-0, 508, 508, 1, 152064, 0x1171256f
-0, 510, 510, 1, 152064, 0x13cb2ded
-0, 512, 512, 1, 152064, 0x3d4ca557
-0, 514, 514, 1, 152064, 0xf2b9e72e
-0, 516, 516, 1, 152064, 0x03f7547a
-0, 518, 518, 1, 152064, 0xc7302955
-0, 520, 520, 1, 152064, 0xe78a46d3
-0, 522, 522, 1, 152064, 0x3726a270
-0, 524, 524, 1, 152064, 0x2f65722a
-0, 526, 526, 1, 152064, 0x55acce40
-0, 528, 528, 1, 152064, 0xf6fa9db2
-0, 530, 530, 1, 152064, 0x70a36937
-0, 532, 532, 1, 152064, 0x9313742d
-0, 534, 534, 1, 152064, 0x2eb14e53
-0, 536, 536, 1, 152064, 0x3d47c9c3
-0, 538, 538, 1, 152064, 0xd0a90348
-0, 540, 540, 1, 152064, 0x6ad48088
-0, 542, 542, 1, 152064, 0x68e64738
-0, 544, 544, 1, 152064, 0x04c3735a
-0, 546, 546, 1, 152064, 0x51d0593f
-0, 548, 548, 1, 152064, 0x42cf2b48
-0, 550, 550, 1, 152064, 0xa5496a0c
-0, 552, 552, 1, 152064, 0x84c25549
-0, 554, 554, 1, 152064, 0x96691600
-0, 556, 556, 1, 152064, 0x423135db
-0, 558, 558, 1, 152064, 0x8d2e08b6
-0, 560, 560, 1, 152064, 0xaeb4c840
-0, 562, 562, 1, 152064, 0xf3e71780
-0, 564, 564, 1, 152064, 0x8858228b
-0, 566, 566, 1, 152064, 0xf28613f8
-0, 568, 568, 1, 152064, 0xb5327882
-0, 570, 570, 1, 152064, 0xbb60bb85
-0, 572, 572, 1, 152064, 0x345ab1c9
-0, 574, 574, 1, 152064, 0x8aac2cba
-0, 576, 576, 1, 152064, 0x7ce15b4c
-0, 578, 578, 1, 152064, 0xc09c55c0
-0, 580, 580, 1, 152064, 0x8482ddd6
-0, 582, 582, 1, 152064, 0xab222a13
-0, 584, 584, 1, 152064, 0xd39b0dea
-0, 586, 586, 1, 152064, 0x6dab6e06
-0, 588, 588, 1, 152064, 0xec0891bd
-0, 590, 590, 1, 152064, 0x88bd9701
-0, 592, 592, 1, 152064, 0xdf13072a
-0, 594, 594, 1, 152064, 0x23b33081
-0, 596, 596, 1, 152064, 0x63943137
-0, 598, 598, 1, 152064, 0xab6a9052
-0, 599, 599, 1, 152064, 0x05485494
+0, 0, 0, 1, 152064, 0x502ec077
+0, 1, 1, 1, 152064, 0x84807243
+0, 2, 2, 1, 152064, 0xd7474a6e
+0, 3, 3, 1, 152064, 0x793469bb
+0, 4, 4, 1, 152064, 0xb7a0faf7
+0, 5, 5, 1, 152064, 0x1d3d3cba
+0, 6, 6, 1, 152064, 0xb62583de
+0, 7, 7, 1, 152064, 0xc8422fb1
+0, 8, 8, 1, 152064, 0x321dc699
+0, 9, 9, 1, 152064, 0x7a34d350
+0, 10, 10, 1, 152064, 0xaa4c302d
+0, 11, 11, 1, 152064, 0x45fa7ab0
+0, 12, 12, 1, 152064, 0xc7262e41
+0, 13, 13, 1, 152064, 0x3550000c
+0, 14, 14, 1, 152064, 0xf4bab54b
+0, 15, 15, 1, 152064, 0xaccf9c1a
+0, 16, 16, 1, 152064, 0x9bee20e9
+0, 17, 17, 1, 152064, 0x47fb7720
+0, 18, 18, 1, 152064, 0x12c63ffb
+0, 19, 19, 1, 152064, 0xfa2b8b4d
+0, 20, 20, 1, 152064, 0x279964bd
+0, 21, 21, 1, 152064, 0xb8b01c7e
+0, 22, 22, 1, 152064, 0x816fa010
+0, 23, 23, 1, 152064, 0x59fe1c8c
+0, 24, 24, 1, 152064, 0x13393fad
+0, 25, 25, 1, 152064, 0x991a50a4
+0, 26, 26, 1, 152064, 0x57df3eb7
+0, 27, 27, 1, 152064, 0x744371df
+0, 28, 28, 1, 152064, 0xe9f6d3ff
+0, 29, 29, 1, 152064, 0xc506fba0
+0, 30, 30, 1, 152064, 0x6295b90e
+0, 31, 31, 1, 152064, 0xa19cee2d
+0, 32, 32, 1, 152064, 0xf8c1b3ca
+0, 33, 33, 1, 152064, 0x69f68ce0
+0, 34, 34, 1, 152064, 0x80558bb6
+0, 35, 35, 1, 152064, 0x27824fa5
+0, 36, 36, 1, 152064, 0x27c929a1
+0, 37, 37, 1, 152064, 0xc0fe06d1
+0, 38, 38, 1, 152064, 0xc52bc58c
+0, 39, 39, 1, 152064, 0x0a5363c7
+0, 40, 40, 1, 152064, 0xd0f45a0d
+0, 41, 41, 1, 152064, 0x274710f9
+0, 42, 42, 1, 152064, 0x89d2d390
+0, 43, 43, 1, 152064, 0x12a9bfb0
+0, 44, 44, 1, 152064, 0x04501a93
+0, 45, 45, 1, 152064, 0xf92cbbf4
+0, 46, 46, 1, 152064, 0xf6d1b27d
+0, 47, 47, 1, 152064, 0xe3e904c3
+0, 48, 48, 1, 152064, 0x58f8516d
+0, 49, 49, 1, 152064, 0x70370c2b
+0, 50, 50, 1, 152064, 0xfeebc88c
+0, 51, 51, 1, 152064, 0x974c6ed6
+0, 52, 52, 1, 152064, 0x401bdcf2
+0, 53, 53, 1, 152064, 0xfe61e278
+0, 54, 54, 1, 152064, 0x96ba8bb9
+0, 55, 55, 1, 152064, 0x988492fd
+0, 56, 56, 1, 152064, 0xd1d913a9
+0, 57, 57, 1, 152064, 0x6bc46f0e
+0, 58, 58, 1, 152064, 0x695ef706
+0, 59, 59, 1, 152064, 0x142045c9
+0, 60, 60, 1, 152064, 0xb390ed87
+0, 61, 61, 1, 152064, 0xb9e6d2e5
+0, 62, 62, 1, 152064, 0xe348797f
+0, 63, 63, 1, 152064, 0x1cbd29d6
+0, 64, 64, 1, 152064, 0xbd7dd694
+0, 65, 65, 1, 152064, 0x516873c3
+0, 66, 66, 1, 152064, 0x27bba182
+0, 67, 67, 1, 152064, 0x7541f920
+0, 68, 68, 1, 152064, 0xfdf67042
+0, 69, 69, 1, 152064, 0x6c3c7896
+0, 70, 70, 1, 152064, 0xed86c467
+0, 71, 71, 1, 152064, 0x4ea83ca2
+0, 72, 72, 1, 152064, 0xa3e6725b
+0, 73, 73, 1, 152064, 0x917f5f16
+0, 74, 74, 1, 152064, 0x8cf2d2e1
+0, 75, 75, 1, 152064, 0x57a8d116
+0, 76, 76, 1, 152064, 0x0db267d4
+0, 77, 77, 1, 152064, 0xce782ac5
+0, 78, 78, 1, 152064, 0x1c9d8518
+0, 79, 79, 1, 152064, 0x47598ac7
+0, 80, 80, 1, 152064, 0xc5033d97
+0, 81, 81, 1, 152064, 0xd7aaa3a4
+0, 82, 82, 1, 152064, 0x078afc96
+0, 83, 83, 1, 152064, 0xc9fe673d
+0, 84, 84, 1, 152064, 0xe9284066
+0, 85, 85, 1, 152064, 0xbc570982
+0, 86, 86, 1, 152064, 0x0aac8574
+0, 87, 87, 1, 152064, 0x098cbeee
+0, 88, 88, 1, 152064, 0x19c36a9d
+0, 89, 89, 1, 152064, 0x8fe4a893
+0, 90, 90, 1, 152064, 0x0b652f17
+0, 91, 91, 1, 152064, 0x10f2e6bf
+0, 92, 92, 1, 152064, 0x7ce5634e
+0, 93, 93, 1, 152064, 0x8fe4ac6c
+0, 94, 94, 1, 152064, 0xcaba749e
+0, 95, 95, 1, 152064, 0x5f8a0d5c
+0, 96, 96, 1, 152064, 0xcaa66bbc
+0, 97, 97, 1, 152064, 0xc87ae617
+0, 98, 98, 1, 152064, 0xe8ef4dd7
+0, 99, 99, 1, 152064, 0xdfca5a07
+0, 100, 100, 1, 152064, 0x5f7eab7d
+0, 101, 101, 1, 152064, 0x8a65ebbb
+0, 102, 102, 1, 152064, 0x4beab4a0
+0, 103, 103, 1, 152064, 0xb5e6ab30
+0, 104, 104, 1, 152064, 0x8fe4f4d4
+0, 105, 105, 1, 152064, 0x95bde1ca
+0, 106, 106, 1, 152064, 0xcc5e3a53
+0, 107, 107, 1, 152064, 0xf09f1dd7
+0, 108, 108, 1, 152064, 0x10179672
+0, 109, 109, 1, 152064, 0x4ad16184
+0, 110, 110, 1, 152064, 0x9efa0e23
+0, 111, 111, 1, 152064, 0x22f59522
+0, 112, 112, 1, 152064, 0x4d38f09d
+0, 113, 113, 1, 152064, 0x4c5ebf56
+0, 114, 114, 1, 152064, 0xb19d5077
+0, 115, 115, 1, 152064, 0xa98576b9
+0, 116, 116, 1, 152064, 0x65324239
+0, 117, 117, 1, 152064, 0x709e4031
+0, 118, 118, 1, 152064, 0xf8e81681
+0, 119, 119, 1, 152064, 0x058514e5
+0, 120, 120, 1, 152064, 0xd1d1c806
+0, 121, 121, 1, 152064, 0x0e4dde57
+0, 122, 122, 1, 152064, 0x49e9c2bb
+0, 123, 123, 1, 152064, 0x01417ce6
+0, 124, 124, 1, 152064, 0xda7ebbf1
+0, 125, 125, 1, 152064, 0xa22906b7
+0, 126, 126, 1, 152064, 0x32e2df87
+0, 127, 127, 1, 152064, 0x69917c8f
+0, 128, 128, 1, 152064, 0xea8ed2cc
+0, 129, 129, 1, 152064, 0x0b8d57f1
+0, 130, 130, 1, 152064, 0x5f683bcd
+0, 131, 131, 1, 152064, 0x5162fe2f
+0, 132, 132, 1, 152064, 0x49c052f8
+0, 133, 133, 1, 152064, 0x990b69ba
+0, 134, 134, 1, 152064, 0xa6d4f99f
+0, 135, 135, 1, 152064, 0xe79ef4da
+0, 136, 136, 1, 152064, 0x5e8a3847
+0, 137, 137, 1, 152064, 0x38b1e75f
+0, 138, 138, 1, 152064, 0xf5c91bed
+0, 139, 139, 1, 152064, 0xd59a6d26
+0, 140, 140, 1, 152064, 0xc361de06
+0, 141, 141, 1, 152064, 0x63ed2229
+0, 142, 142, 1, 152064, 0xb8229205
+0, 143, 143, 1, 152064, 0x7c6619af
+0, 144, 144, 1, 152064, 0x4126b02f
+0, 145, 145, 1, 152064, 0x9250b99b
+0, 146, 146, 1, 152064, 0x589778f9
+0, 147, 147, 1, 152064, 0xed1fa45b
+0, 148, 148, 1, 152064, 0x700b6f32
+0, 149, 149, 1, 152064, 0x0590df55
+0, 150, 150, 1, 152064, 0x3e9c4018
+0, 151, 151, 1, 152064, 0x957b8860
+0, 152, 152, 1, 152064, 0x56161560
+0, 153, 153, 1, 152064, 0xbc43bc3b
+0, 154, 154, 1, 152064, 0x508d8632
+0, 155, 155, 1, 152064, 0xbc5736d8
+0, 156, 156, 1, 152064, 0xed7d3aef
+0, 157, 157, 1, 152064, 0x1dcdda9f
+0, 158, 158, 1, 152064, 0x8ef6d5c9
+0, 159, 159, 1, 152064, 0x15466acc
+0, 160, 160, 1, 152064, 0x45d4cf67
+0, 161, 161, 1, 152064, 0x8c900b9d
+0, 162, 162, 1, 152064, 0x747006e0
+0, 163, 163, 1, 152064, 0xac920a0c
+0, 164, 164, 1, 152064, 0xb8210c27
+0, 165, 165, 1, 152064, 0x7dbb873a
+0, 166, 166, 1, 152064, 0x0d4d7584
+0, 167, 167, 1, 152064, 0xefb3fe60
+0, 168, 168, 1, 152064, 0x905e2644
+0, 169, 169, 1, 152064, 0x7c04e534
+0, 170, 170, 1, 152064, 0x8889972a
+0, 171, 171, 1, 152064, 0x21c7d8ad
+0, 172, 172, 1, 152064, 0x1c641176
+0, 173, 173, 1, 152064, 0xf71489a4
+0, 174, 174, 1, 152064, 0xd7ac5555
+0, 175, 175, 1, 152064, 0xb4609c6d
+0, 176, 176, 1, 152064, 0xf5b2bd5e
+0, 177, 177, 1, 152064, 0x9f43ce57
+0, 178, 178, 1, 152064, 0x77642dd3
+0, 179, 179, 1, 152064, 0x3e79565c
+0, 180, 180, 1, 152064, 0x95f40b8e
+0, 181, 181, 1, 152064, 0x3c8ca4d4
+0, 182, 182, 1, 152064, 0xa02ac497
+0, 183, 183, 1, 152064, 0x4c93b377
+0, 184, 184, 1, 152064, 0x55f5ac68
+0, 185, 185, 1, 152064, 0xf8652eca
+0, 186, 186, 1, 152064, 0x56e94574
+0, 187, 187, 1, 152064, 0x6d8302e1
+0, 188, 188, 1, 152064, 0x29a57061
+0, 189, 189, 1, 152064, 0x24e4cfdc
+0, 190, 190, 1, 152064, 0xf5a5d62a
+0, 191, 191, 1, 152064, 0x998870c1
+0, 192, 192, 1, 152064, 0xa15b1f4e
+0, 193, 193, 1, 152064, 0xb0ccb51f
+0, 194, 194, 1, 152064, 0xeaaf59ab
+0, 195, 195, 1, 152064, 0x7e2b4fe6
+0, 196, 196, 1, 152064, 0x72299fea
+0, 197, 197, 1, 152064, 0x769da8b2
+0, 198, 198, 1, 152064, 0xefad7ef8
+0, 199, 199, 1, 152064, 0x24819983
+0, 200, 200, 1, 152064, 0x2aad32ab
+0, 201, 201, 1, 152064, 0xc80cac79
+0, 202, 202, 1, 152064, 0x1659d628
+0, 203, 203, 1, 152064, 0xef941f66
+0, 204, 204, 1, 152064, 0x0d7fcdb5
+0, 205, 205, 1, 152064, 0x7c1853fa
+0, 206, 206, 1, 152064, 0xb94c4d3c
+0, 207, 207, 1, 152064, 0xc47adfc2
+0, 208, 208, 1, 152064, 0x366a6729
+0, 209, 209, 1, 152064, 0x7eb37b70
+0, 210, 210, 1, 152064, 0xafd54c27
+0, 211, 211, 1, 152064, 0x67b18636
+0, 212, 212, 1, 152064, 0x93b22dcf
+0, 213, 213, 1, 152064, 0xa64991f1
+0, 214, 214, 1, 152064, 0xd32a7102
+0, 215, 215, 1, 152064, 0xff665d1c
+0, 216, 216, 1, 152064, 0xf107cc31
+0, 217, 217, 1, 152064, 0xf5b25652
+0, 218, 218, 1, 152064, 0x8caf783d
+0, 219, 219, 1, 152064, 0x72f3eb00
+0, 220, 220, 1, 152064, 0xb5aea5f8
+0, 221, 221, 1, 152064, 0xee70e870
+0, 222, 222, 1, 152064, 0x7c3a0156
+0, 223, 223, 1, 152064, 0x871b6383
+0, 224, 224, 1, 152064, 0x48d831ff
+0, 225, 225, 1, 152064, 0xca233913
+0, 226, 226, 1, 152064, 0xe14bc5eb
+0, 227, 227, 1, 152064, 0x9b1d27e7
+0, 228, 228, 1, 152064, 0xfb9637f7
+0, 229, 229, 1, 152064, 0x0c022157
+0, 230, 230, 1, 152064, 0x16d35fc9
+0, 231, 231, 1, 152064, 0x6d935f71
+0, 232, 232, 1, 152064, 0xae4066fa
+0, 233, 233, 1, 152064, 0xcef94fdc
+0, 234, 234, 1, 152064, 0xc234edb9
+0, 235, 235, 1, 152064, 0x26a4f2e2
+0, 236, 236, 1, 152064, 0xd29ac23e
+0, 237, 237, 1, 152064, 0xb7604395
+0, 238, 238, 1, 152064, 0x408084f6
+0, 239, 239, 1, 152064, 0x0a02026c
+0, 240, 240, 1, 152064, 0x78b33c7c
+0, 241, 241, 1, 152064, 0xcb02b874
+0, 242, 242, 1, 152064, 0xf566513b
+0, 243, 243, 1, 152064, 0xb34e52b1
+0, 244, 244, 1, 152064, 0xf55ff493
+0, 245, 245, 1, 152064, 0xb0e8282a
+0, 246, 246, 1, 152064, 0xe9510bbe
+0, 247, 247, 1, 152064, 0x292e8c5a
+0, 248, 248, 1, 152064, 0x62b9d2b0
+0, 249, 249, 1, 152064, 0x3a8cc827
+0, 250, 250, 1, 152064, 0x25cc465e
+0, 251, 251, 1, 152064, 0xf2bc32e2
+0, 252, 252, 1, 152064, 0x6141f914
+0, 253, 253, 1, 152064, 0x1171256f
+0, 254, 254, 1, 152064, 0x13cb2ded
+0, 255, 255, 1, 152064, 0x3d4ca557
+0, 256, 256, 1, 152064, 0xf2b9e72e
+0, 257, 257, 1, 152064, 0x03f7547a
+0, 258, 258, 1, 152064, 0xc7302955
+0, 259, 259, 1, 152064, 0xe78a46d3
+0, 260, 260, 1, 152064, 0x3726a270
+0, 261, 261, 1, 152064, 0x2f65722a
+0, 262, 262, 1, 152064, 0x55acce40
+0, 263, 263, 1, 152064, 0xf6fa9db2
+0, 264, 264, 1, 152064, 0x70a36937
+0, 265, 265, 1, 152064, 0x9313742d
+0, 266, 266, 1, 152064, 0x2eb14e53
+0, 267, 267, 1, 152064, 0x3d47c9c3
+0, 268, 268, 1, 152064, 0xd0a90348
+0, 269, 269, 1, 152064, 0x6ad48088
+0, 270, 270, 1, 152064, 0x68e64738
+0, 271, 271, 1, 152064, 0x04c3735a
+0, 272, 272, 1, 152064, 0x51d0593f
+0, 273, 273, 1, 152064, 0x42cf2b48
+0, 274, 274, 1, 152064, 0xa5496a0c
+0, 275, 275, 1, 152064, 0x84c25549
+0, 276, 276, 1, 152064, 0x96691600
+0, 277, 277, 1, 152064, 0x423135db
+0, 278, 278, 1, 152064, 0x8d2e08b6
+0, 279, 279, 1, 152064, 0xaeb4c840
+0, 280, 280, 1, 152064, 0xf3e71780
+0, 281, 281, 1, 152064, 0x8858228b
+0, 282, 282, 1, 152064, 0xf28613f8
+0, 283, 283, 1, 152064, 0xb5327882
+0, 284, 284, 1, 152064, 0xbb60bb85
+0, 285, 285, 1, 152064, 0x345ab1c9
+0, 286, 286, 1, 152064, 0x8aac2cba
+0, 287, 287, 1, 152064, 0x7ce15b4c
+0, 288, 288, 1, 152064, 0xc09c55c0
+0, 289, 289, 1, 152064, 0x8482ddd6
+0, 290, 290, 1, 152064, 0xab222a13
+0, 291, 291, 1, 152064, 0xd39b0dea
+0, 292, 292, 1, 152064, 0x6dab6e06
+0, 293, 293, 1, 152064, 0xec0891bd
+0, 294, 294, 1, 152064, 0x88bd9701
+0, 295, 295, 1, 152064, 0xdf13072a
+0, 296, 296, 1, 152064, 0x23b33081
+0, 297, 297, 1, 152064, 0x63943137
+0, 298, 298, 1, 152064, 0xab6a9052
+0, 299, 299, 1, 152064, 0x05485494
diff --git a/tests/ref/fate/h264-conformance-frext-hpcvflnl_bcrm_a b/tests/ref/fate/h264-conformance-frext-hpcvflnl_bcrm_a
index aafb2d4..65a366e 100644
--- a/tests/ref/fate/h264-conformance-frext-hpcvflnl_bcrm_a
+++ b/tests/ref/fate/h264-conformance-frext-hpcvflnl_bcrm_a
@@ -1,301 +1,301 @@
#tb 0: 1/25
-0, 2, 2, 1, 152064, 0x3e39c08b
-0, 4, 4, 1, 152064, 0xabc67990
-0, 6, 6, 1, 152064, 0x19614e74
-0, 8, 8, 1, 152064, 0xa3776beb
-0, 10, 10, 1, 152064, 0xcce6ffdf
-0, 12, 12, 1, 152064, 0xb0e94746
-0, 14, 14, 1, 152064, 0xdb1a84ef
-0, 16, 16, 1, 152064, 0xb2624509
-0, 18, 18, 1, 152064, 0x32e2d826
-0, 20, 20, 1, 152064, 0xb3bddf0b
-0, 22, 22, 1, 152064, 0x2e273ce3
-0, 24, 24, 1, 152064, 0x67af7e4d
-0, 26, 26, 1, 152064, 0x505c3261
-0, 28, 28, 1, 152064, 0xa43d015e
-0, 30, 30, 1, 152064, 0xad41c1f6
-0, 32, 32, 1, 152064, 0x633ba55f
-0, 34, 34, 1, 152064, 0xe80634f0
-0, 36, 36, 1, 152064, 0x80a07dc9
-0, 38, 38, 1, 152064, 0x0e7a3bbf
-0, 40, 40, 1, 152064, 0xcb099196
-0, 42, 42, 1, 152064, 0x57c96db5
-0, 44, 44, 1, 152064, 0xccd422fa
-0, 46, 46, 1, 152064, 0x0850b7a7
-0, 48, 48, 1, 152064, 0x30e33156
-0, 50, 50, 1, 152064, 0x34e13f9a
-0, 52, 52, 1, 152064, 0x03d36000
-0, 54, 54, 1, 152064, 0xbf7d49da
-0, 56, 56, 1, 152064, 0x77336d09
-0, 58, 58, 1, 152064, 0xca8be5a9
-0, 60, 60, 1, 152064, 0xe57c0b08
-0, 62, 62, 1, 152064, 0xbe77c093
-0, 64, 64, 1, 152064, 0x6bf1ff05
-0, 66, 66, 1, 152064, 0x9142babf
-0, 68, 68, 1, 152064, 0x08db8e67
-0, 70, 70, 1, 152064, 0x69ac8cb6
-0, 72, 72, 1, 152064, 0xaa3b5c88
-0, 74, 74, 1, 152064, 0x9bd32638
-0, 76, 76, 1, 152064, 0x7972115a
-0, 78, 78, 1, 152064, 0x5c1dd47b
-0, 80, 80, 1, 152064, 0x8a196e02
-0, 82, 82, 1, 152064, 0xa89672bc
-0, 84, 84, 1, 152064, 0x27b220e4
-0, 86, 86, 1, 152064, 0xfa38dc4a
-0, 88, 88, 1, 152064, 0x4784c639
-0, 90, 90, 1, 152064, 0xa5e4229a
-0, 92, 92, 1, 152064, 0xa986bdfc
-0, 94, 94, 1, 152064, 0x2951b47b
-0, 96, 96, 1, 152064, 0x4df404a6
-0, 98, 98, 1, 152064, 0xc75155e8
-0, 100, 100, 1, 152064, 0xfc05248c
-0, 102, 102, 1, 152064, 0x5d53da10
-0, 104, 104, 1, 152064, 0x284376ec
-0, 106, 106, 1, 152064, 0x19fce380
-0, 108, 108, 1, 152064, 0x876be6c9
-0, 110, 110, 1, 152064, 0x39eb8ff9
-0, 112, 112, 1, 152064, 0x289c9543
-0, 114, 114, 1, 152064, 0x24dd2356
-0, 116, 116, 1, 152064, 0x1dc17d3c
-0, 118, 118, 1, 152064, 0xd17c00ac
-0, 120, 120, 1, 152064, 0xc2ad54de
-0, 122, 122, 1, 152064, 0xbe11ee2f
-0, 124, 124, 1, 152064, 0x3db9dc89
-0, 126, 126, 1, 152064, 0xac0d7bc2
-0, 128, 128, 1, 152064, 0x8dab2dde
-0, 130, 130, 1, 152064, 0x566ad225
-0, 132, 132, 1, 152064, 0x587c7853
-0, 134, 134, 1, 152064, 0x601c9c80
-0, 136, 136, 1, 152064, 0x2afaf751
-0, 138, 138, 1, 152064, 0x1c9f7e3a
-0, 140, 140, 1, 152064, 0x899475bf
-0, 142, 142, 1, 152064, 0x0d65c7d9
-0, 144, 144, 1, 152064, 0xafd63d12
-0, 146, 146, 1, 152064, 0x162e62b9
-0, 148, 148, 1, 152064, 0x5c9554be
-0, 150, 150, 1, 152064, 0x35fbdaa2
-0, 152, 152, 1, 152064, 0x6438cbd8
-0, 154, 154, 1, 152064, 0xde0772c9
-0, 156, 156, 1, 152064, 0x79f82854
-0, 158, 158, 1, 152064, 0x86957840
-0, 160, 160, 1, 152064, 0xd9468cbf
-0, 162, 162, 1, 152064, 0x23e74609
-0, 164, 164, 1, 152064, 0x3919a146
-0, 166, 166, 1, 152064, 0xd641078b
-0, 168, 168, 1, 152064, 0x24397220
-0, 170, 170, 1, 152064, 0xe7fc3a7c
-0, 172, 172, 1, 152064, 0x3997154a
-0, 174, 174, 1, 152064, 0x2af3952c
-0, 176, 176, 1, 152064, 0x274ac07a
-0, 178, 178, 1, 152064, 0x288f7b09
-0, 180, 180, 1, 152064, 0xe6f9b022
-0, 182, 182, 1, 152064, 0xf09e2fbb
-0, 184, 184, 1, 152064, 0x7244e477
-0, 186, 186, 1, 152064, 0x0dfc72eb
-0, 188, 188, 1, 152064, 0x0322b21f
-0, 190, 190, 1, 152064, 0x18b08205
-0, 192, 192, 1, 152064, 0x6606153e
-0, 194, 194, 1, 152064, 0x85186272
-0, 196, 196, 1, 152064, 0x3369f064
-0, 198, 198, 1, 152064, 0xbe0d5a44
-0, 200, 200, 1, 152064, 0x320258bb
-0, 202, 202, 1, 152064, 0x4d6fb091
-0, 204, 204, 1, 152064, 0xc9bbf5e7
-0, 206, 206, 1, 152064, 0x0aa1b69b
-0, 208, 208, 1, 152064, 0x85b9ac11
-0, 210, 210, 1, 152064, 0xb25ff818
-0, 212, 212, 1, 152064, 0xa155dc25
-0, 214, 214, 1, 152064, 0xa8e03bfd
-0, 216, 216, 1, 152064, 0x0a862956
-0, 218, 218, 1, 152064, 0x11b49264
-0, 220, 220, 1, 152064, 0xa94e664e
-0, 222, 222, 1, 152064, 0x330e0fa2
-0, 224, 224, 1, 152064, 0xaf3d9518
-0, 226, 226, 1, 152064, 0x0836f2e8
-0, 228, 228, 1, 152064, 0xbf6dc578
-0, 230, 230, 1, 152064, 0x7b524d20
-0, 232, 232, 1, 152064, 0x9ef7677f
-0, 234, 234, 1, 152064, 0xeacf3f34
-0, 236, 236, 1, 152064, 0xfb4e3dbe
-0, 238, 238, 1, 152064, 0xb46e25cb
-0, 240, 240, 1, 152064, 0x363c1603
-0, 242, 242, 1, 152064, 0x263fc542
-0, 244, 244, 1, 152064, 0xf106e548
-0, 246, 246, 1, 152064, 0xde43c56a
-0, 248, 248, 1, 152064, 0xc2c4770a
-0, 250, 250, 1, 152064, 0x122fce19
-0, 252, 252, 1, 152064, 0x3ba01434
-0, 254, 254, 1, 152064, 0x0e8ce5ee
-0, 256, 256, 1, 152064, 0x6ceb82e1
-0, 258, 258, 1, 152064, 0xa23ee21c
-0, 260, 260, 1, 152064, 0xc6d960f9
-0, 262, 262, 1, 152064, 0x0de15258
-0, 264, 264, 1, 152064, 0x187b0333
-0, 266, 266, 1, 152064, 0x92e6582f
-0, 268, 268, 1, 152064, 0xb9586ce0
-0, 270, 270, 1, 152064, 0xefd803b5
-0, 272, 272, 1, 152064, 0x24eafb29
-0, 274, 274, 1, 152064, 0x20c73b14
-0, 276, 276, 1, 152064, 0xbd7ceaaa
-0, 278, 278, 1, 152064, 0x775216c8
-0, 280, 280, 1, 152064, 0xa08971c7
-0, 282, 282, 1, 152064, 0xef0ee865
-0, 284, 284, 1, 152064, 0x9ac61c2f
-0, 286, 286, 1, 152064, 0x52ae8ea9
-0, 288, 288, 1, 152064, 0x06571c14
-0, 290, 290, 1, 152064, 0x6e78ad33
-0, 292, 292, 1, 152064, 0xad01c627
-0, 294, 294, 1, 152064, 0xbfe074d3
-0, 296, 296, 1, 152064, 0x9357a183
-0, 298, 298, 1, 152064, 0x8de7767f
-0, 300, 300, 1, 152064, 0xa5e6e76e
-0, 302, 302, 1, 152064, 0xa6f646fe
-0, 304, 304, 1, 152064, 0x132e99f8
-0, 306, 306, 1, 152064, 0xb79f27de
-0, 308, 308, 1, 152064, 0x36d3cdcf
-0, 310, 310, 1, 152064, 0xdc938336
-0, 312, 312, 1, 152064, 0xacaa3a7f
-0, 314, 314, 1, 152064, 0xc61a37fd
-0, 316, 316, 1, 152064, 0x4fe1ddf0
-0, 318, 318, 1, 152064, 0xc0f7d660
-0, 320, 320, 1, 152064, 0xd72458ea
-0, 322, 322, 1, 152064, 0x6978d123
-0, 324, 324, 1, 152064, 0x64e60ccf
-0, 326, 326, 1, 152064, 0xaa07004c
-0, 328, 328, 1, 152064, 0x07cd1064
-0, 330, 330, 1, 152064, 0xa82320e5
-0, 332, 332, 1, 152064, 0xaedd8d30
-0, 334, 334, 1, 152064, 0x79b082ea
-0, 336, 336, 1, 152064, 0x9ed800ab
-0, 338, 338, 1, 152064, 0xde592bb4
-0, 340, 340, 1, 152064, 0xd966df88
-0, 342, 342, 1, 152064, 0xf921988a
-0, 344, 344, 1, 152064, 0x557ad9ae
-0, 346, 346, 1, 152064, 0xc3f31a9a
-0, 348, 348, 1, 152064, 0x65248561
-0, 350, 350, 1, 152064, 0x63df4aa6
-0, 352, 352, 1, 152064, 0x618da0a9
-0, 354, 354, 1, 152064, 0xe6f1c435
-0, 356, 356, 1, 152064, 0x9f90c38f
-0, 358, 358, 1, 152064, 0xd2853e14
-0, 360, 360, 1, 152064, 0x6e0268a9
-0, 362, 362, 1, 152064, 0x393712d1
-0, 364, 364, 1, 152064, 0x470da25f
-0, 366, 366, 1, 152064, 0xaf55cb3d
-0, 368, 368, 1, 152064, 0x6935b8b9
-0, 370, 370, 1, 152064, 0x5409a15f
-0, 372, 372, 1, 152064, 0x09073fee
-0, 374, 374, 1, 152064, 0xfb274e82
-0, 376, 376, 1, 152064, 0x1a770581
-0, 378, 378, 1, 152064, 0x17277d0d
-0, 380, 380, 1, 152064, 0xd4dcd982
-0, 382, 382, 1, 152064, 0x6b04eaf3
-0, 384, 384, 1, 152064, 0x8a3d822e
-0, 386, 386, 1, 152064, 0x1b971ec9
-0, 388, 388, 1, 152064, 0x14e0c0f6
-0, 390, 390, 1, 152064, 0x00667450
-0, 392, 392, 1, 152064, 0xd2385902
-0, 394, 394, 1, 152064, 0x905da6ab
-0, 396, 396, 1, 152064, 0xa3ffb18b
-0, 398, 398, 1, 152064, 0x10d48b19
-0, 400, 400, 1, 152064, 0xb2c7a3bd
-0, 402, 402, 1, 152064, 0x45593e96
-0, 404, 404, 1, 152064, 0x47a0b60c
-0, 406, 406, 1, 152064, 0x68c6d1b9
-0, 408, 408, 1, 152064, 0xbc881fcc
-0, 410, 410, 1, 152064, 0x422cc6f2
-0, 412, 412, 1, 152064, 0x9b686410
-0, 414, 414, 1, 152064, 0x35dc5e86
-0, 416, 416, 1, 152064, 0x247bedaa
-0, 418, 418, 1, 152064, 0x22b76fd1
-0, 420, 420, 1, 152064, 0x67cc7a75
-0, 422, 422, 1, 152064, 0xa197521e
-0, 424, 424, 1, 152064, 0x428c8662
-0, 426, 426, 1, 152064, 0x33dc2c73
-0, 428, 428, 1, 152064, 0x5b538903
-0, 430, 430, 1, 152064, 0x3c4176b6
-0, 432, 432, 1, 152064, 0x774364ba
-0, 434, 434, 1, 152064, 0xf237d03e
-0, 436, 436, 1, 152064, 0xac8746fb
-0, 438, 438, 1, 152064, 0x6b306a84
-0, 440, 440, 1, 152064, 0xa2ace513
-0, 442, 442, 1, 152064, 0x709c9be7
-0, 444, 444, 1, 152064, 0x2403f373
-0, 446, 446, 1, 152064, 0x147bf717
-0, 448, 448, 1, 152064, 0xe58964c8
-0, 450, 450, 1, 152064, 0xa0da36fc
-0, 452, 452, 1, 152064, 0x1ac1355c
-0, 454, 454, 1, 152064, 0x8a31c9f2
-0, 456, 456, 1, 152064, 0x42ba205c
-0, 458, 458, 1, 152064, 0xa11b3575
-0, 460, 460, 1, 152064, 0xcb35207c
-0, 462, 462, 1, 152064, 0x528f6189
-0, 464, 464, 1, 152064, 0x34f05bd7
-0, 466, 466, 1, 152064, 0x72317356
-0, 468, 468, 1, 152064, 0xaabd5028
-0, 470, 470, 1, 152064, 0x13dbeb7b
-0, 472, 472, 1, 152064, 0x62f1e8a8
-0, 474, 474, 1, 152064, 0x1723bfcd
-0, 476, 476, 1, 152064, 0x5c083c00
-0, 478, 478, 1, 152064, 0x52137894
-0, 480, 480, 1, 152064, 0xef1e082c
-0, 482, 482, 1, 152064, 0x664b3d53
-0, 484, 484, 1, 152064, 0x2eb9b296
-0, 486, 486, 1, 152064, 0xd0ca511e
-0, 488, 488, 1, 152064, 0x012d4724
-0, 490, 490, 1, 152064, 0xa847f5af
-0, 492, 492, 1, 152064, 0x483a2fde
-0, 494, 494, 1, 152064, 0xd1ab0257
-0, 496, 496, 1, 152064, 0x414692c7
-0, 498, 498, 1, 152064, 0x0b79df88
-0, 500, 500, 1, 152064, 0xdaa2c4a3
-0, 502, 502, 1, 152064, 0xd1b44500
-0, 504, 504, 1, 152064, 0xfd3d2cf3
-0, 506, 506, 1, 152064, 0xfdc0f748
-0, 508, 508, 1, 152064, 0xce762a2a
-0, 510, 510, 1, 152064, 0x08b63572
-0, 512, 512, 1, 152064, 0x5a46a38d
-0, 514, 514, 1, 152064, 0x03cee9c0
-0, 516, 516, 1, 152064, 0x9ee45473
-0, 518, 518, 1, 152064, 0x5a432386
-0, 520, 520, 1, 152064, 0x54c83d87
-0, 522, 522, 1, 152064, 0xc9caa1de
-0, 524, 524, 1, 152064, 0xa28367f1
-0, 526, 526, 1, 152064, 0x2607cdf1
-0, 528, 528, 1, 152064, 0x06baa8de
-0, 530, 530, 1, 152064, 0xf5346e32
-0, 532, 532, 1, 152064, 0x6d3e732b
-0, 534, 534, 1, 152064, 0x798c584b
-0, 536, 536, 1, 152064, 0x4076c948
-0, 538, 538, 1, 152064, 0x868cf63a
-0, 540, 540, 1, 152064, 0x23107ac5
-0, 542, 542, 1, 152064, 0x306f3fe2
-0, 544, 544, 1, 152064, 0xbd1d71d6
-0, 546, 546, 1, 152064, 0x1429545f
-0, 548, 548, 1, 152064, 0xaded29aa
-0, 550, 550, 1, 152064, 0x9b455a94
-0, 552, 552, 1, 152064, 0xb3774ce7
-0, 554, 554, 1, 152064, 0x92580986
-0, 556, 556, 1, 152064, 0x0eae2f95
-0, 558, 558, 1, 152064, 0x599208b2
-0, 560, 560, 1, 152064, 0x4804c04c
-0, 562, 562, 1, 152064, 0x5f730e8f
-0, 564, 564, 1, 152064, 0x3e501d1e
-0, 566, 566, 1, 152064, 0x32100740
-0, 568, 568, 1, 152064, 0x62226ff8
-0, 570, 570, 1, 152064, 0x7683b622
-0, 572, 572, 1, 152064, 0xc3e0aec1
-0, 574, 574, 1, 152064, 0xfac12608
-0, 576, 576, 1, 152064, 0xb21a5781
-0, 578, 578, 1, 152064, 0x8f1e4964
-0, 580, 580, 1, 152064, 0x0f62dd6e
-0, 582, 582, 1, 152064, 0xac062ac4
-0, 584, 584, 1, 152064, 0x1b320f7a
-0, 586, 586, 1, 152064, 0x346e7211
-0, 588, 588, 1, 152064, 0xe47592f3
-0, 590, 590, 1, 152064, 0xa3a7919c
-0, 592, 592, 1, 152064, 0xa3580fa6
-0, 594, 594, 1, 152064, 0xc73430c1
-0, 596, 596, 1, 152064, 0x994a2c18
-0, 598, 598, 1, 152064, 0x0b5d8d45
-0, 599, 599, 1, 152064, 0x9eed5109
+0, 0, 0, 1, 152064, 0x3e39c08b
+0, 1, 1, 1, 152064, 0xabc67990
+0, 2, 2, 1, 152064, 0x19614e74
+0, 3, 3, 1, 152064, 0xa3776beb
+0, 4, 4, 1, 152064, 0xcce6ffdf
+0, 5, 5, 1, 152064, 0xb0e94746
+0, 6, 6, 1, 152064, 0xdb1a84ef
+0, 7, 7, 1, 152064, 0xb2624509
+0, 8, 8, 1, 152064, 0x32e2d826
+0, 9, 9, 1, 152064, 0xb3bddf0b
+0, 10, 10, 1, 152064, 0x2e273ce3
+0, 11, 11, 1, 152064, 0x67af7e4d
+0, 12, 12, 1, 152064, 0x505c3261
+0, 13, 13, 1, 152064, 0xa43d015e
+0, 14, 14, 1, 152064, 0xad41c1f6
+0, 15, 15, 1, 152064, 0x633ba55f
+0, 16, 16, 1, 152064, 0xe80634f0
+0, 17, 17, 1, 152064, 0x80a07dc9
+0, 18, 18, 1, 152064, 0x0e7a3bbf
+0, 19, 19, 1, 152064, 0xcb099196
+0, 20, 20, 1, 152064, 0x57c96db5
+0, 21, 21, 1, 152064, 0xccd422fa
+0, 22, 22, 1, 152064, 0x0850b7a7
+0, 23, 23, 1, 152064, 0x30e33156
+0, 24, 24, 1, 152064, 0x34e13f9a
+0, 25, 25, 1, 152064, 0x03d36000
+0, 26, 26, 1, 152064, 0xbf7d49da
+0, 27, 27, 1, 152064, 0x77336d09
+0, 28, 28, 1, 152064, 0xca8be5a9
+0, 29, 29, 1, 152064, 0xe57c0b08
+0, 30, 30, 1, 152064, 0xbe77c093
+0, 31, 31, 1, 152064, 0x6bf1ff05
+0, 32, 32, 1, 152064, 0x9142babf
+0, 33, 33, 1, 152064, 0x08db8e67
+0, 34, 34, 1, 152064, 0x69ac8cb6
+0, 35, 35, 1, 152064, 0xaa3b5c88
+0, 36, 36, 1, 152064, 0x9bd32638
+0, 37, 37, 1, 152064, 0x7972115a
+0, 38, 38, 1, 152064, 0x5c1dd47b
+0, 39, 39, 1, 152064, 0x8a196e02
+0, 40, 40, 1, 152064, 0xa89672bc
+0, 41, 41, 1, 152064, 0x27b220e4
+0, 42, 42, 1, 152064, 0xfa38dc4a
+0, 43, 43, 1, 152064, 0x4784c639
+0, 44, 44, 1, 152064, 0xa5e4229a
+0, 45, 45, 1, 152064, 0xa986bdfc
+0, 46, 46, 1, 152064, 0x2951b47b
+0, 47, 47, 1, 152064, 0x4df404a6
+0, 48, 48, 1, 152064, 0xc75155e8
+0, 49, 49, 1, 152064, 0xfc05248c
+0, 50, 50, 1, 152064, 0x5d53da10
+0, 51, 51, 1, 152064, 0x284376ec
+0, 52, 52, 1, 152064, 0x19fce380
+0, 53, 53, 1, 152064, 0x876be6c9
+0, 54, 54, 1, 152064, 0x39eb8ff9
+0, 55, 55, 1, 152064, 0x289c9543
+0, 56, 56, 1, 152064, 0x24dd2356
+0, 57, 57, 1, 152064, 0x1dc17d3c
+0, 58, 58, 1, 152064, 0xd17c00ac
+0, 59, 59, 1, 152064, 0xc2ad54de
+0, 60, 60, 1, 152064, 0xbe11ee2f
+0, 61, 61, 1, 152064, 0x3db9dc89
+0, 62, 62, 1, 152064, 0xac0d7bc2
+0, 63, 63, 1, 152064, 0x8dab2dde
+0, 64, 64, 1, 152064, 0x566ad225
+0, 65, 65, 1, 152064, 0x587c7853
+0, 66, 66, 1, 152064, 0x601c9c80
+0, 67, 67, 1, 152064, 0x2afaf751
+0, 68, 68, 1, 152064, 0x1c9f7e3a
+0, 69, 69, 1, 152064, 0x899475bf
+0, 70, 70, 1, 152064, 0x0d65c7d9
+0, 71, 71, 1, 152064, 0xafd63d12
+0, 72, 72, 1, 152064, 0x162e62b9
+0, 73, 73, 1, 152064, 0x5c9554be
+0, 74, 74, 1, 152064, 0x35fbdaa2
+0, 75, 75, 1, 152064, 0x6438cbd8
+0, 76, 76, 1, 152064, 0xde0772c9
+0, 77, 77, 1, 152064, 0x79f82854
+0, 78, 78, 1, 152064, 0x86957840
+0, 79, 79, 1, 152064, 0xd9468cbf
+0, 80, 80, 1, 152064, 0x23e74609
+0, 81, 81, 1, 152064, 0x3919a146
+0, 82, 82, 1, 152064, 0xd641078b
+0, 83, 83, 1, 152064, 0x24397220
+0, 84, 84, 1, 152064, 0xe7fc3a7c
+0, 85, 85, 1, 152064, 0x3997154a
+0, 86, 86, 1, 152064, 0x2af3952c
+0, 87, 87, 1, 152064, 0x274ac07a
+0, 88, 88, 1, 152064, 0x288f7b09
+0, 89, 89, 1, 152064, 0xe6f9b022
+0, 90, 90, 1, 152064, 0xf09e2fbb
+0, 91, 91, 1, 152064, 0x7244e477
+0, 92, 92, 1, 152064, 0x0dfc72eb
+0, 93, 93, 1, 152064, 0x0322b21f
+0, 94, 94, 1, 152064, 0x18b08205
+0, 95, 95, 1, 152064, 0x6606153e
+0, 96, 96, 1, 152064, 0x85186272
+0, 97, 97, 1, 152064, 0x3369f064
+0, 98, 98, 1, 152064, 0xbe0d5a44
+0, 99, 99, 1, 152064, 0x320258bb
+0, 100, 100, 1, 152064, 0x4d6fb091
+0, 101, 101, 1, 152064, 0xc9bbf5e7
+0, 102, 102, 1, 152064, 0x0aa1b69b
+0, 103, 103, 1, 152064, 0x85b9ac11
+0, 104, 104, 1, 152064, 0xb25ff818
+0, 105, 105, 1, 152064, 0xa155dc25
+0, 106, 106, 1, 152064, 0xa8e03bfd
+0, 107, 107, 1, 152064, 0x0a862956
+0, 108, 108, 1, 152064, 0x11b49264
+0, 109, 109, 1, 152064, 0xa94e664e
+0, 110, 110, 1, 152064, 0x330e0fa2
+0, 111, 111, 1, 152064, 0xaf3d9518
+0, 112, 112, 1, 152064, 0x0836f2e8
+0, 113, 113, 1, 152064, 0xbf6dc578
+0, 114, 114, 1, 152064, 0x7b524d20
+0, 115, 115, 1, 152064, 0x9ef7677f
+0, 116, 116, 1, 152064, 0xeacf3f34
+0, 117, 117, 1, 152064, 0xfb4e3dbe
+0, 118, 118, 1, 152064, 0xb46e25cb
+0, 119, 119, 1, 152064, 0x363c1603
+0, 120, 120, 1, 152064, 0x263fc542
+0, 121, 121, 1, 152064, 0xf106e548
+0, 122, 122, 1, 152064, 0xde43c56a
+0, 123, 123, 1, 152064, 0xc2c4770a
+0, 124, 124, 1, 152064, 0x122fce19
+0, 125, 125, 1, 152064, 0x3ba01434
+0, 126, 126, 1, 152064, 0x0e8ce5ee
+0, 127, 127, 1, 152064, 0x6ceb82e1
+0, 128, 128, 1, 152064, 0xa23ee21c
+0, 129, 129, 1, 152064, 0xc6d960f9
+0, 130, 130, 1, 152064, 0x0de15258
+0, 131, 131, 1, 152064, 0x187b0333
+0, 132, 132, 1, 152064, 0x92e6582f
+0, 133, 133, 1, 152064, 0xb9586ce0
+0, 134, 134, 1, 152064, 0xefd803b5
+0, 135, 135, 1, 152064, 0x24eafb29
+0, 136, 136, 1, 152064, 0x20c73b14
+0, 137, 137, 1, 152064, 0xbd7ceaaa
+0, 138, 138, 1, 152064, 0x775216c8
+0, 139, 139, 1, 152064, 0xa08971c7
+0, 140, 140, 1, 152064, 0xef0ee865
+0, 141, 141, 1, 152064, 0x9ac61c2f
+0, 142, 142, 1, 152064, 0x52ae8ea9
+0, 143, 143, 1, 152064, 0x06571c14
+0, 144, 144, 1, 152064, 0x6e78ad33
+0, 145, 145, 1, 152064, 0xad01c627
+0, 146, 146, 1, 152064, 0xbfe074d3
+0, 147, 147, 1, 152064, 0x9357a183
+0, 148, 148, 1, 152064, 0x8de7767f
+0, 149, 149, 1, 152064, 0xa5e6e76e
+0, 150, 150, 1, 152064, 0xa6f646fe
+0, 151, 151, 1, 152064, 0x132e99f8
+0, 152, 152, 1, 152064, 0xb79f27de
+0, 153, 153, 1, 152064, 0x36d3cdcf
+0, 154, 154, 1, 152064, 0xdc938336
+0, 155, 155, 1, 152064, 0xacaa3a7f
+0, 156, 156, 1, 152064, 0xc61a37fd
+0, 157, 157, 1, 152064, 0x4fe1ddf0
+0, 158, 158, 1, 152064, 0xc0f7d660
+0, 159, 159, 1, 152064, 0xd72458ea
+0, 160, 160, 1, 152064, 0x6978d123
+0, 161, 161, 1, 152064, 0x64e60ccf
+0, 162, 162, 1, 152064, 0xaa07004c
+0, 163, 163, 1, 152064, 0x07cd1064
+0, 164, 164, 1, 152064, 0xa82320e5
+0, 165, 165, 1, 152064, 0xaedd8d30
+0, 166, 166, 1, 152064, 0x79b082ea
+0, 167, 167, 1, 152064, 0x9ed800ab
+0, 168, 168, 1, 152064, 0xde592bb4
+0, 169, 169, 1, 152064, 0xd966df88
+0, 170, 170, 1, 152064, 0xf921988a
+0, 171, 171, 1, 152064, 0x557ad9ae
+0, 172, 172, 1, 152064, 0xc3f31a9a
+0, 173, 173, 1, 152064, 0x65248561
+0, 174, 174, 1, 152064, 0x63df4aa6
+0, 175, 175, 1, 152064, 0x618da0a9
+0, 176, 176, 1, 152064, 0xe6f1c435
+0, 177, 177, 1, 152064, 0x9f90c38f
+0, 178, 178, 1, 152064, 0xd2853e14
+0, 179, 179, 1, 152064, 0x6e0268a9
+0, 180, 180, 1, 152064, 0x393712d1
+0, 181, 181, 1, 152064, 0x470da25f
+0, 182, 182, 1, 152064, 0xaf55cb3d
+0, 183, 183, 1, 152064, 0x6935b8b9
+0, 184, 184, 1, 152064, 0x5409a15f
+0, 185, 185, 1, 152064, 0x09073fee
+0, 186, 186, 1, 152064, 0xfb274e82
+0, 187, 187, 1, 152064, 0x1a770581
+0, 188, 188, 1, 152064, 0x17277d0d
+0, 189, 189, 1, 152064, 0xd4dcd982
+0, 190, 190, 1, 152064, 0x6b04eaf3
+0, 191, 191, 1, 152064, 0x8a3d822e
+0, 192, 192, 1, 152064, 0x1b971ec9
+0, 193, 193, 1, 152064, 0x14e0c0f6
+0, 194, 194, 1, 152064, 0x00667450
+0, 195, 195, 1, 152064, 0xd2385902
+0, 196, 196, 1, 152064, 0x905da6ab
+0, 197, 197, 1, 152064, 0xa3ffb18b
+0, 198, 198, 1, 152064, 0x10d48b19
+0, 199, 199, 1, 152064, 0xb2c7a3bd
+0, 200, 200, 1, 152064, 0x45593e96
+0, 201, 201, 1, 152064, 0x47a0b60c
+0, 202, 202, 1, 152064, 0x68c6d1b9
+0, 203, 203, 1, 152064, 0xbc881fcc
+0, 204, 204, 1, 152064, 0x422cc6f2
+0, 205, 205, 1, 152064, 0x9b686410
+0, 206, 206, 1, 152064, 0x35dc5e86
+0, 207, 207, 1, 152064, 0x247bedaa
+0, 208, 208, 1, 152064, 0x22b76fd1
+0, 209, 209, 1, 152064, 0x67cc7a75
+0, 210, 210, 1, 152064, 0xa197521e
+0, 211, 211, 1, 152064, 0x428c8662
+0, 212, 212, 1, 152064, 0x33dc2c73
+0, 213, 213, 1, 152064, 0x5b538903
+0, 214, 214, 1, 152064, 0x3c4176b6
+0, 215, 215, 1, 152064, 0x774364ba
+0, 216, 216, 1, 152064, 0xf237d03e
+0, 217, 217, 1, 152064, 0xac8746fb
+0, 218, 218, 1, 152064, 0x6b306a84
+0, 219, 219, 1, 152064, 0xa2ace513
+0, 220, 220, 1, 152064, 0x709c9be7
+0, 221, 221, 1, 152064, 0x2403f373
+0, 222, 222, 1, 152064, 0x147bf717
+0, 223, 223, 1, 152064, 0xe58964c8
+0, 224, 224, 1, 152064, 0xa0da36fc
+0, 225, 225, 1, 152064, 0x1ac1355c
+0, 226, 226, 1, 152064, 0x8a31c9f2
+0, 227, 227, 1, 152064, 0x42ba205c
+0, 228, 228, 1, 152064, 0xa11b3575
+0, 229, 229, 1, 152064, 0xcb35207c
+0, 230, 230, 1, 152064, 0x528f6189
+0, 231, 231, 1, 152064, 0x34f05bd7
+0, 232, 232, 1, 152064, 0x72317356
+0, 233, 233, 1, 152064, 0xaabd5028
+0, 234, 234, 1, 152064, 0x13dbeb7b
+0, 235, 235, 1, 152064, 0x62f1e8a8
+0, 236, 236, 1, 152064, 0x1723bfcd
+0, 237, 237, 1, 152064, 0x5c083c00
+0, 238, 238, 1, 152064, 0x52137894
+0, 239, 239, 1, 152064, 0xef1e082c
+0, 240, 240, 1, 152064, 0x664b3d53
+0, 241, 241, 1, 152064, 0x2eb9b296
+0, 242, 242, 1, 152064, 0xd0ca511e
+0, 243, 243, 1, 152064, 0x012d4724
+0, 244, 244, 1, 152064, 0xa847f5af
+0, 245, 245, 1, 152064, 0x483a2fde
+0, 246, 246, 1, 152064, 0xd1ab0257
+0, 247, 247, 1, 152064, 0x414692c7
+0, 248, 248, 1, 152064, 0x0b79df88
+0, 249, 249, 1, 152064, 0xdaa2c4a3
+0, 250, 250, 1, 152064, 0xd1b44500
+0, 251, 251, 1, 152064, 0xfd3d2cf3
+0, 252, 252, 1, 152064, 0xfdc0f748
+0, 253, 253, 1, 152064, 0xce762a2a
+0, 254, 254, 1, 152064, 0x08b63572
+0, 255, 255, 1, 152064, 0x5a46a38d
+0, 256, 256, 1, 152064, 0x03cee9c0
+0, 257, 257, 1, 152064, 0x9ee45473
+0, 258, 258, 1, 152064, 0x5a432386
+0, 259, 259, 1, 152064, 0x54c83d87
+0, 260, 260, 1, 152064, 0xc9caa1de
+0, 261, 261, 1, 152064, 0xa28367f1
+0, 262, 262, 1, 152064, 0x2607cdf1
+0, 263, 263, 1, 152064, 0x06baa8de
+0, 264, 264, 1, 152064, 0xf5346e32
+0, 265, 265, 1, 152064, 0x6d3e732b
+0, 266, 266, 1, 152064, 0x798c584b
+0, 267, 267, 1, 152064, 0x4076c948
+0, 268, 268, 1, 152064, 0x868cf63a
+0, 269, 269, 1, 152064, 0x23107ac5
+0, 270, 270, 1, 152064, 0x306f3fe2
+0, 271, 271, 1, 152064, 0xbd1d71d6
+0, 272, 272, 1, 152064, 0x1429545f
+0, 273, 273, 1, 152064, 0xaded29aa
+0, 274, 274, 1, 152064, 0x9b455a94
+0, 275, 275, 1, 152064, 0xb3774ce7
+0, 276, 276, 1, 152064, 0x92580986
+0, 277, 277, 1, 152064, 0x0eae2f95
+0, 278, 278, 1, 152064, 0x599208b2
+0, 279, 279, 1, 152064, 0x4804c04c
+0, 280, 280, 1, 152064, 0x5f730e8f
+0, 281, 281, 1, 152064, 0x3e501d1e
+0, 282, 282, 1, 152064, 0x32100740
+0, 283, 283, 1, 152064, 0x62226ff8
+0, 284, 284, 1, 152064, 0x7683b622
+0, 285, 285, 1, 152064, 0xc3e0aec1
+0, 286, 286, 1, 152064, 0xfac12608
+0, 287, 287, 1, 152064, 0xb21a5781
+0, 288, 288, 1, 152064, 0x8f1e4964
+0, 289, 289, 1, 152064, 0x0f62dd6e
+0, 290, 290, 1, 152064, 0xac062ac4
+0, 291, 291, 1, 152064, 0x1b320f7a
+0, 292, 292, 1, 152064, 0x346e7211
+0, 293, 293, 1, 152064, 0xe47592f3
+0, 294, 294, 1, 152064, 0xa3a7919c
+0, 295, 295, 1, 152064, 0xa3580fa6
+0, 296, 296, 1, 152064, 0xc73430c1
+0, 297, 297, 1, 152064, 0x994a2c18
+0, 298, 298, 1, 152064, 0x0b5d8d45
+0, 299, 299, 1, 152064, 0x9eed5109
diff --git a/tests/ref/fate/h264-conformance-mr3_tandberg_b b/tests/ref/fate/h264-conformance-mr3_tandberg_b
index 6e0c83a..ee8014e 100644
--- a/tests/ref/fate/h264-conformance-mr3_tandberg_b
+++ b/tests/ref/fate/h264-conformance-mr3_tandberg_b
@@ -8,294 +8,294 @@
0, 6, 6, 1, 38016, 0x7cc17319
0, 7, 7, 1, 38016, 0x0f7e8cab
0, 8, 8, 1, 38016, 0x1876abee
-0, 10, 10, 1, 38016, 0xda748c2f
-0, 11, 11, 1, 38016, 0x7b4dbff0
-0, 12, 12, 1, 38016, 0xd4a1b24a
-0, 13, 13, 1, 38016, 0x714cb4cc
-0, 14, 14, 1, 38016, 0x2c6d80f0
-0, 15, 15, 1, 38016, 0x92266151
-0, 16, 16, 1, 38016, 0x6b766a23
-0, 17, 17, 1, 38016, 0xb24f7efe
-0, 18, 18, 1, 38016, 0x8410838e
-0, 19, 19, 1, 38016, 0x67fe872a
-0, 20, 20, 1, 38016, 0x55b49d36
-0, 21, 21, 1, 38016, 0x7a1c9c41
-0, 22, 22, 1, 38016, 0xb4818e0e
-0, 23, 23, 1, 38016, 0x25f6683c
-0, 24, 24, 1, 38016, 0xe4d141a4
-0, 25, 25, 1, 38016, 0x808216ad
-0, 26, 26, 1, 38016, 0x2acf0baf
-0, 27, 27, 1, 38016, 0xf3de13c4
-0, 28, 28, 1, 38016, 0x5f412187
-0, 29, 29, 1, 38016, 0xb31a340a
-0, 30, 30, 1, 38016, 0x019d42d1
-0, 31, 31, 1, 38016, 0xeeb94b9b
-0, 32, 32, 1, 38016, 0xef55472e
-0, 33, 33, 1, 38016, 0xdb5e3697
-0, 34, 34, 1, 38016, 0x8565303e
-0, 35, 35, 1, 38016, 0x5f9c2c1b
-0, 36, 36, 1, 38016, 0xeb3d27f4
-0, 37, 37, 1, 38016, 0x9a43282d
-0, 38, 38, 1, 38016, 0xe04720c6
-0, 39, 39, 1, 38016, 0x19cc0eba
-0, 40, 40, 1, 38016, 0x218efeb6
-0, 41, 41, 1, 38016, 0x7733f491
-0, 42, 42, 1, 38016, 0x7f3bede9
-0, 43, 43, 1, 38016, 0x49c5ec0d
-0, 44, 44, 1, 38016, 0x803cf19e
-0, 45, 45, 1, 38016, 0x31de0d3f
-0, 46, 46, 1, 38016, 0xa7e30426
-0, 47, 47, 1, 38016, 0xba37f068
-0, 48, 48, 1, 38016, 0x2842bdf8
-0, 49, 49, 1, 38016, 0x76df97dc
-0, 50, 50, 1, 38016, 0xf3246d26
-0, 51, 51, 1, 38016, 0x0a384d72
-0, 52, 52, 1, 38016, 0x40964f41
-0, 53, 53, 1, 38016, 0x46364324
-0, 54, 54, 1, 38016, 0x7cbf3db4
-0, 55, 55, 1, 38016, 0x7a223bec
-0, 56, 56, 1, 38016, 0x458651c1
-0, 57, 57, 1, 38016, 0xb82d7e3c
-0, 58, 58, 1, 38016, 0x0f50a55d
-0, 59, 59, 1, 38016, 0xc306cae4
-0, 60, 60, 1, 38016, 0x9d6ddfcb
-0, 61, 61, 1, 38016, 0xb602e8e9
-0, 62, 62, 1, 38016, 0xbf0ae386
-0, 63, 63, 1, 38016, 0x0a8bd46e
-0, 64, 64, 1, 38016, 0xd437c5c1
-0, 65, 65, 1, 38016, 0xd61d9959
-0, 66, 66, 1, 38016, 0x70639b56
-0, 67, 67, 1, 38016, 0x36fd407b
-0, 68, 68, 1, 38016, 0x58ce3ddd
-0, 69, 69, 1, 38016, 0x86cc1d8c
-0, 70, 70, 1, 38016, 0xee422dc2
-0, 71, 71, 1, 38016, 0xab475639
-0, 72, 72, 1, 38016, 0xc1327ad8
-0, 73, 73, 1, 38016, 0x63d196d4
-0, 74, 74, 1, 38016, 0x1aba8ebd
-0, 75, 75, 1, 38016, 0x74a269ac
-0, 76, 76, 1, 38016, 0x267f3563
-0, 77, 77, 1, 38016, 0xa18ff180
-0, 78, 78, 1, 38016, 0x70c9c9fd
-0, 79, 79, 1, 38016, 0xa6c59f9c
-0, 80, 80, 1, 38016, 0xd7cd8927
-0, 81, 81, 1, 38016, 0xd30b7345
-0, 82, 82, 1, 38016, 0x679a4dda
-0, 83, 83, 1, 38016, 0xeb0562de
-0, 84, 84, 1, 38016, 0xdd7d6cdb
-0, 85, 85, 1, 38016, 0xd6e26b73
-0, 86, 86, 1, 38016, 0xa65a860f
-0, 87, 87, 1, 38016, 0xae95c71e
-0, 88, 88, 1, 38016, 0x1a89ca86
-0, 89, 89, 1, 38016, 0xa33ecee6
-0, 90, 90, 1, 38016, 0x821da6cb
-0, 91, 91, 1, 38016, 0xf0e1612f
-0, 92, 92, 1, 38016, 0x67b8516b
-0, 93, 93, 1, 38016, 0x62f965bc
-0, 94, 94, 1, 38016, 0xd1917aa6
-0, 95, 95, 1, 38016, 0xe72db54d
-0, 96, 96, 1, 38016, 0x9b64e721
-0, 97, 97, 1, 38016, 0xa819efda
-0, 98, 98, 1, 38016, 0xeacfdacb
-0, 99, 99, 1, 38016, 0x52f235e1
-0, 100, 100, 1, 38016, 0x2b512cb8
-0, 101, 101, 1, 38016, 0xaac73fb3
-0, 102, 102, 1, 38016, 0x7d2d504f
-0, 103, 103, 1, 38016, 0x396d503a
-0, 104, 104, 1, 38016, 0x97905235
-0, 105, 105, 1, 38016, 0xf0056693
-0, 106, 106, 1, 38016, 0x728a6a9e
-0, 107, 107, 1, 38016, 0x0eed7824
-0, 108, 108, 1, 38016, 0x59506237
-0, 109, 109, 1, 38016, 0xd4304c93
-0, 110, 110, 1, 38016, 0x7e663ee8
-0, 111, 111, 1, 38016, 0x0ebc2d11
-0, 112, 112, 1, 38016, 0x52db2112
-0, 113, 113, 1, 38016, 0x74aa1815
-0, 114, 114, 1, 38016, 0x57a60dc6
-0, 115, 115, 1, 38016, 0x86e9fa32
-0, 116, 116, 1, 38016, 0x67e8ff09
-0, 117, 117, 1, 38016, 0x26e8f7ea
-0, 118, 118, 1, 38016, 0x183dff56
-0, 119, 119, 1, 38016, 0xa470af8d
-0, 120, 120, 1, 38016, 0xe017d594
-0, 121, 121, 1, 38016, 0xb899d48b
-0, 122, 122, 1, 38016, 0x0d3bc5f7
-0, 123, 123, 1, 38016, 0xd68bbb0d
-0, 124, 124, 1, 38016, 0x8bf5b4cb
-0, 125, 125, 1, 38016, 0x6bfcaa47
-0, 126, 126, 1, 38016, 0x29a9b01b
-0, 127, 127, 1, 38016, 0xcdedbdb7
-0, 128, 128, 1, 38016, 0xdb5ad9c3
-0, 129, 129, 1, 38016, 0x468aeef6
-0, 130, 130, 1, 38016, 0xdc2b143e
-0, 131, 131, 1, 38016, 0x6776277c
-0, 132, 132, 1, 38016, 0xb78d5294
-0, 133, 133, 1, 38016, 0x1dfb63ab
-0, 134, 134, 1, 38016, 0xbd1f99bc
-0, 135, 135, 1, 38016, 0xde16b89a
-0, 136, 136, 1, 38016, 0xbf46edca
-0, 137, 137, 1, 38016, 0x6306e8c4
-0, 138, 138, 1, 38016, 0x7b09d224
-0, 139, 139, 1, 38016, 0xfea1aff6
-0, 140, 140, 1, 38016, 0x183686b0
-0, 141, 141, 1, 38016, 0x665a61ff
-0, 142, 142, 1, 38016, 0xc8af42d1
-0, 143, 143, 1, 38016, 0xe2326bc1
-0, 144, 144, 1, 38016, 0x56dbde82
-0, 145, 145, 1, 38016, 0xa0254f97
-0, 146, 146, 1, 38016, 0x3b74a0b4
-0, 147, 147, 1, 38016, 0x9aee9b7f
-0, 148, 148, 1, 38016, 0xd94b6133
-0, 149, 149, 1, 38016, 0x5819f795
-0, 150, 150, 1, 38016, 0xc45a8c02
-0, 151, 151, 1, 38016, 0x2f9204a0
-0, 152, 152, 1, 38016, 0xbe09e051
-0, 153, 153, 1, 38016, 0xb542badd
-0, 154, 154, 1, 38016, 0x23bd9e00
-0, 155, 155, 1, 38016, 0x4f338d3d
-0, 156, 156, 1, 38016, 0x8c91e8f3
-0, 157, 157, 1, 38016, 0xa7347d57
-0, 158, 158, 1, 38016, 0x6d91de4d
-0, 159, 159, 1, 38016, 0x3443d936
-0, 160, 160, 1, 38016, 0x9d25b4e2
-0, 161, 161, 1, 38016, 0xd93cd4b3
-0, 162, 162, 1, 38016, 0xa1c9e9a0
-0, 163, 163, 1, 38016, 0x1482f220
-0, 164, 164, 1, 38016, 0x1295f270
-0, 165, 165, 1, 38016, 0x399ae9da
-0, 166, 166, 1, 38016, 0x85dcdf28
-0, 167, 167, 1, 38016, 0x4207b9e5
-0, 168, 168, 1, 38016, 0xad1c9d75
-0, 169, 169, 1, 38016, 0x4a266c14
-0, 170, 170, 1, 38016, 0x3afc4508
-0, 171, 171, 1, 38016, 0x2b1b2385
-0, 172, 172, 1, 38016, 0x738f005f
-0, 173, 173, 1, 38016, 0xfec3d833
-0, 174, 174, 1, 38016, 0x3f7f6ae9
-0, 175, 175, 1, 38016, 0xd8551823
-0, 176, 176, 1, 38016, 0x6df03570
-0, 177, 177, 1, 38016, 0x767c3054
-0, 178, 178, 1, 38016, 0x89bd342c
-0, 179, 179, 1, 38016, 0x77ba806c
-0, 180, 180, 1, 38016, 0x1c98005c
-0, 181, 181, 1, 38016, 0xa13ce2a3
-0, 182, 182, 1, 38016, 0x1be59915
-0, 183, 183, 1, 38016, 0x279c6027
-0, 184, 184, 1, 38016, 0x96ac11a2
-0, 185, 185, 1, 38016, 0x3ae95131
-0, 186, 186, 1, 38016, 0xae19f7fe
-0, 187, 187, 1, 38016, 0xcde4efe6
-0, 188, 188, 1, 38016, 0x5ecc3f7a
-0, 189, 189, 1, 38016, 0x79645152
-0, 190, 190, 1, 38016, 0x1ee2e89f
-0, 191, 191, 1, 38016, 0x91d34bb4
-0, 192, 192, 1, 38016, 0xf019d464
-0, 193, 193, 1, 38016, 0x8eb07205
-0, 194, 194, 1, 38016, 0x5399bb5b
-0, 195, 195, 1, 38016, 0x61f0c77a
-0, 196, 196, 1, 38016, 0xb2bd8726
-0, 197, 197, 1, 38016, 0x47b89243
-0, 198, 198, 1, 38016, 0xebfe4d76
-0, 199, 199, 1, 38016, 0xe8f87d91
-0, 200, 200, 1, 38016, 0x5e9fb239
-0, 201, 201, 1, 38016, 0x357ca1f8
-0, 202, 202, 1, 38016, 0x757d2e02
-0, 203, 203, 1, 38016, 0x40672e7c
-0, 204, 204, 1, 38016, 0xd966abca
-0, 205, 205, 1, 38016, 0xe98d0d47
-0, 206, 206, 1, 38016, 0x341babf5
-0, 207, 207, 1, 38016, 0xd12d5a0c
-0, 208, 208, 1, 38016, 0xea2f99ab
-0, 209, 209, 1, 38016, 0x14bce88e
-0, 210, 210, 1, 38016, 0xe4bda9e8
-0, 211, 211, 1, 38016, 0x2c57ec89
-0, 212, 212, 1, 38016, 0x28bbb83e
-0, 213, 213, 1, 38016, 0xf8444b54
-0, 214, 214, 1, 38016, 0x3aba03cd
-0, 215, 215, 1, 38016, 0x373daa20
-0, 216, 216, 1, 38016, 0x69586597
-0, 217, 217, 1, 38016, 0xc0c70d53
-0, 218, 218, 1, 38016, 0x76a5df5a
-0, 219, 219, 1, 38016, 0x1afde8f0
-0, 220, 220, 1, 38016, 0x9638285a
-0, 221, 221, 1, 38016, 0x9f0686c0
-0, 222, 222, 1, 38016, 0xc65b2238
-0, 223, 223, 1, 38016, 0x0d61b610
-0, 224, 224, 1, 38016, 0x78e14e1f
-0, 225, 225, 1, 38016, 0xcf80ac4a
-0, 226, 226, 1, 38016, 0xe094083d
-0, 227, 227, 1, 38016, 0xee5e612e
-0, 228, 228, 1, 38016, 0x51cdad9d
-0, 229, 229, 1, 38016, 0xae41100e
-0, 230, 230, 1, 38016, 0x77558f58
-0, 231, 231, 1, 38016, 0xb9503b95
-0, 232, 232, 1, 38016, 0xb71dffeb
-0, 233, 233, 1, 38016, 0x1872e3e6
-0, 234, 234, 1, 38016, 0x29c3d252
-0, 235, 235, 1, 38016, 0x1c77c6ec
-0, 236, 236, 1, 38016, 0x26feb194
-0, 237, 237, 1, 38016, 0x3307c3c4
-0, 238, 238, 1, 38016, 0x8e5a8080
-0, 239, 239, 1, 38016, 0x933472f7
-0, 240, 240, 1, 38016, 0xd4768d84
-0, 241, 241, 1, 38016, 0x3324485f
-0, 242, 242, 1, 38016, 0xd50af078
-0, 243, 243, 1, 38016, 0x53820752
-0, 244, 244, 1, 38016, 0xbe7f1c47
-0, 245, 245, 1, 38016, 0xe43d3a34
-0, 246, 246, 1, 38016, 0x57194b82
-0, 247, 247, 1, 38016, 0x68a052ed
-0, 248, 248, 1, 38016, 0x5c898052
-0, 249, 249, 1, 38016, 0x7104a6ad
-0, 250, 250, 1, 38016, 0x1676b5e8
-0, 251, 251, 1, 38016, 0xe1cfd375
-0, 252, 252, 1, 38016, 0x16fede04
-0, 253, 253, 1, 38016, 0xca49dd4a
-0, 254, 254, 1, 38016, 0x7b98d9d1
-0, 255, 255, 1, 38016, 0x4020d210
-0, 256, 256, 1, 38016, 0x62c5d1e4
-0, 257, 257, 1, 38016, 0x756abdb4
-0, 258, 258, 1, 38016, 0x558fb00f
-0, 259, 259, 1, 38016, 0x4ab0b1f1
-0, 260, 260, 1, 38016, 0x7c9fb0c2
-0, 261, 261, 1, 38016, 0xcecfbdd0
-0, 262, 262, 1, 38016, 0x70e6d174
-0, 263, 263, 1, 38016, 0x83d7ddde
-0, 264, 264, 1, 38016, 0xbbcde2d9
-0, 265, 265, 1, 38016, 0xc89eeaef
-0, 266, 266, 1, 38016, 0x8565e15c
-0, 267, 267, 1, 38016, 0x28e0db24
-0, 268, 268, 1, 38016, 0x1d9dd334
-0, 269, 269, 1, 38016, 0xce02c452
-0, 270, 270, 1, 38016, 0xe29dbd0c
-0, 271, 271, 1, 38016, 0x4aa3b638
-0, 272, 272, 1, 38016, 0x5533c135
-0, 273, 273, 1, 38016, 0x6c57b65f
-0, 274, 274, 1, 38016, 0x23d3b851
-0, 275, 275, 1, 38016, 0xd8cbb960
-0, 276, 276, 1, 38016, 0x02edb916
-0, 277, 277, 1, 38016, 0xa622bd42
-0, 278, 278, 1, 38016, 0x4ba5be1c
-0, 279, 279, 1, 38016, 0xe69bb625
-0, 280, 280, 1, 38016, 0xbca5b292
-0, 281, 281, 1, 38016, 0xde38b1c8
-0, 282, 282, 1, 38016, 0xe9e3b617
-0, 283, 283, 1, 38016, 0x216cc574
-0, 284, 284, 1, 38016, 0x3780c5ad
-0, 285, 285, 1, 38016, 0x5531e3f9
-0, 286, 286, 1, 38016, 0xe2c5f5d4
-0, 287, 287, 1, 38016, 0x24cefc6e
-0, 288, 288, 1, 38016, 0xa3ce003d
-0, 289, 289, 1, 38016, 0x42d01c9e
-0, 290, 290, 1, 38016, 0xbfc13689
-0, 291, 291, 1, 38016, 0x122647a9
-0, 292, 292, 1, 38016, 0xe45254da
-0, 293, 293, 1, 38016, 0xad955b0c
-0, 294, 294, 1, 38016, 0x4b086abb
-0, 295, 295, 1, 38016, 0xd4857b8c
-0, 296, 296, 1, 38016, 0xa71594ce
-0, 297, 297, 1, 38016, 0x04e4a73d
-0, 298, 298, 1, 38016, 0x295abf63
-0, 299, 299, 1, 38016, 0xbe4ed5dd
-0, 300, 300, 1, 38016, 0x087bcf64
+0, 9, 9, 1, 38016, 0xda748c2f
+0, 10, 10, 1, 38016, 0x7b4dbff0
+0, 11, 11, 1, 38016, 0xd4a1b24a
+0, 12, 12, 1, 38016, 0x714cb4cc
+0, 13, 13, 1, 38016, 0x2c6d80f0
+0, 14, 14, 1, 38016, 0x92266151
+0, 15, 15, 1, 38016, 0x6b766a23
+0, 16, 16, 1, 38016, 0xb24f7efe
+0, 17, 17, 1, 38016, 0x8410838e
+0, 18, 18, 1, 38016, 0x67fe872a
+0, 19, 19, 1, 38016, 0x55b49d36
+0, 20, 20, 1, 38016, 0x7a1c9c41
+0, 21, 21, 1, 38016, 0xb4818e0e
+0, 22, 22, 1, 38016, 0x25f6683c
+0, 23, 23, 1, 38016, 0xe4d141a4
+0, 24, 24, 1, 38016, 0x808216ad
+0, 25, 25, 1, 38016, 0x2acf0baf
+0, 26, 26, 1, 38016, 0xf3de13c4
+0, 27, 27, 1, 38016, 0x5f412187
+0, 28, 28, 1, 38016, 0xb31a340a
+0, 29, 29, 1, 38016, 0x019d42d1
+0, 30, 30, 1, 38016, 0xeeb94b9b
+0, 31, 31, 1, 38016, 0xef55472e
+0, 32, 32, 1, 38016, 0xdb5e3697
+0, 33, 33, 1, 38016, 0x8565303e
+0, 34, 34, 1, 38016, 0x5f9c2c1b
+0, 35, 35, 1, 38016, 0xeb3d27f4
+0, 36, 36, 1, 38016, 0x9a43282d
+0, 37, 37, 1, 38016, 0xe04720c6
+0, 38, 38, 1, 38016, 0x19cc0eba
+0, 39, 39, 1, 38016, 0x218efeb6
+0, 40, 40, 1, 38016, 0x7733f491
+0, 41, 41, 1, 38016, 0x7f3bede9
+0, 42, 42, 1, 38016, 0x49c5ec0d
+0, 43, 43, 1, 38016, 0x803cf19e
+0, 44, 44, 1, 38016, 0x31de0d3f
+0, 45, 45, 1, 38016, 0xa7e30426
+0, 46, 46, 1, 38016, 0xba37f068
+0, 47, 47, 1, 38016, 0x2842bdf8
+0, 48, 48, 1, 38016, 0x76df97dc
+0, 49, 49, 1, 38016, 0xf3246d26
+0, 50, 50, 1, 38016, 0x0a384d72
+0, 51, 51, 1, 38016, 0x40964f41
+0, 52, 52, 1, 38016, 0x46364324
+0, 53, 53, 1, 38016, 0x7cbf3db4
+0, 54, 54, 1, 38016, 0x7a223bec
+0, 55, 55, 1, 38016, 0x458651c1
+0, 56, 56, 1, 38016, 0xb82d7e3c
+0, 57, 57, 1, 38016, 0x0f50a55d
+0, 58, 58, 1, 38016, 0xc306cae4
+0, 59, 59, 1, 38016, 0x9d6ddfcb
+0, 60, 60, 1, 38016, 0xb602e8e9
+0, 61, 61, 1, 38016, 0xbf0ae386
+0, 62, 62, 1, 38016, 0x0a8bd46e
+0, 63, 63, 1, 38016, 0xd437c5c1
+0, 64, 64, 1, 38016, 0xd61d9959
+0, 65, 65, 1, 38016, 0x70639b56
+0, 66, 66, 1, 38016, 0x36fd407b
+0, 67, 67, 1, 38016, 0x58ce3ddd
+0, 68, 68, 1, 38016, 0x86cc1d8c
+0, 69, 69, 1, 38016, 0xee422dc2
+0, 70, 70, 1, 38016, 0xab475639
+0, 71, 71, 1, 38016, 0xc1327ad8
+0, 72, 72, 1, 38016, 0x63d196d4
+0, 73, 73, 1, 38016, 0x1aba8ebd
+0, 74, 74, 1, 38016, 0x74a269ac
+0, 75, 75, 1, 38016, 0x267f3563
+0, 76, 76, 1, 38016, 0xa18ff180
+0, 77, 77, 1, 38016, 0x70c9c9fd
+0, 78, 78, 1, 38016, 0xa6c59f9c
+0, 79, 79, 1, 38016, 0xd7cd8927
+0, 80, 80, 1, 38016, 0xd30b7345
+0, 81, 81, 1, 38016, 0x679a4dda
+0, 82, 82, 1, 38016, 0xeb0562de
+0, 83, 83, 1, 38016, 0xdd7d6cdb
+0, 84, 84, 1, 38016, 0xd6e26b73
+0, 85, 85, 1, 38016, 0xa65a860f
+0, 86, 86, 1, 38016, 0xae95c71e
+0, 87, 87, 1, 38016, 0x1a89ca86
+0, 88, 88, 1, 38016, 0xa33ecee6
+0, 89, 89, 1, 38016, 0x821da6cb
+0, 90, 90, 1, 38016, 0xf0e1612f
+0, 91, 91, 1, 38016, 0x67b8516b
+0, 92, 92, 1, 38016, 0x62f965bc
+0, 93, 93, 1, 38016, 0xd1917aa6
+0, 94, 94, 1, 38016, 0xe72db54d
+0, 95, 95, 1, 38016, 0x9b64e721
+0, 96, 96, 1, 38016, 0xa819efda
+0, 97, 97, 1, 38016, 0xeacfdacb
+0, 98, 98, 1, 38016, 0x52f235e1
+0, 99, 99, 1, 38016, 0x2b512cb8
+0, 100, 100, 1, 38016, 0xaac73fb3
+0, 101, 101, 1, 38016, 0x7d2d504f
+0, 102, 102, 1, 38016, 0x396d503a
+0, 103, 103, 1, 38016, 0x97905235
+0, 104, 104, 1, 38016, 0xf0056693
+0, 105, 105, 1, 38016, 0x728a6a9e
+0, 106, 106, 1, 38016, 0x0eed7824
+0, 107, 107, 1, 38016, 0x59506237
+0, 108, 108, 1, 38016, 0xd4304c93
+0, 109, 109, 1, 38016, 0x7e663ee8
+0, 110, 110, 1, 38016, 0x0ebc2d11
+0, 111, 111, 1, 38016, 0x52db2112
+0, 112, 112, 1, 38016, 0x74aa1815
+0, 113, 113, 1, 38016, 0x57a60dc6
+0, 114, 114, 1, 38016, 0x86e9fa32
+0, 115, 115, 1, 38016, 0x67e8ff09
+0, 116, 116, 1, 38016, 0x26e8f7ea
+0, 117, 117, 1, 38016, 0x183dff56
+0, 118, 118, 1, 38016, 0xa470af8d
+0, 119, 119, 1, 38016, 0xe017d594
+0, 120, 120, 1, 38016, 0xb899d48b
+0, 121, 121, 1, 38016, 0x0d3bc5f7
+0, 122, 122, 1, 38016, 0xd68bbb0d
+0, 123, 123, 1, 38016, 0x8bf5b4cb
+0, 124, 124, 1, 38016, 0x6bfcaa47
+0, 125, 125, 1, 38016, 0x29a9b01b
+0, 126, 126, 1, 38016, 0xcdedbdb7
+0, 127, 127, 1, 38016, 0xdb5ad9c3
+0, 128, 128, 1, 38016, 0x468aeef6
+0, 129, 129, 1, 38016, 0xdc2b143e
+0, 130, 130, 1, 38016, 0x6776277c
+0, 131, 131, 1, 38016, 0xb78d5294
+0, 132, 132, 1, 38016, 0x1dfb63ab
+0, 133, 133, 1, 38016, 0xbd1f99bc
+0, 134, 134, 1, 38016, 0xde16b89a
+0, 135, 135, 1, 38016, 0xbf46edca
+0, 136, 136, 1, 38016, 0x6306e8c4
+0, 137, 137, 1, 38016, 0x7b09d224
+0, 138, 138, 1, 38016, 0xfea1aff6
+0, 139, 139, 1, 38016, 0x183686b0
+0, 140, 140, 1, 38016, 0x665a61ff
+0, 141, 141, 1, 38016, 0xc8af42d1
+0, 142, 142, 1, 38016, 0xe2326bc1
+0, 143, 143, 1, 38016, 0x56dbde82
+0, 144, 144, 1, 38016, 0xa0254f97
+0, 145, 145, 1, 38016, 0x3b74a0b4
+0, 146, 146, 1, 38016, 0x9aee9b7f
+0, 147, 147, 1, 38016, 0xd94b6133
+0, 148, 148, 1, 38016, 0x5819f795
+0, 149, 149, 1, 38016, 0xc45a8c02
+0, 150, 150, 1, 38016, 0x2f9204a0
+0, 151, 151, 1, 38016, 0xbe09e051
+0, 152, 152, 1, 38016, 0xb542badd
+0, 153, 153, 1, 38016, 0x23bd9e00
+0, 154, 154, 1, 38016, 0x4f338d3d
+0, 155, 155, 1, 38016, 0x8c91e8f3
+0, 156, 156, 1, 38016, 0xa7347d57
+0, 157, 157, 1, 38016, 0x6d91de4d
+0, 158, 158, 1, 38016, 0x3443d936
+0, 159, 159, 1, 38016, 0x9d25b4e2
+0, 160, 160, 1, 38016, 0xd93cd4b3
+0, 161, 161, 1, 38016, 0xa1c9e9a0
+0, 162, 162, 1, 38016, 0x1482f220
+0, 163, 163, 1, 38016, 0x1295f270
+0, 164, 164, 1, 38016, 0x399ae9da
+0, 165, 165, 1, 38016, 0x85dcdf28
+0, 166, 166, 1, 38016, 0x4207b9e5
+0, 167, 167, 1, 38016, 0xad1c9d75
+0, 168, 168, 1, 38016, 0x4a266c14
+0, 169, 169, 1, 38016, 0x3afc4508
+0, 170, 170, 1, 38016, 0x2b1b2385
+0, 171, 171, 1, 38016, 0x738f005f
+0, 172, 172, 1, 38016, 0xfec3d833
+0, 173, 173, 1, 38016, 0x3f7f6ae9
+0, 174, 174, 1, 38016, 0xd8551823
+0, 175, 175, 1, 38016, 0x6df03570
+0, 176, 176, 1, 38016, 0x767c3054
+0, 177, 177, 1, 38016, 0x89bd342c
+0, 178, 178, 1, 38016, 0x77ba806c
+0, 179, 179, 1, 38016, 0x1c98005c
+0, 180, 180, 1, 38016, 0xa13ce2a3
+0, 181, 181, 1, 38016, 0x1be59915
+0, 182, 182, 1, 38016, 0x279c6027
+0, 183, 183, 1, 38016, 0x96ac11a2
+0, 184, 184, 1, 38016, 0x3ae95131
+0, 185, 185, 1, 38016, 0xae19f7fe
+0, 186, 186, 1, 38016, 0xcde4efe6
+0, 187, 187, 1, 38016, 0x5ecc3f7a
+0, 188, 188, 1, 38016, 0x79645152
+0, 189, 189, 1, 38016, 0x1ee2e89f
+0, 190, 190, 1, 38016, 0x91d34bb4
+0, 191, 191, 1, 38016, 0xf019d464
+0, 192, 192, 1, 38016, 0x8eb07205
+0, 193, 193, 1, 38016, 0x5399bb5b
+0, 194, 194, 1, 38016, 0x61f0c77a
+0, 195, 195, 1, 38016, 0xb2bd8726
+0, 196, 196, 1, 38016, 0x47b89243
+0, 197, 197, 1, 38016, 0xebfe4d76
+0, 198, 198, 1, 38016, 0xe8f87d91
+0, 199, 199, 1, 38016, 0x5e9fb239
+0, 200, 200, 1, 38016, 0x357ca1f8
+0, 201, 201, 1, 38016, 0x757d2e02
+0, 202, 202, 1, 38016, 0x40672e7c
+0, 203, 203, 1, 38016, 0xd966abca
+0, 204, 204, 1, 38016, 0xe98d0d47
+0, 205, 205, 1, 38016, 0x341babf5
+0, 206, 206, 1, 38016, 0xd12d5a0c
+0, 207, 207, 1, 38016, 0xea2f99ab
+0, 208, 208, 1, 38016, 0x14bce88e
+0, 209, 209, 1, 38016, 0xe4bda9e8
+0, 210, 210, 1, 38016, 0x2c57ec89
+0, 211, 211, 1, 38016, 0x28bbb83e
+0, 212, 212, 1, 38016, 0xf8444b54
+0, 213, 213, 1, 38016, 0x3aba03cd
+0, 214, 214, 1, 38016, 0x373daa20
+0, 215, 215, 1, 38016, 0x69586597
+0, 216, 216, 1, 38016, 0xc0c70d53
+0, 217, 217, 1, 38016, 0x76a5df5a
+0, 218, 218, 1, 38016, 0x1afde8f0
+0, 219, 219, 1, 38016, 0x9638285a
+0, 220, 220, 1, 38016, 0x9f0686c0
+0, 221, 221, 1, 38016, 0xc65b2238
+0, 222, 222, 1, 38016, 0x0d61b610
+0, 223, 223, 1, 38016, 0x78e14e1f
+0, 224, 224, 1, 38016, 0xcf80ac4a
+0, 225, 225, 1, 38016, 0xe094083d
+0, 226, 226, 1, 38016, 0xee5e612e
+0, 227, 227, 1, 38016, 0x51cdad9d
+0, 228, 228, 1, 38016, 0xae41100e
+0, 229, 229, 1, 38016, 0x77558f58
+0, 230, 230, 1, 38016, 0xb9503b95
+0, 231, 231, 1, 38016, 0xb71dffeb
+0, 232, 232, 1, 38016, 0x1872e3e6
+0, 233, 233, 1, 38016, 0x29c3d252
+0, 234, 234, 1, 38016, 0x1c77c6ec
+0, 235, 235, 1, 38016, 0x26feb194
+0, 236, 236, 1, 38016, 0x3307c3c4
+0, 237, 237, 1, 38016, 0x8e5a8080
+0, 238, 238, 1, 38016, 0x933472f7
+0, 239, 239, 1, 38016, 0xd4768d84
+0, 240, 240, 1, 38016, 0x3324485f
+0, 241, 241, 1, 38016, 0xd50af078
+0, 242, 242, 1, 38016, 0x53820752
+0, 243, 243, 1, 38016, 0xbe7f1c47
+0, 244, 244, 1, 38016, 0xe43d3a34
+0, 245, 245, 1, 38016, 0x57194b82
+0, 246, 246, 1, 38016, 0x68a052ed
+0, 247, 247, 1, 38016, 0x5c898052
+0, 248, 248, 1, 38016, 0x7104a6ad
+0, 249, 249, 1, 38016, 0x1676b5e8
+0, 250, 250, 1, 38016, 0xe1cfd375
+0, 251, 251, 1, 38016, 0x16fede04
+0, 252, 252, 1, 38016, 0xca49dd4a
+0, 253, 253, 1, 38016, 0x7b98d9d1
+0, 254, 254, 1, 38016, 0x4020d210
+0, 255, 255, 1, 38016, 0x62c5d1e4
+0, 256, 256, 1, 38016, 0x756abdb4
+0, 257, 257, 1, 38016, 0x558fb00f
+0, 258, 258, 1, 38016, 0x4ab0b1f1
+0, 259, 259, 1, 38016, 0x7c9fb0c2
+0, 260, 260, 1, 38016, 0xcecfbdd0
+0, 261, 261, 1, 38016, 0x70e6d174
+0, 262, 262, 1, 38016, 0x83d7ddde
+0, 263, 263, 1, 38016, 0xbbcde2d9
+0, 264, 264, 1, 38016, 0xc89eeaef
+0, 265, 265, 1, 38016, 0x8565e15c
+0, 266, 266, 1, 38016, 0x28e0db24
+0, 267, 267, 1, 38016, 0x1d9dd334
+0, 268, 268, 1, 38016, 0xce02c452
+0, 269, 269, 1, 38016, 0xe29dbd0c
+0, 270, 270, 1, 38016, 0x4aa3b638
+0, 271, 271, 1, 38016, 0x5533c135
+0, 272, 272, 1, 38016, 0x6c57b65f
+0, 273, 273, 1, 38016, 0x23d3b851
+0, 274, 274, 1, 38016, 0xd8cbb960
+0, 275, 275, 1, 38016, 0x02edb916
+0, 276, 276, 1, 38016, 0xa622bd42
+0, 277, 277, 1, 38016, 0x4ba5be1c
+0, 278, 278, 1, 38016, 0xe69bb625
+0, 279, 279, 1, 38016, 0xbca5b292
+0, 280, 280, 1, 38016, 0xde38b1c8
+0, 281, 281, 1, 38016, 0xe9e3b617
+0, 282, 282, 1, 38016, 0x216cc574
+0, 283, 283, 1, 38016, 0x3780c5ad
+0, 284, 284, 1, 38016, 0x5531e3f9
+0, 285, 285, 1, 38016, 0xe2c5f5d4
+0, 286, 286, 1, 38016, 0x24cefc6e
+0, 287, 287, 1, 38016, 0xa3ce003d
+0, 288, 288, 1, 38016, 0x42d01c9e
+0, 289, 289, 1, 38016, 0xbfc13689
+0, 290, 290, 1, 38016, 0x122647a9
+0, 291, 291, 1, 38016, 0xe45254da
+0, 292, 292, 1, 38016, 0xad955b0c
+0, 293, 293, 1, 38016, 0x4b086abb
+0, 294, 294, 1, 38016, 0xd4857b8c
+0, 295, 295, 1, 38016, 0xa71594ce
+0, 296, 296, 1, 38016, 0x04e4a73d
+0, 297, 297, 1, 38016, 0x295abf63
+0, 298, 298, 1, 38016, 0xbe4ed5dd
+0, 299, 299, 1, 38016, 0x087bcf64
diff --git a/tests/ref/fate/h264-conformance-mr6_bt_b b/tests/ref/fate/h264-conformance-mr6_bt_b
index 4a46efe..3b02506 100644
--- a/tests/ref/fate/h264-conformance-mr6_bt_b
+++ b/tests/ref/fate/h264-conformance-mr6_bt_b
@@ -1,61 +1,61 @@
#tb 0: 1/25
-0, 1, 1, 1, 36864, 0x954464be
-0, 3, 3, 1, 36864, 0xace1d90b
-0, 5, 5, 1, 36864, 0x8f149f03
-0, 7, 7, 1, 36864, 0xea9b21eb
-0, 9, 9, 1, 36864, 0xb51d9fe3
-0, 11, 11, 1, 36864, 0x61bd11d7
-0, 13, 13, 1, 36864, 0x9d36980f
-0, 15, 15, 1, 36864, 0xa4192c5e
-0, 17, 17, 1, 36864, 0x11006433
-0, 19, 19, 1, 36864, 0x4a243e46
-0, 21, 21, 1, 36864, 0x1807b5e8
-0, 23, 23, 1, 36864, 0xbe37743c
-0, 25, 25, 1, 36864, 0x82491319
-0, 27, 27, 1, 36864, 0x006e9914
-0, 29, 29, 1, 36864, 0xa5261884
-0, 31, 31, 1, 36864, 0x2030c9d6
-0, 33, 33, 1, 36864, 0xc80eb1ce
-0, 35, 35, 1, 36864, 0x4d559791
-0, 37, 37, 1, 36864, 0xf5f900ee
-0, 39, 39, 1, 36864, 0x2cc9c0d7
-0, 41, 41, 1, 36864, 0x5ba14186
-0, 43, 43, 1, 36864, 0x47a46865
-0, 45, 45, 1, 36864, 0x5ba180b7
-0, 47, 47, 1, 36864, 0xc67c4876
-0, 49, 49, 1, 36864, 0x4311d75d
-0, 51, 51, 1, 36864, 0x56edb851
-0, 53, 53, 1, 36864, 0x7e5aa3e0
-0, 55, 55, 1, 36864, 0x8df8283a
-0, 57, 57, 1, 36864, 0xb8583ddf
-0, 59, 59, 1, 36864, 0xf33fb779
-0, 61, 61, 1, 36864, 0xe9942ddc
-0, 63, 63, 1, 36864, 0x2bc5f7fa
-0, 65, 65, 1, 36864, 0xc7b66c65
-0, 67, 67, 1, 36864, 0x1a524319
-0, 69, 69, 1, 36864, 0xf60c6141
-0, 71, 71, 1, 36864, 0x113f41f2
-0, 73, 73, 1, 36864, 0xad191a31
-0, 75, 75, 1, 36864, 0x3898264a
-0, 77, 77, 1, 36864, 0x3c2f34a4
-0, 79, 79, 1, 36864, 0xd0fc76aa
-0, 81, 81, 1, 36864, 0x2870b546
-0, 83, 83, 1, 36864, 0x7d326fb4
-0, 85, 85, 1, 36864, 0xd7ed14e1
-0, 87, 87, 1, 36864, 0x205174aa
-0, 89, 89, 1, 36864, 0xa3a88be9
-0, 91, 91, 1, 36864, 0xd6f01751
-0, 93, 93, 1, 36864, 0x5420bb80
-0, 95, 95, 1, 36864, 0xe14518f9
-0, 97, 97, 1, 36864, 0x931db61e
-0, 99, 99, 1, 36864, 0x052ecfae
-0, 101, 101, 1, 36864, 0x29b1b0f5
-0, 103, 103, 1, 36864, 0xa3057117
-0, 105, 105, 1, 36864, 0x954464be
-0, 107, 107, 1, 36864, 0xace1d90b
-0, 109, 109, 1, 36864, 0x8f149f03
-0, 111, 111, 1, 36864, 0x485722c5
-0, 113, 113, 1, 36864, 0x534b18f9
-0, 115, 115, 1, 36864, 0xc893a0a6
-0, 117, 117, 1, 36864, 0x8b04e1dd
-0, 119, 119, 1, 36864, 0xaf536964
+0, 0, 0, 1, 36864, 0x954464be
+0, 1, 1, 1, 36864, 0xace1d90b
+0, 2, 2, 1, 36864, 0x8f149f03
+0, 3, 3, 1, 36864, 0xea9b21eb
+0, 4, 4, 1, 36864, 0xb51d9fe3
+0, 5, 5, 1, 36864, 0x61bd11d7
+0, 6, 6, 1, 36864, 0x9d36980f
+0, 7, 7, 1, 36864, 0xa4192c5e
+0, 8, 8, 1, 36864, 0x11006433
+0, 9, 9, 1, 36864, 0x4a243e46
+0, 10, 10, 1, 36864, 0x1807b5e8
+0, 11, 11, 1, 36864, 0xbe37743c
+0, 12, 12, 1, 36864, 0x82491319
+0, 13, 13, 1, 36864, 0x006e9914
+0, 14, 14, 1, 36864, 0xa5261884
+0, 15, 15, 1, 36864, 0x2030c9d6
+0, 16, 16, 1, 36864, 0xc80eb1ce
+0, 17, 17, 1, 36864, 0x4d559791
+0, 18, 18, 1, 36864, 0xf5f900ee
+0, 19, 19, 1, 36864, 0x2cc9c0d7
+0, 20, 20, 1, 36864, 0x5ba14186
+0, 21, 21, 1, 36864, 0x47a46865
+0, 22, 22, 1, 36864, 0x5ba180b7
+0, 23, 23, 1, 36864, 0xc67c4876
+0, 24, 24, 1, 36864, 0x4311d75d
+0, 25, 25, 1, 36864, 0x56edb851
+0, 26, 26, 1, 36864, 0x7e5aa3e0
+0, 27, 27, 1, 36864, 0x8df8283a
+0, 28, 28, 1, 36864, 0xb8583ddf
+0, 29, 29, 1, 36864, 0xf33fb779
+0, 30, 30, 1, 36864, 0xe9942ddc
+0, 31, 31, 1, 36864, 0x2bc5f7fa
+0, 32, 32, 1, 36864, 0xc7b66c65
+0, 33, 33, 1, 36864, 0x1a524319
+0, 34, 34, 1, 36864, 0xf60c6141
+0, 35, 35, 1, 36864, 0x113f41f2
+0, 36, 36, 1, 36864, 0xad191a31
+0, 37, 37, 1, 36864, 0x3898264a
+0, 38, 38, 1, 36864, 0x3c2f34a4
+0, 39, 39, 1, 36864, 0xd0fc76aa
+0, 40, 40, 1, 36864, 0x2870b546
+0, 41, 41, 1, 36864, 0x7d326fb4
+0, 42, 42, 1, 36864, 0xd7ed14e1
+0, 43, 43, 1, 36864, 0x205174aa
+0, 44, 44, 1, 36864, 0xa3a88be9
+0, 45, 45, 1, 36864, 0xd6f01751
+0, 46, 46, 1, 36864, 0x5420bb80
+0, 47, 47, 1, 36864, 0xe14518f9
+0, 48, 48, 1, 36864, 0x931db61e
+0, 49, 49, 1, 36864, 0x052ecfae
+0, 50, 50, 1, 36864, 0x29b1b0f5
+0, 51, 51, 1, 36864, 0xa3057117
+0, 52, 52, 1, 36864, 0x954464be
+0, 53, 53, 1, 36864, 0xace1d90b
+0, 54, 54, 1, 36864, 0x8f149f03
+0, 55, 55, 1, 36864, 0x485722c5
+0, 56, 56, 1, 36864, 0x534b18f9
+0, 57, 57, 1, 36864, 0xc893a0a6
+0, 58, 58, 1, 36864, 0x8b04e1dd
+0, 59, 59, 1, 36864, 0xaf536964
diff --git a/tests/ref/fate/h264-conformance-mr7_bt_b b/tests/ref/fate/h264-conformance-mr7_bt_b
index f1e561e..25b7054 100644
--- a/tests/ref/fate/h264-conformance-mr7_bt_b
+++ b/tests/ref/fate/h264-conformance-mr7_bt_b
@@ -9,53 +9,53 @@
0, 7, 7, 1, 36864, 0xf2f324dd
0, 8, 8, 1, 36864, 0x592b5a01
0, 9, 9, 1, 36864, 0x4c2f2d91
-0, 11, 11, 1, 36864, 0x8baeb610
-0, 13, 13, 1, 36864, 0x86d47617
-0, 14, 14, 1, 36864, 0xf11011cc
-0, 15, 15, 1, 36864, 0xe56a9daa
-0, 16, 16, 1, 36864, 0xd57119d6
-0, 17, 17, 1, 36864, 0xe28fcde7
-0, 18, 18, 1, 36864, 0x9aeeba86
-0, 19, 19, 1, 36864, 0xa518a7c5
-0, 20, 20, 1, 36864, 0x9af410be
-0, 22, 22, 1, 36864, 0x1fedd12f
-0, 23, 23, 1, 36864, 0xa8032e03
-0, 24, 24, 1, 36864, 0x579e6274
-0, 25, 25, 1, 36864, 0x99846ef6
-0, 26, 26, 1, 36864, 0xb5ad3ca7
-0, 27, 27, 1, 36864, 0x7845cb90
-0, 28, 28, 1, 36864, 0x569fae24
-0, 29, 29, 1, 36864, 0x8a3c9f98
-0, 30, 30, 1, 36864, 0x0b7722af
-0, 31, 31, 1, 36864, 0x699c2dd8
-0, 32, 32, 1, 36864, 0xd477af13
-0, 33, 33, 1, 36864, 0x17b62d7c
-0, 34, 34, 1, 36864, 0xb1ecf6a7
-0, 35, 35, 1, 36864, 0xf9c17e4c
-0, 36, 36, 1, 36864, 0xe7c44618
-0, 37, 37, 1, 36864, 0x7e23654e
-0, 38, 38, 1, 36864, 0xd8a0457c
-0, 39, 39, 1, 36864, 0x57e11df1
-0, 40, 40, 1, 36864, 0xd54d2a43
-0, 41, 41, 1, 36864, 0xc6f03950
-0, 42, 42, 1, 36864, 0x687e750e
-0, 44, 44, 1, 36864, 0x2870b546
-0, 46, 46, 1, 36864, 0xda0370d0
-0, 47, 47, 1, 36864, 0x5a2e0bff
-0, 49, 49, 1, 36864, 0xe1f07533
-0, 50, 50, 1, 36864, 0x3de892b9
-0, 51, 51, 1, 36864, 0xe5c31505
-0, 52, 52, 1, 36864, 0x96b8c082
-0, 53, 53, 1, 36864, 0x55391423
-0, 54, 54, 1, 36864, 0xc285bd71
-0, 55, 55, 1, 36864, 0xf702d9f3
-0, 56, 56, 1, 36864, 0x7afbadf8
-0, 57, 57, 1, 36864, 0xd9b568f7
-0, 58, 58, 1, 36864, 0x579e6274
-0, 59, 59, 1, 36864, 0x8650c61c
-0, 60, 60, 1, 36864, 0xbc359647
-0, 61, 61, 1, 36864, 0x5522328c
-0, 62, 62, 1, 36864, 0x02821fd6
-0, 63, 63, 1, 36864, 0xb4ee9562
-0, 64, 64, 1, 36864, 0xcefedb68
-0, 65, 65, 1, 36864, 0xd959782e
+0, 10, 10, 1, 36864, 0x8baeb610
+0, 11, 11, 1, 36864, 0x86d47617
+0, 12, 12, 1, 36864, 0xf11011cc
+0, 13, 13, 1, 36864, 0xe56a9daa
+0, 14, 14, 1, 36864, 0xd57119d6
+0, 15, 15, 1, 36864, 0xe28fcde7
+0, 16, 16, 1, 36864, 0x9aeeba86
+0, 17, 17, 1, 36864, 0xa518a7c5
+0, 18, 18, 1, 36864, 0x9af410be
+0, 19, 19, 1, 36864, 0x1fedd12f
+0, 20, 20, 1, 36864, 0xa8032e03
+0, 21, 21, 1, 36864, 0x579e6274
+0, 22, 22, 1, 36864, 0x99846ef6
+0, 23, 23, 1, 36864, 0xb5ad3ca7
+0, 24, 24, 1, 36864, 0x7845cb90
+0, 25, 25, 1, 36864, 0x569fae24
+0, 26, 26, 1, 36864, 0x8a3c9f98
+0, 27, 27, 1, 36864, 0x0b7722af
+0, 28, 28, 1, 36864, 0x699c2dd8
+0, 29, 29, 1, 36864, 0xd477af13
+0, 30, 30, 1, 36864, 0x17b62d7c
+0, 31, 31, 1, 36864, 0xb1ecf6a7
+0, 32, 32, 1, 36864, 0xf9c17e4c
+0, 33, 33, 1, 36864, 0xe7c44618
+0, 34, 34, 1, 36864, 0x7e23654e
+0, 35, 35, 1, 36864, 0xd8a0457c
+0, 36, 36, 1, 36864, 0x57e11df1
+0, 37, 37, 1, 36864, 0xd54d2a43
+0, 38, 38, 1, 36864, 0xc6f03950
+0, 39, 39, 1, 36864, 0x687e750e
+0, 40, 40, 1, 36864, 0x2870b546
+0, 41, 41, 1, 36864, 0xda0370d0
+0, 42, 42, 1, 36864, 0x5a2e0bff
+0, 43, 43, 1, 36864, 0xe1f07533
+0, 44, 44, 1, 36864, 0x3de892b9
+0, 45, 45, 1, 36864, 0xe5c31505
+0, 46, 46, 1, 36864, 0x96b8c082
+0, 47, 47, 1, 36864, 0x55391423
+0, 48, 48, 1, 36864, 0xc285bd71
+0, 49, 49, 1, 36864, 0xf702d9f3
+0, 50, 50, 1, 36864, 0x7afbadf8
+0, 51, 51, 1, 36864, 0xd9b568f7
+0, 52, 52, 1, 36864, 0x579e6274
+0, 53, 53, 1, 36864, 0x8650c61c
+0, 54, 54, 1, 36864, 0xbc359647
+0, 55, 55, 1, 36864, 0x5522328c
+0, 56, 56, 1, 36864, 0x02821fd6
+0, 57, 57, 1, 36864, 0xb4ee9562
+0, 58, 58, 1, 36864, 0xcefedb68
+0, 59, 59, 1, 36864, 0xd959782e
diff --git a/tests/ref/fate/h264-conformance-mr8_bt_b b/tests/ref/fate/h264-conformance-mr8_bt_b
index 8b299ec..220acf1 100644
--- a/tests/ref/fate/h264-conformance-mr8_bt_b
+++ b/tests/ref/fate/h264-conformance-mr8_bt_b
@@ -1,59 +1,59 @@
#tb 0: 1/25
-0, 2, 2, 1, 36864, 0x36df68f4
-0, 4, 4, 1, 36864, 0x52d4c6d9
-0, 6, 6, 1, 36864, 0xad16b0be
-0, 8, 8, 1, 36864, 0xf8c72556
-0, 10, 10, 1, 36864, 0x70aaad30
-0, 12, 12, 1, 36864, 0x53cffd5e
-0, 14, 14, 1, 36864, 0xb3fa8abc
-0, 16, 16, 1, 36864, 0x9c894009
-0, 18, 18, 1, 36864, 0xfbc08050
-0, 20, 20, 1, 36864, 0x9d5b2d65
-0, 22, 22, 1, 36864, 0x3bd8bb5d
-0, 24, 24, 1, 36864, 0x8d976ecf
-0, 26, 26, 1, 36864, 0x25010368
-0, 28, 28, 1, 36864, 0xb6e6a11c
-0, 30, 30, 1, 36864, 0x595a3967
-0, 32, 32, 1, 36864, 0x4fbcb9a8
-0, 34, 34, 1, 36864, 0xc7c5c16b
-0, 36, 36, 1, 36864, 0x661ae1eb
-0, 38, 38, 1, 36864, 0x169f04a7
-0, 40, 40, 1, 36864, 0xd124c93a
-0, 42, 42, 1, 36864, 0x3f642dba
-0, 44, 44, 1, 36864, 0xe7ad6956
-0, 46, 46, 1, 36864, 0x47dc76d3
-0, 48, 48, 1, 36864, 0x496a3917
-0, 50, 50, 1, 36864, 0xa976d5f3
-0, 52, 52, 1, 36864, 0x507bb685
-0, 54, 54, 1, 36864, 0x2f61ac12
-0, 56, 56, 1, 36864, 0x527818d8
-0, 58, 58, 1, 36864, 0xa4983396
-0, 60, 60, 1, 36864, 0x3ec9b07b
-0, 62, 62, 1, 36864, 0x7db52d99
-0, 64, 64, 1, 36864, 0xe974fd00
-0, 66, 66, 1, 36864, 0x9c677a4f
-0, 68, 68, 1, 36864, 0x108f3a05
-0, 70, 70, 1, 36864, 0x23a56ba2
-0, 72, 72, 1, 36864, 0x4c8d47e8
-0, 74, 74, 1, 36864, 0x9e0b0f09
-0, 76, 76, 1, 36864, 0x4d262b16
-0, 78, 78, 1, 36864, 0x6122402e
-0, 80, 80, 1, 36864, 0xed037036
-0, 82, 82, 1, 36864, 0x62b3ba08
-0, 84, 84, 1, 36864, 0x7f876930
-0, 86, 86, 1, 36864, 0x4a6c0983
-0, 88, 88, 1, 36864, 0xf9787086
-0, 90, 90, 1, 36864, 0x01d1b1b5
-0, 92, 92, 1, 36864, 0xc1622655
-0, 94, 94, 1, 36864, 0x27e8e0f7
-0, 96, 96, 1, 36864, 0xc1622655
-0, 98, 98, 1, 36864, 0x12c2b7e9
-0, 100, 100, 1, 36864, 0xd752d2ef
-0, 102, 102, 1, 36864, 0xcbb1c3a7
-0, 104, 104, 1, 36864, 0x18c56fba
-0, 106, 106, 1, 36864, 0xb1b3771c
-0, 108, 108, 1, 36864, 0x284ef3c4
-0, 110, 110, 1, 36864, 0xda6eb5a0
-0, 112, 112, 1, 36864, 0x17ad337c
-0, 114, 114, 1, 36864, 0xe2801e4f
-0, 115, 115, 1, 36864, 0x6c33bd17
+0, 0, 0, 1, 36864, 0x36df68f4
+0, 1, 1, 1, 36864, 0x52d4c6d9
+0, 2, 2, 1, 36864, 0xad16b0be
+0, 3, 3, 1, 36864, 0xf8c72556
+0, 4, 4, 1, 36864, 0x70aaad30
+0, 5, 5, 1, 36864, 0x53cffd5e
+0, 6, 6, 1, 36864, 0xb3fa8abc
+0, 7, 7, 1, 36864, 0x9c894009
+0, 8, 8, 1, 36864, 0xfbc08050
+0, 9, 9, 1, 36864, 0x9d5b2d65
+0, 10, 10, 1, 36864, 0x3bd8bb5d
+0, 11, 11, 1, 36864, 0x8d976ecf
+0, 12, 12, 1, 36864, 0x25010368
+0, 13, 13, 1, 36864, 0xb6e6a11c
+0, 14, 14, 1, 36864, 0x595a3967
+0, 15, 15, 1, 36864, 0x4fbcb9a8
+0, 16, 16, 1, 36864, 0xc7c5c16b
+0, 17, 17, 1, 36864, 0x661ae1eb
+0, 18, 18, 1, 36864, 0x169f04a7
+0, 19, 19, 1, 36864, 0xd124c93a
+0, 20, 20, 1, 36864, 0x3f642dba
+0, 21, 21, 1, 36864, 0xe7ad6956
+0, 22, 22, 1, 36864, 0x47dc76d3
+0, 23, 23, 1, 36864, 0x496a3917
+0, 24, 24, 1, 36864, 0xa976d5f3
+0, 25, 25, 1, 36864, 0x507bb685
+0, 26, 26, 1, 36864, 0x2f61ac12
+0, 27, 27, 1, 36864, 0x527818d8
+0, 28, 28, 1, 36864, 0xa4983396
+0, 29, 29, 1, 36864, 0x3ec9b07b
+0, 30, 30, 1, 36864, 0x7db52d99
+0, 31, 31, 1, 36864, 0xe974fd00
+0, 32, 32, 1, 36864, 0x9c677a4f
+0, 33, 33, 1, 36864, 0x108f3a05
+0, 34, 34, 1, 36864, 0x23a56ba2
+0, 35, 35, 1, 36864, 0x4c8d47e8
+0, 36, 36, 1, 36864, 0x9e0b0f09
+0, 37, 37, 1, 36864, 0x4d262b16
+0, 38, 38, 1, 36864, 0x6122402e
+0, 39, 39, 1, 36864, 0xed037036
+0, 40, 40, 1, 36864, 0x62b3ba08
+0, 41, 41, 1, 36864, 0x7f876930
+0, 42, 42, 1, 36864, 0x4a6c0983
+0, 43, 43, 1, 36864, 0xf9787086
+0, 44, 44, 1, 36864, 0x01d1b1b5
+0, 45, 45, 1, 36864, 0xc1622655
+0, 46, 46, 1, 36864, 0x27e8e0f7
+0, 47, 47, 1, 36864, 0xc1622655
+0, 48, 48, 1, 36864, 0x12c2b7e9
+0, 49, 49, 1, 36864, 0xd752d2ef
+0, 50, 50, 1, 36864, 0xcbb1c3a7
+0, 51, 51, 1, 36864, 0x18c56fba
+0, 52, 52, 1, 36864, 0xb1b3771c
+0, 53, 53, 1, 36864, 0x284ef3c4
+0, 54, 54, 1, 36864, 0xda6eb5a0
+0, 55, 55, 1, 36864, 0x17ad337c
+0, 56, 56, 1, 36864, 0xe2801e4f
+0, 57, 57, 1, 36864, 0x6c33bd17
diff --git a/tests/ref/fate/h264-conformance-mr9_bt_b b/tests/ref/fate/h264-conformance-mr9_bt_b
index efc25d4..3744802 100644
--- a/tests/ref/fate/h264-conformance-mr9_bt_b
+++ b/tests/ref/fate/h264-conformance-mr9_bt_b
@@ -9,51 +9,51 @@
0, 7, 7, 1, 36864, 0x75122807
0, 8, 8, 1, 36864, 0x27036a2b
0, 9, 9, 1, 36864, 0x00072654
-0, 11, 11, 1, 36864, 0x49fab4fd
-0, 13, 13, 1, 36864, 0x975a7545
-0, 14, 14, 1, 36864, 0x9b080a2f
-0, 15, 15, 1, 36864, 0x78db960e
-0, 16, 16, 1, 36864, 0xd7a928d4
-0, 17, 17, 1, 36864, 0x0a83ba1b
-0, 18, 18, 1, 36864, 0xad6bb30c
-0, 19, 19, 1, 36864, 0xf6addb0d
-0, 20, 20, 1, 36864, 0x00540a0a
-0, 22, 22, 1, 36864, 0x049cc748
-0, 23, 23, 1, 36864, 0x5b1e2291
-0, 24, 24, 1, 36864, 0x2367706e
-0, 25, 25, 1, 36864, 0x88ef6b11
-0, 26, 26, 1, 36864, 0x85b73230
-0, 27, 27, 1, 36864, 0xe46cd522
-0, 28, 28, 1, 36864, 0x98489c05
-0, 29, 29, 1, 36864, 0x7e439564
-0, 30, 30, 1, 36864, 0x71330799
-0, 31, 31, 1, 36864, 0x81a6239e
-0, 32, 32, 1, 36864, 0x8005a302
-0, 33, 33, 1, 36864, 0xdf132e3f
-0, 34, 34, 1, 36864, 0x2a1d00de
-0, 35, 35, 1, 36864, 0x7bb57e14
-0, 36, 36, 1, 36864, 0xf2a637cf
-0, 37, 37, 1, 36864, 0xae6f6916
-0, 38, 38, 1, 36864, 0x2f1d4763
-0, 39, 39, 1, 36864, 0xa4e1145e
-0, 40, 40, 1, 36864, 0xc1644392
-0, 41, 41, 1, 36864, 0x21853537
-0, 42, 42, 1, 36864, 0x0bc45bac
-0, 44, 44, 1, 36864, 0x84ccb8ee
-0, 46, 46, 1, 36864, 0x65de651c
-0, 47, 47, 1, 36864, 0x33ff027e
-0, 49, 49, 1, 36864, 0xefe47056
-0, 50, 50, 1, 36864, 0x8952b47c
-0, 51, 51, 1, 36864, 0x78730fcf
-0, 52, 52, 1, 36864, 0x14bae79f
-0, 53, 53, 1, 36864, 0x53230fbe
-0, 54, 54, 1, 36864, 0x15b0b245
-0, 55, 55, 1, 36864, 0x45fbd155
-0, 56, 56, 1, 36864, 0x41cfbac4
-0, 57, 57, 1, 36864, 0x0d635d61
-0, 58, 58, 1, 36864, 0x55aa8d3c
-0, 59, 59, 1, 36864, 0x8f02fbaf
-0, 60, 60, 1, 36864, 0xb17fac3f
-0, 61, 61, 1, 36864, 0xc12627f9
-0, 62, 62, 1, 36864, 0xa5971e4a
-0, 63, 63, 1, 36864, 0x3677abfe
+0, 10, 10, 1, 36864, 0x49fab4fd
+0, 11, 11, 1, 36864, 0x975a7545
+0, 12, 12, 1, 36864, 0x9b080a2f
+0, 13, 13, 1, 36864, 0x78db960e
+0, 14, 14, 1, 36864, 0xd7a928d4
+0, 15, 15, 1, 36864, 0x0a83ba1b
+0, 16, 16, 1, 36864, 0xad6bb30c
+0, 17, 17, 1, 36864, 0xf6addb0d
+0, 18, 18, 1, 36864, 0x00540a0a
+0, 19, 19, 1, 36864, 0x049cc748
+0, 20, 20, 1, 36864, 0x5b1e2291
+0, 21, 21, 1, 36864, 0x2367706e
+0, 22, 22, 1, 36864, 0x88ef6b11
+0, 23, 23, 1, 36864, 0x85b73230
+0, 24, 24, 1, 36864, 0xe46cd522
+0, 25, 25, 1, 36864, 0x98489c05
+0, 26, 26, 1, 36864, 0x7e439564
+0, 27, 27, 1, 36864, 0x71330799
+0, 28, 28, 1, 36864, 0x81a6239e
+0, 29, 29, 1, 36864, 0x8005a302
+0, 30, 30, 1, 36864, 0xdf132e3f
+0, 31, 31, 1, 36864, 0x2a1d00de
+0, 32, 32, 1, 36864, 0x7bb57e14
+0, 33, 33, 1, 36864, 0xf2a637cf
+0, 34, 34, 1, 36864, 0xae6f6916
+0, 35, 35, 1, 36864, 0x2f1d4763
+0, 36, 36, 1, 36864, 0xa4e1145e
+0, 37, 37, 1, 36864, 0xc1644392
+0, 38, 38, 1, 36864, 0x21853537
+0, 39, 39, 1, 36864, 0x0bc45bac
+0, 40, 40, 1, 36864, 0x84ccb8ee
+0, 41, 41, 1, 36864, 0x65de651c
+0, 42, 42, 1, 36864, 0x33ff027e
+0, 43, 43, 1, 36864, 0xefe47056
+0, 44, 44, 1, 36864, 0x8952b47c
+0, 45, 45, 1, 36864, 0x78730fcf
+0, 46, 46, 1, 36864, 0x14bae79f
+0, 47, 47, 1, 36864, 0x53230fbe
+0, 48, 48, 1, 36864, 0x15b0b245
+0, 49, 49, 1, 36864, 0x45fbd155
+0, 50, 50, 1, 36864, 0x41cfbac4
+0, 51, 51, 1, 36864, 0x0d635d61
+0, 52, 52, 1, 36864, 0x55aa8d3c
+0, 53, 53, 1, 36864, 0x8f02fbaf
+0, 54, 54, 1, 36864, 0xb17fac3f
+0, 55, 55, 1, 36864, 0xc12627f9
+0, 56, 56, 1, 36864, 0xa5971e4a
+0, 57, 57, 1, 36864, 0x3677abfe
diff --git a/tests/ref/fate/h264-conformance-sharp_mp_field_1_b b/tests/ref/fate/h264-conformance-sharp_mp_field_1_b
index 93e0064..8512102 100644
--- a/tests/ref/fate/h264-conformance-sharp_mp_field_1_b
+++ b/tests/ref/fate/h264-conformance-sharp_mp_field_1_b
@@ -1,16 +1,16 @@
#tb 0: 1/25
-0, 1, 1, 1, 518400, 0xc93c7c47
-0, 3, 3, 1, 518400, 0xa3f2e502
-0, 5, 5, 1, 518400, 0xb98920a4
-0, 7, 7, 1, 518400, 0xad098ec1
-0, 9, 9, 1, 518400, 0x3009b7aa
-0, 11, 11, 1, 518400, 0xcf514018
-0, 13, 13, 1, 518400, 0xd869038d
-0, 15, 15, 1, 518400, 0x3ce5e188
-0, 17, 17, 1, 518400, 0x029b4c14
-0, 19, 19, 1, 518400, 0xd2224afc
-0, 21, 21, 1, 518400, 0xbbca027c
-0, 23, 23, 1, 518400, 0x1f3fa0ac
-0, 25, 25, 1, 518400, 0x823b0125
-0, 27, 27, 1, 518400, 0xaaa27cfb
-0, 29, 29, 1, 518400, 0x5e926a4a
+0, 0, 0, 1, 518400, 0xc93c7c47
+0, 1, 1, 1, 518400, 0xa3f2e502
+0, 2, 2, 1, 518400, 0xb98920a4
+0, 3, 3, 1, 518400, 0xad098ec1
+0, 4, 4, 1, 518400, 0x3009b7aa
+0, 5, 5, 1, 518400, 0xcf514018
+0, 6, 6, 1, 518400, 0xd869038d
+0, 7, 7, 1, 518400, 0x3ce5e188
+0, 8, 8, 1, 518400, 0x029b4c14
+0, 9, 9, 1, 518400, 0xd2224afc
+0, 10, 10, 1, 518400, 0xbbca027c
+0, 11, 11, 1, 518400, 0x1f3fa0ac
+0, 12, 12, 1, 518400, 0x823b0125
+0, 13, 13, 1, 518400, 0xaaa27cfb
+0, 14, 14, 1, 518400, 0x5e926a4a
diff --git a/tests/ref/fate/h264-conformance-sharp_mp_field_2_b b/tests/ref/fate/h264-conformance-sharp_mp_field_2_b
index eddd8c8..5808141 100644
--- a/tests/ref/fate/h264-conformance-sharp_mp_field_2_b
+++ b/tests/ref/fate/h264-conformance-sharp_mp_field_2_b
@@ -1,16 +1,16 @@
#tb 0: 1/25
-0, 1, 1, 1, 518400, 0xc93c7c47
-0, 3, 3, 1, 518400, 0xf0c4b44a
-0, 5, 5, 1, 518400, 0x3f5dc91c
-0, 7, 7, 1, 518400, 0x03dc8453
-0, 9, 9, 1, 518400, 0x5e5227af
-0, 11, 11, 1, 518400, 0x9e7136af
-0, 13, 13, 1, 518400, 0x963a2e3a
-0, 15, 15, 1, 518400, 0xa544be6c
-0, 17, 17, 1, 518400, 0xefa1f63a
-0, 19, 19, 1, 518400, 0x62155ff1
-0, 21, 21, 1, 518400, 0x253eb857
-0, 23, 23, 1, 518400, 0x73530327
-0, 25, 25, 1, 518400, 0x8920c9a3
-0, 27, 27, 1, 518400, 0x4bdd038c
-0, 29, 29, 1, 518400, 0xea6016dd
+0, 0, 0, 1, 518400, 0xc93c7c47
+0, 1, 1, 1, 518400, 0xf0c4b44a
+0, 2, 2, 1, 518400, 0x3f5dc91c
+0, 3, 3, 1, 518400, 0x03dc8453
+0, 4, 4, 1, 518400, 0x5e5227af
+0, 5, 5, 1, 518400, 0x9e7136af
+0, 6, 6, 1, 518400, 0x963a2e3a
+0, 7, 7, 1, 518400, 0xa544be6c
+0, 8, 8, 1, 518400, 0xefa1f63a
+0, 9, 9, 1, 518400, 0x62155ff1
+0, 10, 10, 1, 518400, 0x253eb857
+0, 11, 11, 1, 518400, 0x73530327
+0, 12, 12, 1, 518400, 0x8920c9a3
+0, 13, 13, 1, 518400, 0x4bdd038c
+0, 14, 14, 1, 518400, 0xea6016dd
diff --git a/tests/ref/fate/h264-conformance-sharp_mp_field_3_b b/tests/ref/fate/h264-conformance-sharp_mp_field_3_b
index 09096a0..a572030 100644
--- a/tests/ref/fate/h264-conformance-sharp_mp_field_3_b
+++ b/tests/ref/fate/h264-conformance-sharp_mp_field_3_b
@@ -1,16 +1,16 @@
#tb 0: 1/25
-0, 2, 2, 1, 518400, 0xc93c7c47
-0, 4, 4, 1, 518400, 0x7112ac25
-0, 6, 6, 1, 518400, 0x28bc28d2
-0, 8, 8, 1, 518400, 0x6fc36875
-0, 10, 10, 1, 518400, 0x3de99be0
-0, 12, 12, 1, 518400, 0x97125499
-0, 14, 14, 1, 518400, 0xb96fca3a
-0, 16, 16, 1, 518400, 0x1ec56c0f
-0, 18, 18, 1, 518400, 0xc65901d0
-0, 20, 20, 1, 518400, 0x2baa1bfa
-0, 22, 22, 1, 518400, 0x244fc6b7
-0, 24, 24, 1, 518400, 0xc3536383
-0, 26, 26, 1, 518400, 0xbcf40d5a
-0, 28, 28, 1, 518400, 0x955f4734
-0, 29, 29, 1, 518400, 0xe1b0275e
+0, 0, 0, 1, 518400, 0xc93c7c47
+0, 1, 1, 1, 518400, 0x7112ac25
+0, 2, 2, 1, 518400, 0x28bc28d2
+0, 3, 3, 1, 518400, 0x6fc36875
+0, 4, 4, 1, 518400, 0x3de99be0
+0, 5, 5, 1, 518400, 0x97125499
+0, 6, 6, 1, 518400, 0xb96fca3a
+0, 7, 7, 1, 518400, 0x1ec56c0f
+0, 8, 8, 1, 518400, 0xc65901d0
+0, 9, 9, 1, 518400, 0x2baa1bfa
+0, 10, 10, 1, 518400, 0x244fc6b7
+0, 11, 11, 1, 518400, 0xc3536383
+0, 12, 12, 1, 518400, 0xbcf40d5a
+0, 13, 13, 1, 518400, 0x955f4734
+0, 14, 14, 1, 518400, 0xe1b0275e
diff --git a/tests/ref/fate/h264-conformance-sharp_mp_paff_1r2 b/tests/ref/fate/h264-conformance-sharp_mp_paff_1r2
index 2847e3f..d1a347f 100644
--- a/tests/ref/fate/h264-conformance-sharp_mp_paff_1r2
+++ b/tests/ref/fate/h264-conformance-sharp_mp_paff_1r2
@@ -1,16 +1,16 @@
#tb 0: 1/25
-0, 1, 1, 1, 518400, 0xc93c7c47
-0, 2, 2, 1, 518400, 0xfb452a9c
-0, 4, 4, 1, 518400, 0x2f7a35bd
-0, 6, 6, 1, 518400, 0xe63e30b9
-0, 8, 8, 1, 518400, 0x39628205
-0, 9, 9, 1, 518400, 0x17fa1ea4
-0, 10, 10, 1, 518400, 0xd5ee83e2
-0, 11, 11, 1, 518400, 0x611ee98d
-0, 13, 13, 1, 518400, 0x07c1eeb8
-0, 15, 15, 1, 518400, 0x9dff3418
-0, 17, 17, 1, 518400, 0x87cd2f56
-0, 18, 18, 1, 518400, 0x88675628
-0, 20, 20, 1, 518400, 0x9bb8c9a0
-0, 21, 21, 1, 518400, 0xe6c1df00
-0, 22, 22, 1, 518400, 0xfcaab7a7
+0, 0, 0, 1, 518400, 0xc93c7c47
+0, 1, 1, 1, 518400, 0xfb452a9c
+0, 2, 2, 1, 518400, 0x2f7a35bd
+0, 3, 3, 1, 518400, 0xe63e30b9
+0, 4, 4, 1, 518400, 0x39628205
+0, 5, 5, 1, 518400, 0x17fa1ea4
+0, 6, 6, 1, 518400, 0xd5ee83e2
+0, 7, 7, 1, 518400, 0x611ee98d
+0, 8, 8, 1, 518400, 0x07c1eeb8
+0, 9, 9, 1, 518400, 0x9dff3418
+0, 10, 10, 1, 518400, 0x87cd2f56
+0, 11, 11, 1, 518400, 0x88675628
+0, 12, 12, 1, 518400, 0x9bb8c9a0
+0, 13, 13, 1, 518400, 0xe6c1df00
+0, 14, 14, 1, 518400, 0xfcaab7a7
diff --git a/tests/ref/fate/h264-conformance-sharp_mp_paff_2r b/tests/ref/fate/h264-conformance-sharp_mp_paff_2r
index 22bf8e2..f2bf06f 100644
--- a/tests/ref/fate/h264-conformance-sharp_mp_paff_2r
+++ b/tests/ref/fate/h264-conformance-sharp_mp_paff_2r
@@ -1,16 +1,16 @@
#tb 0: 1/25
-0, 1, 1, 1, 518400, 0xc93c7c47
-0, 2, 2, 1, 518400, 0xfb452a9c
-0, 4, 4, 1, 518400, 0x2f7a35bd
-0, 6, 6, 1, 518400, 0xe63e30b9
-0, 8, 8, 1, 518400, 0x39628205
-0, 9, 9, 1, 518400, 0x17fa1ea4
-0, 10, 10, 1, 518400, 0xd5ee83e2
-0, 11, 11, 1, 518400, 0x4fd6d5c9
-0, 13, 13, 1, 518400, 0x8703c999
-0, 15, 15, 1, 518400, 0x1a87e2d3
-0, 17, 17, 1, 518400, 0xa27fc4d0
-0, 18, 18, 1, 518400, 0x6effab5d
-0, 20, 20, 1, 518400, 0x51ea02c9
-0, 21, 21, 1, 518400, 0xbcf84c88
-0, 22, 22, 1, 518400, 0x1d41076b
+0, 0, 0, 1, 518400, 0xc93c7c47
+0, 1, 1, 1, 518400, 0xfb452a9c
+0, 2, 2, 1, 518400, 0x2f7a35bd
+0, 3, 3, 1, 518400, 0xe63e30b9
+0, 4, 4, 1, 518400, 0x39628205
+0, 5, 5, 1, 518400, 0x17fa1ea4
+0, 6, 6, 1, 518400, 0xd5ee83e2
+0, 7, 7, 1, 518400, 0x4fd6d5c9
+0, 8, 8, 1, 518400, 0x8703c999
+0, 9, 9, 1, 518400, 0x1a87e2d3
+0, 10, 10, 1, 518400, 0xa27fc4d0
+0, 11, 11, 1, 518400, 0x6effab5d
+0, 12, 12, 1, 518400, 0x51ea02c9
+0, 13, 13, 1, 518400, 0xbcf84c88
+0, 14, 14, 1, 518400, 0x1d41076b
diff --git a/tests/ref/fate/idroq-video-encode b/tests/ref/fate/idroq-video-encode
index f243a0d..badb06d 100644
--- a/tests/ref/fate/idroq-video-encode
+++ b/tests/ref/fate/idroq-video-encode
@@ -1 +1 @@
-72e5b060ff0ab8855da22f33a6e04bff
+2ac89fa0e5600152667bcbc661f06cfe
diff --git a/tests/ref/fate/interplay-mve-16bit b/tests/ref/fate/interplay-mve-16bit
index 35dc14b..2469aaa 100644
--- a/tests/ref/fate/interplay-mve-16bit
+++ b/tests/ref/fate/interplay-mve-16bit
@@ -1,131 +1,51 @@
#tb 0: 1/1000000
-#tb 1: 1/44100
0, 0, 0, 0, 614400, 0x00000000
-1, 0, 0, 1447, 5788, 0x916d2db8
-1, 1447, 1447, 1472, 5888, 0xc65cb069
0, 33360, 33360, 0, 614400, 0x00000000
-1, 2919, 2919, 1472, 5888, 0xd8ec1acc
0, 66720, 66720, 0, 614400, 0xa17ea4ec
-1, 4391, 4391, 1472, 5888, 0xb22af0d6
0, 100080, 100080, 0, 614400, 0x4fd207fb
-1, 5863, 5863, 1472, 5888, 0x86bb50d9
0, 133440, 133440, 0, 614400, 0xd7a510fb
-1, 7335, 7335, 1472, 5888, 0x7674d923
0, 166800, 166800, 0, 614400, 0xe901e2f4
-1, 8807, 8807, 1472, 5888, 0xb97c5500
0, 200160, 200160, 0, 614400, 0x4ac5d3c4
-1, 10279, 10279, 1472, 5888, 0xecea1249
0, 233520, 233520, 0, 614400, 0x32e3e99c
-1, 11751, 11751, 1472, 5888, 0x0f4fea81
0, 266880, 266880, 0, 614400, 0x7a2ff20c
-1, 13223, 13223, 1472, 5888, 0x997914d8
0, 300240, 300240, 0, 614400, 0x59941193
-1, 14695, 14695, 1472, 5888, 0xd012f03a
0, 333600, 333600, 0, 614400, 0x92773a2b
-1, 16167, 16167, 1472, 5888, 0x03fd5248
0, 366960, 366960, 0, 614400, 0x4cd14313
-1, 17639, 17639, 1472, 5888, 0x3041a288
0, 400320, 400320, 0, 614400, 0x2a093fa3
-1, 19111, 19111, 1472, 5888, 0xe6105de1
0, 433680, 433680, 0, 614400, 0xf68b8463
-1, 20583, 20583, 1472, 5888, 0xaa38c7bd
0, 467040, 467040, 0, 614400, 0xa9e1969b
-1, 22055, 22055, 1472, 5888, 0xbfff702c
0, 500400, 500400, 0, 614400, 0x461996bb
-1, 23527, 23527, 1472, 5888, 0xbe4319a3
0, 533760, 533760, 0, 614400, 0xae58d053
-1, 24999, 24999, 1472, 5888, 0x2e89d262
0, 567120, 567120, 0, 614400, 0x7693015a
-1, 26471, 26471, 1472, 5888, 0x10992b9c
0, 600480, 600480, 0, 614400, 0x0b3507fa
-1, 27943, 27943, 1472, 5888, 0x972904bf
0, 633840, 633840, 0, 614400, 0xff5c2492
-1, 29415, 29415, 1472, 5888, 0x0093501c
0, 667200, 667200, 0, 614400, 0x636e3e32
-1, 30887, 30887, 1472, 5888, 0x8994ad0e
0, 700560, 700560, 0, 614400, 0x1acd6d0a
-1, 32359, 32359, 1472, 5888, 0x9db37d21
0, 733920, 733920, 0, 614400, 0x67039232
-1, 33831, 33831, 1472, 5888, 0xa8c7300f
0, 767280, 767280, 0, 614400, 0x8ab9c75a
-1, 35303, 35303, 1472, 5888, 0x1b7073b5
0, 800640, 800640, 0, 614400, 0xe824bbe2
-1, 36775, 36775, 1472, 5888, 0x56ad7f7b
0, 834000, 834000, 0, 614400, 0x5133e9ea
-1, 38247, 38247, 1472, 5888, 0x9706a8fb
0, 867360, 867360, 0, 614400, 0xcecf1249
-1, 39719, 39719, 1472, 5888, 0x16c9420e
0, 900720, 900720, 0, 614400, 0xe6d928c1
-1, 41191, 41191, 1472, 5888, 0x3e11be0a
0, 934080, 934080, 0, 614400, 0x8da46ff1
-1, 42663, 42663, 1472, 5888, 0x3e534a32
0, 967440, 967440, 0, 614400, 0x1c778319
-1, 44135, 44135, 1447, 5788, 0x0ffae5f4
0, 1000800, 1000800, 0, 614400, 0x35a19451
-1, 45582, 45582, 1472, 5888, 0xc2018f82
0, 1034160, 1034160, 0, 614400, 0x5145d1b9
-1, 47054, 47054, 1472, 5888, 0x2a11f529
0, 1067520, 1067520, 0, 614400, 0x146ee231
-1, 48526, 48526, 1472, 5888, 0xec282167
0, 1100880, 1100880, 0, 614400, 0xd9b33380
-1, 49998, 49998, 1472, 5888, 0xd61b5a05
0, 1134240, 1134240, 0, 614400, 0x8b112ef8
-1, 51470, 51470, 1472, 5888, 0x61de2741
0, 1167600, 1167600, 0, 614400, 0xb9e79ab0
-1, 52942, 52942, 1472, 5888, 0x17aaff8c
0, 1200960, 1200960, 0, 614400, 0x62d3a498
-1, 54414, 54414, 1472, 5888, 0xd40cd7a6
0, 1234320, 1234320, 0, 614400, 0xaeaaaa58
-1, 55886, 55886, 1472, 5888, 0x840840d4
0, 1267680, 1267680, 0, 614400, 0x8922c440
-1, 57358, 57358, 1472, 5888, 0x7c97ddcf
0, 1301040, 1301040, 0, 614400, 0xd62ef758
-1, 58830, 58830, 1472, 5888, 0xed9150f7
0, 1334400, 1334400, 0, 614400, 0x2a53149f
-1, 60302, 60302, 1472, 5888, 0xbccf973e
0, 1367760, 1367760, 0, 614400, 0x13da47df
-1, 61774, 61774, 1472, 5888, 0x74bda5ea
0, 1401120, 1401120, 0, 614400, 0x27c05c3f
-1, 63246, 63246, 1472, 5888, 0xd083892a
0, 1434480, 1434480, 0, 614400, 0x41ff7ca7
-1, 64718, 64718, 1472, 5888, 0x16e444b2
0, 1467840, 1467840, 0, 614400, 0x6b0e8a07
-1, 66190, 66190, 1472, 5888, 0x68a9cedb
0, 1501200, 1501200, 0, 614400, 0xa200ad9f
-1, 67662, 67662, 1472, 5888, 0x80849f36
0, 1534560, 1534560, 0, 614400, 0x9da7cc77
-1, 69134, 69134, 1472, 5888, 0x63cb7df9
0, 1567920, 1567920, 0, 614400, 0x2f5703be
-1, 70606, 70606, 1472, 5888, 0xf90f754d
0, 1601280, 1601280, 0, 614400, 0x91c720f6
-1, 72078, 72078, 1472, 5888, 0x9c2c867d
0, 1634640, 1634640, 0, 614400, 0x927a882e
-1, 73550, 73550, 1472, 5888, 0x337994a4
-1, 75022, 75022, 1472, 5888, 0xf354a28d
-1, 76494, 76494, 1472, 5888, 0x70933738
-1, 77966, 77966, 1472, 5888, 0x3c019219
-1, 79438, 79438, 1472, 5888, 0xe0c21295
-1, 80910, 80910, 1472, 5888, 0x21869515
-1, 82382, 82382, 1472, 5888, 0xe9b1ec7d
-1, 83854, 83854, 1472, 5888, 0x57825497
-1, 85326, 85326, 1472, 5888, 0xae02ebeb
-1, 86798, 86798, 1472, 5888, 0x0c62e14f
-1, 88270, 88270, 1447, 5788, 0x8a255f8f
-1, 89717, 89717, 1472, 5888, 0x38993359
-1, 91189, 91189, 1472, 5888, 0x390baf95
-1, 92661, 92661, 1472, 5888, 0xb72c72ea
-1, 94133, 94133, 1472, 5888, 0xbbd3c6fe
-1, 95605, 95605, 1472, 5888, 0xefb26f0a
-1, 97077, 97077, 1472, 5888, 0xcc404dd0
-1, 98549, 98549, 1472, 5888, 0xffa23082
-1, 100021, 100021, 1472, 5888, 0xd0c43567
-1, 101493, 101493, 1472, 5888, 0x4d3b7958
-1, 102965, 102965, 1472, 5888, 0x47125aa1
-1, 104437, 104437, 1472, 5888, 0x99286cf3
-1, 105909, 105909, 1472, 5888, 0x478d61e2
-1, 107381, 107381, 1472, 5888, 0xac65b47e
-1, 108853, 108853, 1472, 5888, 0x333c1d1a
-1, 110325, 110325, 1472, 5888, 0x8f960ecf
-1, 111797, 111797, 1472, 5888, 0x58f76aec
-1, 113269, 113269, 1472, 5888, 0xb5e0dded
-1, 114741, 114741, 1472, 5888, 0xaf1a8f9a
diff --git a/tests/ref/fate/interplay-mve-8bit b/tests/ref/fate/interplay-mve-8bit
index 33630e9..abd86eb 100644
--- a/tests/ref/fate/interplay-mve-8bit
+++ b/tests/ref/fate/interplay-mve-8bit
@@ -1,236 +1,111 @@
#tb 0: 1/1000000
-#tb 1: 1/22050
0, 0, 0, 0, 414720, 0xa5cd50ca
-1, 0, 0, 1462, 5848, 0xea04292b
-1, 1462, 1462, 1472, 5888, 0x0e59e942
0, 66728, 66728, 0, 414720, 0x3facd321
-1, 2934, 2934, 1472, 5888, 0x56d480f6
0, 133456, 133456, 0, 414720, 0x849e6d4b
-1, 4406, 4406, 1472, 5888, 0xcb560b22
0, 200184, 200184, 0, 414720, 0xe649363f
-1, 5878, 5878, 1472, 5888, 0xca26865b
0, 266912, 266912, 0, 414720, 0x5bbd7b14
-1, 7350, 7350, 1472, 5888, 0xa434392f
0, 333640, 333640, 0, 414720, 0xe246ab51
-1, 8822, 8822, 1472, 5888, 0xa0615fe4
0, 400368, 400368, 0, 414720, 0x5721b22e
-1, 10294, 10294, 1472, 5888, 0x85b241cd
0, 467096, 467096, 0, 414720, 0xe391e107
-1, 11766, 11766, 1472, 5888, 0x2c417a43
0, 533824, 533824, 0, 414720, 0x04d851ff
-1, 13238, 13238, 1472, 5888, 0x2d5ed665
0, 600552, 600552, 0, 414720, 0x8d80d580
-1, 14710, 14710, 1472, 5888, 0x37267a2d
0, 667280, 667280, 0, 414720, 0x5a24b0bc
-1, 16182, 16182, 1472, 5888, 0x1f803c67
0, 734008, 734008, 0, 414720, 0x06cd6960
-1, 17654, 17654, 1472, 5888, 0xfb7940ef
0, 800736, 800736, 0, 414720, 0xf5ca48b4
-1, 19126, 19126, 1472, 5888, 0x1a5371e8
0, 867464, 867464, 0, 414720, 0x24700f94
-1, 20598, 20598, 1472, 5888, 0x37e29b21
0, 934192, 934192, 0, 414720, 0xb0bfe451
-1, 22070, 22070, 1462, 5848, 0x70065769
0, 1000920, 1000920, 0, 414720, 0x00e9f3d1
-1, 23532, 23532, 1472, 5888, 0xaf624f3d
0, 1067648, 1067648, 0, 414720, 0x0efbffd1
-1, 25004, 25004, 1472, 5888, 0x8f5e5b57
0, 1134376, 1134376, 0, 414720, 0x2ecdfc8d
-1, 26476, 26476, 1472, 5888, 0x93545968
0, 1201104, 1201104, 0, 414720, 0x94b531fc
-1, 27948, 27948, 1472, 5888, 0x915f268f
0, 1267832, 1267832, 0, 414720, 0x2c2579f8
-1, 29420, 29420, 1472, 5888, 0x9cd48ac4
0, 1334560, 1334560, 0, 414720, 0x6c7ecfb8
-1, 30892, 30892, 1472, 5888, 0x812c8e13
0, 1401288, 1401288, 0, 414720, 0x08982527
-1, 32364, 32364, 1472, 5888, 0xe794a2a7
0, 1468016, 1468016, 0, 414720, 0x5c0161b3
-1, 33836, 33836, 1472, 5888, 0x4a056e4b
0, 1534744, 1534744, 0, 414720, 0x453ce413
-1, 35308, 35308, 1472, 5888, 0xa3589992
0, 1601472, 1601472, 0, 414720, 0x634e36b2
-1, 36780, 36780, 1472, 5888, 0x19ea7ec5
0, 1668200, 1668200, 0, 414720, 0x401a683a
-1, 38252, 38252, 1472, 5888, 0x422d5097
0, 1734928, 1734928, 0, 414720, 0x3c5f442e
-1, 39724, 39724, 1472, 5888, 0xc9fd963f
0, 1801656, 1801656, 0, 414720, 0x075ef787
-1, 41196, 41196, 1472, 5888, 0xc556a5ea
0, 1868384, 1868384, 0, 414720, 0x8501a04f
-1, 42668, 42668, 1472, 5888, 0x51557e0f
0, 1935112, 1935112, 0, 414720, 0x3620093b
-1, 44140, 44140, 1462, 5848, 0x4903ad21
0, 2001840, 2001840, 0, 414720, 0xa42d9480
-1, 45602, 45602, 1472, 5888, 0xb1c85e85
0, 2068568, 2068568, 0, 414720, 0x09b150b4
-1, 47074, 47074, 1472, 5888, 0x68963d65
0, 2135296, 2135296, 0, 414720, 0xcad407f0
-1, 48546, 48546, 1472, 5888, 0x62a3124e
0, 2202024, 2202024, 0, 414720, 0x69e5eecd
-1, 50018, 50018, 1472, 5888, 0x4ff1878f
0, 2268752, 2268752, 0, 414720, 0xb92ad2d9
-1, 51490, 51490, 1472, 5888, 0x8b09ac18
0, 2335480, 2335480, 0, 414720, 0xc78eaf29
-1, 52962, 52962, 1472, 5888, 0x67d85338
0, 2402208, 2402208, 0, 414720, 0x47c3fa91
-1, 54434, 54434, 1472, 5888, 0x82eca0a6
0, 2468936, 2468936, 0, 414720, 0x8847b7b8
-1, 55906, 55906, 1472, 5888, 0x81a17eb8
0, 2535664, 2535664, 0, 414720, 0x864cab2f
-1, 57378, 57378, 1472, 5888, 0x7108478c
0, 2602392, 2602392, 0, 414720, 0x78d653e2
-1, 58850, 58850, 1472, 5888, 0xbfc18b09
0, 2669120, 2669120, 0, 414720, 0xda15cbd2
-1, 60322, 60322, 1472, 5888, 0xad93711f
0, 2735848, 2735848, 0, 414720, 0xdf9ce28a
-1, 61794, 61794, 1472, 5888, 0xf8d25e39
0, 2802576, 2802576, 0, 414720, 0xe88c49ca
-1, 63266, 63266, 1472, 5888, 0x41edd04e
0, 2869304, 2869304, 0, 414720, 0xd6bcbc07
-1, 64738, 64738, 1472, 5888, 0xa6557ee2
0, 2936032, 2936032, 0, 414720, 0xf0b4a7bf
-1, 66210, 66210, 1462, 5848, 0xc14d5456
0, 3002760, 3002760, 0, 414720, 0x74f9bfbf
-1, 67672, 67672, 1472, 5888, 0x20a7821f
0, 3069488, 3069488, 0, 414720, 0x904ce103
-1, 69144, 69144, 1472, 5888, 0x9f1a8f9d
0, 3136216, 3136216, 0, 414720, 0xca877e4a
-1, 70616, 70616, 1472, 5888, 0x2f3c6cc8
0, 3202944, 3202944, 0, 414720, 0x588effd6
-1, 72088, 72088, 1472, 5888, 0x757c894a
0, 3269672, 3269672, 0, 414720, 0x6dff8b71
-1, 73560, 73560, 1472, 5888, 0x483e98bb
0, 3336400, 3336400, 0, 414720, 0xbeaae788
-1, 75032, 75032, 1472, 5888, 0x84289c75
0, 3403128, 3403128, 0, 414720, 0x1a4d1242
-1, 76504, 76504, 1472, 5888, 0xf79d5a91
0, 3469856, 3469856, 0, 414720, 0x4ae98ea0
-1, 77976, 77976, 1472, 5888, 0x395b5228
0, 3536584, 3536584, 0, 414720, 0x41ed6d22
-1, 79448, 79448, 1472, 5888, 0x9c937a14
0, 3603312, 3603312, 0, 414720, 0x486e70aa
-1, 80920, 80920, 1472, 5888, 0x40c169cf
0, 3670040, 3670040, 0, 414720, 0xfddc103e
-1, 82392, 82392, 1472, 5888, 0x3e7f99b0
0, 3736768, 3736768, 0, 414720, 0x8620f03e
-1, 83864, 83864, 1472, 5888, 0xd4de993e
0, 3803496, 3803496, 0, 414720, 0x0e4ec273
-1, 85336, 85336, 1472, 5888, 0xae856b09
0, 3870224, 3870224, 0, 414720, 0xb2298b3e
-1, 86808, 86808, 1472, 5888, 0xa2369c95
0, 3936952, 3936952, 0, 414720, 0xb4f50176
-1, 88280, 88280, 1462, 5848, 0x992d516b
0, 4003680, 4003680, 0, 414720, 0xb9c7a495
-1, 89742, 89742, 1472, 5888, 0xcd785ba9
0, 4070408, 4070408, 0, 414720, 0xed270702
-1, 91214, 91214, 1472, 5888, 0x55ea3bce
0, 4137136, 4137136, 0, 414720, 0x98b72586
-1, 92686, 92686, 1472, 5888, 0xf06d4bbf
0, 4203864, 4203864, 0, 414720, 0xd8977cb1
-1, 94158, 94158, 1472, 5888, 0x2a9d4c1a
0, 4270592, 4270592, 0, 414720, 0xff3d3851
-1, 95630, 95630, 1472, 5888, 0xd5e348a3
0, 4337320, 4337320, 0, 414720, 0x7e4f0424
-1, 97102, 97102, 1472, 5888, 0x6431a24c
0, 4404048, 4404048, 0, 414720, 0xa9e75006
-1, 98574, 98574, 1472, 5888, 0x41f9908c
0, 4470776, 4470776, 0, 414720, 0x8f98cba9
-1, 100046, 100046, 1472, 5888, 0x0ed99656
0, 4537504, 4537504, 0, 414720, 0x25ecd620
-1, 101518, 101518, 1472, 5888, 0x635a6392
0, 4604232, 4604232, 0, 414720, 0x78cf5c58
-1, 102990, 102990, 1472, 5888, 0x690c750c
0, 4670960, 4670960, 0, 414720, 0x3fb4b81a
-1, 104462, 104462, 1472, 5888, 0xf9d97b23
0, 4737688, 4737688, 0, 414720, 0xd7b655fa
-1, 105934, 105934, 1472, 5888, 0x75e1606b
0, 4804416, 4804416, 0, 414720, 0xd9158db3
-1, 107406, 107406, 1472, 5888, 0x1bcb43b0
0, 4871144, 4871144, 0, 414720, 0x2e651852
-1, 108878, 108878, 1472, 5888, 0x48c295cb
0, 4937872, 4937872, 0, 414720, 0x9f9adb64
-1, 110350, 110350, 1462, 5848, 0xe47f7b5d
0, 5004600, 5004600, 0, 414720, 0xe9d16e81
-1, 111812, 111812, 1472, 5888, 0x20be7f3e
0, 5071328, 5071328, 0, 414720, 0xbe73daf5
-1, 113284, 113284, 1472, 5888, 0x8c2428c4
0, 5138056, 5138056, 0, 414720, 0x3d164329
-1, 114756, 114756, 1472, 5888, 0x851379af
0, 5204784, 5204784, 0, 414720, 0x1d5a9bc8
-1, 116228, 116228, 1472, 5888, 0x5916647d
0, 5271512, 5271512, 0, 414720, 0x8e8debbe
-1, 117700, 117700, 1472, 5888, 0xef9c6281
0, 5338240, 5338240, 0, 414720, 0x4e7a2bf0
-1, 119172, 119172, 1472, 5888, 0x49660d32
0, 5404968, 5404968, 0, 414720, 0x4a13804d
-1, 120644, 120644, 1472, 5888, 0x62cf36a1
0, 5471696, 5471696, 0, 414720, 0x5dd188d8
-1, 122116, 122116, 1472, 5888, 0x56dff39c
0, 5538424, 5538424, 0, 414720, 0xbe7f4963
-1, 123588, 123588, 1472, 5888, 0x4e6b5b02
0, 5605152, 5605152, 0, 414720, 0xcff3b767
-1, 125060, 125060, 1472, 5888, 0xb8697067
0, 5671880, 5671880, 0, 414720, 0xbbd3afa0
-1, 126532, 126532, 1472, 5888, 0xcb4e2706
0, 5738608, 5738608, 0, 414720, 0xaf9dec62
-1, 128004, 128004, 1472, 5888, 0x6eaa9669
0, 5805336, 5805336, 0, 414720, 0xc74816a1
-1, 129476, 129476, 1472, 5888, 0xfd9d7dba
0, 5872064, 5872064, 0, 414720, 0x51488bfc
-1, 130948, 130948, 1472, 5888, 0xfe137923
0, 5938792, 5938792, 0, 414720, 0x68c10a2c
-1, 132420, 132420, 1462, 5848, 0x1931296f
0, 6005520, 6005520, 0, 414720, 0x10179c4e
-1, 133882, 133882, 1472, 5888, 0xa09a7c03
0, 6072248, 6072248, 0, 414720, 0x18d559b7
-1, 135354, 135354, 1472, 5888, 0xded9802d
0, 6138976, 6138976, 0, 414720, 0x8257aa55
-1, 136826, 136826, 1472, 5888, 0x9f6723b7
0, 6205704, 6205704, 0, 414720, 0x9ea24501
-1, 138298, 138298, 1472, 5888, 0x3ad02476
0, 6272432, 6272432, 0, 414720, 0x238605cc
-1, 139770, 139770, 1472, 5888, 0xa1647e32
0, 6339160, 6339160, 0, 414720, 0xb552deaa
-1, 141242, 141242, 1472, 5888, 0x728672da
0, 6405888, 6405888, 0, 414720, 0x07c3348d
-1, 142714, 142714, 1472, 5888, 0x9c098090
0, 6472616, 6472616, 0, 414720, 0x82f4f9b0
-1, 144186, 144186, 1472, 5888, 0x32a65ea3
0, 6539344, 6539344, 0, 414720, 0xf5d76bc5
-1, 145658, 145658, 1472, 5888, 0xdde141d5
0, 6606072, 6606072, 0, 414720, 0x34b3a1e6
-1, 147130, 147130, 1472, 5888, 0x816c5fb4
0, 6672800, 6672800, 0, 414720, 0xda25e11b
-1, 148602, 148602, 1472, 5888, 0x75e17581
0, 6739528, 6739528, 0, 414720, 0x2b19936b
-1, 150074, 150074, 1472, 5888, 0x59035469
0, 6806256, 6806256, 0, 414720, 0xe91f9f73
-1, 151546, 151546, 1472, 5888, 0x20d340cd
0, 6872984, 6872984, 0, 414720, 0x48d09aab
-1, 153018, 153018, 1472, 5888, 0xa89a8790
0, 6939712, 6939712, 0, 414720, 0xac42bf83
-1, 154490, 154490, 1462, 5848, 0x12b74c34
0, 7006440, 7006440, 0, 414720, 0x2d8ca14e
-1, 155952, 155952, 1472, 5888, 0xcd3b3bef
0, 7073168, 7073168, 0, 414720, 0xe65462fd
-1, 157424, 157424, 1472, 5888, 0xe5c44bf3
0, 7139896, 7139896, 0, 414720, 0xe5bfc929
-1, 158896, 158896, 1472, 5888, 0xb82c4fa4
0, 7206624, 7206624, 0, 414720, 0x66784c58
-1, 160368, 160368, 1472, 5888, 0x05b2443a
0, 7273352, 7273352, 0, 414720, 0x70dbeca8
-1, 161840, 161840, 1472, 5888, 0x78028172
-1, 163312, 163312, 1472, 5888, 0xdfcac19a
-1, 164784, 164784, 1472, 5888, 0x0761a0b9
-1, 166256, 166256, 1472, 5888, 0x77d88607
-1, 167728, 167728, 1472, 5888, 0xdd7f4d77
-1, 169200, 169200, 1472, 5888, 0x366bf58a
-1, 170672, 170672, 1472, 5888, 0x9a3d59b5
-1, 172144, 172144, 1472, 5888, 0x16cb777f
-1, 173616, 173616, 1472, 5888, 0x1d4afe64
-1, 175088, 175088, 1472, 5888, 0xc0fe1e73
-1, 176560, 176560, 1462, 5848, 0xcceb69c8
-1, 178022, 178022, 1472, 5888, 0x89449643
-1, 179494, 179494, 1472, 5888, 0x5fe595b7
-1, 180966, 180966, 1472, 5888, 0x400a8c77
diff --git a/tests/ref/fate/mdec b/tests/ref/fate/mdec
new file mode 100644
index 0000000..b7aab62
--- /dev/null
+++ b/tests/ref/fate/mdec
@@ -0,0 +1,135 @@
+#tb 0: 1/15
+0, 0, 0, 1, 102144, 0x6edc83de
+0, 1, 1, 1, 102144, 0xd0534fda
+0, 2, 2, 1, 102144, 0x6447911f
+0, 3, 3, 1, 102144, 0xf21f3b46
+0, 4, 4, 1, 102144, 0x0975077a
+0, 5, 5, 1, 102144, 0xb9a12d8e
+0, 6, 6, 1, 102144, 0x17413513
+0, 7, 7, 1, 102144, 0x1e622a04
+0, 8, 8, 1, 102144, 0x7489224e
+0, 9, 9, 1, 102144, 0xae14956e
+0, 10, 10, 1, 102144, 0x104fd3a0
+0, 11, 11, 1, 102144, 0xea63a940
+0, 12, 12, 1, 102144, 0x0cf81588
+0, 13, 13, 1, 102144, 0xe4a5b2fd
+0, 14, 14, 1, 102144, 0x0c9aaf77
+0, 15, 15, 1, 102144, 0x065007d7
+0, 16, 16, 1, 102144, 0x54c0c29b
+0, 17, 17, 1, 102144, 0x1114cb8e
+0, 18, 18, 1, 102144, 0xe4270462
+0, 19, 19, 1, 102144, 0x61e5b7fd
+0, 20, 20, 1, 102144, 0x7cbeaca6
+0, 21, 21, 1, 102144, 0xed92daa4
+0, 22, 22, 1, 102144, 0xd8654d0d
+0, 23, 23, 1, 102144, 0x854e842b
+0, 24, 24, 1, 102144, 0x56407c3a
+0, 25, 25, 1, 102144, 0x17db3f90
+0, 26, 26, 1, 102144, 0x8b133b9a
+0, 27, 27, 1, 102144, 0xe4899db9
+0, 28, 28, 1, 102144, 0x579cf092
+0, 29, 29, 1, 102144, 0x19fa5062
+0, 30, 30, 1, 102144, 0x71339792
+0, 31, 31, 1, 102144, 0x970e5c0c
+0, 32, 32, 1, 102144, 0x84ee616a
+0, 33, 33, 1, 102144, 0x1d6f9a23
+0, 34, 34, 1, 102144, 0xc28e19db
+0, 35, 35, 1, 102144, 0x0e898967
+0, 36, 36, 1, 102144, 0x52a8b671
+0, 37, 37, 1, 102144, 0x3f45ea83
+0, 38, 38, 1, 102144, 0x7b0fc603
+0, 39, 39, 1, 102144, 0x14f94469
+0, 40, 40, 1, 102144, 0x5b9f37cc
+0, 41, 41, 1, 102144, 0xf902b7c7
+0, 42, 42, 1, 102144, 0x326836e0
+0, 43, 43, 1, 102144, 0x2e4aebba
+0, 44, 44, 1, 102144, 0xd10ae58c
+0, 45, 45, 1, 102144, 0xbd084ecf
+0, 46, 46, 1, 102144, 0xb2157c0a
+0, 47, 47, 1, 102144, 0xd7f158d4
+0, 48, 48, 1, 102144, 0x3cf86462
+0, 49, 49, 1, 102144, 0x53ecddab
+0, 50, 50, 1, 102144, 0xcdaba8ef
+0, 51, 51, 1, 102144, 0xab9ede18
+0, 52, 52, 1, 102144, 0xb6706e79
+0, 53, 53, 1, 102144, 0x76371069
+0, 54, 54, 1, 102144, 0x3a365016
+0, 55, 55, 1, 102144, 0x52177c09
+0, 56, 56, 1, 102144, 0xc33eb4fb
+0, 57, 57, 1, 102144, 0x16098436
+0, 58, 58, 1, 102144, 0x715d6a2b
+0, 59, 59, 1, 102144, 0xd3abc960
+0, 60, 60, 1, 102144, 0x7f34b0d4
+0, 61, 61, 1, 102144, 0xe3219b9c
+0, 62, 62, 1, 102144, 0x5fa54f54
+0, 63, 63, 1, 102144, 0x0fb746cb
+0, 64, 64, 1, 102144, 0xa6bd2da2
+0, 65, 65, 1, 102144, 0x04579119
+0, 66, 66, 1, 102144, 0xda818691
+0, 67, 67, 1, 102144, 0xe9d44445
+0, 68, 68, 1, 102144, 0x94868dc9
+0, 69, 69, 1, 102144, 0x3ca52ce6
+0, 70, 70, 1, 102144, 0xd7eb4c4f
+0, 71, 71, 1, 102144, 0xfcdfafca
+0, 72, 72, 1, 102144, 0x473a4a5a
+0, 73, 73, 1, 102144, 0xe5a5f3cb
+0, 74, 74, 1, 102144, 0x34070219
+0, 75, 75, 1, 102144, 0x0faa965a
+0, 76, 76, 1, 102144, 0xe2c6acda
+0, 77, 77, 1, 102144, 0xe22776d5
+0, 78, 78, 1, 102144, 0x80d85602
+0, 79, 79, 1, 102144, 0x2f3fa190
+0, 80, 80, 1, 102144, 0x70b461b1
+0, 81, 81, 1, 102144, 0x366c8b27
+0, 82, 82, 1, 102144, 0x65cc0866
+0, 83, 83, 1, 102144, 0x903beb14
+0, 84, 84, 1, 102144, 0xb6c5f5c7
+0, 85, 85, 1, 102144, 0xaa813725
+0, 86, 86, 1, 102144, 0x014a84a0
+0, 87, 87, 1, 102144, 0xd286ece1
+0, 88, 88, 1, 102144, 0x48b1c27d
+0, 89, 89, 1, 102144, 0xa611ef42
+0, 90, 90, 1, 102144, 0x98627584
+0, 91, 91, 1, 102144, 0x43de7c75
+0, 92, 92, 1, 102144, 0xa9e22c68
+0, 93, 93, 1, 102144, 0x84ac34d4
+0, 94, 94, 1, 102144, 0x6abd00ba
+0, 95, 95, 1, 102144, 0x5d11066e
+0, 96, 96, 1, 102144, 0xb6b083aa
+0, 97, 97, 1, 102144, 0x5d152a11
+0, 98, 98, 1, 102144, 0x0c0aec67
+0, 99, 99, 1, 102144, 0xa248bd10
+0, 100, 100, 1, 102144, 0x4e6c12cc
+0, 101, 101, 1, 102144, 0xca1d6753
+0, 102, 102, 1, 102144, 0x116310c3
+0, 103, 103, 1, 102144, 0x16903cd0
+0, 104, 104, 1, 102144, 0x239adfed
+0, 105, 105, 1, 102144, 0x0970ce49
+0, 106, 106, 1, 102144, 0xb628adc1
+0, 107, 107, 1, 102144, 0x473613f7
+0, 108, 108, 1, 102144, 0x3eef3987
+0, 109, 109, 1, 102144, 0x935b99ca
+0, 110, 110, 1, 102144, 0xb9f4d6ee
+0, 111, 111, 1, 102144, 0xac811656
+0, 112, 112, 1, 102144, 0xd1f84af0
+0, 113, 113, 1, 102144, 0xf2fd25f4
+0, 114, 114, 1, 102144, 0x935bbed9
+0, 115, 115, 1, 102144, 0x8c8c3e53
+0, 116, 116, 1, 102144, 0x24afc20f
+0, 117, 117, 1, 102144, 0xad20a451
+0, 118, 118, 1, 102144, 0xd1a0df13
+0, 119, 119, 1, 102144, 0xb0ee53f8
+0, 120, 120, 1, 102144, 0x08cdb591
+0, 121, 121, 1, 102144, 0x89b985b0
+0, 122, 122, 1, 102144, 0xdd27d51f
+0, 123, 123, 1, 102144, 0xa783fce0
+0, 124, 124, 1, 102144, 0xfe5602e8
+0, 125, 125, 1, 102144, 0xfb989934
+0, 126, 126, 1, 102144, 0xf857eb2b
+0, 127, 127, 1, 102144, 0x987a7098
+0, 128, 128, 1, 102144, 0xbc749f42
+0, 129, 129, 1, 102144, 0x221e48a6
+0, 130, 130, 1, 102144, 0x4c4b5da2
+0, 131, 131, 1, 102144, 0x32140027
+0, 132, 132, 1, 102144, 0xbeb4bf18
+0, 133, 133, 1, 102144, 0x523012e5
diff --git a/tests/ref/fate/psx-str-v3-mdec b/tests/ref/fate/mdec-v3
similarity index 100%
rename from tests/ref/fate/psx-str-v3-mdec
rename to tests/ref/fate/mdec-v3
diff --git a/tests/ref/fate/mtv b/tests/ref/fate/mtv
index e32f16e..4f8f616 100644
--- a/tests/ref/fate/mtv
+++ b/tests/ref/fate/mtv
@@ -1,137 +1,138 @@
#tb 0: 1/16
#tb 1: 1/44100
-0, 0, 0, 1, 18432, 0xbd7e0ac8
+0, 0, 0, 1, 12288, 0xc2258ebc
1, 0, 0, 1152, 417, 0xae1cc66a
1, 1152, 1152, 1152, 418, 0xdc3ec850
1, 2304, 2304, 1152, 418, 0x4e8ed05f
-0, 1, 1, 1, 18432, 0xbd7e0ac8
+0, 1, 1, 1, 12288, 0xc2258ebc
1, 3456, 3456, 1152, 418, 0xeb43d574
1, 4608, 4608, 1152, 418, 0x9357c91d
-0, 2, 2, 1, 18432, 0x902e0ab4
+0, 2, 2, 1, 12288, 0xb3fe829c
1, 5760, 5760, 1152, 418, 0x5306d16b
1, 6912, 6912, 1152, 418, 0x46e0d4da
1, 8064, 8064, 1152, 418, 0xac11ce79
-0, 3, 3, 1, 18432, 0xf1940b28
+0, 3, 3, 1, 12288, 0x2315884a
1, 9216, 9216, 1152, 418, 0xffdfc4ad
1, 10368, 10368, 1152, 418, 0xf8a8c2ff
-0, 4, 4, 1, 18432, 0x2c180ac8
+0, 4, 4, 1, 12288, 0x95a08046
1, 11520, 11520, 1152, 418, 0x2d66d83f
1, 12672, 12672, 1152, 418, 0x65c0da12
-0, 5, 5, 1, 18432, 0x2eae0b34
+0, 5, 5, 1, 12288, 0xdb49886b
1, 13824, 13824, 1152, 418, 0x0eafd20f
1, 14976, 14976, 1152, 418, 0x8c6dd949
1, 16128, 16128, 1152, 418, 0x9094c02d
-0, 6, 6, 1, 18432, 0x2eae0b34
+0, 6, 6, 1, 12288, 0xdb49886b
1, 17280, 17280, 1152, 418, 0xb47bd944
1, 18432, 18432, 1152, 418, 0x935ccce7
-0, 7, 7, 1, 18432, 0x2eae0b34
+0, 7, 7, 1, 12288, 0xdb49886b
1, 19584, 19584, 1152, 418, 0x6e3ed020
1, 20736, 20736, 1152, 418, 0x8922cd6c
1, 21888, 21888, 1152, 418, 0xe811c8f8
-0, 8, 8, 1, 18432, 0x2eae0b34
+0, 8, 8, 1, 12288, 0xdb49886b
1, 23040, 23040, 1152, 418, 0xb84adc72
1, 24192, 24192, 1152, 418, 0xa2bbc5f4
-0, 9, 9, 1, 18432, 0x2eae0b34
+0, 9, 9, 1, 12288, 0xdb49886b
1, 25344, 25344, 1152, 418, 0xec0cb67d
1, 26496, 26496, 1152, 418, 0x89d1d014
-0, 10, 10, 1, 18432, 0x2eae0b34
+0, 10, 10, 1, 12288, 0xdb49886b
1, 27648, 27648, 1152, 418, 0xfb5bc872
1, 28800, 28800, 1152, 417, 0x8bfcc7a0
1, 29952, 29952, 1152, 418, 0xeb4ac61b
-0, 11, 11, 1, 18432, 0x2eae0b34
+0, 11, 11, 1, 12288, 0xdb49886b
1, 31104, 31104, 1152, 418, 0xd3cbc3c4
1, 32256, 32256, 1152, 418, 0xa272d092
-0, 12, 12, 1, 18432, 0x2eae0b34
+0, 12, 12, 1, 12288, 0xdb49886b
1, 33408, 33408, 1152, 418, 0x611ec37e
1, 34560, 34560, 1152, 418, 0x70a3d423
1, 35712, 35712, 1152, 418, 0xeff9ccf4
-0, 13, 13, 1, 18432, 0x2eae0b34
+0, 13, 13, 1, 12288, 0xdb49886b
1, 36864, 36864, 1152, 418, 0x9788c65b
1, 38016, 38016, 1152, 418, 0xe9a8cb8c
-0, 14, 14, 1, 18432, 0x2eae0b34
+0, 14, 14, 1, 12288, 0xdb49886b
1, 39168, 39168, 1152, 418, 0x5834c300
1, 40320, 40320, 1152, 418, 0xa4b8cd3a
-0, 15, 15, 1, 18432, 0x2eae0b34
+0, 15, 15, 1, 12288, 0xdb49886b
1, 41472, 41472, 1152, 418, 0x6de2c7f9
1, 42624, 42624, 1152, 418, 0x961bbbf3
1, 43776, 43776, 1152, 418, 0x53edc13a
-0, 16, 16, 1, 18432, 0x2c180ac8
+0, 16, 16, 1, 12288, 0x95a08046
1, 44928, 44928, 1152, 418, 0x2fedc4b0
1, 46080, 46080, 1152, 418, 0xb756c18b
-0, 17, 17, 1, 18432, 0x2eae0b34
+0, 17, 17, 1, 12288, 0xdb49886b
1, 47232, 47232, 1152, 418, 0xaf0ed0e4
1, 48384, 48384, 1152, 418, 0x019fd3f0
1, 49536, 49536, 1152, 418, 0x6e29d83e
-0, 18, 18, 1, 18432, 0x2c180ac8
+0, 18, 18, 1, 12288, 0x95a08046
1, 50688, 50688, 1152, 418, 0x2ddad6bb
1, 51840, 51840, 1152, 418, 0xafefca99
-0, 19, 19, 1, 18432, 0x2eae0b34
+0, 19, 19, 1, 12288, 0xdb49886b
1, 52992, 52992, 1152, 418, 0x366ed013
1, 54144, 54144, 1152, 418, 0x532ac7e0
-0, 20, 20, 1, 18432, 0x2c180ac8
+0, 20, 20, 1, 12288, 0x95a08046
1, 55296, 55296, 1152, 418, 0x1d0cd1ce
1, 56448, 56448, 1152, 417, 0x572ad1e3
1, 57600, 57600, 1152, 418, 0x858cd91f
-0, 21, 21, 1, 18432, 0x2eae0b34
+0, 21, 21, 1, 12288, 0xdb49886b
1, 58752, 58752, 1152, 418, 0x82cacdfd
1, 59904, 59904, 1152, 418, 0xf4dcc6ed
-0, 22, 22, 1, 18432, 0x2c180ac8
+0, 22, 22, 1, 12288, 0x95a08046
1, 61056, 61056, 1152, 418, 0x2cf3ca72
1, 62208, 62208, 1152, 418, 0x5963c859
1, 63360, 63360, 1152, 418, 0xa667c53d
-0, 23, 23, 1, 18432, 0x2eae0b34
+0, 23, 23, 1, 12288, 0xdb49886b
1, 64512, 64512, 1152, 418, 0xb2f1d09c
1, 65664, 65664, 1152, 418, 0x2ec1c8d3
-0, 24, 24, 1, 18432, 0x2eae0b34
+0, 24, 24, 1, 12288, 0xdb49886b
1, 66816, 66816, 1152, 418, 0x5754d2e8
1, 67968, 67968, 1152, 418, 0x1956bdba
-0, 25, 25, 1, 18432, 0x2eae0b34
+0, 25, 25, 1, 12288, 0xdb49886b
1, 69120, 69120, 1152, 418, 0x3e18bd55
1, 70272, 70272, 1152, 418, 0xe4cfc339
1, 71424, 71424, 1152, 418, 0xb426c835
-0, 26, 26, 1, 18432, 0x2eae0b34
+0, 26, 26, 1, 12288, 0xdb49886b
1, 72576, 72576, 1152, 418, 0xd7b6cbcf
1, 73728, 73728, 1152, 418, 0x340ec315
-0, 27, 27, 1, 18432, 0x2eae0b34
+0, 27, 27, 1, 12288, 0xdb49886b
1, 74880, 74880, 1152, 418, 0x23a9baec
1, 76032, 76032, 1152, 418, 0x9f04cd01
-0, 28, 28, 1, 18432, 0x2eae0b34
+0, 28, 28, 1, 12288, 0xdb49886b
1, 77184, 77184, 1152, 418, 0xa80ec223
1, 78336, 78336, 1152, 418, 0x23d6bd5d
1, 79488, 79488, 1152, 418, 0xcb25cf5b
-0, 29, 29, 1, 18432, 0x2eae0b34
+0, 29, 29, 1, 12288, 0xdb49886b
1, 80640, 80640, 1152, 418, 0xccccc217
1, 81792, 81792, 1152, 418, 0x757abbfe
-0, 30, 30, 1, 18432, 0x2eae0b34
+0, 30, 30, 1, 12288, 0xdb49886b
1, 82944, 82944, 1152, 418, 0xa2e6cc68
1, 84096, 84096, 1152, 418, 0xdf77cc05
1, 85248, 85248, 1152, 417, 0xe9d2c5d5
-0, 31, 31, 1, 18432, 0x2eae0b34
+0, 31, 31, 1, 12288, 0xdb49886b
1, 86400, 86400, 1152, 418, 0x50dec174
1, 87552, 87552, 1152, 418, 0xf654b27e
-0, 32, 32, 1, 18432, 0x2c180ac8
+0, 32, 32, 1, 12288, 0x95a08046
1, 88704, 88704, 1152, 418, 0x4d8bc26e
1, 89856, 89856, 1152, 418, 0xccd2bf37
-0, 33, 33, 1, 18432, 0x2eae0b34
+0, 33, 33, 1, 12288, 0xdb49886b
1, 91008, 91008, 1152, 418, 0x6ce2c18a
1, 92160, 92160, 1152, 418, 0xb3cdcf0c
1, 93312, 93312, 1152, 418, 0x55eebe9a
-0, 34, 34, 1, 18432, 0x2c180ac8
+0, 34, 34, 1, 12288, 0x95a08046
1, 94464, 94464, 1152, 418, 0x9031c9ec
1, 95616, 95616, 1152, 418, 0xb037c49d
-0, 35, 35, 1, 18432, 0x2eae0b34
+0, 35, 35, 1, 12288, 0xdb49886b
1, 96768, 96768, 1152, 418, 0x377bcc78
1, 97920, 97920, 1152, 418, 0x3762c725
1, 99072, 99072, 1152, 418, 0x39afbd4d
-0, 36, 36, 1, 18432, 0x2c180ac8
+0, 36, 36, 1, 12288, 0x95a08046
1, 100224, 100224, 1152, 418, 0x655ed6cd
1, 101376, 101376, 1152, 418, 0x09aec202
-0, 37, 37, 1, 18432, 0x2eae0b34
+0, 37, 37, 1, 12288, 0xdb49886b
1, 102528, 102528, 1152, 418, 0xf2d2ce55
1, 103680, 103680, 1152, 418, 0x254ebf04
-0, 38, 38, 1, 18432, 0x2c180ac8
+0, 38, 38, 1, 12288, 0x95a08046
1, 104832, 104832, 1152, 418, 0xa105cdcc
1, 105984, 105984, 1152, 418, 0x1477ba58
1, 107136, 107136, 1152, 418, 0x8d0dcdb2
+0, 39, 39, 1, 3584, 0x0354c435
1, 108288, 108288, 1152, 418, 0x0d7cbef4
1, 109440, 109440, 1152, 294, 0x5e2b87c4
diff --git a/tests/ref/fate/pcm-planar b/tests/ref/fate/pcm-planar
new file mode 100644
index 0000000..91b4a78
--- /dev/null
+++ b/tests/ref/fate/pcm-planar
@@ -0,0 +1,143 @@
+#tb 0: 1/44100
+0, 0, 0, 1471, 5884, 0x00000000
+0, 1471, 1471, 1471, 5884, 0x00000000
+0, 2942, 2942, 1472, 5888, 0x00000000
+0, 4414, 4414, 1471, 5884, 0x00000000
+0, 5885, 5885, 1472, 5888, 0x00000000
+0, 7357, 7357, 1471, 5884, 0x00000000
+0, 8828, 8828, 1472, 5888, 0x00000000
+0, 10300, 10300, 1471, 5884, 0x00000000
+0, 11771, 11771, 1472, 5888, 0x00000000
+0, 13243, 13243, 1471, 5884, 0x00000000
+0, 14714, 14714, 1472, 5888, 0x174b2bd4
+0, 16186, 16186, 1471, 5884, 0xfab9563d
+0, 17657, 17657, 1472, 5888, 0x0129a4f5
+0, 19129, 19129, 1471, 5884, 0xf12b15dd
+0, 20600, 20600, 1472, 5888, 0x60c8c922
+0, 22072, 22072, 1471, 5884, 0x85693c81
+0, 23543, 23543, 1472, 5888, 0xcefcf0e0
+0, 25015, 25015, 1471, 5884, 0x243974ff
+0, 26486, 26486, 1471, 5884, 0x9101b901
+0, 27957, 27957, 1472, 5888, 0xe3c68cb9
+0, 29429, 29429, 1471, 5884, 0x80f2ff5f
+0, 30900, 30900, 1472, 5888, 0xfc2d19dc
+0, 32372, 32372, 1471, 5884, 0xb6e0af21
+0, 33843, 33843, 1472, 5888, 0x476e74ff
+0, 35315, 35315, 1471, 5884, 0x3921bc7f
+0, 36786, 36786, 1472, 5888, 0x44180a3f
+0, 38258, 38258, 1471, 5884, 0x01b5a119
+0, 39729, 39729, 1472, 5888, 0xdd7ad621
+0, 41201, 41201, 1471, 5884, 0xadabe898
+0, 42672, 42672, 1472, 5888, 0x2141ff8e
+0, 44144, 44144, 1471, 5884, 0xfb5118fb
+0, 45615, 45615, 1472, 5888, 0x06d31461
+0, 47087, 47087, 1471, 5884, 0x80ce34c1
+0, 48558, 48558, 1472, 5888, 0x72bf392f
+0, 50030, 50030, 1471, 5884, 0x9d9237cf
+0, 51501, 51501, 1471, 5884, 0xf5c9ce23
+0, 52972, 52972, 1472, 5888, 0x12a05dc5
+0, 54444, 54444, 1471, 5884, 0xd3ed5d4b
+0, 55915, 55915, 1472, 5888, 0x06557401
+0, 57387, 57387, 1471, 5884, 0x53d81662
+0, 58858, 58858, 1472, 5888, 0xd7e0d98d
+0, 60330, 60330, 1471, 5884, 0xdf00752e
+0, 61801, 61801, 1472, 5888, 0x82f1d7a9
+0, 63273, 63273, 1471, 5884, 0x9cb3aba9
+0, 64744, 64744, 1472, 5888, 0xd6f98e91
+0, 66216, 66216, 1471, 5884, 0xaa7f7c09
+0, 67687, 67687, 1472, 5888, 0xb97a82a7
+0, 69159, 69159, 1471, 5884, 0x375a3d53
+0, 70630, 70630, 1472, 5888, 0xa0a460cb
+0, 72102, 72102, 1471, 5884, 0xe05efbab
+0, 73573, 73573, 1472, 5888, 0x95e151f0
+0, 75045, 75045, 1471, 5884, 0x44ac688d
+0, 76516, 76516, 1471, 5884, 0xfc6d929f
+0, 77987, 77987, 1472, 5888, 0x6406c5f1
+0, 79459, 79459, 1471, 5884, 0x4ee9e48c
+0, 80930, 80930, 1472, 5888, 0xd55d43d0
+0, 82402, 82402, 1471, 5884, 0xcae69baf
+0, 83873, 83873, 1472, 5888, 0x4c01f1f5
+0, 85345, 85345, 1471, 5884, 0xf7d6dab6
+0, 86816, 86816, 1472, 5888, 0x1affdeb5
+0, 88288, 88288, 1471, 5884, 0x6db72487
+0, 89759, 89759, 1472, 5888, 0x4f344e49
+0, 91231, 91231, 1471, 5884, 0x2df3827b
+0, 92702, 92702, 1472, 5888, 0x1d1fc283
+0, 94174, 94174, 1471, 5884, 0x22eb1dd5
+0, 95645, 95645, 1472, 5888, 0x734e7093
+0, 97117, 97117, 1471, 5884, 0x357c9531
+0, 98588, 98588, 1472, 5888, 0x108c102d
+0, 100060, 100060, 1471, 5884, 0x96ad26c6
+0, 101531, 101531, 1472, 5888, 0x7bea1996
+0, 103003, 103003, 1471, 5884, 0x124a1f8e
+0, 104474, 104474, 1471, 5884, 0x08d272fb
+0, 105945, 105945, 1472, 5888, 0x88832c6b
+0, 107417, 107417, 1471, 5884, 0xedf41493
+0, 108888, 108888, 1472, 5888, 0xc4f226d7
+0, 110360, 110360, 1471, 5884, 0x97730397
+0, 111831, 111831, 1472, 5888, 0xbc3540e9
+0, 113303, 113303, 1471, 5884, 0x8adfa135
+0, 114774, 114774, 1472, 5888, 0x6d4be121
+0, 116246, 116246, 1471, 5884, 0xc3daea85
+0, 117717, 117717, 1472, 5888, 0x5498e9f0
+0, 119189, 119189, 1471, 5884, 0xa0eb691f
+0, 120660, 120660, 1472, 5888, 0x775c7c59
+0, 122132, 122132, 1471, 5884, 0x9f108fd1
+0, 123603, 123603, 1472, 5888, 0x72d53062
+0, 125075, 125075, 1471, 5884, 0x13a93faa
+0, 126546, 126546, 1472, 5888, 0x64773c8e
+0, 128018, 128018, 1471, 5884, 0xaf696999
+0, 129489, 129489, 1471, 5884, 0xf45e7e81
+0, 130960, 130960, 1472, 5888, 0x00000000
+0, 132432, 132432, 1471, 5884, 0x00000000
+0, 133903, 133903, 1472, 5888, 0x00000000
+0, 135375, 135375, 1471, 5884, 0x00000000
+0, 136846, 136846, 1472, 5888, 0x00000000
+0, 138318, 138318, 1471, 5884, 0x00000000
+0, 139789, 139789, 1472, 5888, 0x00000000
+0, 141261, 141261, 1471, 5884, 0x00000000
+0, 142732, 142732, 1472, 5888, 0x00000000
+0, 144204, 144204, 1471, 5884, 0x00000000
+0, 145675, 145675, 1472, 5888, 0x00000000
+0, 147147, 147147, 1471, 5884, 0x00000000
+0, 148618, 148618, 1472, 5888, 0x00000000
+0, 150090, 150090, 1471, 5884, 0x00000000
+0, 151561, 151561, 1472, 5888, 0x00000000
+0, 153033, 153033, 1471, 5884, 0x00000000
+0, 154504, 154504, 1471, 5884, 0x00000000
+0, 155975, 155975, 1472, 5888, 0x00000000
+0, 157447, 157447, 1471, 5884, 0x00000000
+0, 158918, 158918, 1472, 5888, 0x00000000
+0, 160390, 160390, 1471, 5884, 0x00000000
+0, 161861, 161861, 1472, 5888, 0x00000000
+0, 163333, 163333, 1471, 5884, 0x00000000
+0, 164804, 164804, 1472, 5888, 0x00000000
+0, 166276, 166276, 1471, 5884, 0x00000000
+0, 167747, 167747, 1472, 5888, 0x00000000
+0, 169219, 169219, 1471, 5884, 0x00000000
+0, 170690, 170690, 1472, 5888, 0x00000000
+0, 172162, 172162, 1471, 5884, 0xfe4b2bd4
+0, 173633, 173633, 1472, 5888, 0x00000000
+0, 175105, 175105, 1471, 5884, 0x00000000
+0, 176576, 176576, 1472, 5888, 0x00000000
+0, 178048, 178048, 1471, 5884, 0x00000000
+0, 179519, 179519, 1471, 5884, 0x00000000
+0, 180990, 180990, 1472, 5888, 0x00000000
+0, 182462, 182462, 1471, 5884, 0x00000000
+0, 183933, 183933, 1472, 5888, 0x00000000
+0, 185405, 185405, 1471, 5884, 0x00000000
+0, 186876, 186876, 1472, 5888, 0x00000000
+0, 188348, 188348, 1471, 5884, 0x00000000
+0, 189819, 189819, 1472, 5888, 0x00000000
+0, 191291, 191291, 1471, 5884, 0x00000000
+0, 192762, 192762, 1472, 5888, 0x00000000
+0, 194234, 194234, 1471, 5884, 0x00000000
+0, 195705, 195705, 1472, 5888, 0x00000000
+0, 197177, 197177, 1471, 5884, 0x00000000
+0, 198648, 198648, 1472, 5888, 0x00000000
+0, 200120, 200120, 1471, 5884, 0x00000000
+0, 201591, 201591, 1472, 5888, 0x00000000
+0, 203063, 203063, 1471, 5884, 0x00000000
+0, 204534, 204534, 1472, 5888, 0x00000000
+0, 206006, 206006, 1471, 5884, 0x00000000
+0, 207477, 207477, 1262, 5048, 0x00000000
diff --git a/tests/ref/fate/psx-str b/tests/ref/fate/psx-str
deleted file mode 100644
index a76af1c..0000000
--- a/tests/ref/fate/psx-str
+++ /dev/null
@@ -1,202 +0,0 @@
-#tb 0: 1/15
-#tb 1: 1/37800
-0, 0, 0, 1, 115200, 0x6b106a56
-1, 0, 0, 2016, 8064, 0x02260037
-1, 2016, 2016, 2016, 8064, 0x4ee9f4e9
-0, 1, 1, 1, 115200, 0x53c16930
-1, 4032, 4032, 2016, 8064, 0xf8fd82aa
-0, 2, 2, 1, 115200, 0xe2126f03
-1, 6048, 6048, 2016, 8064, 0xc100792b
-0, 3, 3, 1, 115200, 0xc3c18ba0
-1, 8064, 8064, 2016, 8064, 0xf11a5316
-0, 4, 4, 1, 115200, 0xe281b655
-1, 10080, 10080, 2016, 8064, 0x6937f8c0
-1, 12096, 12096, 2016, 8064, 0xed194e42
-0, 5, 5, 1, 115200, 0x7b1e0536
-1, 14112, 14112, 2016, 8064, 0x619ce54b
-0, 6, 6, 1, 115200, 0xbbd868c5
-1, 16128, 16128, 2016, 8064, 0x544999ec
-0, 7, 7, 1, 115200, 0xfc67bf8e
-1, 18144, 18144, 2016, 8064, 0x0ea877b4
-0, 8, 8, 1, 115200, 0xb463151c
-1, 20160, 20160, 2016, 8064, 0xb764d1c0
-1, 22176, 22176, 2016, 8064, 0x7a2fd211
-0, 9, 9, 1, 115200, 0x6e686846
-1, 24192, 24192, 2016, 8064, 0xff69f6c5
-0, 10, 10, 1, 115200, 0xca36b835
-1, 26208, 26208, 2016, 8064, 0x26c11ec7
-0, 11, 11, 1, 115200, 0x17b91efc
-1, 28224, 28224, 2016, 8064, 0xfb4ecc0c
-0, 12, 12, 1, 115200, 0xc051a49a
-1, 30240, 30240, 2016, 8064, 0x111d799b
-1, 32256, 32256, 2016, 8064, 0xc704dc91
-0, 13, 13, 1, 115200, 0xc68c227b
-1, 34272, 34272, 2016, 8064, 0xa9f372fb
-0, 14, 14, 1, 115200, 0x9ba6b521
-1, 36288, 36288, 2016, 8064, 0xa3f0ad0f
-0, 15, 15, 1, 115200, 0x09d56ecc
-1, 38304, 38304, 2016, 8064, 0x958719b9
-0, 16, 16, 1, 115200, 0xc20e3485
-1, 40320, 40320, 2016, 8064, 0x9b011bf7
-1, 42336, 42336, 2016, 8064, 0x466d96fb
-0, 17, 17, 1, 115200, 0xf07e2c48
-1, 44352, 44352, 2016, 8064, 0x6ed4eb29
-0, 18, 18, 1, 115200, 0x551c6da1
-1, 46368, 46368, 2016, 8064, 0x066966db
-0, 19, 19, 1, 115200, 0xed65bacd
-1, 48384, 48384, 2016, 8064, 0xf60fe0bc
-0, 20, 20, 1, 115200, 0x51a23a3b
-1, 50400, 50400, 2016, 8064, 0x2c845167
-1, 52416, 52416, 2016, 8064, 0x7d63894f
-0, 21, 21, 1, 115200, 0x559ddce1
-1, 54432, 54432, 2016, 8064, 0x0682ee36
-0, 22, 22, 1, 115200, 0x1fef6373
-1, 56448, 56448, 2016, 8064, 0xcaeb7c70
-0, 23, 23, 1, 115200, 0x11b2dece
-1, 58464, 58464, 2016, 8064, 0x93948697
-0, 24, 24, 1, 115200, 0x851b877c
-1, 60480, 60480, 2016, 8064, 0x5805f0d6
-1, 62496, 62496, 2016, 8064, 0xcfb641ff
-0, 25, 25, 1, 115200, 0x5f9a7c99
-1, 64512, 64512, 2016, 8064, 0xe3499bb1
-0, 26, 26, 1, 115200, 0x9ffe6153
-1, 66528, 66528, 2016, 8064, 0x689fe483
-0, 27, 27, 1, 115200, 0x950b0de8
-1, 68544, 68544, 2016, 8064, 0x1b8f2f2d
-0, 28, 28, 1, 115200, 0x6ec4c89a
-1, 70560, 70560, 2016, 8064, 0x23852e71
-1, 72576, 72576, 2016, 8064, 0x15e7b298
-0, 29, 29, 1, 115200, 0xa9234812
-1, 74592, 74592, 2016, 8064, 0x5345a9a3
-0, 30, 30, 1, 115200, 0xc834f491
-1, 76608, 76608, 2016, 8064, 0x257b6ecf
-0, 31, 31, 1, 115200, 0x2cc1a2aa
-1, 78624, 78624, 2016, 8064, 0xaf62836c
-0, 32, 32, 1, 115200, 0x5df53b71
-1, 80640, 80640, 2016, 8064, 0xc3a401e3
-1, 82656, 82656, 2016, 8064, 0x2b98fdf1
-0, 33, 33, 1, 115200, 0xe1d0cb31
-1, 84672, 84672, 2016, 8064, 0x37168697
-0, 34, 34, 1, 115200, 0xa0d2f8ab
-1, 86688, 86688, 2016, 8064, 0x2d876c89
-0, 35, 35, 1, 115200, 0x9342d739
-1, 88704, 88704, 2016, 8064, 0xc40a6ada
-0, 36, 36, 1, 115200, 0x586bc658
-1, 90720, 90720, 2016, 8064, 0xcca6b829
-1, 92736, 92736, 2016, 8064, 0x6667550a
-0, 37, 37, 1, 115200, 0x76902834
-1, 94752, 94752, 2016, 8064, 0x99c1b5cb
-0, 38, 38, 1, 115200, 0x91f25616
-1, 96768, 96768, 2016, 8064, 0xc05d3ed3
-0, 39, 39, 1, 115200, 0xce8c95fb
-1, 98784, 98784, 2016, 8064, 0xdd641781
-0, 40, 40, 1, 115200, 0xdf0d3de6
-1, 100800, 100800, 2016, 8064, 0xa65d49dc
-1, 102816, 102816, 2016, 8064, 0x2a0d5df7
-0, 41, 41, 1, 115200, 0x120db7ae
-1, 104832, 104832, 2016, 8064, 0xa6348438
-0, 42, 42, 1, 115200, 0x2143e287
-1, 106848, 106848, 2016, 8064, 0xf2e1412d
-0, 43, 43, 1, 115200, 0x2498d3b6
-1, 108864, 108864, 2016, 8064, 0xc41c6a7a
-0, 44, 44, 1, 115200, 0x99975ff8
-1, 110880, 110880, 2016, 8064, 0x147edc3d
-1, 112896, 112896, 2016, 8064, 0x17e3cfe7
-0, 45, 45, 1, 115200, 0xbad65f9f
-1, 114912, 114912, 2016, 8064, 0x01fe3969
-0, 46, 46, 1, 115200, 0x5066605b
-1, 116928, 116928, 2016, 8064, 0xc437ac11
-0, 47, 47, 1, 115200, 0x6f8a61a0
-1, 118944, 118944, 2016, 8064, 0xbbf747c1
-0, 48, 48, 1, 115200, 0x80c96143
-1, 120960, 120960, 2016, 8064, 0x2a4b88c0
-1, 122976, 122976, 2016, 8064, 0xcd149c80
-0, 49, 49, 1, 115200, 0x663c6198
-1, 124992, 124992, 2016, 8064, 0xcf339dfc
-0, 50, 50, 1, 115200, 0x0354620b
-1, 127008, 127008, 2016, 8064, 0xc81ff84b
-0, 51, 51, 1, 115200, 0xfe186346
-1, 129024, 129024, 2016, 8064, 0x4d978100
-0, 52, 52, 1, 115200, 0x844962f8
-1, 131040, 131040, 2016, 8064, 0x6da6665b
-1, 133056, 133056, 2016, 8064, 0x12fa354f
-0, 53, 53, 1, 115200, 0x917c672f
-1, 135072, 135072, 2016, 8064, 0x6baedae6
-0, 54, 54, 1, 115200, 0x45086647
-1, 137088, 137088, 2016, 8064, 0xddd77327
-0, 55, 55, 1, 115200, 0xace06816
-1, 139104, 139104, 2016, 8064, 0x0a31c118
-0, 56, 56, 1, 115200, 0x4ef26aa2
-1, 141120, 141120, 2016, 8064, 0x7652ee6e
-1, 143136, 143136, 2016, 8064, 0x486a24cc
-0, 57, 57, 1, 115200, 0xf2046bb3
-1, 145152, 145152, 2016, 8064, 0xf6cf01ee
-0, 58, 58, 1, 115200, 0x846b6eb0
-1, 147168, 147168, 2016, 8064, 0x2a19e830
-0, 59, 59, 1, 115200, 0x8a17716d
-1, 149184, 149184, 2016, 8064, 0xde675a31
-0, 60, 60, 1, 115200, 0x36127568
-1, 151200, 151200, 2016, 8064, 0xeefcc9af
-1, 153216, 153216, 2016, 8064, 0xaec4c989
-0, 61, 61, 1, 115200, 0x3e877b5c
-1, 155232, 155232, 2016, 8064, 0x16b73de9
-0, 62, 62, 1, 115200, 0xea5681e8
-1, 157248, 157248, 2016, 8064, 0x188a582a
-0, 63, 63, 1, 115200, 0x41bc8a39
-1, 159264, 159264, 2016, 8064, 0xc092e73d
-0, 64, 64, 1, 115200, 0x6f839446
-1, 161280, 161280, 2016, 8064, 0xf7ebca97
-1, 163296, 163296, 2016, 8064, 0x170ce07a
-0, 65, 65, 1, 115200, 0xef74a005
-1, 165312, 165312, 2016, 8064, 0xa0705384
-0, 66, 66, 1, 115200, 0x4354b2c2
-1, 167328, 167328, 2016, 8064, 0xd0154a3c
-0, 67, 67, 1, 115200, 0x4607cf99
-1, 169344, 169344, 2016, 8064, 0x57c73c6c
-0, 68, 68, 1, 115200, 0x4c18e8db
-1, 171360, 171360, 2016, 8064, 0x590c9ddb
-1, 173376, 173376, 2016, 8064, 0x2cbe552f
-0, 69, 69, 1, 115200, 0x04d71efb
-1, 175392, 175392, 2016, 8064, 0x0d286932
-0, 70, 70, 1, 115200, 0x32f4b9ae
-1, 177408, 177408, 2016, 8064, 0x5931cea3
-0, 71, 71, 1, 115200, 0x4dd48d01
-1, 179424, 179424, 2016, 8064, 0xaf0fb80d
-0, 72, 72, 1, 115200, 0x5fa9627f
-1, 181440, 181440, 2016, 8064, 0x7fb61e9b
-1, 183456, 183456, 2016, 8064, 0xf17134bb
-0, 73, 73, 1, 115200, 0x7a413f88
-1, 185472, 185472, 2016, 8064, 0xd647859a
-0, 74, 74, 1, 115200, 0xf1b7e5b6
-1, 187488, 187488, 2016, 8064, 0x55a60921
-0, 75, 75, 1, 115200, 0x3d720e05
-1, 189504, 189504, 2016, 8064, 0x3811fa58
-0, 76, 76, 1, 115200, 0x49243fd8
-1, 191520, 191520, 2016, 8064, 0xaceeccea
-1, 193536, 193536, 2016, 8064, 0x5fcedf14
-0, 77, 77, 1, 115200, 0x9834b697
-1, 195552, 195552, 2016, 8064, 0xd8c64abf
-0, 78, 78, 1, 115200, 0x4b8bc217
-1, 197568, 197568, 2016, 8064, 0x79495e8d
-0, 79, 79, 1, 115200, 0x3eaf5504
-1, 199584, 199584, 2016, 8064, 0x4b7db039
-0, 80, 80, 1, 115200, 0x057a3701
-1, 201600, 201600, 2016, 8064, 0x7152f86d
-1, 203616, 203616, 2016, 8064, 0xd92cfc1a
-0, 81, 81, 1, 115200, 0x6e88f21a
-1, 205632, 205632, 2016, 8064, 0x75c540ef
-0, 82, 82, 1, 115200, 0x236c5226
-1, 207648, 207648, 2016, 8064, 0x9c03ef5e
-0, 83, 83, 1, 115200, 0x92212d84
-1, 209664, 209664, 2016, 8064, 0x7b2911c8
-0, 84, 84, 1, 115200, 0xf6b0a4ff
-1, 211680, 211680, 2016, 8064, 0x69d9d553
-1, 213696, 213696, 2016, 8064, 0xcb45d7c5
-0, 85, 85, 1, 115200, 0xb49e9b4e
-1, 215712, 215712, 2016, 8064, 0x37ec8b0a
-0, 86, 86, 1, 115200, 0x4a252440
-1, 217728, 217728, 2016, 8064, 0xe4354221
-0, 87, 87, 1, 115200, 0x65f3339a
-1, 219744, 219744, 2016, 8064, 0xc0d91cdb
-0, 88, 88, 1, 115200, 0x38e40a20
-1, 221760, 221760, 2016, 8064, 0xea0be175
diff --git a/tests/ref/fate/psx-str-demux b/tests/ref/fate/psx-str-demux
new file mode 100644
index 0000000..42c5731
--- /dev/null
+++ b/tests/ref/fate/psx-str-demux
@@ -0,0 +1,202 @@
+#tb 0: 1/15
+#tb 1: 4/75
+0, 0, 0, 1, 8832, 0x01ad3eeb
+1, 0, 0, 1, 2304, 0xf0ad1000
+1, 1, 1, 1, 2304, 0x69269ce6
+0, 1, 1, 1, 8968, 0xe0033799
+1, 2, 2, 1, 2304, 0x124a995d
+0, 2, 2, 1, 9036, 0xd6189ab7
+1, 3, 3, 1, 2304, 0x3fc0ca07
+0, 3, 3, 1, 9192, 0xb44b9ffa
+1, 4, 4, 1, 2304, 0x40a1b447
+0, 4, 4, 1, 9404, 0xe94dfd40
+1, 5, 5, 1, 2304, 0x150dae9f
+1, 6, 6, 1, 2304, 0xad16bc63
+0, 5, 5, 1, 9492, 0xf73f2541
+1, 7, 7, 1, 2304, 0xe989b175
+0, 6, 6, 1, 9652, 0x243d53f8
+1, 8, 8, 1, 2304, 0x3c77cd39
+0, 7, 7, 1, 9872, 0x83f3ea7a
+1, 9, 9, 1, 2304, 0x93f0c2ba
+0, 8, 8, 1, 10052, 0x7604247a
+1, 10, 10, 1, 2304, 0x6e2ad2d0
+1, 11, 11, 1, 2304, 0xf8eab90a
+0, 9, 9, 1, 10100, 0x077107fd
+1, 12, 12, 1, 2304, 0xc039bf0d
+0, 10, 10, 1, 10264, 0xae675eb6
+1, 13, 13, 1, 2304, 0x0900c7e8
+0, 11, 11, 1, 10464, 0x428f83ae
+1, 14, 14, 1, 2304, 0x9722d580
+0, 12, 12, 1, 10580, 0x1bdcd71b
+1, 15, 15, 1, 2304, 0x02eec8de
+1, 16, 16, 1, 2304, 0x4807a2b3
+0, 13, 13, 1, 10800, 0xde75213a
+1, 17, 17, 1, 2304, 0x4643be06
+0, 14, 14, 1, 11236, 0x9387cc8e
+1, 18, 18, 1, 2304, 0x5bd9d249
+0, 15, 15, 1, 11420, 0x3a7d321b
+1, 19, 19, 1, 2304, 0x4e33c2bc
+0, 16, 16, 1, 11632, 0x7edc9cdf
+1, 20, 20, 1, 2304, 0x085ca51d
+1, 21, 21, 1, 2304, 0xa205b202
+0, 17, 17, 1, 11936, 0xf0521017
+1, 22, 22, 1, 2304, 0x71b9bcca
+0, 18, 18, 1, 11804, 0x53b22066
+1, 23, 23, 1, 2304, 0xcb769e5f
+0, 19, 19, 1, 11852, 0x9425fb21
+1, 24, 24, 1, 2304, 0x9322d85a
+0, 20, 20, 1, 12108, 0xc386941d
+1, 25, 25, 1, 2304, 0x7f13bf6e
+1, 26, 26, 1, 2304, 0xd302a5cd
+0, 21, 21, 1, 12796, 0x8b7e5dab
+1, 27, 27, 1, 2304, 0x7a7a9e30
+0, 22, 22, 1, 13316, 0x81235102
+1, 28, 28, 1, 2304, 0x6ffccfdd
+0, 23, 23, 1, 13724, 0xe5fc2bca
+1, 29, 29, 1, 2304, 0xae88bf7a
+0, 24, 24, 1, 14304, 0xa5b1f811
+1, 30, 30, 1, 2304, 0xf816c2f5
+1, 31, 31, 1, 2304, 0xdb42a783
+0, 25, 25, 1, 15216, 0xf4996763
+1, 32, 32, 1, 2304, 0xfc55c021
+0, 26, 26, 1, 16224, 0xe30b0679
+1, 33, 33, 1, 2304, 0x9da68fc1
+0, 27, 27, 1, 10640, 0xaeb122c9
+1, 34, 34, 1, 2304, 0x2f65bb0f
+0, 28, 28, 1, 11652, 0x087d18b1
+1, 35, 35, 1, 2304, 0x6e5da2c7
+1, 36, 36, 1, 2304, 0xb0b0c5f8
+0, 29, 29, 1, 12008, 0x1eeeac41
+1, 37, 37, 1, 2304, 0x32559dc6
+0, 30, 30, 1, 12344, 0x488c64ec
+1, 38, 38, 1, 2304, 0x9168aed0
+0, 31, 31, 1, 13004, 0x02a69339
+1, 39, 39, 1, 2304, 0x32069bce
+0, 32, 32, 1, 14092, 0x348a7d3f
+1, 40, 40, 1, 2304, 0x763ca8e0
+1, 41, 41, 1, 2304, 0x70c7a44e
+0, 33, 33, 1, 15048, 0xa55ef200
+1, 42, 42, 1, 2304, 0x7dc1b275
+0, 34, 34, 1, 16100, 0xac17de5b
+1, 43, 43, 1, 2304, 0x2e26ceae
+0, 35, 35, 1, 13180, 0x4d874f61
+1, 44, 44, 1, 2304, 0xa071a7e2
+0, 36, 36, 1, 14592, 0x5f58f505
+1, 45, 45, 1, 2304, 0xe434ad92
+1, 46, 46, 1, 2304, 0xb4469381
+0, 37, 37, 1, 14372, 0x369bb5d9
+1, 47, 47, 1, 2304, 0x3f20a7c5
+0, 38, 38, 1, 16172, 0x513a97b6
+1, 48, 48, 1, 2304, 0x68ef9ef9
+0, 39, 39, 1, 15136, 0x7f9a3865
+1, 49, 49, 1, 2304, 0x32dbb3e2
+0, 40, 40, 1, 16336, 0x1339ba5f
+1, 50, 50, 1, 2304, 0xdd90c7c3
+1, 51, 51, 1, 2304, 0xd106adb5
+0, 41, 41, 1, 16944, 0x122f71b7
+1, 52, 52, 1, 2304, 0x11dca8c4
+0, 42, 42, 1, 17536, 0x7461b152
+1, 53, 53, 1, 2304, 0x646d98bc
+0, 43, 43, 1, 13940, 0xf5278274
+1, 54, 54, 1, 2304, 0x6f019e81
+0, 44, 44, 1, 8592, 0x4bb2eaea
+1, 55, 55, 1, 2304, 0xc872a896
+1, 56, 56, 1, 2304, 0xc7d7a0bc
+0, 45, 45, 1, 8584, 0x2ff1e3db
+1, 57, 57, 1, 2304, 0x181b880a
+0, 46, 46, 1, 8548, 0xadfd01b4
+1, 58, 58, 1, 2304, 0x6486b158
+0, 47, 47, 1, 8548, 0x9e2ec85f
+1, 59, 59, 1, 2304, 0x26d5a3db
+0, 48, 48, 1, 8540, 0x9e2ad166
+1, 60, 60, 1, 2304, 0x4ff89a4d
+1, 61, 61, 1, 2304, 0xc42e9552
+0, 49, 49, 1, 8524, 0x047bc406
+1, 62, 62, 1, 2304, 0x0dc1c346
+0, 50, 50, 1, 8508, 0xd051ddbb
+1, 63, 63, 1, 2304, 0x5e51b7a5
+0, 51, 51, 1, 8572, 0x40b5004c
+1, 64, 64, 1, 2304, 0xbd49c142
+0, 52, 52, 1, 8564, 0xb379db59
+1, 65, 65, 1, 2304, 0x373da274
+1, 66, 66, 1, 2304, 0xde97b1bb
+0, 53, 53, 1, 8592, 0x22d0bc35
+1, 67, 67, 1, 2304, 0x9715bf29
+0, 54, 54, 1, 8656, 0xa58917d5
+1, 68, 68, 1, 2304, 0xc341b4ef
+0, 55, 55, 1, 8616, 0xc9e4f431
+1, 69, 69, 1, 2304, 0xc610adc6
+0, 56, 56, 1, 8660, 0x7a90ffd1
+1, 70, 70, 1, 2304, 0x67bba315
+1, 71, 71, 1, 2304, 0x949b9c16
+0, 57, 57, 1, 8636, 0xec8ce437
+1, 72, 72, 1, 2304, 0xc7c1a8ca
+0, 58, 58, 1, 8668, 0x8b73139f
+1, 73, 73, 1, 2304, 0x1929bc7e
+0, 59, 59, 1, 8640, 0x3ee30f9c
+1, 74, 74, 1, 2304, 0x5fc97897
+0, 60, 60, 1, 8728, 0xdbe12a94
+1, 75, 75, 1, 2304, 0x272da8d3
+1, 76, 76, 1, 2304, 0x141e904d
+0, 61, 61, 1, 8748, 0xc4132fd5
+1, 77, 77, 1, 2304, 0x9880b0ed
+0, 62, 62, 1, 8720, 0x7ac9316a
+1, 78, 78, 1, 2304, 0x0438932a
+0, 63, 63, 1, 8756, 0xf47d843d
+1, 79, 79, 1, 2304, 0x27069761
+0, 64, 64, 1, 8840, 0x82808e79
+1, 80, 80, 1, 2304, 0x0baba2b7
+1, 81, 81, 1, 2304, 0x4bc491af
+0, 65, 65, 1, 8908, 0x63568647
+1, 82, 82, 1, 2304, 0x72e18e82
+0, 66, 66, 1, 8968, 0xbd26de31
+1, 83, 83, 1, 2304, 0xf85d8a91
+0, 67, 67, 1, 9168, 0xe1cd43a3
+1, 84, 84, 1, 2304, 0x653582e3
+0, 68, 68, 1, 9272, 0x0cc64c79
+1, 85, 85, 1, 2304, 0x6b5e8084
+1, 86, 86, 1, 2304, 0x8cc27d10
+0, 69, 69, 1, 9700, 0x5cd2be73
+1, 87, 87, 1, 2304, 0xcf8f9e1d
+0, 70, 70, 1, 9868, 0x9b1629ae
+1, 88, 88, 1, 2304, 0xecbe89df
+0, 71, 71, 1, 10264, 0xa13cb7db
+1, 89, 89, 1, 2304, 0xa433753d
+0, 72, 72, 1, 10908, 0xe995858e
+1, 90, 90, 1, 2304, 0xe386afe9
+1, 91, 91, 1, 2304, 0x90409771
+0, 73, 73, 1, 11272, 0xebea53f6
+1, 92, 92, 1, 2304, 0x29c88ae5
+0, 74, 74, 1, 12128, 0xdfa8b7aa
+1, 93, 93, 1, 2304, 0x900b9e6a
+0, 75, 75, 1, 12560, 0x46048576
+1, 94, 94, 1, 2304, 0x958cbb49
+0, 76, 76, 1, 12900, 0x5b3aeb76
+1, 95, 95, 1, 2304, 0xf83da537
+1, 96, 96, 1, 2304, 0x5fad9e5f
+0, 77, 77, 1, 13544, 0x0f98fb94
+1, 97, 97, 1, 2304, 0xae15902a
+0, 78, 78, 1, 13968, 0x7c17c4c2
+1, 98, 98, 1, 2304, 0xf2a8b9d8
+0, 79, 79, 1, 15020, 0xe8faa930
+1, 99, 99, 1, 2304, 0x7bc99f71
+0, 80, 80, 1, 16152, 0x3f004f78
+1, 100, 100, 1, 2304, 0x3f199672
+1, 101, 101, 1, 2304, 0x4e258c38
+0, 81, 81, 1, 17224, 0x103f3935
+1, 102, 102, 1, 2304, 0x5119b909
+0, 82, 82, 1, 11956, 0x7af9354a
+1, 103, 103, 1, 2304, 0xad57a533
+0, 83, 83, 1, 12644, 0xe113a4b2
+1, 104, 104, 1, 2304, 0xe40eb453
+0, 84, 84, 1, 13420, 0xdf3ec8a4
+1, 105, 105, 1, 2304, 0x502cc37e
+1, 106, 106, 1, 2304, 0x5b7bae9a
+0, 85, 85, 1, 14140, 0x0ad8a165
+1, 107, 107, 1, 2304, 0x0458a92d
+0, 86, 86, 1, 15192, 0xc55f45cd
+1, 108, 108, 1, 2304, 0x1529aba8
+0, 87, 87, 1, 12740, 0xa13c85db
+1, 109, 109, 1, 2304, 0x1a52a9d1
+0, 88, 88, 1, 14416, 0x9e68b57d
+1, 110, 110, 1, 2304, 0x76a2a7c9
diff --git a/tests/ref/fate/qtrle-1bit b/tests/ref/fate/qtrle-1bit
index 230cae6..1cbaa9c 100644
--- a/tests/ref/fate/qtrle-1bit
+++ b/tests/ref/fate/qtrle-1bit
@@ -1,109 +1,39 @@
#tb 0: 1/1200
-#tb 1: 1/22050
0, 0, 0, 0, 9600, 0xc1632102
-1, 0, 0, 1020, 2040, 0x0a157db4
-1, 1020, 1020, 1020, 2040, 0x00c63e08
0, 100, 100, 0, 9600, 0x0f6c0521
-1, 2040, 2040, 1020, 2040, 0xacf2a25b
-1, 3060, 3060, 1020, 2040, 0xd6189e85
0, 200, 200, 0, 9600, 0x04b90b5a
-1, 4080, 4080, 1020, 2040, 0x8276f843
-1, 5100, 5100, 1020, 2040, 0xadebae73
0, 300, 300, 0, 9600, 0x2ebd4500
-1, 6120, 6120, 1020, 2040, 0x5da76697
-1, 7140, 7140, 1020, 2040, 0x469d0ea7
0, 400, 400, 0, 9600, 0x726f46f4
-1, 8160, 8160, 1020, 2040, 0x0d7412e1
-1, 9180, 9180, 1020, 2040, 0x2f2cc63f
0, 500, 500, 0, 9600, 0x37f6968e
-1, 10200, 10200, 1020, 2040, 0x10106eb7
0, 600, 600, 0, 9600, 0x7305872e
-1, 11220, 11220, 1020, 2040, 0x300124c7
-1, 12240, 12240, 1020, 2040, 0xa329f8e8
0, 700, 700, 0, 9600, 0x222eff5e
-1, 13260, 13260, 1020, 2040, 0xcea35ca5
-1, 14280, 14280, 1020, 2040, 0x55105aef
0, 800, 800, 0, 9600, 0x9317e227
-1, 15300, 15300, 1020, 2040, 0x08980ce1
-1, 16320, 16320, 1020, 2040, 0x367faf24
0, 900, 900, 0, 9600, 0x421eee9d
-1, 17340, 17340, 1020, 2040, 0x75bfef06
-1, 18360, 18360, 1020, 2040, 0x34f1daf4
0, 1000, 1000, 0, 9600, 0xcbcfaaff
-1, 19380, 19380, 1020, 2040, 0x97050317
0, 1100, 1100, 0, 9600, 0xe7d43be2
-1, 20400, 20400, 1020, 2040, 0xd297c536
-1, 21420, 21420, 1020, 2040, 0xa8abad5a
0, 1200, 1200, 0, 9600, 0x0b71e28c
-1, 22440, 22440, 1020, 2040, 0x445ce8e0
-1, 23460, 23460, 1020, 2040, 0xa3f4d940
0, 1300, 1300, 0, 9600, 0xd6a050ca
-1, 24480, 24480, 1020, 2040, 0x0ebb7b26
-1, 25500, 25500, 1020, 2040, 0x4372f6f6
0, 1400, 1400, 0, 9600, 0x0ac6dbf5
-1, 26520, 26520, 1020, 2040, 0xd4365079
-1, 27540, 27540, 1020, 2040, 0x56f902f7
0, 1500, 1500, 0, 9600, 0x5c036038
-1, 28560, 28560, 1020, 2040, 0x4153938a
0, 1600, 1600, 0, 9600, 0x6e417ed6
-1, 29580, 29580, 1020, 2040, 0x14996d86
-1, 30600, 30600, 1020, 2040, 0x3f99c318
0, 1700, 1700, 0, 9600, 0x8bd0dc22
-1, 31620, 31620, 1020, 2040, 0x939978a5
-1, 32640, 32640, 1020, 2040, 0x7086bd44
0, 1800, 1800, 0, 9600, 0xdf3b0877
-1, 33660, 33660, 138, 276, 0x25b89d22
-1, 33798, 33798, 1020, 2040, 0xf3edb106
-1, 34818, 34818, 1020, 2040, 0x0ca61430
0, 1900, 1900, 0, 9600, 0xae6e7823
-1, 35838, 35838, 1020, 2040, 0x7229c458
0, 2000, 2000, 0, 9600, 0x8ff0ac32
-1, 36858, 36858, 1020, 2040, 0xc37edd31
-1, 37878, 37878, 1020, 2040, 0xa3da98b4
0, 2100, 2100, 0, 9600, 0xa2d9e2ce
-1, 38898, 38898, 1020, 2040, 0x69704803
-1, 39918, 39918, 1020, 2040, 0xa79bf334
0, 2200, 2200, 0, 9600, 0x5fd92b65
-1, 40938, 40938, 1020, 2040, 0x59d8d4c4
-1, 41958, 41958, 1020, 2040, 0xf9ff0271
0, 2300, 2300, 0, 9600, 0x81c1c824
-1, 42978, 42978, 1020, 2040, 0xc4ced9d6
-1, 43998, 43998, 1020, 2040, 0x859f1912
0, 2400, 2400, 0, 9600, 0xb8a2ace4
-1, 45018, 45018, 1020, 2040, 0xe7955aa6
0, 2500, 2500, 0, 9600, 0x65b70404
-1, 46038, 46038, 1020, 2040, 0x374624fd
-1, 47058, 47058, 1020, 2040, 0x52121097
0, 2600, 2600, 0, 9600, 0xc5349eb2
-1, 48078, 48078, 1020, 2040, 0x660fe645
-1, 49098, 49098, 1020, 2040, 0xf624176a
0, 2700, 2700, 0, 9600, 0xf60cc2b8
-1, 50118, 50118, 1020, 2040, 0x1f2246dd
-1, 51138, 51138, 1020, 2040, 0x940e0a32
0, 2800, 2800, 0, 9600, 0x31474595
-1, 52158, 52158, 1020, 2040, 0x9c6d338c
-1, 53178, 53178, 1020, 2040, 0xfce0d30a
0, 2900, 2900, 0, 9600, 0xf602635b
-1, 54198, 54198, 1020, 2040, 0xd0ec9aa5
0, 3000, 3000, 0, 9600, 0x873cbd87
-1, 55218, 55218, 1020, 2040, 0x58012141
-1, 56238, 56238, 1020, 2040, 0xde67fc43
0, 3100, 3100, 0, 9600, 0xb9793ffe
-1, 57258, 57258, 1020, 2040, 0x6baa0450
-1, 58278, 58278, 1020, 2040, 0xf4f80252
0, 3200, 3200, 0, 9600, 0x42eb2831
-1, 59298, 59298, 1020, 2040, 0x0cd47ee3
-1, 60318, 60318, 1020, 2040, 0x129cbaa7
0, 3300, 3300, 0, 9600, 0x44cc1dab
-1, 61338, 61338, 1020, 2040, 0x5ef5c0a1
-1, 62358, 62358, 1020, 2040, 0xf660baa7
0, 3400, 3400, 0, 9600, 0xbdcbbb87
-1, 63378, 63378, 1020, 2040, 0xe48bc0a1
0, 3500, 3500, 0, 9600, 0x29c22df7
-1, 64398, 64398, 1020, 2040, 0xdfeabaa7
-1, 65418, 65418, 1020, 2040, 0xed04c0a1
0, 3600, 3600, 0, 9600, 0xde502ef5
-1, 66438, 66438, 1020, 2040, 0xd771baa7
-1, 67458, 67458, 150, 300, 0x521f24e9
-1, 67608, 67608, 738, 1476, 0x9b9394b1
0, 3700, 3700, 0, 9600, 0xaf311aeb
diff --git a/tests/ref/fate/qtrle-2bit b/tests/ref/fate/qtrle-2bit
index 2a43a84..5866db5 100644
--- a/tests/ref/fate/qtrle-2bit
+++ b/tests/ref/fate/qtrle-2bit
@@ -1,109 +1,39 @@
#tb 0: 1/1200
-#tb 1: 1/22050
0, 0, 0, 0, 230400, 0xb1ee55dc
-1, 0, 0, 1020, 2040, 0x0a157db4
-1, 1020, 1020, 1020, 2040, 0x00c63e08
0, 100, 100, 0, 230400, 0x97c580bf
-1, 2040, 2040, 1020, 2040, 0xacf2a25b
-1, 3060, 3060, 1020, 2040, 0xd6189e85
0, 200, 200, 0, 230400, 0xd4bd57e8
-1, 4080, 4080, 1020, 2040, 0x8276f843
-1, 5100, 5100, 1020, 2040, 0xadebae73
0, 300, 300, 0, 230400, 0x412b79aa
-1, 6120, 6120, 1020, 2040, 0x5da76697
-1, 7140, 7140, 1020, 2040, 0x469d0ea7
0, 400, 400, 0, 230400, 0x928a44d1
-1, 8160, 8160, 1020, 2040, 0x0d7412e1
-1, 9180, 9180, 1020, 2040, 0x2f2cc63f
0, 500, 500, 0, 230400, 0x6bbdc0e4
-1, 10200, 10200, 1020, 2040, 0x10106eb7
0, 600, 600, 0, 230400, 0x382e960f
-1, 11220, 11220, 1020, 2040, 0x300124c7
-1, 12240, 12240, 1020, 2040, 0xa329f8e8
0, 700, 700, 0, 230400, 0x62c863ea
-1, 13260, 13260, 1020, 2040, 0xcea35ca5
-1, 14280, 14280, 1020, 2040, 0x55105aef
0, 800, 800, 0, 230400, 0xbfccd3ce
-1, 15300, 15300, 1020, 2040, 0x08980ce1
-1, 16320, 16320, 1020, 2040, 0x367faf24
0, 900, 900, 0, 230400, 0x1987cdd4
-1, 17340, 17340, 1020, 2040, 0x75bfef06
-1, 18360, 18360, 1020, 2040, 0x34f1daf4
0, 1000, 1000, 0, 230400, 0x40279727
-1, 19380, 19380, 1020, 2040, 0x97050317
0, 1100, 1100, 0, 230400, 0x9d4f6746
-1, 20400, 20400, 1020, 2040, 0xd297c536
-1, 21420, 21420, 1020, 2040, 0xa8abad5a
0, 1200, 1200, 0, 230400, 0x7b8a77ec
-1, 22440, 22440, 1020, 2040, 0x445ce8e0
-1, 23460, 23460, 1020, 2040, 0xa3f4d940
0, 1300, 1300, 0, 230400, 0x2ce7a781
-1, 24480, 24480, 1020, 2040, 0x0ebb7b26
-1, 25500, 25500, 1020, 2040, 0x4372f6f6
0, 1400, 1400, 0, 230400, 0xb749815e
-1, 26520, 26520, 1020, 2040, 0xd4365079
-1, 27540, 27540, 1020, 2040, 0x56f902f7
0, 1500, 1500, 0, 230400, 0x61c88610
-1, 28560, 28560, 1020, 2040, 0x4153938a
0, 1600, 1600, 0, 230400, 0x8449114d
-1, 29580, 29580, 1020, 2040, 0x14996d86
-1, 30600, 30600, 1020, 2040, 0x3f99c318
0, 1700, 1700, 0, 230400, 0x5f73e666
-1, 31620, 31620, 1020, 2040, 0x939978a5
-1, 32640, 32640, 1020, 2040, 0x7086bd44
0, 1800, 1800, 0, 230400, 0xbde53ce6
-1, 33660, 33660, 138, 276, 0x25b89d22
-1, 33798, 33798, 1020, 2040, 0xf3edb106
-1, 34818, 34818, 1020, 2040, 0x0ca61430
0, 1900, 1900, 0, 230400, 0x8c7406fd
-1, 35838, 35838, 1020, 2040, 0x7229c458
0, 2000, 2000, 0, 230400, 0xf9e9a3ef
-1, 36858, 36858, 1020, 2040, 0xc37edd31
-1, 37878, 37878, 1020, 2040, 0xa3da98b4
0, 2100, 2100, 0, 230400, 0x7e0a3077
-1, 38898, 38898, 1020, 2040, 0x69704803
-1, 39918, 39918, 1020, 2040, 0xa79bf334
0, 2200, 2200, 0, 230400, 0xd9245c5f
-1, 40938, 40938, 1020, 2040, 0x59d8d4c4
-1, 41958, 41958, 1020, 2040, 0xf9ff0271
0, 2300, 2300, 0, 230400, 0x6d077ea2
-1, 42978, 42978, 1020, 2040, 0xc4ced9d6
-1, 43998, 43998, 1020, 2040, 0x859f1912
0, 2400, 2400, 0, 230400, 0xf622bb2a
-1, 45018, 45018, 1020, 2040, 0xe7955aa6
0, 2500, 2500, 0, 230400, 0x35292dc8
-1, 46038, 46038, 1020, 2040, 0x374624fd
-1, 47058, 47058, 1020, 2040, 0x52121097
0, 2600, 2600, 0, 230400, 0xc0cea946
-1, 48078, 48078, 1020, 2040, 0x660fe645
-1, 49098, 49098, 1020, 2040, 0xf624176a
0, 2700, 2700, 0, 230400, 0x98b27b60
-1, 50118, 50118, 1020, 2040, 0x1f2246dd
-1, 51138, 51138, 1020, 2040, 0x940e0a32
0, 2800, 2800, 0, 230400, 0x668ef6bd
-1, 52158, 52158, 1020, 2040, 0x9c6d338c
-1, 53178, 53178, 1020, 2040, 0xfce0d30a
0, 2900, 2900, 0, 230400, 0x6c07a31c
-1, 54198, 54198, 1020, 2040, 0xd0ec9aa5
0, 3000, 3000, 0, 230400, 0x0b4a6ae1
-1, 55218, 55218, 1020, 2040, 0x58012141
-1, 56238, 56238, 1020, 2040, 0xde67fc43
0, 3100, 3100, 0, 230400, 0x945b9878
-1, 57258, 57258, 1020, 2040, 0x6baa0450
-1, 58278, 58278, 1020, 2040, 0xf4f80252
0, 3200, 3200, 0, 230400, 0xab28031c
-1, 59298, 59298, 1020, 2040, 0x0cd47ee3
-1, 60318, 60318, 1020, 2040, 0x129cbaa7
0, 3300, 3300, 0, 230400, 0x977252b0
-1, 61338, 61338, 1020, 2040, 0x5ef5c0a1
-1, 62358, 62358, 1020, 2040, 0xf660baa7
0, 3400, 3400, 0, 230400, 0x6c3d9706
-1, 63378, 63378, 1020, 2040, 0xe48bc0a1
0, 3500, 3500, 0, 230400, 0xe053bc2a
-1, 64398, 64398, 1020, 2040, 0xdfeabaa7
-1, 65418, 65418, 1020, 2040, 0xed04c0a1
0, 3600, 3600, 0, 230400, 0x4cf2fc7c
-1, 66438, 66438, 1020, 2040, 0xd771baa7
-1, 67458, 67458, 150, 300, 0x521f24e9
-1, 67608, 67608, 738, 1476, 0x9b9394b1
0, 3700, 3700, 0, 230400, 0x610beda7
diff --git a/tests/ref/fate/real-14_4 b/tests/ref/fate/ra-144
similarity index 100%
rename from tests/ref/fate/real-14_4
rename to tests/ref/fate/ra-144
diff --git a/tests/ref/fate/roqvideo b/tests/ref/fate/roqvideo
new file mode 100644
index 0000000..9febedb
--- /dev/null
+++ b/tests/ref/fate/roqvideo
@@ -0,0 +1,211 @@
+#tb 0: 1/30
+0, 0, 0, 1, 393216, 0x56995aac
+0, 1, 1, 1, 393216, 0xf9ed5d6c
+0, 2, 2, 1, 393216, 0xd3285d75
+0, 3, 3, 1, 393216, 0x82d15d62
+0, 4, 4, 1, 393216, 0x893e5d6f
+0, 5, 5, 1, 393216, 0x82d15d62
+0, 6, 6, 1, 393216, 0x893e5d6f
+0, 7, 7, 1, 393216, 0x82d15d62
+0, 8, 8, 1, 393216, 0x893e5d6f
+0, 9, 9, 1, 393216, 0x82d15d62
+0, 10, 10, 1, 393216, 0x893e5d6f
+0, 11, 11, 1, 393216, 0x82d15d62
+0, 12, 12, 1, 393216, 0x893e5d6f
+0, 13, 13, 1, 393216, 0x82d15d62
+0, 14, 14, 1, 393216, 0x893e5d6f
+0, 15, 15, 1, 393216, 0x82d15d62
+0, 16, 16, 1, 393216, 0x2ae39eca
+0, 17, 17, 1, 393216, 0x9254be70
+0, 18, 18, 1, 393216, 0x4b2ed384
+0, 19, 19, 1, 393216, 0xbbd9d8f7
+0, 20, 20, 1, 393216, 0x1f2be0c3
+0, 21, 21, 1, 393216, 0x2434eb25
+0, 22, 22, 1, 393216, 0xa6cced4e
+0, 23, 23, 1, 393216, 0xd116f38b
+0, 24, 24, 1, 393216, 0x6b86f380
+0, 25, 25, 1, 393216, 0xc1b3f8e9
+0, 26, 26, 1, 393216, 0x2993fd5d
+0, 27, 27, 1, 393216, 0xf489fe18
+0, 28, 28, 1, 393216, 0x9ef10501
+0, 29, 29, 1, 393216, 0x8faf0512
+0, 30, 30, 1, 393216, 0xa54d0736
+0, 31, 31, 1, 393216, 0xf4ef01e0
+0, 32, 32, 1, 393216, 0xe241ef51
+0, 33, 33, 1, 393216, 0xcc38e51f
+0, 34, 34, 1, 393216, 0xb1345876
+0, 35, 35, 1, 393216, 0xf9b0968b
+0, 36, 36, 1, 393216, 0x6bb1523f
+0, 37, 37, 1, 393216, 0x83469a05
+0, 38, 38, 1, 393216, 0x73e30882
+0, 39, 39, 1, 393216, 0x8673da66
+0, 40, 40, 1, 393216, 0xb67596d3
+0, 41, 41, 1, 393216, 0xf7638710
+0, 42, 42, 1, 393216, 0x813a8f47
+0, 43, 43, 1, 393216, 0xb3526555
+0, 44, 44, 1, 393216, 0x1b167be3
+0, 45, 45, 1, 393216, 0x99114562
+0, 46, 46, 1, 393216, 0xfafb0693
+0, 47, 47, 1, 393216, 0x121d96c8
+0, 48, 48, 1, 393216, 0xb3c68c5d
+0, 49, 49, 1, 393216, 0x2035b97f
+0, 50, 50, 1, 393216, 0xfbcaeb62
+0, 51, 51, 1, 393216, 0xfd5aea5d
+0, 52, 52, 1, 393216, 0x66efbddd
+0, 53, 53, 1, 393216, 0xf1e17862
+0, 54, 54, 1, 393216, 0x27fa584d
+0, 55, 55, 1, 393216, 0xe644ec5f
+0, 56, 56, 1, 393216, 0x7e3067ba
+0, 57, 57, 1, 393216, 0x1b6ba6fd
+0, 58, 58, 1, 393216, 0x55bdba34
+0, 59, 59, 1, 393216, 0xc67db2e4
+0, 60, 60, 1, 393216, 0x359de8a2
+0, 61, 61, 1, 393216, 0x7b7a32ef
+0, 62, 62, 1, 393216, 0xbe512a66
+0, 63, 63, 1, 393216, 0x681d82bf
+0, 64, 64, 1, 393216, 0xa2320ec5
+0, 65, 65, 1, 393216, 0xcfbd9954
+0, 66, 66, 1, 393216, 0x7fee9854
+0, 67, 67, 1, 393216, 0x70eec155
+0, 68, 68, 1, 393216, 0x114f684e
+0, 69, 69, 1, 393216, 0xe27f034f
+0, 70, 70, 1, 393216, 0xfbbd89b4
+0, 71, 71, 1, 393216, 0xcef4c58a
+0, 72, 72, 1, 393216, 0x9eea88e9
+0, 73, 73, 1, 393216, 0x911cea42
+0, 74, 74, 1, 393216, 0xec5727ea
+0, 75, 75, 1, 393216, 0xda998c33
+0, 76, 76, 1, 393216, 0xc82140ed
+0, 77, 77, 1, 393216, 0x4caa8591
+0, 78, 78, 1, 393216, 0x4944206c
+0, 79, 79, 1, 393216, 0xd4676a94
+0, 80, 80, 1, 393216, 0x9e0340b3
+0, 81, 81, 1, 393216, 0xbdef7f94
+0, 82, 82, 1, 393216, 0xfac05cb0
+0, 83, 83, 1, 393216, 0xfef5a369
+0, 84, 84, 1, 393216, 0x9fcb3711
+0, 85, 85, 1, 393216, 0x6d93f761
+0, 86, 86, 1, 393216, 0xe95dc1ae
+0, 87, 87, 1, 393216, 0x3e561557
+0, 88, 88, 1, 393216, 0x0fa7a049
+0, 89, 89, 1, 393216, 0xf16afb95
+0, 90, 90, 1, 393216, 0xe53a2064
+0, 91, 91, 1, 393216, 0x57f046a4
+0, 92, 92, 1, 393216, 0xf6f16a0c
+0, 93, 93, 1, 393216, 0xcba0c8b0
+0, 94, 94, 1, 393216, 0x5bdbe522
+0, 95, 95, 1, 393216, 0x0fed0151
+0, 96, 96, 1, 393216, 0xbf86faf8
+0, 97, 97, 1, 393216, 0x39854c5f
+0, 98, 98, 1, 393216, 0xd9b7760a
+0, 99, 99, 1, 393216, 0x8edcc1d9
+0, 100, 100, 1, 393216, 0x44ae1435
+0, 101, 101, 1, 393216, 0xbc3d6d73
+0, 102, 102, 1, 393216, 0xedd82647
+0, 103, 103, 1, 393216, 0x1c2e5ce3
+0, 104, 104, 1, 393216, 0x04e29afe
+0, 105, 105, 1, 393216, 0xb191578e
+0, 106, 106, 1, 393216, 0x31d75a06
+0, 107, 107, 1, 393216, 0xfdb6c56e
+0, 108, 108, 1, 393216, 0xf528f484
+0, 109, 109, 1, 393216, 0x87af758e
+0, 110, 110, 1, 393216, 0xc8bdafb7
+0, 111, 111, 1, 393216, 0x573afe93
+0, 112, 112, 1, 393216, 0xb03cb8f5
+0, 113, 113, 1, 393216, 0x6e03ac71
+0, 114, 114, 1, 393216, 0xf919164e
+0, 115, 115, 1, 393216, 0x80059f3c
+0, 116, 116, 1, 393216, 0xf4ea0b1a
+0, 117, 117, 1, 393216, 0xe7720ffb
+0, 118, 118, 1, 393216, 0x1ec0cd56
+0, 119, 119, 1, 393216, 0x2bc8cf18
+0, 120, 120, 1, 393216, 0xe0bf17b5
+0, 121, 121, 1, 393216, 0x660247e1
+0, 122, 122, 1, 393216, 0xcf66f2a9
+0, 123, 123, 1, 393216, 0x5494d5ab
+0, 124, 124, 1, 393216, 0x2c02f2c4
+0, 125, 125, 1, 393216, 0x93fa3783
+0, 126, 126, 1, 393216, 0x4cc50633
+0, 127, 127, 1, 393216, 0x3f179386
+0, 128, 128, 1, 393216, 0x2bca9e1b
+0, 129, 129, 1, 393216, 0x3e4af867
+0, 130, 130, 1, 393216, 0x7e7df93c
+0, 131, 131, 1, 393216, 0x577e4fb0
+0, 132, 132, 1, 393216, 0x34487f0a
+0, 133, 133, 1, 393216, 0x0937bcfc
+0, 134, 134, 1, 393216, 0xa9e75a5e
+0, 135, 135, 1, 393216, 0xf7bc0c89
+0, 136, 136, 1, 393216, 0x06dacca6
+0, 137, 137, 1, 393216, 0x7baaa4bd
+0, 138, 138, 1, 393216, 0x95477f5f
+0, 139, 139, 1, 393216, 0x51117526
+0, 140, 140, 1, 393216, 0x69656d03
+0, 141, 141, 1, 393216, 0xcbd061bb
+0, 142, 142, 1, 393216, 0x8d1d5be2
+0, 143, 143, 1, 393216, 0x43e55930
+0, 144, 144, 1, 393216, 0xb56f5872
+0, 145, 145, 1, 393216, 0x09a255e9
+0, 146, 146, 1, 393216, 0xcaaa5456
+0, 147, 147, 1, 393216, 0xd267501f
+0, 148, 148, 1, 393216, 0x7bef4eca
+0, 149, 149, 1, 393216, 0x9aa94af3
+0, 150, 150, 1, 393216, 0xd39d4a29
+0, 151, 151, 1, 393216, 0x7a754960
+0, 152, 152, 1, 393216, 0x3f004921
+0, 153, 153, 1, 393216, 0x0f784ca8
+0, 154, 154, 1, 393216, 0x2a062c70
+0, 155, 155, 1, 393216, 0x114ef770
+0, 156, 156, 1, 393216, 0xfb7673bf
+0, 157, 157, 1, 393216, 0xbaea88f7
+0, 158, 158, 1, 393216, 0x6fdfe2ec
+0, 159, 159, 1, 393216, 0xb7b2b398
+0, 160, 160, 1, 393216, 0x14ba127e
+0, 161, 161, 1, 393216, 0x660b3041
+0, 162, 162, 1, 393216, 0xe3f3302a
+0, 163, 163, 1, 393216, 0x34c7f1c9
+0, 164, 164, 1, 393216, 0xa8257bf4
+0, 165, 165, 1, 393216, 0xd63fc649
+0, 166, 166, 1, 393216, 0xf8e5b79c
+0, 167, 167, 1, 393216, 0xa67b52ab
+0, 168, 168, 1, 393216, 0xef8f9c74
+0, 169, 169, 1, 393216, 0x6d3aa6b6
+0, 170, 170, 1, 393216, 0x8c174ee6
+0, 171, 171, 1, 393216, 0x2dfbc524
+0, 172, 172, 1, 393216, 0x7d0808b6
+0, 173, 173, 1, 393216, 0x6cbdf6f5
+0, 174, 174, 1, 393216, 0xfe39bc53
+0, 175, 175, 1, 393216, 0xa3d869b0
+0, 176, 176, 1, 393216, 0x09f00057
+0, 177, 177, 1, 393216, 0x6ba56343
+0, 178, 178, 1, 393216, 0xb696ca3e
+0, 179, 179, 1, 393216, 0x4eba0225
+0, 180, 180, 1, 393216, 0xdd45464b
+0, 181, 181, 1, 393216, 0x2909a9ea
+0, 182, 182, 1, 393216, 0x12aa3f85
+0, 183, 183, 1, 393216, 0x59421352
+0, 184, 184, 1, 393216, 0x57ea0313
+0, 185, 185, 1, 393216, 0x4e5f3a38
+0, 186, 186, 1, 393216, 0x55bc932d
+0, 187, 187, 1, 393216, 0x666ee55d
+0, 188, 188, 1, 393216, 0xb0f84a69
+0, 189, 189, 1, 393216, 0xad3ae63f
+0, 190, 190, 1, 393216, 0x970fd47d
+0, 191, 191, 1, 393216, 0x86c418e0
+0, 192, 192, 1, 393216, 0x52c9ce50
+0, 193, 193, 1, 393216, 0xd54c98c8
+0, 194, 194, 1, 393216, 0xb40e5fea
+0, 195, 195, 1, 393216, 0x2aa74875
+0, 196, 196, 1, 393216, 0x305b251e
+0, 197, 197, 1, 393216, 0xab8c0780
+0, 198, 198, 1, 393216, 0x0101dd0e
+0, 199, 199, 1, 393216, 0x23739cab
+0, 200, 200, 1, 393216, 0xf05196a0
+0, 201, 201, 1, 393216, 0x932d1e00
+0, 202, 202, 1, 393216, 0x932d1e00
+0, 203, 203, 1, 393216, 0x932d1e00
+0, 204, 204, 1, 393216, 0x932d1e00
+0, 205, 205, 1, 393216, 0x932d1e00
+0, 206, 206, 1, 393216, 0x932d1e00
+0, 207, 207, 1, 393216, 0x932d1e00
+0, 208, 208, 1, 393216, 0x932d1e00
+0, 209, 209, 1, 393216, 0x932d1e00
diff --git a/tests/ref/fate/real-rv40 b/tests/ref/fate/rv40
similarity index 100%
rename from tests/ref/fate/real-rv40
rename to tests/ref/fate/rv40
diff --git a/tests/ref/fate/sierra-vmd b/tests/ref/fate/sierra-vmd
deleted file mode 100644
index c72813e..0000000
--- a/tests/ref/fate/sierra-vmd
+++ /dev/null
@@ -1,334 +0,0 @@
-#tb 0: 1/10
-#tb 1: 1/22050
-0, 0, 0, 1, 230400, 0x0224ab01
-1, 0, 0, 61740, 123480, 0x3a794c13
-0, 1, 1, 1, 230400, 0x449e4d81
-0, 2, 2, 1, 230400, 0x3e15e07a
-0, 3, 3, 1, 230400, 0xdabe4172
-0, 4, 4, 1, 230400, 0x0947b7db
-0, 5, 5, 1, 230400, 0x934e243b
-0, 6, 6, 1, 230400, 0x6b5c5b6c
-0, 7, 7, 1, 230400, 0x4bf7bbb5
-0, 8, 8, 1, 230400, 0x423eec8e
-0, 9, 9, 1, 230400, 0x63663b5e
-0, 10, 10, 1, 230400, 0x9c258a67
-0, 11, 11, 1, 230400, 0x1c92b6e0
-0, 12, 12, 1, 230400, 0xdd0a0e28
-0, 13, 13, 1, 230400, 0x51d64af1
-0, 14, 14, 1, 230400, 0x5776ac12
-0, 15, 15, 1, 230400, 0x49070132
-0, 16, 16, 1, 230400, 0xa59635ab
-0, 17, 17, 1, 230400, 0xb1f99504
-0, 18, 18, 1, 230400, 0x61fac725
-0, 19, 19, 1, 230400, 0xc32c28d5
-0, 20, 20, 1, 230400, 0x2b7a91d6
-0, 21, 21, 1, 230400, 0x917be717
-0, 22, 22, 1, 230400, 0xd3c5a2ff
-0, 23, 23, 1, 230400, 0x0678a707
-0, 24, 24, 1, 230400, 0x122504e6
-0, 25, 25, 1, 230400, 0x76aebdae
-0, 26, 26, 1, 230400, 0x81357545
-0, 27, 27, 1, 230400, 0x38baeebd
-0, 28, 28, 1, 230400, 0x1c5c44d4
-1, 61740, 61740, 2205, 4410, 0x109d04e0
-0, 29, 29, 1, 230400, 0x60e189cc
-1, 63945, 63945, 2205, 4410, 0x224d244f
-0, 30, 30, 1, 230400, 0xb1f4381c
-1, 66150, 66150, 2205, 4410, 0xbb72413d
-0, 31, 31, 1, 230400, 0xb5048fed
-1, 68355, 68355, 2205, 4410, 0xaa5f5b86
-0, 32, 32, 1, 230400, 0xc947c30e
-1, 70560, 70560, 2205, 4410, 0x94e7aea7
-0, 33, 33, 1, 230400, 0xe8e31c07
-1, 72765, 72765, 2205, 4410, 0xad497ca0
-0, 34, 34, 1, 230400, 0x6d49dd02
-1, 74970, 74970, 2205, 4410, 0x1de10c9e
-0, 35, 35, 1, 230400, 0x293e15d3
-1, 77175, 77175, 2205, 4410, 0x9f55efa8
-0, 36, 36, 1, 230400, 0x354d792e
-1, 79380, 79380, 2205, 4410, 0x220a072a
-0, 37, 37, 1, 230400, 0x35468780
-1, 81585, 81585, 2205, 4410, 0xa7dafb29
-0, 38, 38, 1, 230400, 0x365d3991
-1, 83790, 83790, 2205, 4410, 0xd5e29c7a
-0, 39, 39, 1, 230400, 0xc9debef2
-1, 85995, 85995, 2205, 4410, 0xb8465006
-0, 40, 40, 1, 230400, 0x4c4634c2
-1, 88200, 88200, 2205, 4410, 0x518669c7
-0, 41, 41, 1, 230400, 0x347c2dca
-1, 90405, 90405, 2205, 4410, 0xb5b5efca
-0, 42, 42, 1, 230400, 0x1efa0aaa
-1, 92610, 92610, 2205, 4410, 0x8600015d
-0, 43, 43, 1, 230400, 0xa79a0b5a
-1, 94815, 94815, 2205, 4410, 0xe2f68fe9
-0, 44, 44, 1, 230400, 0xfdb2dcdb
-1, 97020, 97020, 2205, 4410, 0x8d3458d9
-0, 45, 45, 1, 230400, 0x42dbea33
-1, 99225, 99225, 2205, 4410, 0xf1ff4775
-0, 46, 46, 1, 230400, 0x2a207e43
-1, 101430, 101430, 2205, 4410, 0x830f67c9
-0, 47, 47, 1, 230400, 0x86573783
-1, 103635, 103635, 2205, 4410, 0x110e0bc1
-0, 48, 48, 1, 230400, 0xc3968473
-1, 105840, 105840, 2205, 4410, 0x71682f47
-0, 49, 49, 1, 230400, 0x8f62a7b4
-1, 108045, 108045, 2205, 4410, 0x38119095
-0, 50, 50, 1, 230400, 0x5a2e3073
-1, 110250, 110250, 2205, 4410, 0xd2494db6
-0, 51, 51, 1, 230400, 0xd24f5e2c
-1, 112455, 112455, 2205, 4410, 0x8b552509
-0, 52, 52, 1, 230400, 0x1df3c67d
-1, 114660, 114660, 2205, 4410, 0x71e52909
-0, 53, 53, 1, 230400, 0xe4fd884d
-1, 116865, 116865, 2205, 4410, 0x9f0a6f4d
-1, 119070, 119070, 2205, 4410, 0x901302f2
-1, 121275, 121275, 2205, 4410, 0x855d5222
-1, 123480, 123480, 2205, 4410, 0x324bb2fe
-0, 57, 57, 1, 230400, 0x9a228555
-1, 125685, 125685, 2205, 4410, 0xe85f583f
-0, 58, 58, 1, 230400, 0x9eba8ed5
-1, 127890, 127890, 2205, 4410, 0x2cbc67c4
-0, 59, 59, 1, 230400, 0x3d808a3d
-1, 130095, 130095, 2205, 4410, 0xc82e6aa1
-0, 60, 60, 1, 230400, 0xf57e866d
-1, 132300, 132300, 2205, 4410, 0xb9fc423c
-0, 61, 61, 1, 230400, 0x85f594f5
-1, 134505, 134505, 2205, 4410, 0x6b9b4ef9
-0, 62, 62, 1, 230400, 0xb09f99dd
-1, 136710, 136710, 2205, 4410, 0x39290f10
-0, 63, 63, 1, 230400, 0x2b368475
-1, 138915, 138915, 2205, 4410, 0xad718eb4
-0, 64, 64, 1, 230400, 0xa2417afd
-1, 141120, 141120, 2205, 4410, 0x82f463ac
-0, 65, 65, 1, 230400, 0x590b709d
-1, 143325, 143325, 2205, 4410, 0xfac87cac
-0, 66, 66, 1, 230400, 0x5d617705
-1, 145530, 145530, 2205, 4410, 0x9e8bcca7
-0, 67, 67, 1, 230400, 0xabf981ad
-1, 147735, 147735, 2205, 4410, 0x52f79c99
-0, 68, 68, 1, 230400, 0x5a8590cd
-1, 149940, 149940, 2205, 4410, 0xf2d14de2
-0, 69, 69, 1, 230400, 0x1bff853d
-1, 152145, 152145, 2205, 4410, 0x367f95e1
-0, 70, 70, 1, 230400, 0x71d08055
-1, 154350, 154350, 2205, 4410, 0x8bfac293
-0, 71, 71, 1, 230400, 0x2ebd817d
-1, 156555, 156555, 2205, 4410, 0x01ea5040
-0, 72, 72, 1, 230400, 0x6e838255
-1, 158760, 158760, 2205, 4410, 0x8ff5e212
-0, 73, 73, 1, 230400, 0x043984cd
-1, 160965, 160965, 2205, 4410, 0x93f32824
-0, 74, 74, 1, 230400, 0x7ff18495
-1, 163170, 163170, 2205, 4410, 0x998f90dc
-0, 75, 75, 1, 230400, 0xa43b8385
-1, 165375, 165375, 2205, 4410, 0x65231170
-0, 76, 76, 1, 230400, 0x72b5825d
-1, 167580, 167580, 2205, 4410, 0xc79039a1
-0, 77, 77, 1, 230400, 0x3a178085
-1, 169785, 169785, 2205, 4410, 0x0b0e58bd
-0, 78, 78, 1, 230400, 0x67748245
-1, 171990, 171990, 2205, 4410, 0xc24ab4fa
-0, 79, 79, 1, 230400, 0xeddf81d5
-1, 174195, 174195, 2205, 4410, 0xd3796a8e
-0, 80, 80, 1, 230400, 0x8b088665
-1, 176400, 176400, 2205, 4410, 0xa37f8295
-0, 81, 81, 1, 230400, 0x6c408e15
-1, 178605, 178605, 2205, 4410, 0xb760fed7
-0, 82, 82, 1, 230400, 0x81f196dd
-1, 180810, 180810, 2205, 4410, 0x05495a34
-0, 83, 83, 1, 230400, 0xab9f953d
-1, 183015, 183015, 2205, 4410, 0x6f203437
-0, 84, 84, 1, 230400, 0xa5f69795
-1, 185220, 185220, 2205, 4410, 0x71299402
-0, 85, 85, 1, 230400, 0xa772950d
-1, 187425, 187425, 2205, 4410, 0x72e7b346
-0, 86, 86, 1, 230400, 0x6a5596d5
-1, 189630, 189630, 2205, 4410, 0x879b0dae
-0, 87, 87, 1, 230400, 0x1355958d
-1, 191835, 191835, 2205, 4410, 0x041aa1bd
-0, 88, 88, 1, 230400, 0x4134981d
-1, 194040, 194040, 2205, 4410, 0x18a962e6
-0, 89, 89, 1, 230400, 0x8b929515
-1, 196245, 196245, 2205, 4410, 0x21d20539
-0, 90, 90, 1, 230400, 0x482f95c5
-1, 198450, 198450, 2205, 4410, 0x8f449267
-0, 91, 91, 1, 230400, 0x7a9795d5
-1, 200655, 200655, 2205, 4410, 0xecdc01d6
-0, 92, 92, 1, 230400, 0x21c29abd
-1, 202860, 202860, 2205, 4410, 0x458abd5a
-0, 93, 93, 1, 230400, 0x9ae6a475
-1, 205065, 205065, 2205, 4410, 0xa070ea63
-0, 94, 94, 1, 230400, 0x3734aee5
-1, 207270, 207270, 2205, 4410, 0xc25b26ce
-0, 95, 95, 1, 230400, 0xa0a1b365
-1, 209475, 209475, 2205, 4410, 0x4d9237ca
-0, 96, 96, 1, 230400, 0x2dcab1c5
-1, 211680, 211680, 2205, 4410, 0x748e1801
-0, 97, 97, 1, 230400, 0x9c8b6c44
-1, 213885, 213885, 2205, 4410, 0xc96b69e6
-0, 98, 98, 1, 230400, 0x5da75feb
-1, 216090, 216090, 2205, 4410, 0x6663186c
-0, 99, 99, 1, 230400, 0x4d02f8e3
-1, 218295, 218295, 2205, 4410, 0x7f6d3081
-0, 100, 100, 1, 230400, 0x66824f3a
-1, 220500, 220500, 2205, 4410, 0x1a0343b5
-0, 101, 101, 1, 230400, 0x0c9257e2
-1, 222705, 222705, 2205, 4410, 0xc48e338c
-0, 102, 102, 1, 230400, 0xb2927092
-1, 224910, 224910, 2205, 4410, 0x26fc03c8
-0, 103, 103, 1, 230400, 0xb5dc6e9a
-1, 227115, 227115, 2205, 4410, 0x69be7e2d
-0, 104, 104, 1, 230400, 0x6e567bc6
-1, 229320, 229320, 2205, 4410, 0x69a74da1
-0, 105, 105, 1, 230400, 0xbf9e0f7a
-1, 231525, 231525, 2205, 4410, 0x85bd2ab3
-0, 106, 106, 1, 230400, 0xb16f684a
-1, 233730, 233730, 2205, 4410, 0xeff05426
-0, 107, 107, 1, 230400, 0xf9e55e81
-1, 235935, 235935, 2205, 4410, 0x292829e0
-0, 108, 108, 1, 230400, 0xd8d0bcba
-1, 238140, 238140, 2205, 4410, 0x8f741798
-0, 109, 109, 1, 230400, 0x44720ac0
-1, 240345, 240345, 2205, 4410, 0x6b9337e9
-0, 110, 110, 1, 230400, 0x7d4c2058
-1, 242550, 242550, 2205, 4410, 0xe4e1703f
-1, 244755, 244755, 2205, 4410, 0x043d6c35
-1, 246960, 246960, 2205, 4410, 0x3a8988e7
-0, 113, 113, 1, 230400, 0xb0973eb9
-1, 249165, 249165, 2205, 4410, 0x1fa7d2a9
-0, 114, 114, 1, 230400, 0x405a13ce
-1, 251370, 251370, 2205, 4410, 0xe28799e3
-0, 115, 115, 1, 230400, 0x6422f00a
-1, 253575, 253575, 2205, 4410, 0xc2df4470
-0, 116, 116, 1, 230400, 0x924b6c1e
-1, 255780, 255780, 2205, 4410, 0x694d0cf5
-1, 257985, 257985, 2205, 4410, 0x5aac2dcf
-1, 260190, 260190, 2205, 4410, 0x259fa2db
-1, 262395, 262395, 2205, 4410, 0xd16d6803
-1, 264600, 264600, 2205, 4410, 0xa4b3478a
-1, 266805, 266805, 2205, 4410, 0xdbe0443d
-1, 269010, 269010, 2205, 4410, 0x26c16119
-1, 271215, 271215, 2205, 4410, 0x0c06475c
-1, 273420, 273420, 2205, 4410, 0x6ffaba2d
-1, 275625, 275625, 2205, 4410, 0x5b287192
-1, 277830, 277830, 2205, 4410, 0xf2cf2651
-1, 280035, 280035, 2205, 4410, 0x3857673a
-1, 282240, 282240, 2205, 4410, 0x5b555feb
-1, 284445, 284445, 2205, 4410, 0x93f997af
-1, 286650, 286650, 2205, 4410, 0xb3ba8d35
-1, 288855, 288855, 2205, 4410, 0x66433944
-1, 291060, 291060, 2205, 4410, 0xf0005a5f
-1, 293265, 293265, 2205, 4410, 0xb948541f
-1, 295470, 295470, 2205, 4410, 0xc8f1b16f
-1, 297675, 297675, 2205, 4410, 0x7d4b7506
-1, 299880, 299880, 2205, 4410, 0xac723c55
-1, 302085, 302085, 2205, 4410, 0x2926fab5
-1, 304290, 304290, 2205, 4410, 0x31684995
-1, 306495, 306495, 2205, 4410, 0x35ebfca4
-1, 308700, 308700, 2205, 4410, 0x9cd42c18
-1, 310905, 310905, 2205, 4410, 0xd7ecd7b1
-1, 313110, 313110, 2205, 4410, 0x5e13c602
-1, 315315, 315315, 2205, 4410, 0xe955b5e3
-1, 317520, 317520, 2205, 4410, 0xefad19a1
-0, 145, 145, 1, 230400, 0xcf7809c0
-1, 319725, 319725, 2205, 4410, 0x435950de
-0, 146, 146, 1, 230400, 0x883a3863
-1, 321930, 321930, 2205, 4410, 0x9d624ebe
-0, 147, 147, 1, 230400, 0x6adc9e03
-1, 324135, 324135, 2205, 4410, 0x774a9158
-0, 148, 148, 1, 230400, 0x4f5ab7a8
-1, 326340, 326340, 2205, 4410, 0x8c41e66a
-1, 328545, 328545, 2205, 4410, 0x70112740
-1, 330750, 330750, 2205, 4410, 0x55abc7a2
-1, 332955, 332955, 2205, 4410, 0x0ec3183c
-1, 335160, 335160, 2205, 4410, 0x54609c56
-1, 337365, 337365, 2205, 4410, 0x60d49f92
-1, 339570, 339570, 2205, 4410, 0x5fb061c8
-1, 341775, 341775, 2205, 4410, 0x6e119c98
-1, 343980, 343980, 2205, 4410, 0x3f39fc69
-1, 346185, 346185, 2205, 4410, 0xef466d0e
-1, 348390, 348390, 2205, 4410, 0xf4cb6fe1
-1, 350595, 350595, 2205, 4410, 0xc4434439
-1, 352800, 352800, 2205, 4410, 0xd02329d2
-1, 355005, 355005, 2205, 4410, 0x216cffaf
-1, 357210, 357210, 2205, 4410, 0x7e59e8c1
-1, 359415, 359415, 2205, 4410, 0xc7c3346d
-1, 361620, 361620, 2205, 4410, 0x5b3723af
-1, 363825, 363825, 2205, 4410, 0x76097270
-1, 366030, 366030, 2205, 4410, 0xae39a233
-1, 368235, 368235, 2205, 4410, 0x686a471c
-1, 370440, 370440, 2205, 4410, 0x3af3c5e0
-1, 372645, 372645, 2205, 4410, 0x11ac711e
-1, 374850, 374850, 2205, 4410, 0xcd8da8ce
-1, 377055, 377055, 2205, 4410, 0x21296e3a
-1, 379260, 379260, 2205, 4410, 0x77168188
-1, 381465, 381465, 2205, 4410, 0x5fcf59cd
-1, 383670, 383670, 2205, 4410, 0x390c8717
-1, 385875, 385875, 2205, 4410, 0x3d5d5b3c
-1, 388080, 388080, 2205, 4410, 0x3b8f13d3
-1, 390285, 390285, 2205, 4410, 0x5b002c2f
-1, 392490, 392490, 2205, 4410, 0x9e1d2b08
-1, 394695, 394695, 2205, 4410, 0x69454ebd
-1, 396900, 396900, 2205, 4410, 0x62a54bec
-1, 399105, 399105, 2205, 4410, 0x4d231fdb
-1, 401310, 401310, 2205, 4410, 0x65624ff7
-1, 403515, 403515, 2205, 4410, 0x6fc66932
-1, 405720, 405720, 2205, 4410, 0x23200cf6
-1, 407925, 407925, 2205, 4410, 0xf8033122
-1, 410130, 410130, 2205, 4410, 0x0fce0744
-1, 412335, 412335, 2205, 4410, 0x9302683e
-1, 414540, 414540, 2205, 4410, 0xd2380245
-1, 416745, 416745, 2205, 4410, 0x482e0872
-1, 418950, 418950, 2205, 4410, 0xe98e6461
-1, 421155, 421155, 2205, 4410, 0x1db404e3
-1, 423360, 423360, 2205, 4410, 0x47a26d45
-1, 425565, 425565, 2205, 4410, 0x449a348a
-1, 427770, 427770, 2205, 4410, 0xee874f84
-1, 429975, 429975, 2205, 4410, 0xc4ecf965
-1, 432180, 432180, 2205, 4410, 0xcc450bc8
-1, 434385, 434385, 2205, 4410, 0xb18d044b
-1, 436590, 436590, 2205, 4410, 0x895435e8
-1, 438795, 438795, 2205, 4410, 0x57e7574e
-1, 441000, 441000, 2205, 4410, 0x8041ad3d
-1, 443205, 443205, 2205, 4410, 0x853d1616
-1, 445410, 445410, 2205, 4410, 0xa11bb32b
-1, 447615, 447615, 2205, 4410, 0xe10ea0de
-1, 449820, 449820, 2205, 4410, 0xdf2ee328
-1, 452025, 452025, 2205, 4410, 0xd5a6dcae
-1, 454230, 454230, 2205, 4410, 0xd176c00b
-1, 456435, 456435, 2205, 4410, 0x9cd6bcf3
-1, 458640, 458640, 2205, 4410, 0x2569690a
-1, 460845, 460845, 2205, 4410, 0x6824aa1d
-1, 463050, 463050, 2205, 4410, 0xa9110afa
-1, 465255, 465255, 2205, 4410, 0x115c25be
-1, 467460, 467460, 2205, 4410, 0x1100f085
-1, 469665, 469665, 2205, 4410, 0x00000000
-0, 214, 214, 1, 230400, 0xdc0aab94
-1, 471870, 471870, 2205, 4410, 0x00000000
-1, 474075, 474075, 2205, 4410, 0x00000000
-1, 476280, 476280, 2205, 4410, 0x00000000
-1, 478485, 478485, 2205, 4410, 0x00000000
-1, 480690, 480690, 2205, 4410, 0x00000000
-1, 482895, 482895, 2205, 4410, 0x00000000
-1, 485100, 485100, 2205, 4410, 0x00000000
-1, 487305, 487305, 2205, 4410, 0x00000000
-1, 489510, 489510, 2205, 4410, 0x00000000
-1, 491715, 491715, 2205, 4410, 0x00000000
-1, 493920, 493920, 2205, 4410, 0x00000000
-1, 496125, 496125, 2205, 4410, 0x00000000
-1, 498330, 498330, 2205, 4410, 0x00000000
-1, 500535, 500535, 2205, 4410, 0x00000000
-1, 502740, 502740, 2205, 4410, 0x00000000
-1, 504945, 504945, 2205, 4410, 0x00000000
-1, 507150, 507150, 2205, 4410, 0x00000000
-1, 509355, 509355, 2205, 4410, 0x00000000
-1, 511560, 511560, 2205, 4410, 0x00000000
-1, 513765, 513765, 2205, 4410, 0x00000000
-1, 515970, 515970, 2205, 4410, 0x00000000
-1, 518175, 518175, 2205, 4410, 0x00000000
-1, 520380, 520380, 2205, 4410, 0x00000000
-1, 522585, 522585, 2205, 4410, 0x00000000
-1, 524790, 524790, 2205, 4410, 0x00000000
-1, 526995, 526995, 2205, 4410, 0x00000000
-1, 529200, 529200, 2205, 4410, 0x00000000
-1, 531405, 531405, 2205, 4410, 0x00000000
diff --git a/tests/ref/fate/sierra-vmd-audio b/tests/ref/fate/sierra-vmd-audio
new file mode 100644
index 0000000..13d3567
--- /dev/null
+++ b/tests/ref/fate/sierra-vmd-audio
@@ -0,0 +1,216 @@
+#tb 0: 1/22050
+0, 0, 0, 61740, 123480, 0x3a794c13
+0, 61740, 61740, 2205, 4410, 0x109d04e0
+0, 63945, 63945, 2205, 4410, 0x224d244f
+0, 66150, 66150, 2205, 4410, 0xbb72413d
+0, 68355, 68355, 2205, 4410, 0xaa5f5b86
+0, 70560, 70560, 2205, 4410, 0x94e7aea7
+0, 72765, 72765, 2205, 4410, 0xad497ca0
+0, 74970, 74970, 2205, 4410, 0x1de10c9e
+0, 77175, 77175, 2205, 4410, 0x9f55efa8
+0, 79380, 79380, 2205, 4410, 0x220a072a
+0, 81585, 81585, 2205, 4410, 0xa7dafb29
+0, 83790, 83790, 2205, 4410, 0xd5e29c7a
+0, 85995, 85995, 2205, 4410, 0xb8465006
+0, 88200, 88200, 2205, 4410, 0x518669c7
+0, 90405, 90405, 2205, 4410, 0xb5b5efca
+0, 92610, 92610, 2205, 4410, 0x8600015d
+0, 94815, 94815, 2205, 4410, 0xe2f68fe9
+0, 97020, 97020, 2205, 4410, 0x8d3458d9
+0, 99225, 99225, 2205, 4410, 0xf1ff4775
+0, 101430, 101430, 2205, 4410, 0x830f67c9
+0, 103635, 103635, 2205, 4410, 0x110e0bc1
+0, 105840, 105840, 2205, 4410, 0x71682f47
+0, 108045, 108045, 2205, 4410, 0x38119095
+0, 110250, 110250, 2205, 4410, 0xd2494db6
+0, 112455, 112455, 2205, 4410, 0x8b552509
+0, 114660, 114660, 2205, 4410, 0x71e52909
+0, 116865, 116865, 2205, 4410, 0x9f0a6f4d
+0, 119070, 119070, 2205, 4410, 0x901302f2
+0, 121275, 121275, 2205, 4410, 0x855d5222
+0, 123480, 123480, 2205, 4410, 0x324bb2fe
+0, 125685, 125685, 2205, 4410, 0xe85f583f
+0, 127890, 127890, 2205, 4410, 0x2cbc67c4
+0, 130095, 130095, 2205, 4410, 0xc82e6aa1
+0, 132300, 132300, 2205, 4410, 0xb9fc423c
+0, 134505, 134505, 2205, 4410, 0x6b9b4ef9
+0, 136710, 136710, 2205, 4410, 0x39290f10
+0, 138915, 138915, 2205, 4410, 0xad718eb4
+0, 141120, 141120, 2205, 4410, 0x82f463ac
+0, 143325, 143325, 2205, 4410, 0xfac87cac
+0, 145530, 145530, 2205, 4410, 0x9e8bcca7
+0, 147735, 147735, 2205, 4410, 0x52f79c99
+0, 149940, 149940, 2205, 4410, 0xf2d14de2
+0, 152145, 152145, 2205, 4410, 0x367f95e1
+0, 154350, 154350, 2205, 4410, 0x8bfac293
+0, 156555, 156555, 2205, 4410, 0x01ea5040
+0, 158760, 158760, 2205, 4410, 0x8ff5e212
+0, 160965, 160965, 2205, 4410, 0x93f32824
+0, 163170, 163170, 2205, 4410, 0x998f90dc
+0, 165375, 165375, 2205, 4410, 0x65231170
+0, 167580, 167580, 2205, 4410, 0xc79039a1
+0, 169785, 169785, 2205, 4410, 0x0b0e58bd
+0, 171990, 171990, 2205, 4410, 0xc24ab4fa
+0, 174195, 174195, 2205, 4410, 0xd3796a8e
+0, 176400, 176400, 2205, 4410, 0xa37f8295
+0, 178605, 178605, 2205, 4410, 0xb760fed7
+0, 180810, 180810, 2205, 4410, 0x05495a34
+0, 183015, 183015, 2205, 4410, 0x6f203437
+0, 185220, 185220, 2205, 4410, 0x71299402
+0, 187425, 187425, 2205, 4410, 0x72e7b346
+0, 189630, 189630, 2205, 4410, 0x879b0dae
+0, 191835, 191835, 2205, 4410, 0x041aa1bd
+0, 194040, 194040, 2205, 4410, 0x18a962e6
+0, 196245, 196245, 2205, 4410, 0x21d20539
+0, 198450, 198450, 2205, 4410, 0x8f449267
+0, 200655, 200655, 2205, 4410, 0xecdc01d6
+0, 202860, 202860, 2205, 4410, 0x458abd5a
+0, 205065, 205065, 2205, 4410, 0xa070ea63
+0, 207270, 207270, 2205, 4410, 0xc25b26ce
+0, 209475, 209475, 2205, 4410, 0x4d9237ca
+0, 211680, 211680, 2205, 4410, 0x748e1801
+0, 213885, 213885, 2205, 4410, 0xc96b69e6
+0, 216090, 216090, 2205, 4410, 0x6663186c
+0, 218295, 218295, 2205, 4410, 0x7f6d3081
+0, 220500, 220500, 2205, 4410, 0x1a0343b5
+0, 222705, 222705, 2205, 4410, 0xc48e338c
+0, 224910, 224910, 2205, 4410, 0x26fc03c8
+0, 227115, 227115, 2205, 4410, 0x69be7e2d
+0, 229320, 229320, 2205, 4410, 0x69a74da1
+0, 231525, 231525, 2205, 4410, 0x85bd2ab3
+0, 233730, 233730, 2205, 4410, 0xeff05426
+0, 235935, 235935, 2205, 4410, 0x292829e0
+0, 238140, 238140, 2205, 4410, 0x8f741798
+0, 240345, 240345, 2205, 4410, 0x6b9337e9
+0, 242550, 242550, 2205, 4410, 0xe4e1703f
+0, 244755, 244755, 2205, 4410, 0x043d6c35
+0, 246960, 246960, 2205, 4410, 0x3a8988e7
+0, 249165, 249165, 2205, 4410, 0x1fa7d2a9
+0, 251370, 251370, 2205, 4410, 0xe28799e3
+0, 253575, 253575, 2205, 4410, 0xc2df4470
+0, 255780, 255780, 2205, 4410, 0x694d0cf5
+0, 257985, 257985, 2205, 4410, 0x5aac2dcf
+0, 260190, 260190, 2205, 4410, 0x259fa2db
+0, 262395, 262395, 2205, 4410, 0xd16d6803
+0, 264600, 264600, 2205, 4410, 0xa4b3478a
+0, 266805, 266805, 2205, 4410, 0xdbe0443d
+0, 269010, 269010, 2205, 4410, 0x26c16119
+0, 271215, 271215, 2205, 4410, 0x0c06475c
+0, 273420, 273420, 2205, 4410, 0x6ffaba2d
+0, 275625, 275625, 2205, 4410, 0x5b287192
+0, 277830, 277830, 2205, 4410, 0xf2cf2651
+0, 280035, 280035, 2205, 4410, 0x3857673a
+0, 282240, 282240, 2205, 4410, 0x5b555feb
+0, 284445, 284445, 2205, 4410, 0x93f997af
+0, 286650, 286650, 2205, 4410, 0xb3ba8d35
+0, 288855, 288855, 2205, 4410, 0x66433944
+0, 291060, 291060, 2205, 4410, 0xf0005a5f
+0, 293265, 293265, 2205, 4410, 0xb948541f
+0, 295470, 295470, 2205, 4410, 0xc8f1b16f
+0, 297675, 297675, 2205, 4410, 0x7d4b7506
+0, 299880, 299880, 2205, 4410, 0xac723c55
+0, 302085, 302085, 2205, 4410, 0x2926fab5
+0, 304290, 304290, 2205, 4410, 0x31684995
+0, 306495, 306495, 2205, 4410, 0x35ebfca4
+0, 308700, 308700, 2205, 4410, 0x9cd42c18
+0, 310905, 310905, 2205, 4410, 0xd7ecd7b1
+0, 313110, 313110, 2205, 4410, 0x5e13c602
+0, 315315, 315315, 2205, 4410, 0xe955b5e3
+0, 317520, 317520, 2205, 4410, 0xefad19a1
+0, 319725, 319725, 2205, 4410, 0x435950de
+0, 321930, 321930, 2205, 4410, 0x9d624ebe
+0, 324135, 324135, 2205, 4410, 0x774a9158
+0, 326340, 326340, 2205, 4410, 0x8c41e66a
+0, 328545, 328545, 2205, 4410, 0x70112740
+0, 330750, 330750, 2205, 4410, 0x55abc7a2
+0, 332955, 332955, 2205, 4410, 0x0ec3183c
+0, 335160, 335160, 2205, 4410, 0x54609c56
+0, 337365, 337365, 2205, 4410, 0x60d49f92
+0, 339570, 339570, 2205, 4410, 0x5fb061c8
+0, 341775, 341775, 2205, 4410, 0x6e119c98
+0, 343980, 343980, 2205, 4410, 0x3f39fc69
+0, 346185, 346185, 2205, 4410, 0xef466d0e
+0, 348390, 348390, 2205, 4410, 0xf4cb6fe1
+0, 350595, 350595, 2205, 4410, 0xc4434439
+0, 352800, 352800, 2205, 4410, 0xd02329d2
+0, 355005, 355005, 2205, 4410, 0x216cffaf
+0, 357210, 357210, 2205, 4410, 0x7e59e8c1
+0, 359415, 359415, 2205, 4410, 0xc7c3346d
+0, 361620, 361620, 2205, 4410, 0x5b3723af
+0, 363825, 363825, 2205, 4410, 0x76097270
+0, 366030, 366030, 2205, 4410, 0xae39a233
+0, 368235, 368235, 2205, 4410, 0x686a471c
+0, 370440, 370440, 2205, 4410, 0x3af3c5e0
+0, 372645, 372645, 2205, 4410, 0x11ac711e
+0, 374850, 374850, 2205, 4410, 0xcd8da8ce
+0, 377055, 377055, 2205, 4410, 0x21296e3a
+0, 379260, 379260, 2205, 4410, 0x77168188
+0, 381465, 381465, 2205, 4410, 0x5fcf59cd
+0, 383670, 383670, 2205, 4410, 0x390c8717
+0, 385875, 385875, 2205, 4410, 0x3d5d5b3c
+0, 388080, 388080, 2205, 4410, 0x3b8f13d3
+0, 390285, 390285, 2205, 4410, 0x5b002c2f
+0, 392490, 392490, 2205, 4410, 0x9e1d2b08
+0, 394695, 394695, 2205, 4410, 0x69454ebd
+0, 396900, 396900, 2205, 4410, 0x62a54bec
+0, 399105, 399105, 2205, 4410, 0x4d231fdb
+0, 401310, 401310, 2205, 4410, 0x65624ff7
+0, 403515, 403515, 2205, 4410, 0x6fc66932
+0, 405720, 405720, 2205, 4410, 0x23200cf6
+0, 407925, 407925, 2205, 4410, 0xf8033122
+0, 410130, 410130, 2205, 4410, 0x0fce0744
+0, 412335, 412335, 2205, 4410, 0x9302683e
+0, 414540, 414540, 2205, 4410, 0xd2380245
+0, 416745, 416745, 2205, 4410, 0x482e0872
+0, 418950, 418950, 2205, 4410, 0xe98e6461
+0, 421155, 421155, 2205, 4410, 0x1db404e3
+0, 423360, 423360, 2205, 4410, 0x47a26d45
+0, 425565, 425565, 2205, 4410, 0x449a348a
+0, 427770, 427770, 2205, 4410, 0xee874f84
+0, 429975, 429975, 2205, 4410, 0xc4ecf965
+0, 432180, 432180, 2205, 4410, 0xcc450bc8
+0, 434385, 434385, 2205, 4410, 0xb18d044b
+0, 436590, 436590, 2205, 4410, 0x895435e8
+0, 438795, 438795, 2205, 4410, 0x57e7574e
+0, 441000, 441000, 2205, 4410, 0x8041ad3d
+0, 443205, 443205, 2205, 4410, 0x853d1616
+0, 445410, 445410, 2205, 4410, 0xa11bb32b
+0, 447615, 447615, 2205, 4410, 0xe10ea0de
+0, 449820, 449820, 2205, 4410, 0xdf2ee328
+0, 452025, 452025, 2205, 4410, 0xd5a6dcae
+0, 454230, 454230, 2205, 4410, 0xd176c00b
+0, 456435, 456435, 2205, 4410, 0x9cd6bcf3
+0, 458640, 458640, 2205, 4410, 0x2569690a
+0, 460845, 460845, 2205, 4410, 0x6824aa1d
+0, 463050, 463050, 2205, 4410, 0xa9110afa
+0, 465255, 465255, 2205, 4410, 0x115c25be
+0, 467460, 467460, 2205, 4410, 0x1100f085
+0, 469665, 469665, 2205, 4410, 0x00000000
+0, 471870, 471870, 2205, 4410, 0x00000000
+0, 474075, 474075, 2205, 4410, 0x00000000
+0, 476280, 476280, 2205, 4410, 0x00000000
+0, 478485, 478485, 2205, 4410, 0x00000000
+0, 480690, 480690, 2205, 4410, 0x00000000
+0, 482895, 482895, 2205, 4410, 0x00000000
+0, 485100, 485100, 2205, 4410, 0x00000000
+0, 487305, 487305, 2205, 4410, 0x00000000
+0, 489510, 489510, 2205, 4410, 0x00000000
+0, 491715, 491715, 2205, 4410, 0x00000000
+0, 493920, 493920, 2205, 4410, 0x00000000
+0, 496125, 496125, 2205, 4410, 0x00000000
+0, 498330, 498330, 2205, 4410, 0x00000000
+0, 500535, 500535, 2205, 4410, 0x00000000
+0, 502740, 502740, 2205, 4410, 0x00000000
+0, 504945, 504945, 2205, 4410, 0x00000000
+0, 507150, 507150, 2205, 4410, 0x00000000
+0, 509355, 509355, 2205, 4410, 0x00000000
+0, 511560, 511560, 2205, 4410, 0x00000000
+0, 513765, 513765, 2205, 4410, 0x00000000
+0, 515970, 515970, 2205, 4410, 0x00000000
+0, 518175, 518175, 2205, 4410, 0x00000000
+0, 520380, 520380, 2205, 4410, 0x00000000
+0, 522585, 522585, 2205, 4410, 0x00000000
+0, 524790, 524790, 2205, 4410, 0x00000000
+0, 526995, 526995, 2205, 4410, 0x00000000
+0, 529200, 529200, 2205, 4410, 0x00000000
+0, 531405, 531405, 2205, 4410, 0x00000000
diff --git a/tests/ref/fate/sierra-vmd-video b/tests/ref/fate/sierra-vmd-video
new file mode 100644
index 0000000..5b9dde1
--- /dev/null
+++ b/tests/ref/fate/sierra-vmd-video
@@ -0,0 +1,118 @@
+#tb 0: 1/10
+0, 0, 0, 1, 230400, 0x0224ab01
+0, 1, 1, 1, 230400, 0x449e4d81
+0, 2, 2, 1, 230400, 0x3e15e07a
+0, 3, 3, 1, 230400, 0xdabe4172
+0, 4, 4, 1, 230400, 0x0947b7db
+0, 5, 5, 1, 230400, 0x934e243b
+0, 6, 6, 1, 230400, 0x6b5c5b6c
+0, 7, 7, 1, 230400, 0x4bf7bbb5
+0, 8, 8, 1, 230400, 0x423eec8e
+0, 9, 9, 1, 230400, 0x63663b5e
+0, 10, 10, 1, 230400, 0x9c258a67
+0, 11, 11, 1, 230400, 0x1c92b6e0
+0, 12, 12, 1, 230400, 0xdd0a0e28
+0, 13, 13, 1, 230400, 0x51d64af1
+0, 14, 14, 1, 230400, 0x5776ac12
+0, 15, 15, 1, 230400, 0x49070132
+0, 16, 16, 1, 230400, 0xa59635ab
+0, 17, 17, 1, 230400, 0xb1f99504
+0, 18, 18, 1, 230400, 0x61fac725
+0, 19, 19, 1, 230400, 0xc32c28d5
+0, 20, 20, 1, 230400, 0x2b7a91d6
+0, 21, 21, 1, 230400, 0x917be717
+0, 22, 22, 1, 230400, 0xd3c5a2ff
+0, 23, 23, 1, 230400, 0x0678a707
+0, 24, 24, 1, 230400, 0x122504e6
+0, 25, 25, 1, 230400, 0x76aebdae
+0, 26, 26, 1, 230400, 0x81357545
+0, 27, 27, 1, 230400, 0x38baeebd
+0, 28, 28, 1, 230400, 0x1c5c44d4
+0, 29, 29, 1, 230400, 0x60e189cc
+0, 30, 30, 1, 230400, 0xb1f4381c
+0, 31, 31, 1, 230400, 0xb5048fed
+0, 32, 32, 1, 230400, 0xc947c30e
+0, 33, 33, 1, 230400, 0xe8e31c07
+0, 34, 34, 1, 230400, 0x6d49dd02
+0, 35, 35, 1, 230400, 0x293e15d3
+0, 36, 36, 1, 230400, 0x354d792e
+0, 37, 37, 1, 230400, 0x35468780
+0, 38, 38, 1, 230400, 0x365d3991
+0, 39, 39, 1, 230400, 0xc9debef2
+0, 40, 40, 1, 230400, 0x4c4634c2
+0, 41, 41, 1, 230400, 0x347c2dca
+0, 42, 42, 1, 230400, 0x1efa0aaa
+0, 43, 43, 1, 230400, 0xa79a0b5a
+0, 44, 44, 1, 230400, 0xfdb2dcdb
+0, 45, 45, 1, 230400, 0x42dbea33
+0, 46, 46, 1, 230400, 0x2a207e43
+0, 47, 47, 1, 230400, 0x86573783
+0, 48, 48, 1, 230400, 0xc3968473
+0, 49, 49, 1, 230400, 0x8f62a7b4
+0, 50, 50, 1, 230400, 0x5a2e3073
+0, 51, 51, 1, 230400, 0xd24f5e2c
+0, 52, 52, 1, 230400, 0x1df3c67d
+0, 53, 53, 1, 230400, 0xe4fd884d
+0, 57, 57, 1, 230400, 0x9a228555
+0, 58, 58, 1, 230400, 0x9eba8ed5
+0, 59, 59, 1, 230400, 0x3d808a3d
+0, 60, 60, 1, 230400, 0xf57e866d
+0, 61, 61, 1, 230400, 0x85f594f5
+0, 62, 62, 1, 230400, 0xb09f99dd
+0, 63, 63, 1, 230400, 0x2b368475
+0, 64, 64, 1, 230400, 0xa2417afd
+0, 65, 65, 1, 230400, 0x590b709d
+0, 66, 66, 1, 230400, 0x5d617705
+0, 67, 67, 1, 230400, 0xabf981ad
+0, 68, 68, 1, 230400, 0x5a8590cd
+0, 69, 69, 1, 230400, 0x1bff853d
+0, 70, 70, 1, 230400, 0x71d08055
+0, 71, 71, 1, 230400, 0x2ebd817d
+0, 72, 72, 1, 230400, 0x6e838255
+0, 73, 73, 1, 230400, 0x043984cd
+0, 74, 74, 1, 230400, 0x7ff18495
+0, 75, 75, 1, 230400, 0xa43b8385
+0, 76, 76, 1, 230400, 0x72b5825d
+0, 77, 77, 1, 230400, 0x3a178085
+0, 78, 78, 1, 230400, 0x67748245
+0, 79, 79, 1, 230400, 0xeddf81d5
+0, 80, 80, 1, 230400, 0x8b088665
+0, 81, 81, 1, 230400, 0x6c408e15
+0, 82, 82, 1, 230400, 0x81f196dd
+0, 83, 83, 1, 230400, 0xab9f953d
+0, 84, 84, 1, 230400, 0xa5f69795
+0, 85, 85, 1, 230400, 0xa772950d
+0, 86, 86, 1, 230400, 0x6a5596d5
+0, 87, 87, 1, 230400, 0x1355958d
+0, 88, 88, 1, 230400, 0x4134981d
+0, 89, 89, 1, 230400, 0x8b929515
+0, 90, 90, 1, 230400, 0x482f95c5
+0, 91, 91, 1, 230400, 0x7a9795d5
+0, 92, 92, 1, 230400, 0x21c29abd
+0, 93, 93, 1, 230400, 0x9ae6a475
+0, 94, 94, 1, 230400, 0x3734aee5
+0, 95, 95, 1, 230400, 0xa0a1b365
+0, 96, 96, 1, 230400, 0x2dcab1c5
+0, 97, 97, 1, 230400, 0x9c8b6c44
+0, 98, 98, 1, 230400, 0x5da75feb
+0, 99, 99, 1, 230400, 0x4d02f8e3
+0, 100, 100, 1, 230400, 0x66824f3a
+0, 101, 101, 1, 230400, 0x0c9257e2
+0, 102, 102, 1, 230400, 0xb2927092
+0, 103, 103, 1, 230400, 0xb5dc6e9a
+0, 104, 104, 1, 230400, 0x6e567bc6
+0, 105, 105, 1, 230400, 0xbf9e0f7a
+0, 106, 106, 1, 230400, 0xb16f684a
+0, 107, 107, 1, 230400, 0xf9e55e81
+0, 108, 108, 1, 230400, 0xd8d0bcba
+0, 109, 109, 1, 230400, 0x44720ac0
+0, 110, 110, 1, 230400, 0x7d4c2058
+0, 113, 113, 1, 230400, 0xb0973eb9
+0, 114, 114, 1, 230400, 0x405a13ce
+0, 115, 115, 1, 230400, 0x6422f00a
+0, 116, 116, 1, 230400, 0x924b6c1e
+0, 145, 145, 1, 230400, 0xcf7809c0
+0, 146, 146, 1, 230400, 0x883a3863
+0, 147, 147, 1, 230400, 0x6adc9e03
+0, 148, 148, 1, 230400, 0x4f5ab7a8
+0, 214, 214, 1, 230400, 0xdc0aab94
diff --git a/tests/ref/fate/smacker b/tests/ref/fate/smacker
deleted file mode 100644
index b8d4d22..0000000
--- a/tests/ref/fate/smacker
+++ /dev/null
@@ -1,188 +0,0 @@
-#tb 0: 71/1000
-#tb 1: 1/22050
-0, 0, 0, 1, 192000, 0x8926d7fc
-1, 0, 0, 23620, 47240, 0x9974897c
-0, 1, 1, 1, 192000, 0x2506d384
-0, 2, 2, 1, 192000, 0x9a8dc93a
-0, 3, 3, 1, 192000, 0x4badb7f2
-0, 4, 4, 1, 192000, 0xc1fc9631
-0, 5, 5, 1, 192000, 0xfc906592
-0, 6, 6, 1, 192000, 0xeddd28e2
-0, 7, 7, 1, 192000, 0xeee0dcf5
-0, 8, 8, 1, 192000, 0x76798c91
-0, 9, 9, 1, 192000, 0x8a034c1b
-0, 10, 10, 1, 192000, 0x4df3127c
-0, 11, 11, 1, 192000, 0x2eefd36f
-0, 12, 12, 1, 192000, 0x58a2a1d6
-0, 13, 13, 1, 192000, 0x1a3d7971
-0, 14, 14, 1, 192000, 0xa1a65bd5
-0, 15, 15, 1, 192000, 0x344957b9
-1, 23620, 23620, 1564, 3128, 0x7e4064b4
-0, 16, 16, 1, 192000, 0xe23b5f4e
-1, 25184, 25184, 1564, 3128, 0x80883301
-0, 17, 17, 1, 192000, 0xb5c2710b
-1, 26748, 26748, 1568, 3136, 0x2ad2d341
-0, 18, 18, 1, 192000, 0x7a25938f
-1, 28316, 28316, 1564, 3128, 0xda8468e3
-0, 19, 19, 1, 192000, 0x0a84e4c9
-1, 29880, 29880, 1568, 3136, 0x9d6f6cdf
-0, 20, 20, 1, 192000, 0x94209b0d
-1, 31448, 31448, 1564, 3128, 0x1aaa64b5
-0, 21, 21, 1, 192000, 0xf940e51f
-1, 33012, 33012, 1564, 3128, 0x9182728b
-0, 22, 22, 1, 192000, 0xb9fdec42
-1, 34576, 34576, 1568, 3136, 0xfa8e17b3
-0, 23, 23, 1, 192000, 0x7b04a376
-1, 36144, 36144, 1564, 3128, 0x0dc3c1cf
-0, 24, 24, 1, 192000, 0x5fe0026b
-1, 37708, 37708, 1568, 3136, 0x0109639d
-0, 25, 25, 1, 192000, 0x775aca39
-1, 39276, 39276, 1564, 3128, 0x6d8a12d9
-0, 26, 26, 1, 192000, 0xae14fb32
-1, 40840, 40840, 1564, 3128, 0x4b9a9597
-0, 27, 27, 1, 192000, 0x661106e5
-1, 42404, 42404, 1568, 3136, 0x9112710e
-0, 28, 28, 1, 192000, 0xe8658dbf
-1, 43972, 43972, 1564, 3128, 0x8cccf522
-0, 29, 29, 1, 192000, 0x5359f0f9
-1, 45536, 45536, 1564, 3128, 0x6594bbf3
-0, 30, 30, 1, 192000, 0xc1ec80f4
-1, 47100, 47100, 1568, 3136, 0xd878a7d5
-0, 31, 31, 1, 192000, 0xca53806b
-1, 48668, 48668, 1564, 3128, 0xaa6e3905
-0, 32, 32, 1, 192000, 0xf0766b2e
-1, 50232, 50232, 1568, 3136, 0x2a062e04
-0, 33, 33, 1, 192000, 0x39962da8
-1, 51800, 51800, 1564, 3128, 0x84e4006a
-0, 34, 34, 1, 192000, 0x4171c37f
-1, 53364, 53364, 1564, 3128, 0x85183633
-0, 35, 35, 1, 192000, 0x3abf3b46
-1, 54928, 54928, 1568, 3136, 0xb62d4b02
-0, 36, 36, 1, 192000, 0xecc68313
-1, 56496, 56496, 1564, 3128, 0xe209462a
-0, 37, 37, 1, 192000, 0xea339baf
-1, 58060, 58060, 1568, 3136, 0x57c4824b
-0, 38, 38, 1, 192000, 0x616b8f16
-1, 59628, 59628, 1564, 3128, 0x664a9163
-0, 39, 39, 1, 192000, 0xf77a8581
-1, 61192, 61192, 1564, 3128, 0xb4287874
-0, 40, 40, 1, 192000, 0xb315678b
-1, 62756, 62756, 1568, 3136, 0xde626885
-0, 41, 41, 1, 192000, 0x0a4a5218
-1, 64324, 64324, 1564, 3128, 0x919763c2
-0, 42, 42, 1, 192000, 0x98802be4
-1, 65888, 65888, 1564, 3128, 0xa4f664e1
-0, 43, 43, 1, 192000, 0xa2f0fd94
-1, 67452, 67452, 1568, 3136, 0xa0bab0d4
-0, 44, 44, 1, 192000, 0x6671c84f
-1, 69020, 69020, 1564, 3128, 0xe938939c
-0, 45, 45, 1, 192000, 0x38327e31
-1, 70584, 70584, 1568, 3136, 0x3679bfc7
-0, 46, 46, 1, 192000, 0xb85d3e08
-1, 72152, 72152, 1564, 3128, 0xc96c55c3
-0, 47, 47, 1, 192000, 0xdc69eba9
-1, 73716, 73716, 1564, 3128, 0x119114d6
-0, 48, 48, 1, 192000, 0x8955a0b3
-1, 75280, 75280, 1568, 3136, 0x42f3800f
-0, 49, 49, 1, 192000, 0x714a548b
-1, 76848, 76848, 1564, 3128, 0x4250c4ad
-0, 50, 50, 1, 192000, 0xc0471de9
-1, 78412, 78412, 1568, 3136, 0x5cdd4925
-0, 51, 51, 1, 192000, 0x2e16e039
-1, 79980, 79980, 1564, 3128, 0xa4c12360
-0, 52, 52, 1, 192000, 0x9fa4b033
-1, 81544, 81544, 1564, 3128, 0x849f48de
-0, 53, 53, 1, 192000, 0x4a0f9402
-1, 83108, 83108, 1568, 3136, 0x6acd8ff9
-0, 54, 54, 1, 192000, 0x1f3e6843
-1, 84676, 84676, 1564, 3128, 0xb2758556
-0, 55, 55, 1, 192000, 0x31774850
-1, 86240, 86240, 1564, 3128, 0x10f2fcb1
-0, 56, 56, 1, 192000, 0x9d5336a2
-1, 87804, 87804, 1568, 3136, 0xf0f02b23
-0, 57, 57, 1, 192000, 0xf7de27a2
-1, 89372, 89372, 1564, 3128, 0x64f759c6
-0, 58, 58, 1, 192000, 0x98c717ce
-1, 90936, 90936, 1568, 3136, 0x7ec075e3
-0, 59, 59, 1, 192000, 0x615b10b8
-1, 92504, 92504, 1564, 3128, 0xf981d51e
-0, 60, 60, 1, 192000, 0xd5bc0e7e
-1, 94068, 94068, 1564, 3128, 0xc622e8b9
-0, 61, 61, 1, 192000, 0xd5bc0e7e
-1, 95632, 95632, 1568, 3136, 0xf632e2f8
-0, 62, 62, 1, 192000, 0xd5bc0e7e
-1, 97200, 97200, 1564, 3128, 0xda561864
-0, 63, 63, 1, 192000, 0xd5bc0e7e
-1, 98764, 98764, 1568, 3136, 0x14d2e888
-0, 64, 64, 1, 192000, 0xd5bc0e7e
-1, 100332, 100332, 1564, 3128, 0x015bb869
-0, 65, 65, 1, 192000, 0xd5bc0e7e
-1, 101896, 101896, 1564, 3128, 0xedb1fb62
-0, 66, 66, 1, 192000, 0xd5bc0e7e
-1, 103460, 103460, 1568, 3136, 0xe0560c41
-0, 67, 67, 1, 192000, 0xd5bc0e7e
-1, 105028, 105028, 1564, 3128, 0x14773c9a
-0, 68, 68, 1, 192000, 0xd5bc0e7e
-1, 106592, 106592, 1568, 3136, 0x850f1c82
-0, 69, 69, 1, 192000, 0xd5bc0e7e
-1, 108160, 108160, 1564, 3128, 0xb0bd5347
-0, 70, 70, 1, 192000, 0xd5bc0e7e
-1, 109724, 109724, 1564, 3128, 0x8f82edbf
-0, 71, 71, 1, 192000, 0xd5bc0e7e
-1, 111288, 111288, 1568, 3136, 0x493abee2
-0, 72, 72, 1, 192000, 0xd5bc0e7e
-1, 112856, 112856, 1564, 3128, 0xf5daff3f
-0, 73, 73, 1, 192000, 0xd5bc0e7e
-1, 114420, 114420, 1564, 3128, 0x78ad2690
-0, 74, 74, 1, 192000, 0xd5bc0e7e
-1, 115984, 115984, 1568, 3136, 0x490ebafc
-0, 75, 75, 1, 192000, 0xd5bc0e7e
-1, 117552, 117552, 1564, 3128, 0x70333fd2
-0, 76, 76, 1, 192000, 0xd5bc0e7e
-1, 119116, 119116, 1568, 3136, 0x8cb1c350
-0, 77, 77, 1, 192000, 0xd5bc0e7e
-1, 120684, 120684, 1564, 3128, 0x8bd057cb
-0, 78, 78, 1, 192000, 0xd5bc0e7e
-1, 122248, 122248, 1564, 3128, 0x161b3dbc
-0, 79, 79, 1, 192000, 0xd5bc0e7e
-1, 123812, 123812, 1568, 3136, 0xb47fb88a
-0, 80, 80, 1, 192000, 0xd5bc0e7e
-1, 125380, 125380, 1564, 3128, 0x474b381e
-0, 81, 81, 1, 192000, 0xd5bc0e7e
-1, 126944, 126944, 1568, 3136, 0x07c519bb
-0, 82, 82, 1, 192000, 0xd5bc0e7e
-1, 128512, 128512, 1564, 3128, 0x15b916c8
-0, 83, 83, 1, 192000, 0xd5bc0e7e
-1, 130076, 130076, 1564, 3128, 0x0ed7f6fb
-0, 84, 84, 1, 192000, 0xd5bc0e7e
-1, 131640, 131640, 1568, 3136, 0x54d6397b
-0, 85, 85, 1, 192000, 0xd5bc0e7e
-1, 133208, 133208, 1564, 3128, 0x437242bb
-0, 86, 86, 1, 192000, 0xd5bc0e7e
-1, 134772, 134772, 1564, 3128, 0x38f05c4d
-0, 87, 87, 1, 192000, 0xd5bc0e7e
-1, 136336, 136336, 1568, 3136, 0x5d000e59
-0, 88, 88, 1, 192000, 0xd5bc0e7e
-1, 137904, 137904, 1564, 3128, 0xdeab2d04
-0, 89, 89, 1, 192000, 0xd5bc0e7e
-1, 139468, 139468, 1568, 3136, 0x77de6880
-0, 90, 90, 1, 192000, 0xd5bc0e7e
-1, 141036, 141036, 1564, 3128, 0xbc87ef25
-0, 91, 91, 1, 192000, 0xd5bc0e7e
-1, 142600, 142600, 1564, 3128, 0xc1638ade
-0, 92, 92, 1, 192000, 0xd5bc0e7e
-1, 144164, 144164, 1568, 3136, 0xcfb64a5f
-0, 93, 93, 1, 192000, 0xd5bc0e7e
-1, 145732, 145732, 1564, 3128, 0x90b1b826
-0, 94, 94, 1, 192000, 0xd5bc0e7e
-1, 147296, 147296, 1568, 3136, 0x00000000
-0, 95, 95, 1, 192000, 0xd5bc0e7e
-1, 148864, 148864, 1564, 3128, 0x00000000
-0, 96, 96, 1, 192000, 0xd5bc0e7e
-1, 150428, 150428, 1564, 3128, 0x00000000
-0, 97, 97, 1, 192000, 0xd5bc0e7e
-1, 151992, 151992, 1568, 3136, 0x00000000
-0, 98, 98, 1, 192000, 0xd5bc0e7e
-1, 153560, 153560, 1564, 3128, 0x00000000
-0, 99, 99, 1, 192000, 0xd5bc0e7e
-1, 155124, 155124, 1428, 2856, 0x00000000
diff --git a/tests/ref/fate/smacker-audio b/tests/ref/fate/smacker-audio
new file mode 100644
index 0000000..442f479
--- /dev/null
+++ b/tests/ref/fate/smacker-audio
@@ -0,0 +1,87 @@
+#tb 0: 1/22050
+0, 0, 0, 23620, 47240, 0x9974897c
+0, 23620, 23620, 1564, 3128, 0x7e4064b4
+0, 25184, 25184, 1564, 3128, 0x80883301
+0, 26748, 26748, 1568, 3136, 0x2ad2d341
+0, 28316, 28316, 1564, 3128, 0xda8468e3
+0, 29880, 29880, 1568, 3136, 0x9d6f6cdf
+0, 31448, 31448, 1564, 3128, 0x1aaa64b5
+0, 33012, 33012, 1564, 3128, 0x9182728b
+0, 34576, 34576, 1568, 3136, 0xfa8e17b3
+0, 36144, 36144, 1564, 3128, 0x0dc3c1cf
+0, 37708, 37708, 1568, 3136, 0x0109639d
+0, 39276, 39276, 1564, 3128, 0x6d8a12d9
+0, 40840, 40840, 1564, 3128, 0x4b9a9597
+0, 42404, 42404, 1568, 3136, 0x9112710e
+0, 43972, 43972, 1564, 3128, 0x8cccf522
+0, 45536, 45536, 1564, 3128, 0x6594bbf3
+0, 47100, 47100, 1568, 3136, 0xd878a7d5
+0, 48668, 48668, 1564, 3128, 0xaa6e3905
+0, 50232, 50232, 1568, 3136, 0x2a062e04
+0, 51800, 51800, 1564, 3128, 0x84e4006a
+0, 53364, 53364, 1564, 3128, 0x85183633
+0, 54928, 54928, 1568, 3136, 0xb62d4b02
+0, 56496, 56496, 1564, 3128, 0xe209462a
+0, 58060, 58060, 1568, 3136, 0x57c4824b
+0, 59628, 59628, 1564, 3128, 0x664a9163
+0, 61192, 61192, 1564, 3128, 0xb4287874
+0, 62756, 62756, 1568, 3136, 0xde626885
+0, 64324, 64324, 1564, 3128, 0x919763c2
+0, 65888, 65888, 1564, 3128, 0xa4f664e1
+0, 67452, 67452, 1568, 3136, 0xa0bab0d4
+0, 69020, 69020, 1564, 3128, 0xe938939c
+0, 70584, 70584, 1568, 3136, 0x3679bfc7
+0, 72152, 72152, 1564, 3128, 0xc96c55c3
+0, 73716, 73716, 1564, 3128, 0x119114d6
+0, 75280, 75280, 1568, 3136, 0x42f3800f
+0, 76848, 76848, 1564, 3128, 0x4250c4ad
+0, 78412, 78412, 1568, 3136, 0x5cdd4925
+0, 79980, 79980, 1564, 3128, 0xa4c12360
+0, 81544, 81544, 1564, 3128, 0x849f48de
+0, 83108, 83108, 1568, 3136, 0x6acd8ff9
+0, 84676, 84676, 1564, 3128, 0xb2758556
+0, 86240, 86240, 1564, 3128, 0x10f2fcb1
+0, 87804, 87804, 1568, 3136, 0xf0f02b23
+0, 89372, 89372, 1564, 3128, 0x64f759c6
+0, 90936, 90936, 1568, 3136, 0x7ec075e3
+0, 92504, 92504, 1564, 3128, 0xf981d51e
+0, 94068, 94068, 1564, 3128, 0xc622e8b9
+0, 95632, 95632, 1568, 3136, 0xf632e2f8
+0, 97200, 97200, 1564, 3128, 0xda561864
+0, 98764, 98764, 1568, 3136, 0x14d2e888
+0, 100332, 100332, 1564, 3128, 0x015bb869
+0, 101896, 101896, 1564, 3128, 0xedb1fb62
+0, 103460, 103460, 1568, 3136, 0xe0560c41
+0, 105028, 105028, 1564, 3128, 0x14773c9a
+0, 106592, 106592, 1568, 3136, 0x850f1c82
+0, 108160, 108160, 1564, 3128, 0xb0bd5347
+0, 109724, 109724, 1564, 3128, 0x8f82edbf
+0, 111288, 111288, 1568, 3136, 0x493abee2
+0, 112856, 112856, 1564, 3128, 0xf5daff3f
+0, 114420, 114420, 1564, 3128, 0x78ad2690
+0, 115984, 115984, 1568, 3136, 0x490ebafc
+0, 117552, 117552, 1564, 3128, 0x70333fd2
+0, 119116, 119116, 1568, 3136, 0x8cb1c350
+0, 120684, 120684, 1564, 3128, 0x8bd057cb
+0, 122248, 122248, 1564, 3128, 0x161b3dbc
+0, 123812, 123812, 1568, 3136, 0xb47fb88a
+0, 125380, 125380, 1564, 3128, 0x474b381e
+0, 126944, 126944, 1568, 3136, 0x07c519bb
+0, 128512, 128512, 1564, 3128, 0x15b916c8
+0, 130076, 130076, 1564, 3128, 0x0ed7f6fb
+0, 131640, 131640, 1568, 3136, 0x54d6397b
+0, 133208, 133208, 1564, 3128, 0x437242bb
+0, 134772, 134772, 1564, 3128, 0x38f05c4d
+0, 136336, 136336, 1568, 3136, 0x5d000e59
+0, 137904, 137904, 1564, 3128, 0xdeab2d04
+0, 139468, 139468, 1568, 3136, 0x77de6880
+0, 141036, 141036, 1564, 3128, 0xbc87ef25
+0, 142600, 142600, 1564, 3128, 0xc1638ade
+0, 144164, 144164, 1568, 3136, 0xcfb64a5f
+0, 145732, 145732, 1564, 3128, 0x90b1b826
+0, 147296, 147296, 1568, 3136, 0x00000000
+0, 148864, 148864, 1564, 3128, 0x00000000
+0, 150428, 150428, 1564, 3128, 0x00000000
+0, 151992, 151992, 1568, 3136, 0x00000000
+0, 153560, 153560, 1564, 3128, 0x00000000
+0, 155124, 155124, 1428, 2856, 0x00000000
diff --git a/tests/ref/fate/smacker-video b/tests/ref/fate/smacker-video
new file mode 100644
index 0000000..8bd3071
--- /dev/null
+++ b/tests/ref/fate/smacker-video
@@ -0,0 +1,101 @@
+#tb 0: 71/1000
+0, 0, 0, 1, 192000, 0x8926d7fc
+0, 1, 1, 1, 192000, 0x2506d384
+0, 2, 2, 1, 192000, 0x9a8dc93a
+0, 3, 3, 1, 192000, 0x4badb7f2
+0, 4, 4, 1, 192000, 0xc1fc9631
+0, 5, 5, 1, 192000, 0xfc906592
+0, 6, 6, 1, 192000, 0xeddd28e2
+0, 7, 7, 1, 192000, 0xeee0dcf5
+0, 8, 8, 1, 192000, 0x76798c91
+0, 9, 9, 1, 192000, 0x8a034c1b
+0, 10, 10, 1, 192000, 0x4df3127c
+0, 11, 11, 1, 192000, 0x2eefd36f
+0, 12, 12, 1, 192000, 0x58a2a1d6
+0, 13, 13, 1, 192000, 0x1a3d7971
+0, 14, 14, 1, 192000, 0xa1a65bd5
+0, 15, 15, 1, 192000, 0x344957b9
+0, 16, 16, 1, 192000, 0xe23b5f4e
+0, 17, 17, 1, 192000, 0xb5c2710b
+0, 18, 18, 1, 192000, 0x7a25938f
+0, 19, 19, 1, 192000, 0x0a84e4c9
+0, 20, 20, 1, 192000, 0x94209b0d
+0, 21, 21, 1, 192000, 0xf940e51f
+0, 22, 22, 1, 192000, 0xb9fdec42
+0, 23, 23, 1, 192000, 0x7b04a376
+0, 24, 24, 1, 192000, 0x5fe0026b
+0, 25, 25, 1, 192000, 0x775aca39
+0, 26, 26, 1, 192000, 0xae14fb32
+0, 27, 27, 1, 192000, 0x661106e5
+0, 28, 28, 1, 192000, 0xe8658dbf
+0, 29, 29, 1, 192000, 0x5359f0f9
+0, 30, 30, 1, 192000, 0xc1ec80f4
+0, 31, 31, 1, 192000, 0xca53806b
+0, 32, 32, 1, 192000, 0xf0766b2e
+0, 33, 33, 1, 192000, 0x39962da8
+0, 34, 34, 1, 192000, 0x4171c37f
+0, 35, 35, 1, 192000, 0x3abf3b46
+0, 36, 36, 1, 192000, 0xecc68313
+0, 37, 37, 1, 192000, 0xea339baf
+0, 38, 38, 1, 192000, 0x616b8f16
+0, 39, 39, 1, 192000, 0xf77a8581
+0, 40, 40, 1, 192000, 0xb315678b
+0, 41, 41, 1, 192000, 0x0a4a5218
+0, 42, 42, 1, 192000, 0x98802be4
+0, 43, 43, 1, 192000, 0xa2f0fd94
+0, 44, 44, 1, 192000, 0x6671c84f
+0, 45, 45, 1, 192000, 0x38327e31
+0, 46, 46, 1, 192000, 0xb85d3e08
+0, 47, 47, 1, 192000, 0xdc69eba9
+0, 48, 48, 1, 192000, 0x8955a0b3
+0, 49, 49, 1, 192000, 0x714a548b
+0, 50, 50, 1, 192000, 0xc0471de9
+0, 51, 51, 1, 192000, 0x2e16e039
+0, 52, 52, 1, 192000, 0x9fa4b033
+0, 53, 53, 1, 192000, 0x4a0f9402
+0, 54, 54, 1, 192000, 0x1f3e6843
+0, 55, 55, 1, 192000, 0x31774850
+0, 56, 56, 1, 192000, 0x9d5336a2
+0, 57, 57, 1, 192000, 0xf7de27a2
+0, 58, 58, 1, 192000, 0x98c717ce
+0, 59, 59, 1, 192000, 0x615b10b8
+0, 60, 60, 1, 192000, 0xd5bc0e7e
+0, 61, 61, 1, 192000, 0xd5bc0e7e
+0, 62, 62, 1, 192000, 0xd5bc0e7e
+0, 63, 63, 1, 192000, 0xd5bc0e7e
+0, 64, 64, 1, 192000, 0xd5bc0e7e
+0, 65, 65, 1, 192000, 0xd5bc0e7e
+0, 66, 66, 1, 192000, 0xd5bc0e7e
+0, 67, 67, 1, 192000, 0xd5bc0e7e
+0, 68, 68, 1, 192000, 0xd5bc0e7e
+0, 69, 69, 1, 192000, 0xd5bc0e7e
+0, 70, 70, 1, 192000, 0xd5bc0e7e
+0, 71, 71, 1, 192000, 0xd5bc0e7e
+0, 72, 72, 1, 192000, 0xd5bc0e7e
+0, 73, 73, 1, 192000, 0xd5bc0e7e
+0, 74, 74, 1, 192000, 0xd5bc0e7e
+0, 75, 75, 1, 192000, 0xd5bc0e7e
+0, 76, 76, 1, 192000, 0xd5bc0e7e
+0, 77, 77, 1, 192000, 0xd5bc0e7e
+0, 78, 78, 1, 192000, 0xd5bc0e7e
+0, 79, 79, 1, 192000, 0xd5bc0e7e
+0, 80, 80, 1, 192000, 0xd5bc0e7e
+0, 81, 81, 1, 192000, 0xd5bc0e7e
+0, 82, 82, 1, 192000, 0xd5bc0e7e
+0, 83, 83, 1, 192000, 0xd5bc0e7e
+0, 84, 84, 1, 192000, 0xd5bc0e7e
+0, 85, 85, 1, 192000, 0xd5bc0e7e
+0, 86, 86, 1, 192000, 0xd5bc0e7e
+0, 87, 87, 1, 192000, 0xd5bc0e7e
+0, 88, 88, 1, 192000, 0xd5bc0e7e
+0, 89, 89, 1, 192000, 0xd5bc0e7e
+0, 90, 90, 1, 192000, 0xd5bc0e7e
+0, 91, 91, 1, 192000, 0xd5bc0e7e
+0, 92, 92, 1, 192000, 0xd5bc0e7e
+0, 93, 93, 1, 192000, 0xd5bc0e7e
+0, 94, 94, 1, 192000, 0xd5bc0e7e
+0, 95, 95, 1, 192000, 0xd5bc0e7e
+0, 96, 96, 1, 192000, 0xd5bc0e7e
+0, 97, 97, 1, 192000, 0xd5bc0e7e
+0, 98, 98, 1, 192000, 0xd5bc0e7e
+0, 99, 99, 1, 192000, 0xd5bc0e7e
diff --git a/tests/ref/fate/smjpeg b/tests/ref/fate/smjpeg
deleted file mode 100644
index 78b750a..0000000
--- a/tests/ref/fate/smjpeg
+++ /dev/null
@@ -1,425 +0,0 @@
-#tb 0: 1/1000
-#tb 1: 1/22050
-0, 0, 0, 0, 734, 0x5a042c2c
-1, 0, 0, 512, 1024, 0x00000000
-1, 507, 507, 512, 1024, 0x00000000
-1, 1014, 1014, 512, 1024, 0xd89a448e
-1, 1521, 1521, 512, 1024, 0x695b369c
-1, 2029, 2029, 512, 1024, 0xc8ba5707
-0, 111, 111, 0, 763, 0xb5893f2f
-1, 2558, 2558, 512, 1024, 0xdf241fc6
-1, 3065, 3065, 512, 1024, 0x61cf4166
-1, 3572, 3572, 512, 1024, 0x97cbc386
-1, 4079, 4079, 512, 1024, 0x44899d04
-1, 4586, 4586, 512, 1024, 0xa7cbaa62
-0, 222, 222, 0, 3023, 0x0f3907d3
-1, 5116, 5116, 512, 1024, 0xa7aea60c
-1, 5623, 5623, 512, 1024, 0xd7b18a89
-1, 6130, 6130, 512, 1024, 0x268e81f6
-1, 6637, 6637, 512, 1024, 0x9cf83a2f
-1, 7166, 7166, 512, 1024, 0x5559b508
-0, 333, 333, 0, 4800, 0x22e6e18a
-1, 7673, 7673, 512, 1024, 0xe1b9e71c
-1, 8181, 8181, 512, 1024, 0xdcee733e
-1, 8688, 8688, 512, 1024, 0xe5918f60
-1, 9195, 9195, 512, 1024, 0x29dbd209
-1, 9724, 9724, 512, 1024, 0x9bcbcf16
-0, 444, 444, 0, 6417, 0x427adde5
-1, 10231, 10231, 512, 1024, 0x86f5f458
-1, 10738, 10738, 512, 1024, 0xabcbda86
-1, 11246, 11246, 512, 1024, 0xc51f77b9
-1, 11775, 11775, 512, 1024, 0xf6b3a504
-0, 555, 555, 0, 6776, 0x7a74c6ad
-1, 12282, 12282, 512, 1024, 0x1af3e40e
-1, 12789, 12789, 512, 1024, 0x3866b03b
-1, 13296, 13296, 512, 1024, 0xbc005403
-1, 13803, 13803, 512, 1024, 0xe9dfcc51
-1, 14332, 14332, 512, 1024, 0x83c837cb
-0, 666, 666, 0, 6808, 0x1f6eb7c3
-1, 14840, 14840, 512, 1024, 0xfa649580
-1, 15347, 15347, 512, 1024, 0x519452ea
-1, 15854, 15854, 512, 1024, 0xd4978774
-1, 16383, 16383, 512, 1024, 0xe2a3b1cd
-1, 16890, 16890, 512, 1024, 0x9a9472ad
-0, 777, 777, 0, 6726, 0x452087e6
-1, 17397, 17397, 512, 1024, 0xa12d4060
-1, 17905, 17905, 512, 1024, 0x31fb0646
-1, 18412, 18412, 512, 1024, 0xfc44343f
-1, 18941, 18941, 512, 1024, 0x0847751a
-1, 19448, 19448, 512, 1024, 0x227968a2
-0, 888, 888, 0, 6829, 0xee82b109
-1, 19955, 19955, 512, 1024, 0x7cce9f1c
-1, 20462, 20462, 512, 1024, 0xb8356713
-1, 20992, 20992, 512, 1024, 0xb29f6e6f
-1, 21499, 21499, 512, 1024, 0x9e1430ab
-1, 22006, 22006, 512, 1024, 0x26d85423
-0, 999, 999, 0, 7055, 0xf41f1108
-1, 22513, 22513, 512, 1024, 0x6496547d
-1, 23020, 23020, 512, 1024, 0x316b1a86
-1, 23549, 23549, 512, 1024, 0x3cd83afc
-1, 24057, 24057, 512, 1024, 0x993ff633
-0, 1111, 1111, 0, 6977, 0xf8fe1ede
-1, 24564, 24564, 512, 1024, 0x0708d1a2
-1, 25071, 25071, 512, 1024, 0xd7230db9
-1, 25578, 25578, 512, 1024, 0xbb0779ca
-1, 26107, 26107, 512, 1024, 0xc6094e1b
-1, 26614, 26614, 512, 1024, 0x15a8b039
-0, 1222, 1222, 0, 6942, 0x9ad105c6
-1, 27122, 27122, 512, 1024, 0xd6dbe88c
-1, 27629, 27629, 512, 1024, 0x7e8d1140
-1, 28158, 28158, 512, 1024, 0xef88e525
-1, 28665, 28665, 512, 1024, 0x44e21149
-1, 29172, 29172, 512, 1024, 0x65b0f5f4
-0, 1333, 1333, 0, 6926, 0xe239dad6
-1, 29679, 29679, 512, 1024, 0xb955f687
-1, 30186, 30186, 512, 1024, 0xc85fba9c
-1, 30716, 30716, 512, 1024, 0xf59655ad
-1, 31223, 31223, 512, 1024, 0x6de80bf1
-1, 31730, 31730, 512, 1024, 0x2dcf6e41
-0, 1444, 1444, 0, 6966, 0x81dcfab1
-1, 32237, 32237, 512, 1024, 0xd0ddcf8a
-1, 32766, 32766, 512, 1024, 0x00135c2d
-1, 33273, 33273, 512, 1024, 0x697f8efd
-1, 33781, 33781, 512, 1024, 0x7a9bada5
-0, 1555, 1555, 0, 6896, 0x31e6cc02
-1, 34288, 34288, 512, 1024, 0x0d22783c
-1, 34795, 34795, 512, 1024, 0x7726d07d
-1, 35324, 35324, 512, 1024, 0xa2f14f67
-1, 35831, 35831, 512, 1024, 0x7f51060d
-1, 36338, 36338, 512, 1024, 0xc4ec6aea
-0, 1666, 1666, 0, 6889, 0x1cc1006e
-1, 36846, 36846, 512, 1024, 0x9bb37ca4
-1, 37375, 37375, 512, 1024, 0x9b085577
-1, 37882, 37882, 512, 1024, 0x8812f8af
-1, 38389, 38389, 512, 1024, 0x788f5221
-1, 38896, 38896, 512, 1024, 0x3a2ce642
-0, 1777, 1777, 0, 6933, 0xc303f87f
-1, 39403, 39403, 512, 1024, 0x72415692
-1, 39933, 39933, 512, 1024, 0xe3dcc105
-1, 40440, 40440, 512, 1024, 0xb26c0599
-1, 40947, 40947, 512, 1024, 0x5c9e55eb
-1, 41454, 41454, 512, 1024, 0x8fe88707
-0, 1888, 1888, 0, 7034, 0xb4970a20
-1, 41983, 41983, 512, 1024, 0xc5d7beb6
-1, 42490, 42490, 512, 1024, 0xe1d3a3b4
-1, 42998, 42998, 512, 1024, 0x012da0c6
-1, 43505, 43505, 512, 1024, 0x8d010922
-1, 44012, 44012, 512, 1024, 0x3366eb0d
-0, 1999, 1999, 0, 6961, 0xf064095d
-1, 44541, 44541, 512, 1024, 0xc9381a27
-1, 45048, 45048, 512, 1024, 0x0774f685
-1, 45555, 45555, 512, 1024, 0xc5cae0a5
-1, 46062, 46062, 512, 1024, 0xa6f4737c
-0, 2111, 2111, 0, 7089, 0x5ba350f9
-1, 46592, 46592, 512, 1024, 0x8fb6d0d1
-1, 47099, 47099, 512, 1024, 0x05f579c2
-1, 47606, 47606, 512, 1024, 0x56905d99
-1, 48113, 48113, 512, 1024, 0x002ee18d
-1, 48620, 48620, 512, 1024, 0xeb37ef51
-0, 2222, 2222, 0, 7078, 0xa83f3e88
-1, 49149, 49149, 512, 1024, 0x38025635
-1, 49657, 49657, 512, 1024, 0x4fe643c8
-1, 50164, 50164, 512, 1024, 0x11d66ab1
-1, 50671, 50671, 512, 1024, 0xcc3051e9
-1, 51178, 51178, 512, 1024, 0xcd93e854
-0, 2333, 2333, 0, 7147, 0xcda66cfc
-1, 51707, 51707, 512, 1024, 0x38f1196d
-1, 52214, 52214, 512, 1024, 0x657a15fc
-1, 52722, 52722, 512, 1024, 0x669ce2a9
-1, 53229, 53229, 512, 1024, 0x95862dda
-1, 53758, 53758, 512, 1024, 0x1726a7b2
-0, 2444, 2444, 0, 7173, 0xb7455859
-1, 54265, 54265, 512, 1024, 0xd6ece2a1
-1, 54772, 54772, 512, 1024, 0x33ab9553
-1, 55279, 55279, 512, 1024, 0xd50c73a6
-1, 55786, 55786, 512, 1024, 0xfe25b63a
-1, 56316, 56316, 512, 1024, 0x7e2959e3
-0, 2555, 2555, 0, 7213, 0x97b89994
-1, 56823, 56823, 512, 1024, 0xa4c07b34
-1, 57330, 57330, 512, 1024, 0xd6d8f15c
-1, 57837, 57837, 512, 1024, 0x1eccddd7
-1, 58366, 58366, 512, 1024, 0x2b69f9cb
-0, 2666, 2666, 0, 7170, 0xca8b2948
-1, 58874, 58874, 512, 1024, 0x667b775f
-1, 59381, 59381, 512, 1024, 0xad3b84e9
-1, 59888, 59888, 512, 1024, 0x4f29fc67
-1, 60395, 60395, 512, 1024, 0x8d611ab7
-1, 60924, 60924, 512, 1024, 0x278966ea
-0, 2777, 2777, 0, 7174, 0xc7cc6bbb
-1, 61431, 61431, 512, 1024, 0xaf33812b
-1, 61938, 61938, 512, 1024, 0xa55f4265
-1, 62446, 62446, 512, 1024, 0x023cb51c
-1, 62975, 62975, 512, 1024, 0x1d1f1005
-1, 63482, 63482, 512, 1024, 0x874cccf7
-0, 2888, 2888, 0, 7235, 0xc2e68d2b
-1, 63989, 63989, 512, 1024, 0xda705428
-1, 64496, 64496, 512, 1024, 0x48d9b440
-1, 65003, 65003, 512, 1024, 0xa14e0712
-1, 65533, 65533, 512, 1024, 0x7efbad1f
-1, 66040, 66040, 512, 1024, 0xdb82c17f
-0, 3000, 3000, 0, 7261, 0x8204a423
-1, 66547, 66547, 512, 1024, 0xcbe87613
-1, 67054, 67054, 512, 1024, 0x3a63df1d
-1, 67583, 67583, 512, 1024, 0xd5636bba
-1, 68090, 68090, 512, 1024, 0x9397af23
-0, 3111, 3111, 0, 7353, 0xacc7e7c0
-1, 68598, 68598, 512, 1024, 0x32a07c98
-1, 69105, 69105, 512, 1024, 0x202ca667
-1, 69612, 69612, 512, 1024, 0xdf969011
-1, 70141, 70141, 512, 1024, 0xc434d238
-1, 70648, 70648, 512, 1024, 0xe9ad7562
-0, 3222, 3222, 0, 7065, 0x45035c5c
-1, 71155, 71155, 512, 1024, 0xb51b6b50
-1, 71662, 71662, 512, 1024, 0xe70aecd3
-1, 72192, 72192, 512, 1024, 0x03c816b2
-1, 72699, 72699, 512, 1024, 0x869fdf25
-1, 73206, 73206, 512, 1024, 0xd40a0a62
-0, 3333, 3333, 0, 7269, 0x72edbb76
-1, 73713, 73713, 512, 1024, 0x5af7dd35
-1, 74220, 74220, 512, 1024, 0x891ffc72
-1, 74750, 74750, 512, 1024, 0x1ff68a08
-1, 75257, 75257, 512, 1024, 0x5a7517a9
-1, 75764, 75764, 512, 1024, 0x0f959f74
-0, 3444, 3444, 0, 7220, 0xb926772f
-1, 76271, 76271, 512, 1024, 0xe92a12a2
-1, 76778, 76778, 512, 1024, 0x38000e55
-1, 77307, 77307, 512, 1024, 0x39fbdd70
-1, 77814, 77814, 512, 1024, 0xca3d9184
-1, 78322, 78322, 512, 1024, 0x66c8995b
-0, 3555, 3555, 0, 7326, 0x0a66c632
-1, 78829, 78829, 512, 1024, 0xac25acea
-1, 79358, 79358, 512, 1024, 0x3cd1046c
-1, 79865, 79865, 512, 1024, 0x6a1df31c
-1, 80372, 80372, 512, 1024, 0x21ca10a1
-0, 3666, 3666, 0, 7225, 0xe39076ab
-1, 80879, 80879, 512, 1024, 0x1aeccedc
-1, 81387, 81387, 512, 1024, 0xddea1335
-1, 81916, 81916, 512, 1024, 0x19f5ca9f
-1, 82423, 82423, 512, 1024, 0x88e95e43
-1, 82930, 82930, 512, 1024, 0x726284fe
-0, 3777, 3777, 0, 7265, 0xe0209036
-1, 83437, 83437, 512, 1024, 0x6b85b40e
-1, 83966, 83966, 512, 1024, 0x111fee2a
-1, 84474, 84474, 512, 1024, 0x3656b588
-1, 84981, 84981, 512, 1024, 0xa5a2b552
-1, 85488, 85488, 512, 1024, 0x38fb2467
-0, 3888, 3888, 0, 7337, 0x7a5dc093
-1, 85995, 85995, 512, 1024, 0xaa919ccc
-1, 86524, 86524, 512, 1024, 0x15993dbc
-1, 87031, 87031, 512, 1024, 0xbe01a7b9
-1, 87538, 87538, 512, 1024, 0xefe93c09
-1, 88046, 88046, 512, 1024, 0x1bb566e5
-0, 4000, 4000, 0, 7246, 0x519a7a3c
-1, 88575, 88575, 512, 1024, 0x15ce6237
-1, 89082, 89082, 512, 1024, 0xa8552e66
-1, 89589, 89589, 512, 1024, 0x9d80187e
-1, 90096, 90096, 512, 1024, 0x5df3fc30
-1, 90603, 90603, 512, 1024, 0x1a312aa5
-0, 4111, 4111, 0, 7266, 0x352c8078
-1, 91133, 91133, 512, 1024, 0x6bb8e302
-1, 91640, 91640, 512, 1024, 0xbd9684bb
-1, 92147, 92147, 512, 1024, 0x78b0b166
-1, 92654, 92654, 512, 1024, 0xd9af5eae
-0, 4222, 4222, 0, 7323, 0xcaf69d7c
-1, 93183, 93183, 512, 1024, 0xdb90fe82
-1, 93690, 93690, 512, 1024, 0x327614e9
-1, 94198, 94198, 512, 1024, 0x1f19b7fe
-1, 94705, 94705, 512, 1024, 0x46c53f96
-1, 95212, 95212, 512, 1024, 0x921b2189
-0, 4333, 4333, 0, 7309, 0x98c1e6f7
-1, 95741, 95741, 512, 1024, 0xa8fbc85a
-1, 96248, 96248, 512, 1024, 0xabfdaaae
-1, 96755, 96755, 512, 1024, 0x6acc7387
-1, 97263, 97263, 512, 1024, 0x0d9c27b5
-1, 97792, 97792, 512, 1024, 0xba4dd809
-0, 4444, 4444, 0, 7121, 0x913d5bd6
-1, 98299, 98299, 512, 1024, 0x2a2ad521
-1, 98806, 98806, 512, 1024, 0x892de38a
-1, 99313, 99313, 512, 1024, 0xdc97a2eb
-1, 99820, 99820, 512, 1024, 0x4f614ca4
-1, 100350, 100350, 512, 1024, 0x9c8a77ea
-0, 4555, 4555, 111, 7088, 0x56302362
-1, 100857, 100857, 512, 1024, 0x2d30e646
-1, 101364, 101364, 512, 1024, 0x74e800a7
-1, 101871, 101871, 512, 1024, 0x1e01fb02
-1, 102378, 102378, 512, 1024, 0x4ed2c1d8
-0, 4666, 4666, 111, 7104, 0xc0d14f78
-1, 102907, 102907, 512, 1024, 0xf2fdbe63
-1, 103414, 103414, 512, 1024, 0x8d6f63a1
-1, 103922, 103922, 512, 1024, 0xded468d9
-1, 104429, 104429, 512, 1024, 0xccad839e
-1, 104958, 104958, 512, 1024, 0xdde7c082
-0, 4777, 4777, 111, 7169, 0xd03c825b
-1, 105465, 105465, 512, 1024, 0x548613c5
-1, 105972, 105972, 512, 1024, 0x383909bd
-1, 106479, 106479, 512, 1024, 0xfd37627b
-1, 106987, 106987, 512, 1024, 0x6d95a481
-1, 107516, 107516, 512, 1024, 0x56aa87fa
-0, 4888, 4888, 111, 7038, 0x1ecc201d
-1, 108023, 108023, 512, 1024, 0x7b67258c
-1, 108530, 108530, 512, 1024, 0x7dd99a92
-1, 109037, 109037, 512, 1024, 0x4a66d102
-1, 109566, 109566, 512, 1024, 0x7b3fce51
-1, 110074, 110074, 512, 1024, 0xbbd968aa
-0, 5000, 5000, 111, 7015, 0x83c94454
-1, 110581, 110581, 512, 1024, 0x8283ec36
-1, 111088, 111088, 512, 1024, 0x3c96493d
-1, 111595, 111595, 512, 1024, 0xfa4f8cf8
-1, 112124, 112124, 512, 1024, 0xe2cf872d
-1, 112631, 112631, 512, 1024, 0x0a9e7aa6
-0, 5111, 5111, 111, 6983, 0x9e51f54d
-1, 113139, 113139, 512, 1024, 0x6e7a0550
-1, 113646, 113646, 512, 1024, 0x3acfea2f
-1, 114175, 114175, 512, 1024, 0x7111d0fa
-1, 114682, 114682, 512, 1024, 0xe9a1eca9
-0, 5222, 5222, 111, 7088, 0x70d33de1
-1, 115189, 115189, 512, 1024, 0x24da6c46
-1, 115696, 115696, 512, 1024, 0x117cff37
-1, 116204, 116204, 512, 1024, 0x0f27cab6
-1, 116733, 116733, 512, 1024, 0x69b6b4e6
-1, 117240, 117240, 512, 1024, 0x1e6cc841
-0, 5333, 5333, 111, 7096, 0x4d0f81b5
-1, 117747, 117747, 512, 1024, 0xb01e2365
-1, 118254, 118254, 512, 1024, 0x14e200d3
-1, 118783, 118783, 512, 1024, 0xd1184c98
-1, 119290, 119290, 512, 1024, 0xef9140e9
-1, 119798, 119798, 512, 1024, 0x4cbb645e
-0, 5444, 5444, 111, 7106, 0xd1a83ddc
-1, 120305, 120305, 512, 1024, 0xe7fe2f06
-1, 120812, 120812, 512, 1024, 0xf8c45028
-1, 121341, 121341, 512, 1024, 0x561358f4
-1, 121848, 121848, 512, 1024, 0xd0129b77
-1, 122355, 122355, 512, 1024, 0xcc636e88
-0, 5555, 5555, 111, 7219, 0x20f47fe4
-1, 122863, 122863, 512, 1024, 0xe9406321
-1, 123392, 123392, 512, 1024, 0x9f16a041
-1, 123899, 123899, 512, 1024, 0x468bf409
-1, 124406, 124406, 512, 1024, 0x3df70f7b
-1, 124913, 124913, 512, 1024, 0xa880b11b
-0, 5666, 5666, 111, 7184, 0x45dc6a0e
-1, 125420, 125420, 512, 1024, 0x3286c489
-1, 125950, 125950, 512, 1024, 0x39fe9ebc
-1, 126457, 126457, 512, 1024, 0xc533d83b
-1, 126964, 126964, 512, 1024, 0x153b195d
-0, 5777, 5777, 111, 7222, 0x488c6499
-1, 127471, 127471, 512, 1024, 0xd84786a1
-1, 127978, 127978, 512, 1024, 0xdc295aaa
-1, 128507, 128507, 512, 1024, 0xfb764d8c
-1, 129015, 129015, 512, 1024, 0xeebc9db9
-1, 129522, 129522, 512, 1024, 0x7ba9403e
-0, 5888, 5888, 111, 7254, 0xbd097ba7
-1, 130029, 130029, 512, 1024, 0x4e5571ec
-1, 130558, 130558, 512, 1024, 0xd965fad4
-1, 131065, 131065, 512, 1024, 0x87e259f2
-1, 131572, 131572, 512, 1024, 0xae7e533b
-1, 132080, 132080, 512, 1024, 0x313cf4d6
-0, 6000, 6000, 111, 7189, 0x46e06d43
-1, 132587, 132587, 512, 1024, 0xe1844c90
-1, 133116, 133116, 512, 1024, 0xbb057b44
-1, 133623, 133623, 512, 1024, 0xa5099687
-1, 134130, 134130, 512, 1024, 0xbff10707
-1, 134637, 134637, 512, 1024, 0x37c4ffc0
-0, 6111, 6111, 111, 7283, 0x19dd7319
-1, 135166, 135166, 512, 1024, 0xf9fb6caa
-1, 135674, 135674, 512, 1024, 0x3b6a3a1f
-1, 136181, 136181, 512, 1024, 0x83431edb
-1, 136688, 136688, 512, 1024, 0x1eb713cf
-1, 137195, 137195, 512, 1024, 0xd7b07a6d
-0, 6222, 6222, 111, 7161, 0x23171d02
-1, 137724, 137724, 512, 1024, 0x81ae3391
-1, 138231, 138231, 512, 1024, 0xf150130a
-1, 138739, 138739, 512, 1024, 0x09678eaa
-1, 139246, 139246, 512, 1024, 0xb94e06f1
-0, 6333, 6333, 111, 6976, 0xcc610c26
-1, 139775, 139775, 512, 1024, 0x67b1dbc9
-1, 140282, 140282, 512, 1024, 0xd6edc235
-1, 140789, 140789, 512, 1024, 0x34e4c499
-1, 141296, 141296, 512, 1024, 0xeefd89c0
-1, 141804, 141804, 512, 1024, 0x38afdaf1
-0, 6444, 6444, 111, 7056, 0x6cd917b0
-1, 142333, 142333, 512, 1024, 0x29a60d76
-1, 142840, 142840, 512, 1024, 0xe28a4372
-1, 143347, 143347, 512, 1024, 0x7089454d
-1, 143854, 143854, 512, 1024, 0x0c01bb7b
-1, 144383, 144383, 512, 1024, 0xbd776a72
-0, 6555, 6555, 111, 6736, 0x02b78951
-1, 144891, 144891, 512, 1024, 0x86776fd0
-1, 145398, 145398, 512, 1024, 0xb37c88f7
-1, 145905, 145905, 512, 1024, 0x5f90aaf8
-1, 146412, 146412, 512, 1024, 0x203d4222
-1, 146941, 146941, 512, 1024, 0x382692a6
-0, 6666, 6666, 111, 6540, 0x767e0854
-1, 147448, 147448, 512, 1024, 0xf37c95fd
-1, 147956, 147956, 512, 1024, 0x6c0b8877
-1, 148463, 148463, 512, 1024, 0x2e54a8b6
-1, 148992, 148992, 512, 1024, 0x7f266488
-0, 6777, 6777, 111, 6170, 0xc84962fb
-1, 149499, 149499, 512, 1024, 0xfbf20f9a
-1, 150006, 150006, 512, 1024, 0xf2985cc0
-1, 150513, 150513, 512, 1024, 0xc7075340
-1, 151020, 151020, 512, 1024, 0xe4585695
-1, 151550, 151550, 512, 1024, 0xbdffa380
-0, 6888, 6888, 111, 6169, 0x27e06c03
-1, 152057, 152057, 512, 1024, 0x2422a8a9
-1, 152564, 152564, 512, 1024, 0x59cbd75f
-1, 153071, 153071, 512, 1024, 0x04ad1a8c
-1, 153578, 153578, 512, 1024, 0x33c09191
-1, 154107, 154107, 512, 1024, 0x55efa6fd
-0, 7000, 7000, 111, 5864, 0xd14db83f
-1, 154615, 154615, 512, 1024, 0xf73d0e5d
-1, 155122, 155122, 512, 1024, 0x6141ebae
-1, 155629, 155629, 512, 1024, 0x7db17a68
-1, 156158, 156158, 512, 1024, 0xa6c690b6
-1, 156665, 156665, 512, 1024, 0xa6fd6725
-0, 7111, 7111, 111, 5375, 0x4a21055d
-1, 157172, 157172, 512, 1024, 0x50a90b9b
-1, 157680, 157680, 512, 1024, 0xef990dc8
-1, 158187, 158187, 512, 1024, 0x75adf6b5
-1, 158716, 158716, 512, 1024, 0x61eac43e
-1, 159223, 159223, 512, 1024, 0x67797a19
-0, 7222, 7222, 111, 5206, 0x95ead3cb
-1, 159730, 159730, 512, 1024, 0xf325277a
-1, 160237, 160237, 512, 1024, 0x18bf254a
-1, 160767, 160767, 512, 1024, 0x2ce6bee3
-1, 161274, 161274, 512, 1024, 0x8d320860
-0, 7333, 7333, 111, 5220, 0xcfdcc37e
-1, 161781, 161781, 512, 1024, 0xc979b6e8
-1, 162288, 162288, 512, 1024, 0xdb644b41
-1, 162795, 162795, 512, 1024, 0xe1b368ba
-1, 163324, 163324, 512, 1024, 0xacc53d15
-1, 163832, 163832, 512, 1024, 0x42ea8c18
-0, 7444, 7444, 111, 4946, 0x2d864a77
-1, 164339, 164339, 512, 1024, 0xe52c99a4
-1, 164846, 164846, 512, 1024, 0xd7db54a6
-1, 165375, 165375, 512, 1024, 0x7f27a7e3
-1, 165882, 165882, 512, 1024, 0xf7ffeaa9
-1, 166389, 166389, 512, 1024, 0x792b6088
-0, 7555, 7555, 111, 4390, 0x2ab9f462
-1, 166896, 166896, 512, 1024, 0x61d99724
-1, 167404, 167404, 512, 1024, 0x5213720e
-1, 167933, 167933, 512, 1024, 0xac09dd30
-1, 168440, 168440, 512, 1024, 0x960bf6bb
-1, 168947, 168947, 512, 1024, 0xc90168e1
-0, 7666, 7666, 111, 4051, 0x1d09592e
-1, 169454, 169454, 512, 1024, 0x43b45768
-1, 169983, 169983, 512, 1024, 0x935d60a1
-1, 170491, 170491, 512, 1024, 0x9a342ef2
-1, 170998, 170998, 512, 1024, 0xc894709f
-0, 7777, 7777, 111, 3680, 0x39bd6a12
-1, 171505, 171505, 512, 1024, 0x59b43b07
-1, 172012, 172012, 512, 1024, 0x36a1a98d
-1, 172541, 172541, 512, 1024, 0x9e1a121c
-1, 173048, 173048, 512, 1024, 0x02208b78
-1, 173556, 173556, 512, 1024, 0xd1d7b274
-0, 7888, 7888, 111, 2910, 0x6337ece9
-1, 174063, 174063, 512, 1024, 0xdacd5096
-1, 174592, 174592, 512, 1024, 0x51b71ead
-1, 175099, 175099, 512, 1024, 0xd009a7ca
-1, 175606, 175606, 512, 1024, 0xb6d5a938
-1, 176113, 176113, 512, 1024, 0xf3d45e47
-0, 8000, 8000, 111, 2153, 0xf4e3bc17
-1, 176620, 176620, 512, 1024, 0xea8e04fc
-1, 177150, 177150, 512, 1024, 0x0b928bd8
-1, 177657, 177657, 512, 1024, 0x0f02caec
-1, 178164, 178164, 512, 1024, 0xe2b137a8
-1, 178671, 178671, 512, 1024, 0xd5f94892
diff --git a/tests/ref/fate/smjpeg-demux b/tests/ref/fate/smjpeg-demux
new file mode 100644
index 0000000..637f28c
--- /dev/null
+++ b/tests/ref/fate/smjpeg-demux
@@ -0,0 +1,425 @@
+#tb 0: 1/1000
+#tb 1: 1/1000
+0, 0, 0, 0, 734, 0x5a042c2c
+1, 0, 0, 23, 260, 0x00000000
+1, 23, 23, 23, 260, 0x00000000
+1, 46, 46, 23, 260, 0xac9e0a9b
+1, 69, 69, 23, 260, 0x89256f5b
+1, 92, 92, 23, 260, 0x8e646e36
+0, 111, 111, 0, 763, 0xb5893f2f
+1, 116, 116, 23, 260, 0x3ab972fc
+1, 139, 139, 23, 260, 0xaea86bb2
+1, 162, 162, 23, 260, 0x2366447a
+1, 185, 185, 23, 260, 0x82c14f9c
+1, 208, 208, 23, 260, 0xcdcf6fa8
+0, 222, 222, 0, 3023, 0x0f3907d3
+1, 232, 232, 23, 260, 0xb3ed64bd
+1, 255, 255, 23, 260, 0xac304b92
+1, 278, 278, 23, 260, 0xc8bc553b
+1, 301, 301, 23, 260, 0xd35572b4
+1, 325, 325, 23, 260, 0x182f6190
+0, 333, 333, 0, 4800, 0x22e6e18a
+1, 348, 348, 23, 260, 0xbf9145c0
+1, 371, 371, 23, 260, 0x0ec85a7e
+1, 394, 394, 23, 260, 0x3684720e
+1, 417, 417, 23, 260, 0xe985616a
+1, 441, 441, 23, 260, 0x12b147dc
+0, 444, 444, 0, 6417, 0x427adde5
+1, 464, 464, 23, 260, 0xb8b55dd9
+1, 487, 487, 23, 260, 0xfd4a7007
+1, 510, 510, 23, 260, 0xfcc05c9a
+1, 534, 534, 23, 260, 0x20f74aea
+0, 555, 555, 0, 6776, 0x7a74c6ad
+1, 557, 557, 23, 260, 0x025359ca
+1, 580, 580, 23, 260, 0xace44ba1
+1, 603, 603, 23, 260, 0x03506929
+1, 626, 626, 23, 260, 0x8a926f17
+1, 650, 650, 23, 260, 0x4a7061e7
+0, 666, 666, 0, 6808, 0x1f6eb7c3
+1, 673, 673, 23, 260, 0xf8b66cc9
+1, 696, 696, 23, 260, 0xe8c96dec
+1, 719, 719, 23, 260, 0x672a54a6
+1, 743, 743, 23, 260, 0xe97b5698
+1, 766, 766, 23, 260, 0x377f684d
+0, 777, 777, 0, 6726, 0x452087e6
+1, 789, 789, 23, 260, 0xe9a66786
+1, 812, 812, 23, 260, 0xf8e17080
+1, 835, 835, 23, 260, 0x65eb662a
+1, 859, 859, 23, 260, 0xd8d361e9
+1, 882, 882, 23, 260, 0xb8115a0b
+0, 888, 888, 0, 6829, 0xee82b109
+1, 905, 905, 23, 260, 0xa5a85461
+1, 928, 928, 23, 260, 0xf401663b
+1, 952, 952, 23, 260, 0x042f714e
+1, 975, 975, 23, 260, 0xdf195820
+1, 998, 998, 23, 260, 0x0a67653c
+0, 999, 999, 0, 7055, 0xf41f1108
+1, 1021, 1021, 23, 260, 0xe9b44d02
+1, 1044, 1044, 23, 260, 0xbd4747b9
+1, 1068, 1068, 23, 260, 0x3ef66738
+1, 1091, 1091, 23, 260, 0x0f4a6e44
+0, 1111, 1111, 0, 6977, 0xf8fe1ede
+1, 1114, 1114, 23, 260, 0xaa3d6eb6
+1, 1137, 1137, 23, 260, 0xb9a46c4a
+1, 1160, 1160, 23, 260, 0x4f974c2e
+1, 1184, 1184, 23, 260, 0x9e714a00
+1, 1207, 1207, 23, 260, 0x601a7152
+0, 1222, 1222, 0, 6942, 0x9ad105c6
+1, 1230, 1230, 23, 260, 0xaf317064
+1, 1253, 1253, 23, 260, 0x163d4829
+1, 1277, 1277, 23, 260, 0xc56b4f1a
+1, 1300, 1300, 23, 260, 0x7623729c
+1, 1323, 1323, 23, 260, 0xa514694f
+0, 1333, 1333, 0, 6926, 0xe239dad6
+1, 1346, 1346, 23, 260, 0x93ee4ad8
+1, 1369, 1369, 23, 260, 0x6d8e573f
+1, 1393, 1393, 23, 260, 0x13256d68
+1, 1416, 1416, 23, 260, 0x187761a2
+1, 1439, 1439, 23, 260, 0x426045e7
+0, 1444, 1444, 0, 6966, 0x81dcfab1
+1, 1462, 1462, 23, 260, 0x7e7e5891
+1, 1486, 1486, 23, 260, 0xd6926dcc
+1, 1509, 1509, 23, 260, 0xf0196061
+1, 1532, 1532, 23, 260, 0x7cac49a3
+0, 1555, 1555, 0, 6896, 0x31e6cc02
+1, 1555, 1555, 23, 260, 0x24f4549a
+1, 1578, 1578, 23, 260, 0x937f551d
+1, 1602, 1602, 23, 260, 0x9bf462c5
+1, 1625, 1625, 23, 260, 0xd1e07436
+1, 1648, 1648, 23, 260, 0xdab36215
+0, 1666, 1666, 0, 6889, 0x1cc1006e
+1, 1671, 1671, 23, 260, 0xabc5662b
+1, 1695, 1695, 23, 260, 0xa24f6bf1
+1, 1718, 1718, 23, 260, 0x39e664b2
+1, 1741, 1741, 23, 260, 0xf5dc54ca
+1, 1764, 1764, 23, 260, 0xc3b16974
+0, 1777, 1777, 0, 6933, 0xc303f87f
+1, 1787, 1787, 23, 260, 0x6cf46bca
+1, 1811, 1811, 23, 260, 0x7a6b69b9
+1, 1834, 1834, 23, 260, 0xc02f69b9
+1, 1857, 1857, 23, 260, 0x7fc764a9
+1, 1880, 1880, 23, 260, 0xd9705b09
+0, 1888, 1888, 0, 7034, 0xb4970a20
+1, 1904, 1904, 23, 260, 0x17b05f49
+1, 1927, 1927, 23, 260, 0x10ad647c
+1, 1950, 1950, 23, 260, 0xf9636d69
+1, 1973, 1973, 23, 260, 0x622b5ad9
+1, 1996, 1996, 23, 260, 0x175b646d
+0, 1999, 1999, 0, 6961, 0xf064095d
+1, 2020, 2020, 23, 260, 0x722b5827
+1, 2043, 2043, 23, 260, 0x83614974
+1, 2066, 2066, 23, 260, 0x80366587
+1, 2089, 2089, 23, 260, 0x050f6bf9
+0, 2111, 2111, 0, 7089, 0x5ba350f9
+1, 2113, 2113, 23, 260, 0x949d6735
+1, 2136, 2136, 23, 260, 0x62cd7184
+1, 2159, 2159, 23, 260, 0x21e45713
+1, 2182, 2182, 23, 260, 0x56314509
+1, 2205, 2205, 23, 260, 0x7a1570d3
+0, 2222, 2222, 0, 7078, 0xa83f3e88
+1, 2229, 2229, 23, 260, 0x205a6ffb
+1, 2252, 2252, 23, 260, 0xead94483
+1, 2275, 2275, 23, 260, 0x93c84f10
+1, 2298, 2298, 23, 260, 0xdf45726f
+1, 2321, 2321, 23, 260, 0x35016f1e
+0, 2333, 2333, 0, 7147, 0xcda66cfc
+1, 2345, 2345, 23, 260, 0xa8114bcd
+1, 2368, 2368, 23, 260, 0x14c45130
+1, 2391, 2391, 23, 260, 0x97b07052
+1, 2414, 2414, 23, 260, 0x039b6c77
+1, 2438, 2438, 23, 260, 0x46f74635
+0, 2444, 2444, 0, 7173, 0xb7455859
+1, 2461, 2461, 23, 260, 0x4116540d
+1, 2484, 2484, 23, 260, 0x26747067
+1, 2507, 2507, 23, 260, 0x37f16485
+1, 2530, 2530, 23, 260, 0x631d4a33
+1, 2554, 2554, 23, 260, 0x14ed598d
+0, 2555, 2555, 0, 7213, 0x97b89994
+1, 2577, 2577, 23, 260, 0x3f9349e7
+1, 2600, 2600, 23, 260, 0x91295757
+1, 2623, 2623, 23, 260, 0x95de72bc
+1, 2647, 2647, 23, 260, 0xc7ee5ddb
+0, 2666, 2666, 0, 7170, 0xca8b2948
+1, 2670, 2670, 23, 260, 0x38e965cd
+1, 2693, 2693, 23, 260, 0xfae169e9
+1, 2716, 2716, 23, 260, 0x9c226143
+1, 2739, 2739, 23, 260, 0x1a804dbe
+1, 2763, 2763, 23, 260, 0x4aeb633c
+0, 2777, 2777, 0, 7174, 0xc7cc6bbb
+1, 2786, 2786, 23, 260, 0xa66e6bbb
+1, 2809, 2809, 23, 260, 0x51d17109
+1, 2832, 2832, 23, 260, 0x2bc86b9b
+1, 2856, 2856, 23, 260, 0xe56e6378
+1, 2879, 2879, 23, 260, 0x95665b47
+0, 2888, 2888, 0, 7235, 0xc2e68d2b
+1, 2902, 2902, 23, 260, 0x1c255fdb
+1, 2925, 2925, 23, 260, 0x3a2456cb
+1, 2948, 2948, 23, 260, 0xe18e7270
+1, 2972, 2972, 23, 260, 0x55b65c60
+1, 2995, 2995, 23, 260, 0x62be6515
+0, 3000, 3000, 0, 7261, 0x8204a423
+1, 3018, 3018, 23, 260, 0xdba25d09
+1, 3041, 3041, 23, 260, 0xd7cc4e40
+1, 3065, 3065, 23, 260, 0x335661be
+1, 3088, 3088, 23, 260, 0xc3286de3
+0, 3111, 3111, 0, 7353, 0xacc7e7c0
+1, 3111, 3111, 23, 260, 0x47e76e35
+1, 3134, 3134, 23, 260, 0x4b716f77
+1, 3157, 3157, 23, 260, 0x0716519e
+1, 3181, 3181, 23, 260, 0x032b4490
+1, 3204, 3204, 23, 260, 0x15f067e8
+0, 3222, 3222, 0, 7065, 0x45035c5c
+1, 3227, 3227, 23, 260, 0x16766ffa
+1, 3250, 3250, 23, 260, 0xc94154ac
+1, 3274, 3274, 23, 260, 0x74764bcd
+1, 3297, 3297, 23, 260, 0x3fad6f8f
+1, 3320, 3320, 23, 260, 0x5fa972a9
+0, 3333, 3333, 0, 7269, 0x72edbb76
+1, 3343, 3343, 23, 260, 0xde2a4b7b
+1, 3366, 3366, 23, 260, 0xd8494408
+1, 3390, 3390, 23, 260, 0x843d71a6
+1, 3413, 3413, 23, 260, 0x87fd6b60
+1, 3436, 3436, 23, 260, 0x1cc04a39
+0, 3444, 3444, 0, 7220, 0xb926772f
+1, 3459, 3459, 23, 260, 0x9ca24d94
+1, 3482, 3482, 23, 260, 0x820a7087
+1, 3506, 3506, 23, 260, 0x631166b2
+1, 3529, 3529, 23, 260, 0x2f20492a
+1, 3552, 3552, 23, 260, 0x932156d0
+0, 3555, 3555, 0, 7326, 0x0a66c632
+1, 3575, 3575, 23, 260, 0xdad54c90
+1, 3599, 3599, 23, 260, 0xcce84fc9
+1, 3622, 3622, 23, 260, 0xba317486
+1, 3645, 3645, 23, 260, 0xf5a4626a
+0, 3666, 3666, 0, 7225, 0xe39076ab
+1, 3668, 3668, 23, 260, 0x324669fd
+1, 3691, 3691, 23, 260, 0xc7d37113
+1, 3715, 3715, 23, 260, 0xc6e0644f
+1, 3738, 3738, 23, 260, 0x1b91522e
+1, 3761, 3761, 23, 260, 0x9b84667d
+0, 3777, 3777, 0, 7265, 0xe0209036
+1, 3784, 3784, 23, 260, 0xed7e66eb
+1, 3808, 3808, 23, 260, 0xaf806d1f
+1, 3831, 3831, 23, 260, 0x13a66941
+1, 3854, 3854, 23, 260, 0x13095a41
+1, 3877, 3877, 23, 260, 0x5ba05491
+0, 3888, 3888, 0, 7337, 0x7a5dc093
+1, 3900, 3900, 23, 260, 0xbf785887
+1, 3924, 3924, 23, 260, 0x21965973
+1, 3947, 3947, 23, 260, 0xd9aa7134
+1, 3970, 3970, 23, 260, 0x3add62bc
+1, 3993, 3993, 23, 260, 0xb9626260
+0, 4000, 4000, 0, 7246, 0x519a7a3c
+1, 4017, 4017, 23, 260, 0x5b08629f
+1, 4040, 4040, 23, 260, 0x43a34659
+1, 4063, 4063, 23, 260, 0x68575bda
+1, 4086, 4086, 23, 260, 0xd98b715a
+1, 4109, 4109, 23, 260, 0x7d816a77
+0, 4111, 4111, 0, 7266, 0x352c8078
+1, 4133, 4133, 23, 260, 0x16af6ff1
+1, 4156, 4156, 23, 260, 0x6d4557a7
+1, 4179, 4179, 23, 260, 0x0743401a
+1, 4202, 4202, 23, 260, 0x410563d8
+0, 4222, 4222, 0, 7323, 0xcaf69d7c
+1, 4226, 4226, 23, 260, 0x561371d1
+1, 4249, 4249, 23, 260, 0x3ef15872
+1, 4272, 4272, 23, 260, 0x1dd04972
+1, 4295, 4295, 23, 260, 0xed226c62
+1, 4318, 4318, 23, 260, 0x20857046
+0, 4333, 4333, 0, 7309, 0x98c1e6f7
+1, 4342, 4342, 23, 260, 0xed7f4724
+1, 4365, 4365, 23, 260, 0x7a7445cf
+1, 4388, 4388, 23, 260, 0x06ad6a93
+1, 4411, 4411, 23, 260, 0xdd1b6c91
+1, 4435, 4435, 23, 260, 0x05b94d27
+0, 4444, 4444, 0, 7121, 0x913d5bd6
+1, 4458, 4458, 23, 260, 0x12cc5062
+1, 4481, 4481, 23, 260, 0x44526d0f
+1, 4504, 4504, 23, 260, 0xf2ac6d95
+1, 4527, 4527, 23, 260, 0x27174b0f
+1, 4551, 4551, 23, 260, 0xcf125efe
+0, 4555, 4555, 111, 7088, 0x56302362
+1, 4574, 4574, 23, 260, 0xb8ce45a1
+1, 4597, 4597, 23, 260, 0x91895627
+1, 4620, 4620, 23, 260, 0x6edb706a
+1, 4643, 4643, 23, 260, 0x4e16674b
+0, 4666, 4666, 111, 7104, 0xc0d14f78
+1, 4667, 4667, 23, 260, 0xa9d66370
+1, 4690, 4690, 23, 260, 0x8f007043
+1, 4713, 4713, 23, 260, 0xdc1a5583
+1, 4736, 4736, 23, 260, 0x2f025511
+1, 4760, 4760, 23, 260, 0x2a4d6ddb
+0, 4777, 4777, 111, 7169, 0xd03c825b
+1, 4783, 4783, 23, 260, 0x54806f14
+1, 4806, 4806, 23, 260, 0xe0ac6d80
+1, 4829, 4829, 23, 260, 0xd9cf6c97
+1, 4852, 4852, 23, 260, 0xba705b6d
+1, 4876, 4876, 23, 260, 0x0be158e0
+0, 4888, 4888, 111, 7038, 0x1ecc201d
+1, 4899, 4899, 23, 260, 0x32b3645d
+1, 4922, 4922, 23, 260, 0x4a0a55b4
+1, 4945, 4945, 23, 260, 0x078b6fd8
+1, 4969, 4969, 23, 260, 0xc2816368
+1, 4992, 4992, 23, 260, 0xbdee5e4d
+0, 5000, 5000, 111, 7015, 0x83c94454
+1, 5015, 5015, 23, 260, 0x475366aa
+1, 5038, 5038, 23, 260, 0x2f9a44b9
+1, 5061, 5061, 23, 260, 0x91745ee5
+1, 5085, 5085, 23, 260, 0xc29b6e16
+1, 5108, 5108, 23, 260, 0x6ebb6b0e
+0, 5111, 5111, 111, 6983, 0x9e51f54d
+1, 5131, 5131, 23, 260, 0x4e7d7043
+1, 5154, 5154, 23, 260, 0x10b45caf
+1, 5178, 5178, 23, 260, 0x1b1e4e54
+1, 5201, 5201, 23, 260, 0xcc7b6443
+0, 5222, 5222, 111, 7088, 0x70d33de1
+1, 5224, 5224, 23, 260, 0x29936fdd
+1, 5247, 5247, 23, 260, 0x395256e3
+1, 5270, 5270, 23, 260, 0x50fb459f
+1, 5294, 5294, 23, 260, 0x0bef64ec
+1, 5317, 5317, 23, 260, 0xadd372dd
+0, 5333, 5333, 111, 7096, 0x4d0f81b5
+1, 5340, 5340, 23, 260, 0xc49e56dc
+1, 5363, 5363, 23, 260, 0x44e749c1
+1, 5387, 5387, 23, 260, 0x030e6c8a
+1, 5410, 5410, 23, 260, 0x82a47261
+1, 5433, 5433, 23, 260, 0xa3764fcc
+0, 5444, 5444, 111, 7106, 0xd1a83ddc
+1, 5456, 5456, 23, 260, 0xb1a1498a
+1, 5479, 5479, 23, 260, 0xbf9c7184
+1, 5503, 5503, 23, 260, 0xa45f6da8
+1, 5526, 5526, 23, 260, 0x9a2e4d51
+1, 5549, 5549, 23, 260, 0xa15c56ed
+0, 5555, 5555, 111, 7219, 0x20f47fe4
+1, 5572, 5572, 23, 260, 0x7029496c
+1, 5596, 5596, 23, 260, 0xf3595213
+1, 5619, 5619, 23, 260, 0x0dab6c5a
+1, 5642, 5642, 23, 260, 0x0e2367da
+1, 5665, 5665, 23, 260, 0xbb56610a
+0, 5666, 5666, 111, 7184, 0x45dc6a0e
+1, 5688, 5688, 23, 260, 0xcc916c92
+1, 5712, 5712, 23, 260, 0x886c5ba9
+1, 5735, 5735, 23, 260, 0x1b255a69
+1, 5758, 5758, 23, 260, 0xb7a66792
+0, 5777, 5777, 111, 7222, 0x488c6499
+1, 5781, 5781, 23, 260, 0x7d946b0e
+1, 5804, 5804, 23, 260, 0x07d16714
+1, 5828, 5828, 23, 260, 0x77ef6755
+1, 5851, 5851, 23, 260, 0xb2fe6849
+1, 5874, 5874, 23, 260, 0x601b5325
+0, 5888, 5888, 111, 7254, 0xbd097ba7
+1, 5897, 5897, 23, 260, 0x309c68d0
+1, 5921, 5921, 23, 260, 0x7bbe5d49
+1, 5944, 5944, 23, 260, 0x77bc6e47
+1, 5967, 5967, 23, 260, 0x3e0a6b0b
+1, 5990, 5990, 23, 260, 0x2ae458c4
+0, 6000, 6000, 111, 7189, 0x46e06d43
+1, 6013, 6013, 23, 260, 0x17576d4f
+1, 6037, 6037, 23, 260, 0x496c4bbd
+1, 6060, 6060, 23, 260, 0x972758a0
+1, 6083, 6083, 23, 260, 0xa9897452
+1, 6106, 6106, 23, 260, 0xf58c6b92
+0, 6111, 6111, 111, 7283, 0x19dd7319
+1, 6130, 6130, 23, 260, 0x8368709a
+1, 6153, 6153, 23, 260, 0x3890643f
+1, 6176, 6176, 23, 260, 0xdcc1472c
+1, 6199, 6199, 23, 260, 0xb601605c
+0, 6222, 6222, 111, 7161, 0x23171d02
+1, 6222, 6222, 23, 260, 0xfafd6e13
+1, 6246, 6246, 23, 260, 0x20a55dbf
+1, 6269, 6269, 23, 260, 0x84a147e6
+1, 6292, 6292, 23, 260, 0xe2c75bfd
+1, 6315, 6315, 23, 260, 0x52f672c4
+0, 6333, 6333, 111, 6976, 0xcc610c26
+1, 6339, 6339, 23, 260, 0x98af579a
+1, 6362, 6362, 23, 260, 0xf2034f37
+1, 6385, 6385, 23, 260, 0x75576856
+1, 6408, 6408, 23, 260, 0x4a796f1b
+1, 6431, 6431, 23, 260, 0x3a7a5612
+0, 6444, 6444, 111, 7056, 0x6cd917b0
+1, 6455, 6455, 23, 260, 0x1c0646bd
+1, 6478, 6478, 23, 260, 0xfccd6e2c
+1, 6501, 6501, 23, 260, 0x2bdd7139
+1, 6524, 6524, 23, 260, 0xadb4519a
+1, 6548, 6548, 23, 260, 0x8ef655b5
+0, 6555, 6555, 111, 6736, 0x02b78951
+1, 6571, 6571, 23, 260, 0x157852f6
+1, 6594, 6594, 23, 260, 0xec3a4aa8
+1, 6617, 6617, 23, 260, 0x5fa77041
+1, 6640, 6640, 23, 260, 0xe862690f
+1, 6664, 6664, 23, 260, 0xad1759ce
+0, 6666, 6666, 111, 6540, 0x767e0854
+1, 6687, 6687, 23, 260, 0x856f6d2e
+1, 6710, 6710, 23, 260, 0x19496938
+1, 6733, 6733, 23, 260, 0xf3135c06
+1, 6757, 6757, 23, 260, 0xbec861ab
+0, 6777, 6777, 111, 6170, 0xc84962fb
+1, 6780, 6780, 23, 260, 0x97486f09
+1, 6803, 6803, 23, 260, 0x2dcb64ed
+1, 6826, 6826, 23, 260, 0xac196fe8
+1, 6849, 6849, 23, 260, 0xa7d460f8
+1, 6873, 6873, 23, 260, 0x02e55631
+0, 6888, 6888, 111, 6169, 0x27e06c03
+1, 6896, 6896, 23, 260, 0x92556737
+1, 6919, 6919, 23, 260, 0x9ab25599
+1, 6942, 6942, 23, 260, 0x48017498
+1, 6965, 6965, 23, 260, 0x3f376d65
+1, 6989, 6989, 23, 260, 0x553750e2
+0, 7000, 7000, 111, 5864, 0xd14db83f
+1, 7012, 7012, 23, 260, 0x430a6cb9
+1, 7035, 7035, 23, 260, 0x0d4f3b7e
+1, 7058, 7058, 23, 260, 0xc5ee5733
+1, 7082, 7082, 23, 260, 0xec33744f
+1, 7105, 7105, 23, 260, 0xb7ca6c50
+0, 7111, 7111, 111, 5375, 0x4a21055d
+1, 7128, 7128, 23, 260, 0xca8e6e09
+1, 7151, 7151, 23, 260, 0xde7b67d9
+1, 7174, 7174, 23, 260, 0x1eeb47c6
+1, 7198, 7198, 23, 260, 0x97e355f6
+1, 7221, 7221, 23, 260, 0x4cb871da
+0, 7222, 7222, 111, 5206, 0x95ead3cb
+1, 7244, 7244, 23, 260, 0xf9d65f42
+1, 7267, 7267, 23, 260, 0x4df447f9
+1, 7291, 7291, 23, 260, 0x6da55c39
+1, 7314, 7314, 23, 260, 0xf8487192
+0, 7333, 7333, 111, 5220, 0xcfdcc37e
+1, 7337, 7337, 23, 260, 0xa5ef5e84
+1, 7360, 7360, 23, 260, 0xc750404d
+1, 7383, 7383, 23, 260, 0xe62d5ba7
+1, 7407, 7407, 23, 260, 0xa362739c
+1, 7430, 7430, 23, 260, 0x784c57f9
+0, 7444, 7444, 111, 4946, 0x2d864a77
+1, 7453, 7453, 23, 260, 0xac224b6f
+1, 7476, 7476, 23, 260, 0x34506907
+1, 7500, 7500, 23, 260, 0x94207121
+1, 7523, 7523, 23, 260, 0x018754e6
+1, 7546, 7546, 23, 260, 0xa5355133
+0, 7555, 7555, 111, 4390, 0x2ab9f462
+1, 7569, 7569, 23, 260, 0x93724dac
+1, 7592, 7592, 23, 260, 0x41e24c4c
+1, 7616, 7616, 23, 260, 0x1b2a7301
+1, 7639, 7639, 23, 260, 0xcce36e61
+1, 7662, 7662, 23, 260, 0xb323585a
+0, 7666, 7666, 111, 4051, 0x1d09592e
+1, 7685, 7685, 23, 260, 0x6f7c624d
+1, 7709, 7709, 23, 260, 0x87b96a4a
+1, 7732, 7732, 23, 260, 0xf567622a
+1, 7755, 7755, 23, 260, 0x52ce5d35
+0, 7777, 7777, 111, 3680, 0x39bd6a12
+1, 7778, 7778, 23, 260, 0x58a46c28
+1, 7801, 7801, 23, 260, 0x8e3e6d9a
+1, 7825, 7825, 23, 260, 0x5ef66906
+1, 7848, 7848, 23, 260, 0x351b5f9f
+1, 7871, 7871, 23, 260, 0x90b9588a
+0, 7888, 7888, 111, 2910, 0x6337ece9
+1, 7894, 7894, 23, 260, 0x34e8615f
+1, 7918, 7918, 23, 260, 0xcef75ab9
+1, 7941, 7941, 23, 260, 0x471f6bc8
+1, 7964, 7964, 23, 260, 0xd4756c62
+1, 7987, 7987, 23, 260, 0x7c554702
+0, 8000, 8000, 111, 2153, 0xf4e3bc17
+1, 8010, 8010, 23, 260, 0x185272f1
+1, 8034, 8034, 23, 260, 0x0c364348
+1, 8057, 8057, 23, 260, 0x24354467
+1, 8080, 8080, 23, 260, 0x837d5472
+1, 8103, 8103, 23, 260, 0xece2344f
diff --git a/tests/ref/fate/thp b/tests/ref/fate/thp
new file mode 100644
index 0000000..52dd059
--- /dev/null
+++ b/tests/ref/fate/thp
@@ -0,0 +1,73 @@
+#tb 0: 524288/15712911
+0, 0, 0, 1, 291840, 0xbd7e0b22
+0, 1, 1, 1, 291840, 0xf6e12ca5
+0, 2, 2, 1, 291840, 0x528c7049
+0, 3, 3, 1, 291840, 0x93055de9
+0, 4, 4, 1, 291840, 0xf95a51c1
+0, 5, 5, 1, 291840, 0x6ad3a65a
+0, 6, 6, 1, 291840, 0x494684a7
+0, 7, 7, 1, 291840, 0x74c14eb1
+0, 8, 8, 1, 291840, 0x149fcb7e
+0, 9, 9, 1, 291840, 0x25649761
+0, 10, 10, 1, 291840, 0xbc3f9052
+0, 11, 11, 1, 291840, 0x080edfff
+0, 12, 12, 1, 291840, 0x6d7ad684
+0, 13, 13, 1, 291840, 0x6d53844d
+0, 14, 14, 1, 291840, 0xf7ad5385
+0, 15, 15, 1, 291840, 0x0241b56a
+0, 16, 16, 1, 291840, 0x120122c8
+0, 17, 17, 1, 291840, 0x31b0f32a
+0, 18, 18, 1, 291840, 0x14068b98
+0, 19, 19, 1, 291840, 0xeeec658b
+0, 20, 20, 1, 291840, 0x9376374c
+0, 21, 21, 1, 291840, 0x091e8c6e
+0, 22, 22, 1, 291840, 0x744ad07f
+0, 23, 23, 1, 291840, 0xf99c554e
+0, 24, 24, 1, 291840, 0xc84bd677
+0, 25, 25, 1, 291840, 0x3898d474
+0, 26, 26, 1, 291840, 0x1e2910c8
+0, 27, 27, 1, 291840, 0xb11f58bc
+0, 28, 28, 1, 291840, 0xf89170ee
+0, 29, 29, 1, 291840, 0x8f239dc3
+0, 30, 30, 1, 291840, 0x8538c76c
+0, 31, 31, 1, 291840, 0x162ee66f
+0, 32, 32, 1, 291840, 0x5f8708a5
+0, 33, 33, 1, 291840, 0x95802dfb
+0, 34, 34, 1, 291840, 0xc424630d
+0, 35, 35, 1, 291840, 0xfb8a8667
+0, 36, 36, 1, 291840, 0xbad79af5
+0, 37, 37, 1, 291840, 0xc733b325
+0, 38, 38, 1, 291840, 0x4bfbcd70
+0, 39, 39, 1, 291840, 0x502cd950
+0, 40, 40, 1, 291840, 0x8461ca2c
+0, 41, 41, 1, 291840, 0x00219b0d
+0, 42, 42, 1, 291840, 0xa4de45e1
+0, 43, 43, 1, 291840, 0xacd3f4df
+0, 44, 44, 1, 291840, 0x2203a369
+0, 45, 45, 1, 291840, 0x0a66effa
+0, 46, 46, 1, 291840, 0x7ac1fd91
+0, 47, 47, 1, 291840, 0x84970aa7
+0, 48, 48, 1, 291840, 0x569d145f
+0, 49, 49, 1, 291840, 0xe51efe1b
+0, 50, 50, 1, 291840, 0x38e2cd78
+0, 51, 51, 1, 291840, 0x93428ea2
+0, 52, 52, 1, 291840, 0x3d3f5b17
+0, 53, 53, 1, 291840, 0x9546127d
+0, 54, 54, 1, 291840, 0x4178be54
+0, 55, 55, 1, 291840, 0x0d0f8036
+0, 56, 56, 1, 291840, 0xc20557b9
+0, 57, 57, 1, 291840, 0x6d4b2d64
+0, 58, 58, 1, 291840, 0xa750125d
+0, 59, 59, 1, 291840, 0x04623ce3
+0, 60, 60, 1, 291840, 0xc7f2bbc7
+0, 61, 61, 1, 291840, 0x6e271336
+0, 62, 62, 1, 291840, 0xcfbd4246
+0, 63, 63, 1, 291840, 0xe1493be9
+0, 64, 64, 1, 291840, 0x6c731194
+0, 65, 65, 1, 291840, 0x0fc30cc2
+0, 66, 66, 1, 291840, 0x967427f3
+0, 67, 67, 1, 291840, 0x55ae3b00
+0, 68, 68, 1, 291840, 0xbe4f200c
+0, 69, 69, 1, 291840, 0xc515e443
+0, 70, 70, 1, 291840, 0xd738bd69
+0, 71, 71, 1, 291840, 0xa8e0ab69
diff --git a/tests/ref/fate/truemotion1-15 b/tests/ref/fate/truemotion1-15
index 9a5d389..6b5281d 100644
--- a/tests/ref/fate/truemotion1-15
+++ b/tests/ref/fate/truemotion1-15
@@ -1,220 +1,106 @@
#tb 0: 1/15
-#tb 1: 1/44100
0, 0, 0, 1, 161280, 0x7041748d
-1, 0, 0, 2708, 10832, 0xe1a811fa
-1, 2708, 2708, 2708, 10832, 0xb47841f9
0, 1, 1, 1, 161280, 0x3cc4dfb5
-1, 5416, 5416, 2708, 10832, 0x839eedf1
0, 2, 2, 1, 161280, 0xca3af22d
-1, 8124, 8124, 2708, 10832, 0xb48b1f60
0, 3, 3, 1, 161280, 0x23ad1d85
-1, 10832, 10832, 2708, 10832, 0x743936c0
0, 4, 4, 1, 161280, 0x9c9cf364
-1, 13540, 13540, 2708, 10832, 0xe1f039fb
0, 5, 5, 1, 161280, 0x1551d6a8
-1, 16248, 16248, 2708, 10832, 0xef00751a
0, 6, 6, 1, 161280, 0xc39f6b95
-1, 18956, 18956, 2708, 10832, 0x401ed099
0, 7, 7, 1, 161280, 0x3b036dcc
-1, 21665, 21665, 2708, 10832, 0x432a53bd
0, 8, 8, 1, 161280, 0xa6fac1db
-1, 24373, 24373, 2708, 10832, 0xc4276bfd
0, 9, 9, 1, 161280, 0x67656b62
-1, 27081, 27081, 2708, 10832, 0x51f0fa8c
0, 10, 10, 1, 161280, 0xb41f47d1
-1, 29789, 29789, 2708, 10832, 0xcebae622
0, 11, 11, 1, 161280, 0xc207249e
-1, 32497, 32497, 2708, 10832, 0xe9f6dc1f
-1, 35205, 35205, 2708, 10832, 0xda087fee
0, 12, 12, 1, 161280, 0xbee8f843
-1, 37913, 37913, 2708, 10832, 0x67a621bb
0, 13, 13, 1, 161280, 0x092acf46
-1, 40621, 40621, 2708, 10832, 0xd7be207f
0, 14, 14, 1, 161280, 0x8d9e2680
-1, 43329, 43329, 2708, 10832, 0x19d32507
0, 15, 15, 1, 161280, 0x8becc20c
-1, 46037, 46037, 2708, 10832, 0xe1a3fbfa
0, 16, 16, 1, 161280, 0x655e444e
-1, 48745, 48745, 2708, 10832, 0xd10df779
0, 17, 17, 1, 161280, 0x5c112da0
-1, 51453, 51453, 2708, 10832, 0x4428e1a7
0, 18, 18, 1, 161280, 0x232fa9eb
-1, 54161, 54161, 2708, 10832, 0x7ea9b33d
0, 19, 19, 1, 161280, 0x9721745d
-1, 56869, 56869, 2708, 10832, 0x6852a5a5
0, 20, 20, 1, 161280, 0x92f1d880
-1, 59578, 59578, 2708, 10832, 0xfeb78863
0, 21, 21, 1, 161280, 0x16233978
-1, 62286, 62286, 2708, 10832, 0xf157f928
0, 22, 22, 1, 161280, 0x19a27e69
-1, 64994, 64994, 2708, 10832, 0x86414b3e
0, 23, 23, 1, 161280, 0x7b6ad73a
-1, 67702, 67702, 2708, 10832, 0x2e28cdf6
-1, 70410, 70410, 2708, 10832, 0x00212e44
0, 24, 24, 1, 161280, 0xa7a674aa
-1, 73118, 73118, 2708, 10832, 0x2d7f9378
0, 25, 25, 1, 161280, 0x4e434abb
-1, 75826, 75826, 2708, 10832, 0x84cb25d7
0, 26, 26, 1, 161280, 0xb96eea14
-1, 78534, 78534, 2708, 10832, 0x3aca41fa
0, 27, 27, 1, 161280, 0x1350188c
-1, 81242, 81242, 2708, 10832, 0x27ad34b9
0, 28, 28, 1, 161280, 0x79c6f305
-1, 83950, 83950, 2708, 10832, 0xe665144a
0, 29, 29, 1, 161280, 0xa9c7782d
-1, 86658, 86658, 2708, 10832, 0xf9546626
0, 30, 30, 1, 161280, 0x40a4f456
-1, 89366, 89366, 2708, 10832, 0xe71c4f22
0, 31, 31, 1, 161280, 0xaf291ed6
-1, 92074, 92074, 2708, 10832, 0x5e61869c
0, 32, 32, 1, 161280, 0xab29b4e1
-1, 94782, 94782, 2708, 10832, 0x571d2c10
0, 33, 33, 1, 161280, 0xbfcd2712
-1, 97490, 97490, 2708, 10832, 0xf0e08cd5
0, 34, 34, 1, 161280, 0xff22a0d7
-1, 100199, 100199, 2708, 10832, 0x66650e49
0, 35, 35, 1, 161280, 0xb0ae88a9
-1, 102907, 102907, 2708, 10832, 0x4024deaf
-1, 105615, 105615, 2708, 10832, 0xda7bdb14
0, 36, 36, 1, 161280, 0x811d1259
-1, 108323, 108323, 2708, 10832, 0xc27a342f
0, 37, 37, 1, 161280, 0x593c39a1
-1, 111031, 111031, 2708, 10832, 0x574fe679
0, 38, 38, 1, 161280, 0x5a5a97f8
-1, 113739, 113739, 2708, 10832, 0x37db464e
0, 39, 39, 1, 161280, 0xa5639ecf
-1, 116447, 116447, 2708, 10832, 0xb1fa2a83
0, 40, 40, 1, 161280, 0x543920c6
-1, 119155, 119155, 2708, 10832, 0x3d98d9b7
0, 41, 41, 1, 161280, 0xb41689ee
-1, 121863, 121863, 2708, 10832, 0xb7c908e2
0, 42, 42, 1, 161280, 0xc0ad83de
-1, 124571, 124571, 2708, 10832, 0x9f7e44d8
0, 43, 43, 1, 161280, 0x9e9e7456
-1, 127279, 127279, 2708, 10832, 0xae9b8774
0, 44, 44, 1, 161280, 0x777ccbfe
-1, 129987, 129987, 2708, 10832, 0x36916e3f
0, 45, 45, 1, 161280, 0x9c2df916
-1, 132695, 132695, 2708, 10832, 0xd785f5ef
0, 46, 46, 1, 161280, 0xe0c13b35
-1, 135403, 135403, 2708, 10832, 0x2a3a5673
-1, 138112, 138112, 2708, 10832, 0x7320e379
0, 47, 47, 1, 161280, 0x39bfa5a5
-1, 140820, 140820, 2708, 10832, 0xec787be5
0, 48, 48, 1, 161280, 0x35dfb264
-1, 143528, 143528, 2708, 10832, 0xd0d13aa0
0, 49, 49, 1, 161280, 0x43018613
-1, 146236, 146236, 2708, 10832, 0x34dfcb17
0, 50, 50, 1, 161280, 0x43584b8a
-1, 148944, 148944, 2708, 10832, 0x1a9c29f1
0, 51, 51, 1, 161280, 0xa5cd230a
-1, 151652, 151652, 2708, 10832, 0x3e73dcc1
0, 52, 52, 1, 161280, 0x6fe2cfb3
-1, 154360, 154360, 2708, 10832, 0x7855b053
0, 53, 53, 1, 161280, 0x88a7c0db
-1, 157068, 157068, 2708, 10832, 0x5588df8f
0, 54, 54, 1, 161280, 0x476f1cd2
-1, 159776, 159776, 2708, 10832, 0x6f621299
0, 55, 55, 1, 161280, 0x96401d49
-1, 162484, 162484, 2708, 10832, 0xce7f39c2
0, 56, 56, 1, 161280, 0x7d932919
-1, 165192, 165192, 2708, 10832, 0xd88e6552
0, 57, 57, 1, 161280, 0x06465481
-1, 167900, 167900, 2708, 10832, 0xddc63597
0, 58, 58, 1, 161280, 0x39631520
-1, 170608, 170608, 2708, 10832, 0xe3071865
-1, 173316, 173316, 2708, 10832, 0x2a44a123
0, 59, 59, 1, 161280, 0xc3fff780
-1, 176024, 176024, 2708, 10832, 0x08d85d45
0, 60, 60, 1, 161280, 0xa81faf28
-1, 178733, 178733, 2708, 10832, 0x4dc5f83a
0, 61, 61, 1, 161280, 0x7a311f4f
-1, 181441, 181441, 2708, 10832, 0x89497812
0, 62, 62, 1, 161280, 0x52f9b931
-1, 184149, 184149, 2708, 10832, 0x9ee1db54
0, 63, 63, 1, 161280, 0x938cf016
-1, 186857, 186857, 2708, 10832, 0x5277d611
0, 64, 64, 1, 161280, 0xf8f6e19c
-1, 189565, 189565, 2708, 10832, 0x570a619c
0, 65, 65, 1, 161280, 0xca90561b
-1, 192273, 192273, 2708, 10832, 0xa217d70f
0, 66, 66, 1, 161280, 0x8594d06b
-1, 194981, 194981, 2708, 10832, 0x6f0ecbf4
0, 67, 67, 1, 161280, 0xea32bf3b
-1, 197689, 197689, 2708, 10832, 0x2704b114
0, 68, 68, 1, 161280, 0x4646111a
-1, 200397, 200397, 2708, 10832, 0xf24e679f
0, 69, 69, 1, 161280, 0xee891162
-1, 203105, 203105, 2708, 10832, 0x05572099
0, 70, 70, 1, 161280, 0xcfc32082
-1, 205813, 205813, 2708, 10832, 0x33942d0c
-1, 208521, 208521, 2708, 10832, 0xa77ea674
0, 71, 71, 1, 161280, 0x863c281a
-1, 211229, 211229, 2708, 10832, 0xeba663bc
0, 72, 72, 1, 161280, 0x01b591aa
-1, 213937, 213937, 2708, 10832, 0x1338524a
0, 73, 73, 1, 161280, 0x211fbc62
-1, 216645, 216645, 2708, 10832, 0x6182b0b3
0, 74, 74, 1, 161280, 0xae2bafe2
-1, 219354, 219354, 2708, 10832, 0xa410a364
0, 75, 75, 1, 161280, 0xcfe46dca
-1, 222062, 222062, 2708, 10832, 0x2f4374b0
0, 76, 76, 1, 161280, 0xcf8fe8a3
-1, 224770, 224770, 2708, 10832, 0xf41f3a07
0, 77, 77, 1, 161280, 0x3f8474eb
-1, 227478, 227478, 2708, 10832, 0x2b1c50c6
0, 78, 78, 1, 161280, 0x06da345a
-1, 230186, 230186, 2708, 10832, 0x3692ac89
0, 79, 79, 1, 161280, 0xbd4d3280
-1, 232894, 232894, 2708, 10832, 0x5d6bc87e
0, 80, 80, 1, 161280, 0xb5e70fea
-1, 235602, 235602, 2708, 10832, 0x1b1cda0c
0, 81, 81, 1, 161280, 0x0c99c804
-1, 238310, 238310, 2708, 10832, 0x11eaa15f
-1, 241018, 241018, 2708, 10832, 0x73c7d7ef
0, 82, 82, 1, 161280, 0x19841ed4
-1, 243726, 243726, 2708, 10832, 0x65d7e3be
0, 83, 83, 1, 161280, 0xf81dea50
-1, 246434, 246434, 2708, 10832, 0xb9c00688
0, 84, 84, 1, 161280, 0x7777d81c
-1, 249142, 249142, 2708, 10832, 0x0b98c125
0, 85, 85, 1, 161280, 0x0497cfd8
-1, 251850, 251850, 2708, 10832, 0x331ed413
0, 86, 86, 1, 161280, 0x50b6eb64
-1, 254558, 254558, 2708, 10832, 0x9b68f485
0, 87, 87, 1, 161280, 0x5071fc07
-1, 257267, 257267, 2708, 10832, 0x1b865c55
0, 88, 88, 1, 161280, 0xbb7527fb
-1, 259975, 259975, 2708, 10832, 0x68cef565
0, 89, 89, 1, 161280, 0x13054f1f
-1, 262683, 262683, 2708, 10832, 0x3a605f15
0, 90, 90, 1, 161280, 0x4b78fb27
-1, 265391, 265391, 2708, 10832, 0xd72ff22e
0, 91, 91, 1, 161280, 0xf504968f
-1, 268099, 268099, 2708, 10832, 0x1c672b67
0, 92, 92, 1, 161280, 0x555b10b7
-1, 270807, 270807, 2708, 10832, 0xfd1a7e7e
0, 93, 93, 1, 161280, 0xcc0dde40
-1, 273515, 273515, 2708, 10832, 0x9bf20ead
-1, 276223, 276223, 2708, 10832, 0x00000000
0, 94, 94, 1, 161280, 0xcc0dde40
-1, 278931, 278931, 2708, 10832, 0x00000000
0, 95, 95, 1, 161280, 0x367f60c8
-1, 281639, 281639, 2708, 10832, 0x00000000
0, 96, 96, 1, 161280, 0x367f60c8
-1, 284347, 284347, 2708, 10832, 0x00000000
0, 97, 97, 1, 161280, 0x367f60c8
-1, 287055, 287055, 2708, 10832, 0x00000000
0, 98, 98, 1, 161280, 0x367f60c8
-1, 289763, 289763, 2708, 10832, 0x00000000
0, 99, 99, 1, 161280, 0x367f60c8
-1, 292471, 292471, 2708, 10832, 0x00000000
0, 100, 100, 1, 161280, 0x367f60c8
-1, 295179, 295179, 2708, 10832, 0x00000000
0, 101, 101, 1, 161280, 0x367f60c8
-1, 297888, 297888, 2708, 10832, 0x00000000
0, 102, 102, 1, 161280, 0x367f60c8
-1, 300596, 300596, 2708, 10832, 0x00000000
0, 103, 103, 1, 161280, 0x367f60c8
-1, 303304, 303304, 2708, 10832, 0x00000000
0, 104, 104, 1, 161280, 0x367f60c8
diff --git a/tests/ref/fate/truemotion1-24 b/tests/ref/fate/truemotion1-24
index 8d9b150..f097ed0 100644
--- a/tests/ref/fate/truemotion1-24
+++ b/tests/ref/fate/truemotion1-24
@@ -1,45 +1,16 @@
#tb 0: 1/15
-#tb 1: 1/44100
0, 0, 0, 1, 69120, 0x68beb30f
-1, 0, 0, 2708, 10832, 0x1597b4c8
-1, 2708, 2708, 2708, 10832, 0xf9479f8b
0, 1, 1, 1, 69120, 0x3976f5cf
-1, 5416, 5416, 2708, 10832, 0x8db50e74
0, 2, 2, 1, 69120, 0xf815bc3c
-1, 8124, 8124, 2708, 10832, 0x2b33ecbb
0, 3, 3, 1, 69120, 0xa7cc0ae6
-1, 10832, 10832, 2708, 10832, 0x8d0f537b
0, 4, 4, 1, 69120, 0xd85ac282
-1, 13540, 13540, 2708, 10832, 0x922081c7
0, 5, 5, 1, 69120, 0xf7fd7edb
-1, 16248, 16248, 2708, 10832, 0x40291f19
0, 6, 6, 1, 69120, 0x433bb6f6
-1, 18956, 18956, 2708, 10832, 0x88f5271a
0, 7, 7, 1, 69120, 0xdbac8bee
-1, 21665, 21665, 2708, 10832, 0x55c6bbe5
0, 8, 8, 1, 69120, 0x88e2a799
-1, 24373, 24373, 2708, 10832, 0x9b51ae82
0, 9, 9, 1, 69120, 0x49617b26
-1, 27081, 27081, 2708, 10832, 0xcdf2409b
0, 10, 10, 1, 69120, 0xeb44ca01
-1, 29789, 29789, 2708, 10832, 0x0933b1a4
0, 11, 11, 1, 69120, 0x6fea37e8
-1, 32497, 32497, 2708, 10832, 0x24b77006
-1, 35205, 35205, 2708, 10832, 0xf612fa8a
0, 12, 12, 1, 69120, 0xf55d74c7
-1, 37913, 37913, 2708, 10832, 0x99884b06
0, 13, 13, 1, 69120, 0xb5082ca7
-1, 40621, 40621, 2708, 10832, 0x3c746fbe
0, 14, 14, 1, 69120, 0x5876d758
-1, 43329, 43329, 2708, 10832, 0x05f3b08a
-1, 46037, 46037, 2708, 10832, 0xa6560483
-1, 48745, 48745, 2708, 10832, 0xd98a8e19
-1, 51453, 51453, 2708, 10832, 0xf98a0b2e
-1, 54161, 54161, 2708, 10832, 0xb1039582
-1, 56869, 56869, 2708, 10832, 0x85dd5c3f
-1, 59578, 59578, 2708, 10832, 0x19fc801a
-1, 62286, 62286, 2708, 10832, 0x95805089
-1, 64994, 64994, 2708, 10832, 0x576fdec3
-1, 67702, 67702, 2708, 10832, 0x704a0905
-1, 70410, 70410, 2708, 10832, 0xf87ce1fa
-1, 73118, 73118, 2708, 10832, 0xfc0076b9
diff --git a/tests/ref/fate/vc1-ism b/tests/ref/fate/vc1-ism
index a9cfb2c..4daca95 100644
--- a/tests/ref/fate/vc1-ism
+++ b/tests/ref/fate/vc1-ism
@@ -1,121 +1,121 @@
#tb 0: 1/10000000
-0, 0, 0, 0, 37440, 0xd1bc5235
+0, 423334, 423334, 0, 37440, 0xd1bc5235
0, 840000, 840000, 0, 37440, 0x158e6167
-0, 1250000, 1250000, 0, 37440, 0x0faa4481
+0, 1256666, 1256666, 0, 37440, 0x0faa4481
0, 1670000, 1670000, 0, 37440, 0x427158c5
-0, 2090000, 2090000, 0, 37440, 0x4eb53ac6
+0, 2086666, 2086666, 0, 37440, 0x4eb53ac6
0, 2500000, 2500000, 0, 37440, 0x99304eea
-0, 2920000, 2920000, 0, 37440, 0xcc554a6f
+0, 2916666, 2916666, 0, 37440, 0xcc554a6f
0, 3340000, 3340000, 0, 37440, 0xabeb6c35
-0, 3750000, 3750000, 0, 37440, 0xddfc7e18
+0, 3756666, 3756666, 0, 37440, 0xddfc7e18
0, 4170000, 4170000, 0, 37440, 0xaa79b504
-0, 4590000, 4590000, 0, 37440, 0x5cb1c839
+0, 4586666, 4586666, 0, 37440, 0x5cb1c839
0, 5000000, 5000000, 0, 37440, 0x7e36ecca
-0, 5420000, 5420000, 0, 37440, 0xf486f425
+0, 5416666, 5416666, 0, 37440, 0xf486f425
0, 5840000, 5840000, 0, 37440, 0xf1b4138f
-0, 6250000, 6250000, 0, 37440, 0x966f1a49
+0, 6256666, 6256666, 0, 37440, 0x966f1a49
0, 6670000, 6670000, 0, 37440, 0x5eff21da
-0, 7090000, 7090000, 0, 37440, 0x333f39b1
+0, 7086666, 7086666, 0, 37440, 0x333f39b1
0, 7500000, 7500000, 0, 37440, 0x62e5963e
-0, 7920000, 7920000, 0, 37440, 0x26930671
+0, 7916666, 7916666, 0, 37440, 0x26930671
0, 8340000, 8340000, 0, 37440, 0x27b4bb6c
-0, 8750000, 8750000, 0, 37440, 0xdbd07766
+0, 8756666, 8756666, 0, 37440, 0xdbd07766
0, 9170000, 9170000, 0, 37440, 0x04260104
-0, 9590000, 9590000, 0, 37440, 0x9b1e078b
+0, 9586666, 9586666, 0, 37440, 0x9b1e078b
0, 10000000, 10000000, 0, 37440, 0xdf4e2474
-0, 10420000, 10420000, 0, 37440, 0x57d44986
+0, 10416666, 10416666, 0, 37440, 0x57d44986
0, 10840000, 10840000, 0, 37440, 0x8780e34c
-0, 11250000, 11250000, 0, 37440, 0xf80c8bc0
+0, 11256666, 11256666, 0, 37440, 0xf80c8bc0
0, 11670000, 11670000, 0, 37440, 0x630a7583
-0, 12090000, 12090000, 0, 37440, 0x235ae089
+0, 12086666, 12086666, 0, 37440, 0x235ae089
0, 12500000, 12500000, 0, 37440, 0x984b8f0e
-0, 12920000, 12920000, 0, 37440, 0x865cf592
+0, 12916666, 12916666, 0, 37440, 0x865cf592
0, 13340000, 13340000, 0, 37440, 0x70f376f2
-0, 13750000, 13750000, 0, 37440, 0x8b30c035
+0, 13756666, 13756666, 0, 37440, 0x8b30c035
0, 14170000, 14170000, 0, 37440, 0xde772d79
-0, 14590000, 14590000, 0, 37440, 0x8e076be5
+0, 14586666, 14586666, 0, 37440, 0x8e076be5
0, 15000000, 15000000, 0, 37440, 0x3dc2bd9f
-0, 15420000, 15420000, 0, 37440, 0xb782eb67
+0, 15416666, 15416666, 0, 37440, 0xb782eb67
0, 15840000, 15840000, 0, 37440, 0x02025d73
-0, 16250000, 16250000, 0, 37440, 0x86bbbce8
+0, 16256666, 16256666, 0, 37440, 0x86bbbce8
0, 16670000, 16670000, 0, 37440, 0xd6554f62
-0, 17090000, 17090000, 0, 37440, 0xb831b917
+0, 17086666, 17086666, 0, 37440, 0xb831b917
0, 17500000, 17500000, 0, 37440, 0x80643560
-0, 17920000, 17920000, 0, 37440, 0x4ecf9afd
+0, 17916666, 17916666, 0, 37440, 0x4ecf9afd
0, 18340000, 18340000, 0, 37440, 0x9ce51e0b
-0, 18750000, 18750000, 0, 37440, 0x179466cd
+0, 18756666, 18756666, 0, 37440, 0x179466cd
0, 19170000, 19170000, 0, 37440, 0x145fc900
-0, 19590000, 19590000, 0, 37440, 0xb1b50402
+0, 19586666, 19586666, 0, 37440, 0xb1b50402
0, 20000000, 20000000, 0, 37440, 0x0a87552a
-0, 20420000, 20420000, 0, 37440, 0x8f53821d
+0, 20416666, 20416666, 0, 37440, 0x8f53821d
0, 20840000, 20840000, 0, 37440, 0x1c07c825
-0, 21250000, 21250000, 0, 37440, 0x49dde82f
+0, 21256666, 21256666, 0, 37440, 0x49dde82f
0, 21670000, 21670000, 0, 37440, 0xb1a32605
-0, 22090000, 22090000, 0, 37440, 0x410f3cd5
+0, 22086666, 22086666, 0, 37440, 0x410f3cd5
0, 22500000, 22500000, 0, 37440, 0xff5e6696
-0, 22920000, 22920000, 0, 37440, 0x96f678c9
+0, 22916666, 22916666, 0, 37440, 0x96f678c9
0, 23340000, 23340000, 0, 37440, 0x6c9e9e68
-0, 23750000, 23750000, 0, 37440, 0x79a2a655
+0, 23756666, 23756666, 0, 37440, 0x79a2a655
0, 24170000, 24170000, 0, 37440, 0xf237bd6c
-0, 24590000, 24590000, 0, 37440, 0x4051b611
+0, 24586666, 24586666, 0, 37440, 0x4051b611
0, 25000000, 25000000, 0, 37440, 0xc7ccc918
-0, 25420000, 25420000, 0, 37440, 0xbd02c122
+0, 25416666, 25416666, 0, 37440, 0xbd02c122
0, 25840000, 25840000, 0, 37440, 0xacb3c881
-0, 26250000, 26250000, 0, 37440, 0x2abdb940
+0, 26256666, 26256666, 0, 37440, 0x2abdb940
0, 26670000, 26670000, 0, 37440, 0x19d5be85
-0, 27090000, 27090000, 0, 37440, 0xfa5fb1ba
-0, 27500000, 27500000, 0, 37440, 0xdae7a7aa
-0, 27920000, 27920000, 0, 37440, 0x6b0f9f69
+0, 27086666, 27086666, 0, 37440, 0xfa5fb1ba
+0, 27503332, 27503332, 0, 37440, 0xdae7a7aa
+0, 27919998, 27919998, 0, 37440, 0x6b0f9f69
0, 28340000, 28340000, 0, 37440, 0x353e8201
-0, 28750000, 28750000, 0, 37440, 0xa21443aa
+0, 28756666, 28756666, 0, 37440, 0xa21443aa
0, 29170000, 29170000, 0, 37440, 0x66c8d7e0
-0, 29590000, 29590000, 0, 37440, 0xc332068e
+0, 29586666, 29586666, 0, 37440, 0xc332068e
0, 30000000, 30000000, 0, 37440, 0x71431b9b
-0, 30420000, 30420000, 0, 37440, 0x392f15cb
+0, 30416666, 30416666, 0, 37440, 0x392f15cb
0, 30840000, 30840000, 0, 37440, 0x95a146bb
-0, 31250000, 31250000, 0, 37440, 0x7c51740a
+0, 31256666, 31256666, 0, 37440, 0x7c51740a
0, 31670000, 31670000, 0, 37440, 0xa3bdd43c
-0, 32090000, 32090000, 0, 37440, 0xa079f965
+0, 32086666, 32086666, 0, 37440, 0xa079f965
0, 32500000, 32500000, 0, 37440, 0xa95423ea
-0, 32920000, 32920000, 0, 37440, 0xd1bd2c67
+0, 32916666, 32916666, 0, 37440, 0xd1bd2c67
0, 33340000, 33340000, 0, 37440, 0x6cf82844
-0, 33750000, 33750000, 0, 37440, 0xd401e128
+0, 33756666, 33756666, 0, 37440, 0xd401e128
0, 34170000, 34170000, 0, 37440, 0x1f7db118
-0, 34590000, 34590000, 0, 37440, 0x2e0a65a9
+0, 34586666, 34586666, 0, 37440, 0x2e0a65a9
0, 35000000, 35000000, 0, 37440, 0x321c1c40
-0, 35420000, 35420000, 0, 37440, 0x95b2a127
+0, 35416666, 35416666, 0, 37440, 0x95b2a127
0, 35840000, 35840000, 0, 37440, 0xa1471f4b
-0, 36250000, 36250000, 0, 37440, 0x29d148c0
+0, 36256666, 36256666, 0, 37440, 0x29d148c0
0, 36670000, 36670000, 0, 37440, 0x24c07107
-0, 37090000, 37090000, 0, 37440, 0x0ead678d
+0, 37086666, 37086666, 0, 37440, 0x0ead678d
0, 37500000, 37500000, 0, 37440, 0xd0ca6495
-0, 37920000, 37920000, 0, 37440, 0x08f935ef
+0, 37916666, 37916666, 0, 37440, 0x08f935ef
0, 38340000, 38340000, 0, 37440, 0xb5ec3c38
-0, 38750000, 38750000, 0, 37440, 0xce371628
+0, 38756666, 38756666, 0, 37440, 0xce371628
0, 39170000, 39170000, 0, 37440, 0x68170812
-0, 39590000, 39590000, 0, 37440, 0xe222699e
+0, 39586666, 39586666, 0, 37440, 0xe222699e
0, 40000000, 40000000, 0, 37440, 0xd688706c
-0, 40420000, 40420000, 0, 37440, 0x81a033f9
+0, 40416666, 40416666, 0, 37440, 0x81a033f9
0, 40840000, 40840000, 0, 37440, 0x28bd0fbf
-0, 41250000, 41250000, 0, 37440, 0xe36db7b2
+0, 41256666, 41256666, 0, 37440, 0xe36db7b2
0, 41670000, 41670000, 0, 37440, 0x30559121
-0, 42090000, 42090000, 0, 37440, 0xbf2b5fc8
+0, 42086666, 42086666, 0, 37440, 0xbf2b5fc8
0, 42500000, 42500000, 0, 37440, 0x4b427672
-0, 42920000, 42920000, 0, 37440, 0x0544b0b4
+0, 42916666, 42916666, 0, 37440, 0x0544b0b4
0, 43340000, 43340000, 0, 37440, 0x38a70b06
-0, 43750000, 43750000, 0, 37440, 0x4ed62607
+0, 43756666, 43756666, 0, 37440, 0x4ed62607
0, 44170000, 44170000, 0, 37440, 0x6efe8ea6
-0, 44590000, 44590000, 0, 37440, 0x81197e11
+0, 44586666, 44586666, 0, 37440, 0x81197e11
0, 45000000, 45000000, 0, 37440, 0xf4060050
-0, 45420000, 45420000, 0, 37440, 0xaf205f13
+0, 45416666, 45416666, 0, 37440, 0xaf205f13
0, 45840000, 45840000, 0, 37440, 0x5fa21382
-0, 46250000, 46250000, 0, 37440, 0x8627ad05
+0, 46256666, 46256666, 0, 37440, 0x8627ad05
0, 46670000, 46670000, 0, 37440, 0xf7130133
-0, 47090000, 47090000, 0, 37440, 0x76dea7ba
+0, 47086666, 47086666, 0, 37440, 0x76dea7ba
0, 47500000, 47500000, 0, 37440, 0x1dbae1be
-0, 47920000, 47920000, 0, 37440, 0x74a933f7
+0, 47916666, 47916666, 0, 37440, 0x74a933f7
0, 48340000, 48340000, 0, 37440, 0xbdcd41a3
-0, 48750000, 48750000, 0, 37440, 0xf0fe8c1c
+0, 48756666, 48756666, 0, 37440, 0xf0fe8c1c
0, 49170000, 49170000, 0, 37440, 0xc0036222
-0, 49590000, 49590000, 0, 37440, 0x3058385c
-0, 49798332, 49798332, 0, 37440, 0x68141016
+0, 49586666, 49586666, 0, 37440, 0x3058385c
+0, 49586667, 49586667, 0, 37440, 0x68141016
diff --git a/tests/ref/fate/ea-vp60 b/tests/ref/fate/vp60
similarity index 100%
rename from tests/ref/fate/ea-vp60
rename to tests/ref/fate/vp60
diff --git a/tests/ref/fate/ea-vp61 b/tests/ref/fate/vp61
similarity index 100%
rename from tests/ref/fate/ea-vp61
rename to tests/ref/fate/vp61
diff --git a/tests/ref/fate/vqa-cc b/tests/ref/fate/vqa-cc
index 97ae71d..d3c5e6a 100644
--- a/tests/ref/fate/vqa-cc
+++ b/tests/ref/fate/vqa-cc
@@ -1,7 +1,5 @@
#tb 0: 1/15
-#tb 1: 1/22050
0, 0, 0, 1, 192000, 0x00000000
-1, 0, 0, 11024, 22048, 0x0665d7f4
0, 1, 1, 1, 192000, 0x00000000
0, 2, 2, 1, 192000, 0x00000000
0, 3, 3, 1, 192000, 0x00000000
@@ -9,72 +7,33 @@
0, 5, 5, 1, 192000, 0xfd496438
0, 6, 6, 1, 192000, 0x965f0bf3
0, 7, 7, 1, 192000, 0x378fca5f
-1, 11024, 11024, 1470, 2940, 0x0f3c64cb
0, 8, 8, 1, 192000, 0x5ccd8966
-1, 12494, 12494, 1470, 2940, 0xc90b9e78
0, 9, 9, 1, 192000, 0x859676f9
-1, 13964, 13964, 1470, 2940, 0x146246a3
0, 10, 10, 1, 192000, 0x820bfb1c
-1, 15434, 15434, 1470, 2940, 0xd22c714e
0, 11, 11, 1, 192000, 0x7570cc05
-1, 16904, 16904, 1470, 2940, 0xd86b681e
0, 12, 12, 1, 192000, 0xf38bdb06
-1, 18374, 18374, 1470, 2940, 0x12ec8186
0, 13, 13, 1, 192000, 0x9b0cbb44
-1, 19844, 19844, 1470, 2940, 0x69aa85b6
0, 14, 14, 1, 192000, 0x0ed70665
-1, 21314, 21314, 1470, 2940, 0xb24d33b0
0, 15, 15, 1, 192000, 0xd16de7fc
-1, 22784, 22784, 1470, 2940, 0x3f7b0f0d
0, 16, 16, 1, 192000, 0x97afb484
-1, 24254, 24254, 1470, 2940, 0x64f10f7e
0, 17, 17, 1, 192000, 0x012893f3
-1, 25724, 25724, 1470, 2940, 0xd6ea379a
0, 18, 18, 1, 192000, 0x742a4b43
-1, 27194, 27194, 1470, 2940, 0x7c38e830
0, 19, 19, 1, 192000, 0x309dcd75
-1, 28664, 28664, 1470, 2940, 0xc28ff132
0, 20, 20, 1, 192000, 0xed7814ac
-1, 30134, 30134, 1470, 2940, 0xe7b11629
0, 21, 21, 1, 192000, 0xdb7de3d7
-1, 31604, 31604, 1470, 2940, 0xeb86fdcb
0, 22, 22, 1, 192000, 0xe18679a3
-1, 33074, 33074, 1470, 2940, 0x5508f586
0, 23, 23, 1, 192000, 0xb1f213f4
-1, 34544, 34544, 1470, 2940, 0xf4fa1f1b
0, 24, 24, 1, 192000, 0x33c99b5c
-1, 36014, 36014, 1470, 2940, 0x9e5ff976
0, 25, 25, 1, 192000, 0xf66c0c91
-1, 37484, 37484, 1470, 2940, 0xcfc4e08f
0, 26, 26, 1, 192000, 0x929cdc73
-1, 38954, 38954, 1470, 2940, 0x74bde7ed
0, 27, 27, 1, 192000, 0xa723fc3b
-1, 40424, 40424, 1470, 2940, 0x3e4ae245
0, 28, 28, 1, 192000, 0xe6395ccc
-1, 41894, 41894, 1470, 2940, 0x4c6a8e56
0, 29, 29, 1, 192000, 0x147fbf74
-1, 43364, 43364, 1470, 2940, 0xa09d86ab
0, 30, 30, 1, 192000, 0x3ec62d28
-1, 44834, 44834, 1470, 2940, 0xc8531912
0, 31, 31, 1, 192000, 0x22104ffb
-1, 46304, 46304, 1470, 2940, 0xa5f266aa
0, 32, 32, 1, 192000, 0x91f25f58
-1, 47774, 47774, 1470, 2940, 0x587a4187
0, 33, 33, 1, 192000, 0xc91b0e4e
-1, 49244, 49244, 1470, 2940, 0x14752d45
0, 34, 34, 1, 192000, 0x4683df56
-1, 50714, 50714, 1470, 2940, 0x558cde10
0, 35, 35, 1, 192000, 0x8ef8932a
-1, 52184, 52184, 1470, 2940, 0x735fee38
0, 36, 36, 1, 192000, 0xce6c0ec0
-1, 53654, 53654, 1470, 2940, 0xac8bb6c8
0, 37, 37, 1, 192000, 0xcc10e2a0
-1, 55124, 55124, 1470, 2940, 0xa503c73b
-1, 56594, 56594, 1470, 2940, 0x7cd588a3
-1, 58064, 58064, 1470, 2940, 0xa6974b04
-1, 59534, 59534, 1470, 2940, 0xbf448241
-1, 61004, 61004, 1470, 2940, 0x2a5c2759
-1, 62474, 62474, 1470, 2940, 0xd0de5ce0
-1, 63944, 63944, 1470, 2940, 0xc0486649
-1, 65414, 65414, 1470, 2940, 0x48b040af
-1, 66884, 66884, 1470, 2940, 0x82a338a9
diff --git a/tests/ref/fate/vsynth1-asv1 b/tests/ref/fate/vsynth1-asv1
new file mode 100644
index 0000000..768729e
--- /dev/null
+++ b/tests/ref/fate/vsynth1-asv1
@@ -0,0 +1,4 @@
+b4ce4698764ef2328346badb7227ecbe *tests/data/fate/vsynth1-asv1.avi
+1489656 tests/data/fate/vsynth1-asv1.avi
+2dfc5dfc2c1cbbc2543257cd3d2df6af *tests/data/fate/vsynth1-asv1.out.rawvideo
+stddev: 20.00 PSNR: 22.11 MAXDIFF: 158 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-asv2 b/tests/ref/fate/vsynth1-asv2
new file mode 100644
index 0000000..38c6cef
--- /dev/null
+++ b/tests/ref/fate/vsynth1-asv2
@@ -0,0 +1,4 @@
+dfba6eaf58e515e324c2b370bfcd9158 *tests/data/fate/vsynth1-asv2.avi
+1456056 tests/data/fate/vsynth1-asv2.avi
+d451be09793cd0f35b6d91fc36e2571a *tests/data/fate/vsynth1-asv2.out.rawvideo
+stddev: 18.82 PSNR: 22.63 MAXDIFF: 131 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-cljr b/tests/ref/fate/vsynth1-cljr
new file mode 100644
index 0000000..41d40c9
--- /dev/null
+++ b/tests/ref/fate/vsynth1-cljr
@@ -0,0 +1,4 @@
+b4d3d31da0b4b6873ad8239d113c91d2 *tests/data/fate/vsynth1-cljr.avi
+5075660 tests/data/fate/vsynth1-cljr.avi
+72e01607bae16527bc6389cf6db00b5f *tests/data/fate/vsynth1-cljr.out.rawvideo
+stddev: 6.95 PSNR: 31.28 MAXDIFF: 86 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-dnxhd-1080i b/tests/ref/fate/vsynth1-dnxhd-1080i
new file mode 100644
index 0000000..1eddbf8
--- /dev/null
+++ b/tests/ref/fate/vsynth1-dnxhd-1080i
@@ -0,0 +1,4 @@
+3cfbe36a7dd5b48859b8a569d626ef77 *tests/data/fate/vsynth1-dnxhd-1080i.mov
+3031875 tests/data/fate/vsynth1-dnxhd-1080i.mov
+0c651e840f860592f0d5b66030d9fa32 *tests/data/fate/vsynth1-dnxhd-1080i.out.rawvideo
+stddev: 6.29 PSNR: 32.15 MAXDIFF: 64 bytes: 7603200/ 760320
diff --git a/tests/ref/fate/vsynth1-dnxhd-720p b/tests/ref/fate/vsynth1-dnxhd-720p
new file mode 100644
index 0000000..94c28ed
--- /dev/null
+++ b/tests/ref/fate/vsynth1-dnxhd-720p
@@ -0,0 +1,4 @@
+81f5be451dc18cf8a1d333c7885de60b *tests/data/fate/vsynth1-dnxhd-720p.dnxhd
+2293760 tests/data/fate/vsynth1-dnxhd-720p.dnxhd
+94b21e5e68ccf9471eff74afd0ebe319 *tests/data/fate/vsynth1-dnxhd-720p.out.rawvideo
+stddev: 6.32 PSNR: 32.11 MAXDIFF: 183 bytes: 7603200/ 760320
diff --git a/tests/ref/fate/vsynth1-dnxhd-720p-10bit b/tests/ref/fate/vsynth1-dnxhd-720p-10bit
new file mode 100644
index 0000000..a667b9d
--- /dev/null
+++ b/tests/ref/fate/vsynth1-dnxhd-720p-10bit
@@ -0,0 +1,4 @@
+b5e24a055af02edec8674333260214fd *tests/data/fate/vsynth1-dnxhd-720p-10bit.dnxhd
+2293760 tests/data/fate/vsynth1-dnxhd-720p-10bit.dnxhd
+4466ff3d73d01bbe75ea25001d379b63 *tests/data/fate/vsynth1-dnxhd-720p-10bit.out.rawvideo
+stddev: 6.27 PSNR: 32.18 MAXDIFF: 64 bytes: 7603200/ 760320
diff --git a/tests/ref/fate/vsynth1-dnxhd-720p-rd b/tests/ref/fate/vsynth1-dnxhd-720p-rd
new file mode 100644
index 0000000..1de576a
--- /dev/null
+++ b/tests/ref/fate/vsynth1-dnxhd-720p-rd
@@ -0,0 +1,4 @@
+1dc6e95925c4f3a230848ec17c02abed *tests/data/fate/vsynth1-dnxhd-720p-rd.dnxhd
+2293760 tests/data/fate/vsynth1-dnxhd-720p-rd.dnxhd
+02972d2aec120ec1577ec9053d68ae0f *tests/data/fate/vsynth1-dnxhd-720p-rd.out.rawvideo
+stddev: 6.26 PSNR: 32.19 MAXDIFF: 65 bytes: 7603200/ 760320
diff --git a/tests/ref/fate/vsynth1-dv b/tests/ref/fate/vsynth1-dv
new file mode 100644
index 0000000..f5a37ad
--- /dev/null
+++ b/tests/ref/fate/vsynth1-dv
@@ -0,0 +1,4 @@
+27ade3031b17214cf81c19cbf70f37d7 *tests/data/fate/vsynth1-dv.dv
+7200000 tests/data/fate/vsynth1-dv.dv
+02ac7cdeab91d4d5621e7ce96dddc498 *tests/data/fate/vsynth1-dv.out.rawvideo
+stddev: 6.90 PSNR: 31.34 MAXDIFF: 76 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-dv-411 b/tests/ref/fate/vsynth1-dv-411
new file mode 100644
index 0000000..a1f07da
--- /dev/null
+++ b/tests/ref/fate/vsynth1-dv-411
@@ -0,0 +1,4 @@
+bd67f2431db160d4bb6dcd791cea6efd *tests/data/fate/vsynth1-dv-411.dv
+7200000 tests/data/fate/vsynth1-dv-411.dv
+53946d51762b7826773e681fb02f377b *tests/data/fate/vsynth1-dv-411.out.rawvideo
+stddev: 9.45 PSNR: 28.62 MAXDIFF: 84 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-dv-50 b/tests/ref/fate/vsynth1-dv-50
new file mode 100644
index 0000000..18ee398
--- /dev/null
+++ b/tests/ref/fate/vsynth1-dv-50
@@ -0,0 +1,4 @@
+26dba84f0ea895b914ef5b333d8394ac *tests/data/fate/vsynth1-dv-50.dv
+14400000 tests/data/fate/vsynth1-dv-50.dv
+a2ff093e93ffed10f730fa21df02fc50 *tests/data/fate/vsynth1-dv-50.out.rawvideo
+stddev: 1.72 PSNR: 43.38 MAXDIFF: 29 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-ffv1 b/tests/ref/fate/vsynth1-ffv1
new file mode 100644
index 0000000..ab1a582
--- /dev/null
+++ b/tests/ref/fate/vsynth1-ffv1
@@ -0,0 +1,4 @@
+67ddc7edde5cca49290245d881787890 *tests/data/fate/vsynth1-ffv1.avi
+2655376 tests/data/fate/vsynth1-ffv1.avi
+c5ccac874dbf808e9088bc3107860042 *tests/data/fate/vsynth1-ffv1.out.rawvideo
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-ffvhuff b/tests/ref/fate/vsynth1-ffvhuff
new file mode 100644
index 0000000..67f4b35
--- /dev/null
+++ b/tests/ref/fate/vsynth1-ffvhuff
@@ -0,0 +1,4 @@
+da0c0bd12ac141c976ffa6a71832ab4b *tests/data/fate/vsynth1-ffvhuff.avi
+5987208 tests/data/fate/vsynth1-ffvhuff.avi
+c5ccac874dbf808e9088bc3107860042 *tests/data/fate/vsynth1-ffvhuff.out.rawvideo
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-flashsv b/tests/ref/fate/vsynth1-flashsv
new file mode 100644
index 0000000..b934d8d
--- /dev/null
+++ b/tests/ref/fate/vsynth1-flashsv
@@ -0,0 +1,4 @@
+97894502b4cb57aca1105b6333f72dae *tests/data/fate/vsynth1-flashsv.flv
+14681925 tests/data/fate/vsynth1-flashsv.flv
+947cb24ec45a453348ae6fe3fa278071 *tests/data/fate/vsynth1-flashsv.out.rawvideo
+stddev: 2.85 PSNR: 39.03 MAXDIFF: 49 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-flv b/tests/ref/fate/vsynth1-flv
new file mode 100644
index 0000000..4b57bdf
--- /dev/null
+++ b/tests/ref/fate/vsynth1-flv
@@ -0,0 +1,4 @@
+d6a80659cedee7698aefe9c4a8285fa4 *tests/data/fate/vsynth1-flv.flv
+636269 tests/data/fate/vsynth1-flv.flv
+5ab46d8dd01dbb1d63df2a84858a4b05 *tests/data/fate/vsynth1-flv.out.rawvideo
+stddev: 8.02 PSNR: 30.04 MAXDIFF: 105 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-h261 b/tests/ref/fate/vsynth1-h261
new file mode 100644
index 0000000..be7f80a
--- /dev/null
+++ b/tests/ref/fate/vsynth1-h261
@@ -0,0 +1,4 @@
+d155470b713aeebacb85980b0d5f2ce3 *tests/data/fate/vsynth1-h261.avi
+707588 tests/data/fate/vsynth1-h261.avi
+716e83cb51afb1246bfaa80967df48ea *tests/data/fate/vsynth1-h261.out.rawvideo
+stddev: 9.11 PSNR: 28.93 MAXDIFF: 113 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-h263 b/tests/ref/fate/vsynth1-h263
new file mode 100644
index 0000000..5d5d28a
--- /dev/null
+++ b/tests/ref/fate/vsynth1-h263
@@ -0,0 +1,4 @@
+fb4dc9b9eac2628c56cb82cf332e1f58 *tests/data/fate/vsynth1-h263.avi
+659686 tests/data/fate/vsynth1-h263.avi
+1a1ba9a3a63ec1a1a9585fded0a7c954 *tests/data/fate/vsynth1-h263.out.rawvideo
+stddev: 8.03 PSNR: 30.03 MAXDIFF: 103 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-h263p b/tests/ref/fate/vsynth1-h263p
new file mode 100644
index 0000000..9161a1d
--- /dev/null
+++ b/tests/ref/fate/vsynth1-h263p
@@ -0,0 +1,4 @@
+bbcadeceba295e1dad148aea1e57c370 *tests/data/fate/vsynth1-h263p.avi
+2328348 tests/data/fate/vsynth1-h263p.avi
+9554cda00c3487ab3ffda2c3ea22fa2f *tests/data/fate/vsynth1-h263p.out.rawvideo
+stddev: 2.06 PSNR: 41.83 MAXDIFF: 20 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-huffyuv b/tests/ref/fate/vsynth1-huffyuv
new file mode 100644
index 0000000..e237af5
--- /dev/null
+++ b/tests/ref/fate/vsynth1-huffyuv
@@ -0,0 +1,4 @@
+ace2536fa169d835d0fb332abde28d51 *tests/data/fate/vsynth1-huffyuv.avi
+7933800 tests/data/fate/vsynth1-huffyuv.avi
+c5ccac874dbf808e9088bc3107860042 *tests/data/fate/vsynth1-huffyuv.out.rawvideo
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-jpegls b/tests/ref/fate/vsynth1-jpegls
new file mode 100644
index 0000000..68ae0b2
--- /dev/null
+++ b/tests/ref/fate/vsynth1-jpegls
@@ -0,0 +1,4 @@
+870dceeb6d3931dd68b34f0c33be5d26 *tests/data/fate/vsynth1-jpegls.avi
+9089812 tests/data/fate/vsynth1-jpegls.avi
+947cb24ec45a453348ae6fe3fa278071 *tests/data/fate/vsynth1-jpegls.out.rawvideo
+stddev: 2.85 PSNR: 39.03 MAXDIFF: 49 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-ljpeg b/tests/ref/fate/vsynth1-ljpeg
new file mode 100644
index 0000000..4f95667
--- /dev/null
+++ b/tests/ref/fate/vsynth1-ljpeg
@@ -0,0 +1,4 @@
+9092f306f165b98ab0bb4f576f198ad5 *tests/data/fate/vsynth1-ljpeg.avi
+6312936 tests/data/fate/vsynth1-ljpeg.avi
+c5ccac874dbf808e9088bc3107860042 *tests/data/fate/vsynth1-ljpeg.out.rawvideo
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-mjpeg b/tests/ref/fate/vsynth1-mjpeg
new file mode 100644
index 0000000..e32f452
--- /dev/null
+++ b/tests/ref/fate/vsynth1-mjpeg
@@ -0,0 +1,4 @@
+8bbf9513b1822945539f27a6eff3c7fa *tests/data/fate/vsynth1-mjpeg.avi
+1516140 tests/data/fate/vsynth1-mjpeg.avi
+c6ae81b5b896e4d05ff584311aebdb18 *tests/data/fate/vsynth1-mjpeg.out.rawvideo
+stddev: 7.87 PSNR: 30.21 MAXDIFF: 63 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-mpeg1 b/tests/ref/fate/vsynth1-mpeg1
new file mode 100644
index 0000000..5f3d703
--- /dev/null
+++ b/tests/ref/fate/vsynth1-mpeg1
@@ -0,0 +1,4 @@
+1428744c6d5835f27506e69be4f837f4 *tests/data/fate/vsynth1-mpeg1.mpeg1video
+712006 tests/data/fate/vsynth1-mpeg1.mpeg1video
+58f0c332bf689117b57fa629a2bc0d2b *tests/data/fate/vsynth1-mpeg1.out.rawvideo
+stddev: 7.62 PSNR: 30.48 MAXDIFF: 84 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-mpeg1b b/tests/ref/fate/vsynth1-mpeg1b
new file mode 100644
index 0000000..ddd9bef
--- /dev/null
+++ b/tests/ref/fate/vsynth1-mpeg1b
@@ -0,0 +1,4 @@
+777639666b449ab0a7ef260511e40532 *tests/data/fate/vsynth1-mpeg1b.mpeg1video
+1030337 tests/data/fate/vsynth1-mpeg1b.mpeg1video
+91a7fce732b34748e7bf753ebabe2483 *tests/data/fate/vsynth1-mpeg1b.out.rawvideo
+stddev: 6.30 PSNR: 32.13 MAXDIFF: 75 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-mpeg2 b/tests/ref/fate/vsynth1-mpeg2
new file mode 100644
index 0000000..1ee3674
--- /dev/null
+++ b/tests/ref/fate/vsynth1-mpeg2
@@ -0,0 +1,4 @@
+fbddea2368cd2028fc8db4dfd4682e94 *tests/data/fate/vsynth1-mpeg2.mpeg2video
+728044 tests/data/fate/vsynth1-mpeg2.mpeg2video
+b41ca49c1a02e66ce64d262e2cdaec15 *tests/data/fate/vsynth1-mpeg2.out.rawvideo
+stddev: 7.65 PSNR: 30.45 MAXDIFF: 84 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-mpeg2-422 b/tests/ref/fate/vsynth1-mpeg2-422
new file mode 100644
index 0000000..5948446
--- /dev/null
+++ b/tests/ref/fate/vsynth1-mpeg2-422
@@ -0,0 +1,4 @@
+af0cb75451aaa807beb5102707a98823 *tests/data/fate/vsynth1-mpeg2-422.mpeg2video
+728200 tests/data/fate/vsynth1-mpeg2-422.mpeg2video
+eb7fe83ce09af2d79ec16577c9d44e3c *tests/data/fate/vsynth1-mpeg2-422.out.rawvideo
+stddev: 10.29 PSNR: 27.88 MAXDIFF: 168 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-mpeg2-idct-int b/tests/ref/fate/vsynth1-mpeg2-idct-int
new file mode 100644
index 0000000..dd72d71
--- /dev/null
+++ b/tests/ref/fate/vsynth1-mpeg2-idct-int
@@ -0,0 +1,4 @@
+4c067397b504d65532d7779cd36f3f88 *tests/data/fate/vsynth1-mpeg2-idct-int.mpeg2video
+725668 tests/data/fate/vsynth1-mpeg2-idct-int.mpeg2video
+8130f71a467315c9e7bd1a25a01dbb23 *tests/data/fate/vsynth1-mpeg2-idct-int.out.rawvideo
+stddev: 7.65 PSNR: 30.45 MAXDIFF: 80 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-mpeg2-ilace b/tests/ref/fate/vsynth1-mpeg2-ilace
new file mode 100644
index 0000000..be08c31
--- /dev/null
+++ b/tests/ref/fate/vsynth1-mpeg2-ilace
@@ -0,0 +1,4 @@
+ec3f6713c88a2b41f6c369fd64341077 *tests/data/fate/vsynth1-mpeg2-ilace.mpeg2video
+737473 tests/data/fate/vsynth1-mpeg2-ilace.mpeg2video
+97615390fdd69abfcbc7e02df863a7d2 *tests/data/fate/vsynth1-mpeg2-ilace.out.rawvideo
+stddev: 7.67 PSNR: 30.43 MAXDIFF: 84 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-mpeg2-ivlc-qprd b/tests/ref/fate/vsynth1-mpeg2-ivlc-qprd
new file mode 100644
index 0000000..5ef30cd
--- /dev/null
+++ b/tests/ref/fate/vsynth1-mpeg2-ivlc-qprd
@@ -0,0 +1,4 @@
+8f6b20714918e6443e0c03716ed06f0d *tests/data/fate/vsynth1-mpeg2-ivlc-qprd.mpeg2video
+783552 tests/data/fate/vsynth1-mpeg2-ivlc-qprd.mpeg2video
+98eb9da15f880978e7f2ee1e7ce476ef *tests/data/fate/vsynth1-mpeg2-ivlc-qprd.out.rawvideo
+stddev: 10.07 PSNR: 28.06 MAXDIFF: 165 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-mpeg2-thread b/tests/ref/fate/vsynth1-mpeg2-thread
new file mode 100644
index 0000000..55a4fab
--- /dev/null
+++ b/tests/ref/fate/vsynth1-mpeg2-thread
@@ -0,0 +1,4 @@
+ecd183706688bd977c9994c3d1b23d61 *tests/data/fate/vsynth1-mpeg2-thread.mpeg2video
+801313 tests/data/fate/vsynth1-mpeg2-thread.mpeg2video
+d1658911ca83f5616c1d32abc40750de *tests/data/fate/vsynth1-mpeg2-thread.out.rawvideo
+stddev: 7.63 PSNR: 30.48 MAXDIFF: 110 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-mpeg2-thread-ivlc b/tests/ref/fate/vsynth1-mpeg2-thread-ivlc
new file mode 100644
index 0000000..7d04052
--- /dev/null
+++ b/tests/ref/fate/vsynth1-mpeg2-thread-ivlc
@@ -0,0 +1,4 @@
+23d600b026222253c2340e23300a4c02 *tests/data/fate/vsynth1-mpeg2-thread-ivlc.mpeg2video
+791773 tests/data/fate/vsynth1-mpeg2-thread-ivlc.mpeg2video
+d1658911ca83f5616c1d32abc40750de *tests/data/fate/vsynth1-mpeg2-thread-ivlc.out.rawvideo
+stddev: 7.63 PSNR: 30.48 MAXDIFF: 110 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-mpeg4 b/tests/ref/fate/vsynth1-mpeg4
new file mode 100644
index 0000000..9a917d0
--- /dev/null
+++ b/tests/ref/fate/vsynth1-mpeg4
@@ -0,0 +1,4 @@
+59a9e2eed314abface66aaf1b45eb8f2 *tests/data/fate/vsynth1-mpeg4.mp4
+540180 tests/data/fate/vsynth1-mpeg4.mp4
+8828a375448dc5c2215163ba70656f89 *tests/data/fate/vsynth1-mpeg4.out.rawvideo
+stddev: 7.97 PSNR: 30.10 MAXDIFF: 105 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-mpeg4-adap b/tests/ref/fate/vsynth1-mpeg4-adap
new file mode 100644
index 0000000..12cd15e
--- /dev/null
+++ b/tests/ref/fate/vsynth1-mpeg4-adap
@@ -0,0 +1,4 @@
+2d870c0da9ab2231ab5fc06981e70399 *tests/data/fate/vsynth1-mpeg4-adap.avi
+403456 tests/data/fate/vsynth1-mpeg4-adap.avi
+fa2049396479b5f170aa764fed5b2a31 *tests/data/fate/vsynth1-mpeg4-adap.out.rawvideo
+stddev: 14.05 PSNR: 25.17 MAXDIFF: 184 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-mpeg4-adv b/tests/ref/fate/vsynth1-mpeg4-adv
new file mode 100644
index 0000000..e223d5f
--- /dev/null
+++ b/tests/ref/fate/vsynth1-mpeg4-adv
@@ -0,0 +1,4 @@
+7d8eb01fd68d83d62a98585757704d47 *tests/data/fate/vsynth1-mpeg4-adv.avi
+589716 tests/data/fate/vsynth1-mpeg4-adv.avi
+f8b226876b1b2c0b98fd6928fd9adbd8 *tests/data/fate/vsynth1-mpeg4-adv.out.rawvideo
+stddev: 6.98 PSNR: 31.25 MAXDIFF: 84 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-mpeg4-error b/tests/ref/fate/vsynth1-mpeg4-error
new file mode 100644
index 0000000..74d5aaa
--- /dev/null
+++ b/tests/ref/fate/vsynth1-mpeg4-error
@@ -0,0 +1,4 @@
+7416dfd319f04044d4575dc9d1b406e1 *tests/data/fate/vsynth1-mpeg4-error.avi
+756836 tests/data/fate/vsynth1-mpeg4-error.avi
+79e94ba32b37759397362cbcb479d4d3 *tests/data/fate/vsynth1-mpeg4-error.out.rawvideo
+stddev: 18.36 PSNR: 22.85 MAXDIFF: 243 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-mpeg4-nr b/tests/ref/fate/vsynth1-mpeg4-nr
new file mode 100644
index 0000000..a83f4fd
--- /dev/null
+++ b/tests/ref/fate/vsynth1-mpeg4-nr
@@ -0,0 +1,4 @@
+c02f54157ba08ca12ad979c6308212ad *tests/data/fate/vsynth1-mpeg4-nr.avi
+675638 tests/data/fate/vsynth1-mpeg4-nr.avi
+d2b89d5958fb7331f6c9e5b7ecaaa5b6 *tests/data/fate/vsynth1-mpeg4-nr.out.rawvideo
+stddev: 6.99 PSNR: 31.23 MAXDIFF: 86 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-mpeg4-qpel b/tests/ref/fate/vsynth1-mpeg4-qpel
new file mode 100644
index 0000000..254c3ee
--- /dev/null
+++ b/tests/ref/fate/vsynth1-mpeg4-qpel
@@ -0,0 +1,4 @@
+3bf17c3d04f52988386ce106a2a58976 *tests/data/fate/vsynth1-mpeg4-qpel.avi
+860678 tests/data/fate/vsynth1-mpeg4-qpel.avi
+756928496245ecc701f79eebeec8e5e6 *tests/data/fate/vsynth1-mpeg4-qpel.out.rawvideo
+stddev: 5.63 PSNR: 33.12 MAXDIFF: 70 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-mpeg4-qprd b/tests/ref/fate/vsynth1-mpeg4-qprd
new file mode 100644
index 0000000..1a61654
--- /dev/null
+++ b/tests/ref/fate/vsynth1-mpeg4-qprd
@@ -0,0 +1,4 @@
+d6b7e724a6ad66ab5e4c5a499218b40d *tests/data/fate/vsynth1-mpeg4-qprd.avi
+710944 tests/data/fate/vsynth1-mpeg4-qprd.avi
+e65f4c7f343fe2bad1cac44b7da5f7c4 *tests/data/fate/vsynth1-mpeg4-qprd.out.rawvideo
+stddev: 9.79 PSNR: 28.31 MAXDIFF: 176 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-mpeg4-rc b/tests/ref/fate/vsynth1-mpeg4-rc
new file mode 100644
index 0000000..180df10
--- /dev/null
+++ b/tests/ref/fate/vsynth1-mpeg4-rc
@@ -0,0 +1,4 @@
+1c6dadf75f60f4ba59a0fe0b6eaedf57 *tests/data/fate/vsynth1-mpeg4-rc.avi
+830160 tests/data/fate/vsynth1-mpeg4-rc.avi
+4d95e340db9bc57a559162c039f3784e *tests/data/fate/vsynth1-mpeg4-rc.out.rawvideo
+stddev: 10.24 PSNR: 27.92 MAXDIFF: 196 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-mpeg4-thread b/tests/ref/fate/vsynth1-mpeg4-thread
new file mode 100644
index 0000000..66a5508
--- /dev/null
+++ b/tests/ref/fate/vsynth1-mpeg4-thread
@@ -0,0 +1,4 @@
+4f4ea04faad7212374919aa1ec7ff994 *tests/data/fate/vsynth1-mpeg4-thread.avi
+774760 tests/data/fate/vsynth1-mpeg4-thread.avi
+64b96cddf5301990e118978b3a3bcd0d *tests/data/fate/vsynth1-mpeg4-thread.out.rawvideo
+stddev: 10.13 PSNR: 28.02 MAXDIFF: 183 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-msmpeg4 b/tests/ref/fate/vsynth1-msmpeg4
new file mode 100644
index 0000000..55fb06d
--- /dev/null
+++ b/tests/ref/fate/vsynth1-msmpeg4
@@ -0,0 +1,4 @@
+4b08952b0afceb17ee3db31b67f6b778 *tests/data/fate/vsynth1-msmpeg4.avi
+624718 tests/data/fate/vsynth1-msmpeg4.avi
+5ca72c39e3fc5df8e62f223c869589f5 *tests/data/fate/vsynth1-msmpeg4.out.rawvideo
+stddev: 7.98 PSNR: 30.09 MAXDIFF: 104 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-msmpeg4v2 b/tests/ref/fate/vsynth1-msmpeg4v2
new file mode 100644
index 0000000..839078a
--- /dev/null
+++ b/tests/ref/fate/vsynth1-msmpeg4v2
@@ -0,0 +1,4 @@
+88957e35efcc718bce0307627ad3298d *tests/data/fate/vsynth1-msmpeg4v2.avi
+623788 tests/data/fate/vsynth1-msmpeg4v2.avi
+c6ff1041a0ef62c2a2e5ef519e5e94c4 *tests/data/fate/vsynth1-msmpeg4v2.out.rawvideo
+stddev: 7.97 PSNR: 30.10 MAXDIFF: 105 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-prores b/tests/ref/fate/vsynth1-prores
new file mode 100644
index 0000000..ac30a6a
--- /dev/null
+++ b/tests/ref/fate/vsynth1-prores
@@ -0,0 +1,4 @@
+2566517b15c62887bd94daaab1b1a85b *tests/data/fate/vsynth1-prores.mov
+3859037 tests/data/fate/vsynth1-prores.mov
+0a4153637d0cc0a88a8bcbf04cfaf8c6 *tests/data/fate/vsynth1-prores.out.rawvideo
+stddev: 3.17 PSNR: 38.09 MAXDIFF: 39 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-qtrle b/tests/ref/fate/vsynth1-qtrle
new file mode 100644
index 0000000..c9c8ccf
--- /dev/null
+++ b/tests/ref/fate/vsynth1-qtrle
@@ -0,0 +1,4 @@
+7d75328a17e04796a39fe9be3a322946 *tests/data/fate/vsynth1-qtrle.mov
+15263232 tests/data/fate/vsynth1-qtrle.mov
+243325fb2cae1a9245efd49aff936327 *tests/data/fate/vsynth1-qtrle.out.rawvideo
+stddev: 3.42 PSNR: 37.43 MAXDIFF: 48 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-rgb b/tests/ref/fate/vsynth1-rgb
new file mode 100644
index 0000000..e9a5b19
--- /dev/null
+++ b/tests/ref/fate/vsynth1-rgb
@@ -0,0 +1,4 @@
+05f0719cb52486d9a4beb9cfae3f2571 *tests/data/fate/vsynth1-rgb.avi
+15213260 tests/data/fate/vsynth1-rgb.avi
+243325fb2cae1a9245efd49aff936327 *tests/data/fate/vsynth1-rgb.out.rawvideo
+stddev: 3.42 PSNR: 37.43 MAXDIFF: 48 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-roqvideo b/tests/ref/fate/vsynth1-roqvideo
new file mode 100644
index 0000000..5adba69
--- /dev/null
+++ b/tests/ref/fate/vsynth1-roqvideo
@@ -0,0 +1,4 @@
+cf8b7b0e539bab3169c234ca63d71dd8 *tests/data/fate/vsynth1-roqvideo.roq
+101671 tests/data/fate/vsynth1-roqvideo.roq
+0ad983c291b1ed373645c5b12a108c61 *tests/data/fate/vsynth1-roqvideo.out.rawvideo
+stddev: 7.74 PSNR: 30.35 MAXDIFF: 89 bytes: 7603200/ 760320
diff --git a/tests/ref/fate/vsynth1-rv10 b/tests/ref/fate/vsynth1-rv10
new file mode 100644
index 0000000..234015f
--- /dev/null
+++ b/tests/ref/fate/vsynth1-rv10
@@ -0,0 +1,4 @@
+4d7e82de72a83905cf84b8abc3e70b8f *tests/data/fate/vsynth1-rv10.rm
+653905 tests/data/fate/vsynth1-rv10.rm
+1a1ba9a3a63ec1a1a9585fded0a7c954 *tests/data/fate/vsynth1-rv10.out.rawvideo
+stddev: 8.03 PSNR: 30.03 MAXDIFF: 103 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-rv20 b/tests/ref/fate/vsynth1-rv20
new file mode 100644
index 0000000..abcc4a1
--- /dev/null
+++ b/tests/ref/fate/vsynth1-rv20
@@ -0,0 +1,4 @@
+81868601e602eee5b6d80f5ece4aaa98 *tests/data/fate/vsynth1-rv20.rm
+646016 tests/data/fate/vsynth1-rv20.rm
+b45fdb0201b06f7649f44050e262c54c *tests/data/fate/vsynth1-rv20.out.rawvideo
+stddev: 8.26 PSNR: 29.79 MAXDIFF: 103 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-snow b/tests/ref/fate/vsynth1-snow
new file mode 100644
index 0000000..0b47513
--- /dev/null
+++ b/tests/ref/fate/vsynth1-snow
@@ -0,0 +1,4 @@
+d593b3c1a9729ce6dd1721f58fa93712 *tests/data/fate/vsynth1-snow.avi
+136088 tests/data/fate/vsynth1-snow.avi
+91021b7d6d7908648fe78cc1975af8c4 *tests/data/fate/vsynth1-snow.out.rawvideo
+stddev: 22.77 PSNR: 20.98 MAXDIFF: 172 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-snow-hpel b/tests/ref/fate/vsynth1-snow-hpel
new file mode 100644
index 0000000..e2968b1
--- /dev/null
+++ b/tests/ref/fate/vsynth1-snow-hpel
@@ -0,0 +1,4 @@
+301755ff5dcd31c2aefc8f103cfc2917 *tests/data/fate/vsynth1-snow-hpel.avi
+138712 tests/data/fate/vsynth1-snow-hpel.avi
+d6845c8f1310e041afdcebc6bbfc449b *tests/data/fate/vsynth1-snow-hpel.out.rawvideo
+stddev: 22.74 PSNR: 20.99 MAXDIFF: 171 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-snow-ll b/tests/ref/fate/vsynth1-snow-ll
new file mode 100644
index 0000000..fdc5046
--- /dev/null
+++ b/tests/ref/fate/vsynth1-snow-ll
@@ -0,0 +1,4 @@
+6d29e8c06a645cdee45073c4f3d0004e *tests/data/fate/vsynth1-snow-ll.avi
+3419980 tests/data/fate/vsynth1-snow-ll.avi
+c5ccac874dbf808e9088bc3107860042 *tests/data/fate/vsynth1-snow-ll.out.rawvideo
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-svq1 b/tests/ref/fate/vsynth1-svq1
new file mode 100644
index 0000000..0f8a6b2
--- /dev/null
+++ b/tests/ref/fate/vsynth1-svq1
@@ -0,0 +1,4 @@
+5c9d8734693f3cab57f61e76b5b6da7d *tests/data/fate/vsynth1-svq1.mov
+1334367 tests/data/fate/vsynth1-svq1.mov
+9cc35c54b2c77d36bd7e308b393c1f81 *tests/data/fate/vsynth1-svq1.out.rawvideo
+stddev: 9.58 PSNR: 28.50 MAXDIFF: 210 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-v210 b/tests/ref/fate/vsynth1-v210
new file mode 100644
index 0000000..5248676
--- /dev/null
+++ b/tests/ref/fate/vsynth1-v210
@@ -0,0 +1,4 @@
+dd6c870a2a52c9e75ce61c3670e710e7 *tests/data/fate/vsynth1-v210.avi
+14752460 tests/data/fate/vsynth1-v210.avi
+50973792d3f1abe04a51ee0121f077f2 *tests/data/fate/vsynth1-v210.out.rawvideo
+stddev: 1.85 PSNR: 42.78 MAXDIFF: 29 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-wmv1 b/tests/ref/fate/vsynth1-wmv1
new file mode 100644
index 0000000..d487e4e
--- /dev/null
+++ b/tests/ref/fate/vsynth1-wmv1
@@ -0,0 +1,4 @@
+4f3461315776e5118866fa3819cff9b6 *tests/data/fate/vsynth1-wmv1.avi
+626908 tests/data/fate/vsynth1-wmv1.avi
+5182edba5b5e0354b39ce4f3604b62da *tests/data/fate/vsynth1-wmv1.out.rawvideo
+stddev: 7.97 PSNR: 30.09 MAXDIFF: 110 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-wmv2 b/tests/ref/fate/vsynth1-wmv2
new file mode 100644
index 0000000..14304dd
--- /dev/null
+++ b/tests/ref/fate/vsynth1-wmv2
@@ -0,0 +1,4 @@
+13efda9d3811345aadc0632fc9a9332b *tests/data/fate/vsynth1-wmv2.avi
+659852 tests/data/fate/vsynth1-wmv2.avi
+5182edba5b5e0354b39ce4f3604b62da *tests/data/fate/vsynth1-wmv2.out.rawvideo
+stddev: 7.97 PSNR: 30.09 MAXDIFF: 110 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth1-yuv b/tests/ref/fate/vsynth1-yuv
new file mode 100644
index 0000000..927a64a
--- /dev/null
+++ b/tests/ref/fate/vsynth1-yuv
@@ -0,0 +1,4 @@
+aa6b9e862aebcf8902a6d770e7729d59 *tests/data/fate/vsynth1-yuv.avi
+7610060 tests/data/fate/vsynth1-yuv.avi
+c5ccac874dbf808e9088bc3107860042 *tests/data/fate/vsynth1-yuv.out.rawvideo
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-asv1 b/tests/ref/fate/vsynth2-asv1
new file mode 100644
index 0000000..702244e
--- /dev/null
+++ b/tests/ref/fate/vsynth2-asv1
@@ -0,0 +1,4 @@
+4eb34d2de25f67a2706456e999338fe9 *tests/data/fate/vsynth2-asv1.avi
+832512 tests/data/fate/vsynth2-asv1.avi
+c96ff7fd17c52f99ddb7922a4cb9168f *tests/data/fate/vsynth2-asv1.out.rawvideo
+stddev: 10.47 PSNR: 27.73 MAXDIFF: 98 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-asv2 b/tests/ref/fate/vsynth2-asv2
new file mode 100644
index 0000000..8f6f617
--- /dev/null
+++ b/tests/ref/fate/vsynth2-asv2
@@ -0,0 +1,4 @@
+9649a4b68fb1107bad13e8a7574cc72d *tests/data/fate/vsynth2-asv2.avi
+789072 tests/data/fate/vsynth2-asv2.avi
+74a78015b64b2cf8cb9da2e44f508a69 *tests/data/fate/vsynth2-asv2.out.rawvideo
+stddev: 10.28 PSNR: 27.89 MAXDIFF: 95 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-cljr b/tests/ref/fate/vsynth2-cljr
new file mode 100644
index 0000000..91ce30c
--- /dev/null
+++ b/tests/ref/fate/vsynth2-cljr
@@ -0,0 +1,4 @@
+416ddcf73d2d993456f3c49f3eed4f1a *tests/data/fate/vsynth2-cljr.avi
+5075660 tests/data/fate/vsynth2-cljr.avi
+cfe7802bf34aafed7df5dcaa5126ef23 *tests/data/fate/vsynth2-cljr.out.rawvideo
+stddev: 3.69 PSNR: 36.78 MAXDIFF: 22 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-dnxhd-1080i b/tests/ref/fate/vsynth2-dnxhd-1080i
new file mode 100644
index 0000000..41a8d51
--- /dev/null
+++ b/tests/ref/fate/vsynth2-dnxhd-1080i
@@ -0,0 +1,4 @@
+19a91b7da35cecf41e5e3cb322485627 *tests/data/fate/vsynth2-dnxhd-1080i.mov
+3031875 tests/data/fate/vsynth2-dnxhd-1080i.mov
+3c559af629ae0a8fb1a9a0e4b4da7733 *tests/data/fate/vsynth2-dnxhd-1080i.out.rawvideo
+stddev: 1.31 PSNR: 45.77 MAXDIFF: 23 bytes: 7603200/ 760320
diff --git a/tests/ref/fate/vsynth2-dnxhd-720p b/tests/ref/fate/vsynth2-dnxhd-720p
new file mode 100644
index 0000000..afc6fde
--- /dev/null
+++ b/tests/ref/fate/vsynth2-dnxhd-720p
@@ -0,0 +1,4 @@
+58e07cc6ae0a2d36787044d0e82708a6 *tests/data/fate/vsynth2-dnxhd-720p.dnxhd
+2293760 tests/data/fate/vsynth2-dnxhd-720p.dnxhd
+ab601eaafef74d80d3d20b780dddd836 *tests/data/fate/vsynth2-dnxhd-720p.out.rawvideo
+stddev: 1.36 PSNR: 45.45 MAXDIFF: 127 bytes: 7603200/ 760320
diff --git a/tests/ref/fate/vsynth2-dnxhd-720p-10bit b/tests/ref/fate/vsynth2-dnxhd-720p-10bit
new file mode 100644
index 0000000..f087c13
--- /dev/null
+++ b/tests/ref/fate/vsynth2-dnxhd-720p-10bit
@@ -0,0 +1,4 @@
+4b57da2c0c1280469ff3579f7151c227 *tests/data/fate/vsynth2-dnxhd-720p-10bit.dnxhd
+2293760 tests/data/fate/vsynth2-dnxhd-720p-10bit.dnxhd
+31a6aa8b8702e85fa3b48e73f035c4e4 *tests/data/fate/vsynth2-dnxhd-720p-10bit.out.rawvideo
+stddev: 1.35 PSNR: 45.46 MAXDIFF: 23 bytes: 7603200/ 760320
diff --git a/tests/ref/fate/vsynth2-dnxhd-720p-rd b/tests/ref/fate/vsynth2-dnxhd-720p-rd
new file mode 100644
index 0000000..c1b8f96
--- /dev/null
+++ b/tests/ref/fate/vsynth2-dnxhd-720p-rd
@@ -0,0 +1,4 @@
+092ffb7b8cf3c11556bb05dbb8b476ac *tests/data/fate/vsynth2-dnxhd-720p-rd.dnxhd
+2293760 tests/data/fate/vsynth2-dnxhd-720p-rd.dnxhd
+33547ca318acff9448cba719cb99296d *tests/data/fate/vsynth2-dnxhd-720p-rd.out.rawvideo
+stddev: 1.32 PSNR: 45.66 MAXDIFF: 22 bytes: 7603200/ 760320
diff --git a/tests/ref/fate/vsynth2-dv b/tests/ref/fate/vsynth2-dv
new file mode 100644
index 0000000..2aac5ff
--- /dev/null
+++ b/tests/ref/fate/vsynth2-dv
@@ -0,0 +1,4 @@
+bfa766f89bfeabc0ae1044f3954bed52 *tests/data/fate/vsynth2-dv.dv
+7200000 tests/data/fate/vsynth2-dv.dv
+7ec62bd3350a6848364669e6e1e4b9cc *tests/data/fate/vsynth2-dv.out.rawvideo
+stddev: 1.71 PSNR: 43.47 MAXDIFF: 33 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-dv-411 b/tests/ref/fate/vsynth2-dv-411
new file mode 100644
index 0000000..00ecace
--- /dev/null
+++ b/tests/ref/fate/vsynth2-dv-411
@@ -0,0 +1,4 @@
+00a9d8683ac6826af41bcf7223fb0389 *tests/data/fate/vsynth2-dv-411.dv
+7200000 tests/data/fate/vsynth2-dv-411.dv
+3cd4b85065d67bfb7fbab3bea4039711 *tests/data/fate/vsynth2-dv-411.out.rawvideo
+stddev: 2.89 PSNR: 38.91 MAXDIFF: 45 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-dv-50 b/tests/ref/fate/vsynth2-dv-50
new file mode 100644
index 0000000..e7e5dc1
--- /dev/null
+++ b/tests/ref/fate/vsynth2-dv-50
@@ -0,0 +1,4 @@
+61e31c79e8949b25c849753a0785b0d7 *tests/data/fate/vsynth2-dv-50.dv
+14400000 tests/data/fate/vsynth2-dv-50.dv
+af3f2dd5ab62c1a1d98b07d4aeb6852f *tests/data/fate/vsynth2-dv-50.out.rawvideo
+stddev: 0.82 PSNR: 49.82 MAXDIFF: 12 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-ffv1 b/tests/ref/fate/vsynth2-ffv1
new file mode 100644
index 0000000..0a6b184
--- /dev/null
+++ b/tests/ref/fate/vsynth2-ffv1
@@ -0,0 +1,4 @@
+d72b0960e162d4998b9acbabb07e99ab *tests/data/fate/vsynth2-ffv1.avi
+3525804 tests/data/fate/vsynth2-ffv1.avi
+dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-ffv1.out.rawvideo
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-ffvhuff b/tests/ref/fate/vsynth2-ffvhuff
new file mode 100644
index 0000000..1b279aa
--- /dev/null
+++ b/tests/ref/fate/vsynth2-ffvhuff
@@ -0,0 +1,4 @@
+d31aab445b24f738df45fdd7479d6dd7 *tests/data/fate/vsynth2-ffvhuff.avi
+4988056 tests/data/fate/vsynth2-ffvhuff.avi
+dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-ffvhuff.out.rawvideo
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-flashsv b/tests/ref/fate/vsynth2-flashsv
new file mode 100644
index 0000000..cbe79e6
--- /dev/null
+++ b/tests/ref/fate/vsynth2-flashsv
@@ -0,0 +1,4 @@
+0667077971e0cb63b5f49c580006e90e *tests/data/fate/vsynth2-flashsv.flv
+12368953 tests/data/fate/vsynth2-flashsv.flv
+592b3321994e26a990deb3a0a1415de9 *tests/data/fate/vsynth2-flashsv.out.rawvideo
+stddev: 0.65 PSNR: 51.84 MAXDIFF: 14 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-flv b/tests/ref/fate/vsynth2-flv
new file mode 100644
index 0000000..6864a1b
--- /dev/null
+++ b/tests/ref/fate/vsynth2-flv
@@ -0,0 +1,4 @@
+2edc92093d36506bcc0a5c0e17e86113 *tests/data/fate/vsynth2-flv.flv
+131360 tests/data/fate/vsynth2-flv.flv
+8999c8264fb0941561f64c4a736e9d88 *tests/data/fate/vsynth2-flv.out.rawvideo
+stddev: 5.33 PSNR: 33.59 MAXDIFF: 80 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-h261 b/tests/ref/fate/vsynth2-h261
new file mode 100644
index 0000000..908e670
--- /dev/null
+++ b/tests/ref/fate/vsynth2-h261
@@ -0,0 +1,4 @@
+dfd005d4c9030a0dc889c828a6408b9c *tests/data/fate/vsynth2-h261.avi
+191086 tests/data/fate/vsynth2-h261.avi
+db7ceff174823b98834faa2320ca89ac *tests/data/fate/vsynth2-h261.out.rawvideo
+stddev: 6.37 PSNR: 32.03 MAXDIFF: 77 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-h263 b/tests/ref/fate/vsynth2-h263
new file mode 100644
index 0000000..46169d7
--- /dev/null
+++ b/tests/ref/fate/vsynth2-h263
@@ -0,0 +1,4 @@
+9a368687ab34c48079f11a202839a6bc *tests/data/fate/vsynth2-h263.avi
+160106 tests/data/fate/vsynth2-h263.avi
+61213b91b359697ebcefb9e0a53ac54a *tests/data/fate/vsynth2-h263.out.rawvideo
+stddev: 5.43 PSNR: 33.42 MAXDIFF: 77 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-h263p b/tests/ref/fate/vsynth2-h263p
new file mode 100644
index 0000000..6e45957
--- /dev/null
+++ b/tests/ref/fate/vsynth2-h263p
@@ -0,0 +1,4 @@
+c7644d40e9f40bbd98e5a978f9f94bb4 *tests/data/fate/vsynth2-h263p.avi
+868018 tests/data/fate/vsynth2-h263p.avi
+4b0ee791f280029dc03c528f76f195d4 *tests/data/fate/vsynth2-h263p.out.rawvideo
+stddev: 1.91 PSNR: 42.50 MAXDIFF: 19 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-huffyuv b/tests/ref/fate/vsynth2-huffyuv
new file mode 100644
index 0000000..a1c3c22
--- /dev/null
+++ b/tests/ref/fate/vsynth2-huffyuv
@@ -0,0 +1,4 @@
+56cd44907a48990e06bd065e189ff461 *tests/data/fate/vsynth2-huffyuv.avi
+6455232 tests/data/fate/vsynth2-huffyuv.avi
+dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-huffyuv.out.rawvideo
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-jpegls b/tests/ref/fate/vsynth2-jpegls
new file mode 100644
index 0000000..7f17391
--- /dev/null
+++ b/tests/ref/fate/vsynth2-jpegls
@@ -0,0 +1,4 @@
+8a94dc94b6df8bdde9a639246351d816 *tests/data/fate/vsynth2-jpegls.avi
+8334630 tests/data/fate/vsynth2-jpegls.avi
+592b3321994e26a990deb3a0a1415de9 *tests/data/fate/vsynth2-jpegls.out.rawvideo
+stddev: 0.65 PSNR: 51.84 MAXDIFF: 14 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-ljpeg b/tests/ref/fate/vsynth2-ljpeg
new file mode 100644
index 0000000..529b790
--- /dev/null
+++ b/tests/ref/fate/vsynth2-ljpeg
@@ -0,0 +1,4 @@
+554a4a6a5a9058c588f8bf2de405bc70 *tests/data/fate/vsynth2-ljpeg.avi
+4766914 tests/data/fate/vsynth2-ljpeg.avi
+dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-ljpeg.out.rawvideo
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-mjpeg b/tests/ref/fate/vsynth2-mjpeg
new file mode 100644
index 0000000..e7649ff
--- /dev/null
+++ b/tests/ref/fate/vsynth2-mjpeg
@@ -0,0 +1,4 @@
+89df32b46c977fb4cb140ec6c489dd76 *tests/data/fate/vsynth2-mjpeg.avi
+673224 tests/data/fate/vsynth2-mjpeg.avi
+a96a4e15ffcb13e44360df642d049496 *tests/data/fate/vsynth2-mjpeg.out.rawvideo
+stddev: 4.32 PSNR: 35.40 MAXDIFF: 49 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-mpeg1 b/tests/ref/fate/vsynth2-mpeg1
new file mode 100644
index 0000000..a975973
--- /dev/null
+++ b/tests/ref/fate/vsynth2-mpeg1
@@ -0,0 +1,4 @@
+73ca6f1deab02d1d67a0e8495c026a9e *tests/data/fate/vsynth2-mpeg1.mpeg1video
+192783 tests/data/fate/vsynth2-mpeg1.mpeg1video
+56147e94b12f08df7213e610e177823d *tests/data/fate/vsynth2-mpeg1.out.rawvideo
+stddev: 4.95 PSNR: 34.22 MAXDIFF: 57 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-mpeg1b b/tests/ref/fate/vsynth2-mpeg1b
new file mode 100644
index 0000000..4b92ac5
--- /dev/null
+++ b/tests/ref/fate/vsynth2-mpeg1b
@@ -0,0 +1,4 @@
+e026a2fef80c9679776d2b5c8be09338 *tests/data/fate/vsynth2-mpeg1b.mpeg1video
+225198 tests/data/fate/vsynth2-mpeg1b.mpeg1video
+1150495f4bd487486ee53326c42d0bb8 *tests/data/fate/vsynth2-mpeg1b.out.rawvideo
+stddev: 4.10 PSNR: 35.86 MAXDIFF: 59 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-mpeg2 b/tests/ref/fate/vsynth2-mpeg2
new file mode 100644
index 0000000..a2a2ca6
--- /dev/null
+++ b/tests/ref/fate/vsynth2-mpeg2
@@ -0,0 +1,4 @@
+2d55ce623a7be4e8136f80266e487678 *tests/data/fate/vsynth2-mpeg2.mpeg2video
+198667 tests/data/fate/vsynth2-mpeg2.mpeg2video
+b7cae8a1f751b821cddcbe4d5dbc518c *tests/data/fate/vsynth2-mpeg2.out.rawvideo
+stddev: 4.96 PSNR: 34.20 MAXDIFF: 59 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-mpeg2-422 b/tests/ref/fate/vsynth2-mpeg2-422
new file mode 100644
index 0000000..2405cf0
--- /dev/null
+++ b/tests/ref/fate/vsynth2-mpeg2-422
@@ -0,0 +1,4 @@
+2c8e33c2d2efab86fc16a195f6877682 *tests/data/fate/vsynth2-mpeg2-422.mpeg2video
+356124 tests/data/fate/vsynth2-mpeg2-422.mpeg2video
+df6e54e2d8a4feb8382029286857ca6d *tests/data/fate/vsynth2-mpeg2-422.out.rawvideo
+stddev: 3.16 PSNR: 38.13 MAXDIFF: 49 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-mpeg2-idct-int b/tests/ref/fate/vsynth2-mpeg2-idct-int
new file mode 100644
index 0000000..83874b1
--- /dev/null
+++ b/tests/ref/fate/vsynth2-mpeg2-idct-int
@@ -0,0 +1,4 @@
+f979bcca866e6e4cad5dc6cb06e56cfb *tests/data/fate/vsynth2-mpeg2-idct-int.mpeg2video
+198041 tests/data/fate/vsynth2-mpeg2-idct-int.mpeg2video
+92794e70e4a19a494f10efe353d9895d *tests/data/fate/vsynth2-mpeg2-idct-int.out.rawvideo
+stddev: 4.97 PSNR: 34.19 MAXDIFF: 58 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-mpeg2-ilace b/tests/ref/fate/vsynth2-mpeg2-ilace
new file mode 100644
index 0000000..e488bc5
--- /dev/null
+++ b/tests/ref/fate/vsynth2-mpeg2-ilace
@@ -0,0 +1,4 @@
+f90197a8b6e62ae25f82625337f27240 *tests/data/fate/vsynth2-mpeg2-ilace.mpeg2video
+204579 tests/data/fate/vsynth2-mpeg2-ilace.mpeg2video
+ea5057b60146c06d40449cdfc686bf13 *tests/data/fate/vsynth2-mpeg2-ilace.out.rawvideo
+stddev: 4.98 PSNR: 34.18 MAXDIFF: 65 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-mpeg2-ivlc-qprd b/tests/ref/fate/vsynth2-mpeg2-ivlc-qprd
new file mode 100644
index 0000000..30e129b
--- /dev/null
+++ b/tests/ref/fate/vsynth2-mpeg2-ivlc-qprd
@@ -0,0 +1,4 @@
+1ba5efeb53fab7b4b71edc96d86f6c91 *tests/data/fate/vsynth2-mpeg2-ivlc-qprd.mpeg2video
+244694 tests/data/fate/vsynth2-mpeg2-ivlc-qprd.mpeg2video
+b26e21599dee48a174bdbc40b2817e55 *tests/data/fate/vsynth2-mpeg2-ivlc-qprd.out.rawvideo
+stddev: 4.15 PSNR: 35.76 MAXDIFF: 74 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-mpeg2-thread b/tests/ref/fate/vsynth2-mpeg2-thread
new file mode 100644
index 0000000..f43cdbc
--- /dev/null
+++ b/tests/ref/fate/vsynth2-mpeg2-thread
@@ -0,0 +1,4 @@
+889c754a42d7689b228853e1ece6d345 *tests/data/fate/vsynth2-mpeg2-thread.mpeg2video
+179650 tests/data/fate/vsynth2-mpeg2-thread.mpeg2video
+8c6a7ed2eb73bd18fd2bb9829464100d *tests/data/fate/vsynth2-mpeg2-thread.out.rawvideo
+stddev: 4.72 PSNR: 34.65 MAXDIFF: 72 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-mpeg2-thread-ivlc b/tests/ref/fate/vsynth2-mpeg2-thread-ivlc
new file mode 100644
index 0000000..2c42a21
--- /dev/null
+++ b/tests/ref/fate/vsynth2-mpeg2-thread-ivlc
@@ -0,0 +1,4 @@
+10b900e32809758857c596d56746e00e *tests/data/fate/vsynth2-mpeg2-thread-ivlc.mpeg2video
+178801 tests/data/fate/vsynth2-mpeg2-thread-ivlc.mpeg2video
+8c6a7ed2eb73bd18fd2bb9829464100d *tests/data/fate/vsynth2-mpeg2-thread-ivlc.out.rawvideo
+stddev: 4.72 PSNR: 34.65 MAXDIFF: 72 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-mpeg4 b/tests/ref/fate/vsynth2-mpeg4
new file mode 100644
index 0000000..4d96557
--- /dev/null
+++ b/tests/ref/fate/vsynth2-mpeg4
@@ -0,0 +1,4 @@
+8c9afbf564008a8ce6719cc3546deae1 *tests/data/fate/vsynth2-mpeg4.mp4
+119833 tests/data/fate/vsynth2-mpeg4.mp4
+90a3577850239083a9042bef33c50e85 *tests/data/fate/vsynth2-mpeg4.out.rawvideo
+stddev: 5.34 PSNR: 33.57 MAXDIFF: 83 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-mpeg4-adap b/tests/ref/fate/vsynth2-mpeg4-adap
new file mode 100644
index 0000000..d2f3bd1
--- /dev/null
+++ b/tests/ref/fate/vsynth2-mpeg4-adap
@@ -0,0 +1,4 @@
+547e1849dcf910935ff6383ca49e5706 *tests/data/fate/vsynth2-mpeg4-adap.avi
+198510 tests/data/fate/vsynth2-mpeg4-adap.avi
+4affb83f6adc94f31024b4f9e0168945 *tests/data/fate/vsynth2-mpeg4-adap.out.rawvideo
+stddev: 3.75 PSNR: 36.65 MAXDIFF: 71 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-mpeg4-adv b/tests/ref/fate/vsynth2-mpeg4-adv
new file mode 100644
index 0000000..6d7d507
--- /dev/null
+++ b/tests/ref/fate/vsynth2-mpeg4-adv
@@ -0,0 +1,4 @@
+dee7be19486a76d96c88d18eefba8f86 *tests/data/fate/vsynth2-mpeg4-adv.avi
+141546 tests/data/fate/vsynth2-mpeg4-adv.avi
+3f3a21e9db85a9c0f7022f557a5374c1 *tests/data/fate/vsynth2-mpeg4-adv.out.rawvideo
+stddev: 4.94 PSNR: 34.25 MAXDIFF: 69 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-mpeg4-error b/tests/ref/fate/vsynth2-mpeg4-error
new file mode 100644
index 0000000..a3f4453
--- /dev/null
+++ b/tests/ref/fate/vsynth2-mpeg4-error
@@ -0,0 +1,4 @@
+90e65096aa9ebafa3fe3f44a5a47cdc4 *tests/data/fate/vsynth2-mpeg4-error.avi
+176588 tests/data/fate/vsynth2-mpeg4-error.avi
+96baa9e4c24c837a3ba5abd8dd2cdd30 *tests/data/fate/vsynth2-mpeg4-error.out.rawvideo
+stddev: 8.98 PSNR: 29.06 MAXDIFF: 184 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-mpeg4-nr b/tests/ref/fate/vsynth2-mpeg4-nr
new file mode 100644
index 0000000..752b504
--- /dev/null
+++ b/tests/ref/fate/vsynth2-mpeg4-nr
@@ -0,0 +1,4 @@
+c41187c99588fb7229ad330b2f80d28b *tests/data/fate/vsynth2-mpeg4-nr.avi
+155044 tests/data/fate/vsynth2-mpeg4-nr.avi
+f7fc191308679f709405e62271f5c65f *tests/data/fate/vsynth2-mpeg4-nr.out.rawvideo
+stddev: 4.73 PSNR: 34.63 MAXDIFF: 64 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-mpeg4-qpel b/tests/ref/fate/vsynth2-mpeg4-qpel
new file mode 100644
index 0000000..3cba30d
--- /dev/null
+++ b/tests/ref/fate/vsynth2-mpeg4-qpel
@@ -0,0 +1,4 @@
+7680d2e7d34399dfdfb8a49cf1e10239 *tests/data/fate/vsynth2-mpeg4-qpel.avi
+163688 tests/data/fate/vsynth2-mpeg4-qpel.avi
+26dc7c78955fa678fbf150e236eb5627 *tests/data/fate/vsynth2-mpeg4-qpel.out.rawvideo
+stddev: 3.97 PSNR: 36.14 MAXDIFF: 54 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-mpeg4-qprd b/tests/ref/fate/vsynth2-mpeg4-qprd
new file mode 100644
index 0000000..87f5e02
--- /dev/null
+++ b/tests/ref/fate/vsynth2-mpeg4-qprd
@@ -0,0 +1,4 @@
+fd5ab0f55dbc959316e32923e86290df *tests/data/fate/vsynth2-mpeg4-qprd.avi
+231458 tests/data/fate/vsynth2-mpeg4-qprd.avi
+de8a883865e2dff7a51f66da6c48df48 *tests/data/fate/vsynth2-mpeg4-qprd.out.rawvideo
+stddev: 3.71 PSNR: 36.72 MAXDIFF: 61 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-mpeg4-rc b/tests/ref/fate/vsynth2-mpeg4-rc
new file mode 100644
index 0000000..bdd897b
--- /dev/null
+++ b/tests/ref/fate/vsynth2-mpeg4-rc
@@ -0,0 +1,4 @@
+c25ede9e268b834a09a63f5136cd1b95 *tests/data/fate/vsynth2-mpeg4-rc.avi
+226332 tests/data/fate/vsynth2-mpeg4-rc.avi
+2b34e606af895b62a250de98749a19b0 *tests/data/fate/vsynth2-mpeg4-rc.out.rawvideo
+stddev: 4.23 PSNR: 35.60 MAXDIFF: 85 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-mpeg4-thread b/tests/ref/fate/vsynth2-mpeg4-thread
new file mode 100644
index 0000000..e004009
--- /dev/null
+++ b/tests/ref/fate/vsynth2-mpeg4-thread
@@ -0,0 +1,4 @@
+ba30d10ff70d46e7c5b7fa859ea1faa4 *tests/data/fate/vsynth2-mpeg4-thread.avi
+250140 tests/data/fate/vsynth2-mpeg4-thread.avi
+5355deb8c7609a3f1ff2173aab1dee70 *tests/data/fate/vsynth2-mpeg4-thread.out.rawvideo
+stddev: 3.69 PSNR: 36.78 MAXDIFF: 65 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-msmpeg4 b/tests/ref/fate/vsynth2-msmpeg4
new file mode 100644
index 0000000..c65a9af
--- /dev/null
+++ b/tests/ref/fate/vsynth2-msmpeg4
@@ -0,0 +1,4 @@
+26dee25a62a66daba4f38ac6bd8f4677 *tests/data/fate/vsynth2-msmpeg4.avi
+127680 tests/data/fate/vsynth2-msmpeg4.avi
+0e1c6e25c71c6a8fa8e506e3d97ca4c9 *tests/data/fate/vsynth2-msmpeg4.out.rawvideo
+stddev: 5.33 PSNR: 33.59 MAXDIFF: 78 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-msmpeg4v2 b/tests/ref/fate/vsynth2-msmpeg4v2
new file mode 100644
index 0000000..d2b63d8
--- /dev/null
+++ b/tests/ref/fate/vsynth2-msmpeg4v2
@@ -0,0 +1,4 @@
+c09815e40a9d260628e1ebad8b2b3774 *tests/data/fate/vsynth2-msmpeg4v2.avi
+129918 tests/data/fate/vsynth2-msmpeg4v2.avi
+8920194f8bf8f9cdd6c65b3df9e1a292 *tests/data/fate/vsynth2-msmpeg4v2.out.rawvideo
+stddev: 5.33 PSNR: 33.59 MAXDIFF: 80 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-prores b/tests/ref/fate/vsynth2-prores
new file mode 100644
index 0000000..9a834ed
--- /dev/null
+++ b/tests/ref/fate/vsynth2-prores
@@ -0,0 +1,4 @@
+28755ce05e812adbb8b7c180318ffba8 *tests/data/fate/vsynth2-prores.mov
+3884722 tests/data/fate/vsynth2-prores.mov
+ca2f6c1162635dedfa468c90f1fdc0ef *tests/data/fate/vsynth2-prores.out.rawvideo
+stddev: 0.92 PSNR: 48.77 MAXDIFF: 10 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-qtrle b/tests/ref/fate/vsynth2-qtrle
new file mode 100644
index 0000000..ceee854
--- /dev/null
+++ b/tests/ref/fate/vsynth2-qtrle
@@ -0,0 +1,4 @@
+4805f35ca6e03b9279cc18f3f7356366 *tests/data/fate/vsynth2-qtrle.mov
+14798419 tests/data/fate/vsynth2-qtrle.mov
+b2418e0e3a9a8619b31219cbcf24dc82 *tests/data/fate/vsynth2-qtrle.out.rawvideo
+stddev: 1.26 PSNR: 46.06 MAXDIFF: 13 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-rgb b/tests/ref/fate/vsynth2-rgb
new file mode 100644
index 0000000..36ac105
--- /dev/null
+++ b/tests/ref/fate/vsynth2-rgb
@@ -0,0 +1,4 @@
+f2e9c419023c743bf99aa5b2e55ad233 *tests/data/fate/vsynth2-rgb.avi
+15213260 tests/data/fate/vsynth2-rgb.avi
+b2418e0e3a9a8619b31219cbcf24dc82 *tests/data/fate/vsynth2-rgb.out.rawvideo
+stddev: 1.26 PSNR: 46.06 MAXDIFF: 13 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-roqvideo b/tests/ref/fate/vsynth2-roqvideo
new file mode 100644
index 0000000..d4c075a
--- /dev/null
+++ b/tests/ref/fate/vsynth2-roqvideo
@@ -0,0 +1,4 @@
+b46f899b2363065c60f3782ba1f8b7bd *tests/data/fate/vsynth2-roqvideo.roq
+92786 tests/data/fate/vsynth2-roqvideo.roq
+e69fca960dd0911e9b8d589c13e11dc1 *tests/data/fate/vsynth2-roqvideo.out.rawvideo
+stddev: 3.81 PSNR: 36.49 MAXDIFF: 54 bytes: 7603200/ 760320
diff --git a/tests/ref/fate/vsynth2-rv10 b/tests/ref/fate/vsynth2-rv10
new file mode 100644
index 0000000..7afe4fc
--- /dev/null
+++ b/tests/ref/fate/vsynth2-rv10
@@ -0,0 +1,4 @@
+b1467b0e8d8cad730e36d1e8ab49d573 *tests/data/fate/vsynth2-rv10.rm
+154310 tests/data/fate/vsynth2-rv10.rm
+61213b91b359697ebcefb9e0a53ac54a *tests/data/fate/vsynth2-rv10.out.rawvideo
+stddev: 5.43 PSNR: 33.42 MAXDIFF: 77 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-rv20 b/tests/ref/fate/vsynth2-rv20
new file mode 100644
index 0000000..a3440fa
--- /dev/null
+++ b/tests/ref/fate/vsynth2-rv20
@@ -0,0 +1,4 @@
+96acb098850b9bf309f89e48b08fe96f *tests/data/fate/vsynth2-rv20.rm
+153302 tests/data/fate/vsynth2-rv20.rm
+46f314e70d9bac2e7d82cfc230534977 *tests/data/fate/vsynth2-rv20.out.rawvideo
+stddev: 5.48 PSNR: 33.35 MAXDIFF: 81 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-snow b/tests/ref/fate/vsynth2-snow
new file mode 100644
index 0000000..0e78f32
--- /dev/null
+++ b/tests/ref/fate/vsynth2-snow
@@ -0,0 +1,4 @@
+af651d8ef0a66257ac8b2ef8b229f27b *tests/data/fate/vsynth2-snow.avi
+57700 tests/data/fate/vsynth2-snow.avi
+8890189af71a0dd3447c4e8424c9a76b *tests/data/fate/vsynth2-snow.out.rawvideo
+stddev: 10.47 PSNR: 27.72 MAXDIFF: 119 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-snow-hpel b/tests/ref/fate/vsynth2-snow-hpel
new file mode 100644
index 0000000..2194a13
--- /dev/null
+++ b/tests/ref/fate/vsynth2-snow-hpel
@@ -0,0 +1,4 @@
+ac1400b66514aa280300bba6477b4e97 *tests/data/fate/vsynth2-snow-hpel.avi
+61772 tests/data/fate/vsynth2-snow-hpel.avi
+8680d40905f423999d65b996c4dcb984 *tests/data/fate/vsynth2-snow-hpel.out.rawvideo
+stddev: 10.45 PSNR: 27.74 MAXDIFF: 123 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-snow-ll b/tests/ref/fate/vsynth2-snow-ll
new file mode 100644
index 0000000..2d33b08
--- /dev/null
+++ b/tests/ref/fate/vsynth2-snow-ll
@@ -0,0 +1,4 @@
+a8fccf278bbb17d37a756ecf11672b09 *tests/data/fate/vsynth2-snow-ll.avi
+2721758 tests/data/fate/vsynth2-snow-ll.avi
+dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-snow-ll.out.rawvideo
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-svq1 b/tests/ref/fate/vsynth2-svq1
new file mode 100644
index 0000000..251f72d
--- /dev/null
+++ b/tests/ref/fate/vsynth2-svq1
@@ -0,0 +1,4 @@
+138ad38281570f1a3b68d63ed896435d *tests/data/fate/vsynth2-svq1.mov
+766851 tests/data/fate/vsynth2-svq1.mov
+aa03471dac3f49455a33a2b19fda1098 *tests/data/fate/vsynth2-svq1.out.rawvideo
+stddev: 3.23 PSNR: 37.93 MAXDIFF: 61 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-v210 b/tests/ref/fate/vsynth2-v210
new file mode 100644
index 0000000..407ad0e
--- /dev/null
+++ b/tests/ref/fate/vsynth2-v210
@@ -0,0 +1,4 @@
+db0579bd46e1ba133ff86c0f7cdd761f *tests/data/fate/vsynth2-v210.avi
+14752460 tests/data/fate/vsynth2-v210.avi
+a627fb50c8276200fd71383977d87ca3 *tests/data/fate/vsynth2-v210.out.rawvideo
+stddev: 0.34 PSNR: 57.43 MAXDIFF: 6 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-wmv1 b/tests/ref/fate/vsynth2-wmv1
new file mode 100644
index 0000000..4545d42
--- /dev/null
+++ b/tests/ref/fate/vsynth2-wmv1
@@ -0,0 +1,4 @@
+1011e26e7d351c96d7bbfe106d831b69 *tests/data/fate/vsynth2-wmv1.avi
+129530 tests/data/fate/vsynth2-wmv1.avi
+81eee429b665254d19a06607463c0b5e *tests/data/fate/vsynth2-wmv1.out.rawvideo
+stddev: 5.33 PSNR: 33.60 MAXDIFF: 77 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-wmv2 b/tests/ref/fate/vsynth2-wmv2
new file mode 100644
index 0000000..a7384ad
--- /dev/null
+++ b/tests/ref/fate/vsynth2-wmv2
@@ -0,0 +1,4 @@
+1f6598e9776ed00aebdc44cc8d48cb7c *tests/data/fate/vsynth2-wmv2.avi
+129860 tests/data/fate/vsynth2-wmv2.avi
+81eee429b665254d19a06607463c0b5e *tests/data/fate/vsynth2-wmv2.out.rawvideo
+stddev: 5.33 PSNR: 33.60 MAXDIFF: 77 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/vsynth2-yuv b/tests/ref/fate/vsynth2-yuv
new file mode 100644
index 0000000..a2332e0
--- /dev/null
+++ b/tests/ref/fate/vsynth2-yuv
@@ -0,0 +1,4 @@
+30a400773ab26f2c83e469198b156f1d *tests/data/fate/vsynth2-yuv.avi
+7610060 tests/data/fate/vsynth2-yuv.avi
+dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-yuv.out.rawvideo
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
diff --git a/tests/ref/fate/westwood-aud b/tests/ref/fate/westwood-aud
index f8bec10..9fab241 100644
--- a/tests/ref/fate/westwood-aud
+++ b/tests/ref/fate/westwood-aud
@@ -1 +1,12 @@
-5c2528488729035c17c21486797a2a23
+#tb 0: 1/22050
+0, 0, 0, 1024, 512, 0x6694cc55
+0, 1024, 1024, 1024, 512, 0xdbc5cb22
+0, 2048, 2048, 1024, 512, 0x8e5bcbfd
+0, 3072, 3072, 1024, 512, 0x7b2ac519
+0, 4096, 4096, 1024, 512, 0x6ae0cb0c
+0, 5120, 5120, 1024, 512, 0x055ec435
+0, 6144, 6144, 1024, 512, 0x9424c8d6
+0, 7168, 7168, 1024, 512, 0x58fccb7d
+0, 8192, 8192, 1024, 512, 0x348fd253
+0, 9216, 9216, 1024, 512, 0xe1b1c24e
+0, 10240, 10240, 192, 96, 0x95f81350
diff --git a/tests/ref/fate/xtea b/tests/ref/fate/xtea
new file mode 100644
index 0000000..fed0b4d
--- /dev/null
+++ b/tests/ref/fate/xtea
@@ -0,0 +1 @@
+Test encryption/decryption success.
diff --git a/tests/ref/lavf/mov b/tests/ref/lavf/mov
index a4ae2d5..2db01d4 100644
--- a/tests/ref/lavf/mov
+++ b/tests/ref/lavf/mov
@@ -1,3 +1,3 @@
-6c5472152b46e070ae6da359838e1f86 *./tests/data/lavf/lavf.mov
-357717 ./tests/data/lavf/lavf.mov
+a5c982910b1a1547db68ffa35cc2a05a *./tests/data/lavf/lavf.mov
+357741 ./tests/data/lavf/lavf.mov
./tests/data/lavf/lavf.mov CRC=0x2f6a9b26
diff --git a/tests/ref/lavf/pam b/tests/ref/lavf/pam
index 972d728..e53132a 100644
--- a/tests/ref/lavf/pam
+++ b/tests/ref/lavf/pam
@@ -1,3 +1,3 @@
0dce5565222cf0f8b309467f279aecd2 *./tests/data/images/pam/02.pam
./tests/data/images/pam/%02d.pam CRC=0x6da01946
- 304191 ./tests/data/images/pam/02.pam
+304191 ./tests/data/images/pam/02.pam
diff --git a/tests/ref/seek/ac3_ac3 b/tests/ref/seek/ac3_ac3
deleted file mode 100644
index 167dc8d..0000000
--- a/tests/ref/seek/ac3_ac3
+++ /dev/null
@@ -1,49 +0,0 @@
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 556
-ret: 0 st:-1 flags:0 ts:-1.000000
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 556
-ret: 0 st:-1 flags:1 ts: 1.894167
-ret: 0 st: 0 flags:1 dts: 1.880400 pts: 1.880400 pos: 30092 size: 558
-ret: 0 st: 0 flags:0 ts: 0.788333
-ret: 0 st: 0 flags:1 dts: 0.800911 pts: 0.800911 pos: 12818 size: 556
-ret:-1 st: 0 flags:1 ts:-0.317500
-ret: 0 st:-1 flags:0 ts: 2.576668
-ret: 0 st: 0 flags:1 dts: 2.576844 pts: 2.576844 pos: 41238 size: 558
-ret: 0 st:-1 flags:1 ts: 1.470835
-ret: 0 st: 0 flags:1 dts: 1.462533 pts: 1.462533 pos: 23406 size: 556
-ret: 0 st: 0 flags:0 ts: 0.365000
-ret: 0 st: 0 flags:1 dts: 0.383044 pts: 0.383044 pos: 6130 size: 558
-ret:-1 st: 0 flags:1 ts:-0.740833
-ret: 0 st:-1 flags:0 ts: 2.153336
-ret: 0 st: 0 flags:1 dts: 2.158978 pts: 2.158978 pos: 34552 size: 556
-ret: 0 st:-1 flags:1 ts: 1.047503
-ret: 0 st: 0 flags:1 dts: 1.044667 pts: 1.044667 pos: 16718 size: 558
-ret: 0 st: 0 flags:0 ts:-0.058333
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 556
-ret: 0 st: 0 flags:1 ts: 2.835833
-ret: 0 st: 0 flags:1 dts: 2.820600 pts: 2.820600 pos: 45140 size: 556
-ret: 0 st:-1 flags:0 ts: 1.730004
-ret: 0 st: 0 flags:1 dts: 1.741111 pts: 1.741111 pos: 27864 size: 556
-ret: 0 st:-1 flags:1 ts: 0.624171
-ret: 0 st: 0 flags:1 dts: 0.591978 pts: 0.591978 pos: 9474 size: 556
-ret: 0 st: 0 flags:0 ts:-0.481667
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 556
-ret: 0 st: 0 flags:1 ts: 2.412500
-ret: 0 st: 0 flags:1 dts: 2.402733 pts: 2.402733 pos: 38452 size: 558
-ret: 0 st:-1 flags:0 ts: 1.306672
-ret: 0 st: 0 flags:1 dts: 1.323244 pts: 1.323244 pos: 21176 size: 558
-ret: 0 st:-1 flags:1 ts: 0.200839
-ret: 0 st: 0 flags:1 dts: 0.174111 pts: 0.174111 pos: 2786 size: 558
-ret: 0 st: 0 flags:0 ts:-0.904989
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 556
-ret: 0 st: 0 flags:1 ts: 1.989178
-ret: 0 st: 0 flags:1 dts: 1.984867 pts: 1.984867 pos: 31764 size: 558
-ret: 0 st:-1 flags:0 ts: 0.883340
-ret: 0 st: 0 flags:1 dts: 0.905378 pts: 0.905378 pos: 14488 size: 558
-ret:-1 st:-1 flags:1 ts:-0.222493
-ret: 0 st: 0 flags:0 ts: 2.671678
-ret: 0 st: 0 flags:1 dts: 2.681311 pts: 2.681311 pos: 42910 size: 558
-ret: 0 st: 0 flags:1 ts: 1.565844
-ret: 0 st: 0 flags:1 dts: 1.532178 pts: 1.532178 pos: 24520 size: 558
-ret: 0 st:-1 flags:0 ts: 0.460008
-ret: 0 st: 0 flags:1 dts: 0.487511 pts: 0.487511 pos: 7802 size: 556
-ret:-1 st:-1 flags:1 ts:-0.645825
diff --git a/tests/ref/seek/adpcm_qt_aiff b/tests/ref/seek/adpcm_ima_qt_aiff
similarity index 100%
rename from tests/ref/seek/adpcm_qt_aiff
rename to tests/ref/seek/adpcm_ima_qt_aiff
diff --git a/tests/ref/seek/adpcm_ima_wav b/tests/ref/seek/adpcm_ima_wav_wav
similarity index 100%
rename from tests/ref/seek/adpcm_ima_wav
rename to tests/ref/seek/adpcm_ima_wav_wav
diff --git a/tests/ref/seek/adpcm_yam_wav b/tests/ref/seek/adpcm_yamaha_wav
similarity index 100%
rename from tests/ref/seek/adpcm_yam_wav
rename to tests/ref/seek/adpcm_yamaha_wav
diff --git a/tests/ref/seek/alac_m4a b/tests/ref/seek/alac_m4a
deleted file mode 100644
index 51e23e1..0000000
--- a/tests/ref/seek/alac_m4a
+++ /dev/null
@@ -1,53 +0,0 @@
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 40 size: 3236
-ret: 0 st:-1 flags:0 ts:-1.000000
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 40 size: 3236
-ret: 0 st:-1 flags:1 ts: 1.894167
-ret: 0 st: 0 flags:1 dts: 1.857596 pts: 1.857596 pos: 73651 size: 4961
-ret: 0 st: 0 flags:0 ts: 0.788345
-ret: 0 st: 0 flags:1 dts: 0.835918 pts: 0.835918 pos: 29036 size: 3194
-ret: 0 st: 0 flags:1 ts:-0.317506
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 40 size: 3236
-ret: 0 st:-1 flags:0 ts: 2.576668
-ret: 0 st: 0 flags:1 dts: 2.600635 pts: 2.600635 pos: 137557 size: 12843
-ret: 0 st:-1 flags:1 ts: 1.470835
-ret: 0 st: 0 flags:1 dts: 1.393197 pts: 1.393197 pos: 50159 size: 4414
-ret: 0 st: 0 flags:0 ts: 0.365011
-ret: 0 st: 0 flags:1 dts: 0.371519 pts: 0.371519 pos: 12946 size: 3209
-ret: 0 st: 0 flags:1 ts:-0.740839
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 40 size: 3236
-ret: 0 st:-1 flags:0 ts: 2.153336
-ret: 0 st: 0 flags:1 dts: 2.229116 pts: 2.229116 pos: 100935 size: 7896
-ret: 0 st:-1 flags:1 ts: 1.047503
-ret: 0 st: 0 flags:1 dts: 1.021678 pts: 1.021678 pos: 35318 size: 3031
-ret: 0 st: 0 flags:0 ts:-0.058322
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 40 size: 3236
-ret: 0 st: 0 flags:1 ts: 2.835828
-ret: 0 st: 0 flags:1 dts: 2.786395 pts: 2.786395 pos: 163180 size: 12765
-ret: 0 st:-1 flags:0 ts: 1.730004
-ret: 0 st: 0 flags:1 dts: 1.764717 pts: 1.764717 pos: 68680 size: 4971
-ret: 0 st:-1 flags:1 ts: 0.624171
-ret: 0 st: 0 flags:1 dts: 0.557279 pts: 0.557279 pos: 19341 size: 3234
-ret: 0 st: 0 flags:0 ts:-0.481655
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 40 size: 3236
-ret: 0 st: 0 flags:1 ts: 2.412494
-ret: 0 st: 0 flags:1 dts: 2.321995 pts: 2.321995 pos: 108831 size: 7886
-ret: 0 st:-1 flags:0 ts: 1.306672
-ret: 0 st: 0 flags:1 dts: 1.393197 pts: 1.393197 pos: 50159 size: 4414
-ret: 0 st:-1 flags:1 ts: 0.200839
-ret: 0 st: 0 flags:1 dts: 0.185760 pts: 0.185760 pos: 6470 size: 3245
-ret: 0 st: 0 flags:0 ts:-0.904989
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 40 size: 3236
-ret: 0 st: 0 flags:1 ts: 1.989184
-ret: 0 st: 0 flags:1 dts: 1.950476 pts: 1.950476 pos: 78612 size: 6514
-ret: 0 st:-1 flags:0 ts: 0.883340
-ret: 0 st: 0 flags:1 dts: 0.928798 pts: 0.928798 pos: 32230 size: 3088
-ret: 0 st:-1 flags:1 ts:-0.222493
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 40 size: 3236
-ret: 0 st: 0 flags:0 ts: 2.671678
-ret: 0 st: 0 flags:1 dts: 2.693515 pts: 2.693515 pos: 150400 size: 12780
-ret: 0 st: 0 flags:1 ts: 1.565850
-ret: 0 st: 0 flags:1 dts: 1.486077 pts: 1.486077 pos: 54573 size: 4554
-ret: 0 st:-1 flags:0 ts: 0.460008
-ret: 0 st: 0 flags:1 dts: 0.464399 pts: 0.464399 pos: 16155 size: 3186
-ret: 0 st:-1 flags:1 ts:-0.645825
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 40 size: 3236
diff --git a/tests/ref/seek/alac_mov b/tests/ref/seek/alac_mov
new file mode 100644
index 0000000..a281d2e
--- /dev/null
+++ b/tests/ref/seek/alac_mov
@@ -0,0 +1,53 @@
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 36 size: 3236
+ret: 0 st:-1 flags:0 ts:-1.000000
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 36 size: 3236
+ret: 0 st:-1 flags:1 ts: 1.894167
+ret: 0 st: 0 flags:1 dts: 1.857596 pts: 1.857596 pos: 73647 size: 4961
+ret: 0 st: 0 flags:0 ts: 0.788345
+ret: 0 st: 0 flags:1 dts: 0.835918 pts: 0.835918 pos: 29032 size: 3194
+ret: 0 st: 0 flags:1 ts:-0.317506
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 36 size: 3236
+ret: 0 st:-1 flags:0 ts: 2.576668
+ret: 0 st: 0 flags:1 dts: 2.600635 pts: 2.600635 pos: 137553 size: 12843
+ret: 0 st:-1 flags:1 ts: 1.470835
+ret: 0 st: 0 flags:1 dts: 1.393197 pts: 1.393197 pos: 50155 size: 4414
+ret: 0 st: 0 flags:0 ts: 0.365011
+ret: 0 st: 0 flags:1 dts: 0.371519 pts: 0.371519 pos: 12942 size: 3209
+ret: 0 st: 0 flags:1 ts:-0.740839
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 36 size: 3236
+ret: 0 st:-1 flags:0 ts: 2.153336
+ret: 0 st: 0 flags:1 dts: 2.229116 pts: 2.229116 pos: 100931 size: 7896
+ret: 0 st:-1 flags:1 ts: 1.047503
+ret: 0 st: 0 flags:1 dts: 1.021678 pts: 1.021678 pos: 35314 size: 3031
+ret: 0 st: 0 flags:0 ts:-0.058322
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 36 size: 3236
+ret: 0 st: 0 flags:1 ts: 2.835828
+ret: 0 st: 0 flags:1 dts: 2.786395 pts: 2.786395 pos: 163176 size: 12765
+ret: 0 st:-1 flags:0 ts: 1.730004
+ret: 0 st: 0 flags:1 dts: 1.764717 pts: 1.764717 pos: 68676 size: 4971
+ret: 0 st:-1 flags:1 ts: 0.624171
+ret: 0 st: 0 flags:1 dts: 0.557279 pts: 0.557279 pos: 19337 size: 3234
+ret: 0 st: 0 flags:0 ts:-0.481655
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 36 size: 3236
+ret: 0 st: 0 flags:1 ts: 2.412494
+ret: 0 st: 0 flags:1 dts: 2.321995 pts: 2.321995 pos: 108827 size: 7886
+ret: 0 st:-1 flags:0 ts: 1.306672
+ret: 0 st: 0 flags:1 dts: 1.393197 pts: 1.393197 pos: 50155 size: 4414
+ret: 0 st:-1 flags:1 ts: 0.200839
+ret: 0 st: 0 flags:1 dts: 0.185760 pts: 0.185760 pos: 6466 size: 3245
+ret: 0 st: 0 flags:0 ts:-0.904989
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 36 size: 3236
+ret: 0 st: 0 flags:1 ts: 1.989184
+ret: 0 st: 0 flags:1 dts: 1.950476 pts: 1.950476 pos: 78608 size: 6514
+ret: 0 st:-1 flags:0 ts: 0.883340
+ret: 0 st: 0 flags:1 dts: 0.928798 pts: 0.928798 pos: 32226 size: 3088
+ret: 0 st:-1 flags:1 ts:-0.222493
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 36 size: 3236
+ret: 0 st: 0 flags:0 ts: 2.671678
+ret: 0 st: 0 flags:1 dts: 2.693515 pts: 2.693515 pos: 150396 size: 12780
+ret: 0 st: 0 flags:1 ts: 1.565850
+ret: 0 st: 0 flags:1 dts: 1.486077 pts: 1.486077 pos: 54569 size: 4554
+ret: 0 st:-1 flags:0 ts: 0.460008
+ret: 0 st: 0 flags:1 dts: 0.464399 pts: 0.464399 pos: 16151 size: 3186
+ret: 0 st:-1 flags:1 ts:-0.645825
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 36 size: 3236
diff --git a/tests/ref/seek/dv411_dv b/tests/ref/seek/dv_411_dv
similarity index 100%
rename from tests/ref/seek/dv411_dv
rename to tests/ref/seek/dv_411_dv
diff --git a/tests/ref/seek/dv50_dv b/tests/ref/seek/dv_50_dv
similarity index 100%
rename from tests/ref/seek/dv50_dv
rename to tests/ref/seek/dv_50_dv
diff --git a/tests/ref/seek/mpeg1_mpg b/tests/ref/seek/mpeg1_mpeg1video
similarity index 100%
rename from tests/ref/seek/mpeg1_mpg
rename to tests/ref/seek/mpeg1_mpeg1video
diff --git a/tests/ref/seek/mpeg1b_mpg b/tests/ref/seek/mpeg1b_mpeg1video
similarity index 100%
rename from tests/ref/seek/mpeg1b_mpg
rename to tests/ref/seek/mpeg1b_mpeg1video
diff --git a/tests/ref/seek/mpeg2_422_mpg b/tests/ref/seek/mpeg2_422_mpeg2video
similarity index 100%
rename from tests/ref/seek/mpeg2_422_mpg
rename to tests/ref/seek/mpeg2_422_mpeg2video
diff --git a/tests/ref/seek/mpeg2_idct_int_mpg b/tests/ref/seek/mpeg2_idct_int_mpeg2video
similarity index 100%
rename from tests/ref/seek/mpeg2_idct_int_mpg
rename to tests/ref/seek/mpeg2_idct_int_mpeg2video
diff --git a/tests/ref/seek/mpeg2i_mpg b/tests/ref/seek/mpeg2_ilace_mpeg2video
similarity index 100%
rename from tests/ref/seek/mpeg2i_mpg
rename to tests/ref/seek/mpeg2_ilace_mpeg2video
diff --git a/tests/ref/seek/mpeg2ivlc_qprd_mpg b/tests/ref/seek/mpeg2_ivlc_qprd_mpeg2video
similarity index 100%
rename from tests/ref/seek/mpeg2ivlc_qprd_mpg
rename to tests/ref/seek/mpeg2_ivlc_qprd_mpeg2video
diff --git a/tests/ref/seek/mpeg2threadivlc_mpg b/tests/ref/seek/mpeg2_thread_ivlc_mpeg2video
similarity index 100%
rename from tests/ref/seek/mpeg2threadivlc_mpg
rename to tests/ref/seek/mpeg2_thread_ivlc_mpeg2video
diff --git a/tests/ref/seek/mpeg2thread_mpg b/tests/ref/seek/mpeg2_thread_mpeg2video
similarity index 100%
rename from tests/ref/seek/mpeg2thread_mpg
rename to tests/ref/seek/mpeg2_thread_mpeg2video
diff --git a/tests/ref/seek/error_mpeg4_adv_avi b/tests/ref/seek/mpeg4_error_avi
similarity index 100%
rename from tests/ref/seek/error_mpeg4_adv_avi
rename to tests/ref/seek/mpeg4_error_avi
diff --git a/tests/ref/seek/odivx_mp4 b/tests/ref/seek/mpeg4_mp4
similarity index 100%
rename from tests/ref/seek/odivx_mp4
rename to tests/ref/seek/mpeg4_mp4
diff --git a/tests/ref/seek/mpeg4_Q_avi b/tests/ref/seek/mpeg4_qpel_avi
similarity index 100%
rename from tests/ref/seek/mpeg4_Q_avi
rename to tests/ref/seek/mpeg4_qpel_avi
diff --git a/tests/ref/seek/pcm_alaw_wav b/tests/ref/seek/pcm_alaw_wav
index 22d95bf..e5466bd 100644
--- a/tests/ref/seek/pcm_alaw_wav
+++ b/tests/ref/seek/pcm_alaw_wav
@@ -2,52 +2,52 @@ ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st:-1 flags:0 ts:-1.000000
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st:-1 flags:1 ts: 1.894167
-ret: 0 st: 0 flags:1 dts: 1.894127 pts: 1.894127 pos: 30364 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.894172 pts: 1.894172 pos: 167124 size: 4096
ret: 0 st: 0 flags:0 ts: 0.788345
-ret: 0 st: 0 flags:1 dts: 0.788367 pts: 0.788367 pos: 12672 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.788345 pts: 0.788345 pos: 69590 size: 4096
ret: 0 st: 0 flags:1 ts:-0.317506
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st:-1 flags:0 ts: 2.576668
-ret: 0 st: 0 flags:1 dts: 2.576757 pts: 2.576757 pos: 41286 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.576667 pts: 2.576667 pos: 227320 size: 4096
ret: 0 st:-1 flags:1 ts: 1.470835
-ret: 0 st: 0 flags:1 dts: 1.470748 pts: 1.470748 pos: 23590 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.470839 pts: 1.470839 pos: 129786 size: 4096
ret: 0 st: 0 flags:0 ts: 0.365011
-ret: 0 st: 0 flags:1 dts: 0.365125 pts: 0.365125 pos: 5900 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.365011 pts: 0.365011 pos: 32252 size: 4096
ret: 0 st: 0 flags:1 ts:-0.740839
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st:-1 flags:0 ts: 2.153336
-ret: 0 st: 0 flags:1 dts: 2.153379 pts: 2.153379 pos: 34512 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.153333 pts: 2.153333 pos: 189982 size: 4096
ret: 0 st:-1 flags:1 ts: 1.047503
-ret: 0 st: 0 flags:1 dts: 1.047506 pts: 1.047506 pos: 16818 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.047506 pts: 1.047506 pos: 92448 size: 4096
ret: 0 st: 0 flags:0 ts:-0.058322
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st: 0 flags:1 ts: 2.835828
-ret: 0 st: 0 flags:1 dts: 2.835760 pts: 2.835760 pos: 45430 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.835828 pts: 2.835828 pos: 250178 size: 4096
ret: 0 st:-1 flags:0 ts: 1.730004
-ret: 0 st: 0 flags:1 dts: 1.730000 pts: 1.730000 pos: 27738 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.730000 pts: 1.730000 pos: 152644 size: 4096
ret: 0 st:-1 flags:1 ts: 0.624171
-ret: 0 st: 0 flags:1 dts: 0.624127 pts: 0.624127 pos: 10044 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.624172 pts: 0.624172 pos: 55110 size: 4096
ret: 0 st: 0 flags:0 ts:-0.481655
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st: 0 flags:1 ts: 2.412494
-ret: 0 st: 0 flags:1 dts: 2.412381 pts: 2.412381 pos: 38656 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.412494 pts: 2.412494 pos: 212840 size: 4096
ret: 0 st:-1 flags:0 ts: 1.306672
-ret: 0 st: 0 flags:1 dts: 1.306757 pts: 1.306757 pos: 20966 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.306667 pts: 1.306667 pos: 115306 size: 4096
ret: 0 st:-1 flags:1 ts: 0.200839
-ret: 0 st: 0 flags:1 dts: 0.200748 pts: 0.200748 pos: 3270 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.200839 pts: 0.200839 pos: 17772 size: 4096
ret: 0 st: 0 flags:0 ts:-0.904989
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st: 0 flags:1 ts: 1.989184
-ret: 0 st: 0 flags:1 dts: 1.989116 pts: 1.989116 pos: 31884 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.989184 pts: 1.989184 pos: 175504 size: 4096
ret: 0 st:-1 flags:0 ts: 0.883340
-ret: 0 st: 0 flags:1 dts: 0.883379 pts: 0.883379 pos: 14192 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.883333 pts: 0.883333 pos: 77968 size: 4096
ret: 0 st:-1 flags:1 ts:-0.222493
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st: 0 flags:0 ts: 2.671678
-ret: 0 st: 0 flags:1 dts: 2.671746 pts: 2.671746 pos: 42806 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.671678 pts: 2.671678 pos: 235700 size: 4096
ret: 0 st: 0 flags:1 ts: 1.565850
-ret: 0 st: 0 flags:1 dts: 1.565760 pts: 1.565760 pos: 25110 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.565850 pts: 1.565850 pos: 138166 size: 4096
ret: 0 st:-1 flags:0 ts: 0.460008
-ret: 0 st: 0 flags:1 dts: 0.460000 pts: 0.460000 pos: 7418 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.460000 pts: 0.460000 pos: 40630 size: 4096
ret: 0 st:-1 flags:1 ts:-0.645825
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
diff --git a/tests/ref/seek/pcm_mulaw_wav b/tests/ref/seek/pcm_mulaw_wav
index 22d95bf..e5466bd 100644
--- a/tests/ref/seek/pcm_mulaw_wav
+++ b/tests/ref/seek/pcm_mulaw_wav
@@ -2,52 +2,52 @@ ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st:-1 flags:0 ts:-1.000000
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st:-1 flags:1 ts: 1.894167
-ret: 0 st: 0 flags:1 dts: 1.894127 pts: 1.894127 pos: 30364 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.894172 pts: 1.894172 pos: 167124 size: 4096
ret: 0 st: 0 flags:0 ts: 0.788345
-ret: 0 st: 0 flags:1 dts: 0.788367 pts: 0.788367 pos: 12672 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.788345 pts: 0.788345 pos: 69590 size: 4096
ret: 0 st: 0 flags:1 ts:-0.317506
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st:-1 flags:0 ts: 2.576668
-ret: 0 st: 0 flags:1 dts: 2.576757 pts: 2.576757 pos: 41286 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.576667 pts: 2.576667 pos: 227320 size: 4096
ret: 0 st:-1 flags:1 ts: 1.470835
-ret: 0 st: 0 flags:1 dts: 1.470748 pts: 1.470748 pos: 23590 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.470839 pts: 1.470839 pos: 129786 size: 4096
ret: 0 st: 0 flags:0 ts: 0.365011
-ret: 0 st: 0 flags:1 dts: 0.365125 pts: 0.365125 pos: 5900 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.365011 pts: 0.365011 pos: 32252 size: 4096
ret: 0 st: 0 flags:1 ts:-0.740839
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st:-1 flags:0 ts: 2.153336
-ret: 0 st: 0 flags:1 dts: 2.153379 pts: 2.153379 pos: 34512 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.153333 pts: 2.153333 pos: 189982 size: 4096
ret: 0 st:-1 flags:1 ts: 1.047503
-ret: 0 st: 0 flags:1 dts: 1.047506 pts: 1.047506 pos: 16818 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.047506 pts: 1.047506 pos: 92448 size: 4096
ret: 0 st: 0 flags:0 ts:-0.058322
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st: 0 flags:1 ts: 2.835828
-ret: 0 st: 0 flags:1 dts: 2.835760 pts: 2.835760 pos: 45430 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.835828 pts: 2.835828 pos: 250178 size: 4096
ret: 0 st:-1 flags:0 ts: 1.730004
-ret: 0 st: 0 flags:1 dts: 1.730000 pts: 1.730000 pos: 27738 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.730000 pts: 1.730000 pos: 152644 size: 4096
ret: 0 st:-1 flags:1 ts: 0.624171
-ret: 0 st: 0 flags:1 dts: 0.624127 pts: 0.624127 pos: 10044 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.624172 pts: 0.624172 pos: 55110 size: 4096
ret: 0 st: 0 flags:0 ts:-0.481655
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st: 0 flags:1 ts: 2.412494
-ret: 0 st: 0 flags:1 dts: 2.412381 pts: 2.412381 pos: 38656 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.412494 pts: 2.412494 pos: 212840 size: 4096
ret: 0 st:-1 flags:0 ts: 1.306672
-ret: 0 st: 0 flags:1 dts: 1.306757 pts: 1.306757 pos: 20966 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.306667 pts: 1.306667 pos: 115306 size: 4096
ret: 0 st:-1 flags:1 ts: 0.200839
-ret: 0 st: 0 flags:1 dts: 0.200748 pts: 0.200748 pos: 3270 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.200839 pts: 0.200839 pos: 17772 size: 4096
ret: 0 st: 0 flags:0 ts:-0.904989
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st: 0 flags:1 ts: 1.989184
-ret: 0 st: 0 flags:1 dts: 1.989116 pts: 1.989116 pos: 31884 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.989184 pts: 1.989184 pos: 175504 size: 4096
ret: 0 st:-1 flags:0 ts: 0.883340
-ret: 0 st: 0 flags:1 dts: 0.883379 pts: 0.883379 pos: 14192 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.883333 pts: 0.883333 pos: 77968 size: 4096
ret: 0 st:-1 flags:1 ts:-0.222493
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st: 0 flags:0 ts: 2.671678
-ret: 0 st: 0 flags:1 dts: 2.671746 pts: 2.671746 pos: 42806 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.671678 pts: 2.671678 pos: 235700 size: 4096
ret: 0 st: 0 flags:1 ts: 1.565850
-ret: 0 st: 0 flags:1 dts: 1.565760 pts: 1.565760 pos: 25110 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.565850 pts: 1.565850 pos: 138166 size: 4096
ret: 0 st:-1 flags:0 ts: 0.460008
-ret: 0 st: 0 flags:1 dts: 0.460000 pts: 0.460000 pos: 7418 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.460000 pts: 0.460000 pos: 40630 size: 4096
ret: 0 st:-1 flags:1 ts:-0.645825
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
diff --git a/tests/ref/seek/roqav_roq b/tests/ref/seek/roqvideo_roq
similarity index 100%
rename from tests/ref/seek/roqav_roq
rename to tests/ref/seek/roqvideo_roq
diff --git a/tests/ref/seek/snow53_avi b/tests/ref/seek/snow_ll_avi
similarity index 100%
rename from tests/ref/seek/snow53_avi
rename to tests/ref/seek/snow_ll_avi
diff --git a/tests/ref/vsynth1/asv1 b/tests/ref/vsynth1/asv1
deleted file mode 100644
index 10c1b03..0000000
--- a/tests/ref/vsynth1/asv1
+++ /dev/null
@@ -1,4 +0,0 @@
-b4ce4698764ef2328346badb7227ecbe *./tests/data/vsynth1/asv1.avi
-1489656 ./tests/data/vsynth1/asv1.avi
-2dfc5dfc2c1cbbc2543257cd3d2df6af *./tests/data/asv1.vsynth1.out.yuv
-stddev: 20.00 PSNR: 22.11 MAXDIFF: 158 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/asv2 b/tests/ref/vsynth1/asv2
deleted file mode 100644
index 14b0d1c..0000000
--- a/tests/ref/vsynth1/asv2
+++ /dev/null
@@ -1,4 +0,0 @@
-dfba6eaf58e515e324c2b370bfcd9158 *./tests/data/vsynth1/asv2.avi
-1456056 ./tests/data/vsynth1/asv2.avi
-d451be09793cd0f35b6d91fc36e2571a *./tests/data/asv2.vsynth1.out.yuv
-stddev: 18.82 PSNR: 22.63 MAXDIFF: 131 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/cljr b/tests/ref/vsynth1/cljr
deleted file mode 100644
index 4978344..0000000
--- a/tests/ref/vsynth1/cljr
+++ /dev/null
@@ -1,4 +0,0 @@
-b4d3d31da0b4b6873ad8239d113c91d2 *./tests/data/vsynth1/cljr.avi
- 5075660 ./tests/data/vsynth1/cljr.avi
-4debaab994c2c7273bebaa0c5733017b *./tests/data/cljr.vsynth1.out.yuv
-stddev: 30.75 PSNR: 18.37 MAXDIFF: 225 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/dnxhd_1080i b/tests/ref/vsynth1/dnxhd_1080i
deleted file mode 100644
index e989eae..0000000
--- a/tests/ref/vsynth1/dnxhd_1080i
+++ /dev/null
@@ -1,4 +0,0 @@
-3cfbe36a7dd5b48859b8a569d626ef77 *./tests/data/vsynth1/dnxhd-1080i.mov
-3031875 ./tests/data/vsynth1/dnxhd-1080i.mov
-0c651e840f860592f0d5b66030d9fa32 *./tests/data/dnxhd_1080i.vsynth1.out.yuv
-stddev: 6.29 PSNR: 32.15 MAXDIFF: 64 bytes: 760320/ 7603200
diff --git a/tests/ref/vsynth1/dnxhd_720p b/tests/ref/vsynth1/dnxhd_720p
deleted file mode 100644
index 263843d..0000000
--- a/tests/ref/vsynth1/dnxhd_720p
+++ /dev/null
@@ -1,4 +0,0 @@
-81f5be451dc18cf8a1d333c7885de60b *./tests/data/vsynth1/dnxhd-720p.dnxhd
-2293760 ./tests/data/vsynth1/dnxhd-720p.dnxhd
-94b21e5e68ccf9471eff74afd0ebe319 *./tests/data/dnxhd_720p.vsynth1.out.yuv
-stddev: 6.32 PSNR: 32.11 MAXDIFF: 183 bytes: 760320/ 7603200
diff --git a/tests/ref/vsynth1/dnxhd_720p_10bit b/tests/ref/vsynth1/dnxhd_720p_10bit
deleted file mode 100644
index ad97b66..0000000
--- a/tests/ref/vsynth1/dnxhd_720p_10bit
+++ /dev/null
@@ -1,4 +0,0 @@
-b5e24a055af02edec8674333260214fd *./tests/data/vsynth1/dnxhd-720p-10bit.dnxhd
- 2293760 ./tests/data/vsynth1/dnxhd-720p-10bit.dnxhd
-4466ff3d73d01bbe75ea25001d379b63 *./tests/data/dnxhd_720p_10bit.vsynth1.out.yuv
-stddev: 6.27 PSNR: 32.18 MAXDIFF: 64 bytes: 760320/ 7603200
diff --git a/tests/ref/vsynth1/dnxhd_720p_rd b/tests/ref/vsynth1/dnxhd_720p_rd
deleted file mode 100644
index e77c725..0000000
--- a/tests/ref/vsynth1/dnxhd_720p_rd
+++ /dev/null
@@ -1,4 +0,0 @@
-1dc6e95925c4f3a230848ec17c02abed *./tests/data/vsynth1/dnxhd-720p-rd.dnxhd
-2293760 ./tests/data/vsynth1/dnxhd-720p-rd.dnxhd
-02972d2aec120ec1577ec9053d68ae0f *./tests/data/dnxhd_720p_rd.vsynth1.out.yuv
-stddev: 6.26 PSNR: 32.19 MAXDIFF: 65 bytes: 760320/ 7603200
diff --git a/tests/ref/vsynth1/dv b/tests/ref/vsynth1/dv
deleted file mode 100644
index c309bb2..0000000
--- a/tests/ref/vsynth1/dv
+++ /dev/null
@@ -1,4 +0,0 @@
-27ade3031b17214cf81c19cbf70f37d7 *./tests/data/vsynth1/dv.dv
-7200000 ./tests/data/vsynth1/dv.dv
-02ac7cdeab91d4d5621e7ce96dddc498 *./tests/data/dv.vsynth1.out.yuv
-stddev: 6.90 PSNR: 31.34 MAXDIFF: 76 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/dv50 b/tests/ref/vsynth1/dv50
deleted file mode 100644
index 9ae3385..0000000
--- a/tests/ref/vsynth1/dv50
+++ /dev/null
@@ -1,4 +0,0 @@
-26dba84f0ea895b914ef5b333d8394ac *./tests/data/vsynth1/dv50.dv
-14400000 ./tests/data/vsynth1/dv50.dv
-a2ff093e93ffed10f730fa21df02fc50 *./tests/data/dv50.vsynth1.out.yuv
-stddev: 1.72 PSNR: 43.38 MAXDIFF: 29 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/dv_411 b/tests/ref/vsynth1/dv_411
deleted file mode 100644
index 841c3fd..0000000
--- a/tests/ref/vsynth1/dv_411
+++ /dev/null
@@ -1,4 +0,0 @@
-bd67f2431db160d4bb6dcd791cea6efd *./tests/data/vsynth1/dv411.dv
-7200000 ./tests/data/vsynth1/dv411.dv
-b6640a3a572353f51284acb746eb00c4 *./tests/data/dv_411.vsynth1.out.yuv
-stddev: 30.76 PSNR: 18.37 MAXDIFF: 205 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/error b/tests/ref/vsynth1/error
deleted file mode 100644
index bc24d5b..0000000
--- a/tests/ref/vsynth1/error
+++ /dev/null
@@ -1,4 +0,0 @@
-7416dfd319f04044d4575dc9d1b406e1 *./tests/data/vsynth1/error-mpeg4-adv.avi
- 756836 ./tests/data/vsynth1/error-mpeg4-adv.avi
-79e94ba32b37759397362cbcb479d4d3 *./tests/data/error.vsynth1.out.yuv
-stddev: 18.36 PSNR: 22.85 MAXDIFF: 243 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/ffv1 b/tests/ref/vsynth1/ffv1
deleted file mode 100644
index bf90915..0000000
--- a/tests/ref/vsynth1/ffv1
+++ /dev/null
@@ -1,4 +0,0 @@
-67ddc7edde5cca49290245d881787890 *./tests/data/vsynth1/ffv1.avi
-2655376 ./tests/data/vsynth1/ffv1.avi
-c5ccac874dbf808e9088bc3107860042 *./tests/data/ffv1.vsynth1.out.yuv
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/ffvhuff b/tests/ref/vsynth1/ffvhuff
deleted file mode 100644
index 4a1ebdb..0000000
--- a/tests/ref/vsynth1/ffvhuff
+++ /dev/null
@@ -1,4 +0,0 @@
-da0c0bd12ac141c976ffa6a71832ab4b *./tests/data/vsynth1/ffvhuff.avi
- 5987208 ./tests/data/vsynth1/ffvhuff.avi
-c5ccac874dbf808e9088bc3107860042 *./tests/data/ffvhuff.vsynth1.out.yuv
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/flashsv b/tests/ref/vsynth1/flashsv
deleted file mode 100644
index 7920193..0000000
--- a/tests/ref/vsynth1/flashsv
+++ /dev/null
@@ -1,4 +0,0 @@
-97894502b4cb57aca1105b6333f72dae *./tests/data/vsynth1/flashsv.flv
-14681925 ./tests/data/vsynth1/flashsv.flv
-947cb24ec45a453348ae6fe3fa278071 *./tests/data/flashsv.vsynth1.out.yuv
-stddev: 2.85 PSNR: 39.03 MAXDIFF: 49 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/flv b/tests/ref/vsynth1/flv
deleted file mode 100644
index 17f5656..0000000
--- a/tests/ref/vsynth1/flv
+++ /dev/null
@@ -1,4 +0,0 @@
-d6a80659cedee7698aefe9c4a8285fa4 *./tests/data/vsynth1/flv.flv
-636269 ./tests/data/vsynth1/flv.flv
-5ab46d8dd01dbb1d63df2a84858a4b05 *./tests/data/flv.vsynth1.out.yuv
-stddev: 8.02 PSNR: 30.04 MAXDIFF: 105 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/h261 b/tests/ref/vsynth1/h261
deleted file mode 100644
index 36d04f1..0000000
--- a/tests/ref/vsynth1/h261
+++ /dev/null
@@ -1,4 +0,0 @@
-d155470b713aeebacb85980b0d5f2ce3 *./tests/data/vsynth1/h261.avi
-707588 ./tests/data/vsynth1/h261.avi
-716e83cb51afb1246bfaa80967df48ea *./tests/data/h261.vsynth1.out.yuv
-stddev: 9.11 PSNR: 28.93 MAXDIFF: 113 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/h263 b/tests/ref/vsynth1/h263
deleted file mode 100644
index 6351adc..0000000
--- a/tests/ref/vsynth1/h263
+++ /dev/null
@@ -1,4 +0,0 @@
-fb4dc9b9eac2628c56cb82cf332e1f58 *./tests/data/vsynth1/h263.avi
-659686 ./tests/data/vsynth1/h263.avi
-1a1ba9a3a63ec1a1a9585fded0a7c954 *./tests/data/h263.vsynth1.out.yuv
-stddev: 8.03 PSNR: 30.03 MAXDIFF: 103 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/h263p b/tests/ref/vsynth1/h263p
deleted file mode 100644
index 93df549..0000000
--- a/tests/ref/vsynth1/h263p
+++ /dev/null
@@ -1,4 +0,0 @@
-bbcadeceba295e1dad148aea1e57c370 *./tests/data/vsynth1/h263p.avi
-2328348 ./tests/data/vsynth1/h263p.avi
-9554cda00c3487ab3ffda2c3ea22fa2f *./tests/data/h263p.vsynth1.out.yuv
-stddev: 2.06 PSNR: 41.83 MAXDIFF: 20 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/huffyuv b/tests/ref/vsynth1/huffyuv
deleted file mode 100644
index fefc84a..0000000
--- a/tests/ref/vsynth1/huffyuv
+++ /dev/null
@@ -1,4 +0,0 @@
-ace2536fa169d835d0fb332abde28d51 *./tests/data/vsynth1/huffyuv.avi
-7933800 ./tests/data/vsynth1/huffyuv.avi
-c5ccac874dbf808e9088bc3107860042 *./tests/data/huffyuv.vsynth1.out.yuv
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/jpegls b/tests/ref/vsynth1/jpegls
deleted file mode 100644
index 636f7fc..0000000
--- a/tests/ref/vsynth1/jpegls
+++ /dev/null
@@ -1,4 +0,0 @@
-519e26bb1ac0f3db8f90b36537f2f760 *./tests/data/vsynth1/jpegls.avi
-9089812 ./tests/data/vsynth1/jpegls.avi
-947cb24ec45a453348ae6fe3fa278071 *./tests/data/jpegls.vsynth1.out.yuv
-stddev: 2.85 PSNR: 39.03 MAXDIFF: 49 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/ljpeg b/tests/ref/vsynth1/ljpeg
deleted file mode 100644
index 01d59e7..0000000
--- a/tests/ref/vsynth1/ljpeg
+++ /dev/null
@@ -1,4 +0,0 @@
-9092f306f165b98ab0bb4f576f198ad5 *./tests/data/vsynth1/ljpeg.avi
-6312936 ./tests/data/vsynth1/ljpeg.avi
-c5ccac874dbf808e9088bc3107860042 *./tests/data/ljpeg.vsynth1.out.yuv
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mjpeg b/tests/ref/vsynth1/mjpeg
deleted file mode 100644
index 63a0ff0..0000000
--- a/tests/ref/vsynth1/mjpeg
+++ /dev/null
@@ -1,4 +0,0 @@
-8bbf9513b1822945539f27a6eff3c7fa *./tests/data/vsynth1/mjpeg.avi
-1516140 ./tests/data/vsynth1/mjpeg.avi
-c6ae81b5b896e4d05ff584311aebdb18 *./tests/data/mjpeg.vsynth1.out.yuv
-stddev: 7.87 PSNR: 30.21 MAXDIFF: 63 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mpeg b/tests/ref/vsynth1/mpeg
deleted file mode 100644
index 7ae92f1..0000000
--- a/tests/ref/vsynth1/mpeg
+++ /dev/null
@@ -1,4 +0,0 @@
-1428744c6d5835f27506e69be4f837f4 *./tests/data/vsynth1/mpeg1.mpg
-712006 ./tests/data/vsynth1/mpeg1.mpg
-58f0c332bf689117b57fa629a2bc0d2b *./tests/data/mpeg.vsynth1.out.yuv
-stddev: 7.62 PSNR: 30.48 MAXDIFF: 84 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mpeg1b b/tests/ref/vsynth1/mpeg1b
deleted file mode 100644
index 897a0ce..0000000
--- a/tests/ref/vsynth1/mpeg1b
+++ /dev/null
@@ -1,4 +0,0 @@
-777639666b449ab0a7ef260511e40532 *./tests/data/vsynth1/mpeg1b.mpg
-1030337 ./tests/data/vsynth1/mpeg1b.mpg
-91a7fce732b34748e7bf753ebabe2483 *./tests/data/mpeg1b.vsynth1.out.yuv
-stddev: 6.30 PSNR: 32.13 MAXDIFF: 75 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mpeg2 b/tests/ref/vsynth1/mpeg2
deleted file mode 100644
index 0df3b7f..0000000
--- a/tests/ref/vsynth1/mpeg2
+++ /dev/null
@@ -1,4 +0,0 @@
-fbddea2368cd2028fc8db4dfd4682e94 *./tests/data/vsynth1/mpeg2.mpg
-728044 ./tests/data/vsynth1/mpeg2.mpg
-b41ca49c1a02e66ce64d262e2cdaec15 *./tests/data/mpeg2.vsynth1.out.yuv
-stddev: 7.65 PSNR: 30.45 MAXDIFF: 84 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mpeg2_422 b/tests/ref/vsynth1/mpeg2_422
deleted file mode 100644
index beef80b..0000000
--- a/tests/ref/vsynth1/mpeg2_422
+++ /dev/null
@@ -1,4 +0,0 @@
-af0cb75451aaa807beb5102707a98823 *./tests/data/vsynth1/mpeg2_422.mpg
-728200 ./tests/data/vsynth1/mpeg2_422.mpg
-29b518282493203e83b27a939795dc3a *./tests/data/mpeg2_422.vsynth1.out.yuv
-stddev: 63.33 PSNR: 12.10 MAXDIFF: 242 bytes: 10137600/ 7603200
diff --git a/tests/ref/vsynth1/mpeg2_idct_int b/tests/ref/vsynth1/mpeg2_idct_int
deleted file mode 100644
index be73750..0000000
--- a/tests/ref/vsynth1/mpeg2_idct_int
+++ /dev/null
@@ -1,4 +0,0 @@
-4c067397b504d65532d7779cd36f3f88 *./tests/data/vsynth1/mpeg2_idct_int.mpg
-725668 ./tests/data/vsynth1/mpeg2_idct_int.mpg
-9f7b065f98d57cdecf90e6f7a2524eb5 *./tests/data/mpeg2_idct_int.vsynth1.out.yuv
-stddev: 7.65 PSNR: 30.45 MAXDIFF: 81 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mpeg2_ilace b/tests/ref/vsynth1/mpeg2_ilace
deleted file mode 100644
index e05951f..0000000
--- a/tests/ref/vsynth1/mpeg2_ilace
+++ /dev/null
@@ -1,4 +0,0 @@
-ec3f6713c88a2b41f6c369fd64341077 *./tests/data/vsynth1/mpeg2i.mpg
-737473 ./tests/data/vsynth1/mpeg2i.mpg
-97615390fdd69abfcbc7e02df863a7d2 *./tests/data/mpeg2_ilace.vsynth1.out.yuv
-stddev: 7.67 PSNR: 30.43 MAXDIFF: 84 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mpeg2_ivlc_qprd b/tests/ref/vsynth1/mpeg2_ivlc_qprd
deleted file mode 100644
index c8a6694..0000000
--- a/tests/ref/vsynth1/mpeg2_ivlc_qprd
+++ /dev/null
@@ -1,4 +0,0 @@
-8f6b20714918e6443e0c03716ed06f0d *./tests/data/vsynth1/mpeg2ivlc-qprd.mpg
-783552 ./tests/data/vsynth1/mpeg2ivlc-qprd.mpg
-98eb9da15f880978e7f2ee1e7ce476ef *./tests/data/mpeg2_ivlc_qprd.vsynth1.out.yuv
-stddev: 10.07 PSNR: 28.06 MAXDIFF: 165 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mpeg2thread b/tests/ref/vsynth1/mpeg2thread
deleted file mode 100644
index a44c00d..0000000
--- a/tests/ref/vsynth1/mpeg2thread
+++ /dev/null
@@ -1,4 +0,0 @@
-ecd183706688bd977c9994c3d1b23d61 *./tests/data/vsynth1/mpeg2thread.mpg
-801313 ./tests/data/vsynth1/mpeg2thread.mpg
-d1658911ca83f5616c1d32abc40750de *./tests/data/mpeg2thread.vsynth1.out.yuv
-stddev: 7.63 PSNR: 30.48 MAXDIFF: 110 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mpeg2thread_ilace b/tests/ref/vsynth1/mpeg2thread_ilace
deleted file mode 100644
index 0667b68..0000000
--- a/tests/ref/vsynth1/mpeg2thread_ilace
+++ /dev/null
@@ -1,4 +0,0 @@
-23d600b026222253c2340e23300a4c02 *./tests/data/vsynth1/mpeg2threadivlc.mpg
-791773 ./tests/data/vsynth1/mpeg2threadivlc.mpg
-d1658911ca83f5616c1d32abc40750de *./tests/data/mpeg2thread_ilace.vsynth1.out.yuv
-stddev: 7.63 PSNR: 30.48 MAXDIFF: 110 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mpeg4 b/tests/ref/vsynth1/mpeg4
deleted file mode 100644
index b318e6f..0000000
--- a/tests/ref/vsynth1/mpeg4
+++ /dev/null
@@ -1,4 +0,0 @@
-59a9e2eed314abface66aaf1b45eb8f2 *./tests/data/vsynth1/odivx.mp4
-540180 ./tests/data/vsynth1/odivx.mp4
-8828a375448dc5c2215163ba70656f89 *./tests/data/mpeg4.vsynth1.out.yuv
-stddev: 7.97 PSNR: 30.10 MAXDIFF: 105 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mpeg4_adap b/tests/ref/vsynth1/mpeg4_adap
deleted file mode 100644
index 7513a22..0000000
--- a/tests/ref/vsynth1/mpeg4_adap
+++ /dev/null
@@ -1,4 +0,0 @@
-2d870c0da9ab2231ab5fc06981e70399 *./tests/data/vsynth1/mpeg4-adap.avi
-403456 ./tests/data/vsynth1/mpeg4-adap.avi
-fa2049396479b5f170aa764fed5b2a31 *./tests/data/mpeg4_adap.vsynth1.out.yuv
-stddev: 14.05 PSNR: 25.17 MAXDIFF: 184 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mpeg4_qpel b/tests/ref/vsynth1/mpeg4_qpel
deleted file mode 100644
index 51547d8..0000000
--- a/tests/ref/vsynth1/mpeg4_qpel
+++ /dev/null
@@ -1,4 +0,0 @@
-3bf17c3d04f52988386ce106a2a58976 *./tests/data/vsynth1/mpeg4-Q.avi
-860678 ./tests/data/vsynth1/mpeg4-Q.avi
-756928496245ecc701f79eebeec8e5e6 *./tests/data/mpeg4_qpel.vsynth1.out.yuv
-stddev: 5.63 PSNR: 33.12 MAXDIFF: 70 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mpeg4_qprd b/tests/ref/vsynth1/mpeg4_qprd
deleted file mode 100644
index aa3b506..0000000
--- a/tests/ref/vsynth1/mpeg4_qprd
+++ /dev/null
@@ -1,4 +0,0 @@
-d6b7e724a6ad66ab5e4c5a499218b40d *./tests/data/vsynth1/mpeg4-qprd.avi
-710944 ./tests/data/vsynth1/mpeg4-qprd.avi
-e65f4c7f343fe2bad1cac44b7da5f7c4 *./tests/data/mpeg4_qprd.vsynth1.out.yuv
-stddev: 9.79 PSNR: 28.31 MAXDIFF: 176 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mpeg4adv b/tests/ref/vsynth1/mpeg4adv
deleted file mode 100644
index 374f0b2..0000000
--- a/tests/ref/vsynth1/mpeg4adv
+++ /dev/null
@@ -1,4 +0,0 @@
-7d8eb01fd68d83d62a98585757704d47 *./tests/data/vsynth1/mpeg4-adv.avi
-589716 ./tests/data/vsynth1/mpeg4-adv.avi
-f8b226876b1b2c0b98fd6928fd9adbd8 *./tests/data/mpeg4adv.vsynth1.out.yuv
-stddev: 6.98 PSNR: 31.25 MAXDIFF: 84 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mpeg4nr b/tests/ref/vsynth1/mpeg4nr
deleted file mode 100644
index c821490..0000000
--- a/tests/ref/vsynth1/mpeg4nr
+++ /dev/null
@@ -1,4 +0,0 @@
-c02f54157ba08ca12ad979c6308212ad *./tests/data/vsynth1/mpeg4-nr.avi
-675638 ./tests/data/vsynth1/mpeg4-nr.avi
-d2b89d5958fb7331f6c9e5b7ecaaa5b6 *./tests/data/mpeg4nr.vsynth1.out.yuv
-stddev: 6.99 PSNR: 31.23 MAXDIFF: 86 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mpeg4thread b/tests/ref/vsynth1/mpeg4thread
deleted file mode 100644
index d04f436..0000000
--- a/tests/ref/vsynth1/mpeg4thread
+++ /dev/null
@@ -1,4 +0,0 @@
-4f4ea04faad7212374919aa1ec7ff994 *./tests/data/vsynth1/mpeg4-thread.avi
-774760 ./tests/data/vsynth1/mpeg4-thread.avi
-64b96cddf5301990e118978b3a3bcd0d *./tests/data/mpeg4thread.vsynth1.out.yuv
-stddev: 10.13 PSNR: 28.02 MAXDIFF: 183 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/msmpeg4 b/tests/ref/vsynth1/msmpeg4
deleted file mode 100644
index d94d3f0..0000000
--- a/tests/ref/vsynth1/msmpeg4
+++ /dev/null
@@ -1,4 +0,0 @@
-4b08952b0afceb17ee3db31b67f6b778 *./tests/data/vsynth1/msmpeg4.avi
-624718 ./tests/data/vsynth1/msmpeg4.avi
-5ca72c39e3fc5df8e62f223c869589f5 *./tests/data/msmpeg4.vsynth1.out.yuv
-stddev: 7.98 PSNR: 30.09 MAXDIFF: 104 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/msmpeg4v2 b/tests/ref/vsynth1/msmpeg4v2
deleted file mode 100644
index dde152d..0000000
--- a/tests/ref/vsynth1/msmpeg4v2
+++ /dev/null
@@ -1,4 +0,0 @@
-88957e35efcc718bce0307627ad3298d *./tests/data/vsynth1/msmpeg4v2.avi
-623788 ./tests/data/vsynth1/msmpeg4v2.avi
-c6ff1041a0ef62c2a2e5ef519e5e94c4 *./tests/data/msmpeg4v2.vsynth1.out.yuv
-stddev: 7.97 PSNR: 30.10 MAXDIFF: 105 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/prores b/tests/ref/vsynth1/prores
deleted file mode 100644
index 67ae0dc..0000000
--- a/tests/ref/vsynth1/prores
+++ /dev/null
@@ -1,4 +0,0 @@
-2566517b15c62887bd94daaab1b1a85b *./tests/data/vsynth1/prores.mov
-3859037 ./tests/data/vsynth1/prores.mov
-0a4153637d0cc0a88a8bcbf04cfaf8c6 *./tests/data/prores.vsynth1.out.yuv
-stddev: 3.17 PSNR: 38.09 MAXDIFF: 39 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/qtrle b/tests/ref/vsynth1/qtrle
deleted file mode 100644
index 002ee49..0000000
--- a/tests/ref/vsynth1/qtrle
+++ /dev/null
@@ -1,4 +0,0 @@
-7d75328a17e04796a39fe9be3a322946 *./tests/data/vsynth1/qtrle.mov
-15263232 ./tests/data/vsynth1/qtrle.mov
-243325fb2cae1a9245efd49aff936327 *./tests/data/qtrle.vsynth1.out.yuv
-stddev: 3.42 PSNR: 37.43 MAXDIFF: 48 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/rc b/tests/ref/vsynth1/rc
deleted file mode 100644
index be50952..0000000
--- a/tests/ref/vsynth1/rc
+++ /dev/null
@@ -1,4 +0,0 @@
-1c6dadf75f60f4ba59a0fe0b6eaedf57 *./tests/data/vsynth1/mpeg4-rc.avi
-830160 ./tests/data/vsynth1/mpeg4-rc.avi
-4d95e340db9bc57a559162c039f3784e *./tests/data/rc.vsynth1.out.yuv
-stddev: 10.24 PSNR: 27.92 MAXDIFF: 196 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/rgb b/tests/ref/vsynth1/rgb
deleted file mode 100644
index 10a0a13..0000000
--- a/tests/ref/vsynth1/rgb
+++ /dev/null
@@ -1,4 +0,0 @@
-05f0719cb52486d9a4beb9cfae3f2571 *./tests/data/vsynth1/rgb.avi
-15213260 ./tests/data/vsynth1/rgb.avi
-243325fb2cae1a9245efd49aff936327 *./tests/data/rgb.vsynth1.out.yuv
-stddev: 3.42 PSNR: 37.43 MAXDIFF: 48 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/roq b/tests/ref/vsynth1/roq
deleted file mode 100644
index 42456e4..0000000
--- a/tests/ref/vsynth1/roq
+++ /dev/null
@@ -1,4 +0,0 @@
-cf8b7b0e539bab3169c234ca63d71dd8 *./tests/data/vsynth1/roqav.roq
-101671 ./tests/data/vsynth1/roqav.roq
-0ad983c291b1ed373645c5b12a108c61 *./tests/data/roq.vsynth1.out.yuv
-stddev: 7.74 PSNR: 30.35 MAXDIFF: 89 bytes: 760320/ 7603200
diff --git a/tests/ref/vsynth1/rv10 b/tests/ref/vsynth1/rv10
deleted file mode 100644
index 9e0ceec..0000000
--- a/tests/ref/vsynth1/rv10
+++ /dev/null
@@ -1,4 +0,0 @@
-4d7e82de72a83905cf84b8abc3e70b8f *./tests/data/vsynth1/rv10.rm
-653905 ./tests/data/vsynth1/rv10.rm
-1a1ba9a3a63ec1a1a9585fded0a7c954 *./tests/data/rv10.vsynth1.out.yuv
-stddev: 8.03 PSNR: 30.03 MAXDIFF: 103 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/rv20 b/tests/ref/vsynth1/rv20
deleted file mode 100644
index d3b8814..0000000
--- a/tests/ref/vsynth1/rv20
+++ /dev/null
@@ -1,4 +0,0 @@
-81868601e602eee5b6d80f5ece4aaa98 *./tests/data/vsynth1/rv20.rm
-646016 ./tests/data/vsynth1/rv20.rm
-b45fdb0201b06f7649f44050e262c54c *./tests/data/rv20.vsynth1.out.yuv
-stddev: 8.26 PSNR: 29.79 MAXDIFF: 103 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/snow b/tests/ref/vsynth1/snow
deleted file mode 100644
index ac34760..0000000
--- a/tests/ref/vsynth1/snow
+++ /dev/null
@@ -1,4 +0,0 @@
-d593b3c1a9729ce6dd1721f58fa93712 *./tests/data/vsynth1/snow.avi
-136088 ./tests/data/vsynth1/snow.avi
-91021b7d6d7908648fe78cc1975af8c4 *./tests/data/snow.vsynth1.out.yuv
-stddev: 22.77 PSNR: 20.98 MAXDIFF: 172 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/snowll b/tests/ref/vsynth1/snowll
deleted file mode 100644
index 427e52d..0000000
--- a/tests/ref/vsynth1/snowll
+++ /dev/null
@@ -1,4 +0,0 @@
-6d29e8c06a645cdee45073c4f3d0004e *./tests/data/vsynth1/snow53.avi
-3419980 ./tests/data/vsynth1/snow53.avi
-c5ccac874dbf808e9088bc3107860042 *./tests/data/snowll.vsynth1.out.yuv
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/svq1 b/tests/ref/vsynth1/svq1
deleted file mode 100644
index 3137e3b..0000000
--- a/tests/ref/vsynth1/svq1
+++ /dev/null
@@ -1,4 +0,0 @@
-5c9d8734693f3cab57f61e76b5b6da7d *./tests/data/vsynth1/svq1.mov
-1334367 ./tests/data/vsynth1/svq1.mov
-9cc35c54b2c77d36bd7e308b393c1f81 *./tests/data/svq1.vsynth1.out.yuv
-stddev: 9.58 PSNR: 28.50 MAXDIFF: 210 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/v210 b/tests/ref/vsynth1/v210
deleted file mode 100644
index bb84c3e..0000000
--- a/tests/ref/vsynth1/v210
+++ /dev/null
@@ -1,4 +0,0 @@
-dd6c870a2a52c9e75ce61c3670e710e7 *./tests/data/vsynth1/v210.avi
-14752460 ./tests/data/vsynth1/v210.avi
-50973792d3f1abe04a51ee0121f077f2 *./tests/data/v210.vsynth1.out.yuv
-stddev: 1.85 PSNR: 42.78 MAXDIFF: 29 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/vref b/tests/ref/vsynth1/vref
deleted file mode 100644
index 2defdac..0000000
--- a/tests/ref/vsynth1/vref
+++ /dev/null
@@ -1,2 +0,0 @@
-c5ccac874dbf808e9088bc3107860042 *./tests/data/vsynth1.ref.yuv
-7603200 ./tests/data/vsynth1.ref.yuv
diff --git a/tests/ref/vsynth1/wmv1 b/tests/ref/vsynth1/wmv1
deleted file mode 100644
index 8c32ea8..0000000
--- a/tests/ref/vsynth1/wmv1
+++ /dev/null
@@ -1,4 +0,0 @@
-4f3461315776e5118866fa3819cff9b6 *./tests/data/vsynth1/wmv1.avi
-626908 ./tests/data/vsynth1/wmv1.avi
-5182edba5b5e0354b39ce4f3604b62da *./tests/data/wmv1.vsynth1.out.yuv
-stddev: 7.97 PSNR: 30.09 MAXDIFF: 110 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/wmv2 b/tests/ref/vsynth1/wmv2
deleted file mode 100644
index 8e1e88d..0000000
--- a/tests/ref/vsynth1/wmv2
+++ /dev/null
@@ -1,4 +0,0 @@
-13efda9d3811345aadc0632fc9a9332b *./tests/data/vsynth1/wmv2.avi
-659852 ./tests/data/vsynth1/wmv2.avi
-5182edba5b5e0354b39ce4f3604b62da *./tests/data/wmv2.vsynth1.out.yuv
-stddev: 7.97 PSNR: 30.09 MAXDIFF: 110 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/yuv b/tests/ref/vsynth1/yuv
deleted file mode 100644
index b98dda5..0000000
--- a/tests/ref/vsynth1/yuv
+++ /dev/null
@@ -1,4 +0,0 @@
-aa6b9e862aebcf8902a6d770e7729d59 *./tests/data/vsynth1/yuv.avi
-7610060 ./tests/data/vsynth1/yuv.avi
-c5ccac874dbf808e9088bc3107860042 *./tests/data/yuv.vsynth1.out.yuv
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/asv1 b/tests/ref/vsynth2/asv1
deleted file mode 100644
index 1d0385c..0000000
--- a/tests/ref/vsynth2/asv1
+++ /dev/null
@@ -1,4 +0,0 @@
-4eb34d2de25f67a2706456e999338fe9 *./tests/data/vsynth2/asv1.avi
-832512 ./tests/data/vsynth2/asv1.avi
-c96ff7fd17c52f99ddb7922a4cb9168f *./tests/data/asv1.vsynth2.out.yuv
-stddev: 10.47 PSNR: 27.73 MAXDIFF: 98 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/asv2 b/tests/ref/vsynth2/asv2
deleted file mode 100644
index 21ce40a..0000000
--- a/tests/ref/vsynth2/asv2
+++ /dev/null
@@ -1,4 +0,0 @@
-9649a4b68fb1107bad13e8a7574cc72d *./tests/data/vsynth2/asv2.avi
-789072 ./tests/data/vsynth2/asv2.avi
-74a78015b64b2cf8cb9da2e44f508a69 *./tests/data/asv2.vsynth2.out.yuv
-stddev: 10.28 PSNR: 27.89 MAXDIFF: 95 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/cljr b/tests/ref/vsynth2/cljr
deleted file mode 100644
index 562f35f..0000000
--- a/tests/ref/vsynth2/cljr
+++ /dev/null
@@ -1,4 +0,0 @@
-416ddcf73d2d993456f3c49f3eed4f1a *./tests/data/vsynth2/cljr.avi
- 5075660 ./tests/data/vsynth2/cljr.avi
-3a70ba2a535ef9c7fc6478b27a2cb58a *./tests/data/cljr.vsynth2.out.yuv
-stddev: 10.48 PSNR: 27.72 MAXDIFF: 64 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/dnxhd_1080i b/tests/ref/vsynth2/dnxhd_1080i
deleted file mode 100644
index b9a6fac..0000000
--- a/tests/ref/vsynth2/dnxhd_1080i
+++ /dev/null
@@ -1,4 +0,0 @@
-19a91b7da35cecf41e5e3cb322485627 *./tests/data/vsynth2/dnxhd-1080i.mov
-3031875 ./tests/data/vsynth2/dnxhd-1080i.mov
-3c559af629ae0a8fb1a9a0e4b4da7733 *./tests/data/dnxhd_1080i.vsynth2.out.yuv
-stddev: 1.31 PSNR: 45.77 MAXDIFF: 23 bytes: 760320/ 7603200
diff --git a/tests/ref/vsynth2/dnxhd_720p b/tests/ref/vsynth2/dnxhd_720p
deleted file mode 100644
index eab04c6..0000000
--- a/tests/ref/vsynth2/dnxhd_720p
+++ /dev/null
@@ -1,4 +0,0 @@
-58e07cc6ae0a2d36787044d0e82708a6 *./tests/data/vsynth2/dnxhd-720p.dnxhd
-2293760 ./tests/data/vsynth2/dnxhd-720p.dnxhd
-ab601eaafef74d80d3d20b780dddd836 *./tests/data/dnxhd_720p.vsynth2.out.yuv
-stddev: 1.36 PSNR: 45.45 MAXDIFF: 127 bytes: 760320/ 7603200
diff --git a/tests/ref/vsynth2/dnxhd_720p_10bit b/tests/ref/vsynth2/dnxhd_720p_10bit
deleted file mode 100644
index 60c0d84..0000000
--- a/tests/ref/vsynth2/dnxhd_720p_10bit
+++ /dev/null
@@ -1,4 +0,0 @@
-4b57da2c0c1280469ff3579f7151c227 *./tests/data/vsynth2/dnxhd-720p-10bit.dnxhd
- 2293760 ./tests/data/vsynth2/dnxhd-720p-10bit.dnxhd
-31a6aa8b8702e85fa3b48e73f035c4e4 *./tests/data/dnxhd_720p_10bit.vsynth2.out.yuv
-stddev: 1.35 PSNR: 45.46 MAXDIFF: 23 bytes: 760320/ 7603200
diff --git a/tests/ref/vsynth2/dnxhd_720p_rd b/tests/ref/vsynth2/dnxhd_720p_rd
deleted file mode 100644
index 2d5c4d5..0000000
--- a/tests/ref/vsynth2/dnxhd_720p_rd
+++ /dev/null
@@ -1,4 +0,0 @@
-092ffb7b8cf3c11556bb05dbb8b476ac *./tests/data/vsynth2/dnxhd-720p-rd.dnxhd
-2293760 ./tests/data/vsynth2/dnxhd-720p-rd.dnxhd
-33547ca318acff9448cba719cb99296d *./tests/data/dnxhd_720p_rd.vsynth2.out.yuv
-stddev: 1.32 PSNR: 45.66 MAXDIFF: 22 bytes: 760320/ 7603200
diff --git a/tests/ref/vsynth2/dv b/tests/ref/vsynth2/dv
deleted file mode 100644
index 6c010b9..0000000
--- a/tests/ref/vsynth2/dv
+++ /dev/null
@@ -1,4 +0,0 @@
-bfa766f89bfeabc0ae1044f3954bed52 *./tests/data/vsynth2/dv.dv
-7200000 ./tests/data/vsynth2/dv.dv
-7ec62bd3350a6848364669e6e1e4b9cc *./tests/data/dv.vsynth2.out.yuv
-stddev: 1.71 PSNR: 43.47 MAXDIFF: 33 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/dv50 b/tests/ref/vsynth2/dv50
deleted file mode 100644
index 7e0083b..0000000
--- a/tests/ref/vsynth2/dv50
+++ /dev/null
@@ -1,4 +0,0 @@
-61e31c79e8949b25c849753a0785b0d7 *./tests/data/vsynth2/dv50.dv
-14400000 ./tests/data/vsynth2/dv50.dv
-af3f2dd5ab62c1a1d98b07d4aeb6852f *./tests/data/dv50.vsynth2.out.yuv
-stddev: 0.82 PSNR: 49.82 MAXDIFF: 12 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/dv_411 b/tests/ref/vsynth2/dv_411
deleted file mode 100644
index 2340ef0..0000000
--- a/tests/ref/vsynth2/dv_411
+++ /dev/null
@@ -1,4 +0,0 @@
-00a9d8683ac6826af41bcf7223fb0389 *./tests/data/vsynth2/dv411.dv
-7200000 ./tests/data/vsynth2/dv411.dv
-7f9fa421028aabb11eaf4c6513a5a843 *./tests/data/dv_411.vsynth2.out.yuv
-stddev: 10.09 PSNR: 28.05 MAXDIFF: 60 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/error b/tests/ref/vsynth2/error
deleted file mode 100644
index 424c549..0000000
--- a/tests/ref/vsynth2/error
+++ /dev/null
@@ -1,4 +0,0 @@
-90e65096aa9ebafa3fe3f44a5a47cdc4 *./tests/data/vsynth2/error-mpeg4-adv.avi
- 176588 ./tests/data/vsynth2/error-mpeg4-adv.avi
-96baa9e4c24c837a3ba5abd8dd2cdd30 *./tests/data/error.vsynth2.out.yuv
-stddev: 8.98 PSNR: 29.06 MAXDIFF: 184 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/ffv1 b/tests/ref/vsynth2/ffv1
deleted file mode 100644
index d251af5..0000000
--- a/tests/ref/vsynth2/ffv1
+++ /dev/null
@@ -1,4 +0,0 @@
-d72b0960e162d4998b9acbabb07e99ab *./tests/data/vsynth2/ffv1.avi
-3525804 ./tests/data/vsynth2/ffv1.avi
-dde5895817ad9d219f79a52d0bdfb001 *./tests/data/ffv1.vsynth2.out.yuv
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/ffvhuff b/tests/ref/vsynth2/ffvhuff
deleted file mode 100644
index 47fc659..0000000
--- a/tests/ref/vsynth2/ffvhuff
+++ /dev/null
@@ -1,4 +0,0 @@
-d31aab445b24f738df45fdd7479d6dd7 *./tests/data/vsynth2/ffvhuff.avi
- 4988056 ./tests/data/vsynth2/ffvhuff.avi
-dde5895817ad9d219f79a52d0bdfb001 *./tests/data/ffvhuff.vsynth2.out.yuv
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/flashsv b/tests/ref/vsynth2/flashsv
deleted file mode 100644
index bfbb9e1..0000000
--- a/tests/ref/vsynth2/flashsv
+++ /dev/null
@@ -1,4 +0,0 @@
-0667077971e0cb63b5f49c580006e90e *./tests/data/vsynth2/flashsv.flv
-12368953 ./tests/data/vsynth2/flashsv.flv
-592b3321994e26a990deb3a0a1415de9 *./tests/data/flashsv.vsynth2.out.yuv
-stddev: 0.65 PSNR: 51.84 MAXDIFF: 14 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/flv b/tests/ref/vsynth2/flv
deleted file mode 100644
index 716177f..0000000
--- a/tests/ref/vsynth2/flv
+++ /dev/null
@@ -1,4 +0,0 @@
-2edc92093d36506bcc0a5c0e17e86113 *./tests/data/vsynth2/flv.flv
-131360 ./tests/data/vsynth2/flv.flv
-8999c8264fb0941561f64c4a736e9d88 *./tests/data/flv.vsynth2.out.yuv
-stddev: 5.33 PSNR: 33.59 MAXDIFF: 80 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/h261 b/tests/ref/vsynth2/h261
deleted file mode 100644
index 07c29ab..0000000
--- a/tests/ref/vsynth2/h261
+++ /dev/null
@@ -1,4 +0,0 @@
-dfd005d4c9030a0dc889c828a6408b9c *./tests/data/vsynth2/h261.avi
-191086 ./tests/data/vsynth2/h261.avi
-db7ceff174823b98834faa2320ca89ac *./tests/data/h261.vsynth2.out.yuv
-stddev: 6.37 PSNR: 32.03 MAXDIFF: 77 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/h263 b/tests/ref/vsynth2/h263
deleted file mode 100644
index 7e3fd33..0000000
--- a/tests/ref/vsynth2/h263
+++ /dev/null
@@ -1,4 +0,0 @@
-9a368687ab34c48079f11a202839a6bc *./tests/data/vsynth2/h263.avi
-160106 ./tests/data/vsynth2/h263.avi
-61213b91b359697ebcefb9e0a53ac54a *./tests/data/h263.vsynth2.out.yuv
-stddev: 5.43 PSNR: 33.42 MAXDIFF: 77 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/h263p b/tests/ref/vsynth2/h263p
deleted file mode 100644
index 314726f..0000000
--- a/tests/ref/vsynth2/h263p
+++ /dev/null
@@ -1,4 +0,0 @@
-c7644d40e9f40bbd98e5a978f9f94bb4 *./tests/data/vsynth2/h263p.avi
-868018 ./tests/data/vsynth2/h263p.avi
-4b0ee791f280029dc03c528f76f195d4 *./tests/data/h263p.vsynth2.out.yuv
-stddev: 1.91 PSNR: 42.50 MAXDIFF: 19 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/huffyuv b/tests/ref/vsynth2/huffyuv
deleted file mode 100644
index 740862a..0000000
--- a/tests/ref/vsynth2/huffyuv
+++ /dev/null
@@ -1,4 +0,0 @@
-56cd44907a48990e06bd065e189ff461 *./tests/data/vsynth2/huffyuv.avi
-6455232 ./tests/data/vsynth2/huffyuv.avi
-dde5895817ad9d219f79a52d0bdfb001 *./tests/data/huffyuv.vsynth2.out.yuv
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/jpegls b/tests/ref/vsynth2/jpegls
deleted file mode 100644
index e7fa2df..0000000
--- a/tests/ref/vsynth2/jpegls
+++ /dev/null
@@ -1,4 +0,0 @@
-4fc53937f048c900ae6d50fda9dba206 *./tests/data/vsynth2/jpegls.avi
-8334630 ./tests/data/vsynth2/jpegls.avi
-592b3321994e26a990deb3a0a1415de9 *./tests/data/jpegls.vsynth2.out.yuv
-stddev: 0.65 PSNR: 51.84 MAXDIFF: 14 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/ljpeg b/tests/ref/vsynth2/ljpeg
deleted file mode 100644
index 54c1d86..0000000
--- a/tests/ref/vsynth2/ljpeg
+++ /dev/null
@@ -1,4 +0,0 @@
-554a4a6a5a9058c588f8bf2de405bc70 *./tests/data/vsynth2/ljpeg.avi
-4766914 ./tests/data/vsynth2/ljpeg.avi
-dde5895817ad9d219f79a52d0bdfb001 *./tests/data/ljpeg.vsynth2.out.yuv
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mjpeg b/tests/ref/vsynth2/mjpeg
deleted file mode 100644
index adee328..0000000
--- a/tests/ref/vsynth2/mjpeg
+++ /dev/null
@@ -1,4 +0,0 @@
-89df32b46c977fb4cb140ec6c489dd76 *./tests/data/vsynth2/mjpeg.avi
-673224 ./tests/data/vsynth2/mjpeg.avi
-a96a4e15ffcb13e44360df642d049496 *./tests/data/mjpeg.vsynth2.out.yuv
-stddev: 4.32 PSNR: 35.40 MAXDIFF: 49 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mpeg b/tests/ref/vsynth2/mpeg
deleted file mode 100644
index 5a051c8..0000000
--- a/tests/ref/vsynth2/mpeg
+++ /dev/null
@@ -1,4 +0,0 @@
-73ca6f1deab02d1d67a0e8495c026a9e *./tests/data/vsynth2/mpeg1.mpg
-192783 ./tests/data/vsynth2/mpeg1.mpg
-56147e94b12f08df7213e610e177823d *./tests/data/mpeg.vsynth2.out.yuv
-stddev: 4.95 PSNR: 34.22 MAXDIFF: 57 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mpeg1b b/tests/ref/vsynth2/mpeg1b
deleted file mode 100644
index f51aa3f..0000000
--- a/tests/ref/vsynth2/mpeg1b
+++ /dev/null
@@ -1,4 +0,0 @@
-e026a2fef80c9679776d2b5c8be09338 *./tests/data/vsynth2/mpeg1b.mpg
-225198 ./tests/data/vsynth2/mpeg1b.mpg
-1150495f4bd487486ee53326c42d0bb8 *./tests/data/mpeg1b.vsynth2.out.yuv
-stddev: 4.10 PSNR: 35.86 MAXDIFF: 59 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mpeg2 b/tests/ref/vsynth2/mpeg2
deleted file mode 100644
index 5232eea..0000000
--- a/tests/ref/vsynth2/mpeg2
+++ /dev/null
@@ -1,4 +0,0 @@
-2d55ce623a7be4e8136f80266e487678 *./tests/data/vsynth2/mpeg2.mpg
-198667 ./tests/data/vsynth2/mpeg2.mpg
-b7cae8a1f751b821cddcbe4d5dbc518c *./tests/data/mpeg2.vsynth2.out.yuv
-stddev: 4.96 PSNR: 34.20 MAXDIFF: 59 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mpeg2_422 b/tests/ref/vsynth2/mpeg2_422
deleted file mode 100644
index c4e28dd..0000000
--- a/tests/ref/vsynth2/mpeg2_422
+++ /dev/null
@@ -1,4 +0,0 @@
-2c8e33c2d2efab86fc16a195f6877682 *./tests/data/vsynth2/mpeg2_422.mpg
-356124 ./tests/data/vsynth2/mpeg2_422.mpg
-de44597c6c470f3e7019b31245a3ff69 *./tests/data/mpeg2_422.vsynth2.out.yuv
-stddev: 54.55 PSNR: 13.39 MAXDIFF: 201 bytes: 10137600/ 7603200
diff --git a/tests/ref/vsynth2/mpeg2_idct_int b/tests/ref/vsynth2/mpeg2_idct_int
deleted file mode 100644
index 9900497..0000000
--- a/tests/ref/vsynth2/mpeg2_idct_int
+++ /dev/null
@@ -1,4 +0,0 @@
-f979bcca866e6e4cad5dc6cb06e56cfb *./tests/data/vsynth2/mpeg2_idct_int.mpg
-198041 ./tests/data/vsynth2/mpeg2_idct_int.mpg
-f6d9bf24ff8676a7f6076c05cd2c81a3 *./tests/data/mpeg2_idct_int.vsynth2.out.yuv
-stddev: 4.97 PSNR: 34.19 MAXDIFF: 58 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mpeg2_ilace b/tests/ref/vsynth2/mpeg2_ilace
deleted file mode 100644
index 99d80a4..0000000
--- a/tests/ref/vsynth2/mpeg2_ilace
+++ /dev/null
@@ -1,4 +0,0 @@
-f90197a8b6e62ae25f82625337f27240 *./tests/data/vsynth2/mpeg2i.mpg
-204579 ./tests/data/vsynth2/mpeg2i.mpg
-ea5057b60146c06d40449cdfc686bf13 *./tests/data/mpeg2_ilace.vsynth2.out.yuv
-stddev: 4.98 PSNR: 34.18 MAXDIFF: 65 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mpeg2_ivlc_qprd b/tests/ref/vsynth2/mpeg2_ivlc_qprd
deleted file mode 100644
index d8aa1ab..0000000
--- a/tests/ref/vsynth2/mpeg2_ivlc_qprd
+++ /dev/null
@@ -1,4 +0,0 @@
-1ba5efeb53fab7b4b71edc96d86f6c91 *./tests/data/vsynth2/mpeg2ivlc-qprd.mpg
-244694 ./tests/data/vsynth2/mpeg2ivlc-qprd.mpg
-b26e21599dee48a174bdbc40b2817e55 *./tests/data/mpeg2_ivlc_qprd.vsynth2.out.yuv
-stddev: 4.15 PSNR: 35.76 MAXDIFF: 74 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mpeg2thread b/tests/ref/vsynth2/mpeg2thread
deleted file mode 100644
index 7d7ed21..0000000
--- a/tests/ref/vsynth2/mpeg2thread
+++ /dev/null
@@ -1,4 +0,0 @@
-889c754a42d7689b228853e1ece6d345 *./tests/data/vsynth2/mpeg2thread.mpg
-179650 ./tests/data/vsynth2/mpeg2thread.mpg
-8c6a7ed2eb73bd18fd2bb9829464100d *./tests/data/mpeg2thread.vsynth2.out.yuv
-stddev: 4.72 PSNR: 34.65 MAXDIFF: 72 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mpeg2thread_ilace b/tests/ref/vsynth2/mpeg2thread_ilace
deleted file mode 100644
index 1320db9..0000000
--- a/tests/ref/vsynth2/mpeg2thread_ilace
+++ /dev/null
@@ -1,4 +0,0 @@
-10b900e32809758857c596d56746e00e *./tests/data/vsynth2/mpeg2threadivlc.mpg
-178801 ./tests/data/vsynth2/mpeg2threadivlc.mpg
-8c6a7ed2eb73bd18fd2bb9829464100d *./tests/data/mpeg2thread_ilace.vsynth2.out.yuv
-stddev: 4.72 PSNR: 34.65 MAXDIFF: 72 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mpeg4 b/tests/ref/vsynth2/mpeg4
deleted file mode 100644
index 8ccab86..0000000
--- a/tests/ref/vsynth2/mpeg4
+++ /dev/null
@@ -1,4 +0,0 @@
-8c9afbf564008a8ce6719cc3546deae1 *./tests/data/vsynth2/odivx.mp4
-119833 ./tests/data/vsynth2/odivx.mp4
-90a3577850239083a9042bef33c50e85 *./tests/data/mpeg4.vsynth2.out.yuv
-stddev: 5.34 PSNR: 33.57 MAXDIFF: 83 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mpeg4_adap b/tests/ref/vsynth2/mpeg4_adap
deleted file mode 100644
index b7a07de..0000000
--- a/tests/ref/vsynth2/mpeg4_adap
+++ /dev/null
@@ -1,4 +0,0 @@
-547e1849dcf910935ff6383ca49e5706 *./tests/data/vsynth2/mpeg4-adap.avi
-198510 ./tests/data/vsynth2/mpeg4-adap.avi
-4affb83f6adc94f31024b4f9e0168945 *./tests/data/mpeg4_adap.vsynth2.out.yuv
-stddev: 3.75 PSNR: 36.65 MAXDIFF: 71 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mpeg4_qpel b/tests/ref/vsynth2/mpeg4_qpel
deleted file mode 100644
index d1f4515..0000000
--- a/tests/ref/vsynth2/mpeg4_qpel
+++ /dev/null
@@ -1,4 +0,0 @@
-7680d2e7d34399dfdfb8a49cf1e10239 *./tests/data/vsynth2/mpeg4-Q.avi
-163688 ./tests/data/vsynth2/mpeg4-Q.avi
-26dc7c78955fa678fbf150e236eb5627 *./tests/data/mpeg4_qpel.vsynth2.out.yuv
-stddev: 3.97 PSNR: 36.14 MAXDIFF: 54 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mpeg4_qprd b/tests/ref/vsynth2/mpeg4_qprd
deleted file mode 100644
index 17eec96..0000000
--- a/tests/ref/vsynth2/mpeg4_qprd
+++ /dev/null
@@ -1,4 +0,0 @@
-fd5ab0f55dbc959316e32923e86290df *./tests/data/vsynth2/mpeg4-qprd.avi
-231458 ./tests/data/vsynth2/mpeg4-qprd.avi
-de8a883865e2dff7a51f66da6c48df48 *./tests/data/mpeg4_qprd.vsynth2.out.yuv
-stddev: 3.71 PSNR: 36.72 MAXDIFF: 61 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mpeg4adv b/tests/ref/vsynth2/mpeg4adv
deleted file mode 100644
index b47cbf1..0000000
--- a/tests/ref/vsynth2/mpeg4adv
+++ /dev/null
@@ -1,4 +0,0 @@
-dee7be19486a76d96c88d18eefba8f86 *./tests/data/vsynth2/mpeg4-adv.avi
-141546 ./tests/data/vsynth2/mpeg4-adv.avi
-3f3a21e9db85a9c0f7022f557a5374c1 *./tests/data/mpeg4adv.vsynth2.out.yuv
-stddev: 4.94 PSNR: 34.25 MAXDIFF: 69 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mpeg4nr b/tests/ref/vsynth2/mpeg4nr
deleted file mode 100644
index ec36d27..0000000
--- a/tests/ref/vsynth2/mpeg4nr
+++ /dev/null
@@ -1,4 +0,0 @@
-c41187c99588fb7229ad330b2f80d28b *./tests/data/vsynth2/mpeg4-nr.avi
-155044 ./tests/data/vsynth2/mpeg4-nr.avi
-f7fc191308679f709405e62271f5c65f *./tests/data/mpeg4nr.vsynth2.out.yuv
-stddev: 4.73 PSNR: 34.63 MAXDIFF: 64 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mpeg4thread b/tests/ref/vsynth2/mpeg4thread
deleted file mode 100644
index 63f355b..0000000
--- a/tests/ref/vsynth2/mpeg4thread
+++ /dev/null
@@ -1,4 +0,0 @@
-ba30d10ff70d46e7c5b7fa859ea1faa4 *./tests/data/vsynth2/mpeg4-thread.avi
-250140 ./tests/data/vsynth2/mpeg4-thread.avi
-5355deb8c7609a3f1ff2173aab1dee70 *./tests/data/mpeg4thread.vsynth2.out.yuv
-stddev: 3.69 PSNR: 36.78 MAXDIFF: 65 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/msmpeg4 b/tests/ref/vsynth2/msmpeg4
deleted file mode 100644
index 7620273..0000000
--- a/tests/ref/vsynth2/msmpeg4
+++ /dev/null
@@ -1,4 +0,0 @@
-26dee25a62a66daba4f38ac6bd8f4677 *./tests/data/vsynth2/msmpeg4.avi
-127680 ./tests/data/vsynth2/msmpeg4.avi
-0e1c6e25c71c6a8fa8e506e3d97ca4c9 *./tests/data/msmpeg4.vsynth2.out.yuv
-stddev: 5.33 PSNR: 33.59 MAXDIFF: 78 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/msmpeg4v2 b/tests/ref/vsynth2/msmpeg4v2
deleted file mode 100644
index 9fe913d..0000000
--- a/tests/ref/vsynth2/msmpeg4v2
+++ /dev/null
@@ -1,4 +0,0 @@
-c09815e40a9d260628e1ebad8b2b3774 *./tests/data/vsynth2/msmpeg4v2.avi
-129918 ./tests/data/vsynth2/msmpeg4v2.avi
-8920194f8bf8f9cdd6c65b3df9e1a292 *./tests/data/msmpeg4v2.vsynth2.out.yuv
-stddev: 5.33 PSNR: 33.59 MAXDIFF: 80 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/prores b/tests/ref/vsynth2/prores
deleted file mode 100644
index 44bd405..0000000
--- a/tests/ref/vsynth2/prores
+++ /dev/null
@@ -1,4 +0,0 @@
-28755ce05e812adbb8b7c180318ffba8 *./tests/data/vsynth2/prores.mov
-3884722 ./tests/data/vsynth2/prores.mov
-ca2f6c1162635dedfa468c90f1fdc0ef *./tests/data/prores.vsynth2.out.yuv
-stddev: 0.92 PSNR: 48.77 MAXDIFF: 10 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/qtrle b/tests/ref/vsynth2/qtrle
deleted file mode 100644
index 5dd0425..0000000
--- a/tests/ref/vsynth2/qtrle
+++ /dev/null
@@ -1,4 +0,0 @@
-4805f35ca6e03b9279cc18f3f7356366 *./tests/data/vsynth2/qtrle.mov
-14798419 ./tests/data/vsynth2/qtrle.mov
-b2418e0e3a9a8619b31219cbcf24dc82 *./tests/data/qtrle.vsynth2.out.yuv
-stddev: 1.26 PSNR: 46.06 MAXDIFF: 13 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/rc b/tests/ref/vsynth2/rc
deleted file mode 100644
index 14d9a6c..0000000
--- a/tests/ref/vsynth2/rc
+++ /dev/null
@@ -1,4 +0,0 @@
-c25ede9e268b834a09a63f5136cd1b95 *./tests/data/vsynth2/mpeg4-rc.avi
-226332 ./tests/data/vsynth2/mpeg4-rc.avi
-2b34e606af895b62a250de98749a19b0 *./tests/data/rc.vsynth2.out.yuv
-stddev: 4.23 PSNR: 35.60 MAXDIFF: 85 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/rgb b/tests/ref/vsynth2/rgb
deleted file mode 100644
index ea83470..0000000
--- a/tests/ref/vsynth2/rgb
+++ /dev/null
@@ -1,4 +0,0 @@
-f2e9c419023c743bf99aa5b2e55ad233 *./tests/data/vsynth2/rgb.avi
-15213260 ./tests/data/vsynth2/rgb.avi
-b2418e0e3a9a8619b31219cbcf24dc82 *./tests/data/rgb.vsynth2.out.yuv
-stddev: 1.26 PSNR: 46.06 MAXDIFF: 13 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/roq b/tests/ref/vsynth2/roq
deleted file mode 100644
index a9650de..0000000
--- a/tests/ref/vsynth2/roq
+++ /dev/null
@@ -1,4 +0,0 @@
-b46f899b2363065c60f3782ba1f8b7bd *./tests/data/vsynth2/roqav.roq
-92786 ./tests/data/vsynth2/roqav.roq
-e69fca960dd0911e9b8d589c13e11dc1 *./tests/data/roq.vsynth2.out.yuv
-stddev: 3.81 PSNR: 36.49 MAXDIFF: 54 bytes: 760320/ 7603200
diff --git a/tests/ref/vsynth2/rv10 b/tests/ref/vsynth2/rv10
deleted file mode 100644
index 75b9265..0000000
--- a/tests/ref/vsynth2/rv10
+++ /dev/null
@@ -1,4 +0,0 @@
-b1467b0e8d8cad730e36d1e8ab49d573 *./tests/data/vsynth2/rv10.rm
-154310 ./tests/data/vsynth2/rv10.rm
-61213b91b359697ebcefb9e0a53ac54a *./tests/data/rv10.vsynth2.out.yuv
-stddev: 5.43 PSNR: 33.42 MAXDIFF: 77 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/rv20 b/tests/ref/vsynth2/rv20
deleted file mode 100644
index 903881f..0000000
--- a/tests/ref/vsynth2/rv20
+++ /dev/null
@@ -1,4 +0,0 @@
-96acb098850b9bf309f89e48b08fe96f *./tests/data/vsynth2/rv20.rm
-153302 ./tests/data/vsynth2/rv20.rm
-46f314e70d9bac2e7d82cfc230534977 *./tests/data/rv20.vsynth2.out.yuv
-stddev: 5.48 PSNR: 33.35 MAXDIFF: 81 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/snow b/tests/ref/vsynth2/snow
deleted file mode 100644
index 922110b..0000000
--- a/tests/ref/vsynth2/snow
+++ /dev/null
@@ -1,4 +0,0 @@
-af651d8ef0a66257ac8b2ef8b229f27b *./tests/data/vsynth2/snow.avi
-57700 ./tests/data/vsynth2/snow.avi
-8890189af71a0dd3447c4e8424c9a76b *./tests/data/snow.vsynth2.out.yuv
-stddev: 10.47 PSNR: 27.72 MAXDIFF: 119 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/snowll b/tests/ref/vsynth2/snowll
deleted file mode 100644
index 0eb4945..0000000
--- a/tests/ref/vsynth2/snowll
+++ /dev/null
@@ -1,4 +0,0 @@
-a8fccf278bbb17d37a756ecf11672b09 *./tests/data/vsynth2/snow53.avi
-2721758 ./tests/data/vsynth2/snow53.avi
-dde5895817ad9d219f79a52d0bdfb001 *./tests/data/snowll.vsynth2.out.yuv
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/svq1 b/tests/ref/vsynth2/svq1
deleted file mode 100644
index 8adca64..0000000
--- a/tests/ref/vsynth2/svq1
+++ /dev/null
@@ -1,4 +0,0 @@
-138ad38281570f1a3b68d63ed896435d *./tests/data/vsynth2/svq1.mov
-766851 ./tests/data/vsynth2/svq1.mov
-aa03471dac3f49455a33a2b19fda1098 *./tests/data/svq1.vsynth2.out.yuv
-stddev: 3.23 PSNR: 37.93 MAXDIFF: 61 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/v210 b/tests/ref/vsynth2/v210
deleted file mode 100644
index 31160bd..0000000
--- a/tests/ref/vsynth2/v210
+++ /dev/null
@@ -1,4 +0,0 @@
-db0579bd46e1ba133ff86c0f7cdd761f *./tests/data/vsynth2/v210.avi
-14752460 ./tests/data/vsynth2/v210.avi
-a627fb50c8276200fd71383977d87ca3 *./tests/data/v210.vsynth2.out.yuv
-stddev: 0.34 PSNR: 57.43 MAXDIFF: 6 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/vref b/tests/ref/vsynth2/vref
deleted file mode 100644
index 8f83b6c..0000000
--- a/tests/ref/vsynth2/vref
+++ /dev/null
@@ -1,2 +0,0 @@
-dde5895817ad9d219f79a52d0bdfb001 *./tests/data/vsynth2.ref.yuv
-7603200 ./tests/data/vsynth2.ref.yuv
diff --git a/tests/ref/vsynth2/wmv1 b/tests/ref/vsynth2/wmv1
deleted file mode 100644
index 12c3f57..0000000
--- a/tests/ref/vsynth2/wmv1
+++ /dev/null
@@ -1,4 +0,0 @@
-1011e26e7d351c96d7bbfe106d831b69 *./tests/data/vsynth2/wmv1.avi
-129530 ./tests/data/vsynth2/wmv1.avi
-81eee429b665254d19a06607463c0b5e *./tests/data/wmv1.vsynth2.out.yuv
-stddev: 5.33 PSNR: 33.60 MAXDIFF: 77 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/wmv2 b/tests/ref/vsynth2/wmv2
deleted file mode 100644
index 27fcd12..0000000
--- a/tests/ref/vsynth2/wmv2
+++ /dev/null
@@ -1,4 +0,0 @@
-1f6598e9776ed00aebdc44cc8d48cb7c *./tests/data/vsynth2/wmv2.avi
-129860 ./tests/data/vsynth2/wmv2.avi
-81eee429b665254d19a06607463c0b5e *./tests/data/wmv2.vsynth2.out.yuv
-stddev: 5.33 PSNR: 33.60 MAXDIFF: 77 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/yuv b/tests/ref/vsynth2/yuv
deleted file mode 100644
index 6593ce9..0000000
--- a/tests/ref/vsynth2/yuv
+++ /dev/null
@@ -1,4 +0,0 @@
-30a400773ab26f2c83e469198b156f1d *./tests/data/vsynth2/yuv.avi
-7610060 ./tests/data/vsynth2/yuv.avi
-dde5895817ad9d219f79a52d0bdfb001 *./tests/data/yuv.vsynth2.out.yuv
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
diff --git a/tests/regression-funcs.sh b/tests/regression-funcs.sh
index 3889129..ce5aee8 100755
--- a/tests/regression-funcs.sh
+++ b/tests/regression-funcs.sh
@@ -20,17 +20,13 @@ outfile="$datadir/$test_ref/"
# various files
avconv="$target_exec ${target_path}/avconv"
-tiny_psnr="tests/tiny_psnr"
raw_src="${target_path}/$raw_src_dir/%02d.pgm"
raw_dst="$datadir/$this.out.yuv"
-raw_ref="$datadir/$test_ref.ref.yuv"
pcm_src="$target_datadir/asynth1.sw"
-pcm_dst="$datadir/$this.out.wav"
-pcm_ref="$datadir/$test_ref.ref.wav"
crcfile="$datadir/$this.crc"
target_crcfile="$target_datadir/$this.crc"
-cleanfiles="$raw_dst $pcm_dst $crcfile"
+cleanfiles="$raw_dst $crcfile"
trap 'rm -f -- $cleanfiles' EXIT
mkdir -p "$datadir"
@@ -62,28 +58,7 @@ do_avconv()
set -- $* ${target_path}/$f
run_avconv $*
do_md5sum $f
- if [ $f = $raw_dst ] ; then
- $tiny_psnr $f $raw_ref
- elif [ $f = $pcm_dst ] ; then
- $tiny_psnr $f $pcm_ref 2
- else
- wc -c $f
- fi
-}
-
-do_avconv_nomd5()
-{
- f="$1"
- shift
- set -- $* ${target_path}/$f
- run_avconv $*
- if [ $f = $raw_dst ] ; then
- $tiny_psnr $f $raw_ref
- elif [ $f = $pcm_dst ] ; then
- $tiny_psnr $f $pcm_ref 2
- else
- wc -c $f
- fi
+ echo $(wc -c $f)
}
do_avconv_crc()
@@ -93,25 +68,3 @@ do_avconv_crc()
run_avconv $* -f crc "$target_crcfile"
echo "$f $(cat $crcfile)"
}
-
-do_video_decoding()
-{
- do_avconv $raw_dst $DEC_OPTS $1 -i $target_path/$file -f rawvideo $ENC_OPTS $2
-}
-
-do_video_encoding()
-{
- file=${outfile}$1
- do_avconv $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $ENC_OPTS $2
-}
-
-do_audio_encoding()
-{
- file=${outfile}$1
- do_avconv $file $DEC_OPTS -ac 2 -ar 44100 -f s16le -i $pcm_src -ab 128k $ENC_OPTS $2
-}
-
-do_audio_decoding()
-{
- do_avconv $pcm_dst $DEC_OPTS -i $target_path/$file -sample_fmt s16 -f wav
-}
diff --git a/tests/rotozoom.c b/tests/rotozoom.c
index 9ce45cd..69c88c2 100644
--- a/tests/rotozoom.c
+++ b/tests/rotozoom.c
@@ -24,6 +24,8 @@
#include <stdio.h>
#include <inttypes.h>
+#include "utils.c"
+
#define FIXP (1 << 16)
#define MY_PI 205887 // (M_PI * FIX)
@@ -53,136 +55,12 @@ static int64_t int_sin(int64_t a)
return a - int_pow(a, 3) / 6 + int_pow(a, 5) / 120 - int_pow(a, 7) / 5040;
}
-#define SCALEBITS 8
-#define ONE_HALF (1 << (SCALEBITS - 1))
-#define FIX(x) ((int) ((x) * (1L << SCALEBITS) + 0.5))
-
-static void rgb24_to_yuv420p(unsigned char *lum, unsigned char *cb,
- unsigned char *cr, unsigned char *src,
- int width, int height)
-{
- int wrap, wrap3, x, y;
- int r, g, b, r1, g1, b1;
- unsigned char *p;
-
- wrap = width;
- wrap3 = width * 3;
- p = src;
- for (y = 0; y < height; y += 2) {
- for (x = 0; x < width; x += 2) {
- r = p[0];
- g = p[1];
- b = p[2];
- r1 = r;
- g1 = g;
- b1 = b;
- lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
- FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
- r = p[3];
- g = p[4];
- b = p[5];
- r1 += r;
- g1 += g;
- b1 += b;
- lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
- FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
- p += wrap3;
- lum += wrap;
-
- r = p[0];
- g = p[1];
- b = p[2];
- r1 += r;
- g1 += g;
- b1 += b;
- lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
- FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
- r = p[3];
- g = p[4];
- b = p[5];
- r1 += r;
- g1 += g;
- b1 += b;
- lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
- FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
-
- cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +
- FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
- cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 -
- FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
-
- cb++;
- cr++;
- p += -wrap3 + 2 * 3;
- lum += -wrap + 2;
- }
- p += wrap3;
- lum += wrap;
- }
-}
+static unsigned char tab_r[256 * 256];
+static unsigned char tab_g[256 * 256];
+static unsigned char tab_b[256 * 256];
-/* cif format */
-#define DEFAULT_WIDTH 352
-#define DEFAULT_HEIGHT 288
-#define DEFAULT_NB_PICT 50
-
-static void pgmyuv_save(const char *filename, int w, int h,
- unsigned char *rgb_tab)
-{
- FILE *f;
- int i, h2, w2;
- unsigned char *cb, *cr;
- unsigned char *lum_tab, *cb_tab, *cr_tab;
-
- lum_tab = malloc(w * h);
- cb_tab = malloc(w * h / 4);
- cr_tab = malloc(w * h / 4);
-
- rgb24_to_yuv420p(lum_tab, cb_tab, cr_tab, rgb_tab, w, h);
-
- f = fopen(filename, "wb");
- fprintf(f, "P5\n%d %d\n%d\n", w, h * 3 / 2, 255);
- fwrite(lum_tab, 1, w * h, f);
- h2 = h / 2;
- w2 = w / 2;
- cb = cb_tab;
- cr = cr_tab;
- for (i = 0; i < h2; i++) {
- fwrite(cb, 1, w2, f);
- fwrite(cr, 1, w2, f);
- cb += w2;
- cr += w2;
- }
- fclose(f);
-
- free(lum_tab);
- free(cb_tab);
- free(cr_tab);
-}
-
-unsigned char *rgb_tab;
-int width, height, wrap;
-
-static void put_pixel(int x, int y, int r, int g, int b)
-{
- unsigned char *p;
-
- if (x < 0 || x >= width ||
- y < 0 || y >= height)
- return;
-
- p = rgb_tab + y * wrap + x * 3;
- p[0] = r;
- p[1] = g;
- p[2] = b;
-}
-
-unsigned char tab_r[256 * 256];
-unsigned char tab_g[256 * 256];
-unsigned char tab_b[256 * 256];
-
-int h_cos[360];
-int h_sin[360];
+static int h_cos[360];
+static int h_sin[360];
static int ipol(uint8_t *src, int x, int y)
{
@@ -280,13 +158,17 @@ int main(int argc, char **argv)
{
int w, h, i;
char buf[1024];
+ int isdir = 0;
if (argc != 3) {
- printf("usage: %s directory/ image.pnm\n"
+ printf("usage: %s image.pnm file|dir\n"
"generate a test video stream\n", argv[0]);
return 1;
}
+ if (!freopen(argv[2], "wb", stdout))
+ isdir = 1;
+
w = DEFAULT_WIDTH;
h = DEFAULT_HEIGHT;
@@ -295,13 +177,17 @@ int main(int argc, char **argv)
width = w;
height = h;
- if (init_demo(argv[2]))
+ if (init_demo(argv[1]))
return 1;
for (i = 0; i < DEFAULT_NB_PICT; i++) {
- snprintf(buf, sizeof(buf), "%s%02d.pgm", argv[1], i);
gen_image(i, w, h);
- pgmyuv_save(buf, w, h, rgb_tab);
+ if (isdir) {
+ snprintf(buf, sizeof(buf), "%s%02d.pgm", argv[2], i);
+ pgmyuv_save(buf, w, h, rgb_tab);
+ } else {
+ pgmyuv_save(NULL, w, h, rgb_tab);
+ }
}
free(rgb_tab);
diff --git a/tests/utils.c b/tests/utils.c
new file mode 100644
index 0000000..2fdc491
--- /dev/null
+++ b/tests/utils.c
@@ -0,0 +1,170 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define SCALEBITS 8
+#define ONE_HALF (1 << (SCALEBITS - 1))
+#define FIX(x) ((int) ((x) * (1L << SCALEBITS) + 0.5))
+
+#define err_if(expr) do { \
+ if (expr) { \
+ fprintf(stderr, "%s\n", strerror(errno)); \
+ exit(1); \
+ } \
+} while (0)
+
+static void rgb24_to_yuv420p(unsigned char *lum, unsigned char *cb,
+ unsigned char *cr, unsigned char *src,
+ int width, int height)
+{
+ int wrap, wrap3, x, y;
+ int r, g, b, r1, g1, b1;
+ unsigned char *p;
+
+ wrap = width;
+ wrap3 = width * 3;
+ p = src;
+ for (y = 0; y < height; y += 2) {
+ for (x = 0; x < width; x += 2) {
+ r = p[0];
+ g = p[1];
+ b = p[2];
+ r1 = r;
+ g1 = g;
+ b1 = b;
+ lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
+ FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
+ r = p[3];
+ g = p[4];
+ b = p[5];
+ r1 += r;
+ g1 += g;
+ b1 += b;
+ lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
+ FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
+ p += wrap3;
+ lum += wrap;
+
+ r = p[0];
+ g = p[1];
+ b = p[2];
+ r1 += r;
+ g1 += g;
+ b1 += b;
+ lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
+ FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
+ r = p[3];
+ g = p[4];
+ b = p[5];
+ r1 += r;
+ g1 += g;
+ b1 += b;
+ lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
+ FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
+
+ cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +
+ FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
+ cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 -
+ FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
+
+ cb++;
+ cr++;
+ p += -wrap3 + 2 * 3;
+ lum += -wrap + 2;
+ }
+ p += wrap3;
+ lum += wrap;
+ }
+}
+
+/* cif format */
+#define DEFAULT_WIDTH 352
+#define DEFAULT_HEIGHT 288
+#define DEFAULT_NB_PICT 50
+
+static void pgmyuv_save(const char *filename, int w, int h,
+ unsigned char *rgb_tab)
+{
+ FILE *f;
+ int i, h2, w2;
+ unsigned char *cb, *cr;
+ unsigned char *lum_tab, *cb_tab, *cr_tab;
+
+ lum_tab = malloc(w * h);
+ cb_tab = malloc(w * h / 4);
+ cr_tab = malloc(w * h / 4);
+
+ rgb24_to_yuv420p(lum_tab, cb_tab, cr_tab, rgb_tab, w, h);
+
+ if (filename) {
+ f = fopen(filename, "wb");
+ fprintf(f, "P5\n%d %d\n%d\n", w, h * 3 / 2, 255);
+ } else {
+ f = stdout;
+ }
+
+ err_if(fwrite(lum_tab, 1, w * h, f) != w * h);
+ h2 = h / 2;
+ w2 = w / 2;
+ cb = cb_tab;
+ cr = cr_tab;
+
+ if (filename) {
+ for (i = 0; i < h2; i++) {
+ err_if(fwrite(cb, 1, w2, f) != w2);
+ err_if(fwrite(cr, 1, w2, f) != w2);
+ cb += w2;
+ cr += w2;
+ }
+ fclose(f);
+ } else {
+ for (i = 0; i < h2; i++) {
+ err_if(fwrite(cb, 1, w2, f) != w2);
+ cb += w2;
+ }
+ for (i = 0; i < h2; i++) {
+ err_if(fwrite(cr, 1, w2, f) != w2);
+ cr += w2;
+ }
+ }
+
+ free(lum_tab);
+ free(cb_tab);
+ free(cr_tab);
+}
+
+static unsigned char *rgb_tab;
+static int width, height, wrap;
+
+static void put_pixel(int x, int y, int r, int g, int b)
+{
+ unsigned char *p;
+
+ if (x < 0 || x >= width ||
+ y < 0 || y >= height)
+ return;
+
+ p = rgb_tab + y * wrap + x * 3;
+ p[0] = r;
+ p[1] = g;
+ p[2] = b;
+}
diff --git a/tests/videogen.c b/tests/videogen.c
index 1aad700..0b7f67e 100644
--- a/tests/videogen.c
+++ b/tests/videogen.c
@@ -25,134 +25,7 @@
#include <stdint.h>
#include <stdio.h>
-#define SCALEBITS 8
-#define ONE_HALF (1 << (SCALEBITS - 1))
-#define FIX(x) ((int) ((x) * (1L << SCALEBITS) + 0.5))
-
-static void rgb24_to_yuv420p(uint8_t *lum, uint8_t *cb, uint8_t *cr,
- uint8_t *src, int width, int height)
-{
- int wrap, wrap3, x, y;
- int r, g, b, r1, g1, b1;
- uint8_t *p;
-
- wrap = width;
- wrap3 = width * 3;
- p = src;
- for (y = 0; y < height; y += 2) {
- for (x = 0; x < width; x += 2) {
- r = p[0];
- g = p[1];
- b = p[2];
- r1 = r;
- g1 = g;
- b1 = b;
- lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
- FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
- r = p[3];
- g = p[4];
- b = p[5];
- r1 += r;
- g1 += g;
- b1 += b;
- lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
- FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
- p += wrap3;
- lum += wrap;
-
- r = p[0];
- g = p[1];
- b = p[2];
- r1 += r;
- g1 += g;
- b1 += b;
- lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
- FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
- r = p[3];
- g = p[4];
- b = p[5];
- r1 += r;
- g1 += g;
- b1 += b;
- lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
- FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
-
- cb[0] = 128 + ((- FIX(0.16874) * r1 -
- FIX(0.33126) * g1 +
- FIX(0.50000) * b1 +
- 4 * ONE_HALF - 1)
- >> (SCALEBITS + 2));
- cr[0] = 128 + ((FIX(0.50000) * r1 -
- FIX(0.41869) * g1 -
- FIX(0.08131) * b1 +
- 4 * ONE_HALF - 1)
- >> (SCALEBITS + 2));
-
- cb++;
- cr++;
- p += -wrap3 + 2 * 3;
- lum += -wrap + 2;
- }
- p += wrap3;
- lum += wrap;
- }
-}
-
-/* cif format */
-#define DEFAULT_WIDTH 352
-#define DEFAULT_HEIGHT 288
-#define DEFAULT_NB_PICT 50 /* 2 seconds */
-
-static void pgmyuv_save(const char *filename, int w, int h,
- unsigned char *rgb_tab)
-{
- FILE *f;
- int i, h2, w2;
- unsigned char *cb, *cr;
- unsigned char *lum_tab, *cb_tab, *cr_tab;
-
- lum_tab = malloc(w * h);
- cb_tab = malloc((w * h) / 4);
- cr_tab = malloc((w * h) / 4);
-
- rgb24_to_yuv420p(lum_tab, cb_tab, cr_tab, rgb_tab, w, h);
-
- f = fopen(filename, "wb");
- fprintf(f, "P5\n%d %d\n%d\n", w, (h * 3) / 2, 255);
- fwrite(lum_tab, 1, w * h, f);
- h2 = h / 2;
- w2 = w / 2;
- cb = cb_tab;
- cr = cr_tab;
- for (i = 0; i < h2; i++) {
- fwrite(cb, 1, w2, f);
- fwrite(cr, 1, w2, f);
- cb += w2;
- cr += w2;
- }
- fclose(f);
-
- free(lum_tab);
- free(cb_tab);
- free(cr_tab);
-}
-
-unsigned char *rgb_tab;
-int width, height, wrap;
-
-static void put_pixel(int x, int y, int r, int g, int b)
-{
- unsigned char *p;
-
- if (x < 0 || x >= width ||
- y < 0 || y >= height)
- return;
-
- p = rgb_tab + y * wrap + x * 3;
- p[0] = r;
- p[1] = g;
- p[2] = b;
-}
+#include "utils.c"
static unsigned int myrnd(unsigned int *seed_ptr, int n)
{
@@ -200,9 +73,9 @@ typedef struct VObj {
int r, g, b;
} VObj;
-VObj objs[NB_OBJS];
+static VObj objs[NB_OBJS];
-unsigned int seed = 1;
+static unsigned int seed = 1;
static void gen_image(int num, int w, int h)
{
@@ -272,13 +145,17 @@ int main(int argc, char **argv)
{
int w, h, i;
char buf[1024];
+ int isdir = 0;
if (argc != 2) {
- printf("usage: %s file\n"
+ printf("usage: %s file|dir\n"
"generate a test video stream\n", argv[0]);
exit(1);
}
+ if (!freopen(argv[1], "wb", stdout))
+ isdir = 1;
+
w = DEFAULT_WIDTH;
h = DEFAULT_HEIGHT;
@@ -288,9 +165,13 @@ int main(int argc, char **argv)
height = h;
for (i = 0; i < DEFAULT_NB_PICT; i++) {
- snprintf(buf, sizeof(buf), "%s%02d.pgm", argv[1], i);
gen_image(i, w, h);
- pgmyuv_save(buf, w, h, rgb_tab);
+ if (isdir) {
+ snprintf(buf, sizeof(buf), "%s%02d.pgm", argv[1], i);
+ pgmyuv_save(buf, w, h, rgb_tab);
+ } else {
+ pgmyuv_save(NULL, w, h, rgb_tab);
+ }
}
free(rgb_tab);
diff --git a/tools/aviocat.c b/tools/aviocat.c
index f5da526..52a96bd 100644
--- a/tools/aviocat.c
+++ b/tools/aviocat.c
@@ -20,8 +20,8 @@
#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
+#include "libavutil/time.h"
#include "libavformat/avformat.h"
static int usage(const char *argv0, int ret)
@@ -82,7 +82,7 @@ int main(int argc, char **argv)
if (bps) {
avio_flush(output);
while ((av_gettime() - start_time) * bps / AV_TIME_BASE < stream_pos)
- usleep(50 * 1000);
+ av_usleep(50 * 1000);
}
}
diff --git a/tools/graph2dot.c b/tools/graph2dot.c
index a52416d..6ea2f32 100644
--- a/tools/graph2dot.c
+++ b/tools/graph2dot.c
@@ -80,7 +80,7 @@ static void print_digraph(FILE *outfile, AVFilterGraph *graph)
av_get_channel_layout_string(buf, sizeof(buf), -1,
link->channel_layout);
fprintf(outfile,
- " [ label= \"fmt:%s sr:%"PRId64 " cl:%s\" ]",
+ " [ label= \"fmt:%s sr:%d cl:%s\" ]",
av_get_sample_fmt_name(link->format),
link->sample_rate, buf);
}
diff --git a/tools/ismindex.c b/tools/ismindex.c
index 5980869..54c49dc 100644
--- a/tools/ismindex.c
+++ b/tools/ismindex.c
@@ -209,10 +209,14 @@ static int read_mfra(struct VideoFiles *files, int start_index,
avio_seek(f, avio_size(f) - 4, SEEK_SET);
mfra_size = avio_rb32(f);
avio_seek(f, -mfra_size, SEEK_CUR);
- if (avio_rb32(f) != mfra_size)
+ if (avio_rb32(f) != mfra_size) {
+ err = AVERROR_INVALIDDATA;
goto fail;
- if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a'))
+ }
+ if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
+ err = AVERROR_INVALIDDATA;
goto fail;
+ }
while (!read_tfra(files, start_index, f)) {
/* Empty */
}
@@ -223,6 +227,8 @@ static int read_mfra(struct VideoFiles *files, int start_index,
fail:
if (f)
avio_close(f);
+ if (err)
+ fprintf(stderr, "Unable to read the MFRA atom in %s\n", file);
return err;
}
@@ -355,7 +361,7 @@ static int handle_file(struct VideoFiles *files, const char *file, int split)
avformat_close_input(&ctx);
- read_mfra(files, orig_files, file, split);
+ err = read_mfra(files, orig_files, file, split);
fail:
if (ctx)
@@ -420,6 +426,7 @@ static void output_client_manifest(struct VideoFiles *files,
"Duration=\"%"PRId64 "\">\n", files->duration * 10);
if (files->video_file >= 0) {
struct VideoFile *vf = files->files[files->video_file];
+ struct VideoFile *first_vf = vf;
int index = 0;
fprintf(out,
"\t<StreamIndex Type=\"video\" QualityLevels=\"%d\" "
@@ -439,15 +446,26 @@ static void output_client_manifest(struct VideoFiles *files,
fprintf(out, "%02X", vf->codec_private[j]);
fprintf(out, "\" />\n");
index++;
+ if (vf->chunks != first_vf->chunks)
+ fprintf(stderr, "Mismatched number of video chunks in %s and %s\n",
+ vf->name, first_vf->name);
}
- vf = files->files[files->video_file];
- for (i = 0; i < vf->chunks; i++)
+ vf = first_vf;
+ for (i = 0; i < vf->chunks; i++) {
+ for (j = files->video_file + 1; j < files->nb_files; j++) {
+ if (files->files[j]->is_video &&
+ vf->offsets[i].duration != files->files[j]->offsets[i].duration)
+ fprintf(stderr, "Mismatched duration of video chunk %d in %s and %s\n",
+ i, vf->name, files->files[j]->name);
+ }
fprintf(out, "\t\t<c n=\"%d\" d=\"%d\" />\n", i,
vf->offsets[i].duration);
+ }
fprintf(out, "\t</StreamIndex>\n");
}
if (files->audio_file >= 0) {
struct VideoFile *vf = files->files[files->audio_file];
+ struct VideoFile *first_vf = vf;
int index = 0;
fprintf(out,
"\t<StreamIndex Type=\"audio\" QualityLevels=\"%d\" "
@@ -469,11 +487,21 @@ static void output_client_manifest(struct VideoFiles *files,
fprintf(out, "%02X", vf->codec_private[j]);
fprintf(out, "\" />\n");
index++;
+ if (vf->chunks != first_vf->chunks)
+ fprintf(stderr, "Mismatched number of audio chunks in %s and %s\n",
+ vf->name, first_vf->name);
}
- vf = files->files[files->audio_file];
- for (i = 0; i < vf->chunks; i++)
+ vf = first_vf;
+ for (i = 0; i < vf->chunks; i++) {
+ for (j = files->audio_file + 1; j < files->nb_files; j++) {
+ if (files->files[j]->is_audio &&
+ vf->offsets[i].duration != files->files[j]->offsets[i].duration)
+ fprintf(stderr, "Mismatched duration of audio chunk %d in %s and %s\n",
+ i, vf->name, files->files[j]->name);
+ }
fprintf(out, "\t\t<c n=\"%d\" d=\"%d\" />\n",
i, vf->offsets[i].duration);
+ }
fprintf(out, "\t</StreamIndex>\n");
}
fprintf(out, "</SmoothStreamingMedia>\n");
@@ -509,7 +537,8 @@ int main(int argc, char **argv)
} else if (argv[i][0] == '-') {
return usage(argv[0], 1);
} else {
- handle_file(&vf, argv[i], split);
+ if (handle_file(&vf, argv[i], split))
+ return 1;
}
}
if (!vf.nb_files || (!basename && !split))
diff --git a/tools/lavfi-showfiltfmts.c b/tools/lavfi-showfiltfmts.c
deleted file mode 100644
index d25cf3e..0000000
--- a/tools/lavfi-showfiltfmts.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2009 Stefano Sabatini
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "libavformat/avformat.h"
-#include "libavutil/pixdesc.h"
-#include "libavfilter/avfilter.h"
-
-int main(int argc, char **argv)
-{
- AVFilter *filter;
- AVFilterContext *filter_ctx;
- const char *filter_name;
- const char *filter_args = NULL;
- int i, j;
-
- av_log_set_level(AV_LOG_DEBUG);
-
- if (!argv[1]) {
- fprintf(stderr, "Missing filter name as argument\n");
- return 1;
- }
-
- filter_name = argv[1];
- if (argv[2])
- filter_args = argv[2];
-
- avfilter_register_all();
-
- /* get a corresponding filter and open it */
- if (!(filter = avfilter_get_by_name(filter_name))) {
- fprintf(stderr, "Unrecognized filter with name '%s'\n", filter_name);
- return 1;
- }
-
- if (avfilter_open(&filter_ctx, filter, NULL) < 0) {
- fprintf(stderr, "Impossible to open filter with name '%s'\n",
- filter_name);
- return 1;
- }
- if (avfilter_init_filter(filter_ctx, filter_args, NULL) < 0) {
- fprintf(stderr, "Impossible to init filter '%s' with arguments '%s'\n",
- filter_name, filter_args);
- return 1;
- }
-
- /* create a link for each of the input pads */
- for (i = 0; i < filter_ctx->input_count; i++) {
- AVFilterLink *link = av_mallocz(sizeof(AVFilterLink));
- link->type = filter_ctx->filter->inputs[i].type;
- filter_ctx->inputs[i] = link;
- }
- for (i = 0; i < filter_ctx->output_count; i++) {
- AVFilterLink *link = av_mallocz(sizeof(AVFilterLink));
- link->type = filter_ctx->filter->outputs[i].type;
- filter_ctx->outputs[i] = link;
- }
-
- if (filter->query_formats)
- filter->query_formats(filter_ctx);
- else
- avfilter_default_query_formats(filter_ctx);
-
- /* print the supported formats in input */
- for (i = 0; i < filter_ctx->input_count; i++) {
- AVFilterFormats *fmts = filter_ctx->inputs[i]->out_formats;
- for (j = 0; j < fmts->format_count; j++)
- printf("INPUT[%d] %s: %s\n",
- i, filter_ctx->filter->inputs[i].name,
- av_pix_fmt_descriptors[fmts->formats[j]].name);
- }
-
- /* print the supported formats in output */
- for (i = 0; i < filter_ctx->output_count; i++) {
- AVFilterFormats *fmts = filter_ctx->outputs[i]->in_formats;
- for (j = 0; j < fmts->format_count; j++)
- printf("OUTPUT[%d] %s: %s\n",
- i, filter_ctx->filter->outputs[i].name,
- av_pix_fmt_descriptors[fmts->formats[j]].name);
- }
-
- avfilter_free(filter_ctx);
- fflush(stdout);
- return 0;
-}
diff --git a/tools/patcheck b/tools/patcheck
index b3943c5..78ca824 100755
--- a/tools/patcheck
+++ b/tools/patcheck
@@ -67,7 +67,7 @@ $EGREP $OPT '^\+ *(const *|)static' $*| $EGREP --color=always '[^=]= *(0|NULL)[^
cat $TMP
hiegrep '# *ifdef * (HAVE|CONFIG)_' 'ifdefs that should be #if' $*
-hiegrep '\b(awnser|cant|dont|wont|usefull|successfull|occured|teh|alot|wether|skiped|heigth|informations|colums|loosy|loosing|seperate|preceed|upto|paket|posible|unkown|inpossible|dimention)\b' 'common typos' $*
+hiegrep '\b(awnser|cant|dont|wont|usefull|successfull|occured|teh|alot|wether|skiped|heigth|informations|colums|loosy|loosing|seperate|preceed|upto|paket|posible|unkown|inpossible|dimention|acheive)\b' 'common typos' $*
hiegrep 'av_log\( *NULL' 'Missing context in av_log' $*
hiegrep '[^sn]printf' 'Please use av_log' $*
diff --git a/tools/pktdumper.c b/tools/pktdumper.c
index c3a3a21..d23cd96 100644
--- a/tools/pktdumper.c
+++ b/tools/pktdumper.c
@@ -25,6 +25,7 @@
#include <string.h>
#include <unistd.h>
+#include "libavutil/time.h"
#include "libavformat/avformat.h"
#define PKTFILESUFF "_%08" PRId64 "_%02d_%010" PRId64 "_%06d_%c.bin"
@@ -122,7 +123,7 @@ int main(int argc, char **argv)
avformat_close_input(&fctx);
while (donotquit)
- usleep(60 * 1000000);
+ av_usleep(60 * 1000000);
return 0;
}
--
Libav/FFmpeg packaging
More information about the pkg-multimedia-commits
mailing list