diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2011-03-23 02:42:56 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-03-23 02:42:56 +0100 |
commit | 4fa0e24736bff7d7fbdfb36ed578a1db166817d4 (patch) | |
tree | 3e74e32f82b02ff498320e07424d330473f44fd3 | |
parent | 4952afff75bc60df9c842bc248f1da8fe57e04a6 (diff) | |
parent | ee26abf2a4884bb56959bac8215758195776c553 (diff) | |
download | ffmpeg-4fa0e24736bff7d7fbdfb36ed578a1db166817d4.tar.gz |
Merge remote-tracking branch 'newdev/master'
* newdev/master: (33 commits)
Fix an infinite loop when RoQ encoded generated a frame with a size greater than the maximum valid size.
Add kbdwin.o to AC3 decoder
Detect byte-swapped AC-3 and support decoding it directly.
cosmetics: indentation
Always copy input data for AC3 decoder.
ac3enc: make sym_quant() branch-free
cosmetics: indentation
Add a CPU flag for the Atom processor.
id3v2: skip broken tags with invalid size
id3v2: don't explicitly skip padding
Make sure kbhit() is in conio.h
fate: update wmv8-drm reference
vc1: make P-frame deblock filter bit-exact.
configure: Add the -D parameter to the dlltool command
amr: Set the AVFMT_GENERIC_INDEX flag
amr: Set the pkt->pos field properly to the start of the packet
amr: Set the codec->bit_rate field based on the last packet
rtsp: Specify unicast for TCP interleaved streams, too
Set the correct target for mingw64 dlltool
applehttp: Change the variable for stream position in seconds into int64_t
...
Conflicts:
ffmpeg.c
ffplay.c
libavcodec/ac3dec.c
libavformat/avio.h
libavformat/id3v2.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rwxr-xr-x | configure | 10 | ||||
-rw-r--r-- | ffmpeg.c | 60 | ||||
-rw-r--r-- | libavcodec/Makefile | 2 | ||||
-rw-r--r-- | libavcodec/ac3dec.c | 32 | ||||
-rw-r--r-- | libavcodec/ac3enc.c | 12 | ||||
-rw-r--r-- | libavcodec/dct.h | 2 | ||||
-rw-r--r-- | libavcodec/fft.h | 1 | ||||
-rw-r--r-- | libavcodec/ffv1.c | 2 | ||||
-rw-r--r-- | libavcodec/roqvideoenc.c | 17 | ||||
-rw-r--r-- | libavcodec/vc1.c | 1 | ||||
-rw-r--r-- | libavcodec/vc1.h | 4 | ||||
-rw-r--r-- | libavcodec/vc1dec.c | 418 | ||||
-rw-r--r-- | libavformat/amr.c | 7 | ||||
-rw-r--r-- | libavformat/applehttp.c | 3 | ||||
-rw-r--r-- | libavformat/asfdec.c | 3 | ||||
-rw-r--r-- | libavformat/avio.h | 10 | ||||
-rw-r--r-- | libavformat/avio_internal.h | 5 | ||||
-rw-r--r-- | libavformat/aviobuf.c | 17 | ||||
-rw-r--r-- | libavformat/flvdec.c | 5 | ||||
-rw-r--r-- | libavformat/id3v2.c | 19 | ||||
-rw-r--r-- | libavformat/mp3dec.c | 2 | ||||
-rw-r--r-- | libavformat/rmenc.c | 2 | ||||
-rw-r--r-- | libavformat/rtsp.c | 2 | ||||
-rw-r--r-- | libavformat/utils.c | 4 | ||||
-rw-r--r-- | libavformat/wtv.c | 4 | ||||
-rw-r--r-- | libavutil/cpu.c | 1 | ||||
-rw-r--r-- | libavutil/cpu.h | 1 | ||||
-rw-r--r-- | libavutil/x86/cpu.c | 28 | ||||
-rw-r--r-- | tests/ref/fate/vc1 | 22 | ||||
-rw-r--r-- | tests/ref/fate/wmv8-drm | 250 |
30 files changed, 533 insertions, 413 deletions
@@ -1040,7 +1040,6 @@ HAVE_LIST=" bswap closesocket cmov - conio_h dcbzl dev_bktr_ioctl_bt848_h dev_bktr_ioctl_meteor_h @@ -1070,6 +1069,7 @@ HAVE_LIST=" inet_aton inline_asm isatty + kbhit ldbrx libdc1394_1 libdc1394_2 @@ -1118,7 +1118,6 @@ HAVE_LIST=" sys_soundcard_h sys_videoio_h ten_operands - termios_h threads truncf vfp_args @@ -2423,7 +2422,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 @@ -2433,7 +2432,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)"; \ @@ -2794,6 +2793,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 @@ -2801,7 +2801,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 libcrystalhd/libcrystalhd_if.h @@ -2810,7 +2809,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 @@ -69,12 +69,7 @@ #include <sys/select.h> #endif -#if HAVE_TERMIOS_H -#include <fcntl.h> -#include <sys/ioctl.h> -#include <sys/time.h> -#include <termios.h> -#elif HAVE_CONIO_H +#if HAVE_KBHIT #include <conio.h> #endif #include <time.h> @@ -343,12 +338,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) @@ -436,9 +425,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; @@ -452,26 +438,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 @@ -482,25 +448,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_KBHIT if(kbhit()) return(getch()); #endif @@ -2511,7 +2459,11 @@ static int transcode(AVFormatContext **output_files, if (!using_stdin) { if(verbose >= 0) +#if HAVE_KBHIT 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(); diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 8343d92bc6..4d3fbe1771 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -57,7 +57,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 diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 094b2615ff..7f12d9cba0 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -208,6 +208,11 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx) } s->downmixed = 1; + /* allocate context input buffer */ + 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; } @@ -1306,26 +1311,17 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size, int blk, ch, err; const uint8_t *channel_map; const float *output[AC3_MAX_CHANNELS]; - // if it seems to be byte-swapped AC-3 (aka DNET) - int is_swapped = buf_size >= 2 && AV_RB16(buf) == 0x770B; - - /* initialize the GetBitContext with the start of valid AC-3 Frame */ - if (is_swapped || avctx->error_recognition >= FF_ER_CAREFUL) { - /* allocate context input buffer */ - if (!s->input_buffer) - s->input_buffer = av_mallocz(AC3_FRAME_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); - if (!s->input_buffer) - return AVERROR(ENOMEM); - /* 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 (is_swapped) { - 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 + /* 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; - } + 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 */ diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c index 5b76ae6735..4413e5bd6b 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; } diff --git a/libavcodec/dct.h b/libavcodec/dct.h index 44cf04d41d..ffc1d9aed2 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 5a0f41ff6e..2dad05d2f5 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); diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c index 4219d62e1f..7d1492ff46 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); } diff --git a/libavcodec/roqvideoenc.c b/libavcodec/roqvideoenc.c index 0efbca8742..9030affb31 100644 --- a/libavcodec/roqvideoenc.c +++ b/libavcodec/roqvideoenc.c @@ -898,9 +898,20 @@ static void roq_encode_video(RoqContext *enc) for (i=0; i<enc->width*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; } diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index 27cd0108a5..1b77105f07 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); diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h index d826c5a817..8d907c3bf0 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 1a437a892a..4bc7c9d962 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; } @@ -2686,7 +2770,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 +2812,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 +2906,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,12 +2919,13 @@ 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; + int apply_loop_filter; /* select codingmode used for VLC tables selection */ switch(v->c_ac_table_index){ @@ -2860,29 +2952,45 @@ static void vc1_decode_p_blocks(VC1Context *v) 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 = 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++) { 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, 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; } } 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; } - ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END)); + 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)); } -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 +3020,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 +3028,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 +3042,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 +3064,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 +3082,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; } } @@ -3116,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); @@ -3145,12 +3258,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 +3323,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 */ @@ -3217,15 +3345,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 +3362,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 +3380,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 +3413,23 @@ 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); + 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; ff_er_frame_end(s); @@ -3324,8 +3450,19 @@ assert(s->current_picture.pict_type == s->pict_type); ff_print_debug_info(s, pict); } +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; } @@ -3345,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/libavformat/amr.c b/libavformat/amr.c index 0459632b10..66763f3fa7 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 (url_feof(s->pb)) { @@ -153,8 +154,11 @@ 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->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); @@ -177,6 +181,7 @@ AVInputFormat ff_amr_demuxer = { amr_read_header, amr_read_packet, NULL, + .flags = AVFMT_GENERIC_INDEX, }; #endif diff --git a/libavformat/applehttp.c b/libavformat/applehttp.c index 324494ad74..8a6b232e51 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) diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c index 71f4e79fd5..aac52ee045 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" @@ -1241,7 +1242,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 2d2afc7112..55eefb5bde 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 @@ -512,10 +515,6 @@ int64_t avio_size(AVIOContext *s); */ int url_feof(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))); @@ -622,9 +621,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/avio_internal.h b/libavformat/avio_internal.h index 12578fac6c..88da0f635c 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 b8cfb9286a..174df21b89 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -406,6 +406,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) @@ -932,10 +941,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, ...) { @@ -978,15 +989,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 d84051c7a8..e3449a6746 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/id3v2.c b/libavformat/id3v2.c index 027b8d717c..95353276b5 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -187,9 +187,9 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t int isv34, unsync; unsigned tlen; char tag[5]; - int64_t next; + 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; @@ -282,20 +282,15 @@ 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 */ - avio_skip(s->pb, 10); - - av_free(buffer); - return; + end += 10; error: - av_log(s, AV_LOG_INFO, "ID3v2.%d tag skipped, cannot handle %s\n", version, reason); - avio_seek(s->pb, len, SEEK_CUR); + 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; } void ff_id3v2_read(AVFormatContext *s, const char *magic) diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c index b7386fb78f..1306888b46 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/rmenc.c b/libavformat/rmenc.c index 4835cf4435..28ee173fb8 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 */ diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index f50650ed8f..0b8430938d 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", diff --git a/libavformat/utils.c b/libavformat/utils.c index b4923bad92..b4b48643dd 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2554,7 +2554,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); } @@ -2563,7 +2563,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); } diff --git a/libavformat/wtv.c b/libavformat/wtv.c index 35d987c061..a9ad2718ad 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)); diff --git a/libavutil/cpu.c b/libavutil/cpu.c index 3459ce435d..66262b9afd 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 d60e062e19..ff0c2e64ac 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 14d0fe10c8..2cefdbfbe5 100644 --- a/libavutil/x86/cpu.c +++ b/libavutil/x86/cpu.c @@ -135,16 +135,24 @@ int ff_get_cpu_flags_x86(void) } } - if (!strncmp(vendor.c, "GenuineIntel", 12) && - 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; + 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; + } + /* 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; 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 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 |