From e87a6f0dc99c2266e68ef66afaf83462d353964c Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sun, 20 Mar 2011 19:49:10 +0000 Subject: [PATCH 01/33] Move ff_dct_init_mmx declaration to dct.h This was missed in 0aded94. Signed-off-by: Mans Rullgard --- libavcodec/dct.h | 2 ++ libavcodec/fft.h | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/dct.h b/libavcodec/dct.h index 141518d250..faddaa3d7b 100644 --- a/libavcodec/dct.h +++ b/libavcodec/dct.h @@ -47,4 +47,6 @@ struct DCTContext { int ff_dct_init(DCTContext *s, int nbits, enum DCTTransformType type); void ff_dct_end (DCTContext *s); +void ff_dct_init_mmx(DCTContext *s); + #endif diff --git a/libavcodec/fft.h b/libavcodec/fft.h index a7ba00fe1a..36be9962ad 100644 --- a/libavcodec/fft.h +++ b/libavcodec/fft.h @@ -99,7 +99,6 @@ int ff_fft_init(FFTContext *s, int nbits, int inverse); void ff_fft_init_altivec(FFTContext *s); void ff_fft_init_mmx(FFTContext *s); void ff_fft_init_arm(FFTContext *s); -void ff_dct_init_mmx(DCTContext *s); void ff_fft_end(FFTContext *s); From cb48e245e6e770f146220fac0a8bd4dc1a5e006c Mon Sep 17 00:00:00 2001 From: "Panagiotis H.M. Issaris" Date: Thu, 10 Mar 2011 16:07:52 +0100 Subject: [PATCH 02/33] Do no modify terminal parameters using termios.h Remove usage of tcgetattr and tcsetattr to modify terminal parameters, and rely on ctrl-c to stop instead of pressing 'q'. On systems with conio.h, keep the old behavior. Changing the terminal settings causes problems if multiple instances are running asynchronously on the same terminal, such as during a parallel FATE run, or if the process crashes before restoring the terminal. In both cases, the terminal state is messed up requiring a manual reset. Signed-off-by: Mans Rullgard --- configure | 2 -- ffmpeg.c | 60 ++++++------------------------------------------------- 2 files changed, 6 insertions(+), 56 deletions(-) diff --git a/configure b/configure index 99c67c36ab..4fd71cd8f6 100755 --- a/configure +++ b/configure @@ -1114,7 +1114,6 @@ HAVE_LIST=" sys_soundcard_h sys_videoio_h ten_operands - termios_h threads truncf vfp_args @@ -2791,7 +2790,6 @@ check_header poll.h check_header sys/mman.h check_header sys/resource.h check_header sys/select.h -check_header termios.h check_header vdpau/vdpau.h check_header vdpau/vdpau_x11.h check_header X11/extensions/XvMClib.h diff --git a/ffmpeg.c b/ffmpeg.c index 02bc193668..645fdb6db8 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -69,12 +69,7 @@ #include #endif -#if HAVE_TERMIOS_H -#include -#include -#include -#include -#elif HAVE_CONIO_H +#if HAVE_CONIO_H #include #endif #include @@ -340,12 +335,6 @@ typedef struct AVInputFile { int nb_streams; /* nb streams we are aware of */ } AVInputFile; -#if HAVE_TERMIOS_H - -/* init terminal so that we can grab keys */ -static struct termios oldtty; -#endif - #if CONFIG_AVFILTER static int configure_filters(AVInputStream *ist, AVOutputStream *ost) @@ -423,9 +412,6 @@ static int configure_filters(AVInputStream *ist, AVOutputStream *ost) static void term_exit(void) { av_log(NULL, AV_LOG_QUIET, ""); -#if HAVE_TERMIOS_H - tcsetattr (0, TCSANOW, &oldtty); -#endif } static volatile int received_sigterm = 0; @@ -439,26 +425,6 @@ sigterm_handler(int sig) static void term_init(void) { -#if HAVE_TERMIOS_H - struct termios tty; - - tcgetattr (0, &tty); - oldtty = tty; - atexit(term_exit); - - tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP - |INLCR|IGNCR|ICRNL|IXON); - tty.c_oflag |= OPOST; - tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN); - tty.c_cflag &= ~(CSIZE|PARENB); - tty.c_cflag |= CS8; - tty.c_cc[VMIN] = 1; - tty.c_cc[VTIME] = 0; - - tcsetattr (0, TCSANOW, &tty); - signal(SIGQUIT, sigterm_handler); /* Quit (POSIX). */ -#endif - signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */ signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */ #ifdef SIGXCPU @@ -469,25 +435,7 @@ static void term_init(void) /* read a key without blocking */ static int read_key(void) { -#if HAVE_TERMIOS_H - int n = 1; - unsigned char ch; - struct timeval tv; - fd_set rfds; - - FD_ZERO(&rfds); - FD_SET(0, &rfds); - tv.tv_sec = 0; - tv.tv_usec = 0; - n = select(1, &rfds, NULL, NULL, &tv); - if (n > 0) { - n = read(0, &ch, 1); - if (n == 1) - return ch; - - return n; - } -#elif HAVE_CONIO_H +#if HAVE_CONIO_H if(kbhit()) return(getch()); #endif @@ -2489,7 +2437,11 @@ static int transcode(AVFormatContext **output_files, } if (!using_stdin && verbose >= 0) { +#if HAVE_CONIO_H fprintf(stderr, "Press [q] to stop encoding\n"); +#else + fprintf(stderr, "Press ctrl-c to stop encoding\n"); +#endif url_set_interrupt_cb(decode_interrupt_cb); } term_init(); From 027f60f32b758aa8e7c08685729084b1a12d81e9 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sun, 20 Mar 2011 22:04:47 +0000 Subject: [PATCH 03/33] ffv1: allocate correct size for sample buffer This fixes a typo in the size calculation for the sample buffer introduced in cbabccc367424. Signed-off-by: Mans Rullgard --- libavcodec/ffv1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c index e1e19d2e1f..8b46091462 100644 --- a/libavcodec/ffv1.c +++ b/libavcodec/ffv1.c @@ -792,7 +792,7 @@ static av_cold int init_slice_contexts(FFV1Context *f){ fs->slice_x = sxs; fs->slice_y = sys; - fs->sample_buffer = av_malloc(6 * (fs->width+6) * sizeof(*fs->sample_buffer)); + fs->sample_buffer = av_malloc(9 * (fs->width+6) * sizeof(*fs->sample_buffer)); if (!fs->sample_buffer) return AVERROR(ENOMEM); } From e42500cb4f5e51aec072fe1994c367823ca36f47 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 17 Mar 2011 07:35:18 +0100 Subject: [PATCH 04/33] lavf: replace some more avio_seek(SEEK_CUR) with avio_skip Signed-off-by: Ronald S. Bultje --- libavformat/mp3dec.c | 2 +- libavformat/wtv.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c index 407377354a..dbecf3d2a7 100644 --- a/libavformat/mp3dec.c +++ b/libavformat/mp3dec.c @@ -90,7 +90,7 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) return -1; /* Check for Xing / Info tag */ - avio_seek(s->pb, xing_offtbl[c.lsf == 1][c.nb_channels == 1], SEEK_CUR); + avio_skip(s->pb, xing_offtbl[c.lsf == 1][c.nb_channels == 1]); v = avio_rb32(s->pb); if(v == MKBETAG('X', 'i', 'n', 'g') || v == MKBETAG('I', 'n', 'f', 'o')) { v = avio_rb32(s->pb); diff --git a/libavformat/wtv.c b/libavformat/wtv.c index ab51af4023..963a6bc753 100644 --- a/libavformat/wtv.c +++ b/libavformat/wtv.c @@ -701,10 +701,10 @@ static AVStream * parse_media_type(AVFormatContext *s, AVStream *st, int sid, return NULL; if (!ff_guidcmp(formattype, format_videoinfo2)) { int consumed = parse_videoinfoheader2(s, st); - avio_seek(pb, FFMAX(size - consumed, 0), SEEK_CUR); + avio_skip(pb, FFMAX(size - consumed, 0)); } else if (!ff_guidcmp(formattype, format_mpeg2_video)) { int consumed = parse_videoinfoheader2(s, st); - avio_seek(pb, FFMAX(size - consumed, 0), SEEK_CUR); + avio_skip(pb, FFMAX(size - consumed, 0)); } else { if (ff_guidcmp(formattype, format_none)) av_log(s, AV_LOG_WARNING, "unknown formattype:"PRI_GUID"\n", ARG_GUID(formattype)); From 447fe3369177c11a49a3d376cfa3a2be468ac913 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 17 Mar 2011 07:41:19 +0100 Subject: [PATCH 05/33] rmenc: replace avio_seek(0) with avio_tell() Signed-off-by: Ronald S. Bultje --- libavformat/rmenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/rmenc.c b/libavformat/rmenc.c index aa11744f43..6f8b0937f3 100644 --- a/libavformat/rmenc.c +++ b/libavformat/rmenc.c @@ -436,7 +436,7 @@ static int rm_write_trailer(AVFormatContext *s) if (!url_is_streamed(s->pb)) { /* end of file: finish to write header */ - index_pos = avio_seek(pb, 0, SEEK_CUR); + index_pos = avio_tell(pb); data_size = index_pos - rm->data_pos; /* FIXME: write index */ From 8d9769a77b49b0d633c835d99ed3c0aa3f3b77a1 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 17 Mar 2011 14:03:31 +0100 Subject: [PATCH 06/33] avio: deprecate url_fileno It's an evil hack that assumes an AVIOContext is always based on top of an URLContext. It's also not used anywhere. Signed-off-by: Ronald S. Bultje --- libavformat/avio.h | 3 ++- libavformat/aviobuf.c | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libavformat/avio.h b/libavformat/avio.h index e9d3b1752b..1b483b3a4d 100644 --- a/libavformat/avio.h +++ b/libavformat/avio.h @@ -623,9 +623,10 @@ int url_resetbuf(AVIOContext *s, int flags); int avio_open(AVIOContext **s, const char *url, int flags); int avio_close(AVIOContext *s); -URLContext *url_fileno(AVIOContext *s); #if FF_API_OLD_AVIO +attribute_deprecated URLContext *url_fileno(AVIOContext *s); + /** * @deprecated use AVIOContext.max_packet_size directly. */ diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index 4cd3bdc47d..9f0f292aff 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -923,10 +923,12 @@ int avio_close(AVIOContext *s) return url_close(h); } +#if FF_API_OLD_AVIO URLContext *url_fileno(AVIOContext *s) { return s->opaque; } +#endif int avio_printf(AVIOContext *s, const char *fmt, ...) { From 72452cc475544b6e294676abd3fa5e0518f81841 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 1 Mar 2011 11:37:55 -0500 Subject: [PATCH 07/33] vc1: warn for unimplemented pan-scan feature. --- libavcodec/vc1.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index 0f8a42c45a..77e71db778 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -863,6 +863,7 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) } } if(v->panscanflag) { + av_log_missing_feature(v->s.avctx, "Pan-scan", 0); //... } v->rnd = get_bits1(gb); From b81a935bd99c2664b07f717113e71d1aa32be991 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 1 Mar 2011 11:37:55 -0500 Subject: [PATCH 08/33] vc1: fix up memleaks in the error codepath. Introduce end: and err: labels at the end of vc1_decode_frame(), which will clean up allocated memory consistently. --- libavcodec/vc1dec.c | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 62cf96c54e..98940714eb 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -3217,15 +3217,14 @@ static int vc1_decode_frame(AVCodecContext *avctx, divider = find_next_marker(buf, buf + buf_size); if((divider == (buf + buf_size)) || AV_RB32(divider) != VC1_CODE_FIELD){ av_log(avctx, AV_LOG_ERROR, "Error in WVC1 interlaced frame\n"); - av_free(buf2); - return -1; + goto err; } buf_size2 = vc1_unescape_buffer(buf, divider - buf, buf2); // TODO if(!v->warn_interlaced++) av_log(v->s.avctx, AV_LOG_ERROR, "Interlaced WVC1 support is not implemented\n"); - av_free(buf2);return -1; + goto err; }else{ buf_size2 = vc1_unescape_buffer(buf, buf_size, buf2); } @@ -3235,19 +3234,16 @@ static int vc1_decode_frame(AVCodecContext *avctx, // do parse frame header if(v->profile < PROFILE_ADVANCED) { if(vc1_parse_frame_header(v, &s->gb) == -1) { - av_free(buf2); - return -1; + goto err; } } else { if(vc1_parse_frame_header_adv(v, &s->gb) == -1) { - av_free(buf2); - return -1; + goto err; } } if(v->res_sprite && (s->pict_type!=FF_I_TYPE)){ - av_free(buf2); - return -1; + goto err; } // for hurry_up==5 @@ -3256,33 +3252,29 @@ static int vc1_decode_frame(AVCodecContext *avctx, /* skip B-frames if we don't have reference frames */ if(s->last_picture_ptr==NULL && (s->pict_type==FF_B_TYPE || s->dropable)){ - av_free(buf2); - return -1;//buf_size; + goto err; } /* skip b frames if we are in a hurry */ if(avctx->hurry_up && s->pict_type==FF_B_TYPE) return -1;//buf_size; if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==FF_B_TYPE) || (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=FF_I_TYPE) || avctx->skip_frame >= AVDISCARD_ALL) { - av_free(buf2); - return buf_size; + goto end; } /* skip everything if we are in a hurry>=5 */ if(avctx->hurry_up>=5) { - av_free(buf2); - return -1;//buf_size; + goto err; } if(s->next_p_frame_damaged){ if(s->pict_type==FF_B_TYPE) - return buf_size; + goto end; else s->next_p_frame_damaged=0; } if(MPV_frame_start(s, avctx) < 0) { - av_free(buf2); - return -1; + goto err; } s->me.qpel_put= s->dsp.put_qpel_pixels_tab; @@ -3293,17 +3285,17 @@ static int vc1_decode_frame(AVCodecContext *avctx, ff_vdpau_vc1_decode_picture(s, buf_start, (buf + buf_size) - buf_start); else if (avctx->hwaccel) { if (avctx->hwaccel->start_frame(avctx, buf, buf_size) < 0) - return -1; + goto err; if (avctx->hwaccel->decode_slice(avctx, buf_start, (buf + buf_size) - buf_start) < 0) - return -1; + goto err; if (avctx->hwaccel->end_frame(avctx) < 0) - return -1; + goto err; } else { ff_er_frame_start(s); v->bits = buf_size * 8; vc1_decode_blocks(v); -//av_log(s->avctx, AV_LOG_INFO, "Consumed %i/%i bits\n", get_bits_count(&s->gb), buf_size*8); +//av_log(s->avctx, AV_LOG_INFO, "Consumed %i/%i bits\n", get_bits_count(&s->gb), s->gb.size_in_bits); // if(get_bits_count(&s->gb) > buf_size * 8) // return -1; ff_er_frame_end(s); @@ -3324,8 +3316,13 @@ assert(s->current_picture.pict_type == s->pict_type); ff_print_debug_info(s, pict); } +end: av_free(buf2); return buf_size; + +err: + av_free(buf2); + return -1; } From f44d6445b7a189fde27ca0e95c7eb08f697e109f Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 21 Mar 2011 10:00:43 -0400 Subject: [PATCH 09/33] vc1: slice support. Also reset coded_block at each new slice, fixes problems in slice playback. --- libavcodec/vc1dec.c | 81 +++++++++++++++++++++++++++++++-------------- 1 file changed, 57 insertions(+), 24 deletions(-) diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 98940714eb..cef26e159c 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -2686,7 +2686,7 @@ static void vc1_decode_i_blocks(VC1Context *v) /** Decode blocks of I-frame for advanced profile */ -static void vc1_decode_i_blocks_adv(VC1Context *v) +static void vc1_decode_i_blocks_adv(VC1Context *v, int mby_start, int mby_end) { int k; MpegEncContext *s = &v->s; @@ -2728,8 +2728,15 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) s->mb_x = s->mb_y = 0; s->mb_intra = 1; s->first_slice_line = 1; + s->mb_y = mby_start; + if (mby_start) { + s->mb_x = 0; + ff_init_block_index(s); + memset(&s->coded_block[s->block_index[0]-s->b8_stride], 0, + s->b8_stride * sizeof(*s->coded_block)); + } idct8x8_fn = v->vc1dsp.vc1_inv_trans_8x8_put_signed[0]; - for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) { + for(; s->mb_y < mby_end; s->mb_y++) { s->mb_x = 0; ff_init_block_index(s); for(;s->mb_x < s->mb_width; s->mb_x++) { @@ -2815,7 +2822,7 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) if(v->s.loop_filter) vc1_loop_filter_iblk(v, v->pq); if(get_bits_count(&s->gb) > v->bits) { - ff_er_add_slice(s, 0, 0, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)); + ff_er_add_slice(s, 0, mby_start, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)); av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n", get_bits_count(&s->gb), v->bits); return; } @@ -2828,10 +2835,10 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) } if (v->s.loop_filter) ff_draw_horiz_band(s, (s->mb_height-1)*16, 16); - ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END)); + ff_er_add_slice(s, 0, mby_start, s->mb_width - 1, mby_end - 1, (AC_END|DC_END|MV_END)); } -static void vc1_decode_p_blocks(VC1Context *v) +static void vc1_decode_p_blocks(VC1Context *v, int mby_start, int mby_end) { MpegEncContext *s = &v->s; @@ -2862,7 +2869,7 @@ static void vc1_decode_p_blocks(VC1Context *v) s->first_slice_line = 1; memset(v->cbp_base, 0, sizeof(v->cbp_base[0])*2*s->mb_stride); - for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) { + for(s->mb_y = mby_start; s->mb_y < mby_end; s->mb_y++) { s->mb_x = 0; ff_init_block_index(s); for(; s->mb_x < s->mb_width; s->mb_x++) { @@ -2870,7 +2877,7 @@ static void vc1_decode_p_blocks(VC1Context *v) vc1_decode_p_mb(v); if(get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) { - ff_er_add_slice(s, 0, 0, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)); + ff_er_add_slice(s, 0, mby_start, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)); av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n", get_bits_count(&s->gb), v->bits,s->mb_x,s->mb_y); return; } @@ -2879,10 +2886,10 @@ static void vc1_decode_p_blocks(VC1Context *v) ff_draw_horiz_band(s, s->mb_y * 16, 16); s->first_slice_line = 0; } - ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END)); + ff_er_add_slice(s, 0, mby_start, s->mb_width - 1, mby_end - 1, (AC_END|DC_END|MV_END)); } -static void vc1_decode_b_blocks(VC1Context *v) +static void vc1_decode_b_blocks(VC1Context *v, int mby_start, int mby_end) { MpegEncContext *s = &v->s; @@ -2912,7 +2919,7 @@ static void vc1_decode_b_blocks(VC1Context *v) } s->first_slice_line = 1; - for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) { + for(s->mb_y = mby_start; s->mb_y < mby_end; s->mb_y++) { s->mb_x = 0; ff_init_block_index(s); for(; s->mb_x < s->mb_width; s->mb_x++) { @@ -2920,7 +2927,7 @@ static void vc1_decode_b_blocks(VC1Context *v) vc1_decode_b_mb(v); if(get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) { - ff_er_add_slice(s, 0, 0, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)); + ff_er_add_slice(s, 0, mby_start, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)); av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n", get_bits_count(&s->gb), v->bits,s->mb_x,s->mb_y); return; } @@ -2934,7 +2941,7 @@ static void vc1_decode_b_blocks(VC1Context *v) } if (v->s.loop_filter) ff_draw_horiz_band(s, (s->mb_height-1)*16, 16); - ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END)); + ff_er_add_slice(s, 0, mby_start, s->mb_width - 1, mby_end - 1, (AC_END|DC_END|MV_END)); } static void vc1_decode_skip_blocks(VC1Context *v) @@ -2956,18 +2963,17 @@ static void vc1_decode_skip_blocks(VC1Context *v) s->pict_type = FF_P_TYPE; } -static void vc1_decode_blocks(VC1Context *v) +static void vc1_decode_blocks(VC1Context *v, int mby_start, int mby_end) { v->s.esc3_level_length = 0; if(v->x8_type){ ff_intrax8_decode_picture(&v->x8, 2*v->pq+v->halfpq, v->pq*(!v->pquantizer) ); }else{ - switch(v->s.pict_type) { case FF_I_TYPE: if(v->profile == PROFILE_ADVANCED) - vc1_decode_i_blocks_adv(v); + vc1_decode_i_blocks_adv(v, mby_start, mby_end); else vc1_decode_i_blocks(v); break; @@ -2975,16 +2981,16 @@ static void vc1_decode_blocks(VC1Context *v) if(v->p_frame_skipped) vc1_decode_skip_blocks(v); else - vc1_decode_p_blocks(v); + vc1_decode_p_blocks(v, mby_start, mby_end); break; case FF_B_TYPE: if(v->bi_type){ if(v->profile == PROFILE_ADVANCED) - vc1_decode_i_blocks_adv(v); + vc1_decode_i_blocks_adv(v, mby_start, mby_end); else vc1_decode_i_blocks(v); }else - vc1_decode_b_blocks(v); + vc1_decode_b_blocks(v, mby_start, mby_end); break; } } @@ -3145,12 +3151,17 @@ static int vc1_decode_frame(AVCodecContext *avctx, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; + int buf_size = avpkt->size, n_slices = 0, i; VC1Context *v = avctx->priv_data; MpegEncContext *s = &v->s; AVFrame *pict = data; uint8_t *buf2 = NULL; const uint8_t *buf_start = buf; + struct { + uint8_t *buf; + GetBitContext gb; + int mby_start; + } *slices = NULL; /* no supplementary picture */ if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == VC1_CODE_ENDOFSEQ)) { @@ -3205,10 +3216,20 @@ static int vc1_decode_frame(AVCodecContext *avctx, init_get_bits(&s->gb, buf2, buf_size2*8); vc1_decode_entry_point(avctx, v, &s->gb); break; - case VC1_CODE_SLICE: - av_log(avctx, AV_LOG_ERROR, "Sliced decoding is not implemented (yet)\n"); - av_free(buf2); - return -1; + case VC1_CODE_SLICE: { + int buf_size3; + slices = av_realloc(slices, sizeof(*slices) * (n_slices+1)); + if (!slices) goto err; + slices[n_slices].buf = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!slices[n_slices].buf) goto err; + buf_size3 = vc1_unescape_buffer(start + 4, size, + slices[n_slices].buf); + init_get_bits(&slices[n_slices].gb, slices[n_slices].buf, + buf_size3 << 3); + slices[n_slices].mby_start = get_bits(&slices[n_slices].gb, 9); + n_slices++; + break; + } } } }else if(v->interlace && ((buf[0] & 0xC0) == 0xC0)){ /* WVC1 interlaced stores both fields divided by marker */ @@ -3294,7 +3315,13 @@ static int vc1_decode_frame(AVCodecContext *avctx, ff_er_frame_start(s); v->bits = buf_size * 8; - vc1_decode_blocks(v); + for (i = 0; i <= n_slices; i++) { + if (i && get_bits1(&s->gb)) + vc1_parse_frame_header_adv(v, &s->gb); + vc1_decode_blocks(v, i == 0 ? 0 : FFMAX(0, slices[i-1].mby_start), + i == n_slices ? s->mb_height : FFMIN(s->mb_height, slices[i].mby_start)); + if (i != n_slices) s->gb = slices[i].gb; + } //av_log(s->avctx, AV_LOG_INFO, "Consumed %i/%i bits\n", get_bits_count(&s->gb), s->gb.size_in_bits); // if(get_bits_count(&s->gb) > buf_size * 8) // return -1; @@ -3318,10 +3345,16 @@ assert(s->current_picture.pict_type == s->pict_type); end: av_free(buf2); + for (i = 0; i < n_slices; i++) + av_free(slices[i].buf); + av_free(slices); return buf_size; err: av_free(buf2); + for (i = 0; i < n_slices; i++) + av_free(slices[i].buf); + av_free(slices); return -1; } From 933e90a69a4b9c558d4fae9dffb15378910481d3 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 14 Mar 2011 20:38:59 +0100 Subject: [PATCH 10/33] avio: make av_url_read_fseek/fpause internal. Signed-off-by: Ronald S. Bultje --- libavformat/asfdec.c | 3 ++- libavformat/avio.h | 7 +++---- libavformat/avio_internal.h | 5 +++++ libavformat/aviobuf.c | 15 ++++++++++++--- libavformat/flvdec.c | 5 +++-- libavformat/utils.c | 4 ++-- 6 files changed, 27 insertions(+), 12 deletions(-) diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c index b5fc92071e..15dc55b823 100644 --- a/libavformat/asfdec.c +++ b/libavformat/asfdec.c @@ -25,6 +25,7 @@ #include "libavutil/avstring.h" #include "libavcodec/mpegaudio.h" #include "avformat.h" +#include "avio_internal.h" #include "riff.h" #include "asf.h" #include "asfcrypt.h" @@ -1243,7 +1244,7 @@ static int asf_read_seek(AVFormatContext *s, int stream_index, int64_t pts, int /* Try using the protocol's read_seek if available */ if(s->pb) { - int ret = av_url_read_fseek(s->pb, stream_index, pts, flags); + int ret = ffio_read_seek(s->pb, stream_index, pts, flags); if(ret >= 0) asf_reset_header(s); if (ret != AVERROR(ENOSYS)) diff --git a/libavformat/avio.h b/libavformat/avio.h index 1b483b3a4d..753fa0cc89 100644 --- a/libavformat/avio.h +++ b/libavformat/avio.h @@ -415,6 +415,9 @@ attribute_deprecated void put_tag(AVIOContext *s, const char *tag); * @} */ +attribute_deprecated int av_url_read_fpause(AVIOContext *h, int pause); +attribute_deprecated int64_t av_url_read_fseek( AVIOContext *h, int stream_index, + int64_t timestamp, int flags); /** * @defgroup old_url_f_funcs Old url_f* functions @@ -513,10 +516,6 @@ static av_always_inline int64_t avio_tell(AVIOContext *s) */ int64_t avio_size(AVIOContext *s); -int av_url_read_fpause(AVIOContext *h, int pause); -int64_t av_url_read_fseek(AVIOContext *h, int stream_index, - int64_t timestamp, int flags); - /** @warning currently size is limited */ #ifdef __GNUC__ int avio_printf(AVIOContext *s, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 2, 3))); diff --git a/libavformat/avio_internal.h b/libavformat/avio_internal.h index 9653a65820..7dd9bdf6a0 100644 --- a/libavformat/avio_internal.h +++ b/libavformat/avio_internal.h @@ -66,4 +66,9 @@ uint64_t ffio_read_varlen(AVIOContext *bc); /** @warning must be called before any I/O */ int ffio_set_buf_size(AVIOContext *s, int buf_size); +int ffio_read_pause(AVIOContext *h, int pause); +int64_t ffio_read_seek( AVIOContext *h, int stream_index, + int64_t timestamp, int flags); + + #endif // AVFORMAT_AVIO_INTERNAL_H diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index 9f0f292aff..bb417e0506 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -397,6 +397,15 @@ void put_flush_packet(AVIOContext *s) { avio_flush(s); } +int av_url_read_fpause(AVIOContext *s, int pause) +{ + return ffio_read_pause(s, pause); +} +int64_t av_url_read_fseek(AVIOContext *s, int stream_index, + int64_t timestamp, int flags) +{ + return ffio_read_seek(s, stream_index, timestamp, flags); +} #endif int avio_put_str(AVIOContext *s, const char *str) @@ -971,15 +980,15 @@ int url_fget_max_packet_size(AVIOContext *s) } #endif -int av_url_read_fpause(AVIOContext *s, int pause) +int ffio_read_pause(AVIOContext *s, int pause) { if (!s->read_pause) return AVERROR(ENOSYS); return s->read_pause(s->opaque, pause); } -int64_t av_url_read_fseek(AVIOContext *s, int stream_index, - int64_t timestamp, int flags) +int64_t ffio_read_seek(AVIOContext *s, int stream_index, + int64_t timestamp, int flags) { URLContext *h = s->opaque; int64_t ret; diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 1143adf40e..2152f7d55a 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -28,6 +28,7 @@ #include "libavcodec/bytestream.h" #include "libavcodec/mpeg4audio.h" #include "avformat.h" +#include "avio_internal.h" #include "flv.h" typedef struct { @@ -461,7 +462,7 @@ leave: static int flv_read_seek(AVFormatContext *s, int stream_index, int64_t ts, int flags) { - return av_url_read_fseek(s->pb, stream_index, ts, flags); + return ffio_read_seek(s->pb, stream_index, ts, flags); } #if 0 /* don't know enough to implement this */ @@ -482,7 +483,7 @@ static int flv_read_seek2(AVFormatContext *s, int stream_index, ts = av_rescale_rnd(ts, 1000, AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ? AV_ROUND_DOWN : AV_ROUND_UP); } - ret = av_url_read_fseek(s->pb, stream_index, ts, flags); + ret = ffio_read_seek(s->pb, stream_index, ts, flags); } if (ret == AVERROR(ENOSYS)) diff --git a/libavformat/utils.c b/libavformat/utils.c index 89ce39593b..8c0bf77f35 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2553,7 +2553,7 @@ int av_read_play(AVFormatContext *s) if (s->iformat->read_play) return s->iformat->read_play(s); if (s->pb) - return av_url_read_fpause(s->pb, 0); + return ffio_read_pause(s->pb, 0); return AVERROR(ENOSYS); } @@ -2562,7 +2562,7 @@ int av_read_pause(AVFormatContext *s) if (s->iformat->read_pause) return s->iformat->read_pause(s); if (s->pb) - return av_url_read_fpause(s->pb, 1); + return ffio_read_pause(s->pb, 1); return AVERROR(ENOSYS); } From bca6dee386307e4f3646632d98a9db87ce9de249 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 17 Mar 2011 07:10:23 +0100 Subject: [PATCH 11/33] id3v2: explicitly seek to the end of the tag after reading Current code might stop in the middle of an invalid tag. fixes issue2650 Signed-off-by: Ronald S. Bultje --- libavformat/id3v2.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index bb360202fc..fb4c761a27 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -186,7 +186,7 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t { int isv34, tlen, unsync; char tag[5]; - int64_t next; + int64_t next, end = avio_tell(s->pb) + len; int taghdrlen; const char *reason; AVIOContext pb; @@ -284,8 +284,9 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t avio_skip(s->pb, len); } if (version == 4 && flags & 0x10) /* Footer preset, always 10 bytes, skip over it */ - avio_skip(s->pb, 10); + end += 10; + avio_seek(s->pb, end, SEEK_SET); av_free(buffer); return; From eb1e7f78ea9f8db391961d8fe30b3fae3ea20d5c Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 15 Mar 2011 07:54:22 +0100 Subject: [PATCH 12/33] id3v2: simplify error handling. Signed-off-by: Ronald S. Bultje --- libavformat/id3v2.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index fb4c761a27..13272a493f 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -188,7 +188,7 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t char tag[5]; int64_t next, end = avio_tell(s->pb) + len; int taghdrlen; - const char *reason; + const char *reason = NULL; AVIOContext pb; unsigned char *buffer = NULL; int buffer_size = 0; @@ -286,14 +286,12 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t if (version == 4 && flags & 0x10) /* Footer preset, always 10 bytes, skip over it */ end += 10; + error: + if (reason) + av_log(s, AV_LOG_INFO, "ID3v2.%d tag skipped, cannot handle %s\n", version, reason); avio_seek(s->pb, end, SEEK_SET); av_free(buffer); return; - - error: - av_log(s, AV_LOG_INFO, "ID3v2.%d tag skipped, cannot handle %s\n", version, reason); - avio_seek(s->pb, len, SEEK_CUR); - av_free(buffer); } void ff_id3v2_read(AVFormatContext *s, const char *magic) From 648c79624fa70414dfb644fcb84b9de15e6568b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 21 Mar 2011 15:52:54 +0200 Subject: [PATCH 13/33] ffplay: Don't assume ic->pb is non-null This fixes crashes on exit when plaing some RealRTSP streams (among other), e.g. rtsp://dl.lib.brown.edu:554/areserves/1093545294660883.mp3. These crashes have been present since 3e68b3ba7b015cf21. Signed-off-by: Ronald S. Bultje --- ffplay.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ffplay.c b/ffplay.c index 1e5244c805..ddd2c4d4f2 100644 --- a/ffplay.c +++ b/ffplay.c @@ -2568,9 +2568,9 @@ static int decode_thread(void *arg) } ret = av_read_frame(ic, pkt); if (ret < 0) { - if (ret == AVERROR_EOF || ic->pb->eof_reached) + if (ret == AVERROR_EOF || (ic->pb && ic->pb->eof_reached)) eof=1; - if (ic->pb->error) + if (ic->pb && ic->pb->error) break; SDL_Delay(100); /* wait for user event */ continue; From dc8b73c0690fbefaf8147653758919875361e8d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 21 Mar 2011 12:20:18 +0200 Subject: [PATCH 14/33] applehttp: Change the variable for stream position in seconds into int64_t A similar variable for the total stream duration was changed to int64_t in b79c3df08807c96a945, due to overflows in some odd streams. Signed-off-by: Luca Barbato --- libavformat/applehttp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavformat/applehttp.c b/libavformat/applehttp.c index af67b28f2d..56fb795ecf 100644 --- a/libavformat/applehttp.c +++ b/libavformat/applehttp.c @@ -496,7 +496,8 @@ static int applehttp_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { AppleHTTPContext *c = s->priv_data; - int pos = 0, i; + int64_t pos = 0; + int i; struct variant *var = c->variants[0]; if ((flags & AVSEEK_FLAG_BYTE) || !c->finished) From 417516f63f8a9ee214ee9fa6fcb483962ea0f096 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 21 Mar 2011 20:22:51 +0100 Subject: [PATCH 15/33] Set the correct target for mingw64 dlltool That fixes .lib creation for the win64 target. --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 4fd71cd8f6..a2ad321e34 100755 --- a/configure +++ b/configure @@ -2405,7 +2405,7 @@ case $target_os in LIBTARGET=i386 if enabled x86_64; then enable malloc_aligned - LIBTARGET=x64 + LIBTARGET="i386:x86-64" elif enabled arm; then LIBTARGET=arm fi From 895678f8239213db1d074a39653fcd78bdf87c25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 21 Mar 2011 14:19:09 +0200 Subject: [PATCH 16/33] rtsp: Specify unicast for TCP interleaved streams, too According to the RFC, the default is multicast if nothing is specified, which doesn't make sense for TCP. According to a bug report, some Axis camera models give a "400 Bad Request" error if this is omitted. Signed-off-by: Luca Barbato --- libavformat/rtsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 6d538cd1dc..5b98a2846c 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -1157,7 +1157,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, continue; snprintf(transport, sizeof(transport) - 1, "%s/TCP;", trans_pref); - if (rt->server_type == RTSP_SERVER_WMS) + if (rt->transport != RTSP_TRANSPORT_RDT) av_strlcat(transport, "unicast;", sizeof(transport)); av_strlcatf(transport, sizeof(transport), "interleaved=%d-%d", From 2890cba8b50cc8c6656bc5f5cd0ebb5fd80fb5e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 9 Feb 2011 12:13:32 +0200 Subject: [PATCH 17/33] amr: Set the codec->bit_rate field based on the last packet This allows libavformat to guess an estimated duration for amr files. For streams with varying bit rates (or with silence descriptors or "no frame" blocks) the guess is, of course, inaccurate. --- libavformat/amr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavformat/amr.c b/libavformat/amr.c index ba2ed4f30c..f2fecf3ee1 100644 --- a/libavformat/amr.c +++ b/libavformat/amr.c @@ -153,6 +153,9 @@ static int amr_read_packet(AVFormatContext *s, 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= avio_tell(s->pb); pkt->data[0]=toc; From 026fa81de4cf4f1af742245fa9e750a38040f9fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 9 Feb 2011 12:16:51 +0200 Subject: [PATCH 18/33] amr: Set the pkt->pos field properly to the start of the packet Previously, the field pointed to the second byte of the packet (which is the first byte of the actual AMR payload). --- libavformat/amr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavformat/amr.c b/libavformat/amr.c index f2fecf3ee1..76136e626b 100644 --- a/libavformat/amr.c +++ b/libavformat/amr.c @@ -121,6 +121,7 @@ static int amr_read_packet(AVFormatContext *s, { AVCodecContext *enc = s->streams[0]->codec; int read, size = 0, toc, mode; + int64_t pos = avio_tell(s->pb); if (s->pb->eof_reached) { @@ -157,7 +158,7 @@ static int amr_read_packet(AVFormatContext *s, s->streams[0]->codec->bit_rate = size*8*50; pkt->stream_index = 0; - pkt->pos= avio_tell(s->pb); + 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); From af79dd36f302d209eff18ee21410d987faad01a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 9 Feb 2011 12:19:39 +0200 Subject: [PATCH 19/33] amr: Set the AVFMT_GENERIC_INDEX flag This makes the amr demuxer support seeking, closing roundup issue 2593. --- libavformat/amr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/amr.c b/libavformat/amr.c index 76136e626b..260bd6ada6 100644 --- a/libavformat/amr.c +++ b/libavformat/amr.c @@ -181,6 +181,7 @@ AVInputFormat ff_amr_demuxer = { amr_read_header, amr_read_packet, NULL, + .flags = AVFMT_GENERIC_INDEX, }; #endif From 77e41e047dc487e318a0a47e02cfa99d25459b8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 21 Mar 2011 22:41:38 +0200 Subject: [PATCH 20/33] configure: Add the -D parameter to the dlltool command This is required for the generated .lib file to actually be usable by MSVC. Signed-off-by: Luca Barbato --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index a2ad321e34..e38f20b60e 100755 --- a/configure +++ b/configure @@ -2415,7 +2415,7 @@ case $target_os in SLIBSUF=".dll" SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME)-$(LIBVERSION)$(SLIBSUF)' SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)' - SLIB_EXTRA_CMD=-'$(DLLTOOL) -m $(LIBTARGET) -d $$(@:$(SLIBSUF)=.def) -l $(SUBDIR)$(SLIBNAME_WITH_MAJOR:$(SLIBSUF)=.lib)' + SLIB_EXTRA_CMD=-'$(DLLTOOL) -m $(LIBTARGET) -d $$(@:$(SLIBSUF)=.def) -l $(SUBDIR)$(SLIBNAME_WITH_MAJOR:$(SLIBSUF)=.lib) -D $(SLIBNAME_WITH_MAJOR)' SLIB_INSTALL_EXTRA_CMD='-install -m 644 $(SUBDIR)$(SLIBNAME_WITH_MAJOR:$(SLIBSUF)=.lib) "$(SHLIBDIR)/$(SLIBNAME:$(SLIBSUF)=.lib)"; \ install -m 644 $(SUBDIR)$(SLIBNAME_WITH_MAJOR:$(SLIBSUF)=.lib) "$(SHLIBDIR)/$(SLIBNAME_WITH_MAJOR:$(SLIBSUF)=.lib)"; \ install -d "$(LIBDIR)"; \ From c47d3835021effc04bc1fd2cef6be31e1b186491 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 21 Mar 2011 21:26:26 -0400 Subject: [PATCH 21/33] vc1: make P-frame deblock filter bit-exact. --- libavcodec/vc1.h | 4 +- libavcodec/vc1dec.c | 296 ++++++++++++++++++++++++++++++-------------- tests/ref/fate/vc1 | 22 ++-- 3 files changed, 217 insertions(+), 105 deletions(-) diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h index 7ec796d0e0..00dcfbf1d2 100644 --- a/libavcodec/vc1.h +++ b/libavcodec/vc1.h @@ -236,7 +236,7 @@ typedef struct VC1Context{ //@} int ttfrm; ///< Transform type info present at frame level uint8_t ttmbf; ///< Transform type flag - uint8_t ttblk4x4; ///< Value of ttblk which indicates a 4x4 transform + int *ttblk_base, *ttblk; ///< Transform type at the block level int codingset; ///< index of current table set from 11.8 to use for luma block decoding int codingset2; ///< index of current table set from 11.8 to use for chroma block decoding int pqindex; ///< raw pqindex used in coding set selection @@ -311,6 +311,8 @@ typedef struct VC1Context{ int x8_type; uint32_t *cbp_base, *cbp; + uint8_t *is_intra_base, *is_intra; + int16_t (*luma_mv_base)[2], (*luma_mv)[2]; uint8_t bfraction_lut_index;///< Index for BFRACTION value (see Table 40, reproduced into ff_vc1_bfraction_lut[]) uint8_t broken_link; ///< Broken link flag (BROKEN_LINK syntax element) uint8_t closed_entry; ///< Closed entry point flag (CLOSED_ENTRY syntax element) diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index cef26e159c..55f12a6aa6 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -209,6 +209,8 @@ static void vc1_mc_1mv(VC1Context *v, int dir) } uvmx = (mx + ((mx & 3) == 3)) >> 1; uvmy = (my + ((my & 3) == 3)) >> 1; + v->luma_mv[s->mb_x][0] = uvmx; + v->luma_mv[s->mb_x][1] = uvmy; if(v->fastuvmc) { uvmx = uvmx + ((uvmx<0)?(uvmx&1):-(uvmx&1)); uvmy = uvmy + ((uvmy<0)?(uvmy&1):-(uvmy&1)); @@ -477,6 +479,7 @@ static void vc1_mc_4mv_chroma(VC1Context *v) } else { s->current_picture.motion_val[1][s->block_index[0]][0] = 0; s->current_picture.motion_val[1][s->block_index[0]][1] = 0; + v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0; return; //no need to do MC for inter blocks } @@ -484,6 +487,8 @@ static void vc1_mc_4mv_chroma(VC1Context *v) s->current_picture.motion_val[1][s->block_index[0]][1] = ty; uvmx = (tx + ((tx&3) == 3)) >> 1; uvmy = (ty + ((ty&3) == 3)) >> 1; + v->luma_mv[s->mb_x][0] = uvmx; + v->luma_mv[s->mb_x][1] = uvmy; if(v->fastuvmc) { uvmx = uvmx + ((uvmx<0)?(uvmx&1):-(uvmx&1)); uvmy = uvmy + ((uvmy<0)?(uvmy&1):-(uvmy&1)); @@ -652,8 +657,9 @@ static void vc1_mc_4mv_chroma(VC1Context *v) /** Predict and set motion vector */ -static inline void vc1_pred_mv(MpegEncContext *s, int n, int dmv_x, int dmv_y, int mv1, int r_x, int r_y, uint8_t* is_intra) +static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, int mv1, int r_x, int r_y, uint8_t* is_intra) { + MpegEncContext *s = &v->s; int xy, wrap, off = 0; int16_t *A, *B, *C; int px, py; @@ -678,6 +684,7 @@ static inline void vc1_pred_mv(MpegEncContext *s, int n, int dmv_x, int dmv_y, i s->current_picture.motion_val[0][xy + wrap][1] = 0; s->current_picture.motion_val[0][xy + wrap + 1][0] = 0; s->current_picture.motion_val[0][xy + wrap + 1][1] = 0; + v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0; s->current_picture.motion_val[1][xy + 1][0] = 0; s->current_picture.motion_val[1][xy + 1][1] = 0; s->current_picture.motion_val[1][xy + wrap][0] = 0; @@ -1953,7 +1960,7 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, int c /** Decode P block */ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquant, int ttmb, int first_block, - uint8_t *dst, int linesize, int skip_block, int apply_filter, int cbp_top, int cbp_left) + uint8_t *dst, int linesize, int skip_block, int *ttmb_out) { MpegEncContext *s = &v->s; GetBitContext *gb = &s->gb; @@ -2011,10 +2018,6 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan else{ v->vc1dsp.vc1_inv_trans_8x8_add(dst, linesize, block); } - if(apply_filter && cbp_top & 0xC) - v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq); - if(apply_filter && cbp_left & 0xA) - v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq); } break; case TT_4X4: @@ -2038,10 +2041,6 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan v->vc1dsp.vc1_inv_trans_4x4_dc(dst + (j&1)*4 + (j&2)*2*linesize, linesize, block + off); else v->vc1dsp.vc1_inv_trans_4x4(dst + (j&1)*4 + (j&2)*2*linesize, linesize, block + off); - if(apply_filter && (j&2 ? pat & (1<<(j-2)) : (cbp_top & (1 << (j + 2))))) - v->vc1dsp.vc1_v_loop_filter4(dst + (j&1)*4 + (j&2)*2*linesize, linesize, v->pq); - if(apply_filter && (j&1 ? pat & (1<<(j-1)) : (cbp_left & (1 << (j + 1))))) - v->vc1dsp.vc1_h_loop_filter4(dst + (j&1)*4 + (j&2)*2*linesize, linesize, v->pq); } } break; @@ -2066,10 +2065,6 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan v->vc1dsp.vc1_inv_trans_8x4_dc(dst + j*4*linesize, linesize, block + off); else v->vc1dsp.vc1_inv_trans_8x4(dst + j*4*linesize, linesize, block + off); - if(apply_filter && j ? pat & 0x3 : (cbp_top & 0xC)) - v->vc1dsp.vc1_v_loop_filter8(dst + j*4*linesize, linesize, v->pq); - if(apply_filter && cbp_left & (2 << j)) - v->vc1dsp.vc1_h_loop_filter4(dst + j*4*linesize, linesize, v->pq); } } break; @@ -2094,14 +2089,12 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan v->vc1dsp.vc1_inv_trans_4x8_dc(dst + j*4, linesize, block + off); else v->vc1dsp.vc1_inv_trans_4x8(dst + j*4, linesize, block + off); - if(apply_filter && cbp_top & (2 << j)) - v->vc1dsp.vc1_v_loop_filter4(dst + j*4, linesize, v->pq); - if(apply_filter && j ? pat & 0x5 : (cbp_left & 0xA)) - v->vc1dsp.vc1_h_loop_filter8(dst + j*4, linesize, v->pq); } } break; } + if (ttmb_out) + *ttmb_out |= ttblk << (n * 4); return pat; } @@ -2110,6 +2103,155 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan static const int size_table [6] = { 0, 2, 3, 4, 5, 8 }; static const int offset_table[6] = { 0, 1, 3, 7, 15, 31 }; +static av_always_inline void vc1_apply_p_v_loop_filter(VC1Context *v, int block_num) +{ + MpegEncContext *s = &v->s; + int mb_cbp = v->cbp[s->mb_x - s->mb_stride], + block_cbp = mb_cbp >> (block_num * 4), bottom_cbp, + mb_is_intra = v->is_intra[s->mb_x - s->mb_stride], + block_is_intra = mb_is_intra >> (block_num * 4), bottom_is_intra; + int idx, linesize = block_num > 3 ? s->uvlinesize : s->linesize, ttblk; + uint8_t *dst; + + if(block_num > 3) { + dst = s->dest[block_num - 3]; + } else { + dst = s->dest[0] + (block_num & 1) * 8 + ((block_num & 2) * 4 - 8) * linesize; + } + if (s->mb_y != s->mb_height || block_num < 2) { + int16_t (*mv)[2]; + int mv_stride; + + if(block_num > 3) { + bottom_cbp = v->cbp[s->mb_x] >> (block_num * 4); + bottom_is_intra = v->is_intra[s->mb_x] >> (block_num * 4); + mv = &v->luma_mv[s->mb_x - s->mb_stride]; + mv_stride = s->mb_stride; + } else { + bottom_cbp = (block_num < 2) ? (mb_cbp >> ((block_num + 2) * 4)) : + (v->cbp[s->mb_x] >> ((block_num - 2) * 4)); + bottom_is_intra = (block_num < 2) ? (mb_is_intra >> ((block_num + 2) * 4)) : + (v->is_intra[s->mb_x] >> ((block_num - 2) * 4)); + mv_stride = s->b8_stride; + mv = &s->current_picture.motion_val[0][s->block_index[block_num] - 2 * mv_stride]; + } + + if (bottom_is_intra & 1 || block_is_intra & 1 || + mv[0][0] != mv[mv_stride][0] || mv[0][1] != mv[mv_stride][1]) { + v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq); + } else { + idx = ((bottom_cbp >> 2) | block_cbp) & 3; + if(idx == 3) { + v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq); + } else if (idx) { + if (idx == 1) + v->vc1dsp.vc1_v_loop_filter4(dst + 4, linesize, v->pq); + else + v->vc1dsp.vc1_v_loop_filter4(dst, linesize, v->pq); + } + } + } + + dst -= 4 * linesize; + ttblk = (v->ttblk[s->mb_x - s->mb_stride] >> (block_num * 4)) & 0xf; + if (ttblk == TT_4X4 || ttblk == TT_8X4) { + idx = (block_cbp | (block_cbp >> 2)) & 3; + if (idx == 3) { + v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq); + } else if (idx) { + if (idx == 1) + v->vc1dsp.vc1_v_loop_filter4(dst + 4, linesize, v->pq); + else + v->vc1dsp.vc1_v_loop_filter4(dst, linesize, v->pq); + } + } +} + +static av_always_inline void vc1_apply_p_h_loop_filter(VC1Context *v, int block_num) +{ + MpegEncContext *s = &v->s; + int mb_cbp = v->cbp[s->mb_x - 1 - s->mb_stride], + block_cbp = mb_cbp >> (block_num * 4), right_cbp, + mb_is_intra = v->is_intra[s->mb_x - 1 - s->mb_stride], + block_is_intra = mb_is_intra >> (block_num * 4), right_is_intra; + int idx, linesize = block_num > 3 ? s->uvlinesize : s->linesize, ttblk; + uint8_t *dst; + + if (block_num > 3) { + dst = s->dest[block_num - 3] - 8 * linesize; + } else { + dst = s->dest[0] + (block_num & 1) * 8 + ((block_num & 2) * 4 - 16) * linesize - 8; + } + + if (s->mb_x != s->mb_width || !(block_num & 5)) { + int16_t (*mv)[2]; + + if(block_num > 3) { + right_cbp = v->cbp[s->mb_x - s->mb_stride] >> (block_num * 4); + right_is_intra = v->is_intra[s->mb_x - s->mb_stride] >> (block_num * 4); + mv = &v->luma_mv[s->mb_x - s->mb_stride - 1]; + }else{ + right_cbp = (block_num & 1) ? (v->cbp[s->mb_x - s->mb_stride] >> ((block_num - 1) * 4)) : + (mb_cbp >> ((block_num + 1) * 4)); + right_is_intra = (block_num & 1) ? (v->is_intra[s->mb_x - s->mb_stride] >> ((block_num - 1) * 4)) : + (mb_is_intra >> ((block_num + 1) * 4)); + mv = &s->current_picture.motion_val[0][s->block_index[block_num] - s->b8_stride * 2 - 2]; + } + if (block_is_intra & 1 || right_is_intra & 1 || mv[0][0] != mv[1][0] || mv[0][1] != mv[1][1]) { + v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq); + } else { + idx = ((right_cbp >> 1) | block_cbp) & 5; // FIXME check + if (idx == 5) { + v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq); + } else if (idx) { + if (idx == 1) + v->vc1dsp.vc1_h_loop_filter4(dst+4*linesize, linesize, v->pq); + else + v->vc1dsp.vc1_h_loop_filter4(dst, linesize, v->pq); + } + } + } + + dst -= 4; + ttblk = (v->ttblk[s->mb_x - s->mb_stride - 1] >> (block_num * 4)) & 0xf; + if (ttblk == TT_4X4 || ttblk == TT_4X8) { + idx = (block_cbp | (block_cbp >> 1)) & 5; + if (idx == 5) { + v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq); + } else if (idx) { + if (idx == 1) + v->vc1dsp.vc1_h_loop_filter4(dst + linesize*4, linesize, v->pq); + else + v->vc1dsp.vc1_h_loop_filter4(dst, linesize, v->pq); + } + } +} + +static void vc1_apply_p_loop_filter(VC1Context *v) +{ + MpegEncContext *s = &v->s; + int i; + + for (i = 0; i < 6; i++) { + vc1_apply_p_v_loop_filter(v, i); + } + + /* V always preceedes H, therefore we run H one MB before V; + * at the end of a row, we catch up to complete the row */ + if (s->mb_x) { + for (i = 0; i < 6; i++) { + vc1_apply_p_h_loop_filter(v, i); + } + if (s->mb_x == s->mb_width - 1) { + s->mb_x++; + ff_update_block_index(s); + for (i = 0; i < 6; i++) { + vc1_apply_p_h_loop_filter(v, i); + } + } + } +} + /** Decode one P-frame MB (in Simple/Main profile) */ static int vc1_decode_p_mb(VC1Context *v) @@ -2129,8 +2271,7 @@ static int vc1_decode_p_mb(VC1Context *v) int first_block = 1; int dst_idx, off; int skipped, fourmv; - int block_cbp = 0, pat; - int apply_loop_filter; + int block_cbp = 0, pat, block_tt = 0, block_intra = 0; mquant = v->pq; /* Loosy initialization */ @@ -2143,7 +2284,6 @@ static int vc1_decode_p_mb(VC1Context *v) else skipped = v->s.mbskip_table[mb_pos]; - apply_loop_filter = s->loop_filter && !(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY); if (!fourmv) /* 1MV mode */ { if (!skipped) @@ -2157,7 +2297,7 @@ static int vc1_decode_p_mb(VC1Context *v) s->current_picture.motion_val[1][s->block_index[0]][1] = 0; } s->current_picture.mb_type[mb_pos] = s->mb_intra ? MB_TYPE_INTRA : MB_TYPE_16x16; - vc1_pred_mv(s, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0]); + vc1_pred_mv(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0]); /* FIXME Set DC val for inter block ? */ if (s->mb_intra && !mb_has_coeffs) @@ -2211,38 +2351,10 @@ static int vc1_decode_p_mb(VC1Context *v) if(v->a_avail) v->vc1dsp.vc1_v_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize); } - if(apply_loop_filter && s->mb_x && s->mb_x != (s->mb_width - 1) && s->mb_y && s->mb_y != (s->mb_height - 1)){ - int left_cbp, top_cbp; - if(i & 4){ - left_cbp = v->cbp[s->mb_x - 1] >> (i * 4); - top_cbp = v->cbp[s->mb_x - s->mb_stride] >> (i * 4); - }else{ - left_cbp = (i & 1) ? (cbp >> ((i-1)*4)) : (v->cbp[s->mb_x - 1] >> ((i+1)*4)); - top_cbp = (i & 2) ? (cbp >> ((i-2)*4)) : (v->cbp[s->mb_x - s->mb_stride] >> ((i+2)*4)); - } - if(left_cbp & 0xC) - v->vc1dsp.vc1_v_loop_filter8(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, v->pq); - if(top_cbp & 0xA) - v->vc1dsp.vc1_h_loop_filter8(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, v->pq); - } block_cbp |= 0xF << (i << 2); + block_intra |= 1 << i; } else if(val) { - int left_cbp = 0, top_cbp = 0, filter = 0; - if(apply_loop_filter && s->mb_x && s->mb_x != (s->mb_width - 1) && s->mb_y && s->mb_y != (s->mb_height - 1)){ - filter = 1; - if(i & 4){ - left_cbp = v->cbp[s->mb_x - 1] >> (i * 4); - top_cbp = v->cbp[s->mb_x - s->mb_stride] >> (i * 4); - }else{ - left_cbp = (i & 1) ? (cbp >> ((i-1)*4)) : (v->cbp[s->mb_x - 1] >> ((i+1)*4)); - top_cbp = (i & 2) ? (cbp >> ((i-2)*4)) : (v->cbp[s->mb_x - s->mb_stride] >> ((i+2)*4)); - } - if(left_cbp & 0xC) - v->vc1dsp.vc1_v_loop_filter8(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, v->pq); - if(top_cbp & 0xA) - v->vc1dsp.vc1_h_loop_filter8(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, v->pq); - } - pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY), filter, left_cbp, top_cbp); + pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY), &block_tt); block_cbp |= pat << (i << 2); if(!v->ttmbf && ttmb < 8) ttmb = -1; first_block = 0; @@ -2258,9 +2370,8 @@ static int vc1_decode_p_mb(VC1Context *v) } s->current_picture.mb_type[mb_pos] = MB_TYPE_SKIP; s->current_picture.qscale_table[mb_pos] = 0; - vc1_pred_mv(s, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0]); + vc1_pred_mv(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0]); vc1_mc_1mv(v, 0); - return 0; } } //1MV mode else //4MV mode @@ -2284,7 +2395,7 @@ static int vc1_decode_p_mb(VC1Context *v) if(val) { GET_MVDATA(dmv_x, dmv_y); } - vc1_pred_mv(s, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0]); + vc1_pred_mv(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0]); if(!s->mb_intra) vc1_mc_4mv_luma(v, i); intra_count += s->mb_intra; is_intra[i] = s->mb_intra; @@ -2299,8 +2410,9 @@ static int vc1_decode_p_mb(VC1Context *v) if(!coded_inter) coded_inter = !is_intra[i] & is_coded[i]; } // if there are no coded blocks then don't do anything more - if(!intra_count && !coded_inter) return 0; dst_idx = 0; + if(!intra_count && !coded_inter) + goto end; GET_MQUANT(); s->current_picture.qscale_table[mb_pos] = mquant; /* test if block is intra and has pred */ @@ -2344,44 +2456,15 @@ static int vc1_decode_p_mb(VC1Context *v) if(v->a_avail) v->vc1dsp.vc1_v_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize); } - if(v->s.loop_filter && s->mb_x && s->mb_x != (s->mb_width - 1) && s->mb_y && s->mb_y != (s->mb_height - 1)){ - int left_cbp, top_cbp; - if(i & 4){ - left_cbp = v->cbp[s->mb_x - 1] >> (i * 4); - top_cbp = v->cbp[s->mb_x - s->mb_stride] >> (i * 4); - }else{ - left_cbp = (i & 1) ? (cbp >> ((i-1)*4)) : (v->cbp[s->mb_x - 1] >> ((i+1)*4)); - top_cbp = (i & 2) ? (cbp >> ((i-2)*4)) : (v->cbp[s->mb_x - s->mb_stride] >> ((i+2)*4)); - } - if(left_cbp & 0xC) - v->vc1dsp.vc1_v_loop_filter8(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, v->pq); - if(top_cbp & 0xA) - v->vc1dsp.vc1_h_loop_filter8(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, v->pq); - } block_cbp |= 0xF << (i << 2); + block_intra |= 1 << i; } else if(is_coded[i]) { - int left_cbp = 0, top_cbp = 0, filter = 0; - if(v->s.loop_filter && s->mb_x && s->mb_x != (s->mb_width - 1) && s->mb_y && s->mb_y != (s->mb_height - 1)){ - filter = 1; - if(i & 4){ - left_cbp = v->cbp[s->mb_x - 1] >> (i * 4); - top_cbp = v->cbp[s->mb_x - s->mb_stride] >> (i * 4); - }else{ - left_cbp = (i & 1) ? (cbp >> ((i-1)*4)) : (v->cbp[s->mb_x - 1] >> ((i+1)*4)); - top_cbp = (i & 2) ? (cbp >> ((i-2)*4)) : (v->cbp[s->mb_x - s->mb_stride] >> ((i+2)*4)); - } - if(left_cbp & 0xC) - v->vc1dsp.vc1_v_loop_filter8(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, v->pq); - if(top_cbp & 0xA) - v->vc1dsp.vc1_h_loop_filter8(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, v->pq); - } - pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY), filter, left_cbp, top_cbp); + pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY), &block_tt); block_cbp |= pat << (i << 2); if(!v->ttmbf && ttmb < 8) ttmb = -1; first_block = 0; } } - return 0; } else //Skipped MB { @@ -2393,18 +2476,19 @@ static int vc1_decode_p_mb(VC1Context *v) } for (i=0; i<4; i++) { - vc1_pred_mv(s, i, 0, 0, 0, v->range_x, v->range_y, v->mb_type[0]); + vc1_pred_mv(v, i, 0, 0, 0, v->range_x, v->range_y, v->mb_type[0]); vc1_mc_4mv_luma(v, i); } vc1_mc_4mv_chroma(v); s->current_picture.qscale_table[mb_pos] = 0; - return 0; } } +end: v->cbp[s->mb_x] = block_cbp; + v->ttblk[s->mb_x] = block_tt; + v->is_intra[s->mb_x] = block_intra; - /* Should never happen */ - return -1; + return 0; } /** Decode one B-frame MB (in Main profile) @@ -2546,7 +2630,7 @@ static void vc1_decode_b_mb(VC1Context *v) i & 4 ? s->uvlinesize : s->linesize, s->block[i]); } else if(val) { - vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY), 0, 0, 0); + vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY), NULL); if(!v->ttmbf && ttmb < 8) ttmb = -1; first_block = 0; } @@ -2841,6 +2925,7 @@ static void vc1_decode_i_blocks_adv(VC1Context *v, int mby_start, int mby_end) static void vc1_decode_p_blocks(VC1Context *v, int mby_start, int mby_end) { MpegEncContext *s = &v->s; + int apply_loop_filter; /* select codingmode used for VLC tables selection */ switch(v->c_ac_table_index){ @@ -2867,6 +2952,7 @@ static void vc1_decode_p_blocks(VC1Context *v, int mby_start, int mby_end) break; } + apply_loop_filter = s->loop_filter && !(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY); s->first_slice_line = 1; memset(v->cbp_base, 0, sizeof(v->cbp_base[0])*2*s->mb_stride); for(s->mb_y = mby_start; s->mb_y < mby_end; s->mb_y++) { @@ -2876,6 +2962,8 @@ static void vc1_decode_p_blocks(VC1Context *v, int mby_start, int mby_end) ff_update_block_index(s); vc1_decode_p_mb(v); + if (s->mb_y != mby_start && apply_loop_filter) + vc1_apply_p_loop_filter(v); if(get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) { ff_er_add_slice(s, 0, mby_start, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)); av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n", get_bits_count(&s->gb), v->bits,s->mb_x,s->mb_y); @@ -2883,9 +2971,22 @@ static void vc1_decode_p_blocks(VC1Context *v, int mby_start, int mby_end) } } memmove(v->cbp_base, v->cbp, sizeof(v->cbp_base[0])*s->mb_stride); - ff_draw_horiz_band(s, s->mb_y * 16, 16); + memmove(v->ttblk_base, v->ttblk, sizeof(v->ttblk_base[0])*s->mb_stride); + memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0])*s->mb_stride); + memmove(v->luma_mv_base, v->luma_mv, sizeof(v->luma_mv_base[0])*s->mb_stride); + if (s->mb_y != mby_start) ff_draw_horiz_band(s, (s->mb_y-1) * 16, 16); s->first_slice_line = 0; } + if (apply_loop_filter) { + s->mb_x = 0; + ff_init_block_index(s); + for (; s->mb_x < s->mb_width; s->mb_x++) { + ff_update_block_index(s); + vc1_apply_p_loop_filter(v); + } + } + if (mby_end >= mby_start) + ff_draw_horiz_band(s, (mby_end-1) * 16, 16); ff_er_add_slice(s, 0, mby_start, s->mb_width - 1, mby_end - 1, (AC_END|DC_END|MV_END)); } @@ -3122,6 +3223,12 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) v->cbp_base = av_malloc(sizeof(v->cbp_base[0]) * 2 * s->mb_stride); v->cbp = v->cbp_base + s->mb_stride; + v->ttblk_base = av_malloc(sizeof(v->ttblk_base[0]) * 2 * s->mb_stride); + v->ttblk = v->ttblk_base + s->mb_stride; + v->is_intra_base = av_malloc(sizeof(v->is_intra_base[0]) * 2 * s->mb_stride); + v->is_intra = v->is_intra_base + s->mb_stride; + v->luma_mv_base = av_malloc(sizeof(v->luma_mv_base[0]) * 2 * s->mb_stride); + v->luma_mv = v->luma_mv_base + s->mb_stride; /* allocate block type info in that way so it could be used with s->block_index[] */ v->mb_type_base = av_malloc(s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2); @@ -3375,6 +3482,9 @@ static av_cold int vc1_decode_end(AVCodecContext *avctx) av_freep(&v->over_flags_plane); av_freep(&v->mb_type_base); av_freep(&v->cbp_base); + av_freep(&v->ttblk_base); + av_freep(&v->is_intra_base); // FIXME use v->mb_type[] + av_freep(&v->luma_mv_base); ff_intrax8_common_end(&v->x8); return 0; } diff --git a/tests/ref/fate/vc1 b/tests/ref/fate/vc1 index 123237c91f..69e9b4ad64 100644 --- a/tests/ref/fate/vc1 +++ b/tests/ref/fate/vc1 @@ -2,14 +2,14 @@ 0, 3600, 38016, 0xf4715db5 0, 7200, 38016, 0xf4715db5 0, 10800, 38016, 0xf46af0e1 -0, 14400, 38016, 0x96992cf1 -0, 18000, 38016, 0xbaadd874 -0, 21600, 38016, 0x751f4328 -0, 25200, 38016, 0x751f4328 -0, 28800, 38016, 0xf7294772 -0, 32400, 38016, 0xf7294772 -0, 36000, 38016, 0xf1d12133 -0, 39600, 38016, 0xf1d12133 -0, 43200, 38016, 0xf1d12133 -0, 46800, 38016, 0xf1d12133 -0, 50400, 38016, 0xf1d12133 +0, 14400, 38016, 0x9c1c2cf1 +0, 18000, 38016, 0xff12d87f +0, 21600, 38016, 0x7408432b +0, 25200, 38016, 0x7408432b +0, 28800, 38016, 0x8d11479a +0, 32400, 38016, 0x8d11479a +0, 36000, 38016, 0xc4a121ab +0, 39600, 38016, 0xc4a121ab +0, 43200, 38016, 0xc4a121ab +0, 46800, 38016, 0xc4a121ab +0, 50400, 38016, 0xc4a121ab From 2a569799a90986cf137792cc03a56752447652c7 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Tue, 22 Mar 2011 02:49:37 +0000 Subject: [PATCH 22/33] fate: update wmv8-drm reference This updates the wmv8-drm reference after c47d383. Signed-off-by: Mans Rullgard --- tests/ref/fate/wmv8-drm | 250 ++++++++++++++++++++-------------------- 1 file changed, 125 insertions(+), 125 deletions(-) diff --git a/tests/ref/fate/wmv8-drm b/tests/ref/fate/wmv8-drm index 4dc0f0e4f9..015053587e 100644 --- a/tests/ref/fate/wmv8-drm +++ b/tests/ref/fate/wmv8-drm @@ -34,129 +34,129 @@ 0, 123750, 84480, 0xabf7c25d 0, 127500, 84480, 0x912600ee 0, 131250, 84480, 0x7ee7c70b -0, 135000, 84480, 0xe212b0d1 -0, 138750, 84480, 0xd4fa6c16 -0, 142500, 84480, 0xd10fa126 -0, 146250, 84480, 0xda91d3aa -0, 150000, 84480, 0xd90be940 -0, 153750, 84480, 0x908a009b -0, 157500, 84480, 0xdd26d6e9 -0, 161250, 84480, 0xfeda8de9 -0, 165000, 84480, 0x96d66505 -0, 168750, 84480, 0xf43b4b1b -0, 172500, 84480, 0xd44122c2 -0, 176250, 84480, 0xc65da7a9 -0, 180000, 84480, 0xbf4178f2 -0, 183750, 84480, 0x96be846a -0, 187500, 84480, 0x73e6459e -0, 191250, 84480, 0x70086917 -0, 195000, 84480, 0x9b12571d -0, 198750, 84480, 0xe4ce7bce -0, 202500, 84480, 0x845672e5 -0, 206250, 84480, 0x1c17e189 -0, 210000, 84480, 0x12a877d0 -0, 213750, 84480, 0xca62e8ed -0, 217500, 84480, 0x87beb28f -0, 221250, 84480, 0x1ba915a4 -0, 225000, 84480, 0x159fc9c4 -0, 228750, 84480, 0xcec3e3ef -0, 232500, 84480, 0x96a42f48 -0, 236250, 84480, 0xcd17decf -0, 240000, 84480, 0x4cf95d6c -0, 243750, 84480, 0xa258400e -0, 247500, 84480, 0xb9c566d8 -0, 251250, 84480, 0xc39f6dab -0, 255000, 84480, 0xd08a0880 -0, 258750, 84480, 0x41e3a70f -0, 262500, 84480, 0x0ded83d9 -0, 266250, 84480, 0x74a915ea -0, 270000, 84480, 0x00c2c849 -0, 273750, 84480, 0x709a9b07 -0, 277500, 84480, 0xfb276daa -0, 281250, 84480, 0x89ca744b -0, 285000, 84480, 0x457ba569 -0, 288750, 84480, 0xc37c8d57 -0, 292500, 84480, 0x1890a97e -0, 296250, 84480, 0xe455b8d0 -0, 300000, 84480, 0x1f6bdbce -0, 303750, 84480, 0x9df90ed1 -0, 307500, 84480, 0xff80328c -0, 311250, 84480, 0x0e115940 -0, 315000, 84480, 0x09ddc11d -0, 318750, 84480, 0xeef241e9 -0, 322500, 84480, 0xbe3578b4 -0, 326250, 84480, 0x2a83f0f3 -0, 330000, 84480, 0xb41d01c2 -0, 333750, 84480, 0x630efd97 -0, 337500, 84480, 0xd592140d -0, 341250, 84480, 0x7110f627 -0, 345000, 84480, 0x2dbaa590 -0, 348750, 84480, 0x13d80be5 -0, 352500, 84480, 0xb8f3740d -0, 356250, 84480, 0xd9a6fcef -0, 360000, 84480, 0x56bfa4e3 -0, 363750, 84480, 0x49364550 -0, 367500, 84480, 0x0a2f1690 -0, 371250, 84480, 0xb87fccbf -0, 375000, 84480, 0xb2aa69f7 -0, 378750, 84480, 0x176bf378 -0, 382500, 84480, 0xe7a6de45 -0, 386250, 84480, 0x8e3900a6 -0, 390000, 84480, 0x24a72099 -0, 393750, 84480, 0x5394df95 -0, 397500, 84480, 0xd648c92e -0, 401250, 84480, 0xab95fb62 -0, 405000, 84480, 0xe3239cb0 -0, 408750, 84480, 0xb4f93467 -0, 412500, 84480, 0x94d0d01d -0, 416250, 84480, 0x6316a25e -0, 420000, 84480, 0x6316a25e -0, 423750, 84480, 0x6316a25e -0, 427500, 84480, 0x6316a25e -0, 431250, 84480, 0x6316a25e -0, 435000, 84480, 0x6316a25e -0, 438750, 84480, 0x6316a25e +0, 135000, 84480, 0x09c5b0d1 +0, 138750, 84480, 0x6dbe6c0c +0, 142500, 84480, 0x0fe0a120 +0, 146250, 84480, 0x2352d3a2 +0, 150000, 84480, 0xb22ce92e +0, 153750, 84480, 0x31db0099 +0, 157500, 84480, 0xad2dd73a +0, 161250, 84480, 0xb9af8e20 +0, 165000, 84480, 0x7b956549 +0, 168750, 84480, 0x3f774b87 +0, 172500, 84480, 0x824a23a3 +0, 176250, 84480, 0x4469a8d8 +0, 180000, 84480, 0xc80c7a0a +0, 183750, 84480, 0xcf958549 +0, 187500, 84480, 0x449746e3 +0, 191250, 84480, 0xbac66a82 +0, 195000, 84480, 0x99e85855 +0, 198750, 84480, 0xa4a17d17 +0, 202500, 84480, 0xe29c7587 +0, 206250, 84480, 0x551de592 +0, 210000, 84480, 0xe0877bce +0, 213750, 84480, 0x9660eb35 +0, 217500, 84480, 0x0a34b644 +0, 221250, 84480, 0x352919f0 +0, 225000, 84480, 0xef56ce27 +0, 228750, 84480, 0x030fe862 +0, 232500, 84480, 0x2eba33e2 +0, 236250, 84480, 0x242de401 +0, 240000, 84480, 0xbadd61ca +0, 243750, 84480, 0x2060465b +0, 247500, 84480, 0x256e6965 +0, 251250, 84480, 0x243b7084 +0, 255000, 84480, 0x8b3c0b47 +0, 258750, 84480, 0xc174a9af +0, 262500, 84480, 0xb6d48686 +0, 266250, 84480, 0xa3dd1871 +0, 270000, 84480, 0x04cdcaf7 +0, 273750, 84480, 0x55f89c94 +0, 277500, 84480, 0xda657032 +0, 281250, 84480, 0x38ba7698 +0, 285000, 84480, 0x4d03a7f2 +0, 288750, 84480, 0x115d9035 +0, 292500, 84480, 0x24c6acc6 +0, 296250, 84480, 0xdd2bbcae +0, 300000, 84480, 0xb4fee0b9 +0, 303750, 84480, 0xc51c14e0 +0, 307500, 84480, 0xfb7737de +0, 311250, 84480, 0x38675fb0 +0, 315000, 84480, 0x4752c710 +0, 318750, 84480, 0xfeb7491b +0, 322500, 84480, 0xaa248122 +0, 326250, 84480, 0x9a4af87c +0, 330000, 84480, 0xedcf09df +0, 333750, 84480, 0x563a05df +0, 337500, 84480, 0x0dde1e03 +0, 341250, 84480, 0xd8f0ff65 +0, 345000, 84480, 0xbeb9ae1a +0, 348750, 84480, 0x416d1468 +0, 352500, 84480, 0x66c87d4c +0, 356250, 84480, 0xa67c0774 +0, 360000, 84480, 0xd8f8aec1 +0, 363750, 84480, 0xadfa502b +0, 367500, 84480, 0x50bf20e4 +0, 371250, 84480, 0xbcb3d8cc +0, 375000, 84480, 0xa54677d7 +0, 378750, 84480, 0x3566042d +0, 382500, 84480, 0x4c9eed57 +0, 386250, 84480, 0xc3b90e58 +0, 390000, 84480, 0x3c042bfa +0, 393750, 84480, 0x19f8e890 +0, 397500, 84480, 0xd3dacfb9 +0, 401250, 84480, 0x2365fc6f +0, 405000, 84480, 0xa2c19d00 +0, 408750, 84480, 0xce94336f +0, 412500, 84480, 0xfa9bcf14 +0, 416250, 84480, 0x24d6a243 +0, 420000, 84480, 0x24d6a243 +0, 423750, 84480, 0x24d6a243 +0, 427500, 84480, 0x24d6a243 +0, 431250, 84480, 0x24d6a243 +0, 435000, 84480, 0x24d6a243 +0, 438750, 84480, 0x24d6a243 0, 442500, 84480, 0xae1c8854 -0, 446250, 84480, 0x30fe68bf -0, 450000, 84480, 0xfd1435c8 -0, 453750, 84480, 0xddf57fab -0, 457500, 84480, 0xc3553a51 -0, 461250, 84480, 0xd9ce7ae8 -0, 465000, 84480, 0x671765cb -0, 468750, 84480, 0x78336eab -0, 472500, 84480, 0xb66b659c -0, 476250, 84480, 0x0e1f68bb -0, 480000, 84480, 0x8f4669dc -0, 483750, 84480, 0x60c47360 -0, 487500, 84480, 0x93037246 -0, 491250, 84480, 0xdebe620d -0, 495000, 84480, 0x7555161e -0, 498750, 84480, 0xcbaf4311 -0, 502500, 84480, 0x8e3783a0 -0, 506250, 84480, 0x3888008f -0, 510000, 84480, 0x8a4fa114 -0, 513750, 84480, 0xac0bf10b -0, 517500, 84480, 0xb485ff7f -0, 521250, 84480, 0xeaec2133 -0, 525000, 84480, 0x105827cd -0, 528750, 84480, 0x55ff4b2d -0, 532500, 84480, 0x78c64a49 -0, 536250, 84480, 0x3897731d -0, 540000, 84480, 0x9ca891aa -0, 543750, 84480, 0x24a6ab0a -0, 547500, 84480, 0x88fdc6fb -0, 551250, 84480, 0x05afea61 -0, 555000, 84480, 0xe703e2cf -0, 558750, 84480, 0x9eb0e64a -0, 562500, 84480, 0x92a7f0ab -0, 566250, 84480, 0xec2bfbfb -0, 570000, 84480, 0x7db600ad -0, 573750, 84480, 0x4abd6393 -0, 577500, 84480, 0x54ce06b5 -0, 581250, 84480, 0x7cb6f150 -0, 585000, 84480, 0x099d4aeb -0, 588750, 84480, 0x0bcfdc31 -0, 592500, 84480, 0xe4e72d1f -0, 596250, 84480, 0xbce22331 -0, 600000, 84480, 0x020545d7 -0, 603750, 84480, 0x71869e48 +0, 446250, 84480, 0xbb8968bf +0, 450000, 84480, 0x6f923623 +0, 453750, 84480, 0x22e98029 +0, 457500, 84480, 0x8ac33af3 +0, 461250, 84480, 0x05947b6e +0, 465000, 84480, 0xfc35661a +0, 468750, 84480, 0x0e6b6e47 +0, 472500, 84480, 0x82c764bb +0, 476250, 84480, 0x57a36833 +0, 480000, 84480, 0xc8dd690a +0, 483750, 84480, 0x02c47232 +0, 487500, 84480, 0x6645715d +0, 491250, 84480, 0xc64860f7 +0, 495000, 84480, 0x4f5614b3 +0, 498750, 84480, 0xa70842ca +0, 502500, 84480, 0x379d8458 +0, 506250, 84480, 0xa14701cf +0, 510000, 84480, 0xad1aa2b2 +0, 513750, 84480, 0xee28f320 +0, 517500, 84480, 0x505801e9 +0, 521250, 84480, 0x7947233b +0, 525000, 84480, 0x3ce72a9d +0, 528750, 84480, 0xa6834e64 +0, 532500, 84480, 0xfebf4d70 +0, 536250, 84480, 0x4a0775e2 +0, 540000, 84480, 0x9d7e945b +0, 543750, 84480, 0xaa9eadd9 +0, 547500, 84480, 0xaa85c9b1 +0, 551250, 84480, 0xa005edaf +0, 555000, 84480, 0x7fc4e5cc +0, 558750, 84480, 0xb0f6e8d1 +0, 562500, 84480, 0x9ef9f330 +0, 566250, 84480, 0xbe14ff1f +0, 570000, 84480, 0xd494048c +0, 573750, 84480, 0x046166a7 +0, 577500, 84480, 0x052a09b2 +0, 581250, 84480, 0x71fff4ab +0, 585000, 84480, 0xb9684e41 +0, 588750, 84480, 0x1ddce068 +0, 592500, 84480, 0xb9de300e +0, 596250, 84480, 0x13962590 +0, 600000, 84480, 0xde79482f +0, 603750, 84480, 0x7d1ca064 From b58b9fa3b5243f02e5212db9171b2f02de4524ea Mon Sep 17 00:00:00 2001 From: Dave Yeo Date: Tue, 22 Mar 2011 03:47:48 +0000 Subject: [PATCH 23/33] Make sure kbhit() is in conio.h Conio.h is a non-standard header and may not have kbhit() prototyped. This fixes compile on OS/2 where the EMX version (we're using a fork) of conio.h only has getch() and getche(). Signed-off-by: Mans Rullgard --- configure | 4 ++-- ffmpeg.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/configure b/configure index e38f20b60e..19b9f9842d 100755 --- a/configure +++ b/configure @@ -1037,7 +1037,6 @@ HAVE_LIST=" bswap closesocket cmov - conio_h dcbzl dev_bktr_ioctl_bt848_h dev_bktr_ioctl_meteor_h @@ -1067,6 +1066,7 @@ HAVE_LIST=" inet_aton inline_asm isatty + kbhit ldbrx libdc1394_1 libdc1394_2 @@ -2775,6 +2775,7 @@ check_func ${malloc_prefix}posix_memalign && enable posix_memalign check_func setrlimit check_func strerror_r check_func strtok_r +check_func_headers conio.h kbhit check_func_headers io.h setmode check_func_headers lzo/lzo1x.h lzo1x_999_compress check_lib2 "windows.h psapi.h" GetProcessMemoryInfo -lpsapi @@ -2782,7 +2783,6 @@ check_func_headers windows.h GetProcessTimes check_func_headers windows.h MapViewOfFile check_func_headers windows.h VirtualAlloc -check_header conio.h check_header dlfcn.h check_header dxva2api.h check_header malloc.h diff --git a/ffmpeg.c b/ffmpeg.c index 645fdb6db8..6922e62244 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -69,7 +69,7 @@ #include #endif -#if HAVE_CONIO_H +#if HAVE_KBHIT #include #endif #include @@ -435,7 +435,7 @@ static void term_init(void) /* read a key without blocking */ static int read_key(void) { -#if HAVE_CONIO_H +#if HAVE_KBHIT if(kbhit()) return(getch()); #endif @@ -2437,7 +2437,7 @@ static int transcode(AVFormatContext **output_files, } if (!using_stdin && verbose >= 0) { -#if HAVE_CONIO_H +#if HAVE_KBHIT fprintf(stderr, "Press [q] to stop encoding\n"); #else fprintf(stderr, "Press ctrl-c to stop encoding\n"); From 1885488757dc4c6b2d275e4524ed6dd19e97f9b0 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 22 Mar 2011 10:35:34 +0100 Subject: [PATCH 24/33] id3v2: don't explicitly skip padding It's pointless, since there's a seek to the end of tag later. --- libavformat/id3v2.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index 13272a493f..96f3e1c61a 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -279,10 +279,6 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t avio_seek(s->pb, next, SEEK_SET); } - if (len > 0) { - /* Skip padding */ - avio_skip(s->pb, len); - } if (version == 4 && flags & 0x10) /* Footer preset, always 10 bytes, skip over it */ end += 10; From c5f4c0fd5c791ba97eb266cc30ae2172c10feb20 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 22 Mar 2011 10:35:35 +0100 Subject: [PATCH 25/33] id3v2: skip broken tags with invalid size fixes issue2649. --- libavformat/id3v2.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index 96f3e1c61a..4fecffe6ba 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -237,11 +237,11 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t tag[3] = 0; tlen = avio_rb24(s->pb); } - len -= taghdrlen + tlen; - - if (len < 0) + if (tlen < 0 || tlen > len - taghdrlen) { + av_log(s, AV_LOG_WARNING, "Invalid size in frame %s, skipping the rest of tag.\n", tag); break; - + } + len -= taghdrlen + tlen; next = avio_tell(s->pb) + tlen; if (tflags & ID3v2_FLAG_DATALEN) { From eba586b0d9f0546c7c9c965edb71e7b29721217d Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 21 Mar 2011 23:32:40 -0400 Subject: [PATCH 26/33] Add a CPU flag for the Atom processor. The Atom has SSSE3 support, which is useful in many cases, but sometimes the SSSE3 version is slower than the SSE2 equivalent on the Atom, but is generally faster on other processors supporting SSSE3. This flag allows for selectively disabling certain SSSE3 functions on the Atom. --- libavutil/cpu.c | 1 + libavutil/cpu.h | 1 + libavutil/x86/cpu.c | 12 ++++++++++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/libavutil/cpu.c b/libavutil/cpu.c index eba067a91a..ddccd000bc 100644 --- a/libavutil/cpu.c +++ b/libavutil/cpu.c @@ -58,6 +58,7 @@ int main(void) cpu_flags & AV_CPU_FLAG_SSE3 ? "SSE3 " : "", cpu_flags & AV_CPU_FLAG_SSE3SLOW ? "SSE3(slow) " : "", cpu_flags & AV_CPU_FLAG_SSSE3 ? "SSSE3 " : "", + cpu_flags & AV_CPU_FLAG_ATOM ? "Atom " : "", cpu_flags & AV_CPU_FLAG_SSE4 ? "SSE4.1 " : "", cpu_flags & AV_CPU_FLAG_SSE42 ? "SSE4.2 " : "", cpu_flags & AV_CPU_FLAG_AVX ? "AVX " : "", diff --git a/libavutil/cpu.h b/libavutil/cpu.h index 3a87fc0506..11ba368678 100644 --- a/libavutil/cpu.h +++ b/libavutil/cpu.h @@ -34,6 +34,7 @@ #define AV_CPU_FLAG_SSE3 0x0040 ///< Prescott SSE3 functions #define AV_CPU_FLAG_SSE3SLOW 0x20000000 ///< SSE3 supported, but usually not faster #define AV_CPU_FLAG_SSSE3 0x0080 ///< Conroe SSSE3 functions +#define AV_CPU_FLAG_ATOM 0x10000000 ///< Atom processor, some SSSE3 instructions are slower #define AV_CPU_FLAG_SSE4 0x0100 ///< Penryn SSE4.1 functions #define AV_CPU_FLAG_SSE42 0x0200 ///< Nehalem SSE4.2 functions #define AV_CPU_FLAG_AVX 0x4000 ///< AVX functions: requires OS support even if YMM registers aren't used diff --git a/libavutil/x86/cpu.c b/libavutil/x86/cpu.c index c11956d3c3..4bc56912b5 100644 --- a/libavutil/x86/cpu.c +++ b/libavutil/x86/cpu.c @@ -135,8 +135,8 @@ int ff_get_cpu_flags_x86(void) } } - if (!strncmp(vendor.c, "GenuineIntel", 12) && - family == 6 && (model == 9 || model == 13 || model == 14)) { + 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 @@ -145,6 +145,14 @@ int ff_get_cpu_flags_x86(void) * 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 + * on the Atom, but is generally faster on other processors supporting + * SSSE3. This flag allows for selectively disabling certain SSSE3 + * functions on the Atom. */ + if (family == 6 && model == 28) + rval |= AV_CPU_FLAG_ATOM; } return rval; From 45ed82255025a200beae3b56a84bee20aad41465 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 21 Mar 2011 23:33:00 -0400 Subject: [PATCH 27/33] cosmetics: indentation --- libavutil/x86/cpu.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libavutil/x86/cpu.c b/libavutil/x86/cpu.c index 4bc56912b5..78aeadf0a1 100644 --- a/libavutil/x86/cpu.c +++ b/libavutil/x86/cpu.c @@ -137,14 +137,14 @@ 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 From 85ab2904700c5bf8b55a33ad598191e36318e195 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 22 Mar 2011 14:36:18 -0400 Subject: [PATCH 28/33] ac3enc: make sym_quant() branch-free --- libavcodec/ac3enc.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c index d9b06d9f3a..202e611cc0 100644 --- a/libavcodec/ac3enc.c +++ b/libavcodec/ac3enc.c @@ -1096,17 +1096,7 @@ static int compute_bit_allocation(AC3EncodeContext *s) */ static inline int sym_quant(int c, int e, int levels) { - int v; - - if (c >= 0) { - v = (levels * (c << e)) >> 24; - v = (v + 1) >> 1; - v = (levels >> 1) + v; - } else { - v = (levels * ((-c) << e)) >> 24; - v = (v + 1) >> 1; - v = (levels >> 1) - v; - } + int v = ((((levels * c) >> (24 - e)) + 1) >> 1) + (levels >> 1); av_assert2(v >= 0 && v < levels); return v; } From 67fc8652b9866978cdd6b49ecd293f2891466058 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 22 Mar 2011 14:11:34 -0400 Subject: [PATCH 29/33] Always copy input data for AC3 decoder. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Depending on error_recognition is not correct, low values do certainly not mean it is ok to crash. Based on a patch by Reimar Döffinger --- libavcodec/ac3dec.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index b089adcb21..f19625194d 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -209,11 +209,9 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx) s->downmixed = 1; /* allocate context input buffer */ - if (avctx->error_recognition >= FF_ER_CAREFUL) { s->input_buffer = av_mallocz(AC3_FRAME_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); if (!s->input_buffer) return AVERROR(ENOMEM); - } avctx->sample_fmt = AV_SAMPLE_FMT_S16; return 0; @@ -1314,15 +1312,12 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size, const uint8_t *channel_map; const float *output[AC3_MAX_CHANNELS]; - /* initialize the GetBitContext with the start of valid AC-3 Frame */ - if (s->input_buffer) { /* copy input buffer to decoder context to avoid reading past the end of the buffer, which can be caused by a damaged input stream. */ memcpy(s->input_buffer, buf, FFMIN(buf_size, AC3_FRAME_BUFFER_SIZE)); - init_get_bits(&s->gbc, s->input_buffer, buf_size * 8); - } else { + buf = s->input_buffer; + /* initialize the GetBitContext with the start of valid AC-3 Frame */ init_get_bits(&s->gbc, buf, buf_size * 8); - } /* parse the syncinfo */ *data_size = 0; From 40728b5169f23a6420b3d9758f485fd2cd99050d Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 22 Mar 2011 14:14:41 -0400 Subject: [PATCH 30/33] cosmetics: indentation --- libavcodec/ac3dec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index f19625194d..a9a67ced33 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -1312,12 +1312,12 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size, const uint8_t *channel_map; const float *output[AC3_MAX_CHANNELS]; - /* copy input buffer to decoder context to avoid reading past the end - of the buffer, which can be caused by a damaged input stream. */ + /* copy input buffer to decoder context to avoid reading past the end + of the buffer, which can be caused by a damaged input stream. */ memcpy(s->input_buffer, buf, FFMIN(buf_size, AC3_FRAME_BUFFER_SIZE)); buf = s->input_buffer; /* initialize the GetBitContext with the start of valid AC-3 Frame */ - init_get_bits(&s->gbc, buf, buf_size * 8); + init_get_bits(&s->gbc, buf, buf_size * 8); /* parse the syncinfo */ *data_size = 0; From 4c886d613df8b217c6d62cb2c94e88f848177b23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reimar=20D=C3=B6ffinger?= Date: Tue, 22 Mar 2011 14:22:07 -0400 Subject: [PATCH 31/33] Detect byte-swapped AC-3 and support decoding it directly. This allows the AC-3 decoder to be used directly with RealMedia decoders that unlike the libavformat one do not byte-swap automatically. Since the new code is only used in case we would fail directly otherwise there should be no risk for regressions. --- libavcodec/ac3dec.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index a9a67ced33..071cc6a54f 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -1314,6 +1314,11 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size, /* copy input buffer to decoder context to avoid reading past the end of the buffer, which can be caused by a damaged input stream. */ + if (buf_size >= 2 && AV_RB16(buf) == 0x770B) { + // seems to be byte-swapped AC-3 + int cnt = FFMIN(buf_size, AC3_FRAME_BUFFER_SIZE) >> 1; + s->dsp.bswap16_buf((uint16_t *)s->input_buffer, (const uint16_t *)buf, cnt); + } else memcpy(s->input_buffer, buf, FFMIN(buf_size, AC3_FRAME_BUFFER_SIZE)); buf = s->input_buffer; /* initialize the GetBitContext with the start of valid AC-3 Frame */ From a6d2227bc8a269c243bbcf3c3a22e94912755bb8 Mon Sep 17 00:00:00 2001 From: Kieran Kunhya Date: Tue, 22 Mar 2011 22:17:41 +0000 Subject: [PATCH 32/33] Add kbdwin.o to AC3 decoder Fixes --disable-everything --enable-decoder=ac3 Signed-off-by: Mans Rullgard --- libavcodec/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 04e35a180c..91dcdbe527 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -56,7 +56,7 @@ OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o aaccoder.o \ psymodel.o iirfilter.o \ mpeg4audio.o kbdwin.o OBJS-$(CONFIG_AASC_DECODER) += aasc.o msrledec.o -OBJS-$(CONFIG_AC3_DECODER) += ac3dec.o ac3dec_data.o ac3.o +OBJS-$(CONFIG_AC3_DECODER) += ac3dec.o ac3dec_data.o ac3.o kbdwin.o OBJS-$(CONFIG_AC3_ENCODER) += ac3enc_float.o ac3tab.o ac3.o kbdwin.o OBJS-$(CONFIG_AC3_FIXED_ENCODER) += ac3enc_fixed.o ac3tab.o ac3.o OBJS-$(CONFIG_ALAC_DECODER) += alac.o From ee26abf2a4884bb56959bac8215758195776c553 Mon Sep 17 00:00:00 2001 From: Vitor Sessak Date: Sun, 20 Mar 2011 18:30:29 +0100 Subject: [PATCH 33/33] Fix an infinite loop when RoQ encoded generated a frame with a size greater than the maximum valid size. Signed-off-by: Ronald S. Bultje --- libavcodec/roqvideoenc.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/libavcodec/roqvideoenc.c b/libavcodec/roqvideoenc.c index f4b5de0adf..052dcef3de 100644 --- a/libavcodec/roqvideoenc.c +++ b/libavcodec/roqvideoenc.c @@ -898,9 +898,20 @@ static void roq_encode_video(RoqContext *enc) for (i=0; iwidth*enc->height/64; i++) gather_data_for_cel(tempData->cel_evals + i, enc, tempData); - /* Quake 3 can't handle chunks bigger than 65536 bytes */ - if (tempData->mainChunkSize/8 > 65536) { - enc->lambda *= .8; + /* Quake 3 can't handle chunks bigger than 65535 bytes */ + if (tempData->mainChunkSize/8 > 65535) { + av_log(enc->avctx, AV_LOG_ERROR, + "Warning, generated a frame too big (%d > 65535), " + "try using a smaller qscale value.\n", + tempData->mainChunkSize/8); + enc->lambda *= 1.5; + tempData->mainChunkSize = 0; + memset(tempData->used_option, 0, sizeof(tempData->used_option)); + memset(tempData->codebooks.usedCB4, 0, + sizeof(tempData->codebooks.usedCB4)); + memset(tempData->codebooks.usedCB2, 0, + sizeof(tempData->codebooks.usedCB2)); + goto retry_encode; }