Merge commit 'fe1c1198e670242f3cf9e3e1eef27cff77f3ee23'

* commit 'fe1c1198e670242f3cf9e3e1eef27cff77f3ee23':
  lavf: use dts difference instead of AVPacket.duration in find_stream_info()
  avf: introduce nobuffer option
  fate: make yadif tests consistent across systems
  vf_hqdn3d: support 9 and 10bit colordepth
  vf_hqdn3d: reduce intermediate precision
  vf_hqdn3d: simplify and optimize
  factor identical ff_inplace_start_frame out of two filters
  vf_hqdn3d: cosmetics
  avprobe/avconv: fix tentative declaration compile errors on MSVS.

Conflicts:
	doc/APIchanges
	ffmpeg.c
	ffprobe.c
	libavformat/avformat.h
	libavformat/options_table.h
	libavformat/utils.c
	libavformat/version.h
	tests/fate/filter.mak
	tests/ref/fate/filter-yadif-mode0
	tests/ref/fate/filter-yadif-mode1

Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Michael Niedermayer 2012-07-29 22:58:17 +02:00
commit 7c26761b81
15 changed files with 322 additions and 335 deletions

View File

@ -63,6 +63,9 @@ API changes, most recent first:
2012-03-26 - a67d9cf - lavfi 2.66.100
Add avfilter_fill_frame_from_{audio_,}buffer_ref() functions.
2012-07-xx - xxxxxxx - lavf 54.13.0 - avformat.h
Add AVFMT_FLAG_NOBUFFER for low latency use cases.
2012-07-10 - 5fade8a - lavu 51.37.0
Add av_malloc_array() and av_mallocz_array()

View File

@ -122,7 +122,7 @@ typedef struct {
int ofile_idx, ostream_idx; // output
} AudioChannelMap;
static const OptionDef options[];
static const OptionDef *options;
#define MAX_STREAMS 1024 /* arbitrary sanity check value */
@ -5955,7 +5955,7 @@ static int opt_progress(const char *opt, const char *arg)
}
#define OFFSET(x) offsetof(OptionsContext, x)
static const OptionDef options[] = {
static const OptionDef real_options[] = {
/* main options */
#include "cmdutils_common_opts.h"
{ "f", HAS_ARG | OPT_STRING | OPT_OFFSET, {.off = OFFSET(format)}, "force format", "fmt" },
@ -6107,6 +6107,7 @@ int main(int argc, char **argv)
OptionsContext o = { 0 };
int64_t ti;
options = real_options;
reset_options(&o, 0);
av_log_set_flags(AV_LOG_SKIP_REPEATED);

View File

@ -65,7 +65,7 @@ static int show_private_data = 1;
static char *print_format;
static const OptionDef options[];
static const OptionDef *options;
/* FFprobe context */
static const char *input_filename;
@ -2108,7 +2108,7 @@ static int opt_show_versions(const char *opt, const char *arg)
return 0;
}
static const OptionDef options[] = {
static const OptionDef real_options[] = {
#include "cmdutils_common_opts.h"
{ "f", HAS_ARG, {(void*)opt_format}, "force format", "format" },
{ "unit", OPT_BOOL, {(void*)&show_value_unit}, "show unit of the displayed values" },
@ -2151,6 +2151,7 @@ int main(int argc, char **argv)
int ret;
av_log_set_flags(AV_LOG_SKIP_REPEATED);
options = real_options;
parse_loglevel(argc, argv, options);
av_register_all();
avformat_network_init();

View File

@ -209,42 +209,6 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
return 0;
}
static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
{
AVFilterLink *outlink = inlink->dst->outputs[0];
AVFilterBufferRef *outpicref = NULL, *for_next_filter;
int ret = 0;
if (inpicref->perms & AV_PERM_PRESERVE) {
outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE,
outlink->w, outlink->h);
if (!outpicref)
return AVERROR(ENOMEM);
avfilter_copy_buffer_ref_props(outpicref, inpicref);
outpicref->video->w = outlink->w;
outpicref->video->h = outlink->h;
} else {
outpicref = avfilter_ref_buffer(inpicref, ~0);
if (!outpicref)
return AVERROR(ENOMEM);
}
for_next_filter = avfilter_ref_buffer(outpicref, ~0);
if (for_next_filter)
ret = ff_start_frame(outlink, for_next_filter);
else
ret = AVERROR(ENOMEM);
if (ret < 0) {
avfilter_unref_bufferp(&outpicref);
return ret;
}
outlink->out_buf = outpicref;
return 0;
}
static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
{
return 0;
@ -291,7 +255,7 @@ AVFilter avfilter_vf_delogo = {
.inputs = (const AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.get_video_buffer = ff_null_get_video_buffer,
.start_frame = start_frame,
.start_frame = ff_inplace_start_frame,
.draw_slice = null_draw_slice,
.end_frame = end_frame,
.min_perms = AV_PERM_WRITE | AV_PERM_READ,

View File

@ -180,41 +180,6 @@ static int config_input(AVFilterLink *inlink)
return 0;
}
static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
{
AVFilterLink *outlink = inlink->dst->outputs[0];
AVFilterBufferRef *outpicref = NULL, *for_next_filter;
int ret = 0;
if (inpicref->perms & AV_PERM_PRESERVE) {
outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
if (!outpicref)
return AVERROR(ENOMEM);
avfilter_copy_buffer_ref_props(outpicref, inpicref);
outpicref->video->w = outlink->w;
outpicref->video->h = outlink->h;
} else {
outpicref = avfilter_ref_buffer(inpicref, ~0);
if (!outpicref)
return AVERROR(ENOMEM);
}
for_next_filter = avfilter_ref_buffer(outpicref, ~0);
if (for_next_filter)
ret = ff_start_frame(outlink, for_next_filter);
else
ret = AVERROR(ENOMEM);
if (ret < 0) {
avfilter_unref_bufferp(&outpicref);
return ret;
}
outlink->out_buf = outpicref;
return 0;
}
static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
{
return 0;
@ -261,7 +226,7 @@ AVFilter avfilter_vf_gradfun = {
.inputs = (const AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.config_props = config_input,
.start_frame = start_frame,
.start_frame = ff_inplace_start_frame,
.draw_slice = null_draw_slice,
.end_frame = end_frame,
.min_perms = AV_PERM_READ, },

View File

@ -1,6 +1,7 @@
/*
* Copyright (c) 2003 Daniel Moreno <comac AT comac DOT darktech DOT org>
* Copyright (c) 2010 Baptiste Coudurier
* Copyright (c) 2012 Loren Merritt
*
* This file is part of FFmpeg, ported from MPlayer.
*
@ -26,171 +27,141 @@
*/
#include "libavutil/pixdesc.h"
#include "libavutil/intreadwrite.h"
#include "avfilter.h"
#include "formats.h"
#include "internal.h"
#include "video.h"
typedef struct {
int Coefs[4][512*16];
unsigned int *Line;
unsigned short *Frame[3];
int16_t coefs[4][512*16];
uint16_t *line;
uint16_t *frame_prev[3];
int hsub, vsub;
int depth;
} HQDN3DContext;
static inline unsigned int LowPassMul(unsigned int PrevMul, unsigned int CurrMul, int *Coef)
#define RIGHTSHIFT(a,b) (((a)+(((1<<(b))-1)>>1))>>(b))
#define LOAD(x) ((depth==8 ? src[x] : AV_RN16A(src+(x)*2)) << (16-depth))
#define STORE(x,val) (depth==8 ? dst[x] = RIGHTSHIFT(val, 16-depth)\
: AV_WN16A(dst+(x)*2, RIGHTSHIFT(val, 16-depth)))
static inline uint32_t lowpass(int prev, int cur, int16_t *coef)
{
// int dMul= (PrevMul&0xFFFFFF)-(CurrMul&0xFFFFFF);
int dMul= PrevMul-CurrMul;
unsigned int d=((dMul+0x10007FF)>>12);
return CurrMul + Coef[d];
int d = (prev-cur)>>4;
return cur + coef[d];
}
static void deNoiseTemporal(unsigned char *FrameSrc,
unsigned char *FrameDest,
unsigned short *FrameAnt,
int W, int H, int sStride, int dStride,
int *Temporal)
av_always_inline
static void denoise_temporal(uint8_t *src, uint8_t *dst,
uint16_t *frame_ant,
int w, int h, int sstride, int dstride,
int16_t *temporal, int depth)
{
long X, Y;
unsigned int PixelDst;
long x, y;
uint32_t tmp;
for (Y = 0; Y < H; Y++) {
for (X = 0; X < W; X++) {
PixelDst = LowPassMul(FrameAnt[X]<<8, FrameSrc[X]<<16, Temporal);
FrameAnt[X] = ((PixelDst+0x1000007F)>>8);
FrameDest[X]= ((PixelDst+0x10007FFF)>>16);
temporal += 0x1000;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
frame_ant[x] = tmp = lowpass(frame_ant[x], LOAD(x), temporal);
STORE(x, tmp);
}
FrameSrc += sStride;
FrameDest += dStride;
FrameAnt += W;
src += sstride;
dst += dstride;
frame_ant += w;
}
}
static void deNoiseSpacial(unsigned char *Frame,
unsigned char *FrameDest,
unsigned int *LineAnt,
int W, int H, int sStride, int dStride,
int *Horizontal, int *Vertical)
av_always_inline
static void denoise_spatial(uint8_t *src, uint8_t *dst,
uint16_t *line_ant, uint16_t *frame_ant,
int w, int h, int sstride, int dstride,
int16_t *spatial, int16_t *temporal, int depth)
{
long X, Y;
long sLineOffs = 0, dLineOffs = 0;
unsigned int PixelAnt;
unsigned int PixelDst;
long x, y;
uint32_t pixel_ant;
uint32_t tmp;
/* First pixel has no left nor top neighbor. */
PixelDst = LineAnt[0] = PixelAnt = Frame[0]<<16;
FrameDest[0]= ((PixelDst+0x10007FFF)>>16);
spatial += 0x1000;
temporal += 0x1000;
/* First line has no top neighbor, only left. */
for (X = 1; X < W; X++) {
PixelDst = LineAnt[X] = LowPassMul(PixelAnt, Frame[X]<<16, Horizontal);
FrameDest[X]= ((PixelDst+0x10007FFF)>>16);
}
for (Y = 1; Y < H; Y++) {
unsigned int PixelAnt;
sLineOffs += sStride, dLineOffs += dStride;
/* First pixel on each line doesn't have previous pixel */
PixelAnt = Frame[sLineOffs]<<16;
PixelDst = LineAnt[0] = LowPassMul(LineAnt[0], PixelAnt, Vertical);
FrameDest[dLineOffs]= ((PixelDst+0x10007FFF)>>16);
for (X = 1; X < W; X++) {
unsigned int PixelDst;
/* The rest are normal */
PixelAnt = LowPassMul(PixelAnt, Frame[sLineOffs+X]<<16, Horizontal);
PixelDst = LineAnt[X] = LowPassMul(LineAnt[X], PixelAnt, Vertical);
FrameDest[dLineOffs+X]= ((PixelDst+0x10007FFF)>>16);
}
}
}
static void deNoise(unsigned char *Frame,
unsigned char *FrameDest,
unsigned int *LineAnt,
unsigned short **FrameAntPtr,
int W, int H, int sStride, int dStride,
int *Horizontal, int *Vertical, int *Temporal)
{
long X, Y;
long sLineOffs = 0, dLineOffs = 0;
unsigned int PixelAnt;
unsigned int PixelDst;
unsigned short* FrameAnt=(*FrameAntPtr);
if (!FrameAnt) {
(*FrameAntPtr) = FrameAnt = av_malloc(W*H*sizeof(unsigned short));
for (Y = 0; Y < H; Y++) {
unsigned short* dst=&FrameAnt[Y*W];
unsigned char* src=Frame+Y*sStride;
for (X = 0; X < W; X++) dst[X]=src[X]<<8;
}
}
if (!Horizontal[0] && !Vertical[0]) {
deNoiseTemporal(Frame, FrameDest, FrameAnt,
W, H, sStride, dStride, Temporal);
return;
}
if (!Temporal[0]) {
deNoiseSpacial(Frame, FrameDest, LineAnt,
W, H, sStride, dStride, Horizontal, Vertical);
return;
}
/* First pixel has no left nor top neighbor. Only previous frame */
LineAnt[0] = PixelAnt = Frame[0]<<16;
PixelDst = LowPassMul(FrameAnt[0]<<8, PixelAnt, Temporal);
FrameAnt[0] = ((PixelDst+0x1000007F)>>8);
FrameDest[0]= ((PixelDst+0x10007FFF)>>16);
/* First line has no top neighbor. Only left one for each pixel and
/* First line has no top neighbor. Only left one for each tmp and
* last frame */
for (X = 1; X < W; X++) {
LineAnt[X] = PixelAnt = LowPassMul(PixelAnt, Frame[X]<<16, Horizontal);
PixelDst = LowPassMul(FrameAnt[X]<<8, PixelAnt, Temporal);
FrameAnt[X] = ((PixelDst+0x1000007F)>>8);
FrameDest[X]= ((PixelDst+0x10007FFF)>>16);
pixel_ant = LOAD(0);
for (x = 0; x < w; x++) {
line_ant[x] = tmp = pixel_ant = lowpass(pixel_ant, LOAD(x), spatial);
frame_ant[x] = tmp = lowpass(frame_ant[x], tmp, temporal);
STORE(x, tmp);
}
for (Y = 1; Y < H; Y++) {
unsigned int PixelAnt;
unsigned short* LinePrev=&FrameAnt[Y*W];
sLineOffs += sStride, dLineOffs += dStride;
/* First pixel on each line doesn't have previous pixel */
PixelAnt = Frame[sLineOffs]<<16;
LineAnt[0] = LowPassMul(LineAnt[0], PixelAnt, Vertical);
PixelDst = LowPassMul(LinePrev[0]<<8, LineAnt[0], Temporal);
LinePrev[0] = ((PixelDst+0x1000007F)>>8);
FrameDest[dLineOffs]= ((PixelDst+0x10007FFF)>>16);
for (X = 1; X < W; X++) {
unsigned int PixelDst;
/* The rest are normal */
PixelAnt = LowPassMul(PixelAnt, Frame[sLineOffs+X]<<16, Horizontal);
LineAnt[X] = LowPassMul(LineAnt[X], PixelAnt, Vertical);
PixelDst = LowPassMul(LinePrev[X]<<8, LineAnt[X], Temporal);
LinePrev[X] = ((PixelDst+0x1000007F)>>8);
FrameDest[dLineOffs+X]= ((PixelDst+0x10007FFF)>>16);
for (y = 1; y < h; y++) {
src += sstride;
dst += dstride;
frame_ant += w;
pixel_ant = LOAD(0);
for (x = 0; x < w-1; x++) {
line_ant[x] = tmp = lowpass(line_ant[x], pixel_ant, spatial);
pixel_ant = lowpass(pixel_ant, LOAD(x+1), spatial);
frame_ant[x] = tmp = lowpass(frame_ant[x], tmp, temporal);
STORE(x, tmp);
}
line_ant[x] = tmp = lowpass(line_ant[x], pixel_ant, spatial);
frame_ant[x] = tmp = lowpass(frame_ant[x], tmp, temporal);
STORE(x, tmp);
}
}
static void PrecalcCoefs(int *Ct, double Dist25)
av_always_inline
static void denoise_depth(uint8_t *src, uint8_t *dst,
uint16_t *line_ant, uint16_t **frame_ant_ptr,
int w, int h, int sstride, int dstride,
int16_t *spatial, int16_t *temporal, int depth)
{
long x, y;
uint16_t *frame_ant = *frame_ant_ptr;
if (!frame_ant) {
uint8_t *frame_src = src;
*frame_ant_ptr = frame_ant = av_malloc(w*h*sizeof(uint16_t));
for (y = 0; y < h; y++, src += sstride, frame_ant += w)
for (x = 0; x < w; x++)
frame_ant[x] = LOAD(x);
src = frame_src;
frame_ant = *frame_ant_ptr;
}
if (spatial[0])
denoise_spatial(src, dst, line_ant, frame_ant,
w, h, sstride, dstride, spatial, temporal, depth);
else
denoise_temporal(src, dst, frame_ant,
w, h, sstride, dstride, temporal, depth);
}
#define denoise(...) \
switch (hqdn3d->depth) {\
case 8: denoise_depth(__VA_ARGS__, 8); break;\
case 9: denoise_depth(__VA_ARGS__, 9); break;\
case 10: denoise_depth(__VA_ARGS__, 10); break;\
}
static void precalc_coefs(int16_t *ct, double dist25)
{
int i;
double Gamma, Simil, C;
double gamma, simil, C;
Gamma = log(0.25) / log(1.0 - Dist25/255.0 - 0.00001);
gamma = log(0.25) / log(1.0 - FFMIN(dist25,252.0)/255.0 - 0.00001);
for (i = -255*16; i <= 255*16; i++) {
Simil = 1.0 - FFABS(i) / (16*255.0);
C = pow(Simil, Gamma) * 65536.0 * i / 16.0;
Ct[16*256+i] = lrint(C);
// lowpass() truncates (not rounds) the diff, so +15/32 for the midpoint of the bin.
double f = (i + 15.0/32.0) / 16.0;
simil = 1.0 - FFABS(f) / 255.0;
C = pow(simil, gamma) * 256.0 * f;
ct[16*256+i] = lrint(C);
}
Ct[0] = !!Dist25;
ct[0] = !!dist25;
}
#define PARAM1_DEFAULT 4.0
@ -200,57 +171,57 @@ static void PrecalcCoefs(int *Ct, double Dist25)
static int init(AVFilterContext *ctx, const char *args)
{
HQDN3DContext *hqdn3d = ctx->priv;
double LumSpac, LumTmp, ChromSpac, ChromTmp;
double Param1, Param2, Param3, Param4;
double lum_spac, lum_tmp, chrom_spac, chrom_tmp;
double param1, param2, param3, param4;
LumSpac = PARAM1_DEFAULT;
ChromSpac = PARAM2_DEFAULT;
LumTmp = PARAM3_DEFAULT;
ChromTmp = LumTmp * ChromSpac / LumSpac;
lum_spac = PARAM1_DEFAULT;
chrom_spac = PARAM2_DEFAULT;
lum_tmp = PARAM3_DEFAULT;
chrom_tmp = lum_tmp * chrom_spac / lum_spac;
if (args) {
switch (sscanf(args, "%lf:%lf:%lf:%lf",
&Param1, &Param2, &Param3, &Param4)) {
&param1, &param2, &param3, &param4)) {
case 1:
LumSpac = Param1;
ChromSpac = PARAM2_DEFAULT * Param1 / PARAM1_DEFAULT;
LumTmp = PARAM3_DEFAULT * Param1 / PARAM1_DEFAULT;
ChromTmp = LumTmp * ChromSpac / LumSpac;
lum_spac = param1;
chrom_spac = PARAM2_DEFAULT * param1 / PARAM1_DEFAULT;
lum_tmp = PARAM3_DEFAULT * param1 / PARAM1_DEFAULT;
chrom_tmp = lum_tmp * chrom_spac / lum_spac;
break;
case 2:
LumSpac = Param1;
ChromSpac = Param2;
LumTmp = PARAM3_DEFAULT * Param1 / PARAM1_DEFAULT;
ChromTmp = LumTmp * ChromSpac / LumSpac;
lum_spac = param1;
chrom_spac = param2;
lum_tmp = PARAM3_DEFAULT * param1 / PARAM1_DEFAULT;
chrom_tmp = lum_tmp * chrom_spac / lum_spac;
break;
case 3:
LumSpac = Param1;
ChromSpac = Param2;
LumTmp = Param3;
ChromTmp = LumTmp * ChromSpac / LumSpac;
lum_spac = param1;
chrom_spac = param2;
lum_tmp = param3;
chrom_tmp = lum_tmp * chrom_spac / lum_spac;
break;
case 4:
LumSpac = Param1;
ChromSpac = Param2;
LumTmp = Param3;
ChromTmp = Param4;
lum_spac = param1;
chrom_spac = param2;
lum_tmp = param3;
chrom_tmp = param4;
break;
}
}
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)) {
lum_spac, chrom_spac, lum_tmp, chrom_tmp);
if (lum_spac < 0 || chrom_spac < 0 || isnan(chrom_tmp)) {
av_log(ctx, AV_LOG_ERROR,
"Invalid negative value for luma or chroma spatial strength, "
"or resulting value for chroma temporal strength is nan.\n");
return AVERROR(EINVAL);
}
PrecalcCoefs(hqdn3d->Coefs[0], LumSpac);
PrecalcCoefs(hqdn3d->Coefs[1], LumTmp);
PrecalcCoefs(hqdn3d->Coefs[2], ChromSpac);
PrecalcCoefs(hqdn3d->Coefs[3], ChromTmp);
precalc_coefs(hqdn3d->coefs[0], lum_spac);
precalc_coefs(hqdn3d->coefs[1], lum_tmp);
precalc_coefs(hqdn3d->coefs[2], chrom_spac);
precalc_coefs(hqdn3d->coefs[3], chrom_tmp);
return 0;
}
@ -259,16 +230,32 @@ static void uninit(AVFilterContext *ctx)
{
HQDN3DContext *hqdn3d = ctx->priv;
av_freep(&hqdn3d->Line);
av_freep(&hqdn3d->Frame[0]);
av_freep(&hqdn3d->Frame[1]);
av_freep(&hqdn3d->Frame[2]);
av_freep(&hqdn3d->line);
av_freep(&hqdn3d->frame_prev[0]);
av_freep(&hqdn3d->frame_prev[1]);
av_freep(&hqdn3d->frame_prev[2]);
}
static int query_formats(AVFilterContext *ctx)
{
static const enum PixelFormat pix_fmts[] = {
PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_YUV411P, PIX_FMT_NONE
PIX_FMT_YUV420P,
PIX_FMT_YUV422P,
PIX_FMT_YUV444P,
PIX_FMT_YUV410P,
PIX_FMT_YUV411P,
PIX_FMT_YUV440P,
PIX_FMT_YUVJ420P,
PIX_FMT_YUVJ422P,
PIX_FMT_YUVJ444P,
PIX_FMT_YUVJ440P,
AV_NE( PIX_FMT_YUV420P9BE, PIX_FMT_YUV420P9LE ),
AV_NE( PIX_FMT_YUV422P9BE, PIX_FMT_YUV422P9LE ),
AV_NE( PIX_FMT_YUV444P9BE, PIX_FMT_YUV444P9LE ),
AV_NE( PIX_FMT_YUV420P10BE, PIX_FMT_YUV420P10LE ),
AV_NE( PIX_FMT_YUV422P10BE, PIX_FMT_YUV422P10LE ),
AV_NE( PIX_FMT_YUV444P10BE, PIX_FMT_YUV444P10LE ),
PIX_FMT_NONE
};
ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
@ -282,9 +269,10 @@ static int config_input(AVFilterLink *inlink)
hqdn3d->hsub = av_pix_fmt_descriptors[inlink->format].log2_chroma_w;
hqdn3d->vsub = av_pix_fmt_descriptors[inlink->format].log2_chroma_h;
hqdn3d->depth = av_pix_fmt_descriptors[inlink->format].comp[0].depth_minus1+1;
hqdn3d->Line = av_malloc(inlink->w * sizeof(*hqdn3d->Line));
if (!hqdn3d->Line)
hqdn3d->line = av_malloc(inlink->w * sizeof(*hqdn3d->line));
if (!hqdn3d->line)
return AVERROR(ENOMEM);
return 0;
@ -301,28 +289,16 @@ static int end_frame(AVFilterLink *inlink)
AVFilterLink *outlink = inlink->dst->outputs[0];
AVFilterBufferRef *inpic = inlink ->cur_buf;
AVFilterBufferRef *outpic = outlink->out_buf;
int cw = inpic->video->w >> hqdn3d->hsub;
int ch = inpic->video->h >> hqdn3d->vsub;
int ret;
int ret, c;
deNoise(inpic->data[0], outpic->data[0],
hqdn3d->Line, &hqdn3d->Frame[0], inpic->video->w, inpic->video->h,
inpic->linesize[0], outpic->linesize[0],
hqdn3d->Coefs[0],
hqdn3d->Coefs[0],
hqdn3d->Coefs[1]);
deNoise(inpic->data[1], outpic->data[1],
hqdn3d->Line, &hqdn3d->Frame[1], cw, ch,
inpic->linesize[1], outpic->linesize[1],
hqdn3d->Coefs[2],
hqdn3d->Coefs[2],
hqdn3d->Coefs[3]);
deNoise(inpic->data[2], outpic->data[2],
hqdn3d->Line, &hqdn3d->Frame[2], cw, ch,
inpic->linesize[2], outpic->linesize[2],
hqdn3d->Coefs[2],
hqdn3d->Coefs[2],
hqdn3d->Coefs[3]);
for (c = 0; c < 3; c++) {
denoise(inpic->data[c], outpic->data[c],
hqdn3d->line, &hqdn3d->frame_prev[c],
inpic->video->w >> (!!c * hqdn3d->hsub),
inpic->video->h >> (!!c * hqdn3d->vsub),
inpic->linesize[c], outpic->linesize[c],
hqdn3d->coefs[c?2:0], hqdn3d->coefs[c?3:1]);
}
if ((ret = ff_draw_slice(outlink, 0, inpic->video->h, 1)) < 0 ||
(ret = ff_end_frame(outlink)) < 0)
@ -341,6 +317,7 @@ AVFilter avfilter_vf_hqdn3d = {
.inputs = (const AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.start_frame = ff_inplace_start_frame,
.draw_slice = null_draw_slice,
.config_props = config_input,
.end_frame = end_frame },

View File

@ -157,6 +157,42 @@ int ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
return ff_start_frame(link->dst->outputs[0], buf_out);
}
// for filters that support (but don't require) outpic==inpic
int ff_inplace_start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
{
AVFilterLink *outlink = inlink->dst->outputs[0];
AVFilterBufferRef *outpicref = NULL, *for_next_filter;
int ret = 0;
if ((inpicref->perms & AV_PERM_WRITE) && !(inpicref->perms & AV_PERM_PRESERVE)) {
outpicref = avfilter_ref_buffer(inpicref, ~0);
if (!outpicref)
return AVERROR(ENOMEM);
} else {
outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
if (!outpicref)
return AVERROR(ENOMEM);
avfilter_copy_buffer_ref_props(outpicref, inpicref);
outpicref->video->w = outlink->w;
outpicref->video->h = outlink->h;
}
for_next_filter = avfilter_ref_buffer(outpicref, ~0);
if (for_next_filter)
ret = ff_start_frame(outlink, for_next_filter);
else
ret = AVERROR(ENOMEM);
if (ret < 0) {
avfilter_unref_bufferp(&outpicref);
return ret;
}
outlink->out_buf = outpicref;
return 0;
}
static int default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
{
AVFilterLink *outlink = NULL;

View File

@ -42,6 +42,7 @@ AVFilterBufferRef *ff_null_get_video_buffer(AVFilterLink *link, int perms, int w
AVFilterBufferRef *ff_get_video_buffer(AVFilterLink *link, int perms,
int w, int h);
int ff_inplace_start_frame(AVFilterLink *link, AVFilterBufferRef *picref);
int ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref);
int ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir);
int ff_null_end_frame(AVFilterLink *link);

View File

@ -741,6 +741,15 @@ typedef struct AVStream {
int64_t codec_info_duration;
int nb_decoded_frames;
int found_decoder;
/**
* Those are used for average framerate estimation.
*/
int64_t fps_first_dts;
int fps_first_dts_idx;
int64_t fps_last_dts;
int fps_last_dts_idx;
} *info;
int pts_wrap_bits; /**< number of bits in pts (used for wrapping control) */
@ -948,6 +957,7 @@ typedef struct AVFormatContext {
#define AVFMT_FLAG_IGNDTS 0x0008 ///< Ignore DTS on frames that contain both DTS & PTS
#define AVFMT_FLAG_NOFILLIN 0x0010 ///< Do not infer any values from other values, just return what is stored in the container
#define AVFMT_FLAG_NOPARSE 0x0020 ///< Do not use AVParsers, you also must set AVFMT_FLAG_NOFILLIN as the fillin code works on frames and no parsing -> no frames. Also seeking to frames can not work if parsing to find frame boundaries has been disabled
#define AVFMT_FLAG_NOBUFFER 0x0040 ///< Do not buffer frames when possible
#define AVFMT_FLAG_CUSTOM_IO 0x0080 ///< The caller has supplied a custom AVIOContext, don't avio_close() it.
#define AVFMT_FLAG_DISCARD_CORRUPT 0x0100 ///< Discard frames marked corrupted
#define AVFMT_FLAG_MP4A_LATM 0x8000 ///< Enable RTP MP4A-LATM payload

View File

@ -47,6 +47,7 @@ static const AVOption options[]={
{"sortdts", "try to interleave outputted packets by dts", 0, AV_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_SORT_DTS }, INT_MIN, INT_MAX, D, "fflags"},
{"keepside", "dont merge side data", 0, AV_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_KEEP_SIDE_DATA }, INT_MIN, INT_MAX, D, "fflags"},
{"latm", "enable RTP MP4A-LATM payload", 0, AV_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_MP4A_LATM }, INT_MIN, INT_MAX, E, "fflags"},
{"nobuffer", "reduce the latency introduced by optional buffering", 0, AV_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_NOBUFFER }, 0, INT_MAX, D, "fflags"},
{"analyzeduration", "how many microseconds are analyzed to estimate duration", OFFSET(max_analyze_duration), AV_OPT_TYPE_INT, {.dbl = 5*AV_TIME_BASE }, 0, INT_MAX, D},
{"cryptokey", "decryption key", OFFSET(key), AV_OPT_TYPE_BINARY, {.dbl = 0}, 0, 0, D},
{"indexmem", "max memory used for timestamp index (per stream)", OFFSET(max_index_size), AV_OPT_TYPE_INT, {.dbl = 1<<20 }, 0, INT_MAX, D},

View File

@ -2557,6 +2557,8 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
for (i=0; i<ic->nb_streams; i++) {
ic->streams[i]->info->last_dts = AV_NOPTS_VALUE;
ic->streams[i]->info->fps_first_dts = AV_NOPTS_VALUE;
ic->streams[i]->info->fps_last_dts = AV_NOPTS_VALUE;
}
count = 0;
@ -2630,13 +2632,37 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
break;
}
pkt= add_to_pktbuf(&ic->packet_buffer, &pkt1, &ic->packet_buffer_end);
if ((ret = av_dup_packet(pkt)) < 0)
goto find_stream_info_err;
if (ic->flags & AVFMT_FLAG_NOBUFFER) {
pkt = &pkt1;
} else {
pkt = add_to_pktbuf(&ic->packet_buffer, &pkt1,
&ic->packet_buffer_end);
if ((ret = av_dup_packet(pkt)) < 0)
goto find_stream_info_err;
}
read_size += pkt->size;
st = ic->streams[pkt->stream_index];
if (pkt->dts != AV_NOPTS_VALUE && st->codec_info_nb_frames > 1) {
/* check for non-increasing dts */
if (st->info->fps_last_dts != AV_NOPTS_VALUE &&
st->info->fps_last_dts >= pkt->dts) {
av_log(ic, AV_LOG_DEBUG, "Non-increasing DTS in stream %d: "
"packet %d with DTS %"PRId64", packet %d with DTS "
"%"PRId64"\n", st->index, st->info->fps_last_dts_idx,
st->info->fps_last_dts, st->codec_info_nb_frames, pkt->dts);
st->info->fps_first_dts = st->info->fps_last_dts = AV_NOPTS_VALUE;
}
/* update stored dts values */
if (st->info->fps_first_dts == AV_NOPTS_VALUE) {
st->info->fps_first_dts = pkt->dts;
st->info->fps_first_dts_idx = st->codec_info_nb_frames;
}
st->info->fps_last_dts = pkt->dts;
st->info->fps_last_dts_idx = st->codec_info_nb_frames;
}
if (st->codec_info_nb_frames>1) {
int64_t t=0;
if (st->time_base.den > 0)
@ -2756,10 +2782,12 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
st->codec->codec_tag= tag;
}
if (st->codec_info_nb_frames>2 && !st->avg_frame_rate.num && st->info->codec_info_duration)
/* estimate average framerate if not set by demuxer */
if (st->codec_info_nb_frames>2 && !st->avg_frame_rate.num && st->info->codec_info_duration) {
av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
(st->codec_info_nb_frames-2)*(int64_t)st->time_base.den,
st->info->codec_info_duration*(int64_t)st->time_base.num, 60000);
}
// the check for tb_unreliable() is not completely correct, since this is not about handling
// a unreliable/inexact time base, but a time base that is finer than necessary, as e.g.
// ipmovie.c produces.

View File

@ -30,7 +30,7 @@
#include "libavutil/avutil.h"
#define LIBAVFORMAT_VERSION_MAJOR 54
#define LIBAVFORMAT_VERSION_MINOR 21
#define LIBAVFORMAT_VERSION_MINOR 22
#define LIBAVFORMAT_VERSION_MICRO 100
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \

View File

@ -35,10 +35,10 @@ FATE_FILTER += fate-filter-delogo
FATE_SAMPLES_AVCONV += fate-filter-delogo
FATE_YADIF += fate-filter-yadif-mode0
fate-filter-yadif-mode0: CMD = framecrc -i $(SAMPLES)/mpeg2/mpeg2_field_encoding.ts -vf yadif=0
fate-filter-yadif-mode0: CMD = framecrc -flags bitexact -idct simple -i $(SAMPLES)/mpeg2/mpeg2_field_encoding.ts -vf yadif=0
FATE_YADIF += fate-filter-yadif-mode1
fate-filter-yadif-mode1: CMD = framecrc -i $(SAMPLES)/mpeg2/mpeg2_field_encoding.ts -vf yadif=1
fate-filter-yadif-mode1: CMD = framecrc -flags bitexact -idct simple -i $(SAMPLES)/mpeg2/mpeg2_field_encoding.ts -vf yadif=1
FATE_FILTER += $(FATE_YADIF)
FATE_SAMPLES_AVCONV += $(FATE_YADIF)

View File

@ -1,32 +1,32 @@
#tb 0: 1/25
0, 9, 9, 1, 622080, 0x1511cae9
0, 10, 10, 1, 622080, 0x6e77e746
0, 11, 11, 1, 622080, 0x89aac777
0, 12, 12, 1, 622080, 0x7e0a9335
0, 13, 13, 1, 622080, 0x5f34759b
0, 14, 14, 1, 622080, 0xfac498a6
0, 15, 15, 1, 622080, 0xe60e7a9e
0, 16, 16, 1, 622080, 0x44875bbd
0, 17, 17, 1, 622080, 0xfa761aab
0, 18, 18, 1, 622080, 0x59be119c
0, 19, 19, 1, 622080, 0x21316b36
0, 20, 20, 1, 622080, 0x929fde5b
0, 21, 21, 1, 622080, 0xfca8990c
0, 22, 22, 1, 622080, 0x1ec87d02
0, 23, 23, 1, 622080, 0x5768eea0
0, 24, 24, 1, 622080, 0x1a0894ab
0, 25, 25, 1, 622080, 0xb4e61323
0, 26, 26, 1, 622080, 0xb773341a
0, 27, 27, 1, 622080, 0x8a914cf7
0, 28, 28, 1, 622080, 0xf1cfbc7d
0, 29, 29, 1, 622080, 0xebaeb317
0, 30, 30, 1, 622080, 0xbae9adf4
0, 31, 31, 1, 622080, 0x593544fd
0, 32, 32, 1, 622080, 0x2cd8ec0b
0, 33, 33, 1, 622080, 0x8032d9d4
0, 34, 34, 1, 622080, 0x5c67ace7
0, 35, 35, 1, 622080, 0x95714528
0, 36, 36, 1, 622080, 0xa11cbed2
0, 37, 37, 1, 622080, 0x7389f8f1
0, 38, 38, 1, 622080, 0xa694f3f2
0, 39, 39, 1, 622080, 0xac3a3d09
0, 9, 9, 1, 622080, 0x4440caef
0, 10, 10, 1, 622080, 0xce67e69d
0, 11, 11, 1, 622080, 0x1dbdc653
0, 12, 12, 1, 622080, 0x82c591d1
0, 13, 13, 1, 622080, 0x8193740b
0, 14, 14, 1, 622080, 0xcb219711
0, 15, 15, 1, 622080, 0x1870783b
0, 16, 16, 1, 622080, 0x7080590b
0, 17, 17, 1, 622080, 0x6df4175d
0, 18, 18, 1, 622080, 0x6b530e95
0, 19, 19, 1, 622080, 0x7f9d66f7
0, 20, 20, 1, 622080, 0x338cda81
0, 21, 21, 1, 622080, 0xb13797f8
0, 22, 22, 1, 622080, 0xb51e7ca4
0, 23, 23, 1, 622080, 0x353eed75
0, 24, 24, 1, 622080, 0xf93e92b0
0, 25, 25, 1, 622080, 0xd0811094
0, 26, 26, 1, 622080, 0xb04a3141
0, 27, 27, 1, 622080, 0x4ab84909
0, 28, 28, 1, 622080, 0xa0fcb8fb
0, 29, 29, 1, 622080, 0x9003aebb
0, 30, 30, 1, 622080, 0x153faa3e
0, 31, 31, 1, 622080, 0xae724063
0, 32, 32, 1, 622080, 0xeb4de77a
0, 33, 33, 1, 622080, 0x209ed8c7
0, 34, 34, 1, 622080, 0xe2bbac96
0, 35, 35, 1, 622080, 0xe945441e
0, 36, 36, 1, 622080, 0x8f8cbd5f
0, 37, 37, 1, 622080, 0xbc3cf717
0, 38, 38, 1, 622080, 0x0109f125
0, 39, 39, 1, 622080, 0x230c373f

View File

@ -1,34 +1,34 @@
#tb 0: 1/25
0, 9, 9, 1, 622080, 0x1511cae9
0, 10, 10, 1, 622080, 0xb88ca855
0, 11, 11, 1, 622080, 0x6e77e746
0, 12, 12, 1, 622080, 0x5da19198
0, 13, 13, 1, 622080, 0xee31c8a8
0, 14, 14, 1, 622080, 0xcbb7aac5
0, 15, 15, 1, 622080, 0x19972f1a
0, 16, 16, 1, 622080, 0xac7d34b9
0, 17, 17, 1, 622080, 0x4adfe592
0, 18, 18, 1, 622080, 0x5d738330
0, 19, 19, 1, 622080, 0xb60b4447
0, 20, 20, 1, 622080, 0x1e11acf4
0, 21, 21, 1, 622080, 0x5ed635d0
0, 22, 22, 1, 622080, 0x939857af
0, 23, 23, 1, 622080, 0x530b28fd
0, 24, 24, 1, 622080, 0x3bc0d5d3
0, 25, 25, 1, 622080, 0x77e0fe99
0, 26, 26, 1, 622080, 0xd2151c1e
0, 27, 27, 1, 622080, 0xe021a815
0, 28, 28, 1, 622080, 0xceae4f12
0, 29, 29, 1, 622080, 0x4c2f3330
0, 30, 30, 1, 622080, 0xf534c392
0, 31, 31, 1, 622080, 0x88f01c11
0, 32, 32, 1, 622080, 0x654d5df2
0, 33, 33, 1, 622080, 0x89ef6f8a
0, 34, 34, 1, 622080, 0x78a7b5f1
0, 35, 35, 1, 622080, 0x8152d67f
0, 36, 36, 1, 622080, 0x6590ff5f
0, 37, 37, 1, 622080, 0x51d2be96
0, 38, 38, 1, 622080, 0x483f65f7
0, 39, 39, 1, 622080, 0x7a69143d
0, 40, 40, 1, 622080, 0xeccc58ff
0, 41, 41, 1, 622080, 0xc4d2c370
0, 9, 9, 1, 622080, 0x4440caef
0, 10, 10, 1, 622080, 0xa5cea88b
0, 11, 11, 1, 622080, 0xce67e69d
0, 12, 12, 1, 622080, 0x9a57891f
0, 13, 13, 1, 622080, 0xc171c0c5
0, 14, 14, 1, 622080, 0x20db9890
0, 15, 15, 1, 622080, 0xdb181d52
0, 16, 16, 1, 622080, 0xc2b913d1
0, 17, 17, 1, 622080, 0xf1d9c5fb
0, 18, 18, 1, 622080, 0x669c5775
0, 19, 19, 1, 622080, 0x01921a16
0, 20, 20, 1, 622080, 0xd5047bc9
0, 21, 21, 1, 622080, 0xa8b006eb
0, 22, 22, 1, 622080, 0xf0e125a7
0, 23, 23, 1, 622080, 0x4afe2976
0, 24, 24, 1, 622080, 0x637fcbfe
0, 25, 25, 1, 622080, 0xd9a8f5ac
0, 26, 26, 1, 622080, 0x4540039f
0, 27, 27, 1, 622080, 0x3039906f
0, 28, 28, 1, 622080, 0x52872cf9
0, 29, 29, 1, 622080, 0x82de12ee
0, 30, 30, 1, 622080, 0x7e849cc9
0, 31, 31, 1, 622080, 0xffe6f770
0, 32, 32, 1, 622080, 0xb67f3233
0, 33, 33, 1, 622080, 0x15fe44b4
0, 34, 34, 1, 622080, 0x380f8563
0, 35, 35, 1, 622080, 0xb964d70f
0, 36, 36, 1, 622080, 0x4f60f7f4
0, 37, 37, 1, 622080, 0xd0afb742
0, 38, 38, 1, 622080, 0xb9a15294
0, 39, 39, 1, 622080, 0xb70b01a9
0, 40, 40, 1, 622080, 0xcb3a371f
0, 41, 41, 1, 622080, 0x82dfb1f2