* 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>tags/n1.0
| @@ -63,6 +63,9 @@ API changes, most recent first: | |||||
| 2012-03-26 - a67d9cf - lavfi 2.66.100 | 2012-03-26 - a67d9cf - lavfi 2.66.100 | ||||
| Add avfilter_fill_frame_from_{audio_,}buffer_ref() functions. | 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 | 2012-07-10 - 5fade8a - lavu 51.37.0 | ||||
| Add av_malloc_array() and av_mallocz_array() | Add av_malloc_array() and av_mallocz_array() | ||||
| @@ -122,7 +122,7 @@ typedef struct { | |||||
| int ofile_idx, ostream_idx; // output | int ofile_idx, ostream_idx; // output | ||||
| } AudioChannelMap; | } AudioChannelMap; | ||||
| static const OptionDef options[]; | |||||
| static const OptionDef *options; | |||||
| #define MAX_STREAMS 1024 /* arbitrary sanity check value */ | #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) | #define OFFSET(x) offsetof(OptionsContext, x) | ||||
| static const OptionDef options[] = { | |||||
| static const OptionDef real_options[] = { | |||||
| /* main options */ | /* main options */ | ||||
| #include "cmdutils_common_opts.h" | #include "cmdutils_common_opts.h" | ||||
| { "f", HAS_ARG | OPT_STRING | OPT_OFFSET, {.off = OFFSET(format)}, "force format", "fmt" }, | { "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 }; | OptionsContext o = { 0 }; | ||||
| int64_t ti; | int64_t ti; | ||||
| options = real_options; | |||||
| reset_options(&o, 0); | reset_options(&o, 0); | ||||
| av_log_set_flags(AV_LOG_SKIP_REPEATED); | av_log_set_flags(AV_LOG_SKIP_REPEATED); | ||||
| @@ -65,7 +65,7 @@ static int show_private_data = 1; | |||||
| static char *print_format; | static char *print_format; | ||||
| static const OptionDef options[]; | |||||
| static const OptionDef *options; | |||||
| /* FFprobe context */ | /* FFprobe context */ | ||||
| static const char *input_filename; | static const char *input_filename; | ||||
| @@ -2108,7 +2108,7 @@ static int opt_show_versions(const char *opt, const char *arg) | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| static const OptionDef options[] = { | |||||
| static const OptionDef real_options[] = { | |||||
| #include "cmdutils_common_opts.h" | #include "cmdutils_common_opts.h" | ||||
| { "f", HAS_ARG, {(void*)opt_format}, "force format", "format" }, | { "f", HAS_ARG, {(void*)opt_format}, "force format", "format" }, | ||||
| { "unit", OPT_BOOL, {(void*)&show_value_unit}, "show unit of the displayed values" }, | { "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; | int ret; | ||||
| av_log_set_flags(AV_LOG_SKIP_REPEATED); | av_log_set_flags(AV_LOG_SKIP_REPEATED); | ||||
| options = real_options; | |||||
| parse_loglevel(argc, argv, options); | parse_loglevel(argc, argv, options); | ||||
| av_register_all(); | av_register_all(); | ||||
| avformat_network_init(); | avformat_network_init(); | ||||
| @@ -209,42 +209,6 @@ static av_cold int init(AVFilterContext *ctx, const char *args) | |||||
| return 0; | 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) | static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) | ||||
| { | { | ||||
| return 0; | return 0; | ||||
| @@ -291,7 +255,7 @@ AVFilter avfilter_vf_delogo = { | |||||
| .inputs = (const AVFilterPad[]) {{ .name = "default", | .inputs = (const AVFilterPad[]) {{ .name = "default", | ||||
| .type = AVMEDIA_TYPE_VIDEO, | .type = AVMEDIA_TYPE_VIDEO, | ||||
| .get_video_buffer = ff_null_get_video_buffer, | .get_video_buffer = ff_null_get_video_buffer, | ||||
| .start_frame = start_frame, | |||||
| .start_frame = ff_inplace_start_frame, | |||||
| .draw_slice = null_draw_slice, | .draw_slice = null_draw_slice, | ||||
| .end_frame = end_frame, | .end_frame = end_frame, | ||||
| .min_perms = AV_PERM_WRITE | AV_PERM_READ, | .min_perms = AV_PERM_WRITE | AV_PERM_READ, | ||||
| @@ -180,41 +180,6 @@ static int config_input(AVFilterLink *inlink) | |||||
| return 0; | 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) | static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) | ||||
| { | { | ||||
| return 0; | return 0; | ||||
| @@ -261,7 +226,7 @@ AVFilter avfilter_vf_gradfun = { | |||||
| .inputs = (const AVFilterPad[]) {{ .name = "default", | .inputs = (const AVFilterPad[]) {{ .name = "default", | ||||
| .type = AVMEDIA_TYPE_VIDEO, | .type = AVMEDIA_TYPE_VIDEO, | ||||
| .config_props = config_input, | .config_props = config_input, | ||||
| .start_frame = start_frame, | |||||
| .start_frame = ff_inplace_start_frame, | |||||
| .draw_slice = null_draw_slice, | .draw_slice = null_draw_slice, | ||||
| .end_frame = end_frame, | .end_frame = end_frame, | ||||
| .min_perms = AV_PERM_READ, }, | .min_perms = AV_PERM_READ, }, | ||||
| @@ -1,6 +1,7 @@ | |||||
| /* | /* | ||||
| * Copyright (c) 2003 Daniel Moreno <comac AT comac DOT darktech DOT org> | * Copyright (c) 2003 Daniel Moreno <comac AT comac DOT darktech DOT org> | ||||
| * Copyright (c) 2010 Baptiste Coudurier | * Copyright (c) 2010 Baptiste Coudurier | ||||
| * Copyright (c) 2012 Loren Merritt | |||||
| * | * | ||||
| * This file is part of FFmpeg, ported from MPlayer. | * This file is part of FFmpeg, ported from MPlayer. | ||||
| * | * | ||||
| @@ -26,171 +27,141 @@ | |||||
| */ | */ | ||||
| #include "libavutil/pixdesc.h" | #include "libavutil/pixdesc.h" | ||||
| #include "libavutil/intreadwrite.h" | |||||
| #include "avfilter.h" | #include "avfilter.h" | ||||
| #include "formats.h" | #include "formats.h" | ||||
| #include "internal.h" | #include "internal.h" | ||||
| #include "video.h" | #include "video.h" | ||||
| typedef struct { | 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 hsub, vsub; | ||||
| int depth; | |||||
| } HQDN3DContext; | } 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; | |||||
| 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); | |||||
| long x, y; | |||||
| uint32_t tmp; | |||||
| 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; | |||||
| /* First pixel has no left nor top neighbor. */ | |||||
| PixelDst = LineAnt[0] = PixelAnt = Frame[0]<<16; | |||||
| FrameDest[0]= ((PixelDst+0x10007FFF)>>16); | |||||
| /* 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); | |||||
| long x, y; | |||||
| uint32_t pixel_ant; | |||||
| uint32_t tmp; | |||||
| spatial += 0x1000; | |||||
| temporal += 0x1000; | |||||
| /* First line has no top neighbor. Only left one for each tmp and | |||||
| * last frame */ | |||||
| 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; | |||||
| 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); | |||||
| 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 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) | |||||
| 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; | |||||
| 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; | |||||
| } | |||||
| 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 (!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 | |||||
| * 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); | |||||
| } | |||||
| 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); | |||||
| } | |||||
| 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); | |||||
| } | |||||
| #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 PrecalcCoefs(int *Ct, double Dist25) | |||||
| static void precalc_coefs(int16_t *ct, double dist25) | |||||
| { | { | ||||
| int i; | 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++) { | 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 | #define PARAM1_DEFAULT 4.0 | ||||
| @@ -200,57 +171,57 @@ static void PrecalcCoefs(int *Ct, double Dist25) | |||||
| static int init(AVFilterContext *ctx, const char *args) | static int init(AVFilterContext *ctx, const char *args) | ||||
| { | { | ||||
| HQDN3DContext *hqdn3d = ctx->priv; | 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) { | if (args) { | ||||
| switch (sscanf(args, "%lf:%lf:%lf:%lf", | switch (sscanf(args, "%lf:%lf:%lf:%lf", | ||||
| &Param1, &Param2, &Param3, &Param4)) { | |||||
| ¶m1, ¶m2, ¶m3, ¶m4)) { | |||||
| case 1: | 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; | break; | ||||
| case 2: | 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; | break; | ||||
| case 3: | 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; | break; | ||||
| case 4: | case 4: | ||||
| LumSpac = Param1; | |||||
| ChromSpac = Param2; | |||||
| LumTmp = Param3; | |||||
| ChromTmp = Param4; | |||||
| lum_spac = param1; | |||||
| chrom_spac = param2; | |||||
| lum_tmp = param3; | |||||
| chrom_tmp = param4; | |||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| av_log(ctx, AV_LOG_VERBOSE, "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)) { | |||||
| lum_spac, chrom_spac, lum_tmp, chrom_tmp); | |||||
| if (lum_spac < 0 || chrom_spac < 0 || isnan(chrom_tmp)) { | |||||
| av_log(ctx, AV_LOG_ERROR, | av_log(ctx, AV_LOG_ERROR, | ||||
| "Invalid negative value for luma or chroma spatial strength, " | "Invalid negative value for luma or chroma spatial strength, " | ||||
| "or resulting value for chroma temporal strength is nan.\n"); | "or resulting value for chroma temporal strength is nan.\n"); | ||||
| return AVERROR(EINVAL); | 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; | return 0; | ||||
| } | } | ||||
| @@ -259,16 +230,32 @@ static void uninit(AVFilterContext *ctx) | |||||
| { | { | ||||
| HQDN3DContext *hqdn3d = ctx->priv; | 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 int query_formats(AVFilterContext *ctx) | ||||
| { | { | ||||
| static const enum PixelFormat pix_fmts[] = { | 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)); | 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->hsub = av_pix_fmt_descriptors[inlink->format].log2_chroma_w; | ||||
| hqdn3d->vsub = av_pix_fmt_descriptors[inlink->format].log2_chroma_h; | 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 AVERROR(ENOMEM); | ||||
| return 0; | return 0; | ||||
| @@ -301,28 +289,16 @@ static int end_frame(AVFilterLink *inlink) | |||||
| AVFilterLink *outlink = inlink->dst->outputs[0]; | AVFilterLink *outlink = inlink->dst->outputs[0]; | ||||
| AVFilterBufferRef *inpic = inlink ->cur_buf; | AVFilterBufferRef *inpic = inlink ->cur_buf; | ||||
| AVFilterBufferRef *outpic = outlink->out_buf; | AVFilterBufferRef *outpic = outlink->out_buf; | ||||
| int cw = inpic->video->w >> hqdn3d->hsub; | |||||
| int ch = inpic->video->h >> hqdn3d->vsub; | |||||
| int ret; | |||||
| 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]); | |||||
| int ret, c; | |||||
| 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 || | if ((ret = ff_draw_slice(outlink, 0, inpic->video->h, 1)) < 0 || | ||||
| (ret = ff_end_frame(outlink)) < 0) | (ret = ff_end_frame(outlink)) < 0) | ||||
| @@ -341,6 +317,7 @@ AVFilter avfilter_vf_hqdn3d = { | |||||
| .inputs = (const AVFilterPad[]) {{ .name = "default", | .inputs = (const AVFilterPad[]) {{ .name = "default", | ||||
| .type = AVMEDIA_TYPE_VIDEO, | .type = AVMEDIA_TYPE_VIDEO, | ||||
| .start_frame = ff_inplace_start_frame, | |||||
| .draw_slice = null_draw_slice, | .draw_slice = null_draw_slice, | ||||
| .config_props = config_input, | .config_props = config_input, | ||||
| .end_frame = end_frame }, | .end_frame = end_frame }, | ||||
| @@ -157,6 +157,42 @@ int ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) | |||||
| return ff_start_frame(link->dst->outputs[0], buf_out); | 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) | static int default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) | ||||
| { | { | ||||
| AVFilterLink *outlink = NULL; | AVFilterLink *outlink = NULL; | ||||
| @@ -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, | AVFilterBufferRef *ff_get_video_buffer(AVFilterLink *link, int perms, | ||||
| int w, int h); | 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_start_frame(AVFilterLink *link, AVFilterBufferRef *picref); | ||||
| int ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir); | int ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir); | ||||
| int ff_null_end_frame(AVFilterLink *link); | int ff_null_end_frame(AVFilterLink *link); | ||||
| @@ -741,6 +741,15 @@ typedef struct AVStream { | |||||
| int64_t codec_info_duration; | int64_t codec_info_duration; | ||||
| int nb_decoded_frames; | int nb_decoded_frames; | ||||
| int found_decoder; | 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; | } *info; | ||||
| int pts_wrap_bits; /**< number of bits in pts (used for wrapping control) */ | 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_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_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_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_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_DISCARD_CORRUPT 0x0100 ///< Discard frames marked corrupted | ||||
| #define AVFMT_FLAG_MP4A_LATM 0x8000 ///< Enable RTP MP4A-LATM payload | #define AVFMT_FLAG_MP4A_LATM 0x8000 ///< Enable RTP MP4A-LATM payload | ||||
| @@ -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"}, | {"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"}, | {"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"}, | {"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}, | {"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}, | {"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}, | {"indexmem", "max memory used for timestamp index (per stream)", OFFSET(max_index_size), AV_OPT_TYPE_INT, {.dbl = 1<<20 }, 0, INT_MAX, D}, | ||||
| @@ -2557,6 +2557,8 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) | |||||
| for (i=0; i<ic->nb_streams; i++) { | for (i=0; i<ic->nb_streams; i++) { | ||||
| ic->streams[i]->info->last_dts = AV_NOPTS_VALUE; | 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; | count = 0; | ||||
| @@ -2630,13 +2632,37 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) | |||||
| break; | 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; | read_size += pkt->size; | ||||
| st = ic->streams[pkt->stream_index]; | 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) { | if (st->codec_info_nb_frames>1) { | ||||
| int64_t t=0; | int64_t t=0; | ||||
| if (st->time_base.den > 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; | 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, | 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->codec_info_nb_frames-2)*(int64_t)st->time_base.den, | ||||
| st->info->codec_info_duration*(int64_t)st->time_base.num, 60000); | 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 | // 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. | // a unreliable/inexact time base, but a time base that is finer than necessary, as e.g. | ||||
| // ipmovie.c produces. | // ipmovie.c produces. | ||||
| @@ -30,7 +30,7 @@ | |||||
| #include "libavutil/avutil.h" | #include "libavutil/avutil.h" | ||||
| #define LIBAVFORMAT_VERSION_MAJOR 54 | #define LIBAVFORMAT_VERSION_MAJOR 54 | ||||
| #define LIBAVFORMAT_VERSION_MINOR 21 | |||||
| #define LIBAVFORMAT_VERSION_MINOR 22 | |||||
| #define LIBAVFORMAT_VERSION_MICRO 100 | #define LIBAVFORMAT_VERSION_MICRO 100 | ||||
| #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ | #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ | ||||
| @@ -35,10 +35,10 @@ FATE_FILTER += fate-filter-delogo | |||||
| FATE_SAMPLES_AVCONV += fate-filter-delogo | FATE_SAMPLES_AVCONV += fate-filter-delogo | ||||
| FATE_YADIF += fate-filter-yadif-mode0 | 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_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_FILTER += $(FATE_YADIF) | ||||
| FATE_SAMPLES_AVCONV += $(FATE_YADIF) | FATE_SAMPLES_AVCONV += $(FATE_YADIF) | ||||
| @@ -1,32 +1,32 @@ | |||||
| #tb 0: 1/25 | #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 | |||||
| @@ -1,34 +1,34 @@ | |||||
| #tb 0: 1/25 | #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 | |||||