From f7813a5324be39d13ab536c245d15dfc602a7849 Mon Sep 17 00:00:00 2001 From: Tim Redfern Date: Sun, 29 Dec 2013 12:19:38 +0000 Subject: basic type mechanism working --- ffmpeg/libavcodec/012v.c | 8 +- ffmpeg/libavcodec/4xm.c | 200 +- ffmpeg/libavcodec/8bps.c | 38 +- ffmpeg/libavcodec/8svx.c | 4 +- ffmpeg/libavcodec/Makefile | 181 +- ffmpeg/libavcodec/a64multienc.c | 22 +- ffmpeg/libavcodec/aac.h | 5 +- ffmpeg/libavcodec/aac_ac3_parser.c | 26 +- ffmpeg/libavcodec/aac_ac3_parser.h | 14 +- ffmpeg/libavcodec/aac_adtstoasc_bsf.c | 6 +- ffmpeg/libavcodec/aac_tablegen.h | 2 +- ffmpeg/libavcodec/aaccoder.c | 10 +- ffmpeg/libavcodec/aacdec.c | 746 ++++-- ffmpeg/libavcodec/aacenc.c | 12 +- ffmpeg/libavcodec/aacenc.h | 9 +- ffmpeg/libavcodec/aacps.c | 21 +- ffmpeg/libavcodec/aacps_tablegen.c | 2 +- ffmpeg/libavcodec/aacps_tablegen.h | 6 +- ffmpeg/libavcodec/aacpsdsp.c | 10 +- ffmpeg/libavcodec/aacpsdsp.h | 10 +- ffmpeg/libavcodec/aacpsy.c | 87 +- ffmpeg/libavcodec/aacpsy.h | 50 - ffmpeg/libavcodec/aacsbr.c | 22 +- ffmpeg/libavcodec/aacsbrdata.h | 6 +- ffmpeg/libavcodec/aactab.c | 519 ++++ ffmpeg/libavcodec/aactab.h | 4 + ffmpeg/libavcodec/aasc.c | 8 +- ffmpeg/libavcodec/ac3dec.c | 102 +- ffmpeg/libavcodec/ac3dec.h | 3 +- ffmpeg/libavcodec/ac3dsp.c | 14 + ffmpeg/libavcodec/ac3dsp.h | 14 + ffmpeg/libavcodec/ac3enc.c | 6 +- ffmpeg/libavcodec/ac3enc.h | 8 +- ffmpeg/libavcodec/ac3enc_fixed.c | 13 +- ffmpeg/libavcodec/ac3enc_float.c | 14 +- ffmpeg/libavcodec/ac3enc_opts_template.c | 8 +- ffmpeg/libavcodec/ac3enc_template.c | 14 +- ffmpeg/libavcodec/ac3tab.c | 2 +- ffmpeg/libavcodec/acelp_vectors.c | 4 +- ffmpeg/libavcodec/adpcm.c | 182 +- ffmpeg/libavcodec/adpcm.h | 4 +- ffmpeg/libavcodec/adpcm_data.c | 23 +- ffmpeg/libavcodec/adpcm_data.h | 4 + ffmpeg/libavcodec/adpcmenc.c | 10 +- ffmpeg/libavcodec/adx.c | 8 +- ffmpeg/libavcodec/adx_parser.c | 8 +- ffmpeg/libavcodec/adxdec.c | 2 +- ffmpeg/libavcodec/adxenc.c | 2 +- ffmpeg/libavcodec/alac.c | 36 +- ffmpeg/libavcodec/alacenc.c | 11 +- ffmpeg/libavcodec/allcodecs.c | 40 +- ffmpeg/libavcodec/alpha/dsputil_alpha_asm.S | 11 - ffmpeg/libavcodec/alpha/hpeldsp_alpha.c | 3 +- ffmpeg/libavcodec/alpha/hpeldsp_alpha.h | 1 + ffmpeg/libavcodec/alpha/hpeldsp_alpha_asm.S | 10 - ffmpeg/libavcodec/alpha/regdef.h | 11 + ffmpeg/libavcodec/alsdec.c | 177 +- ffmpeg/libavcodec/amrnbdec.c | 2 +- ffmpeg/libavcodec/amrwbdec.c | 2 +- ffmpeg/libavcodec/anm.c | 2 +- ffmpeg/libavcodec/ansi.c | 23 +- ffmpeg/libavcodec/apedec.c | 496 +++- ffmpeg/libavcodec/arm/Makefile | 146 +- ffmpeg/libavcodec/arm/aacpsdsp_init_arm.c | 8 +- ffmpeg/libavcodec/arm/aacpsdsp_neon.S | 8 +- ffmpeg/libavcodec/arm/ac3dsp_arm.S | 8 +- ffmpeg/libavcodec/arm/ac3dsp_armv6.S | 8 +- ffmpeg/libavcodec/arm/ac3dsp_init_arm.c | 3 + ffmpeg/libavcodec/arm/ac3dsp_neon.S | 31 +- ffmpeg/libavcodec/arm/dca.h | 86 +- ffmpeg/libavcodec/arm/dcadsp_init_arm.c | 34 + ffmpeg/libavcodec/arm/dsputil_init_neon.c | 5 - ffmpeg/libavcodec/arm/dsputil_neon.S | 23 - ffmpeg/libavcodec/arm/fft_fixed_neon.S | 8 +- ffmpeg/libavcodec/arm/fft_init_arm.c | 25 +- ffmpeg/libavcodec/arm/fmtconvert_init_arm.c | 19 +- ffmpeg/libavcodec/arm/fmtconvert_vfp.S | 245 +- ffmpeg/libavcodec/arm/h264cmc_neon.S | 23 +- ffmpeg/libavcodec/arm/h264dsp_init_arm.c | 10 +- ffmpeg/libavcodec/arm/h264idct_neon.S | 18 +- ffmpeg/libavcodec/arm/h264pred_init_arm.c | 8 +- ffmpeg/libavcodec/arm/hpeldsp_arm.h | 2 +- ffmpeg/libavcodec/arm/hpeldsp_init_arm.c | 10 +- ffmpeg/libavcodec/arm/hpeldsp_init_armv6.c | 1 + ffmpeg/libavcodec/arm/hpeldsp_init_neon.c | 4 +- ffmpeg/libavcodec/arm/int_neon.S | 14 +- ffmpeg/libavcodec/arm/mdct_fixed_neon.S | 8 +- ffmpeg/libavcodec/arm/mpegaudiodsp_fixed_armv6.S | 8 +- ffmpeg/libavcodec/arm/mpegaudiodsp_init_arm.c | 8 +- ffmpeg/libavcodec/arm/neon.S | 8 +- ffmpeg/libavcodec/arm/rv34dsp_neon.S | 8 +- ffmpeg/libavcodec/arm/rv40dsp_init_arm.c | 4 +- ffmpeg/libavcodec/arm/rv40dsp_neon.S | 8 +- ffmpeg/libavcodec/arm/sbrdsp_init_arm.c | 8 +- ffmpeg/libavcodec/arm/sbrdsp_neon.S | 8 +- ffmpeg/libavcodec/arm/simple_idct_arm.S | 16 +- ffmpeg/libavcodec/arm/vp56dsp_init_arm.c | 39 - ffmpeg/libavcodec/arm/vp56dsp_neon.S | 121 - ffmpeg/libavcodec/arm/vp8dsp.h | 8 +- ffmpeg/libavcodec/arm/vp8dsp_armv6.S | 8 +- ffmpeg/libavcodec/arm/vp8dsp_init_armv6.c | 8 +- ffmpeg/libavcodec/arm/vp8dsp_init_neon.c | 8 +- ffmpeg/libavcodec/arm/vp8dsp_neon.S | 165 +- ffmpeg/libavcodec/ass.c | 144 +- ffmpeg/libavcodec/ass.h | 39 +- ffmpeg/libavcodec/ass_split.h | 2 +- ffmpeg/libavcodec/assdec.c | 52 +- ffmpeg/libavcodec/assenc.c | 66 +- ffmpeg/libavcodec/asv.c | 1 - ffmpeg/libavcodec/asv.h | 1 - ffmpeg/libavcodec/asvdec.c | 9 +- ffmpeg/libavcodec/asvenc.c | 31 +- ffmpeg/libavcodec/atrac.c | 82 +- ffmpeg/libavcodec/atrac.h | 69 +- ffmpeg/libavcodec/atrac1.c | 6 +- ffmpeg/libavcodec/atrac1data.h | 4 +- ffmpeg/libavcodec/atrac3.c | 145 +- ffmpeg/libavcodec/atrac3data.h | 4 +- ffmpeg/libavcodec/audio_frame_queue.c | 3 +- ffmpeg/libavcodec/audio_frame_queue.h | 8 +- ffmpeg/libavcodec/audioconvert.c | 4 + ffmpeg/libavcodec/audioconvert.h | 14 + ffmpeg/libavcodec/aura.c | 2 +- ffmpeg/libavcodec/avcodec.h | 769 ++++-- ffmpeg/libavcodec/avfft.c | 11 +- ffmpeg/libavcodec/avpacket.c | 233 +- ffmpeg/libavcodec/avrndec.c | 3 +- ffmpeg/libavcodec/avs.c | 25 +- ffmpeg/libavcodec/avuidec.c | 2 +- ffmpeg/libavcodec/avuienc.c | 4 +- ffmpeg/libavcodec/bethsoftvideo.c | 28 +- ffmpeg/libavcodec/bfi.c | 4 +- ffmpeg/libavcodec/bfin/Makefile | 2 +- ffmpeg/libavcodec/bfin/dsputil_bfin.c | 4 +- ffmpeg/libavcodec/bfin/hpel_pixels_bfin.S | 2 +- ffmpeg/libavcodec/bfin/hpeldsp_bfin.c | 6 +- ffmpeg/libavcodec/bfin/vp3_bfin.c | 23 +- ffmpeg/libavcodec/bgmc.c | 14 +- ffmpeg/libavcodec/bgmc.h | 4 +- ffmpeg/libavcodec/bink.c | 24 +- ffmpeg/libavcodec/binkaudio.c | 10 +- ffmpeg/libavcodec/binkdata.h | 2 +- ffmpeg/libavcodec/binkdsp.c | 5 +- ffmpeg/libavcodec/binkdsp.h | 10 +- ffmpeg/libavcodec/bintext.c | 6 +- ffmpeg/libavcodec/bintext.h | 2 +- ffmpeg/libavcodec/bit_depth_template.c | 8 +- ffmpeg/libavcodec/bitstream.c | 208 +- ffmpeg/libavcodec/bitstream_filter.c | 58 +- ffmpeg/libavcodec/bmp.c | 6 +- ffmpeg/libavcodec/bmp.h | 4 - ffmpeg/libavcodec/bmpenc.c | 30 +- ffmpeg/libavcodec/bmv.c | 14 +- ffmpeg/libavcodec/brender_pix.c | 9 +- ffmpeg/libavcodec/bytestream.h | 3 + ffmpeg/libavcodec/c93.c | 44 +- ffmpeg/libavcodec/cabac.c | 27 +- ffmpeg/libavcodec/cabac_functions.h | 33 +- ffmpeg/libavcodec/cavs.c | 496 ++-- ffmpeg/libavcodec/cavs.h | 2 +- ffmpeg/libavcodec/cavsdata.h | 67 - ffmpeg/libavcodec/cavsdec.c | 52 +- ffmpeg/libavcodec/cavsdsp.c | 78 +- ffmpeg/libavcodec/cbrt_tablegen.h | 3 +- ffmpeg/libavcodec/cdgraphics.c | 8 +- ffmpeg/libavcodec/cdxl.c | 14 +- ffmpeg/libavcodec/chomp_bsf.c | 5 +- ffmpeg/libavcodec/cinepak.c | 2 +- ffmpeg/libavcodec/cljr.c | 20 +- ffmpeg/libavcodec/cllc.c | 110 +- ffmpeg/libavcodec/cngdec.c | 2 +- ffmpeg/libavcodec/cngenc.c | 2 +- ffmpeg/libavcodec/codec_desc.c | 121 +- ffmpeg/libavcodec/cook.c | 15 +- ffmpeg/libavcodec/cook_parser.c | 15 +- ffmpeg/libavcodec/cos_tablegen.c | 13 +- ffmpeg/libavcodec/cpia.c | 2 +- ffmpeg/libavcodec/crystalhd.c | 18 +- ffmpeg/libavcodec/cscd.c | 2 +- ffmpeg/libavcodec/cyuv.c | 4 +- ffmpeg/libavcodec/dca.c | 37 + ffmpeg/libavcodec/dca.h | 6 + ffmpeg/libavcodec/dca_parser.c | 52 +- ffmpeg/libavcodec/dca_parser.h | 36 - ffmpeg/libavcodec/dcadata.h | 55 +- ffmpeg/libavcodec/dcadec.c | 333 ++- ffmpeg/libavcodec/dcadsp.c | 33 +- ffmpeg/libavcodec/dcadsp.h | 9 + ffmpeg/libavcodec/dcaenc.c | 1084 +++++--- ffmpeg/libavcodec/dcaenc.h | 601 +---- ffmpeg/libavcodec/dct-test.c | 21 +- ffmpeg/libavcodec/dct.c | 16 +- ffmpeg/libavcodec/dct32.c | 276 -- ffmpeg/libavcodec/dct32.h | 8 +- ffmpeg/libavcodec/dct32_fixed.c | 10 +- ffmpeg/libavcodec/dct32_float.c | 10 +- ffmpeg/libavcodec/dfa.c | 45 +- ffmpeg/libavcodec/dirac.c | 6 +- ffmpeg/libavcodec/dirac_dwt.c | 15 +- ffmpeg/libavcodec/dirac_dwt.h | 3 - ffmpeg/libavcodec/diracdec.c | 112 +- ffmpeg/libavcodec/dnxhddec.c | 11 +- ffmpeg/libavcodec/dnxhdenc.c | 49 +- ffmpeg/libavcodec/dnxhdenc.h | 1 - ffmpeg/libavcodec/dpcm.c | 2 +- ffmpeg/libavcodec/dpx.c | 196 +- ffmpeg/libavcodec/dpxenc.c | 87 +- ffmpeg/libavcodec/dsicinav.c | 132 +- ffmpeg/libavcodec/dsputil.c | 205 +- ffmpeg/libavcodec/dsputil.h | 25 +- ffmpeg/libavcodec/dsputil_template.c | 3 - ffmpeg/libavcodec/dump_extradata_bsf.c | 5 +- ffmpeg/libavcodec/dv.c | 695 +---- ffmpeg/libavcodec/dv_profile.c | 8 +- ffmpeg/libavcodec/dv_profile.h | 8 +- ffmpeg/libavcodec/dv_tablegen.c | 3 - ffmpeg/libavcodec/dv_tablegen.h | 16 +- ffmpeg/libavcodec/dv_vlc_data.h | 259 -- ffmpeg/libavcodec/dvbsub.c | 2 +- ffmpeg/libavcodec/dvbsubdec.c | 24 +- ffmpeg/libavcodec/dvdata.c | 227 +- ffmpeg/libavcodec/dvdata.h | 95 +- ffmpeg/libavcodec/dvdec.c | 59 +- ffmpeg/libavcodec/dvdsubdec.c | 124 +- ffmpeg/libavcodec/dvdsubenc.c | 2 +- ffmpeg/libavcodec/dxa.c | 76 +- ffmpeg/libavcodec/dxtory.c | 186 +- ffmpeg/libavcodec/dxva2_mpeg2.c | 3 +- ffmpeg/libavcodec/dxva2_vc1.c | 2 +- ffmpeg/libavcodec/eac3enc.c | 14 +- ffmpeg/libavcodec/eac3enc.h | 8 +- ffmpeg/libavcodec/eacmv.c | 22 +- ffmpeg/libavcodec/eamad.c | 59 +- ffmpeg/libavcodec/eatgq.c | 11 +- ffmpeg/libavcodec/eatgv.c | 43 +- ffmpeg/libavcodec/eatqi.c | 7 +- ffmpeg/libavcodec/elbg.c | 8 +- ffmpeg/libavcodec/elbg.h | 8 +- ffmpeg/libavcodec/error_resilience.c | 56 +- ffmpeg/libavcodec/escape124.c | 49 +- ffmpeg/libavcodec/escape130.c | 411 +-- ffmpeg/libavcodec/evrcdec.c | 12 +- ffmpeg/libavcodec/exr.c | 493 +++- ffmpeg/libavcodec/faxcompr.c | 181 +- ffmpeg/libavcodec/fft-internal.h | 21 +- ffmpeg/libavcodec/fft-test.c | 14 +- ffmpeg/libavcodec/fft.c | 353 --- ffmpeg/libavcodec/fft.h | 25 +- ffmpeg/libavcodec/fft_fixed.c | 3 +- ffmpeg/libavcodec/fft_float.c | 3 +- ffmpeg/libavcodec/ffv1.c | 20 +- ffmpeg/libavcodec/ffv1.h | 11 +- ffmpeg/libavcodec/ffv1dec.c | 342 ++- ffmpeg/libavcodec/ffv1enc.c | 385 ++- ffmpeg/libavcodec/ffwavesynth.c | 2 +- ffmpeg/libavcodec/flac.c | 16 +- ffmpeg/libavcodec/flac_parser.c | 66 +- ffmpeg/libavcodec/flacdata.c | 2 +- ffmpeg/libavcodec/flacdata.h | 2 +- ffmpeg/libavcodec/flacdec.c | 94 +- ffmpeg/libavcodec/flacenc.c | 4 +- ffmpeg/libavcodec/flashsv.c | 161 +- ffmpeg/libavcodec/flashsv2enc.c | 15 +- ffmpeg/libavcodec/flashsvenc.c | 55 +- ffmpeg/libavcodec/flicvideo.c | 73 +- ffmpeg/libavcodec/flvdec.c | 10 +- ffmpeg/libavcodec/flvenc.c | 2 +- ffmpeg/libavcodec/fmtconvert.c | 16 +- ffmpeg/libavcodec/fmtconvert.h | 21 +- ffmpeg/libavcodec/frame_thread_encoder.c | 6 +- ffmpeg/libavcodec/fraps.c | 15 +- ffmpeg/libavcodec/frwu.c | 2 +- ffmpeg/libavcodec/g722.h | 8 +- ffmpeg/libavcodec/g722dec.c | 4 +- ffmpeg/libavcodec/g722enc.c | 10 +- ffmpeg/libavcodec/g723_1.c | 5 +- ffmpeg/libavcodec/g726.c | 37 +- ffmpeg/libavcodec/g729dec.c | 14 +- ffmpeg/libavcodec/get_bits.h | 78 +- ffmpeg/libavcodec/gif.c | 276 +- ffmpeg/libavcodec/gif.h | 2 + ffmpeg/libavcodec/gifdec.c | 43 +- ffmpeg/libavcodec/golomb.h | 326 +-- ffmpeg/libavcodec/gsm.h | 18 +- ffmpeg/libavcodec/gsm_parser.c | 11 +- ffmpeg/libavcodec/gsmdec.c | 20 +- ffmpeg/libavcodec/gsmdec_data.c | 26 + ffmpeg/libavcodec/gsmdec_data.h | 2 + ffmpeg/libavcodec/gsmdec_template.c | 21 +- ffmpeg/libavcodec/h261.c | 72 +- ffmpeg/libavcodec/h261.h | 27 +- ffmpeg/libavcodec/h261_parser.c | 45 +- ffmpeg/libavcodec/h261data.c | 144 +- ffmpeg/libavcodec/h261data.h | 42 - ffmpeg/libavcodec/h261dec.c | 586 ++--- ffmpeg/libavcodec/h261enc.c | 389 +-- ffmpeg/libavcodec/h263.c | 35 +- ffmpeg/libavcodec/h263.h | 9 +- ffmpeg/libavcodec/h263data.h | 5 - ffmpeg/libavcodec/h263dec.c | 725 +++--- ffmpeg/libavcodec/h264.c | 1223 +++++---- ffmpeg/libavcodec/h264.h | 88 +- ffmpeg/libavcodec/h264_cabac.c | 48 +- ffmpeg/libavcodec/h264_cavlc.c | 44 +- ffmpeg/libavcodec/h264_direct.c | 2 +- ffmpeg/libavcodec/h264_loopfilter.c | 18 +- ffmpeg/libavcodec/h264_mb_template.c | 6 +- ffmpeg/libavcodec/h264_mp4toannexb_bsf.c | 186 +- ffmpeg/libavcodec/h264_mvpred.h | 6 +- ffmpeg/libavcodec/h264_parser.c | 429 ++- ffmpeg/libavcodec/h264_ps.c | 760 +++--- ffmpeg/libavcodec/h264_refs.c | 65 +- ffmpeg/libavcodec/h264_sei.c | 277 +- ffmpeg/libavcodec/h264chroma.c | 7 +- ffmpeg/libavcodec/h264chroma.h | 5 +- ffmpeg/libavcodec/h264chroma_template.c | 28 + ffmpeg/libavcodec/h264data.h | 101 - ffmpeg/libavcodec/h264dsp.c | 37 +- ffmpeg/libavcodec/h264dsp.h | 9 + ffmpeg/libavcodec/h264idct_template.c | 4 +- ffmpeg/libavcodec/h264pred.c | 18 +- ffmpeg/libavcodec/h264qpel.c | 3 +- ffmpeg/libavcodec/hpeldsp.c | 22 +- ffmpeg/libavcodec/hpeldsp.h | 19 +- ffmpeg/libavcodec/huffman.c | 10 +- ffmpeg/libavcodec/huffman.h | 3 +- ffmpeg/libavcodec/huffyuv.h | 1 - ffmpeg/libavcodec/huffyuvdec.c | 8 +- ffmpeg/libavcodec/huffyuvenc.c | 152 +- ffmpeg/libavcodec/idcinvideo.c | 2 +- ffmpeg/libavcodec/iff.c | 160 +- ffmpeg/libavcodec/iirfilter.c | 16 +- ffmpeg/libavcodec/imc.c | 192 +- ffmpeg/libavcodec/imgconvert.c | 31 +- ffmpeg/libavcodec/imx_dump_header_bsf.c | 5 +- ffmpeg/libavcodec/indeo2.c | 28 +- ffmpeg/libavcodec/indeo3.c | 190 +- ffmpeg/libavcodec/indeo4.c | 98 +- ffmpeg/libavcodec/indeo4data.h | 8 +- ffmpeg/libavcodec/indeo5.c | 105 +- ffmpeg/libavcodec/intelh263dec.c | 7 +- ffmpeg/libavcodec/internal.h | 37 +- ffmpeg/libavcodec/interplayvideo.c | 27 +- ffmpeg/libavcodec/intrax8.c | 15 +- ffmpeg/libavcodec/intrax8.h | 3 + ffmpeg/libavcodec/ituh263dec.c | 44 +- ffmpeg/libavcodec/ituh263enc.c | 10 +- ffmpeg/libavcodec/ivi_common.c | 594 +++-- ffmpeg/libavcodec/ivi_common.h | 2 +- ffmpeg/libavcodec/ivi_dsp.c | 204 +- ffmpeg/libavcodec/ivi_dsp.h | 93 + ffmpeg/libavcodec/j2k.c | 391 --- ffmpeg/libavcodec/j2k.h | 234 -- ffmpeg/libavcodec/j2k_dwt.c | 386 --- ffmpeg/libavcodec/j2k_dwt.h | 63 - ffmpeg/libavcodec/j2kdec.c | 1093 -------- ffmpeg/libavcodec/j2kenc.c | 359 +-- ffmpeg/libavcodec/jfdctint.c | 8 +- ffmpeg/libavcodec/jpegls.c | 77 +- ffmpeg/libavcodec/jpegls.h | 79 +- ffmpeg/libavcodec/jpeglsdec.c | 297 ++- ffmpeg/libavcodec/jpeglsdec.h | 3 +- ffmpeg/libavcodec/jpeglsenc.c | 257 +- ffmpeg/libavcodec/jvdec.c | 28 +- ffmpeg/libavcodec/kgv1dec.c | 31 +- ffmpeg/libavcodec/kmvc.c | 33 +- ffmpeg/libavcodec/lagarith.c | 34 +- ffmpeg/libavcodec/lcldec.c | 16 +- ffmpeg/libavcodec/lclenc.c | 26 +- ffmpeg/libavcodec/libaacplus.c | 46 +- ffmpeg/libavcodec/libavcodec.pc | 8 +- ffmpeg/libavcodec/libavcodec.v | 2 - ffmpeg/libavcodec/libcelt_dec.c | 2 +- ffmpeg/libavcodec/libfaac.c | 19 +- ffmpeg/libavcodec/libfdk-aacenc.c | 3 +- ffmpeg/libavcodec/libgsm.c | 8 +- ffmpeg/libavcodec/libilbc.c | 4 +- ffmpeg/libavcodec/libmp3lame.c | 31 +- ffmpeg/libavcodec/libopencore-amr.c | 11 +- ffmpeg/libavcodec/libopenjpegdec.c | 41 +- ffmpeg/libavcodec/libopenjpegenc.c | 206 +- ffmpeg/libavcodec/libopusdec.c | 6 +- ffmpeg/libavcodec/libopusenc.c | 28 +- ffmpeg/libavcodec/libschroedinger.c | 5 +- ffmpeg/libavcodec/libschroedingerdec.c | 2 +- ffmpeg/libavcodec/libschroedingerenc.c | 26 +- ffmpeg/libavcodec/libspeexdec.c | 14 +- ffmpeg/libavcodec/libspeexenc.c | 6 +- ffmpeg/libavcodec/libstagefright.cpp | 27 +- ffmpeg/libavcodec/libtheoraenc.c | 29 +- ffmpeg/libavcodec/libtwolame.c | 4 +- ffmpeg/libavcodec/libutvideo.h | 11 +- ffmpeg/libavcodec/libutvideodec.cpp | 21 +- ffmpeg/libavcodec/libutvideoenc.cpp | 5 +- ffmpeg/libavcodec/libvo-aacenc.c | 2 +- ffmpeg/libavcodec/libvo-amrwbenc.c | 8 +- ffmpeg/libavcodec/libvorbisdec.c | 4 +- ffmpeg/libavcodec/libvorbisenc.c | 7 +- ffmpeg/libavcodec/libvpxdec.c | 16 +- ffmpeg/libavcodec/libvpxenc.c | 255 +- ffmpeg/libavcodec/libx264.c | 100 +- ffmpeg/libavcodec/libxavs.c | 44 +- ffmpeg/libavcodec/libxvid.c | 142 +- ffmpeg/libavcodec/libxvid_rc.c | 7 +- ffmpeg/libavcodec/ljpegenc.c | 406 +-- ffmpeg/libavcodec/loco.c | 4 +- ffmpeg/libavcodec/lpc.c | 54 +- ffmpeg/libavcodec/lpc.h | 2 +- ffmpeg/libavcodec/lzwenc.c | 7 +- ffmpeg/libavcodec/mace.c | 8 +- ffmpeg/libavcodec/mathops.h | 19 + ffmpeg/libavcodec/mathtables.c | 22 +- ffmpeg/libavcodec/mdct.c | 203 -- ffmpeg/libavcodec/mdct_fixed.c | 3 +- ffmpeg/libavcodec/mdct_float.c | 3 +- ffmpeg/libavcodec/mdec.c | 16 +- ffmpeg/libavcodec/mimic.c | 11 +- ffmpeg/libavcodec/mips/Makefile | 1 - ffmpeg/libavcodec/mips/fft_init_table.c | 67 - ffmpeg/libavcodec/mips/fft_mips.c | 2 +- ffmpeg/libavcodec/mips/fft_table.h | 63 - ffmpeg/libavcodec/mjpeg.c | 4 +- ffmpeg/libavcodec/mjpega_dump_header_bsf.c | 5 +- ffmpeg/libavcodec/mjpegbdec.c | 2 +- ffmpeg/libavcodec/mjpegdec.c | 629 +++-- ffmpeg/libavcodec/mjpegdec.h | 6 +- ffmpeg/libavcodec/mjpegenc.c | 271 +- ffmpeg/libavcodec/mjpegenc.h | 10 +- ffmpeg/libavcodec/mlp_parser.c | 5 + ffmpeg/libavcodec/mlpdec.c | 49 +- ffmpeg/libavcodec/mlpdsp.c | 13 +- ffmpeg/libavcodec/mmvideo.c | 36 +- ffmpeg/libavcodec/motion_est.c | 18 +- ffmpeg/libavcodec/motionpixels.c | 61 +- ffmpeg/libavcodec/movsub_bsf.c | 10 +- ffmpeg/libavcodec/mp3_header_compress_bsf.c | 88 - ffmpeg/libavcodec/mp3_header_decompress_bsf.c | 5 +- ffmpeg/libavcodec/mpc.c | 3 +- ffmpeg/libavcodec/mpc7.c | 2 +- ffmpeg/libavcodec/mpc8.c | 2 +- ffmpeg/libavcodec/mpeg12.c | 2699 +------------------ ffmpeg/libavcodec/mpeg12.h | 30 +- ffmpeg/libavcodec/mpeg12decdata.h | 93 - ffmpeg/libavcodec/mpeg12enc.c | 1244 +++++---- ffmpeg/libavcodec/mpeg4video.c | 182 +- ffmpeg/libavcodec/mpeg4video.h | 155 +- ffmpeg/libavcodec/mpeg4video_parser.c | 88 +- ffmpeg/libavcodec/mpeg4videodec.c | 3008 ++++++++++++---------- ffmpeg/libavcodec/mpeg4videoenc.c | 1242 ++++----- ffmpeg/libavcodec/mpegaudio.h | 6 +- ffmpeg/libavcodec/mpegaudio_tablegen.h | 9 +- ffmpeg/libavcodec/mpegaudiodec.c | 2076 --------------- ffmpeg/libavcodec/mpegaudiodec_float.c | 30 +- ffmpeg/libavcodec/mpegaudiodecheader.c | 1 - ffmpeg/libavcodec/mpegaudiodsp.c | 5 +- ffmpeg/libavcodec/mpegaudiodsp.h | 10 +- ffmpeg/libavcodec/mpegaudiodsp_fixed.c | 10 +- ffmpeg/libavcodec/mpegaudiodsp_float.c | 10 +- ffmpeg/libavcodec/mpegaudiodsp_template.c | 9 +- ffmpeg/libavcodec/mpegaudioenc.c | 788 ------ ffmpeg/libavcodec/mpegaudiotab.h | 14 - ffmpeg/libavcodec/mpegvideo.c | 416 ++- ffmpeg/libavcodec/mpegvideo.h | 118 +- ffmpeg/libavcodec/mpegvideo_enc.c | 343 ++- ffmpeg/libavcodec/mpegvideo_motion.c | 1100 ++++---- ffmpeg/libavcodec/mpegvideo_parser.c | 17 +- ffmpeg/libavcodec/mpegvideo_xvmc.c | 52 +- ffmpeg/libavcodec/mqc.c | 147 +- ffmpeg/libavcodec/mqc.h | 35 +- ffmpeg/libavcodec/mqcdec.c | 22 +- ffmpeg/libavcodec/msgsmdec.c | 6 +- ffmpeg/libavcodec/msgsmdec.h | 2 +- ffmpeg/libavcodec/msmpeg4.c | 957 +------ ffmpeg/libavcodec/msmpeg4data.c | 10 +- ffmpeg/libavcodec/msmpeg4enc.c | 4 +- ffmpeg/libavcodec/msrle.c | 26 +- ffmpeg/libavcodec/msrledec.c | 10 +- ffmpeg/libavcodec/mss1.c | 38 +- ffmpeg/libavcodec/mss2.c | 50 +- ffmpeg/libavcodec/mss3.c | 65 +- ffmpeg/libavcodec/mss4.c | 68 +- ffmpeg/libavcodec/msvideo1.c | 26 +- ffmpeg/libavcodec/msvideo1enc.c | 32 +- ffmpeg/libavcodec/mvcdec.c | 9 +- ffmpeg/libavcodec/mxpegdec.c | 51 +- ffmpeg/libavcodec/nellymoserdec.c | 2 +- ffmpeg/libavcodec/nellymoserenc.c | 2 +- ffmpeg/libavcodec/noise_bsf.c | 8 +- ffmpeg/libavcodec/nuv.c | 56 +- ffmpeg/libavcodec/old_codec_ids.h | 2 + ffmpeg/libavcodec/options.c | 39 +- ffmpeg/libavcodec/options_table.h | 43 +- ffmpeg/libavcodec/os2threads.h | 162 -- ffmpeg/libavcodec/paf.c | 63 +- ffmpeg/libavcodec/pamenc.c | 54 +- ffmpeg/libavcodec/parser.c | 17 +- ffmpeg/libavcodec/pcm-mpeg.c | 312 --- ffmpeg/libavcodec/pcm.c | 60 +- ffmpeg/libavcodec/pcx.c | 133 +- ffmpeg/libavcodec/pcxenc.c | 34 +- ffmpeg/libavcodec/pgssubdec.c | 32 +- ffmpeg/libavcodec/pictordec.c | 19 +- ffmpeg/libavcodec/png_parser.c | 49 +- ffmpeg/libavcodec/pngdec.c | 122 +- ffmpeg/libavcodec/pngdsp.c | 5 +- ffmpeg/libavcodec/pngenc.c | 73 +- ffmpeg/libavcodec/pnm.c | 28 +- ffmpeg/libavcodec/pnm.h | 2 - ffmpeg/libavcodec/pnmdec.c | 55 +- ffmpeg/libavcodec/pnmenc.c | 82 +- ffmpeg/libavcodec/ppc/Makefile | 22 +- ffmpeg/libavcodec/ppc/dsputil_ppc.c | 5 +- ffmpeg/libavcodec/ppc/fdct_altivec.c | 2 - ffmpeg/libavcodec/ppc/fft_altivec.c | 25 +- ffmpeg/libavcodec/ppc/fmtconvert_altivec.c | 21 +- ffmpeg/libavcodec/ppc/gmc_altivec.c | 4 +- ffmpeg/libavcodec/ppc/h264_altivec.c | 748 ------ ffmpeg/libavcodec/ppc/h264_qpel.c | 317 --- ffmpeg/libavcodec/ppc/h264_qpel_template.c | 507 ---- ffmpeg/libavcodec/ppc/h264chroma_init.c | 10 +- ffmpeg/libavcodec/ppc/hpeldsp_altivec.c | 37 +- ffmpeg/libavcodec/ppc/int_altivec.c | 8 +- ffmpeg/libavcodec/ppc/mpegaudiodec_altivec.c | 130 - ffmpeg/libavcodec/ppc/mpegvideo_altivec.c | 14 +- ffmpeg/libavcodec/ppc/vc1dsp_altivec.c | 9 +- ffmpeg/libavcodec/ppc/vorbisdsp_altivec.c | 7 +- ffmpeg/libavcodec/ppc/vp3dsp_altivec.c | 16 +- ffmpeg/libavcodec/ppc/vp8dsp_altivec.c | 57 +- ffmpeg/libavcodec/proresdata.c | 8 +- ffmpeg/libavcodec/proresdec.h | 1 + ffmpeg/libavcodec/proresdec2.c | 235 +- ffmpeg/libavcodec/proresdec_lgpl.c | 219 +- ffmpeg/libavcodec/proresdsp.c | 17 +- ffmpeg/libavcodec/proresenc_anatoliy.c | 10 +- ffmpeg/libavcodec/proresenc_kostya.c | 257 +- ffmpeg/libavcodec/psymodel.c | 2 +- ffmpeg/libavcodec/pthread.c | 1064 +------- ffmpeg/libavcodec/ptx.c | 7 +- ffmpeg/libavcodec/put_bits.h | 8 + ffmpeg/libavcodec/qcelpdec.c | 18 +- ffmpeg/libavcodec/qdm2.c | 735 +++--- ffmpeg/libavcodec/qdrw.c | 2 +- ffmpeg/libavcodec/qpeg.c | 56 +- ffmpeg/libavcodec/qtrle.c | 97 +- ffmpeg/libavcodec/qtrleenc.c | 46 +- ffmpeg/libavcodec/r210dec.c | 6 +- ffmpeg/libavcodec/r210enc.c | 8 +- ffmpeg/libavcodec/ra144.c | 14 +- ffmpeg/libavcodec/ra144.h | 6 +- ffmpeg/libavcodec/ra144dec.c | 12 +- ffmpeg/libavcodec/ra144enc.c | 7 +- ffmpeg/libavcodec/ra288.c | 10 +- ffmpeg/libavcodec/ralf.c | 13 +- ffmpeg/libavcodec/ralfdata.h | 8 +- ffmpeg/libavcodec/rangecoder.c | 6 +- ffmpeg/libavcodec/ratecontrol.c | 10 +- ffmpeg/libavcodec/raw.c | 12 + ffmpeg/libavcodec/rawdec.c | 55 +- ffmpeg/libavcodec/rawenc.c | 2 +- ffmpeg/libavcodec/rdft.c | 4 +- ffmpeg/libavcodec/remove_extradata_bsf.c | 5 +- ffmpeg/libavcodec/rl2.c | 2 +- ffmpeg/libavcodec/roqaudioenc.c | 2 +- ffmpeg/libavcodec/roqvideo.h | 1 - ffmpeg/libavcodec/roqvideodec.c | 2 +- ffmpeg/libavcodec/roqvideoenc.c | 11 +- ffmpeg/libavcodec/rpza.c | 28 +- ffmpeg/libavcodec/rtjpeg.c | 13 +- ffmpeg/libavcodec/rv10.c | 632 ++--- ffmpeg/libavcodec/rv10enc.c | 2 +- ffmpeg/libavcodec/rv20enc.c | 2 +- ffmpeg/libavcodec/rv30.c | 8 +- ffmpeg/libavcodec/rv30dsp.c | 12 +- ffmpeg/libavcodec/rv34.c | 43 +- ffmpeg/libavcodec/rv34_parser.c | 8 +- ffmpeg/libavcodec/rv34dsp.c | 8 +- ffmpeg/libavcodec/rv34dsp.h | 8 +- ffmpeg/libavcodec/rv40.c | 8 +- ffmpeg/libavcodec/rv40dsp.c | 10 +- ffmpeg/libavcodec/s302m.c | 14 +- ffmpeg/libavcodec/s3tc.c | 2 +- ffmpeg/libavcodec/sanm.c | 22 +- ffmpeg/libavcodec/sbrdsp.c | 73 +- ffmpeg/libavcodec/sbrdsp.h | 8 +- ffmpeg/libavcodec/sgidec.c | 33 +- ffmpeg/libavcodec/sgienc.c | 30 +- ffmpeg/libavcodec/sgirledec.c | 10 +- ffmpeg/libavcodec/sh4/Makefile | 7 +- ffmpeg/libavcodec/sh4/dsputil_align.c | 312 --- ffmpeg/libavcodec/sh4/dsputil_sh4.c | 5 +- ffmpeg/libavcodec/sh4/dsputil_sh4.h | 6 - ffmpeg/libavcodec/sh4/h264chroma_init.c | 132 - ffmpeg/libavcodec/sh4/hpeldsp.c | 347 --- ffmpeg/libavcodec/sh4/qpel.c | 862 ------- ffmpeg/libavcodec/shorten.c | 78 +- ffmpeg/libavcodec/simple_idct.c | 4 + ffmpeg/libavcodec/simple_idct.h | 5 + ffmpeg/libavcodec/simple_idct_template.c | 16 +- ffmpeg/libavcodec/sipr.c | 4 +- ffmpeg/libavcodec/sipr16k.c | 4 +- ffmpeg/libavcodec/smacker.c | 198 +- ffmpeg/libavcodec/smc.c | 24 +- ffmpeg/libavcodec/snow.c | 111 +- ffmpeg/libavcodec/snow.h | 17 +- ffmpeg/libavcodec/snowdec.c | 68 +- ffmpeg/libavcodec/snowenc.c | 326 +-- ffmpeg/libavcodec/sonic.c | 337 ++- ffmpeg/libavcodec/sp5xdec.c | 4 +- ffmpeg/libavcodec/sparc/dsputil_vis.c | 22 - ffmpeg/libavcodec/sparc/hpeldsp_vis.c | 23 +- ffmpeg/libavcodec/sparc/vis.h | 105 +- ffmpeg/libavcodec/srtdec.c | 3 +- ffmpeg/libavcodec/srtenc.c | 48 +- ffmpeg/libavcodec/sunrast.c | 12 +- ffmpeg/libavcodec/sunrast.h | 8 +- ffmpeg/libavcodec/sunrastenc.c | 21 +- ffmpeg/libavcodec/svq1dec.c | 52 +- ffmpeg/libavcodec/svq1enc.c | 119 +- ffmpeg/libavcodec/svq3.c | 83 +- ffmpeg/libavcodec/tableprint.h | 14 +- ffmpeg/libavcodec/tak.c | 21 +- ffmpeg/libavcodec/tak.h | 2 - ffmpeg/libavcodec/tak_parser.c | 8 +- ffmpeg/libavcodec/takdec.c | 68 +- ffmpeg/libavcodec/targa.c | 8 +- ffmpeg/libavcodec/targa_y216dec.c | 9 +- ffmpeg/libavcodec/targaenc.c | 24 +- ffmpeg/libavcodec/textdec.c | 53 +- ffmpeg/libavcodec/thread.h | 15 + ffmpeg/libavcodec/tiertexseqv.c | 30 +- ffmpeg/libavcodec/tiff.c | 627 ++--- ffmpeg/libavcodec/tiff.h | 110 +- ffmpeg/libavcodec/tiff_data.c | 8 +- ffmpeg/libavcodec/tiff_data.h | 8 +- ffmpeg/libavcodec/tiffenc.c | 320 +-- ffmpeg/libavcodec/timecode.c | 150 -- ffmpeg/libavcodec/timecode.h | 106 - ffmpeg/libavcodec/tmv.c | 2 +- ffmpeg/libavcodec/truemotion1.c | 78 +- ffmpeg/libavcodec/truemotion2.c | 73 +- ffmpeg/libavcodec/truespeech.c | 2 +- ffmpeg/libavcodec/tscc.c | 2 +- ffmpeg/libavcodec/tscc2.c | 44 +- ffmpeg/libavcodec/tta.c | 207 +- ffmpeg/libavcodec/twinvq.c | 974 +++---- ffmpeg/libavcodec/twinvq_data.h | 325 +-- ffmpeg/libavcodec/txd.c | 7 +- ffmpeg/libavcodec/ulti.c | 26 +- ffmpeg/libavcodec/utils.c | 871 +++++-- ffmpeg/libavcodec/utvideodec.c | 16 +- ffmpeg/libavcodec/utvideoenc.c | 27 +- ffmpeg/libavcodec/v210dec.c | 9 +- ffmpeg/libavcodec/v210dec.h | 8 +- ffmpeg/libavcodec/v210enc.c | 4 +- ffmpeg/libavcodec/v210x.c | 2 +- ffmpeg/libavcodec/v308dec.c | 10 +- ffmpeg/libavcodec/v308enc.c | 4 +- ffmpeg/libavcodec/v408dec.c | 12 +- ffmpeg/libavcodec/v408enc.c | 6 +- ffmpeg/libavcodec/v410dec.c | 2 +- ffmpeg/libavcodec/v410enc.c | 4 +- ffmpeg/libavcodec/vaapi.c | 25 +- ffmpeg/libavcodec/vaapi_mpeg2.c | 4 +- ffmpeg/libavcodec/vaapi_mpeg4.c | 35 +- ffmpeg/libavcodec/vaapi_vc1.c | 2 +- ffmpeg/libavcodec/vb.c | 2 +- ffmpeg/libavcodec/vble.c | 2 +- ffmpeg/libavcodec/vc1.c | 187 +- ffmpeg/libavcodec/vc1.h | 29 +- ffmpeg/libavcodec/vc1_parser.c | 17 +- ffmpeg/libavcodec/vc1dec.c | 647 +++-- ffmpeg/libavcodec/vc1dsp.c | 27 +- ffmpeg/libavcodec/vc1dsp.h | 4 +- ffmpeg/libavcodec/vcr1.c | 23 +- ffmpeg/libavcodec/vda.h | 11 + ffmpeg/libavcodec/vda_h264.c | 36 +- ffmpeg/libavcodec/vda_h264_dec.c | 133 +- ffmpeg/libavcodec/vdpau.c | 116 +- ffmpeg/libavcodec/vdpau.h | 72 +- ffmpeg/libavcodec/vdpau_h264.c | 38 +- ffmpeg/libavcodec/vdpau_internal.h | 50 +- ffmpeg/libavcodec/vdpau_mpeg12.c | 21 +- ffmpeg/libavcodec/vdpau_mpeg4.c | 17 +- ffmpeg/libavcodec/vdpau_vc1.c | 26 +- ffmpeg/libavcodec/version.h | 76 +- ffmpeg/libavcodec/videodsp.c | 3 +- ffmpeg/libavcodec/videodsp.h | 29 +- ffmpeg/libavcodec/videodsp_template.c | 32 +- ffmpeg/libavcodec/vima.c | 30 +- ffmpeg/libavcodec/vmdav.c | 405 +-- ffmpeg/libavcodec/vmnc.c | 482 ++-- ffmpeg/libavcodec/vorbis_parser.c | 34 +- ffmpeg/libavcodec/vorbis_parser.h | 26 +- ffmpeg/libavcodec/vorbisdec.c | 84 +- ffmpeg/libavcodec/vorbisdsp.c | 11 +- ffmpeg/libavcodec/vorbisenc.c | 22 +- ffmpeg/libavcodec/vp3.c | 50 +- ffmpeg/libavcodec/vp3dsp.c | 4 +- ffmpeg/libavcodec/vp5.c | 7 +- ffmpeg/libavcodec/vp56.c | 65 +- ffmpeg/libavcodec/vp56.h | 27 +- ffmpeg/libavcodec/vp56data.c | 186 ++ ffmpeg/libavcodec/vp56data.h | 221 +- ffmpeg/libavcodec/vp56dsp.c | 12 +- ffmpeg/libavcodec/vp56dsp.h | 4 +- ffmpeg/libavcodec/vp6.c | 37 +- ffmpeg/libavcodec/vp6data.h | 4 +- ffmpeg/libavcodec/vp8.c | 99 +- ffmpeg/libavcodec/vp8.h | 16 +- ffmpeg/libavcodec/vp8dsp.c | 38 +- ffmpeg/libavcodec/vp8dsp.h | 2 +- ffmpeg/libavcodec/vqavideo.c | 19 +- ffmpeg/libavcodec/w32pthreads.h | 272 -- ffmpeg/libavcodec/wavpack.c | 819 +++--- ffmpeg/libavcodec/wma.c | 11 +- ffmpeg/libavcodec/wma_common.c | 8 +- ffmpeg/libavcodec/wmadec.c | 13 +- ffmpeg/libavcodec/wmaenc.c | 15 +- ffmpeg/libavcodec/wmalosslessdec.c | 57 +- ffmpeg/libavcodec/wmaprodec.c | 36 +- ffmpeg/libavcodec/wmavoice.c | 94 +- ffmpeg/libavcodec/wmv2.c | 27 +- ffmpeg/libavcodec/wmv2dec.c | 4 +- ffmpeg/libavcodec/wmv2enc.c | 9 +- ffmpeg/libavcodec/wnv1.c | 11 +- ffmpeg/libavcodec/ws-snd1.c | 2 +- ffmpeg/libavcodec/x86/Makefile | 63 +- ffmpeg/libavcodec/x86/ac3dsp.asm | 36 - ffmpeg/libavcodec/x86/ac3dsp_init.c | 85 +- ffmpeg/libavcodec/x86/cabac.h | 84 +- ffmpeg/libavcodec/x86/cavsdsp.c | 132 +- ffmpeg/libavcodec/x86/constants.c | 14 + ffmpeg/libavcodec/x86/dirac_dwt.c | 2 +- ffmpeg/libavcodec/x86/diracdsp_mmx.c | 2 +- ffmpeg/libavcodec/x86/dnxhdenc.c | 3 +- ffmpeg/libavcodec/x86/dsputil.asm | 13 +- ffmpeg/libavcodec/x86/dsputil_mmx.c | 1064 +------- ffmpeg/libavcodec/x86/dsputil_mmx.h | 113 - ffmpeg/libavcodec/x86/dsputil_qns_template.c | 2 +- ffmpeg/libavcodec/x86/dsputil_rnd_template.c | 221 -- ffmpeg/libavcodec/x86/dsputilenc_mmx.c | 115 +- ffmpeg/libavcodec/x86/fdct.c | 12 +- ffmpeg/libavcodec/x86/fft.asm | 7 +- ffmpeg/libavcodec/x86/fft.h | 3 - ffmpeg/libavcodec/x86/fft_init.c | 27 +- ffmpeg/libavcodec/x86/fmtconvert.asm | 2 +- ffmpeg/libavcodec/x86/fmtconvert_init.c | 53 +- ffmpeg/libavcodec/x86/fpelbase.asm | 106 - ffmpeg/libavcodec/x86/h264_chromamc_10bit.asm | 8 +- ffmpeg/libavcodec/x86/h264_deblock.asm | 19 +- ffmpeg/libavcodec/x86/h264_deblock_10bit.asm | 8 +- ffmpeg/libavcodec/x86/h264_idct.asm | 83 +- ffmpeg/libavcodec/x86/h264_idct_10bit.asm | 8 +- ffmpeg/libavcodec/x86/h264_intrapred.asm | 5 +- ffmpeg/libavcodec/x86/h264_intrapred_10bit.asm | 8 +- ffmpeg/libavcodec/x86/h264_intrapred_init.c | 22 +- ffmpeg/libavcodec/x86/h264_qpel.c | 60 +- ffmpeg/libavcodec/x86/h264_qpel_10bit.asm | 8 +- ffmpeg/libavcodec/x86/h264_weight_10bit.asm | 8 +- ffmpeg/libavcodec/x86/h264chroma_init.c | 19 +- ffmpeg/libavcodec/x86/h264dsp_init.c | 254 +- ffmpeg/libavcodec/x86/hpeldsp.asm | 26 +- ffmpeg/libavcodec/x86/hpeldsp_avg_template.c | 77 - ffmpeg/libavcodec/x86/hpeldsp_init.c | 286 +- ffmpeg/libavcodec/x86/hpeldsp_rnd_template.c | 242 +- ffmpeg/libavcodec/x86/idct_mmx_xvid.c | 34 +- ffmpeg/libavcodec/x86/idct_sse2_xvid.c | 6 +- ffmpeg/libavcodec/x86/lpc.c | 25 +- ffmpeg/libavcodec/x86/mathops.h | 8 +- ffmpeg/libavcodec/x86/mlpdsp.c | 6 +- ffmpeg/libavcodec/x86/motion_est.c | 11 +- ffmpeg/libavcodec/x86/mpegaudiodec.c | 273 -- ffmpeg/libavcodec/x86/mpegvideo.c | 155 +- ffmpeg/libavcodec/x86/mpegvideoenc.c | 135 +- ffmpeg/libavcodec/x86/mpegvideoenc_template.c | 4 +- ffmpeg/libavcodec/x86/pngdsp.asm | 8 +- ffmpeg/libavcodec/x86/pngdsp_init.c | 10 +- ffmpeg/libavcodec/x86/proresdsp_init.c | 11 +- ffmpeg/libavcodec/x86/qpelbase.asm | 176 -- ffmpeg/libavcodec/x86/rv34dsp.asm | 8 +- ffmpeg/libavcodec/x86/rv34dsp_init.c | 16 +- ffmpeg/libavcodec/x86/rv40dsp.asm | 14 +- ffmpeg/libavcodec/x86/rv40dsp_init.c | 65 +- ffmpeg/libavcodec/x86/sbrdsp.asm | 211 +- ffmpeg/libavcodec/x86/sbrdsp_init.c | 40 +- ffmpeg/libavcodec/x86/simple_idct.c | 4 +- ffmpeg/libavcodec/x86/snowdsp.c | 2 +- ffmpeg/libavcodec/x86/v210.asm | 8 +- ffmpeg/libavcodec/x86/vc1dsp_init.c | 25 +- ffmpeg/libavcodec/x86/vc1dsp_mmx.c | 93 +- ffmpeg/libavcodec/x86/videodsp.asm | 852 +++--- ffmpeg/libavcodec/x86/videodsp_init.c | 212 +- ffmpeg/libavcodec/x86/vorbisdsp_init.c | 7 +- ffmpeg/libavcodec/x86/vp3dsp.asm | 2 +- ffmpeg/libavcodec/x86/vp3dsp_init.c | 16 +- ffmpeg/libavcodec/x86/vp56dsp.asm | 170 -- ffmpeg/libavcodec/x86/vp56dsp_init.c | 48 - ffmpeg/libavcodec/x86/vp8dsp.asm | 1555 ----------- ffmpeg/libavcodec/x86/vp8dsp_init.c | 293 ++- ffmpeg/libavcodec/x86/w64xmmtest.c | 14 +- ffmpeg/libavcodec/xan.c | 150 +- ffmpeg/libavcodec/xbmdec.c | 14 +- ffmpeg/libavcodec/xbmenc.c | 21 +- ffmpeg/libavcodec/xfacedec.c | 2 +- ffmpeg/libavcodec/xfaceenc.c | 4 +- ffmpeg/libavcodec/xl.c | 43 +- ffmpeg/libavcodec/xsubdec.c | 2 +- ffmpeg/libavcodec/xsubenc.c | 10 +- ffmpeg/libavcodec/xvmc.h | 4 +- ffmpeg/libavcodec/xvmc_internal.h | 4 +- ffmpeg/libavcodec/xwddec.c | 4 +- ffmpeg/libavcodec/xwdenc.c | 31 +- ffmpeg/libavcodec/xxan.c | 89 +- ffmpeg/libavcodec/y41pdec.c | 9 +- ffmpeg/libavcodec/y41penc.c | 4 +- ffmpeg/libavcodec/yop.c | 24 +- ffmpeg/libavcodec/yuv4dec.c | 9 +- ffmpeg/libavcodec/yuv4enc.c | 4 +- ffmpeg/libavcodec/zerocodec.c | 18 +- ffmpeg/libavcodec/zmbv.c | 14 +- ffmpeg/libavcodec/zmbvenc.c | 48 +- 821 files changed, 32057 insertions(+), 42871 deletions(-) delete mode 100644 ffmpeg/libavcodec/aacpsy.h delete mode 100644 ffmpeg/libavcodec/arm/vp56dsp_init_arm.c delete mode 100644 ffmpeg/libavcodec/arm/vp56dsp_neon.S delete mode 100644 ffmpeg/libavcodec/cavsdata.h delete mode 100644 ffmpeg/libavcodec/dca_parser.h delete mode 100644 ffmpeg/libavcodec/dct32.c delete mode 100644 ffmpeg/libavcodec/dv_vlc_data.h delete mode 100644 ffmpeg/libavcodec/fft.c delete mode 100644 ffmpeg/libavcodec/h261data.h delete mode 100644 ffmpeg/libavcodec/j2k.c delete mode 100644 ffmpeg/libavcodec/j2k.h delete mode 100644 ffmpeg/libavcodec/j2k_dwt.c delete mode 100644 ffmpeg/libavcodec/j2k_dwt.h delete mode 100644 ffmpeg/libavcodec/j2kdec.c delete mode 100644 ffmpeg/libavcodec/mdct.c delete mode 100644 ffmpeg/libavcodec/mips/fft_init_table.c delete mode 100644 ffmpeg/libavcodec/mips/fft_table.h delete mode 100644 ffmpeg/libavcodec/mp3_header_compress_bsf.c delete mode 100644 ffmpeg/libavcodec/mpeg12decdata.h delete mode 100644 ffmpeg/libavcodec/mpegaudiodec.c delete mode 100644 ffmpeg/libavcodec/mpegaudioenc.c delete mode 100644 ffmpeg/libavcodec/os2threads.h delete mode 100644 ffmpeg/libavcodec/pcm-mpeg.c delete mode 100644 ffmpeg/libavcodec/ppc/h264_altivec.c delete mode 100644 ffmpeg/libavcodec/ppc/h264_qpel.c delete mode 100644 ffmpeg/libavcodec/ppc/h264_qpel_template.c delete mode 100644 ffmpeg/libavcodec/ppc/mpegaudiodec_altivec.c delete mode 100644 ffmpeg/libavcodec/sh4/dsputil_align.c delete mode 100644 ffmpeg/libavcodec/sh4/h264chroma_init.c delete mode 100644 ffmpeg/libavcodec/sh4/hpeldsp.c delete mode 100644 ffmpeg/libavcodec/sh4/qpel.c delete mode 100644 ffmpeg/libavcodec/timecode.c delete mode 100644 ffmpeg/libavcodec/timecode.h delete mode 100644 ffmpeg/libavcodec/w32pthreads.h delete mode 100644 ffmpeg/libavcodec/x86/dsputil_mmx.h delete mode 100644 ffmpeg/libavcodec/x86/dsputil_rnd_template.c delete mode 100644 ffmpeg/libavcodec/x86/fpelbase.asm delete mode 100644 ffmpeg/libavcodec/x86/hpeldsp_avg_template.c delete mode 100644 ffmpeg/libavcodec/x86/mpegaudiodec.c delete mode 100644 ffmpeg/libavcodec/x86/qpelbase.asm delete mode 100644 ffmpeg/libavcodec/x86/vp56dsp.asm delete mode 100644 ffmpeg/libavcodec/x86/vp56dsp_init.c (limited to 'ffmpeg/libavcodec') diff --git a/ffmpeg/libavcodec/012v.c b/ffmpeg/libavcodec/012v.c index 58e3cd6..c2b6a35 100644 --- a/ffmpeg/libavcodec/012v.c +++ b/ffmpeg/libavcodec/012v.c @@ -49,6 +49,12 @@ static int zero12v_decode_frame(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_ERROR, "Width 1 not supported.\n"); return AVERROR_INVALIDDATA; } + + if ( avctx->codec_tag == MKTAG('0', '1', '2', 'v') + && avpkt->size % avctx->height == 0 + && avpkt->size / avctx->height * 3 >= width * 8) + stride = avpkt->size / avctx->height; + if (avpkt->size < avctx->height * stride) { av_log(avctx, AV_LOG_ERROR, "Packet too small: %d instead of %d\n", avpkt->size, avctx->height * stride); @@ -144,10 +150,10 @@ static int zero12v_decode_frame(AVCodecContext *avctx, void *data, AVCodec ff_zero12v_decoder = { .name = "012v", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_012V, .init = zero12v_decode_init, .decode = zero12v_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"), }; diff --git a/ffmpeg/libavcodec/4xm.c b/ffmpeg/libavcodec/4xm.c index cd22aa4..eb07cc3 100644 --- a/ffmpeg/libavcodec/4xm.c +++ b/ffmpeg/libavcodec/4xm.c @@ -24,6 +24,7 @@ * 4XM codec. */ +#include "libavutil/avassert.h" #include "libavutil/frame.h" #include "libavutil/intreadwrite.h" #include "avcodec.h" @@ -32,7 +33,6 @@ #include "get_bits.h" #include "internal.h" -#include "libavutil/avassert.h" #define BLOCK_TYPE_VLC_BITS 5 #define ACDC_VLC_BITS 9 @@ -329,12 +329,12 @@ static inline void mcdc(uint16_t *dst, const uint16_t *src, int log2w, } break; default: - av_assert2(0); + av_assert0(0); } } -static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, - int log2w, int log2h, int stride) +static int decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, + int log2w, int log2h, int stride) { const int index = size2index[log2h][log2w]; const int h = 1 << log2h; @@ -343,57 +343,30 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, BLOCK_TYPE_VLC_BITS, 1); uint16_t *start = (uint16_t *)f->last_picture->data[0]; uint16_t *end = start + stride * (f->avctx->height - h + 1) - (1 << log2w); + int ret; + int scale = 1; + unsigned dc = 0; - av_assert2(code >= 0 && code <= 6); + av_assert0(code >= 0 && code <= 6 && log2w >= 0); - if (code == 0) { - if (bytestream2_get_bytes_left(&f->g) < 1) { - av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n"); - return; - } - src += f->mv[bytestream2_get_byteu(&f->g)]; - if (start > src || src > end) { - av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); - return; - } - mcdc(dst, src, log2w, h, stride, 1, 0); - } else if (code == 1) { + if (code == 1) { log2h--; - decode_p_block(f, dst, src, log2w, log2h, stride); - decode_p_block(f, dst + (stride << log2h), - src + (stride << log2h), log2w, log2h, stride); + if ((ret = decode_p_block(f, dst, src, log2w, log2h, stride)) < 0) + return ret; + return decode_p_block(f, dst + (stride << log2h), + src + (stride << log2h), + log2w, log2h, stride); } else if (code == 2) { log2w--; - decode_p_block(f, dst , src, log2w, log2h, stride); - decode_p_block(f, dst + (1 << log2w), - src + (1 << log2w), log2w, log2h, stride); - } else if (code == 3 && f->version < 2) { - mcdc(dst, src, log2w, h, stride, 1, 0); - } else if (code == 4) { - if (bytestream2_get_bytes_left(&f->g) < 1) { - av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n"); - return; - } - src += f->mv[bytestream2_get_byteu(&f->g)]; - if (start > src || src > end) { - av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); - return; - } - if (bytestream2_get_bytes_left(&f->g2) < 2){ - av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n"); - return; - } - mcdc(dst, src, log2w, h, stride, 1, bytestream2_get_le16u(&f->g2)); - } else if (code == 5) { - if (bytestream2_get_bytes_left(&f->g2) < 2) { - av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n"); - return; - } - mcdc(dst, src, log2w, h, stride, 0, bytestream2_get_le16u(&f->g2)); + if ((ret = decode_p_block(f, dst , src, log2w, log2h, stride)) < 0) + return ret; + return decode_p_block(f, dst + (1 << log2w), + src + (1 << log2w), + log2w, log2h, stride); } else if (code == 6) { if (bytestream2_get_bytes_left(&f->g2) < 4) { av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n"); - return; + return AVERROR_INVALIDDATA; } if (log2w) { dst[0] = bytestream2_get_le16u(&f->g2); @@ -402,7 +375,43 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, dst[0] = bytestream2_get_le16u(&f->g2); dst[stride] = bytestream2_get_le16u(&f->g2); } + return 0; + } + + if ((code&3)==0 && bytestream2_get_bytes_left(&f->g) < 1) { + av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n"); + return AVERROR_INVALIDDATA; + } + + if (code == 0) { + src += f->mv[bytestream2_get_byte(&f->g)]; + } else if (code == 3 && f->version >= 2) { + return 0; + } else if (code == 4) { + src += f->mv[bytestream2_get_byte(&f->g)]; + if (bytestream2_get_bytes_left(&f->g2) < 2){ + av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n"); + return AVERROR_INVALIDDATA; + } + dc = bytestream2_get_le16(&f->g2); + } else if (code == 5) { + if (bytestream2_get_bytes_left(&f->g2) < 2){ + av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n"); + return AVERROR_INVALIDDATA; + } + av_assert0(start <= src && src <= end); + scale = 0; + dc = bytestream2_get_le16(&f->g2); } + + if (start > src || src > end) { + av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); + return AVERROR_INVALIDDATA; + } + + mcdc(dst, src, log2w, h, stride, scale, dc); + + return 0; } static int decode_p_frame(FourXContext *f, AVFrame *frame, @@ -411,16 +420,28 @@ static int decode_p_frame(FourXContext *f, AVFrame *frame, int x, y; const int width = f->avctx->width; const int height = f->avctx->height; - uint16_t *src = (uint16_t *)f->last_picture->data[0]; uint16_t *dst = (uint16_t *)frame->data[0]; const int stride = frame->linesize[0] >> 1; + uint16_t *src; unsigned int bitstream_size, bytestream_size, wordstream_size, extra, bytestream_offset, wordstream_offset; + int ret; + + if (!f->last_picture->data[0]) { + if ((ret = ff_get_buffer(f->avctx, f->last_picture, + AV_GET_BUFFER_FLAG_REF)) < 0) { + return ret; + } + for (y=0; yavctx->height; y++) + memset(f->last_picture->data[0] + y*f->last_picture->linesize[0], 0, 2*f->avctx->width); + } + + src = (uint16_t *)f->last_picture->data[0]; if (f->version > 1) { extra = 20; if (length < extra) - return -1; + return AVERROR_INVALIDDATA; bitstream_size = AV_RL32(buf + 8); wordstream_size = AV_RL32(buf + 12); bytestream_size = AV_RL32(buf + 16); @@ -440,14 +461,12 @@ static int decode_p_frame(FourXContext *f, AVFrame *frame, return AVERROR_INVALIDDATA; } - av_fast_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size, - bitstream_size + FF_INPUT_BUFFER_PADDING_SIZE); + av_fast_padded_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size, + bitstream_size); if (!f->bitstream_buffer) return AVERROR(ENOMEM); f->dsp.bswap_buf(f->bitstream_buffer, (const uint32_t*)(buf + extra), bitstream_size / 4); - memset((uint8_t*)f->bitstream_buffer + bitstream_size, - 0, FF_INPUT_BUFFER_PADDING_SIZE); init_get_bits(&f->gb, f->bitstream_buffer, 8 * bitstream_size); wordstream_offset = extra + bitstream_size; @@ -461,7 +480,8 @@ static int decode_p_frame(FourXContext *f, AVFrame *frame, for (y = 0; y < height; y += 8) { for (x = 0; x < width; x += 8) - decode_p_block(f, dst + x, src + x, 3, 3, stride); + if ((ret = decode_p_block(f, dst + x, src + x, 3, 3, stride)) < 0) + return ret; src += 8 * stride; dst += 8 * stride; } @@ -484,8 +504,10 @@ static int decode_i_block(FourXContext *f, int16_t *block) /* DC coef */ val = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3); - if (val >> 4) + if (val >> 4) { av_log(f->avctx, AV_LOG_ERROR, "error dc run != 0\n"); + return AVERROR_INVALIDDATA; + } if (val) val = get_xbits(&f->gb, val); @@ -503,7 +525,12 @@ static int decode_i_block(FourXContext *f, int16_t *block) if (code == 0xf0) { i += 16; } else { - level = get_xbits(&f->gb, code & 0xf); + if (code & 0xf) { + level = get_xbits(&f->gb, code & 0xf); + } else { + av_log(f->avctx, AV_LOG_ERROR, "0 coeff\n"); + return AVERROR_INVALIDDATA; + } i += code >> 4; if (i >= 64) { av_log(f->avctx, AV_LOG_ERROR, "run %d oveflow\n", i); @@ -582,7 +609,8 @@ static int decode_i_mb(FourXContext *f) } static const uint8_t *read_huffman_tables(FourXContext *f, - const uint8_t * const buf, int buf_size) + const uint8_t * const buf, + int buf_size) { int frequency[512] = { 0 }; uint8_t flag[512]; @@ -605,6 +633,7 @@ static const uint8_t *read_huffman_tables(FourXContext *f, av_log(f->avctx, AV_LOG_ERROR, "invalid data in read_huffman_tables\n"); return NULL; } + for (i = start; i <= end; i++) frequency[i] = *ptr++; start = *ptr++; @@ -711,9 +740,9 @@ static int decode_i2_frame(FourXContext *f, AVFrame *frame, const uint8_t *buf, color[1] = bytestream2_get_le16u(&g3); if (color[0] & 0x8000) - av_log(NULL, AV_LOG_ERROR, "unk bit 1\n"); + av_log(f->avctx, AV_LOG_ERROR, "unk bit 1\n"); if (color[1] & 0x8000) - av_log(NULL, AV_LOG_ERROR, "unk bit 2\n"); + av_log(f->avctx, AV_LOG_ERROR, "unk bit 2\n"); color[2] = mix(color[0], color[1]); color[3] = mix(color[1], color[0]); @@ -742,7 +771,10 @@ static int decode_i_frame(FourXContext *f, AVFrame *frame, const uint8_t *buf, i unsigned int prestream_size; const uint8_t *prestream; - if (bitstream_size > (1<<26) || length < bitstream_size + 12) { + if (bitstream_size > (1 << 26)) + return AVERROR_INVALIDDATA; + + if (length < bitstream_size + 12) { av_log(f->avctx, AV_LOG_ERROR, "packet size too small\n"); return AVERROR_INVALIDDATA; } @@ -751,14 +783,13 @@ static int decode_i_frame(FourXContext *f, AVFrame *frame, const uint8_t *buf, i prestream = buf + bitstream_size + 12; if (prestream_size + bitstream_size + 12 != length - || bitstream_size > (1 << 26) || prestream_size > (1 << 26)) { av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d %d\n", prestream_size, bitstream_size, length); return AVERROR_INVALIDDATA; } - prestream = read_huffman_tables(f, prestream, buf + length - prestream); + prestream = read_huffman_tables(f, prestream, prestream_size); if (!prestream) { av_log(f->avctx, AV_LOG_ERROR, "Error reading Huffman tables.\n"); return AVERROR_INVALIDDATA; @@ -770,14 +801,12 @@ static int decode_i_frame(FourXContext *f, AVFrame *frame, const uint8_t *buf, i prestream_size = length + buf - prestream; - av_fast_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size, - prestream_size + FF_INPUT_BUFFER_PADDING_SIZE); + av_fast_padded_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size, + prestream_size); if (!f->bitstream_buffer) return AVERROR(ENOMEM); f->dsp.bswap_buf(f->bitstream_buffer, (const uint32_t*)prestream, prestream_size / 4); - memset((uint8_t*)f->bitstream_buffer + prestream_size, - 0, FF_INPUT_BUFFER_PADDING_SIZE); init_get_bits(&f->pre_gb, f->bitstream_buffer, 8 * prestream_size); f->last_dc = 0 * 128 * 8 * 8; @@ -806,27 +835,35 @@ static int decode_frame(AVCodecContext *avctx, void *data, AVFrame *picture = data; int i, frame_4cc, frame_size, ret; - if (buf_size < 12) + if (buf_size < 20) return AVERROR_INVALIDDATA; - frame_4cc = AV_RL32(buf); - if (buf_size != AV_RL32(buf + 4) + 8 || buf_size < 20) + + av_assert0(avctx->width % 16 == 0 && avctx->height % 16 == 0); + + if (buf_size < AV_RL32(buf + 4) + 8) { av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d\n", buf_size, AV_RL32(buf + 4)); + return AVERROR_INVALIDDATA; + } + + frame_4cc = AV_RL32(buf); if (frame_4cc == AV_RL32("cfrm")) { int free_index = -1; + int id, whole_size; const int data_size = buf_size - 20; - const int id = AV_RL32(buf + 12); - const int whole_size = AV_RL32(buf + 16); CFrameBuffer *cfrm; - if (data_size < 0 || whole_size < 0) { - av_log(f->avctx, AV_LOG_ERROR, "sizes invalid\n"); + if (f->version <= 1) { + av_log(f->avctx, AV_LOG_ERROR, "cfrm in version %d\n", f->version); return AVERROR_INVALIDDATA; } - if (f->version <= 1) { - av_log(f->avctx, AV_LOG_ERROR, "cfrm in version %d\n", f->version); + id = AV_RL32(buf + 12); + whole_size = AV_RL32(buf + 16); + + if (data_size < 0 || whole_size < 0) { + av_log(f->avctx, AV_LOG_ERROR, "sizes invalid\n"); return AVERROR_INVALIDDATA; } @@ -870,6 +907,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %d\n", id, avctx->frame_number); + if (f->version <= 1) + return AVERROR_INVALIDDATA; + cfrm->size = cfrm->id = 0; frame_4cc = AV_RL32("pfrm"); } else @@ -900,14 +940,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, return ret; } } else if (frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")) { - if (!f->last_picture->data[0]) { - if ((ret = ff_get_buffer(avctx, f->last_picture, - AV_GET_BUFFER_FLAG_REF)) < 0) - return ret; - for (i=0; iheight; i++) - memset(f->last_picture->data[0] + i*f->last_picture->linesize[0], 0, 2*avctx->width); - } - f->current_picture->pict_type = AV_PICTURE_TYPE_P; if ((ret = decode_p_frame(f, f->current_picture, buf, frame_size)) < 0) { av_log(f->avctx, AV_LOG_ERROR, "decode p frame failed\n"); @@ -984,6 +1016,7 @@ static av_cold int decode_end(AVCodecContext *avctx) AVCodec ff_fourxm_decoder = { .name = "4xm", + .long_name = NULL_IF_CONFIG_SMALL("4X Movie"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_4XM, .priv_data_size = sizeof(FourXContext), @@ -991,5 +1024,4 @@ AVCodec ff_fourxm_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("4X Movie"), }; diff --git a/ffmpeg/libavcodec/8bps.c b/ffmpeg/libavcodec/8bps.c index a910551..1709368 100644 --- a/ffmpeg/libavcodec/8bps.c +++ b/ffmpeg/libavcodec/8bps.c @@ -64,7 +64,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, unsigned char *pixptr, *pixptr_end; unsigned int height = avctx->height; // Real image height unsigned int dlen, p, row; - const unsigned char *lp, *dp; + const unsigned char *lp, *dp, *ep; unsigned char count; unsigned int planes = c->planes; unsigned char *planemap = c->planemap; @@ -73,6 +73,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; + ep = encoded + buf_size; + /* Set data pointer after line lengths */ dp = encoded + planes * (height << 1); @@ -84,19 +86,19 @@ static int decode_frame(AVCodecContext *avctx, void *data, for (row = 0; row < height; row++) { pixptr = frame->data[0] + row * frame->linesize[0] + planemap[p]; pixptr_end = pixptr + frame->linesize[0]; - if(lp - encoded + row*2 + 1 >= buf_size) - return -1; + if (ep - lp < row * 2 + 2) + return AVERROR_INVALIDDATA; dlen = av_be2ne16(*(const unsigned short *)(lp + row * 2)); /* Decode a row of this plane */ while (dlen > 0) { - if (dp + 1 >= buf + buf_size) + if (ep - dp <= 1) return AVERROR_INVALIDDATA; if ((count = *dp++) <= 127) { count++; dlen -= count + 1; - if (pixptr + count * planes > pixptr_end) + if (pixptr_end - pixptr < count * planes) break; - if (dp + count > buf + buf_size) + if (ep - dp < count) return AVERROR_INVALIDDATA; while (count--) { *pixptr = *dp++; @@ -104,7 +106,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, } } else { count = 257 - count; - if (pixptr + count * planes > pixptr_end) + if (pixptr_end - pixptr < count * planes) break; while (count--) { *pixptr = *dp; @@ -117,7 +119,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, } } - if (avctx->bits_per_coded_sample <= 8) { + if ((avctx->bits_per_coded_sample & 0x1f) <= 8) { const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); @@ -157,17 +159,7 @@ static av_cold int decode_init(AVCodecContext *avctx) case 32: avctx->pix_fmt = AV_PIX_FMT_RGB32; c->planes = 4; -#if HAVE_BIGENDIAN - c->planemap[0] = 1; // 1st plane is red - c->planemap[1] = 2; // 2nd plane is green - c->planemap[2] = 3; // 3rd plane is blue - c->planemap[3] = 0; // 4th plane is alpha -#else - c->planemap[0] = 2; // 1st plane is red - c->planemap[1] = 1; // 2nd plane is green - c->planemap[2] = 0; // 3rd plane is blue - c->planemap[3] = 3; // 4th plane is alpha -#endif + /* handle planemap setup later for decoding rgb24 data as rbg32 */ break; default: av_log(avctx, AV_LOG_ERROR, "Error: Unsupported color depth: %u.\n", @@ -175,16 +167,22 @@ static av_cold int decode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } + if (avctx->pix_fmt == AV_PIX_FMT_RGB32) { + c->planemap[0] = HAVE_BIGENDIAN ? 1 : 2; // 1st plane is red + c->planemap[1] = HAVE_BIGENDIAN ? 2 : 1; // 2nd plane is green + c->planemap[2] = HAVE_BIGENDIAN ? 3 : 0; // 3rd plane is blue + c->planemap[3] = HAVE_BIGENDIAN ? 0 : 3; // 4th plane is alpha + } return 0; } AVCodec ff_eightbps_decoder = { .name = "8bps", + .long_name = NULL_IF_CONFIG_SMALL("QuickTime 8BPS video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_8BPS, .priv_data_size = sizeof(EightBpsContext), .init = decode_init, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("QuickTime 8BPS video"), }; diff --git a/ffmpeg/libavcodec/8svx.c b/ffmpeg/libavcodec/8svx.c index 82fda6f..eff525c 100644 --- a/ffmpeg/libavcodec/8svx.c +++ b/ffmpeg/libavcodec/8svx.c @@ -187,6 +187,7 @@ static av_cold int eightsvx_decode_close(AVCodecContext *avctx) #if CONFIG_EIGHTSVX_FIB_DECODER AVCodec ff_eightsvx_fib_decoder = { .name = "8svx_fib", + .long_name = NULL_IF_CONFIG_SMALL("8SVX fibonacci"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_8SVX_FIB, .priv_data_size = sizeof (EightSvxContext), @@ -194,7 +195,6 @@ AVCodec ff_eightsvx_fib_decoder = { .decode = eightsvx_decode_frame, .close = eightsvx_decode_close, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("8SVX fibonacci"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P, AV_SAMPLE_FMT_NONE }, }; @@ -202,6 +202,7 @@ AVCodec ff_eightsvx_fib_decoder = { #if CONFIG_EIGHTSVX_EXP_DECODER AVCodec ff_eightsvx_exp_decoder = { .name = "8svx_exp", + .long_name = NULL_IF_CONFIG_SMALL("8SVX exponential"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_8SVX_EXP, .priv_data_size = sizeof (EightSvxContext), @@ -209,7 +210,6 @@ AVCodec ff_eightsvx_exp_decoder = { .decode = eightsvx_decode_frame, .close = eightsvx_decode_close, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("8SVX exponential"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P, AV_SAMPLE_FMT_NONE }, }; diff --git a/ffmpeg/libavcodec/Makefile b/ffmpeg/libavcodec/Makefile index 0d73067..ef74f21 100644 --- a/ffmpeg/libavcodec/Makefile +++ b/ffmpeg/libavcodec/Makefile @@ -38,15 +38,17 @@ OBJS-$(CONFIG_AUDIO_FRAME_QUEUE) += audio_frame_queue.o OBJS-$(CONFIG_CRYSTALHD) += crystalhd.o OBJS-$(CONFIG_DCT) += dct.o dct32_fixed.o dct32_float.o OBJS-$(CONFIG_DXVA2) += dxva2.o -OBJS-$(CONFIG_DSPUTIL) += dsputil.o faanidct.o \ - simple_idct.o \ - jrevdct.o +OBJS-$(CONFIG_DSPUTIL) += dsputil.o faanidct.o \ + simple_idct.o jrevdct.o OBJS-$(CONFIG_ENCODERS) += faandct.o jfdctfst.o jfdctint.o OBJS-$(CONFIG_ERROR_RESILIENCE) += error_resilience.o +OBJS-$(CONFIG_EXIF) += exif.o tiff_common.o FFT-OBJS-$(CONFIG_HARDCODED_TABLES) += cos_tables.o cos_fixed_tables.o OBJS-$(CONFIG_FFT) += avfft.o fft_fixed.o fft_float.o \ + fft_fixed_32.o fft_init_table.o \ $(FFT-OBJS-yes) OBJS-$(CONFIG_GOLOMB) += golomb.o +OBJS-$(CONFIG_H263DSP) += h263dsp.o OBJS-$(CONFIG_H264CHROMA) += h264chroma.o OBJS-$(CONFIG_H264DSP) += h264dsp.o h264idct.o OBJS-$(CONFIG_H264PRED) += h264pred.o @@ -56,7 +58,7 @@ OBJS-$(CONFIG_HUFFMAN) += huffman.o OBJS-$(CONFIG_LIBXVID) += libxvid_rc.o OBJS-$(CONFIG_LPC) += lpc.o OBJS-$(CONFIG_LSP) += lsp.o -OBJS-$(CONFIG_MDCT) += mdct_fixed.o mdct_float.o +OBJS-$(CONFIG_MDCT) += mdct_fixed.o mdct_float.o mdct_fixed_32.o OBJS-$(CONFIG_MPEGAUDIO) += mpegaudio.o mpegaudiodata.o \ mpegaudiodecheader.o OBJS-$(CONFIG_MPEGAUDIODSP) += mpegaudiodsp.o \ @@ -92,6 +94,7 @@ OBJS-$(CONFIG_AC3_DECODER) += ac3dec.o ac3dec_data.o ac3.o kbdwin.o OBJS-$(CONFIG_AC3_ENCODER) += ac3enc_float.o ac3enc.o ac3tab.o \ ac3.o kbdwin.o OBJS-$(CONFIG_AC3_FIXED_ENCODER) += ac3enc_fixed.o ac3enc.o ac3tab.o ac3.o +OBJS-$(CONFIG_AIC_DECODER) += aic.o OBJS-$(CONFIG_ALAC_DECODER) += alac.o alac_data.o OBJS-$(CONFIG_ALAC_ENCODER) += alacenc.o alac_data.o OBJS-$(CONFIG_ALS_DECODER) += alsdec.o bgmc.o mpeg4audio.o @@ -111,6 +114,8 @@ OBJS-$(CONFIG_AMV_ENCODER) += mjpegenc.o mjpeg.o \ OBJS-$(CONFIG_ANM_DECODER) += anm.o OBJS-$(CONFIG_ANSI_DECODER) += ansi.o cga_data.o OBJS-$(CONFIG_APE_DECODER) += apedec.o +OBJS-$(CONFIG_SSA_DECODER) += assdec.o ass.o ass_split.o +OBJS-$(CONFIG_SSA_ENCODER) += assenc.o ass.o OBJS-$(CONFIG_ASS_DECODER) += assdec.o ass.o ass_split.o OBJS-$(CONFIG_ASS_ENCODER) += assenc.o ass.o OBJS-$(CONFIG_ASV1_DECODER) += asvdec.o asv.o mpeg12data.o @@ -156,7 +161,7 @@ OBJS-$(CONFIG_CPIA_DECODER) += cpia.o OBJS-$(CONFIG_CSCD_DECODER) += cscd.o OBJS-$(CONFIG_CYUV_DECODER) += cyuv.o OBJS-$(CONFIG_DCA_DECODER) += dcadec.o dca.o dcadsp.o \ - dca_parser.o synth_filter.o + synth_filter.o OBJS-$(CONFIG_DCA_ENCODER) += dcaenc.o dca.o OBJS-$(CONFIG_DIRAC_DECODER) += diracdec.o dirac.o diracdsp.o \ dirac_arith.o mpeg12data.o dirac_dwt.o @@ -172,7 +177,7 @@ OBJS-$(CONFIG_DVBSUB_ENCODER) += dvbsub.o OBJS-$(CONFIG_DVDSUB_DECODER) += dvdsubdec.o OBJS-$(CONFIG_DVDSUB_ENCODER) += dvdsubenc.o OBJS-$(CONFIG_DVVIDEO_DECODER) += dvdec.o dv.o dvdata.o dv_profile.o -OBJS-$(CONFIG_DVVIDEO_ENCODER) += dv.o dvdata.o dv_profile.o +OBJS-$(CONFIG_DVVIDEO_ENCODER) += dvenc.o dv.o dvdata.o dv_profile.o OBJS-$(CONFIG_DXA_DECODER) += dxa.o OBJS-$(CONFIG_DXTORY_DECODER) += dxtory.o OBJS-$(CONFIG_EAC3_DECODER) += eac3dec.o eac3_data.o @@ -182,8 +187,8 @@ OBJS-$(CONFIG_EAMAD_DECODER) += eamad.o eaidct.o mpeg12.o \ mpeg12data.o OBJS-$(CONFIG_EATGQ_DECODER) += eatgq.o eaidct.o OBJS-$(CONFIG_EATGV_DECODER) += eatgv.o -OBJS-$(CONFIG_EATQI_DECODER) += eatqi.o eaidct.o mpeg12.o \ - mpeg12data.o +OBJS-$(CONFIG_EATQI_DECODER) += eatqi.o eaidct.o mpeg12dec.o \ + mpeg12.o mpeg12data.o OBJS-$(CONFIG_EIGHTBPS_DECODER) += 8bps.o OBJS-$(CONFIG_EIGHTSVX_EXP_DECODER) += 8svx.o OBJS-$(CONFIG_EIGHTSVX_FIB_DECODER) += 8svx.o @@ -206,6 +211,7 @@ OBJS-$(CONFIG_FLIC_DECODER) += flicvideo.o OBJS-$(CONFIG_FOURXM_DECODER) += 4xm.o OBJS-$(CONFIG_FRAPS_DECODER) += fraps.o OBJS-$(CONFIG_FRWU_DECODER) += frwu.o +OBJS-$(CONFIG_G2M_DECODER) += g2meet.o mjpeg.o OBJS-$(CONFIG_G723_1_DECODER) += g723_1.o acelp_vectors.o \ celp_filters.o celp_math.o OBJS-$(CONFIG_G723_1_ENCODER) += g723_1.o acelp_vectors.o celp_math.o @@ -214,8 +220,8 @@ OBJS-$(CONFIG_GIF_DECODER) += gifdec.o lzw.o OBJS-$(CONFIG_GIF_ENCODER) += gif.o lzwenc.o OBJS-$(CONFIG_GSM_DECODER) += gsmdec.o gsmdec_data.o msgsmdec.o OBJS-$(CONFIG_GSM_MS_DECODER) += gsmdec.o gsmdec_data.o msgsmdec.o -OBJS-$(CONFIG_H261_DECODER) += h261dec.o h261.o h261data.o -OBJS-$(CONFIG_H261_ENCODER) += h261enc.o h261.o h261data.o +OBJS-$(CONFIG_H261_DECODER) += h261dec.o h261data.o h261.o +OBJS-$(CONFIG_H261_ENCODER) += h261enc.o h261data.o h261.o OBJS-$(CONFIG_H263_DECODER) += h263dec.o h263.o ituh263dec.o \ mpeg4video.o mpeg4videodec.o flvdec.o\ intelh263dec.o @@ -226,6 +232,10 @@ OBJS-$(CONFIG_H264_DECODER) += h264.o \ cabac.o h264_sei.o h264_ps.o \ h264_refs.o h264_cavlc.o h264_cabac.o OBJS-$(CONFIG_H264_VDA_DECODER) += vda_h264_dec.o +OBJS-$(CONFIG_HEVC_DECODER) += hevc.o hevc_mvs.o hevc_ps.o hevc_sei.o \ + hevc_cabac.o hevc_refs.o hevcpred.o \ + hevcdsp.o hevc_filter.o cabac.o +OBJS-$(CONFIG_HNM4_VIDEO_DECODER) += hnm4video.o OBJS-$(CONFIG_HUFFYUV_DECODER) += huffyuv.o huffyuvdec.o OBJS-$(CONFIG_HUFFYUV_ENCODER) += huffyuv.o huffyuvenc.o OBJS-$(CONFIG_IAC_DECODER) += imc.o @@ -241,8 +251,10 @@ OBJS-$(CONFIG_INDEO5_DECODER) += indeo5.o ivi_common.o ivi_dsp.o OBJS-$(CONFIG_INTERPLAY_DPCM_DECODER) += dpcm.o OBJS-$(CONFIG_INTERPLAY_VIDEO_DECODER) += interplayvideo.o OBJS-$(CONFIG_JACOSUB_DECODER) += jacosubdec.o ass.o -OBJS-$(CONFIG_JPEG2000_DECODER) += j2kdec.o mqcdec.o mqc.o j2k.o j2k_dwt.o -OBJS-$(CONFIG_JPEG2000_ENCODER) += j2kenc.o mqcenc.o mqc.o j2k.o j2k_dwt.o +OBJS-$(CONFIG_JPEG2000_ENCODER) += j2kenc.o mqcenc.o mqc.o jpeg2000.o \ + jpeg2000dwt.o +OBJS-$(CONFIG_JPEG2000_DECODER) += jpeg2000dec.o jpeg2000.o \ + jpeg2000dwt.o mqcdec.o mqc.o OBJS-$(CONFIG_JPEGLS_DECODER) += jpeglsdec.o jpegls.o \ mjpegdec.o mjpeg.o OBJS-$(CONFIG_JPEGLS_ENCODER) += jpeglsenc.o jpegls.o @@ -255,6 +267,8 @@ OBJS-$(CONFIG_LOCO_DECODER) += loco.o OBJS-$(CONFIG_MACE3_DECODER) += mace.o OBJS-$(CONFIG_MACE6_DECODER) += mace.o OBJS-$(CONFIG_MDEC_DECODER) += mdec.o mpeg12.o mpeg12data.o +OBJS-$(CONFIG_METASOUND_DECODER) += metasound.o metasound_data.o \ + twinvq.o OBJS-$(CONFIG_MICRODVD_DECODER) += microdvddec.o ass.o OBJS-$(CONFIG_MIMIC_DECODER) += mimic.o OBJS-$(CONFIG_MJPEG_DECODER) += mjpegdec.o mjpeg.o @@ -265,41 +279,40 @@ OBJS-$(CONFIG_MMVIDEO_DECODER) += mmvideo.o OBJS-$(CONFIG_MOTIONPIXELS_DECODER) += motionpixels.o OBJS-$(CONFIG_MOVTEXT_DECODER) += movtextdec.o ass.o OBJS-$(CONFIG_MOVTEXT_ENCODER) += movtextenc.o ass_split.o -OBJS-$(CONFIG_MP1_DECODER) += mpegaudiodec.o +OBJS-$(CONFIG_MP1_DECODER) += mpegaudiodec_fixed.o OBJS-$(CONFIG_MP1FLOAT_DECODER) += mpegaudiodec_float.o -OBJS-$(CONFIG_MP2_DECODER) += mpegaudiodec.o -OBJS-$(CONFIG_MP2_ENCODER) += mpegaudioenc.o mpegaudio.o \ +OBJS-$(CONFIG_MP2_DECODER) += mpegaudiodec_fixed.o +OBJS-$(CONFIG_MP2_ENCODER) += mpegaudioenc_float.o mpegaudio.o \ + mpegaudiodata.o mpegaudiodsp_data.o +OBJS-$(CONFIG_MP2FIXED_ENCODER) += mpegaudioenc_fixed.o mpegaudio.o \ mpegaudiodata.o mpegaudiodsp_data.o OBJS-$(CONFIG_MP2FLOAT_DECODER) += mpegaudiodec_float.o -OBJS-$(CONFIG_MP3_DECODER) += mpegaudiodec.o -OBJS-$(CONFIG_MP3ADU_DECODER) += mpegaudiodec.o +OBJS-$(CONFIG_MP3_DECODER) += mpegaudiodec_fixed.o +OBJS-$(CONFIG_MP3ADU_DECODER) += mpegaudiodec_fixed.o OBJS-$(CONFIG_MP3ADUFLOAT_DECODER) += mpegaudiodec_float.o OBJS-$(CONFIG_MP3FLOAT_DECODER) += mpegaudiodec_float.o -OBJS-$(CONFIG_MP3ON4_DECODER) += mpegaudiodec.o mpeg4audio.o +OBJS-$(CONFIG_MP3ON4_DECODER) += mpegaudiodec_fixed.o mpeg4audio.o OBJS-$(CONFIG_MP3ON4FLOAT_DECODER) += mpegaudiodec_float.o mpeg4audio.o OBJS-$(CONFIG_MPC7_DECODER) += mpc7.o mpc.o OBJS-$(CONFIG_MPC8_DECODER) += mpc8.o mpc.o OBJS-$(CONFIG_MPEGVIDEO_DECODER) += mpeg12.o mpeg12data.o \ mpegvideo.o error_resilience.o -OBJS-$(CONFIG_MPEG_XVMC_DECODER) += mpegvideo_xvmc.o -OBJS-$(CONFIG_MPEG1VIDEO_DECODER) += mpeg12.o mpeg12data.o -OBJS-$(CONFIG_MPEG1VIDEO_ENCODER) += mpeg12enc.o mpeg12.o \ - -OBJS-$(CONFIG_MPEG2VIDEO_DECODER) += mpeg12.o mpeg12data.o -OBJS-$(CONFIG_MPEG2VIDEO_ENCODER) += mpeg12enc.o mpeg12.o \ - timecode.o +OBJS-$(CONFIG_MPEG1VIDEO_DECODER) += mpeg12dec.o mpeg12.o mpeg12data.o +OBJS-$(CONFIG_MPEG1VIDEO_ENCODER) += mpeg12enc.o mpeg12.o +OBJS-$(CONFIG_MPEG2VIDEO_DECODER) += mpeg12dec.o mpeg12.o mpeg12data.o +OBJS-$(CONFIG_MPEG2VIDEO_ENCODER) += mpeg12enc.o mpeg12.o OBJS-$(CONFIG_MPL2_DECODER) += mpl2dec.o ass.o -OBJS-$(CONFIG_MSMPEG4V1_DECODER) += msmpeg4.o msmpeg4data.o -OBJS-$(CONFIG_MSMPEG4V2_DECODER) += msmpeg4.o msmpeg4data.o h263dec.o \ - h263.o ituh263dec.o mpeg4videodec.o +OBJS-$(CONFIG_MSMPEG4V1_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o +OBJS-$(CONFIG_MSMPEG4V2_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o \ + h263dec.o h263.o ituh263dec.o \ + mpeg4videodec.o OBJS-$(CONFIG_MSMPEG4V2_ENCODER) += msmpeg4.o msmpeg4enc.o msmpeg4data.o \ - h263dec.o h263.o ituh263dec.o \ + h263.o +OBJS-$(CONFIG_MSMPEG4V3_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o \ + h263dec.o h263.o ituh263dec.o \ mpeg4videodec.o -OBJS-$(CONFIG_MSMPEG4V3_DECODER) += msmpeg4.o msmpeg4data.o h263dec.o \ - h263.o ituh263dec.o mpeg4videodec.o OBJS-$(CONFIG_MSMPEG4V3_ENCODER) += msmpeg4.o msmpeg4enc.o msmpeg4data.o \ - h263dec.o h263.o ituh263dec.o \ - mpeg4videodec.o + h263.o OBJS-$(CONFIG_MSRLE_DECODER) += msrle.o msrledec.o OBJS-$(CONFIG_MSA1_DECODER) += mss3.o mss34dsp.o OBJS-$(CONFIG_MSS1_DECODER) += mss1.o mss12.o @@ -317,27 +330,27 @@ OBJS-$(CONFIG_NUV_DECODER) += nuv.o rtjpeg.o OBJS-$(CONFIG_PAF_VIDEO_DECODER) += paf.o OBJS-$(CONFIG_PAF_AUDIO_DECODER) += paf.o OBJS-$(CONFIG_PAM_DECODER) += pnmdec.o pnm.o -OBJS-$(CONFIG_PAM_ENCODER) += pamenc.o pnm.o +OBJS-$(CONFIG_PAM_ENCODER) += pamenc.o OBJS-$(CONFIG_PBM_DECODER) += pnmdec.o pnm.o -OBJS-$(CONFIG_PBM_ENCODER) += pnmenc.o pnm.o +OBJS-$(CONFIG_PBM_ENCODER) += pnmenc.o OBJS-$(CONFIG_PCX_DECODER) += pcx.o OBJS-$(CONFIG_PCX_ENCODER) += pcxenc.o OBJS-$(CONFIG_PGM_DECODER) += pnmdec.o pnm.o -OBJS-$(CONFIG_PGM_ENCODER) += pnmenc.o pnm.o +OBJS-$(CONFIG_PGM_ENCODER) += pnmenc.o OBJS-$(CONFIG_PGMYUV_DECODER) += pnmdec.o pnm.o -OBJS-$(CONFIG_PGMYUV_ENCODER) += pnmenc.o pnm.o +OBJS-$(CONFIG_PGMYUV_ENCODER) += pnmenc.o OBJS-$(CONFIG_PGSSUB_DECODER) += pgssubdec.o OBJS-$(CONFIG_PICTOR_DECODER) += pictordec.o cga_data.o OBJS-$(CONFIG_PJS_DECODER) += textdec.o ass.o OBJS-$(CONFIG_PNG_DECODER) += png.o pngdec.o pngdsp.o OBJS-$(CONFIG_PNG_ENCODER) += png.o pngenc.o OBJS-$(CONFIG_PPM_DECODER) += pnmdec.o pnm.o -OBJS-$(CONFIG_PPM_ENCODER) += pnmenc.o pnm.o -OBJS-$(CONFIG_PRORES_DECODER) += proresdec2.o proresdsp.o +OBJS-$(CONFIG_PPM_ENCODER) += pnmenc.o +OBJS-$(CONFIG_PRORES_DECODER) += proresdec2.o proresdsp.o proresdata.o OBJS-$(CONFIG_PRORES_LGPL_DECODER) += proresdec_lgpl.o proresdsp.o proresdata.o OBJS-$(CONFIG_PRORES_ENCODER) += proresenc_anatoliy.o -OBJS-$(CONFIG_PRORES_ANATOLIY_ENCODER) += proresenc_anatoliy.o -OBJS-$(CONFIG_PRORES_KOSTYA_ENCODER) += proresenc_kostya.o proresdata.o proresdsp.o +OBJS-$(CONFIG_PRORES_AW_ENCODER) += proresenc_anatoliy.o +OBJS-$(CONFIG_PRORES_KS_ENCODER) += proresenc_kostya.o proresdata.o proresdsp.o OBJS-$(CONFIG_PTX_DECODER) += ptx.o OBJS-$(CONFIG_QCELP_DECODER) += qcelpdec.o \ celp_filters.o acelp_vectors.o \ @@ -372,6 +385,7 @@ OBJS-$(CONFIG_RV30_DECODER) += rv30.o rv34.o rv30dsp.o rv34dsp.o OBJS-$(CONFIG_RV40_DECODER) += rv40.o rv34.o rv34dsp.o rv40dsp.o OBJS-$(CONFIG_SAMI_DECODER) += samidec.o ass.o OBJS-$(CONFIG_S302M_DECODER) += s302m.o +OBJS-$(CONFIG_S302M_ENCODER) += s302menc.o OBJS-$(CONFIG_SANM_DECODER) += sanm.o OBJS-$(CONFIG_SGI_DECODER) += sgidec.o OBJS-$(CONFIG_SGI_ENCODER) += sgienc.o rle.o @@ -384,6 +398,7 @@ OBJS-$(CONFIG_SIPR_DECODER) += sipr.o acelp_pitch_delay.o \ OBJS-$(CONFIG_SMACKAUD_DECODER) += smacker.o OBJS-$(CONFIG_SMACKER_DECODER) += smacker.o OBJS-$(CONFIG_SMC_DECODER) += smc.o +OBJS-$(CONFIG_SMVJPEG_DECODER) += smvjpegdec.o OBJS-$(CONFIG_SNOW_DECODER) += snowdec.o snow.o snow_dwt.o OBJS-$(CONFIG_SNOW_ENCODER) += snowenc.o snow.o snow_dwt.o \ h263.o ituh263enc.o @@ -415,7 +430,7 @@ OBJS-$(CONFIG_TARGA_Y216_DECODER) += targa_y216dec.o OBJS-$(CONFIG_THEORA_DECODER) += xiph.o OBJS-$(CONFIG_THP_DECODER) += mjpegdec.o mjpeg.o OBJS-$(CONFIG_TIERTEXSEQVIDEO_DECODER) += tiertexseqv.o -OBJS-$(CONFIG_TIFF_DECODER) += tiff.o lzw.o faxcompr.o tiff_data.o +OBJS-$(CONFIG_TIFF_DECODER) += tiff.o lzw.o faxcompr.o tiff_data.o tiff_common.o OBJS-$(CONFIG_TIFF_ENCODER) += tiffenc.o rle.o lzwenc.o tiff_data.o OBJS-$(CONFIG_TMV_DECODER) += tmv.o cga_data.o OBJS-$(CONFIG_TRUEHD_DECODER) += mlpdec.o mlpdsp.o @@ -424,8 +439,9 @@ OBJS-$(CONFIG_TRUEMOTION2_DECODER) += truemotion2.o OBJS-$(CONFIG_TRUESPEECH_DECODER) += truespeech.o OBJS-$(CONFIG_TSCC_DECODER) += tscc.o msrledec.o OBJS-$(CONFIG_TSCC2_DECODER) += tscc2.o -OBJS-$(CONFIG_TTA_DECODER) += tta.o -OBJS-$(CONFIG_TWINVQ_DECODER) += twinvq.o +OBJS-$(CONFIG_TTA_DECODER) += tta.o ttadata.o +OBJS-$(CONFIG_TTA_ENCODER) += ttaenc.o ttadata.o +OBJS-$(CONFIG_TWINVQ_DECODER) += twinvqdec.o twinvq.o OBJS-$(CONFIG_TXD_DECODER) += txd.o s3tc.o OBJS-$(CONFIG_ULTI_DECODER) += ulti.o OBJS-$(CONFIG_UTVIDEO_DECODER) += utvideodec.o utvideo.o @@ -442,8 +458,8 @@ OBJS-$(CONFIG_V210X_DECODER) += v210x.o OBJS-$(CONFIG_VB_DECODER) += vb.o OBJS-$(CONFIG_VBLE_DECODER) += vble.o OBJS-$(CONFIG_VC1_DECODER) += vc1dec.o vc1.o vc1data.o vc1dsp.o \ - msmpeg4.o msmpeg4data.o \ - intrax8.o intrax8dsp.o + msmpeg4dec.o msmpeg4.o msmpeg4data.o \ + intrax8.o intrax8dsp.o wmv2dsp.o OBJS-$(CONFIG_VCR1_DECODER) += vcr1.o OBJS-$(CONFIG_VMDAUDIO_DECODER) += vmdav.o OBJS-$(CONFIG_VMDVIDEO_DECODER) += vmdav.o @@ -458,9 +474,13 @@ OBJS-$(CONFIG_VP5_DECODER) += vp5.o vp56.o vp56data.o vp56dsp.o \ OBJS-$(CONFIG_VP6_DECODER) += vp6.o vp56.o vp56data.o vp56dsp.o \ vp6dsp.o vp56rac.o OBJS-$(CONFIG_VP8_DECODER) += vp8.o vp8dsp.o vp56rac.o +OBJS-$(CONFIG_VP9_DECODER) += vp9.o vp9dsp.o vp56rac.o OBJS-$(CONFIG_VPLAYER_DECODER) += textdec.o ass.o OBJS-$(CONFIG_VQA_DECODER) += vqavideo.o OBJS-$(CONFIG_WAVPACK_DECODER) += wavpack.o +OBJS-$(CONFIG_WAVPACK_ENCODER) += wavpackenc.o +OBJS-$(CONFIG_WEBP_DECODER) += vp8.o vp8dsp.o vp56rac.o +OBJS-$(CONFIG_WEBP_DECODER) += webp.o OBJS-$(CONFIG_WEBVTT_DECODER) += webvttdec.o OBJS-$(CONFIG_WMALOSSLESS_DECODER) += wmalosslessdec.o wma_common.o OBJS-$(CONFIG_WMAPRO_DECODER) += wmaprodec.o wma.o wma_common.o @@ -471,13 +491,12 @@ OBJS-$(CONFIG_WMAV2_ENCODER) += wmaenc.o wma.o wma_common.o aactab.o OBJS-$(CONFIG_WMAVOICE_DECODER) += wmavoice.o \ celp_filters.o \ acelp_vectors.o acelp_filters.o -OBJS-$(CONFIG_WMV1_DECODER) += msmpeg4.o msmpeg4data.o +OBJS-$(CONFIG_WMV1_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o OBJS-$(CONFIG_WMV2_DECODER) += wmv2dec.o wmv2.o wmv2dsp.o \ - msmpeg4.o msmpeg4data.o \ + msmpeg4dec.o msmpeg4.o msmpeg4data.o \ intrax8.o intrax8dsp.o OBJS-$(CONFIG_WMV2_ENCODER) += wmv2enc.o wmv2.o wmv2dsp.o \ - msmpeg4.o msmpeg4enc.o msmpeg4data.o \ - mpeg4videodec.o ituh263dec.o h263dec.o + msmpeg4.o msmpeg4enc.o msmpeg4data.o OBJS-$(CONFIG_WNV1_DECODER) += wnv1.o OBJS-$(CONFIG_WS_SND1_DECODER) += ws-snd1.o OBJS-$(CONFIG_XAN_DPCM_DECODER) += dpcm.o @@ -507,8 +526,8 @@ OBJS-$(CONFIG_ZMBV_ENCODER) += zmbvenc.o # (AD)PCM decoders/encoders OBJS-$(CONFIG_PCM_ALAW_DECODER) += pcm.o OBJS-$(CONFIG_PCM_ALAW_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_BLURAY_DECODER) += pcm-mpeg.o -OBJS-$(CONFIG_PCM_DVD_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_BLURAY_DECODER) += pcm-bluray.o +OBJS-$(CONFIG_PCM_DVD_DECODER) += pcm-dvd.o OBJS-$(CONFIG_PCM_F32BE_DECODER) += pcm.o OBJS-$(CONFIG_PCM_F32BE_ENCODER) += pcm.o OBJS-$(CONFIG_PCM_F32LE_DECODER) += pcm.o @@ -567,6 +586,7 @@ OBJS-$(CONFIG_ADPCM_ADX_DECODER) += adxdec.o adx.o OBJS-$(CONFIG_ADPCM_ADX_ENCODER) += adxenc.o adx.o OBJS-$(CONFIG_ADPCM_AFC_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_CT_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_DTK_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_EA_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_EA_MAXIS_XA_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_EA_R1_DECODER) += adpcm.o adpcm_data.o @@ -577,6 +597,7 @@ OBJS-$(CONFIG_ADPCM_G722_DECODER) += g722.o g722dec.o OBJS-$(CONFIG_ADPCM_G722_ENCODER) += g722.o g722enc.o OBJS-$(CONFIG_ADPCM_G726_DECODER) += g726.o OBJS-$(CONFIG_ADPCM_G726_ENCODER) += g726.o +OBJS-$(CONFIG_ADPCM_G726LE_DECODER) += g726.o OBJS-$(CONFIG_ADPCM_IMA_AMV_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_APC_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_DK3_DECODER) += adpcm.o adpcm_data.o @@ -587,6 +608,7 @@ OBJS-$(CONFIG_ADPCM_IMA_ISS_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_OKI_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_QT_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_QT_ENCODER) += adpcmenc.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_IMA_RAD_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_SMJPEG_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_WAV_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_WAV_ENCODER) += adpcmenc.o adpcm_data.o @@ -605,20 +627,22 @@ OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcmenc.o adpcm_data.o OBJS-$(CONFIG_VIMA_DECODER) += vima.o adpcm_data.o # hardware accelerators -OBJS-$(CONFIG_H263_VAAPI_HWACCEL) += vaapi_mpeg4.o +OBJS-$(CONFIG_H263_VAAPI_HWACCEL) += vaapi_mpeg4.o vaapi_mpeg.o OBJS-$(CONFIG_H263_VDPAU_HWACCEL) += vdpau_mpeg4.o OBJS-$(CONFIG_H264_DXVA2_HWACCEL) += dxva2_h264.o OBJS-$(CONFIG_H264_VAAPI_HWACCEL) += vaapi_h264.o OBJS-$(CONFIG_H264_VDA_HWACCEL) += vda_h264.o OBJS-$(CONFIG_H264_VDPAU_HWACCEL) += vdpau_h264.o OBJS-$(CONFIG_MPEG1_VDPAU_HWACCEL) += vdpau_mpeg12.o +OBJS-$(CONFIG_MPEG1_XVMC_HWACCEL) += mpegvideo_xvmc.o OBJS-$(CONFIG_MPEG2_DXVA2_HWACCEL) += dxva2_mpeg2.o -OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL) += vaapi_mpeg2.o +OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL) += vaapi_mpeg2.o vaapi_mpeg.o OBJS-$(CONFIG_MPEG2_VDPAU_HWACCEL) += vdpau_mpeg12.o -OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL) += vaapi_mpeg4.o +OBJS-$(CONFIG_MPEG2_XVMC_HWACCEL) += mpegvideo_xvmc.o +OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL) += vaapi_mpeg4.o vaapi_mpeg.o OBJS-$(CONFIG_MPEG4_VDPAU_HWACCEL) += vdpau_mpeg4.o OBJS-$(CONFIG_VC1_DXVA2_HWACCEL) += dxva2_vc1.o -OBJS-$(CONFIG_VC1_VAAPI_HWACCEL) += vaapi_vc1.o +OBJS-$(CONFIG_VC1_VAAPI_HWACCEL) += vaapi_vc1.o vaapi_mpeg.o OBJS-$(CONFIG_VC1_VDPAU_HWACCEL) += vdpau_vc1.o # libavformat dependencies @@ -627,7 +651,7 @@ OBJS-$(CONFIG_ADX_DEMUXER) += adx.o OBJS-$(CONFIG_CAF_DEMUXER) += mpeg4audio.o mpegaudiodata.o \ ac3tab.o OBJS-$(CONFIG_DV_DEMUXER) += dv_profile.o -OBJS-$(CONFIG_DV_MUXER) += dv_profile.o timecode.o +OBJS-$(CONFIG_DV_MUXER) += dv_profile.o OBJS-$(CONFIG_FLAC_DEMUXER) += flac.o flacdata.o vorbis_data.o \ vorbis_parser.o xiph.o OBJS-$(CONFIG_FLAC_MUXER) += flac.o flacdata.o vorbis_data.o @@ -643,11 +667,11 @@ OBJS-$(CONFIG_MATROSKA_MUXER) += mpeg4audio.o mpegaudiodata.o \ flac.o flacdata.o vorbis_data.o xiph.o OBJS-$(CONFIG_MP2_MUXER) += mpegaudiodata.o mpegaudiodecheader.o OBJS-$(CONFIG_MP3_MUXER) += mpegaudiodata.o mpegaudiodecheader.o -OBJS-$(CONFIG_MOV_DEMUXER) += mpeg4audio.o mpegaudiodata.o ac3tab.o timecode.o +OBJS-$(CONFIG_MOV_DEMUXER) += mpeg4audio.o mpegaudiodata.o ac3tab.o OBJS-$(CONFIG_MOV_MUXER) += mpeg4audio.o mpegaudiodata.o OBJS-$(CONFIG_MPEGTS_MUXER) += mpeg4audio.o OBJS-$(CONFIG_MPEGTS_DEMUXER) += mpeg4audio.o mpegaudiodata.o -OBJS-$(CONFIG_MXF_MUXER) += timecode.o dnxhddata.o +OBJS-$(CONFIG_MXF_MUXER) += dnxhddata.o OBJS-$(CONFIG_NUT_MUXER) += mpegaudiodata.o OBJS-$(CONFIG_OGG_DEMUXER) += xiph.o flac.o flacdata.o \ mpeg12data.o vorbis_parser.o \ @@ -664,10 +688,14 @@ OBJS-$(CONFIG_WEBM_MUXER) += mpeg4audio.o mpegaudiodata.o \ vorbis_data.o OBJS-$(CONFIG_WTV_DEMUXER) += mpeg4audio.o mpegaudiodata.o +# libavfilter dependencies +OBJS-$(CONFIG_ELBG_FILTER) += elbg.o + # external codec libraries OBJS-$(CONFIG_LIBAACPLUS_ENCODER) += libaacplus.o OBJS-$(CONFIG_LIBCELT_DECODER) += libcelt_dec.o OBJS-$(CONFIG_LIBFAAC_ENCODER) += libfaac.o +OBJS-$(CONFIG_LIBFDK_AAC_DECODER) += libfdk-aacdec.o OBJS-$(CONFIG_LIBFDK_AAC_ENCODER) += libfdk-aacenc.o OBJS-$(CONFIG_LIBGSM_DECODER) += libgsm.o OBJS-$(CONFIG_LIBGSM_ENCODER) += libgsm.o @@ -689,6 +717,7 @@ OBJS-$(CONFIG_LIBSCHROEDINGER_DECODER) += libschroedingerdec.o \ libschroedinger.o OBJS-$(CONFIG_LIBSCHROEDINGER_ENCODER) += libschroedingerenc.o \ libschroedinger.o +OBJS-$(CONFIG_LIBSHINE_ENCODER) += libshine.o OBJS-$(CONFIG_LIBSPEEX_DECODER) += libspeexdec.o OBJS-$(CONFIG_LIBSPEEX_ENCODER) += libspeexenc.o OBJS-$(CONFIG_LIBSTAGEFRIGHT_H264_DECODER)+= libstagefright.o @@ -703,11 +732,14 @@ OBJS-$(CONFIG_LIBVORBIS_ENCODER) += libvorbisenc.o \ vorbis_data.o vorbis_parser.o xiph.o OBJS-$(CONFIG_LIBVPX_VP8_DECODER) += libvpxdec.o OBJS-$(CONFIG_LIBVPX_VP8_ENCODER) += libvpxenc.o -OBJS-$(CONFIG_LIBVPX_VP9_DECODER) += libvpxdec.o -OBJS-$(CONFIG_LIBVPX_VP9_ENCODER) += libvpxenc.o +OBJS-$(CONFIG_LIBVPX_VP9_DECODER) += libvpxdec.o libvpx.o +OBJS-$(CONFIG_LIBVPX_VP9_ENCODER) += libvpxenc.o libvpx.o +OBJS-$(CONFIG_LIBWAVPACK_ENCODER) += libwavpackenc.o +OBJS-$(CONFIG_LIBWEBP_ENCODER) += libwebpenc.o OBJS-$(CONFIG_LIBX264_ENCODER) += libx264.o OBJS-$(CONFIG_LIBXAVS_ENCODER) += libxavs.o OBJS-$(CONFIG_LIBXVID_ENCODER) += libxvid.o +OBJS-$(CONFIG_LIBZVBI_TELETEXT_DECODER) += libzvbi-teletextdec.o # parsers OBJS-$(CONFIG_AAC_PARSER) += aac_parser.o aac_ac3_parser.o \ @@ -722,6 +754,7 @@ OBJS-$(CONFIG_COOK_PARSER) += cook_parser.o OBJS-$(CONFIG_DCA_PARSER) += dca_parser.o dca.o OBJS-$(CONFIG_DIRAC_PARSER) += dirac_parser.o OBJS-$(CONFIG_DNXHD_PARSER) += dnxhd_parser.o +OBJS-$(CONFIG_DPX_PARSER) += dpx_parser.o OBJS-$(CONFIG_DVBSUB_PARSER) += dvbsub_parser.o OBJS-$(CONFIG_DVD_NAV_PARSER) += dvd_nav_parser.o OBJS-$(CONFIG_DVDSUB_PARSER) += dvdsub_parser.o @@ -735,6 +768,7 @@ OBJS-$(CONFIG_H264_PARSER) += h264_parser.o h264.o \ h264_refs.o h264_sei.o h264_direct.o \ h264_loopfilter.o h264_cabac.o \ h264_cavlc.o h264_ps.o +OBJS-$(CONFIG_HEVC_PARSER) += hevc_parser.o OBJS-$(CONFIG_MJPEG_PARSER) += mjpeg_parser.o OBJS-$(CONFIG_MLP_PARSER) += mlp_parser.o mlp.o OBJS-$(CONFIG_MPEG4VIDEO_PARSER) += mpeg4video_parser.o h263.o \ @@ -745,6 +779,7 @@ OBJS-$(CONFIG_MPEGAUDIO_PARSER) += mpegaudio_parser.o \ mpegaudiodecheader.o mpegaudiodata.o OBJS-$(CONFIG_MPEGVIDEO_PARSER) += mpegvideo_parser.o \ mpeg12.o mpeg12data.o +OBJS-$(CONFIG_PNG_PARSER) += png_parser.o OBJS-$(CONFIG_PNM_PARSER) += pnm_parser.o pnm.o OBJS-$(CONFIG_RV30_PARSER) += rv34_parser.o OBJS-$(CONFIG_RV40_PARSER) += rv34_parser.o @@ -755,6 +790,7 @@ OBJS-$(CONFIG_VC1_PARSER) += vc1_parser.o vc1.o vc1data.o \ OBJS-$(CONFIG_VORBIS_PARSER) += vorbis_parser.o xiph.o OBJS-$(CONFIG_VP3_PARSER) += vp3_parser.o OBJS-$(CONFIG_VP8_PARSER) += vp8_parser.o +OBJS-$(CONFIG_VP9_PARSER) += vp9_parser.o # bitstream filters OBJS-$(CONFIG_AAC_ADTSTOASC_BSF) += aac_adtstoasc_bsf.o aacadtsdec.o \ @@ -766,7 +802,6 @@ OBJS-$(CONFIG_IMX_DUMP_HEADER_BSF) += imx_dump_header_bsf.o OBJS-$(CONFIG_MJPEG2JPEG_BSF) += mjpeg2jpeg_bsf.o mjpeg.o OBJS-$(CONFIG_MJPEGA_DUMP_HEADER_BSF) += mjpega_dump_header_bsf.o OBJS-$(CONFIG_MOV2TEXTSUB_BSF) += movsub_bsf.o -OBJS-$(CONFIG_MP3_HEADER_COMPRESS_BSF) += mp3_header_compress_bsf.o OBJS-$(CONFIG_MP3_HEADER_DECOMPRESS_BSF) += mp3_header_decompress_bsf.o \ mpegaudiodata.o OBJS-$(CONFIG_NOISE_BSF) += noise_bsf.o @@ -774,12 +809,14 @@ OBJS-$(CONFIG_REMOVE_EXTRADATA_BSF) += remove_extradata_bsf.o OBJS-$(CONFIG_TEXT2MOVSUB_BSF) += movsub_bsf.o # thread libraries -OBJS-$(HAVE_PTHREADS) += pthread.o -OBJS-$(HAVE_W32THREADS) += pthread.o -OBJS-$(HAVE_OS2THREADS) += pthread.o +OBJS-$(HAVE_LIBC_MSVCRT) += file_open.o +OBJS-$(HAVE_THREADS) += pthread.o pthread_slice.o pthread_frame.o OBJS-$(CONFIG_FRAME_THREAD_ENCODER) += frame_thread_encoder.o +# Windows resource file +SLIBOBJS-$(HAVE_GNU_WINDRES) += avcodecres.o + SKIPHEADERS += %_tablegen.h \ %_tables.h \ aac_tablegen_decl.h \ @@ -791,23 +828,22 @@ SKIPHEADERS += %_tablegen.h \ SKIPHEADERS-$(CONFIG_DXVA2) += dxva2.h dxva2_internal.h SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER) += libschroedinger.h SKIPHEADERS-$(CONFIG_LIBUTVIDEO) += libutvideo.h -SKIPHEADERS-$(CONFIG_MPEG_XVMC_DECODER) += xvmc.h +SKIPHEADERS-$(CONFIG_XVMC) += xvmc.h SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_internal.h SKIPHEADERS-$(CONFIG_VDA) += vda.h -SKIPHEADERS-$(CONFIG_VDPAU) += vdpau.h -SKIPHEADERS-$(HAVE_OS2THREADS) += os2threads.h -SKIPHEADERS-$(HAVE_W32THREADS) += w32pthreads.h +SKIPHEADERS-$(CONFIG_VDPAU) += vdpau.h vdpau_internal.h TESTPROGS = cabac \ - dct \ fft \ fft-fixed \ + fft-fixed32 \ golomb \ iirfilter \ imgconvert \ rangecoder \ snowenc \ +TESTPROGS-$(CONFIG_DCT) += dct TESTPROGS-$(HAVE_MMX) += motion TESTOBJS = dctref.o @@ -827,6 +863,7 @@ HOSTPROGS = aac_tablegen \ CLEANFILES = *_tables.c *_tables.h *_tablegen$(HOSTEXESUF) $(SUBDIR)dct-test$(EXESUF): $(SUBDIR)dctref.o $(SUBDIR)aandcttab.o +$(SUBDIR)dv_tablegen$(HOSTEXESUF): $(SUBDIR)dvdata_host.o TRIG_TABLES = cos cos_fixed sin TRIG_TABLES := $(TRIG_TABLES:%=$(SUBDIR)%_tables.c) @@ -852,9 +889,9 @@ ifdef CONFIG_HARDCODED_TABLES $(SUBDIR)aacdec.o: $(SUBDIR)cbrt_tables.h $(SUBDIR)aacps.o: $(SUBDIR)aacps_tables.h $(SUBDIR)aactab.o: $(SUBDIR)aac_tables.h -$(SUBDIR)dv.o: $(SUBDIR)dv_tables.h +$(SUBDIR)dvenc.o: $(SUBDIR)dv_tables.h $(SUBDIR)sinewin.o: $(SUBDIR)sinewin_tables.h -$(SUBDIR)mpegaudiodec.o: $(SUBDIR)mpegaudio_tables.h +$(SUBDIR)mpegaudiodec_fixed.o: $(SUBDIR)mpegaudio_tables.h $(SUBDIR)mpegaudiodec_float.o: $(SUBDIR)mpegaudio_tables.h $(SUBDIR)motionpixels.o: $(SUBDIR)motionpixels_tables.h $(SUBDIR)pcm.o: $(SUBDIR)pcm_tables.h diff --git a/ffmpeg/libavcodec/a64multienc.c b/ffmpeg/libavcodec/a64multienc.c index eaf7b46..6dd5c2c 100644 --- a/ffmpeg/libavcodec/a64multienc.c +++ b/ffmpeg/libavcodec/a64multienc.c @@ -40,9 +40,6 @@ #define C64YRES 200 typedef struct A64Context { - /* general variables */ - AVFrame picture; - /* variables for multicolor modes */ AVLFG randctx; int mc_lifetime; @@ -189,6 +186,7 @@ static void render_charset(AVCodecContext *avctx, uint8_t *charset, static av_cold int a64multi_close_encoder(AVCodecContext *avctx) { A64Context *c = avctx->priv_data; + av_frame_free(&avctx->coded_frame); av_free(c->mc_meta_charset); av_free(c->mc_best_cb); av_free(c->mc_charset); @@ -240,8 +238,12 @@ static av_cold int a64multi_init_encoder(AVCodecContext *avctx) AV_WB32(avctx->extradata, c->mc_lifetime); AV_WB32(avctx->extradata + 16, INTERLACED); - avcodec_get_frame_defaults(&c->picture); - avctx->coded_frame = &c->picture; + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) { + a64multi_close_encoder(avctx); + return AVERROR(ENOMEM); + } + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; avctx->coded_frame->key_frame = 1; if (!avctx->codec_tag) @@ -271,7 +273,7 @@ static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { A64Context *c = avctx->priv_data; - AVFrame *const p = &c->picture; + AVFrame *const p = avctx->coded_frame; int frame; int x, y; @@ -338,8 +340,8 @@ static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt, buf = pkt->data; /* calc optimal new charset + charmaps */ - ff_init_elbg(meta, 32, 1000 * c->mc_lifetime, best_cb, CHARSET_CHARS, 50, charmap, &c->randctx); - ff_do_elbg (meta, 32, 1000 * c->mc_lifetime, best_cb, CHARSET_CHARS, 50, charmap, &c->randctx); + avpriv_init_elbg(meta, 32, 1000 * c->mc_lifetime, best_cb, CHARSET_CHARS, 50, charmap, &c->randctx); + avpriv_do_elbg (meta, 32, 1000 * c->mc_lifetime, best_cb, CHARSET_CHARS, 50, charmap, &c->randctx); /* create colorram map and a c64 readable charset */ render_charset(avctx, charset, colram); @@ -396,6 +398,7 @@ static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt, #if CONFIG_A64MULTI_ENCODER AVCodec ff_a64multi_encoder = { .name = "a64multi", + .long_name = NULL_IF_CONFIG_SMALL("Multicolor charset for Commodore 64"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_A64_MULTI, .priv_data_size = sizeof(A64Context), @@ -403,13 +406,13 @@ AVCodec ff_a64multi_encoder = { .encode2 = a64multi_encode_frame, .close = a64multi_close_encoder, .pix_fmts = (const enum AVPixelFormat[]) {AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("Multicolor charset for Commodore 64"), .capabilities = CODEC_CAP_DELAY, }; #endif #if CONFIG_A64MULTI5_ENCODER AVCodec ff_a64multi5_encoder = { .name = "a64multi5", + .long_name = NULL_IF_CONFIG_SMALL("Multicolor charset for Commodore 64, extended with 5th color (colram)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_A64_MULTI5, .priv_data_size = sizeof(A64Context), @@ -417,7 +420,6 @@ AVCodec ff_a64multi5_encoder = { .encode2 = a64multi_encode_frame, .close = a64multi_close_encoder, .pix_fmts = (const enum AVPixelFormat[]) {AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("Multicolor charset for Commodore 64, extended with 5th color (colram)"), .capabilities = CODEC_CAP_DELAY, }; #endif diff --git a/ffmpeg/libavcodec/aac.h b/ffmpeg/libavcodec/aac.h index d586e27..89f463e 100644 --- a/ffmpeg/libavcodec/aac.h +++ b/ffmpeg/libavcodec/aac.h @@ -157,7 +157,7 @@ typedef struct LongTermPrediction { typedef struct IndividualChannelStream { uint8_t max_sfb; ///< number of scalefactor bands per group enum WindowSequence window_sequence[2]; - uint8_t use_kb_window[2]; ///< If set, use Kaiser-Bessel window, otherwise use a sinus window. + uint8_t use_kb_window[2]; ///< If set, use Kaiser-Bessel window, otherwise use a sine window. int num_window_groups; uint8_t group_len[8]; LongTermPrediction ltp; @@ -234,7 +234,7 @@ typedef struct SingleChannelElement { int sf_idx[128]; ///< scalefactor indices (used by encoder) uint8_t zeroes[128]; ///< band is not coded (used by encoder) DECLARE_ALIGNED(32, float, coeffs)[1024]; ///< coefficients for IMDCT - DECLARE_ALIGNED(32, float, saved)[1024]; ///< overlap + DECLARE_ALIGNED(32, float, saved)[1536]; ///< overlap DECLARE_ALIGNED(32, float, ret_buf)[2048]; ///< PCM output buffer DECLARE_ALIGNED(16, float, ltp_state)[3072]; ///< time signal for LTP PredictorState predictor_state[MAX_PREDICTORS]; @@ -290,6 +290,7 @@ struct AACContext { */ FFTContext mdct; FFTContext mdct_small; + FFTContext mdct_ld; FFTContext mdct_ltp; FmtConvertContext fmt_conv; AVFloatDSPContext fdsp; diff --git a/ffmpeg/libavcodec/aac_ac3_parser.c b/ffmpeg/libavcodec/aac_ac3_parser.c index 6f1e188..7fefda5 100644 --- a/ffmpeg/libavcodec/aac_ac3_parser.c +++ b/ffmpeg/libavcodec/aac_ac3_parser.c @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/channel_layout.h" #include "libavutil/common.h" #include "parser.h" #include "aac_ac3_parser.h" @@ -82,14 +83,23 @@ get_next: if (avctx->codec_id != AV_CODEC_ID_AAC) { avctx->sample_rate = s->sample_rate; - /* allow downmixing to stereo (or mono for AC-3) */ - if(avctx->request_channels > 0 && - avctx->request_channels < s->channels && - (avctx->request_channels <= 2 || - (avctx->request_channels == 1 && - (avctx->codec_id == AV_CODEC_ID_AC3 || - avctx->codec_id == AV_CODEC_ID_EAC3)))) { - avctx->channels = avctx->request_channels; + /* (E-)AC-3: allow downmixing to stereo or mono */ +#if FF_API_REQUEST_CHANNELS +FF_DISABLE_DEPRECATION_WARNINGS + if (avctx->request_channels == 1) + avctx->request_channel_layout = AV_CH_LAYOUT_MONO; + else if (avctx->request_channels == 2) + avctx->request_channel_layout = AV_CH_LAYOUT_STEREO; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + if (s->channels > 1 && + avctx->request_channel_layout == AV_CH_LAYOUT_MONO) { + avctx->channels = 1; + avctx->channel_layout = AV_CH_LAYOUT_MONO; + } else if (s->channels > 2 && + avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) { + avctx->channels = 2; + avctx->channel_layout = AV_CH_LAYOUT_STEREO; } else { avctx->channels = s->channels; avctx->channel_layout = s->channel_layout; diff --git a/ffmpeg/libavcodec/aac_ac3_parser.h b/ffmpeg/libavcodec/aac_ac3_parser.h index ca49d2f..c2506a5 100644 --- a/ffmpeg/libavcodec/aac_ac3_parser.h +++ b/ffmpeg/libavcodec/aac_ac3_parser.h @@ -28,13 +28,13 @@ #include "parser.h" typedef enum { - AAC_AC3_PARSE_ERROR_SYNC = -1, - AAC_AC3_PARSE_ERROR_BSID = -2, - AAC_AC3_PARSE_ERROR_SAMPLE_RATE = -3, - AAC_AC3_PARSE_ERROR_FRAME_SIZE = -4, - AAC_AC3_PARSE_ERROR_FRAME_TYPE = -5, - AAC_AC3_PARSE_ERROR_CRC = -6, - AAC_AC3_PARSE_ERROR_CHANNEL_CFG = -7, + AAC_AC3_PARSE_ERROR_SYNC = -0x1030c0a, + AAC_AC3_PARSE_ERROR_BSID = -0x2030c0a, + AAC_AC3_PARSE_ERROR_SAMPLE_RATE = -0x3030c0a, + AAC_AC3_PARSE_ERROR_FRAME_SIZE = -0x4030c0a, + AAC_AC3_PARSE_ERROR_FRAME_TYPE = -0x5030c0a, + AAC_AC3_PARSE_ERROR_CRC = -0x6030c0a, + AAC_AC3_PARSE_ERROR_CHANNEL_CFG = -0x7030c0a, } AACAC3ParseError; typedef struct AACAC3ParseContext { diff --git a/ffmpeg/libavcodec/aac_adtstoasc_bsf.c b/ffmpeg/libavcodec/aac_adtstoasc_bsf.c index c7d7b3a..c8f9e0a 100644 --- a/ffmpeg/libavcodec/aac_adtstoasc_bsf.c +++ b/ffmpeg/libavcodec/aac_adtstoasc_bsf.c @@ -112,7 +112,7 @@ static int aac_adtstoasc_filter(AVBitStreamFilterContext *bsfc, } AVBitStreamFilter ff_aac_adtstoasc_bsf = { - "aac_adtstoasc", - sizeof(AACBSFContext), - aac_adtstoasc_filter, + .name = "aac_adtstoasc", + .priv_data_size = sizeof(AACBSFContext), + .filter = aac_adtstoasc_filter, }; diff --git a/ffmpeg/libavcodec/aac_tablegen.h b/ffmpeg/libavcodec/aac_tablegen.h index 2b080ba..1c19a15 100644 --- a/ffmpeg/libavcodec/aac_tablegen.h +++ b/ffmpeg/libavcodec/aac_tablegen.h @@ -35,7 +35,7 @@ void ff_aac_tableinit(void) { int i; for (i = 0; i < 428; i++) - ff_aac_pow2sf_tab[i] = pow(2, (i - POW_SF2_ZERO) / 4.); + ff_aac_pow2sf_tab[i] = pow(2, (i - POW_SF2_ZERO) / 4.0); } #endif /* CONFIG_HARDCODED_TABLES */ diff --git a/ffmpeg/libavcodec/aaccoder.c b/ffmpeg/libavcodec/aaccoder.c index 994de28..50a246f 100644 --- a/ffmpeg/libavcodec/aaccoder.c +++ b/ffmpeg/libavcodec/aaccoder.c @@ -710,7 +710,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx, const float lambda) { int start = 0, i, w, w2, g; - int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / avctx->channels; + int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / avctx->channels * (lambda / 120.f); float dists[128] = { 0 }, uplims[128]; float maxvals[128]; int fflag, minscaler; @@ -1113,25 +1113,25 @@ static void search_for_ms(AACEncContext *s, ChannelElement *cpe, } AACCoefficientsEncoder ff_aac_coders[AAC_CODER_NB] = { - { + [AAC_CODER_FAAC] = { search_for_quantizers_faac, encode_window_bands_info, quantize_and_encode_band, search_for_ms, }, - { + [AAC_CODER_ANMR] = { search_for_quantizers_anmr, encode_window_bands_info, quantize_and_encode_band, search_for_ms, }, - { + [AAC_CODER_TWOLOOP] = { search_for_quantizers_twoloop, codebook_trellis_rate, quantize_and_encode_band, search_for_ms, }, - { + [AAC_CODER_FAST] = { search_for_quantizers_fast, encode_window_bands_info, quantize_and_encode_band, diff --git a/ffmpeg/libavcodec/aacdec.c b/ffmpeg/libavcodec/aacdec.c index 37c7de5..1e15cb4 100644 --- a/ffmpeg/libavcodec/aacdec.c +++ b/ffmpeg/libavcodec/aacdec.c @@ -2,6 +2,7 @@ * AAC decoder * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org ) * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com ) + * Copyright (c) 2008-2013 Alex Converse * * AAC LATM decoder * Copyright (c) 2008-2010 Paul Kendall @@ -73,6 +74,7 @@ * N SinuSoidal Coding (Transient, Sinusoid, Noise) * Y Parametric Stereo * N Direct Stream Transfer + * Y Enhanced AAC Low Delay (ER AAC ELD) * * Note: - HE AAC v1 comprises LC AAC with Spectral Band Replication. * - HE AAC v2 comprises LC AAC with Spectral Band Replication and @@ -103,6 +105,7 @@ #include #include #include +#include #include #if ARCH_ARM @@ -148,6 +151,8 @@ static av_cold int che_configure(AACContext *ac, enum ChannelPosition che_pos, int type, int id, int *channels) { + if (*channels >= MAX_CHANNELS) + return AVERROR_INVALIDDATA; if (che_pos) { if (!ac->che[type][id]) { if (!(ac->che[type][id] = av_mallocz(sizeof(ChannelElement)))) @@ -213,28 +218,39 @@ struct elem_to_channel { static int assign_pair(struct elem_to_channel e2c_vec[MAX_ELEM_ID], uint8_t (*layout_map)[3], int offset, uint64_t left, - uint64_t right, int pos) + uint64_t right, int pos) { if (layout_map[offset][0] == TYPE_CPE) { e2c_vec[offset] = (struct elem_to_channel) { - .av_position = left | right, .syn_ele = TYPE_CPE, - .elem_id = layout_map[offset ][1], .aac_position = pos }; + .av_position = left | right, + .syn_ele = TYPE_CPE, + .elem_id = layout_map[offset][1], + .aac_position = pos + }; return 1; } else { - e2c_vec[offset] = (struct elem_to_channel) { - .av_position = left, .syn_ele = TYPE_SCE, - .elem_id = layout_map[offset ][1], .aac_position = pos }; + e2c_vec[offset] = (struct elem_to_channel) { + .av_position = left, + .syn_ele = TYPE_SCE, + .elem_id = layout_map[offset][1], + .aac_position = pos + }; e2c_vec[offset + 1] = (struct elem_to_channel) { - .av_position = right, .syn_ele = TYPE_SCE, - .elem_id = layout_map[offset + 1][1], .aac_position = pos }; + .av_position = right, + .syn_ele = TYPE_SCE, + .elem_id = layout_map[offset + 1][1], + .aac_position = pos + }; return 2; } } -static int count_paired_channels(uint8_t (*layout_map)[3], int tags, int pos, int *current) { +static int count_paired_channels(uint8_t (*layout_map)[3], int tags, int pos, + int *current) +{ int num_pos_channels = 0; - int first_cpe = 0; - int sce_parity = 0; + int first_cpe = 0; + int sce_parity = 0; int i; for (i = *current; i < tags; i++) { if (layout_map[i][2] != pos) @@ -248,7 +264,7 @@ static int count_paired_channels(uint8_t (*layout_map)[3], int tags, int pos, in } } num_pos_channels += 2; - first_cpe = 1; + first_cpe = 1; } else { num_pos_channels++; sce_parity ^= 1; @@ -256,7 +272,7 @@ static int count_paired_channels(uint8_t (*layout_map)[3], int tags, int pos, in } if (sce_parity && ((pos == AAC_CHANNEL_FRONT && first_cpe) || pos == AAC_CHANNEL_SIDE)) - return -1; + return -1; *current = i; return num_pos_channels; } @@ -264,7 +280,7 @@ static int count_paired_channels(uint8_t (*layout_map)[3], int tags, int pos, in static uint64_t sniff_channel_order(uint8_t (*layout_map)[3], int tags) { int i, n, total_non_cc_elements; - struct elem_to_channel e2c_vec[4*MAX_ELEM_ID] = {{ 0 }}; + struct elem_to_channel e2c_vec[4 * MAX_ELEM_ID] = { { 0 } }; int num_front_channels, num_side_channels, num_back_channels; uint64_t layout; @@ -288,8 +304,11 @@ static uint64_t sniff_channel_order(uint8_t (*layout_map)[3], int tags) i = 0; if (num_front_channels & 1) { e2c_vec[i] = (struct elem_to_channel) { - .av_position = AV_CH_FRONT_CENTER, .syn_ele = TYPE_SCE, - .elem_id = layout_map[i][1], .aac_position = AAC_CHANNEL_FRONT }; + .av_position = AV_CH_FRONT_CENTER, + .syn_ele = TYPE_SCE, + .elem_id = layout_map[i][1], + .aac_position = AAC_CHANNEL_FRONT + }; i++; num_front_channels--; } @@ -346,22 +365,31 @@ static uint64_t sniff_channel_order(uint8_t (*layout_map)[3], int tags) } if (num_back_channels) { e2c_vec[i] = (struct elem_to_channel) { - .av_position = AV_CH_BACK_CENTER, .syn_ele = TYPE_SCE, - .elem_id = layout_map[i][1], .aac_position = AAC_CHANNEL_BACK }; + .av_position = AV_CH_BACK_CENTER, + .syn_ele = TYPE_SCE, + .elem_id = layout_map[i][1], + .aac_position = AAC_CHANNEL_BACK + }; i++; num_back_channels--; } if (i < tags && layout_map[i][2] == AAC_CHANNEL_LFE) { e2c_vec[i] = (struct elem_to_channel) { - .av_position = AV_CH_LOW_FREQUENCY, .syn_ele = TYPE_LFE, - .elem_id = layout_map[i][1], .aac_position = AAC_CHANNEL_LFE }; + .av_position = AV_CH_LOW_FREQUENCY, + .syn_ele = TYPE_LFE, + .elem_id = layout_map[i][1], + .aac_position = AAC_CHANNEL_LFE + }; i++; } while (i < tags && layout_map[i][2] == AAC_CHANNEL_LFE) { e2c_vec[i] = (struct elem_to_channel) { - .av_position = UINT64_MAX, .syn_ele = TYPE_LFE, - .elem_id = layout_map[i][1], .aac_position = AAC_CHANNEL_LFE }; + .av_position = UINT64_MAX, + .syn_ele = TYPE_LFE, + .elem_id = layout_map[i][1], + .aac_position = AAC_CHANNEL_LFE + }; i++; } @@ -369,12 +397,11 @@ static uint64_t sniff_channel_order(uint8_t (*layout_map)[3], int tags) total_non_cc_elements = n = i; do { int next_n = 0; - for (i = 1; i < n; i++) { - if (e2c_vec[i-1].av_position > e2c_vec[i].av_position) { - FFSWAP(struct elem_to_channel, e2c_vec[i-1], e2c_vec[i]); + for (i = 1; i < n; i++) + if (e2c_vec[i - 1].av_position > e2c_vec[i].av_position) { + FFSWAP(struct elem_to_channel, e2c_vec[i - 1], e2c_vec[i]); next_n = i; } - } n = next_n; } while (n > 0); @@ -416,12 +443,13 @@ static void pop_output_configuration(AACContext *ac) { } /** - * Configure output channel order based on the current program configuration element. + * Configure output channel order based on the current program + * configuration element. * * @return Returns error status. 0 - OK, !0 - error */ static int output_configure(AACContext *ac, - uint8_t layout_map[MAX_ELEM_ID*4][3], int tags, + uint8_t layout_map[MAX_ELEM_ID * 4][3], int tags, enum OCStatus oc_type, int get_new_frame) { AVCodecContext *avctx = ac->avctx; @@ -457,8 +485,8 @@ static int output_configure(AACContext *ac, memcpy(ac->tag_che_map, ac->che, 4 * MAX_ELEM_ID * sizeof(ac->che[0][0])); if (layout) avctx->channel_layout = layout; - ac->oc[1].channel_layout = layout; - avctx->channels = ac->oc[1].channels = channels; + ac->oc[1].channel_layout = layout; + avctx->channels = ac->oc[1].channels = channels; ac->oc[1].status = oc_type; if (get_new_frame) { @@ -493,36 +521,59 @@ static void flush(AVCodecContext *avctx) * @return Returns error status. 0 - OK, !0 - error */ static int set_default_channel_config(AVCodecContext *avctx, - uint8_t (*layout_map)[3], - int *tags, - int channel_config) + uint8_t (*layout_map)[3], + int *tags, + int channel_config) { if (channel_config < 1 || channel_config > 7) { - av_log(avctx, AV_LOG_ERROR, "invalid default channel configuration (%d)\n", + av_log(avctx, AV_LOG_ERROR, + "invalid default channel configuration (%d)\n", channel_config); - return -1; + return AVERROR_INVALIDDATA; } *tags = tags_per_config[channel_config]; - memcpy(layout_map, aac_channel_layout_map[channel_config-1], *tags * sizeof(*layout_map)); + memcpy(layout_map, aac_channel_layout_map[channel_config - 1], + *tags * sizeof(*layout_map)); + + /* + * AAC specification has 7.1(wide) as a default layout for 8-channel streams. + * However, at least Nero AAC encoder encodes 7.1 streams using the default + * channel config 7, mapping the side channels of the original audio stream + * to the second AAC_CHANNEL_FRONT pair in the AAC stream. Similarly, e.g. FAAD + * decodes the second AAC_CHANNEL_FRONT pair as side channels, therefore decoding + * the incorrect streams as if they were correct (and as the encoder intended). + * + * As actual intended 7.1(wide) streams are very rare, default to assuming a + * 7.1 layout was intended. + */ + if (channel_config == 7 && avctx->strict_std_compliance < FF_COMPLIANCE_STRICT) { + av_log(avctx, AV_LOG_INFO, "Assuming an incorrectly encoded 7.1 channel layout" + " instead of a spec-compliant 7.1(wide) layout, use -strict %d to decode" + " according to the specification instead.\n", FF_COMPLIANCE_STRICT); + layout_map[2][2] = AAC_CHANNEL_SIDE; + } + return 0; } static ChannelElement *get_che(AACContext *ac, int type, int elem_id) { - // For PCE based channel configurations map the channels solely based on tags. + /* For PCE based channel configurations map the channels solely based + * on tags. */ if (!ac->oc[1].m4ac.chan_config) { return ac->tag_che_map[type][elem_id]; } // Allow single CPE stereo files to be signalled with mono configuration. - if (!ac->tags_mapped && type == TYPE_CPE && ac->oc[1].m4ac.chan_config == 1) { + if (!ac->tags_mapped && type == TYPE_CPE && + ac->oc[1].m4ac.chan_config == 1) { uint8_t layout_map[MAX_ELEM_ID*4][3]; int layout_map_tags; push_output_configuration(ac); av_log(ac->avctx, AV_LOG_DEBUG, "mono with CPE\n"); - if (set_default_channel_config(ac->avctx, layout_map, &layout_map_tags, - 2) < 0) + if (set_default_channel_config(ac->avctx, layout_map, + &layout_map_tags, 2) < 0) return NULL; if (output_configure(ac, layout_map, layout_map_tags, OC_TRIAL_FRAME, 1) < 0) @@ -532,15 +583,16 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id) ac->oc[1].m4ac.ps = 0; } // And vice-versa - if (!ac->tags_mapped && type == TYPE_SCE && ac->oc[1].m4ac.chan_config == 2) { - uint8_t layout_map[MAX_ELEM_ID*4][3]; + if (!ac->tags_mapped && type == TYPE_SCE && + ac->oc[1].m4ac.chan_config == 2) { + uint8_t layout_map[MAX_ELEM_ID * 4][3]; int layout_map_tags; push_output_configuration(ac); av_log(ac->avctx, AV_LOG_DEBUG, "stereo with SCE\n"); - if (set_default_channel_config(ac->avctx, layout_map, &layout_map_tags, - 1) < 0) + if (set_default_channel_config(ac->avctx, layout_map, + &layout_map_tags, 1) < 0) return NULL; if (output_configure(ac, layout_map, layout_map_tags, OC_TRIAL_FRAME, 1) < 0) @@ -550,7 +602,8 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id) if (ac->oc[1].m4ac.sbr) ac->oc[1].m4ac.ps = -1; } - // For indexed channel configurations map the channels solely based on position. + /* For indexed channel configurations map the channels solely based + * on position. */ switch (ac->oc[1].m4ac.chan_config) { case 7: if (ac->tags_mapped == 3 && type == TYPE_CPE) { @@ -558,9 +611,12 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id) return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][2]; } case 6: - /* Some streams incorrectly code 5.1 audio as SCE[0] CPE[0] CPE[1] SCE[1] - instead of SCE[0] CPE[0] CPE[1] LFE[0]. If we seem to have - encountered such a stream, transfer the LFE[0] element to the SCE[1]'s mapping */ + /* Some streams incorrectly code 5.1 audio as + * SCE[0] CPE[0] CPE[1] SCE[1] + * instead of + * SCE[0] CPE[0] CPE[1] LFE[0]. + * If we seem to have encountered such a stream, transfer + * the LFE[0] element to the SCE[1]'s mapping */ if (ac->tags_mapped == tags_per_config[ac->oc[1].m4ac.chan_config] - 1 && (type == TYPE_LFE || type == TYPE_SCE)) { ac->tags_mapped++; return ac->tag_che_map[type][elem_id] = ac->che[TYPE_LFE][0]; @@ -571,13 +627,16 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id) return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][1]; } case 4: - if (ac->tags_mapped == 2 && ac->oc[1].m4ac.chan_config == 4 && type == TYPE_SCE) { + if (ac->tags_mapped == 2 && + ac->oc[1].m4ac.chan_config == 4 && + type == TYPE_SCE) { ac->tags_mapped++; return ac->tag_che_map[TYPE_SCE][elem_id] = ac->che[TYPE_SCE][1]; } case 3: case 2: - if (ac->tags_mapped == (ac->oc[1].m4ac.chan_config != 2) && type == TYPE_CPE) { + if (ac->tags_mapped == (ac->oc[1].m4ac.chan_config != 2) && + type == TYPE_CPE) { ac->tags_mapped++; return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][0]; } else if (ac->oc[1].m4ac.chan_config == 2) { @@ -594,7 +653,8 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id) } /** - * Decode an array of 4 bit element IDs, optionally interleaved with a stereo/mono switching bit. + * Decode an array of 4 bit element IDs, optionally interleaved with a + * stereo/mono switching bit. * * @param type speaker type/position for these channels */ @@ -636,7 +696,8 @@ static int decode_pce(AVCodecContext *avctx, MPEG4AudioConfig *m4ac, uint8_t (*layout_map)[3], GetBitContext *gb) { - int num_front, num_side, num_back, num_lfe, num_assoc_data, num_cc, sampling_index; + int num_front, num_side, num_back, num_lfe, num_assoc_data, num_cc; + int sampling_index; int comment_len; int tags; @@ -644,7 +705,9 @@ static int decode_pce(AVCodecContext *avctx, MPEG4AudioConfig *m4ac, sampling_index = get_bits(gb, 4); if (m4ac->sampling_index != sampling_index) - av_log(avctx, AV_LOG_WARNING, "Sample rate index in program config element does not match the sample rate index configured by the container.\n"); + av_log(avctx, AV_LOG_WARNING, + "Sample rate index in program config element does not " + "match the sample rate index configured by the container.\n"); num_front = get_bits(gb, 4); num_side = get_bits(gb, 4); @@ -685,7 +748,7 @@ static int decode_pce(AVCodecContext *avctx, MPEG4AudioConfig *m4ac, comment_len = get_bits(gb, 8) * 8; if (get_bits_left(gb) < comment_len) { av_log(avctx, AV_LOG_ERROR, "decode_pce: " overread_err); - return -1; + return AVERROR_INVALIDDATA; } skip_bits_long(gb, comment_len); return tags; @@ -704,7 +767,7 @@ static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx, MPEG4AudioConfig *m4ac, int channel_config) { - int extension_flag, ret; + int extension_flag, ret, ep_config, res_flags; uint8_t layout_map[MAX_ELEM_ID*4][3]; int tags = 0; @@ -727,7 +790,8 @@ static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx, if (tags < 0) return tags; } else { - if ((ret = set_default_channel_config(avctx, layout_map, &tags, channel_config))) + if ((ret = set_default_channel_config(avctx, layout_map, + &tags, channel_config))) return ret; } @@ -749,14 +813,90 @@ static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx, case AOT_ER_AAC_LTP: case AOT_ER_AAC_SCALABLE: case AOT_ER_AAC_LD: - skip_bits(gb, 3); /* aacSectionDataResilienceFlag - * aacScalefactorDataResilienceFlag - * aacSpectralDataResilienceFlag - */ + res_flags = get_bits(gb, 3); + if (res_flags) { + avpriv_report_missing_feature(avctx, + "AAC data resilience (flags %x)", + res_flags); + return AVERROR_PATCHWELCOME; + } break; } skip_bits1(gb); // extensionFlag3 (TBD in version 3) } + switch (m4ac->object_type) { + case AOT_ER_AAC_LC: + case AOT_ER_AAC_LTP: + case AOT_ER_AAC_SCALABLE: + case AOT_ER_AAC_LD: + ep_config = get_bits(gb, 2); + if (ep_config) { + avpriv_report_missing_feature(avctx, + "epConfig %d", ep_config); + return AVERROR_PATCHWELCOME; + } + } + return 0; +} + +static int decode_eld_specific_config(AACContext *ac, AVCodecContext *avctx, + GetBitContext *gb, + MPEG4AudioConfig *m4ac, + int channel_config) +{ + int ret, ep_config, res_flags; + uint8_t layout_map[MAX_ELEM_ID*4][3]; + int tags = 0; + const int ELDEXT_TERM = 0; + + m4ac->ps = 0; + m4ac->sbr = 0; + + if (get_bits1(gb)) { // frameLengthFlag + avpriv_request_sample(avctx, "960/120 MDCT window"); + return AVERROR_PATCHWELCOME; + } + + res_flags = get_bits(gb, 3); + if (res_flags) { + avpriv_report_missing_feature(avctx, + "AAC data resilience (flags %x)", + res_flags); + return AVERROR_PATCHWELCOME; + } + + if (get_bits1(gb)) { // ldSbrPresentFlag + avpriv_report_missing_feature(avctx, + "Low Delay SBR"); + return AVERROR_PATCHWELCOME; + } + + while (get_bits(gb, 4) != ELDEXT_TERM) { + int len = get_bits(gb, 4); + if (len == 15) + len += get_bits(gb, 8); + if (len == 15 + 255) + len += get_bits(gb, 16); + if (get_bits_left(gb) < len * 8 + 4) { + av_log(ac->avctx, AV_LOG_ERROR, overread_err); + return AVERROR_INVALIDDATA; + } + skip_bits_long(gb, 8 * len); + } + + if ((ret = set_default_channel_config(avctx, layout_map, + &tags, channel_config))) + return ret; + + if (ac && (ret = output_configure(ac, layout_map, tags, OC_GLOBAL_HDR, 0))) + return ret; + + ep_config = get_bits(gb, 2); + if (ep_config) { + avpriv_report_missing_feature(avctx, + "epConfig %d", ep_config); + return AVERROR_PATCHWELCOME; + } return 0; } @@ -779,22 +919,31 @@ static int decode_audio_specific_config(AACContext *ac, int sync_extension) { GetBitContext gb; - int i; - int ret; + int i, ret; av_dlog(avctx, "audio specific config size %d\n", bit_size >> 3); for (i = 0; i < bit_size >> 3; i++) - av_dlog(avctx, "%02x ", data[i]); + av_dlog(avctx, "%02x ", data[i]); av_dlog(avctx, "\n"); if ((ret = init_get_bits(&gb, data, bit_size)) < 0) return ret; - if ((i = avpriv_mpeg4audio_get_config(m4ac, data, bit_size, sync_extension)) < 0) - return -1; + if ((i = avpriv_mpeg4audio_get_config(m4ac, data, bit_size, + sync_extension)) < 0) + return AVERROR_INVALIDDATA; if (m4ac->sampling_index > 12) { - av_log(avctx, AV_LOG_ERROR, "invalid sampling rate index %d\n", m4ac->sampling_index); - return -1; + av_log(avctx, AV_LOG_ERROR, + "invalid sampling rate index %d\n", + m4ac->sampling_index); + return AVERROR_INVALIDDATA; + } + if (m4ac->object_type == AOT_ER_AAC_LD && + (m4ac->sampling_index < 3 || m4ac->sampling_index > 7)) { + av_log(avctx, AV_LOG_ERROR, + "invalid low delay sampling rate index %d\n", + m4ac->sampling_index); + return AVERROR_INVALIDDATA; } skip_bits_long(&gb, i); @@ -803,18 +952,30 @@ static int decode_audio_specific_config(AACContext *ac, case AOT_AAC_MAIN: case AOT_AAC_LC: case AOT_AAC_LTP: - if (decode_ga_specific_config(ac, avctx, &gb, m4ac, m4ac->chan_config)) - return -1; + case AOT_ER_AAC_LC: + case AOT_ER_AAC_LD: + if ((ret = decode_ga_specific_config(ac, avctx, &gb, + m4ac, m4ac->chan_config)) < 0) + return ret; + break; + case AOT_ER_AAC_ELD: + if ((ret = decode_eld_specific_config(ac, avctx, &gb, + m4ac, m4ac->chan_config)) < 0) + return ret; break; default: - av_log(avctx, AV_LOG_ERROR, "Audio object type %s%d is not supported.\n", - m4ac->sbr == 1? "SBR+" : "", m4ac->object_type); - return -1; + avpriv_report_missing_feature(avctx, + "Audio object type %s%d", + m4ac->sbr == 1 ? "SBR+" : "", + m4ac->object_type); + return AVERROR(ENOSYS); } - av_dlog(avctx, "AOT %d chan config %d sampling index %d (%d) SBR %d PS %d\n", + av_dlog(avctx, + "AOT %d chan config %d sampling index %d (%d) SBR %d PS %d\n", m4ac->object_type, m4ac->chan_config, m4ac->sampling_index, - m4ac->sample_rate, m4ac->sbr, m4ac->ps); + m4ac->sample_rate, m4ac->sbr, + m4ac->ps); return get_bits_count(&gb); } @@ -872,10 +1033,12 @@ static void reset_predictor_group(PredictorState *ps, int group_num) reset_predict_state(&ps[i]); } -#define AAC_INIT_VLC_STATIC(num, size) \ - INIT_VLC_STATIC(&vlc_spectral[num], 8, ff_aac_spectral_sizes[num], \ - ff_aac_spectral_bits[num], sizeof( ff_aac_spectral_bits[num][0]), sizeof( ff_aac_spectral_bits[num][0]), \ - ff_aac_spectral_codes[num], sizeof(ff_aac_spectral_codes[num][0]), sizeof(ff_aac_spectral_codes[num][0]), \ +#define AAC_INIT_VLC_STATIC(num, size) \ + INIT_VLC_STATIC(&vlc_spectral[num], 8, ff_aac_spectral_sizes[num], \ + ff_aac_spectral_bits[num], sizeof(ff_aac_spectral_bits[num][0]), \ + sizeof(ff_aac_spectral_bits[num][0]), \ + ff_aac_spectral_codes[num], sizeof(ff_aac_spectral_codes[num][0]), \ + sizeof(ff_aac_spectral_codes[num][0]), \ size); static void aacdec_init(AACContext *ac); @@ -883,6 +1046,7 @@ static void aacdec_init(AACContext *ac); static av_cold int aac_decode_init(AVCodecContext *avctx) { AACContext *ac = avctx->priv_data; + int ret; ac->avctx = avctx; ac->oc[1].m4ac.sample_rate = avctx->sample_rate; @@ -892,10 +1056,11 @@ static av_cold int aac_decode_init(AVCodecContext *avctx) avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; if (avctx->extradata_size > 0) { - if (decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac, - avctx->extradata, - avctx->extradata_size*8, 1) < 0) - return -1; + if ((ret = decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac, + avctx->extradata, + avctx->extradata_size * 8, + 1)) < 0) + return ret; } else { int sr, i; uint8_t layout_map[MAX_ELEM_ID*4][3]; @@ -952,18 +1117,26 @@ static av_cold int aac_decode_init(AVCodecContext *avctx) ff_aac_tableinit(); - INIT_VLC_STATIC(&vlc_scalefactors,7,FF_ARRAY_ELEMS(ff_aac_scalefactor_code), - ff_aac_scalefactor_bits, sizeof(ff_aac_scalefactor_bits[0]), sizeof(ff_aac_scalefactor_bits[0]), - ff_aac_scalefactor_code, sizeof(ff_aac_scalefactor_code[0]), sizeof(ff_aac_scalefactor_code[0]), + INIT_VLC_STATIC(&vlc_scalefactors, 7, + FF_ARRAY_ELEMS(ff_aac_scalefactor_code), + ff_aac_scalefactor_bits, + sizeof(ff_aac_scalefactor_bits[0]), + sizeof(ff_aac_scalefactor_bits[0]), + ff_aac_scalefactor_code, + sizeof(ff_aac_scalefactor_code[0]), + sizeof(ff_aac_scalefactor_code[0]), 352); ff_mdct_init(&ac->mdct, 11, 1, 1.0 / (32768.0 * 1024.0)); + ff_mdct_init(&ac->mdct_ld, 10, 1, 1.0 / (32768.0 * 512.0)); ff_mdct_init(&ac->mdct_small, 8, 1, 1.0 / (32768.0 * 128.0)); ff_mdct_init(&ac->mdct_ltp, 11, 0, -2.0 * 32768.0); // window initialization ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024); + ff_kbd_window_init(ff_aac_kbd_long_512, 4.0, 512); ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128); ff_init_ff_sine_windows(10); + ff_init_ff_sine_windows( 9); ff_init_ff_sine_windows( 7); cbrt_tableinit(); @@ -985,7 +1158,7 @@ static int skip_data_stream_element(AACContext *ac, GetBitContext *gb) if (get_bits_left(gb) < 8 * count) { av_log(ac->avctx, AV_LOG_ERROR, "skip_data_stream_element: "overread_err); - return -1; + return AVERROR_INVALIDDATA; } skip_bits_long(gb, 8 * count); return 0; @@ -997,9 +1170,11 @@ static int decode_prediction(AACContext *ac, IndividualChannelStream *ics, int sfb; if (get_bits1(gb)) { ics->predictor_reset_group = get_bits(gb, 5); - if (ics->predictor_reset_group == 0 || ics->predictor_reset_group > 30) { - av_log(ac->avctx, AV_LOG_ERROR, "Invalid Predictor Reset Group.\n"); - return -1; + if (ics->predictor_reset_group == 0 || + ics->predictor_reset_group > 30) { + av_log(ac->avctx, AV_LOG_ERROR, + "Invalid Predictor Reset Group.\n"); + return AVERROR_INVALIDDATA; } } for (sfb = 0; sfb < FFMIN(ics->max_sfb, ff_aac_pred_sfb_max[ac->oc[1].m4ac.sampling_index]); sfb++) { @@ -1028,14 +1203,25 @@ static void decode_ltp(LongTermPrediction *ltp, static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics, GetBitContext *gb) { - if (get_bits1(gb)) { - av_log(ac->avctx, AV_LOG_ERROR, "Reserved bit set.\n"); - return AVERROR_INVALIDDATA; + int aot = ac->oc[1].m4ac.object_type; + if (aot != AOT_ER_AAC_ELD) { + if (get_bits1(gb)) { + av_log(ac->avctx, AV_LOG_ERROR, "Reserved bit set.\n"); + return AVERROR_INVALIDDATA; + } + ics->window_sequence[1] = ics->window_sequence[0]; + ics->window_sequence[0] = get_bits(gb, 2); + if (aot == AOT_ER_AAC_LD && + ics->window_sequence[0] != ONLY_LONG_SEQUENCE) { + av_log(ac->avctx, AV_LOG_ERROR, + "AAC LD is only defined for ONLY_LONG_SEQUENCE but " + "window sequence %d found.\n", ics->window_sequence[0]); + ics->window_sequence[0] = ONLY_LONG_SEQUENCE; + return AVERROR_INVALIDDATA; + } + ics->use_kb_window[1] = ics->use_kb_window[0]; + ics->use_kb_window[0] = get_bits1(gb); } - ics->window_sequence[1] = ics->window_sequence[0]; - ics->window_sequence[0] = get_bits(gb, 2); - ics->use_kb_window[1] = ics->use_kb_window[0]; - ics->use_kb_window[0] = get_bits1(gb); ics->num_window_groups = 1; ics->group_len[0] = 1; if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { @@ -1057,20 +1243,36 @@ static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics, } else { ics->max_sfb = get_bits(gb, 6); ics->num_windows = 1; - ics->swb_offset = ff_swb_offset_1024[ac->oc[1].m4ac.sampling_index]; - ics->num_swb = ff_aac_num_swb_1024[ac->oc[1].m4ac.sampling_index]; + if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD) { + ics->swb_offset = ff_swb_offset_512[ac->oc[1].m4ac.sampling_index]; + ics->num_swb = ff_aac_num_swb_512[ac->oc[1].m4ac.sampling_index]; + if (!ics->num_swb || !ics->swb_offset) + return AVERROR_BUG; + } else { + ics->swb_offset = ff_swb_offset_1024[ac->oc[1].m4ac.sampling_index]; + ics->num_swb = ff_aac_num_swb_1024[ac->oc[1].m4ac.sampling_index]; + } ics->tns_max_bands = ff_tns_max_bands_1024[ac->oc[1].m4ac.sampling_index]; - ics->predictor_present = get_bits1(gb); - ics->predictor_reset_group = 0; + if (aot != AOT_ER_AAC_ELD) { + ics->predictor_present = get_bits1(gb); + ics->predictor_reset_group = 0; + } if (ics->predictor_present) { - if (ac->oc[1].m4ac.object_type == AOT_AAC_MAIN) { + if (aot == AOT_AAC_MAIN) { if (decode_prediction(ac, ics, gb)) { goto fail; } - } else if (ac->oc[1].m4ac.object_type == AOT_AAC_LC) { - av_log(ac->avctx, AV_LOG_ERROR, "Prediction is not allowed in AAC-LC.\n"); + } else if (aot == AOT_AAC_LC || + aot == AOT_ER_AAC_LC) { + av_log(ac->avctx, AV_LOG_ERROR, + "Prediction is not allowed in AAC-LC.\n"); goto fail; } else { + if (aot == AOT_ER_AAC_LD) { + av_log(ac->avctx, AV_LOG_ERROR, + "LTP in ER AAC LD not yet implemented.\n"); + return AVERROR_PATCHWELCOME; + } if ((ics->ltp.present = get_bits(gb, 1))) decode_ltp(&ics->ltp, gb, ics->max_sfb); } @@ -1079,7 +1281,8 @@ static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics, if (ics->max_sfb > ics->num_swb) { av_log(ac->avctx, AV_LOG_ERROR, - "Number of scalefactor bands in group (%d) exceeds limit (%d).\n", + "Number of scalefactor bands in group (%d) " + "exceeds limit (%d).\n", ics->max_sfb, ics->num_swb); goto fail; } @@ -1112,20 +1315,20 @@ static int decode_band_types(AACContext *ac, enum BandType band_type[120], int sect_band_type = get_bits(gb, 4); if (sect_band_type == 12) { av_log(ac->avctx, AV_LOG_ERROR, "invalid band type\n"); - return -1; + return AVERROR_INVALIDDATA; } do { sect_len_incr = get_bits(gb, bits); sect_end += sect_len_incr; if (get_bits_left(gb) < 0) { av_log(ac->avctx, AV_LOG_ERROR, "decode_band_types: "overread_err); - return -1; + return AVERROR_INVALIDDATA; } if (sect_end > ics->max_sfb) { av_log(ac->avctx, AV_LOG_ERROR, "Number of bands (%d) exceeds limit (%d).\n", sect_end, ics->max_sfb); - return -1; + return AVERROR_INVALIDDATA; } } while (sect_len_incr == (1 << bits) - 1); for (; k < sect_end; k++) { @@ -1162,8 +1365,9 @@ static int decode_scalefactors(AACContext *ac, float sf[120], GetBitContext *gb, int run_end = band_type_run_end[idx]; if (band_type[idx] == ZERO_BT) { for (; i < run_end; i++, idx++) - sf[idx] = 0.; - } else if ((band_type[idx] == INTENSITY_BT) || (band_type[idx] == INTENSITY_BT2)) { + sf[idx] = 0.0; + } else if ((band_type[idx] == INTENSITY_BT) || + (band_type[idx] == INTENSITY_BT2)) { for (; i < run_end; i++, idx++) { offset[2] += get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60; clipped_offset = av_clip(offset[2], -155, 100); @@ -1196,7 +1400,7 @@ static int decode_scalefactors(AACContext *ac, float sf[120], GetBitContext *gb, if (offset[0] > 255U) { av_log(ac->avctx, AV_LOG_ERROR, "Scalefactor (%d) out of range.\n", offset[0]); - return -1; + return AVERROR_INVALIDDATA; } sf[idx] = -ff_aac_pow2sf_tab[offset[0] - 100 + POW_SF2_ZERO]; } @@ -1251,10 +1455,11 @@ static int decode_tns(AACContext *ac, TemporalNoiseShaping *tns, tns->length[w][filt] = get_bits(gb, 6 - 2 * is8); if ((tns->order[w][filt] = get_bits(gb, 5 - 2 * is8)) > tns_max_order) { - av_log(ac->avctx, AV_LOG_ERROR, "TNS filter order %d is greater than maximum %d.\n", + av_log(ac->avctx, AV_LOG_ERROR, + "TNS filter order %d is greater than maximum %d.\n", tns->order[w][filt], tns_max_order); tns->order[w][filt] = 0; - return -1; + return AVERROR_INVALIDDATA; } if (tns->order[w][filt]) { tns->direction[w][filt] = get_bits1(gb); @@ -1283,7 +1488,9 @@ static void decode_mid_side_stereo(ChannelElement *cpe, GetBitContext *gb, { int idx; if (ms_present == 1) { - for (idx = 0; idx < cpe->ch[0].ics.num_window_groups * cpe->ch[0].ics.max_sfb; idx++) + for (idx = 0; + idx < cpe->ch[0].ics.num_window_groups * cpe->ch[0].ics.max_sfb; + idx++) cpe->ms_mask[idx] = get_bits1(gb); } else if (ms_present == 2) { memset(cpe->ms_mask, 1, sizeof(cpe->ms_mask[0]) * cpe->ch[0].ics.num_window_groups * cpe->ch[0].ics.max_sfb); @@ -1382,7 +1589,8 @@ static int decode_spectrum_and_dequant(AACContext *ac, float coef[1024], float *coef_base = coef; for (g = 0; g < ics->num_windows; g++) - memset(coef + g * 128 + offsets[ics->max_sfb], 0, sizeof(float) * (c - offsets[ics->max_sfb])); + memset(coef + g * 128 + offsets[ics->max_sfb], 0, + sizeof(float) * (c - offsets[ics->max_sfb])); for (g = 0; g < ics->num_window_groups; g++) { unsigned g_len = ics->group_len[g]; @@ -1537,7 +1745,7 @@ static int decode_spectrum_and_dequant(AACContext *ac, float coef[1024], if (b > 8) { av_log(ac->avctx, AV_LOG_ERROR, "error in spectral data, ESC overflow\n"); - return -1; + return AVERROR_INVALIDDATA; } SKIP_BITS(re, gb, b + 1); @@ -1652,14 +1860,20 @@ static void apply_prediction(AACContext *ac, SingleChannelElement *sce) } if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) { - for (sfb = 0; sfb < ff_aac_pred_sfb_max[ac->oc[1].m4ac.sampling_index]; sfb++) { - for (k = sce->ics.swb_offset[sfb]; k < sce->ics.swb_offset[sfb + 1]; k++) { + for (sfb = 0; + sfb < ff_aac_pred_sfb_max[ac->oc[1].m4ac.sampling_index]; + sfb++) { + for (k = sce->ics.swb_offset[sfb]; + k < sce->ics.swb_offset[sfb + 1]; + k++) { predict(&sce->predictor_state[k], &sce->coeffs[k], - sce->ics.predictor_present && sce->ics.prediction_used[sfb]); + sce->ics.predictor_present && + sce->ics.prediction_used[sfb]); } } if (sce->ics.predictor_reset_group) - reset_predictor_group(sce->predictor_state, sce->ics.predictor_reset_group); + reset_predictor_group(sce->predictor_state, + sce->ics.predictor_reset_group); } else reset_all_predictors(sce->predictor_state); } @@ -1679,7 +1893,14 @@ static int decode_ics(AACContext *ac, SingleChannelElement *sce, TemporalNoiseShaping *tns = &sce->tns; IndividualChannelStream *ics = &sce->ics; float *out = sce->coeffs; - int global_gain, pulse_present = 0; + int global_gain, eld_syntax, er_syntax, pulse_present = 0; + int ret; + + eld_syntax = ac->oc[1].m4ac.object_type == AOT_ER_AAC_ELD; + er_syntax = ac->oc[1].m4ac.object_type == AOT_ER_AAC_LC || + ac->oc[1].m4ac.object_type == AOT_ER_AAC_LTP || + ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD || + ac->oc[1].m4ac.object_type == AOT_ER_AAC_ELD; /* This assignment is to silence a GCC warning about the variable being used * uninitialized when in fact it always is. @@ -1693,33 +1914,45 @@ static int decode_ics(AACContext *ac, SingleChannelElement *sce, return AVERROR_INVALIDDATA; } - if (decode_band_types(ac, sce->band_type, sce->band_type_run_end, gb, ics) < 0) - return -1; - if (decode_scalefactors(ac, sce->sf, gb, global_gain, ics, sce->band_type, sce->band_type_run_end) < 0) - return -1; + if ((ret = decode_band_types(ac, sce->band_type, + sce->band_type_run_end, gb, ics)) < 0) + return ret; + if ((ret = decode_scalefactors(ac, sce->sf, gb, global_gain, ics, + sce->band_type, sce->band_type_run_end)) < 0) + return ret; pulse_present = 0; if (!scale_flag) { - if ((pulse_present = get_bits1(gb))) { + if (!eld_syntax && (pulse_present = get_bits1(gb))) { if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { - av_log(ac->avctx, AV_LOG_ERROR, "Pulse tool not allowed in eight short sequence.\n"); - return -1; + av_log(ac->avctx, AV_LOG_ERROR, + "Pulse tool not allowed in eight short sequence.\n"); + return AVERROR_INVALIDDATA; } if (decode_pulses(&pulse, gb, ics->swb_offset, ics->num_swb)) { - av_log(ac->avctx, AV_LOG_ERROR, "Pulse data corrupt or invalid.\n"); - return -1; + av_log(ac->avctx, AV_LOG_ERROR, + "Pulse data corrupt or invalid.\n"); + return AVERROR_INVALIDDATA; } } - if ((tns->present = get_bits1(gb)) && decode_tns(ac, tns, gb, ics)) - return -1; - if (get_bits1(gb)) { + tns->present = get_bits1(gb); + if (tns->present && !er_syntax) + if (decode_tns(ac, tns, gb, ics) < 0) + return AVERROR_INVALIDDATA; + if (!eld_syntax && get_bits1(gb)) { avpriv_request_sample(ac->avctx, "SSR"); return AVERROR_PATCHWELCOME; } + // I see no textual basis in the spec for this occuring after SSR gain + // control, but this is what both reference and real implmentations do + if (tns->present && er_syntax) + if (decode_tns(ac, tns, gb, ics) < 0) + return AVERROR_INVALIDDATA; } - if (decode_spectrum_and_dequant(ac, out, gb, sce->sf, pulse_present, &pulse, ics, sce->band_type) < 0) - return -1; + if (decode_spectrum_and_dequant(ac, out, gb, sce->sf, pulse_present, + &pulse, ics, sce->band_type) < 0) + return AVERROR_INVALIDDATA; if (ac->oc[1].m4ac.object_type == AOT_AAC_MAIN && !common_window) apply_prediction(ac, sce); @@ -1740,7 +1973,8 @@ static void apply_mid_side_stereo(AACContext *ac, ChannelElement *cpe) for (g = 0; g < ics->num_window_groups; g++) { for (i = 0; i < ics->max_sfb; i++, idx++) { if (cpe->ms_mask[idx] && - cpe->ch[0].band_type[idx] < NOISE_BT && cpe->ch[1].band_type[idx] < NOISE_BT) { + cpe->ch[0].band_type[idx] < NOISE_BT && + cpe->ch[1].band_type[idx] < NOISE_BT) { for (group = 0; group < ics->group_len[g]; group++) { ac->fdsp.butterflies_float(ch0 + group * 128 + offsets[i], ch1 + group * 128 + offsets[i], @@ -1760,7 +1994,8 @@ static void apply_mid_side_stereo(AACContext *ac, ChannelElement *cpe) * [1] mask is decoded from bitstream; [2] mask is all 1s; * [3] reserved for scalable AAC */ -static void apply_intensity_stereo(AACContext *ac, ChannelElement *cpe, int ms_present) +static void apply_intensity_stereo(AACContext *ac, + ChannelElement *cpe, int ms_present) { const IndividualChannelStream *ics = &cpe->ch[1].ics; SingleChannelElement *sce1 = &cpe->ch[1]; @@ -1771,7 +2006,8 @@ static void apply_intensity_stereo(AACContext *ac, ChannelElement *cpe, int ms_p float scale; for (g = 0; g < ics->num_window_groups; g++) { for (i = 0; i < ics->max_sfb;) { - if (sce1->band_type[idx] == INTENSITY_BT || sce1->band_type[idx] == INTENSITY_BT2) { + if (sce1->band_type[idx] == INTENSITY_BT || + sce1->band_type[idx] == INTENSITY_BT2) { const int bt_run_end = sce1->band_type_run_end[idx]; for (; i < bt_run_end; i++, idx++) { c = -1 + 2 * (sce1->band_type[idx] - 14); @@ -1803,21 +2039,23 @@ static void apply_intensity_stereo(AACContext *ac, ChannelElement *cpe, int ms_p static int decode_cpe(AACContext *ac, GetBitContext *gb, ChannelElement *cpe) { int i, ret, common_window, ms_present = 0; + int eld_syntax = ac->oc[1].m4ac.object_type == AOT_ER_AAC_ELD; - common_window = get_bits1(gb); + common_window = eld_syntax || get_bits1(gb); if (common_window) { if (decode_ics_info(ac, &cpe->ch[0].ics, gb)) return AVERROR_INVALIDDATA; i = cpe->ch[1].ics.use_kb_window[0]; cpe->ch[1].ics = cpe->ch[0].ics; cpe->ch[1].ics.use_kb_window[1] = i; - if (cpe->ch[1].ics.predictor_present && (ac->oc[1].m4ac.object_type != AOT_AAC_MAIN)) + if (cpe->ch[1].ics.predictor_present && + (ac->oc[1].m4ac.object_type != AOT_AAC_MAIN)) if ((cpe->ch[1].ics.ltp.present = get_bits(gb, 1))) decode_ltp(&cpe->ch[1].ics.ltp, gb, cpe->ch[1].ics.max_sfb); ms_present = get_bits(gb, 2); if (ms_present == 3) { av_log(ac->avctx, AV_LOG_ERROR, "ms_present = 3 is reserved.\n"); - return -1; + return AVERROR_INVALIDDATA; } else if (ms_present) decode_mid_side_stereo(cpe, gb, ms_present); } @@ -1885,7 +2123,7 @@ static int decode_cce(AACContext *ac, GetBitContext *gb, ChannelElement *che) int idx = 0; int cge = 1; int gain = 0; - float gain_cache = 1.; + float gain_cache = 1.0; if (c) { cge = coup->coupling_point == AFTER_IMDCT ? 1 : get_bits1(gb); gain = cge ? get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60: 0; @@ -2045,10 +2283,12 @@ static int decode_extension_payload(AACContext *ac, GetBitContext *gb, int cnt, } else if (ac->oc[1].m4ac.ps == -1 && ac->oc[1].status < OC_LOCKED && ac->avctx->channels == 1) { ac->oc[1].m4ac.sbr = 1; ac->oc[1].m4ac.ps = 1; + ac->avctx->profile = FF_PROFILE_AAC_HE_V2; output_configure(ac, ac->oc[1].layout_map, ac->oc[1].layout_map_tags, ac->oc[1].status, 1); } else { ac->oc[1].m4ac.sbr = 1; + ac->avctx->profile = FF_PROFILE_AAC_HE; } res = ff_decode_sbr_extension(ac, &che->sbr, gb, crc_flag, cnt, elem_type); break; @@ -2282,6 +2522,81 @@ static void imdct_and_windowing(AACContext *ac, SingleChannelElement *sce) } } +static void imdct_and_windowing_ld(AACContext *ac, SingleChannelElement *sce) +{ + IndividualChannelStream *ics = &sce->ics; + float *in = sce->coeffs; + float *out = sce->ret; + float *saved = sce->saved; + const float *lwindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_long_512 : ff_sine_512; + float *buf = ac->buf_mdct; + + // imdct + ac->mdct.imdct_half(&ac->mdct_ld, buf, in); + + // window overlapping + ac->fdsp.vector_fmul_window(out, saved, buf, lwindow_prev, 256); + + // buffer update + memcpy(saved, buf + 256, 256 * sizeof(float)); +} + +static void imdct_and_windowing_eld(AACContext *ac, SingleChannelElement *sce) +{ + float *in = sce->coeffs; + float *out = sce->ret; + float *saved = sce->saved; + const float *const window = ff_aac_eld_window; + float *buf = ac->buf_mdct; + int i; + const int n = 512; + const int n2 = n >> 1; + const int n4 = n >> 2; + + // Inverse transform, mapped to the conventional IMDCT by + // Chivukula, R.K.; Reznik, Y.A.; Devarajan, V., + // "Efficient algorithms for MPEG-4 AAC-ELD, AAC-LD and AAC-LC filterbanks," + // International Conference on Audio, Language and Image Processing, ICALIP 2008. + // URL: http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=4590245&isnumber=4589950 + for (i = 0; i < n2; i+=2) { + float temp; + temp = in[i ]; in[i ] = -in[n - 1 - i]; in[n - 1 - i] = temp; + temp = -in[i + 1]; in[i + 1] = in[n - 2 - i]; in[n - 2 - i] = temp; + } + ac->mdct.imdct_half(&ac->mdct_ld, buf, in); + for (i = 0; i < n; i+=2) { + buf[i] = -buf[i]; + } + // Like with the regular IMDCT at this point we still have the middle half + // of a transform but with even symmetry on the left and odd symmetry on + // the right + + // window overlapping + // The spec says to use samples [0..511] but the reference decoder uses + // samples [128..639]. + for (i = n4; i < n2; i ++) { + out[i - n4] = buf[n2 - 1 - i] * window[i - n4] + + saved[ i + n2] * window[i + n - n4] + + -saved[ n + n2 - 1 - i] * window[i + 2*n - n4] + + -saved[2*n + n2 + i] * window[i + 3*n - n4]; + } + for (i = 0; i < n2; i ++) { + out[n4 + i] = buf[i] * window[i + n2 - n4] + + -saved[ n - 1 - i] * window[i + n2 + n - n4] + + -saved[ n + i] * window[i + n2 + 2*n - n4] + + saved[2*n + n - 1 - i] * window[i + n2 + 3*n - n4]; + } + for (i = 0; i < n4; i ++) { + out[n2 + n4 + i] = buf[ i + n2] * window[i + n - n4] + + -saved[ n2 - 1 - i] * window[i + 2*n - n4] + + -saved[ n + n2 + i] * window[i + 3*n - n4]; + } + + // buffer update + memmove(saved + n, saved, 2 * n * sizeof(float)); + memcpy( saved, buf, n * sizeof(float)); +} + /** * Apply dependent channel coupling (applied before IMDCT). * @@ -2378,6 +2693,17 @@ static void apply_channel_coupling(AACContext *ac, ChannelElement *cc, static void spectral_to_sample(AACContext *ac) { int i, type; + void (*imdct_and_window)(AACContext *ac, SingleChannelElement *sce); + switch (ac->oc[1].m4ac.object_type) { + case AOT_ER_AAC_LD: + imdct_and_window = imdct_and_windowing_ld; + break; + case AOT_ER_AAC_ELD: + imdct_and_window = imdct_and_windowing_eld; + break; + default: + imdct_and_window = ac->imdct_and_windowing; + } for (type = 3; type >= 0; type--) { for (i = 0; i < MAX_ELEM_ID; i++) { ChannelElement *che = ac->che[type][i]; @@ -2399,11 +2725,11 @@ static void spectral_to_sample(AACContext *ac) if (type <= TYPE_CPE) apply_channel_coupling(ac, che, type, i, BETWEEN_TNS_AND_IMDCT, apply_dependent_coupling); if (type != TYPE_CCE || che->coup.coupling_point == AFTER_IMDCT) { - ac->imdct_and_windowing(ac, &che->ch[0]); + imdct_and_window(ac, &che->ch[0]); if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) ac->update_ltp(ac, &che->ch[0]); if (type == TYPE_CPE) { - ac->imdct_and_windowing(ac, &che->ch[1]); + imdct_and_window(ac, &che->ch[1]); if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) ac->update_ltp(ac, &che->ch[1]); } @@ -2423,7 +2749,7 @@ static int parse_adts_frame_header(AACContext *ac, GetBitContext *gb) int size; AACADTSHeaderInfo hdr_info; uint8_t layout_map[MAX_ELEM_ID*4][3]; - int layout_map_tags; + int layout_map_tags, ret; size = avpriv_aac_parse_header(gb, &hdr_info); if (size > 0) { @@ -2437,12 +2763,15 @@ static int parse_adts_frame_header(AACContext *ac, GetBitContext *gb) push_output_configuration(ac); if (hdr_info.chan_config) { ac->oc[1].m4ac.chan_config = hdr_info.chan_config; - if (set_default_channel_config(ac->avctx, layout_map, - &layout_map_tags, hdr_info.chan_config)) - return -7; - if (output_configure(ac, layout_map, layout_map_tags, - FFMAX(ac->oc[1].status, OC_TRIAL_FRAME), 0)) - return -7; + if ((ret = set_default_channel_config(ac->avctx, + layout_map, + &layout_map_tags, + hdr_info.chan_config)) < 0) + return ret; + if ((ret = output_configure(ac, layout_map, layout_map_tags, + FFMAX(ac->oc[1].status, + OC_TRIAL_FRAME), 0)) < 0) + return ret; } else { ac->oc[1].m4ac.chan_config = 0; /** @@ -2476,6 +2805,70 @@ static int parse_adts_frame_header(AACContext *ac, GetBitContext *gb) return size; } +static int aac_decode_er_frame(AVCodecContext *avctx, void *data, + int *got_frame_ptr, GetBitContext *gb) +{ + AACContext *ac = avctx->priv_data; + ChannelElement *che; + int err, i; + int samples = 1024; + int chan_config = ac->oc[1].m4ac.chan_config; + int aot = ac->oc[1].m4ac.object_type; + + if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD) + samples >>= 1; + + ac->frame = data; + + if ((err = frame_configure_elements(avctx)) < 0) + return err; + + // The FF_PROFILE_AAC_* defines are all object_type - 1 + // This may lead to an undefined profile being signaled + ac->avctx->profile = ac->oc[1].m4ac.object_type - 1; + + ac->tags_mapped = 0; + + if (chan_config < 0 || chan_config >= 8) { + avpriv_request_sample(avctx, "Unknown ER channel configuration %d", + ac->oc[1].m4ac.chan_config); + return AVERROR_INVALIDDATA; + } + for (i = 0; i < tags_per_config[chan_config]; i++) { + const int elem_type = aac_channel_layout_map[chan_config-1][i][0]; + const int elem_id = aac_channel_layout_map[chan_config-1][i][1]; + if (!(che=get_che(ac, elem_type, elem_id))) { + av_log(ac->avctx, AV_LOG_ERROR, + "channel element %d.%d is not allocated\n", + elem_type, elem_id); + return AVERROR_INVALIDDATA; + } + if (aot != AOT_ER_AAC_ELD) + skip_bits(gb, 4); + switch (elem_type) { + case TYPE_SCE: + err = decode_ics(ac, &che->ch[0], gb, 0, 0); + break; + case TYPE_CPE: + err = decode_cpe(ac, gb, che); + break; + case TYPE_LFE: + err = decode_ics(ac, &che->ch[0], gb, 0, 0); + break; + } + if (err < 0) + return err; + } + + spectral_to_sample(ac); + + ac->frame->nb_samples = samples; + *got_frame_ptr = 1; + + skip_bits_long(gb, get_bits_left(gb)); + return 0; +} + static int aac_decode_frame_int(AVCodecContext *avctx, void *data, int *got_frame_ptr, GetBitContext *gb, AVPacket *avpkt) { @@ -2489,22 +2882,23 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, ac->frame = data; if (show_bits(gb, 12) == 0xfff) { - if (parse_adts_frame_header(ac, gb) < 0) { + if ((err = parse_adts_frame_header(ac, gb)) < 0) { av_log(avctx, AV_LOG_ERROR, "Error decoding AAC frame header.\n"); - err = -1; goto fail; } if (ac->oc[1].m4ac.sampling_index > 12) { av_log(ac->avctx, AV_LOG_ERROR, "invalid sampling rate index %d\n", ac->oc[1].m4ac.sampling_index); - err = -1; + err = AVERROR_INVALIDDATA; goto fail; } } - if (frame_configure_elements(avctx) < 0) { - err = -1; + if ((err = frame_configure_elements(avctx)) < 0) goto fail; - } + + // The FF_PROFILE_AAC_* defines are all object_type - 1 + // This may lead to an undefined profile being signaled + ac->avctx->profile = ac->oc[1].m4ac.object_type - 1; ac->tags_mapped = 0; // parse @@ -2515,7 +2909,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, if (!(che=get_che(ac, elem_type, elem_id))) { av_log(ac->avctx, AV_LOG_ERROR, "channel element %d.%d is not allocated\n", elem_type, elem_id); - err = -1; + err = AVERROR_INVALIDDATA; goto fail; } samples = 1024; @@ -2573,7 +2967,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, elem_id += get_bits(gb, 8) - 1; if (get_bits_left(gb) < 8 * elem_id) { av_log(avctx, AV_LOG_ERROR, "TYPE_FIL: "overread_err); - err = -1; + err = AVERROR_INVALIDDATA; goto fail; } while (elem_id > 0) @@ -2582,7 +2976,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, break; default: - err = -1; /* should not happen, but keeps compiler happy */ + err = AVERROR_BUG; /* should not happen, but keeps compiler happy */ break; } @@ -2594,7 +2988,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, if (get_bits_left(gb) < 3) { av_log(avctx, AV_LOG_ERROR, overread_err); - err = -1; + err = AVERROR_INVALIDDATA; goto fail; } } @@ -2609,6 +3003,8 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, if (samples) ac->frame->nb_samples = samples; + else + av_frame_unref(ac->frame); *got_frame_ptr = !!samples; if (is_dmono) { @@ -2681,9 +3077,20 @@ static int aac_decode_frame(AVCodecContext *avctx, void *data, if (INT_MAX / 8 <= buf_size) return AVERROR_INVALIDDATA; - init_get_bits(&gb, buf, buf_size * 8); + if ((err = init_get_bits(&gb, buf, buf_size * 8)) < 0) + return err; - if ((err = aac_decode_frame_int(avctx, data, got_frame_ptr, &gb, avpkt)) < 0) + switch (ac->oc[1].m4ac.object_type) { + case AOT_ER_AAC_LC: + case AOT_ER_AAC_LTP: + case AOT_ER_AAC_LD: + case AOT_ER_AAC_ELD: + err = aac_decode_er_frame(avctx, data, got_frame_ptr, &gb); + break; + default: + err = aac_decode_frame_int(avctx, data, got_frame_ptr, &gb, avpkt); + } + if (err < 0) return err; buf_consumed = (get_bits_count(&gb) + 7) >> 3; @@ -2709,6 +3116,7 @@ static av_cold int aac_decode_close(AVCodecContext *avctx) ff_mdct_end(&ac->mdct); ff_mdct_end(&ac->mdct_small); + ff_mdct_end(&ac->mdct_ld); ff_mdct_end(&ac->mdct_ltp); return 0; } @@ -2717,13 +3125,13 @@ static av_cold int aac_decode_close(AVCodecContext *avctx) #define LOAS_SYNC_WORD 0x2b7 ///< 11 bits LOAS sync word struct LATMContext { - AACContext aac_ctx; ///< containing AACContext - int initialized; ///< initialized after a valid extradata was seen + AACContext aac_ctx; ///< containing AACContext + int initialized; ///< initialized after a valid extradata was seen // parser data - int audio_mux_version_A; ///< LATM syntax version - int frame_length_type; ///< 0/1 variable/fixed frame length - int frame_length; ///< frame length for fixed frame length + int audio_mux_version_A; ///< LATM syntax version + int frame_length_type; ///< 0/1 variable/fixed frame length + int frame_length; ///< frame length for fixed frame length }; static inline uint32_t latm_get_value(GetBitContext *b) @@ -3021,13 +3429,13 @@ static const AVClass aac_decoder_class = { AVCodec ff_aac_decoder = { .name = "aac", + .long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_AAC, .priv_data_size = sizeof(AACContext), .init = aac_decode_init, .close = aac_decode_close, .decode = aac_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, @@ -3044,13 +3452,13 @@ AVCodec ff_aac_decoder = { */ AVCodec ff_aac_latm_decoder = { .name = "aac_latm", + .long_name = NULL_IF_CONFIG_SMALL("AAC LATM (Advanced Audio Coding LATM syntax)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_AAC_LATM, .priv_data_size = sizeof(struct LATMContext), .init = latm_decode_init, .close = aac_decode_close, .decode = latm_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("AAC LATM (Advanced Audio Coding LATM syntax)"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, diff --git a/ffmpeg/libavcodec/aacenc.c b/ffmpeg/libavcodec/aacenc.c index 80dd3d8..5596b4b 100644 --- a/ffmpeg/libavcodec/aacenc.c +++ b/ffmpeg/libavcodec/aacenc.c @@ -593,7 +593,7 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, coeffs[ch] = cpe->ch[ch].coeffs; s->psy.model->analyze(&s->psy, start_ch, coeffs, wi); for (ch = 0; ch < chans; ch++) { - s->cur_channel = start_ch * 2 + ch; + s->cur_channel = start_ch + ch; s->coder->search_for_quantizers(avctx, s, &cpe->ch[ch], s->lambda); } cpe->common_window = 0; @@ -609,7 +609,7 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, } } } - s->cur_channel = start_ch * 2; + s->cur_channel = start_ch; if (s->options.stereo_mode && cpe->common_window) { if (s->options.stereo_mode > 0) { IndividualChannelStream *ics = &cpe->ch[0].ics; @@ -791,7 +791,11 @@ static const AVOption aacenc_options[] = { {"auto", "Selected by the Encoder", 0, AV_OPT_TYPE_CONST, {.i64 = -1 }, INT_MIN, INT_MAX, AACENC_FLAGS, "stereo_mode"}, {"ms_off", "Disable Mid/Side coding", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, INT_MIN, INT_MAX, AACENC_FLAGS, "stereo_mode"}, {"ms_force", "Force Mid/Side for the whole frame if possible", 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, INT_MIN, INT_MAX, AACENC_FLAGS, "stereo_mode"}, - {"aac_coder", "", offsetof(AACEncContext, options.aac_coder), AV_OPT_TYPE_INT, {.i64 = 2}, 0, AAC_CODER_NB-1, AACENC_FLAGS}, + {"aac_coder", "", offsetof(AACEncContext, options.aac_coder), AV_OPT_TYPE_INT, {.i64 = AAC_CODER_TWOLOOP}, 0, AAC_CODER_NB-1, AACENC_FLAGS, "aac_coder"}, + {"faac", "FAAC-inspired method", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_FAAC}, INT_MIN, INT_MAX, AACENC_FLAGS, "aac_coder"}, + {"anmr", "ANMR method", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_ANMR}, INT_MIN, INT_MAX, AACENC_FLAGS, "aac_coder"}, + {"twoloop", "Two loop searching method", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_TWOLOOP}, INT_MIN, INT_MAX, AACENC_FLAGS, "aac_coder"}, + {"fast", "Constant quantizer", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_FAST}, INT_MIN, INT_MAX, AACENC_FLAGS, "aac_coder"}, {NULL} }; @@ -811,6 +815,7 @@ static const int mpeg4audio_sample_rates[16] = { AVCodec ff_aac_encoder = { .name = "aac", + .long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_AAC, .priv_data_size = sizeof(AACEncContext), @@ -822,6 +827,5 @@ AVCodec ff_aac_encoder = { CODEC_CAP_EXPERIMENTAL, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"), .priv_class = &aacenc_class, }; diff --git a/ffmpeg/libavcodec/aacenc.h b/ffmpeg/libavcodec/aacenc.h index cebdd18..ecd6811 100644 --- a/ffmpeg/libavcodec/aacenc.h +++ b/ffmpeg/libavcodec/aacenc.h @@ -30,7 +30,14 @@ #include "audio_frame_queue.h" #include "psymodel.h" -#define AAC_CODER_NB 4 +typedef enum AACCoder { + AAC_CODER_FAAC = 0, + AAC_CODER_ANMR, + AAC_CODER_TWOLOOP, + AAC_CODER_FAST, + + AAC_CODER_NB, +}AACCoder; typedef struct AACEncOptions { int stereo_mode; diff --git a/ffmpeg/libavcodec/aacps.c b/ffmpeg/libavcodec/aacps.c index b82001e..9b7bdae 100644 --- a/ffmpeg/libavcodec/aacps.c +++ b/ffmpeg/libavcodec/aacps.c @@ -322,14 +322,15 @@ static void hybrid2_re(float (*in)[2], float (*out)[32][2], const float filter[8 } /** Split one subband into 6 subsubbands with a complex filter */ -static void hybrid6_cx(PSDSPContext *dsp, float (*in)[2], float (*out)[32][2], const float (*filter)[8][2], int len) +static void hybrid6_cx(PSDSPContext *dsp, float (*in)[2], float (*out)[32][2], + TABLE_CONST float (*filter)[8][2], int len) { int i; int N = 8; LOCAL_ALIGNED_16(float, temp, [8], [2]); for (i = 0; i < len; i++, in++) { - dsp->hybrid_analysis(temp, in, filter, 1, N); + dsp->hybrid_analysis(temp, in, (const float (*)[8][2]) filter, 1, N); out[0][i][0] = temp[6][0]; out[0][i][1] = temp[6][1]; out[1][i][0] = temp[7][0]; @@ -345,12 +346,14 @@ static void hybrid6_cx(PSDSPContext *dsp, float (*in)[2], float (*out)[32][2], c } } -static void hybrid4_8_12_cx(PSDSPContext *dsp, float (*in)[2], float (*out)[32][2], const float (*filter)[8][2], int N, int len) +static void hybrid4_8_12_cx(PSDSPContext *dsp, + float (*in)[2], float (*out)[32][2], + TABLE_CONST float (*filter)[8][2], int N, int len) { int i; for (i = 0; i < len; i++, in++) { - dsp->hybrid_analysis(out[0] + i, in, filter, 32, N); + dsp->hybrid_analysis(out[0] + i, in, (const float (*)[8][2]) filter, 32, N); } } @@ -685,7 +688,8 @@ static void decorrelation(PSContext *ps, float (*out)[32][2], const float (*s)[3 memcpy(ap_delay[k][m], ap_delay[k][m]+numQMFSlots, 5*sizeof(ap_delay[k][m][0])); } ps->dsp.decorrelate(out[k], delay[k] + PS_MAX_DELAY - 2, ap_delay[k], - phi_fract[is34][k], Q_fract_allpass[is34][k], + phi_fract[is34][k], + (const float (*)[2]) Q_fract_allpass[is34][k], transient_gain[b], g_decay_slope, nL - n0); } for (; k < SHORT_DELAY_BAND[is34]; k++) { @@ -763,7 +767,7 @@ static void stereo_processing(PSContext *ps, float (*l)[32][2], float (*r)[32][2 int8_t (*ipd_mapped)[PS_MAX_NR_IIDICC] = ipd_mapped_buf; int8_t (*opd_mapped)[PS_MAX_NR_IIDICC] = opd_mapped_buf; const int8_t *k_to_i = is34 ? k_to_i_34 : k_to_i_20; - const float (*H_LUT)[8][4] = (PS_BASELINE || ps->icc_mode < 3) ? HA : HB; + TABLE_CONST float (*H_LUT)[8][4] = (PS_BASELINE || ps->icc_mode < 3) ? HA : HB; //Remapping if (ps->num_env_old) { @@ -823,7 +827,8 @@ static void stereo_processing(PSContext *ps, float (*l)[32][2], float (*r)[32][2 h12 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps->iid_quant][icc_mapped[e][b]][1]; h21 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps->iid_quant][icc_mapped[e][b]][2]; h22 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps->iid_quant][icc_mapped[e][b]][3]; - if (!PS_BASELINE && ps->enable_ipdopd && b < ps->nr_ipdopd_par) { + + if (!PS_BASELINE && ps->enable_ipdopd && 2*b <= NR_PAR_BANDS[is34]) { //The spec say says to only run this smoother when enable_ipdopd //is set but the reference decoder appears to run it constantly float h11i, h12i, h21i, h22i; @@ -913,7 +918,7 @@ int ff_ps_apply(AVCodecContext *avctx, PSContext *ps, float L[2][38][64], float memset(ps->ap_delay + top, 0, (NR_ALLPASS_BANDS[is34] - top)*sizeof(ps->ap_delay[0])); hybrid_analysis(&ps->dsp, Lbuf, ps->in_buf, L, is34, len); - decorrelation(ps, Rbuf, Lbuf, is34); + decorrelation(ps, Rbuf, (const float (*)[32][2]) Lbuf, is34); stereo_processing(ps, Lbuf, Rbuf, is34); hybrid_synthesis(&ps->dsp, L, Lbuf, is34, len); hybrid_synthesis(&ps->dsp, R, Rbuf, is34, len); diff --git a/ffmpeg/libavcodec/aacps_tablegen.c b/ffmpeg/libavcodec/aacps_tablegen.c index f56930b..47d4205 100644 --- a/ffmpeg/libavcodec/aacps_tablegen.c +++ b/ffmpeg/libavcodec/aacps_tablegen.c @@ -82,7 +82,7 @@ int main(void) write_float_3d_array(f34_2_4, 4, 8, 2); printf("};\n"); - printf("static const DECLARE_ALIGNED(16, float, Q_fract_allpass)[2][50][3][2] = {\n"); + printf("static TABLE_CONST DECLARE_ALIGNED(16, float, Q_fract_allpass)[2][50][3][2] = {\n"); write_float_4d_array(Q_fract_allpass, 2, 50, 3, 2); printf("};\n"); printf("static const DECLARE_ALIGNED(16, float, phi_fract)[2][50][2] = {\n"); diff --git a/ffmpeg/libavcodec/aacps_tablegen.h b/ffmpeg/libavcodec/aacps_tablegen.h index 1f9c326..9df38ff 100644 --- a/ffmpeg/libavcodec/aacps_tablegen.h +++ b/ffmpeg/libavcodec/aacps_tablegen.h @@ -28,6 +28,7 @@ #if CONFIG_HARDCODED_TABLES #define ps_tableinit() +#define TABLE_CONST const #include "libavcodec/aacps_tables.h" #else #include "libavutil/common.h" @@ -37,6 +38,7 @@ #define NR_ALLPASS_BANDS20 30 #define NR_ALLPASS_BANDS34 50 #define PS_AP_LINKS 3 +#define TABLE_CONST static float pd_re_smooth[8*8*8]; static float pd_im_smooth[8*8*8]; static float HA[46][8][4]; @@ -45,7 +47,7 @@ static DECLARE_ALIGNED(16, float, f20_0_8) [ 8][8][2]; static DECLARE_ALIGNED(16, float, f34_0_12)[12][8][2]; static DECLARE_ALIGNED(16, float, f34_1_8) [ 8][8][2]; static DECLARE_ALIGNED(16, float, f34_2_4) [ 4][8][2]; -static DECLARE_ALIGNED(16, float, Q_fract_allpass)[2][50][3][2]; +static TABLE_CONST DECLARE_ALIGNED(16, float, Q_fract_allpass)[2][50][3][2]; static DECLARE_ALIGNED(16, float, phi_fract)[2][50][2]; static const float g0_Q8[] = { @@ -192,7 +194,7 @@ static void ps_tableinit(void) for (k = 0; k < NR_ALLPASS_BANDS34; k++) { double f_center, theta; if (k < FF_ARRAY_ELEMS(f_center_34)) - f_center = f_center_34[k] / 24.; + f_center = f_center_34[k] / 24.0; else f_center = k - 26.5f; for (m = 0; m < PS_AP_LINKS; m++) { diff --git a/ffmpeg/libavcodec/aacpsdsp.c b/ffmpeg/libavcodec/aacpsdsp.c index 9526d3a..5dc1a6a 100644 --- a/ffmpeg/libavcodec/aacpsdsp.c +++ b/ffmpeg/libavcodec/aacpsdsp.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2010 Alex Converse * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -93,7 +93,7 @@ static void ps_hybrid_synthesis_deint_c(float out[2][38][64], static void ps_decorrelate_c(float (*out)[2], float (*delay)[2], float (*ap_delay)[PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2], - const float phi_fract[2], float (*Q_fract)[2], + const float phi_fract[2], const float (*Q_fract)[2], const float *transient_gain, float g_decay_slope, int len) diff --git a/ffmpeg/libavcodec/aacpsdsp.h b/ffmpeg/libavcodec/aacpsdsp.h index df01e0b..0ef3023 100644 --- a/ffmpeg/libavcodec/aacpsdsp.h +++ b/ffmpeg/libavcodec/aacpsdsp.h @@ -1,20 +1,20 @@ /* * Copyright (c) 2012 Mans Rullgard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -38,7 +38,7 @@ typedef struct PSDSPContext { int i, int len); void (*decorrelate)(float (*out)[2], float (*delay)[2], float (*ap_delay)[PS_QMF_TIME_SLOTS+PS_MAX_AP_DELAY][2], - const float phi_fract[2], float (*Q_fract)[2], + const float phi_fract[2], const float (*Q_fract)[2], const float *transient_gain, float g_decay_slope, int len); diff --git a/ffmpeg/libavcodec/aacpsy.c b/ffmpeg/libavcodec/aacpsy.c index e399be5..d2a782e 100644 --- a/ffmpeg/libavcodec/aacpsy.c +++ b/ffmpeg/libavcodec/aacpsy.c @@ -24,6 +24,7 @@ * AAC encoder psychoacoustic model */ +#include "libavutil/attributes.h" #include "libavutil/libm.h" #include "avcodec.h" @@ -217,6 +218,10 @@ static const float psy_fir_coeffs[] = { -5.52212e-17 * 2, -0.313819 * 2 }; +#if ARCH_MIPS +# include "mips/aacpsy_mips.h" +#endif /* ARCH_MIPS */ + /** * Calculate the ABR attack threshold from the above LAME psymodel table. */ @@ -250,7 +255,8 @@ static float lame_calc_attack_threshold(int bitrate) /** * LAME psy model specific initialization */ -static void lame_window_init(AacPsyContext *ctx, AVCodecContext *avctx) { +static av_cold void lame_window_init(AacPsyContext *ctx, AVCodecContext *avctx) +{ int i, j; for (i = 0; i < avctx->channels; i++) { @@ -312,7 +318,7 @@ static av_cold int psy_3gpp_init(FFPsyContext *ctx) { AacPsyCoeffs *coeffs = pctx->psy_coef[j]; const uint8_t *band_sizes = ctx->bands[j]; float line_to_frequency = ctx->avctx->sample_rate / (j ? 256.f : 2048.0f); - float avg_chan_bits = chan_bitrate / ctx->avctx->sample_rate * (j ? 128.0f : 1024.0f); + float avg_chan_bits = chan_bitrate * (j ? 128.0f : 1024.0f) / ctx->avctx->sample_rate; /* reference encoder uses 2.4% here instead of 60% like the spec says */ float bark_pe = 0.024f * PSY_3GPP_BITS_TO_PE(avg_chan_bits) / num_bark; float en_spread_low = j ? PSY_3GPP_EN_SPREAD_LOW_S : PSY_3GPP_EN_SPREAD_LOW_L; @@ -560,25 +566,12 @@ static float calc_reduced_thr_3gpp(AacPsyBand *band, float min_snr, return thr; } -/** - * Calculate band thresholds as suggested in 3GPP TS26.403 - */ -static void psy_3gpp_analyze_channel(FFPsyContext *ctx, int channel, - const float *coefs, const FFPsyWindowInfo *wi) +#ifndef calc_thr_3gpp +static void calc_thr_3gpp(const FFPsyWindowInfo *wi, const int num_bands, AacPsyChannel *pch, + const uint8_t *band_sizes, const float *coefs) { - AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data; - AacPsyChannel *pch = &pctx->ch[channel]; - int start = 0; int i, w, g; - float desired_bits, desired_pe, delta_pe, reduction= NAN, spread_en[128] = {0}; - float a = 0.0f, active_lines = 0.0f, norm_fac = 0.0f; - float pe = pctx->chan_bitrate > 32000 ? 0.0f : FFMAX(50.0f, 100.0f - pctx->chan_bitrate * 100.0f / 32000.0f); - const int num_bands = ctx->num_bands[wi->num_windows == 8]; - const uint8_t *band_sizes = ctx->bands[wi->num_windows == 8]; - AacPsyCoeffs *coeffs = pctx->psy_coef[wi->num_windows == 8]; - const float avoid_hole_thr = wi->num_windows == 8 ? PSY_3GPP_AH_THR_SHORT : PSY_3GPP_AH_THR_LONG; - - //calculate energies, initial thresholds and related values - 5.4.2 "Threshold Calculation" + int start = 0; for (w = 0; w < wi->num_windows*16; w += 16) { for (g = 0; g < num_bands; g++) { AacPsyBand *band = &pch->band[w+g]; @@ -597,6 +590,48 @@ static void psy_3gpp_analyze_channel(FFPsyContext *ctx, int channel, start += band_sizes[g]; } } +} +#endif /* calc_thr_3gpp */ + +#ifndef psy_hp_filter +static void psy_hp_filter(const float *firbuf, float *hpfsmpl, const float *psy_fir_coeffs) +{ + int i, j; + for (i = 0; i < AAC_BLOCK_SIZE_LONG; i++) { + float sum1, sum2; + sum1 = firbuf[i + (PSY_LAME_FIR_LEN - 1) / 2]; + sum2 = 0.0; + for (j = 0; j < ((PSY_LAME_FIR_LEN - 1) / 2) - 1; j += 2) { + sum1 += psy_fir_coeffs[j] * (firbuf[i + j] + firbuf[i + PSY_LAME_FIR_LEN - j]); + sum2 += psy_fir_coeffs[j + 1] * (firbuf[i + j + 1] + firbuf[i + PSY_LAME_FIR_LEN - j - 1]); + } + /* NOTE: The LAME psymodel expects it's input in the range -32768 to 32768. + * Tuning this for normalized floats would be difficult. */ + hpfsmpl[i] = (sum1 + sum2) * 32768.0f; + } +} +#endif /* psy_hp_filter */ + +/** + * Calculate band thresholds as suggested in 3GPP TS26.403 + */ +static void psy_3gpp_analyze_channel(FFPsyContext *ctx, int channel, + const float *coefs, const FFPsyWindowInfo *wi) +{ + AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data; + AacPsyChannel *pch = &pctx->ch[channel]; + int i, w, g; + float desired_bits, desired_pe, delta_pe, reduction= NAN, spread_en[128] = {0}; + float a = 0.0f, active_lines = 0.0f, norm_fac = 0.0f; + float pe = pctx->chan_bitrate > 32000 ? 0.0f : FFMAX(50.0f, 100.0f - pctx->chan_bitrate * 100.0f / 32000.0f); + const int num_bands = ctx->num_bands[wi->num_windows == 8]; + const uint8_t *band_sizes = ctx->bands[wi->num_windows == 8]; + AacPsyCoeffs *coeffs = pctx->psy_coef[wi->num_windows == 8]; + const float avoid_hole_thr = wi->num_windows == 8 ? PSY_3GPP_AH_THR_SHORT : PSY_3GPP_AH_THR_LONG; + + //calculate energies, initial thresholds and related values - 5.4.2 "Threshold Calculation" + calc_thr_3gpp(wi, num_bands, pch, band_sizes, coefs); + //modify thresholds and energies - spread, threshold in quiet, pre-echo control for (w = 0; w < wi->num_windows*16; w += 16) { AacPsyBand *bands = &pch->band[w]; @@ -802,20 +837,10 @@ static FFPsyWindowInfo psy_lame_window(FFPsyContext *ctx, const float *audio, float energy_subshort[(AAC_NUM_BLOCKS_SHORT + 1) * PSY_LAME_NUM_SUBBLOCKS]; float energy_short[AAC_NUM_BLOCKS_SHORT + 1] = { 0 }; const float *firbuf = la + (AAC_BLOCK_SIZE_SHORT/4 - PSY_LAME_FIR_LEN); - int j, att_sum = 0; + int att_sum = 0; /* LAME comment: apply high pass filter of fs/4 */ - for (i = 0; i < AAC_BLOCK_SIZE_LONG; i++) { - float sum1, sum2; - sum1 = firbuf[i + (PSY_LAME_FIR_LEN - 1) / 2]; - sum2 = 0.0; - for (j = 0; j < ((PSY_LAME_FIR_LEN - 1) / 2) - 1; j += 2) { - sum1 += psy_fir_coeffs[j] * (firbuf[i + j] + firbuf[i + PSY_LAME_FIR_LEN - j]); - sum2 += psy_fir_coeffs[j + 1] * (firbuf[i + j + 1] + firbuf[i + PSY_LAME_FIR_LEN - j - 1]); - } - /* NOTE: The LAME psymodel expects it's input in the range -32768 to 32768. Tuning this for normalized floats would be difficult. */ - hpfsmpl[i] = (sum1 + sum2) * 32768.0f; - } + psy_hp_filter(firbuf, hpfsmpl, psy_fir_coeffs); /* Calculate the energies of each sub-shortblock */ for (i = 0; i < PSY_LAME_NUM_SUBBLOCKS; i++) { diff --git a/ffmpeg/libavcodec/aacpsy.h b/ffmpeg/libavcodec/aacpsy.h deleted file mode 100644 index 05c93cd..0000000 --- a/ffmpeg/libavcodec/aacpsy.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * AAC encoder psychoacoustic model - * Copyright (C) 2008 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_AACPSY_H -#define AVCODEC_AACPSY_H - -#include "avcodec.h" -#include "aac.h" -//#include "lowpass.h" - -enum AACPsyModelType{ - AAC_PSY_TEST, ///< a sample model to exercise encoder - AAC_PSY_3GPP, ///< model following recommendations from 3GPP TS 26.403 - - AAC_NB_PSY_MODELS ///< total number of psychoacoustic models, since it's not a part of the ABI new models can be added freely -}; - -/** - * context used by psychoacoustic model - */ -typedef struct AACPsyContext { - AVCodecContext *avctx; ///< encoder context -}AACPsyContext; - -/** - * Cleanup model context at the end. - * - * @param ctx model context - */ -void ff_aac_psy_end(AACPsyContext *ctx); - -#endif /* AVCODEC_AACPSY_H */ diff --git a/ffmpeg/libavcodec/aacsbr.c b/ffmpeg/libavcodec/aacsbr.c index 0b6779c..290fb81 100644 --- a/ffmpeg/libavcodec/aacsbr.c +++ b/ffmpeg/libavcodec/aacsbr.c @@ -932,6 +932,7 @@ static void read_sbr_extension(AACContext *ac, SpectralBandReplication *sbr, } else { #if 1 *num_bits_left -= ff_ps_read_data(ac->avctx, gb, &sbr->ps, *num_bits_left); + ac->avctx->profile = FF_PROFILE_AAC_HE_V2; #else avpriv_report_missing_feature(ac->avctx, "Parametric Stereo"); skip_bits_long(gb, *num_bits_left); // bs_fill_bits @@ -1701,12 +1702,18 @@ void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac, sbr_qmf_analysis(&ac->fdsp, &sbr->mdct_ana, &sbr->dsp, ch ? R : L, sbr->data[ch].analysis_filterbank_samples, (float*)sbr->qmf_filter_scratch, sbr->data[ch].W, sbr->data[ch].Ypos); - sbr->c.sbr_lf_gen(ac, sbr, sbr->X_low, sbr->data[ch].W, sbr->data[ch].Ypos); + sbr->c.sbr_lf_gen(ac, sbr, sbr->X_low, + (const float (*)[32][32][2]) sbr->data[ch].W, + sbr->data[ch].Ypos); sbr->data[ch].Ypos ^= 1; if (sbr->start) { - sbr->c.sbr_hf_inverse_filter(&sbr->dsp, sbr->alpha0, sbr->alpha1, sbr->X_low, sbr->k[0]); + sbr->c.sbr_hf_inverse_filter(&sbr->dsp, sbr->alpha0, sbr->alpha1, + (const float (*)[40][2]) sbr->X_low, sbr->k[0]); sbr_chirp(sbr, &sbr->data[ch]); - sbr_hf_gen(ac, sbr, sbr->X_high, sbr->X_low, sbr->alpha0, sbr->alpha1, + sbr_hf_gen(ac, sbr, sbr->X_high, + (const float (*)[40][2]) sbr->X_low, + (const float (*)[2]) sbr->alpha0, + (const float (*)[2]) sbr->alpha1, sbr->data[ch].bw_array, sbr->data[ch].t_env, sbr->data[ch].bs_num_env); @@ -1716,16 +1723,17 @@ void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac, sbr_env_estimate(sbr->e_curr, sbr->X_high, sbr, &sbr->data[ch]); sbr_gain_calc(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a); sbr->c.sbr_hf_assemble(sbr->data[ch].Y[sbr->data[ch].Ypos], - sbr->X_high, sbr, &sbr->data[ch], + (const float (*)[40][2]) sbr->X_high, + sbr, &sbr->data[ch], sbr->data[ch].e_a); } } /* synthesis */ sbr->c.sbr_x_gen(sbr, sbr->X[ch], - sbr->data[ch].Y[1-sbr->data[ch].Ypos], - sbr->data[ch].Y[ sbr->data[ch].Ypos], - sbr->X_low, ch); + (const float (*)[64][2]) sbr->data[ch].Y[1-sbr->data[ch].Ypos], + (const float (*)[64][2]) sbr->data[ch].Y[ sbr->data[ch].Ypos], + (const float (*)[40][2]) sbr->X_low, ch); } if (ac->oc[1].m4ac.ps == 1) { diff --git a/ffmpeg/libavcodec/aacsbrdata.h b/ffmpeg/libavcodec/aacsbrdata.h index dd7a827..12575ee 100644 --- a/ffmpeg/libavcodec/aacsbrdata.h +++ b/ffmpeg/libavcodec/aacsbrdata.h @@ -352,7 +352,7 @@ static DECLARE_ALIGNED(32, float, sbr_qmf_window_us)[640] = { 0.8537385600, }; -/* First two entries repeated at end to simplify SIMD implementations. */ +/* First eight entries repeated at end to simplify SIMD implementations. */ const DECLARE_ALIGNED(16, float, ff_sbr_noise_table)[][2] = { {-0.99948153278296, -0.59483417516607}, { 0.97113454393991, -0.67528515225647}, { 0.14130051758487, -0.95090983575689}, {-0.47005496701697, -0.37340549728647}, @@ -610,7 +610,11 @@ const DECLARE_ALIGNED(16, float, ff_sbr_noise_table)[][2] = { {-0.93412041758744, 0.41374052024363}, { 0.96063943315511, 0.93116709541280}, { 0.97534253457837, 0.86150930812689}, { 0.99642466504163, 0.70190043427512}, {-0.94705089665984, -0.29580042814306}, { 0.91599807087376, -0.98147830385781}, +// Start of duplicated table {-0.99948153278296, -0.59483417516607}, { 0.97113454393991, -0.67528515225647}, +{ 0.14130051758487, -0.95090983575689}, {-0.47005496701697, -0.37340549728647}, +{ 0.80705063769351, 0.29653668284408}, {-0.38981478896926, 0.89572605717087}, +{-0.01053049862020, -0.66959058036166}, {-0.91266367957293, -0.11522938140034}, }; #endif /* AVCODEC_AACSBRDATA_H */ diff --git a/ffmpeg/libavcodec/aactab.c b/ffmpeg/libavcodec/aactab.c index 6cbb8c4..7ec8374 100644 --- a/ffmpeg/libavcodec/aactab.c +++ b/ffmpeg/libavcodec/aactab.c @@ -34,12 +34,17 @@ #include DECLARE_ALIGNED(32, float, ff_aac_kbd_long_1024)[1024]; +DECLARE_ALIGNED(32, float, ff_aac_kbd_long_512 )[512]; DECLARE_ALIGNED(32, float, ff_aac_kbd_short_128)[128]; const uint8_t ff_aac_num_swb_1024[] = { 41, 41, 47, 49, 49, 51, 47, 47, 43, 43, 43, 40, 40 }; +const uint8_t ff_aac_num_swb_512[] = { + 0, 0, 0, 36, 36, 37, 31, 31, 0, 0, 0, 0, 0 +}; + const uint8_t ff_aac_num_swb_128[] = { 12, 12, 12, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15 }; @@ -1114,6 +1119,14 @@ static const uint16_t swb_offset_1024_48[] = { 928, 1024 }; +static const uint16_t swb_offset_512_48[] = { + 0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 60, + 68, 76, 84, 92, 100, 112, 124, 136, + 148, 164, 184, 208, 236, 268, 300, 332, + 364, 396, 428, 460, 512 +}; + static const uint16_t swb_offset_128_48[] = { 0, 4, 8, 12, 16, 20, 28, 36, 44, 56, 68, 80, 96, 112, 128 @@ -1129,6 +1142,14 @@ static const uint16_t swb_offset_1024_32[] = { 928, 960, 992, 1024 }; +static const uint16_t swb_offset_512_32[] = { + 0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 64, + 72, 80, 88, 96, 108, 120, 132, 144, + 160, 176, 192, 212, 236, 260, 288, 320, + 352, 384, 416, 448, 480, 512 +}; + static const uint16_t swb_offset_1024_24[] = { 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 52, 60, 68, 76, @@ -1138,6 +1159,13 @@ static const uint16_t swb_offset_1024_24[] = { 600, 652, 704, 768, 832, 896, 960, 1024 }; +static const uint16_t swb_offset_512_24[] = { + 0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 52, 60, 68, 80, + 92, 104, 120, 140, 164, 192, 224, 256, + 288, 320, 352, 384, 416, 448, 480, 512, +}; + static const uint16_t swb_offset_128_24[] = { 0, 4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 64, 76, 92, 108, 128 @@ -1179,6 +1207,14 @@ const uint16_t * const ff_swb_offset_1024[] = { swb_offset_1024_8 }; +const uint16_t * const ff_swb_offset_512[] = { + NULL, NULL, NULL, + swb_offset_512_48, swb_offset_512_48, swb_offset_512_32, + swb_offset_512_24, swb_offset_512_24, NULL, + NULL, NULL, NULL, + NULL +}; + const uint16_t * const ff_swb_offset_128[] = { /* The last entry on the following row is swb_offset_128_64 but is a duplicate of swb_offset_128_96. */ @@ -1205,3 +1241,486 @@ const uint8_t ff_tns_max_bands_128[] = { 9, 9, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14 }; // @} + +const DECLARE_ALIGNED(32, float, ff_aac_eld_window)[1920] = { + 0.00338834, 0.00567745, 0.00847677, 0.01172641, + 0.01532555, 0.01917664, 0.02318809, 0.02729259, + 0.03144503, 0.03560261, 0.03972499, 0.04379783, + 0.04783094, 0.05183357, 0.05581342, 0.05977723, + 0.06373173, 0.06768364, 0.07163937, 0.07559976, + 0.07956096, 0.08352024, 0.08747623, 0.09143035, + 0.09538618, 0.09934771, 0.10331917, 0.10730456, + 0.11130697, 0.11532867, 0.11937133, 0.12343922, + 0.12753911, 0.13167705, 0.13585812, 0.14008529, + 0.14435986, 0.14868291, 0.15305531, 0.15747594, + 0.16194193, 0.16645070, 0.17099991, 0.17558633, + 0.18020600, 0.18485548, 0.18953191, 0.19423322, + 0.19895800, 0.20370512, 0.20847374, 0.21326312, + 0.21807244, 0.22290083, 0.22774742, 0.23261210, + 0.23749542, 0.24239767, 0.24731889, 0.25225887, + 0.25721719, 0.26219330, 0.26718648, 0.27219630, + 0.27722262, 0.28226514, 0.28732336, 0.29239628, + 0.29748247, 0.30258055, 0.30768914, 0.31280508, + 0.31792385, 0.32304172, 0.32815579, 0.33326397, + 0.33836470, 0.34345661, 0.34853868, 0.35361188, + 0.35867865, 0.36374072, 0.36879900, 0.37385347, + 0.37890349, 0.38394836, 0.38898730, 0.39401912, + 0.39904236, 0.40405575, 0.40905820, 0.41404819, + 0.41902398, 0.42398423, 0.42892805, 0.43385441, + 0.43876210, 0.44365014, 0.44851786, 0.45336632, + 0.45819759, 0.46301302, 0.46781309, 0.47259722, + 0.47736435, 0.48211365, 0.48684450, 0.49155594, + 0.49624679, 0.50091636, 0.50556440, 0.51019132, + 0.51479771, 0.51938391, 0.52394998, 0.52849587, + 0.53302151, 0.53752680, 0.54201160, 0.54647575, + 0.55091916, 0.55534181, 0.55974376, 0.56412513, + 0.56848615, 0.57282710, 0.57714834, 0.58145030, + 0.58492489, 0.58918511, 0.59342326, 0.59763936, + 0.60183347, 0.60600561, 0.61015581, 0.61428412, + 0.61839056, 0.62247517, 0.62653799, 0.63057912, + 0.63459872, 0.63859697, 0.64257403, 0.64653001, + 0.65046495, 0.65437887, 0.65827181, 0.66214383, + 0.66599499, 0.66982535, 0.67363499, 0.67742394, + 0.68119219, 0.68493972, 0.68866653, 0.69237258, + 0.69605778, 0.69972207, 0.70336537, 0.70698758, + 0.71058862, 0.71416837, 0.71772674, 0.72126361, + 0.72477889, 0.72827246, 0.73174419, 0.73519392, + 0.73862141, 0.74202643, 0.74540874, 0.74876817, + 0.75210458, 0.75541785, 0.75870785, 0.76197437, + 0.76521709, 0.76843570, 0.77162988, 0.77479939, + 0.77794403, 0.78106359, 0.78415789, 0.78722670, + 0.79026979, 0.79328694, 0.79627791, 0.79924244, + 0.80218027, 0.80509112, 0.80797472, 0.81083081, + 0.81365915, 0.81645949, 0.81923160, 0.82197528, + 0.82469037, 0.82737673, 0.83003419, 0.83266262, + 0.83526186, 0.83783176, 0.84037217, 0.84288297, + 0.84536401, 0.84781517, 0.85023632, 0.85262739, + 0.85498836, 0.85731921, 0.85961993, 0.86189052, + 0.86413101, 0.86634140, 0.86852173, 0.87067211, + 0.87279275, 0.87488384, 0.87694559, 0.87897824, + 0.88098206, 0.88295729, 0.88490423, 0.88682332, + 0.88871519, 0.89058048, 0.89241983, 0.89423391, + 0.89602338, 0.89778893, 0.89953126, 0.90125142, + 0.90295086, 0.90463104, 0.90629341, 0.90793946, + 0.90957067, 0.91118856, 0.91279464, 0.91439073, + 0.91597898, 0.91756153, 0.91914049, 0.92071690, + 0.92229070, 0.92386182, 0.92542993, 0.92698946, + 0.92852960, 0.93003929, 0.93150727, 0.93291739, + 0.93424863, 0.93547974, 0.93658982, 0.93756587, + 0.93894072, 0.93922780, 0.93955477, 0.93991290, + 0.94029104, 0.94067794, 0.94106258, 0.94144084, + 0.94181549, 0.94218963, 0.94256628, 0.94294662, + 0.94332998, 0.94371562, 0.94410280, 0.94449122, + 0.94488106, 0.94527249, 0.94566568, 0.94606074, + 0.94645772, 0.94685665, 0.94725759, 0.94766054, + 0.94806547, 0.94847234, 0.94888115, 0.94929190, + 0.94970469, 0.95011960, 0.95053672, 0.95095604, + 0.95137751, 0.95180105, 0.95222658, 0.95265413, + 0.95308380, 0.95351571, 0.95394994, 0.95438653, + 0.95482538, 0.95526643, 0.95570958, 0.95615486, + 0.95660234, 0.95705214, 0.95750433, 0.95795892, + 0.95841582, 0.95887493, 0.95933616, 0.95979949, + 0.96026500, 0.96073277, 0.96120286, 0.96167526, + 0.96214986, 0.96262655, 0.96310522, 0.96358586, + 0.96406853, 0.96455330, 0.96504026, 0.96552936, + 0.96602051, 0.96651360, 0.96700850, 0.96750520, + 0.96800376, 0.96850424, 0.96900670, 0.96951112, + 0.97001738, 0.97052533, 0.97103488, 0.97154597, + 0.97205867, 0.97257304, 0.97308915, 0.97360694, + 0.97412631, 0.97464711, 0.97516923, 0.97569262, + 0.97621735, 0.97674350, 0.97727111, 0.97780016, + 0.97833051, 0.97886205, 0.97939463, 0.97992823, + 0.98046291, 0.98099875, 0.98153580, 0.98207405, + 0.98261337, 0.98315364, 0.98369474, 0.98423664, + 0.98477941, 0.98532311, 0.98586780, 0.98641348, + 0.98696003, 0.98750734, 0.98805530, 0.98860389, + 0.98915320, 0.98970328, 0.99025423, 0.99080602, + 0.99135855, 0.99191171, 0.99246541, 0.99301962, + 0.99357443, 0.99412992, 0.99468617, 0.99524320, + 0.99580092, 0.99635926, 0.99691814, 0.99747748, + 0.99803721, 0.99859725, 0.99915752, 0.99971793, + 1.00028215, 1.00084319, 1.00140472, 1.00196665, + 1.00252889, 1.00309139, 1.00365404, 1.00421679, + 1.00477954, 1.00534221, 1.00590474, 1.00646713, + 1.00702945, 1.00759179, 1.00815424, 1.00871678, + 1.00927930, 1.00984169, 1.01040384, 1.01096575, + 1.01152747, 1.01208910, 1.01265070, 1.01321226, + 1.01377365, 1.01433478, 1.01489551, 1.01545584, + 1.01601582, 1.01657553, 1.01713502, 1.01769427, + 1.01825316, 1.01881154, 1.01936929, 1.01992639, + 1.02048289, 1.02103888, 1.02159441, 1.02214945, + 1.02270387, 1.02325751, 1.02381025, 1.02436204, + 1.02491295, 1.02546304, 1.02601238, 1.02656092, + 1.02710853, 1.02765508, 1.02820041, 1.02874449, + 1.02928737, 1.02982913, 1.03036981, 1.03090937, + 1.03144768, 1.03198460, 1.03252000, 1.03305384, + 1.03358617, 1.03411707, 1.03464659, 1.03517470, + 1.03570128, 1.03622620, 1.03674934, 1.03727066, + 1.03779024, 1.03830815, 1.03882446, 1.03933914, + 1.03985206, 1.04036312, 1.04087217, 1.04137920, + 1.04188428, 1.04238748, 1.04288888, 1.04338845, + 1.04388610, 1.04438170, 1.04487515, 1.04536645, + 1.04585569, 1.04634297, 1.04682838, 1.04731192, + 1.04779350, 1.04827303, 1.04875042, 1.04922568, + 1.04969891, 1.05017022, 1.05063974, 1.05110746, + 1.05157332, 1.05203721, 1.05249907, 1.05295889, + 1.05341676, 1.05387277, 1.05432700, 1.05477948, + 1.05523018, 1.05567906, 1.05612608, 1.05657124, + 1.05701459, 1.05745616, 1.05789601, 1.05833426, + 1.05877109, 1.05920669, 1.05964125, 1.06007444, + 1.06050542, 1.06093335, 1.06135746, 1.06177909, + 1.06220164, 1.06262858, 1.06306309, 1.06350050, + 1.06392837, 1.06433391, 1.06470443, 1.06502996, + 1.06481076, 1.06469765, 1.06445004, 1.06408002, + 1.06361382, 1.06307719, 1.06249453, 1.06188365, + 1.06125612, 1.06062291, 1.05999418, 1.05937132, + 1.05874726, 1.05811486, 1.05746728, 1.05680000, + 1.05611070, 1.05539715, 1.05465735, 1.05389329, + 1.05311083, 1.05231578, 1.05151372, 1.05070811, + 1.04990044, 1.04909210, 1.04828434, 1.04747647, + 1.04666590, 1.04585003, 1.04502628, 1.04419009, + 1.04333499, 1.04245452, 1.04154244, 1.04059452, + 1.03960846, 1.03858207, 1.03751326, 1.03640189, + 1.03524976, 1.03405868, 1.03283047, 1.03156812, + 1.03027574, 1.02895743, 1.02761717, 1.02625804, + 1.02488222, 1.02349184, 1.02208892, 1.02067450, + 1.01924861, 1.01781123, 1.01636229, 1.01490045, + 1.01342315, 1.01192778, 1.01041175, 1.00887284, + 1.00730915, 1.00571882, 1.00409996, 1.00245032, + 1.00076734, 0.99904842, 0.99729101, 0.99549380, + 0.99365664, 0.99177946, 0.98986234, 0.98791024, + 0.98593294, 0.98394037, 0.98194226, 0.97994532, + 0.97795324, 0.97596955, 0.97399748, 0.97203326, + 0.97006624, 0.96808546, 0.96608018, 0.96404416, + 0.96197556, 0.95987276, 0.95773420, 0.95556018, + 0.95335291, 0.95111462, 0.94884764, 0.94655663, + 0.94424858, 0.94193055, 0.93960953, 0.93729154, + 0.93498157, 0.93268456, 0.93040503, 0.92813771, + 0.92586755, 0.92357910, 0.92125731, 0.91889642, + 0.91649998, 0.91407191, 0.91161623, 0.90913975, + 0.90665202, 0.90416271, 0.90168115, 0.89920934, + 0.89674189, 0.89427312, 0.89179743, 0.88931147, + 0.88681415, 0.88430445, 0.88178141, 0.87924528, + 0.87669753, 0.87413966, 0.87157318, 0.86899958, + 0.86642037, 0.86383703, 0.86125106, 0.85866393, + 0.85604236, 0.85344385, 0.85083093, 0.84820550, + 0.84556943, 0.84292458, 0.84027278, 0.83761586, + 0.83495565, 0.83229393, 0.82963243, 0.82697135, + 0.82430933, 0.82164496, 0.81897669, 0.81630017, + 0.81360822, 0.81089355, 0.80814924, 0.80537741, + 0.80258920, 0.79979611, 0.79700954, 0.79423813, + 0.79148780, 0.78876432, 0.78607290, 0.78340590, + 0.78074288, 0.77806279, 0.77534514, 0.77258187, + 0.76977737, 0.76693654, 0.76406441, 0.76116851, + 0.75825892, 0.75534582, 0.75243924, 0.74954634, + 0.74667135, 0.74381840, 0.74099145, 0.73819147, + 0.73541641, 0.73266408, 0.72993193, 0.72720913, + 0.72447661, 0.72171494, 0.71890515, 0.71603932, + 0.71312056, 0.71015250, 0.70713900, 0.70409084, + 0.70102565, 0.69796137, 0.69491556, 0.69189772, + 0.68890931, 0.68595141, 0.68302498, 0.68012852, + 0.67725801, 0.67440936, 0.67157841, 0.66876081, + 0.66595195, 0.66314722, 0.66034194, 0.65753027, + 0.65470525, 0.65185984, 0.64898709, 0.64608214, + 0.64314221, 0.64016460, 0.63714680, 0.63409034, + 0.63100082, 0.62788400, 0.62474577, 0.62159473, + 0.61844225, 0.61529977, 0.61217866, 0.60908811, + 0.60603510, 0.60302654, 0.60006916, 0.59716588, + 0.59431580, 0.59151787, 0.58877068, 0.58606495, + 0.58338353, 0.58070891, 0.57802356, 0.57530864, + 0.57254404, 0.56970958, 0.56678577, 0.56376860, + 0.56066951, 0.55750064, 0.55427451, 0.55101301, + 0.54774732, 0.54450907, 0.54132936, 0.53822744, + 0.53521072, 0.53228613, 0.52945979, 0.52671997, + 0.52403708, 0.52138072, 0.51872085, 0.51603570, + 0.51331170, 0.51053560, 0.50769466, 0.50478931, + 0.50183308, 0.49884001, 0.49582406, 0.49279905, + 0.48985748, 0.48679641, 0.48379429, 0.48085363, + 0.47796576, 0.47512151, 0.47231151, 0.46952402, + 0.46674486, 0.46395978, 0.46115496, 0.45832607, + 0.45547830, 0.45261727, 0.44974866, 0.44688011, + 0.44402125, 0.44118178, 0.43837094, 0.43558772, + 0.43282082, 0.43005847, 0.42728913, 0.42450572, + 0.42170567, 0.41888658, 0.41604633, 0.41318897, + 0.41032472, 0.40746405, 0.40461724, 0.40178943, + 0.39898066, 0.39619073, 0.39341940, 0.39066519, + 0.38792536, 0.38519713, 0.38247773, 0.37976476, + 0.37705620, 0.37435006, 0.37164438, 0.36893869, + 0.36623396, 0.36353124, 0.36083153, 0.35813533, + 0.35544262, 0.35275338, 0.35006755, 0.34738530, + 0.34470699, 0.34203296, 0.33936359, 0.33669922, + 0.33404027, 0.33138711, 0.32874013, 0.32609944, + 0.32346493, 0.32083645, 0.31821388, 0.31559703, + 0.31298573, 0.31037987, 0.30777941, 0.30518446, + 0.30259525, 0.30001202, 0.29743499, 0.29486428, + 0.29229989, 0.28974179, 0.28718997, 0.28464452, + 0.28210562, 0.27957346, 0.27704820, 0.27452992, + 0.27201854, 0.26951399, 0.26701622, 0.26452533, + 0.26204158, 0.25956526, 0.25709662, 0.25463583, + 0.25218294, 0.24973798, 0.24730100, 0.24487207, + 0.24245133, 0.24003893, 0.23763500, 0.23523959, + 0.23285262, 0.23047401, 0.22810369, 0.22574170, + 0.22338818, 0.22104329, 0.21870719, 0.21637986, + 0.21406117, 0.21175095, 0.20944904, 0.20715535, + 0.20486987, 0.20259261, 0.20032356, 0.19806259, + 0.19580944, 0.19356385, 0.19132556, 0.18909442, + 0.18687040, 0.18465350, 0.18244372, 0.18024164, + 0.17804841, 0.17586521, 0.17369322, 0.17153360, + 0.16938755, 0.16725622, 0.16514081, 0.16304247, + 0.16098974, 0.15896561, 0.15696026, 0.15497259, + 0.15300151, 0.15104590, 0.14910466, 0.14717666, + 0.14526081, 0.14335599, 0.14146111, 0.13957570, + 0.13769993, 0.13583399, 0.13397806, 0.13213229, + 0.13029682, 0.12847178, 0.12665729, 0.12485353, + 0.12306074, 0.12127916, 0.11950900, 0.11775043, + 0.11600347, 0.11426820, 0.11254464, 0.11083292, + 0.10913318, 0.10744559, 0.10577028, 0.10410733, + 0.10245672, 0.10081842, 0.09919240, 0.09757872, + 0.09597750, 0.09438884, 0.09281288, 0.09124964, + 0.08969907, 0.08816111, 0.08663570, 0.08512288, + 0.08362274, 0.08213540, 0.08066096, 0.07919944, + 0.07775076, 0.07631484, 0.07489161, 0.07348108, + 0.07208335, 0.07069851, 0.06932666, 0.06796781, + 0.06662187, 0.06528874, 0.06396833, 0.06266065, + 0.06136578, 0.06008380, 0.05881480, 0.05755876, + 0.05631557, 0.05508511, 0.05386728, 0.05266206, + 0.05146951, 0.05028971, 0.04912272, 0.04796855, + 0.04682709, 0.04569825, 0.04458194, 0.04347817, + 0.04238704, 0.04130868, 0.04024318, 0.03919056, + 0.03815071, 0.03712352, 0.03610890, 0.03510679, + 0.03411720, 0.03314013, 0.03217560, 0.03122343, + 0.03028332, 0.02935494, 0.02843799, 0.02753230, + 0.02663788, 0.02575472, 0.02488283, 0.02402232, + 0.02317341, 0.02233631, 0.02151124, 0.02069866, + 0.01989922, 0.01911359, 0.01834241, 0.01758563, + 0.01684248, 0.01611219, 0.01539397, 0.01468726, + 0.01399167, 0.01330687, 0.01263250, 0.01196871, + 0.01131609, 0.01067527, 0.01004684, 0.00943077, + 0.00882641, 0.00823307, 0.00765011, 0.00707735, + 0.00651513, 0.00596377, 0.00542364, 0.00489514, + 0.00437884, 0.00387530, 0.00338509, 0.00290795, + 0.00244282, 0.00198860, 0.00154417, 0.00110825, + 0.00067934, 0.00025589, -0.00016357, -0.00057897, + -0.00098865, -0.00139089, -0.00178397, -0.00216547, + -0.00253230, -0.00288133, -0.00320955, -0.00351626, + -0.00380315, -0.00407198, -0.00432457, -0.00456373, + -0.00479326, -0.00501699, -0.00523871, -0.00546066, + -0.00568360, -0.00590821, -0.00613508, -0.00636311, + -0.00658944, -0.00681117, -0.00702540, -0.00722982, + -0.00742268, -0.00760226, -0.00776687, -0.00791580, + -0.00804933, -0.00816774, -0.00827139, -0.00836122, + -0.00843882, -0.00850583, -0.00856383, -0.00861430, + -0.00865853, -0.00869781, -0.00873344, -0.00876633, + -0.00879707, -0.00882622, -0.00885433, -0.00888132, + -0.00890652, -0.00892925, -0.00894881, -0.00896446, + -0.00897541, -0.00898088, -0.00898010, -0.00897234, + -0.00895696, -0.00893330, -0.00890076, -0.00885914, + -0.00880875, -0.00874987, -0.00868282, -0.00860825, + -0.00852716, -0.00844055, -0.00834941, -0.00825485, + -0.00815807, -0.00806025, -0.00796253, -0.00786519, + -0.00776767, -0.00766937, -0.00756971, -0.00746790, + -0.00736305, -0.00725422, -0.00714055, -0.00702161, + -0.00689746, -0.00676816, -0.00663381, -0.00649489, + -0.00635230, -0.00620694, -0.00605969, -0.00591116, + -0.00576167, -0.00561155, -0.00546110, -0.00531037, + -0.00515917, -0.00500732, -0.00485462, -0.00470075, + -0.00454530, -0.00438786, -0.00422805, -0.00406594, + -0.00390204, -0.00373686, -0.00357091, -0.00340448, + -0.00323770, -0.00307066, -0.00290344, -0.00273610, + -0.00256867, -0.00240117, -0.00223365, -0.00206614, + -0.00189866, -0.00173123, -0.00156390, -0.00139674, + -0.00122989, -0.00106351, -0.00089772, -0.00073267, + -0.00056849, -0.00040530, -0.00024324, -0.00008241, + 0.00008214, 0.00024102, 0.00039922, 0.00055660, + 0.00071299, 0.00086826, 0.00102224, 0.00117480, + 0.00132579, 0.00147507, 0.00162252, 0.00176804, + 0.00191161, 0.00205319, 0.00219277, 0.00233029, + 0.00246567, 0.00259886, 0.00272975, 0.00285832, + 0.00298453, 0.00310839, 0.00322990, 0.00334886, + 0.00346494, 0.00357778, 0.00368706, 0.00379273, + 0.00389501, 0.00399411, 0.00409020, 0.00418350, + 0.00427419, 0.00436249, 0.00444858, 0.00453250, + 0.00461411, 0.00469328, 0.00476988, 0.00484356, + 0.00491375, 0.00497987, 0.00504139, 0.00509806, + 0.00514990, 0.00519693, 0.00523920, 0.00527700, + 0.00531083, 0.00534122, 0.00536864, 0.00539357, + 0.00541649, 0.00543785, 0.00545809, 0.00547713, + 0.00549441, 0.00550936, 0.00552146, 0.00553017, + 0.00553494, 0.00553524, 0.00553058, 0.00552065, + 0.00550536, 0.00548459, 0.00545828, 0.00542662, + 0.00539007, 0.00534910, 0.00530415, 0.00525568, + 0.00520417, 0.00515009, 0.00509387, 0.00503595, + 0.00497674, 0.00491665, 0.00485605, 0.00479503, + 0.00473336, 0.00467082, 0.00460721, 0.00454216, + 0.00447517, 0.00440575, 0.00433344, 0.00425768, + 0.00417786, 0.00409336, 0.00400363, 0.00390837, + 0.00380759, 0.00370130, 0.00358952, 0.00347268, + 0.00335157, 0.00322699, 0.00309975, 0.00297088, + 0.00284164, 0.00271328, 0.00258700, 0.00246328, + 0.00234195, 0.00222281, 0.00210562, 0.00198958, + 0.00187331, 0.00175546, 0.00163474, 0.00151020, + 0.00138130, 0.00124750, 0.00110831, 0.00096411, + 0.00081611, 0.00066554, 0.00051363, 0.00036134, + 0.00020940, 0.00005853, -0.00009058, -0.00023783, + -0.00038368, -0.00052861, -0.00067310, -0.00081757, + -0.00096237, -0.00110786, -0.00125442, -0.00140210, + -0.00155065, -0.00169984, -0.00184940, -0.00199910, + -0.00214872, -0.00229798, -0.00244664, -0.00259462, + -0.00274205, -0.00288912, -0.00303596, -0.00318259, + -0.00332890, -0.00347480, -0.00362024, -0.00376519, + -0.00390962, -0.00405345, -0.00419658, -0.00433902, + -0.00448085, -0.00462219, -0.00476309, -0.00490357, + -0.00504361, -0.00518321, -0.00532243, -0.00546132, + -0.00559988, -0.00573811, -0.00587602, -0.00601363, + -0.00615094, -0.00628795, -0.00642466, -0.00656111, + -0.00669737, -0.00683352, -0.00696963, -0.00710578, + -0.00724208, -0.00737862, -0.00751554, -0.00765295, + -0.00779098, -0.00792976, -0.00806941, -0.00821006, + -0.00835183, -0.00849485, -0.00863926, -0.00878522, + -0.00893293, -0.00908260, -0.00923444, -0.00938864, + -0.00954537, -0.00970482, -0.00986715, -0.01003173, + -0.01019711, -0.01036164, -0.01052357, -0.01068184, + -0.01083622, -0.01098652, -0.01113252, -0.01127409, + -0.01141114, -0.01154358, -0.01167135, -0.01179439, + -0.01191268, -0.01202619, -0.01213493, -0.01223891, + -0.01233817, -0.01243275, -0.01252272, -0.01260815, + -0.01268915, -0.01276583, -0.01283832, -0.01290685, + -0.01297171, -0.01303320, -0.01309168, -0.01314722, + -0.01319969, -0.01324889, -0.01329466, -0.01333693, + -0.01337577, -0.01341125, -0.01344345, -0.01347243, + -0.01349823, -0.01352089, -0.01354045, -0.01355700, + -0.01357068, -0.01358164, -0.01359003, -0.01359587, + -0.01359901, -0.01359931, -0.01359661, -0.01359087, + -0.01358219, -0.01357065, -0.01355637, -0.01353935, + -0.01351949, -0.01349670, -0.01347088, -0.01344214, + -0.01341078, -0.01337715, -0.01334158, -0.01330442, + -0.01326601, -0.01322671, -0.01318689, -0.01314692, + -0.01310123, -0.01306470, -0.01302556, -0.01298381, + -0.01293948, -0.01289255, -0.01284305, -0.01279095, + -0.01273625, -0.01267893, -0.01261897, -0.01255632, + -0.01249096, -0.01242283, -0.01235190, -0.01227827, + -0.01220213, -0.01212366, -0.01204304, -0.01196032, + -0.01187543, -0.01178829, -0.01169884, -0.01160718, + -0.01151352, -0.01141809, -0.01132111, -0.01122272, + -0.01112304, -0.01102217, -0.01092022, -0.01081730, + -0.01071355, -0.01060912, -0.01050411, -0.01039854, + -0.01029227, -0.01018521, -0.01007727, -0.00996859, + -0.00985959, -0.00975063, -0.00964208, -0.00953420, + -0.00942723, -0.00932135, -0.00921677, -0.00911364, + -0.00901208, -0.00891220, -0.00881412, -0.00871792, + -0.00862369, -0.00853153, -0.00844149, -0.00835360, + -0.00826785, -0.00818422, -0.00810267, -0.00802312, + -0.00794547, -0.00786959, -0.00779533, -0.00772165, + -0.00764673, -0.00756886, -0.00748649, -0.00739905, + -0.00730681, -0.00721006, -0.00710910, -0.00700419, + -0.00689559, -0.00678354, -0.00666829, -0.00655007, + -0.00642916, -0.00630579, -0.00618022, -0.00605267, + -0.00592333, -0.00579240, -0.00566006, -0.00552651, + -0.00539194, -0.00525653, -0.00512047, -0.00498390, + -0.00484693, -0.00470969, -0.00457228, -0.00443482, + -0.00429746, -0.00416034, -0.00402359, -0.00388738, + -0.00375185, -0.00361718, -0.00348350, -0.00335100, + -0.00321991, -0.00309043, -0.00296276, -0.00283698, + -0.00271307, -0.00259098, -0.00247066, -0.00235210, + -0.00223531, -0.00212030, -0.00200709, -0.00189576, + -0.00178647, -0.00167936, -0.00157457, -0.00147216, + -0.00137205, -0.00127418, -0.00117849, -0.00108498, + -0.00099375, -0.00090486, -0.00081840, -0.00073444, + -0.00065309, -0.00057445, -0.00049860, -0.00042551, + -0.00035503, -0.00028700, -0.00022125, -0.00015761, + -0.00009588, -0.00003583, 0.00002272, 0.00007975, + 0.00013501, 0.00018828, 0.00023933, 0.00028784, + 0.00033342, 0.00037572, 0.00041438, 0.00044939, + 0.00048103, 0.00050958, 0.00053533, 0.00055869, + 0.00058015, 0.00060022, 0.00061935, 0.00063781, + 0.00065568, 0.00067303, 0.00068991, 0.00070619, + 0.00072155, 0.00073567, 0.00074826, 0.00075912, + 0.00076811, 0.00077509, 0.00077997, 0.00078275, + 0.00078351, 0.00078237, 0.00077943, 0.00077484, + 0.00076884, 0.00076160, 0.00075335, 0.00074423, + 0.00073442, 0.00072404, 0.00071323, 0.00070209, + 0.00069068, 0.00067906, 0.00066728, 0.00065534, + 0.00064321, 0.00063086, 0.00061824, 0.00060534, + 0.00059211, 0.00057855, 0.00056462, 0.00055033, + 0.00053566, 0.00052063, 0.00050522, 0.00048949, + 0.00047349, 0.00045728, 0.00044092, 0.00042447, + 0.00040803, 0.00039166, 0.00037544, 0.00035943, + 0.00034371, 0.00032833, 0.00031333, 0.00029874, + 0.00028452, 0.00027067, 0.00025715, 0.00024395, + 0.00023104, 0.00021842, 0.00020606, 0.00019398, + 0.00018218, 0.00017069, 0.00015953, 0.00014871, + 0.00013827, 0.00012823, 0.00011861, 0.00010942, + 0.00010067, 0.00009236, 0.00008448, 0.00007703, + 0.00006999, 0.00006337, 0.00005714, 0.00005129, + 0.00004583, 0.00004072, 0.00003597, 0.00003157, + 0.00002752, 0.00002380, 0.00002042, 0.00001736, + 0.00001461, 0.00001215, 0.00000998, 0.00000807, + 0.00000641, 0.00000499, 0.00000378, 0.00000278, + 0.00000196, 0.00000132, 0.00000082, 0.00000046, + 0.00000020, 0.00000005, -0.00000003, -0.00000006, + -0.00000004, -0.00000001, 0.00000001, 0.00000001, + 0.00000001, 0.00000001, -0.00000001, -0.00000004, + -0.00000005, -0.00000003, 0.00000005, 0.00000020, + 0.00000043, 0.00000077, 0.00000123, 0.00000183, + 0.00000257, 0.00000348, 0.00000455, 0.00000581, + 0.00000727, 0.00000893, 0.00001080, 0.00001290, + 0.00001522, 0.00001778, 0.00002057, 0.00002362, + 0.00002691, 0.00003044, 0.00003422, 0.00003824, + 0.00004250, 0.00004701, 0.00005176, 0.00005676, + 0.00006200, 0.00006749, 0.00007322, 0.00007920, + 0.00008541, 0.00009186, 0.00009854, 0.00010543, + 0.00011251, 0.00011975, 0.00012714, 0.00013465, + 0.00014227, 0.00014997, 0.00015775, 0.00016558, + 0.00017348, 0.00018144, 0.00018947, 0.00019756, + 0.00020573, 0.00021399, 0.00022233, 0.00023076, + 0.00023924, 0.00024773, 0.00025621, 0.00026462, + 0.00027293, 0.00028108, 0.00028904, 0.00029675, + 0.00030419, 0.00031132, 0.00031810, 0.00032453, + 0.00033061, 0.00033632, 0.00034169, 0.00034672, + 0.00035142, 0.00035580, 0.00035988, 0.00036369, + 0.00036723, 0.00037053, 0.00037361, 0.00037647, + 0.00037909, 0.00038145, 0.00038352, 0.00038527, + 0.00038663, 0.00038757, 0.00038801, 0.00038790, + 0.00038717, 0.00038572, 0.00038350, 0.00038044, + 0.00037651, 0.00037170, 0.00036597, 0.00035936, + 0.00035191, 0.00034370, 0.00033480, 0.00032531, + 0.00031537, 0.00030512, 0.00029470, 0.00028417, + 0.00027354, 0.00026279, 0.00025191, 0.00024081, + 0.00022933, 0.00021731, 0.00020458, 0.00019101, + 0.00017654, 0.00016106, 0.00014452, 0.00012694, + 0.00010848, 0.00008929, 0.00006953, 0.00004935, + 0.00002884, 0.00000813, -0.00001268, -0.00003357, + -0.00005457, -0.00007574, -0.00009714, -0.00011882, + -0.00014082, -0.00016318, -0.00018595, -0.00020912, + -0.00023265, -0.00025650, -0.00028060, -0.00030492, + -0.00032941, -0.00035400, -0.00037865, -0.00040333, + -0.00042804, -0.00045279, -0.00047759, -0.00050243, + -0.00052728, -0.00055209, -0.00057685, -0.00060153, + -0.00062611, -0.00065056, -0.00067485, -0.00069895, + -0.00072287, -0.00074660, -0.00077013, -0.00079345, + -0.00081653, -0.00083936, -0.00086192, -0.00088421, + -0.00090619, -0.00092786, -0.00094919, -0.00097017, + -0.00099077, -0.00101098, -0.00103077, -0.00105012, + -0.00106904, -0.00108750, -0.00110549, -0.00112301, + -0.00114005, -0.00115660, -0.00117265, -0.00118821, + -0.00120325, -0.00121779, -0.00123180, -0.00124528, + -0.00125822, -0.00127061, -0.00128243, -0.00129368, + -0.00130435, -0.00131445, -0.00132395, -0.00133285, + -0.00134113, -0.00134878, -0.00135577, -0.00136215, + -0.00136797, -0.00137333, -0.00137834, -0.00138305, + -0.00138748, -0.00139163, -0.00139551, -0.00139913, + -0.00140249, -0.00140559, -0.00140844, -0.00141102, + -0.00141334, -0.00141538, -0.00141714, -0.00141861, + -0.00141978, -0.00142064, -0.00142117, -0.00142138, + -0.00142125, -0.00142077, -0.00141992, -0.00141870, + -0.00141710, -0.00141510, -0.00141268, -0.00140986, + -0.00140663, -0.00140301, -0.00139900, -0.00139460, + -0.00138981, -0.00138464, -0.00137908, -0.00137313, + -0.00136680, -0.00136010, -0.00135301, -0.00134555, + -0.00133772, -0.00132952, -0.00132095, -0.00131201, + -0.00130272, -0.00129307, -0.00128309, -0.00127277, + -0.00126211, -0.00125113, -0.00123981, -0.00122817, + -0.00121622, -0.00120397, -0.00119141, -0.00117859, + -0.00116552, -0.00115223, -0.00113877, -0.00112517, + -0.00111144, -0.00109764, -0.00108377, -0.00106989, +}; diff --git a/ffmpeg/libavcodec/aactab.h b/ffmpeg/libavcodec/aactab.h index 6ed3b4a..699d99d 100644 --- a/ffmpeg/libavcodec/aactab.h +++ b/ffmpeg/libavcodec/aactab.h @@ -45,13 +45,16 @@ * @{ */ DECLARE_ALIGNED(32, extern float, ff_aac_kbd_long_1024)[1024]; +DECLARE_ALIGNED(32, extern float, ff_aac_kbd_long_512 )[512]; DECLARE_ALIGNED(32, extern float, ff_aac_kbd_short_128)[128]; +const DECLARE_ALIGNED(32, extern float, ff_aac_eld_window)[1920]; // @} /* @name number of scalefactor window bands for long and short transform windows respectively * @{ */ extern const uint8_t ff_aac_num_swb_1024[]; +extern const uint8_t ff_aac_num_swb_512 []; extern const uint8_t ff_aac_num_swb_128 []; // @} @@ -69,6 +72,7 @@ extern const float *ff_aac_codebook_vector_vals[]; extern const uint16_t *ff_aac_codebook_vector_idx[]; extern const uint16_t * const ff_swb_offset_1024[13]; +extern const uint16_t * const ff_swb_offset_512 [13]; extern const uint16_t * const ff_swb_offset_128 [13]; extern const uint8_t ff_tns_max_bands_1024[13]; diff --git a/ffmpeg/libavcodec/aasc.c b/ffmpeg/libavcodec/aasc.c index 26ba30d..38658f8 100644 --- a/ffmpeg/libavcodec/aasc.c +++ b/ffmpeg/libavcodec/aasc.c @@ -107,11 +107,9 @@ static int aasc_decode_frame(AVCodecContext *avctx, switch (compr) { case 0: stride = (avctx->width * psize + psize) & ~psize; + if (buf_size < stride * avctx->height) + return AVERROR_INVALIDDATA; for (i = avctx->height - 1; i >= 0; i--) { - if (avctx->width * psize > buf_size) { - av_log(avctx, AV_LOG_ERROR, "Next line is beyond buffer bounds\n"); - break; - } memcpy(s->frame->data[0] + i * s->frame->linesize[0], buf, avctx->width * psize); buf += stride; buf_size -= stride; @@ -153,6 +151,7 @@ static av_cold int aasc_decode_end(AVCodecContext *avctx) AVCodec ff_aasc_decoder = { .name = "aasc", + .long_name = NULL_IF_CONFIG_SMALL("Autodesk RLE"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_AASC, .priv_data_size = sizeof(AascContext), @@ -160,5 +159,4 @@ AVCodec ff_aasc_decoder = { .close = aasc_decode_end, .decode = aasc_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Autodesk RLE"), }; diff --git a/ffmpeg/libavcodec/ac3dec.c b/ffmpeg/libavcodec/ac3dec.c index a70d92a..1995412 100644 --- a/ffmpeg/libavcodec/ac3dec.c +++ b/ffmpeg/libavcodec/ac3dec.c @@ -29,6 +29,7 @@ #include #include +#include "libavutil/channel_layout.h" #include "libavutil/crc.h" #include "libavutil/opt.h" #include "internal.h" @@ -178,11 +179,20 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx) avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; /* allow downmixing to stereo or mono */ - if (avctx->channels > 0 && avctx->request_channels > 0 && - avctx->request_channels < avctx->channels && - avctx->request_channels <= 2) { - avctx->channels = avctx->request_channels; - } +#if FF_API_REQUEST_CHANNELS +FF_DISABLE_DEPRECATION_WARNINGS + if (avctx->request_channels == 1) + avctx->request_channel_layout = AV_CH_LAYOUT_MONO; + else if (avctx->request_channels == 2) + avctx->request_channel_layout = AV_CH_LAYOUT_STEREO; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + if (avctx->channels > 1 && + avctx->request_channel_layout == AV_CH_LAYOUT_MONO) + avctx->channels = 1; + else if (avctx->channels > 2 && + avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) + avctx->channels = 2; s->downmixed = 1; for (i = 0; i < AC3_MAX_CHANNELS; i++) { @@ -251,7 +261,6 @@ static int parse_frame_header(AC3DecodeContext *s) s->bit_alloc_params.sr_code = hdr.sr_code; s->bitstream_mode = hdr.bitstream_mode; s->channel_mode = hdr.channel_mode; - s->channel_layout = hdr.channel_layout; s->lfe_on = hdr.lfe_on; s->bit_alloc_params.sr_shift = hdr.sr_shift; s->sample_rate = hdr.sample_rate; @@ -290,7 +299,7 @@ static int parse_frame_header(AC3DecodeContext *s) return ff_eac3_parse_header(s); } else { av_log(s->avctx, AV_LOG_ERROR, "E-AC-3 support not compiled in\n"); - return -1; + return AVERROR(ENOSYS); } } @@ -429,7 +438,7 @@ static void ac3_decode_transform_coeffs_ch(AC3DecodeContext *s, int ch_index, ma int end_freq = s->end_freq[ch_index]; uint8_t *baps = s->bap[ch_index]; int8_t *exps = s->dexps[ch_index]; - int *coeffs = s->fixed_coeffs[ch_index]; + int32_t *coeffs = s->fixed_coeffs[ch_index]; int dither = (ch_index == CPL_CH) || s->dither_flag[ch_index]; GetBitContext *gbc = &s->gbc; int freq; @@ -488,6 +497,10 @@ static void ac3_decode_transform_coeffs_ch(AC3DecodeContext *s, int ch_index, ma break; default: /* 6 to 15 */ /* Shift mantissa and sign-extend it. */ + if (bap > 15) { + av_log(s->avctx, AV_LOG_ERROR, "bap %d is invalid in plain AC-3\n", bap); + bap = 15; + } mantissa = get_sbits(gbc, quantization_tab[bap]); mantissa <<= 24 - quantization_tab[bap]; break; @@ -747,8 +760,8 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) i = !s->channel_mode; do { if (get_bits1(gbc)) { - s->dynamic_range[i] = ((dynamic_range_tab[get_bits(gbc, 8)] - 1.0) * - s->drc_scale) + 1.0; + s->dynamic_range[i] = powf(dynamic_range_tab[get_bits(gbc, 8)], + s->drc_scale); } else if (blk == 0) { s->dynamic_range[i] = 1.0f; } @@ -786,12 +799,12 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) if (start_subband >= end_subband) { av_log(s->avctx, AV_LOG_ERROR, "invalid spectral extension " "range (%d >= %d)\n", start_subband, end_subband); - return -1; + return AVERROR_INVALIDDATA; } if (dst_start_freq >= src_start_freq) { av_log(s->avctx, AV_LOG_ERROR, "invalid spectral extension " "copy start bin (%d >= %d)\n", dst_start_freq, src_start_freq); - return -1; + return AVERROR_INVALIDDATA; } s->spx_dst_start_freq = dst_start_freq; @@ -868,7 +881,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) if (channel_mode < AC3_CHMODE_STEREO) { av_log(s->avctx, AV_LOG_ERROR, "coupling not allowed in mono or dual-mono\n"); - return -1; + return AVERROR_INVALIDDATA; } /* check for enhanced coupling */ @@ -898,7 +911,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) if (cpl_start_subband >= cpl_end_subband) { av_log(s->avctx, AV_LOG_ERROR, "invalid coupling range (%d >= %d)\n", cpl_start_subband, cpl_end_subband); - return -1; + return AVERROR_INVALIDDATA; } s->start_freq[CPL_CH] = cpl_start_subband * 12 + 37; s->end_freq[CPL_CH] = cpl_end_subband * 12 + 37; @@ -920,7 +933,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) if (!blk) { av_log(s->avctx, AV_LOG_ERROR, "new coupling strategy must " "be present in block 0\n"); - return -1; + return AVERROR_INVALIDDATA; } else { s->cpl_in_use[blk] = s->cpl_in_use[blk-1]; } @@ -950,7 +963,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) } else if (!blk) { av_log(s->avctx, AV_LOG_ERROR, "new coupling coordinates must " "be present in block 0\n"); - return -1; + return AVERROR_INVALIDDATA; } } else { /* channel not in coupling */ @@ -1005,7 +1018,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) int bandwidth_code = get_bits(gbc, 6); if (bandwidth_code > 60) { av_log(s->avctx, AV_LOG_ERROR, "bandwidth code = %d > 60\n", bandwidth_code); - return -1; + return AVERROR_INVALIDDATA; } s->end_freq[ch] = bandwidth_code * 3 + 73; } @@ -1028,7 +1041,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) s->num_exp_groups[ch], s->dexps[ch][0], &s->dexps[ch][s->start_freq[ch]+!!ch])) { av_log(s->avctx, AV_LOG_ERROR, "exponent out-of-range\n"); - return -1; + return AVERROR_INVALIDDATA; } if (ch != CPL_CH && ch != s->lfe_ch) skip_bits(gbc, 2); /* skip gainrng */ @@ -1048,7 +1061,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) } else if (!blk) { av_log(s->avctx, AV_LOG_ERROR, "new bit allocation info must " "be present in block 0\n"); - return -1; + return AVERROR_INVALIDDATA; } } @@ -1079,7 +1092,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) } } else if (!s->eac3 && !blk) { av_log(s->avctx, AV_LOG_ERROR, "new snr offsets must be present in block 0\n"); - return -1; + return AVERROR_INVALIDDATA; } } @@ -1118,7 +1131,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) } else if (!s->eac3 && !blk) { av_log(s->avctx, AV_LOG_ERROR, "new coupling leak info must " "be present in block 0\n"); - return -1; + return AVERROR_INVALIDDATA; } s->first_cpl_leak = 0; } @@ -1130,7 +1143,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) s->dba_mode[ch] = get_bits(gbc, 2); if (s->dba_mode[ch] == DBA_RESERVED) { av_log(s->avctx, AV_LOG_ERROR, "delta bit allocation strategy reserved\n"); - return -1; + return AVERROR_INVALIDDATA; } bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2); } @@ -1171,7 +1184,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) s->dba_offsets[ch], s->dba_lengths[ch], s->dba_values[ch], s->mask[ch])) { av_log(s->avctx, AV_LOG_ERROR, "error in bit allocation\n"); - return -1; + return AVERROR_INVALIDDATA; } } if (bit_alloc_stages[ch] > 0) { @@ -1291,7 +1304,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, switch (err) { case AAC_AC3_PARSE_ERROR_SYNC: av_log(avctx, AV_LOG_ERROR, "frame sync error\n"); - return -1; + return AVERROR_INVALIDDATA; case AAC_AC3_PARSE_ERROR_BSID: av_log(avctx, AV_LOG_ERROR, "invalid bitstream id\n"); break; @@ -1305,17 +1318,20 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, /* skip frame if CRC is ok. otherwise use error concealment. */ /* TODO: add support for substreams and dependent frames */ if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT || s->substreamid) { - av_log(avctx, AV_LOG_ERROR, "unsupported frame type : " + av_log(avctx, AV_LOG_WARNING, "unsupported frame type : " "skipping frame\n"); *got_frame_ptr = 0; - return s->frame_size; + return buf_size; } else { av_log(avctx, AV_LOG_ERROR, "invalid frame type\n"); } break; - default: - av_log(avctx, AV_LOG_ERROR, "invalid header\n"); + case AAC_AC3_PARSE_ERROR_CRC: + case AAC_AC3_PARSE_ERROR_CHANNEL_CFG: break; + default: // Normal AVERROR do not try to recover. + *got_frame_ptr = 0; + return err; } } else { /* check that reported frame size fits in input buffer */ @@ -1327,6 +1343,8 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, if (av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, &buf[2], s->frame_size - 2)) { av_log(avctx, AV_LOG_ERROR, "frame CRC mismatch\n"); + if (avctx->err_recognition & AV_EF_EXPLODE) + return AVERROR_INVALIDDATA; err = AAC_AC3_PARSE_ERROR_CRC; } } @@ -1344,14 +1362,15 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, s->output_mode = s->channel_mode; if (s->lfe_on) s->output_mode |= AC3_OUTPUT_LFEON; - if (avctx->request_channels > 0 && avctx->request_channels <= 2 && - avctx->request_channels < s->channels) { - s->out_channels = avctx->request_channels; - s->output_mode = avctx->request_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO; - s->channel_layout = avpriv_ac3_channel_layout_tab[s->output_mode]; + if (s->channels > 1 && + avctx->request_channel_layout == AV_CH_LAYOUT_MONO) { + s->out_channels = 1; + s->output_mode = AC3_CHMODE_MONO; + } else if (s->channels > 2 && + avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) { + s->out_channels = 2; + s->output_mode = AC3_CHMODE_STEREO; } - avctx->channels = s->out_channels; - avctx->channel_layout = s->channel_layout; s->loro_center_mix_level = gain_levels[s-> center_mix_level]; s->loro_surround_mix_level = gain_levels[s->surround_mix_level]; @@ -1367,6 +1386,9 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, return AVERROR_INVALIDDATA; } avctx->channels = s->out_channels; + avctx->channel_layout = avpriv_ac3_channel_layout_tab[s->output_mode & ~AC3_OUTPUT_LFEON]; + if (s->output_mode & AC3_OUTPUT_LFEON) + avctx->channel_layout |= AV_CH_LOW_FREQUENCY; /* set audio service type based on bitstream mode for AC-3 */ avctx->audio_service_type = s->bitstream_mode; @@ -1374,7 +1396,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, avctx->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE; /* get output buffer */ - frame->nb_samples = s->num_blocks * 256; + frame->nb_samples = s->num_blocks * AC3_BLOCK_SIZE; if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; @@ -1395,7 +1417,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, } if (err) for (ch = 0; ch < s->out_channels; ch++) - memcpy(((float*)frame->data[ch]) + AC3_BLOCK_SIZE*blk, output[ch], 1024); + memcpy(((float*)frame->data[ch]) + AC3_BLOCK_SIZE*blk, output[ch], sizeof(**output) * AC3_BLOCK_SIZE); for (ch = 0; ch < s->out_channels; ch++) output[ch] = s->outptr[channel_map[ch]]; for (ch = 0; ch < s->out_channels; ch++) { @@ -1408,7 +1430,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, /* keep last block for error concealment in next frame */ for (ch = 0; ch < s->out_channels; ch++) - memcpy(s->output[ch], output[ch], 1024); + memcpy(s->output[ch], output[ch], sizeof(**output) * AC3_BLOCK_SIZE); *got_frame_ptr = 1; @@ -1450,6 +1472,7 @@ static const AVClass ac3_decoder_class = { AVCodec ff_ac3_decoder = { .name = "ac3", + .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_AC3, .priv_data_size = sizeof (AC3DecodeContext), @@ -1457,7 +1480,6 @@ AVCodec ff_ac3_decoder = { .close = ac3_decode_end, .decode = ac3_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, .priv_class = &ac3_decoder_class, @@ -1473,6 +1495,7 @@ static const AVClass eac3_decoder_class = { AVCodec ff_eac3_decoder = { .name = "eac3", + .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52B (AC-3, E-AC-3)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_EAC3, .priv_data_size = sizeof (AC3DecodeContext), @@ -1480,7 +1503,6 @@ AVCodec ff_eac3_decoder = { .close = ac3_decode_end, .decode = ac3_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52B (AC-3, E-AC-3)"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, .priv_class = &eac3_decoder_class, diff --git a/ffmpeg/libavcodec/ac3dec.h b/ffmpeg/libavcodec/ac3dec.h index 6c99ef6..fa447c4 100644 --- a/ffmpeg/libavcodec/ac3dec.h +++ b/ffmpeg/libavcodec/ac3dec.h @@ -81,7 +81,6 @@ typedef struct AC3DecodeContext { int num_blocks; ///< number of audio blocks int bitstream_mode; ///< bitstream mode (bsmod) int channel_mode; ///< channel mode (acmod) - int channel_layout; ///< channel layout int lfe_on; ///< lfe channel in use int channel_map; ///< custom channel map int center_mix_level; ///< Center mix level index @@ -209,7 +208,7 @@ typedef struct AC3DecodeContext { float *dlyptr[AC3_MAX_CHANNELS]; ///@name Aligned arrays - DECLARE_ALIGNED(16, int, fixed_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< fixed-point transform coefficients + DECLARE_ALIGNED(16, int32_t, fixed_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< fixed-point transform coefficients DECLARE_ALIGNED(32, float, transform_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< transform coefficients DECLARE_ALIGNED(32, float, delay)[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< delay - added to the next block DECLARE_ALIGNED(32, float, window)[AC3_BLOCK_SIZE]; ///< window coefficients diff --git a/ffmpeg/libavcodec/ac3dsp.c b/ffmpeg/libavcodec/ac3dsp.c index 6df3a68..feda6dd 100644 --- a/ffmpeg/libavcodec/ac3dsp.c +++ b/ffmpeg/libavcodec/ac3dsp.c @@ -239,6 +239,19 @@ static void ac3_downmix_c(float **samples, float (*matrix)[2], } } +static void apply_window_int16_c(int16_t *output, const int16_t *input, + const int16_t *window, unsigned int len) +{ + int i; + int len2 = len >> 1; + + for (i = 0; i < len2; i++) { + int16_t w = window[i]; + output[i] = (MUL16(input[i], w) + (1 << 14)) >> 15; + output[len-i-1] = (MUL16(input[len-i-1], w) + (1 << 14)) >> 15; + } +} + av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact) { c->ac3_exponent_min = ac3_exponent_min_c; @@ -253,6 +266,7 @@ av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact) c->sum_square_butterfly_int32 = ac3_sum_square_butterfly_int32_c; c->sum_square_butterfly_float = ac3_sum_square_butterfly_float_c; c->downmix = ac3_downmix_c; + c->apply_window_int16 = apply_window_int16_c; if (ARCH_ARM) ff_ac3dsp_init_arm(c, bit_exact); diff --git a/ffmpeg/libavcodec/ac3dsp.h b/ffmpeg/libavcodec/ac3dsp.h index bafbc89..bced597 100644 --- a/ffmpeg/libavcodec/ac3dsp.h +++ b/ffmpeg/libavcodec/ac3dsp.h @@ -134,6 +134,20 @@ typedef struct AC3DSPContext { void (*downmix)(float **samples, float (*matrix)[2], int out_ch, int in_ch, int len); + + /** + * Apply symmetric window in 16-bit fixed-point. + * @param output destination array + * constraints: 16-byte aligned + * @param input source array + * constraints: 16-byte aligned + * @param window window array + * constraints: 16-byte aligned, at least len/2 elements + * @param len full window length + * constraints: multiple of ? greater than zero + */ + void (*apply_window_int16)(int16_t *output, const int16_t *input, + const int16_t *window, unsigned int len); } AC3DSPContext; void ff_ac3dsp_init (AC3DSPContext *c, int bit_exact); diff --git a/ffmpeg/libavcodec/ac3enc.c b/ffmpeg/libavcodec/ac3enc.c index 15ff343..37c496c 100644 --- a/ffmpeg/libavcodec/ac3enc.c +++ b/ffmpeg/libavcodec/ac3enc.c @@ -26,10 +26,9 @@ * The simplest AC-3 encoder. */ -//#define ASSERT_LEVEL 2 - #include +#include "libavutil/attributes.h" #include "libavutil/avassert.h" #include "libavutil/avstring.h" #include "libavutil/channel_layout.h" @@ -754,7 +753,7 @@ static void count_frame_bits_fixed(AC3EncodeContext *s) * Initialize bit allocation. * Set default parameter codes and calculate parameter values. */ -static void bit_alloc_init(AC3EncodeContext *s) +static av_cold void bit_alloc_init(AC3EncodeContext *s) { int ch; @@ -2018,6 +2017,7 @@ av_cold int ff_ac3_encode_close(AVCodecContext *avctx) AC3EncodeContext *s = avctx->priv_data; av_freep(&s->windowed_samples); + if (s->planar_samples) for (ch = 0; ch < s->channels; ch++) av_freep(&s->planar_samples[ch]); av_freep(&s->planar_samples); diff --git a/ffmpeg/libavcodec/ac3enc.h b/ffmpeg/libavcodec/ac3enc.h index be9dcf2..a04e704 100644 --- a/ffmpeg/libavcodec/ac3enc.h +++ b/ffmpeg/libavcodec/ac3enc.h @@ -3,20 +3,20 @@ * Copyright (c) 2000 Fabrice Bellard * Copyright (c) 2006-2010 Justin Ruggles * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/ac3enc_fixed.c b/ffmpeg/libavcodec/ac3enc_fixed.c index 5d8dd5c..5194d42 100644 --- a/ffmpeg/libavcodec/ac3enc_fixed.c +++ b/ffmpeg/libavcodec/ac3enc_fixed.c @@ -70,17 +70,6 @@ av_cold int AC3_NAME(mdct_init)(AC3EncodeContext *s) } -/* - * Apply KBD window to input samples prior to MDCT. - */ -static void apply_window(void *dsp, int16_t *output, const int16_t *input, - const int16_t *window, unsigned int len) -{ - DSPContext *dsp0 = dsp; - dsp0->apply_window_int16(output, input, window, len); -} - - /* * Normalize the input samples to use the maximum available precision. * This assumes signed 16-bit input samples. @@ -154,6 +143,7 @@ static av_cold int ac3_fixed_encode_init(AVCodecContext *avctx) AVCodec ff_ac3_fixed_encoder = { .name = "ac3_fixed", + .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_AC3, .priv_data_size = sizeof(AC3EncodeContext), @@ -162,7 +152,6 @@ AVCodec ff_ac3_fixed_encoder = { .close = ff_ac3_encode_close, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), .priv_class = &ac3enc_class, .channel_layouts = ff_ac3_channel_layouts, .defaults = ac3_defaults, diff --git a/ffmpeg/libavcodec/ac3enc_float.c b/ffmpeg/libavcodec/ac3enc_float.c index 7864f41..35fb418 100644 --- a/ffmpeg/libavcodec/ac3enc_float.c +++ b/ffmpeg/libavcodec/ac3enc_float.c @@ -87,18 +87,6 @@ av_cold int ff_ac3_float_mdct_init(AC3EncodeContext *s) } -/* - * Apply KBD window to input samples prior to MDCT. - */ -static void apply_window(void *dsp, float *output, - const float *input, const float *window, - unsigned int len) -{ - AVFloatDSPContext *fdsp = dsp; - fdsp->vector_fmul(output, input, window, len); -} - - /* * Normalize the input samples. * Not needed for the floating-point encoder. @@ -152,6 +140,7 @@ static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl) #if CONFIG_AC3_ENCODER AVCodec ff_ac3_encoder = { .name = "ac3", + .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_AC3, .priv_data_size = sizeof(AC3EncodeContext), @@ -160,7 +149,6 @@ AVCodec ff_ac3_encoder = { .close = ff_ac3_encode_close, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), .priv_class = &ac3enc_class, .channel_layouts = ff_ac3_channel_layouts, .defaults = ac3_defaults, diff --git a/ffmpeg/libavcodec/ac3enc_opts_template.c b/ffmpeg/libavcodec/ac3enc_opts_template.c index 339a08f..a252be9 100644 --- a/ffmpeg/libavcodec/ac3enc_opts_template.c +++ b/ffmpeg/libavcodec/ac3enc_opts_template.c @@ -2,20 +2,20 @@ * AC-3 encoder options * Copyright (c) 2011 Justin Ruggles * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/ac3enc_template.c b/ffmpeg/libavcodec/ac3enc_template.c index 0389c2e..4689f70 100644 --- a/ffmpeg/libavcodec/ac3enc_template.c +++ b/ffmpeg/libavcodec/ac3enc_template.c @@ -34,10 +34,6 @@ static void scale_coefficients(AC3EncodeContext *s); -static void apply_window(void *dsp, SampleType *output, - const SampleType *input, const SampleType *window, - unsigned int len); - static int normalize_samples(AC3EncodeContext *s); static void clip_coefficients(DSPContext *dsp, CoefType *coef, unsigned int len); @@ -105,11 +101,11 @@ static void apply_mdct(AC3EncodeContext *s) const SampleType *input_samples = &s->planar_samples[ch][blk * AC3_BLOCK_SIZE]; #if CONFIG_AC3ENC_FLOAT - apply_window(&s->fdsp, s->windowed_samples, input_samples, - s->mdct_window, AC3_WINDOW_SIZE); + s->fdsp.vector_fmul(s->windowed_samples, input_samples, + s->mdct_window, AC3_WINDOW_SIZE); #else - apply_window(&s->dsp, s->windowed_samples, input_samples, - s->mdct_window, AC3_WINDOW_SIZE); + s->ac3dsp.apply_window_int16(s->windowed_samples, input_samples, + s->mdct_window, AC3_WINDOW_SIZE); #endif if (s->fixed_point) @@ -361,7 +357,7 @@ static void compute_rematrixing_strategy(AC3EncodeContext *s) } for (bnd = 0; bnd < block->num_rematrixing_bands; bnd++) { - /* calculate calculate sum of squared coeffs for one band in one block */ + /* calculate sum of squared coeffs for one band in one block */ int start = ff_ac3_rematrix_band_tab[bnd]; int end = FFMIN(nb_coefs, ff_ac3_rematrix_band_tab[bnd+1]); CoefSumType sum[4]; diff --git a/ffmpeg/libavcodec/ac3tab.c b/ffmpeg/libavcodec/ac3tab.c index 9d20d90..1ae7ddf 100644 --- a/ffmpeg/libavcodec/ac3tab.c +++ b/ffmpeg/libavcodec/ac3tab.c @@ -114,7 +114,7 @@ const uint8_t ff_ac3_enc_channel_map[8][2][6] = { }; /** - * Table to remap channels from from AC-3 order to SMPTE order. + * Table to remap channels from AC-3 order to SMPTE order. * [channel_mode][lfe][ch] */ const uint8_t ff_ac3_dec_channel_map[8][2][6] = { diff --git a/ffmpeg/libavcodec/acelp_vectors.c b/ffmpeg/libavcodec/acelp_vectors.c index c9d6f87..86851a3 100644 --- a/ffmpeg/libavcodec/acelp_vectors.c +++ b/ffmpeg/libavcodec/acelp_vectors.c @@ -114,10 +114,10 @@ const float ff_b60_sinc[61] = { 0.898529 , 0.865051 , 0.769257 , 0.624054 , 0.448639 , 0.265289 , 0.0959167 , -0.0412598 , -0.134338 , -0.178986 , -0.178528 , -0.142609 , -0.0849304 , -0.0205078 , 0.0369568 , 0.0773926 , 0.0955200 , 0.0912781 , - 0.0689392 , 0.0357056 , 0. , -0.0305481 , -0.0504150 , -0.0570068 , + 0.0689392 , 0.0357056 , 0.0 , -0.0305481 , -0.0504150 , -0.0570068 , -0.0508423 , -0.0350037 , -0.0141602 , 0.00665283, 0.0230713 , 0.0323486 , 0.0335388 , 0.0275879 , 0.0167847 , 0.00411987, -0.00747681, -0.0156860 , --0.0193481 , -0.0183716 , -0.0137634 , -0.00704956, 0. , 0.00582886 , +-0.0193481 , -0.0183716 , -0.0137634 , -0.00704956, 0.0 , 0.00582886 , 0.00939941, 0.0103760 , 0.00903320, 0.00604248, 0.00238037, -0.00109863 , -0.00366211, -0.00497437, -0.00503540, -0.00402832, -0.00241089, -0.000579834, 0.00103760, 0.00222778, 0.00277710, 0.00271606, 0.00213623, 0.00115967 , diff --git a/ffmpeg/libavcodec/adpcm.c b/ffmpeg/libavcodec/adpcm.c index 3f8cfbc..8e20de2 100644 --- a/ffmpeg/libavcodec/adpcm.c +++ b/ffmpeg/libavcodec/adpcm.c @@ -1,6 +1,18 @@ /* * Copyright (c) 2001-2003 The ffmpeg Project * + * first version by Francois Revol (revol@free.fr) + * fringe ADPCM codecs (e.g., DK3, DK4, Westwood) + * by Mike Melanson (melanson@pcisys.net) + * CD-ROM XA ADPCM codec by BERO + * EA ADPCM decoder by Robin Kay (komadori@myrealbox.com) + * EA ADPCM R1/R2/R3 decoder by Peter Ross (pross@xvid.org) + * EA IMA EACS decoder by Peter Ross (pross@xvid.org) + * EA IMA SEAD decoder by Peter Ross (pross@xvid.org) + * EA ADPCM XAS decoder by Peter Ross (pross@xvid.org) + * MAXIS EA ADPCM decoder by Robert Marston (rmarston@gmail.com) + * THP ADPCM decoder by Marco Gerards (mgerards@xs4all.nl) + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -19,7 +31,6 @@ */ #include "avcodec.h" #include "get_bits.h" -#include "put_bits.h" #include "bytestream.h" #include "adpcm.h" #include "adpcm_data.h" @@ -28,18 +39,6 @@ /** * @file * ADPCM decoders - * First version by Francois Revol (revol@free.fr) - * Fringe ADPCM codecs (e.g., DK3, DK4, Westwood) - * by Mike Melanson (melanson@pcisys.net) - * CD-ROM XA ADPCM codec by BERO - * EA ADPCM decoder by Robin Kay (komadori@myrealbox.com) - * EA ADPCM R1/R2/R3 decoder by Peter Ross (pross@xvid.org) - * EA IMA EACS decoder by Peter Ross (pross@xvid.org) - * EA IMA SEAD decoder by Peter Ross (pross@xvid.org) - * EA ADPCM XAS decoder by Peter Ross (pross@xvid.org) - * MAXIS EA ADPCM decoder by Robert Marston (rmarston@gmail.com) - * THP ADPCM decoder by Marco Gerards (mgerards@xs4all.nl) - * * Features and limitations: * * Reference documents: @@ -96,6 +95,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) unsigned int max_channels = 2; switch(avctx->codec->id) { + case AV_CODEC_ID_ADPCM_DTK: case AV_CODEC_ID_ADPCM_EA: min_channels = 2; break; @@ -118,10 +118,8 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) c->status[0].step = c->status[1].step = 511; break; case AV_CODEC_ID_ADPCM_IMA_WAV: - if (avctx->bits_per_coded_sample != 4) { - av_log(avctx, AV_LOG_ERROR, "Only 4-bit ADPCM IMA WAV files are supported\n"); - return -1; - } + if (avctx->bits_per_coded_sample < 2 || avctx->bits_per_coded_sample > 5) + return AVERROR_INVALIDDATA; break; case AV_CODEC_ID_ADPCM_IMA_APC: if (avctx->extradata && avctx->extradata_size >= 8) { @@ -148,6 +146,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) case AV_CODEC_ID_ADPCM_EA_XAS: case AV_CODEC_ID_ADPCM_THP: case AV_CODEC_ID_ADPCM_AFC: + case AV_CODEC_ID_ADPCM_DTK: avctx->sample_fmt = AV_SAMPLE_FMT_S16P; break; case AV_CODEC_ID_ADPCM_IMA_WS: @@ -187,6 +186,29 @@ static inline short adpcm_ima_expand_nibble(ADPCMChannelStatus *c, char nibble, return (short)c->predictor; } +static inline int16_t adpcm_ima_wav_expand_nibble(ADPCMChannelStatus *c, GetBitContext *gb, int bps) +{ + int nibble, step_index, predictor, sign, delta, diff, step, shift; + + shift = bps - 1; + nibble = get_bits_le(gb, bps), + step = ff_adpcm_step_table[c->step_index]; + step_index = c->step_index + ff_adpcm_index_tables[bps - 2][nibble]; + step_index = av_clip(step_index, 0, 88); + + sign = nibble & (1 << shift); + delta = nibble & ((1 << shift) - 1); + diff = ((2 * delta + 1) * step) >> shift; + predictor = c->predictor; + if (sign) predictor -= diff; + else predictor += diff; + + c->predictor = av_clip_int16(predictor); + c->step_index = step_index; + + return (int16_t)c->predictor; +} + static inline int adpcm_ima_qt_expand_nibble(ADPCMChannelStatus *c, int nibble, int shift) { int step_index; @@ -550,11 +572,20 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb, buf_size = FFMIN(buf_size, avctx->block_align); nb_samples = 1 + (buf_size - 4 * ch) * 2 / ch; break; + case AV_CODEC_ID_ADPCM_IMA_RAD: + if (avctx->block_align > 0) + buf_size = FFMIN(buf_size, avctx->block_align); + nb_samples = (buf_size - 4 * ch) * 2 / ch; + break; case AV_CODEC_ID_ADPCM_IMA_WAV: + { + int bsize = ff_adpcm_ima_block_sizes[avctx->bits_per_coded_sample - 2]; + int bsamples = ff_adpcm_ima_block_samples[avctx->bits_per_coded_sample - 2]; if (avctx->block_align > 0) buf_size = FFMIN(buf_size, avctx->block_align); - nb_samples = 1 + (buf_size - 4 * ch) / (4 * ch) * 8; + nb_samples = 1 + (buf_size - 4 * ch) / (bsize * ch) * bsamples; break; + } case AV_CODEC_ID_ADPCM_MS: if (avctx->block_align > 0) buf_size = FFMIN(buf_size, avctx->block_align); @@ -591,6 +622,10 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb, break; } case AV_CODEC_ID_ADPCM_THP: + if (avctx->extradata) { + nb_samples = buf_size / (8 * ch) * 14; + break; + } has_coded_samples = 1; bytestream2_skip(gb, 4); // channel size *coded_samples = bytestream2_get_be32(gb); @@ -603,6 +638,9 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb, case AV_CODEC_ID_ADPCM_XA: nb_samples = (buf_size / 128) * 224 / ch; break; + case AV_CODEC_ID_ADPCM_DTK: + nb_samples = buf_size / (16 * ch) * 28; + break; } /* validate coded sample count */ @@ -707,6 +745,23 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, } } + if (avctx->bits_per_coded_sample != 4) { + int samples_per_block = ff_adpcm_ima_block_samples[avctx->bits_per_coded_sample - 2]; + GetBitContext g; + + init_get_bits8(&g, gb.buffer, bytestream2_get_bytes_left(&gb)); + for (n = 0; n < (nb_samples - 1) / samples_per_block; n++) { + for (i = 0; i < avctx->channels; i++) { + cs = &c->status[i]; + samples = &samples_p[i][1 + n * samples_per_block]; + for (m = 0; m < samples_per_block; m++) { + samples[m] = adpcm_ima_wav_expand_nibble(cs, &g, + avctx->bits_per_coded_sample); + } + } + } + bytestream2_skip(&gb, avctx->block_align - avctx->channels * 4); + } else { for (n = 0; n < (nb_samples - 1) / 8; n++) { for (i = 0; i < avctx->channels; i++) { cs = &c->status[i]; @@ -718,6 +773,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, } } } + } break; case AV_CODEC_ID_ADPCM_4XM: for (i = 0; i < avctx->channels; i++) @@ -904,6 +960,31 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, *samples++ = adpcm_ima_oki_expand_nibble(&c->status[st], v & 0x0F); } break; + case AV_CODEC_ID_ADPCM_IMA_RAD: + for (channel = 0; channel < avctx->channels; channel++) { + cs = &c->status[channel]; + cs->step_index = sign_extend(bytestream2_get_le16u(&gb), 16); + cs->predictor = sign_extend(bytestream2_get_le16u(&gb), 16); + if (cs->step_index > 88u){ + av_log(avctx, AV_LOG_ERROR, "ERROR: step_index[%d] = %i\n", + channel, cs->step_index); + return AVERROR_INVALIDDATA; + } + } + for (n = 0; n < nb_samples / 2; n++) { + int byte[2]; + + byte[0] = bytestream2_get_byteu(&gb); + if (st) + byte[1] = bytestream2_get_byteu(&gb); + for(channel = 0; channel < avctx->channels; channel++) { + *samples++ = adpcm_ima_expand_nibble(&c->status[channel], byte[channel] & 0x0F, 3); + } + for(channel = 0; channel < avctx->channels; channel++) { + *samples++ = adpcm_ima_expand_nibble(&c->status[channel], byte[channel] >> 4 , 3); + } + } + break; case AV_CODEC_ID_ADPCM_IMA_WS: if (c->vqa_version == 3) { for (channel = 0; channel < avctx->channels; channel++) { @@ -1321,6 +1402,18 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, int table[6][16]; int ch; + if (avctx->extradata) { + GetByteContext tb; + if (avctx->extradata_size < 32 * avctx->channels) { + av_log(avctx, AV_LOG_ERROR, "Missing coeff table\n"); + return AVERROR_INVALIDDATA; + } + + bytestream2_init(&tb, avctx->extradata, avctx->extradata_size); + for (i = 0; i < avctx->channels; i++) + for (n = 0; n < 16; n++) + table[i][n] = sign_extend(bytestream2_get_be16u(&tb), 16); + } else { for (i = 0; i < avctx->channels; i++) for (n = 0; n < 16; n++) table[i][n] = sign_extend(bytestream2_get_be16u(&gb), 16); @@ -1330,6 +1423,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, c->status[i].sample1 = sign_extend(bytestream2_get_be16u(&gb), 16); c->status[i].sample2 = sign_extend(bytestream2_get_be16u(&gb), 16); } + } for (ch = 0; ch < avctx->channels; ch++) { samples = samples_p[ch]; @@ -1363,6 +1457,54 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, } break; } + case AV_CODEC_ID_ADPCM_DTK: + for (channel = 0; channel < avctx->channels; channel++) { + samples = samples_p[channel]; + + /* Read in every sample for this channel. */ + for (i = 0; i < nb_samples / 28; i++) { + int byte, header; + if (channel) + bytestream2_skipu(&gb, 1); + header = bytestream2_get_byteu(&gb); + bytestream2_skipu(&gb, 3 - channel); + + /* Decode 28 samples. */ + for (n = 0; n < 28; n++) { + int32_t sampledat, prev; + + switch (header >> 4) { + case 1: + prev = (c->status[channel].sample1 * 0x3c); + break; + case 2: + prev = (c->status[channel].sample1 * 0x73) - (c->status[channel].sample2 * 0x34); + break; + case 3: + prev = (c->status[channel].sample1 * 0x62) - (c->status[channel].sample2 * 0x37); + break; + default: + prev = 0; + } + + prev = av_clip((prev + 0x20) >> 6, -0x200000, 0x1fffff); + + byte = bytestream2_get_byteu(&gb); + if (!channel) + sampledat = sign_extend(byte, 4); + else + sampledat = sign_extend(byte >> 4, 4); + + sampledat = (((sampledat << 12) >> (header & 0xf)) << 6) + prev; + *samples++ = av_clip_int16(sampledat >> 6); + c->status[channel].sample2 = c->status[channel].sample1; + c->status[channel].sample1 = sampledat; + } + } + if (!channel) + bytestream2_seek(&gb, 0, SEEK_SET); + } + break; default: return -1; @@ -1390,13 +1532,13 @@ static const enum AVSampleFormat sample_fmts_both[] = { AV_SAMPLE_FMT_S16, #define ADPCM_DECODER(id_, sample_fmts_, name_, long_name_) \ AVCodec ff_ ## name_ ## _decoder = { \ .name = #name_, \ + .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ .type = AVMEDIA_TYPE_AUDIO, \ .id = id_, \ .priv_data_size = sizeof(ADPCMDecodeContext), \ .init = adpcm_decode_init, \ .decode = adpcm_decode_frame, \ .capabilities = CODEC_CAP_DR1, \ - .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ .sample_fmts = sample_fmts_, \ } @@ -1404,6 +1546,7 @@ AVCodec ff_ ## name_ ## _decoder = { \ ADPCM_DECODER(AV_CODEC_ID_ADPCM_4XM, sample_fmts_s16p, adpcm_4xm, "ADPCM 4X Movie"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_AFC, sample_fmts_s16p, adpcm_afc, "ADPCM Nintendo Gamecube AFC"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_CT, sample_fmts_s16, adpcm_ct, "ADPCM Creative Technology"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_DTK, sample_fmts_s16p, adpcm_dtk, "ADPCM Nintendo Gamecube DTK"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA, sample_fmts_s16, adpcm_ea, "ADPCM Electronic Arts"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_MAXIS_XA, sample_fmts_s16, adpcm_ea_maxis_xa, "ADPCM Electronic Arts Maxis CDROM XA"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_R1, sample_fmts_s16p, adpcm_ea_r1, "ADPCM Electronic Arts R1"); @@ -1419,6 +1562,7 @@ ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_EA_SEAD, sample_fmts_s16, adpcm_ima_ea_sead ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_ISS, sample_fmts_s16, adpcm_ima_iss, "ADPCM IMA Funcom ISS"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_OKI, sample_fmts_s16, adpcm_ima_oki, "ADPCM IMA Dialogic OKI"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_QT, sample_fmts_s16p, adpcm_ima_qt, "ADPCM IMA QuickTime"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_RAD, sample_fmts_s16, adpcm_ima_rad, "ADPCM IMA Radical"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_SMJPEG, sample_fmts_s16, adpcm_ima_smjpeg, "ADPCM IMA Loki SDL MJPEG"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_WAV, sample_fmts_s16p, adpcm_ima_wav, "ADPCM IMA WAV"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_WS, sample_fmts_both, adpcm_ima_ws, "ADPCM IMA Westwood"); diff --git a/ffmpeg/libavcodec/adpcm.h b/ffmpeg/libavcodec/adpcm.h index 08fd23f..f43a28c 100644 --- a/ffmpeg/libavcodec/adpcm.h +++ b/ffmpeg/libavcodec/adpcm.h @@ -38,8 +38,8 @@ typedef struct ADPCMChannelStatus { int prev_sample; /* MS version */ - int16_t sample1; - int16_t sample2; + int sample1; + int sample2; int coeff1; int coeff2; int idelta; diff --git a/ffmpeg/libavcodec/adpcm_data.c b/ffmpeg/libavcodec/adpcm_data.c index 0625fc9..1d3e579 100644 --- a/ffmpeg/libavcodec/adpcm_data.c +++ b/ffmpeg/libavcodec/adpcm_data.c @@ -27,12 +27,33 @@ /* ff_adpcm_step_table[] and ff_adpcm_index_table[] are from the ADPCM reference source */ -/* This is the index table: */ +static const int8_t adpcm_index_table2[4] = { + -1, 2, + -1, 2, +}; + +static const int8_t adpcm_index_table3[8] = { + -1, -1, 1, 2, + -1, -1, 1, 2, +}; + const int8_t ff_adpcm_index_table[16] = { -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8, }; +static const int8_t adpcm_index_table5[32] = { + -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16, + -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16, +}; + +const int8_t const *ff_adpcm_index_tables[4] = { + &adpcm_index_table2[0], + &adpcm_index_table3[0], + &ff_adpcm_index_table[0], + &adpcm_index_table5[0], +}; + /** * This is the step table. Note that many programs use slight deviations from * this table, but such deviations are negligible: diff --git a/ffmpeg/libavcodec/adpcm_data.h b/ffmpeg/libavcodec/adpcm_data.h index 0ebb7c3..a14d520 100644 --- a/ffmpeg/libavcodec/adpcm_data.h +++ b/ffmpeg/libavcodec/adpcm_data.h @@ -28,6 +28,10 @@ #include +static const uint8_t ff_adpcm_ima_block_sizes[4] = { 4, 12, 4, 20 }; +static const uint8_t ff_adpcm_ima_block_samples[4] = { 16, 32, 8, 32 }; + +extern const int8_t const *ff_adpcm_index_tables[4]; extern const int8_t ff_adpcm_index_table[16]; extern const int16_t ff_adpcm_step_table[89]; extern const int16_t ff_adpcm_oki_step_table[49]; diff --git a/ffmpeg/libavcodec/adpcmenc.c b/ffmpeg/libavcodec/adpcmenc.c index 762cf67..5391570 100644 --- a/ffmpeg/libavcodec/adpcmenc.c +++ b/ffmpeg/libavcodec/adpcmenc.c @@ -1,6 +1,10 @@ /* * Copyright (c) 2001-2003 The ffmpeg Project * + * first version by Francois Revol (revol@free.fr) + * fringe ADPCM codecs (e.g., DK3, DK4, Westwood) + * by Mike Melanson (melanson@pcisys.net) + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -28,10 +32,6 @@ /** * @file * ADPCM encoders - * First version by Francois Revol (revol@free.fr) - * Fringe ADPCM codecs (e.g., DK3, DK4, Westwood) - * by Mike Melanson (melanson@pcisys.net) - * * See ADPCM decoder reference documents for codec information. */ @@ -708,6 +708,7 @@ static const enum AVSampleFormat sample_fmts_p[] = { #define ADPCM_ENCODER(id_, name_, sample_fmts_, long_name_) \ AVCodec ff_ ## name_ ## _encoder = { \ .name = #name_, \ + .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ .type = AVMEDIA_TYPE_AUDIO, \ .id = id_, \ .priv_data_size = sizeof(ADPCMEncodeContext), \ @@ -715,7 +716,6 @@ AVCodec ff_ ## name_ ## _encoder = { \ .encode2 = adpcm_encode_frame, \ .close = adpcm_encode_close, \ .sample_fmts = sample_fmts_, \ - .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ } ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt, sample_fmts_p, "ADPCM IMA QuickTime"); diff --git a/ffmpeg/libavcodec/adx.c b/ffmpeg/libavcodec/adx.c index 4c88f81..94bc386 100644 --- a/ffmpeg/libavcodec/adx.c +++ b/ffmpeg/libavcodec/adx.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2011 Justin Ruggles * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/adx_parser.c b/ffmpeg/libavcodec/adx_parser.c index 706e242..1fa718f 100644 --- a/ffmpeg/libavcodec/adx_parser.c +++ b/ffmpeg/libavcodec/adx_parser.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2011 Justin Ruggles * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/adxdec.c b/ffmpeg/libavcodec/adxdec.c index 7d7fe3a..e59cc92 100644 --- a/ffmpeg/libavcodec/adxdec.c +++ b/ffmpeg/libavcodec/adxdec.c @@ -174,6 +174,7 @@ static void adx_decode_flush(AVCodecContext *avctx) AVCodec ff_adpcm_adx_decoder = { .name = "adpcm_adx", + .long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_ADPCM_ADX, .priv_data_size = sizeof(ADXContext), @@ -181,7 +182,6 @@ AVCodec ff_adpcm_adx_decoder = { .decode = adx_decode_frame, .flush = adx_decode_flush, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_NONE }, }; diff --git a/ffmpeg/libavcodec/adxenc.c b/ffmpeg/libavcodec/adxenc.c index df07c81..05e3245 100644 --- a/ffmpeg/libavcodec/adxenc.c +++ b/ffmpeg/libavcodec/adxenc.c @@ -158,6 +158,7 @@ static int adx_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, AVCodec ff_adpcm_adx_encoder = { .name = "adpcm_adx", + .long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_ADPCM_ADX, .priv_data_size = sizeof(ADXContext), @@ -165,5 +166,4 @@ AVCodec ff_adpcm_adx_encoder = { .encode2 = adx_encode_frame, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"), }; diff --git a/ffmpeg/libavcodec/alac.c b/ffmpeg/libavcodec/alac.c index 0018b9a..3f37f61 100644 --- a/ffmpeg/libavcodec/alac.c +++ b/ffmpeg/libavcodec/alac.c @@ -50,6 +50,7 @@ #include "get_bits.h" #include "bytestream.h" #include "internal.h" +#include "thread.h" #include "unary.h" #include "mathops.h" #include "alac_data.h" @@ -287,9 +288,10 @@ static int decode_element(AVCodecContext *avctx, AVFrame *frame, int ch_index, return AVERROR_INVALIDDATA; } if (!alac->nb_samples) { + ThreadFrame tframe = { .f = frame }; /* get output buffer */ frame->nb_samples = output_samples; - if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0) return ret; } else if (output_samples != alac->nb_samples) { av_log(avctx, AV_LOG_ERROR, "sample count mismatch: %u != %d\n", @@ -318,6 +320,9 @@ static int decode_element(AVCodecContext *avctx, AVFrame *frame, int ch_index, rice_history_mult[ch] = get_bits(&alac->gb, 3); lpc_order[ch] = get_bits(&alac->gb, 5); + if (lpc_order[ch] >= alac->max_samples_per_frame) + return AVERROR_INVALIDDATA; + /* read the predictor table */ for (i = lpc_order[ch] - 1; i >= 0; i--) lpc_coefs[ch][i] = get_sbits(&alac->gb, 16); @@ -443,7 +448,8 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data, int channels; int ch, ret, got_end; - init_get_bits(&alac->gb, avpkt->data, avpkt->size * 8); + if ((ret = init_get_bits8(&alac->gb, avpkt->data, avpkt->size)) < 0) + return ret; got_end = 0; alac->nb_samples = 0; @@ -460,9 +466,8 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data, } channels = (element == TYPE_CPE) ? 2 : 1; - if ( ch + channels > alac->channels - || ff_alac_channel_layout_offsets[alac->channels - 1][ch] + channels > alac->channels - ) { + if (ch + channels > alac->channels || + ff_alac_channel_layout_offsets[alac->channels - 1][ch] + channels > alac->channels) { av_log(avctx, AV_LOG_ERROR, "invalid element channel count\n"); return AVERROR_INVALIDDATA; } @@ -508,11 +513,7 @@ static av_cold int alac_decode_close(AVCodecContext *avctx) static int allocate_buffers(ALACContext *alac) { int ch; - int buf_size; - - if (alac->max_samples_per_frame > INT_MAX / sizeof(int32_t)) - goto buf_alloc_fail; - buf_size = alac->max_samples_per_frame * sizeof(int32_t); + int buf_size = alac->max_samples_per_frame * sizeof(int32_t); for (ch = 0; ch < FFMIN(alac->channels, 2); ch++) { FF_ALLOC_OR_GOTO(alac->avctx, alac->predict_error_buffer[ch], @@ -543,7 +544,8 @@ static int alac_set_info(ALACContext *alac) bytestream2_skipu(&gb, 12); // size:4, alac:4, version:4 alac->max_samples_per_frame = bytestream2_get_be32u(&gb); - if (!alac->max_samples_per_frame || alac->max_samples_per_frame > INT_MAX) { + if (!alac->max_samples_per_frame || + alac->max_samples_per_frame > INT_MAX / sizeof(int32_t)) { av_log(alac->avctx, AV_LOG_ERROR, "max samples per frame invalid: %u\n", alac->max_samples_per_frame); return AVERROR_INVALIDDATA; @@ -615,14 +617,22 @@ static av_cold int alac_decode_init(AVCodecContext * avctx) return 0; } +static int init_thread_copy(AVCodecContext *avctx) +{ + ALACContext *alac = avctx->priv_data; + alac->avctx = avctx; + return allocate_buffers(alac); +} + AVCodec ff_alac_decoder = { .name = "alac", + .long_name = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_ALAC, .priv_data_size = sizeof(ALACContext), .init = alac_decode_init, .close = alac_decode_close, .decode = alac_decode_frame, - .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"), + .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy), + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, }; diff --git a/ffmpeg/libavcodec/alacenc.c b/ffmpeg/libavcodec/alacenc.c index 4ee558c..bc68a06 100644 --- a/ffmpeg/libavcodec/alacenc.c +++ b/ffmpeg/libavcodec/alacenc.c @@ -274,7 +274,7 @@ static void alac_linear_predictor(AlacEncodeContext *s, int ch) // generate warm-up samples residual[0] = samples[0]; for (i = 1; i <= lpc.lpc_order; i++) - residual[i] = samples[i] - samples[i-1]; + residual[i] = sign_extend(samples[i] - samples[i-1], s->write_sample_size); // perform lpc on remaining samples for (i = lpc.lpc_order + 1; i < s->frame_size; i++) { @@ -483,7 +483,6 @@ static av_cold int alac_encode_close(AVCodecContext *avctx) ff_lpc_end(&s->lpc_ctx); av_freep(&avctx->extradata); avctx->extradata_size = 0; - av_freep(&avctx->coded_frame); return 0; } @@ -579,12 +578,6 @@ static av_cold int alac_encode_init(AVCodecContext *avctx) goto error; } - avctx->coded_frame = avcodec_alloc_frame(); - if (!avctx->coded_frame) { - ret = AVERROR(ENOMEM); - goto error; - } - s->avctx = avctx; if ((ret = ff_lpc_init(&s->lpc_ctx, avctx->frame_size, @@ -641,6 +634,7 @@ static int alac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, AVCodec ff_alac_encoder = { .name = "alac", + .long_name = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_ALAC, .priv_data_size = sizeof(AlacEncodeContext), @@ -652,5 +646,4 @@ AVCodec ff_alac_encoder = { .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S32P, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"), }; diff --git a/ffmpeg/libavcodec/allcodecs.c b/ffmpeg/libavcodec/allcodecs.c index 1eaf2d3..e3a8251 100644 --- a/ffmpeg/libavcodec/allcodecs.c +++ b/ffmpeg/libavcodec/allcodecs.c @@ -24,8 +24,9 @@ * Provide registration of all codecs, parsers and bitstream filters for libavcodec. */ -#include "avcodec.h" #include "config.h" +#include "avcodec.h" +#include "version.h" #define REGISTER_HWACCEL(X, x) \ { \ @@ -79,7 +80,9 @@ void avcodec_register_all(void) REGISTER_HWACCEL(H264_VAAPI, h264_vaapi); REGISTER_HWACCEL(H264_VDA, h264_vda); REGISTER_HWACCEL(H264_VDPAU, h264_vdpau); + REGISTER_HWACCEL(MPEG1_XVMC, mpeg1_xvmc); REGISTER_HWACCEL(MPEG1_VDPAU, mpeg1_vdpau); + REGISTER_HWACCEL(MPEG2_XVMC, mpeg2_xvmc); REGISTER_HWACCEL(MPEG2_DXVA2, mpeg2_dxva2); REGISTER_HWACCEL(MPEG2_VAAPI, mpeg2_vaapi); REGISTER_HWACCEL(MPEG2_VDPAU, mpeg2_vdpau); @@ -96,6 +99,7 @@ void avcodec_register_all(void) REGISTER_ENCODER(A64MULTI, a64multi); REGISTER_ENCODER(A64MULTI5, a64multi5); REGISTER_DECODER(AASC, aasc); + REGISTER_DECODER(AIC, aic); REGISTER_ENCDEC (AMV, amv); REGISTER_DECODER(ANM, anm); REGISTER_DECODER(ANSI, ansi); @@ -153,6 +157,7 @@ void avcodec_register_all(void) REGISTER_DECODER(FOURXM, fourxm); REGISTER_DECODER(FRAPS, fraps); REGISTER_DECODER(FRWU, frwu); + REGISTER_DECODER(G2M, g2m); REGISTER_ENCDEC (GIF, gif); REGISTER_ENCDEC (H261, h261); REGISTER_ENCDEC (H263, h263); @@ -162,6 +167,8 @@ void avcodec_register_all(void) REGISTER_DECODER(H264_CRYSTALHD, h264_crystalhd); REGISTER_DECODER(H264_VDA, h264_vda); REGISTER_DECODER(H264_VDPAU, h264_vdpau); + REGISTER_DECODER(HEVC, hevc); + REGISTER_DECODER(HNM4_VIDEO, hnm4_video); REGISTER_ENCDEC (HUFFYUV, huffyuv); REGISTER_DECODER(IDCIN, idcin); REGISTER_DECODER(IFF_BYTERUN1, iff_byterun1); @@ -185,7 +192,9 @@ void avcodec_register_all(void) REGISTER_DECODER(MJPEGB, mjpegb); REGISTER_DECODER(MMVIDEO, mmvideo); REGISTER_DECODER(MOTIONPIXELS, motionpixels); +#if FF_API_XVMC REGISTER_DECODER(MPEG_XVMC, mpeg_xvmc); +#endif /* FF_API_XVMC */ REGISTER_ENCDEC (MPEG1VIDEO, mpeg1video); REGISTER_ENCDEC (MPEG2VIDEO, mpeg2video); REGISTER_ENCDEC (MPEG4, mpeg4); @@ -220,8 +229,8 @@ void avcodec_register_all(void) REGISTER_ENCDEC (PNG, png); REGISTER_ENCDEC (PPM, ppm); REGISTER_ENCDEC (PRORES, prores); - REGISTER_ENCODER(PRORES_ANATOLIY, prores_anatoliy); - REGISTER_ENCODER(PRORES_KOSTYA, prores_kostya); + REGISTER_ENCODER(PRORES_AW, prores_aw); + REGISTER_ENCODER(PRORES_KS, prores_ks); REGISTER_DECODER(PRORES_LGPL, prores_lgpl); REGISTER_DECODER(PTX, ptx); REGISTER_DECODER(QDRAW, qdraw); @@ -237,12 +246,13 @@ void avcodec_register_all(void) REGISTER_ENCDEC (RV20, rv20); REGISTER_DECODER(RV30, rv30); REGISTER_DECODER(RV40, rv40); - REGISTER_DECODER(S302M, s302m); + REGISTER_ENCDEC (S302M, s302m); REGISTER_DECODER(SANM, sanm); REGISTER_ENCDEC (SGI, sgi); REGISTER_DECODER(SGIRLE, sgirle); REGISTER_DECODER(SMACKER, smacker); REGISTER_DECODER(SMC, smc); + REGISTER_DECODER(SMVJPEG, smvjpeg); REGISTER_ENCDEC (SNOW, snow); REGISTER_DECODER(SP5X, sp5x); REGISTER_ENCDEC (SUNRAST, sunrast); @@ -282,7 +292,9 @@ void avcodec_register_all(void) REGISTER_DECODER(VP6A, vp6a); REGISTER_DECODER(VP6F, vp6f); REGISTER_DECODER(VP8, vp8); + REGISTER_DECODER(VP9, vp9); REGISTER_DECODER(VQA, vqa); + REGISTER_DECODER(WEBP, webp); REGISTER_ENCDEC (WMV1, wmv1); REGISTER_ENCDEC (WMV2, wmv2); REGISTER_DECODER(WMV3, wmv3); @@ -334,11 +346,13 @@ void avcodec_register_all(void) REGISTER_DECODER(IMC, imc); REGISTER_DECODER(MACE3, mace3); REGISTER_DECODER(MACE6, mace6); + REGISTER_DECODER(METASOUND, metasound); REGISTER_DECODER(MLP, mlp); REGISTER_DECODER(MP1, mp1); REGISTER_DECODER(MP1FLOAT, mp1float); REGISTER_ENCDEC (MP2, mp2); REGISTER_DECODER(MP2FLOAT, mp2float); + REGISTER_ENCODER(MP2FIXED, mp2fixed); REGISTER_DECODER(MP3, mp3); REGISTER_DECODER(MP3FLOAT, mp3float); REGISTER_DECODER(MP3ADU, mp3adu); @@ -362,11 +376,11 @@ void avcodec_register_all(void) REGISTER_DECODER(TAK, tak); REGISTER_DECODER(TRUEHD, truehd); REGISTER_DECODER(TRUESPEECH, truespeech); - REGISTER_DECODER(TTA, tta); + REGISTER_ENCDEC (TTA, tta); REGISTER_DECODER(TWINVQ, twinvq); REGISTER_DECODER(VMDAUDIO, vmdaudio); REGISTER_ENCDEC (VORBIS, vorbis); - REGISTER_DECODER(WAVPACK, wavpack); + REGISTER_ENCDEC (WAVPACK, wavpack); REGISTER_DECODER(WMALOSSLESS, wmalossless); REGISTER_DECODER(WMAPRO, wmapro); REGISTER_ENCDEC (WMAV1, wmav1); @@ -417,6 +431,7 @@ void avcodec_register_all(void) REGISTER_ENCDEC (ADPCM_ADX, adpcm_adx); REGISTER_DECODER(ADPCM_AFC, adpcm_afc); REGISTER_DECODER(ADPCM_CT, adpcm_ct); + REGISTER_DECODER(ADPCM_DTK, adpcm_dtk); REGISTER_DECODER(ADPCM_EA, adpcm_ea); REGISTER_DECODER(ADPCM_EA_MAXIS_XA, adpcm_ea_maxis_xa); REGISTER_DECODER(ADPCM_EA_R1, adpcm_ea_r1); @@ -425,6 +440,7 @@ void avcodec_register_all(void) REGISTER_DECODER(ADPCM_EA_XAS, adpcm_ea_xas); REGISTER_ENCDEC (ADPCM_G722, adpcm_g722); REGISTER_ENCDEC (ADPCM_G726, adpcm_g726); + REGISTER_DECODER(ADPCM_G726LE, adpcm_g726le); REGISTER_DECODER(ADPCM_IMA_AMV, adpcm_ima_amv); REGISTER_DECODER(ADPCM_IMA_APC, adpcm_ima_apc); REGISTER_DECODER(ADPCM_IMA_DK3, adpcm_ima_dk3); @@ -434,6 +450,7 @@ void avcodec_register_all(void) REGISTER_DECODER(ADPCM_IMA_ISS, adpcm_ima_iss); REGISTER_DECODER(ADPCM_IMA_OKI, adpcm_ima_oki); REGISTER_ENCDEC (ADPCM_IMA_QT, adpcm_ima_qt); + REGISTER_DECODER(ADPCM_IMA_RAD, adpcm_ima_rad); REGISTER_DECODER(ADPCM_IMA_SMJPEG, adpcm_ima_smjpeg); REGISTER_ENCDEC (ADPCM_IMA_WAV, adpcm_ima_wav); REGISTER_DECODER(ADPCM_IMA_WS, adpcm_ima_ws); @@ -448,6 +465,7 @@ void avcodec_register_all(void) REGISTER_DECODER(VIMA, vima); /* subtitles */ + REGISTER_ENCDEC (SSA, ssa); REGISTER_ENCDEC (ASS, ass); REGISTER_ENCDEC (DVBSUB, dvbsub); REGISTER_ENCDEC (DVDSUB, dvdsub); @@ -471,7 +489,7 @@ void avcodec_register_all(void) /* external libraries */ REGISTER_DECODER(LIBCELT, libcelt); REGISTER_ENCODER(LIBFAAC, libfaac); - REGISTER_ENCODER(LIBFDK_AAC, libfdk_aac); + REGISTER_ENCDEC (LIBFDK_AAC, libfdk_aac); REGISTER_ENCDEC (LIBGSM, libgsm); REGISTER_ENCDEC (LIBGSM_MS, libgsm_ms); REGISTER_ENCDEC (LIBILBC, libilbc); @@ -481,6 +499,7 @@ void avcodec_register_all(void) REGISTER_ENCDEC (LIBOPENJPEG, libopenjpeg); REGISTER_ENCDEC (LIBOPUS, libopus); REGISTER_ENCDEC (LIBSCHROEDINGER, libschroedinger); + REGISTER_ENCODER(LIBSHINE, libshine); REGISTER_ENCDEC (LIBSPEEX, libspeex); REGISTER_DECODER(LIBSTAGEFRIGHT_H264, libstagefright_h264); REGISTER_ENCODER(LIBTHEORA, libtheora); @@ -491,10 +510,13 @@ void avcodec_register_all(void) REGISTER_ENCDEC (LIBVORBIS, libvorbis); REGISTER_ENCDEC (LIBVPX_VP8, libvpx_vp8); REGISTER_ENCDEC (LIBVPX_VP9, libvpx_vp9); + REGISTER_ENCODER(LIBWAVPACK, libwavpack); + REGISTER_ENCODER(LIBWEBP, libwebp); REGISTER_ENCODER(LIBX264, libx264); REGISTER_ENCODER(LIBX264RGB, libx264rgb); REGISTER_ENCODER(LIBXAVS, libxavs); REGISTER_ENCODER(LIBXVID, libxvid); + REGISTER_DECODER(LIBZVBI_TELETEXT, libzvbi_teletext); REGISTER_ENCODER(LIBAACPLUS, libaacplus); /* text */ @@ -513,6 +535,7 @@ void avcodec_register_all(void) REGISTER_PARSER(DCA, dca); REGISTER_PARSER(DIRAC, dirac); REGISTER_PARSER(DNXHD, dnxhd); + REGISTER_PARSER(DPX, dpx); REGISTER_PARSER(DVBSUB, dvbsub); REGISTER_PARSER(DVDSUB, dvdsub); REGISTER_PARSER(DVD_NAV, dvd_nav); @@ -521,6 +544,7 @@ void avcodec_register_all(void) REGISTER_PARSER(H261, h261); REGISTER_PARSER(H263, h263); REGISTER_PARSER(H264, h264); + REGISTER_PARSER(HEVC, hevc); REGISTER_PARSER(MJPEG, mjpeg); REGISTER_PARSER(MLP, mlp); REGISTER_PARSER(MPEG4VIDEO, mpeg4video); @@ -535,6 +559,7 @@ void avcodec_register_all(void) REGISTER_PARSER(VORBIS, vorbis); REGISTER_PARSER(VP3, vp3); REGISTER_PARSER(VP8, vp8); + REGISTER_PARSER(VP9, vp9); /* bitstream filters */ REGISTER_BSF(AAC_ADTSTOASC, aac_adtstoasc); @@ -544,7 +569,6 @@ void avcodec_register_all(void) REGISTER_BSF(IMX_DUMP_HEADER, imx_dump_header); REGISTER_BSF(MJPEG2JPEG, mjpeg2jpeg); REGISTER_BSF(MJPEGA_DUMP_HEADER, mjpega_dump_header); - REGISTER_BSF(MP3_HEADER_COMPRESS, mp3_header_compress); REGISTER_BSF(MP3_HEADER_DECOMPRESS, mp3_header_decompress); REGISTER_BSF(MOV2TEXTSUB, mov2textsub); REGISTER_BSF(NOISE, noise); diff --git a/ffmpeg/libavcodec/alpha/dsputil_alpha_asm.S b/ffmpeg/libavcodec/alpha/dsputil_alpha_asm.S index 5c5f90a..d801bcf 100644 --- a/ffmpeg/libavcodec/alpha/dsputil_alpha_asm.S +++ b/ffmpeg/libavcodec/alpha/dsputil_alpha_asm.S @@ -26,17 +26,6 @@ #include "regdef.h" -/* Some nicer register names. */ -#define ta t10 -#define tb t11 -#define tc t12 -#define td AT -/* Danger: these overlap with the argument list and the return value */ -#define te a5 -#define tf a4 -#define tg a3 -#define th v0 - .set noat .set noreorder .arch pca56 diff --git a/ffmpeg/libavcodec/alpha/hpeldsp_alpha.c b/ffmpeg/libavcodec/alpha/hpeldsp_alpha.c index 9a092f5..8d54807 100644 --- a/ffmpeg/libavcodec/alpha/hpeldsp_alpha.c +++ b/ffmpeg/libavcodec/alpha/hpeldsp_alpha.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/attributes.h" #include "libavcodec/hpeldsp.h" #include "hpeldsp_alpha.h" #include "asm.h" @@ -173,7 +174,7 @@ static void put_pixels16_axp_asm(uint8_t *block, const uint8_t *pixels, put_pixels_axp_asm(block + 8, pixels + 8, line_size, h); } -void ff_hpeldsp_init_alpha(HpelDSPContext* c, int flags) +av_cold void ff_hpeldsp_init_alpha(HpelDSPContext *c, int flags) { c->put_pixels_tab[0][0] = put_pixels16_axp_asm; c->put_pixels_tab[0][1] = put_pixels16_x2_axp; diff --git a/ffmpeg/libavcodec/alpha/hpeldsp_alpha.h b/ffmpeg/libavcodec/alpha/hpeldsp_alpha.h index 53e8604..985182c 100644 --- a/ffmpeg/libavcodec/alpha/hpeldsp_alpha.h +++ b/ffmpeg/libavcodec/alpha/hpeldsp_alpha.h @@ -20,6 +20,7 @@ #define AVCODEC_ALPHA_HPELDSP_ALPHA_H #include +#include void put_pixels_axp_asm(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h); diff --git a/ffmpeg/libavcodec/alpha/hpeldsp_alpha_asm.S b/ffmpeg/libavcodec/alpha/hpeldsp_alpha_asm.S index afc3d42..df386c4 100644 --- a/ffmpeg/libavcodec/alpha/hpeldsp_alpha_asm.S +++ b/ffmpeg/libavcodec/alpha/hpeldsp_alpha_asm.S @@ -26,16 +26,6 @@ #include "regdef.h" -/* Some nicer register names. */ -#define ta t10 -#define tb t11 -#define tc t12 -#define td AT -/* Danger: these overlap with the argument list and the return value */ -#define te a5 -#define tf a4 -#define tg a3 -#define th v0 .set noat .set noreorder diff --git a/ffmpeg/libavcodec/alpha/regdef.h b/ffmpeg/libavcodec/alpha/regdef.h index aa1959f..f05577a 100644 --- a/ffmpeg/libavcodec/alpha/regdef.h +++ b/ffmpeg/libavcodec/alpha/regdef.h @@ -63,4 +63,15 @@ #define sp $30 /* stack pointer */ #define zero $31 /* reads as zero, writes are noops */ +/* Some nicer register names. */ +#define ta t10 +#define tb t11 +#define tc t12 +#define td AT +/* Danger: these overlap with the argument list and the return value */ +#define te a5 +#define tf a4 +#define tg a3 +#define th v0 + #endif /* AVCODEC_ALPHA_REGDEF_H */ diff --git a/ffmpeg/libavcodec/alsdec.c b/ffmpeg/libavcodec/alsdec.c index 96d467c..f554eaa 100644 --- a/ffmpeg/libavcodec/alsdec.c +++ b/ffmpeg/libavcodec/alsdec.c @@ -1,6 +1,6 @@ /* * MPEG-4 ALS decoder - * Copyright (c) 2009 Thilo Borgmann + * Copyright (c) 2009 Thilo Borgmann * * This file is part of FFmpeg. * @@ -22,13 +22,9 @@ /** * @file * MPEG-4 ALS decoder - * @author Thilo Borgmann + * @author Thilo Borgmann */ - -//#define DEBUG - - #include "avcodec.h" #include "get_bits.h" #include "unary.h" @@ -297,12 +293,12 @@ static av_cold int read_specific_config(ALSDecContext *ctx) avctx->extradata_size * 8, 1); if (config_offset < 0) - return -1; + return AVERROR_INVALIDDATA; skip_bits_long(&gb, config_offset); if (get_bits_left(&gb) < (30 << 3)) - return -1; + return AVERROR_INVALIDDATA; // read the fixed items als_id = get_bits_long(&gb, 32); @@ -337,7 +333,7 @@ static av_cold int read_specific_config(ALSDecContext *ctx) // check for ALSSpecificConfig struct if (als_id != MKBETAG('A','L','S','\0')) - return -1; + return AVERROR_INVALIDDATA; ctx->cur_frame_length = sconf->frame_length; @@ -352,7 +348,7 @@ static av_cold int read_specific_config(ALSDecContext *ctx) int chan_pos_bits = av_ceil_log2(avctx->channels); int bits_needed = avctx->channels * chan_pos_bits + 7; if (get_bits_left(&gb) < bits_needed) - return -1; + return AVERROR_INVALIDDATA; if (!(sconf->chan_pos = av_malloc(avctx->channels * sizeof(*sconf->chan_pos)))) return AVERROR(ENOMEM); @@ -378,7 +374,7 @@ static av_cold int read_specific_config(ALSDecContext *ctx) // read fixed header and trailer sizes, // if size = 0xFFFFFFFF then there is no data field! if (get_bits_left(&gb) < 64) - return -1; + return AVERROR_INVALIDDATA; header_size = get_bits_long(&gb, 32); trailer_size = get_bits_long(&gb, 32); @@ -392,10 +388,10 @@ static av_cold int read_specific_config(ALSDecContext *ctx) // skip the header and trailer data if (get_bits_left(&gb) < ht_size) - return -1; + return AVERROR_INVALIDDATA; if (ht_size > INT32_MAX) - return -1; + return AVERROR_PATCHWELCOME; skip_bits_long(&gb, ht_size); @@ -403,7 +399,7 @@ static av_cold int read_specific_config(ALSDecContext *ctx) // initialize CRC calculation if (sconf->crc_enabled) { if (get_bits_left(&gb) < 32) - return -1; + return AVERROR_INVALIDDATA; if (avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_CAREFUL)) { ctx->crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE); @@ -648,7 +644,7 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) if (bd->block_length & (sub_blocks - 1)) { av_log(avctx, AV_LOG_WARNING, "Block length is not evenly divisible by the number of subblocks.\n"); - return -1; + return AVERROR_INVALIDDATA; } sb_length = bd->block_length >> log2_sub_blocks; @@ -979,20 +975,18 @@ static int decode_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) */ static int read_block(ALSDecContext *ctx, ALSBlockData *bd) { - GetBitContext *gb = &ctx->gb; int ret; + GetBitContext *gb = &ctx->gb; *bd->shift_lsbs = 0; // read block type flag and read the samples accordingly if (get_bits1(gb)) { - if ((ret = read_var_block_data(ctx, bd)) < 0) - return ret; + ret = read_var_block_data(ctx, bd); } else { - if ((ret = read_const_block_data(ctx, bd)) < 0) - return ret; + ret = read_const_block_data(ctx, bd); } - return 0; + return ret; } @@ -1001,12 +995,16 @@ static int read_block(ALSDecContext *ctx, ALSBlockData *bd) static int decode_block(ALSDecContext *ctx, ALSBlockData *bd) { unsigned int smp; + int ret = 0; // read block type flag and read the samples accordingly if (*bd->const_block) decode_const_block_data(ctx, bd); - else if (decode_var_block_data(ctx, bd)) - return -1; + else + ret = decode_var_block_data(ctx, bd); // always return 0 + + if (ret < 0) + return ret; // TODO: read RLSLMS extension data @@ -1024,14 +1022,10 @@ static int read_decode_block(ALSDecContext *ctx, ALSBlockData *bd) { int ret; - ret = read_block(ctx, bd); - - if (ret) + if ((ret = read_block(ctx, bd)) < 0) return ret; - ret = decode_block(ctx, bd); - - return ret; + return decode_block(ctx, bd); } @@ -1057,6 +1051,7 @@ static int decode_blocks_ind(ALSDecContext *ctx, unsigned int ra_frame, unsigned int c, const unsigned int *div_blocks, unsigned int *js_blocks) { + int ret; unsigned int b; ALSBlockData bd = { 0 }; @@ -1077,10 +1072,10 @@ static int decode_blocks_ind(ALSDecContext *ctx, unsigned int ra_frame, for (b = 0; b < ctx->num_blocks; b++) { bd.block_length = div_blocks[b]; - if (read_decode_block(ctx, &bd)) { + if ((ret = read_decode_block(ctx, &bd)) < 0) { // damaged block, write zero for the rest of the frame zero_remaining(b, ctx->num_blocks, div_blocks, bd.raw_samples); - return -1; + return ret; } bd.raw_samples += div_blocks[b]; bd.ra_block = 0; @@ -1099,6 +1094,7 @@ static int decode_blocks(ALSDecContext *ctx, unsigned int ra_frame, ALSSpecificConfig *sconf = &ctx->sconf; unsigned int offset = 0; unsigned int b; + int ret; ALSBlockData bd[2] = { { 0 } }; bd[0].ra_block = ra_frame; @@ -1140,12 +1136,9 @@ static int decode_blocks(ALSDecContext *ctx, unsigned int ra_frame, bd[0].raw_other = bd[1].raw_samples; bd[1].raw_other = bd[0].raw_samples; - if(read_decode_block(ctx, &bd[0]) || read_decode_block(ctx, &bd[1])) { - // damaged block, write zero for the rest of the frame - zero_remaining(b, ctx->num_blocks, div_blocks, bd[0].raw_samples); - zero_remaining(b, ctx->num_blocks, div_blocks, bd[1].raw_samples); - return -1; - } + if ((ret = read_decode_block(ctx, &bd[0])) < 0 || + (ret = read_decode_block(ctx, &bd[1])) < 0) + goto fail; // reconstruct joint-stereo blocks if (bd[0].js_blocks) { @@ -1171,8 +1164,19 @@ static int decode_blocks(ALSDecContext *ctx, unsigned int ra_frame, sizeof(*ctx->raw_samples[c]) * sconf->max_order); return 0; +fail: + // damaged block, write zero for the rest of the frame + zero_remaining(b, ctx->num_blocks, div_blocks, bd[0].raw_samples); + zero_remaining(b, ctx->num_blocks, div_blocks, bd[1].raw_samples); + return ret; } +static inline int als_weighting(GetBitContext *gb, int k, int off) +{ + int idx = av_clip(decode_rice(gb, k) + off, + 0, FF_ARRAY_ELEMS(mcc_weightings) - 1); + return mcc_weightings[idx]; +} /** Read the channel data. */ @@ -1188,19 +1192,19 @@ static int read_channel_data(ALSDecContext *ctx, ALSChannelData *cd, int c) if (current->master_channel >= channels) { av_log(ctx->avctx, AV_LOG_ERROR, "Invalid master channel.\n"); - return -1; + return AVERROR_INVALIDDATA; } if (current->master_channel != c) { current->time_diff_flag = get_bits1(gb); - current->weighting[0] = mcc_weightings[av_clip(decode_rice(gb, 1) + 16, 0, 31)]; - current->weighting[1] = mcc_weightings[av_clip(decode_rice(gb, 2) + 14, 0, 31)]; - current->weighting[2] = mcc_weightings[av_clip(decode_rice(gb, 1) + 16, 0, 31)]; + current->weighting[0] = als_weighting(gb, 1, 16); + current->weighting[1] = als_weighting(gb, 2, 14); + current->weighting[2] = als_weighting(gb, 1, 16); if (current->time_diff_flag) { - current->weighting[3] = mcc_weightings[av_clip(decode_rice(gb, 1) + 16, 0, 31)]; - current->weighting[4] = mcc_weightings[av_clip(decode_rice(gb, 1) + 16, 0, 31)]; - current->weighting[5] = mcc_weightings[av_clip(decode_rice(gb, 1) + 16, 0, 31)]; + current->weighting[3] = als_weighting(gb, 1, 16); + current->weighting[4] = als_weighting(gb, 1, 16); + current->weighting[5] = als_weighting(gb, 1, 16); current->time_diff_sign = get_bits1(gb); current->time_diff_index = get_bits(gb, ctx->ltp_lag_length - 3) + 3; @@ -1213,7 +1217,7 @@ static int read_channel_data(ALSDecContext *ctx, ALSChannelData *cd, int c) if (entries == channels) { av_log(ctx->avctx, AV_LOG_ERROR, "Damaged channel data.\n"); - return -1; + return AVERROR_INVALIDDATA; } align_get_bits(gb); @@ -1245,7 +1249,7 @@ static int revert_channel_correlation(ALSDecContext *ctx, ALSBlockData *bd, if (dep == channels) { av_log(ctx->avctx, AV_LOG_WARNING, "Invalid channel correlation.\n"); - return -1; + return AVERROR_INVALIDDATA; } bd->const_block = ctx->const_block + c; @@ -1316,8 +1320,8 @@ static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame) unsigned int div_blocks[32]; ///< block sizes. unsigned int c; unsigned int js_blocks[2]; - uint32_t bs_info = 0; + int ret; // skip the size of the ra unit if present in the frame if (sconf->ra_flag == RA_FLAG_FRAMES && ra_frame) @@ -1348,13 +1352,15 @@ static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame) independent_bs = 1; if (independent_bs) { - if (decode_blocks_ind(ctx, ra_frame, c, div_blocks, js_blocks)) - return -1; - + ret = decode_blocks_ind(ctx, ra_frame, c, + div_blocks, js_blocks); + if (ret < 0) + return ret; independent_bs--; } else { - if (decode_blocks(ctx, ra_frame, c, div_blocks, js_blocks)) - return -1; + ret = decode_blocks(ctx, ra_frame, c, div_blocks, js_blocks); + if (ret < 0) + return ret; c++; } @@ -1373,7 +1379,7 @@ static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame) for (c = 0; c < avctx->channels; c++) if (ctx->chan_data[c] < ctx->chan_data_buffer) { av_log(ctx->avctx, AV_LOG_ERROR, "Invalid channel data.\n"); - return -1; + return AVERROR_INVALIDDATA; } memset(reverted_channels, 0, sizeof(*reverted_channels) * avctx->channels); @@ -1385,6 +1391,11 @@ static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame) for (b = 0; b < ctx->num_blocks; b++) { bd.block_length = div_blocks[b]; + if (bd.block_length <= 0) { + av_log(ctx->avctx, AV_LOG_WARNING, + "Invalid block length %d in channel data!\n", bd.block_length); + continue; + } for (c = 0; c < avctx->channels; c++) { bd.const_block = ctx->const_block + c; @@ -1405,11 +1416,12 @@ static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame) return ret; } - for (c = 0; c < avctx->channels; c++) - if (revert_channel_correlation(ctx, &bd, ctx->chan_data, - reverted_channels, offset, c)) - return -1; - + for (c = 0; c < avctx->channels; c++) { + ret = revert_channel_correlation(ctx, &bd, ctx->chan_data, + reverted_channels, offset, c); + if (ret < 0) + return ret; + } for (c = 0; c < avctx->channels; c++) { bd.const_block = ctx->const_block + c; bd.shift_lsbs = ctx->shift_lsbs + c; @@ -1558,6 +1570,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, if (ctx->cur_frame_length != sconf->frame_length && ctx->crc_org != ctx->crc) { av_log(avctx, AV_LOG_ERROR, "CRC error.\n"); + if (avctx->err_recognition & AV_EF_EXPLODE) + return AVERROR_INVALIDDATA; } } @@ -1611,30 +1625,30 @@ static av_cold int decode_init(AVCodecContext *avctx) { unsigned int c; unsigned int channel_size; - int num_buffers; + int num_buffers, ret; ALSDecContext *ctx = avctx->priv_data; ALSSpecificConfig *sconf = &ctx->sconf; ctx->avctx = avctx; if (!avctx->extradata) { av_log(avctx, AV_LOG_ERROR, "Missing required ALS extradata.\n"); - return -1; + return AVERROR_INVALIDDATA; } - if (read_specific_config(ctx)) { + if ((ret = read_specific_config(ctx)) < 0) { av_log(avctx, AV_LOG_ERROR, "Reading ALSSpecificConfig failed.\n"); - decode_end(avctx); - return -1; + goto fail; } - if (check_specific_config(ctx)) { - decode_end(avctx); - return -1; + if ((ret = check_specific_config(ctx)) < 0) { + goto fail; } - if (sconf->bgmc) - ff_bgmc_init(avctx, &ctx->bgmc_lut, &ctx->bgmc_lut_status); - + if (sconf->bgmc) { + ret = ff_bgmc_init(avctx, &ctx->bgmc_lut, &ctx->bgmc_lut_status); + if (ret < 0) + goto fail; + } if (sconf->floating) { avctx->sample_fmt = AV_SAMPLE_FMT_FLT; avctx->bits_per_raw_sample = 32; @@ -1669,7 +1683,8 @@ static av_cold int decode_init(AVCodecContext *avctx) !ctx->quant_cof_buffer || !ctx->lpc_cof_buffer || !ctx->lpc_cof_reversed_buffer) { av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n"); - return AVERROR(ENOMEM); + ret = AVERROR(ENOMEM); + goto fail; } // assign quantized parcor coefficient buffers @@ -1694,8 +1709,8 @@ static av_cold int decode_init(AVCodecContext *avctx) !ctx->use_ltp || !ctx->ltp_lag || !ctx->ltp_gain || !ctx->ltp_gain_buffer) { av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n"); - decode_end(avctx); - return AVERROR(ENOMEM); + ret = AVERROR(ENOMEM); + goto fail; } for (c = 0; c < num_buffers; c++) @@ -1712,8 +1727,8 @@ static av_cold int decode_init(AVCodecContext *avctx) if (!ctx->chan_data_buffer || !ctx->chan_data || !ctx->reverted_channels) { av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n"); - decode_end(avctx); - return AVERROR(ENOMEM); + ret = AVERROR(ENOMEM); + goto fail; } for (c = 0; c < num_buffers; c++) @@ -1733,8 +1748,8 @@ static av_cold int decode_init(AVCodecContext *avctx) // allocate previous raw sample buffer if (!ctx->prev_raw_samples || !ctx->raw_buffer|| !ctx->raw_samples) { av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n"); - decode_end(avctx); - return AVERROR(ENOMEM); + ret = AVERROR(ENOMEM); + goto fail; } // assign raw samples buffers @@ -1751,14 +1766,18 @@ static av_cold int decode_init(AVCodecContext *avctx) av_get_bytes_per_sample(avctx->sample_fmt)); if (!ctx->crc_buffer) { av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n"); - decode_end(avctx); - return AVERROR(ENOMEM); + ret = AVERROR(ENOMEM); + goto fail; } } ff_dsputil_init(&ctx->dsp, avctx); return 0; + +fail: + decode_end(avctx); + return ret; } @@ -1774,6 +1793,7 @@ static av_cold void flush(AVCodecContext *avctx) AVCodec ff_als_decoder = { .name = "als", + .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 Audio Lossless Coding (ALS)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_MP4ALS, .priv_data_size = sizeof(ALSDecContext), @@ -1782,5 +1802,4 @@ AVCodec ff_als_decoder = { .decode = decode_frame, .flush = flush, .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 Audio Lossless Coding (ALS)"), }; diff --git a/ffmpeg/libavcodec/amrnbdec.c b/ffmpeg/libavcodec/amrnbdec.c index 6376db1..43ddb62 100644 --- a/ffmpeg/libavcodec/amrnbdec.c +++ b/ffmpeg/libavcodec/amrnbdec.c @@ -1082,13 +1082,13 @@ static int amrnb_decode_frame(AVCodecContext *avctx, void *data, AVCodec ff_amrnb_decoder = { .name = "amrnb", + .long_name = NULL_IF_CONFIG_SMALL("AMR-NB (Adaptive Multi-Rate NarrowBand)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_AMR_NB, .priv_data_size = sizeof(AMRContext), .init = amrnb_decode_init, .decode = amrnb_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("AMR-NB (Adaptive Multi-Rate NarrowBand)"), .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE }, }; diff --git a/ffmpeg/libavcodec/amrwbdec.c b/ffmpeg/libavcodec/amrwbdec.c index 8c3eb56..bf668bb 100644 --- a/ffmpeg/libavcodec/amrwbdec.c +++ b/ffmpeg/libavcodec/amrwbdec.c @@ -1267,13 +1267,13 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, AVCodec ff_amrwb_decoder = { .name = "amrwb", + .long_name = NULL_IF_CONFIG_SMALL("AMR-WB (Adaptive Multi-Rate WideBand)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_AMR_WB, .priv_data_size = sizeof(AMRWBContext), .init = amrwb_decode_init, .decode = amrwb_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("AMR-WB (Adaptive Multi-Rate WideBand)"), .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE }, }; diff --git a/ffmpeg/libavcodec/anm.c b/ffmpeg/libavcodec/anm.c index 9aef6d3..79a87dd 100644 --- a/ffmpeg/libavcodec/anm.c +++ b/ffmpeg/libavcodec/anm.c @@ -189,6 +189,7 @@ static av_cold int decode_end(AVCodecContext *avctx) AVCodec ff_anm_decoder = { .name = "anm", + .long_name = NULL_IF_CONFIG_SMALL("Deluxe Paint Animation"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_ANM, .priv_data_size = sizeof(AnmContext), @@ -196,5 +197,4 @@ AVCodec ff_anm_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Deluxe Paint Animation"), }; diff --git a/ffmpeg/libavcodec/ansi.c b/ffmpeg/libavcodec/ansi.c index 93915f8..143b0aa 100644 --- a/ffmpeg/libavcodec/ansi.c +++ b/ffmpeg/libavcodec/ansi.c @@ -91,7 +91,7 @@ static av_cold int decode_init(AVCodecContext *avctx) s->bg = DEFAULT_BG_COLOR; if (!avctx->width || !avctx->height) - avcodec_set_dimensions(avctx, 80<<3, 25<<4); + ff_set_dimensions(avctx, 80 << 3, 25 << 4); return 0; } @@ -116,7 +116,7 @@ static void hscroll(AVCodecContext *avctx) AnsiContext *s = avctx->priv_data; int i; - if (s->y < avctx->height - s->font_height) { + if (s->y <= avctx->height - 2*s->font_height) { s->y += s->font_height; return; } @@ -169,7 +169,7 @@ static void draw_char(AVCodecContext *avctx, int c) ff_draw_pc_font(s->frame->data[0] + s->y * s->frame->linesize[0] + s->x, s->frame->linesize[0], s->font, s->font_height, c, fg, bg); s->x += FONT_WIDTH; - if (s->x >= avctx->width) { + if (s->x > avctx->width - FONT_WIDTH) { s->x = 0; hscroll(avctx); } @@ -182,7 +182,10 @@ static void draw_char(AVCodecContext *avctx, int c) static int execute_code(AVCodecContext * avctx, int c) { AnsiContext *s = avctx->priv_data; - int ret, i, width, height; + int ret, i; + int width = avctx->width; + int height = avctx->height; + switch(c) { case 'A': //Cursor Up s->y = FFMAX(s->y - (s->nb_args > 0 ? s->args[0]*s->font_height : s->font_height), 0); @@ -205,8 +208,6 @@ static int execute_code(AVCodecContext * avctx, int c) case 'l': //reset screen mode if (s->nb_args < 2) s->args[0] = DEFAULT_SCREEN_MODE; - width = avctx->width; - height = avctx->height; switch(s->args[0]) { case 0: case 1: case 4: case 5: case 13: case 19: //320x200 (25 rows) s->font = avpriv_cga_font; @@ -243,9 +244,13 @@ static int execute_code(AVCodecContext * avctx, int c) default: avpriv_request_sample(avctx, "Unsupported screen mode"); } + s->x = av_clip(s->x, 0, width - FONT_WIDTH); + s->y = av_clip(s->y, 0, height - s->font_height); if (width != avctx->width || height != avctx->height) { av_frame_unref(s->frame); - avcodec_set_dimensions(avctx, width, height); + ret = ff_set_dimensions(avctx, width, height); + if (ret < 0) + return ret; if ((ret = ff_get_buffer(avctx, s->frame, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; @@ -336,6 +341,8 @@ static int execute_code(AVCodecContext * avctx, int c) avpriv_request_sample(avctx, "Unknown escape code"); break; } + s->x = av_clip(s->x, 0, avctx->width - FONT_WIDTH); + s->y = av_clip(s->y, 0, avctx->height - s->font_height); return 0; } @@ -462,6 +469,7 @@ static av_cold int decode_close(AVCodecContext *avctx) AVCodec ff_ansi_decoder = { .name = "ansi", + .long_name = NULL_IF_CONFIG_SMALL("ASCII/ANSI art"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_ANSI, .priv_data_size = sizeof(AnsiContext), @@ -469,5 +477,4 @@ AVCodec ff_ansi_decoder = { .close = decode_close, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("ASCII/ANSI art"), }; diff --git a/ffmpeg/libavcodec/apedec.c b/ffmpeg/libavcodec/apedec.c index 1581d8e..58072d4 100644 --- a/ffmpeg/libavcodec/apedec.c +++ b/ffmpeg/libavcodec/apedec.c @@ -27,6 +27,8 @@ #include "dsputil.h" #include "bytestream.h" #include "internal.h" +#include "get_bits.h" +#include "unary.h" /** * @file @@ -123,6 +125,8 @@ typedef struct APEPredictor { int32_t coeffsA[2][4]; ///< adaption coefficients int32_t coeffsB[2][5]; ///< adaption coefficients int32_t historybuffer[HISTORY_SIZE + PREDICTOR_SIZE]; + + unsigned int sample_pos; } APEPredictor; /** Decoder context */ @@ -154,6 +158,7 @@ typedef struct APEContext { APERice riceX; ///< rice code parameters for the second channel APERice riceY; ///< rice code parameters for the first channel APEFilter filters[APE_FILTER_LEVELS][2]; ///< filters used for reconstruction + GetBitContext gb; uint8_t *data; ///< current frame data uint8_t *data_end; ///< frame data end @@ -171,11 +176,18 @@ typedef struct APEContext { static void ape_apply_filters(APEContext *ctx, int32_t *decoded0, int32_t *decoded1, int count); +static void entropy_decode_mono_0000(APEContext *ctx, int blockstodecode); +static void entropy_decode_stereo_0000(APEContext *ctx, int blockstodecode); +static void entropy_decode_mono_3860(APEContext *ctx, int blockstodecode); +static void entropy_decode_stereo_3860(APEContext *ctx, int blockstodecode); static void entropy_decode_mono_3900(APEContext *ctx, int blockstodecode); static void entropy_decode_stereo_3900(APEContext *ctx, int blockstodecode); +static void entropy_decode_stereo_3930(APEContext *ctx, int blockstodecode); static void entropy_decode_mono_3990(APEContext *ctx, int blockstodecode); static void entropy_decode_stereo_3990(APEContext *ctx, int blockstodecode); +static void predictor_decode_mono_3800(APEContext *ctx, int count); +static void predictor_decode_stereo_3800(APEContext *ctx, int count); static void predictor_decode_mono_3930(APEContext *ctx, int count); static void predictor_decode_stereo_3930(APEContext *ctx, int count); static void predictor_decode_mono_3950(APEContext *ctx, int count); @@ -235,7 +247,9 @@ static av_cold int ape_decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_DEBUG, "Compression Level: %d - Flags: %d\n", s->compression_level, s->flags); - if (s->compression_level % 1000 || s->compression_level > COMPRESSION_LEVEL_INSANE || !s->compression_level) { + if (s->compression_level % 1000 || s->compression_level > COMPRESSION_LEVEL_INSANE || + !s->compression_level || + (s->fileversion < 3930 && s->compression_level == COMPRESSION_LEVEL_INSANE)) { av_log(avctx, AV_LOG_ERROR, "Incorrect compression level %d\n", s->compression_level); return AVERROR_INVALIDDATA; @@ -249,15 +263,27 @@ static av_cold int ape_decode_init(AVCodecContext *avctx) filter_alloc_fail); } - if (s->fileversion < 3990) { + if (s->fileversion < 3860) { + s->entropy_decode_mono = entropy_decode_mono_0000; + s->entropy_decode_stereo = entropy_decode_stereo_0000; + } else if (s->fileversion < 3900) { + s->entropy_decode_mono = entropy_decode_mono_3860; + s->entropy_decode_stereo = entropy_decode_stereo_3860; + } else if (s->fileversion < 3930) { s->entropy_decode_mono = entropy_decode_mono_3900; s->entropy_decode_stereo = entropy_decode_stereo_3900; + } else if (s->fileversion < 3990) { + s->entropy_decode_mono = entropy_decode_mono_3900; + s->entropy_decode_stereo = entropy_decode_stereo_3930; } else { s->entropy_decode_mono = entropy_decode_mono_3990; s->entropy_decode_stereo = entropy_decode_stereo_3990; } - if (s->fileversion < 3950) { + if (s->fileversion < 3930) { + s->predictor_decode_mono = predictor_decode_mono_3800; + s->predictor_decode_stereo = predictor_decode_stereo_3800; + } else if (s->fileversion < 3950) { s->predictor_decode_mono = predictor_decode_mono_3930; s->predictor_decode_stereo = predictor_decode_stereo_3930; } else { @@ -435,6 +461,53 @@ static inline void update_rice(APERice *rice, unsigned int x) rice->k++; } +static inline int get_rice_ook(GetBitContext *gb, int k) +{ + unsigned int x; + + x = get_unary(gb, 1, get_bits_left(gb)); + + if (k) + x = (x << k) | get_bits(gb, k); + + return x; +} + +static inline int ape_decode_value_3860(APEContext *ctx, GetBitContext *gb, + APERice *rice) +{ + unsigned int x, overflow; + + overflow = get_unary(gb, 1, get_bits_left(gb)); + + if (ctx->fileversion > 3880) { + while (overflow >= 16) { + overflow -= 16; + rice->k += 4; + } + } + + if (!rice->k) + x = overflow; + else if(rice->k <= MIN_CACHE_BITS) { + x = (overflow << rice->k) + get_bits(gb, rice->k); + } else { + av_log(ctx->avctx, AV_LOG_ERROR, "Too many bits: %d\n", rice->k); + return AVERROR_INVALIDDATA; + } + rice->ksum += x - (rice->ksum + 8 >> 4); + if (rice->ksum < (rice->k ? 1 << (rice->k + 4) : 0)) + rice->k--; + else if (rice->ksum >= (1 << (rice->k + 5)) && rice->k < 24) + rice->k++; + + /* Convert to signed */ + if (x & 1) + return (x >> 1) + 1; + else + return -(x >> 1); +} + static inline int ape_decode_value_3900(APEContext *ctx, APERice *rice) { unsigned int x, overflow; @@ -448,9 +521,13 @@ static inline int ape_decode_value_3900(APEContext *ctx, APERice *rice) } else tmpk = (rice->k < 1) ? 0 : rice->k - 1; - if (tmpk <= 16) + if (tmpk <= 16 || ctx->fileversion < 3910) { + if (tmpk > 23) { + av_log(ctx->avctx, AV_LOG_ERROR, "Too many bits: %d\n", tmpk); + return AVERROR_INVALIDDATA; + } x = range_decode_bits(ctx, tmpk); - else if (tmpk <= 32) { + } else if (tmpk <= 32) { x = range_decode_bits(ctx, 16); x |= (range_decode_bits(ctx, tmpk - 16) << 16); } else { @@ -514,6 +591,88 @@ static inline int ape_decode_value_3990(APEContext *ctx, APERice *rice) return -(x >> 1); } +static void decode_array_0000(APEContext *ctx, GetBitContext *gb, + int32_t *out, APERice *rice, int blockstodecode) +{ + int i; + int ksummax, ksummin; + + rice->ksum = 0; + for (i = 0; i < 5; i++) { + out[i] = get_rice_ook(&ctx->gb, 10); + rice->ksum += out[i]; + } + rice->k = av_log2(rice->ksum / 10) + 1; + if (rice->k >= 24) + return; + for (; i < 64; i++) { + out[i] = get_rice_ook(&ctx->gb, rice->k); + rice->ksum += out[i]; + rice->k = av_log2(rice->ksum / ((i + 1) * 2)) + 1; + if (rice->k >= 24) + return; + } + ksummax = 1 << rice->k + 7; + ksummin = rice->k ? (1 << rice->k + 6) : 0; + for (; i < blockstodecode; i++) { + out[i] = get_rice_ook(&ctx->gb, rice->k); + rice->ksum += out[i] - out[i - 64]; + while (rice->ksum < ksummin) { + rice->k--; + ksummin = rice->k ? ksummin >> 1 : 0; + ksummax >>= 1; + } + while (rice->ksum >= ksummax) { + rice->k++; + if (rice->k > 24) + return; + ksummax <<= 1; + ksummin = ksummin ? ksummin << 1 : 128; + } + } + + for (i = 0; i < blockstodecode; i++) { + if (out[i] & 1) + out[i] = (out[i] >> 1) + 1; + else + out[i] = -(out[i] >> 1); + } +} + +static void entropy_decode_mono_0000(APEContext *ctx, int blockstodecode) +{ + decode_array_0000(ctx, &ctx->gb, ctx->decoded[0], &ctx->riceY, + blockstodecode); +} + +static void entropy_decode_stereo_0000(APEContext *ctx, int blockstodecode) +{ + decode_array_0000(ctx, &ctx->gb, ctx->decoded[0], &ctx->riceY, + blockstodecode); + decode_array_0000(ctx, &ctx->gb, ctx->decoded[1], &ctx->riceX, + blockstodecode); +} + +static void entropy_decode_mono_3860(APEContext *ctx, int blockstodecode) +{ + int32_t *decoded0 = ctx->decoded[0]; + + while (blockstodecode--) + *decoded0++ = ape_decode_value_3860(ctx, &ctx->gb, &ctx->riceY); +} + +static void entropy_decode_stereo_3860(APEContext *ctx, int blockstodecode) +{ + int32_t *decoded0 = ctx->decoded[0]; + int32_t *decoded1 = ctx->decoded[1]; + int blocks = blockstodecode; + + while (blockstodecode--) + *decoded0++ = ape_decode_value_3860(ctx, &ctx->gb, &ctx->riceY); + while (blocks--) + *decoded1++ = ape_decode_value_3860(ctx, &ctx->gb, &ctx->riceX); +} + static void entropy_decode_mono_3900(APEContext *ctx, int blockstodecode) { int32_t *decoded0 = ctx->decoded[0]; @@ -523,6 +682,22 @@ static void entropy_decode_mono_3900(APEContext *ctx, int blockstodecode) } static void entropy_decode_stereo_3900(APEContext *ctx, int blockstodecode) +{ + int32_t *decoded0 = ctx->decoded[0]; + int32_t *decoded1 = ctx->decoded[1]; + int blocks = blockstodecode; + + while (blockstodecode--) + *decoded0++ = ape_decode_value_3900(ctx, &ctx->riceY); + range_dec_normalize(ctx); + // because of some implementation peculiarities we need to backpedal here + ctx->ptr -= 1; + range_start_decoding(ctx); + while (blocks--) + *decoded1++ = ape_decode_value_3900(ctx, &ctx->riceX); +} + +static void entropy_decode_stereo_3930(APEContext *ctx, int blockstodecode) { int32_t *decoded0 = ctx->decoded[0]; int32_t *decoded1 = ctx->decoded[1]; @@ -555,9 +730,13 @@ static void entropy_decode_stereo_3990(APEContext *ctx, int blockstodecode) static int init_entropy_decoder(APEContext *ctx) { /* Read the CRC */ - if (ctx->data_end - ctx->ptr < 6) - return AVERROR_INVALIDDATA; - ctx->CRC = bytestream_get_be32(&ctx->ptr); + if (ctx->fileversion >= 3900) { + if (ctx->data_end - ctx->ptr < 6) + return AVERROR_INVALIDDATA; + ctx->CRC = bytestream_get_be32(&ctx->ptr); + } else { + ctx->CRC = get_bits_long(&ctx->gb, 32); + } /* Read the frame flags if they exist */ ctx->frameflags = 0; @@ -575,15 +754,29 @@ static int init_entropy_decoder(APEContext *ctx) ctx->riceY.k = 10; ctx->riceY.ksum = (1 << ctx->riceY.k) * 16; - /* The first 8 bits of input are ignored. */ - ctx->ptr++; + if (ctx->fileversion >= 3900) { + /* The first 8 bits of input are ignored. */ + ctx->ptr++; - range_start_decoding(ctx); + range_start_decoding(ctx); + } return 0; } -static const int32_t initial_coeffs[4] = { +static const int32_t initial_coeffs_fast_3320[1] = { + 375, +}; + +static const int32_t initial_coeffs_a_3800[3] = { + 64, 115, 64, +}; + +static const int32_t initial_coeffs_b_3800[2] = { + 740, 0 +}; + +static const int32_t initial_coeffs_3930[4] = { 360, 317, -109, 98 }; @@ -596,13 +789,35 @@ static void init_predictor_decoder(APEContext *ctx) p->buf = p->historybuffer; /* Initialize and zero the coefficients */ - memcpy(p->coeffsA[0], initial_coeffs, sizeof(initial_coeffs)); - memcpy(p->coeffsA[1], initial_coeffs, sizeof(initial_coeffs)); + if (ctx->fileversion < 3930) { + if (ctx->compression_level == COMPRESSION_LEVEL_FAST) { + memcpy(p->coeffsA[0], initial_coeffs_fast_3320, + sizeof(initial_coeffs_fast_3320)); + memcpy(p->coeffsA[1], initial_coeffs_fast_3320, + sizeof(initial_coeffs_fast_3320)); + } else { + memcpy(p->coeffsA[0], initial_coeffs_a_3800, + sizeof(initial_coeffs_a_3800)); + memcpy(p->coeffsA[1], initial_coeffs_a_3800, + sizeof(initial_coeffs_a_3800)); + } + } else { + memcpy(p->coeffsA[0], initial_coeffs_3930, sizeof(initial_coeffs_3930)); + memcpy(p->coeffsA[1], initial_coeffs_3930, sizeof(initial_coeffs_3930)); + } memset(p->coeffsB, 0, sizeof(p->coeffsB)); + if (ctx->fileversion < 3930) { + memcpy(p->coeffsB[0], initial_coeffs_b_3800, + sizeof(initial_coeffs_b_3800)); + memcpy(p->coeffsB[1], initial_coeffs_b_3800, + sizeof(initial_coeffs_b_3800)); + } p->filterA[0] = p->filterA[1] = 0; p->filterB[0] = p->filterB[1] = 0; p->lastA[0] = p->lastA[1] = 0; + + p->sample_pos = 0; } /** Get inverse sign of integer (-1 for positive, 1 for negative and 0 for zero) */ @@ -610,6 +825,224 @@ static inline int APESIGN(int32_t x) { return (x < 0) - (x > 0); } +static av_always_inline int filter_fast_3320(APEPredictor *p, + const int decoded, const int filter, + const int delayA) +{ + int32_t predictionA; + + p->buf[delayA] = p->lastA[filter]; + if (p->sample_pos < 3) { + p->lastA[filter] = decoded; + p->filterA[filter] = decoded; + return decoded; + } + + predictionA = p->buf[delayA] * 2 - p->buf[delayA - 1]; + p->lastA[filter] = decoded + (predictionA * p->coeffsA[filter][0] >> 9); + + if ((decoded ^ predictionA) > 0) + p->coeffsA[filter][0]++; + else + p->coeffsA[filter][0]--; + + p->filterA[filter] += p->lastA[filter]; + + return p->filterA[filter]; +} + +static av_always_inline int filter_3800(APEPredictor *p, + const int decoded, const int filter, + const int delayA, const int delayB, + const int start, const int shift) +{ + int32_t predictionA, predictionB, sign; + int32_t d0, d1, d2, d3, d4; + + p->buf[delayA] = p->lastA[filter]; + p->buf[delayB] = p->filterB[filter]; + if (p->sample_pos < start) { + predictionA = decoded + p->filterA[filter]; + p->lastA[filter] = decoded; + p->filterB[filter] = decoded; + p->filterA[filter] = predictionA; + return predictionA; + } + d2 = p->buf[delayA]; + d1 = (p->buf[delayA] - p->buf[delayA - 1]) << 1; + d0 = p->buf[delayA] + ((p->buf[delayA - 2] - p->buf[delayA - 1]) << 3); + d3 = p->buf[delayB] * 2 - p->buf[delayB - 1]; + d4 = p->buf[delayB]; + + predictionA = d0 * p->coeffsA[filter][0] + + d1 * p->coeffsA[filter][1] + + d2 * p->coeffsA[filter][2]; + + sign = APESIGN(decoded); + p->coeffsA[filter][0] += (((d0 >> 30) & 2) - 1) * sign; + p->coeffsA[filter][1] += (((d1 >> 28) & 8) - 4) * sign; + p->coeffsA[filter][2] += (((d2 >> 28) & 8) - 4) * sign; + + predictionB = d3 * p->coeffsB[filter][0] - + d4 * p->coeffsB[filter][1]; + p->lastA[filter] = decoded + (predictionA >> 11); + sign = APESIGN(p->lastA[filter]); + p->coeffsB[filter][0] += (((d3 >> 29) & 4) - 2) * sign; + p->coeffsB[filter][1] -= (((d4 >> 30) & 2) - 1) * sign; + + p->filterB[filter] = p->lastA[filter] + (predictionB >> shift); + p->filterA[filter] = p->filterB[filter] + ((p->filterA[filter] * 31) >> 5); + + return p->filterA[filter]; +} + +static void long_filter_high_3800(int32_t *buffer, int order, int shift, + int32_t *coeffs, int32_t *delay, int length) +{ + int i, j; + int32_t dotprod, sign; + + memset(coeffs, 0, order * sizeof(*coeffs)); + for (i = 0; i < order; i++) + delay[i] = buffer[i]; + for (i = order; i < length; i++) { + dotprod = 0; + sign = APESIGN(buffer[i]); + for (j = 0; j < order; j++) { + dotprod += delay[j] * coeffs[j]; + coeffs[j] -= (((delay[j] >> 30) & 2) - 1) * sign; + } + buffer[i] -= dotprod >> shift; + for (j = 0; j < order - 1; j++) + delay[j] = delay[j + 1]; + delay[order - 1] = buffer[i]; + } +} + +static void long_filter_ehigh_3830(int32_t *buffer, int length) +{ + int i, j; + int32_t dotprod, sign; + int32_t coeffs[8], delay[8]; + + memset(coeffs, 0, sizeof(coeffs)); + memset(delay, 0, sizeof(delay)); + for (i = 0; i < length; i++) { + dotprod = 0; + sign = APESIGN(buffer[i]); + for (j = 7; j >= 0; j--) { + dotprod += delay[j] * coeffs[j]; + coeffs[j] -= (((delay[j] >> 30) & 2) - 1) * sign; + } + for (j = 7; j > 0; j--) + delay[j] = delay[j - 1]; + delay[0] = buffer[i]; + buffer[i] -= dotprod >> 9; + } +} + +static void predictor_decode_stereo_3800(APEContext *ctx, int count) +{ + APEPredictor *p = &ctx->predictor; + int32_t *decoded0 = ctx->decoded[0]; + int32_t *decoded1 = ctx->decoded[1]; + int32_t coeffs[256], delay[256]; + int start = 4, shift = 10; + + if (ctx->compression_level == COMPRESSION_LEVEL_HIGH) { + start = 16; + long_filter_high_3800(decoded0, 16, 9, coeffs, delay, count); + long_filter_high_3800(decoded1, 16, 9, coeffs, delay, count); + } else if (ctx->compression_level == COMPRESSION_LEVEL_EXTRA_HIGH) { + int order = 128, shift2 = 11; + + if (ctx->fileversion >= 3830) { + order <<= 1; + shift++; + shift2++; + long_filter_ehigh_3830(decoded0 + order, count - order); + long_filter_ehigh_3830(decoded1 + order, count - order); + } + start = order; + long_filter_high_3800(decoded0, order, shift2, coeffs, delay, count); + long_filter_high_3800(decoded1, order, shift2, coeffs, delay, count); + } + + while (count--) { + int X = *decoded0, Y = *decoded1; + if (ctx->compression_level == COMPRESSION_LEVEL_FAST) { + *decoded0 = filter_fast_3320(p, Y, 0, YDELAYA); + decoded0++; + *decoded1 = filter_fast_3320(p, X, 1, XDELAYA); + decoded1++; + } else { + *decoded0 = filter_3800(p, Y, 0, YDELAYA, YDELAYB, + start, shift); + decoded0++; + *decoded1 = filter_3800(p, X, 1, XDELAYA, XDELAYB, + start, shift); + decoded1++; + } + + /* Combined */ + p->buf++; + p->sample_pos++; + + /* Have we filled the history buffer? */ + if (p->buf == p->historybuffer + HISTORY_SIZE) { + memmove(p->historybuffer, p->buf, + PREDICTOR_SIZE * sizeof(*p->historybuffer)); + p->buf = p->historybuffer; + } + } +} + +static void predictor_decode_mono_3800(APEContext *ctx, int count) +{ + APEPredictor *p = &ctx->predictor; + int32_t *decoded0 = ctx->decoded[0]; + int32_t coeffs[256], delay[256]; + int start = 4, shift = 10; + + if (ctx->compression_level == COMPRESSION_LEVEL_HIGH) { + start = 16; + long_filter_high_3800(decoded0, 16, 9, coeffs, delay, count); + } else if (ctx->compression_level == COMPRESSION_LEVEL_EXTRA_HIGH) { + int order = 128, shift2 = 11; + + if (ctx->fileversion >= 3830) { + order <<= 1; + shift++; + shift2++; + long_filter_ehigh_3830(decoded0 + order, count - order); + } + start = order; + long_filter_high_3800(decoded0, order, shift2, coeffs, delay, count); + } + + while (count--) { + if (ctx->compression_level == COMPRESSION_LEVEL_FAST) { + *decoded0 = filter_fast_3320(p, *decoded0, 0, YDELAYA); + decoded0++; + } else { + *decoded0 = filter_3800(p, *decoded0, 0, YDELAYA, YDELAYB, + start, shift); + decoded0++; + } + + /* Combined */ + p->buf++; + p->sample_pos++; + + /* Have we filled the history buffer? */ + if (p->buf == p->historybuffer + HISTORY_SIZE) { + memmove(p->historybuffer, p->buf, + PREDICTOR_SIZE * sizeof(*p->historybuffer)); + p->buf = p->historybuffer; + } + } +} + static av_always_inline int predictor_update_3930(APEPredictor *p, const int decoded, const int filter, const int delayA) @@ -1005,7 +1438,7 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data, } if (s->fileversion < 3950) // previous versions overread two bytes buf_size += 2; - av_fast_malloc(&s->data, &s->data_size, buf_size); + av_fast_padded_malloc(&s->data, &s->data_size, buf_size); if (!s->data) return AVERROR(ENOMEM); s->dsp.bswap_buf((uint32_t*)s->data, (const uint32_t*)buf, buf_size >> 2); @@ -1015,16 +1448,25 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data, nblocks = bytestream_get_be32(&s->ptr); offset = bytestream_get_be32(&s->ptr); - if (offset > 3) { - av_log(avctx, AV_LOG_ERROR, "Incorrect offset passed\n"); - s->data = NULL; - return AVERROR_INVALIDDATA; - } - if (s->data_end - s->ptr < offset) { - av_log(avctx, AV_LOG_ERROR, "Packet is too small\n"); - return AVERROR_INVALIDDATA; + if (s->fileversion >= 3900) { + if (offset > 3) { + av_log(avctx, AV_LOG_ERROR, "Incorrect offset passed\n"); + s->data = NULL; + return AVERROR_INVALIDDATA; + } + if (s->data_end - s->ptr < offset) { + av_log(avctx, AV_LOG_ERROR, "Packet is too small\n"); + return AVERROR_INVALIDDATA; + } + s->ptr += offset; + } else { + if ((ret = init_get_bits8(&s->gb, s->ptr, s->data_end - s->ptr)) < 0) + return ret; + if (s->fileversion > 3800) + skip_bits_long(&s->gb, offset * 8); + else + skip_bits_long(&s->gb, offset); } - s->ptr += offset; if (!nblocks || nblocks > INT_MAX) { av_log(avctx, AV_LOG_ERROR, "Invalid sample count: %u.\n", nblocks); @@ -1045,6 +1487,10 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data, } blockstodecode = FFMIN(s->blocks_per_loop, s->samples); + // for old files coefficients were not interleaved, + // so we need to decode all of them at once + if (s->fileversion < 3930) + blockstodecode = s->samples; /* reallocate decoded sample buffer if needed */ av_fast_malloc(&s->decoded_buffer, &s->decoded_size, @@ -1128,6 +1574,7 @@ static const AVClass ape_decoder_class = { AVCodec ff_ape_decoder = { .name = "ape", + .long_name = NULL_IF_CONFIG_SMALL("Monkey's Audio"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_APE, .priv_data_size = sizeof(APEContext), @@ -1136,7 +1583,6 @@ AVCodec ff_ape_decoder = { .decode = ape_decode_frame, .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DELAY | CODEC_CAP_DR1, .flush = ape_flush, - .long_name = NULL_IF_CONFIG_SMALL("Monkey's Audio"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S32P, diff --git a/ffmpeg/libavcodec/arm/Makefile b/ffmpeg/libavcodec/arm/Makefile index 011404c..277abd9 100644 --- a/ffmpeg/libavcodec/arm/Makefile +++ b/ffmpeg/libavcodec/arm/Makefile @@ -1,116 +1,98 @@ ARCH_HEADERS = mathops.h +OBJS += arm/fmtconvert_init_arm.o + +OBJS-$(CONFIG_AAC_DECODER) += arm/aacpsdsp_init_arm.o \ + arm/sbrdsp_init_arm.o OBJS-$(CONFIG_AC3DSP) += arm/ac3dsp_init_arm.o \ arm/ac3dsp_arm.o - -OBJS-$(CONFIG_AAC_DECODER) += arm/sbrdsp_init_arm.o \ - arm/aacpsdsp_init_arm.o - -OBJS-$(CONFIG_DCA_DECODER) += arm/dcadsp_init_arm.o \ - -ARMV6-OBJS-$(CONFIG_AC3DSP) += arm/ac3dsp_armv6.o - +OBJS-$(CONFIG_DCA_DECODER) += arm/dcadsp_init_arm.o +OBJS-$(CONFIG_DSPUTIL) += arm/dsputil_init_arm.o \ + arm/dsputil_arm.o \ + arm/jrevdct_arm.o \ + arm/simple_idct_arm.o +OBJS-$(CONFIG_FFT) += arm/fft_init_arm.o \ + arm/fft_fixed_init_arm.o OBJS-$(CONFIG_FLAC_DECODER) += arm/flacdsp_init_arm.o \ - arm/flacdsp_arm.o \ - + arm/flacdsp_arm.o +OBJS-$(CONFIG_H264CHROMA) += arm/h264chroma_init_arm.o +OBJS-$(CONFIG_H264DSP) += arm/h264dsp_init_arm.o +OBJS-$(CONFIG_H264PRED) += arm/h264pred_init_arm.o +OBJS-$(CONFIG_H264QPEL) += arm/h264qpel_init_arm.o +OBJS-$(CONFIG_HPELDSP) += arm/hpeldsp_init_arm.o \ + arm/hpeldsp_arm.o OBJS-$(CONFIG_MPEGAUDIODSP) += arm/mpegaudiodsp_init_arm.o -ARMV6-OBJS-$(CONFIG_MPEGAUDIODSP) += arm/mpegaudiodsp_fixed_armv6.o - OBJS-$(CONFIG_MPEGVIDEO) += arm/mpegvideo_arm.o +OBJS-$(CONFIG_VC1_DECODER) += arm/vc1dsp_init_arm.o OBJS-$(CONFIG_VORBIS_DECODER) += arm/vorbisdsp_init_arm.o OBJS-$(CONFIG_VP3DSP) += arm/vp3dsp_init_arm.o -OBJS-$(CONFIG_VP5_DECODER) += arm/vp56dsp_init_arm.o -OBJS-$(CONFIG_VP6_DECODER) += arm/vp56dsp_init_arm.o +OBJS-$(CONFIG_VP6_DECODER) += arm/vp6dsp_init_arm.o OBJS-$(CONFIG_VP8_DECODER) += arm/vp8dsp_init_arm.o -ARMV6-OBJS-$(CONFIG_VP8_DECODER) += arm/vp8_armv6.o \ - arm/vp8dsp_init_armv6.o \ - arm/vp8dsp_armv6.o - -OBJS-$(CONFIG_H264CHROMA) += arm/h264chroma_init_arm.o -OBJS-$(CONFIG_H264DSP) += arm/h264dsp_init_arm.o -OBJS-$(CONFIG_H264PRED) += arm/h264pred_init_arm.o -OBJS-$(CONFIG_H264QPEL) += arm/h264qpel_init_arm.o - -OBJS-$(CONFIG_HPELDSP) += arm/hpeldsp_arm.o \ - arm/hpeldsp_init_arm.o - OBJS-$(CONFIG_RV30_DECODER) += arm/rv34dsp_init_arm.o OBJS-$(CONFIG_RV40_DECODER) += arm/rv34dsp_init_arm.o \ - arm/rv40dsp_init_arm.o \ - + arm/rv40dsp_init_arm.o OBJS-$(CONFIG_VIDEODSP) += arm/videodsp_init_arm.o \ -OBJS += arm/dsputil_init_arm.o \ - arm/dsputil_arm.o \ - arm/fft_init_arm.o \ - arm/fft_fixed_init_arm.o \ - arm/fmtconvert_init_arm.o \ - arm/jrevdct_arm.o \ - arm/simple_idct_arm.o \ - +ARMV5TE-OBJS-$(CONFIG_DSPUTIL) += arm/dsputil_init_armv5te.o \ + arm/simple_idct_armv5te.o ARMV5TE-OBJS-$(CONFIG_MPEGVIDEO) += arm/mpegvideo_armv5te.o \ - arm/mpegvideo_armv5te_s.o \ - + arm/mpegvideo_armv5te_s.o ARMV5TE-OBJS-$(CONFIG_VIDEODSP) += arm/videodsp_init_armv5te.o \ - arm/videodsp_armv5te.o \ - -ARMV5TE-OBJS += arm/dsputil_init_armv5te.o \ - arm/simple_idct_armv5te.o \ + arm/videodsp_armv5te.o -ARMV6-OBJS += arm/dsputil_init_armv6.o \ +ARMV6-OBJS-$(CONFIG_DSPUTIL) += arm/dsputil_init_armv6.o \ arm/dsputil_armv6.o \ arm/simple_idct_armv6.o \ -ARMV6-OBJS-$(CONFIG_HPELDSP) += arm/hpeldsp_armv6.o \ - arm/hpeldsp_init_armv6.o - -VFP-OBJS-$(HAVE_ARMV6) += arm/fmtconvert_vfp.o +ARMV6-OBJS-$(CONFIG_AC3DSP) += arm/ac3dsp_armv6.o +ARMV6-OBJS-$(CONFIG_H264DSP) += arm/h264dsp_armv6.o +ARMV6-OBJS-$(CONFIG_HPELDSP) += arm/hpeldsp_init_armv6.o \ + arm/hpeldsp_armv6.o +ARMV6-OBJS-$(CONFIG_MPEGAUDIODSP) += arm/mpegaudiodsp_fixed_armv6.o +ARMV6-OBJS-$(CONFIG_VP8_DECODER) += arm/vp8_armv6.o \ + arm/vp8dsp_init_armv6.o \ + arm/vp8dsp_armv6.o -NEON-OBJS-$(CONFIG_FFT) += arm/fft_neon.o \ - arm/fft_fixed_neon.o \ +VFP-OBJS += arm/fmtconvert_vfp.o -NEON-OBJS-$(CONFIG_MDCT) += arm/mdct_neon.o \ - arm/mdct_fixed_neon.o \ +VFP-OBJS-$(CONFIG_DCA_DECODER) += arm/dcadsp_vfp.o \ + arm/synth_filter_vfp.o +VFP-OBJS-$(CONFIG_FFT) += arm/fft_vfp.o +VFP-OBJS-$(CONFIG_MDCT) += arm/mdct_vfp.o +VFP-OBJS-$(HAVE_ARMV6) += arm/fmtconvert_vfp_armv6.o -NEON-OBJS-$(CONFIG_RDFT) += arm/rdft_neon.o \ +NEON-OBJS += arm/fmtconvert_neon.o +NEON-OBJS-$(CONFIG_AC3DSP) += arm/ac3dsp_neon.o +NEON-OBJS-$(CONFIG_AAC_DECODER) += arm/aacpsdsp_neon.o \ + arm/sbrdsp_neon.o +NEON-OBJS-$(CONFIG_DCA_DECODER) += arm/dcadsp_neon.o \ + arm/synth_filter_neon.o +NEON-OBJS-$(CONFIG_DSPUTIL) += arm/dsputil_init_neon.o \ + arm/dsputil_neon.o \ + arm/int_neon.o \ + arm/simple_idct_neon.o +NEON-OBJS-$(CONFIG_FFT) += arm/fft_neon.o \ + arm/fft_fixed_neon.o NEON-OBJS-$(CONFIG_H264CHROMA) += arm/h264cmc_neon.o NEON-OBJS-$(CONFIG_H264DSP) += arm/h264dsp_neon.o \ - arm/h264idct_neon.o \ - -NEON-OBJS-$(CONFIG_H264PRED) += arm/h264pred_neon.o \ - + arm/h264idct_neon.o +NEON-OBJS-$(CONFIG_H264PRED) += arm/h264pred_neon.o NEON-OBJS-$(CONFIG_H264QPEL) += arm/h264qpel_neon.o \ - -NEON-OBJS-$(CONFIG_HPELDSP) += arm/hpeldsp_neon.o \ - arm/hpeldsp_init_neon.o - -NEON-OBJS-$(CONFIG_AC3DSP) += arm/ac3dsp_neon.o - -NEON-OBJS-$(CONFIG_AAC_DECODER) += arm/sbrdsp_neon.o \ - arm/aacpsdsp_neon.o - -NEON-OBJS-$(CONFIG_DCA_DECODER) += arm/dcadsp_neon.o \ - arm/synth_filter_neon.o \ - + arm/hpeldsp_neon.o +NEON-OBJS-$(CONFIG_HPELDSP) += arm/hpeldsp_init_neon.o \ + arm/hpeldsp_neon.o +NEON-OBJS-$(CONFIG_MDCT) += arm/mdct_neon.o \ + arm/mdct_fixed_neon.o NEON-OBJS-$(CONFIG_MPEGVIDEO) += arm/mpegvideo_neon.o +NEON-OBJS-$(CONFIG_RDFT) += arm/rdft_neon.o NEON-OBJS-$(CONFIG_RV30_DECODER) += arm/rv34dsp_neon.o NEON-OBJS-$(CONFIG_RV40_DECODER) += arm/rv34dsp_neon.o \ - arm/rv40dsp_neon.o \ - + arm/rv40dsp_neon.o +NEON-OBJS-$(CONFIG_VC1_DECODER) += arm/vc1dsp_init_neon.o \ + arm/vc1dsp_neon.o NEON-OBJS-$(CONFIG_VORBIS_DECODER) += arm/vorbisdsp_neon.o - NEON-OBJS-$(CONFIG_VP3DSP) += arm/vp3dsp_neon.o - -NEON-OBJS-$(CONFIG_VP5_DECODER) += arm/vp56dsp_neon.o \ - -NEON-OBJS-$(CONFIG_VP6_DECODER) += arm/vp56dsp_neon.o \ - +NEON-OBJS-$(CONFIG_VP6_DECODER) += arm/vp6dsp_neon.o NEON-OBJS-$(CONFIG_VP8_DECODER) += arm/vp8dsp_init_neon.o \ arm/vp8dsp_neon.o - -NEON-OBJS += arm/dsputil_init_neon.o \ - arm/dsputil_neon.o \ - arm/fmtconvert_neon.o \ - arm/int_neon.o \ - arm/simple_idct_neon.o \ diff --git a/ffmpeg/libavcodec/arm/aacpsdsp_init_arm.c b/ffmpeg/libavcodec/arm/aacpsdsp_init_arm.c index 6326376..e04787c 100644 --- a/ffmpeg/libavcodec/arm/aacpsdsp_init_arm.c +++ b/ffmpeg/libavcodec/arm/aacpsdsp_init_arm.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2012 Mans Rullgard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/arm/aacpsdsp_neon.S b/ffmpeg/libavcodec/arm/aacpsdsp_neon.S index fb00900..a93bbfe 100644 --- a/ffmpeg/libavcodec/arm/aacpsdsp_neon.S +++ b/ffmpeg/libavcodec/arm/aacpsdsp_neon.S @@ -1,20 +1,20 @@ /* * Copyright (c) 2012 Mans Rullgard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/arm/ac3dsp_arm.S b/ffmpeg/libavcodec/arm/ac3dsp_arm.S index ed8eb37..1aea190 100644 --- a/ffmpeg/libavcodec/arm/ac3dsp_arm.S +++ b/ffmpeg/libavcodec/arm/ac3dsp_arm.S @@ -1,20 +1,20 @@ /* * Copyright (c) 2011 Mans Rullgard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/arm/ac3dsp_armv6.S b/ffmpeg/libavcodec/arm/ac3dsp_armv6.S index 2028d0b..1d2563d 100644 --- a/ffmpeg/libavcodec/arm/ac3dsp_armv6.S +++ b/ffmpeg/libavcodec/arm/ac3dsp_armv6.S @@ -1,20 +1,20 @@ /* * Copyright (c) 2011 Mans Rullgard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/arm/ac3dsp_init_arm.c b/ffmpeg/libavcodec/arm/ac3dsp_init_arm.c index ffe0747..a3c32ff 100644 --- a/ffmpeg/libavcodec/arm/ac3dsp_init_arm.c +++ b/ffmpeg/libavcodec/arm/ac3dsp_init_arm.c @@ -31,6 +31,8 @@ void ff_ac3_lshift_int16_neon(int16_t *src, unsigned len, unsigned shift); void ff_ac3_rshift_int32_neon(int32_t *src, unsigned len, unsigned shift); void ff_float_to_fixed24_neon(int32_t *dst, const float *src, unsigned int len); void ff_ac3_extract_exponents_neon(uint8_t *exp, int32_t *coef, int nb_coefs); +void ff_apply_window_int16_neon(int16_t *dst, const int16_t *src, + const int16_t *window, unsigned n); void ff_ac3_sum_square_butterfly_int32_neon(int64_t sum[4], const int32_t *coef0, const int32_t *coef1, @@ -64,6 +66,7 @@ av_cold void ff_ac3dsp_init_arm(AC3DSPContext *c, int bit_exact) c->ac3_rshift_int32 = ff_ac3_rshift_int32_neon; c->float_to_fixed24 = ff_float_to_fixed24_neon; c->extract_exponents = ff_ac3_extract_exponents_neon; + c->apply_window_int16 = ff_apply_window_int16_neon; c->sum_square_butterfly_int32 = ff_ac3_sum_square_butterfly_int32_neon; c->sum_square_butterfly_float = ff_ac3_sum_square_butterfly_float_neon; } diff --git a/ffmpeg/libavcodec/arm/ac3dsp_neon.S b/ffmpeg/libavcodec/arm/ac3dsp_neon.S index 42f35e3..89d0ae8 100644 --- a/ffmpeg/libavcodec/arm/ac3dsp_neon.S +++ b/ffmpeg/libavcodec/arm/ac3dsp_neon.S @@ -1,20 +1,20 @@ /* * Copyright (c) 2011 Mans Rullgard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -109,6 +109,29 @@ function ff_ac3_extract_exponents_neon, export=1 bx lr endfunc +function ff_apply_window_int16_neon, export=1 + push {r4,lr} + add r4, r1, r3, lsl #1 + add lr, r0, r3, lsl #1 + sub r4, r4, #16 + sub lr, lr, #16 + mov r12, #-16 +1: + vld1.16 {q0}, [r1,:128]! + vld1.16 {q2}, [r2,:128]! + vld1.16 {q1}, [r4,:128], r12 + vrev64.16 q3, q2 + vqrdmulh.s16 q0, q0, q2 + vqrdmulh.s16 d2, d2, d7 + vqrdmulh.s16 d3, d3, d6 + vst1.16 {q0}, [r0,:128]! + vst1.16 {q1}, [lr,:128], r12 + subs r3, r3, #16 + bgt 1b + + pop {r4,pc} +endfunc + function ff_ac3_sum_square_butterfly_int32_neon, export=1 vmov.i64 q0, #0 vmov.i64 q1, #0 diff --git a/ffmpeg/libavcodec/arm/dca.h b/ffmpeg/libavcodec/arm/dca.h index 2cfd18a..35971a8 100644 --- a/ffmpeg/libavcodec/arm/dca.h +++ b/ffmpeg/libavcodec/arm/dca.h @@ -1,20 +1,20 @@ /* * Copyright (c) 2011 Mans Rullgard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -30,50 +30,48 @@ #define decode_blockcodes decode_blockcodes static inline int decode_blockcodes(int code1, int code2, int levels, - int *values) + int32_t *values) { - int v0, v1, v2, v3, v4, v5; + int32_t v0, v1, v2, v3, v4, v5; - __asm__ ("smmul %8, %14, %18 \n" - "smmul %11, %15, %18 \n" - "smlabb %14, %8, %17, %14 \n" - "smlabb %15, %11, %17, %15 \n" - "smmul %9, %8, %18 \n" - "smmul %12, %11, %18 \n" - "sub %14, %14, %16, lsr #1 \n" - "sub %15, %15, %16, lsr #1 \n" - "smlabb %8, %9, %17, %8 \n" - "smlabb %11, %12, %17, %11 \n" - "smmul %10, %9, %18 \n" - "smmul %13, %12, %18 \n" - "str %14, %0 \n" - "str %15, %4 \n" - "sub %8, %8, %16, lsr #1 \n" - "sub %11, %11, %16, lsr #1 \n" - "smlabb %9, %10, %17, %9 \n" - "smlabb %12, %13, %17, %12 \n" - "smmul %14, %10, %18 \n" - "smmul %15, %13, %18 \n" - "str %8, %1 \n" - "str %11, %5 \n" - "sub %9, %9, %16, lsr #1 \n" - "sub %12, %12, %16, lsr #1 \n" - "smlabb %10, %14, %17, %10 \n" - "smlabb %13, %15, %17, %13 \n" - "str %9, %2 \n" - "str %12, %6 \n" - "sub %10, %10, %16, lsr #1 \n" - "sub %13, %13, %16, lsr #1 \n" - "str %10, %3 \n" - "str %13, %7 \n" - : "=m"(values[0]), "=m"(values[1]), - "=m"(values[2]), "=m"(values[3]), - "=m"(values[4]), "=m"(values[5]), - "=m"(values[6]), "=m"(values[7]), - "=&r"(v0), "=&r"(v1), "=&r"(v2), + __asm__ ("smmul %0, %6, %10 \n" + "smmul %3, %7, %10 \n" + "smlabb %6, %0, %9, %6 \n" + "smlabb %7, %3, %9, %7 \n" + "smmul %1, %0, %10 \n" + "smmul %4, %3, %10 \n" + "sub %6, %6, %8, lsr #1 \n" + "sub %7, %7, %8, lsr #1 \n" + "smlabb %0, %1, %9, %0 \n" + "smlabb %3, %4, %9, %3 \n" + "smmul %2, %1, %10 \n" + "smmul %5, %4, %10 \n" + "str %6, [%11, #0] \n" + "str %7, [%11, #16] \n" + "sub %0, %0, %8, lsr #1 \n" + "sub %3, %3, %8, lsr #1 \n" + "smlabb %1, %2, %9, %1 \n" + "smlabb %4, %5, %9, %4 \n" + "smmul %6, %2, %10 \n" + "smmul %7, %5, %10 \n" + "str %0, [%11, #4] \n" + "str %3, [%11, #20] \n" + "sub %1, %1, %8, lsr #1 \n" + "sub %4, %4, %8, lsr #1 \n" + "smlabb %2, %6, %9, %2 \n" + "smlabb %5, %7, %9, %5 \n" + "str %1, [%11, #8] \n" + "str %4, [%11, #24] \n" + "sub %2, %2, %8, lsr #1 \n" + "sub %5, %5, %8, lsr #1 \n" + "str %2, [%11, #12] \n" + "str %5, [%11, #28] \n" + : "=&r"(v0), "=&r"(v1), "=&r"(v2), "=&r"(v3), "=&r"(v4), "=&r"(v5), "+&r"(code1), "+&r"(code2) - : "r"(levels - 1), "r"(-levels), "r"(ff_inverse[levels])); + : "r"(levels - 1), "r"(-levels), + "r"(ff_inverse[levels]), "r"(values) + : "memory"); return code1 | code2; } diff --git a/ffmpeg/libavcodec/arm/dcadsp_init_arm.c b/ffmpeg/libavcodec/arm/dcadsp_init_arm.c index 56568e0..8893f48 100644 --- a/ffmpeg/libavcodec/arm/dcadsp_init_arm.c +++ b/ffmpeg/libavcodec/arm/dcadsp_init_arm.c @@ -24,13 +24,47 @@ #include "libavutil/attributes.h" #include "libavcodec/dcadsp.h" +void ff_dca_lfe_fir_vfp(float *out, const float *in, const float *coefs, + int decifactor, float scale); +void ff_dca_qmf_32_subbands_vfp(float samples_in[32][8], int sb_act, + SynthFilterContext *synth, FFTContext *imdct, + float synth_buf_ptr[512], + int *synth_buf_offset, float synth_buf2[32], + const float window[512], float *samples_out, + float raXin[32], float scale); void ff_dca_lfe_fir_neon(float *out, const float *in, const float *coefs, int decifactor, float scale); +void ff_synth_filter_float_vfp(FFTContext *imdct, + float *synth_buf_ptr, int *synth_buf_offset, + float synth_buf2[32], const float window[512], + float out[32], const float in[32], + float scale); + +void ff_synth_filter_float_neon(FFTContext *imdct, + float *synth_buf_ptr, int *synth_buf_offset, + float synth_buf2[32], const float window[512], + float out[32], const float in[32], + float scale); + av_cold void ff_dcadsp_init_arm(DCADSPContext *s) { int cpu_flags = av_get_cpu_flags(); + if (have_vfp(cpu_flags) && !have_vfpv3(cpu_flags)) { + s->lfe_fir = ff_dca_lfe_fir_vfp; + s->qmf_32_subbands = ff_dca_qmf_32_subbands_vfp; + } if (have_neon(cpu_flags)) s->lfe_fir = ff_dca_lfe_fir_neon; } + +av_cold void ff_synth_filter_init_arm(SynthFilterContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_vfp(cpu_flags) && !have_vfpv3(cpu_flags)) + s->synth_filter_float = ff_synth_filter_float_vfp; + if (have_neon(cpu_flags)) + s->synth_filter_float = ff_synth_filter_float_neon; +} diff --git a/ffmpeg/libavcodec/arm/dsputil_init_neon.c b/ffmpeg/libavcodec/arm/dsputil_init_neon.c index 6d19af7..c1f250a 100644 --- a/ffmpeg/libavcodec/arm/dsputil_init_neon.c +++ b/ffmpeg/libavcodec/arm/dsputil_init_neon.c @@ -45,9 +45,6 @@ int32_t ff_scalarproduct_int16_neon(const int16_t *v1, const int16_t *v2, int le int32_t ff_scalarproduct_and_madd_int16_neon(int16_t *v1, const int16_t *v2, const int16_t *v3, int len, int mul); -void ff_apply_window_int16_neon(int16_t *dst, const int16_t *src, - const int16_t *window, unsigned n); - av_cold void ff_dsputil_init_neon(DSPContext *c, AVCodecContext *avctx) { const int high_bit_depth = avctx->bits_per_raw_sample > 8; @@ -76,6 +73,4 @@ av_cold void ff_dsputil_init_neon(DSPContext *c, AVCodecContext *avctx) c->scalarproduct_int16 = ff_scalarproduct_int16_neon; c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_neon; - - c->apply_window_int16 = ff_apply_window_int16_neon; } diff --git a/ffmpeg/libavcodec/arm/dsputil_neon.S b/ffmpeg/libavcodec/arm/dsputil_neon.S index 307e122..6c8231e 100644 --- a/ffmpeg/libavcodec/arm/dsputil_neon.S +++ b/ffmpeg/libavcodec/arm/dsputil_neon.S @@ -169,29 +169,6 @@ NOVFP ldr r2, [sp] bx lr endfunc -function ff_apply_window_int16_neon, export=1 - push {r4,lr} - add r4, r1, r3, lsl #1 - add lr, r0, r3, lsl #1 - sub r4, r4, #16 - sub lr, lr, #16 - mov r12, #-16 -1: - vld1.16 {q0}, [r1,:128]! - vld1.16 {q2}, [r2,:128]! - vld1.16 {q1}, [r4,:128], r12 - vrev64.16 q3, q2 - vqrdmulh.s16 q0, q0, q2 - vqrdmulh.s16 d2, d2, d7 - vqrdmulh.s16 d3, d3, d6 - vst1.16 {q0}, [r0,:128]! - vst1.16 {q1}, [lr,:128], r12 - subs r3, r3, #16 - bgt 1b - - pop {r4,pc} -endfunc - function ff_vector_clip_int32_neon, export=1 vdup.32 q0, r2 vdup.32 q1, r3 diff --git a/ffmpeg/libavcodec/arm/fft_fixed_neon.S b/ffmpeg/libavcodec/arm/fft_fixed_neon.S index fa33eac..d4a38a2 100644 --- a/ffmpeg/libavcodec/arm/fft_fixed_neon.S +++ b/ffmpeg/libavcodec/arm/fft_fixed_neon.S @@ -1,20 +1,20 @@ /* * Copyright (c) 2011 Mans Rullgard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/arm/fft_init_arm.c b/ffmpeg/libavcodec/arm/fft_init_arm.c index 8c98abc..7e49b9c 100644 --- a/ffmpeg/libavcodec/arm/fft_init_arm.c +++ b/ffmpeg/libavcodec/arm/fft_init_arm.c @@ -26,22 +26,25 @@ void ff_fft_permute_neon(FFTContext *s, FFTComplex *z); void ff_fft_calc_neon(FFTContext *s, FFTComplex *z); +void ff_imdct_half_vfp(FFTContext *s, FFTSample *output, const FFTSample *input); + void ff_imdct_calc_neon(FFTContext *s, FFTSample *output, const FFTSample *input); void ff_imdct_half_neon(FFTContext *s, FFTSample *output, const FFTSample *input); void ff_mdct_calc_neon(FFTContext *s, FFTSample *output, const FFTSample *input); void ff_rdft_calc_neon(struct RDFTContext *s, FFTSample *z); -void ff_synth_filter_float_neon(FFTContext *imdct, - float *synth_buf_ptr, int *synth_buf_offset, - float synth_buf2[32], const float window[512], - float out[32], const float in[32], - float scale); - av_cold void ff_fft_init_arm(FFTContext *s) { int cpu_flags = av_get_cpu_flags(); + if (have_vfp(cpu_flags)) { +#if CONFIG_MDCT + if (!have_vfpv3(cpu_flags)) + s->imdct_half = ff_imdct_half_vfp; +#endif + } + if (have_neon(cpu_flags)) { #if CONFIG_FFT s->fft_permute = ff_fft_permute_neon; @@ -65,13 +68,3 @@ av_cold void ff_rdft_init_arm(RDFTContext *s) s->rdft_calc = ff_rdft_calc_neon; } #endif - -#if CONFIG_DCA_DECODER -av_cold void ff_synth_filter_init_arm(SynthFilterContext *s) -{ - int cpu_flags = av_get_cpu_flags(); - - if (have_neon(cpu_flags)) - s->synth_filter_float = ff_synth_filter_float_neon; -} -#endif diff --git a/ffmpeg/libavcodec/arm/fmtconvert_init_arm.c b/ffmpeg/libavcodec/arm/fmtconvert_init_arm.c index 1d99c97..37319ed 100644 --- a/ffmpeg/libavcodec/arm/fmtconvert_init_arm.c +++ b/ffmpeg/libavcodec/arm/fmtconvert_init_arm.c @@ -25,9 +25,15 @@ #include "libavcodec/avcodec.h" #include "libavcodec/fmtconvert.h" -void ff_int32_to_float_fmul_scalar_neon(float *dst, const int *src, +void ff_int32_to_float_fmul_scalar_neon(float *dst, const int32_t *src, float mul, int len); +void ff_int32_to_float_fmul_scalar_vfp(float *dst, const int32_t *src, + float mul, int len); +void ff_int32_to_float_fmul_array8_vfp(FmtConvertContext *c, float *dst, + const int32_t *src, const float *mul, + int len); + void ff_float_to_int16_neon(int16_t *dst, const float *src, long len); void ff_float_to_int16_interleave_neon(int16_t *, const float **, long, int); @@ -37,8 +43,15 @@ av_cold void ff_fmt_convert_init_arm(FmtConvertContext *c, AVCodecContext *avctx { int cpu_flags = av_get_cpu_flags(); - if (have_vfp(cpu_flags) && have_armv6(cpu_flags)) { - c->float_to_int16 = ff_float_to_int16_vfp; + if (have_vfp(cpu_flags)) { + if (!have_vfpv3(cpu_flags)) { + c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_vfp; + c->int32_to_float_fmul_array8 = ff_int32_to_float_fmul_array8_vfp; + } + + if (have_armv6(cpu_flags)) { + c->float_to_int16 = ff_float_to_int16_vfp; + } } if (have_neon(cpu_flags)) { diff --git a/ffmpeg/libavcodec/arm/fmtconvert_vfp.S b/ffmpeg/libavcodec/arm/fmtconvert_vfp.S index 7b012bc..b14af45 100644 --- a/ffmpeg/libavcodec/arm/fmtconvert_vfp.S +++ b/ffmpeg/libavcodec/arm/fmtconvert_vfp.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008 Siarhei Siamashka + * Copyright (c) 2013 RISC OS Open Ltd * * This file is part of FFmpeg. * @@ -22,57 +22,200 @@ #include "libavutil/arm/asm.S" /** - * ARM VFP optimized float to int16 conversion. - * Assume that len is a positive number and is multiple of 8, destination - * buffer is at least 4 bytes aligned (8 bytes alignment is better for - * performance), little-endian byte sex. + * ARM VFP optimised int32 to float conversion. + * Assume len is a multiple of 8, destination buffer is at least 4 bytes aligned + * (16 bytes alignment is best for BCM2835), little-endian. */ -@ void ff_float_to_int16_vfp(int16_t *dst, const float *src, int len) -function ff_float_to_int16_vfp, export=1 - push {r4-r8,lr} - vpush {d8-d11} - vldmia r1!, {s16-s23} - vcvt.s32.f32 s0, s16 - vcvt.s32.f32 s1, s17 - vcvt.s32.f32 s2, s18 - vcvt.s32.f32 s3, s19 - vcvt.s32.f32 s4, s20 - vcvt.s32.f32 s5, s21 - vcvt.s32.f32 s6, s22 - vcvt.s32.f32 s7, s23 +@ void ff_int32_to_float_fmul_array8_vfp(FmtConvertContext *c, float *dst, const int32_t *src, const float *mul, int len) +function ff_int32_to_float_fmul_array8_vfp, export=1 + push {lr} + ldr a1, [sp, #4] + subs lr, a1, #3*8 + bcc 50f @ too short to pipeline + @ Now need to find (len / 8) % 3. The approximation + @ x / 24 = (x * 0xAB) >> 12 + @ is good for x < 4096, which is true for both AC3 and DCA. + mov a1, #0xAB + ldr ip, =0x03070000 @ RunFast mode, short vectors of length 8, stride 1 + mul a1, lr, a1 + vpush {s16-s31} + mov a1, a1, lsr #12 + add a1, a1, a1, lsl #1 + rsb a1, a1, lr, lsr #3 + cmp a1, #1 + fmrx a1, FPSCR + fmxr FPSCR, ip + beq 11f + blo 10f + @ Array is (2 + multiple of 3) x 8 floats long + @ drop through... + vldmia a3!, {s16-s23} + vldmia a4!, {s2,s3} + vldmia a3!, {s24-s31} + vcvt.f32.s32 s16, s16 + vcvt.f32.s32 s17, s17 + vcvt.f32.s32 s18, s18 + vcvt.f32.s32 s19, s19 + vcvt.f32.s32 s20, s20 + vcvt.f32.s32 s21, s21 + vcvt.f32.s32 s22, s22 + vcvt.f32.s32 s23, s23 + vmul.f32 s16, s16, s2 + @ drop through... +3: + vldmia a3!, {s8-s15} + vldmia a4!, {s1} + vcvt.f32.s32 s24, s24 + vcvt.f32.s32 s25, s25 + vcvt.f32.s32 s26, s26 + vcvt.f32.s32 s27, s27 + vcvt.f32.s32 s28, s28 + vcvt.f32.s32 s29, s29 + vcvt.f32.s32 s30, s30 + vcvt.f32.s32 s31, s31 + vmul.f32 s24, s24, s3 + vstmia a2!, {s16-s19} + vstmia a2!, {s20-s23} +2: + vldmia a3!, {s16-s23} + vldmia a4!, {s2} + vcvt.f32.s32 s8, s8 + vcvt.f32.s32 s9, s9 + vcvt.f32.s32 s10, s10 + vcvt.f32.s32 s11, s11 + vcvt.f32.s32 s12, s12 + vcvt.f32.s32 s13, s13 + vcvt.f32.s32 s14, s14 + vcvt.f32.s32 s15, s15 + vmul.f32 s8, s8, s1 + vstmia a2!, {s24-s27} + vstmia a2!, {s28-s31} 1: - subs r2, r2, #8 - vmov r3, r4, s0, s1 - vmov r5, r6, s2, s3 - vmov r7, r8, s4, s5 - vmov ip, lr, s6, s7 - it gt - vldmiagt r1!, {s16-s23} - ssat r4, #16, r4 - ssat r3, #16, r3 - ssat r6, #16, r6 - ssat r5, #16, r5 - pkhbt r3, r3, r4, lsl #16 - pkhbt r4, r5, r6, lsl #16 - itttt gt - vcvtgt.s32.f32 s0, s16 - vcvtgt.s32.f32 s1, s17 - vcvtgt.s32.f32 s2, s18 - vcvtgt.s32.f32 s3, s19 - itttt gt - vcvtgt.s32.f32 s4, s20 - vcvtgt.s32.f32 s5, s21 - vcvtgt.s32.f32 s6, s22 - vcvtgt.s32.f32 s7, s23 - ssat r8, #16, r8 - ssat r7, #16, r7 - ssat lr, #16, lr - ssat ip, #16, ip - pkhbt r5, r7, r8, lsl #16 - pkhbt r6, ip, lr, lsl #16 - stmia r0!, {r3-r6} - bgt 1b + vldmia a3!, {s24-s31} + vldmia a4!, {s3} + vcvt.f32.s32 s16, s16 + vcvt.f32.s32 s17, s17 + vcvt.f32.s32 s18, s18 + vcvt.f32.s32 s19, s19 + vcvt.f32.s32 s20, s20 + vcvt.f32.s32 s21, s21 + vcvt.f32.s32 s22, s22 + vcvt.f32.s32 s23, s23 + vmul.f32 s16, s16, s2 + vstmia a2!, {s8-s11} + vstmia a2!, {s12-s15} - vpop {d8-d11} - pop {r4-r8,pc} + subs lr, lr, #8*3 + bpl 3b + + vcvt.f32.s32 s24, s24 + vcvt.f32.s32 s25, s25 + vcvt.f32.s32 s26, s26 + vcvt.f32.s32 s27, s27 + vcvt.f32.s32 s28, s28 + vcvt.f32.s32 s29, s29 + vcvt.f32.s32 s30, s30 + vcvt.f32.s32 s31, s31 + vmul.f32 s24, s24, s3 + vstmia a2!, {s16-s19} + vstmia a2!, {s20-s23} + vstmia a2!, {s24-s27} + vstmia a2!, {s28-s31} + + fmxr FPSCR, a1 + vpop {s16-s31} + pop {pc} + +10: @ Array is (multiple of 3) x 8 floats long + vldmia a3!, {s8-s15} + vldmia a4!, {s1,s2} + vldmia a3!, {s16-s23} + vcvt.f32.s32 s8, s8 + vcvt.f32.s32 s9, s9 + vcvt.f32.s32 s10, s10 + vcvt.f32.s32 s11, s11 + vcvt.f32.s32 s12, s12 + vcvt.f32.s32 s13, s13 + vcvt.f32.s32 s14, s14 + vcvt.f32.s32 s15, s15 + vmul.f32 s8, s8, s1 + b 1b + +11: @ Array is (1 + multiple of 3) x 8 floats long + vldmia a3!, {s24-s31} + vldmia a4!, {s3} + vldmia a3!, {s8-s15} + vldmia a4!, {s1} + vcvt.f32.s32 s24, s24 + vcvt.f32.s32 s25, s25 + vcvt.f32.s32 s26, s26 + vcvt.f32.s32 s27, s27 + vcvt.f32.s32 s28, s28 + vcvt.f32.s32 s29, s29 + vcvt.f32.s32 s30, s30 + vcvt.f32.s32 s31, s31 + vmul.f32 s24, s24, s3 + b 2b + +50: + ldr lr, =0x03070000 @ RunFast mode, short vectors of length 8, stride 1 + fmrx ip, FPSCR + fmxr FPSCR, lr +51: + vldmia a3!, {s8-s15} + vldmia a4!, {s0} + vcvt.f32.s32 s8, s8 + vcvt.f32.s32 s9, s9 + vcvt.f32.s32 s10, s10 + vcvt.f32.s32 s11, s11 + vcvt.f32.s32 s12, s12 + vcvt.f32.s32 s13, s13 + vcvt.f32.s32 s14, s14 + vcvt.f32.s32 s15, s15 + vmul.f32 s8, s8, s0 + subs a1, a1, #8 + vstmia a2!, {s8-s11} + vstmia a2!, {s12-s15} + bne 51b + + fmxr FPSCR, ip + pop {pc} +endfunc + +/** + * ARM VFP optimised int32 to float conversion. + * Assume len is a multiple of 8, destination buffer is at least 4 bytes aligned + * (16 bytes alignment is best for BCM2835), little-endian. + * TODO: could be further optimised by unrolling and interleaving, as above + */ +@ void ff_int32_to_float_fmul_scalar_vfp(float *dst, const int32_t *src, float mul, int len) +function ff_int32_to_float_fmul_scalar_vfp, export=1 +VFP tmp .req a4 +VFP len .req a3 +NOVFP tmp .req a3 +NOVFP len .req a4 +NOVFP vmov s0, a3 + ldr tmp, =0x03070000 @ RunFast mode, short vectors of length 8, stride 1 + fmrx ip, FPSCR + fmxr FPSCR, tmp +1: + vldmia a2!, {s8-s15} + vcvt.f32.s32 s8, s8 + vcvt.f32.s32 s9, s9 + vcvt.f32.s32 s10, s10 + vcvt.f32.s32 s11, s11 + vcvt.f32.s32 s12, s12 + vcvt.f32.s32 s13, s13 + vcvt.f32.s32 s14, s14 + vcvt.f32.s32 s15, s15 + vmul.f32 s8, s8, s0 + subs len, len, #8 + vstmia a1!, {s8-s11} + vstmia a1!, {s12-s15} + bne 1b + + fmxr FPSCR, ip + bx lr endfunc + .unreq tmp + .unreq len diff --git a/ffmpeg/libavcodec/arm/h264cmc_neon.S b/ffmpeg/libavcodec/arm/h264cmc_neon.S index 3427e36..0bcae11 100644 --- a/ffmpeg/libavcodec/arm/h264cmc_neon.S +++ b/ffmpeg/libavcodec/arm/h264cmc_neon.S @@ -1,20 +1,20 @@ /* * Copyright (c) 2008 Mans Rullgard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -39,6 +39,9 @@ function ff_\type\()_\codec\()_chroma_mc8_neon, export=1 add r6, r6, r7, lsl #1 vld1.16 {d22[],d23[]}, [r6,:16] .endif + .ifc \codec,vc1 + vmov.u16 q11, #28 + .endif A muls r7, r4, r5 T mul r7, r4, r5 @@ -183,6 +186,9 @@ function ff_\type\()_\codec\()_chroma_mc4_neon, export=1 add r6, r6, r7, lsl #1 vld1.16 {d22[],d23[]}, [r6,:16] .endif + .ifc \codec,vc1 + vmov.u16 q11, #28 + .endif A muls r7, r4, r5 T mul r7, r4, r5 @@ -376,14 +382,12 @@ function ff_\type\()_h264_chroma_mc2_neon, export=1 endfunc .endm -#if CONFIG_H264_DECODER h264_chroma_mc8 put h264_chroma_mc8 avg h264_chroma_mc4 put h264_chroma_mc4 avg h264_chroma_mc2 put h264_chroma_mc2 avg -#endif #if CONFIG_RV40_DECODER const rv40bias @@ -398,3 +402,10 @@ endconst h264_chroma_mc4 put, rv40 h264_chroma_mc4 avg, rv40 #endif + +#if CONFIG_VC1_DECODER + h264_chroma_mc8 put, vc1 + h264_chroma_mc8 avg, vc1 + h264_chroma_mc4 put, vc1 + h264_chroma_mc4 avg, vc1 +#endif diff --git a/ffmpeg/libavcodec/arm/h264dsp_init_arm.c b/ffmpeg/libavcodec/arm/h264dsp_init_arm.c index 785b604..2cafbaf 100644 --- a/ffmpeg/libavcodec/arm/h264dsp_init_arm.c +++ b/ffmpeg/libavcodec/arm/h264dsp_init_arm.c @@ -24,6 +24,8 @@ #include "libavutil/arm/cpu.h" #include "libavcodec/h264dsp.h" +int ff_h264_find_start_code_candidate_armv6(const uint8_t *buf, int size); + void ff_h264_v_loop_filter_luma_neon(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0); void ff_h264_h_loop_filter_luma_neon(uint8_t *pix, int stride, int alpha, @@ -68,8 +70,8 @@ void ff_h264_idct8_add4_neon(uint8_t *dst, const int *block_offset, int16_t *block, int stride, const uint8_t nnzc[6*8]); -static av_cold void ff_h264dsp_init_neon(H264DSPContext *c, const int bit_depth, - const int chroma_format_idc) +static av_cold void h264dsp_init_neon(H264DSPContext *c, const int bit_depth, + const int chroma_format_idc) { #if HAVE_NEON if (bit_depth == 8) { @@ -106,6 +108,8 @@ av_cold void ff_h264dsp_init_arm(H264DSPContext *c, const int bit_depth, { int cpu_flags = av_get_cpu_flags(); + if (have_armv6(cpu_flags)) + c->h264_find_start_code_candidate = ff_h264_find_start_code_candidate_armv6; if (have_neon(cpu_flags)) - ff_h264dsp_init_neon(c, bit_depth, chroma_format_idc); + h264dsp_init_neon(c, bit_depth, chroma_format_idc); } diff --git a/ffmpeg/libavcodec/arm/h264idct_neon.S b/ffmpeg/libavcodec/arm/h264idct_neon.S index fa5b90c..2edeca2 100644 --- a/ffmpeg/libavcodec/arm/h264idct_neon.S +++ b/ffmpeg/libavcodec/arm/h264idct_neon.S @@ -187,8 +187,8 @@ endfunc vshr.s16 q2, q10, #1 vadd.i16 q0, q8, q12 vld1.16 {q14-q15},[r1,:128] - vst1.16 {q7}, [r1,:128]! - vst1.16 {q7}, [r1,:128]! + vst1.16 {q3}, [r1,:128]! + vst1.16 {q3}, [r1,:128]! vsub.i16 q1, q8, q12 vshr.s16 q3, q14, #1 vsub.i16 q2, q2, q14 @@ -267,16 +267,16 @@ endfunc .endm function ff_h264_idct8_add_neon, export=1 - vmov.i16 q7, #0 + vmov.i16 q3, #0 vld1.16 {q8-q9}, [r1,:128] - vst1.16 {q7}, [r1,:128]! - vst1.16 {q7}, [r1,:128]! + vst1.16 {q3}, [r1,:128]! + vst1.16 {q3}, [r1,:128]! vld1.16 {q10-q11},[r1,:128] - vst1.16 {q7}, [r1,:128]! - vst1.16 {q7}, [r1,:128]! + vst1.16 {q3}, [r1,:128]! + vst1.16 {q3}, [r1,:128]! vld1.16 {q12-q13},[r1,:128] - vst1.16 {q7}, [r1,:128]! - vst1.16 {q7}, [r1,:128]! + vst1.16 {q3}, [r1,:128]! + vst1.16 {q3}, [r1,:128]! idct8x8_cols 0 idct8x8_cols 1 diff --git a/ffmpeg/libavcodec/arm/h264pred_init_arm.c b/ffmpeg/libavcodec/arm/h264pred_init_arm.c index 5ec39ce..1562f0b 100644 --- a/ffmpeg/libavcodec/arm/h264pred_init_arm.c +++ b/ffmpeg/libavcodec/arm/h264pred_init_arm.c @@ -45,9 +45,9 @@ void ff_pred8x8_0lt_dc_neon(uint8_t *src, ptrdiff_t stride); void ff_pred8x8_l00_dc_neon(uint8_t *src, ptrdiff_t stride); void ff_pred8x8_0l0_dc_neon(uint8_t *src, ptrdiff_t stride); -static av_cold void ff_h264_pred_init_neon(H264PredContext *h, int codec_id, - const int bit_depth, - const int chroma_format_idc) +static av_cold void h264_pred_init_neon(H264PredContext *h, int codec_id, + const int bit_depth, + const int chroma_format_idc) { #if HAVE_NEON const int high_depth = bit_depth > 8; @@ -88,5 +88,5 @@ av_cold void ff_h264_pred_init_arm(H264PredContext *h, int codec_id, int cpu_flags = av_get_cpu_flags(); if (have_neon(cpu_flags)) - ff_h264_pred_init_neon(h, codec_id, bit_depth, chroma_format_idc); + h264_pred_init_neon(h, codec_id, bit_depth, chroma_format_idc); } diff --git a/ffmpeg/libavcodec/arm/hpeldsp_arm.h b/ffmpeg/libavcodec/arm/hpeldsp_arm.h index e79bc6f..3f18c62 100644 --- a/ffmpeg/libavcodec/arm/hpeldsp_arm.h +++ b/ffmpeg/libavcodec/arm/hpeldsp_arm.h @@ -23,7 +23,7 @@ #include "libavcodec/hpeldsp.h" -void ff_hpeldsp_init_armv6(HpelDSPContext* c, int flags); +void ff_hpeldsp_init_armv6(HpelDSPContext *c, int flags); void ff_hpeldsp_init_neon(HpelDSPContext *c, int flags); #endif /* AVCODEC_ARM_HPELDSP_H */ diff --git a/ffmpeg/libavcodec/arm/hpeldsp_init_arm.c b/ffmpeg/libavcodec/arm/hpeldsp_init_arm.c index bae93eb..2cc2b78 100644 --- a/ffmpeg/libavcodec/arm/hpeldsp_init_arm.c +++ b/ffmpeg/libavcodec/arm/hpeldsp_init_arm.c @@ -20,7 +20,9 @@ */ #include "libavutil/arm/cpu.h" +#include "libavutil/attributes.h" #include "libavcodec/bit_depth_template.c" // for CALL_2X_PIXELS +#include "libavcodec/rnd_avg.h" #include "hpeldsp_arm.h" void ff_put_pixels8_arm(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h); @@ -41,7 +43,7 @@ CALL_2X_PIXELS(ff_put_no_rnd_pixels16_x2_arm, ff_put_no_rnd_pixels8_x2_arm, 8) CALL_2X_PIXELS(ff_put_no_rnd_pixels16_y2_arm, ff_put_no_rnd_pixels8_y2_arm, 8) CALL_2X_PIXELS(ff_put_no_rnd_pixels16_xy2_arm, ff_put_no_rnd_pixels8_xy2_arm,8) -void ff_hpeldsp_init_arm(HpelDSPContext* c, int flags) +av_cold void ff_hpeldsp_init_arm(HpelDSPContext *c, int flags) { int cpu_flags = av_get_cpu_flags(); @@ -63,6 +65,8 @@ void ff_hpeldsp_init_arm(HpelDSPContext* c, int flags) c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_arm; c->put_no_rnd_pixels_tab[1][3] = ff_put_no_rnd_pixels8_xy2_arm; - if (have_armv6(cpu_flags)) ff_hpeldsp_init_armv6(c, flags); - if (have_neon(cpu_flags)) ff_hpeldsp_init_neon(c, flags); + if (have_armv6(cpu_flags)) + ff_hpeldsp_init_armv6(c, flags); + if (have_neon(cpu_flags)) + ff_hpeldsp_init_neon(c, flags); } diff --git a/ffmpeg/libavcodec/arm/hpeldsp_init_armv6.c b/ffmpeg/libavcodec/arm/hpeldsp_init_armv6.c index da4caf8..967a8e0 100644 --- a/ffmpeg/libavcodec/arm/hpeldsp_init_armv6.c +++ b/ffmpeg/libavcodec/arm/hpeldsp_init_armv6.c @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include #include "libavutil/attributes.h" diff --git a/ffmpeg/libavcodec/arm/hpeldsp_init_neon.c b/ffmpeg/libavcodec/arm/hpeldsp_init_neon.c index d577735..d9feadd 100644 --- a/ffmpeg/libavcodec/arm/hpeldsp_init_neon.c +++ b/ffmpeg/libavcodec/arm/hpeldsp_init_neon.c @@ -19,8 +19,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include +#include "libavutil/attributes.h" #include "hpeldsp_arm.h" void ff_put_pixels16_neon(uint8_t *, const uint8_t *, ptrdiff_t, int); @@ -50,7 +52,7 @@ void ff_avg_pixels16_x2_no_rnd_neon(uint8_t *, const uint8_t *, ptrdiff_t, int); void ff_avg_pixels16_y2_no_rnd_neon(uint8_t *, const uint8_t *, ptrdiff_t, int); void ff_avg_pixels16_xy2_no_rnd_neon(uint8_t *, const uint8_t *, ptrdiff_t, int); -void ff_hpeldsp_init_neon(HpelDSPContext *c, int flags) +av_cold void ff_hpeldsp_init_neon(HpelDSPContext *c, int flags) { c->put_pixels_tab[0][0] = ff_put_pixels16_neon; c->put_pixels_tab[0][1] = ff_put_pixels16_x2_neon; diff --git a/ffmpeg/libavcodec/arm/int_neon.S b/ffmpeg/libavcodec/arm/int_neon.S index 6b28a97..b3f5a69 100644 --- a/ffmpeg/libavcodec/arm/int_neon.S +++ b/ffmpeg/libavcodec/arm/int_neon.S @@ -1,6 +1,6 @@ /* * ARM NEON optimised integer operations - * Copyright (c) 2009 Kostya Shishkov + * Copyright (c) 2009 Konstantin Shishkov * * This file is part of FFmpeg. * @@ -41,10 +41,10 @@ function ff_scalarproduct_int16_neon, export=1 vpadd.s32 d16, d0, d1 vpadd.s32 d17, d2, d3 - vpadd.s32 d10, d4, d5 - vpadd.s32 d11, d6, d7 + vpadd.s32 d18, d4, d5 + vpadd.s32 d19, d6, d7 vpadd.s32 d0, d16, d17 - vpadd.s32 d1, d10, d11 + vpadd.s32 d1, d18, d19 vpadd.s32 d2, d0, d1 vpaddl.s32 d3, d2 vmov.32 r0, d3[0] @@ -81,10 +81,10 @@ function ff_scalarproduct_and_madd_int16_neon, export=1 vpadd.s32 d16, d0, d1 vpadd.s32 d17, d2, d3 - vpadd.s32 d10, d4, d5 - vpadd.s32 d11, d6, d7 + vpadd.s32 d18, d4, d5 + vpadd.s32 d19, d6, d7 vpadd.s32 d0, d16, d17 - vpadd.s32 d1, d10, d11 + vpadd.s32 d1, d18, d19 vpadd.s32 d2, d0, d1 vpaddl.s32 d3, d2 vmov.32 r0, d3[0] diff --git a/ffmpeg/libavcodec/arm/mdct_fixed_neon.S b/ffmpeg/libavcodec/arm/mdct_fixed_neon.S index c77be59..365c5e7 100644 --- a/ffmpeg/libavcodec/arm/mdct_fixed_neon.S +++ b/ffmpeg/libavcodec/arm/mdct_fixed_neon.S @@ -1,20 +1,20 @@ /* * Copyright (c) 2011 Mans Rullgard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/arm/mpegaudiodsp_fixed_armv6.S b/ffmpeg/libavcodec/arm/mpegaudiodsp_fixed_armv6.S index 49bd0bc..977abb6 100644 --- a/ffmpeg/libavcodec/arm/mpegaudiodsp_fixed_armv6.S +++ b/ffmpeg/libavcodec/arm/mpegaudiodsp_fixed_armv6.S @@ -1,20 +1,20 @@ /* * Copyright (c) 2011 Mans Rullgard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/arm/mpegaudiodsp_init_arm.c b/ffmpeg/libavcodec/arm/mpegaudiodsp_init_arm.c index e73aee6..98e0c8a 100644 --- a/ffmpeg/libavcodec/arm/mpegaudiodsp_init_arm.c +++ b/ffmpeg/libavcodec/arm/mpegaudiodsp_init_arm.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2011 Mans Rullgard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/arm/neon.S b/ffmpeg/libavcodec/arm/neon.S index 716a607..787bc4b 100644 --- a/ffmpeg/libavcodec/arm/neon.S +++ b/ffmpeg/libavcodec/arm/neon.S @@ -1,20 +1,20 @@ /* * Copyright (c) 2008 Mans Rullgard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/arm/rv34dsp_neon.S b/ffmpeg/libavcodec/arm/rv34dsp_neon.S index a29123f..3d4a83d 100644 --- a/ffmpeg/libavcodec/arm/rv34dsp_neon.S +++ b/ffmpeg/libavcodec/arm/rv34dsp_neon.S @@ -1,20 +1,20 @@ /* * Copyright (c) 2011 Janne Grunau * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/arm/rv40dsp_init_arm.c b/ffmpeg/libavcodec/arm/rv40dsp_init_arm.c index fec3702..3bf9ac7 100644 --- a/ffmpeg/libavcodec/arm/rv40dsp_init_arm.c +++ b/ffmpeg/libavcodec/arm/rv40dsp_init_arm.c @@ -70,7 +70,7 @@ void ff_rv40_v_weak_loop_filter_neon(uint8_t *src, ptrdiff_t stride, int filter_ int filter_q1, int alpha, int beta, int lim_p0q0, int lim_q1, int lim_p1); -static av_cold void ff_rv40dsp_init_neon(RV34DSPContext *c) +static av_cold void rv40dsp_init_neon(RV34DSPContext *c) { c->put_pixels_tab[0][ 1] = ff_put_rv40_qpel16_mc10_neon; c->put_pixels_tab[0][ 3] = ff_put_rv40_qpel16_mc30_neon; @@ -144,5 +144,5 @@ av_cold void ff_rv40dsp_init_arm(RV34DSPContext *c) int cpu_flags = av_get_cpu_flags(); if (have_neon(cpu_flags)) - ff_rv40dsp_init_neon(c); + rv40dsp_init_neon(c); } diff --git a/ffmpeg/libavcodec/arm/rv40dsp_neon.S b/ffmpeg/libavcodec/arm/rv40dsp_neon.S index 6bd45eb..099f88c 100644 --- a/ffmpeg/libavcodec/arm/rv40dsp_neon.S +++ b/ffmpeg/libavcodec/arm/rv40dsp_neon.S @@ -2,20 +2,20 @@ * Copyright (c) 2011 Janne Grunau * Copyright (c) 2011 Mans Rullgard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/arm/sbrdsp_init_arm.c b/ffmpeg/libavcodec/arm/sbrdsp_init_arm.c index 4da7967..4fb69f9 100644 --- a/ffmpeg/libavcodec/arm/sbrdsp_init_arm.c +++ b/ffmpeg/libavcodec/arm/sbrdsp_init_arm.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2012 Mans Rullgard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/arm/sbrdsp_neon.S b/ffmpeg/libavcodec/arm/sbrdsp_neon.S index 610397f..e66abd6 100644 --- a/ffmpeg/libavcodec/arm/sbrdsp_neon.S +++ b/ffmpeg/libavcodec/arm/sbrdsp_neon.S @@ -1,20 +1,20 @@ /* * Copyright (c) 2012 Mans Rullgard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/arm/simple_idct_arm.S b/ffmpeg/libavcodec/arm/simple_idct_arm.S index dd1c815..50d20c9 100644 --- a/ffmpeg/libavcodec/arm/simple_idct_arm.S +++ b/ffmpeg/libavcodec/arm/simple_idct_arm.S @@ -83,7 +83,7 @@ __row_loop: orrs r5, r5, r7 @ R5=R4 | R3 | R2 | R7 beq __almost_empty_row -__b_evaluation: +@@ __b_evaluation: @@ at this point, R0=block (temp), R1(free), R2=ROWr32[1], R3=ROWr32[2], R4=ROWr32[3], @@ R5=(temp), R6=ROWr16[0], R7=ROWr16[1], R8-R11 free, @@ R12=__const_ptr_, R14=&block[n] @@ -159,7 +159,7 @@ __end_b_evaluation: @@ R5=b2, R6=ROWr16[0], R7=b3, R8 (free), R9 (free), R10 (free), R11 (free), @@ R12=__const_ptr_, R14=&block[n] -__a_evaluation: +@@ __a_evaluation: @@ a0 = (W4 * row[0]) + (1 << (ROW_SHIFT - 1)); @@ a1 = a0 + W6 * row[2]; @@ a2 = a0 - W6 * row[2]; @@ -295,7 +295,7 @@ __end_row_loop: add r14, r0, #14 @ R14=&block[7], better start from the last col, and decrease the value until col=0, i.e. R14=block. __col_loop: -__b_evaluation2: +@@ __b_evaluation2: @@ at this point, R0=block (temp), R1-R11 (free) @@ R12=__const_ptr_, R14=&block[n] @@ proceed with b0-b3 first, followed by a0-a3 @@ -357,12 +357,12 @@ __b_evaluation2: it ne mlane r1, r10, r4, r1 @ R1-=W5*ROWr16[7x8]=b1 @@ R4 is free now -__end_b_evaluation2: +@@ __end_b_evaluation2: @@ at this point, R0=b0, R1=b1, R2 (free), R3 (free), R4 (free), @@ R5=b2, R6 (free), R7=b3, R8 (free), R9 (free), R10 (free), R11 (free), @@ R12=__const_ptr_, R14=&block[n] -__a_evaluation2: +@@ __a_evaluation2: @@ a0 = (W4 * col[8x0]) + (1 << (COL_SHIFT - 1)); @@ a1 = a0 + W6 * row[2]; @@ a2 = a0 - W6 * row[2]; @@ -414,7 +414,7 @@ __a_evaluation2: itt ne subne r2, r2, r10 @ R2-=W2*ROWr16[6] (a1) addne r3, r3, r10 @ R3+=W2*ROWr16[6] (a2) -__end_a_evaluation2: +@@ __end_a_evaluation2: @@ at this point, R0=b0, R1=b1, R2=a1, R3=a2, R4=a3, @@ R5=b2, R6=a0, R7=b3, R8 (free), R9 (free), R10 (free), R11 (free), @@ R12=__const_ptr_, R14=&block[n] @@ -452,7 +452,7 @@ __end_a_evaluation2: strh r8, [r14, #96] strh r9, [r14, #112] -__end_col_loop: +@@ __end_col_loop: @@ at this point, R0-R11 (free) @@ R12=__const_ptr_, R14=&block[n] ldr r0, [sp, #0] @ R0=block @@ -463,7 +463,7 @@ __end_col_loop: -__end_simple_idct_arm: +@@ __end_simple_idct_arm: @@ restore registers to previous status! add sp, sp, #8 @@ the local variables! ldmfd sp!, {r4-r11, r15} @@ update PC with LR content. diff --git a/ffmpeg/libavcodec/arm/vp56dsp_init_arm.c b/ffmpeg/libavcodec/arm/vp56dsp_init_arm.c deleted file mode 100644 index f53cbae..0000000 --- a/ffmpeg/libavcodec/arm/vp56dsp_init_arm.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2010 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include "libavutil/attributes.h" -#include "libavutil/arm/cpu.h" -#include "libavcodec/avcodec.h" -#include "libavcodec/vp56dsp.h" - -void ff_vp6_edge_filter_hor_neon(uint8_t *yuv, int stride, int t); -void ff_vp6_edge_filter_ver_neon(uint8_t *yuv, int stride, int t); - -av_cold void ff_vp56dsp_init_arm(VP56DSPContext *s, enum AVCodecID codec) -{ - int cpu_flags = av_get_cpu_flags(); - - if (codec != AV_CODEC_ID_VP5 && have_neon(cpu_flags)) { - s->edge_filter_hor = ff_vp6_edge_filter_hor_neon; - s->edge_filter_ver = ff_vp6_edge_filter_ver_neon; - } -} diff --git a/ffmpeg/libavcodec/arm/vp56dsp_neon.S b/ffmpeg/libavcodec/arm/vp56dsp_neon.S deleted file mode 100644 index 03dd28d..0000000 --- a/ffmpeg/libavcodec/arm/vp56dsp_neon.S +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2010 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/arm/asm.S" - -.macro vp6_edge_filter - vdup.16 q3, r2 @ t - vmov.i16 q13, #1 - vsubl.u8 q0, d20, d18 @ p[ 0] - p[-s] - vsubl.u8 q1, d16, d22 @ p[-2*s] - p[ s] - vsubl.u8 q14, d21, d19 - vsubl.u8 q15, d17, d23 - vadd.i16 q2, q0, q0 @ 2*(p[0]-p[-s]) - vadd.i16 d29, d28, d28 - vadd.i16 q0, q0, q1 @ p[0]-p[-s] + p[-2*s]-p[s] - vadd.i16 d28, d28, d30 - vadd.i16 q0, q0, q2 @ 3*(p[0]-p[-s]) + p[-2*s]-p[s] - vadd.i16 d28, d28, d29 - vrshr.s16 q0, q0, #3 @ v - vrshr.s16 d28, d28, #3 - vsub.i16 q8, q3, q13 @ t-1 - vabs.s16 q1, q0 @ V - vshr.s16 q2, q0, #15 @ s - vabs.s16 d30, d28 - vshr.s16 d29, d28, #15 - vsub.i16 q12, q1, q3 @ V-t - vsub.i16 d31, d30, d6 - vsub.i16 q12, q12, q13 @ V-t-1 - vsub.i16 d31, d31, d26 - vcge.u16 q12, q12, q8 @ V-t-1 >= t-1 - vcge.u16 d31, d31, d16 - vadd.i16 q13, q3, q3 @ 2*t - vadd.i16 d16, d6, d6 - vsub.i16 q13, q13, q1 @ 2*t - V - vsub.i16 d16, d16, d30 - vadd.i16 q13, q13, q2 @ += s - vadd.i16 d16, d16, d29 - veor q13, q13, q2 @ ^= s - veor d16, d16, d29 - vbif q0, q13, q12 - vbif d28, d16, d31 - vmovl.u8 q1, d20 - vmovl.u8 q15, d21 - vaddw.u8 q2, q0, d18 - vaddw.u8 q3, q14, d19 - vsub.i16 q1, q1, q0 - vsub.i16 d30, d30, d28 - vqmovun.s16 d18, q2 - vqmovun.s16 d19, q3 - vqmovun.s16 d20, q1 - vqmovun.s16 d21, q15 -.endm - -function ff_vp6_edge_filter_ver_neon, export=1 - sub r0, r0, r1, lsl #1 - vld1.8 {q8}, [r0], r1 @ p[-2*s] - vld1.8 {q9}, [r0], r1 @ p[-s] - vld1.8 {q10}, [r0], r1 @ p[0] - vld1.8 {q11}, [r0] @ p[s] - vp6_edge_filter - sub r0, r0, r1, lsl #1 - sub r1, r1, #8 - vst1.8 {d18}, [r0]! - vst1.32 {d19[0]}, [r0], r1 - vst1.8 {d20}, [r0]! - vst1.32 {d21[0]}, [r0] - bx lr -endfunc - -function ff_vp6_edge_filter_hor_neon, export=1 - sub r3, r0, #1 - sub r0, r0, #2 - vld1.32 {d16[0]}, [r0], r1 - vld1.32 {d18[0]}, [r0], r1 - vld1.32 {d20[0]}, [r0], r1 - vld1.32 {d22[0]}, [r0], r1 - vld1.32 {d16[1]}, [r0], r1 - vld1.32 {d18[1]}, [r0], r1 - vld1.32 {d20[1]}, [r0], r1 - vld1.32 {d22[1]}, [r0], r1 - vld1.32 {d17[0]}, [r0], r1 - vld1.32 {d19[0]}, [r0], r1 - vld1.32 {d21[0]}, [r0], r1 - vld1.32 {d23[0]}, [r0], r1 - vtrn.8 q8, q9 - vtrn.8 q10, q11 - vtrn.16 q8, q10 - vtrn.16 q9, q11 - vp6_edge_filter - vtrn.8 q9, q10 - vst1.16 {d18[0]}, [r3], r1 - vst1.16 {d20[0]}, [r3], r1 - vst1.16 {d18[1]}, [r3], r1 - vst1.16 {d20[1]}, [r3], r1 - vst1.16 {d18[2]}, [r3], r1 - vst1.16 {d20[2]}, [r3], r1 - vst1.16 {d18[3]}, [r3], r1 - vst1.16 {d20[3]}, [r3], r1 - vst1.16 {d19[0]}, [r3], r1 - vst1.16 {d21[0]}, [r3], r1 - vst1.16 {d19[1]}, [r3], r1 - vst1.16 {d21[1]}, [r3], r1 - bx lr -endfunc diff --git a/ffmpeg/libavcodec/arm/vp8dsp.h b/ffmpeg/libavcodec/arm/vp8dsp.h index ce00e4a..6041ef1 100644 --- a/ffmpeg/libavcodec/arm/vp8dsp.h +++ b/ffmpeg/libavcodec/arm/vp8dsp.h @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/arm/vp8dsp_armv6.S b/ffmpeg/libavcodec/arm/vp8dsp_armv6.S index 5207758..a14b188 100644 --- a/ffmpeg/libavcodec/arm/vp8dsp_armv6.S +++ b/ffmpeg/libavcodec/arm/vp8dsp_armv6.S @@ -5,20 +5,20 @@ * Copyright (c) 2010 Rob Clark * Copyright (c) 2011 Mans Rullgard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * This code was partially ported from libvpx, which uses this license: diff --git a/ffmpeg/libavcodec/arm/vp8dsp_init_armv6.c b/ffmpeg/libavcodec/arm/vp8dsp_init_armv6.c index e15e191..563268e 100644 --- a/ffmpeg/libavcodec/arm/vp8dsp_init_armv6.c +++ b/ffmpeg/libavcodec/arm/vp8dsp_init_armv6.c @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/arm/vp8dsp_init_neon.c b/ffmpeg/libavcodec/arm/vp8dsp_init_neon.c index 0468181..ae045a6 100644 --- a/ffmpeg/libavcodec/arm/vp8dsp_init_neon.c +++ b/ffmpeg/libavcodec/arm/vp8dsp_init_neon.c @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/arm/vp8dsp_neon.S b/ffmpeg/libavcodec/arm/vp8dsp_neon.S index 04e7c5c..436b340 100644 --- a/ffmpeg/libavcodec/arm/vp8dsp_neon.S +++ b/ffmpeg/libavcodec/arm/vp8dsp_neon.S @@ -1576,18 +1576,19 @@ endconst /* Bilinear MC */ function ff_put_vp8_bilin16_h_neon, export=1 - ldr r3, [sp, #4] @ mx - rsb r12, r3, #8 - vdup.8 d0, r3 + push {lr} + ldr lr, [sp, #8] @ mx + rsb r12, lr, #8 + vdup.8 d0, lr vdup.8 d1, r12 - ldr r12, [sp] @ h + ldr r12, [sp, #4] @ h 1: subs r12, r12, #2 - vld1.8 {d2-d4}, [r2], r1 + vld1.8 {d2-d4}, [r2], r3 vext.8 q2, q1, q2, #1 vmull.u8 q8, d2, d1 vmlal.u8 q8, d4, d0 - vld1.8 {d18-d20},[r2], r1 + vld1.8 {d18-d20},[r2], r3 vmull.u8 q3, d3, d1 vmlal.u8 q3, d5, d0 vext.8 q10, q9, q10, #1 @@ -1603,24 +1604,25 @@ function ff_put_vp8_bilin16_h_neon, export=1 vst1.8 {q3}, [r0,:128], r1 bgt 1b - bx lr + pop {pc} endfunc function ff_put_vp8_bilin16_v_neon, export=1 - ldr r3, [sp, #8] @ my - rsb r12, r3, #8 - vdup.8 d0, r3 + push {lr} + ldr lr, [sp, #12] @ my + rsb r12, lr, #8 + vdup.8 d0, lr vdup.8 d1, r12 - ldr r12, [sp] @ h - vld1.8 {q1}, [r2], r1 + ldr r12, [sp, #4] @ h + vld1.8 {q1}, [r2], r3 1: subs r12, r12, #2 - vld1.8 {q2}, [r2], r1 + vld1.8 {q2}, [r2], r3 vmull.u8 q3, d2, d1 vmlal.u8 q3, d4, d0 vmull.u8 q8, d3, d1 vmlal.u8 q8, d5, d0 - vld1.8 {q1}, [r2], r1 + vld1.8 {q1}, [r2], r3 vmull.u8 q9, d4, d1 vmlal.u8 q9, d2, d0 vmull.u8 q10, d5, d1 @@ -1633,21 +1635,22 @@ function ff_put_vp8_bilin16_v_neon, export=1 vst1.8 {q3}, [r0,:128], r1 bgt 1b - bx lr + pop {pc} endfunc function ff_put_vp8_bilin16_hv_neon, export=1 - ldr r3, [sp, #4] @ mx - rsb r12, r3, #8 - vdup.8 d0, r3 + push {lr} + ldr lr, [sp, #8] @ mx + rsb r12, lr, #8 + vdup.8 d0, lr vdup.8 d1, r12 - ldr r3, [sp, #8] @ my - rsb r12, r3, #8 - vdup.8 d2, r3 + ldr lr, [sp, #12] @ my + rsb r12, lr, #8 + vdup.8 d2, lr vdup.8 d3, r12 - ldr r12, [sp] @ h + ldr r12, [sp, #4] @ h - vld1.8 {d4-d6}, [r2], r1 + vld1.8 {d4-d6}, [r2], r3 vext.8 q3, q2, q3, #1 vmull.u8 q8, d4, d1 vmlal.u8 q8, d6, d0 @@ -1657,11 +1660,11 @@ function ff_put_vp8_bilin16_hv_neon, export=1 vrshrn.u16 d5, q9, #3 1: subs r12, r12, #2 - vld1.8 {d18-d20},[r2], r1 + vld1.8 {d18-d20},[r2], r3 vext.8 q10, q9, q10, #1 vmull.u8 q11, d18, d1 vmlal.u8 q11, d20, d0 - vld1.8 {d26-d28},[r2], r1 + vld1.8 {d26-d28},[r2], r3 vmull.u8 q12, d19, d1 vmlal.u8 q12, d21, d0 vext.8 q14, q13, q14, #1 @@ -1689,22 +1692,23 @@ function ff_put_vp8_bilin16_hv_neon, export=1 vst1.8 {q10}, [r0,:128], r1 bgt 1b - bx lr + pop {pc} endfunc function ff_put_vp8_bilin8_h_neon, export=1 - ldr r3, [sp, #4] @ mx - rsb r12, r3, #8 - vdup.8 d0, r3 + push {lr} + ldr lr, [sp, #8] @ mx + rsb r12, lr, #8 + vdup.8 d0, lr vdup.8 d1, r12 - ldr r12, [sp] @ h + ldr r12, [sp, #4] @ h 1: subs r12, r12, #2 - vld1.8 {q1}, [r2], r1 + vld1.8 {q1}, [r2], r3 vext.8 d3, d2, d3, #1 vmull.u8 q2, d2, d1 vmlal.u8 q2, d3, d0 - vld1.8 {q3}, [r2], r1 + vld1.8 {q3}, [r2], r3 vext.8 d7, d6, d7, #1 vmull.u8 q8, d6, d1 vmlal.u8 q8, d7, d0 @@ -1714,22 +1718,23 @@ function ff_put_vp8_bilin8_h_neon, export=1 vst1.8 {d16}, [r0,:64], r1 bgt 1b - bx lr + pop {pc} endfunc function ff_put_vp8_bilin8_v_neon, export=1 - ldr r3, [sp, #8] @ my - rsb r12, r3, #8 - vdup.8 d0, r3 + push {lr} + ldr lr, [sp, #12] @ my + rsb r12, lr, #8 + vdup.8 d0, lr vdup.8 d1, r12 - ldr r12, [sp] @ h - vld1.8 {d2}, [r2], r1 + ldr r12, [sp, #4] @ h + vld1.8 {d2}, [r2], r3 1: subs r12, r12, #2 - vld1.8 {d3}, [r2], r1 + vld1.8 {d3}, [r2], r3 vmull.u8 q2, d2, d1 vmlal.u8 q2, d3, d0 - vld1.8 {d2}, [r2], r1 + vld1.8 {d2}, [r2], r3 vmull.u8 q3, d3, d1 vmlal.u8 q3, d2, d0 vrshrn.u16 d4, q2, #3 @@ -1738,32 +1743,33 @@ function ff_put_vp8_bilin8_v_neon, export=1 vst1.8 {d6}, [r0,:64], r1 bgt 1b - bx lr + pop {pc} endfunc function ff_put_vp8_bilin8_hv_neon, export=1 - ldr r3, [sp, #4] @ mx - rsb r12, r3, #8 - vdup.8 d0, r3 + push {lr} + ldr lr, [sp, #8] @ mx + rsb r12, lr, #8 + vdup.8 d0, lr vdup.8 d1, r12 - ldr r3, [sp, #8] @ my - rsb r12, r3, #8 - vdup.8 d2, r3 + ldr lr, [sp, #12] @ my + rsb r12, lr, #8 + vdup.8 d2, lr vdup.8 d3, r12 - ldr r12, [sp] @ h + ldr r12, [sp, #4] @ h - vld1.8 {q2}, [r2], r1 + vld1.8 {q2}, [r2], r3 vext.8 d5, d4, d5, #1 vmull.u8 q9, d4, d1 vmlal.u8 q9, d5, d0 vrshrn.u16 d22, q9, #3 1: subs r12, r12, #2 - vld1.8 {q3}, [r2], r1 + vld1.8 {q3}, [r2], r3 vext.8 d7, d6, d7, #1 vmull.u8 q8, d6, d1 vmlal.u8 q8, d7, d0 - vld1.8 {q2}, [r2], r1 + vld1.8 {q2}, [r2], r3 vext.8 d5, d4, d5, #1 vmull.u8 q9, d4, d1 vmlal.u8 q9, d5, d0 @@ -1779,20 +1785,21 @@ function ff_put_vp8_bilin8_hv_neon, export=1 vst1.8 {d23}, [r0,:64], r1 bgt 1b - bx lr + pop {pc} endfunc function ff_put_vp8_bilin4_h_neon, export=1 - ldr r3, [sp, #4] @ mx - rsb r12, r3, #8 - vdup.8 d0, r3 + push {lr} + ldr lr, [sp, #8] @ mx + rsb r12, lr, #8 + vdup.8 d0, lr vdup.8 d1, r12 - ldr r12, [sp] @ h + ldr r12, [sp, #4] @ h 1: subs r12, r12, #2 - vld1.8 {d2}, [r2], r1 + vld1.8 {d2}, [r2], r3 vext.8 d3, d2, d3, #1 - vld1.8 {d6}, [r2], r1 + vld1.8 {d6}, [r2], r3 vext.8 d7, d6, d7, #1 vtrn.32 q1, q3 vmull.u8 q2, d2, d1 @@ -1802,20 +1809,21 @@ function ff_put_vp8_bilin4_h_neon, export=1 vst1.32 {d4[1]}, [r0,:32], r1 bgt 1b - bx lr + pop {pc} endfunc function ff_put_vp8_bilin4_v_neon, export=1 - ldr r3, [sp, #8] @ my - rsb r12, r3, #8 - vdup.8 d0, r3 + push {lr} + ldr lr, [sp, #12] @ my + rsb r12, lr, #8 + vdup.8 d0, lr vdup.8 d1, r12 - ldr r12, [sp] @ h - vld1.32 {d2[]}, [r2], r1 + ldr r12, [sp, #4] @ h + vld1.32 {d2[]}, [r2], r3 1: vld1.32 {d3[]}, [r2] - vld1.32 {d2[1]}, [r2], r1 - vld1.32 {d3[1]}, [r2], r1 + vld1.32 {d2[1]}, [r2], r3 + vld1.32 {d3[1]}, [r2], r3 vmull.u8 q2, d2, d1 vmlal.u8 q2, d3, d0 vtrn.32 d3, d2 @@ -1825,30 +1833,31 @@ function ff_put_vp8_bilin4_v_neon, export=1 subs r12, r12, #2 bgt 1b - bx lr + pop {pc} endfunc function ff_put_vp8_bilin4_hv_neon, export=1 - ldr r3, [sp, #4] @ mx - rsb r12, r3, #8 - vdup.8 d0, r3 + push {lr} + ldr lr, [sp, #8] @ mx + rsb r12, lr, #8 + vdup.8 d0, lr vdup.8 d1, r12 - ldr r3, [sp, #8] @ my - rsb r12, r3, #8 - vdup.8 d2, r3 + ldr lr, [sp, #12] @ my + rsb r12, lr, #8 + vdup.8 d2, lr vdup.8 d3, r12 - ldr r12, [sp] @ h + ldr r12, [sp, #4] @ h - vld1.8 {d4}, [r2], r1 + vld1.8 {d4}, [r2], r3 vext.8 d5, d4, d4, #1 vmull.u8 q9, d4, d1 vmlal.u8 q9, d5, d0 vrshrn.u16 d22, q9, #3 1: subs r12, r12, #2 - vld1.8 {d6}, [r2], r1 + vld1.8 {d6}, [r2], r3 vext.8 d7, d6, d6, #1 - vld1.8 {d4}, [r2], r1 + vld1.8 {d4}, [r2], r3 vext.8 d5, d4, d4, #1 vtrn.32 q3, q2 vmull.u8 q8, d6, d1 @@ -1863,5 +1872,5 @@ function ff_put_vp8_bilin4_hv_neon, export=1 vst1.32 {d20[1]}, [r0,:32], r1 bgt 1b - bx lr + pop {pc} endfunc diff --git a/ffmpeg/libavcodec/ass.c b/ffmpeg/libavcodec/ass.c index db0fdd8..ccc9570 100644 --- a/ffmpeg/libavcodec/ass.c +++ b/ffmpeg/libavcodec/ass.c @@ -23,6 +23,7 @@ #include "ass.h" #include "libavutil/avassert.h" #include "libavutil/avstring.h" +#include "libavutil/bprint.h" #include "libavutil/common.h" int ff_ass_subtitle_header(AVCodecContext *avctx, @@ -53,55 +54,136 @@ int ff_ass_subtitle_header(AVCodecContext *avctx, int ff_ass_subtitle_header_default(AVCodecContext *avctx) { return ff_ass_subtitle_header(avctx, ASS_DEFAULT_FONT, - ASS_DEFAULT_FONT_SIZE, - ASS_DEFAULT_COLOR, - ASS_DEFAULT_BACK_COLOR, - ASS_DEFAULT_BOLD, - ASS_DEFAULT_ITALIC, - ASS_DEFAULT_UNDERLINE, - ASS_DEFAULT_ALIGNMENT); + ASS_DEFAULT_FONT_SIZE, + ASS_DEFAULT_COLOR, + ASS_DEFAULT_BACK_COLOR, + ASS_DEFAULT_BOLD, + ASS_DEFAULT_ITALIC, + ASS_DEFAULT_UNDERLINE, + ASS_DEFAULT_ALIGNMENT); } -static int ts_to_string(char *str, int strlen, int ts) +static void insert_ts(AVBPrint *buf, int ts) { - int h, m, s; - h = ts/360000; ts -= 360000*h; - m = ts/ 6000; ts -= 6000*m; - s = ts/ 100; ts -= 100*s; - return snprintf(str, strlen, "%d:%02d:%02d.%02d", h, m, s, ts); + if (ts == -1) { + av_bprintf(buf, "9:59:59.99,"); + } else { + int h, m, s; + + h = ts/360000; ts -= 360000*h; + m = ts/ 6000; ts -= 6000*m; + s = ts/ 100; ts -= 100*s; + av_bprintf(buf, "%d:%02d:%02d.%02d,", h, m, s, ts); + } } -int ff_ass_add_rect(AVSubtitle *sub, const char *dialog, - int ts_start, int duration, int raw) +int ff_ass_bprint_dialog(AVBPrint *buf, const char *dialog, + int ts_start, int duration, int raw) { - int len = 0, dlen; - char s_start[16], s_end[16], header[48] = {0}; - AVSubtitleRect **rects; + int dlen; + + if (!raw || raw == 2) { + long int layer = 0; + + if (raw == 2) { + /* skip ReadOrder */ + dialog = strchr(dialog, ','); + if (!dialog) + return AVERROR_INVALIDDATA; + dialog++; - if (!raw) { - ts_to_string(s_start, sizeof(s_start), ts_start); - if (duration == -1) - snprintf(s_end, sizeof(s_end), "9:59:59.99"); - else - ts_to_string(s_end, sizeof(s_end), ts_start + duration); - len = snprintf(header, sizeof(header), "Dialogue: 0,%s,%s,Default,", - s_start, s_end); - av_assert0(len < sizeof(header)); + /* extract Layer or Marked */ + layer = strtol(dialog, (char**)&dialog, 10); + if (*dialog != ',') + return AVERROR_INVALIDDATA; + dialog++; + } + av_bprintf(buf, "Dialogue: %ld,", layer); + insert_ts(buf, ts_start); + insert_ts(buf, duration == -1 ? -1 : ts_start + duration); + if (raw != 2) + av_bprintf(buf, "Default,"); } dlen = strcspn(dialog, "\n"); dlen += dialog[dlen] == '\n'; + av_bprintf(buf, "%.*s", dlen, dialog); + if (raw == 2) + av_bprintf(buf, "\r\n"); + + return dlen; +} + +int ff_ass_add_rect(AVSubtitle *sub, const char *dialog, + int ts_start, int duration, int raw) +{ + AVBPrint buf; + int ret, dlen; + AVSubtitleRect **rects; + + av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED); + if ((ret = ff_ass_bprint_dialog(&buf, dialog, ts_start, duration, raw)) < 0) + goto err; + dlen = ret; + if (!av_bprint_is_complete(&buf)) + goto errnomem; + rects = av_realloc(sub->rects, (sub->num_rects+1) * sizeof(*sub->rects)); if (!rects) - return AVERROR(ENOMEM); + goto errnomem; sub->rects = rects; sub->end_display_time = FFMAX(sub->end_display_time, 10 * duration); rects[sub->num_rects] = av_mallocz(sizeof(*rects[0])); rects[sub->num_rects]->type = SUBTITLE_ASS; - rects[sub->num_rects]->ass = av_malloc(len + dlen + 1); - strcpy (rects[sub->num_rects]->ass , header); - av_strlcpy(rects[sub->num_rects]->ass + len, dialog, dlen + 1); + ret = av_bprint_finalize(&buf, &rects[sub->num_rects]->ass); + if (ret < 0) + goto err; sub->num_rects++; return dlen; + +errnomem: + ret = AVERROR(ENOMEM); +err: + av_bprint_finalize(&buf, NULL); + return ret; +} + +void ff_ass_bprint_text_event(AVBPrint *buf, const char *p, int size, + const char *linebreaks, int keep_ass_markup) +{ + const char *p_end = p + size; + + for (; p < p_end && *p; p++) { + + /* forced custom line breaks, not accounted as "normal" EOL */ + if (linebreaks && strchr(linebreaks, *p)) { + av_bprintf(buf, "\\N"); + + /* standard ASS escaping so random characters don't get mis-interpreted + * as ASS */ + } else if (!keep_ass_markup && strchr("{}\\", *p)) { + av_bprintf(buf, "\\%c", *p); + + /* some packets might end abruptly (no \0 at the end, like for example + * in some cases of demuxing from a classic video container), some + * might be terminated with \n or \r\n which we have to remove (for + * consistency with those who haven't), and we also have to deal with + * evil cases such as \r at the end of the buffer (and no \0 terminated + * character) */ + } else if (p[0] == '\n') { + /* some stuff left so we can insert a line break */ + if (p < p_end - 1) + av_bprintf(buf, "\\N"); + } else if (p[0] == '\r' && p < p_end - 1 && p[1] == '\n') { + /* \r followed by a \n, we can skip it. We don't insert the \N yet + * because we don't know if it is followed by more text */ + continue; + + /* finally, a sane character */ + } else { + av_bprint_chars(buf, *p, 1); + } + } + av_bprintf(buf, "\r\n"); } diff --git a/ffmpeg/libavcodec/ass.h b/ffmpeg/libavcodec/ass.h index e9339e4..2df38e6 100644 --- a/ffmpeg/libavcodec/ass.h +++ b/ffmpeg/libavcodec/ass.h @@ -23,6 +23,7 @@ #define AVCODEC_ASS_H #include "avcodec.h" +#include "libavutil/bprint.h" /** * @name Default values for ASS style @@ -76,7 +77,9 @@ int ff_ass_subtitle_header_default(AVCodecContext *avctx); * @param ts_start start timestamp for this dialog (in 1/100 second unit) * @param duration duration for this dialog (in 1/100 second unit), can be -1 * to last until the end of the presentation - * @param raw when set to 1, it indicates that dialog contains a whole ASS + * @param raw when set to 2, it indicates that dialog contains an ASS + * dialog line as muxed in Matroska + * when set to 1, it indicates that dialog contains a whole SSA * dialog line which should be copied as is. * when set to 0, it indicates that dialog contains only the Text * part of the ASS dialog line, the rest of the line @@ -88,4 +91,38 @@ int ff_ass_subtitle_header_default(AVCodecContext *avctx); int ff_ass_add_rect(AVSubtitle *sub, const char *dialog, int ts_start, int duration, int raw); +/** + * Add an ASS dialog line to an AVBPrint buffer. + * + * @param buf pointer to an initialized AVBPrint buffer + * @param dialog ASS dialog to add to sub + * @param ts_start start timestamp for this dialog (in 1/100 second unit) + * @param duration duration for this dialog (in 1/100 second unit), can be -1 + * to last until the end of the presentation + * @param raw when set to 2, it indicates that dialog contains an ASS + * dialog line as muxed in Matroska + * when set to 1, it indicates that dialog contains a whole SSA + * dialog line which should be copied as is. + * when set to 0, it indicates that dialog contains only the Text + * part of the ASS dialog line, the rest of the line + * will be generated. + * @return number of characters read from dialog. It can be less than the whole + * length of dialog, if dialog contains several lines of text. + * A negative value indicates an error. + */ +int ff_ass_bprint_dialog(AVBPrint *buf, const char *dialog, + int ts_start, int duration, int raw); + +/** + * Escape a text subtitle using ASS syntax into an AVBPrint buffer. + * Newline characters will be escaped to \N. + * + * @param buf pointer to an initialized AVBPrint buffer + * @param p source text + * @param size size of the source text + * @param linebreaks additional newline chars, which will be escaped to \N + * @param keep_ass_markup braces and backslash will not be escaped if set + */ +void ff_ass_bprint_text_event(AVBPrint *buf, const char *p, int size, + const char *linebreaks, int keep_ass_markup); #endif /* AVCODEC_ASS_H */ diff --git a/ffmpeg/libavcodec/ass_split.h b/ffmpeg/libavcodec/ass_split.h index 7a6a75e..06c1ce3 100644 --- a/ffmpeg/libavcodec/ass_split.h +++ b/ffmpeg/libavcodec/ass_split.h @@ -124,7 +124,7 @@ typedef struct { void (*text)(void *priv, const char *text, int len); void (*new_line)(void *priv, int forced); void (*style)(void *priv, char style, int close); - void (*color)(void *priv, unsigned int color, unsigned int color_id); + void (*color)(void *priv, unsigned int /* color */, unsigned int color_id); void (*alpha)(void *priv, int alpha, int alpha_id); void (*font_name)(void *priv, const char *name); void (*font_size)(void *priv, int size); diff --git a/ffmpeg/libavcodec/assdec.c b/ffmpeg/libavcodec/assdec.c index d790656..11dbde0 100644 --- a/ffmpeg/libavcodec/assdec.c +++ b/ffmpeg/libavcodec/assdec.c @@ -41,7 +41,15 @@ static av_cold int ass_decode_init(AVCodecContext *avctx) return 0; } -static int ass_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, +static int ass_decode_close(AVCodecContext *avctx) +{ + ff_ass_split_free(avctx->priv_data); + avctx->priv_data = NULL; + return 0; +} + +#if CONFIG_SSA_DECODER +static int ssa_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, AVPacket *avpkt) { const char *ptr = avpkt->data; @@ -64,19 +72,49 @@ static int ass_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, return avpkt->size; } -static int ass_decode_close(AVCodecContext *avctx) +AVCodec ff_ssa_decoder = { + .name = "ssa", + .long_name = NULL_IF_CONFIG_SMALL("SSA (SubStation Alpha) subtitle"), + .type = AVMEDIA_TYPE_SUBTITLE, + .id = AV_CODEC_ID_SSA, + .init = ass_decode_init, + .decode = ssa_decode_frame, + .close = ass_decode_close, +}; +#endif + +#if CONFIG_ASS_DECODER +static int ass_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, + AVPacket *avpkt) { - ff_ass_split_free(avctx->priv_data); - avctx->priv_data = NULL; - return 0; + int ret; + AVSubtitle *sub = data; + const char *ptr = avpkt->data; + static const AVRational ass_tb = {1, 100}; + const int ts_start = av_rescale_q(avpkt->pts, avctx->time_base, ass_tb); + const int ts_duration = av_rescale_q(avpkt->duration, avctx->time_base, ass_tb); + + if (avpkt->size <= 0) + return avpkt->size; + + ret = ff_ass_add_rect(sub, ptr, ts_start, ts_duration, 2); + if (ret < 0) { + if (ret == AVERROR_INVALIDDATA) + av_log(avctx, AV_LOG_ERROR, "Invalid ASS packet\n"); + return ret; + } + + *got_sub_ptr = avpkt->size > 0; + return avpkt->size; } AVCodec ff_ass_decoder = { .name = "ass", - .long_name = NULL_IF_CONFIG_SMALL("SSA (SubStation Alpha) subtitle"), + .long_name = NULL_IF_CONFIG_SMALL("ASS (Advanced SubStation Alpha) subtitle"), .type = AVMEDIA_TYPE_SUBTITLE, - .id = AV_CODEC_ID_SSA, + .id = AV_CODEC_ID_ASS, .init = ass_decode_init, .decode = ass_decode_frame, .close = ass_decode_close, }; +#endif diff --git a/ffmpeg/libavcodec/assenc.c b/ffmpeg/libavcodec/assenc.c index 50b89c0..5dc3b09 100644 --- a/ffmpeg/libavcodec/assenc.c +++ b/ffmpeg/libavcodec/assenc.c @@ -22,10 +22,16 @@ #include #include "avcodec.h" +#include "ass_split.h" +#include "ass.h" #include "libavutil/avstring.h" #include "libavutil/internal.h" #include "libavutil/mem.h" +typedef struct { + int id; ///< current event id, ReadOrder field +} ASSEncodeContext; + static av_cold int ass_encode_init(AVCodecContext *avctx) { avctx->extradata = av_malloc(avctx->subtitle_header_size + 1); @@ -41,15 +47,54 @@ static int ass_encode_frame(AVCodecContext *avctx, unsigned char *buf, int bufsize, const AVSubtitle *sub) { + ASSEncodeContext *s = avctx->priv_data; int i, len, total_len = 0; for (i=0; inum_rects; i++) { + char ass_line[2048]; + const char *ass = sub->rects[i]->ass; + if (sub->rects[i]->type != SUBTITLE_ASS) { av_log(avctx, AV_LOG_ERROR, "Only SUBTITLE_ASS type supported.\n"); return -1; } - len = av_strlcpy(buf+total_len, sub->rects[i]->ass, bufsize-total_len); + if (strncmp(ass, "Dialogue: ", 10)) { + av_log(avctx, AV_LOG_ERROR, "AVSubtitle rectangle ass \"%s\"" + " does not look like a SSA markup\n", ass); + return AVERROR_INVALIDDATA; + } + + if (avctx->codec->id == AV_CODEC_ID_ASS) { + long int layer; + char *p; + + if (i > 0) { + av_log(avctx, AV_LOG_ERROR, "ASS encoder supports only one " + "ASS rectangle field.\n"); + return AVERROR_INVALIDDATA; + } + + ass += 10; // skip "Dialogue: " + /* parse Layer field. If it's a Marked field, the content + * will be "Marked=N" instead of the layer num, so we will + * have layer=0, which is fine. */ + layer = strtol(ass, &p, 10); + +#define SKIP_ENTRY(ptr) do { \ + char *sep = strchr(ptr, ','); \ + if (sep) \ + ptr = sep + 1; \ +} while (0) + + SKIP_ENTRY(p); // skip layer or marked + SKIP_ENTRY(p); // skip start timestamp + SKIP_ENTRY(p); // skip end timestamp + snprintf(ass_line, sizeof(ass_line), "%d,%ld,%s", ++s->id, layer, p); + ass_line[strcspn(ass_line, "\r\n")] = 0; + ass = ass_line; + } + len = av_strlcpy(buf+total_len, ass, bufsize-total_len); if (len > bufsize-total_len-1) { av_log(avctx, AV_LOG_ERROR, "Buffer too small for ASS event.\n"); @@ -62,11 +107,26 @@ static int ass_encode_frame(AVCodecContext *avctx, return total_len; } -AVCodec ff_ass_encoder = { - .name = "ass", +#if CONFIG_SSA_ENCODER +AVCodec ff_ssa_encoder = { + .name = "ssa", .long_name = NULL_IF_CONFIG_SMALL("SSA (SubStation Alpha) subtitle"), .type = AVMEDIA_TYPE_SUBTITLE, .id = AV_CODEC_ID_SSA, .init = ass_encode_init, .encode_sub = ass_encode_frame, + .priv_data_size = sizeof(ASSEncodeContext), +}; +#endif + +#if CONFIG_ASS_ENCODER +AVCodec ff_ass_encoder = { + .name = "ass", + .long_name = NULL_IF_CONFIG_SMALL("ASS (Advanced SubStation Alpha) subtitle"), + .type = AVMEDIA_TYPE_SUBTITLE, + .id = AV_CODEC_ID_ASS, + .init = ass_encode_init, + .encode_sub = ass_encode_frame, + .priv_data_size = sizeof(ASSEncodeContext), }; +#endif diff --git a/ffmpeg/libavcodec/asv.c b/ffmpeg/libavcodec/asv.c index 21f179b..58d2a89 100644 --- a/ffmpeg/libavcodec/asv.c +++ b/ffmpeg/libavcodec/asv.c @@ -89,6 +89,5 @@ av_cold void ff_asv_common_init(AVCodecContext *avctx) { a->mb_width2 = (avctx->width + 0) / 16; a->mb_height2 = (avctx->height + 0) / 16; - avctx->coded_frame= &a->picture; a->avctx= avctx; } diff --git a/ffmpeg/libavcodec/asv.h b/ffmpeg/libavcodec/asv.h index ca67c67..ce3c73a 100644 --- a/ffmpeg/libavcodec/asv.h +++ b/ffmpeg/libavcodec/asv.h @@ -38,7 +38,6 @@ typedef struct ASV1Context{ AVCodecContext *avctx; DSPContext dsp; - AVFrame picture; PutBitContext pb; GetBitContext gb; ScanTable scantable; diff --git a/ffmpeg/libavcodec/asvdec.c b/ffmpeg/libavcodec/asvdec.c index 7dca22b..038b461 100644 --- a/ffmpeg/libavcodec/asvdec.c +++ b/ffmpeg/libavcodec/asvdec.c @@ -28,7 +28,6 @@ #include "asv.h" #include "avcodec.h" -#include "put_bits.h" #include "internal.h" #include "mathops.h" #include "mpeg12data.h" @@ -272,6 +271,10 @@ static av_cold int decode_init(AVCodecContext *avctx) const int scale = avctx->codec_id == AV_CODEC_ID_ASV1 ? 1 : 2; int i; + if (avctx->extradata_size < 1) { + av_log(avctx, AV_LOG_WARNING, "No extradata provided\n"); + } + ff_asv_common_init(avctx); init_vlcs(a); ff_init_scantable(a->dsp.idct_permutation, &a->scantable, ff_asv_scantab); @@ -307,6 +310,7 @@ static av_cold int decode_end(AVCodecContext *avctx) #if CONFIG_ASV1_DECODER AVCodec ff_asv1_decoder = { .name = "asv1", + .long_name = NULL_IF_CONFIG_SMALL("ASUS V1"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_ASV1, .priv_data_size = sizeof(ASV1Context), @@ -314,13 +318,13 @@ AVCodec ff_asv1_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("ASUS V1"), }; #endif #if CONFIG_ASV2_DECODER AVCodec ff_asv2_decoder = { .name = "asv2", + .long_name = NULL_IF_CONFIG_SMALL("ASUS V2"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_ASV2, .priv_data_size = sizeof(ASV1Context), @@ -328,7 +332,6 @@ AVCodec ff_asv2_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("ASUS V2"), }; #endif diff --git a/ffmpeg/libavcodec/asvenc.c b/ffmpeg/libavcodec/asvenc.c index a09aa73..dd3d4f5 100644 --- a/ffmpeg/libavcodec/asvenc.c +++ b/ffmpeg/libavcodec/asvenc.c @@ -148,14 +148,16 @@ static inline int encode_mb(ASV1Context *a, int16_t block[6][64]){ return 0; } -static inline void dct_get(ASV1Context *a, int mb_x, int mb_y){ +static inline void dct_get(ASV1Context *a, const AVFrame *frame, + int mb_x, int mb_y) +{ int16_t (*block)[64]= a->block; - int linesize= a->picture.linesize[0]; + int linesize = frame->linesize[0]; int i; - uint8_t *ptr_y = a->picture.data[0] + (mb_y * 16* linesize ) + mb_x * 16; - uint8_t *ptr_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8; - uint8_t *ptr_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8; + uint8_t *ptr_y = frame->data[0] + (mb_y * 16* linesize ) + mb_x * 16; + uint8_t *ptr_cb = frame->data[1] + (mb_y * 8 * frame->linesize[1]) + mb_x * 8; + uint8_t *ptr_cr = frame->data[2] + (mb_y * 8 * frame->linesize[2]) + mb_x * 8; a->dsp.get_pixels(block[0], ptr_y , linesize); a->dsp.get_pixels(block[1], ptr_y + 8, linesize); @@ -165,8 +167,8 @@ static inline void dct_get(ASV1Context *a, int mb_x, int mb_y){ a->dsp.fdct(block[i]); if(!(a->avctx->flags&CODEC_FLAG_GRAY)){ - a->dsp.get_pixels(block[4], ptr_cb, a->picture.linesize[1]); - a->dsp.get_pixels(block[5], ptr_cr, a->picture.linesize[2]); + a->dsp.get_pixels(block[4], ptr_cb, frame->linesize[1]); + a->dsp.get_pixels(block[5], ptr_cr, frame->linesize[2]); for(i=4; i<6; i++) a->dsp.fdct(block[i]); } @@ -176,7 +178,6 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { ASV1Context * const a = avctx->priv_data; - AVFrame * const p= &a->picture; int size, ret; int mb_x, mb_y; @@ -186,13 +187,9 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, init_put_bits(&a->pb, pkt->data, pkt->size); - *p = *pict; - p->pict_type= AV_PICTURE_TYPE_I; - p->key_frame= 1; - for(mb_y=0; mb_ymb_height2; mb_y++){ for(mb_x=0; mb_xmb_width2; mb_x++){ - dct_get(a, mb_x, mb_y); + dct_get(a, pict, mb_x, mb_y); encode_mb(a, a->block); } } @@ -200,7 +197,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, if(a->mb_width2 != a->mb_width){ mb_x= a->mb_width2; for(mb_y=0; mb_ymb_height2; mb_y++){ - dct_get(a, mb_x, mb_y); + dct_get(a, pict, mb_x, mb_y); encode_mb(a, a->block); } } @@ -208,7 +205,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, if(a->mb_height2 != a->mb_height){ mb_y= a->mb_height2; for(mb_x=0; mb_xmb_width; mb_x++){ - dct_get(a, mb_x, mb_y); + dct_get(a, pict, mb_x, mb_y); encode_mb(a, a->block); } } @@ -262,6 +259,7 @@ static av_cold int encode_init(AVCodecContext *avctx){ #if CONFIG_ASV1_ENCODER AVCodec ff_asv1_encoder = { .name = "asv1", + .long_name = NULL_IF_CONFIG_SMALL("ASUS V1"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_ASV1, .priv_data_size = sizeof(ASV1Context), @@ -269,13 +267,13 @@ AVCodec ff_asv1_encoder = { .encode2 = encode_frame, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("ASUS V1"), }; #endif #if CONFIG_ASV2_ENCODER AVCodec ff_asv2_encoder = { .name = "asv2", + .long_name = NULL_IF_CONFIG_SMALL("ASUS V2"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_ASV2, .priv_data_size = sizeof(ASV1Context), @@ -283,6 +281,5 @@ AVCodec ff_asv2_encoder = { .encode2 = encode_frame, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("ASUS V2"), }; #endif diff --git a/ffmpeg/libavcodec/atrac.c b/ffmpeg/libavcodec/atrac.c index ea342a0..12e8997 100644 --- a/ffmpeg/libavcodec/atrac.c +++ b/ffmpeg/libavcodec/atrac.c @@ -1,6 +1,7 @@ /* - * Atrac common functions - * Copyright (c) 2006-2008 Maxim Poliakovski + * common functions for the ATRAC family of decoders + * + * Copyright (c) 2006-2013 Maxim Poliakovski * Copyright (c) 2006-2008 Benjamin Larsson * * This file is part of FFmpeg. @@ -44,11 +45,7 @@ static const float qmf_48tap_half[24] = { -0.043596379, -0.099384367, 0.13207909, 0.46424159 }; -/** - * Generate common tables - */ - -void ff_atrac_generate_tables(void) +av_cold void ff_atrac_generate_tables(void) { int i; float s; @@ -66,20 +63,69 @@ void ff_atrac_generate_tables(void) } } +av_cold void ff_atrac_init_gain_compensation(AtracGCContext *gctx, int id2exp_offset, + int loc_scale) +{ + int i; -/** - * Quadrature mirror synthesis filter. - * - * @param inlo lower part of spectrum - * @param inhi higher part of spectrum - * @param nIn size of spectrum buffer - * @param pOut out buffer - * @param delayBuf delayBuf buffer - * @param temp temp buffer - */ + gctx->loc_scale = loc_scale; + gctx->loc_size = 1 << loc_scale; + gctx->id2exp_offset = id2exp_offset; + /* Generate gain level table. */ + for (i = 0; i < 16; i++) + gctx->gain_tab1[i] = powf(2.0, id2exp_offset - i); + + /* Generate gain interpolation table. */ + for (i = -15; i < 16; i++) + gctx->gain_tab2[i + 15] = powf(2.0, -1.0f / gctx->loc_size * i); +} + +void ff_atrac_gain_compensation(AtracGCContext *gctx, float *in, float *prev, + AtracGainInfo *gc_now, AtracGainInfo *gc_next, + int num_samples, float *out) +{ + float lev, gc_scale, gain_inc; + int i, pos, lastpos; + + gc_scale = gc_next->num_points ? gctx->gain_tab1[gc_next->lev_code[0]] + : 1.0f; + + if (!gc_now->num_points) { + for (pos = 0; pos < num_samples; pos++) + out[pos] = in[pos] * gc_scale + prev[pos]; + } else { + pos = 0; + + for (i = 0; i < gc_now->num_points; i++) { + lastpos = gc_now->loc_code[i] << gctx->loc_scale; + + lev = gctx->gain_tab1[gc_now->lev_code[i]]; + gain_inc = gctx->gain_tab2[(i + 1 < gc_now->num_points ? gc_now->lev_code[i + 1] + : gctx->id2exp_offset) - + gc_now->lev_code[i] + 15]; + + /* apply constant gain level and overlap */ + for (; pos < lastpos; pos++) + out[pos] = (in[pos] * gc_scale + prev[pos]) * lev; + + /* interpolate between two different gain levels */ + for (; pos < lastpos + gctx->loc_size; pos++) { + out[pos] = (in[pos] * gc_scale + prev[pos]) * lev; + lev *= gain_inc; + } + } + + for (; pos < num_samples; pos++) + out[pos] = in[pos] * gc_scale + prev[pos]; + } + + /* copy the overlapping part into the delay buffer */ + memcpy(prev, &in[num_samples], num_samples * sizeof(float)); +} -void ff_atrac_iqmf (float *inlo, float *inhi, unsigned int nIn, float *pOut, float *delayBuf, float *temp) +void ff_atrac_iqmf(float *inlo, float *inhi, unsigned int nIn, float *pOut, + float *delayBuf, float *temp) { int i, j; float *p1, *p3; diff --git a/ffmpeg/libavcodec/atrac.h b/ffmpeg/libavcodec/atrac.h index 8607b01..05208bb 100644 --- a/ffmpeg/libavcodec/atrac.h +++ b/ffmpeg/libavcodec/atrac.h @@ -1,6 +1,7 @@ /* - * Atrac common data - * Copyright (c) 2009 Maxim Poliakovski + * common functions for the ATRAC family of decoders + * + * Copyright (c) 2009-2013 Maxim Poliakovski * Copyright (c) 2009 Benjamin Larsson * * This file is part of FFmpeg. @@ -22,15 +23,75 @@ /** * @file - * Atrac common header + * ATRAC common header */ #ifndef AVCODEC_ATRAC_H #define AVCODEC_ATRAC_H +/** + * Gain control parameters for one subband. + */ +typedef struct AtracGainInfo { + int num_points; ///< number of gain control points + int lev_code[7]; ///< level at corresponding control point + int loc_code[7]; ///< location of gain control points +} AtracGainInfo; + +/** + * Gain compensation context structure. + */ +typedef struct AtracGCContext { + float gain_tab1[16]; ///< gain compensation level table + float gain_tab2[31]; ///< gain compensation interpolation table + int id2exp_offset; ///< offset for converting level index into level exponent + int loc_scale; ///< scale of location code = 2^loc_scale samples + int loc_size; ///< size of location code in samples +} AtracGCContext; + extern float ff_atrac_sf_table[64]; +/** + * Generate common tables. + */ void ff_atrac_generate_tables(void); -void ff_atrac_iqmf (float *inlo, float *inhi, unsigned int nIn, float *pOut, float *delayBuf, float *temp); + +/** + * Initialize gain compensation context. + * + * @param gctx pointer to gain compensation context to initialize + * @param id2exp_offset offset for converting level index into level exponent + * @param loc_scale location size factor + */ +void ff_atrac_init_gain_compensation(AtracGCContext *gctx, int id2exp_offset, + int loc_scale); + +/** + * Apply gain compensation and perform the MDCT overlapping part. + * + * @param gctx pointer to gain compensation context + * @param in input buffer + * @param prev previous buffer to perform overlap against + * @param gc_now gain control information for current frame + * @param gc_next gain control information for next frame + * @param num_samples number of samples to process + * @param out output data goes here + */ +void ff_atrac_gain_compensation(AtracGCContext *gctx, float *in, float *prev, + AtracGainInfo *gc_now, AtracGainInfo *gc_next, + int num_samples, float *out); + +/** + * Quadrature mirror synthesis filter. + * + * @param inlo lower part of spectrum + * @param inhi higher part of spectrum + * @param nIn size of spectrum buffer + * @param pOut out buffer + * @param delayBuf delayBuf buffer + * @param temp temp buffer + */ +void ff_atrac_iqmf(float *inlo, float *inhi, unsigned int nIn, float *pOut, + float *delayBuf, float *temp); #endif /* AVCODEC_ATRAC_H */ diff --git a/ffmpeg/libavcodec/atrac1.c b/ffmpeg/libavcodec/atrac1.c index 7c1d1eb..d059d75 100644 --- a/ffmpeg/libavcodec/atrac1.c +++ b/ffmpeg/libavcodec/atrac1.c @@ -1,5 +1,5 @@ /* - * Atrac 1 compatible decoder + * ATRAC1 compatible decoder * Copyright (c) 2009 Maxim Poliakovski * Copyright (c) 2009 Benjamin Larsson * @@ -22,7 +22,7 @@ /** * @file - * Atrac 1 compatible decoder. + * ATRAC1 compatible decoder. * This decoder handles raw ATRAC1 data and probably SDDS data. */ @@ -377,6 +377,7 @@ static av_cold int atrac1_decode_init(AVCodecContext *avctx) AVCodec ff_atrac1_decoder = { .name = "atrac1", + .long_name = NULL_IF_CONFIG_SMALL("ATRAC1 (Adaptive TRansform Acoustic Coding)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_ATRAC1, .priv_data_size = sizeof(AT1Ctx), @@ -384,7 +385,6 @@ AVCodec ff_atrac1_decoder = { .close = atrac1_decode_end, .decode = atrac1_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Atrac 1 (Adaptive TRansform Acoustic Coding)"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, }; diff --git a/ffmpeg/libavcodec/atrac1data.h b/ffmpeg/libavcodec/atrac1data.h index ebebe4b..08f8357 100644 --- a/ffmpeg/libavcodec/atrac1data.h +++ b/ffmpeg/libavcodec/atrac1data.h @@ -1,5 +1,5 @@ /* - * Atrac 1 compatible decoder data + * ATRAC 1 compatible decoder data * Copyright (c) 2009 Maxim Poliakovski * Copyright (c) 2009 Benjamin Larsson * @@ -22,7 +22,7 @@ /** * @file - * Atrac 1 compatible decoder data + * ATRAC1 compatible decoder data */ #ifndef AVCODEC_ATRAC1DATA_H diff --git a/ffmpeg/libavcodec/atrac3.c b/ffmpeg/libavcodec/atrac3.c index a9e98f8..fc3b2fd 100644 --- a/ffmpeg/libavcodec/atrac3.c +++ b/ffmpeg/libavcodec/atrac3.c @@ -1,5 +1,5 @@ /* - * Atrac 3 compatible decoder + * ATRAC3 compatible decoder * Copyright (c) 2006-2008 Maxim Poliakovski * Copyright (c) 2006-2008 Benjamin Larsson * @@ -22,10 +22,10 @@ /** * @file - * Atrac 3 compatible decoder. + * ATRAC3 compatible decoder. * This decoder handles Sony's ATRAC3 data. * - * Container formats used to store atrac 3 data: + * Container formats used to store ATRAC3 data: * RealMedia (.rm), RIFF WAV (.wav, .at3), Sony OpenMG (.oma, .aa3). * * To use this decoder, a calling application must supply the extradata @@ -36,6 +36,7 @@ #include #include +#include "libavutil/attributes.h" #include "libavutil/float_dsp.h" #include "libavutil/libm.h" #include "avcodec.h" @@ -54,14 +55,8 @@ #define SAMPLES_PER_FRAME 1024 #define MDCT_SIZE 512 -typedef struct GainInfo { - int num_gain_data; - int lev_code[8]; - int loc_code[8]; -} GainInfo; - typedef struct GainBlock { - GainInfo g_block[4]; + AtracGainInfo g_block[4]; } GainBlock; typedef struct TonalComponent { @@ -111,7 +106,8 @@ typedef struct ATRAC3Context { int scrambled_stream; //@} - FFTContext mdct_ctx; + AtracGCContext gainc_ctx; + FFTContext mdct_ctx; FmtConvertContext fmt_conv; AVFloatDSPContext fdsp; } ATRAC3Context; @@ -119,9 +115,6 @@ typedef struct ATRAC3Context { static DECLARE_ALIGNED(32, float, mdct_window)[MDCT_SIZE]; static VLC_TYPE atrac3_vlc_table[4096][2]; static VLC spectral_coeff_tab[7]; -static float gain_tab1[16]; -static float gain_tab2[31]; - /** * Regular 512 points IMDCT without overlapping, with the exception of the @@ -178,7 +171,7 @@ static int decode_bytes(const uint8_t *input, uint8_t *out, int bytes) return off; } -static av_cold void init_atrac3_window(void) +static av_cold void init_imdct_window(void) { int i, j; @@ -417,89 +410,31 @@ static int decode_tonal_components(GetBitContext *gb, static int decode_gain_control(GetBitContext *gb, GainBlock *block, int num_bands) { - int i, cf, num_data; + int b, j; int *level, *loc; - GainInfo *gain = block->g_block; + AtracGainInfo *gain = block->g_block; - for (i = 0; i <= num_bands; i++) { - num_data = get_bits(gb, 3); - gain[i].num_gain_data = num_data; - level = gain[i].lev_code; - loc = gain[i].loc_code; + for (b = 0; b <= num_bands; b++) { + gain[b].num_points = get_bits(gb, 3); + level = gain[b].lev_code; + loc = gain[b].loc_code; - for (cf = 0; cf < gain[i].num_gain_data; cf++) { - level[cf] = get_bits(gb, 4); - loc [cf] = get_bits(gb, 5); - if (cf && loc[cf] <= loc[cf - 1]) + for (j = 0; j < gain[b].num_points; j++) { + level[j] = get_bits(gb, 4); + loc[j] = get_bits(gb, 5); + if (j && loc[j] <= loc[j - 1]) return AVERROR_INVALIDDATA; } } /* Clear the unused blocks. */ - for (; i < 4 ; i++) - gain[i].num_gain_data = 0; + for (; b < 4 ; b++) + gain[b].num_points = 0; return 0; } -/** - * Apply gain parameters and perform the MDCT overlapping part - * - * @param input input buffer - * @param prev previous buffer to perform overlap against - * @param output output buffer - * @param gain1 current band gain info - * @param gain2 next band gain info - */ -static void gain_compensate_and_overlap(float *input, float *prev, - float *output, GainInfo *gain1, - GainInfo *gain2) -{ - float g1, g2, gain_inc; - int i, j, num_data, start_loc, end_loc; - - - if (gain2->num_gain_data == 0) - g1 = 1.0; - else - g1 = gain_tab1[gain2->lev_code[0]]; - - if (gain1->num_gain_data == 0) { - for (i = 0; i < 256; i++) - output[i] = input[i] * g1 + prev[i]; - } else { - num_data = gain1->num_gain_data; - gain1->loc_code[num_data] = 32; - gain1->lev_code[num_data] = 4; - - for (i = 0, j = 0; i < num_data; i++) { - start_loc = gain1->loc_code[i] * 8; - end_loc = start_loc + 8; - - g2 = gain_tab1[gain1->lev_code[i]]; - gain_inc = gain_tab2[gain1->lev_code[i + 1] - - gain1->lev_code[i ] + 15]; - - /* interpolate */ - for (; j < start_loc; j++) - output[j] = (input[j] * g1 + prev[j]) * g2; - - /* interpolation is done over eight samples */ - for (; j < end_loc; j++) { - output[j] = (input[j] * g1 + prev[j]) * g2; - g2 *= gain_inc; - } - } - - for (; j < 256; j++) - output[j] = input[j] * g1 + prev[j]; - } - - /* Delay for the overlapping part. */ - memcpy(prev, &input[256], 256 * sizeof(*prev)); -} - /** * Combine the tonal band spectrum and regular band spectrum * @@ -664,8 +599,8 @@ static int decode_channel_sound_unit(ATRAC3Context *q, GetBitContext *gb, snd->num_components = decode_tonal_components(gb, snd->components, snd->bands_coded); - if (snd->num_components == -1) - return -1; + if (snd->num_components < 0) + return snd->num_components; num_subbands = decode_spectrum(gb, snd->spectrum); @@ -690,11 +625,10 @@ static int decode_channel_sound_unit(ATRAC3Context *q, GetBitContext *gb, memset(snd->imdct_buf, 0, 512 * sizeof(*snd->imdct_buf)); /* gain compensation and overlapping */ - gain_compensate_and_overlap(snd->imdct_buf, - &snd->prev_frame[band * 256], - &output[band * 256], - &gain1->g_block[band], - &gain2->g_block[band]); + ff_atrac_gain_compensation(&q->gainc_ctx, snd->imdct_buf, + &snd->prev_frame[band * 256], + &gain1->g_block[band], &gain2->g_block[band], + 256, &output[band * 256]); } /* Swap the gain control buffers for the next frame. */ @@ -838,11 +772,11 @@ static int atrac3_decode_frame(AVCodecContext *avctx, void *data, return avctx->block_align; } -static void atrac3_init_static_data(void) +static av_cold void atrac3_init_static_data(void) { int i; - init_atrac3_window(); + init_imdct_window(); ff_atrac_generate_tables(); /* Initialize the VLC tables. */ @@ -854,13 +788,6 @@ static void atrac3_init_static_data(void) huff_bits[i], 1, 1, huff_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); } - - /* Generate gain tables */ - for (i = 0; i < 16; i++) - gain_tab1[i] = exp2f (4 - i); - - for (i = -15; i < 16; i++) - gain_tab2[i + 15] = exp2f (i * -0.125); } static av_cold int atrac3_decode_init(AVCodecContext *avctx) @@ -922,11 +849,6 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) return AVERROR(EINVAL); } - if (q->coding_mode == JOINT_STEREO && avctx->channels < 2) { - av_log(avctx, AV_LOG_ERROR, "Invalid coding mode\n"); - return AVERROR_INVALIDDATA; - } - /* Check the extradata */ if (version != 4) { @@ -949,9 +871,13 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) if (q->coding_mode == STEREO) av_log(avctx, AV_LOG_DEBUG, "Normal stereo detected.\n"); - else if (q->coding_mode == JOINT_STEREO) + else if (q->coding_mode == JOINT_STEREO) { + if (avctx->channels != 2) { + av_log(avctx, AV_LOG_ERROR, "Invalid coding mode\n"); + return AVERROR_INVALIDDATA; + } av_log(avctx, AV_LOG_DEBUG, "Joint stereo detected.\n"); - else { + } else { av_log(avctx, AV_LOG_ERROR, "Unknown channel coding mode %x!\n", q->coding_mode); return AVERROR_INVALIDDATA; @@ -988,6 +914,7 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) q->matrix_coeff_index_next[i] = 3; } + ff_atrac_init_gain_compensation(&q->gainc_ctx, 4, 3); avpriv_float_dsp_init(&q->fdsp, avctx->flags & CODEC_FLAG_BITEXACT); ff_fmt_convert_init(&q->fmt_conv, avctx); @@ -1002,6 +929,7 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) AVCodec ff_atrac3_decoder = { .name = "atrac3", + .long_name = NULL_IF_CONFIG_SMALL("ATRAC3 (Adaptive TRansform Acoustic Coding 3)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_ATRAC3, .priv_data_size = sizeof(ATRAC3Context), @@ -1009,7 +937,6 @@ AVCodec ff_atrac3_decoder = { .close = atrac3_decode_close, .decode = atrac3_decode_frame, .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Atrac 3 (Adaptive TRansform Acoustic Coding 3)"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, }; diff --git a/ffmpeg/libavcodec/atrac3data.h b/ffmpeg/libavcodec/atrac3data.h index 9963d4e..5d91274 100644 --- a/ffmpeg/libavcodec/atrac3data.h +++ b/ffmpeg/libavcodec/atrac3data.h @@ -1,5 +1,5 @@ /* - * Atrac 3 compatible decoder data + * ATRAC3 compatible decoder data * Copyright (c) 2006-2007 Maxim Poliakovski * Copyright (c) 2006-2007 Benjamin Larsson * @@ -22,7 +22,7 @@ /** * @file - * Atrac 3 AKA RealAudio 8 compatible decoder data + * ATRAC3 AKA RealAudio 8 compatible decoder data */ #ifndef AVCODEC_ATRAC3DATA_H diff --git a/ffmpeg/libavcodec/audio_frame_queue.c b/ffmpeg/libavcodec/audio_frame_queue.c index ba6e225..1220345 100644 --- a/ffmpeg/libavcodec/audio_frame_queue.c +++ b/ffmpeg/libavcodec/audio_frame_queue.c @@ -19,12 +19,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/attributes.h" #include "libavutil/common.h" #include "audio_frame_queue.h" #include "internal.h" #include "libavutil/avassert.h" -void ff_af_queue_init(AVCodecContext *avctx, AudioFrameQueue *afq) +av_cold void ff_af_queue_init(AVCodecContext *avctx, AudioFrameQueue *afq) { afq->avctx = avctx; afq->remaining_delay = avctx->delay; diff --git a/ffmpeg/libavcodec/audio_frame_queue.h b/ffmpeg/libavcodec/audio_frame_queue.h index 7e98afe..2e317bb 100644 --- a/ffmpeg/libavcodec/audio_frame_queue.h +++ b/ffmpeg/libavcodec/audio_frame_queue.h @@ -2,20 +2,20 @@ * Audio Frame Queue * Copyright (c) 2012 Justin Ruggles * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/audioconvert.c b/ffmpeg/libavcodec/audioconvert.c index 5d8a348..5e46fae 100644 --- a/ffmpeg/libavcodec/audioconvert.c +++ b/ffmpeg/libavcodec/audioconvert.c @@ -32,6 +32,8 @@ #include "avcodec.h" #include "audioconvert.h" +#if FF_API_AUDIO_CONVERT + struct AVAudioConvert { int in_channels, out_channels; int fmt_pair; @@ -114,3 +116,5 @@ if(ctx->fmt_pair == ofmt + AV_SAMPLE_FMT_NB*ifmt){\ } return 0; } + +#endif /* FF_API_AUDIO_CONVERT */ diff --git a/ffmpeg/libavcodec/audioconvert.h b/ffmpeg/libavcodec/audioconvert.h index 61124b3..556ab31 100644 --- a/ffmpeg/libavcodec/audioconvert.h +++ b/ffmpeg/libavcodec/audioconvert.h @@ -26,8 +26,11 @@ /** * @file * Audio format conversion routines + * This interface is deprecated and will be dropped in a future + * version. You should use the libswresample library instead. */ +#if FF_API_AUDIO_CONVERT #include "libavutil/cpu.h" #include "avcodec.h" @@ -45,14 +48,20 @@ typedef struct AVAudioConvert AVAudioConvert; * @param[in] matrix Channel mixing matrix (of dimension in_channel*out_channels). Set to NULL to ignore. * @param flags See AV_CPU_FLAG_xx * @return NULL on error + * @deprecated See libswresample */ + +attribute_deprecated AVAudioConvert *av_audio_convert_alloc(enum AVSampleFormat out_fmt, int out_channels, enum AVSampleFormat in_fmt, int in_channels, const float *matrix, int flags); /** * Free audio sample format converter context + * @deprecated See libswresample */ + +attribute_deprecated void av_audio_convert_free(AVAudioConvert *ctx); /** @@ -62,9 +71,14 @@ void av_audio_convert_free(AVAudioConvert *ctx); * @param[in] in array of input buffers for each channel * @param[in] in_stride distance between consecutive input samples (measured in bytes) * @param len length of audio frame size (measured in samples) + * @deprecated See libswresample */ + +attribute_deprecated int av_audio_convert(AVAudioConvert *ctx, void * const out[6], const int out_stride[6], const void * const in[6], const int in_stride[6], int len); +#endif /* FF_API_AUDIO_CONVERT */ + #endif /* AVCODEC_AUDIOCONVERT_H */ diff --git a/ffmpeg/libavcodec/aura.c b/ffmpeg/libavcodec/aura.c index 34d46ae..8d0f16a 100644 --- a/ffmpeg/libavcodec/aura.c +++ b/ffmpeg/libavcodec/aura.c @@ -99,10 +99,10 @@ static int aura_decode_frame(AVCodecContext *avctx, AVCodec ff_aura2_decoder = { .name = "aura2", + .long_name = NULL_IF_CONFIG_SMALL("Auravision Aura 2"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_AURA2, .init = aura_decode_init, .decode = aura_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Auravision Aura 2"), }; diff --git a/ffmpeg/libavcodec/avcodec.h b/ffmpeg/libavcodec/avcodec.h index c3bd534..c614829 100644 --- a/ffmpeg/libavcodec/avcodec.h +++ b/ffmpeg/libavcodec/avcodec.h @@ -23,11 +23,13 @@ /** * @file - * external API header + * @ingroup libavc + * Libavcodec external API header */ #include #include "libavutil/samplefmt.h" +#include "libavutil/attributes.h" #include "libavutil/avutil.h" #include "libavutil/buffer.h" #include "libavutil/cpu.h" @@ -38,7 +40,13 @@ #include "libavutil/pixfmt.h" #include "libavutil/rational.h" -#include "libavcodec/version.h" +#include "version.h" + +#if FF_API_FAST_MALLOC +// to provide fast_*alloc +#include "libavutil/mem.h" +#endif + /** * @defgroup libavc Encoding/Decoding Library * @{ @@ -102,7 +110,9 @@ enum AVCodecID { /* video codecs */ AV_CODEC_ID_MPEG1VIDEO, AV_CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding +#if FF_API_XVMC AV_CODEC_ID_MPEG2VIDEO_XVMC, +#endif /* FF_API_XVMC */ AV_CODEC_ID_H261, AV_CODEC_ID_H263, AV_CODEC_ID_RV10, @@ -269,6 +279,13 @@ enum AVCodecID { AV_CODEC_ID_CLLC, AV_CODEC_ID_MSS2, AV_CODEC_ID_VP9, + AV_CODEC_ID_AIC, + AV_CODEC_ID_ESCAPE130_DEPRECATED, + AV_CODEC_ID_G2M_DEPRECATED, + AV_CODEC_ID_WEBP_DEPRECATED, + AV_CODEC_ID_HNM4_VIDEO, + AV_CODEC_ID_HEVC_DEPRECATED, + AV_CODEC_ID_BRENDER_PIX= MKBETAG('B','P','I','X'), AV_CODEC_ID_Y41P = MKBETAG('Y','4','1','P'), AV_CODEC_ID_ESCAPE130 = MKBETAG('E','1','3','0'), @@ -292,6 +309,10 @@ enum AVCodecID { AV_CODEC_ID_MVC1 = MKBETAG('M','V','C','1'), AV_CODEC_ID_MVC2 = MKBETAG('M','V','C','2'), AV_CODEC_ID_SNOW = MKBETAG('S','N','O','W'), + AV_CODEC_ID_WEBP = MKBETAG('W','E','B','P'), + AV_CODEC_ID_SMVJPEG = MKBETAG('S','M','V','J'), + AV_CODEC_ID_HEVC = MKBETAG('H','2','6','5'), +#define AV_CODEC_ID_H265 AV_CODEC_ID_HEVC /* various PCM "codecs" */ AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs @@ -323,6 +344,8 @@ enum AVCodecID { AV_CODEC_ID_PCM_LXF, AV_CODEC_ID_S302M, AV_CODEC_ID_PCM_S8_PLANAR, + AV_CODEC_ID_PCM_S24LE_PLANAR_DEPRECATED, + AV_CODEC_ID_PCM_S32LE_PLANAR_DEPRECATED, AV_CODEC_ID_PCM_S24LE_PLANAR = MKBETAG(24,'P','S','P'), AV_CODEC_ID_PCM_S32LE_PLANAR = MKBETAG(32,'P','S','P'), AV_CODEC_ID_PCM_S16BE_PLANAR = MKBETAG('P','S','P',16), @@ -361,6 +384,9 @@ enum AVCodecID { AV_CODEC_ID_VIMA = MKBETAG('V','I','M','A'), AV_CODEC_ID_ADPCM_AFC = MKBETAG('A','F','C',' '), AV_CODEC_ID_ADPCM_IMA_OKI = MKBETAG('O','K','I',' '), + AV_CODEC_ID_ADPCM_DTK = MKBETAG('D','T','K',' '), + AV_CODEC_ID_ADPCM_IMA_RAD = MKBETAG('R','A','D',' '), + AV_CODEC_ID_ADPCM_G726LE = MKBETAG('6','2','7','G'), /* AMR */ AV_CODEC_ID_AMR_NB = 0x12000, @@ -409,7 +435,9 @@ enum AVCodecID { AV_CODEC_ID_MLP, AV_CODEC_ID_GSM_MS, /* as found in WAV */ AV_CODEC_ID_ATRAC3, +#if FF_API_VOXWARE AV_CODEC_ID_VOXWARE, +#endif AV_CODEC_ID_APE, AV_CODEC_ID_NELLYMOSER, AV_CODEC_ID_MUSEPACK8, @@ -441,6 +469,7 @@ enum AVCodecID { AV_CODEC_ID_OPUS_DEPRECATED, AV_CODEC_ID_COMFORT_NOISE, AV_CODEC_ID_TAK_DEPRECATED, + AV_CODEC_ID_METASOUND, AV_CODEC_ID_FFWAVESYNTH = MKBETAG('F','F','W','S'), AV_CODEC_ID_SONIC = MKBETAG('S','O','N','C'), AV_CODEC_ID_SONIC_LS = MKBETAG('S','O','N','L'), @@ -473,6 +502,7 @@ enum AVCodecID { AV_CODEC_ID_MPL2 = MKBETAG('M','P','L','2'), AV_CODEC_ID_VPLAYER = MKBETAG('V','P','l','r'), AV_CODEC_ID_PJS = MKBETAG('P','h','J','S'), + AV_CODEC_ID_ASS = MKBETAG('A','S','S',' '), ///< ASS as defined in Matroska /* other specific kind of codecs (generally used for attachments) */ AV_CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs. @@ -539,8 +569,14 @@ typedef struct AVCodecDescriptor { #define AV_CODEC_PROP_LOSSLESS (1 << 2) /** * Subtitle codec is bitmap based + * Decoded AVSubtitle data can be read from the AVSubtitleRect->pict field. */ #define AV_CODEC_PROP_BITMAP_SUB (1 << 16) +/** + * Subtitle codec is text based. + * Decoded AVSubtitle data can be read from the AVSubtitleRect->ass field. + */ +#define AV_CODEC_PROP_TEXT_SUB (1 << 17) /** * @ingroup lavc_decoding @@ -599,36 +635,26 @@ enum AVColorPrimaries{ AVCOL_PRI_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC AVCOL_PRI_SMPTE240M = 7, ///< functionally identical to above AVCOL_PRI_FILM = 8, + AVCOL_PRI_BT2020 = 9, ///< ITU-R BT2020 AVCOL_PRI_NB , ///< Not part of ABI }; enum AVColorTransferCharacteristic{ - AVCOL_TRC_BT709 = 1, ///< also ITU-R BT1361 - AVCOL_TRC_UNSPECIFIED = 2, - AVCOL_TRC_GAMMA22 = 4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM - AVCOL_TRC_GAMMA28 = 5, ///< also ITU-R BT470BG - AVCOL_TRC_SMPTE240M = 7, - AVCOL_TRC_NB , ///< Not part of ABI -}; - -enum AVColorSpace{ - AVCOL_SPC_RGB = 0, - AVCOL_SPC_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B - AVCOL_SPC_UNSPECIFIED = 2, - AVCOL_SPC_FCC = 4, - AVCOL_SPC_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 - AVCOL_SPC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above - AVCOL_SPC_SMPTE240M = 7, - AVCOL_SPC_YCOCG = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16 - AVCOL_SPC_NB , ///< Not part of ABI -}; -#define AVCOL_SPC_YCGCO AVCOL_SPC_YCOCG - -enum AVColorRange{ - AVCOL_RANGE_UNSPECIFIED = 0, - AVCOL_RANGE_MPEG = 1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges - AVCOL_RANGE_JPEG = 2, ///< the normal 2^n-1 "JPEG" YUV ranges - AVCOL_RANGE_NB , ///< Not part of ABI + AVCOL_TRC_BT709 = 1, ///< also ITU-R BT1361 + AVCOL_TRC_UNSPECIFIED = 2, + AVCOL_TRC_GAMMA22 = 4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM + AVCOL_TRC_GAMMA28 = 5, ///< also ITU-R BT470BG + AVCOL_TRC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 or 625 / ITU-R BT1358 525 or 625 / ITU-R BT1700 NTSC + AVCOL_TRC_SMPTE240M = 7, + AVCOL_TRC_LINEAR = 8, ///< "Linear transfer characteristics" + AVCOL_TRC_LOG = 9, ///< "Logarithmic transfer characteristic (100:1 range)" + AVCOL_TRC_LOG_SQRT = 10, ///< "Logarithmic transfer characteristic (100 * Sqrt( 10 ) : 1 range)" + AVCOL_TRC_IEC61966_2_4 = 11, ///< IEC 61966-2-4 + AVCOL_TRC_BT1361_ECG = 12, ///< ITU-R BT1361 Extended Colour Gamut + AVCOL_TRC_IEC61966_2_1 = 13, ///< IEC 61966-2-1 (sRGB or sYCC) + AVCOL_TRC_BT2020_10 = 14, ///< ITU-R BT2020 for 10 bit system + AVCOL_TRC_BT2020_12 = 15, ///< ITU-R BT2020 for 12 bit system + AVCOL_TRC_NB , ///< Not part of ABI }; /** @@ -670,15 +696,26 @@ typedef struct RcOverride{ float quality_factor; } RcOverride; +#if FF_API_MAX_BFRAMES +/** + * @deprecated there is no libavcodec-wide limit on the number of B-frames + */ #define FF_MAX_B_FRAMES 16 +#endif /* encoding support These flags can be passed in AVCodecContext.flags before initialization. Note: Not everything is supported yet. */ +/** + * Allow decoders to produce frames with data planes that are not aligned + * to CPU requirements (e.g. due to cropping). + */ +#define CODEC_FLAG_UNALIGNED 0x0001 #define CODEC_FLAG_QSCALE 0x0002 ///< Use fixed qscale. #define CODEC_FLAG_4MV 0x0004 ///< 4 MV per MB allowed / advanced prediction for H.263. +#define CODEC_FLAG_OUTPUT_CORRUPT 0x0008 ///< Output even those frames that might be corrupted #define CODEC_FLAG_QPEL 0x0010 ///< Use qpel MC. #define CODEC_FLAG_GMC 0x0020 ///< Use GMC. #define CODEC_FLAG_MV0 0x0040 ///< Always try a MB with MV=<0,0>. @@ -729,8 +766,16 @@ typedef struct RcOverride{ */ #define CODEC_CAP_DR1 0x0002 #define CODEC_CAP_TRUNCATED 0x0008 -/* Codec can export data for HW decoding (XvMC). */ +#if FF_API_XVMC +/* Codec can export data for HW decoding. This flag indicates that + * the codec would call get_format() with list that might contain HW accelerated + * pixel formats (XvMC, VDPAU, VAAPI, etc). The application can pick any of them + * including raw image format. + * The application can use the passed context to determine bitstream version, + * chroma format, resolution etc. + */ #define CODEC_CAP_HWACCEL 0x0010 +#endif /* FF_API_XVMC */ /** * Encoder or decoder requires flushing with NULL input at the end in order to * give the complete and correct output. @@ -760,10 +805,12 @@ typedef struct RcOverride{ * This can be used to prevent truncation of the last audio samples. */ #define CODEC_CAP_SMALL_LAST_FRAME 0x0040 +#if FF_API_CAP_VDPAU /** * Codec can export data for HW decoding (VDPAU). */ #define CODEC_CAP_HWACCEL_VDPAU 0x0080 +#endif /** * Codec can output multiple frames per AVPacket * Normally demuxers return one frame at a time, demuxers which do not do @@ -785,12 +832,12 @@ typedef struct RcOverride{ * Codec should fill in channel configuration and samplerate instead of container */ #define CODEC_CAP_CHANNEL_CONF 0x0400 - +#if FF_API_NEG_LINESIZES /** - * Codec is able to deal with negative linesizes + * @deprecated no codecs use this capability */ #define CODEC_CAP_NEG_LINESIZES 0x0800 - +#endif /** * Codec supports frame-level multithreading. */ @@ -820,6 +867,7 @@ typedef struct RcOverride{ */ #define CODEC_CAP_LOSSLESS 0x80000000 +#if FF_API_MB_TYPE //The following defines may change, don't expect compatibility if you use them. #define MB_TYPE_INTRA4x4 0x0001 #define MB_TYPE_INTRA16x16 0x0002 //FIXME H.264-specific @@ -843,6 +891,7 @@ typedef struct RcOverride{ #define MB_TYPE_QUANT 0x00010000 #define MB_TYPE_CBP 0x00020000 //Note bits 24-31 are reserved for codec specific use (h264 ref0, mpeg1 0mv, ...) +#endif /** * Pan Scan area. @@ -873,10 +922,12 @@ typedef struct AVPanScan{ int16_t position[3][2]; }AVPanScan; +#if FF_API_QSCALE_TYPE #define FF_QSCALE_TYPE_MPEG1 0 #define FF_QSCALE_TYPE_MPEG2 1 #define FF_QSCALE_TYPE_H264 2 #define FF_QSCALE_TYPE_VP56 3 +#endif #if FF_API_GET_BUFFER #define FF_BUFFER_TYPE_INTERNAL 1 @@ -988,6 +1039,24 @@ enum AVPacketSideDataType { * by data. */ AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, + + /** + * The optional first identifier line of a WebVTT cue. + */ + AV_PKT_DATA_WEBVTT_IDENTIFIER, + + /** + * The optional settings (rendering instructions) that immediately + * follow the timestamp specifier of a WebVTT cue. + */ + AV_PKT_DATA_WEBVTT_SETTINGS, + + /** + * A list of zero terminated key/value strings. There is no end marker for + * the list, so it is required to rely on the side data size to stop. This + * side data includes updated metadata which appeared in the stream. + */ + AV_PKT_DATA_METADATA_UPDATE, }; /** @@ -1221,7 +1290,7 @@ typedef struct AVCodecContext { * rv10: additional flags * mpeg4: global headers (they can be in the bitstream or here) * The allocated memory should be FF_INPUT_BUFFER_PADDING_SIZE bytes larger - * than extradata_size to avoid prolems if it is read with the bitstream reader. + * than extradata_size to avoid problems if it is read with the bitstream reader. * The bytewise contents of extradata must not depend on the architecture or CPU endianness. * - encoding: Set/allocated/freed by libavcodec. * - decoding: Set/allocated/freed by user. @@ -1281,20 +1350,26 @@ typedef struct AVCodecContext { /** * picture width / height. * - encoding: MUST be set by user. - * - decoding: Set by libavcodec. - * Note: For compatibility it is possible to set this instead of - * coded_width/height before decoding. + * - decoding: May be set by the user before opening the decoder if known e.g. + * from the container. Some decoders will require the dimensions + * to be set by the caller. During decoding, the decoder may + * overwrite those values as required. */ int width, height; /** - * Bitstream width / height, may be different from width/height if lowres enabled. + * Bitstream width / height, may be different from width/height e.g. when + * the decoded frame is cropped before being output or lowres is enabled. * - encoding: unused - * - decoding: Set by user before init if known. Codec should override / dynamically change if needed. + * - decoding: May be set by the user before opening the decoder if known + * e.g. from the container. During decoding, the decoder may + * overwrite those values as required. */ int coded_width, coded_height; +#if FF_API_ASPECT_EXTENDED #define FF_ASPECT_EXTENDED 15 +#endif /** * the number of pictures in a group of pictures, or 0 for intra_only @@ -1621,12 +1696,15 @@ typedef struct AVCodecContext { #define SLICE_FLAG_ALLOW_FIELD 0x0002 ///< allow draw_horiz_band() with field slices (MPEG2 field pics) #define SLICE_FLAG_ALLOW_PLANE 0x0004 ///< allow draw_horiz_band() with 1 component at a time (SVQ1) +#if FF_API_XVMC /** * XVideo Motion Acceleration * - encoding: forbidden * - decoding: set by decoder + * @deprecated XvMC doesn't need it anymore. */ - int xvmc_acceleration; + attribute_deprecated int xvmc_acceleration; +#endif /* FF_API_XVMC */ /** * macroblock decision mode @@ -1894,7 +1972,7 @@ typedef struct AVCodecContext { * - decoding: Set by user. * @deprecated Deprecated in favor of request_channel_layout. */ - int request_channels; + attribute_deprecated int request_channels; #endif /** @@ -2025,8 +2103,10 @@ typedef struct AVCodecContext { /** * This callback is called at the beginning of each frame to get data * buffer(s) for it. There may be one contiguous buffer for all the data or - * there may be a buffer per each data plane or anything in between. Each - * buffer must be reference-counted using the AVBuffer API. + * there may be a buffer per each data plane or anything in between. What + * this means is, you may set however many entries in buf[] you feel necessary. + * Each buffer must be reference-counted using the AVBuffer API (see description + * of buf[] below). * * The following fields will be set in the frame before this callback is * called: @@ -2047,8 +2127,11 @@ typedef struct AVCodecContext { * extended_data must be allocated with av_malloc() and will be freed in * av_frame_unref(). * * otherwise exended_data must point to data - * - buf[] must contain references to the buffers that contain the frame - * data. + * - buf[] must contain one or more pointers to AVBufferRef structures. Each of + * the frame's data and extended_data pointers must be contained in these. That + * is, one AVBufferRef for each allocated chunk of memory, not necessarily one + * AVBufferRef per data[] entry. See: av_buffer_create(), av_buffer_alloc(), + * and av_buffer_ref(). * - extended_buf and nb_extended_buf must be allocated with av_malloc() by * this callback and filled with the extra buffers if there are more * buffers than buf[] can hold. extended_buf will be freed in @@ -2356,12 +2439,16 @@ typedef struct AVCodecContext { */ int workaround_bugs; #define FF_BUG_AUTODETECT 1 ///< autodetection +#if FF_API_OLD_MSMPEG4 #define FF_BUG_OLD_MSMPEG4 2 +#endif #define FF_BUG_XVID_ILACE 4 #define FF_BUG_UMP4 8 #define FF_BUG_NO_PADDING 16 #define FF_BUG_AMV 32 +#if FF_API_AC_VLC #define FF_BUG_AC_VLC 0 ///< Will be removed, libavcodec can now handle these non-compliant files by default. +#endif #define FF_BUG_QPEL_CHROMA 64 #define FF_BUG_STD_QPEL 128 #define FF_BUG_QPEL_CHROMA2 256 @@ -2411,7 +2498,12 @@ typedef struct AVCodecContext { #define FF_DEBUG_BITSTREAM 4 #define FF_DEBUG_MB_TYPE 8 #define FF_DEBUG_QP 16 +#if FF_API_DEBUG_MV +/** + * @deprecated this option does nothing + */ #define FF_DEBUG_MV 32 +#endif #define FF_DEBUG_DCT_COEFF 0x00000040 #define FF_DEBUG_SKIP 0x00000080 #define FF_DEBUG_STARTCODE 0x00000100 @@ -2419,13 +2511,17 @@ typedef struct AVCodecContext { #define FF_DEBUG_ER 0x00000400 #define FF_DEBUG_MMCO 0x00000800 #define FF_DEBUG_BUGS 0x00001000 -#define FF_DEBUG_VIS_QP 0x00002000 -#define FF_DEBUG_VIS_MB_TYPE 0x00004000 +#if FF_API_DEBUG_MV +#define FF_DEBUG_VIS_QP 0x00002000 ///< only access through AVOptions from outside libavcodec +#define FF_DEBUG_VIS_MB_TYPE 0x00004000 ///< only access through AVOptions from outside libavcodec +#endif #define FF_DEBUG_BUFFERS 0x00008000 #define FF_DEBUG_THREADS 0x00010000 +#if FF_API_DEBUG_MV /** * debug + * Code outside libavcodec should access this field using AVOptions * - encoding: Set by user. * - decoding: Set by user. */ @@ -2433,6 +2529,7 @@ typedef struct AVCodecContext { #define FF_DEBUG_VIS_MV_P_FOR 0x00000001 //visualize forward predicted MVs of P frames #define FF_DEBUG_VIS_MV_B_FOR 0x00000002 //visualize forward predicted MVs of B frames #define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames +#endif /** * Error recognition; may misdetect some more or less valid parts as errors. @@ -2440,14 +2537,21 @@ typedef struct AVCodecContext { * - decoding: Set by user. */ int err_recognition; + +/** + * Verify checksums embedded in the bitstream (could be of either encoded or + * decoded data, depending on the codec) and print an error message on mismatch. + * If AV_EF_EXPLODE is also set, a mismatching checksum will result in the + * decoder returning an error. + */ #define AV_EF_CRCCHECK (1<<0) -#define AV_EF_BITSTREAM (1<<1) -#define AV_EF_BUFFER (1<<2) -#define AV_EF_EXPLODE (1<<3) +#define AV_EF_BITSTREAM (1<<1) ///< detect bitstream specification deviations +#define AV_EF_BUFFER (1<<2) ///< detect improper bitstream length +#define AV_EF_EXPLODE (1<<3) ///< abort decoding on minor error detection -#define AV_EF_CAREFUL (1<<16) -#define AV_EF_COMPLIANT (1<<17) -#define AV_EF_AGGRESSIVE (1<<18) +#define AV_EF_CAREFUL (1<<16) ///< consider things that violate the spec, are fast to calculate and have not been seen in the wild as errors +#define AV_EF_COMPLIANT (1<<17) ///< consider all spec non compliancies as errors +#define AV_EF_AGGRESSIVE (1<<18) ///< consider things that a sane encoder should not do as an error /** @@ -2519,7 +2623,9 @@ typedef struct AVCodecContext { #define FF_IDCT_SIMPLEVIS 18 #define FF_IDCT_FAAN 20 #define FF_IDCT_SIMPLENEON 22 +#if FF_API_ARCH_ALPHA #define FF_IDCT_SIMPLEALPHA 23 +#endif /** * bits per sample/pixel from the demuxer (needed for huffyuv). @@ -2535,17 +2641,21 @@ typedef struct AVCodecContext { */ int bits_per_raw_sample; +#if FF_API_LOWRES /** * low resolution decoding, 1-> 1/2 size, 2->1/4 size * - encoding: unused * - decoding: Set by user. + * Code outside libavcodec should access this field using: + * av_codec_{get,set}_lowres(avctx) */ int lowres; +#endif /** * the picture in the bitstream * - encoding: Set by libavcodec. - * - decoding: Set by libavcodec. + * - decoding: unused */ AVFrame *coded_frame; @@ -2617,13 +2727,13 @@ typedef struct AVCodecContext { */ int (*execute2)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count); +#if FF_API_THREAD_OPAQUE /** - * thread opaque - * Can be used by execute() to store some per AVCodecContext stuff. - * - encoding: set by execute() - * - decoding: set by execute() + * @deprecated this field should not be used from outside of lavc */ + attribute_deprecated void *thread_opaque; +#endif /** * noise vs. sse weight for the nsse comparsion function @@ -2649,6 +2759,8 @@ typedef struct AVCodecContext { #define FF_PROFILE_AAC_HE_V2 28 #define FF_PROFILE_AAC_LD 22 #define FF_PROFILE_AAC_ELD 38 +#define FF_PROFILE_MPEG2_AAC_LOW 128 +#define FF_PROFILE_MPEG2_AAC_HE 131 #define FF_PROFILE_DTS 20 #define FF_PROFILE_DTS_ES 30 @@ -2702,6 +2814,17 @@ typedef struct AVCodecContext { #define FF_PROFILE_MPEG4_SIMPLE_STUDIO 14 #define FF_PROFILE_MPEG4_ADVANCED_SIMPLE 15 +#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_0 0 +#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_1 1 +#define FF_PROFILE_JPEG2000_CSTREAM_NO_RESTRICTION 2 +#define FF_PROFILE_JPEG2000_DCINEMA_2K 3 +#define FF_PROFILE_JPEG2000_DCINEMA_4K 4 + + +#define FF_PROFILE_HEVC_MAIN 1 +#define FF_PROFILE_HEVC_MAIN_10 2 +#define FF_PROFILE_HEVC_MAIN_STILL_PICTURE 3 + /** * level * - encoding: Set by user. @@ -2742,21 +2865,22 @@ typedef struct AVCodecContext { uint8_t *subtitle_header; int subtitle_header_size; +#if FF_API_ERROR_RATE /** - * Simulates errors in the bitstream to test error concealment. - * - encoding: Set by user. - * - decoding: unused + * @deprecated use the 'error_rate' private AVOption of the mpegvideo + * encoders */ + attribute_deprecated int error_rate; +#endif +#if FF_API_CODEC_PKT /** - * Current packet as passed into the decoder, to avoid having - * to pass the packet into every function. Currently only valid - * inside lavc and get/release_buffer callbacks. - * - decoding: set by avcodec_decode_*, read by get_buffer() for setting pkt_pts - * - encoding: unused + * @deprecated this field is not supposed to be accessed from outside lavc */ + attribute_deprecated AVPacket *pkt; +#endif /** * VBV delay coded in the last frame (in periods of a 27 MHz clock). @@ -2771,7 +2895,7 @@ typedef struct AVCodecContext { * Code outside libavcodec should access this field using: * av_codec_{get,set}_pkt_timebase(avctx) * - encoding unused. - * - decodimg set by user + * - decoding set by user. */ AVRational pkt_timebase; @@ -2784,6 +2908,17 @@ typedef struct AVCodecContext { */ const AVCodecDescriptor *codec_descriptor; +#if !FF_API_LOWRES + /** + * low resolution decoding, 1-> 1/2 size, 2->1/4 size + * - encoding: unused + * - decoding: Set by user. + * Code outside libavcodec should access this field using: + * av_codec_{get,set}_lowres(avctx) + */ + int lowres; +#endif + /** * Current statistics for PTS correction. * - decoding: maintained and used by libavcodec, not intended to be used by user apps @@ -2811,6 +2946,41 @@ typedef struct AVCodecContext { #define FF_SUB_CHARENC_MODE_DO_NOTHING -1 ///< do nothing (demuxer outputs a stream supposed to be already in UTF-8, or the codec is bitmap for instance) #define FF_SUB_CHARENC_MODE_AUTOMATIC 0 ///< libavcodec will select the mode itself #define FF_SUB_CHARENC_MODE_PRE_DECODER 1 ///< the AVPacket data needs to be recoded to UTF-8 before being fed to the decoder, requires iconv + + /** + * Skip processing alpha if supported by codec. + * Note that if the format uses pre-multiplied alpha (common with VP6, + * and recommended due to better video quality/compression) + * the image will look as if alpha-blended onto a black background. + * However for formats that do not use pre-multiplied alpha + * there might be serious artefacts (though e.g. libswscale currently + * assumes pre-multiplied alpha anyway). + * Code outside libavcodec should access this field using AVOptions + * + * - decoding: set by user + * - encoding: unused + */ + int skip_alpha; + + /** + * Number of samples to skip after a discontinuity + * - decoding: unused + * - encoding: set by libavcodec + */ + int seek_preroll; + +#if !FF_API_DEBUG_MV + /** + * debug motion vectors + * Code outside libavcodec should access this field using AVOptions + * - encoding: Set by user. + * - decoding: Set by user. + */ + int debug_mv; +#define FF_DEBUG_VIS_MV_P_FOR 0x00000001 //visualize forward predicted MVs of P frames +#define FF_DEBUG_VIS_MV_B_FOR 0x00000002 //visualize forward predicted MVs of B frames +#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames +#endif } AVCodecContext; AVRational av_codec_get_pkt_timebase (const AVCodecContext *avctx); @@ -2819,6 +2989,12 @@ void av_codec_set_pkt_timebase (AVCodecContext *avctx, AVRational const AVCodecDescriptor *av_codec_get_codec_descriptor(const AVCodecContext *avctx); void av_codec_set_codec_descriptor(AVCodecContext *avctx, const AVCodecDescriptor *desc); +int av_codec_get_lowres(const AVCodecContext *avctx); +void av_codec_set_lowres(AVCodecContext *avctx, int val); + +int av_codec_get_seek_preroll(const AVCodecContext *avctx); +void av_codec_set_seek_preroll(AVCodecContext *avctx, int val); + /** * AVProfile. */ @@ -2859,7 +3035,9 @@ typedef struct AVCodec { const int *supported_samplerates; ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0 const enum AVSampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1 const uint64_t *channel_layouts; ///< array of support channel layouts, or NULL if unknown. array is terminated by 0 - uint8_t max_lowres; ///< maximum value for lowres supported by the decoder +#if FF_API_LOWRES + uint8_t max_lowres; ///< maximum value for lowres supported by the decoder, no direct access, use av_codec_get_max_lowres() +#endif const AVClass *priv_class; ///< AVClass for the private context const AVProfile *profiles; ///< array of recognized profiles, or NULL if unknown, array is terminated by {FF_PROFILE_UNKNOWN} @@ -2926,6 +3104,10 @@ typedef struct AVCodec { void (*flush)(AVCodecContext *); } AVCodec; +int av_codec_get_max_lowres(const AVCodec *codec); + +struct MpegEncContext; + /** * AVHWAccel. */ @@ -2987,6 +3169,7 @@ typedef struct AVHWAccel { * * Meaningful slice information (codec specific) is guaranteed to * be parsed at this point. This function is mandatory. + * The only exception is XvMC, that works on MB level. * * @param avctx the codec context * @param buf the slice data buffer base @@ -3014,6 +3197,17 @@ typedef struct AVHWAccel { * AVCodecContext.release_buffer(). */ int priv_data_size; + + /** + * Called for every Macroblock in a slice. + * + * XvMC uses it to replace the ff_MPV_decode_mb(). + * Instead of decoding to raw picture, MB parameters are + * stored in an array provided by the video driver. + * + * @param s the mpeg context + */ + void (*decode_mb)(struct MpegEncContext *s); } AVHWAccel; /** @@ -3024,11 +3218,13 @@ typedef struct AVHWAccel { */ /** - * four components are given, that's all. - * the last component is alpha + * Picture data structure. + * + * Up to four components can be stored into it, the last component is + * alpha. */ typedef struct AVPicture { - uint8_t *data[AV_NUM_DATA_POINTERS]; + uint8_t *data[AV_NUM_DATA_POINTERS]; ///< pointers to the image data planes int linesize[AV_NUM_DATA_POINTERS]; ///< number of bytes per line } AVPicture; @@ -3135,40 +3331,6 @@ void avcodec_register(AVCodec *codec); */ void avcodec_register_all(void); - -#if FF_API_ALLOC_CONTEXT -/** - * Allocate an AVCodecContext and set its fields to default values. The - * resulting struct can be deallocated by simply calling av_free(). - * - * @return An AVCodecContext filled with default values or NULL on failure. - * @see avcodec_get_context_defaults - * - * @deprecated use avcodec_alloc_context3() - */ -attribute_deprecated -AVCodecContext *avcodec_alloc_context(void); - -/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API! - * we WILL change its arguments and name a few times! */ -attribute_deprecated -AVCodecContext *avcodec_alloc_context2(enum AVMediaType); - -/** - * Set the fields of the given AVCodecContext to default values. - * - * @param s The AVCodecContext of which the fields should be set to default values. - * @deprecated use avcodec_get_context_defaults3 - */ -attribute_deprecated -void avcodec_get_context_defaults(AVCodecContext *s); - -/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API! - * we WILL change its arguments and name a few times! */ -attribute_deprecated -void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType); -#endif - /** * Allocate an AVCodecContext and set its fields to default values. The * resulting struct can be deallocated by calling avcodec_close() on it followed @@ -3228,26 +3390,27 @@ const AVClass *avcodec_get_subtitle_rect_class(void); * can use this AVCodecContext to decode/encode video/audio data. * * @param dest target codec context, should be initialized with - * avcodec_alloc_context3(), but otherwise uninitialized + * avcodec_alloc_context3(NULL), but otherwise uninitialized * @param src source codec context * @return AVERROR() on error (e.g. memory allocation error), 0 on success */ int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src); +#if FF_API_AVFRAME_LAVC /** - * Allocate an AVFrame and set its fields to default values. The resulting - * struct must be freed using avcodec_free_frame(). - * - * @return An AVFrame filled with default values or NULL on failure. - * @see avcodec_get_frame_defaults + * @deprecated use av_frame_alloc() */ +attribute_deprecated AVFrame *avcodec_alloc_frame(void); /** * Set the fields of the given AVFrame to default values. * * @param frame The AVFrame of which the fields should be set to default values. + * + * @deprecated use av_frame_unref() */ +attribute_deprecated void avcodec_get_frame_defaults(AVFrame *frame); /** @@ -3259,41 +3422,11 @@ void avcodec_get_frame_defaults(AVFrame *frame); * @warning this function does NOT free the data buffers themselves * (it does not know how, since they might have been allocated with * a custom get_buffer()). - */ -void avcodec_free_frame(AVFrame **frame); - -#if FF_API_AVCODEC_OPEN -/** - * Initialize the AVCodecContext to use the given AVCodec. Prior to using this - * function the context has to be allocated. * - * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(), - * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for - * retrieving a codec. - * - * @warning This function is not thread safe! - * - * @code - * avcodec_register_all(); - * codec = avcodec_find_decoder(AV_CODEC_ID_H264); - * if (!codec) - * exit(1); - * - * context = avcodec_alloc_context3(codec); - * - * if (avcodec_open(context, codec) < 0) - * exit(1); - * @endcode - * - * @param avctx The context which will be set up to use the given codec. - * @param codec The codec to use within the context. - * @return zero on success, a negative value on error - * @see avcodec_alloc_context3, avcodec_find_decoder, avcodec_find_encoder, avcodec_close - * - * @deprecated use avcodec_open2 + * @deprecated use av_frame_free() */ attribute_deprecated -int avcodec_open(AVCodecContext *avctx, AVCodec *codec); +void avcodec_free_frame(AVFrame **frame); #endif /** @@ -3434,6 +3567,13 @@ int av_dup_packet(AVPacket *pkt); */ int av_copy_packet(AVPacket *dst, AVPacket *src); +/** + * Copy packet side data + * + * @return 0 on success, negative AVERROR on fail + */ +int av_copy_packet_side_data(AVPacket *dst, AVPacket *src); + /** * Free a packet. * @@ -3478,6 +3618,84 @@ int av_packet_merge_side_data(AVPacket *pkt); int av_packet_split_side_data(AVPacket *pkt); +/** + * Pack a dictionary for use in side_data. + * + * @param dict The dictionary to pack. + * @param size pointer to store the size of the returned data + * @return pointer to data if successful, NULL otherwise + */ +uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size); +/** + * Unpack a dictionary from side_data. + * + * @param data data from side_data + * @param size size of the data + * @param dict the metadata storage dictionary + * @return 0 on success, < 0 on failure + */ +int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **dict); + + +/** + * Convenience function to free all the side data stored. + * All the other fields stay untouched. + * + * @param pkt packet + */ +void av_packet_free_side_data(AVPacket *pkt); + +/** + * Setup a new reference to the data described by a given packet + * + * If src is reference-counted, setup dst as a new reference to the + * buffer in src. Otherwise allocate a new buffer in dst and copy the + * data from src into it. + * + * All the other fields are copied from src. + * + * @see av_packet_unref + * + * @param dst Destination packet + * @param src Source packet + * + * @return 0 on success, a negative AVERROR on error. + */ +int av_packet_ref(AVPacket *dst, AVPacket *src); + +/** + * Wipe the packet. + * + * Unreference the buffer referenced by the packet and reset the + * remaining packet fields to their default values. + * + * @param pkt The packet to be unreferenced. + */ +void av_packet_unref(AVPacket *pkt); + +/** + * Move every field in src to dst and reset src. + * + * @see av_packet_unref + * + * @param src Source packet, will be reset + * @param dst Destination packet + */ +void av_packet_move_ref(AVPacket *dst, AVPacket *src); + +/** + * Copy only "properties" fields from src to dst. + * + * Properties for the purpose of this function are all the fields + * beside those related to the packet data (buf, data, size) + * + * @param dst Destination packet + * @param src Source packet + * + * @return 0 on success AVERROR on failure. + * + */ +int av_packet_copy_props(AVPacket *dst, const AVPacket *src); /** * @} @@ -3549,6 +3767,28 @@ void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height); void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, int linesize_align[AV_NUM_DATA_POINTERS]); +/** + * Converts AVChromaLocation to swscale x/y chroma position. + * + * The positions represent the chroma (0,0) position in a coordinates system + * with luma (0,0) representing the origin and luma(1,1) representing 256,256 + * + * @param xpos horizontal chroma sample position + * @param ypos vertical chroma sample position + */ +int avcodec_enum_to_chroma_pos(int *xpos, int *ypos, enum AVChromaLocation pos); + +/** + * Converts swscale x/y chroma position to AVChromaLocation. + * + * The positions represent the chroma (0,0) position in a coordinates system + * with luma (0,0) representing the origin and luma(1,1) representing 256,256 + * + * @param xpos horizontal chroma sample position + * @param ypos vertical chroma sample position + */ +enum AVChromaLocation avcodec_chroma_pos_to_enum(int xpos, int ypos); + #if FF_API_OLD_DECODE_AUDIO /** * Wrapper function which calls avcodec_decode_audio4. @@ -3613,19 +3853,25 @@ attribute_deprecated int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *s * Decode the audio frame of size avpkt->size from avpkt->data into frame. * * Some decoders may support multiple frames in a single AVPacket. Such - * decoders would then just decode the first frame. In this case, - * avcodec_decode_audio4 has to be called again with an AVPacket containing - * the remaining data in order to decode the second frame, etc... - * Even if no frames are returned, the packet needs to be fed to the decoder - * with remaining data until it is completely consumed or an error occurs. + * decoders would then just decode the first frame and the return value would be + * less than the packet size. In this case, avcodec_decode_audio4 has to be + * called again with an AVPacket containing the remaining data in order to + * decode the second frame, etc... Even if no frames are returned, the packet + * needs to be fed to the decoder with remaining data until it is completely + * consumed or an error occurs. + * + * Some decoders (those marked with CODEC_CAP_DELAY) have a delay between input + * and output. This means that for some packets they will not immediately + * produce decoded output and need to be flushed at the end of decoding to get + * all the decoded data. Flushing is done by calling this function with packets + * with avpkt->data set to NULL and avpkt->size set to 0 until it stops + * returning samples. It is safe to flush even those decoders that are not + * marked with CODEC_CAP_DELAY, then no samples will be returned. * * @warning The input buffer, avpkt->data must be FF_INPUT_BUFFER_PADDING_SIZE * larger than the actual read bytes because some optimized bitstream * readers read 32 or 64 bits at once and could read over the end. * - * @note You might have to align the input buffer. The alignment requirements - * depend on the CPU and the decoder. - * * @param avctx the codec context * @param[out] frame The AVFrame in which to store decoded audio samples. * The decoder will allocate a buffer for the decoded frame by @@ -3637,10 +3883,13 @@ attribute_deprecated int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *s * to the frame if av_frame_is_writable() returns 1. * When AVCodecContext.refcounted_frames is set to 0, the returned * reference belongs to the decoder and is valid only until the - * next call to this function or until closing the decoder. - * The caller may not write to it. + * next call to this function or until closing or flushing the + * decoder. The caller may not write to it. * @param[out] got_frame_ptr Zero if no frame could be decoded, otherwise it is - * non-zero. + * non-zero. Note that this field being set to zero + * does not mean that an error has occurred. For + * decoders with CODEC_CAP_DELAY set, no given decode + * call is guaranteed to produce a frame. * @param[in] avpkt The input AVPacket containing the input buffer. * At least avpkt->data and avpkt->size should be set. Some * decoders might also require additional fields to be set. @@ -3663,13 +3912,6 @@ int avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame, * @warning The end of the input buffer buf should be set to 0 to ensure that * no overreading happens for damaged MPEG streams. * - * @note You might have to align the input buffer avpkt->data. - * The alignment requirements depend on the CPU: on some CPUs it isn't - * necessary at all, on others it won't work at all if not aligned and on others - * it will work but it will have an impact on performance. - * - * In practice, avpkt->data should have 4 byte alignment at minimum. - * * @note Codecs which have the CODEC_CAP_DELAY capability set have a delay * between input and output, these need to be fed with avpkt->data=NULL, * avpkt->size=0 at the end to return the remaining frames. @@ -3686,10 +3928,10 @@ int avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame, * to the frame if av_frame_is_writable() returns 1. * When AVCodecContext.refcounted_frames is set to 0, the returned * reference belongs to the decoder and is valid only until the - * next call to this function or until closing the decoder. The - * caller may not write to it. + * next call to this function or until closing or flushing the + * decoder. The caller may not write to it. * - * @param[in] avpkt The input AVpacket containing the input buffer. + * @param[in] avpkt The input AVPacket containing the input buffer. * You can create such packet with av_init_packet() and by then setting * data and size, some decoders might in addition need other fields like * flags&AV_PKT_FLAG_KEY. All decoders are designed to use the least @@ -3712,6 +3954,14 @@ int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, * and reusing a get_buffer written for video codecs would probably perform badly * due to a potentially very different allocation pattern. * + * Some decoders (those marked with CODEC_CAP_DELAY) have a delay between input + * and output. This means that for some packets they will not immediately + * produce decoded output and need to be flushed at the end of decoding to get + * all the decoded data. Flushing is done by calling this function with packets + * with avpkt->data set to NULL and avpkt->size set to 0 until it stops + * returning subtitles. It is safe to flush even those decoders that are not + * marked with CODEC_CAP_DELAY, then no subtitles will be returned. + * * @param avctx the codec context * @param[out] sub The AVSubtitle in which the decoded subtitle will be stored, must be freed with avsubtitle_free if *got_sub_ptr is set. @@ -3727,6 +3977,13 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, * @{ */ +enum AVPictureStructure { + AV_PICTURE_STRUCTURE_UNKNOWN, //< unknown + AV_PICTURE_STRUCTURE_TOP_FIELD, //< coded as top field + AV_PICTURE_STRUCTURE_BOTTOM_FIELD, //< coded as bottom field + AV_PICTURE_STRUCTURE_FRAME, //< coded as frame +}; + typedef struct AVCodecParserContext { void *priv_data; struct AVCodecParser *parser; @@ -3861,6 +4118,26 @@ typedef struct AVCodecParserContext { * For all other types, this is in units of AVCodecContext.time_base. */ int duration; + + enum AVFieldOrder field_order; + + /** + * Indicate whether a picture is coded as a frame, top field or bottom field. + * + * For example, H.264 field_pic_flag equal to 0 corresponds to + * AV_PICTURE_STRUCTURE_FRAME. An H.264 picture with field_pic_flag + * equal to 1 and bottom_field_flag equal to 0 corresponds to + * AV_PICTURE_STRUCTURE_TOP_FIELD. + */ + enum AVPictureStructure picture_structure; + + /** + * Picture number incremented in presentation or output order. + * This field may be reinitialized at the first picture of a new sequence. + * + * For example, this corresponds to H.264 PicOrderCnt. + */ + int output_picture_number; } AVCodecParserContext; typedef struct AVCodecParser { @@ -3918,7 +4195,7 @@ int av_parser_parse2(AVCodecParserContext *s, /** * @return 0 if the output buffer is a subset of the input, 1 if it is allocated and must be freed - * @deprecated use AVBitstreamFilter + * @deprecated use AVBitStreamFilter */ int av_parser_change(AVCodecParserContext *s, AVCodecContext *avctx, @@ -4192,15 +4469,18 @@ void av_resample_close(struct AVResampleContext *c); */ /** - * Allocate memory for a picture. Call avpicture_free() to free it. + * Allocate memory for the pixels of a picture and setup the AVPicture + * fields for it. * - * @see avpicture_fill() + * Call avpicture_free() to free it. * - * @param picture the picture to be filled in - * @param pix_fmt the format of the picture - * @param width the width of the picture - * @param height the height of the picture - * @return zero if successful, a negative value if not + * @param picture the picture structure to be filled in + * @param pix_fmt the pixel format of the picture + * @param width the width of the picture + * @param height the height of the picture + * @return zero if successful, a negative error code otherwise + * + * @see av_image_alloc(), avpicture_fill() */ int avpicture_alloc(AVPicture *picture, enum AVPixelFormat pix_fmt, int width, int height); @@ -4214,8 +4494,25 @@ int avpicture_alloc(AVPicture *picture, enum AVPixelFormat pix_fmt, int width, i void avpicture_free(AVPicture *picture); /** - * Fill in the AVPicture fields, always assume a linesize alignment of - * 1. + * Setup the picture fields based on the specified image parameters + * and the provided image data buffer. + * + * The picture fields are filled in by using the image data buffer + * pointed to by ptr. + * + * If ptr is NULL, the function will fill only the picture linesize + * array and return the required size for the image buffer. + * + * To allocate an image buffer and fill the picture data in one call, + * use avpicture_alloc(). + * + * @param picture the picture to be filled in + * @param ptr buffer where the image data is stored, or NULL + * @param pix_fmt the pixel format of the image + * @param width the width of the image in pixels + * @param height the height of the image in pixels + * @return the size in bytes required for src, a negative error code + * in case of failure * * @see av_image_fill_arrays() */ @@ -4223,19 +4520,36 @@ int avpicture_fill(AVPicture *picture, const uint8_t *ptr, enum AVPixelFormat pix_fmt, int width, int height); /** - * Copy pixel data from an AVPicture into a buffer, always assume a - * linesize alignment of 1. + * Copy pixel data from an AVPicture into a buffer. + * + * avpicture_get_size() can be used to compute the required size for + * the buffer to fill. + * + * @param src source picture with filled data + * @param pix_fmt picture pixel format + * @param width picture width + * @param height picture height + * @param dest destination buffer + * @param dest_size destination buffer size in bytes + * @return the number of bytes written to dest, or a negative value + * (error code) on error, for example if the destination buffer is not + * big enough * * @see av_image_copy_to_buffer() */ -int avpicture_layout(const AVPicture* src, enum AVPixelFormat pix_fmt, +int avpicture_layout(const AVPicture *src, enum AVPixelFormat pix_fmt, int width, int height, unsigned char *dest, int dest_size); /** * Calculate the size in bytes that a picture of the given width and height * would occupy if stored in the given picture format. - * Always assume a linesize alignment of 1. + * + * @param pix_fmt picture pixel format + * @param width picture width + * @param height picture height + * @return the computed picture buffer size or a negative error code + * in case of error * * @see av_image_get_buffer_size(). */ @@ -4358,7 +4672,7 @@ int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt, enum AVPixelFormat * @param[out] loss_ptr Combination of flags informing you what kind of losses will occur. * @return The best pixel format to convert to or -1 if none was found. */ -enum AVPixelFormat avcodec_find_best_pix_fmt_of_list(enum AVPixelFormat *pix_fmt_list, +enum AVPixelFormat avcodec_find_best_pix_fmt_of_list(const enum AVPixelFormat *pix_fmt_list, enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr); @@ -4396,8 +4710,8 @@ enum AVPixelFormat avcodec_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr); attribute_deprecated -#if AV_HAVE_INCOMPATIBLE_FORK_ABI -enum AVPixelFormat avcodec_find_best_pix_fmt2(enum AVPixelFormat *pix_fmt_list, +#if AV_HAVE_INCOMPATIBLE_LIBAV_ABI +enum AVPixelFormat avcodec_find_best_pix_fmt2(const enum AVPixelFormat *pix_fmt_list, enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr); #else @@ -4412,7 +4726,13 @@ enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const en * @} */ +#if FF_API_SET_DIMENSIONS +/** + * @deprecated this function is not supposed to be used from outside of lavc + */ +attribute_deprecated void avcodec_set_dimensions(AVCodecContext *s, int width, int height); +#endif /** * Put a string representing the codec tag codec_tag in buf. @@ -4466,7 +4786,13 @@ int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels, int buf_size, int align); /** - * Flush buffers, should be called when seeking or when switching to a different stream. + * Reset the internal decoder state / flush internal buffers. Should be called + * e.g. when seeking or when switching to a different stream. + * + * @note when refcounted frames are not used (i.e. avctx->refcounted_frames is 0), + * this invalidates the frames previously returned from the decoder. When + * refcounted frames are used, the decoder just releases any references it might + * keep internally, but the caller's reference remains valid. */ void avcodec_flush_buffers(AVCodecContext *avctx); @@ -4526,42 +4852,85 @@ typedef struct AVBitStreamFilter { struct AVBitStreamFilter *next; } AVBitStreamFilter; +/** + * Register a bitstream filter. + * + * The filter will be accessible to the application code through + * av_bitstream_filter_next() or can be directly initialized with + * av_bitstream_filter_init(). + * + * @see avcodec_register_all() + */ void av_register_bitstream_filter(AVBitStreamFilter *bsf); + +/** + * Create and initialize a bitstream filter context given a bitstream + * filter name. + * + * The returned context must be freed with av_bitstream_filter_close(). + * + * @param name the name of the bitstream filter + * @return a bitstream filter context if a matching filter was found + * and successfully initialized, NULL otherwise + */ AVBitStreamFilterContext *av_bitstream_filter_init(const char *name); + +/** + * Filter bitstream. + * + * This function filters the buffer buf with size buf_size, and places the + * filtered buffer in the buffer pointed to by poutbuf. + * + * The output buffer must be freed by the caller. + * + * @param bsfc bitstream filter context created by av_bitstream_filter_init() + * @param avctx AVCodecContext accessed by the filter, may be NULL. + * If specified, this must point to the encoder context of the + * output stream the packet is sent to. + * @param args arguments which specify the filter configuration, may be NULL + * @param poutbuf pointer which is updated to point to the filtered buffer + * @param poutbuf_size pointer which is updated to the filtered buffer size in bytes + * @param buf buffer containing the data to filter + * @param buf_size size in bytes of buf + * @param keyframe set to non-zero if the buffer to filter corresponds to a key-frame packet data + * @return >= 0 in case of success, or a negative error code in case of failure + * + * If the return value is positive, an output buffer is allocated and + * is availble in *poutbuf, and is distinct from the input buffer. + * + * If the return value is 0, the output buffer is not allocated and + * should be considered identical to the input buffer, or in case + * *poutbuf was set it points to the input buffer (not necessarily to + * its starting address). + */ int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size, int keyframe); -void av_bitstream_filter_close(AVBitStreamFilterContext *bsf); - -AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f); - -/* memory */ /** - * Reallocate the given block if it is not large enough, otherwise do nothing. + * Release bitstream filter context. * - * @see av_realloc + * @param bsf the bitstream filter context created with + * av_bitstream_filter_init(), can be NULL */ -void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size); +void av_bitstream_filter_close(AVBitStreamFilterContext *bsf); /** - * Allocate a buffer, reusing the given one if large enough. + * If f is NULL, return the first registered bitstream filter, + * if f is non-NULL, return the next registered bitstream filter + * after f, or NULL if f is the last one. * - * Contrary to av_fast_realloc the current buffer contents might not be - * preserved and on error the old buffer is freed, thus no special - * handling to avoid memleaks is necessary. - * - * @param ptr pointer to pointer to already allocated buffer, overwritten with pointer to new buffer - * @param size size of the buffer *ptr points to - * @param min_size minimum size of *ptr buffer after returning, *ptr will be NULL and - * *size 0 if an error occurred. + * This function can be used to iterate over all registered bitstream + * filters. */ -void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size); +AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f); + +/* memory */ /** * Same behaviour av_fast_malloc but the buffer has additional - * FF_INPUT_BUFFER_PADDING_SIZE at the end which will will always be 0. + * FF_INPUT_BUFFER_PADDING_SIZE at the end which will always be 0. * * In addition the whole buffer will initially and after resizes * be 0-initialized so that no uninitialized data will ever appear. diff --git a/ffmpeg/libavcodec/avfft.c b/ffmpeg/libavcodec/avfft.c index 9e0ddaa..2200f37 100644 --- a/ffmpeg/libavcodec/avfft.c +++ b/ffmpeg/libavcodec/avfft.c @@ -16,6 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/attributes.h" #include "libavutil/mem.h" #include "avfft.h" #include "fft.h" @@ -26,7 +27,7 @@ FFTContext *av_fft_init(int nbits, int inverse) { - FFTContext *s = av_malloc(sizeof(*s)); + FFTContext *s = av_mallocz(sizeof(*s)); if (s && ff_fft_init(s, nbits, inverse)) av_freep(&s); @@ -44,7 +45,7 @@ void av_fft_calc(FFTContext *s, FFTComplex *z) s->fft_calc(s, z); } -void av_fft_end(FFTContext *s) +av_cold void av_fft_end(FFTContext *s) { if (s) { ff_fft_end(s); @@ -79,7 +80,7 @@ void av_mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input) s->mdct_calc(s, output, input); } -void av_mdct_end(FFTContext *s) +av_cold void av_mdct_end(FFTContext *s) { if (s) { ff_mdct_end(s); @@ -106,7 +107,7 @@ void av_rdft_calc(RDFTContext *s, FFTSample *data) s->rdft_calc(s, data); } -void av_rdft_end(RDFTContext *s) +av_cold void av_rdft_end(RDFTContext *s) { if (s) { ff_rdft_end(s); @@ -133,7 +134,7 @@ void av_dct_calc(DCTContext *s, FFTSample *data) s->dct_calc(s, data); } -void av_dct_end(DCTContext *s) +av_cold void av_dct_end(DCTContext *s) { if (s) { ff_dct_end(s); diff --git a/ffmpeg/libavcodec/avpacket.c b/ffmpeg/libavcodec/avpacket.c index 651036e..f966bfe 100644 --- a/ffmpeg/libavcodec/avpacket.c +++ b/ffmpeg/libavcodec/avpacket.c @@ -23,21 +23,14 @@ #include "libavutil/avassert.h" #include "libavutil/common.h" +#include "libavutil/internal.h" #include "libavutil/mem.h" #include "avcodec.h" #include "bytestream.h" #include "internal.h" -void ff_packet_free_side_data(AVPacket *pkt) -{ - int i; - for (i = 0; i < pkt->side_data_elems; i++) - av_free(pkt->side_data[i].data); - av_freep(&pkt->side_data); - pkt->side_data_elems = 0; -} - #if FF_API_DESTRUCT_PACKET + void av_destruct_packet(AVPacket *pkt) { av_free(pkt->data); @@ -63,32 +56,45 @@ void av_init_packet(AVPacket *pkt) pkt->flags = 0; pkt->stream_index = 0; #if FF_API_DESTRUCT_PACKET +FF_DISABLE_DEPRECATION_WARNINGS pkt->destruct = NULL; +FF_ENABLE_DEPRECATION_WARNINGS #endif pkt->buf = NULL; pkt->side_data = NULL; pkt->side_data_elems = 0; } -int av_new_packet(AVPacket *pkt, int size) +static int packet_alloc(AVBufferRef **buf, int size) { - AVBufferRef *buf = NULL; - + int ret; if ((unsigned)size >= (unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE) return AVERROR(EINVAL); - av_buffer_realloc(&buf, size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!buf) - return AVERROR(ENOMEM); + ret = av_buffer_realloc(buf, size + FF_INPUT_BUFFER_PADDING_SIZE); + if (ret < 0) + return ret; + + memset((*buf)->data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE); - memset(buf->data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE); + return 0; +} + +int av_new_packet(AVPacket *pkt, int size) +{ + AVBufferRef *buf = NULL; + int ret = packet_alloc(&buf, size); + if (ret < 0) + return ret; av_init_packet(pkt); pkt->buf = buf; pkt->data = buf->data; pkt->size = size; #if FF_API_DESTRUCT_PACKET +FF_DISABLE_DEPRECATION_WARNINGS pkt->destruct = dummy_destruct_packet; +FF_ENABLE_DEPRECATION_WARNINGS #endif return 0; @@ -123,7 +129,9 @@ int av_grow_packet(AVPacket *pkt, int grow_by) return AVERROR(ENOMEM); memcpy(pkt->buf->data, pkt->data, FFMIN(pkt->size, pkt->size + grow_by)); #if FF_API_DESTRUCT_PACKET +FF_DISABLE_DEPRECATION_WARNINGS pkt->destruct = dummy_destruct_packet; +FF_ENABLE_DEPRECATION_WARNINGS #endif } pkt->data = pkt->buf->data; @@ -146,7 +154,9 @@ int av_packet_from_data(AVPacket *pkt, uint8_t *data, int size) pkt->data = data; pkt->size = size; #if FF_API_DESTRUCT_PACKET +FF_DISABLE_DEPRECATION_WARNINGS pkt->destruct = dummy_destruct_packet; +FF_ENABLE_DEPRECATION_WARNINGS #endif return 0; @@ -180,7 +190,7 @@ do { \ } while (0) /* Makes duplicates of data, side_data, but does not copy any other fields */ -static int copy_packet_data(AVPacket *pkt, AVPacket *src) +static int copy_packet_data(AVPacket *pkt, AVPacket *src, int dup) { pkt->data = NULL; pkt->side_data = NULL; @@ -194,27 +204,44 @@ static int copy_packet_data(AVPacket *pkt, AVPacket *src) DUP_DATA(pkt->data, src->data, pkt->size, 1, ALLOC_BUF); } #if FF_API_DESTRUCT_PACKET +FF_DISABLE_DEPRECATION_WARNINGS pkt->destruct = dummy_destruct_packet; +FF_ENABLE_DEPRECATION_WARNINGS #endif + if (pkt->side_data_elems && dup) + pkt->side_data = src->side_data; + if (pkt->side_data_elems && !dup) { + return av_copy_packet_side_data(pkt, src); + } + return 0; - if (pkt->side_data_elems) { - int i; +failed_alloc: + av_free_packet(pkt); + return AVERROR(ENOMEM); +} +int av_copy_packet_side_data(AVPacket *pkt, AVPacket *src) +{ + if (src->side_data_elems) { + int i; DUP_DATA(pkt->side_data, src->side_data, - pkt->side_data_elems * sizeof(*pkt->side_data), 0, ALLOC_MALLOC); - memset(pkt->side_data, 0, - pkt->side_data_elems * sizeof(*pkt->side_data)); - for (i = 0; i < pkt->side_data_elems; i++) { + src->side_data_elems * sizeof(*src->side_data), 0, ALLOC_MALLOC); + if (src != pkt) { + memset(pkt->side_data, 0, + src->side_data_elems * sizeof(*src->side_data)); + } + for (i = 0; i < src->side_data_elems; i++) { DUP_DATA(pkt->side_data[i].data, src->side_data[i].data, src->side_data[i].size, 1, ALLOC_MALLOC); pkt->side_data[i].size = src->side_data[i].size; pkt->side_data[i].type = src->side_data[i].type; } } + pkt->side_data_elems = src->side_data_elems; return 0; failed_alloc: - av_destruct_packet(pkt); + av_free_packet(pkt); return AVERROR(ENOMEM); } @@ -222,13 +249,15 @@ int av_dup_packet(AVPacket *pkt) { AVPacket tmp_pkt; +FF_DISABLE_DEPRECATION_WARNINGS if (!pkt->buf && pkt->data #if FF_API_DESTRUCT_PACKET && !pkt->destruct #endif ) { +FF_ENABLE_DEPRECATION_WARNINGS tmp_pkt = *pkt; - return copy_packet_data(pkt, &tmp_pkt); + return copy_packet_data(pkt, &tmp_pkt, 1); } return 0; } @@ -236,14 +265,22 @@ int av_dup_packet(AVPacket *pkt) int av_copy_packet(AVPacket *dst, AVPacket *src) { *dst = *src; - return copy_packet_data(dst, src); + return copy_packet_data(dst, src, 0); +} + +void av_packet_free_side_data(AVPacket *pkt) +{ + int i; + for (i = 0; i < pkt->side_data_elems; i++) + av_free(pkt->side_data[i].data); + av_freep(&pkt->side_data); + pkt->side_data_elems = 0; } void av_free_packet(AVPacket *pkt) { if (pkt) { - int i; - +FF_DISABLE_DEPRECATION_WARNINGS if (pkt->buf) av_buffer_unref(&pkt->buf); #if FF_API_DESTRUCT_PACKET @@ -251,13 +288,11 @@ void av_free_packet(AVPacket *pkt) pkt->destruct(pkt); pkt->destruct = NULL; #endif +FF_ENABLE_DEPRECATION_WARNINGS pkt->data = NULL; pkt->size = 0; - for (i = 0; i < pkt->side_data_elems; i++) - av_free(pkt->side_data[i].data); - av_freep(&pkt->side_data); - pkt->side_data_elems = 0; + av_packet_free_side_data(pkt); } } @@ -276,7 +311,7 @@ uint8_t *av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, if (!pkt->side_data) return NULL; - pkt->side_data[elems].data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); + pkt->side_data[elems].data = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE); if (!pkt->side_data[elems].data) return NULL; pkt->side_data[elems].size = size; @@ -321,7 +356,9 @@ int av_packet_merge_side_data(AVPacket *pkt){ pkt->buf = buf; pkt->data = p = buf->data; #if FF_API_DESTRUCT_PACKET +FF_DISABLE_DEPRECATION_WARNINGS pkt->destruct = dummy_destruct_packet; +FF_ENABLE_DEPRECATION_WARNINGS #endif pkt->size = size - FF_INPUT_BUFFER_PADDING_SIZE; bytestream_put_buffer(&p, old.data, old.size); @@ -365,7 +402,7 @@ int av_packet_split_side_data(AVPacket *pkt){ for (i=0; ; i++){ size= AV_RB32(p); av_assert0(size<=INT_MAX && p - pkt->data >= size); - pkt->side_data[i].data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); + pkt->side_data[i].data = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE); pkt->side_data[i].size = size; pkt->side_data[i].type = p[4]&127; if (!pkt->side_data[i].data) @@ -383,6 +420,66 @@ int av_packet_split_side_data(AVPacket *pkt){ return 0; } +uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size) +{ + AVDictionaryEntry *t = NULL; + uint8_t *data = NULL; + *size = 0; + + if (!dict) + return NULL; + + while ((t = av_dict_get(dict, "", t, AV_DICT_IGNORE_SUFFIX))) { + const size_t keylen = strlen(t->key); + const size_t valuelen = strlen(t->value); + const size_t new_size = *size + keylen + 1 + valuelen + 1; + uint8_t *const new_data = av_realloc(data, new_size); + + if (!new_data) + goto fail; + data = new_data; + if (new_size > INT_MAX) + goto fail; + + memcpy(data + *size, t->key, keylen + 1); + memcpy(data + *size + keylen + 1, t->value, valuelen + 1); + + *size = new_size; + } + + return data; + +fail: + av_freep(&data); + *size = 0; + return NULL; +} + +int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **dict) +{ + const uint8_t *end = data + size; + int ret = 0; + + if (!dict || !data || !size) + return ret; + if (size && end[-1]) + return AVERROR_INVALIDDATA; + while (data < end) { + const uint8_t *key = data; + const uint8_t *val = data + strlen(key) + 1; + + if (val >= end) + return AVERROR_INVALIDDATA; + + ret = av_dict_set(dict, key, val, 0); + if (ret < 0) + break; + data = val + strlen(val) + 1; + } + + return ret; +} + int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type, int size) { @@ -398,3 +495,71 @@ int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type, } return AVERROR(ENOENT); } + +int av_packet_copy_props(AVPacket *dst, const AVPacket *src) +{ + int i; + + dst->pts = src->pts; + dst->dts = src->dts; + dst->pos = src->pos; + dst->duration = src->duration; + dst->convergence_duration = src->convergence_duration; + dst->flags = src->flags; + dst->stream_index = src->stream_index; + dst->side_data_elems = src->side_data_elems; + + for (i = 0; i < src->side_data_elems; i++) { + enum AVPacketSideDataType type = src->side_data[i].type; + int size = src->side_data[i].size; + uint8_t *src_data = src->side_data[i].data; + uint8_t *dst_data = av_packet_new_side_data(dst, type, size); + + if (!dst_data) { + av_packet_free_side_data(dst); + return AVERROR(ENOMEM); + } + memcpy(dst_data, src_data, size); + } + + return 0; +} + +void av_packet_unref(AVPacket *pkt) +{ + av_packet_free_side_data(pkt); + av_buffer_unref(&pkt->buf); + av_init_packet(pkt); + pkt->data = NULL; + pkt->size = 0; +} + +int av_packet_ref(AVPacket *dst, AVPacket *src) +{ + int ret; + + ret = av_packet_copy_props(dst, src); + if (ret < 0) + return ret; + + if (!src->buf) { + ret = packet_alloc(&dst->buf, src->size); + if (ret < 0) + goto fail; + memcpy(dst->buf->data, src->data, src->size); + } else + dst->buf = av_buffer_ref(src->buf); + + dst->size = src->size; + dst->data = dst->buf->data; + return 0; +fail: + av_packet_free_side_data(dst); + return ret; +} + +void av_packet_move_ref(AVPacket *dst, AVPacket *src) +{ + *dst = *src; + av_init_packet(src); +} diff --git a/ffmpeg/libavcodec/avrndec.c b/ffmpeg/libavcodec/avrndec.c index 40aca17..7a50a5c 100644 --- a/ffmpeg/libavcodec/avrndec.c +++ b/ffmpeg/libavcodec/avrndec.c @@ -119,14 +119,13 @@ static int decode_frame(AVCodecContext *avctx, void *data, AVCodec ff_avrn_decoder = { .name = "avrn", + .long_name = NULL_IF_CONFIG_SMALL("Avid AVI Codec"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_AVRN, .priv_data_size = sizeof(AVRnContext), .init = init, .close = end, .decode = decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Avid AVI Codec"), .capabilities = CODEC_CAP_DR1, .max_lowres = 3, }; - diff --git a/ffmpeg/libavcodec/avs.c b/ffmpeg/libavcodec/avs.c index e3733d7..c4eaf20 100644 --- a/ffmpeg/libavcodec/avs.c +++ b/ffmpeg/libavcodec/avs.c @@ -25,7 +25,7 @@ typedef struct { - AVFrame picture; + AVFrame *frame; } AvsContext; typedef enum { @@ -52,7 +52,7 @@ avs_decode_frame(AVCodecContext * avctx, int buf_size = avpkt->size; AvsContext *const avs = avctx->priv_data; AVFrame *picture = data; - AVFrame *const p = &avs->picture; + AVFrame *const p = avs->frame; const uint8_t *table, *vect; uint8_t *out; int i, j, x, y, stride, ret, vect_w = 3, vect_h = 3; @@ -65,8 +65,8 @@ avs_decode_frame(AVCodecContext * avctx, p->pict_type = AV_PICTURE_TYPE_P; p->key_frame = 0; - out = avs->picture.data[0]; - stride = avs->picture.linesize[0]; + out = p->data[0]; + stride = p->linesize[0]; if (buf_end - buf < 4) return AVERROR_INVALIDDATA; @@ -76,7 +76,7 @@ avs_decode_frame(AVCodecContext * avctx, if (type == AVS_PALETTE) { int first, last; - uint32_t *pal = (uint32_t *) avs->picture.data[1]; + uint32_t *pal = (uint32_t *) p->data[1]; first = AV_RL16(buf); last = first + AV_RL16(buf + 2); @@ -149,7 +149,7 @@ avs_decode_frame(AVCodecContext * avctx, align_get_bits(&change_map); } - if ((ret = av_frame_ref(picture, &avs->picture)) < 0) + if ((ret = av_frame_ref(picture, p)) < 0) return ret; *got_frame = 1; @@ -159,22 +159,28 @@ avs_decode_frame(AVCodecContext * avctx, static av_cold int avs_decode_init(AVCodecContext * avctx) { AvsContext *s = avctx->priv_data; + + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); + avctx->pix_fmt = AV_PIX_FMT_PAL8; - avcodec_set_dimensions(avctx, 318, 198); - avcodec_get_frame_defaults(&s->picture); + ff_set_dimensions(avctx, 318, 198); + return 0; } static av_cold int avs_decode_end(AVCodecContext *avctx) { AvsContext *s = avctx->priv_data; - av_frame_unref(&s->picture); + av_frame_free(&s->frame); return 0; } AVCodec ff_avs_decoder = { .name = "avs", + .long_name = NULL_IF_CONFIG_SMALL("AVS (Audio Video Standard) video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_AVS, .priv_data_size = sizeof(AvsContext), @@ -182,5 +188,4 @@ AVCodec ff_avs_decoder = { .decode = avs_decode_frame, .close = avs_decode_end, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("AVS (Audio Video Standard) video"), }; diff --git a/ffmpeg/libavcodec/avuidec.c b/ffmpeg/libavcodec/avuidec.c index a574f5b..7fb644c 100644 --- a/ffmpeg/libavcodec/avuidec.c +++ b/ffmpeg/libavcodec/avuidec.c @@ -121,10 +121,10 @@ static int avui_decode_frame(AVCodecContext *avctx, void *data, AVCodec ff_avui_decoder = { .name = "avui", + .long_name = NULL_IF_CONFIG_SMALL("Avid Meridien Uncompressed"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_AVUI, .init = avui_decode_init, .decode = avui_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Avid Meridien Uncompressed"), }; diff --git a/ffmpeg/libavcodec/avuienc.c b/ffmpeg/libavcodec/avuienc.c index a4970a0..eb0046c 100644 --- a/ffmpeg/libavcodec/avuienc.c +++ b/ffmpeg/libavcodec/avuienc.c @@ -25,7 +25,7 @@ static av_cold int avui_encode_init(AVCodecContext *avctx) { - avctx->coded_frame = avcodec_alloc_frame(); + avctx->coded_frame = av_frame_alloc(); if (avctx->width != 720 || avctx->height != 486 && avctx->height != 576) { av_log(avctx, AV_LOG_ERROR, "Only 720x486 and 720x576 are supported.\n"); @@ -101,6 +101,7 @@ static av_cold int avui_encode_close(AVCodecContext *avctx) AVCodec ff_avui_encoder = { .name = "avui", + .long_name = NULL_IF_CONFIG_SMALL("Avid Meridien Uncompressed"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_AVUI, .init = avui_encode_init, @@ -108,5 +109,4 @@ AVCodec ff_avui_encoder = { .close = avui_encode_close, .capabilities = CODEC_CAP_EXPERIMENTAL, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_UYVY422, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Avid Meridien Uncompressed"), }; diff --git a/ffmpeg/libavcodec/bethsoftvideo.c b/ffmpeg/libavcodec/bethsoftvideo.c index 474265f..37cd22e 100644 --- a/ffmpeg/libavcodec/bethsoftvideo.c +++ b/ffmpeg/libavcodec/bethsoftvideo.c @@ -34,21 +34,25 @@ #include "internal.h" typedef struct BethsoftvidContext { - AVFrame frame; + AVFrame *frame; GetByteContext g; } BethsoftvidContext; static av_cold int bethsoftvid_decode_init(AVCodecContext *avctx) { BethsoftvidContext *vid = avctx->priv_data; - avcodec_get_frame_defaults(&vid->frame); avctx->pix_fmt = AV_PIX_FMT_PAL8; + + vid->frame = av_frame_alloc(); + if (!vid->frame) + return AVERROR(ENOMEM); + return 0; } static int set_palette(BethsoftvidContext *ctx) { - uint32_t *palette = (uint32_t *)ctx->frame.data[1]; + uint32_t *palette = (uint32_t *)ctx->frame->data[1]; int a; if (bytestream2_get_bytes_left(&ctx->g) < 256*3) @@ -58,7 +62,7 @@ static int set_palette(BethsoftvidContext *ctx) palette[a] = 0xFFU << 24 | bytestream2_get_be24u(&ctx->g) * 4; palette[a] |= palette[a] >> 6 & 0x30303; } - ctx->frame.palette_has_changed = 1; + ctx->frame->palette_has_changed = 1; return 0; } @@ -75,9 +79,9 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx, int code, ret; int yoffset; - if ((ret = ff_reget_buffer(avctx, &vid->frame)) < 0) + if ((ret = ff_reget_buffer(avctx, vid->frame)) < 0) return ret; - wrap_to_next_line = vid->frame.linesize[0] - avctx->width; + wrap_to_next_line = vid->frame->linesize[0] - avctx->width; if (avpkt->side_data_elems > 0 && avpkt->side_data[0].type == AV_PKT_DATA_PALETTE) { @@ -88,8 +92,8 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx, } bytestream2_init(&vid->g, avpkt->data, avpkt->size); - dst = vid->frame.data[0]; - frame_end = vid->frame.data[0] + vid->frame.linesize[0] * avctx->height; + dst = vid->frame->data[0]; + frame_end = vid->frame->data[0] + vid->frame->linesize[0] * avctx->height; switch(block_type = bytestream2_get_byte(&vid->g)){ case PALETTE_BLOCK: { @@ -104,7 +108,7 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx, yoffset = bytestream2_get_le16(&vid->g); if(yoffset >= avctx->height) return AVERROR_INVALIDDATA; - dst += vid->frame.linesize[0] * yoffset; + dst += vid->frame->linesize[0] * yoffset; } // main code @@ -134,7 +138,7 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx, } end: - if ((ret = av_frame_ref(data, &vid->frame)) < 0) + if ((ret = av_frame_ref(data, vid->frame)) < 0) return ret; *got_frame = 1; @@ -145,12 +149,13 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx, static av_cold int bethsoftvid_decode_end(AVCodecContext *avctx) { BethsoftvidContext * vid = avctx->priv_data; - av_frame_unref(&vid->frame); + av_frame_free(&vid->frame); return 0; } AVCodec ff_bethsoftvid_decoder = { .name = "bethsoftvid", + .long_name = NULL_IF_CONFIG_SMALL("Bethesda VID video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_BETHSOFTVID, .priv_data_size = sizeof(BethsoftvidContext), @@ -158,5 +163,4 @@ AVCodec ff_bethsoftvid_decoder = { .close = bethsoftvid_decode_end, .decode = bethsoftvid_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Bethesda VID video"), }; diff --git a/ffmpeg/libavcodec/bfi.c b/ffmpeg/libavcodec/bfi.c index 9cfcd14..c7ac378 100644 --- a/ffmpeg/libavcodec/bfi.c +++ b/ffmpeg/libavcodec/bfi.c @@ -42,6 +42,8 @@ static av_cold int bfi_decode_init(AVCodecContext *avctx) BFIContext *bfi = avctx->priv_data; avctx->pix_fmt = AV_PIX_FMT_PAL8; bfi->dst = av_mallocz(avctx->width * avctx->height); + if (!bfi->dst) + return AVERROR(ENOMEM); return 0; } @@ -175,6 +177,7 @@ static av_cold int bfi_decode_close(AVCodecContext *avctx) AVCodec ff_bfi_decoder = { .name = "bfi", + .long_name = NULL_IF_CONFIG_SMALL("Brute Force & Ignorance"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_BFI, .priv_data_size = sizeof(BFIContext), @@ -182,5 +185,4 @@ AVCodec ff_bfi_decoder = { .close = bfi_decode_close, .decode = bfi_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Brute Force & Ignorance"), }; diff --git a/ffmpeg/libavcodec/bfin/Makefile b/ffmpeg/libavcodec/bfin/Makefile index f7a5f42..c293360 100644 --- a/ffmpeg/libavcodec/bfin/Makefile +++ b/ffmpeg/libavcodec/bfin/Makefile @@ -3,7 +3,7 @@ OBJS += bfin/dsputil_bfin.o \ bfin/idct_bfin.o \ bfin/pixels_bfin.o \ -OBJS-$(CONFIG_HPELDS) += bfin/hpeldsp_bfin.o \ +OBJS-$(CONFIG_HPELDSP) += bfin/hpeldsp_bfin.o \ bfin/hpel_pixels_bfin.o OBJS-$(CONFIG_MPEGVIDEOENC) += bfin/mpegvideo_bfin.o OBJS-$(CONFIG_VP3DSP) += bfin/vp3_bfin.o \ diff --git a/ffmpeg/libavcodec/bfin/dsputil_bfin.c b/ffmpeg/libavcodec/bfin/dsputil_bfin.c index c9a0f15..a95fd6b 100644 --- a/ffmpeg/libavcodec/bfin/dsputil_bfin.c +++ b/ffmpeg/libavcodec/bfin/dsputil_bfin.c @@ -132,7 +132,7 @@ av_cold void ff_dsputil_init_bfin(DSPContext *c, AVCodecContext *avctx) c->add_pixels_clamped = ff_bfin_add_pixels_clamped; if (!high_bit_depth) - c->get_pixels = ff_bfin_get_pixels; + c->get_pixels = ff_bfin_get_pixels; c->clear_blocks = bfin_clear_blocks; c->pix_sum = ff_bfin_pix_sum; c->pix_norm1 = ff_bfin_pix_norm1; @@ -163,7 +163,7 @@ av_cold void ff_dsputil_init_bfin(DSPContext *c, AVCodecContext *avctx) if (avctx->dct_algo == FF_DCT_AUTO) c->fdct = ff_bfin_fdct; - if (avctx->idct_algo == FF_IDCT_AUTO) { + if (avctx->idct_algo == FF_IDCT_AUTO) { c->idct_permutation_type = FF_NO_IDCT_PERM; c->idct = ff_bfin_idct; c->idct_add = bfin_idct_add; diff --git a/ffmpeg/libavcodec/bfin/hpel_pixels_bfin.S b/ffmpeg/libavcodec/bfin/hpel_pixels_bfin.S index b22bc29..c0cbf1f 100644 --- a/ffmpeg/libavcodec/bfin/hpel_pixels_bfin.S +++ b/ffmpeg/libavcodec/bfin/hpel_pixels_bfin.S @@ -20,7 +20,7 @@ */ #include "config_bfin.h" -/** +/* motion compensation primitives diff --git a/ffmpeg/libavcodec/bfin/hpeldsp_bfin.c b/ffmpeg/libavcodec/bfin/hpeldsp_bfin.c index 8b4af49..2df551b 100644 --- a/ffmpeg/libavcodec/bfin/hpeldsp_bfin.c +++ b/ffmpeg/libavcodec/bfin/hpeldsp_bfin.c @@ -21,6 +21,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include +#include + +#include "libavutil/attributes.h" #include "libavcodec/hpeldsp.h" #include "hpeldsp_bfin.h" @@ -95,7 +99,7 @@ static void bfin_put_pixels16_y2_nornd (uint8_t *block, const uint8_t *pixels, p ff_bfin_put_pixels16uc_nornd (block, pixels, pixels+line_size, line_size, h); } -void ff_hpeldsp_init_bfin(HpelDSPContext* c, int flags) +av_cold void ff_hpeldsp_init_bfin(HpelDSPContext *c, int flags) { c->put_pixels_tab[0][0] = bfin_put_pixels16; c->put_pixels_tab[0][1] = bfin_put_pixels16_x2; diff --git a/ffmpeg/libavcodec/bfin/vp3_bfin.c b/ffmpeg/libavcodec/bfin/vp3_bfin.c index 366955b..868c431 100644 --- a/ffmpeg/libavcodec/bfin/vp3_bfin.c +++ b/ffmpeg/libavcodec/bfin/vp3_bfin.c @@ -28,33 +28,38 @@ #include "vp3_bfin.h" /* Intra iDCT offset 128 */ -static void ff_bfin_vp3_idct_put (uint8_t *dest, int line_size, int16_t *block) +static void bfin_vp3_idct_put(uint8_t *dest, int line_size, int16_t *block) { - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP + 128; + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP + 128; int i,j; ff_bfin_vp3_idct (block); for (i=0;i<8;i++) for (j=0;j<8;j++) - dest[line_size*i+j]=cm[block[i*8+j]]; + dest[line_size*i + j] = cm[block[j*8 + i]]; memset(block, 0, 128); } /* Inter iDCT */ -static void ff_bfin_vp3_idct_add (uint8_t *dest, int line_size, int16_t *block) +static void bfin_vp3_idct_add(uint8_t *dest, int line_size, int16_t *block) { + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + int i, j; + ff_bfin_vp3_idct (block); - ff_bfin_add_pixels_clamped (block, dest, line_size); + for (i = 0; i < 8; i++) + for (j = 0; j < 8; j++) + dest[line_size*i + j] = cm[dest[line_size*i + j] + block[j*8 + i]]; memset(block, 0, 128); } av_cold void ff_vp3dsp_init_bfin(VP3DSPContext *c, int flags) { - // FIXME: these functions are disabled because they expect unpermutated - // IDCT coefficients as input, but the coefficients are transposed - //c->idct_add = ff_bfin_vp3_idct_add; - //c->idct_put = ff_bfin_vp3_idct_put; + if (!(flags & CODEC_FLAG_BITEXACT)) { + c->idct_add = bfin_vp3_idct_add; + c->idct_put = bfin_vp3_idct_put; + } } diff --git a/ffmpeg/libavcodec/bgmc.c b/ffmpeg/libavcodec/bgmc.c index f48ac2e..1a6817b 100644 --- a/ffmpeg/libavcodec/bgmc.c +++ b/ffmpeg/libavcodec/bgmc.c @@ -1,6 +1,6 @@ /* * Block Gilbert-Moore decoder - * Copyright (c) 2010 Thilo Borgmann + * Copyright (c) 2010 Thilo Borgmann * * This file is part of FFmpeg. * @@ -22,9 +22,10 @@ /** * @file * Block Gilbert-Moore decoder as used by MPEG-4 ALS - * @author Thilo Borgmann + * @author Thilo Borgmann */ +#include "libavutil/attributes.h" #include "bgmc.h" #define FREQ_BITS 14 // bits used by frequency counters @@ -456,7 +457,8 @@ static uint8_t *bgmc_lut_getp(uint8_t *lut, int *lut_status, int delta) /** Initialize the lookup table arrays */ -int ff_bgmc_init(AVCodecContext *avctx, uint8_t **cf_lut, int **cf_lut_status) +av_cold int ff_bgmc_init(AVCodecContext *avctx, + uint8_t **cf_lut, int **cf_lut_status) { *cf_lut = av_malloc(sizeof(**cf_lut) * LUT_BUFF * 16 * LUT_SIZE); *cf_lut_status = av_malloc(sizeof(**cf_lut_status) * LUT_BUFF); @@ -475,7 +477,7 @@ int ff_bgmc_init(AVCodecContext *avctx, uint8_t **cf_lut, int **cf_lut_status) /** Release the lookup table arrays */ -void ff_bgmc_end(uint8_t **cf_lut, int **cf_lut_status) +av_cold void ff_bgmc_end(uint8_t **cf_lut, int **cf_lut_status) { av_freep(cf_lut); av_freep(cf_lut_status); @@ -483,8 +485,8 @@ void ff_bgmc_end(uint8_t **cf_lut, int **cf_lut_status) /** Initialize decoding and reads the first value */ -void ff_bgmc_decode_init(GetBitContext *gb, unsigned int *h, unsigned int *l, - unsigned int *v) +void ff_bgmc_decode_init(GetBitContext *gb, unsigned int *h, + unsigned int *l, unsigned int *v) { *h = TOP_VALUE; *l = 0; diff --git a/ffmpeg/libavcodec/bgmc.h b/ffmpeg/libavcodec/bgmc.h index 9e386fd..4893736 100644 --- a/ffmpeg/libavcodec/bgmc.h +++ b/ffmpeg/libavcodec/bgmc.h @@ -1,6 +1,6 @@ /* * Block Gilbert-Moore decoder - * Copyright (c) 2010 Thilo Borgmann + * Copyright (c) 2010 Thilo Borgmann * * This file is part of FFmpeg. * @@ -22,7 +22,7 @@ /** * @file * Block Gilbert-Moore decoder header - * @author Thilo Borgmann + * @author Thilo Borgmann */ diff --git a/ffmpeg/libavcodec/bink.c b/ffmpeg/libavcodec/bink.c index 9bab4b9..f23542f 100644 --- a/ffmpeg/libavcodec/bink.c +++ b/ffmpeg/libavcodec/bink.c @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/attributes.h" #include "libavutil/imgutils.h" #include "libavutil/internal.h" #include "avcodec.h" @@ -119,6 +120,7 @@ typedef struct BinkContext { int version; ///< internal Bink file version int has_alpha; int swap_planes; + unsigned frame_num; Bundle bundle[BINKB_NB_SRC]; ///< bundles for decoding all data types Tree col_high[16]; ///< trees for decoding high nibble in "colours" data type @@ -142,7 +144,7 @@ enum BlockTypes { }; /** - * Initialize length length in all bundles. + * Initialize length in all bundles. * * @param c decoder context * @param width plane width @@ -183,7 +185,7 @@ static av_cold int init_bundles(BinkContext *c) blocks = bw * bh; for (i = 0; i < BINKB_NB_SRC; i++) { - c->bundle[i].data = av_malloc(blocks * 64); + c->bundle[i].data = av_mallocz(blocks * 64); if (!c->bundle[i].data) return AVERROR(ENOMEM); c->bundle[i].data_end = c->bundle[i].data + blocks * 64; @@ -528,14 +530,14 @@ static inline int get_value(BinkContext *c, int bundle) return ret; } -static void binkb_init_bundle(BinkContext *c, int bundle_num) +static av_cold void binkb_init_bundle(BinkContext *c, int bundle_num) { c->bundle[bundle_num].cur_dec = c->bundle[bundle_num].cur_ptr = c->bundle[bundle_num].data; c->bundle[bundle_num].len = 13; } -static void binkb_init_bundles(BinkContext *c) +static av_cold void binkb_init_bundles(BinkContext *c) { int i; for (i = 0; i < BINKB_NB_SRC; i++) @@ -1205,6 +1207,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac if (c->version >= 'i') skip_bits_long(&gb, 32); + c->frame_num++; + for (plane = 0; plane < 3; plane++) { plane_idx = (!plane || !c->swap_planes) ? plane : (plane ^ 3); @@ -1213,7 +1217,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac return ret; } else { if ((ret = binkb_decode_plane(c, frame, &gb, plane_idx, - !avctx->frame_number, !!plane)) < 0) + c->frame_num == 1, !!plane)) < 0) return ret; } if (get_bits_count(&gb) >= bits_count) @@ -1331,14 +1335,22 @@ static av_cold int decode_end(AVCodecContext *avctx) return 0; } +static void flush(AVCodecContext *avctx) +{ + BinkContext * const c = avctx->priv_data; + + c->frame_num = 0; +} + AVCodec ff_bink_decoder = { .name = "binkvideo", + .long_name = NULL_IF_CONFIG_SMALL("Bink video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_BINKVIDEO, .priv_data_size = sizeof(BinkContext), .init = decode_init, .close = decode_end, .decode = decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Bink video"), + .flush = flush, .capabilities = CODEC_CAP_DR1, }; diff --git a/ffmpeg/libavcodec/binkaudio.c b/ffmpeg/libavcodec/binkaudio.c index ef5569a..8db4533 100644 --- a/ffmpeg/libavcodec/binkaudio.c +++ b/ffmpeg/libavcodec/binkaudio.c @@ -36,10 +36,9 @@ #include "rdft.h" #include "fmtconvert.h" #include "internal.h" +#include "wma.h" #include "libavutil/intfloat.h" -extern const uint16_t ff_wma_critical_freqs[25]; - static float quant_table[96]; #define MAX_CHANNELS 2 @@ -309,7 +308,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, return AVERROR(ENOMEM); s->packet_buffer = buf; memcpy(s->packet_buffer, avpkt->data, avpkt->size); - init_get_bits(gb, s->packet_buffer, avpkt->size * 8); + if ((ret = init_get_bits8(gb, s->packet_buffer, avpkt->size)) < 0) + return ret; consumed = avpkt->size; /* skip reported size */ @@ -336,6 +336,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, AVCodec ff_binkaudio_rdft_decoder = { .name = "binkaudio_rdft", + .long_name = NULL_IF_CONFIG_SMALL("Bink Audio (RDFT)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_BINKAUDIO_RDFT, .priv_data_size = sizeof(BinkAudioContext), @@ -343,11 +344,11 @@ AVCodec ff_binkaudio_rdft_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DELAY | CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Bink Audio (RDFT)") }; AVCodec ff_binkaudio_dct_decoder = { .name = "binkaudio_dct", + .long_name = NULL_IF_CONFIG_SMALL("Bink Audio (DCT)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_BINKAUDIO_DCT, .priv_data_size = sizeof(BinkAudioContext), @@ -355,5 +356,4 @@ AVCodec ff_binkaudio_dct_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DELAY | CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Bink Audio (DCT)") }; diff --git a/ffmpeg/libavcodec/binkdata.h b/ffmpeg/libavcodec/binkdata.h index b9dc1f2..57619be 100644 --- a/ffmpeg/libavcodec/binkdata.h +++ b/ffmpeg/libavcodec/binkdata.h @@ -1,6 +1,6 @@ /* * Bink video decoder - * Copyright (C) 2009 Kostya Shishkov + * Copyright (C) 2009 Konstantin Shishkov * * This file is part of FFmpeg. * diff --git a/ffmpeg/libavcodec/binkdsp.c b/ffmpeg/libavcodec/binkdsp.c index c751743..a23f9c7 100644 --- a/ffmpeg/libavcodec/binkdsp.c +++ b/ffmpeg/libavcodec/binkdsp.c @@ -1,6 +1,6 @@ /* * Bink DSP routines - * Copyright (c) 2009 Kostya Shishkov + * Copyright (c) 2009 Konstantin Shishkov * * This file is part of FFmpeg. * @@ -24,6 +24,7 @@ * Bink DSP routines */ +#include "libavutil/attributes.h" #include "dsputil.h" #include "binkdsp.h" @@ -128,7 +129,7 @@ static void scale_block_c(const uint8_t src[64]/*align 8*/, uint8_t *dst/*align } } -void ff_binkdsp_init(BinkDSPContext *c) +av_cold void ff_binkdsp_init(BinkDSPContext *c) { c->idct_add = bink_idct_add_c; c->idct_put = bink_idct_put_c; diff --git a/ffmpeg/libavcodec/binkdsp.h b/ffmpeg/libavcodec/binkdsp.h index 4968413..6b84e01 100644 --- a/ffmpeg/libavcodec/binkdsp.h +++ b/ffmpeg/libavcodec/binkdsp.h @@ -1,21 +1,21 @@ /* * Bink DSP routines - * Copyright (c) 2009 Kostya Shishkov + * Copyright (c) 2009 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/bintext.c b/ffmpeg/libavcodec/bintext.c index f8059aa..97fceb1 100644 --- a/ffmpeg/libavcodec/bintext.c +++ b/ffmpeg/libavcodec/bintext.c @@ -220,6 +220,7 @@ static av_cold int decode_end(AVCodecContext *avctx) #if CONFIG_BINTEXT_DECODER AVCodec ff_bintext_decoder = { .name = "bintext", + .long_name = NULL_IF_CONFIG_SMALL("Binary text"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_BINTEXT, .priv_data_size = sizeof(XbinContext), @@ -227,12 +228,12 @@ AVCodec ff_bintext_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Binary text"), }; #endif #if CONFIG_XBIN_DECODER AVCodec ff_xbin_decoder = { .name = "xbin", + .long_name = NULL_IF_CONFIG_SMALL("eXtended BINary text"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_XBIN, .priv_data_size = sizeof(XbinContext), @@ -240,12 +241,12 @@ AVCodec ff_xbin_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("eXtended BINary text"), }; #endif #if CONFIG_IDF_DECODER AVCodec ff_idf_decoder = { .name = "idf", + .long_name = NULL_IF_CONFIG_SMALL("iCEDraw text"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_IDF, .priv_data_size = sizeof(XbinContext), @@ -253,6 +254,5 @@ AVCodec ff_idf_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("iCEDraw text"), }; #endif diff --git a/ffmpeg/libavcodec/bintext.h b/ffmpeg/libavcodec/bintext.h index ea834a0..21428ba 100644 --- a/ffmpeg/libavcodec/bintext.h +++ b/ffmpeg/libavcodec/bintext.h @@ -28,7 +28,7 @@ #define AVCODEC_BINTEXT_H /* flag values passed between avformat and avcodec; - * while these are identical to the XBIN flags, they are are also used + * while these are identical to the XBIN flags, they are also used * for the BINTEXT and IDF decoders. */ #define BINTEXT_PALETTE 0x1 diff --git a/ffmpeg/libavcodec/bit_depth_template.c b/ffmpeg/libavcodec/bit_depth_template.c index 1a6d007..96f5ede 100644 --- a/ffmpeg/libavcodec/bit_depth_template.c +++ b/ffmpeg/libavcodec/bit_depth_template.c @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/bitstream.c b/ffmpeg/libavcodec/bitstream.c index 6bcdadb..99119cd 100644 --- a/ffmpeg/libavcodec/bitstream.c +++ b/ffmpeg/libavcodec/bitstream.c @@ -28,6 +28,7 @@ * bitstream api. */ +#include "libavutil/atomic.h" #include "libavutil/avassert.h" #include "avcodec.h" #include "mathops.h" @@ -45,81 +46,87 @@ const uint8_t ff_log2_run[41]={ void avpriv_align_put_bits(PutBitContext *s) { - put_bits(s,s->bit_left & 7,0); + put_bits(s, s->bit_left & 7, 0); } -void avpriv_put_string(PutBitContext *pb, const char *string, int terminate_string) +void avpriv_put_string(PutBitContext *pb, const char *string, + int terminate_string) { - while(*string){ + while (*string) { put_bits(pb, 8, *string); string++; } - if(terminate_string) + if (terminate_string) put_bits(pb, 8, 0); } void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length) { - int words= length>>4; - int bits= length&15; + int words = length >> 4; + int bits = length & 15; int i; - if(length==0) return; + if (length == 0) + return; - if(CONFIG_SMALL || words < 16 || put_bits_count(pb)&7){ - for(i=0; i>(16-bits)); + put_bits(pb, bits, AV_RB16(src + 2 * words) >> (16 - bits)); } /* VLC decoding */ -#define GET_DATA(v, table, i, wrap, size) \ -{\ - const uint8_t *ptr = (const uint8_t *)table + i * wrap;\ - switch(size) {\ - case 1:\ - v = *(const uint8_t *)ptr;\ - break;\ - case 2:\ - v = *(const uint16_t *)ptr;\ - break;\ - default:\ - v = *(const uint32_t *)ptr;\ - break;\ - }\ +#define GET_DATA(v, table, i, wrap, size) \ +{ \ + const uint8_t *ptr = (const uint8_t *)table + i * wrap; \ + switch(size) { \ + case 1: \ + v = *(const uint8_t *)ptr; \ + break; \ + case 2: \ + v = *(const uint16_t *)ptr; \ + break; \ + default: \ + v = *(const uint32_t *)ptr; \ + break; \ + } \ } static int alloc_table(VLC *vlc, int size, int use_static) { - int index; - index = vlc->table_size; + int index = vlc->table_size; + vlc->table_size += size; if (vlc->table_size > vlc->table_allocated) { - if(use_static) + if (use_static) abort(); // cannot do anything, init_vlc() is used with too little memory vlc->table_allocated += (1 << vlc->bits); - vlc->table = av_realloc_f(vlc->table, - vlc->table_allocated, sizeof(VLC_TYPE) * 2); - if (!vlc->table) - return -1; + vlc->table = av_realloc_f(vlc->table, vlc->table_allocated, sizeof(VLC_TYPE) * 2); + if (!vlc->table) { + vlc->table_allocated = 0; + vlc->table_size = 0; + return AVERROR(ENOMEM); + } } return index; } -static av_always_inline uint32_t bitswap_32(uint32_t x) { - return (uint32_t)ff_reverse[x&0xFF]<<24 - | (uint32_t)ff_reverse[(x>>8)&0xFF]<<16 - | (uint32_t)ff_reverse[(x>>16)&0xFF]<<8 - | (uint32_t)ff_reverse[x>>24]; +static av_always_inline uint32_t bitswap_32(uint32_t x) +{ + return (uint32_t)ff_reverse[ x & 0xFF] << 24 | + (uint32_t)ff_reverse[(x >> 8) & 0xFF] << 16 | + (uint32_t)ff_reverse[(x >> 16) & 0xFF] << 8 | + (uint32_t)ff_reverse[ x >> 24]; } typedef struct { @@ -132,10 +139,9 @@ typedef struct { static int compare_vlcspec(const void *a, const void *b) { - const VLCcode *sa=a, *sb=b; + const VLCcode *sa = a, *sb = b; return (sa->code >> 1) - (sb->code >> 1); } - /** * Build VLC decoding tables suitable for use with get_vlc(). * @@ -164,7 +170,7 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes, table_index = alloc_table(vlc, table_size, flags & INIT_VLC_USE_NEW_STATIC); av_dlog(NULL, "new table index=%d size=%d\n", table_index, table_size); if (table_index < 0) - return -1; + return table_index; table = &vlc->table[table_index]; for (i = 0; i < table_size; i++) { @@ -174,8 +180,8 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes, /* first pass: map codes and compute auxiliary table sizes */ for (i = 0; i < nb_codes; i++) { - n = codes[i].bits; - code = codes[i].code; + n = codes[i].bits; + code = codes[i].code; symbol = codes[i].symbol; av_dlog(NULL, "i=%d n=%d code=0x%x\n", i, n, code); if (n <= table_nb_bits) { @@ -191,7 +197,7 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes, av_dlog(NULL, "%4x: code=%d n=%d\n", j, i, n); if (table[j][1] /*bits*/ != 0) { av_log(NULL, AV_LOG_ERROR, "incorrect codes\n"); - return -1; + return AVERROR_INVALIDDATA; } table[j][1] = n; //bits table[j][0] = symbol; @@ -222,7 +228,7 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes, j, codes[i].bits + table_nb_bits); index = build_table(vlc, subtable_bits, k-i, codes+i, flags); if (index < 0) - return -1; + return index; /* note: realloc has been done, so reload tables */ table = &vlc->table[table_index]; table[j][0] = index; //code @@ -260,61 +266,67 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes, with av_free_static(), 0 if ff_free_vlc() will be used. */ int ff_init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes, - const void *bits, int bits_wrap, int bits_size, - const void *codes, int codes_wrap, int codes_size, - const void *symbols, int symbols_wrap, int symbols_size, - int flags) + const void *bits, int bits_wrap, int bits_size, + const void *codes, int codes_wrap, int codes_size, + const void *symbols, int symbols_wrap, int symbols_size, + int flags) { VLCcode *buf; int i, j, ret; + VLCcode localbuf[1500]; // the maximum currently needed is 1296 by rv34 + void *state; vlc->bits = nb_bits; - if(flags & INIT_VLC_USE_NEW_STATIC){ - VLC dyn_vlc = *vlc; - - if (vlc->table_size) - return 0; - - ret = ff_init_vlc_sparse(&dyn_vlc, nb_bits, nb_codes, - bits, bits_wrap, bits_size, - codes, codes_wrap, codes_size, - symbols, symbols_wrap, symbols_size, - flags & ~INIT_VLC_USE_NEW_STATIC); - av_assert0(ret >= 0); - av_assert0(dyn_vlc.table_size <= vlc->table_allocated); - if(dyn_vlc.table_size < vlc->table_allocated) - av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", dyn_vlc.table_size, vlc->table_allocated); - memcpy(vlc->table, dyn_vlc.table, dyn_vlc.table_size * sizeof(*vlc->table)); - vlc->table_size = dyn_vlc.table_size; - ff_free_vlc(&dyn_vlc); - return 0; - }else { - vlc->table = NULL; + if (flags & INIT_VLC_USE_NEW_STATIC) { + while (state = avpriv_atomic_ptr_cas(&vlc->init_state, NULL, vlc)) { + if (state == vlc + 1) { + av_assert0(vlc->table_size && vlc->table_size == vlc->table_allocated); + return 0; + } + } + av_assert0(!vlc->table_size); + av_assert0(nb_codes + 1 <= FF_ARRAY_ELEMS(localbuf)); + buf = localbuf; + } else { + vlc->table = NULL; vlc->table_allocated = 0; - vlc->table_size = 0; - } + vlc->table_size = 0; - av_dlog(NULL, "build table nb_codes=%d\n", nb_codes); + buf = av_malloc((nb_codes + 1) * sizeof(VLCcode)); + if (!buf) + return AVERROR(ENOMEM); + } - buf = av_malloc((nb_codes+1)*sizeof(VLCcode)); av_assert0(symbols_size <= 2 || !symbols); j = 0; #define COPY(condition)\ - for (i = 0; i < nb_codes; i++) {\ - GET_DATA(buf[j].bits, bits, i, bits_wrap, bits_size);\ - if (!(condition))\ - continue;\ - GET_DATA(buf[j].code, codes, i, codes_wrap, codes_size);\ - if (flags & INIT_VLC_LE)\ - buf[j].code = bitswap_32(buf[j].code);\ - else\ - buf[j].code <<= 32 - buf[j].bits;\ - if (symbols)\ - GET_DATA(buf[j].symbol, symbols, i, symbols_wrap, symbols_size)\ - else\ - buf[j].symbol = i;\ - j++;\ + for (i = 0; i < nb_codes; i++) { \ + GET_DATA(buf[j].bits, bits, i, bits_wrap, bits_size); \ + if (!(condition)) \ + continue; \ + if (buf[j].bits > 3*nb_bits || buf[j].bits>32) { \ + av_log(NULL, AV_LOG_ERROR, "Too long VLC (%d) in init_vlc\n", buf[j].bits);\ + if (!(flags & INIT_VLC_USE_NEW_STATIC)) \ + av_free(buf); \ + return -1; \ + } \ + GET_DATA(buf[j].code, codes, i, codes_wrap, codes_size); \ + if (buf[j].code >= (1LL< nb_bits); // qsort is the slowest part of init_vlc, and could probably be improved or avoided @@ -324,10 +336,18 @@ int ff_init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes, ret = build_table(vlc, nb_bits, nb_codes, buf, flags); - av_free(buf); - if (ret < 0) { - av_freep(&vlc->table); - return -1; + if (flags & INIT_VLC_USE_NEW_STATIC) { + if(vlc->table_size != vlc->table_allocated) + av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", vlc->table_size, vlc->table_allocated); + state = avpriv_atomic_ptr_cas(&vlc->init_state, vlc, vlc+1); + av_assert0(state == vlc); + av_assert0(ret >= 0); + } else { + av_free(buf); + if (ret < 0) { + av_freep(&vlc->table); + return ret; + } } return 0; } diff --git a/ffmpeg/libavcodec/bitstream_filter.c b/ffmpeg/libavcodec/bitstream_filter.c index 328a9f6..3ee582f 100644 --- a/ffmpeg/libavcodec/bitstream_filter.c +++ b/ffmpeg/libavcodec/bitstream_filter.c @@ -21,37 +21,49 @@ #include #include "avcodec.h" +#include "libavutil/atomic.h" #include "libavutil/mem.h" -static AVBitStreamFilter *first_bitstream_filter= NULL; +static AVBitStreamFilter *first_bitstream_filter = NULL; -AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f){ - if(f) return f->next; - else return first_bitstream_filter; +AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f) +{ + if (f) + return f->next; + else + return first_bitstream_filter; } -void av_register_bitstream_filter(AVBitStreamFilter *bsf){ - bsf->next = first_bitstream_filter; - first_bitstream_filter= bsf; +void av_register_bitstream_filter(AVBitStreamFilter *bsf) +{ + do { + bsf->next = first_bitstream_filter; + } while(bsf->next != avpriv_atomic_ptr_cas((void * volatile *)&first_bitstream_filter, bsf->next, bsf)); } -AVBitStreamFilterContext *av_bitstream_filter_init(const char *name){ - AVBitStreamFilter *bsf= first_bitstream_filter; +AVBitStreamFilterContext *av_bitstream_filter_init(const char *name) +{ + AVBitStreamFilter *bsf = first_bitstream_filter; - while(bsf){ - if(!strcmp(name, bsf->name)){ - AVBitStreamFilterContext *bsfc= av_mallocz(sizeof(AVBitStreamFilterContext)); - bsfc->filter= bsf; - bsfc->priv_data = bsf->priv_data_size ? av_mallocz(bsf->priv_data_size) : NULL; + while (bsf) { + if (!strcmp(name, bsf->name)) { + AVBitStreamFilterContext *bsfc = + av_mallocz(sizeof(AVBitStreamFilterContext)); + bsfc->filter = bsf; + bsfc->priv_data = + bsf->priv_data_size ? av_mallocz(bsf->priv_data_size) : NULL; return bsfc; } - bsf= bsf->next; + bsf = bsf->next; } return NULL; } -void av_bitstream_filter_close(AVBitStreamFilterContext *bsfc){ - if(bsfc->filter->close) +void av_bitstream_filter_close(AVBitStreamFilterContext *bsfc) +{ + if (!bsfc) + return; + if (bsfc->filter->close) bsfc->filter->close(bsfc); av_freep(&bsfc->priv_data); av_parser_close(bsfc->parser); @@ -60,9 +72,11 @@ void av_bitstream_filter_close(AVBitStreamFilterContext *bsfc){ int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe){ - *poutbuf= (uint8_t *) buf; - *poutbuf_size= buf_size; - return bsfc->filter->filter(bsfc, avctx, args, poutbuf, poutbuf_size, buf, buf_size, keyframe); + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe) +{ + *poutbuf = (uint8_t *)buf; + *poutbuf_size = buf_size; + return bsfc->filter->filter(bsfc, avctx, args, poutbuf, poutbuf_size, + buf, buf_size, keyframe); } diff --git a/ffmpeg/libavcodec/bmp.c b/ffmpeg/libavcodec/bmp.c index a3bb1a7..404c47d 100644 --- a/ffmpeg/libavcodec/bmp.c +++ b/ffmpeg/libavcodec/bmp.c @@ -244,7 +244,7 @@ static int bmp_decode_frame(AVCodecContext *avctx, // OS/2 bitmap, 3 bytes per palette entry if ((hsize-ihsize-14) < (colors << 2)) { if ((hsize-ihsize-14) < colors * 3) { - av_log(avctx, AV_LOG_ERROR, "palette doesnt fit in packet\n"); + av_log(avctx, AV_LOG_ERROR, "palette doesn't fit in packet\n"); return AVERROR_INVALIDDATA; } for (i = 0; i < colors; i++) @@ -256,7 +256,7 @@ static int bmp_decode_frame(AVCodecContext *avctx, buf = buf0 + hsize; } if (comp == BMP_RLE4 || comp == BMP_RLE8) { - if (height < 0) { + if (comp == BMP_RLE8 && height < 0) { p->data[0] += p->linesize[0] * (avctx->height - 1); p->linesize[0] = -p->linesize[0]; } @@ -330,9 +330,9 @@ static int bmp_decode_frame(AVCodecContext *avctx, AVCodec ff_bmp_decoder = { .name = "bmp", + .long_name = NULL_IF_CONFIG_SMALL("BMP (Windows and OS/2 bitmap)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_BMP, .decode = bmp_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("BMP (Windows and OS/2 bitmap)"), }; diff --git a/ffmpeg/libavcodec/bmp.h b/ffmpeg/libavcodec/bmp.h index b24a1fa..fb21090 100644 --- a/ffmpeg/libavcodec/bmp.h +++ b/ffmpeg/libavcodec/bmp.h @@ -24,10 +24,6 @@ #include "avcodec.h" -typedef struct BMPContext { - AVFrame picture; -} BMPContext; - typedef enum { BMP_RGB =0, BMP_RLE8 =1, diff --git a/ffmpeg/libavcodec/bmpenc.c b/ffmpeg/libavcodec/bmpenc.c index bda6799..2a1956d 100644 --- a/ffmpeg/libavcodec/bmpenc.c +++ b/ffmpeg/libavcodec/bmpenc.c @@ -32,11 +32,6 @@ static const uint32_t rgb565_masks[] = { 0xF800, 0x07E0, 0x001F }; static const uint32_t rgb444_masks[] = { 0x0F00, 0x00F0, 0x000F }; static av_cold int bmp_encode_init(AVCodecContext *avctx){ - BMPContext *s = avctx->priv_data; - - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame = &s->picture; - switch (avctx->pix_fmt) { case AV_PIX_FMT_BGRA: avctx->bits_per_coded_sample = 32; @@ -62,26 +57,29 @@ static av_cold int bmp_encode_init(AVCodecContext *avctx){ break; default: av_log(avctx, AV_LOG_INFO, "unsupported pixel format\n"); - return -1; + return AVERROR(EINVAL); } + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + return 0; } static int bmp_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { - BMPContext *s = avctx->priv_data; - AVFrame * const p = &s->picture; + const AVFrame * const p = pict; int n_bytes_image, n_bytes_per_row, n_bytes, i, n, hsize, ret; const uint32_t *pal = NULL; uint32_t palette256[256]; int pad_bytes_per_row, pal_entries = 0, compression = BMP_RGB; int bit_count = avctx->bits_per_coded_sample; uint8_t *ptr, *buf; - *p = *pict; - p->pict_type= AV_PICTURE_TYPE_I; - p->key_frame= 1; + + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->key_frame = 1; switch (avctx->pix_fmt) { case AV_PIX_FMT_RGB444: compression = BMP_BITFIELDS; @@ -165,13 +163,20 @@ static int bmp_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return 0; } +static av_cold int bmp_encode_close(AVCodecContext *avctx) +{ + av_frame_free(&avctx->coded_frame); + return 0; +} + AVCodec ff_bmp_encoder = { .name = "bmp", + .long_name = NULL_IF_CONFIG_SMALL("BMP (Windows and OS/2 bitmap)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_BMP, - .priv_data_size = sizeof(BMPContext), .init = bmp_encode_init, .encode2 = bmp_encode_frame, + .close = bmp_encode_close, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGRA, AV_PIX_FMT_BGR24, AV_PIX_FMT_RGB565, AV_PIX_FMT_RGB555, AV_PIX_FMT_RGB444, @@ -179,5 +184,4 @@ AVCodec ff_bmp_encoder = { AV_PIX_FMT_MONOBLACK, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("BMP (Windows and OS/2 bitmap)"), }; diff --git a/ffmpeg/libavcodec/bmv.c b/ffmpeg/libavcodec/bmv.c index 2628e4a..baa1c8b 100644 --- a/ffmpeg/libavcodec/bmv.c +++ b/ffmpeg/libavcodec/bmv.c @@ -2,20 +2,20 @@ * Discworld II BMV video and audio decoder * Copyright (c) 2011 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -139,7 +139,7 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame, mode += 1 + advance_mode; if (mode >= 4) mode -= 3; - if (FFABS(dst_end - dst) < len) + if (len <= 0 || FFABS(dst_end - dst) < len) return AVERROR_INVALIDDATA; switch (mode) { case 1: @@ -340,21 +340,21 @@ static int bmv_aud_decode_frame(AVCodecContext *avctx, void *data, AVCodec ff_bmv_video_decoder = { .name = "bmv_video", + .long_name = NULL_IF_CONFIG_SMALL("Discworld II BMV video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_BMV_VIDEO, .priv_data_size = sizeof(BMVDecContext), .init = decode_init, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Discworld II BMV video"), }; AVCodec ff_bmv_audio_decoder = { .name = "bmv_audio", + .long_name = NULL_IF_CONFIG_SMALL("Discworld II BMV audio"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_BMV_AUDIO, .init = bmv_aud_decode_init, .decode = bmv_aud_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Discworld II BMV audio"), }; diff --git a/ffmpeg/libavcodec/brender_pix.c b/ffmpeg/libavcodec/brender_pix.c index b30b882..23a46cc 100644 --- a/ffmpeg/libavcodec/brender_pix.c +++ b/ffmpeg/libavcodec/brender_pix.c @@ -128,11 +128,8 @@ static int brpix_decode_frame(AVCodecContext *avctx, return AVERROR_PATCHWELCOME; } - if (av_image_check_size(hdr.width, hdr.height, 0, avctx) < 0) - return AVERROR_INVALIDDATA; - - if (hdr.width != avctx->width || hdr.height != avctx->height) - avcodec_set_dimensions(avctx, hdr.width, hdr.height); + if ((ret = ff_set_dimensions(avctx, hdr.width, hdr.height)) < 0) + return ret; if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; @@ -211,9 +208,9 @@ static int brpix_decode_frame(AVCodecContext *avctx, AVCodec ff_brender_pix_decoder = { .name = "brender_pix", + .long_name = NULL_IF_CONFIG_SMALL("BRender PIX image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_BRENDER_PIX, .decode = brpix_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("BRender PIX image"), }; diff --git a/ffmpeg/libavcodec/bytestream.h b/ffmpeg/libavcodec/bytestream.h index af7f75b..f245859 100644 --- a/ffmpeg/libavcodec/bytestream.h +++ b/ffmpeg/libavcodec/bytestream.h @@ -26,6 +26,7 @@ #include #include +#include "libavutil/avassert.h" #include "libavutil/common.h" #include "libavutil/intreadwrite.h" @@ -131,6 +132,7 @@ static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size) { + av_assert0(buf_size >= 0); g->buffer = buf; g->buffer_start = buf; g->buffer_end = buf + buf_size; @@ -140,6 +142,7 @@ static av_always_inline void bytestream2_init_writer(PutByteContext *p, uint8_t *buf, int buf_size) { + av_assert0(buf_size >= 0); p->buffer = buf; p->buffer_start = buf; p->buffer_end = buf + buf_size; diff --git a/ffmpeg/libavcodec/c93.c b/ffmpeg/libavcodec/c93.c index 9aaa3ee..ad3fa3b 100644 --- a/ffmpeg/libavcodec/c93.c +++ b/ffmpeg/libavcodec/c93.c @@ -24,7 +24,7 @@ #include "internal.h" typedef struct { - AVFrame pictures[2]; + AVFrame *pictures[2]; int currentpic; } C93DecoderContext; @@ -46,21 +46,27 @@ typedef enum { #define C93_HAS_PALETTE 0x01 #define C93_FIRST_FRAME 0x02 -static av_cold int decode_init(AVCodecContext *avctx) +static av_cold int decode_end(AVCodecContext *avctx) { - C93DecoderContext *s = avctx->priv_data; - avctx->pix_fmt = AV_PIX_FMT_PAL8; - avcodec_get_frame_defaults(&s->pictures[0]); - avcodec_get_frame_defaults(&s->pictures[1]); + C93DecoderContext * const c93 = avctx->priv_data; + + av_frame_free(&c93->pictures[0]); + av_frame_free(&c93->pictures[1]); + return 0; } -static av_cold int decode_end(AVCodecContext *avctx) +static av_cold int decode_init(AVCodecContext *avctx) { - C93DecoderContext * const c93 = avctx->priv_data; + C93DecoderContext *s = avctx->priv_data; + avctx->pix_fmt = AV_PIX_FMT_PAL8; - av_frame_unref(&c93->pictures[0]); - av_frame_unref(&c93->pictures[1]); + s->pictures[0] = av_frame_alloc(); + s->pictures[1] = av_frame_alloc(); + if (!s->pictures[0] || !s->pictures[1]) { + decode_end(avctx); + return AVERROR(ENOMEM); + } return 0; } @@ -121,12 +127,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; C93DecoderContext * const c93 = avctx->priv_data; - AVFrame * const newpic = &c93->pictures[c93->currentpic]; - AVFrame * const oldpic = &c93->pictures[c93->currentpic^1]; + AVFrame * const newpic = c93->pictures[c93->currentpic]; + AVFrame * const oldpic = c93->pictures[c93->currentpic^1]; GetByteContext gb; uint8_t *out; int stride, ret, i, x, y, b, bt = 0; + if ((ret = ff_set_dimensions(avctx, WIDTH, HEIGHT)) < 0) + return ret; + c93->currentpic ^= 1; if ((ret = ff_reget_buffer(avctx, newpic)) < 0) @@ -168,7 +177,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, case C93_4X4_FROM_PREV: for (j = 0; j < 8; j += 4) { for (i = 0; i < 8; i += 4) { - offset = bytestream2_get_le16(&gb); + int offset = bytestream2_get_le16(&gb); + int from_x = offset % WIDTH; + int from_y = offset / WIDTH; + if (block_type == C93_4X4_FROM_CURR && from_y == y+j && + (FFABS(from_x - x-i) < 4 || FFABS(from_x - x-i) > WIDTH-4)) { + avpriv_request_sample(avctx, "block overlap %d %d %d %d\n", from_x, x+i, from_y, y+j); + return AVERROR_INVALIDDATA; + } if ((ret = copy_block(avctx, &out[j*stride+i], copy_from, offset, 4, stride)) < 0) return ret; @@ -245,6 +261,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, AVCodec ff_c93_decoder = { .name = "c93", + .long_name = NULL_IF_CONFIG_SMALL("Interplay C93"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_C93, .priv_data_size = sizeof(C93DecoderContext), @@ -252,5 +269,4 @@ AVCodec ff_c93_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Interplay C93"), }; diff --git a/ffmpeg/libavcodec/cabac.c b/ffmpeg/libavcodec/cabac.c index 187b7dc..dff0a91 100644 --- a/ffmpeg/libavcodec/cabac.c +++ b/ffmpeg/libavcodec/cabac.c @@ -73,9 +73,6 @@ static const uint8_t lps_range[64][4]= { { 6, 8, 9, 11}, { 6, 7, 9, 10}, { 6, 7, 8, 9}, { 2, 2, 2, 2}, }; -static uint8_t h264_lps_state[2*64]; -static uint8_t h264_mps_state[2*64]; - static const uint8_t mps_state[64]= { 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16, @@ -140,33 +137,32 @@ void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size){ void ff_init_cabac_states(void) { int i, j; + static int initialized = 0; + + if (initialized) + return; for(i=0; i<64; i++){ for(j=0; j<4; j++){ //FIXME check if this is worth the 1 shift we save ff_h264_lps_range[j*2*64+2*i+0]= ff_h264_lps_range[j*2*64+2*i+1]= lps_range[i][j]; } - - ff_h264_mlps_state[128+2*i+0]= - h264_mps_state[2 * i + 0] = 2 * mps_state[i] + 0; - ff_h264_mlps_state[128+2*i+1]= - h264_mps_state[2 * i + 1] = 2 * mps_state[i] + 1; + ff_h264_mlps_state[128 + 2 * i + 0] = 2 * mps_state[i] + 0; + ff_h264_mlps_state[128 + 2 * i + 1] = 2 * mps_state[i] + 1; if( i ){ - h264_lps_state[2*i+0]= ff_h264_mlps_state[128-2*i-1]= 2*lps_state[i]+0; - h264_lps_state[2*i+1]= ff_h264_mlps_state[128-2*i-2]= 2*lps_state[i]+1; }else{ - h264_lps_state[2*i+0]= ff_h264_mlps_state[128-2*i-1]= 1; - h264_lps_state[2*i+1]= ff_h264_mlps_state[128-2*i-2]= 0; } } for(i=0; i< 63; i++){ ff_h264_last_coeff_flag_offset_8x8[i] = last_coeff_flag_offset_8x8[i]; } + + initialized = 1; } #ifdef TEST @@ -174,7 +170,6 @@ void ff_init_cabac_states(void) #include "libavutil/lfg.h" #include "avcodec.h" -#include "cabac.h" static inline void put_cabac_bit(CABACContext *c, int b){ put_bits(&c->pb, 1, b); @@ -206,11 +201,11 @@ static void put_cabac(CABACContext *c, uint8_t * const state, int bit){ if(bit == ((*state)&1)){ c->range -= RangeLPS; - *state = h264_mps_state[*state]; + *state = ff_h264_mlps_state[128 + *state]; }else{ c->low += c->range - RangeLPS; c->range = RangeLPS; - *state= h264_lps_state[*state]; + *state= ff_h264_mlps_state[127 - *state]; } renorm_cabac_encoder(c); @@ -306,7 +301,7 @@ STOP_TIMER("get_cabac_bypass") for(i=0; ilow+= c->bytestream[0]<<1; #endif c->low -= CABAC_MASK; - c->bytestream += CABAC_BITS / 8; +#if !UNCHECKED_BITSTREAM_READER + if (c->bytestream < c->bytestream_end) +#endif + c->bytestream += CABAC_BITS / 8; } static inline void renorm_cabac_decoder_once(CABACContext *c){ @@ -76,7 +79,10 @@ static void refill2(CABACContext *c){ #endif c->low += x<bytestream += CABAC_BITS/8; +#if !UNCHECKED_BITSTREAM_READER + if (c->bytestream < c->bytestream_end) +#endif + c->bytestream += CABAC_BITS/8; } static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){ @@ -111,6 +117,7 @@ static int av_unused get_cabac(CABACContext *c, uint8_t * const state){ return get_cabac_inline(c,state); } +#ifndef get_cabac_bypass static int av_unused get_cabac_bypass(CABACContext *c){ int range; c->low += c->low; @@ -126,7 +133,7 @@ static int av_unused get_cabac_bypass(CABACContext *c){ return 1; } } - +#endif #ifndef get_cabac_bypass_sign static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){ @@ -159,4 +166,24 @@ static int av_unused get_cabac_terminate(CABACContext *c){ } } +/** + * Skip @p n bytes and reset the decoder. + * @return the address of the first skipped byte or NULL if there's less than @p n bytes left + */ +static av_unused const uint8_t* skip_bytes(CABACContext *c, int n) { + const uint8_t *ptr = c->bytestream; + + if (c->low & 0x1) + ptr--; +#if CABAC_BITS == 16 + if (c->low & 0x1FF) + ptr--; +#endif + if ((int) (c->bytestream_end - ptr) < n) + return NULL; + ff_init_cabac_decoder(c, ptr + n, c->bytestream_end - ptr - n); + + return ptr; +} + #endif /* AVCODEC_CABAC_FUNCTIONS_H */ diff --git a/ffmpeg/libavcodec/cavs.c b/ffmpeg/libavcodec/cavs.c index dffd6cc..cc54429 100644 --- a/ffmpeg/libavcodec/cavs.c +++ b/ffmpeg/libavcodec/cavs.c @@ -33,28 +33,28 @@ #include "cavs.h" static const uint8_t alpha_tab[64] = { - 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, - 4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 20, - 22, 24, 26, 28, 30, 33, 33, 35, 35, 36, 37, 37, 39, 39, 42, 44, - 46, 48, 50, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64 + 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, + 4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 20, + 22, 24, 26, 28, 30, 33, 33, 35, 35, 36, 37, 37, 39, 39, 42, 44, + 46, 48, 50, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64 }; static const uint8_t beta_tab[64] = { - 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, - 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, - 6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 27 + 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, + 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, + 6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 27 }; static const uint8_t tc_tab[64] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, - 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, - 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, + 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, + 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9 }; /** mark block as unavailable, i.e. out of picture - or not yet decoded */ + * or not yet decoded */ static const cavs_vector un_mv = { 0, 0, 1, NOT_AVAIL }; static const int8_t left_modifier_l[8] = { 0, -1, 6, -1, -1, 7, 6, 7 }; @@ -77,7 +77,7 @@ static inline int get_bs(cavs_vector *mvP, cavs_vector *mvQ, int b) if (b) { mvP += MV_BWD_OFFS; mvQ += MV_BWD_OFFS; - if ((abs(mvP->x - mvQ->x) >= 4) || (abs(mvP->y - mvQ->y) >= 4)) + if ((abs(mvP->x - mvQ->x) >= 4) || (abs(mvP->y - mvQ->y) >= 4)) return 1; } else { if (mvP->ref != mvQ->ref) @@ -126,7 +126,7 @@ void ff_cavs_filter(AVSContext *h, enum cavs_mb mb_type) /* determine bs */ if (mb_type == I_8X8) memset(bs, 2, 8); - else{ + else { memset(bs, 0, 8); if (ff_cavs_partition_flags[mb_type] & SPLITV) { bs[2] = get_bs(&h->mv[MV_FWD_X0], &h->mv[MV_FWD_X1], mb_type > P_8X8); @@ -229,31 +229,30 @@ void ff_cavs_load_intra_pred_luma(AVSContext *h, uint8_t *top, void ff_cavs_load_intra_pred_chroma(AVSContext *h) { /* extend borders by one pixel */ - h->left_border_u[9] = h->left_border_u[8]; - h->left_border_v[9] = h->left_border_v[8]; + h->left_border_u[9] = h->left_border_u[8]; + h->left_border_v[9] = h->left_border_v[8]; h->top_border_u[h->mbx * 10 + 9] = h->top_border_u[h->mbx * 10 + 8]; h->top_border_v[h->mbx * 10 + 9] = h->top_border_v[h->mbx * 10 + 8]; if (h->mbx && h->mby) { h->top_border_u[h->mbx * 10] = h->left_border_u[0] = h->topleft_border_u; h->top_border_v[h->mbx * 10] = h->left_border_v[0] = h->topleft_border_v; } else { - h->left_border_u[0] = h->left_border_u[1]; - h->left_border_v[0] = h->left_border_v[1]; + h->left_border_u[0] = h->left_border_u[1]; + h->left_border_v[0] = h->left_border_v[1]; h->top_border_u[h->mbx * 10] = h->top_border_u[h->mbx * 10 + 1]; h->top_border_v[h->mbx * 10] = h->top_border_v[h->mbx * 10 + 1]; } } -static void intra_pred_vert(uint8_t *d,uint8_t *top,uint8_t *left,int stride) +static void intra_pred_vert(uint8_t *d, uint8_t *top, uint8_t *left, int stride) { int y; uint64_t a = AV_RN64(&top[1]); - for (y = 0; y < 8; y++) { + for (y = 0; y < 8; y++) *((uint64_t *)(d + y * stride)) = a; - } } -static void intra_pred_horiz(uint8_t *d,uint8_t *top,uint8_t *left,int stride) +static void intra_pred_horiz(uint8_t *d, uint8_t *top, uint8_t *left, int stride) { int y; uint64_t a; @@ -263,7 +262,7 @@ static void intra_pred_horiz(uint8_t *d,uint8_t *top,uint8_t *left,int stride) } } -static void intra_pred_dc_128(uint8_t *d,uint8_t *top,uint8_t *left,int stride) +static void intra_pred_dc_128(uint8_t *d, uint8_t *top, uint8_t *left, int stride) { int y; uint64_t a = 0x8080808080808080ULL; @@ -271,15 +270,15 @@ static void intra_pred_dc_128(uint8_t *d,uint8_t *top,uint8_t *left,int stride) *((uint64_t *)(d + y * stride)) = a; } -static void intra_pred_plane(uint8_t *d,uint8_t *top,uint8_t *left,int stride) +static void intra_pred_plane(uint8_t *d, uint8_t *top, uint8_t *left, int stride) { int x, y, ia; int ih = 0; int iv = 0; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; for (x = 0; x < 4; x++) { - ih += (x + 1) * (top [5 + x] - top [3 - x]); + ih += (x + 1) * (top[5 + x] - top[3 - x]); iv += (x + 1) * (left[5 + x] - left[3 - x]); } ia = (top[8] + left[8]) << 4; @@ -290,10 +289,10 @@ static void intra_pred_plane(uint8_t *d,uint8_t *top,uint8_t *left,int stride) d[y * stride + x] = cm[(ia + (x - 3) * ih + (y - 3) * iv + 16) >> 5]; } -#define LOWPASS(ARRAY,INDEX) \ +#define LOWPASS(ARRAY, INDEX) \ ((ARRAY[(INDEX) - 1] + 2 * ARRAY[(INDEX)] + ARRAY[(INDEX) + 1] + 2) >> 2) -static void intra_pred_lp(uint8_t *d,uint8_t *top,uint8_t *left,int stride) +static void intra_pred_lp(uint8_t *d, uint8_t *top, uint8_t *left, int stride) { int x, y; for (y = 0; y < 8; y++) @@ -301,7 +300,7 @@ static void intra_pred_lp(uint8_t *d,uint8_t *top,uint8_t *left,int stride) d[y * stride + x] = (LOWPASS(top, x + 1) + LOWPASS(left, y + 1)) >> 1; } -static void intra_pred_down_left(uint8_t *d,uint8_t *top,uint8_t *left,int stride) +static void intra_pred_down_left(uint8_t *d, uint8_t *top, uint8_t *left, int stride) { int x, y; for (y = 0; y < 8; y++) @@ -309,7 +308,7 @@ static void intra_pred_down_left(uint8_t *d,uint8_t *top,uint8_t *left,int strid d[y * stride + x] = (LOWPASS(top, x + y + 2) + LOWPASS(left, x + y + 2)) >> 1; } -static void intra_pred_down_right(uint8_t *d,uint8_t *top,uint8_t *left,int stride) +static void intra_pred_down_right(uint8_t *d, uint8_t *top, uint8_t *left, int stride) { int x, y; for (y = 0; y < 8; y++) @@ -322,7 +321,7 @@ static void intra_pred_down_right(uint8_t *d,uint8_t *top,uint8_t *left,int stri d[y * stride + x] = LOWPASS(left, y - x); } -static void intra_pred_lp_left(uint8_t *d,uint8_t *top,uint8_t *left,int stride) +static void intra_pred_lp_left(uint8_t *d, uint8_t *top, uint8_t *left, int stride) { int x, y; for (y = 0; y < 8; y++) @@ -330,7 +329,7 @@ static void intra_pred_lp_left(uint8_t *d,uint8_t *top,uint8_t *left,int stride) d[y * stride + x] = LOWPASS(left, y + 1); } -static void intra_pred_lp_top(uint8_t *d,uint8_t *top,uint8_t *left,int stride) +static void intra_pred_lp_top(uint8_t *d, uint8_t *top, uint8_t *left, int stride) { int x, y; for (y = 0; y < 8; y++) @@ -352,8 +351,8 @@ static inline void modify_pred(const int8_t *mod_table, int *mode) void ff_cavs_modify_mb_i(AVSContext *h, int *pred_mode_uv) { /* save pred modes before they get modified */ - h->pred_mode_Y[3] = h->pred_mode_Y[5]; - h->pred_mode_Y[6] = h->pred_mode_Y[8]; + h->pred_mode_Y[3] = h->pred_mode_Y[5]; + h->pred_mode_Y[6] = h->pred_mode_Y[8]; h->top_pred_Y[h->mbx * 2 + 0] = h->pred_mode_Y[7]; h->top_pred_Y[h->mbx * 2 + 1] = h->pred_mode_Y[8]; @@ -376,124 +375,144 @@ void ff_cavs_modify_mb_i(AVSContext *h, int *pred_mode_uv) * ****************************************************************************/ -static inline void mc_dir_part(AVSContext *h, AVFrame *pic, - int chroma_height,int delta,int list,uint8_t *dest_y, - uint8_t *dest_cb,uint8_t *dest_cr,int src_x_offset, - int src_y_offset,qpel_mc_func *qpix_op, - h264_chroma_mc_func chroma_op,cavs_vector *mv) +static inline void mc_dir_part(AVSContext *h, AVFrame *pic, int chroma_height, + int delta, int list, uint8_t *dest_y, + uint8_t *dest_cb, uint8_t *dest_cr, + int src_x_offset, int src_y_offset, + qpel_mc_func *qpix_op, + h264_chroma_mc_func chroma_op, cavs_vector *mv) { - const int mx= mv->x + src_x_offset*8; - const int my= mv->y + src_y_offset*8; - const int luma_xy= (mx&3) + ((my&3)<<2); - uint8_t * src_y = pic->data[0] + (mx >> 2) + (my >> 2) * h->l_stride; - uint8_t * src_cb = pic->data[1] + (mx >> 3) + (my >> 3) * h->c_stride; - uint8_t * src_cr = pic->data[2] + (mx >> 3) + (my >> 3) * h->c_stride; - int extra_width = 0; - int extra_height= extra_width; - int emu=0; - const int full_mx= mx>>2; - const int full_my= my>>2; - const int pic_width = 16*h->mb_width; - const int pic_height = 16*h->mb_height; + const int mx = mv->x + src_x_offset * 8; + const int my = mv->y + src_y_offset * 8; + const int luma_xy = (mx & 3) + ((my & 3) << 2); + uint8_t *src_y = pic->data[0] + (mx >> 2) + (my >> 2) * h->l_stride; + uint8_t *src_cb = pic->data[1] + (mx >> 3) + (my >> 3) * h->c_stride; + uint8_t *src_cr = pic->data[2] + (mx >> 3) + (my >> 3) * h->c_stride; + int extra_width = 0; + int extra_height = extra_width; + const int full_mx = mx >> 2; + const int full_my = my >> 2; + const int pic_width = 16 * h->mb_width; + const int pic_height = 16 * h->mb_height; + int emu = 0; if (!pic->data[0]) return; - if(mx&7) extra_width -= 3; - if(my&7) extra_height -= 3; - - if( full_mx < 0-extra_width - || full_my < 0-extra_height - || full_mx + 16/*FIXME*/ > pic_width + extra_width - || full_my + 16/*FIXME*/ > pic_height + extra_height){ - h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_y - 2 - 2*h->l_stride, h->l_stride, - 16+5, 16+5/*FIXME*/, full_mx-2, full_my-2, pic_width, pic_height); - src_y= h->edge_emu_buffer + 2 + 2*h->l_stride; - emu=1; + if (mx & 7) + extra_width -= 3; + if (my & 7) + extra_height -= 3; + + if (full_mx < 0 - extra_width || + full_my < 0 - extra_height || + full_mx + 16 /* FIXME */ > pic_width + extra_width || + full_my + 16 /* FIXME */ > pic_height + extra_height) { + h->vdsp.emulated_edge_mc(h->edge_emu_buffer, + src_y - 2 - 2 * h->l_stride, + h->l_stride, h->l_stride, + 16 + 5, 16 + 5 /* FIXME */, + full_mx - 2, full_my - 2, + pic_width, pic_height); + src_y = h->edge_emu_buffer + 2 + 2 * h->l_stride; + emu = 1; } - qpix_op[luma_xy](dest_y, src_y, h->l_stride); //FIXME try variable height perhaps? + // FIXME try variable height perhaps? + qpix_op[luma_xy](dest_y, src_y, h->l_stride); - if(emu){ - h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cb, h->c_stride, - 9, 9/*FIXME*/, (mx>>3), (my>>3), pic_width>>1, pic_height>>1); - src_cb= h->edge_emu_buffer; + if (emu) { + h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cb, + h->c_stride, h->c_stride, + 9, 9 /* FIXME */, + mx >> 3, my >> 3, + pic_width >> 1, pic_height >> 1); + src_cb = h->edge_emu_buffer; } - chroma_op(dest_cb, src_cb, h->c_stride, chroma_height, mx&7, my&7); - - if(emu){ - h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cr, h->c_stride, - 9, 9/*FIXME*/, (mx>>3), (my>>3), pic_width>>1, pic_height>>1); - src_cr= h->edge_emu_buffer; + chroma_op(dest_cb, src_cb, h->c_stride, chroma_height, mx & 7, my & 7); + + if (emu) { + h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cr, + h->c_stride, h->c_stride, + 9, 9 /* FIXME */, + mx >> 3, my >> 3, + pic_width >> 1, pic_height >> 1); + src_cr = h->edge_emu_buffer; } - chroma_op(dest_cr, src_cr, h->c_stride, chroma_height, mx&7, my&7); + chroma_op(dest_cr, src_cr, h->c_stride, chroma_height, mx & 7, my & 7); } -static inline void mc_part_std(AVSContext *h,int chroma_height,int delta, - uint8_t *dest_y,uint8_t *dest_cb,uint8_t *dest_cr, - int x_offset, int y_offset,qpel_mc_func *qpix_put, - h264_chroma_mc_func chroma_put,qpel_mc_func *qpix_avg, - h264_chroma_mc_func chroma_avg, cavs_vector *mv) +static inline void mc_part_std(AVSContext *h, int chroma_height, int delta, + uint8_t *dest_y, + uint8_t *dest_cb, + uint8_t *dest_cr, + int x_offset, int y_offset, + qpel_mc_func *qpix_put, + h264_chroma_mc_func chroma_put, + qpel_mc_func *qpix_avg, + h264_chroma_mc_func chroma_avg, + cavs_vector *mv) { - qpel_mc_func *qpix_op= qpix_put; - h264_chroma_mc_func chroma_op= chroma_put; + qpel_mc_func *qpix_op = qpix_put; + h264_chroma_mc_func chroma_op = chroma_put; - dest_y += 2*x_offset + 2*y_offset*h->l_stride; - dest_cb += x_offset + y_offset*h->c_stride; - dest_cr += x_offset + y_offset*h->c_stride; - x_offset += 8*h->mbx; - y_offset += 8*h->mby; + dest_y += x_offset * 2 + y_offset * h->l_stride * 2; + dest_cb += x_offset + y_offset * h->c_stride; + dest_cr += x_offset + y_offset * h->c_stride; + x_offset += 8 * h->mbx; + y_offset += 8 * h->mby; - if(mv->ref >= 0){ + if (mv->ref >= 0) { AVFrame *ref = h->DPB[mv->ref].f; mc_dir_part(h, ref, chroma_height, delta, 0, dest_y, dest_cb, dest_cr, x_offset, y_offset, qpix_op, chroma_op, mv); - qpix_op= qpix_avg; - chroma_op= chroma_avg; + qpix_op = qpix_avg; + chroma_op = chroma_avg; } - if((mv+MV_BWD_OFFS)->ref >= 0){ + if ((mv + MV_BWD_OFFS)->ref >= 0) { AVFrame *ref = h->DPB[0].f; mc_dir_part(h, ref, chroma_height, delta, 1, dest_y, dest_cb, dest_cr, x_offset, y_offset, - qpix_op, chroma_op, mv+MV_BWD_OFFS); + qpix_op, chroma_op, mv + MV_BWD_OFFS); } } -void ff_cavs_inter(AVSContext *h, enum cavs_mb mb_type) { - if(ff_cavs_partition_flags[mb_type] == 0){ // 16x16 +void ff_cavs_inter(AVSContext *h, enum cavs_mb mb_type) +{ + if (ff_cavs_partition_flags[mb_type] == 0) { // 16x16 mc_part_std(h, 8, 0, h->cy, h->cu, h->cv, 0, 0, - h->cdsp.put_cavs_qpel_pixels_tab[0], - h->h264chroma.put_h264_chroma_pixels_tab[0], - h->cdsp.avg_cavs_qpel_pixels_tab[0], - h->h264chroma.avg_h264_chroma_pixels_tab[0], - &h->mv[MV_FWD_X0]); - }else{ + h->cdsp.put_cavs_qpel_pixels_tab[0], + h->h264chroma.put_h264_chroma_pixels_tab[0], + h->cdsp.avg_cavs_qpel_pixels_tab[0], + h->h264chroma.avg_h264_chroma_pixels_tab[0], + &h->mv[MV_FWD_X0]); + } else { mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 0, 0, - h->cdsp.put_cavs_qpel_pixels_tab[1], - h->h264chroma.put_h264_chroma_pixels_tab[1], - h->cdsp.avg_cavs_qpel_pixels_tab[1], - h->h264chroma.avg_h264_chroma_pixels_tab[1], - &h->mv[MV_FWD_X0]); + h->cdsp.put_cavs_qpel_pixels_tab[1], + h->h264chroma.put_h264_chroma_pixels_tab[1], + h->cdsp.avg_cavs_qpel_pixels_tab[1], + h->h264chroma.avg_h264_chroma_pixels_tab[1], + &h->mv[MV_FWD_X0]); mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 4, 0, - h->cdsp.put_cavs_qpel_pixels_tab[1], - h->h264chroma.put_h264_chroma_pixels_tab[1], - h->cdsp.avg_cavs_qpel_pixels_tab[1], - h->h264chroma.avg_h264_chroma_pixels_tab[1], - &h->mv[MV_FWD_X1]); + h->cdsp.put_cavs_qpel_pixels_tab[1], + h->h264chroma.put_h264_chroma_pixels_tab[1], + h->cdsp.avg_cavs_qpel_pixels_tab[1], + h->h264chroma.avg_h264_chroma_pixels_tab[1], + &h->mv[MV_FWD_X1]); mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 0, 4, - h->cdsp.put_cavs_qpel_pixels_tab[1], - h->h264chroma.put_h264_chroma_pixels_tab[1], - h->cdsp.avg_cavs_qpel_pixels_tab[1], - h->h264chroma.avg_h264_chroma_pixels_tab[1], - &h->mv[MV_FWD_X2]); + h->cdsp.put_cavs_qpel_pixels_tab[1], + h->h264chroma.put_h264_chroma_pixels_tab[1], + h->cdsp.avg_cavs_qpel_pixels_tab[1], + h->h264chroma.avg_h264_chroma_pixels_tab[1], + &h->mv[MV_FWD_X2]); mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 4, 4, - h->cdsp.put_cavs_qpel_pixels_tab[1], - h->h264chroma.put_h264_chroma_pixels_tab[1], - h->cdsp.avg_cavs_qpel_pixels_tab[1], - h->h264chroma.avg_h264_chroma_pixels_tab[1], - &h->mv[MV_FWD_X3]); + h->cdsp.put_cavs_qpel_pixels_tab[1], + h->h264chroma.put_h264_chroma_pixels_tab[1], + h->cdsp.avg_cavs_qpel_pixels_tab[1], + h->h264chroma.avg_h264_chroma_pixels_tab[1], + &h->mv[MV_FWD_X3]); } } @@ -503,15 +522,21 @@ void ff_cavs_inter(AVSContext *h, enum cavs_mb mb_type) { * ****************************************************************************/ -static inline void scale_mv(AVSContext *h, int *d_x, int *d_y, cavs_vector *src, int distp) { +static inline void scale_mv(AVSContext *h, int *d_x, int *d_y, + cavs_vector *src, int distp) +{ int den = h->scale_den[src->ref]; - *d_x = (src->x*distp*den + 256 + (src->x>>31)) >> 9; - *d_y = (src->y*distp*den + 256 + (src->y>>31)) >> 9; + *d_x = (src->x * distp * den + 256 + (src->x >> 31)) >> 9; + *d_y = (src->y * distp * den + 256 + (src->y >> 31)) >> 9; } -static inline void mv_pred_median(AVSContext *h, cavs_vector *mvP, - cavs_vector *mvA, cavs_vector *mvB, cavs_vector *mvC) { +static inline void mv_pred_median(AVSContext *h, + cavs_vector *mvP, + cavs_vector *mvA, + cavs_vector *mvB, + cavs_vector *mvC) +{ int ax, ay, bx, by, cx, cy; int len_ab, len_bc, len_ca, len_mid; @@ -520,14 +545,14 @@ static inline void mv_pred_median(AVSContext *h, cavs_vector *mvP, scale_mv(h, &bx, &by, mvB, mvP->dist); scale_mv(h, &cx, &cy, mvC, mvP->dist); /* find the geometrical median of the three candidates */ - len_ab = abs(ax - bx) + abs(ay - by); - len_bc = abs(bx - cx) + abs(by - cy); - len_ca = abs(cx - ax) + abs(cy - ay); + len_ab = abs(ax - bx) + abs(ay - by); + len_bc = abs(bx - cx) + abs(by - cy); + len_ca = abs(cx - ax) + abs(cy - ay); len_mid = mid_pred(len_ab, len_bc, len_ca); - if(len_mid == len_ab) { + if (len_mid == len_ab) { mvP->x = cx; mvP->y = cy; - } else if(len_mid == len_bc) { + } else if (len_mid == len_bc) { mvP->x = ax; mvP->y = ay; } else { @@ -537,47 +562,49 @@ static inline void mv_pred_median(AVSContext *h, cavs_vector *mvP, } void ff_cavs_mv(AVSContext *h, enum cavs_mv_loc nP, enum cavs_mv_loc nC, - enum cavs_mv_pred mode, enum cavs_block size, int ref) { + enum cavs_mv_pred mode, enum cavs_block size, int ref) +{ cavs_vector *mvP = &h->mv[nP]; cavs_vector *mvA = &h->mv[nP-1]; cavs_vector *mvB = &h->mv[nP-4]; cavs_vector *mvC = &h->mv[nC]; const cavs_vector *mvP2 = NULL; - mvP->ref = ref; + mvP->ref = ref; mvP->dist = h->dist[mvP->ref]; - if(mvC->ref == NOT_AVAIL) - mvC = &h->mv[nP-5]; // set to top-left (mvD) - if((mode == MV_PRED_PSKIP) && - ((mvA->ref == NOT_AVAIL) || (mvB->ref == NOT_AVAIL) || - ((mvA->x | mvA->y | mvA->ref) == 0) || - ((mvB->x | mvB->y | mvB->ref) == 0) )) { + if (mvC->ref == NOT_AVAIL) + mvC = &h->mv[nP - 5]; // set to top-left (mvD) + if (mode == MV_PRED_PSKIP && + (mvA->ref == NOT_AVAIL || + mvB->ref == NOT_AVAIL || + (mvA->x | mvA->y | mvA->ref) == 0 || + (mvB->x | mvB->y | mvB->ref) == 0)) { mvP2 = &un_mv; /* if there is only one suitable candidate, take it */ - } else if((mvA->ref >= 0) && (mvB->ref < 0) && (mvC->ref < 0)) { - mvP2= mvA; - } else if((mvA->ref < 0) && (mvB->ref >= 0) && (mvC->ref < 0)) { - mvP2= mvB; - } else if((mvA->ref < 0) && (mvB->ref < 0) && (mvC->ref >= 0)) { - mvP2= mvC; - } else if(mode == MV_PRED_LEFT && mvA->ref == ref){ - mvP2= mvA; - } else if(mode == MV_PRED_TOP && mvB->ref == ref){ - mvP2= mvB; - } else if(mode == MV_PRED_TOPRIGHT && mvC->ref == ref){ - mvP2= mvC; + } else if (mvA->ref >= 0 && mvB->ref < 0 && mvC->ref < 0) { + mvP2 = mvA; + } else if (mvA->ref < 0 && mvB->ref >= 0 && mvC->ref < 0) { + mvP2 = mvB; + } else if (mvA->ref < 0 && mvB->ref < 0 && mvC->ref >= 0) { + mvP2 = mvC; + } else if (mode == MV_PRED_LEFT && mvA->ref == ref) { + mvP2 = mvA; + } else if (mode == MV_PRED_TOP && mvB->ref == ref) { + mvP2 = mvB; + } else if (mode == MV_PRED_TOPRIGHT && mvC->ref == ref) { + mvP2 = mvC; } - if(mvP2){ + if (mvP2) { mvP->x = mvP2->x; mvP->y = mvP2->y; - }else + } else mv_pred_median(h, mvP, mvA, mvB, mvC); - if(mode < MV_PRED_PSKIP) { + if (mode < MV_PRED_PSKIP) { mvP->x += get_se_golomb(&h->gb); mvP->y += get_se_golomb(&h->gb); } - set_mvs(mvP,size); + set_mvs(mvP, size); } /***************************************************************************** @@ -589,36 +616,37 @@ void ff_cavs_mv(AVSContext *h, enum cavs_mv_loc nP, enum cavs_mv_loc nC, /** * initialise predictors for motion vectors and intra prediction */ -void ff_cavs_init_mb(AVSContext *h) { +void ff_cavs_init_mb(AVSContext *h) +{ int i; /* copy predictors from top line (MB B and C) into cache */ - for(i=0;i<3;i++) { - h->mv[MV_FWD_B2+i] = h->top_mv[0][h->mbx*2+i]; - h->mv[MV_BWD_B2+i] = h->top_mv[1][h->mbx*2+i]; + for (i = 0; i < 3; i++) { + h->mv[MV_FWD_B2 + i] = h->top_mv[0][h->mbx * 2 + i]; + h->mv[MV_BWD_B2 + i] = h->top_mv[1][h->mbx * 2 + i]; } - h->pred_mode_Y[1] = h->top_pred_Y[h->mbx*2+0]; - h->pred_mode_Y[2] = h->top_pred_Y[h->mbx*2+1]; + h->pred_mode_Y[1] = h->top_pred_Y[h->mbx * 2 + 0]; + h->pred_mode_Y[2] = h->top_pred_Y[h->mbx * 2 + 1]; /* clear top predictors if MB B is not available */ - if(!(h->flags & B_AVAIL)) { - h->mv[MV_FWD_B2] = un_mv; - h->mv[MV_FWD_B3] = un_mv; - h->mv[MV_BWD_B2] = un_mv; - h->mv[MV_BWD_B3] = un_mv; + if (!(h->flags & B_AVAIL)) { + h->mv[MV_FWD_B2] = un_mv; + h->mv[MV_FWD_B3] = un_mv; + h->mv[MV_BWD_B2] = un_mv; + h->mv[MV_BWD_B3] = un_mv; h->pred_mode_Y[1] = h->pred_mode_Y[2] = NOT_AVAIL; - h->flags &= ~(C_AVAIL|D_AVAIL); - } else if(h->mbx) { + h->flags &= ~(C_AVAIL | D_AVAIL); + } else if (h->mbx) { h->flags |= D_AVAIL; } - if(h->mbx == h->mb_width-1) //MB C not available + if (h->mbx == h->mb_width - 1) // MB C not available h->flags &= ~C_AVAIL; /* clear top-right predictors if MB C is not available */ - if(!(h->flags & C_AVAIL)) { + if (!(h->flags & C_AVAIL)) { h->mv[MV_FWD_C2] = un_mv; h->mv[MV_BWD_C2] = un_mv; } /* clear top-left predictors if MB D is not available */ - if(!(h->flags & D_AVAIL)) { + if (!(h->flags & D_AVAIL)) { h->mv[MV_FWD_D3] = un_mv; h->mv[MV_BWD_D3] = un_mv; } @@ -629,38 +657,39 @@ void ff_cavs_init_mb(AVSContext *h) { * macroblock address * @return 0 if end of frame is reached, 1 otherwise */ -int ff_cavs_next_mb(AVSContext *h) { +int ff_cavs_next_mb(AVSContext *h) +{ int i; h->flags |= A_AVAIL; - h->cy += 16; - h->cu += 8; - h->cv += 8; + h->cy += 16; + h->cu += 8; + h->cv += 8; /* copy mvs as predictors to the left */ - for(i=0;i<=20;i+=4) - h->mv[i] = h->mv[i+2]; + for (i = 0; i <= 20; i += 4) + h->mv[i] = h->mv[i + 2]; /* copy bottom mvs from cache to top line */ - h->top_mv[0][h->mbx*2+0] = h->mv[MV_FWD_X2]; - h->top_mv[0][h->mbx*2+1] = h->mv[MV_FWD_X3]; - h->top_mv[1][h->mbx*2+0] = h->mv[MV_BWD_X2]; - h->top_mv[1][h->mbx*2+1] = h->mv[MV_BWD_X3]; + h->top_mv[0][h->mbx * 2 + 0] = h->mv[MV_FWD_X2]; + h->top_mv[0][h->mbx * 2 + 1] = h->mv[MV_FWD_X3]; + h->top_mv[1][h->mbx * 2 + 0] = h->mv[MV_BWD_X2]; + h->top_mv[1][h->mbx * 2 + 1] = h->mv[MV_BWD_X3]; /* next MB address */ h->mbidx++; h->mbx++; - if(h->mbx == h->mb_width) { //new mb line - h->flags = B_AVAIL|C_AVAIL; + if (h->mbx == h->mb_width) { // New mb line + h->flags = B_AVAIL | C_AVAIL; /* clear left pred_modes */ h->pred_mode_Y[3] = h->pred_mode_Y[6] = NOT_AVAIL; /* clear left mv predictors */ - for(i=0;i<=20;i+=4) + for (i = 0; i <= 20; i += 4) h->mv[i] = un_mv; h->mbx = 0; h->mby++; /* re-calculate sample pointers */ h->cy = h->cur.f->data[0] + h->mby * 16 * h->l_stride; - h->cu = h->cur.f->data[1] + h->mby * 8 * h->c_stride; - h->cv = h->cur.f->data[2] + h->mby * 8 * h->c_stride; - if(h->mby == h->mb_height) { //frame end + h->cu = h->cur.f->data[1] + h->mby * 8 * h->c_stride; + h->cv = h->cur.f->data[2] + h->mby * 8 * h->c_stride; + if (h->mby == h->mb_height) { // Frame end return 0; } } @@ -673,26 +702,27 @@ int ff_cavs_next_mb(AVSContext *h) { * ****************************************************************************/ -int ff_cavs_init_pic(AVSContext *h) { +int ff_cavs_init_pic(AVSContext *h) +{ int i; /* clear some predictors */ - for(i=0;i<=20;i+=4) + for (i = 0; i <= 20; i += 4) h->mv[i] = un_mv; h->mv[MV_BWD_X0] = ff_cavs_dir_mv; set_mvs(&h->mv[MV_BWD_X0], BLK_16X16); h->mv[MV_FWD_X0] = ff_cavs_dir_mv; set_mvs(&h->mv[MV_FWD_X0], BLK_16X16); h->pred_mode_Y[3] = h->pred_mode_Y[6] = NOT_AVAIL; - h->cy = h->cur.f->data[0]; - h->cu = h->cur.f->data[1]; - h->cv = h->cur.f->data[2]; - h->l_stride = h->cur.f->linesize[0]; - h->c_stride = h->cur.f->linesize[1]; - h->luma_scan[2] = 8*h->l_stride; - h->luma_scan[3] = 8*h->l_stride+8; - h->mbx = h->mby = h->mbidx = 0; - h->flags = 0; + h->cy = h->cur.f->data[0]; + h->cu = h->cur.f->data[1]; + h->cv = h->cur.f->data[2]; + h->l_stride = h->cur.f->linesize[0]; + h->c_stride = h->cur.f->linesize[1]; + h->luma_scan[2] = 8 * h->l_stride; + h->luma_scan[3] = 8 * h->l_stride + 8; + h->mbx = h->mby = h->mbidx = 0; + h->flags = 0; return 0; } @@ -708,23 +738,26 @@ int ff_cavs_init_pic(AVSContext *h) { * this data has to be stored for one complete row of macroblocks * and this storage space is allocated here */ -void ff_cavs_init_top_lines(AVSContext *h) { +void ff_cavs_init_top_lines(AVSContext *h) +{ /* alloc top line of predictors */ - h->top_qp = av_mallocz( h->mb_width); - h->top_mv[0] = av_mallocz((h->mb_width*2+1)*sizeof(cavs_vector)); - h->top_mv[1] = av_mallocz((h->mb_width*2+1)*sizeof(cavs_vector)); - h->top_pred_Y = av_mallocz( h->mb_width*2*sizeof(*h->top_pred_Y)); - h->top_border_y = av_mallocz((h->mb_width+1)*16); - h->top_border_u = av_mallocz( h->mb_width * 10); - h->top_border_v = av_mallocz( h->mb_width * 10); + h->top_qp = av_mallocz(h->mb_width); + h->top_mv[0] = av_mallocz((h->mb_width * 2 + 1) * sizeof(cavs_vector)); + h->top_mv[1] = av_mallocz((h->mb_width * 2 + 1) * sizeof(cavs_vector)); + h->top_pred_Y = av_mallocz(h->mb_width * 2 * sizeof(*h->top_pred_Y)); + h->top_border_y = av_mallocz((h->mb_width + 1) * 16); + h->top_border_u = av_mallocz(h->mb_width * 10); + h->top_border_v = av_mallocz(h->mb_width * 10); /* alloc space for co-located MVs and types */ - h->col_mv = av_mallocz( h->mb_width*h->mb_height*4*sizeof(cavs_vector)); - h->col_type_base = av_mallocz(h->mb_width*h->mb_height); - h->block = av_mallocz(64*sizeof(int16_t)); + h->col_mv = av_mallocz(h->mb_width * h->mb_height * 4 * + sizeof(cavs_vector)); + h->col_type_base = av_mallocz(h->mb_width * h->mb_height); + h->block = av_mallocz(64 * sizeof(int16_t)); } -av_cold int ff_cavs_init(AVCodecContext *avctx) { +av_cold int ff_cavs_init(AVCodecContext *avctx) +{ AVSContext *h = avctx->priv_data; ff_dsputil_init(&h->dsp, avctx); @@ -735,8 +768,8 @@ av_cold int ff_cavs_init(AVCodecContext *avctx) { h->cdsp.idct_perm); ff_init_scantable(h->dsp.idct_permutation, &h->scantable, ff_zigzag_direct); - h->avctx = avctx; - avctx->pix_fmt= AV_PIX_FMT_YUV420P; + h->avctx = avctx; + avctx->pix_fmt = AV_PIX_FMT_YUV420P; h->cur.f = av_frame_alloc(); h->DPB[0].f = av_frame_alloc(); @@ -746,29 +779,30 @@ av_cold int ff_cavs_init(AVCodecContext *avctx) { return AVERROR(ENOMEM); } - h->luma_scan[0] = 0; - h->luma_scan[1] = 8; - h->intra_pred_l[ INTRA_L_VERT] = intra_pred_vert; - h->intra_pred_l[ INTRA_L_HORIZ] = intra_pred_horiz; - h->intra_pred_l[ INTRA_L_LP] = intra_pred_lp; - h->intra_pred_l[ INTRA_L_DOWN_LEFT] = intra_pred_down_left; + h->luma_scan[0] = 0; + h->luma_scan[1] = 8; + h->intra_pred_l[INTRA_L_VERT] = intra_pred_vert; + h->intra_pred_l[INTRA_L_HORIZ] = intra_pred_horiz; + h->intra_pred_l[INTRA_L_LP] = intra_pred_lp; + h->intra_pred_l[INTRA_L_DOWN_LEFT] = intra_pred_down_left; h->intra_pred_l[INTRA_L_DOWN_RIGHT] = intra_pred_down_right; - h->intra_pred_l[ INTRA_L_LP_LEFT] = intra_pred_lp_left; - h->intra_pred_l[ INTRA_L_LP_TOP] = intra_pred_lp_top; - h->intra_pred_l[ INTRA_L_DC_128] = intra_pred_dc_128; - h->intra_pred_c[ INTRA_C_LP] = intra_pred_lp; - h->intra_pred_c[ INTRA_C_HORIZ] = intra_pred_horiz; - h->intra_pred_c[ INTRA_C_VERT] = intra_pred_vert; - h->intra_pred_c[ INTRA_C_PLANE] = intra_pred_plane; - h->intra_pred_c[ INTRA_C_LP_LEFT] = intra_pred_lp_left; - h->intra_pred_c[ INTRA_C_LP_TOP] = intra_pred_lp_top; - h->intra_pred_c[ INTRA_C_DC_128] = intra_pred_dc_128; - h->mv[ 7] = un_mv; - h->mv[19] = un_mv; + h->intra_pred_l[INTRA_L_LP_LEFT] = intra_pred_lp_left; + h->intra_pred_l[INTRA_L_LP_TOP] = intra_pred_lp_top; + h->intra_pred_l[INTRA_L_DC_128] = intra_pred_dc_128; + h->intra_pred_c[INTRA_C_LP] = intra_pred_lp; + h->intra_pred_c[INTRA_C_HORIZ] = intra_pred_horiz; + h->intra_pred_c[INTRA_C_VERT] = intra_pred_vert; + h->intra_pred_c[INTRA_C_PLANE] = intra_pred_plane; + h->intra_pred_c[INTRA_C_LP_LEFT] = intra_pred_lp_left; + h->intra_pred_c[INTRA_C_LP_TOP] = intra_pred_lp_top; + h->intra_pred_c[INTRA_C_DC_128] = intra_pred_dc_128; + h->mv[7] = un_mv; + h->mv[19] = un_mv; return 0; } -av_cold int ff_cavs_end(AVCodecContext *avctx) { +av_cold int ff_cavs_end(AVCodecContext *avctx) +{ AVSContext *h = avctx->priv_data; av_frame_free(&h->cur.f); diff --git a/ffmpeg/libavcodec/cavs.h b/ffmpeg/libavcodec/cavs.h index b0cdb8f..f3c05dc 100644 --- a/ffmpeg/libavcodec/cavs.h +++ b/ffmpeg/libavcodec/cavs.h @@ -210,7 +210,7 @@ typedef struct AVSContext { 6: A3 X2 X3 */ int pred_mode_Y[3*3]; int *top_pred_Y; - int l_stride, c_stride; + ptrdiff_t l_stride, c_stride; int luma_scan[4]; int qp; int qp_fixed; diff --git a/ffmpeg/libavcodec/cavsdata.h b/ffmpeg/libavcodec/cavsdata.h deleted file mode 100644 index 67fae3c..0000000 --- a/ffmpeg/libavcodec/cavsdata.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Chinese AVS video (AVS1-P2, JiZhun profile) decoder. - * Copyright (c) 2006 Stefan Gehrer - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_CAVSDATA_H -#define AVCODEC_CAVSDATA_H - -#include "cavs.h" - -const uint8_t ff_cavs_partition_flags[30] = { - 0, //I_8X8 - 0, //P_SKIP - 0, //P_16X16 - SPLITH, //P_16X8 - SPLITV, //P_8X16 - SPLITH|SPLITV, //P_8X8 - SPLITH|SPLITV, //B_SKIP - SPLITH|SPLITV, //B_DIRECT - 0, //B_FWD_16X16 - 0, //B_BWD_16X16 - 0, //B_SYM_16X16 - FWD0|FWD1 |SPLITH, - FWD0|FWD1 |SPLITV, - BWD0|BWD1 |SPLITH, - BWD0|BWD1 |SPLITV, - FWD0|BWD1 |SPLITH, - FWD0|BWD1 |SPLITV, - BWD0|FWD1 |SPLITH, - BWD0|FWD1 |SPLITV, - FWD0|FWD1 |SYM1|SPLITH, - FWD0|FWD1 |SYM1 |SPLITV, - BWD0|FWD1 |SYM1|SPLITH, - BWD0|FWD1 |SYM1 |SPLITV, - FWD0|FWD1|SYM0 |SPLITH, - FWD0|FWD1|SYM0 |SPLITV, - FWD0|BWD1|SYM0 |SPLITH, - FWD0|BWD1|SYM0 |SPLITV, - FWD0|FWD1|SYM0|SYM1|SPLITH, - FWD0|FWD1|SYM0|SYM1 |SPLITV, - SPLITH|SPLITV, //B_8X8 = 29 -}; - -/** mark block as "no prediction from this direction" - e.g. forward motion vector in BWD partition */ -const cavs_vector ff_cavs_dir_mv = {0,0,1,REF_DIR}; - -/** mark block as using intra prediction */ -const cavs_vector ff_cavs_intra_mv = {0,0,1,REF_INTRA}; - -#endif /* AVCODEC_CAVSDATA_H */ diff --git a/ffmpeg/libavcodec/cavsdec.c b/ffmpeg/libavcodec/cavsdec.c index 2ef3eb3..44d0ec0 100644 --- a/ffmpeg/libavcodec/cavsdec.c +++ b/ffmpeg/libavcodec/cavsdec.c @@ -535,7 +535,7 @@ static inline int dequant(AVSContext *h, int16_t *level_buf, uint8_t *run_buf, av_log(h->avctx, AV_LOG_ERROR, "position out of block bounds at pic %d MB(%d,%d)\n", h->cur.poc, h->mbx, h->mby); - return -1; + return AVERROR_INVALIDDATA; } dst[scantab[pos]] = (level_buf[coeff_num] * mul + round) >> shift; } @@ -555,7 +555,7 @@ static int decode_residual_block(AVSContext *h, GetBitContext *gb, const struct dec_2dvlc *r, int esc_golomb_order, int qp, uint8_t *dst, int stride) { - int i, esc_code, level, mask; + int i, esc_code, level, mask, ret; unsigned int level_code, run; int16_t level_buf[65]; uint8_t run_buf[65]; @@ -565,8 +565,10 @@ static int decode_residual_block(AVSContext *h, GetBitContext *gb, level_code = get_ue_code(gb, r->golomb_order); if (level_code >= ESCAPE_CODE) { run = ((level_code - ESCAPE_CODE) >> 1) + 1; - if(run > 64) - return -1; + if(run > 64) { + av_log(h->avctx, AV_LOG_ERROR, "run %d is too large\n", run); + return AVERROR_INVALIDDATA; + } esc_code = get_ue_code(gb, esc_golomb_order); level = esc_code + (run > r->max_run ? 1 : r->level_add[run]); while (level > r->inc_limit) @@ -583,9 +585,9 @@ static int decode_residual_block(AVSContext *h, GetBitContext *gb, level_buf[i] = level; run_buf[i] = run; } - if (dequant(h, level_buf, run_buf, block, dequant_mul[qp], - dequant_shift[qp], i)) - return -1; + if ((ret = dequant(h, level_buf, run_buf, block, dequant_mul[qp], + dequant_shift[qp], i)) < 0) + return ret; h->cdsp.cavs_idct8_add(dst, block, stride); h->dsp.clear_block(block); return 0; @@ -609,8 +611,8 @@ static inline int decode_residual_inter(AVSContext *h) /* get coded block pattern */ int cbp = get_ue_golomb(&h->gb); if (cbp > 63U) { - av_log(h->avctx, AV_LOG_ERROR, "illegal inter cbp\n"); - return -1; + av_log(h->avctx, AV_LOG_ERROR, "illegal inter cbp %d\n", cbp); + return AVERROR_INVALIDDATA; } h->cbp = cbp_tab[cbp][1]; @@ -672,7 +674,7 @@ static int decode_mb_i(AVSContext *h, int cbp_code) pred_mode_uv = get_ue_golomb(gb); if (pred_mode_uv > 6) { av_log(h->avctx, AV_LOG_ERROR, "illegal intra chroma pred mode\n"); - return -1; + return AVERROR_INVALIDDATA; } ff_cavs_modify_mb_i(h, &pred_mode_uv); @@ -681,7 +683,7 @@ static int decode_mb_i(AVSContext *h, int cbp_code) cbp_code = get_ue_golomb(gb); if (cbp_code > 63U) { av_log(h->avctx, AV_LOG_ERROR, "illegal intra cbp\n"); - return -1; + return AVERROR_INVALIDDATA; } h->cbp = cbp_tab[cbp_code][0]; if (h->cbp && !h->qp_fixed) @@ -892,8 +894,10 @@ static inline int decode_slice_header(AVSContext *h, GetBitContext *gb) if (h->stc > 0xAF) av_log(h->avctx, AV_LOG_ERROR, "unexpected start code 0x%02x\n", h->stc); - if (h->stc >= h->mb_height) - return -1; + if (h->stc >= h->mb_height) { + av_log(h->avctx, AV_LOG_ERROR, "stc 0x%02x is too large\n", h->stc); + return AVERROR_INVALIDDATA; + } h->mby = h->stc; h->mbidx = h->mby * h->mb_width; @@ -948,6 +952,11 @@ static int decode_pic(AVSContext *h) int ret; enum cavs_mb mb_type; + if (!h->top_qp) { + av_log(h->avctx, AV_LOG_ERROR, "No sequence header decoded yet\n"); + return AVERROR_INVALIDDATA; + } + av_frame_unref(h->cur.f); skip_bits(&h->gb, 16);//bbv_dwlay @@ -955,12 +964,12 @@ static int decode_pic(AVSContext *h) h->cur.f->pict_type = get_bits(&h->gb, 2) + AV_PICTURE_TYPE_I; if (h->cur.f->pict_type > AV_PICTURE_TYPE_B) { av_log(h->avctx, AV_LOG_ERROR, "illegal picture type\n"); - return -1; + return AVERROR_INVALIDDATA; } /* make sure we have the reference frames we need */ if (!h->DPB[0].f->data[0] || (!h->DPB[1].f->data[0] && h->cur.f->pict_type == AV_PICTURE_TYPE_B)) - return -1; + return AVERROR_INVALIDDATA; } else { h->cur.f->pict_type = AV_PICTURE_TYPE_I; if (get_bits1(&h->gb)) @@ -1156,12 +1165,17 @@ static int cavs_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return 0; } + h->stc = 0; + buf_ptr = buf; buf_end = buf + buf_size; for(;;) { - buf_ptr = avpriv_mpv_find_start_code(buf_ptr, buf_end, &stc); - if ((stc & 0xFFFFFE00) || buf_ptr == buf_end) + buf_ptr = avpriv_find_start_code(buf_ptr, buf_end, &stc); + if ((stc & 0xFFFFFE00) || buf_ptr == buf_end) { + if (!h->stc) + av_log(h->avctx, AV_LOG_WARNING, "no frame decoded\n"); return FFMAX(0, buf_ptr - buf); + } input_size = (buf_end - buf_ptr) * 8; switch (stc) { case CAVS_START_CODE: @@ -1178,8 +1192,6 @@ static int cavs_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, *got_frame = 0; if (!h->got_keyframe) break; - if(!h->top_qp) - break; init_get_bits(&h->gb, buf_ptr, input_size); h->stc = stc; if (decode_pic(h)) @@ -1214,6 +1226,7 @@ static int cavs_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVCodec ff_cavs_decoder = { .name = "cavs", + .long_name = NULL_IF_CONFIG_SMALL("Chinese AVS (Audio Video Standard) (AVS1-P2, JiZhun profile)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_CAVS, .priv_data_size = sizeof(AVSContext), @@ -1222,5 +1235,4 @@ AVCodec ff_cavs_decoder = { .decode = cavs_decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY, .flush = cavs_flush, - .long_name = NULL_IF_CONFIG_SMALL("Chinese AVS (Audio Video Standard) (AVS1-P2, JiZhun profile)"), }; diff --git a/ffmpeg/libavcodec/cavsdsp.c b/ffmpeg/libavcodec/cavsdsp.c index 904e2df..61283c2 100644 --- a/ffmpeg/libavcodec/cavsdsp.c +++ b/ffmpeg/libavcodec/cavsdsp.c @@ -186,7 +186,7 @@ static void cavs_filter_ch_c(uint8_t *d, int stride, int alpha, int beta, int tc static void cavs_idct8_add_c(uint8_t *dst, int16_t *block, int stride) { int i; int16_t (*src)[8] = (int16_t(*)[8])block; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; src[0][0] += 8; @@ -261,7 +261,7 @@ static void cavs_idct8_add_c(uint8_t *dst, int16_t *block, int stride) { #define CAVS_SUBPIX(OPNAME, OP, NAME, A, B, C, D, E, F) \ static void OPNAME ## cavs_filt8_h_ ## NAME(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ const int h=8;\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ int i;\ for(i=0; iPFX ## _pixels_tab[IDX][ 0] = ff_ ## PFX ## NUM ## _mc00_c; \ - c->PFX ## _pixels_tab[IDX][ 1] = ff_ ## PFX ## NUM ## _mc10_c; \ - c->PFX ## _pixels_tab[IDX][ 2] = ff_ ## PFX ## NUM ## _mc20_c; \ - c->PFX ## _pixels_tab[IDX][ 3] = ff_ ## PFX ## NUM ## _mc30_c; \ - c->PFX ## _pixels_tab[IDX][ 4] = ff_ ## PFX ## NUM ## _mc01_c; \ - c->PFX ## _pixels_tab[IDX][ 5] = ff_ ## PFX ## NUM ## _mc11_c; \ - c->PFX ## _pixels_tab[IDX][ 6] = ff_ ## PFX ## NUM ## _mc21_c; \ - c->PFX ## _pixels_tab[IDX][ 7] = ff_ ## PFX ## NUM ## _mc31_c; \ - c->PFX ## _pixels_tab[IDX][ 8] = ff_ ## PFX ## NUM ## _mc02_c; \ - c->PFX ## _pixels_tab[IDX][ 9] = ff_ ## PFX ## NUM ## _mc12_c; \ - c->PFX ## _pixels_tab[IDX][10] = ff_ ## PFX ## NUM ## _mc22_c; \ - c->PFX ## _pixels_tab[IDX][11] = ff_ ## PFX ## NUM ## _mc32_c; \ - c->PFX ## _pixels_tab[IDX][12] = ff_ ## PFX ## NUM ## _mc03_c; \ - c->PFX ## _pixels_tab[IDX][13] = ff_ ## PFX ## NUM ## _mc13_c; \ - c->PFX ## _pixels_tab[IDX][14] = ff_ ## PFX ## NUM ## _mc23_c; \ - c->PFX ## _pixels_tab[IDX][15] = ff_ ## PFX ## NUM ## _mc33_c + c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_c; \ + c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_c; \ + c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_c; \ + c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_c; \ + c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_c; \ + c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_c; \ + c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_c; \ + c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_c; \ + c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_c; \ + c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_c; \ + c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_c; \ + c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_c; \ + c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_c; \ + c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_c; \ + c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_c; \ + c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_c dspfunc(put_cavs_qpel, 0, 16); dspfunc(put_cavs_qpel, 1, 8); dspfunc(avg_cavs_qpel, 0, 16); diff --git a/ffmpeg/libavcodec/cbrt_tablegen.h b/ffmpeg/libavcodec/cbrt_tablegen.h index a9d34dc..0db64fc 100644 --- a/ffmpeg/libavcodec/cbrt_tablegen.h +++ b/ffmpeg/libavcodec/cbrt_tablegen.h @@ -36,12 +36,13 @@ static void cbrt_tableinit(void) { if (!cbrt_tab[(1<<13) - 1]) { int i; + /* cbrtf() isn't available on all systems, so we use powf(). */ for (i = 0; i < 1<<13; i++) { union { float f; uint32_t i; } f; - f.f = cbrtf(i) * i; + f.f = pow(i, 1.0 / 3.0) * i; cbrt_tab[i] = f.i; } } diff --git a/ffmpeg/libavcodec/cdgraphics.c b/ffmpeg/libavcodec/cdgraphics.c index d22e9f6..b7a8fa7 100644 --- a/ffmpeg/libavcodec/cdgraphics.c +++ b/ffmpeg/libavcodec/cdgraphics.c @@ -265,7 +265,7 @@ static int cdg_decode_frame(AVCodecContext *avctx, int buf_size = avpkt->size; int ret; uint8_t command, inst; - uint8_t cdg_data[CDG_DATA_SIZE]; + uint8_t cdg_data[CDG_DATA_SIZE] = {0}; AVFrame *frame = data; CDGraphicsContext *cc = avctx->priv_data; @@ -289,7 +289,9 @@ static int cdg_decode_frame(AVCodecContext *avctx, inst = bytestream_get_byte(&buf); inst &= CDG_MASK; buf += 2; /// skipping 2 unneeded bytes - bytestream_get_buffer(&buf, cdg_data, buf_size - CDG_HEADER_SIZE); + + if (buf_size > CDG_HEADER_SIZE) + bytestream_get_buffer(&buf, cdg_data, buf_size - CDG_HEADER_SIZE); if ((command & CDG_MASK) == CDG_COMMAND) { switch (inst) { @@ -368,6 +370,7 @@ static av_cold int cdg_decode_end(AVCodecContext *avctx) AVCodec ff_cdgraphics_decoder = { .name = "cdgraphics", + .long_name = NULL_IF_CONFIG_SMALL("CD Graphics video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_CDGRAPHICS, .priv_data_size = sizeof(CDGraphicsContext), @@ -375,5 +378,4 @@ AVCodec ff_cdgraphics_decoder = { .close = cdg_decode_end, .decode = cdg_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("CD Graphics video"), }; diff --git a/ffmpeg/libavcodec/cdxl.c b/ffmpeg/libavcodec/cdxl.c index 7e7b7bc..13ad57c 100644 --- a/ffmpeg/libavcodec/cdxl.c +++ b/ffmpeg/libavcodec/cdxl.c @@ -19,6 +19,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +/** + * @file + * Commodore CDXL video decoder + * @author Paul B Mahol + */ + #define UNCHECKED_BITSTREAM_READER 1 #include "libavutil/intreadwrite.h" @@ -239,10 +245,8 @@ static int cdxl_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_PATCHWELCOME; } - if ((ret = av_image_check_size(w, h, 0, avctx)) < 0) + if ((ret = ff_set_dimensions(avctx, w, h)) < 0) return ret; - if (w != avctx->width || h != avctx->height) - avcodec_set_dimensions(avctx, w, h); aligned_width = FFALIGN(c->avctx->width, 16); c->padded_bits = aligned_width - c->avctx->width; @@ -285,13 +289,14 @@ static av_cold int cdxl_decode_end(AVCodecContext *avctx) { CDXLVideoContext *c = avctx->priv_data; - av_free(c->new_video); + av_freep(&c->new_video); return 0; } AVCodec ff_cdxl_decoder = { .name = "cdxl", + .long_name = NULL_IF_CONFIG_SMALL("Commodore CDXL video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_CDXL, .priv_data_size = sizeof(CDXLVideoContext), @@ -299,5 +304,4 @@ AVCodec ff_cdxl_decoder = { .close = cdxl_decode_end, .decode = cdxl_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Commodore CDXL video"), }; diff --git a/ffmpeg/libavcodec/chomp_bsf.c b/ffmpeg/libavcodec/chomp_bsf.c index eaefaaa..2b93fa9 100644 --- a/ffmpeg/libavcodec/chomp_bsf.c +++ b/ffmpeg/libavcodec/chomp_bsf.c @@ -41,7 +41,6 @@ static int chomp_filter(AVBitStreamFilterContext *bsfc, * This filter removes a string of NULL bytes from the end of a packet. */ AVBitStreamFilter ff_chomp_bsf = { - "chomp", - 0, - chomp_filter, + .name = "chomp", + .filter = chomp_filter, }; diff --git a/ffmpeg/libavcodec/cinepak.c b/ffmpeg/libavcodec/cinepak.c index f5bc113..082d0b2 100644 --- a/ffmpeg/libavcodec/cinepak.c +++ b/ffmpeg/libavcodec/cinepak.c @@ -477,6 +477,7 @@ static av_cold int cinepak_decode_end(AVCodecContext *avctx) AVCodec ff_cinepak_decoder = { .name = "cinepak", + .long_name = NULL_IF_CONFIG_SMALL("Cinepak"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_CINEPAK, .priv_data_size = sizeof(CinepakContext), @@ -484,5 +485,4 @@ AVCodec ff_cinepak_decoder = { .close = cinepak_decode_end, .decode = cinepak_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Cinepak"), }; diff --git a/ffmpeg/libavcodec/cljr.c b/ffmpeg/libavcodec/cljr.c index 2120864..7e0773b 100644 --- a/ffmpeg/libavcodec/cljr.c +++ b/ffmpeg/libavcodec/cljr.c @@ -87,28 +87,33 @@ static av_cold int decode_init(AVCodecContext *avctx) AVCodec ff_cljr_decoder = { .name = "cljr", + .long_name = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_CLJR, .init = decode_init, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"), }; #endif #if CONFIG_CLJR_ENCODER typedef struct CLJRContext { AVClass *avclass; - AVFrame picture; int dither_type; } CLJRContext; static av_cold int encode_init(AVCodecContext *avctx) { - CLJRContext * const a = avctx->priv_data; + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); - avctx->coded_frame = &a->picture; + return 0; +} +static av_cold int encode_close(AVCodecContext *avctx) +{ + av_frame_free(&avctx->coded_frame); return 0; } @@ -168,7 +173,7 @@ static const AVOption options[] = { { NULL }, }; -static const AVClass class = { +static const AVClass cljr_class = { .class_name = "cljr encoder", .item_name = av_default_item_name, .option = options, @@ -177,14 +182,15 @@ static const AVClass class = { AVCodec ff_cljr_encoder = { .name = "cljr", + .long_name = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_CLJR, .priv_data_size = sizeof(CLJRContext), .init = encode_init, .encode2 = encode_frame, + .close = encode_close, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV411P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"), - .priv_class = &class, + .priv_class = &cljr_class, }; #endif diff --git a/ffmpeg/libavcodec/cllc.c b/ffmpeg/libavcodec/cllc.c index 6378c79..ee77381 100644 --- a/ffmpeg/libavcodec/cllc.c +++ b/ffmpeg/libavcodec/cllc.c @@ -1,7 +1,7 @@ /* * Canopus Lossless Codec decoder * - * Copyright (c) 2012 Derek Buitenhuis + * Copyright (c) 2012-2013 Derek Buitenhuis * * This file is part of FFmpeg. * @@ -136,14 +136,13 @@ static int read_argb_line(CLLCContext *ctx, GetBitContext *gb, int *top_left, CLOSE_READER(bits, gb); - dst -= 4 * ctx->avctx->width; - top_left[0] = dst[0]; + top_left[0] = outbuf[0]; /* Only stash components if they are not transparent */ if (top_left[0]) { - top_left[1] = dst[1]; - top_left[2] = dst[2]; - top_left[3] = dst[3]; + top_left[1] = outbuf[1]; + top_left[2] = outbuf[2]; + top_left[3] = outbuf[3]; } return 0; @@ -174,7 +173,35 @@ static int read_rgb24_component_line(CLLCContext *ctx, GetBitContext *gb, CLOSE_READER(bits, gb); /* Stash the first pixel */ - *top_left = dst[-3 * ctx->avctx->width]; + *top_left = outbuf[0]; + + return 0; +} + +static int read_yuv_component_line(CLLCContext *ctx, GetBitContext *gb, + int *top_left, VLC *vlc, uint8_t *outbuf, + int is_chroma) +{ + int pred, code; + int i; + + OPEN_READER(bits, gb); + + pred = *top_left; + + /* Simultaneously read and restore the line */ + for (i = 0; i < ctx->avctx->width >> is_chroma; i++) { + UPDATE_CACHE(bits, gb); + GET_VLC(code, bits, gb, vlc->table, 7, 2); + + pred += code; + outbuf[i] = pred; + } + + CLOSE_READER(bits, gb); + + /* Stash the first pixel */ + *top_left = outbuf[0]; return 0; } @@ -267,6 +294,61 @@ static int decode_rgb24_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) return 0; } +static int decode_yuv_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) +{ + AVCodecContext *avctx = ctx->avctx; + uint8_t block; + uint8_t *dst[3]; + int pred[3]; + int ret; + int i, j; + VLC vlc[2]; + + pred[0] = 0x80; + pred[1] = 0x80; + pred[2] = 0x80; + + dst[0] = pic->data[0]; + dst[1] = pic->data[1]; + dst[2] = pic->data[2]; + + skip_bits(gb, 8); + + block = get_bits(gb, 8); + if (block) { + avpriv_request_sample(ctx->avctx, "Blocked YUV"); + return AVERROR_PATCHWELCOME; + } + + /* Read in code table for luma and chroma */ + for (i = 0; i < 2; i++) { + ret = read_code_table(ctx, gb, &vlc[i]); + if (ret < 0) { + for (j = 0; j <= i; j++) + ff_free_vlc(&vlc[j]); + + av_log(ctx->avctx, AV_LOG_ERROR, + "Could not read code table %d.\n", i); + return ret; + } + } + + /* Read in and restore every line */ + for (i = 0; i < avctx->height; i++) { + read_yuv_component_line(ctx, gb, &pred[0], &vlc[0], dst[0], 0); /* Y */ + read_yuv_component_line(ctx, gb, &pred[1], &vlc[1], dst[1], 1); /* U */ + read_yuv_component_line(ctx, gb, &pred[2], &vlc[1], dst[2], 1); /* V */ + + for (j = 0; j < 3; j++) + dst[j] += pic->linesize[j]; + } + + for (i = 0; i < 2; i++) + ff_free_vlc(&vlc[i]); + + return 0; +} + static int cllc_decode_frame(AVCodecContext *avctx, void *data, int *got_picture_ptr, AVPacket *avpkt) { @@ -324,6 +406,18 @@ static int cllc_decode_frame(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_DEBUG, "Frame coding type: %d\n", coding_type); switch (coding_type) { + case 0: + avctx->pix_fmt = AV_PIX_FMT_YUV422P; + avctx->bits_per_raw_sample = 8; + + if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) + return ret; + + ret = decode_yuv_frame(ctx, &gb, pic); + if (ret < 0) + return ret; + + break; case 1: case 2: avctx->pix_fmt = AV_PIX_FMT_RGB24; @@ -387,6 +481,7 @@ static av_cold int cllc_decode_init(AVCodecContext *avctx) AVCodec ff_cllc_decoder = { .name = "cllc", + .long_name = NULL_IF_CONFIG_SMALL("Canopus Lossless Codec"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_CLLC, .priv_data_size = sizeof(CLLCContext), @@ -394,5 +489,4 @@ AVCodec ff_cllc_decoder = { .decode = cllc_decode_frame, .close = cllc_decode_close, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Canopus Lossless Codec"), }; diff --git a/ffmpeg/libavcodec/cngdec.c b/ffmpeg/libavcodec/cngdec.c index 675f77d..12241c3 100644 --- a/ffmpeg/libavcodec/cngdec.c +++ b/ffmpeg/libavcodec/cngdec.c @@ -157,6 +157,7 @@ static int cng_decode_frame(AVCodecContext *avctx, void *data, AVCodec ff_comfortnoise_decoder = { .name = "comfortnoise", + .long_name = NULL_IF_CONFIG_SMALL("RFC 3389 comfort noise generator"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_COMFORT_NOISE, .priv_data_size = sizeof(CNGContext), @@ -164,7 +165,6 @@ AVCodec ff_comfortnoise_decoder = { .decode = cng_decode_frame, .flush = cng_decode_flush, .close = cng_decode_close, - .long_name = NULL_IF_CONFIG_SMALL("RFC 3389 comfort noise generator"), .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, .capabilities = CODEC_CAP_DELAY | CODEC_CAP_DR1, diff --git a/ffmpeg/libavcodec/cngenc.c b/ffmpeg/libavcodec/cngenc.c index 4ab3019..5ab6e36 100644 --- a/ffmpeg/libavcodec/cngenc.c +++ b/ffmpeg/libavcodec/cngenc.c @@ -104,13 +104,13 @@ static int cng_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, AVCodec ff_comfortnoise_encoder = { .name = "comfortnoise", + .long_name = NULL_IF_CONFIG_SMALL("RFC 3389 comfort noise generator"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_COMFORT_NOISE, .priv_data_size = sizeof(CNGContext), .init = cng_encode_init, .encode2 = cng_encode_frame, .close = cng_encode_close, - .long_name = NULL_IF_CONFIG_SMALL("RFC 3389 comfort noise generator"), .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, }; diff --git a/ffmpeg/libavcodec/codec_desc.c b/ffmpeg/libavcodec/codec_desc.c index ded09c9..c62734f 100644 --- a/ffmpeg/libavcodec/codec_desc.c +++ b/ffmpeg/libavcodec/codec_desc.c @@ -21,10 +21,10 @@ #include -#include "avcodec.h" - #include "libavutil/common.h" #include "libavutil/internal.h" +#include "avcodec.h" +#include "version.h" static const AVCodecDescriptor codec_descriptors[] = { /* video codecs */ @@ -42,6 +42,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 video"), .props = AV_CODEC_PROP_LOSSY, }, +#if FF_API_XVMC { .id = AV_CODEC_ID_MPEG2VIDEO_XVMC, .type = AVMEDIA_TYPE_VIDEO, @@ -49,6 +50,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video XvMC (X-Video Motion Compensation)"), .props = AV_CODEC_PROP_LOSSY, }, +#endif /* FF_API_XVMC */ { .id = AV_CODEC_ID_H261, .type = AVMEDIA_TYPE_VIDEO, @@ -74,7 +76,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .id = AV_CODEC_ID_RV20, .type = AVMEDIA_TYPE_VIDEO, .name = "rv20", - .long_name = NULL_IF_CONFIG_SMALL("RealVideo 1.0"), + .long_name = NULL_IF_CONFIG_SMALL("RealVideo 2.0"), .props = AV_CODEC_PROP_LOSSY, }, { @@ -943,7 +945,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .id = AV_CODEC_ID_DPX, .type = AVMEDIA_TYPE_VIDEO, .name = "dpx", - .long_name = NULL_IF_CONFIG_SMALL("DPX image"), + .long_name = NULL_IF_CONFIG_SMALL("DPX (Digital Picture Exchange) image"), .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { @@ -1240,6 +1242,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("MS Windows Media Video V9 Screen"), .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, }, + { + .id = AV_CODEC_ID_AIC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "aic", + .long_name = NULL_IF_CONFIG_SMALL("Apple Intermediate Codec"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, { .id = AV_CODEC_ID_Y41P, .type = AVMEDIA_TYPE_VIDEO, @@ -1276,12 +1285,6 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"), .props = AV_CODEC_PROP_INTRA_ONLY, }, - { - .id = AV_CODEC_ID_G2M, - .type = AVMEDIA_TYPE_VIDEO, - .name = "g2m", - .long_name = NULL_IF_CONFIG_SMALL("GoToMeeting"), - }, { .id = AV_CODEC_ID_AVUI, .type = AVMEDIA_TYPE_VIDEO, @@ -1364,6 +1367,42 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("BRender PIX image"), .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, + { + .id = AV_CODEC_ID_SMVJPEG, + .type = AVMEDIA_TYPE_VIDEO, + .name = "smv", + .long_name = NULL_IF_CONFIG_SMALL("Sigmatel Motion Video"), + }, + + { + .id = AV_CODEC_ID_G2M, + .type = AVMEDIA_TYPE_VIDEO, + .name = "g2m", + .long_name = NULL_IF_CONFIG_SMALL("Go2Meeting"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_WEBP, + .type = AVMEDIA_TYPE_VIDEO, + .name = "webp", + .long_name = NULL_IF_CONFIG_SMALL("WebP"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY | + AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_HNM4_VIDEO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "hnm4video", + .long_name = NULL_IF_CONFIG_SMALL("HNM 4 video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_HEVC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "hevc", + .long_name = NULL_IF_CONFIG_SMALL("H.265 / HEVC (High Efficiency Video Coding)"), + .props = AV_CODEC_PROP_LOSSY, + }, /* various PCM "codecs" */ { @@ -1574,7 +1613,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_AUDIO, .name = "s302m", .long_name = NULL_IF_CONFIG_SMALL("SMPTE 302M"), - .props = AV_CODEC_PROP_LOSSY, + .props = AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_PCM_S8_PLANAR, @@ -1809,6 +1848,27 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Dialogic OKI"), .props = AV_CODEC_PROP_LOSSY, }, + { + .id = AV_CODEC_ID_ADPCM_DTK, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_dtk", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM Nintendo Gamecube DTK"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_IMA_RAD, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_ima_rad", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Radical"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_G726LE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_g726le", + .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM little-endian"), + .props = AV_CODEC_PROP_LOSSY, + }, /* AMR */ { @@ -2093,9 +2153,10 @@ static const AVCodecDescriptor codec_descriptors[] = { .id = AV_CODEC_ID_ATRAC3, .type = AVMEDIA_TYPE_AUDIO, .name = "atrac3", - .long_name = NULL_IF_CONFIG_SMALL("Atrac 3 (Adaptive TRansform Acoustic Coding 3)"), + .long_name = NULL_IF_CONFIG_SMALL("ATRAC3 (Adaptive TRansform Acoustic Coding 3)"), .props = AV_CODEC_PROP_LOSSY, }, +#if FF_API_VOXWARE { .id = AV_CODEC_ID_VOXWARE, .type = AVMEDIA_TYPE_AUDIO, @@ -2103,6 +2164,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("Voxware RT29 Metasound"), .props = AV_CODEC_PROP_LOSSY, }, +#endif { .id = AV_CODEC_ID_APE, .type = AVMEDIA_TYPE_AUDIO, @@ -2156,7 +2218,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .id = AV_CODEC_ID_ATRAC3P, .type = AVMEDIA_TYPE_AUDIO, .name = "atrac3p", - .long_name = NULL_IF_CONFIG_SMALL("Sony ATRAC3+"), + .long_name = NULL_IF_CONFIG_SMALL("ATRAC3+ (Adaptive TRansform Acoustic Coding 3+)"), .props = AV_CODEC_PROP_LOSSY, }, { @@ -2205,7 +2267,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .id = AV_CODEC_ID_ATRAC1, .type = AVMEDIA_TYPE_AUDIO, .name = "atrac1", - .long_name = NULL_IF_CONFIG_SMALL("Atrac 1 (Adaptive TRansform Acoustic Coding)"), + .long_name = NULL_IF_CONFIG_SMALL("ATRAC1 (Adaptive TRansform Acoustic Coding)"), .props = AV_CODEC_PROP_LOSSY, }, { @@ -2352,6 +2414,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("TAK (Tom's lossless Audio Kompressor)"), .props = AV_CODEC_PROP_LOSSLESS, }, + { + .id = AV_CODEC_ID_METASOUND, + .type = AVMEDIA_TYPE_AUDIO, + .name = "metasound", + .long_name = NULL_IF_CONFIG_SMALL("Voxware MetaSound"), + .props = AV_CODEC_PROP_LOSSY, + }, { .id = AV_CODEC_ID_EVRC, .type = AVMEDIA_TYPE_AUDIO, @@ -2387,6 +2456,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_SUBTITLE, .name = "text", .long_name = NULL_IF_CONFIG_SMALL("raw UTF-8 text"), + .props = AV_CODEC_PROP_TEXT_SUB, }, { .id = AV_CODEC_ID_XSUB, @@ -2395,17 +2465,26 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("XSUB"), .props = AV_CODEC_PROP_BITMAP_SUB, }, + { + .id = AV_CODEC_ID_ASS, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "ass", + .long_name = NULL_IF_CONFIG_SMALL("ASS (Advanced SSA) subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, + }, { .id = AV_CODEC_ID_SSA, .type = AVMEDIA_TYPE_SUBTITLE, .name = "ssa", - .long_name = NULL_IF_CONFIG_SMALL("SSA (SubStation Alpha) / ASS (Advanced SSA) subtitle"), + .long_name = NULL_IF_CONFIG_SMALL("SSA (SubStation Alpha) subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, }, { .id = AV_CODEC_ID_MOV_TEXT, .type = AVMEDIA_TYPE_SUBTITLE, .name = "mov_text", .long_name = NULL_IF_CONFIG_SMALL("MOV text"), + .props = AV_CODEC_PROP_TEXT_SUB, }, { .id = AV_CODEC_ID_HDMV_PGS_SUBTITLE, @@ -2425,24 +2504,28 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_SUBTITLE, .name = "srt", .long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle with embedded timing"), + .props = AV_CODEC_PROP_TEXT_SUB, }, { .id = AV_CODEC_ID_SUBRIP, .type = AVMEDIA_TYPE_SUBTITLE, .name = "subrip", .long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, }, { .id = AV_CODEC_ID_MICRODVD, .type = AVMEDIA_TYPE_SUBTITLE, .name = "microdvd", .long_name = NULL_IF_CONFIG_SMALL("MicroDVD subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, }, { .id = AV_CODEC_ID_MPL2, .type = AVMEDIA_TYPE_SUBTITLE, .name = "mpl2", .long_name = NULL_IF_CONFIG_SMALL("MPL2 subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, }, { .id = AV_CODEC_ID_EIA_608, @@ -2455,48 +2538,56 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_SUBTITLE, .name = "jacosub", .long_name = NULL_IF_CONFIG_SMALL("JACOsub subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, }, { .id = AV_CODEC_ID_PJS, .type = AVMEDIA_TYPE_SUBTITLE, .name = "pjs", .long_name = NULL_IF_CONFIG_SMALL("PJS (Phoenix Japanimation Society) subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, }, { .id = AV_CODEC_ID_SAMI, .type = AVMEDIA_TYPE_SUBTITLE, .name = "sami", .long_name = NULL_IF_CONFIG_SMALL("SAMI subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, }, { .id = AV_CODEC_ID_REALTEXT, .type = AVMEDIA_TYPE_SUBTITLE, .name = "realtext", .long_name = NULL_IF_CONFIG_SMALL("RealText subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, }, { .id = AV_CODEC_ID_SUBVIEWER1, .type = AVMEDIA_TYPE_SUBTITLE, .name = "subviewer1", .long_name = NULL_IF_CONFIG_SMALL("SubViewer v1 subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, }, { .id = AV_CODEC_ID_SUBVIEWER, .type = AVMEDIA_TYPE_SUBTITLE, .name = "subviewer", .long_name = NULL_IF_CONFIG_SMALL("SubViewer subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, }, { .id = AV_CODEC_ID_VPLAYER, .type = AVMEDIA_TYPE_SUBTITLE, .name = "vplayer", .long_name = NULL_IF_CONFIG_SMALL("VPlayer subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, }, { .id = AV_CODEC_ID_WEBVTT, .type = AVMEDIA_TYPE_SUBTITLE, .name = "webvtt", .long_name = NULL_IF_CONFIG_SMALL("WebVTT subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, }, { .id = AV_CODEC_ID_BINTEXT, diff --git a/ffmpeg/libavcodec/cook.c b/ffmpeg/libavcodec/cook.c index 08cd401..402093c 100644 --- a/ffmpeg/libavcodec/cook.c +++ b/ffmpeg/libavcodec/cook.c @@ -51,6 +51,7 @@ #include "fft.h" #include "internal.h" #include "sinewin.h" +#include "unary.h" #include "cookdata.h" @@ -228,7 +229,7 @@ static av_cold int init_cook_mlt(COOKContext *q) /* Initialize the MDCT. */ if ((ret = ff_mdct_init(&q->mdct_ctx, av_log2(mlt_size) + 1, 1, 1.0 / 32768.0))) { - av_free(q->mlt_window); + av_freep(&q->mlt_window); return ret; } av_log(q->avctx, AV_LOG_DEBUG, "MDCT initialized, order = %d.\n", @@ -302,8 +303,8 @@ static av_cold int cook_decode_close(AVCodecContext *avctx) av_log(avctx, AV_LOG_DEBUG, "Deallocating memory.\n"); /* Free allocated memory buffers. */ - av_free(q->mlt_window); - av_free(q->decoded_bytes_buffer); + av_freep(&q->mlt_window); + av_freep(&q->decoded_bytes_buffer); /* Free the transform. */ ff_mdct_end(&q->mdct_ctx); @@ -331,11 +332,7 @@ static void decode_gain_info(GetBitContext *gb, int *gaininfo) { int i, n; - while (get_bits1(gb)) { - /* NOTHING */ - } - - n = get_bits_count(gb) - 1; // amount of elements*2 to update + n = get_unary(gb, 0, get_bits_left(gb)); // amount of elements*2 to update i = 0; while (n--) { @@ -1279,6 +1276,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) AVCodec ff_cook_decoder = { .name = "cook", + .long_name = NULL_IF_CONFIG_SMALL("Cook / Cooker / Gecko (RealAudio G2)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_COOK, .priv_data_size = sizeof(COOKContext), @@ -1286,7 +1284,6 @@ AVCodec ff_cook_decoder = { .close = cook_decode_close, .decode = cook_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Cook / Cooker / Gecko (RealAudio G2)"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, }; diff --git a/ffmpeg/libavcodec/cook_parser.c b/ffmpeg/libavcodec/cook_parser.c index f140e90..6dbbfd8 100644 --- a/ffmpeg/libavcodec/cook_parser.c +++ b/ffmpeg/libavcodec/cook_parser.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2012 Justin Ruggles * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -40,11 +40,12 @@ static int cook_parse(AVCodecParserContext *s1, AVCodecContext *avctx, { CookParseContext *s = s1->priv_data; - if (s->duration) - s1->duration = s->duration; - else if (avctx->extradata && avctx->extradata_size >= 8 && avctx->channels) + if (!s->duration && + avctx->extradata && avctx->extradata_size >= 8 && avctx->channels) s->duration = AV_RB16(avctx->extradata + 4) / avctx->channels; + s1->duration = s->duration; + /* always return the full packet. this parser isn't doing any splitting or combining, only setting packet duration */ *poutbuf = buf; diff --git a/ffmpeg/libavcodec/cos_tablegen.c b/ffmpeg/libavcodec/cos_tablegen.c index 313a1d2..48b7b90 100644 --- a/ffmpeg/libavcodec/cos_tablegen.c +++ b/ffmpeg/libavcodec/cos_tablegen.c @@ -37,11 +37,16 @@ static int clip_f15(int v) static void printval(double val, int fixed) { - if (fixed) - printf(" "FIXEDFMT",", clip_f15(lrint(val * (double)(1<<15)))); - else - printf(" "FLOATFMT",", val); + if (fixed) { + /* lrint() isn't always available, so round and cast manually. */ + double new_val = val * (double) (1 << 15); + + new_val = new_val >= 0 ? floor(new_val + 0.5) : ceil(new_val - 0.5); + printf(" "FIXEDFMT",", clip_f15((long int) new_val)); + } else { + printf(" "FLOATFMT",", val); + } } int main(int argc, char *argv[]) diff --git a/ffmpeg/libavcodec/cpia.c b/ffmpeg/libavcodec/cpia.c index 4f83503..44226fb 100644 --- a/ffmpeg/libavcodec/cpia.c +++ b/ffmpeg/libavcodec/cpia.c @@ -222,6 +222,7 @@ static av_cold int cpia_decode_end(AVCodecContext *avctx) AVCodec ff_cpia_decoder = { .name = "cpia", + .long_name = NULL_IF_CONFIG_SMALL("CPiA video format"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_CPIA, .priv_data_size = sizeof(CpiaContext), @@ -229,5 +230,4 @@ AVCodec ff_cpia_decoder = { .close = cpia_decode_end, .decode = cpia_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("CPiA video format"), }; diff --git a/ffmpeg/libavcodec/crystalhd.c b/ffmpeg/libavcodec/crystalhd.c index 5dee825..12a8f8e 100644 --- a/ffmpeg/libavcodec/crystalhd.c +++ b/ffmpeg/libavcodec/crystalhd.c @@ -915,8 +915,8 @@ static int decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *a H264Context *h = priv->parser->priv_data; index = av_parser_parse2(priv->parser, avctx, &pout, &psize, - in_data, len, avctx->pkt->pts, - avctx->pkt->dts, 0); + in_data, len, avctx->internal->pkt->pts, + avctx->internal->pkt->dts, 0); if (index < 0) { av_log(avctx, AV_LOG_WARNING, "CrystalHD: Failed to parse h.264 packet to " @@ -950,7 +950,7 @@ static int decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *a * avoiding mangling so we need to build a mapping to values * we know will not be mangled. */ - uint64_t pts = opaque_list_push(priv, avctx->pkt->pts, pic_type); + uint64_t pts = opaque_list_push(priv, avctx->internal->pkt->pts, pic_type); if (!pts) { if (free_data) { av_freep(&in_data); @@ -1088,6 +1088,7 @@ static AVClass h264_class = { AVCodec ff_h264_crystalhd_decoder = { .name = "h264_crystalhd", + .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (CrystalHD acceleration)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, .priv_data_size = sizeof(CHDContext), @@ -1096,7 +1097,6 @@ AVCodec ff_h264_crystalhd_decoder = { .decode = decode, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY, .flush = flush, - .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (CrystalHD acceleration)"), .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE}, .priv_class = &h264_class, }; @@ -1112,6 +1112,7 @@ static AVClass mpeg2_class = { AVCodec ff_mpeg2_crystalhd_decoder = { .name = "mpeg2_crystalhd", + .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 Video (CrystalHD acceleration)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MPEG2VIDEO, .priv_data_size = sizeof(CHDContext), @@ -1120,7 +1121,6 @@ AVCodec ff_mpeg2_crystalhd_decoder = { .decode = decode, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY, .flush = flush, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 Video (CrystalHD acceleration)"), .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE}, .priv_class = &mpeg2_class, }; @@ -1136,6 +1136,7 @@ static AVClass mpeg4_class = { AVCodec ff_mpeg4_crystalhd_decoder = { .name = "mpeg4_crystalhd", + .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 Part 2 (CrystalHD acceleration)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MPEG4, .priv_data_size = sizeof(CHDContext), @@ -1144,7 +1145,6 @@ AVCodec ff_mpeg4_crystalhd_decoder = { .decode = decode, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY, .flush = flush, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 Part 2 (CrystalHD acceleration)"), .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE}, .priv_class = &mpeg4_class, }; @@ -1160,6 +1160,7 @@ static AVClass msmpeg4_class = { AVCodec ff_msmpeg4_crystalhd_decoder = { .name = "msmpeg4_crystalhd", + .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 Part 2 Microsoft variant version 3 (CrystalHD acceleration)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MSMPEG4V3, .priv_data_size = sizeof(CHDContext), @@ -1168,7 +1169,6 @@ AVCodec ff_msmpeg4_crystalhd_decoder = { .decode = decode, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_EXPERIMENTAL, .flush = flush, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 Part 2 Microsoft variant version 3 (CrystalHD acceleration)"), .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE}, .priv_class = &msmpeg4_class, }; @@ -1184,6 +1184,7 @@ static AVClass vc1_class = { AVCodec ff_vc1_crystalhd_decoder = { .name = "vc1_crystalhd", + .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1 (CrystalHD acceleration)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VC1, .priv_data_size = sizeof(CHDContext), @@ -1192,7 +1193,6 @@ AVCodec ff_vc1_crystalhd_decoder = { .decode = decode, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY, .flush = flush, - .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1 (CrystalHD acceleration)"), .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE}, .priv_class = &vc1_class, }; @@ -1208,6 +1208,7 @@ static AVClass wmv3_class = { AVCodec ff_wmv3_crystalhd_decoder = { .name = "wmv3_crystalhd", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 (CrystalHD acceleration)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_WMV3, .priv_data_size = sizeof(CHDContext), @@ -1216,7 +1217,6 @@ AVCodec ff_wmv3_crystalhd_decoder = { .decode = decode, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY, .flush = flush, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 (CrystalHD acceleration)"), .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE}, .priv_class = &wmv3_class, }; diff --git a/ffmpeg/libavcodec/cscd.c b/ffmpeg/libavcodec/cscd.c index 0a5fa69..e875dd7 100644 --- a/ffmpeg/libavcodec/cscd.c +++ b/ffmpeg/libavcodec/cscd.c @@ -159,6 +159,7 @@ static av_cold int decode_end(AVCodecContext *avctx) { AVCodec ff_cscd_decoder = { .name = "camstudio", + .long_name = NULL_IF_CONFIG_SMALL("CamStudio"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_CSCD, .priv_data_size = sizeof(CamStudioContext), @@ -166,5 +167,4 @@ AVCodec ff_cscd_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("CamStudio"), }; diff --git a/ffmpeg/libavcodec/cyuv.c b/ffmpeg/libavcodec/cyuv.c index 3a30138..c686123 100644 --- a/ffmpeg/libavcodec/cyuv.c +++ b/ffmpeg/libavcodec/cyuv.c @@ -178,25 +178,25 @@ static int cyuv_decode_frame(AVCodecContext *avctx, #if CONFIG_AURA_DECODER AVCodec ff_aura_decoder = { .name = "aura", + .long_name = NULL_IF_CONFIG_SMALL("Auravision AURA"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_AURA, .priv_data_size = sizeof(CyuvDecodeContext), .init = cyuv_decode_init, .decode = cyuv_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Auravision AURA"), }; #endif #if CONFIG_CYUV_DECODER AVCodec ff_cyuv_decoder = { .name = "cyuv", + .long_name = NULL_IF_CONFIG_SMALL("Creative YUV (CYUV)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_CYUV, .priv_data_size = sizeof(CyuvDecodeContext), .init = cyuv_decode_init, .decode = cyuv_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Creative YUV (CYUV)"), }; #endif diff --git a/ffmpeg/libavcodec/dca.c b/ffmpeg/libavcodec/dca.c index bbe1f10..1c1c080 100644 --- a/ffmpeg/libavcodec/dca.c +++ b/ffmpeg/libavcodec/dca.c @@ -23,7 +23,9 @@ */ #include +#include +#include "put_bits.h" #include "dca.h" const uint32_t avpriv_dca_sample_rates[16] = @@ -31,3 +33,38 @@ const uint32_t avpriv_dca_sample_rates[16] = 0, 8000, 16000, 32000, 0, 0, 11025, 22050, 44100, 0, 0, 12000, 24000, 48000, 96000, 192000 }; + +int ff_dca_convert_bitstream(const uint8_t *src, int src_size, uint8_t *dst, + int max_size) +{ + uint32_t mrk; + int i, tmp; + const uint16_t *ssrc = (const uint16_t *) src; + uint16_t *sdst = (uint16_t *) dst; + PutBitContext pb; + + if ((unsigned) src_size > (unsigned) max_size) + src_size = max_size; + + mrk = AV_RB32(src); + switch (mrk) { + case DCA_MARKER_RAW_BE: + memcpy(dst, src, src_size); + return src_size; + case DCA_MARKER_RAW_LE: + for (i = 0; i < (src_size + 1) >> 1; i++) + *sdst++ = av_bswap16(*ssrc++); + return src_size; + case DCA_MARKER_14B_BE: + case DCA_MARKER_14B_LE: + init_put_bits(&pb, dst, max_size); + for (i = 0; i < (src_size + 1) >> 1; i++, src += 2) { + tmp = ((mrk == DCA_MARKER_14B_BE) ? AV_RB16(src) : AV_RL16(src)) & 0x3FFF; + put_bits(&pb, 14, tmp); + } + flush_put_bits(&pb); + return (put_bits_count(&pb) + 7) >> 3; + default: + return AVERROR_INVALIDDATA; + } +} diff --git a/ffmpeg/libavcodec/dca.h b/ffmpeg/libavcodec/dca.h index 3da93aa..d60b282 100644 --- a/ffmpeg/libavcodec/dca.h +++ b/ffmpeg/libavcodec/dca.h @@ -39,4 +39,10 @@ extern av_export const uint32_t avpriv_dca_sample_rates[16]; +/** + * Convert bitstream to one representation based on sync marker + */ +int ff_dca_convert_bitstream(const uint8_t *src, int src_size, uint8_t *dst, + int max_size); + #endif /* AVCODEC_DCA_H */ diff --git a/ffmpeg/libavcodec/dca_parser.c b/ffmpeg/libavcodec/dca_parser.c index 266520f..9b73371 100644 --- a/ffmpeg/libavcodec/dca_parser.c +++ b/ffmpeg/libavcodec/dca_parser.c @@ -24,9 +24,7 @@ #include "parser.h" #include "dca.h" -#include "dca_parser.h" #include "get_bits.h" -#include "put_bits.h" typedef struct DCAParseContext { ParseContext pc; @@ -63,6 +61,7 @@ static int dca_find_frame_end(DCAParseContext * pc1, const uint8_t * buf, if (!pc1->lastmarker || state == pc1->lastmarker || pc1->lastmarker == DCA_HD_MARKER) { start_found = 1; pc1->lastmarker = state; + i++; break; } } @@ -77,10 +76,6 @@ static int dca_find_frame_end(DCAParseContext * pc1, const uint8_t * buf, if (IS_MARKER(state, i, buf, buf_size) && (state == pc1->lastmarker || pc1->lastmarker == DCA_HD_MARKER)) { if(pc1->framesize > pc1->size) continue; - // We have to check that we really read a full frame here, and that it isn't a pure HD frame, because their size is not constant. - if(!pc1->framesize && state == pc1->lastmarker && state != DCA_HD_MARKER){ - pc1->framesize = pc1->hd_pos ? pc1->hd_pos : pc1->size; - } pc->frame_start_found = 0; pc->state = -1; pc1->size = 0; @@ -101,43 +96,8 @@ static av_cold int dca_parse_init(AVCodecParserContext * s) return 0; } -int ff_dca_convert_bitstream(const uint8_t *src, int src_size, uint8_t *dst, - int max_size) -{ - uint32_t mrk; - int i, tmp; - const uint16_t *ssrc = (const uint16_t *) src; - uint16_t *sdst = (uint16_t *) dst; - PutBitContext pb; - - if ((unsigned) src_size > (unsigned) max_size) - src_size = max_size; - - mrk = AV_RB32(src); - switch (mrk) { - case DCA_MARKER_RAW_BE: - memcpy(dst, src, src_size); - return src_size; - case DCA_MARKER_RAW_LE: - for (i = 0; i < (src_size + 1) >> 1; i++) - *sdst++ = av_bswap16(*ssrc++); - return src_size; - case DCA_MARKER_14B_BE: - case DCA_MARKER_14B_LE: - init_put_bits(&pb, dst, max_size); - for (i = 0; i < (src_size + 1) >> 1; i++, src += 2) { - tmp = ((mrk == DCA_MARKER_14B_BE) ? AV_RB16(src) : AV_RL16(src)) & 0x3FFF; - put_bits(&pb, 14, tmp); - } - flush_put_bits(&pb); - return (put_bits_count(&pb) + 7) >> 3; - default: - return AVERROR_INVALIDDATA; - } -} - static int dca_parse_params(const uint8_t *buf, int buf_size, int *duration, - int *sample_rate) + int *sample_rate, int *framesize) { GetBitContext gb; uint8_t hdr[12 + FF_INPUT_BUFFER_PADDING_SIZE] = { 0 }; @@ -157,7 +117,11 @@ static int dca_parse_params(const uint8_t *buf, int buf_size, int *duration, return AVERROR_INVALIDDATA; *duration = 256 * (sample_blocks / 8); - skip_bits(&gb, 20); + *framesize = get_bits(&gb, 14) + 1; + if (*framesize < 95) + return AVERROR_INVALIDDATA; + + skip_bits(&gb, 6); sr_code = get_bits(&gb, 4); *sample_rate = avpriv_dca_sample_rates[sr_code]; if (*sample_rate == 0) @@ -188,7 +152,7 @@ static int dca_parse(AVCodecParserContext * s, } /* read the duration and sample rate from the frame header */ - if (!dca_parse_params(buf, buf_size, &duration, &sample_rate)) { + if (!dca_parse_params(buf, buf_size, &duration, &sample_rate, &pc1->framesize)) { s->duration = duration; avctx->sample_rate = sample_rate; } else diff --git a/ffmpeg/libavcodec/dca_parser.h b/ffmpeg/libavcodec/dca_parser.h deleted file mode 100644 index f480eab..0000000 --- a/ffmpeg/libavcodec/dca_parser.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * DCA parser - * Copyright (C) 2004 Gildas Bazin - * Copyright (C) 2004 Benjamin Zores - * Copyright (C) 2006 Benjamin Larsson - * Copyright (C) 2007 Konstantin Shishkov - * - * This file is part of Libav. - * - * Libav is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * Libav is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_DCA_PARSER_H -#define AVCODEC_DCA_PARSER_H - -#include - -/** - * Convert bitstream to one representation based on sync marker - */ -int ff_dca_convert_bitstream(const uint8_t *src, int src_size, uint8_t *dst, - int max_size); - -#endif /* AVCODEC_DCA_PARSER_H */ diff --git a/ffmpeg/libavcodec/dcadata.h b/ffmpeg/libavcodec/dcadata.h index 15df49e..5154fbc 100644 --- a/ffmpeg/libavcodec/dcadata.h +++ b/ffmpeg/libavcodec/dcadata.h @@ -7505,24 +7505,19 @@ DECLARE_ALIGNED(16, static const float, lfe_fir_128)[] = 0.01724460535, 0.47964480519, 0.48503074050, 0.01805862412, }; -/* 10^-(dB/20), with dB being a list of dB values ranging from 0 to -72 */ -/* do a 20*log10(dca_downmix_coeffs) to reconvert the values */ - -static const float dca_downmix_coeffs[65] = { - 1.000000000000000, 0.988553094656939, 0.971627951577106, 0.944060876285923, 0.917275935389780, 0.891250938133746, - 0.865964323360065, 0.841395141645195, 0.817523037943650, 0.794328234724281, 0.771791515585012, 0.749894209332456, - 0.728618174513228, 0.707945784384138, 0.687859912308808, 0.668343917568615, 0.649381631576211, 0.630957344480193, - 0.613055792149821, 0.595662143529010, 0.578761988349121, 0.562341325190349, 0.546386549881854, 0.530884444230988, - 0.515822165072306, 0.501187233627272, 0.446683592150963, 0.398107170553497, 0.354813389233575, 0.316227766016838, - 0.281838293126445, 0.251188643150958, 0.223872113856834, 0.199526231496888, 0.177827941003892, 0.158489319246111, - 0.141253754462275, 0.125892541179417, 0.112201845430196, 0.100000000000000, 0.089125093813374, 0.079432823472428, - 0.070794578438414, 0.063095734448019, 0.053088444423099, 0.044668359215096, 0.037583740428844, 0.031622776601684, - 0.026607250597988, 0.022387211385683, 0.018836490894898, 0.015848931924611, 0.013335214321633, 0.011220184543020, - 0.009440608762859, 0.007943282347243, 0.005623413251903, 0.003981071705535, 0.002818382931264, 0.001995262314969, - 0.001412537544623, 0.001000000000000, 0.000501187233627, 0.000251188643151, 0.000000000000000, -}; - -static const float dca_downmix_scale_factors[241] = { +/* + * D.11 Look-up Table for Downmix Scale Factors + * + * Note that the range of the entries in DmixTable[] is between -60 dB and 0 dB + * with addition of -inf (|DMixCoeff| = 0), which is coded with a DmixCode = 0. + * Furthermore, the range [-60 to 0] is subdivided into 3 regions, each with a + * different grid resolution: + * + * 1) [-60.000 to -30] with resolution of 0.500 dB + * 2) [-29.750 to -15] with resolution of 0.250 dB + * 3) [-14.875 to 0] with resolution of 0.125 dB + */ +static const float dca_dmixtable[241] = { 0.001000, 0.001059, 0.001122, 0.001189, 0.001259, 0.001334, 0.001413, 0.001496, 0.001585, 0.001679, 0.001778, 0.001884, 0.001995, 0.002113, 0.002239, 0.002371, 0.002512, 0.002661, 0.002818, 0.002985, 0.003162, 0.003350, 0.003548, 0.003758, @@ -7553,20 +7548,20 @@ static const float dca_downmix_scale_factors[241] = { 0.707107, 0.718208, 0.728618, 0.739180, 0.749894, 0.760764, 0.771792, 0.782979, 0.794328, 0.805842, 0.817523, 0.829373, 0.841395, 0.853591, 0.865964, 0.878517, 0.891251, 0.904170, 0.917276, 0.930572, 0.944061, 0.957745, 0.971628, 0.985712, - 1.000000 + 1.000000, }; -static const uint8_t dca_default_coeffs[10][5][2] = { - { { 13, 13 }, }, - { { 0, 64 }, { 64, 0 }, }, - { { 0, 64 }, { 64, 0 }, }, - { { 0, 64 }, { 64, 0 }, }, - { { 0, 64 }, { 64, 0 }, }, - { { 6, 6 }, { 0, 25 }, { 25, 0 }, }, - { { 0, 25 }, { 25, 0 }, { 13, 13 }, }, - { { 6, 6 }, { 0, 25 }, { 25, 0 }, { 13, 13 }, }, - { { 0, 25 }, { 25, 0 }, { 0, 13 }, { 13, 0 }, }, - { { 6, 6 }, { 0, 25 }, { 25, 0 }, { 0, 13 }, { 13, 0 }, }, +static const float dca_default_coeffs[10][6][2] = { + { { 0.707107, 0.707107 }, { 0.000000, 0.000000 }, }, // A [LFE] + { { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, { 0.000000, 0.000000 }, }, // A + B (dual mono) [LFE] + { { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, { 0.000000, 0.000000 }, }, // L + R (stereo) [LFE] + { { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, { 0.000000, 0.000000 }, }, // (L+R) + (L-R) (sum-difference) [LFE] + { { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, { 0.000000, 0.000000 }, }, // LT + RT (left and right total) [LFE] + { { 0.501187, 0.501187 }, { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.000000, 0.000000 }, }, // C + L + R [LFE] + { { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.501187 }, { 0.000000, 0.000000 }, }, // L + R + S [LFE] + { { 0.501187, 0.501187 }, { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.501187 }, { 0.000000, 0.000000 }, }, // C + L + R + S [LFE] + { { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.000000 }, { 0.000000, 0.501187 }, { 0.000000, 0.000000 }, }, // L + R + SL + SR [LFE] + { { 0.501187, 0.501187 }, { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.000000 }, { 0.000000, 0.501187 }, { 0.000000, 0.000000 }, }, // C + L + R + SL + SR [LFE] }; /* downmix coeffs diff --git a/ffmpeg/libavcodec/dcadec.c b/ffmpeg/libavcodec/dcadec.c index cf4412c..cc2fa0a 100644 --- a/ffmpeg/libavcodec/dcadec.c +++ b/ffmpeg/libavcodec/dcadec.c @@ -32,15 +32,14 @@ #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" #include "libavutil/mathematics.h" +#include "libavutil/opt.h" #include "libavutil/samplefmt.h" #include "avcodec.h" #include "fft.h" #include "get_bits.h" -#include "put_bits.h" #include "dcadata.h" #include "dcahuff.h" #include "dca.h" -#include "dca_parser.h" #include "mathops.h" #include "synth_filter.h" #include "dcadsp.h" @@ -327,6 +326,8 @@ static const int8_t dca_channel_reorder_nolfe_xch[][9] = { #define DCA_BUFFER_PADDING_SIZE 1024 +#define DCA_NSYNCAUX 0x9A1105A0 + /** Bit allocation */ typedef struct { int offset; ///< code values offset @@ -348,6 +349,7 @@ static av_always_inline int get_bitalloc(GetBitContext *gb, BitAlloc *ba, } typedef struct { + const AVClass *class; ///< class for AVOptions AVCodecContext *avctx; /* Frame header */ int frame_type; ///< type of the current frame @@ -360,7 +362,6 @@ typedef struct { int bit_rate; ///< transmission bit rate int bit_rate_index; ///< transmission bit rate index - int downmix; ///< embedded downmix enabled int dynrange; ///< embedded dynamic range flag int timestamp; ///< embedded time stamp flag int aux_data; ///< auxiliary data flag @@ -402,9 +403,16 @@ typedef struct { int scale_factor[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][2]; ///< scale factors (2 if transient) int joint_huff[DCA_PRIM_CHANNELS_MAX]; ///< joint subband scale factors codebook int joint_scale_factor[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< joint subband scale factors - int downmix_coef[DCA_PRIM_CHANNELS_MAX][2]; ///< stereo downmix coefficients + float downmix_coef[DCA_PRIM_CHANNELS_MAX + 1][2]; ///< stereo downmix coefficients int dynrange_coef; ///< dynamic range coefficient + /* Core substream's embedded downmix coefficients (cf. ETSI TS 102 114 V1.4.1) + * Input: primary audio channels (incl. LFE if present) + * Output: downmix audio channels (up to 4, no LFE) */ + uint8_t core_downmix; ///< embedded downmix coefficients available + uint8_t core_downmix_amode; ///< audio channel arrangement of embedded downmix + uint16_t core_downmix_codes[DCA_PRIM_CHANNELS_MAX + 1][4]; ///< embedded downmix coefficients (9-bit codes) + int high_freq_vq[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< VQ encoded high frequency subbands float lfe_data[2 * DCA_LFE_MAX * (DCA_BLOCKS_MAX + 4)]; ///< Low frequency effect data @@ -439,6 +447,7 @@ typedef struct { /* XCh extension information */ int xch_present; ///< XCh extension present and valid int xch_base_channel; ///< index of first (only) channel containing XCH data + int xch_disable; ///< whether the XCh extension should be decoded or not /* XXCH extension information */ int xxch_chset; @@ -591,7 +600,7 @@ static int dca_parse_audio_coding_header(DCAContext *s, int base_channel, if (get_bits1(&s->gb)) { embedded_downmix = get_bits1(&s->gb); scale_factor = - 1.0f / dca_downmix_scale_factors[(get_bits(&s->gb, 6) - 1) << 2]; + 1.0f / dca_dmixtable[(get_bits(&s->gb, 6) - 1) << 2]; s->xxch_dmix_sf[s->xxch_chset] = scale_factor; @@ -612,7 +621,7 @@ static int dca_parse_audio_coding_header(DCAContext *s, int base_channel, coeff = get_bits(&s->gb, 7); sign = (coeff & 64) ? 1.0 : -1.0; - mag = dca_downmix_scale_factors[((coeff & 63) - 1) << 2]; + mag = dca_dmixtable[((coeff & 63) - 1) << 2]; ichan = dca_xxch2index(s, 1 << i); s->xxch_dmix_coeff[j][ichan] = sign * mag; } @@ -726,7 +735,7 @@ static int dca_parse_frame_header(DCAContext *s) if (!s->bit_rate) return AVERROR_INVALIDDATA; - s->downmix = get_bits(&s->gb, 1); /* note: this is FixedBit == 0 */ + skip_bits1(&s->gb); // always 0 (reserved, cf. ETSI TS 102 114 V1.4.1) s->dynrange = get_bits(&s->gb, 1); s->timestamp = get_bits(&s->gb, 1); s->aux_data = get_bits(&s->gb, 1); @@ -737,10 +746,10 @@ static int dca_parse_frame_header(DCAContext *s) s->lfe = get_bits(&s->gb, 2); s->predictor_history = get_bits(&s->gb, 1); - if (s->lfe == 3) { + if (s->lfe > 2) { s->lfe = 0; - avpriv_request_sample(s->avctx, "LFE = 3"); - return AVERROR_PATCHWELCOME; + av_log(s->avctx, AV_LOG_ERROR, "Invalid LFE value: %d\n", s->lfe); + return AVERROR_INVALIDDATA; } /* TODO: check CRC */ @@ -773,7 +782,6 @@ static int dca_parse_frame_header(DCAContext *s) s->sample_rate); av_log(s->avctx, AV_LOG_DEBUG, "bit rate: %i bits/s\n", s->bit_rate); - av_log(s->avctx, AV_LOG_DEBUG, "downmix: %i\n", s->downmix); av_log(s->avctx, AV_LOG_DEBUG, "dynrange: %i\n", s->dynrange); av_log(s->avctx, AV_LOG_DEBUG, "timestamp: %i\n", s->timestamp); av_log(s->avctx, AV_LOG_DEBUG, "aux_data: %i\n", s->aux_data); @@ -956,27 +964,6 @@ static int dca_subframe_header(DCAContext *s, int base_channel, int block_index) } } - /* Stereo downmix coefficients */ - if (!base_channel && s->prim_channels > 2) { - if (s->downmix) { - for (j = base_channel; j < s->prim_channels; j++) { - s->downmix_coef[j][0] = get_bits(&s->gb, 7); - s->downmix_coef[j][1] = get_bits(&s->gb, 7); - } - } else { - int am = s->amode & DCA_CHANNEL_MASK; - if (am >= FF_ARRAY_ELEMS(dca_default_coeffs)) { - av_log(s->avctx, AV_LOG_ERROR, - "Invalid channel mode %d\n", am); - return AVERROR_INVALIDDATA; - } - for (j = base_channel; j < FFMIN(s->prim_channels, FF_ARRAY_ELEMS(dca_default_coeffs[am])); j++) { - s->downmix_coef[j][0] = dca_default_coeffs[am][j][0]; - s->downmix_coef[j][1] = dca_default_coeffs[am][j][1]; - } - } - } - /* Dynamic range coefficient */ if (!base_channel && s->dynrange) s->dynrange_coef = get_bits(&s->gb, 8); @@ -1076,16 +1063,6 @@ static int dca_subframe_header(DCAContext *s, int base_channel, int block_index) av_log(s->avctx, AV_LOG_DEBUG, "\n"); } } - if (!base_channel && s->prim_channels > 2 && s->downmix) { - av_log(s->avctx, AV_LOG_DEBUG, "Downmix coeffs:\n"); - for (j = 0; j < s->prim_channels; j++) { - av_log(s->avctx, AV_LOG_DEBUG, "Channel 0, %d = %f\n", j, - dca_downmix_coeffs[s->downmix_coef[j][0]]); - av_log(s->avctx, AV_LOG_DEBUG, "Channel 1, %d = %f\n", j, - dca_downmix_coeffs[s->downmix_coef[j][1]]); - } - av_log(s->avctx, AV_LOG_DEBUG, "\n"); - } for (j = base_channel; j < s->prim_channels; j++) for (k = s->vq_start_subband[j]; k < s->subband_activity[j]; k++) av_log(s->avctx, AV_LOG_DEBUG, "VQ index: %i\n", s->high_freq_vq[j][k]); @@ -1108,10 +1085,8 @@ static void qmf_32_subbands(DCAContext *s, int chans, float scale) { const float *prCoeff; - int i; int sb_act = s->subband_activity[chans]; - int subindex; scale *= sqrt(1 / 8.0); @@ -1121,25 +1096,11 @@ static void qmf_32_subbands(DCAContext *s, int chans, else /* Perfect reconstruction */ prCoeff = fir_32bands_perfect; - for (i = sb_act; i < 32; i++) - s->raXin[i] = 0.0; - - /* Reconstructed channel sample index */ - for (subindex = 0; subindex < 8; subindex++) { - /* Load in one sample from each subband and clear inactive subbands */ - for (i = 0; i < sb_act; i++) { - unsigned sign = (i - 1) & 2; - uint32_t v = AV_RN32A(&samples_in[i][subindex]) ^ sign << 30; - AV_WN32A(&s->raXin[i], v); - } - - s->synth.synth_filter_float(&s->imdct, - s->subband_fir_hist[chans], - &s->hist_index[chans], - s->subband_fir_noidea[chans], prCoeff, - samples_out, s->raXin, scale); - samples_out += 32; - } + s->dcadsp.qmf_32_subbands(samples_in, sb_act, &s->synth, &s->imdct, + s->subband_fir_hist[chans], + &s->hist_index[chans], + s->subband_fir_noidea[chans], prCoeff, + samples_out, s->raXin, scale); } static void lfe_interpolation_fir(DCAContext *s, int decimation_select, @@ -1196,29 +1157,23 @@ static void lfe_interpolation_fir(DCAContext *s, int decimation_select, op2 \ } -static void dca_downmix(float **samples, int srcfmt, - int downmix_coef[DCA_PRIM_CHANNELS_MAX][2], +static void dca_downmix(float **samples, int srcfmt, int lfe_present, + float coef[DCA_PRIM_CHANNELS_MAX + 1][2], const int8_t *channel_mapping) { int c, l, r, sl, sr, s; int i; float t, u, v; - float coef[DCA_PRIM_CHANNELS_MAX][2]; - - for (i = 0; i < DCA_PRIM_CHANNELS_MAX; i++) { - coef[i][0] = dca_downmix_coeffs[downmix_coef[i][0]]; - coef[i][1] = dca_downmix_coeffs[downmix_coef[i][1]]; - } switch (srcfmt) { case DCA_MONO: - case DCA_CHANNEL: - case DCA_STEREO_TOTAL: - case DCA_STEREO_SUMDIFF: case DCA_4F2R: av_log(NULL, AV_LOG_ERROR, "Not implemented!\n"); break; + case DCA_CHANNEL: case DCA_STEREO: + case DCA_STEREO_TOTAL: + case DCA_STEREO_SUMDIFF: break; case DCA_3F: c = channel_mapping[0]; @@ -1253,13 +1208,21 @@ static void dca_downmix(float **samples, int srcfmt, MIX_REAR2(samples, sl, sr, 3, coef)); break; } + if (lfe_present) { + int lf_buf = dca_lfe_index[srcfmt]; + int lf_idx = dca_channels [srcfmt]; + for (i = 0; i < 256; i++) { + samples[0][i] += samples[lf_buf][i] * coef[lf_idx][0]; + samples[1][i] += samples[lf_buf][i] * coef[lf_idx][1]; + } + } } #ifndef decode_blockcodes /* Very compact version of the block code decoder that does not use table * look-up but is slightly slower */ -static int decode_blockcode(int code, int levels, int *values) +static int decode_blockcode(int code, int levels, int32_t *values) { int i; int offset = (levels - 1) >> 1; @@ -1273,7 +1236,7 @@ static int decode_blockcode(int code, int levels, int *values) return code; } -static int decode_blockcodes(int code1, int code2, int levels, int *values) +static int decode_blockcodes(int code1, int code2, int levels, int32_t *values) { return decode_blockcode(code1, levels, values) | decode_blockcode(code2, levels, values + 4); @@ -1302,7 +1265,7 @@ static int dca_subsubframe(DCAContext *s, int base_channel, int block_index) /* FIXME */ float (*subband_samples)[DCA_SUBBANDS][8] = s->subband_samples[block_index]; - LOCAL_ALIGNED_16(int, block, [8]); + LOCAL_ALIGNED_16(int32_t, block, [8 * DCA_SUBBANDS]); /* * Audio data @@ -1315,6 +1278,8 @@ static int dca_subsubframe(DCAContext *s, int base_channel, int block_index) quant_step_table = lossy_quant_d; for (k = base_channel; k < s->prim_channels; k++) { + float rscale[DCA_SUBBANDS]; + if (get_bits_left(&s->gb) < 0) return AVERROR_INVALIDDATA; @@ -1337,11 +1302,12 @@ static int dca_subsubframe(DCAContext *s, int base_channel, int block_index) * Extract bits from the bit stream */ if (!abits) { - memset(subband_samples[k][l], 0, 8 * sizeof(subband_samples[0][0][0])); + rscale[l] = 0; + memset(block + 8 * l, 0, 8 * sizeof(block[0])); } else { /* Deal with transients */ int sfi = s->transition_mode[k][l] && subsubframe >= s->transition_mode[k][l]; - float rscale = quant_step_size * s->scale_factor[k][l][sfi] * + rscale[l] = quant_step_size * s->scale_factor[k][l][sfi] * s->scalefactor_adj[k][sel]; if (abits >= 11 || !dca_smpl_bitalloc[abits].vlc[sel].table) { @@ -1355,7 +1321,7 @@ static int dca_subsubframe(DCAContext *s, int base_channel, int block_index) block_code1 = get_bits(&s->gb, size); block_code2 = get_bits(&s->gb, size); err = decode_blockcodes(block_code1, block_code2, - levels, block); + levels, block + 8 * l); if (err) { av_log(s->avctx, AV_LOG_ERROR, "ERROR: block code look-up failed\n"); @@ -1364,19 +1330,23 @@ static int dca_subsubframe(DCAContext *s, int base_channel, int block_index) } else { /* no coding */ for (m = 0; m < 8; m++) - block[m] = get_sbits(&s->gb, abits - 3); + block[8 * l + m] = get_sbits(&s->gb, abits - 3); } } else { /* Huffman coded */ for (m = 0; m < 8; m++) - block[m] = get_bitalloc(&s->gb, + block[8 * l + m] = get_bitalloc(&s->gb, &dca_smpl_bitalloc[abits], sel); } - s->fmt_conv.int32_to_float_fmul_scalar(subband_samples[k][l], - block, rscale, 8); } + } + + s->fmt_conv.int32_to_float_fmul_array8(&s->fmt_conv, subband_samples[k][0], + block, rscale, 8 * s->vq_start_subband[k]); + for (l = 0; l < s->vq_start_subband[k]; l++) { + int m; /* * Inverse ADPCM if in prediction mode */ @@ -1424,6 +1394,7 @@ static int dca_subsubframe(DCAContext *s, int base_channel, int block_index) #endif } else { av_log(s->avctx, AV_LOG_ERROR, "Didn't get subframe DSYNC\n"); + return AVERROR_INVALIDDATA; } } @@ -1452,13 +1423,8 @@ static int dca_filter_channels(DCAContext *s, int block_index) M_SQRT1_2 / 32768.0 /* pcm_to_double[s->source_pcm_res] */); } - /* Down mixing */ - if (s->avctx->request_channels == 2 && s->prim_channels > 2) { - dca_downmix(s->samples_chanptr, s->amode, s->downmix_coef, s->channel_order_tab); - } - /* Generate LFE samples for this subsubframe FIXME!!! */ - if (s->output & DCA_LFE) { + if (s->lfe) { lfe_interpolation_fir(s, s->lfe, 2 * s->lfe, s->lfe_data + 2 * s->lfe * (block_index + 4), s->samples_chanptr[s->lfe_index], @@ -1466,13 +1432,21 @@ static int dca_filter_channels(DCAContext *s, int block_index) /* Outputs 20bits pcm samples */ } + /* Downmixing to Stereo */ + if (s->prim_channels + !!s->lfe > 2 && + s->avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) { + dca_downmix(s->samples_chanptr, s->amode, !!s->lfe, s->downmix_coef, + s->channel_order_tab); + } + return 0; } static int dca_subframe_footer(DCAContext *s, int base_channel) { - int aux_data_count = 0, i; + int in, out, aux_data_count, aux_data_end, reserved; + uint32_t nsyncaux; /* * Unpack optional information @@ -1483,13 +1457,89 @@ static int dca_subframe_footer(DCAContext *s, int base_channel) if (s->timestamp) skip_bits_long(&s->gb, 32); - if (s->aux_data) + if (s->aux_data) { aux_data_count = get_bits(&s->gb, 6); - for (i = 0; i < aux_data_count; i++) - get_bits(&s->gb, 8); + // align (32-bit) + skip_bits_long(&s->gb, (-get_bits_count(&s->gb)) & 31); + + aux_data_end = 8 * aux_data_count + get_bits_count(&s->gb); + + if ((nsyncaux = get_bits_long(&s->gb, 32)) != DCA_NSYNCAUX) { + av_log(s->avctx, AV_LOG_ERROR, "nSYNCAUX mismatch %#"PRIx32"\n", + nsyncaux); + return AVERROR_INVALIDDATA; + } + + if (get_bits1(&s->gb)) { // bAUXTimeStampFlag + avpriv_request_sample(s->avctx, + "Auxiliary Decode Time Stamp Flag"); + // align (4-bit) + skip_bits(&s->gb, (-get_bits_count(&s->gb)) & 4); + // 44 bits: nMSByte (8), nMarker (4), nLSByte (28), nMarker (4) + skip_bits_long(&s->gb, 44); + } + + if ((s->core_downmix = get_bits1(&s->gb))) { + int am = get_bits(&s->gb, 3); + switch (am) { + case 0: + s->core_downmix_amode = DCA_MONO; + break; + case 1: + s->core_downmix_amode = DCA_STEREO; + break; + case 2: + s->core_downmix_amode = DCA_STEREO_TOTAL; + break; + case 3: + s->core_downmix_amode = DCA_3F; + break; + case 4: + s->core_downmix_amode = DCA_2F1R; + break; + case 5: + s->core_downmix_amode = DCA_2F2R; + break; + case 6: + s->core_downmix_amode = DCA_3F1R; + break; + default: + av_log(s->avctx, AV_LOG_ERROR, + "Invalid mode %d for embedded downmix coefficients\n", + am); + return AVERROR_INVALIDDATA; + } + for (out = 0; out < dca_channels[s->core_downmix_amode]; out++) { + for (in = 0; in < s->prim_channels + !!s->lfe; in++) { + uint16_t tmp = get_bits(&s->gb, 9); + if ((tmp & 0xFF) > 241) { + av_log(s->avctx, AV_LOG_ERROR, + "Invalid downmix coefficient code %"PRIu16"\n", + tmp); + return AVERROR_INVALIDDATA; + } + s->core_downmix_codes[in][out] = tmp; + } + } + } + + align_get_bits(&s->gb); // byte align + skip_bits(&s->gb, 16); // nAUXCRC16 + + // additional data (reserved, cf. ETSI TS 102 114 V1.4.1) + if ((reserved = (aux_data_end - get_bits_count(&s->gb))) < 0) { + av_log(s->avctx, AV_LOG_ERROR, + "Overread auxiliary data by %d bits\n", -reserved); + return AVERROR_INVALIDDATA; + } else if (reserved) { + avpriv_request_sample(s->avctx, + "Core auxiliary data reserved content"); + skip_bits_long(&s->gb, reserved); + } + } - if (s->crc_present && (s->downmix || s->dynrange)) + if (s->crc_present && s->dynrange) get_bits(&s->gb, 16); } @@ -2120,6 +2170,54 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, /* record number of core channels incase less than max channels are requested */ num_core_channels = s->prim_channels; + if (s->prim_channels + !!s->lfe > 2 && + avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) { + /* Stereo downmix coefficients + * + * The decoder can only downmix to 2-channel, so we need to ensure + * embedded downmix coefficients are actually targeting 2-channel. + */ + if (s->core_downmix && (s->core_downmix_amode == DCA_STEREO || + s->core_downmix_amode == DCA_STEREO_TOTAL)) { + int sign, code; + for (i = 0; i < s->prim_channels + !!s->lfe; i++) { + sign = s->core_downmix_codes[i][0] & 0x100 ? 1 : -1; + code = s->core_downmix_codes[i][0] & 0x0FF; + s->downmix_coef[i][0] = (!code ? 0.0f : + sign * dca_dmixtable[code - 1]); + sign = s->core_downmix_codes[i][1] & 0x100 ? 1 : -1; + code = s->core_downmix_codes[i][1] & 0x0FF; + s->downmix_coef[i][1] = (!code ? 0.0f : + sign * dca_dmixtable[code - 1]); + } + } else { + int am = s->amode & DCA_CHANNEL_MASK; + if (am >= FF_ARRAY_ELEMS(dca_default_coeffs)) { + av_log(s->avctx, AV_LOG_ERROR, + "Invalid channel mode %d\n", am); + return AVERROR_INVALIDDATA; + } + if (s->prim_channels + !!s->lfe > + FF_ARRAY_ELEMS(dca_default_coeffs[0])) { + avpriv_request_sample(s->avctx, "Downmixing %d channels", + s->prim_channels + !!s->lfe); + return AVERROR_PATCHWELCOME; + } + for (i = 0; i < s->prim_channels + !!s->lfe; i++) { + s->downmix_coef[i][0] = dca_default_coeffs[am][i][0]; + s->downmix_coef[i][1] = dca_default_coeffs[am][i][1]; + } + } + av_dlog(s->avctx, "Stereo downmix coeffs:\n"); + for (i = 0; i < s->prim_channels + !!s->lfe; i++) { + av_dlog(s->avctx, "L, input channel %d = %f\n", i, + s->downmix_coef[i][0]); + av_dlog(s->avctx, "R, input channel %d = %f\n", i, + s->downmix_coef[i][1]); + } + av_dlog(s->avctx, "\n"); + } + if (s->ext_coding) s->core_ext_mask = dca_ext_audio_descr_mask[s->ext_descr]; else @@ -2237,10 +2335,15 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, { /* xxx should also do MA extensions */ if (s->amode < 16) { avctx->channel_layout = dca_core_channel_layout[s->amode]; - - if (s->xch_present && (!avctx->request_channels || - avctx->request_channels - > num_core_channels + !!s->lfe)) { +#if FF_API_REQUEST_CHANNELS +FF_DISABLE_DEPRECATION_WARNINGS + if (s->xch_present && !s->xch_disable && + (!avctx->request_channels || + avctx->request_channels > num_core_channels + !!s->lfe)) { +FF_ENABLE_DEPRECATION_WARNINGS +#else + if (s->xch_present && !s->xch_disable) { +#endif avctx->channel_layout |= AV_CH_BACK_CENTER; if (s->lfe) { avctx->channel_layout |= AV_CH_LOW_FREQUENCY; @@ -2269,7 +2372,8 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } - if (avctx->request_channels == 2 && s->prim_channels > 2) { + if (s->prim_channels + !!s->lfe > 2 && + avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) { channels = 2; s->output = DCA_STEREO; avctx->channel_layout = AV_CH_LAYOUT_STEREO; @@ -2484,10 +2588,15 @@ static av_cold int dca_decode_init(AVCodecContext *avctx) avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; /* allow downmixing to stereo */ - if (avctx->channels > 0 && avctx->request_channels < avctx->channels && - avctx->request_channels == 2) { - avctx->channels = avctx->request_channels; - } +#if FF_API_REQUEST_CHANNELS +FF_DISABLE_DEPRECATION_WARNINGS + if (avctx->request_channels == 2) + avctx->request_channel_layout = AV_CH_LAYOUT_STEREO; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + if (avctx->channels > 2 && + avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) + avctx->channels = 2; return 0; } @@ -2509,17 +2618,31 @@ static const AVProfile profiles[] = { { FF_PROFILE_UNKNOWN }, }; +static const AVOption options[] = { + { "disable_xch", "disable decoding of the XCh extension", offsetof(DCAContext, xch_disable), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM|AV_OPT_FLAG_AUDIO_PARAM }, + { NULL }, +}; + +static const AVClass dca_decoder_class = { + .class_name = "DCA decoder", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, + .category = AV_CLASS_CATEGORY_DECODER, +}; + AVCodec ff_dca_decoder = { .name = "dca", + .long_name = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_DTS, .priv_data_size = sizeof(DCAContext), .init = dca_decode_init, .decode = dca_decode_frame, .close = dca_decode_end, - .long_name = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"), .capabilities = CODEC_CAP_CHANNEL_CONF | CODEC_CAP_DR1, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, .profiles = NULL_IF_CONFIG_SMALL(profiles), + .priv_class = &dca_decoder_class, }; diff --git a/ffmpeg/libavcodec/dcadsp.c b/ffmpeg/libavcodec/dcadsp.c index dd4994d..abeba24 100644 --- a/ffmpeg/libavcodec/dcadsp.c +++ b/ffmpeg/libavcodec/dcadsp.c @@ -20,6 +20,8 @@ */ #include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/intreadwrite.h" #include "dcadsp.h" static void dca_lfe_fir_c(float *out, const float *in, const float *coefs, @@ -44,8 +46,37 @@ static void dca_lfe_fir_c(float *out, const float *in, const float *coefs, } } -void ff_dcadsp_init(DCADSPContext *s) +static void dca_qmf_32_subbands(float samples_in[32][8], int sb_act, + SynthFilterContext *synth, FFTContext *imdct, + float synth_buf_ptr[512], + int *synth_buf_offset, float synth_buf2[32], + const float window[512], float *samples_out, + float raXin[32], float scale) +{ + int i; + int subindex; + + for (i = sb_act; i < 32; i++) + raXin[i] = 0.0; + + /* Reconstructed channel sample index */ + for (subindex = 0; subindex < 8; subindex++) { + /* Load in one sample from each subband and clear inactive subbands */ + for (i = 0; i < sb_act; i++) { + unsigned sign = (i - 1) & 2; + uint32_t v = AV_RN32A(&samples_in[i][subindex]) ^ sign << 30; + AV_WN32A(&raXin[i], v); + } + + synth->synth_filter_float(imdct, synth_buf_ptr, synth_buf_offset, + synth_buf2, window, samples_out, raXin, scale); + samples_out += 32; + } +} + +av_cold void ff_dcadsp_init(DCADSPContext *s) { s->lfe_fir = dca_lfe_fir_c; + s->qmf_32_subbands = dca_qmf_32_subbands; if (ARCH_ARM) ff_dcadsp_init_arm(s); } diff --git a/ffmpeg/libavcodec/dcadsp.h b/ffmpeg/libavcodec/dcadsp.h index bb157f7..d86c1f3 100644 --- a/ffmpeg/libavcodec/dcadsp.h +++ b/ffmpeg/libavcodec/dcadsp.h @@ -19,9 +19,18 @@ #ifndef AVCODEC_DCADSP_H #define AVCODEC_DCADSP_H +#include "avfft.h" +#include "synth_filter.h" + typedef struct DCADSPContext { void (*lfe_fir)(float *out, const float *in, const float *coefs, int decifactor, float scale); + void (*qmf_32_subbands)(float samples_in[32][8], int sb_act, + SynthFilterContext *synth, FFTContext *imdct, + float synth_buf_ptr[512], + int *synth_buf_offset, float synth_buf2[32], + const float window[512], float *samples_out, + float raXin[32], float scale); } DCADSPContext; void ff_dcadsp_init(DCADSPContext *s); diff --git a/ffmpeg/libavcodec/dcaenc.c b/ffmpeg/libavcodec/dcaenc.c index 4799ef4..cb73f42 100644 --- a/ffmpeg/libavcodec/dcaenc.c +++ b/ffmpeg/libavcodec/dcaenc.c @@ -1,6 +1,6 @@ /* * DCA encoder - * Copyright (C) 2008 Alexander E. Patrakov + * Copyright (C) 2008-2012 Alexander E. Patrakov * 2010 Benjamin Larsson * 2011 Xiang Wang * @@ -21,211 +21,683 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/avassert.h" #include "libavutil/channel_layout.h" #include "libavutil/common.h" -#include "libavutil/avassert.h" #include "avcodec.h" +#include "dca.h" +#include "dcadata.h" +#include "dcaenc.h" #include "internal.h" #include "put_bits.h" -#include "dcaenc.h" -#include "dcadata.h" -#include "dca.h" - -#undef NDEBUG #define MAX_CHANNELS 6 -#define DCA_SUBBANDS_32 32 -#define DCA_MAX_FRAME_SIZE 16383 +#define DCA_MAX_FRAME_SIZE 16384 #define DCA_HEADER_SIZE 13 +#define DCA_LFE_SAMPLES 8 -#define DCA_SUBBANDS 32 ///< Subband activity count -#define QUANTIZER_BITS 16 +#define DCA_SUBBANDS 32 #define SUBFRAMES 1 -#define SUBSUBFRAMES 4 -#define PCM_SAMPLES (SUBFRAMES*SUBSUBFRAMES*8) -#define LFE_BITS 8 -#define LFE_INTERPOLATION 64 -#define LFE_PRESENT 2 -#define LFE_MISSING 0 - -static const int8_t dca_lfe_index[] = { - 1,2,2,2,2,3,2,3,2,3,2,3,1,3,2,3 -}; - -static const int8_t dca_channel_reorder_lfe[][9] = { - { 0, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 1, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 1, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 1, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 1, -1, -1, -1, -1, -1, -1, -1 }, - { 1, 2, 0, -1, -1, -1, -1, -1, -1 }, - { 0, 1, -1, 2, -1, -1, -1, -1, -1 }, - { 1, 2, 0, -1, 3, -1, -1, -1, -1 }, - { 0, 1, -1, 2, 3, -1, -1, -1, -1 }, - { 1, 2, 0, -1, 3, 4, -1, -1, -1 }, - { 2, 3, -1, 0, 1, 4, 5, -1, -1 }, - { 1, 2, 0, -1, 3, 4, 5, -1, -1 }, - { 0, -1, 4, 5, 2, 3, 1, -1, -1 }, - { 3, 4, 1, -1, 0, 2, 5, 6, -1 }, - { 2, 3, -1, 5, 7, 0, 1, 4, 6 }, - { 3, 4, 1, -1, 0, 2, 5, 7, 6 }, -}; - -static const int8_t dca_channel_reorder_nolfe[][9] = { - { 0, -1, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 1, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 1, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 1, -1, -1, -1, -1, -1, -1, -1 }, - { 0, 1, -1, -1, -1, -1, -1, -1, -1 }, - { 1, 2, 0, -1, -1, -1, -1, -1, -1 }, - { 0, 1, 2, -1, -1, -1, -1, -1, -1 }, - { 1, 2, 0, 3, -1, -1, -1, -1, -1 }, - { 0, 1, 2, 3, -1, -1, -1, -1, -1 }, - { 1, 2, 0, 3, 4, -1, -1, -1, -1 }, - { 2, 3, 0, 1, 4, 5, -1, -1, -1 }, - { 1, 2, 0, 3, 4, 5, -1, -1, -1 }, - { 0, 4, 5, 2, 3, 1, -1, -1, -1 }, - { 3, 4, 1, 0, 2, 5, 6, -1, -1 }, - { 2, 3, 5, 7, 0, 1, 4, 6, -1 }, - { 3, 4, 1, 0, 2, 5, 7, 6, -1 }, -}; +#define SUBSUBFRAMES 2 +#define SUBBAND_SAMPLES (SUBFRAMES * SUBSUBFRAMES * 8) +#define AUBANDS 25 -typedef struct { +typedef struct DCAContext { PutBitContext pb; - int32_t history[MAX_CHANNELS][512]; /* This is a circular buffer */ - int start[MAX_CHANNELS]; int frame_size; - int prim_channels; + int frame_bits; + int fullband_channels; + int channels; int lfe_channel; - int sample_rate_code; - int scale_factor[MAX_CHANNELS][DCA_SUBBANDS_32]; + int samplerate_index; + int bitrate_index; + int channel_config; + const int32_t *band_interpolation; + const int32_t *band_spectrum; int lfe_scale_factor; - int lfe_data[SUBFRAMES*SUBSUBFRAMES*4]; + softfloat lfe_quant; + int32_t lfe_peak_cb; + + int32_t history[512][MAX_CHANNELS]; /* This is a circular buffer */ + int32_t subband[SUBBAND_SAMPLES][DCA_SUBBANDS][MAX_CHANNELS]; + int32_t quantized[SUBBAND_SAMPLES][DCA_SUBBANDS][MAX_CHANNELS]; + int32_t peak_cb[DCA_SUBBANDS][MAX_CHANNELS]; + int32_t downsampled_lfe[DCA_LFE_SAMPLES]; + int32_t masking_curve_cb[SUBSUBFRAMES][256]; + int abits[DCA_SUBBANDS][MAX_CHANNELS]; + int scale_factor[DCA_SUBBANDS][MAX_CHANNELS]; + softfloat quant[DCA_SUBBANDS][MAX_CHANNELS]; + int32_t eff_masking_curve_cb[256]; + int32_t band_masking_cb[32]; + int32_t worst_quantization_noise; + int32_t worst_noise_ever; + int consumed_bits; +} DCAContext; - int a_mode; ///< audio channels arrangement - int num_channel; - int lfe_state; - int lfe_offset; - const int8_t *channel_order_tab; ///< channel reordering table, lfe and non lfe +static int32_t cos_table[2048]; +static int32_t band_interpolation[2][512]; +static int32_t band_spectrum[2][8]; +static int32_t auf[9][AUBANDS][256]; +static int32_t cb_to_add[256]; +static int32_t cb_to_level[2048]; +static int32_t lfe_fir_64i[512]; - int32_t pcm[FFMAX(LFE_INTERPOLATION, DCA_SUBBANDS_32)]; - int32_t subband[PCM_SAMPLES][MAX_CHANNELS][DCA_SUBBANDS_32]; /* [sample][channel][subband] */ -} DCAContext; +/* Transfer function of outer and middle ear, Hz -> dB */ +static double hom(double f) +{ + double f1 = f / 1000; + + return -3.64 * pow(f1, -0.8) + + 6.8 * exp(-0.6 * (f1 - 3.4) * (f1 - 3.4)) + - 6.0 * exp(-0.15 * (f1 - 8.7) * (f1 - 8.7)) + - 0.0006 * (f1 * f1) * (f1 * f1); +} + +static double gammafilter(int i, double f) +{ + double h = (f - fc[i]) / erb[i]; + + h = 1 + h * h; + h = 1 / (h * h); + return 20 * log10(h); +} -static int32_t cos_table[128]; +static int encode_init(AVCodecContext *avctx) +{ + DCAContext *c = avctx->priv_data; + uint64_t layout = avctx->channel_layout; + int i, min_frame_bits; + + c->fullband_channels = c->channels = avctx->channels; + c->lfe_channel = (avctx->channels == 3 || avctx->channels == 6); + c->band_interpolation = band_interpolation[1]; + c->band_spectrum = band_spectrum[1]; + c->worst_quantization_noise = -2047; + c->worst_noise_ever = -2047; + + if (!layout) { + av_log(avctx, AV_LOG_WARNING, "No channel layout specified. The " + "encoder will guess the layout, but it " + "might be incorrect.\n"); + layout = av_get_default_channel_layout(avctx->channels); + } + switch (layout) { + case AV_CH_LAYOUT_MONO: c->channel_config = 0; break; + case AV_CH_LAYOUT_STEREO: c->channel_config = 2; break; + case AV_CH_LAYOUT_2_2: c->channel_config = 8; break; + case AV_CH_LAYOUT_5POINT0: c->channel_config = 9; break; + case AV_CH_LAYOUT_5POINT1: c->channel_config = 9; break; + default: + av_log(avctx, AV_LOG_ERROR, "Unsupported channel layout!\n"); + return AVERROR_PATCHWELCOME; + } + + if (c->lfe_channel) + c->fullband_channels--; + + for (i = 0; i < 9; i++) { + if (sample_rates[i] == avctx->sample_rate) + break; + } + if (i == 9) + return AVERROR(EINVAL); + c->samplerate_index = i; + + if (avctx->bit_rate < 32000 || avctx->bit_rate > 3840000) { + av_log(avctx, AV_LOG_ERROR, "Bit rate %i not supported.", avctx->bit_rate); + return AVERROR(EINVAL); + } + for (i = 0; dca_bit_rates[i] < avctx->bit_rate; i++) + ; + c->bitrate_index = i; + avctx->bit_rate = dca_bit_rates[i]; + c->frame_bits = FFALIGN((avctx->bit_rate * 512 + avctx->sample_rate - 1) / avctx->sample_rate, 32); + min_frame_bits = 132 + (493 + 28 * 32) * c->fullband_channels + c->lfe_channel * 72; + if (c->frame_bits < min_frame_bits || c->frame_bits > (DCA_MAX_FRAME_SIZE << 3)) + return AVERROR(EINVAL); + + c->frame_size = (c->frame_bits + 7) / 8; + + avctx->frame_size = 32 * SUBBAND_SAMPLES; + + if (!cos_table[0]) { + int j, k; + + for (i = 0; i < 2048; i++) { + cos_table[i] = (int32_t)(0x7fffffff * cos(M_PI * i / 1024)); + cb_to_level[i] = (int32_t)(0x7fffffff * pow(10, -0.005 * i)); + } + + /* FIXME: probably incorrect */ + for (i = 0; i < 256; i++) { + lfe_fir_64i[i] = (int32_t)(0x01ffffff * lfe_fir_64[i]); + lfe_fir_64i[511 - i] = (int32_t)(0x01ffffff * lfe_fir_64[i]); + } + + for (i = 0; i < 512; i++) { + band_interpolation[0][i] = (int32_t)(0x1000000000ULL * fir_32bands_perfect[i]); + band_interpolation[1][i] = (int32_t)(0x1000000000ULL * fir_32bands_nonperfect[i]); + } + + for (i = 0; i < 9; i++) { + for (j = 0; j < AUBANDS; j++) { + for (k = 0; k < 256; k++) { + double freq = sample_rates[i] * (k + 0.5) / 512; + + auf[i][j][k] = (int32_t)(10 * (hom(freq) + gammafilter(j, freq))); + } + } + } + + for (i = 0; i < 256; i++) { + double add = 1 + pow(10, -0.01 * i); + cb_to_add[i] = (int32_t)(100 * log10(add)); + } + for (j = 0; j < 8; j++) { + double accum = 0; + for (i = 0; i < 512; i++) { + double reconst = fir_32bands_perfect[i] * ((i & 64) ? (-1) : 1); + accum += reconst * cos(2 * M_PI * (i + 0.5 - 256) * (j + 0.5) / 512); + } + band_spectrum[0][j] = (int32_t)(200 * log10(accum)); + } + for (j = 0; j < 8; j++) { + double accum = 0; + for (i = 0; i < 512; i++) { + double reconst = fir_32bands_nonperfect[i] * ((i & 64) ? (-1) : 1); + accum += reconst * cos(2 * M_PI * (i + 0.5 - 256) * (j + 0.5) / 512); + } + band_spectrum[1][j] = (int32_t)(200 * log10(accum)); + } + } + return 0; +} + +static inline int32_t cos_t(int x) +{ + return cos_table[x & 2047]; +} + +static inline int32_t sin_t(int x) +{ + return cos_t(x - 512); +} + +static inline int32_t half32(int32_t a) +{ + return (a + 1) >> 1; +} static inline int32_t mul32(int32_t a, int32_t b) { - int64_t r = (int64_t) a * b; - /* round the result before truncating - improves accuracy */ - return (r + 0x80000000) >> 32; + int64_t r = (int64_t)a * b + 0x80000000ULL; + return r >> 32; +} + +static void subband_transform(DCAContext *c, const int32_t *input) +{ + int ch, subs, i, k, j; + + for (ch = 0; ch < c->fullband_channels; ch++) { + /* History is copied because it is also needed for PSY */ + int32_t hist[512]; + int hist_start = 0; + + for (i = 0; i < 512; i++) + hist[i] = c->history[i][ch]; + + for (subs = 0; subs < SUBBAND_SAMPLES; subs++) { + int32_t accum[64]; + int32_t resp; + int band; + + /* Calculate the convolutions at once */ + for (i = 0; i < 64; i++) + accum[i] = 0; + + for (k = 0, i = hist_start, j = 0; + i < 512; k = (k + 1) & 63, i++, j++) + accum[k] += mul32(hist[i], c->band_interpolation[j]); + for (i = 0; i < hist_start; k = (k + 1) & 63, i++, j++) + accum[k] += mul32(hist[i], c->band_interpolation[j]); + + for (k = 16; k < 32; k++) + accum[k] = accum[k] - accum[31 - k]; + for (k = 32; k < 48; k++) + accum[k] = accum[k] + accum[95 - k]; + + for (band = 0; band < 32; band++) { + resp = 0; + for (i = 16; i < 48; i++) { + int s = (2 * band + 1) * (2 * (i + 16) + 1); + resp += mul32(accum[i], cos_t(s << 3)) >> 3; + } + + c->subband[subs][band][ch] = ((band + 1) & 2) ? -resp : resp; + } + + /* Copy in 32 new samples from input */ + for (i = 0; i < 32; i++) + hist[i + hist_start] = input[(subs * 32 + i) * c->channels + ch]; + hist_start = (hist_start + 32) & 511; + } + } +} + +static void lfe_downsample(DCAContext *c, const int32_t *input) +{ + /* FIXME: make 128x LFE downsampling possible */ + int i, j, lfes; + int32_t hist[512]; + int32_t accum; + int hist_start = 0; + + for (i = 0; i < 512; i++) + hist[i] = c->history[i][c->channels - 1]; + + for (lfes = 0; lfes < DCA_LFE_SAMPLES; lfes++) { + /* Calculate the convolution */ + accum = 0; + + for (i = hist_start, j = 0; i < 512; i++, j++) + accum += mul32(hist[i], lfe_fir_64i[j]); + for (i = 0; i < hist_start; i++, j++) + accum += mul32(hist[i], lfe_fir_64i[j]); + + c->downsampled_lfe[lfes] = accum; + + /* Copy in 64 new samples from input */ + for (i = 0; i < 64; i++) + hist[i + hist_start] = input[(lfes * 64 + i) * c->channels + c->channels - 1]; + + hist_start = (hist_start + 64) & 511; + } } -/* Integer version of the cosine modulated Pseudo QMF */ +typedef struct { + int32_t re; + int32_t im; +} cplx32; -static void qmf_init(void) +static void fft(const int32_t in[2 * 256], cplx32 out[256]) { - int i; - int32_t c[17], s[17]; - s[0] = 0; /* sin(index * PI / 64) * 0x7fffffff */ - c[0] = 0x7fffffff; /* cos(index * PI / 64) * 0x7fffffff */ - - for (i = 1; i <= 16; i++) { - s[i] = 2 * (mul32(c[i - 1], 105372028) + mul32(s[i - 1], 2144896908)); - c[i] = 2 * (mul32(c[i - 1], 2144896908) - mul32(s[i - 1], 105372028)); + cplx32 buf[256], rin[256], rout[256]; + int i, j, k, l; + + /* do two transforms in parallel */ + for (i = 0; i < 256; i++) { + /* Apply the Hann window */ + rin[i].re = mul32(in[2 * i], 0x3fffffff - (cos_t(8 * i + 2) >> 1)); + rin[i].im = mul32(in[2 * i + 1], 0x3fffffff - (cos_t(8 * i + 6) >> 1)); + } + /* pre-rotation */ + for (i = 0; i < 256; i++) { + buf[i].re = mul32(cos_t(4 * i + 2), rin[i].re) + - mul32(sin_t(4 * i + 2), rin[i].im); + buf[i].im = mul32(cos_t(4 * i + 2), rin[i].im) + + mul32(sin_t(4 * i + 2), rin[i].re); + } + + for (j = 256, l = 1; j != 1; j >>= 1, l <<= 1) { + for (k = 0; k < 256; k += j) { + for (i = k; i < k + j / 2; i++) { + cplx32 sum, diff; + int t = 8 * l * i; + + sum.re = buf[i].re + buf[i + j / 2].re; + sum.im = buf[i].im + buf[i + j / 2].im; + + diff.re = buf[i].re - buf[i + j / 2].re; + diff.im = buf[i].im - buf[i + j / 2].im; + + buf[i].re = half32(sum.re); + buf[i].im = half32(sum.im); + + buf[i + j / 2].re = mul32(diff.re, cos_t(t)) + - mul32(diff.im, sin_t(t)); + buf[i + j / 2].im = mul32(diff.im, cos_t(t)) + + mul32(diff.re, sin_t(t)); + } + } + } + /* post-rotation */ + for (i = 0; i < 256; i++) { + int b = ff_reverse[i]; + rout[i].re = mul32(buf[b].re, cos_t(4 * i)) + - mul32(buf[b].im, sin_t(4 * i)); + rout[i].im = mul32(buf[b].im, cos_t(4 * i)) + + mul32(buf[b].re, sin_t(4 * i)); + } + for (i = 0; i < 256; i++) { + /* separate the results of the two transforms */ + cplx32 o1, o2; + + o1.re = rout[i].re - rout[255 - i].re; + o1.im = rout[i].im + rout[255 - i].im; + + o2.re = rout[i].im - rout[255 - i].im; + o2.im = -rout[i].re - rout[255 - i].re; + + /* combine them into one long transform */ + out[i].re = mul32( o1.re + o2.re, cos_t(2 * i + 1)) + + mul32( o1.im - o2.im, sin_t(2 * i + 1)); + out[i].im = mul32( o1.im + o2.im, cos_t(2 * i + 1)) + + mul32(-o1.re + o2.re, sin_t(2 * i + 1)); } +} - for (i = 0; i < 16; i++) { - cos_table[i ] = c[i] >> 3; /* avoid output overflow */ - cos_table[i + 16] = s[16 - i] >> 3; - cos_table[i + 32] = -s[i] >> 3; - cos_table[i + 48] = -c[16 - i] >> 3; - cos_table[i + 64] = -c[i] >> 3; - cos_table[i + 80] = -s[16 - i] >> 3; - cos_table[i + 96] = s[i] >> 3; - cos_table[i + 112] = c[16 - i] >> 3; +static int32_t get_cb(int32_t in) +{ + int i, res; + + res = 0; + if (in < 0) + in = -in; + for (i = 1024; i > 0; i >>= 1) { + if (cb_to_level[i + res] >= in) + res += i; } + return -res; } -static int32_t band_delta_factor(int band, int sample_num) +static int32_t add_cb(int32_t a, int32_t b) { - int index = band * (2 * sample_num + 1); - if (band == 0) - return 0x07ffffff; - else - return cos_table[index & 127]; + if (a < b) + FFSWAP(int32_t, a, b); + + if (a - b >= 256) + return a; + return a + cb_to_add[a - b]; } -static void add_new_samples(DCAContext *c, const int32_t *in, - int count, int channel) +static void adjust_jnd(int samplerate_index, + const int32_t in[512], int32_t out_cb[256]) { - int i; + int32_t power[256]; + cplx32 out[256]; + int32_t out_cb_unnorm[256]; + int32_t denom; + const int32_t ca_cb = -1114; + const int32_t cs_cb = 928; + int i, j; - /* Place new samples into the history buffer */ - for (i = 0; i < count; i++) { - c->history[channel][c->start[channel] + i] = in[i]; - av_assert0(c->start[channel] + i < 512); + fft(in, out); + + for (j = 0; j < 256; j++) { + power[j] = add_cb(get_cb(out[j].re), get_cb(out[j].im)); + out_cb_unnorm[j] = -2047; /* and can only grow */ + } + + for (i = 0; i < AUBANDS; i++) { + denom = ca_cb; /* and can only grow */ + for (j = 0; j < 256; j++) + denom = add_cb(denom, power[j] + auf[samplerate_index][i][j]); + for (j = 0; j < 256; j++) + out_cb_unnorm[j] = add_cb(out_cb_unnorm[j], + -denom + auf[samplerate_index][i][j]); } - c->start[channel] += count; - if (c->start[channel] == 512) - c->start[channel] = 0; - av_assert0(c->start[channel] < 512); + + for (j = 0; j < 256; j++) + out_cb[j] = add_cb(out_cb[j], -out_cb_unnorm[j] - ca_cb - cs_cb); } -static void qmf_decompose(DCAContext *c, int32_t in[32], int32_t out[32], - int channel) +typedef void (*walk_band_t)(DCAContext *c, int band1, int band2, int f, + int32_t spectrum1, int32_t spectrum2, int channel, + int32_t * arg); + +static void walk_band_low(DCAContext *c, int band, int channel, + walk_band_t walk, int32_t *arg) { - int band, i, j, k; - int32_t resp; - int32_t accum[DCA_SUBBANDS_32] = {0}; + int f; - add_new_samples(c, in, DCA_SUBBANDS_32, channel); + if (band == 0) { + for (f = 0; f < 4; f++) + walk(c, 0, 0, f, 0, -2047, channel, arg); + } else { + for (f = 0; f < 8; f++) + walk(c, band, band - 1, 8 * band - 4 + f, + c->band_spectrum[7 - f], c->band_spectrum[f], channel, arg); + } +} - /* Calculate the dot product of the signal with the (possibly inverted) - reference decoder's response to this vector: - (0.0, 0.0, ..., 0.0, -1.0, 1.0, 0.0, ..., 0.0) - so that -1.0 cancels 1.0 from the previous step */ +static void walk_band_high(DCAContext *c, int band, int channel, + walk_band_t walk, int32_t *arg) +{ + int f; - for (k = 48, j = 0, i = c->start[channel]; i < 512; k++, j++, i++) - accum[(k & 32) ? (31 - (k & 31)) : (k & 31)] += mul32(c->history[channel][i], UnQMF[j]); - for (i = 0; i < c->start[channel]; k++, j++, i++) - accum[(k & 32) ? (31 - (k & 31)) : (k & 31)] += mul32(c->history[channel][i], UnQMF[j]); + if (band == 31) { + for (f = 0; f < 4; f++) + walk(c, 31, 31, 256 - 4 + f, 0, -2047, channel, arg); + } else { + for (f = 0; f < 8; f++) + walk(c, band, band + 1, 8 * band + 4 + f, + c->band_spectrum[f], c->band_spectrum[7 - f], channel, arg); + } +} - resp = 0; - /* TODO: implement FFT instead of this naive calculation */ - for (band = 0; band < DCA_SUBBANDS_32; band++) { - for (j = 0; j < 32; j++) - resp += mul32(accum[j], band_delta_factor(band, j)); +static void update_band_masking(DCAContext *c, int band1, int band2, + int f, int32_t spectrum1, int32_t spectrum2, + int channel, int32_t * arg) +{ + int32_t value = c->eff_masking_curve_cb[f] - spectrum1; + + if (value < c->band_masking_cb[band1]) + c->band_masking_cb[band1] = value; +} + +static void calc_masking(DCAContext *c, const int32_t *input) +{ + int i, k, band, ch, ssf; + int32_t data[512]; + + for (i = 0; i < 256; i++) + for (ssf = 0; ssf < SUBSUBFRAMES; ssf++) + c->masking_curve_cb[ssf][i] = -2047; + + for (ssf = 0; ssf < SUBSUBFRAMES; ssf++) + for (ch = 0; ch < c->fullband_channels; ch++) { + for (i = 0, k = 128 + 256 * ssf; k < 512; i++, k++) + data[i] = c->history[k][ch]; + for (k -= 512; i < 512; i++, k++) + data[i] = input[k * c->channels + ch]; + adjust_jnd(c->samplerate_index, data, c->masking_curve_cb[ssf]); + } + for (i = 0; i < 256; i++) { + int32_t m = 2048; + + for (ssf = 0; ssf < SUBSUBFRAMES; ssf++) + if (c->masking_curve_cb[ssf][i] < m) + m = c->masking_curve_cb[ssf][i]; + c->eff_masking_curve_cb[i] = m; + } - out[band] = (band & 2) ? (-resp) : resp; + for (band = 0; band < 32; band++) { + c->band_masking_cb[band] = 2048; + walk_band_low(c, band, 0, update_band_masking, NULL); + walk_band_high(c, band, 0, update_band_masking, NULL); } } -static int32_t lfe_fir_64i[512]; -static int lfe_downsample(DCAContext *c, int32_t in[LFE_INTERPOLATION]) +static void find_peaks(DCAContext *c) { - int i, j; - int channel = c->prim_channels; - int32_t accum = 0; - - add_new_samples(c, in, LFE_INTERPOLATION, channel); - for (i = c->start[channel], j = 0; i < 512; i++, j++) - accum += mul32(c->history[channel][i], lfe_fir_64i[j]); - for (i = 0; i < c->start[channel]; i++, j++) - accum += mul32(c->history[channel][i], lfe_fir_64i[j]); - return accum; + int band, ch; + + for (band = 0; band < 32; band++) + for (ch = 0; ch < c->fullband_channels; ch++) { + int sample; + int32_t m = 0; + + for (sample = 0; sample < SUBBAND_SAMPLES; sample++) { + int32_t s = abs(c->subband[sample][band][ch]); + if (m < s) + m = s; + } + c->peak_cb[band][ch] = get_cb(m); + } + + if (c->lfe_channel) { + int sample; + int32_t m = 0; + + for (sample = 0; sample < DCA_LFE_SAMPLES; sample++) + if (m < abs(c->downsampled_lfe[sample])) + m = abs(c->downsampled_lfe[sample]); + c->lfe_peak_cb = get_cb(m); + } } -static void init_lfe_fir(void) +static const int snr_fudge = 128; +#define USED_1ABITS 1 +#define USED_NABITS 2 +#define USED_26ABITS 4 + +static int init_quantization_noise(DCAContext *c, int noise) { - static int initialized = 0; - int i; - if (initialized) - return; + int ch, band, ret = 0; + + c->consumed_bits = 132 + 493 * c->fullband_channels; + if (c->lfe_channel) + c->consumed_bits += 72; + + /* attempt to guess the bit distribution based on the prevoius frame */ + for (ch = 0; ch < c->fullband_channels; ch++) { + for (band = 0; band < 32; band++) { + int snr_cb = c->peak_cb[band][ch] - c->band_masking_cb[band] - noise; + + if (snr_cb >= 1312) { + c->abits[band][ch] = 26; + ret |= USED_26ABITS; + } else if (snr_cb >= 222) { + c->abits[band][ch] = 8 + mul32(snr_cb - 222, 69000000); + ret |= USED_NABITS; + } else if (snr_cb >= 0) { + c->abits[band][ch] = 2 + mul32(snr_cb, 106000000); + ret |= USED_NABITS; + } else { + c->abits[band][ch] = 1; + ret |= USED_1ABITS; + } + } + } - for (i = 0; i < 512; i++) - lfe_fir_64i[i] = lfe_fir_64[i] * (1 << 25); //float -> int32_t - initialized = 1; + for (band = 0; band < 32; band++) + for (ch = 0; ch < c->fullband_channels; ch++) { + c->consumed_bits += bit_consumption[c->abits[band][ch]]; + } + + return ret; +} + +static void assign_bits(DCAContext *c) +{ + /* Find the bounds where the binary search should work */ + int low, high, down; + int used_abits = 0; + + init_quantization_noise(c, c->worst_quantization_noise); + low = high = c->worst_quantization_noise; + if (c->consumed_bits > c->frame_bits) { + while (c->consumed_bits > c->frame_bits) { + av_assert0(used_abits != USED_1ABITS); + low = high; + high += snr_fudge; + used_abits = init_quantization_noise(c, high); + } + } else { + while (c->consumed_bits <= c->frame_bits) { + high = low; + if (used_abits == USED_26ABITS) + goto out; /* The requested bitrate is too high, pad with zeros */ + low -= snr_fudge; + used_abits = init_quantization_noise(c, low); + } + } + + /* Now do a binary search between low and high to see what fits */ + for (down = snr_fudge >> 1; down; down >>= 1) { + init_quantization_noise(c, high - down); + if (c->consumed_bits <= c->frame_bits) + high -= down; + } + init_quantization_noise(c, high); +out: + c->worst_quantization_noise = high; + if (high > c->worst_noise_ever) + c->worst_noise_ever = high; +} + +static void shift_history(DCAContext *c, const int32_t *input) +{ + int k, ch; + + for (k = 0; k < 512; k++) + for (ch = 0; ch < c->channels; ch++) + c->history[k][ch] = input[k * c->channels + ch]; +} + +static int32_t quantize_value(int32_t value, softfloat quant) +{ + int32_t offset = 1 << (quant.e - 1); + + value = mul32(value, quant.m) + offset; + value = value >> quant.e; + return value; +} + +static int calc_one_scale(int32_t peak_cb, int abits, softfloat *quant) +{ + int32_t peak; + int our_nscale, try_remove; + softfloat our_quant; + + av_assert0(peak_cb <= 0); + av_assert0(peak_cb >= -2047); + + our_nscale = 127; + peak = cb_to_level[-peak_cb]; + + for (try_remove = 64; try_remove > 0; try_remove >>= 1) { + if (scalefactor_inv[our_nscale - try_remove].e + stepsize_inv[abits].e <= 17) + continue; + our_quant.m = mul32(scalefactor_inv[our_nscale - try_remove].m, stepsize_inv[abits].m); + our_quant.e = scalefactor_inv[our_nscale - try_remove].e + stepsize_inv[abits].e - 17; + if ((quant_levels[abits] - 1) / 2 < quantize_value(peak, our_quant)) + continue; + our_nscale -= try_remove; + } + + if (our_nscale >= 125) + our_nscale = 124; + + quant->m = mul32(scalefactor_inv[our_nscale].m, stepsize_inv[abits].m); + quant->e = scalefactor_inv[our_nscale].e + stepsize_inv[abits].e - 17; + av_assert0((quant_levels[abits] - 1) / 2 >= quantize_value(peak, *quant)); + + return our_nscale; +} + +static void calc_scales(DCAContext *c) +{ + int band, ch; + + for (band = 0; band < 32; band++) + for (ch = 0; ch < c->fullband_channels; ch++) + c->scale_factor[band][ch] = calc_one_scale(c->peak_cb[band][ch], + c->abits[band][ch], + &c->quant[band][ch]); + + if (c->lfe_channel) + c->lfe_scale_factor = calc_one_scale(c->lfe_peak_cb, 11, &c->lfe_quant); +} + +static void quantize_all(DCAContext *c) +{ + int sample, band, ch; + + for (sample = 0; sample < SUBBAND_SAMPLES; sample++) + for (band = 0; band < 32; band++) + for (ch = 0; ch < c->fullband_channels; ch++) + c->quantized[sample][band][ch] = quantize_value(c->subband[sample][band][ch], c->quant[band][ch]); } static void put_frame_header(DCAContext *c) @@ -244,19 +716,19 @@ static void put_frame_header(DCAContext *c) put_bits(&c->pb, 1, 0); /* Number of PCM sample blocks */ - put_bits(&c->pb, 7, PCM_SAMPLES-1); + put_bits(&c->pb, 7, SUBBAND_SAMPLES - 1); /* Primary frame byte size */ - put_bits(&c->pb, 14, c->frame_size-1); + put_bits(&c->pb, 14, c->frame_size - 1); - /* Audio channel arrangement: L + R (stereo) */ - put_bits(&c->pb, 6, c->num_channel); + /* Audio channel arrangement */ + put_bits(&c->pb, 6, c->channel_config); /* Core audio sampling frequency */ - put_bits(&c->pb, 4, c->sample_rate_code); + put_bits(&c->pb, 4, bitstream_sfreq[c->samplerate_index]); - /* Transmission bit rate: 1411.2 kbps */ - put_bits(&c->pb, 5, 0x16); /* FIXME: magic number */ + /* Transmission bit rate */ + put_bits(&c->pb, 5, c->bitrate_index); /* Embedded down mix: disabled */ put_bits(&c->pb, 1, 0); @@ -282,8 +754,8 @@ static void put_frame_header(DCAContext *c) /* Audio sync word insertion flag: after each sub-frame */ put_bits(&c->pb, 1, 0); - /* Low frequency effects flag: not present or interpolation factor=64 */ - put_bits(&c->pb, 2, c->lfe_state); + /* Low frequency effects flag: not present or 64x subsampling */ + put_bits(&c->pb, 2, c->lfe_channel ? 2 : 0); /* Predictor history switch flag: on */ put_bits(&c->pb, 1, 1); @@ -321,82 +793,68 @@ static void put_primary_audio_header(DCAContext *c) put_bits(&c->pb, 4, SUBFRAMES - 1); /* Number of primary audio channels */ - put_bits(&c->pb, 3, c->prim_channels - 1); + put_bits(&c->pb, 3, c->fullband_channels - 1); /* Subband activity count */ - for (ch = 0; ch < c->prim_channels; ch++) + for (ch = 0; ch < c->fullband_channels; ch++) put_bits(&c->pb, 5, DCA_SUBBANDS - 2); /* High frequency VQ start subband */ - for (ch = 0; ch < c->prim_channels; ch++) + for (ch = 0; ch < c->fullband_channels; ch++) put_bits(&c->pb, 5, DCA_SUBBANDS - 1); /* Joint intensity coding index: 0, 0 */ - for (ch = 0; ch < c->prim_channels; ch++) + for (ch = 0; ch < c->fullband_channels; ch++) put_bits(&c->pb, 3, 0); /* Transient mode codebook: A4, A4 (arbitrary) */ - for (ch = 0; ch < c->prim_channels; ch++) + for (ch = 0; ch < c->fullband_channels; ch++) put_bits(&c->pb, 2, 0); /* Scale factor code book: 7 bit linear, 7-bit sqrt table (for each channel) */ - for (ch = 0; ch < c->prim_channels; ch++) + for (ch = 0; ch < c->fullband_channels; ch++) put_bits(&c->pb, 3, 6); /* Bit allocation quantizer select: linear 5-bit */ - for (ch = 0; ch < c->prim_channels; ch++) + for (ch = 0; ch < c->fullband_channels; ch++) put_bits(&c->pb, 3, 6); /* Quantization index codebook select: dummy data to avoid transmission of scale factor adjustment */ - for (i = 1; i < 11; i++) - for (ch = 0; ch < c->prim_channels; ch++) + for (ch = 0; ch < c->fullband_channels; ch++) put_bits(&c->pb, bitlen[i], thr[i]); /* Scale factor adjustment index: not transmitted */ + /* Audio header CRC check word: not transmitted */ } -/** - * 8-23 bits quantization - * @param sample - * @param bits - */ -static inline uint32_t quantize(int32_t sample, int bits) -{ - av_assert0(sample < 1 << (bits - 1)); - av_assert0(sample >= -(1 << (bits - 1))); - return sample & ((1 << bits) - 1); -} - -static inline int find_scale_factor7(int64_t max_value, int bits) +static void put_subframe_samples(DCAContext *c, int ss, int band, int ch) { - int i = 0, j = 128, q; - max_value = ((max_value << 15) / lossy_quant[bits + 3]) >> (bits - 1); - while (i < j) { - q = (i + j) >> 1; - if (max_value < scale_factor_quant7[q]) - j = q; - else - i = q + 1; + if (c->abits[band][ch] <= 7) { + int sum, i, j; + for (i = 0; i < 8; i += 4) { + sum = 0; + for (j = 3; j >= 0; j--) { + sum *= quant_levels[c->abits[band][ch]]; + sum += c->quantized[ss * 8 + i + j][band][ch]; + sum += (quant_levels[c->abits[band][ch]] - 1) / 2; + } + put_bits(&c->pb, bit_consumption[c->abits[band][ch]] / 4, sum); + } + } else { + int i; + for (i = 0; i < 8; i++) { + int bits = bit_consumption[c->abits[band][ch]] / 16; + int32_t mask = (1 << bits) - 1; + put_bits(&c->pb, bits, c->quantized[ss * 8 + i][band][ch] & mask); + } } - av_assert1(i < 128); - return i; -} - -static inline void put_sample7(DCAContext *c, int64_t sample, int bits, - int scale_factor) -{ - sample = (sample << 15) / ((int64_t) lossy_quant[bits + 3] * scale_factor_quant7[scale_factor]); - put_bits(&c->pb, bits, quantize((int) sample, bits)); } -static void put_subframe(DCAContext *c, - int32_t subband_data[8 * SUBSUBFRAMES][MAX_CHANNELS][32], - int subframe) +static void put_subframe(DCAContext *c, int subframe) { - int i, sub, ss, ch, max_value; - int32_t *lfe_data = c->lfe_data + 4 * SUBSUBFRAMES * subframe; + int i, band, ss, ch; /* Subsubframes count */ put_bits(&c->pb, 2, SUBSUBFRAMES -1); @@ -405,44 +863,27 @@ static void put_subframe(DCAContext *c, put_bits(&c->pb, 3, 0); /* Prediction mode: no ADPCM, in each channel and subband */ - for (ch = 0; ch < c->prim_channels; ch++) - for (sub = 0; sub < DCA_SUBBANDS; sub++) + for (ch = 0; ch < c->fullband_channels; ch++) + for (band = 0; band < DCA_SUBBANDS; band++) put_bits(&c->pb, 1, 0); /* Prediction VQ addres: not transmitted */ /* Bit allocation index */ - for (ch = 0; ch < c->prim_channels; ch++) - for (sub = 0; sub < DCA_SUBBANDS; sub++) - put_bits(&c->pb, 5, QUANTIZER_BITS+3); + for (ch = 0; ch < c->fullband_channels; ch++) + for (band = 0; band < DCA_SUBBANDS; band++) + put_bits(&c->pb, 5, c->abits[band][ch]); if (SUBSUBFRAMES > 1) { /* Transition mode: none for each channel and subband */ - for (ch = 0; ch < c->prim_channels; ch++) - for (sub = 0; sub < DCA_SUBBANDS; sub++) + for (ch = 0; ch < c->fullband_channels; ch++) + for (band = 0; band < DCA_SUBBANDS; band++) put_bits(&c->pb, 1, 0); /* codebook A4 */ } - /* Determine scale_factor */ - for (ch = 0; ch < c->prim_channels; ch++) - for (sub = 0; sub < DCA_SUBBANDS; sub++) { - max_value = 0; - for (i = 0; i < 8 * SUBSUBFRAMES; i++) - max_value = FFMAX(max_value, FFABS(subband_data[i][ch][sub])); - c->scale_factor[ch][sub] = find_scale_factor7(max_value, QUANTIZER_BITS); - } - - if (c->lfe_channel) { - max_value = 0; - for (i = 0; i < 4 * SUBSUBFRAMES; i++) - max_value = FFMAX(max_value, FFABS(lfe_data[i])); - c->lfe_scale_factor = find_scale_factor7(max_value, LFE_BITS); - } - - /* Scale factors: the same for each channel and subband, - encoded according to Table D.1.2 */ - for (ch = 0; ch < c->prim_channels; ch++) - for (sub = 0; sub < DCA_SUBBANDS; sub++) - put_bits(&c->pb, 7, c->scale_factor[ch][sub]); + /* Scale factors */ + for (ch = 0; ch < c->fullband_channels; ch++) + for (band = 0; band < DCA_SUBBANDS; band++) + put_bits(&c->pb, 7, c->scale_factor[band][ch]); /* Joint subband scale factor codebook select: not transmitted */ /* Scale factors for joint subband coding: not transmitted */ @@ -451,152 +892,83 @@ static void put_subframe(DCAContext *c, /* Stde information CRC check word: not transmitted */ /* VQ encoded high frequency subbands: not transmitted */ - /* LFE data */ + /* LFE data: 8 samples and scalefactor */ if (c->lfe_channel) { - for (i = 0; i < 4 * SUBSUBFRAMES; i++) - put_sample7(c, lfe_data[i], LFE_BITS, c->lfe_scale_factor); + for (i = 0; i < DCA_LFE_SAMPLES; i++) + put_bits(&c->pb, 8, quantize_value(c->downsampled_lfe[i], c->lfe_quant) & 0xff); put_bits(&c->pb, 8, c->lfe_scale_factor); } /* Audio data (subsubframes) */ - for (ss = 0; ss < SUBSUBFRAMES ; ss++) - for (ch = 0; ch < c->prim_channels; ch++) - for (sub = 0; sub < DCA_SUBBANDS; sub++) - for (i = 0; i < 8; i++) - put_sample7(c, subband_data[ss * 8 + i][ch][sub], QUANTIZER_BITS, c->scale_factor[ch][sub]); + for (ch = 0; ch < c->fullband_channels; ch++) + for (band = 0; band < DCA_SUBBANDS; band++) + put_subframe_samples(c, ss, band, ch); /* DSYNC */ put_bits(&c->pb, 16, 0xffff); } -static void put_frame(DCAContext *c, - int32_t subband_data[PCM_SAMPLES][MAX_CHANNELS][32], - uint8_t *frame) -{ - int i; - init_put_bits(&c->pb, frame + DCA_HEADER_SIZE, DCA_MAX_FRAME_SIZE-DCA_HEADER_SIZE); - - put_primary_audio_header(c); - for (i = 0; i < SUBFRAMES; i++) - put_subframe(c, &subband_data[SUBSUBFRAMES * 8 * i], i); - - flush_put_bits(&c->pb); - c->frame_size = (put_bits_count(&c->pb) >> 3) + DCA_HEADER_SIZE; - - init_put_bits(&c->pb, frame, DCA_HEADER_SIZE); - put_frame_header(c); - flush_put_bits(&c->pb); -} - static int encode_frame(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr) { - int i, k, channel; DCAContext *c = avctx->priv_data; - const int16_t *samples; - int ret, real_channel = 0; + const int32_t *samples; + int ret, i; - if ((ret = ff_alloc_packet2(avctx, avpkt, DCA_MAX_FRAME_SIZE + DCA_HEADER_SIZE)) < 0) + if ((ret = ff_alloc_packet2(avctx, avpkt, c->frame_size )) < 0) return ret; - samples = (const int16_t *)frame->data[0]; - for (i = 0; i < PCM_SAMPLES; i ++) { /* i is the decimated sample number */ - for (channel = 0; channel < c->prim_channels + 1; channel++) { - real_channel = c->channel_order_tab[channel]; - if (real_channel >= 0) { - /* Get 32 PCM samples */ - for (k = 0; k < 32; k++) { /* k is the sample number in a 32-sample block */ - c->pcm[k] = samples[avctx->channels * (32 * i + k) + channel] << 16; - } - /* Put subband samples into the proper place */ - qmf_decompose(c, c->pcm, &c->subband[i][real_channel][0], real_channel); - } - } - } - - if (c->lfe_channel) { - for (i = 0; i < PCM_SAMPLES / 2; i++) { - for (k = 0; k < LFE_INTERPOLATION; k++) /* k is the sample number in a 32-sample block */ - c->pcm[k] = samples[avctx->channels * (LFE_INTERPOLATION*i+k) + c->lfe_offset] << 16; - c->lfe_data[i] = lfe_downsample(c, c->pcm); - } - } - - put_frame(c, c->subband, avpkt->data); + samples = (const int32_t *)frame->data[0]; - avpkt->size = c->frame_size; - *got_packet_ptr = 1; - return 0; -} - -static int encode_init(AVCodecContext *avctx) -{ - DCAContext *c = avctx->priv_data; - int i; - uint64_t layout = avctx->channel_layout; - - c->prim_channels = avctx->channels; - c->lfe_channel = (avctx->channels == 3 || avctx->channels == 6); - - if (!layout) { - av_log(avctx, AV_LOG_WARNING, "No channel layout specified. The " - "encoder will guess the layout, but it " - "might be incorrect.\n"); - layout = av_get_default_channel_layout(avctx->channels); - } - switch (layout) { - case AV_CH_LAYOUT_STEREO: c->a_mode = 2; c->num_channel = 2; break; - case AV_CH_LAYOUT_5POINT0: c->a_mode = 9; c->num_channel = 9; break; - case AV_CH_LAYOUT_5POINT1: c->a_mode = 9; c->num_channel = 9; break; - case AV_CH_LAYOUT_5POINT0_BACK: c->a_mode = 9; c->num_channel = 9; break; - case AV_CH_LAYOUT_5POINT1_BACK: c->a_mode = 9; c->num_channel = 9; break; - default: - av_log(avctx, AV_LOG_ERROR, - "Only stereo, 5.0, 5.1 channel layouts supported at the moment!\n"); - return AVERROR_PATCHWELCOME; - } + subband_transform(c, samples); + if (c->lfe_channel) + lfe_downsample(c, samples); - if (c->lfe_channel) { - init_lfe_fir(); - c->prim_channels--; - c->channel_order_tab = dca_channel_reorder_lfe[c->a_mode]; - c->lfe_state = LFE_PRESENT; - c->lfe_offset = dca_lfe_index[c->a_mode]; - } else { - c->channel_order_tab = dca_channel_reorder_nolfe[c->a_mode]; - c->lfe_state = LFE_MISSING; - } + calc_masking(c, samples); + find_peaks(c); + assign_bits(c); + calc_scales(c); + quantize_all(c); + shift_history(c, samples); - for (i = 0; i < 16; i++) { - if (avpriv_dca_sample_rates[i] && (avpriv_dca_sample_rates[i] == avctx->sample_rate)) - break; - } - if (i == 16) { - av_log(avctx, AV_LOG_ERROR, "Sample rate %iHz not supported, only ", avctx->sample_rate); - for (i = 0; i < 16; i++) - av_log(avctx, AV_LOG_ERROR, "%d, ", avpriv_dca_sample_rates[i]); - av_log(avctx, AV_LOG_ERROR, "supported.\n"); - return -1; - } - c->sample_rate_code = i; + init_put_bits(&c->pb, avpkt->data, avpkt->size); + put_frame_header(c); + put_primary_audio_header(c); + for (i = 0; i < SUBFRAMES; i++) + put_subframe(c, i); - avctx->frame_size = 32 * PCM_SAMPLES; + flush_put_bits(&c->pb); - if (!cos_table[127]) - qmf_init(); + avpkt->pts = frame->pts; + avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples); + avpkt->size = c->frame_size + 1; + *got_packet_ptr = 1; return 0; } +static const AVCodecDefault defaults[] = { + { "b", "1411200" }, + { NULL }, +}; + AVCodec ff_dca_encoder = { - .name = "dca", - .type = AVMEDIA_TYPE_AUDIO, - .id = AV_CODEC_ID_DTS, - .priv_data_size = sizeof(DCAContext), - .init = encode_init, - .encode2 = encode_frame, - .capabilities = CODEC_CAP_EXPERIMENTAL, - .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, - AV_SAMPLE_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"), + .name = "dca", + .long_name = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_DTS, + .priv_data_size = sizeof(DCAContext), + .init = encode_init, + .encode2 = encode_frame, + .capabilities = CODEC_CAP_EXPERIMENTAL, + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S32, + AV_SAMPLE_FMT_NONE }, + .supported_samplerates = sample_rates, + .channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO, + AV_CH_LAYOUT_STEREO, + AV_CH_LAYOUT_2_2, + AV_CH_LAYOUT_5POINT0, + AV_CH_LAYOUT_5POINT1, + 0 }, + .defaults = defaults, }; diff --git a/ffmpeg/libavcodec/dcaenc.h b/ffmpeg/libavcodec/dcaenc.h index 121e5da..20f557b 100644 --- a/ffmpeg/libavcodec/dcaenc.h +++ b/ffmpeg/libavcodec/dcaenc.h @@ -1,6 +1,6 @@ /* * DCA encoder tables - * Copyright (C) 2008 Alexander E. Patrakov + * Copyright (C) 2008-2012 Alexander E. Patrakov * * This file is part of FFmpeg. * @@ -24,523 +24,90 @@ #include -/* This is a scaled version of the response of the reference decoder to - this vector of subband samples: ( 1.0 0.0 0.0 ... 0.0 ) - */ +typedef struct { + int32_t m; + int32_t e; +} softfloat; -static const int32_t UnQMF[512] = { - 7, - 4, - -961, - -2844, - -8024, - -18978, - -32081, - -15635, - -16582, - -18359, - -17180, - -14868, - -11664, - -8051, - -4477, - -1327, - -1670, - -6019, - -11590, - -18030, - -24762, - -30965, - -35947, - -36145, - -37223, - -86311, - -57024, - -27215, - -11274, - -4684, - 42, - 108, - 188, - 250, - -1007, - -596, - -2289, - -12218, - -27191, - -124367, - -184256, - -250538, - -323499, - -397784, - -468855, - -532072, - -583000, - -618041, - -777916, - -783868, - -765968, - -724740, - -662468, - -583058, - -490548, - -401623, - -296090, - -73154, - -36711, - -7766, - -2363, - -4905, - 2388, - 2681, - 5651, - 4086, - 71110, - 139742, - 188067, - 151237, - 101355, - 309917, - 343690, - 358839, - 357555, - 334606, - 289625, - 224152, - 142063, - 48725, - 74996, - 238425, - 411666, - 584160, - 744276, - 880730, - 983272, - 1041933, - 1054396, - 789531, - 851022, - 864032, - 675431, - 418134, - 35762, - 66911, - 103502, - 136403, - -55147, - -245269, - -499595, - -808470, - -1136858, - -2010912, - -2581654, - -3151901, - -3696328, - -4196599, - -4633761, - -4993229, - -5262495, - -5436311, - -477650, - -901314, - -1308090, - -1677468, - -1985525, - -2212848, - -2341196, - -2373915, - -2269552, - -2620489, - -2173858, - -1629954, - -946595, - -193499, - 1119459, - 1138657, - 1335311, - 1126544, - 2765033, - 3139603, - 3414913, - 3599213, - 3676363, - 3448981, - 3328726, - 3111551, - 2810887, - 2428657, - 1973684, - 1457278, - 893848, - 300995, - -292521, - -867621, - -1404936, - -1871278, - -2229831, - -2440932, - -2462684, - -2255006, - -1768898, - -1079574, - 82115, - 1660302, - 3660715, - 6123610, - 8329598, - 11888744, - 15722147, - 19737089, - 25647773, - 31039399, - 36868007, - 43124253, - 49737161, - 56495958, - 63668945, - 71039511, - 78540240, - 86089058, - 93600041, - 100981151, - 108136061, - 114970055, - 121718321, - 127566038, - 132774642, - 137247294, - 140894737, - 143635018, - 145395599, - 146114032, - 145742999, - 144211606, - 141594341, - 137808404, - 132914122, - 126912246, - 120243281, - 112155281, - 103338368, - 93904953, - 83439152, - 72921548, - 62192990, - 51434918, - 40894003, - 30786726, - 21384955, - 12939112, - 5718193, - -5790, - -3959261, - -5870978, - -5475538, - -2517061, - 3247310, - 12042937, - 24076729, - 39531397, - 58562863, - 81297002, - 107826748, - 138209187, - 172464115, - 210569037, - 252468018, - 298045453, - 347168648, - 399634888, - 455137189, - 513586535, - 574537650, - 637645129, - 702597163, - 768856566, - 836022040, - 903618096, - 971159680, - 1038137214, - 1103987353, - 1168195035, - 1230223053, - 1289539180, - 1345620373, - 1397957958, - 1446063657, - 1489474689, - 1527740502, - 1560502307, - 1587383079, - 1608071145, - 1622301248, - 1629859340, - 1630584888, - 1624373875, - 1611178348, - 1591018893, - 1563948667, - 1530105004, - 1489673227, - 1442904075, - 1390107674, - 1331590427, - 1267779478, - 1199115126, - 1126053392, - 1049146257, - 968928307, - 885965976, - 800851610, - 714186243, - 626590147, - 538672486, - 451042824, - 364299927, - 279026812, - 195785029, - 115109565, - 37503924, - -36564551, - -106668063, - -172421668, - -233487283, - -289575706, - -340448569, - -385919511, - -425854915, - -460174578, - -488840702, - -511893328, - -529405118, - -541489888, - -548312207, - -550036471, - -547005316, - -539436808, - -527630488, - -512084785, - -492941605, - -470665204, - -445668379, - -418328829, - -389072810, - -358293846, - -326396227, - -293769619, - -260792276, - -227825056, - -195208961, - -163262121, - -132280748, - -102533727, - -74230062, - -47600637, - -22817785, - -25786, - 20662895, - 39167253, - 55438413, - 69453741, - 81242430, - 90795329, - 98213465, - 103540643, - 106917392, - 108861938, - 108539682, - 106780704, - 103722568, - 99043289, - 93608686, - 87266209, - 80212203, - 72590022, - 64603428, - 56362402, - 48032218, - 39749162, - 31638971, - 23814664, - 16376190, - 9409836, - 2988017, - -2822356, - -7976595, - -12454837, - -16241147, - -19331944, - -21735011, - -23468284, - -24559822, - -25042936, - -25035583, - -24429587, - -23346408, - -21860411, - -20015718, - -17025330, - -14968728, - -12487138, - -9656319, - -7846681, - -5197816, - -2621904, - -144953, - 2144746, - 3990570, - 5845884, - 7454650, - 8820394, - 9929891, - 10784445, - 11390921, - 11762056, - 11916017, - 12261189, - 12117604, - 11815303, - 11374622, - 10815301, - 10157241, - 9418799, - 8629399, - 7780776, - 7303680, - 6353499, - 5392738, - 4457895, - 3543062, - 1305978, - 1402521, - 1084092, - 965652, - -151008, - -666667, - -1032157, - -1231475, - -1319043, - -1006023, - -915720, - -773426, - -612377, - -445864, - -291068, - -161337, - -66484, - -11725, - 133453, - 388184, - 615856, - 804033, - 942377, - 1022911, - 1041247, - 995854, - 891376, - 572246, - 457992, - 316365, - 172738, - 43037, - -117662, - -98542, - -70279, - -41458, - -535790, - -959038, - -1364456, - -1502265, - -1568530, - -2378681, - -2701111, - -2976407, - -3182552, - -3314415, - -3366600, - -3337701, - -3232252, - -3054999, - 1984841, - 1925903, - 1817377, - 1669153, - 1490069, - 1292040, - 1086223, - 890983, - 699163, - 201358, - 266971, - 296990, - 198419, - 91119, - 4737, - 5936, - 2553, - 2060, - -3828, - -1664, - -4917, - -20796, - -36822, - -131247, - -154923, - -162055, - -161354, - -148762, - -125754, - -94473, - -57821, - -19096, - 15172, - 43004, - 65624, - 81354, - 89325, - 89524, - 82766, - 71075, - 55128, - 13686, - 6921, - 1449, - 420, - 785, - -215, - -179, - -113, - -49, - 6002, - 16007, - 42978, - 100662, - 171472, - 83975, - 93702, - 108813, - 111893, - 110272, - 103914, - 93973, - 81606, - 68041, - -54058, - -60695, - -65277, - -67224, - -66213, - -62082, - -55574, - -42988, - -35272, - -63735, - -33501, - -12671, - -4038, - -1232, - 5, - 7 +static const int sample_rates[] = { + 8000, 16000, 32000, 11025, 22050, 44100, 12000, 24000, 48000, 0, +}; + +static const uint8_t bitstream_sfreq[] = { 1, 2, 3, 6, 7, 8, 11, 12, 13 }; + +/* Auditory filter center frequencies and bandwidths, in Hz. + * The last two are made up, because there is no scientific data. + */ +static uint16_t fc[] = { + 50, 150, 250, 350, 450, 570, 700, 840, 1000, 1170, 1370, 1600, 1850, 2150, + 2500, 2900, 3400, 4000, 4800, 5800, 7000, 8500, 10500, 13500, 17000 +}; + +static uint16_t erb[] = { + 80, 100, 100, 100, 110, 120, 140, 150, 160, 190, 210, 240, 280, + 320, 380, 450, 550, 700, 900, 1100, 1300, 1800, 2500, 3500, 4500 +}; + +static const softfloat stepsize_inv[27] = { + {0, 0}, {1342177360, 21}, {2147483647, 21}, {1342177360, 20}, + {1819901661, 20}, {2147483647, 20}, {1278263843, 19}, {1579032492, 19}, + {1412817763, 18}, {1220162327, 17}, {1118482133, 16}, {1917391412, 16}, + {1766017772, 15}, {1525212826, 14}, {1290553940, 13}, {2097179000, 13}, + {1677683200, 12}, {1497972244, 11}, {1310893147, 10}, {1165354136, 9}, + {1748031204, 9}, {1542092044, 8}, {1636178017, 7}, {1636178017, 6}, + {1636178017, 5}, {1636178017, 4}, {1636178017, 3}, +}; + +static const softfloat scalefactor_inv[128] = { + {2147483647, 1}, {2147483647, 1}, {2147483647, 2}, {2147483647, 2}, + {2147483647, 2}, {2147483647, 2}, {1431655765, 2}, {1431655765, 2}, + {1431655765, 2}, {2147483647, 3}, {2147483647, 3}, {1717986918, 3}, + {1431655765, 3}, {1227133513, 3}, {1227133513, 3}, {2147483647, 4}, + {1717986918, 4}, {1561806289, 4}, {1431655765, 4}, {1227133513, 4}, + {2147483647, 5}, {1908874353, 5}, {1717986918, 5}, {1493901668, 5}, + {1321528398, 5}, {1145324612, 5}, {2021161080, 6}, {1808407282, 6}, + {1561806289, 6}, {1374389534, 6}, {1227133513, 6}, {2147483647, 7}, + {1908874353, 7}, {1676084798, 7}, {1477838209, 7}, {1296593900, 7}, + {1145324612, 7}, {2021161080, 8}, {1773405851, 8}, {1561806289, 8}, + {1374389534, 8}, {1216273924, 8}, {2139127680, 9}, {1882725390, 9}, + {1660893697, 9}, {1462116526, 9}, {1287484341, 9}, {1135859119, 9}, + {1999112050, 10}, {1762037865, 10}, {1552982525, 10}, {1367551775, 10}, + {1205604855, 10}, {2124660150, 11}, {1871509153, 11}, {1648443220, 11}, + {1452459217, 11}, {1279990253, 11}, {1127704233, 11}, {1987368509, 12}, + {1750814693, 12}, {1542632939, 12}, {1359099663, 12}, {1197398995, 12}, + {2109880792, 13}, {1858853132, 13}, {1638006149, 13}, {1443165385, 13}, + {1271479187, 13}, {1120235993, 13}, {1973767086, 14}, {1739045674, 14}, + {1532153461, 14}, {1349922194, 14}, {1189384493, 14}, {2095804865, 15}, + {1846464029, 15}, {1626872524, 15}, {1433347133, 15}, {1262853884, 15}, + {1112619678, 15}, {1960569045, 16}, {1727349015, 16}, {1521881227, 16}, + {1340842289, 16}, {1181357555, 16}, {2081669156, 17}, {1834047752, 17}, + {1615889229, 17}, {1423675973, 17}, {1254322457, 17}, {1105123583, 17}, + {1947330755, 18}, {1715693602, 18}, {1511607799, 18}, {1331801790, 18}, + {1173384427, 18}, {2067616532, 19}, {1821667648, 19}, {1604980024, 19}, + {1414066955, 19}, {1245861410, 19}, {1097665748, 19}, {1934193616, 20}, + {1704119624, 20}, {1501412075, 20}, {1322817107, 20}, {1165466323, 20}, + {2053666205, 21}, {1809379407, 21}, {1594151671, 21}, {1404526328, 21}, + {1237455941, 21}, {1090259329, 21}, {1921143210, 22}, {1692621231, 22}, + {1491281857, 22}, {1313892269, 22}, {1157603482, 22}, {2039810470, 23}, + {1797172644, 23}, {1583396912, 23}, {1395050052, 23}, {1229107276, 23}, + {1082903494, 23}, {1082903494, 23}, {1082903494, 23}, {1082903494, 23}, +}; + +/* manually derived from + * Table B.5: Selection of quantization levels and codebooks + * FIXME: will become invalid when Huffman codes are introduced. + */ +static const int bit_consumption[27] = { + -8, 28, 40, 48, 52, 60, 68, 76, 80, 96, + 112, 128, 144, 160, 176, 192, 208, 224, 240, 256, + 272, 288, 304, 320, 336, 352, 368, +}; + +/* Table B.5: Selection of quantization levels and codebooks */ +static const int quant_levels[27] = { + 1, 3, 5, 7, 9, 13, 17, 25, 32, 64, + 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, + 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, }; #endif /* AVCODEC_DCAENC_H */ diff --git a/ffmpeg/libavcodec/dct-test.c b/ffmpeg/libavcodec/dct-test.c index 3647336..547ea02 100644 --- a/ffmpeg/libavcodec/dct-test.c +++ b/ffmpeg/libavcodec/dct-test.c @@ -47,8 +47,6 @@ #include "x86/idct_xvid.h" #include "dctref.h" -#undef printf - // BFIN void ff_bfin_idct(int16_t *block); void ff_bfin_fdct(int16_t *block); @@ -63,8 +61,6 @@ void ff_simple_idct_armv5te(int16_t *data); void ff_simple_idct_armv6(int16_t *data); void ff_simple_idct_neon(int16_t *data); -void ff_simple_idct_axp(int16_t *data); - struct algo { const char *name; void (*func)(int16_t *block); @@ -84,7 +80,11 @@ static const struct algo fdct_tab[] = { #if HAVE_MMX_INLINE { "MMX", ff_fdct_mmx, NO_PERM, AV_CPU_FLAG_MMX }, +#endif +#if HAVE_MMXEXT_INLINE { "MMXEXT", ff_fdct_mmxext, NO_PERM, AV_CPU_FLAG_MMXEXT }, +#endif +#if HAVE_SSE2_INLINE { "SSE2", ff_fdct_sse2, NO_PERM, AV_CPU_FLAG_SSE2 }, #endif @@ -125,7 +125,11 @@ static const struct algo idct_tab[] = { #if HAVE_MMX_INLINE { "SIMPLE-MMX", ff_simple_idct_mmx, MMX_SIMPLE_PERM, AV_CPU_FLAG_MMX }, { "XVID-MMX", ff_idct_xvid_mmx, NO_PERM, AV_CPU_FLAG_MMX, 1 }, +#endif +#if HAVE_MMXEXT_INLINE { "XVID-MMXEXT", ff_idct_xvid_mmxext, NO_PERM, AV_CPU_FLAG_MMXEXT, 1 }, +#endif +#if HAVE_SSE2_INLINE { "XVID-SSE2", ff_idct_xvid_sse2, SSE2_PERM, AV_CPU_FLAG_SSE2, 1 }, #if ARCH_X86_64 && HAVE_YASM { "PR-SSE2", ff_prores_idct_put_10_sse2_wrap, TRANSPOSE_PERM, AV_CPU_FLAG_SSE2, 1 }, @@ -150,10 +154,6 @@ static const struct algo idct_tab[] = { { "SIMPLE-NEON", ff_simple_idct_neon, PARTTRANS_PERM, AV_CPU_FLAG_NEON }, #endif -#if ARCH_ALPHA - { "SIMPLE-ALPHA", ff_simple_idct_axp, NO_PERM }, -#endif - { 0 } }; @@ -572,5 +572,8 @@ int main(int argc, char **argv) } } - return err; + if (err) + printf("Error: %d.\n", err); + + return !!err; } diff --git a/ffmpeg/libavcodec/dct.c b/ffmpeg/libavcodec/dct.c index e2ac0a8..b1ee06a 100644 --- a/ffmpeg/libavcodec/dct.c +++ b/ffmpeg/libavcodec/dct.c @@ -40,7 +40,7 @@ /* cos((M_PI * x / (2 * n)) */ #define COS(s, n, x) (s->costab[x]) -static void ff_dst_calc_I_c(DCTContext *ctx, FFTSample *data) +static void dst_calc_I_c(DCTContext *ctx, FFTSample *data) { int n = 1 << ctx->nbits; int i; @@ -70,7 +70,7 @@ static void ff_dst_calc_I_c(DCTContext *ctx, FFTSample *data) data[n - 1] = 0; } -static void ff_dct_calc_I_c(DCTContext *ctx, FFTSample *data) +static void dct_calc_I_c(DCTContext *ctx, FFTSample *data) { int n = 1 << ctx->nbits; int i; @@ -100,7 +100,7 @@ static void ff_dct_calc_I_c(DCTContext *ctx, FFTSample *data) data[i] = data[i - 2] - data[i]; } -static void ff_dct_calc_III_c(DCTContext *ctx, FFTSample *data) +static void dct_calc_III_c(DCTContext *ctx, FFTSample *data) { int n = 1 << ctx->nbits; int i; @@ -133,7 +133,7 @@ static void ff_dct_calc_III_c(DCTContext *ctx, FFTSample *data) } } -static void ff_dct_calc_II_c(DCTContext *ctx, FFTSample *data) +static void dct_calc_II_c(DCTContext *ctx, FFTSample *data) { int n = 1 << ctx->nbits; int i; @@ -201,10 +201,10 @@ av_cold int ff_dct_init(DCTContext *s, int nbits, enum DCTTransformType inverse) s->csc2[i] = 0.5 / sin((M_PI / (2 * n) * (2 * i + 1))); switch (inverse) { - case DCT_I : s->dct_calc = ff_dct_calc_I_c; break; - case DCT_II : s->dct_calc = ff_dct_calc_II_c; break; - case DCT_III: s->dct_calc = ff_dct_calc_III_c; break; - case DST_I : s->dct_calc = ff_dst_calc_I_c; break; + case DCT_I : s->dct_calc = dct_calc_I_c; break; + case DCT_II : s->dct_calc = dct_calc_II_c; break; + case DCT_III: s->dct_calc = dct_calc_III_c; break; + case DST_I : s->dct_calc = dst_calc_I_c; break; } } diff --git a/ffmpeg/libavcodec/dct32.c b/ffmpeg/libavcodec/dct32.c deleted file mode 100644 index fb53d53..0000000 --- a/ffmpeg/libavcodec/dct32.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Template for the Discrete Cosine Transform for 32 samples - * Copyright (c) 2001, 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "dct32.h" -#include "mathops.h" - -#if DCT32_FLOAT -# define dct32 ff_dct32_float -# define FIXHR(x) ((float)(x)) -# define MULH3(x, y, s) ((s)*(y)*(x)) -# define INTFLOAT float -#else -# define dct32 ff_dct32_fixed -# define FIXHR(a) ((int)((a) * (1LL<<32) + 0.5)) -# define MULH3(x, y, s) MULH((s)*(x), y) -# define INTFLOAT int -#endif - - -/* tab[i][j] = 1.0 / (2.0 * cos(pi*(2*k+1) / 2^(6 - j))) */ - -/* cos(i*pi/64) */ - -#define COS0_0 FIXHR(0.50060299823519630134/2) -#define COS0_1 FIXHR(0.50547095989754365998/2) -#define COS0_2 FIXHR(0.51544730992262454697/2) -#define COS0_3 FIXHR(0.53104259108978417447/2) -#define COS0_4 FIXHR(0.55310389603444452782/2) -#define COS0_5 FIXHR(0.58293496820613387367/2) -#define COS0_6 FIXHR(0.62250412303566481615/2) -#define COS0_7 FIXHR(0.67480834145500574602/2) -#define COS0_8 FIXHR(0.74453627100229844977/2) -#define COS0_9 FIXHR(0.83934964541552703873/2) -#define COS0_10 FIXHR(0.97256823786196069369/2) -#define COS0_11 FIXHR(1.16943993343288495515/4) -#define COS0_12 FIXHR(1.48416461631416627724/4) -#define COS0_13 FIXHR(2.05778100995341155085/8) -#define COS0_14 FIXHR(3.40760841846871878570/8) -#define COS0_15 FIXHR(10.19000812354805681150/32) - -#define COS1_0 FIXHR(0.50241928618815570551/2) -#define COS1_1 FIXHR(0.52249861493968888062/2) -#define COS1_2 FIXHR(0.56694403481635770368/2) -#define COS1_3 FIXHR(0.64682178335999012954/2) -#define COS1_4 FIXHR(0.78815462345125022473/2) -#define COS1_5 FIXHR(1.06067768599034747134/4) -#define COS1_6 FIXHR(1.72244709823833392782/4) -#define COS1_7 FIXHR(5.10114861868916385802/16) - -#define COS2_0 FIXHR(0.50979557910415916894/2) -#define COS2_1 FIXHR(0.60134488693504528054/2) -#define COS2_2 FIXHR(0.89997622313641570463/2) -#define COS2_3 FIXHR(2.56291544774150617881/8) - -#define COS3_0 FIXHR(0.54119610014619698439/2) -#define COS3_1 FIXHR(1.30656296487637652785/4) - -#define COS4_0 FIXHR(0.70710678118654752439/2) - -/* butterfly operator */ -#define BF(a, b, c, s)\ -{\ - tmp0 = val##a + val##b;\ - tmp1 = val##a - val##b;\ - val##a = tmp0;\ - val##b = MULH3(tmp1, c, 1<<(s));\ -} - -#define BF0(a, b, c, s)\ -{\ - tmp0 = tab[a] + tab[b];\ - tmp1 = tab[a] - tab[b];\ - val##a = tmp0;\ - val##b = MULH3(tmp1, c, 1<<(s));\ -} - -#define BF1(a, b, c, d)\ -{\ - BF(a, b, COS4_0, 1);\ - BF(c, d,-COS4_0, 1);\ - val##c += val##d;\ -} - -#define BF2(a, b, c, d)\ -{\ - BF(a, b, COS4_0, 1);\ - BF(c, d,-COS4_0, 1);\ - val##c += val##d;\ - val##a += val##c;\ - val##c += val##b;\ - val##b += val##d;\ -} - -#define ADD(a, b) val##a += val##b - -/* DCT32 without 1/sqrt(2) coef zero scaling. */ -void dct32(INTFLOAT *out, const INTFLOAT *tab) -{ - INTFLOAT tmp0, tmp1; - - INTFLOAT val0 , val1 , val2 , val3 , val4 , val5 , val6 , val7 , - val8 , val9 , val10, val11, val12, val13, val14, val15, - val16, val17, val18, val19, val20, val21, val22, val23, - val24, val25, val26, val27, val28, val29, val30, val31; - - /* pass 1 */ - BF0( 0, 31, COS0_0 , 1); - BF0(15, 16, COS0_15, 5); - /* pass 2 */ - BF( 0, 15, COS1_0 , 1); - BF(16, 31,-COS1_0 , 1); - /* pass 1 */ - BF0( 7, 24, COS0_7 , 1); - BF0( 8, 23, COS0_8 , 1); - /* pass 2 */ - BF( 7, 8, COS1_7 , 4); - BF(23, 24,-COS1_7 , 4); - /* pass 3 */ - BF( 0, 7, COS2_0 , 1); - BF( 8, 15,-COS2_0 , 1); - BF(16, 23, COS2_0 , 1); - BF(24, 31,-COS2_0 , 1); - /* pass 1 */ - BF0( 3, 28, COS0_3 , 1); - BF0(12, 19, COS0_12, 2); - /* pass 2 */ - BF( 3, 12, COS1_3 , 1); - BF(19, 28,-COS1_3 , 1); - /* pass 1 */ - BF0( 4, 27, COS0_4 , 1); - BF0(11, 20, COS0_11, 2); - /* pass 2 */ - BF( 4, 11, COS1_4 , 1); - BF(20, 27,-COS1_4 , 1); - /* pass 3 */ - BF( 3, 4, COS2_3 , 3); - BF(11, 12,-COS2_3 , 3); - BF(19, 20, COS2_3 , 3); - BF(27, 28,-COS2_3 , 3); - /* pass 4 */ - BF( 0, 3, COS3_0 , 1); - BF( 4, 7,-COS3_0 , 1); - BF( 8, 11, COS3_0 , 1); - BF(12, 15,-COS3_0 , 1); - BF(16, 19, COS3_0 , 1); - BF(20, 23,-COS3_0 , 1); - BF(24, 27, COS3_0 , 1); - BF(28, 31,-COS3_0 , 1); - - - - /* pass 1 */ - BF0( 1, 30, COS0_1 , 1); - BF0(14, 17, COS0_14, 3); - /* pass 2 */ - BF( 1, 14, COS1_1 , 1); - BF(17, 30,-COS1_1 , 1); - /* pass 1 */ - BF0( 6, 25, COS0_6 , 1); - BF0( 9, 22, COS0_9 , 1); - /* pass 2 */ - BF( 6, 9, COS1_6 , 2); - BF(22, 25,-COS1_6 , 2); - /* pass 3 */ - BF( 1, 6, COS2_1 , 1); - BF( 9, 14,-COS2_1 , 1); - BF(17, 22, COS2_1 , 1); - BF(25, 30,-COS2_1 , 1); - - /* pass 1 */ - BF0( 2, 29, COS0_2 , 1); - BF0(13, 18, COS0_13, 3); - /* pass 2 */ - BF( 2, 13, COS1_2 , 1); - BF(18, 29,-COS1_2 , 1); - /* pass 1 */ - BF0( 5, 26, COS0_5 , 1); - BF0(10, 21, COS0_10, 1); - /* pass 2 */ - BF( 5, 10, COS1_5 , 2); - BF(21, 26,-COS1_5 , 2); - /* pass 3 */ - BF( 2, 5, COS2_2 , 1); - BF(10, 13,-COS2_2 , 1); - BF(18, 21, COS2_2 , 1); - BF(26, 29,-COS2_2 , 1); - /* pass 4 */ - BF( 1, 2, COS3_1 , 2); - BF( 5, 6,-COS3_1 , 2); - BF( 9, 10, COS3_1 , 2); - BF(13, 14,-COS3_1 , 2); - BF(17, 18, COS3_1 , 2); - BF(21, 22,-COS3_1 , 2); - BF(25, 26, COS3_1 , 2); - BF(29, 30,-COS3_1 , 2); - - /* pass 5 */ - BF1( 0, 1, 2, 3); - BF2( 4, 5, 6, 7); - BF1( 8, 9, 10, 11); - BF2(12, 13, 14, 15); - BF1(16, 17, 18, 19); - BF2(20, 21, 22, 23); - BF1(24, 25, 26, 27); - BF2(28, 29, 30, 31); - - /* pass 6 */ - - ADD( 8, 12); - ADD(12, 10); - ADD(10, 14); - ADD(14, 9); - ADD( 9, 13); - ADD(13, 11); - ADD(11, 15); - - out[ 0] = val0; - out[16] = val1; - out[ 8] = val2; - out[24] = val3; - out[ 4] = val4; - out[20] = val5; - out[12] = val6; - out[28] = val7; - out[ 2] = val8; - out[18] = val9; - out[10] = val10; - out[26] = val11; - out[ 6] = val12; - out[22] = val13; - out[14] = val14; - out[30] = val15; - - ADD(24, 28); - ADD(28, 26); - ADD(26, 30); - ADD(30, 25); - ADD(25, 29); - ADD(29, 27); - ADD(27, 31); - - out[ 1] = val16 + val24; - out[17] = val17 + val25; - out[ 9] = val18 + val26; - out[25] = val19 + val27; - out[ 5] = val20 + val28; - out[21] = val21 + val29; - out[13] = val22 + val30; - out[29] = val23 + val31; - out[ 3] = val24 + val20; - out[19] = val25 + val21; - out[11] = val26 + val22; - out[27] = val27 + val23; - out[ 7] = val28 + val18; - out[23] = val29 + val19; - out[15] = val30 + val17; - out[31] = val31; -} diff --git a/ffmpeg/libavcodec/dct32.h b/ffmpeg/libavcodec/dct32.h index 110338d..f4b2471 100644 --- a/ffmpeg/libavcodec/dct32.h +++ b/ffmpeg/libavcodec/dct32.h @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/dct32_fixed.c b/ffmpeg/libavcodec/dct32_fixed.c index 7eb9dc1..9025d5e 100644 --- a/ffmpeg/libavcodec/dct32_fixed.c +++ b/ffmpeg/libavcodec/dct32_fixed.c @@ -1,20 +1,20 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define DCT32_FLOAT 0 -#include "dct32.c" +#include "dct32_template.c" diff --git a/ffmpeg/libavcodec/dct32_float.c b/ffmpeg/libavcodec/dct32_float.c index 727ec3c..597c9bb 100644 --- a/ffmpeg/libavcodec/dct32_float.c +++ b/ffmpeg/libavcodec/dct32_float.c @@ -1,20 +1,20 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define DCT32_FLOAT 1 -#include "dct32.c" +#include "dct32_template.c" diff --git a/ffmpeg/libavcodec/dfa.c b/ffmpeg/libavcodec/dfa.c index b20cd0e..b1be475 100644 --- a/ffmpeg/libavcodec/dfa.c +++ b/ffmpeg/libavcodec/dfa.c @@ -254,13 +254,16 @@ static int decode_wdlt(GetByteContext *gb, uint8_t *frame, int width, int height y += skip_lines; segments = bytestream2_get_le16(gb); } + if (frame_end <= frame) - return -1; + return AVERROR_INVALIDDATA; if (segments & 0x8000) { frame[width - 1] = segments & 0xFF; segments = bytestream2_get_le16(gb); } line_ptr = frame; + if (frame_end - frame < width) + return AVERROR_INVALIDDATA; frame += width; y++; while (segments--) { @@ -288,9 +291,26 @@ static int decode_wdlt(GetByteContext *gb, uint8_t *frame, int width, int height return 0; } -static int decode_unk6(GetByteContext *gb, uint8_t *frame, int width, int height) +static int decode_tdlt(GetByteContext *gb, uint8_t *frame, int width, int height) { - return AVERROR_PATCHWELCOME; + const uint8_t *frame_end = frame + width * height; + uint32_t segments = bytestream2_get_le32(gb); + int skip, copy; + + while (segments--) { + if (bytestream2_get_bytes_left(gb) < 2) + return AVERROR_INVALIDDATA; + copy = bytestream2_get_byteu(gb) * 2; + skip = bytestream2_get_byteu(gb) * 2; + if (frame_end - frame < copy + skip || + bytestream2_get_bytes_left(gb) < copy) + return AVERROR_INVALIDDATA; + frame += skip; + bytestream2_get_buffer(gb, frame, copy); + frame += copy; + } + + return 0; } static int decode_blck(GetByteContext *gb, uint8_t *frame, int width, int height) @@ -304,11 +324,11 @@ typedef int (*chunk_decoder)(GetByteContext *gb, uint8_t *frame, int width, int static const chunk_decoder decoder[8] = { decode_copy, decode_tsw1, decode_bdlt, decode_wdlt, - decode_unk6, decode_dsw1, decode_blck, decode_dds1, + decode_tdlt, decode_dsw1, decode_blck, decode_dds1, }; static const char* chunk_name[8] = { - "COPY", "TSW1", "BDLT", "WDLT", "????", "DSW1", "BLCK", "DDS1" + "COPY", "TSW1", "BDLT", "WDLT", "TDLT", "DSW1", "BLCK", "DDS1" }; static int dfa_decode_frame(AVCodecContext *avctx, @@ -323,6 +343,7 @@ static int dfa_decode_frame(AVCodecContext *avctx, uint8_t *dst; int ret; int i, pal_elems; + int version = avctx->extradata_size==2 ? AV_RL16(avctx->extradata) : 0; if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; @@ -357,9 +378,17 @@ static int dfa_decode_frame(AVCodecContext *avctx, buf = s->frame_buf; dst = frame->data[0]; for (i = 0; i < avctx->height; i++) { - memcpy(dst, buf, avctx->width); + if(version == 0x100) { + int j; + for(j = 0; j < avctx->width; j++) { + dst[j] = buf[ (i&3)*(avctx->width /4) + (j/4) + + ((j&3)*(avctx->height/4) + (i/4))*avctx->width]; + } + } else { + memcpy(dst, buf, avctx->width); + buf += avctx->width; + } dst += frame->linesize[0]; - buf += avctx->width; } memcpy(frame->data[1], s->pal, sizeof(s->pal)); @@ -379,6 +408,7 @@ static av_cold int dfa_decode_end(AVCodecContext *avctx) AVCodec ff_dfa_decoder = { .name = "dfa", + .long_name = NULL_IF_CONFIG_SMALL("Chronomaster DFA"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_DFA, .priv_data_size = sizeof(DfaContext), @@ -386,5 +416,4 @@ AVCodec ff_dfa_decoder = { .close = dfa_decode_end, .decode = dfa_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Chronomaster DFA"), }; diff --git a/ffmpeg/libavcodec/dirac.c b/ffmpeg/libavcodec/dirac.c index e132acc..3dad75a 100644 --- a/ffmpeg/libavcodec/dirac.c +++ b/ffmpeg/libavcodec/dirac.c @@ -30,6 +30,7 @@ #include "dirac.h" #include "avcodec.h" #include "golomb.h" +#include "internal.h" #include "mpeg12data.h" /* defaults for source parameters */ @@ -317,11 +318,10 @@ int avpriv_dirac_parse_sequence_header(AVCodecContext *avctx, GetBitContext *gb, if (ret = parse_source_parameters(avctx, gb, source)) return ret; - if (ret = av_image_check_size(source->width, source->height, 0, avctx)) + ret = ff_set_dimensions(avctx, source->width, source->height); + if (ret < 0) return ret; - avcodec_set_dimensions(avctx, source->width, source->height); - /* [DIRAC_STD] picture_coding_mode shall be 0 for fields and 1 for frames * currently only used to signal field coding */ picture_coding_mode = svq3_get_ue_golomb(gb); diff --git a/ffmpeg/libavcodec/dirac_dwt.c b/ffmpeg/libavcodec/dirac_dwt.c index a2848f0..51a924b 100644 --- a/ffmpeg/libavcodec/dirac_dwt.c +++ b/ffmpeg/libavcodec/dirac_dwt.c @@ -535,6 +535,7 @@ int ff_spatial_idwt_init2(DWTContext *d, IDWTELEM *buffer, int width, int height d->vertical_compose_l0 = (void*)vertical_compose_fidelityiL0; d->vertical_compose_h0 = (void*)vertical_compose_fidelityiH0; d->horizontal_compose = horizontal_compose_fidelityi; + d->support = 0; // not really used break; case DWT_DIRAC_DAUB9_7: d->spatial_compose = spatial_compose_daub97i_dy; @@ -569,17 +570,3 @@ void ff_spatial_idwt_slice2(DWTContext *d, int y) } } -int ff_spatial_idwt2(IDWTELEM *buffer, int width, int height, int stride, - enum dwt_type type, int decomposition_count, IDWTELEM *temp) -{ - DWTContext d; - int y; - - if (ff_spatial_idwt_init2(&d, buffer, width, height, stride, type, decomposition_count, temp)) - return -1; - - for (y = 0; y < d.height; y += 4) - ff_spatial_idwt_slice2(&d, y); - - return 0; -} diff --git a/ffmpeg/libavcodec/dirac_dwt.h b/ffmpeg/libavcodec/dirac_dwt.h index 9514e95..25c13d1 100644 --- a/ffmpeg/libavcodec/dirac_dwt.h +++ b/ffmpeg/libavcodec/dirac_dwt.h @@ -80,9 +80,6 @@ int ff_spatial_idwt_init2(DWTContext *d, IDWTELEM *buffer, int width, int height int stride, enum dwt_type type, int decomposition_count, IDWTELEM *temp); -int ff_spatial_idwt2(IDWTELEM *buffer, int width, int height, int stride, - enum dwt_type type, int decomposition_count, IDWTELEM *temp); - void ff_spatial_idwt_slice2(DWTContext *d, int y); // shared stuff for simd optimiztions diff --git a/ffmpeg/libavcodec/diracdec.c b/ffmpeg/libavcodec/diracdec.c index 81d2b65..5eca4f6 100644 --- a/ffmpeg/libavcodec/diracdec.c +++ b/ffmpeg/libavcodec/diracdec.c @@ -80,7 +80,7 @@ #define DIVRNDUP(a, b) (((a) + (b) - 1) / (b)) typedef struct { - AVFrame avframe; + AVFrame *avframe; int interpolated[3]; /* 1 if hpel[] is valid */ uint8_t *hpel[3][4]; uint8_t *hpel_base[3][4]; @@ -112,7 +112,7 @@ typedef struct SubBand { typedef struct Plane { int width; int height; - int stride; + ptrdiff_t stride; int idwt_width; int idwt_height; @@ -291,7 +291,7 @@ static DiracFrame *remove_frame(DiracFrame *framelist[], int picnum) int i, remove_idx = -1; for (i = 0; framelist[i]; i++) - if (framelist[i]->avframe.display_picture_number == picnum) { + if (framelist[i]->avframe->display_picture_number == picnum) { remove_pic = framelist[i]; remove_idx = i; } @@ -364,8 +364,8 @@ static void free_sequence_buffers(DiracContext *s) int i, j, k; for (i = 0; i < MAX_FRAMES; i++) { - if (s->all_frames[i].avframe.data[0]) { - av_frame_unref(&s->all_frames[i].avframe); + if (s->all_frames[i].avframe->data[0]) { + av_frame_unref(s->all_frames[i].avframe); memset(s->all_frames[i].interpolated, 0, sizeof(s->all_frames[i].interpolated)); } @@ -393,6 +393,8 @@ static void free_sequence_buffers(DiracContext *s) static av_cold int dirac_decode_init(AVCodecContext *avctx) { DiracContext *s = avctx->priv_data; + int i; + s->avctx = avctx; s->frame_number = -1; @@ -404,6 +406,9 @@ static av_cold int dirac_decode_init(AVCodecContext *avctx) ff_dsputil_init(&s->dsp, avctx); ff_diracdsp_init(&s->diracdsp); + for (i = 0; i < MAX_FRAMES; i++) + s->all_frames[i].avframe = av_frame_alloc(); + return 0; } @@ -417,7 +422,13 @@ static void dirac_decode_flush(AVCodecContext *avctx) static av_cold int dirac_decode_end(AVCodecContext *avctx) { + DiracContext *s = avctx->priv_data; + int i; + dirac_decode_flush(avctx); + for (i = 0; i < MAX_FRAMES; i++) + av_frame_free(&s->all_frames[i].avframe); + return 0; } @@ -567,7 +578,7 @@ static av_always_inline void decode_subband_internal(DiracContext *s, SubBand *b if (!b->length) return; - init_get_bits(&gb, b->coeff_data, b->length*8); + init_get_bits8(&gb, b->coeff_data, b->length); if (is_arith) ff_dirac_init_arith_decoder(&c, &gb, b->length); @@ -1414,7 +1425,8 @@ static int mc_subpel(DiracContext *s, DiracBlock *block, const uint8_t *src[5], y + p->yblen > p->height+EDGE_WIDTH/2 || x < 0 || y < 0) { for (i = 0; i < nplanes; i++) { - ff_emulated_edge_mc(s->edge_emu_buffer[i], src[i], p->stride, + ff_emulated_edge_mc(s->edge_emu_buffer[i], src[i], + p->stride, p->stride, p->xblen, p->yblen, x, y, p->width+EDGE_WIDTH/2, p->height+EDGE_WIDTH/2); src[i] = s->edge_emu_buffer[i]; @@ -1518,8 +1530,8 @@ static void interpolate_refplane(DiracContext *s, DiracFrame *ref, int plane, in just use 8 for everything for the moment */ int i, edge = EDGE_WIDTH/2; - ref->hpel[plane][0] = ref->avframe.data[plane]; - s->dsp.draw_edges(ref->hpel[plane][0], ref->avframe.linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); /* EDGE_TOP | EDGE_BOTTOM values just copied to make it build, this needs to be ensured */ + ref->hpel[plane][0] = ref->avframe->data[plane]; + s->dsp.draw_edges(ref->hpel[plane][0], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); /* EDGE_TOP | EDGE_BOTTOM values just copied to make it build, this needs to be ensured */ /* no need for hpel if we only have fpel vectors */ if (!s->mv_precision) @@ -1527,18 +1539,18 @@ static void interpolate_refplane(DiracContext *s, DiracFrame *ref, int plane, in for (i = 1; i < 4; i++) { if (!ref->hpel_base[plane][i]) - ref->hpel_base[plane][i] = av_malloc((height+2*edge) * ref->avframe.linesize[plane] + 32); + ref->hpel_base[plane][i] = av_malloc((height+2*edge) * ref->avframe->linesize[plane] + 32); /* we need to be 16-byte aligned even for chroma */ - ref->hpel[plane][i] = ref->hpel_base[plane][i] + edge*ref->avframe.linesize[plane] + 16; + ref->hpel[plane][i] = ref->hpel_base[plane][i] + edge*ref->avframe->linesize[plane] + 16; } if (!ref->interpolated[plane]) { s->diracdsp.dirac_hpel_filter(ref->hpel[plane][1], ref->hpel[plane][2], ref->hpel[plane][3], ref->hpel[plane][0], - ref->avframe.linesize[plane], width, height); - s->dsp.draw_edges(ref->hpel[plane][1], ref->avframe.linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); - s->dsp.draw_edges(ref->hpel[plane][2], ref->avframe.linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); - s->dsp.draw_edges(ref->hpel[plane][3], ref->avframe.linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); + ref->avframe->linesize[plane], width, height); + s->dsp.draw_edges(ref->hpel[plane][1], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); + s->dsp.draw_edges(ref->hpel[plane][2], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); + s->dsp.draw_edges(ref->hpel[plane][3], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); } ref->interpolated[plane] = 1; } @@ -1564,7 +1576,7 @@ static int dirac_decode_frame_internal(DiracContext *s) for (comp = 0; comp < 3; comp++) { Plane *p = &s->plane[comp]; - uint8_t *frame = s->current_picture->avframe.data[comp]; + uint8_t *frame = s->current_picture->avframe->data[comp]; /* FIXME: small resolutions */ for (i = 0; i < 4; i++) @@ -1639,7 +1651,7 @@ static int dirac_decode_picture_header(DiracContext *s) GetBitContext *gb = &s->gb; /* [DIRAC_STD] 11.1.1 Picture Header. picture_header() PICTURE_NUM */ - picnum = s->current_picture->avframe.display_picture_number = get_bits_long(gb, 32); + picnum = s->current_picture->avframe->display_picture_number = get_bits_long(gb, 32); av_log(s->avctx,AV_LOG_DEBUG,"PICTURE_NUM: %d\n",picnum); @@ -1658,9 +1670,9 @@ static int dirac_decode_picture_header(DiracContext *s) /* Jordi: this is needed if the referenced picture hasn't yet arrived */ for (j = 0; j < MAX_REFERENCE_FRAMES && refdist; j++) if (s->ref_frames[j] - && FFABS(s->ref_frames[j]->avframe.display_picture_number - refnum) < refdist) { + && FFABS(s->ref_frames[j]->avframe->display_picture_number - refnum) < refdist) { s->ref_pics[i] = s->ref_frames[j]; - refdist = FFABS(s->ref_frames[j]->avframe.display_picture_number - refnum); + refdist = FFABS(s->ref_frames[j]->avframe->display_picture_number - refnum); } if (!s->ref_pics[i] || refdist) @@ -1669,21 +1681,21 @@ static int dirac_decode_picture_header(DiracContext *s) /* if there were no references at all, allocate one */ if (!s->ref_pics[i]) for (j = 0; j < MAX_FRAMES; j++) - if (!s->all_frames[j].avframe.data[0]) { + if (!s->all_frames[j].avframe->data[0]) { s->ref_pics[i] = &s->all_frames[j]; - ff_get_buffer(s->avctx, &s->ref_pics[i]->avframe, AV_GET_BUFFER_FLAG_REF); + ff_get_buffer(s->avctx, s->ref_pics[i]->avframe, AV_GET_BUFFER_FLAG_REF); break; } } /* retire the reference frames that are not used anymore */ - if (s->current_picture->avframe.reference) { + if (s->current_picture->avframe->reference) { retire = picnum + dirac_get_se_golomb(gb); if (retire != picnum) { DiracFrame *retire_pic = remove_frame(s->ref_frames, retire); if (retire_pic) - retire_pic->avframe.reference &= DELAYED_PIC_REF; + retire_pic->avframe->reference &= DELAYED_PIC_REF; else av_log(s->avctx, AV_LOG_DEBUG, "Frame to retire not found\n"); } @@ -1691,7 +1703,7 @@ static int dirac_decode_picture_header(DiracContext *s) /* if reference array is full, remove the oldest as per the spec */ while (add_frame(s->ref_frames, MAX_REFERENCE_FRAMES, s->current_picture)) { av_log(s->avctx, AV_LOG_ERROR, "Reference frame overflow\n"); - remove_frame(s->ref_frames, s->ref_frames[0]->avframe.display_picture_number)->avframe.reference &= DELAYED_PIC_REF; + remove_frame(s->ref_frames, s->ref_frames[0]->avframe->display_picture_number)->avframe->reference &= DELAYED_PIC_REF; } } @@ -1716,7 +1728,7 @@ static int get_delayed_pic(DiracContext *s, AVFrame *picture, int *got_frame) /* find frame with lowest picture number */ for (i = 1; s->delay_frames[i]; i++) - if (s->delay_frames[i]->avframe.display_picture_number < out->avframe.display_picture_number) { + if (s->delay_frames[i]->avframe->display_picture_number < out->avframe->display_picture_number) { out = s->delay_frames[i]; out_idx = i; } @@ -1725,9 +1737,9 @@ static int get_delayed_pic(DiracContext *s, AVFrame *picture, int *got_frame) s->delay_frames[i] = s->delay_frames[i+1]; if (out) { - out->avframe.reference ^= DELAYED_PIC_REF; + out->avframe->reference ^= DELAYED_PIC_REF; *got_frame = 1; - if((ret = av_frame_ref(picture, &out->avframe)) < 0) + if((ret = av_frame_ref(picture, out->avframe)) < 0) return ret; } @@ -1789,14 +1801,14 @@ static int dirac_decode_data_unit(AVCodecContext *avctx, const uint8_t *buf, int /* find an unused frame */ for (i = 0; i < MAX_FRAMES; i++) - if (s->all_frames[i].avframe.data[0] == NULL) + if (s->all_frames[i].avframe->data[0] == NULL) pic = &s->all_frames[i]; if (!pic) { av_log(avctx, AV_LOG_ERROR, "framelist full\n"); return -1; } - avcodec_get_frame_defaults(&pic->avframe); + av_frame_unref(pic->avframe); /* [DIRAC_STD] Defined in 9.6.1 ... */ tmp = parse_code & 0x03; /* [DIRAC_STD] num_refs() */ @@ -1807,16 +1819,16 @@ static int dirac_decode_data_unit(AVCodecContext *avctx, const uint8_t *buf, int s->num_refs = tmp; s->is_arith = (parse_code & 0x48) == 0x08; /* [DIRAC_STD] using_ac() */ s->low_delay = (parse_code & 0x88) == 0x88; /* [DIRAC_STD] is_low_delay() */ - pic->avframe.reference = (parse_code & 0x0C) == 0x0C; /* [DIRAC_STD] is_reference() */ - pic->avframe.key_frame = s->num_refs == 0; /* [DIRAC_STD] is_intra() */ - pic->avframe.pict_type = s->num_refs + 1; /* Definition of AVPictureType in avutil.h */ + pic->avframe->reference = (parse_code & 0x0C) == 0x0C; /* [DIRAC_STD] is_reference() */ + pic->avframe->key_frame = s->num_refs == 0; /* [DIRAC_STD] is_intra() */ + pic->avframe->pict_type = s->num_refs + 1; /* Definition of AVPictureType in avutil.h */ - if ((ret = ff_get_buffer(avctx, &pic->avframe, (parse_code & 0x0C) == 0x0C ? AV_GET_BUFFER_FLAG_REF : 0)) < 0) + if ((ret = ff_get_buffer(avctx, pic->avframe, (parse_code & 0x0C) == 0x0C ? AV_GET_BUFFER_FLAG_REF : 0)) < 0) return ret; s->current_picture = pic; - s->plane[0].stride = pic->avframe.linesize[0]; - s->plane[1].stride = pic->avframe.linesize[1]; - s->plane[2].stride = pic->avframe.linesize[2]; + s->plane[0].stride = pic->avframe->linesize[0]; + s->plane[1].stride = pic->avframe->linesize[1]; + s->plane[2].stride = pic->avframe->linesize[2]; /* [DIRAC_STD] 11.1 Picture parse. picture_parse() */ if (dirac_decode_picture_header(s)) @@ -1832,7 +1844,7 @@ static int dirac_decode_data_unit(AVCodecContext *avctx, const uint8_t *buf, int static int dirac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *pkt) { DiracContext *s = avctx->priv_data; - DiracFrame *picture = data; + AVFrame *picture = data; uint8_t *buf = pkt->data; int buf_size = pkt->size; int i, data_unit_size, buf_idx = 0; @@ -1840,8 +1852,8 @@ static int dirac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, /* release unused frames */ for (i = 0; i < MAX_FRAMES; i++) - if (s->all_frames[i].avframe.data[0] && !s->all_frames[i].avframe.reference) { - av_frame_unref(&s->all_frames[i].avframe); + if (s->all_frames[i].avframe->data[0] && !s->all_frames[i].avframe->reference) { + av_frame_unref(s->all_frames[i].avframe); memset(s->all_frames[i].interpolated, 0, sizeof(s->all_frames[i].interpolated)); } @@ -1886,46 +1898,47 @@ static int dirac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (!s->current_picture) return buf_size; - if (s->current_picture->avframe.display_picture_number > s->frame_number) { + if (s->current_picture->avframe->display_picture_number > s->frame_number) { DiracFrame *delayed_frame = remove_frame(s->delay_frames, s->frame_number); - s->current_picture->avframe.reference |= DELAYED_PIC_REF; + s->current_picture->avframe->reference |= DELAYED_PIC_REF; if (add_frame(s->delay_frames, MAX_DELAY, s->current_picture)) { - int min_num = s->delay_frames[0]->avframe.display_picture_number; + int min_num = s->delay_frames[0]->avframe->display_picture_number; /* Too many delayed frames, so we display the frame with the lowest pts */ av_log(avctx, AV_LOG_ERROR, "Delay frame overflow\n"); delayed_frame = s->delay_frames[0]; for (i = 1; s->delay_frames[i]; i++) - if (s->delay_frames[i]->avframe.display_picture_number < min_num) - min_num = s->delay_frames[i]->avframe.display_picture_number; + if (s->delay_frames[i]->avframe->display_picture_number < min_num) + min_num = s->delay_frames[i]->avframe->display_picture_number; delayed_frame = remove_frame(s->delay_frames, min_num); add_frame(s->delay_frames, MAX_DELAY, s->current_picture); } if (delayed_frame) { - delayed_frame->avframe.reference ^= DELAYED_PIC_REF; - if((ret=av_frame_ref(data, &delayed_frame->avframe)) < 0) + delayed_frame->avframe->reference ^= DELAYED_PIC_REF; + if((ret=av_frame_ref(data, delayed_frame->avframe)) < 0) return ret; *got_frame = 1; } - } else if (s->current_picture->avframe.display_picture_number == s->frame_number) { + } else if (s->current_picture->avframe->display_picture_number == s->frame_number) { /* The right frame at the right time :-) */ - if((ret=av_frame_ref(data, &s->current_picture->avframe)) < 0) + if((ret=av_frame_ref(data, s->current_picture->avframe)) < 0) return ret; *got_frame = 1; } if (*got_frame) - s->frame_number = picture->avframe.display_picture_number + 1; + s->frame_number = picture->display_picture_number + 1; return buf_idx; } AVCodec ff_dirac_decoder = { .name = "dirac", + .long_name = NULL_IF_CONFIG_SMALL("BBC Dirac VC-2"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_DIRAC, .priv_data_size = sizeof(DiracContext), @@ -1934,5 +1947,4 @@ AVCodec ff_dirac_decoder = { .decode = dirac_decode_frame, .capabilities = CODEC_CAP_DELAY, .flush = dirac_decode_flush, - .long_name = NULL_IF_CONFIG_SMALL("BBC Dirac VC-2"), }; diff --git a/ffmpeg/libavcodec/dnxhddec.c b/ffmpeg/libavcodec/dnxhddec.c index 11bed00..42775df 100644 --- a/ffmpeg/libavcodec/dnxhddec.c +++ b/ffmpeg/libavcodec/dnxhddec.c @@ -22,9 +22,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -//#define TRACE -//#define DEBUG - #include "libavutil/imgutils.h" #include "avcodec.h" #include "get_bits.h" @@ -380,9 +377,9 @@ static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, first_field = 1; } - if (av_image_check_size(ctx->width, ctx->height, 0, avctx)) - return -1; - avcodec_set_dimensions(avctx, ctx->width, ctx->height); + ret = ff_set_dimensions(avctx, ctx->width, ctx->height); + if (ret < 0) + return ret; if (first_field) { if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) @@ -416,6 +413,7 @@ static av_cold int dnxhd_decode_close(AVCodecContext *avctx) AVCodec ff_dnxhd_decoder = { .name = "dnxhd", + .long_name = NULL_IF_CONFIG_SMALL("VC3/DNxHD"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_DNXHD, .priv_data_size = sizeof(DNXHDContext), @@ -423,5 +421,4 @@ AVCodec ff_dnxhd_decoder = { .close = dnxhd_decode_close, .decode = dnxhd_decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, - .long_name = NULL_IF_CONFIG_SMALL("VC3/DNxHD"), }; diff --git a/ffmpeg/libavcodec/dnxhdenc.c b/ffmpeg/libavcodec/dnxhdenc.c index 4b6ce2f..c2fbd5c 100644 --- a/ffmpeg/libavcodec/dnxhdenc.c +++ b/ffmpeg/libavcodec/dnxhdenc.c @@ -23,9 +23,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -//#define DEBUG #define RC_VARIANCE 1 // use variance or ssd for fast rc +#include "libavutil/attributes.h" #include "libavutil/internal.h" #include "libavutil/opt.h" #include "avcodec.h" @@ -33,7 +33,6 @@ #include "internal.h" #include "mpegvideo.h" #include "dnxhdenc.h" -#include "internal.h" #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM #define DNX10BIT_QMAT_SHIFT 18 // The largest value that will not lead to overflow for 10bit samples. @@ -43,7 +42,7 @@ static const AVOption options[]={ {NULL} }; -static const AVClass class = { +static const AVClass dnxhd_class = { .class_name = "dnxhd", .item_name = av_default_item_name, .option = options, @@ -115,7 +114,7 @@ static int dnxhd_10bit_dct_quantize(MpegEncContext *ctx, int16_t *block, return last_non_zero; } -static int dnxhd_init_vlc(DNXHDEncContext *ctx) +static av_cold int dnxhd_init_vlc(DNXHDEncContext *ctx) { int i, j, level, run; int max_level = 1<<(ctx->cid_table->bit_depth+2); @@ -170,7 +169,7 @@ static int dnxhd_init_vlc(DNXHDEncContext *ctx) return -1; } -static int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias) +static av_cold int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias) { // init first elem to 1 to avoid div by 0 in convert_matrix uint16_t weight_matrix[64] = {1,}; // convert_matrix needs uint16_t* @@ -234,7 +233,7 @@ static int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias) return -1; } -static int dnxhd_init_rc(DNXHDEncContext *ctx) +static av_cold int dnxhd_init_rc(DNXHDEncContext *ctx) { FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_rc, 8160*ctx->m.avctx->qmax*sizeof(RCEntry), fail); if (ctx->m.avctx->mb_decision != FF_MB_DECISION_RD) @@ -248,7 +247,7 @@ static int dnxhd_init_rc(DNXHDEncContext *ctx) return -1; } -static int dnxhd_encode_init(AVCodecContext *avctx) +static av_cold int dnxhd_encode_init(AVCodecContext *avctx) { DNXHDEncContext *ctx = avctx->priv_data; int i, index, bit_depth; @@ -330,9 +329,12 @@ static int dnxhd_encode_init(AVCodecContext *avctx) FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_bits, ctx->m.mb_num *sizeof(uint16_t), fail); FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_qscale, ctx->m.mb_num *sizeof(uint8_t), fail); - ctx->frame.key_frame = 1; - ctx->frame.pict_type = AV_PICTURE_TYPE_I; - ctx->m.avctx->coded_frame = &ctx->frame; + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + + avctx->coded_frame->key_frame = 1; + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; if (avctx->thread_count > MAX_THREADS) { av_log(avctx, AV_LOG_ERROR, "too many threads\n"); @@ -353,7 +355,7 @@ static int dnxhd_encode_init(AVCodecContext *avctx) static int dnxhd_write_header(AVCodecContext *avctx, uint8_t *buf) { DNXHDEncContext *ctx = avctx->priv_data; - const uint8_t header_prefix[5] = { 0x00,0x00,0x02,0x80,0x01 }; + static const uint8_t header_prefix[5] = { 0x00,0x00,0x02,0x80,0x01 }; memset(buf, 0, 640); @@ -923,19 +925,14 @@ static void dnxhd_load_picture(DNXHDEncContext *ctx, const AVFrame *frame) { int i; - for (i = 0; i < 3; i++) { - ctx->frame.data[i] = frame->data[i]; - ctx->frame.linesize[i] = frame->linesize[i]; - } - for (i = 0; i < ctx->m.avctx->thread_count; i++) { - ctx->thread[i]->m.linesize = ctx->frame.linesize[0]<interlaced; - ctx->thread[i]->m.uvlinesize = ctx->frame.linesize[1]<interlaced; + ctx->thread[i]->m.linesize = frame->linesize[0] << ctx->interlaced; + ctx->thread[i]->m.uvlinesize = frame->linesize[1] << ctx->interlaced; ctx->thread[i]->dct_y_offset = ctx->m.linesize *8; ctx->thread[i]->dct_uv_offset = ctx->m.uvlinesize*8; } - ctx->frame.interlaced_frame = frame->interlaced_frame; + ctx->m.avctx->coded_frame->interlaced_frame = frame->interlaced_frame; ctx->cur_field = frame->interlaced_frame && !frame->top_field_first; } @@ -955,9 +952,9 @@ static int dnxhd_encode_picture(AVCodecContext *avctx, AVPacket *pkt, encode_coding_unit: for (i = 0; i < 3; i++) { - ctx->src[i] = ctx->frame.data[i]; + ctx->src[i] = frame->data[i]; if (ctx->interlaced && ctx->cur_field) - ctx->src[i] += ctx->frame.linesize[i]; + ctx->src[i] += frame->linesize[i]; } dnxhd_write_header(avctx, buf); @@ -995,14 +992,14 @@ static int dnxhd_encode_picture(AVCodecContext *avctx, AVPacket *pkt, goto encode_coding_unit; } - ctx->frame.quality = ctx->qscale*FF_QP2LAMBDA; + avctx->coded_frame->quality = ctx->qscale * FF_QP2LAMBDA; pkt->flags |= AV_PKT_FLAG_KEY; *got_packet = 1; return 0; } -static int dnxhd_encode_end(AVCodecContext *avctx) +static av_cold int dnxhd_encode_end(AVCodecContext *avctx) { DNXHDEncContext *ctx = avctx->priv_data; int max_level = 1<<(ctx->cid_table->bit_depth+2); @@ -1028,6 +1025,8 @@ static int dnxhd_encode_end(AVCodecContext *avctx) for (i = 1; i < avctx->thread_count; i++) av_freep(&ctx->thread[i]); + av_frame_free(&avctx->coded_frame); + return 0; } @@ -1038,6 +1037,7 @@ static const AVCodecDefault dnxhd_defaults[] = { AVCodec ff_dnxhd_encoder = { .name = "dnxhd", + .long_name = NULL_IF_CONFIG_SMALL("VC3/DNxHD"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_DNXHD, .priv_data_size = sizeof(DNXHDEncContext), @@ -1048,7 +1048,6 @@ AVCodec ff_dnxhd_encoder = { .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("VC3/DNxHD"), - .priv_class = &class, + .priv_class = &dnxhd_class, .defaults = dnxhd_defaults, }; diff --git a/ffmpeg/libavcodec/dnxhdenc.h b/ffmpeg/libavcodec/dnxhdenc.h index 9b59b96..110b0ad 100644 --- a/ffmpeg/libavcodec/dnxhdenc.h +++ b/ffmpeg/libavcodec/dnxhdenc.h @@ -43,7 +43,6 @@ typedef struct DNXHDEncContext { AVClass *class; MpegEncContext m; ///< Used for quantization dsp functions - AVFrame frame; int cid; const CIDEntry *cid_table; uint8_t *msip; ///< Macroblock Scan Indexes Payload diff --git a/ffmpeg/libavcodec/dpcm.c b/ffmpeg/libavcodec/dpcm.c index 402b0f9..0c0bcca 100644 --- a/ffmpeg/libavcodec/dpcm.c +++ b/ffmpeg/libavcodec/dpcm.c @@ -328,13 +328,13 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, #define DPCM_DECODER(id_, name_, long_name_) \ AVCodec ff_ ## name_ ## _decoder = { \ .name = #name_, \ + .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ .type = AVMEDIA_TYPE_AUDIO, \ .id = id_, \ .priv_data_size = sizeof(DPCMContext), \ .init = dpcm_decode_init, \ .decode = dpcm_decode_frame, \ .capabilities = CODEC_CAP_DR1, \ - .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ } DPCM_DECODER(AV_CODEC_ID_INTERPLAY_DPCM, interplay_dpcm, "DPCM Interplay"); diff --git a/ffmpeg/libavcodec/dpx.c b/ffmpeg/libavcodec/dpx.c index 0d60a7e..5c3c3e8 100644 --- a/ffmpeg/libavcodec/dpx.c +++ b/ffmpeg/libavcodec/dpx.c @@ -25,6 +25,18 @@ #include "avcodec.h" #include "internal.h" +static unsigned int read16(const uint8_t **ptr, int is_big) +{ + unsigned int temp; + if (is_big) { + temp = AV_RB16(*ptr); + } else { + temp = AV_RL16(*ptr); + } + *ptr += 2; + return temp; +} + static unsigned int read32(const uint8_t **ptr, int is_big) { unsigned int temp; @@ -66,6 +78,7 @@ static int decode_frame(AVCodecContext *avctx, int magic_num, endian; int x, y, i, ret; int w, h, bits_per_color, descriptor, elements, packing, total_size; + int encoding; unsigned int rgbBuffer = 0; int n_datum = 0; @@ -98,11 +111,9 @@ static int decode_frame(AVCodecContext *avctx, buf = avpkt->data + 0x304; w = read32(&buf, endian); h = read32(&buf, endian); - if ((ret = av_image_check_size(w, h, 0, avctx)) < 0) - return ret; - if (w != avctx->width || h != avctx->height) - avcodec_set_dimensions(avctx, w, h); + if ((ret = ff_set_dimensions(avctx, w, h)) < 0) + return ret; // Need to end in 0x320 to read the descriptor buf += 20; @@ -113,9 +124,19 @@ static int decode_frame(AVCodecContext *avctx, avctx->bits_per_raw_sample = bits_per_color = buf[0]; buf++; - packing = *((uint16_t*)buf); + packing = read16(&buf, endian); + encoding = read16(&buf, endian); + + if (packing > 1) { + avpriv_report_missing_feature(avctx, "Packing %d", packing); + return AVERROR_PATCHWELCOME; + } + if (encoding) { + avpriv_report_missing_feature(avctx, "Encoding %d", encoding); + return AVERROR_PATCHWELCOME; + } - buf += 824; + buf += 820; avctx->sample_aspect_ratio.num = read32(&buf, endian); avctx->sample_aspect_ratio.den = read32(&buf, endian); if (avctx->sample_aspect_ratio.num > 0 && avctx->sample_aspect_ratio.den > 0) @@ -126,57 +147,101 @@ static int decode_frame(AVCodecContext *avctx, avctx->sample_aspect_ratio = (AVRational){ 0, 1 }; switch (descriptor) { - case 51: // RGBA - elements = 4; - break; - case 50: // RGB - elements = 3; - break; - default: - av_log(avctx, AV_LOG_ERROR, "Unsupported descriptor %d\n", descriptor); - return AVERROR_INVALIDDATA; + case 6: // Y + elements = 1; + break; + case 52: // ABGR + case 51: // RGBA + elements = 4; + break; + case 50: // RGB + elements = 3; + break; + default: + avpriv_report_missing_feature(avctx, "Descriptor %d", descriptor); + return AVERROR_PATCHWELCOME; } switch (bits_per_color) { - case 8: - if (elements == 4) { - avctx->pix_fmt = AV_PIX_FMT_RGBA; - } else { - avctx->pix_fmt = AV_PIX_FMT_RGB24; - } - total_size = avctx->width * avctx->height * elements; - break; - case 10: - if (!packing) { - av_log(avctx, AV_LOG_ERROR, "Packing to 32bit required\n"); - return -1; - } - avctx->pix_fmt = AV_PIX_FMT_GBRP10; - total_size = (avctx->width * avctx->height * elements + 2) / 3 * 4; - break; - case 12: - if (!packing) { - av_log(avctx, AV_LOG_ERROR, "Packing to 16bit required\n"); - return -1; - } - if (endian) { - avctx->pix_fmt = AV_PIX_FMT_GBRP12BE; - } else { - avctx->pix_fmt = AV_PIX_FMT_GBRP12LE; - } - total_size = 2 * avctx->width * avctx->height * elements; - break; - case 16: - if (endian) { - avctx->pix_fmt = elements == 4 ? AV_PIX_FMT_RGBA64BE : AV_PIX_FMT_RGB48BE; - } else { - avctx->pix_fmt = elements == 4 ? AV_PIX_FMT_RGBA64LE : AV_PIX_FMT_RGB48LE; - } - total_size = 2 * avctx->width * avctx->height * elements; - break; - default: - av_log(avctx, AV_LOG_ERROR, "Unsupported color depth : %d\n", bits_per_color); - return AVERROR_INVALIDDATA; + case 8: + total_size = avctx->width * avctx->height * elements; + break; + case 10: + if (!packing) { + av_log(avctx, AV_LOG_ERROR, "Packing to 32bit required\n"); + return -1; + } + total_size = (avctx->width * elements + 2) / 3 * 4 * avctx->height; + break; + case 12: + if (!packing) { + av_log(avctx, AV_LOG_ERROR, "Packing to 16bit required\n"); + return -1; + } + total_size = 2 * avctx->width * avctx->height * elements; + break; + case 16: + total_size = 2 * avctx->width * avctx->height * elements; + break; + case 1: + case 32: + case 64: + avpriv_report_missing_feature(avctx, "Depth %d", bits_per_color); + return AVERROR_PATCHWELCOME; + default: + return AVERROR_INVALIDDATA; + } + + switch (1000 * descriptor + 10 * bits_per_color + endian) { + case 6081: + case 6080: + avctx->pix_fmt = AV_PIX_FMT_GRAY8; + break; + case 50081: + case 50080: + avctx->pix_fmt = AV_PIX_FMT_RGB24; + break; + case 52081: + case 52080: + avctx->pix_fmt = AV_PIX_FMT_ABGR; + break; + case 51081: + case 51080: + avctx->pix_fmt = AV_PIX_FMT_RGBA; + break; + case 50100: + case 51100: + case 50101: + case 51101: + avctx->pix_fmt = AV_PIX_FMT_GBRP10; + break; + case 50120: + case 51120: + case 50121: + case 51121: + avctx->pix_fmt = AV_PIX_FMT_GBRP12; + break; + case 6161: + avctx->pix_fmt = AV_PIX_FMT_GRAY16BE; + break; + case 6160: + avctx->pix_fmt = AV_PIX_FMT_GRAY16LE; + break; + case 50161: + avctx->pix_fmt = AV_PIX_FMT_RGB48BE; + break; + case 50160: + avctx->pix_fmt = AV_PIX_FMT_RGB48LE; + break; + case 51161: + avctx->pix_fmt = AV_PIX_FMT_RGBA64BE; + break; + case 51160: + avctx->pix_fmt = AV_PIX_FMT_RGBA64LE; + break; + default: + av_log(avctx, AV_LOG_ERROR, "Unsupported format\n"); + return AVERROR_PATCHWELCOME; } if ((ret = ff_get_buffer(avctx, p, 0)) < 0) @@ -210,6 +275,7 @@ static int decode_frame(AVCodecContext *avctx, read10in32(&buf, &rgbBuffer, &n_datum, endian); } + n_datum = 0; for (i = 0; i < 3; i++) ptr[i] += p->linesize[i]; } @@ -220,18 +286,12 @@ static int decode_frame(AVCodecContext *avctx, (uint16_t*)ptr[1], (uint16_t*)ptr[2]}; for (y = 0; y < avctx->width; y++) { - *dst[2] = *((uint16_t*)buf); - *dst[2] = (*dst[2] >> 4) | (*dst[2] << 12); + *dst[2] = read16(&buf, endian) >> 4; dst[2]++; - buf += 2; - *dst[0] = *((uint16_t*)buf); - *dst[0] = (*dst[0] >> 4) | (*dst[0] << 12); + *dst[0] = read16(&buf, endian) >> 4; dst[0]++; - buf += 2; - *dst[1] = *((uint16_t*)buf); - *dst[1] = (*dst[1] >> 4) | (*dst[1] << 12); + *dst[1] = read16(&buf, endian) >> 4; dst[1]++; - buf += 2; // For 12 bit, ignore alpha if (elements == 4) buf += 2; @@ -243,11 +303,9 @@ static int decode_frame(AVCodecContext *avctx, case 16: elements *= 2; case 8: - for (x = 0; x < avctx->height; x++) { - memcpy(ptr[0], buf, elements*avctx->width); - ptr[0] += p->linesize[0]; - buf += elements*avctx->width; - } + av_image_copy_plane(ptr[0], p->linesize[0], + buf, elements * avctx->width, + elements * avctx->width, avctx->height); break; } @@ -258,9 +316,9 @@ static int decode_frame(AVCodecContext *avctx, AVCodec ff_dpx_decoder = { .name = "dpx", + .long_name = NULL_IF_CONFIG_SMALL("DPX (Digital Picture Exchange) image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_DPX, .decode = decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("DPX image"), .capabilities = CODEC_CAP_DR1, }; diff --git a/ffmpeg/libavcodec/dpxenc.c b/ffmpeg/libavcodec/dpxenc.c index f210bbc..0eb1297 100644 --- a/ffmpeg/libavcodec/dpxenc.c +++ b/ffmpeg/libavcodec/dpxenc.c @@ -26,7 +26,6 @@ #include "internal.h" typedef struct DPXContext { - AVFrame picture; int big_endian; int bits_per_component; int descriptor; @@ -36,44 +35,35 @@ typedef struct DPXContext { static av_cold int encode_init(AVCodecContext *avctx) { DPXContext *s = avctx->priv_data; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); - avctx->coded_frame = &s->picture; - avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; - avctx->coded_frame->key_frame = 1; - - s->big_endian = 1; - s->bits_per_component = 8; - s->descriptor = 50; /* RGB */ - s->planar = 0; + s->big_endian = !!(desc->flags & AV_PIX_FMT_FLAG_BE); + s->bits_per_component = desc->comp[0].depth_minus1 + 1; + s->descriptor = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) ? 51 : 50; + s->planar = !!(desc->flags & AV_PIX_FMT_FLAG_PLANAR); switch (avctx->pix_fmt) { - case AV_PIX_FMT_RGB24: + case AV_PIX_FMT_ABGR: + s->descriptor = 52; + break; + case AV_PIX_FMT_GRAY16BE: + case AV_PIX_FMT_GRAY16LE: + case AV_PIX_FMT_GRAY8: + s->descriptor = 6; break; + case AV_PIX_FMT_GBRP10BE: + case AV_PIX_FMT_GBRP10LE: + case AV_PIX_FMT_GBRP12BE: + case AV_PIX_FMT_GBRP12LE: + case AV_PIX_FMT_RGB24: + case AV_PIX_FMT_RGBA64BE: + case AV_PIX_FMT_RGBA64LE: case AV_PIX_FMT_RGBA: - s->descriptor = 51; /* RGBA */ break; case AV_PIX_FMT_RGB48LE: - s->big_endian = 0; case AV_PIX_FMT_RGB48BE: - s->bits_per_component = avctx->bits_per_raw_sample ? avctx->bits_per_raw_sample : 16; - break; - case AV_PIX_FMT_RGBA64LE: - s->big_endian = 0; - case AV_PIX_FMT_RGBA64BE: - s->descriptor = 51; - s->bits_per_component = 16; - break; - case AV_PIX_FMT_GBRP10LE: - s->big_endian = 0; - case AV_PIX_FMT_GBRP10BE: - s->bits_per_component = 10; - s->planar = 1; - break; - case AV_PIX_FMT_GBRP12LE: - s->big_endian = 0; - case AV_PIX_FMT_GBRP12BE: - s->bits_per_component = 12; - s->planar = 1; + if (avctx->bits_per_raw_sample) + s->bits_per_component = avctx->bits_per_raw_sample; break; default: av_log(avctx, AV_LOG_INFO, "unsupported pixel format\n"); @@ -132,11 +122,11 @@ static void encode_gbrp10(AVCodecContext *avctx, const AVPicture *pic, uint8_t * if (s->big_endian) { value = (AV_RB16(src[0] + 2*x) << 12) | (AV_RB16(src[1] + 2*x) << 2) - | (AV_RB16(src[2] + 2*x) << 22); + | ((unsigned)AV_RB16(src[2] + 2*x) << 22); } else { value = (AV_RL16(src[0] + 2*x) << 12) | (AV_RL16(src[1] + 2*x) << 2) - | (AV_RL16(src[2] + 2*x) << 22); + | ((unsigned)AV_RL16(src[2] + 2*x) << 22); } write32(dst, value); dst += 4; @@ -252,23 +242,20 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, } AVCodec ff_dpx_encoder = { - .name = "dpx", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_DPX, + .name = "dpx", + .long_name = NULL_IF_CONFIG_SMALL("DPX (Digital Picture Exchange) image"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_DPX, .priv_data_size = sizeof(DPXContext), - .init = encode_init, - .encode2 = encode_frame, - .pix_fmts = (const enum AVPixelFormat[]){ - AV_PIX_FMT_RGB24, - AV_PIX_FMT_RGBA, - AV_PIX_FMT_RGB48LE, - AV_PIX_FMT_RGB48BE, - AV_PIX_FMT_RGBA64LE, - AV_PIX_FMT_RGBA64BE, - AV_PIX_FMT_GBRP10LE, - AV_PIX_FMT_GBRP10BE, - AV_PIX_FMT_GBRP12LE, - AV_PIX_FMT_GBRP12BE, + .init = encode_init, + .encode2 = encode_frame, + .pix_fmts = (const enum AVPixelFormat[]){ + AV_PIX_FMT_GRAY8, + AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_ABGR, + AV_PIX_FMT_GRAY16LE, AV_PIX_FMT_GRAY16BE, + AV_PIX_FMT_RGB48LE, AV_PIX_FMT_RGB48BE, + AV_PIX_FMT_RGBA64LE, AV_PIX_FMT_RGBA64BE, + AV_PIX_FMT_GBRP10LE, AV_PIX_FMT_GBRP10BE, + AV_PIX_FMT_GBRP12LE, AV_PIX_FMT_GBRP12BE, AV_PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("DPX image"), }; diff --git a/ffmpeg/libavcodec/dsicinav.c b/ffmpeg/libavcodec/dsicinav.c index f0e8f02..2d06ad8 100644 --- a/ffmpeg/libavcodec/dsicinav.c +++ b/ffmpeg/libavcodec/dsicinav.c @@ -39,7 +39,7 @@ typedef enum CinVideoBitmapIndex { typedef struct CinVideoContext { AVCodecContext *avctx; - AVFrame frame; + AVFrame *frame; unsigned int bitmap_size; uint32_t palette[256]; uint8_t *bitmap_table[3]; @@ -118,7 +118,9 @@ static av_cold int cinvideo_decode_init(AVCodecContext *avctx) cin->avctx = avctx; avctx->pix_fmt = AV_PIX_FMT_PAL8; - avcodec_get_frame_defaults(&cin->frame); + cin->frame = av_frame_alloc(); + if (!cin->frame) + return AVERROR(ENOMEM); cin->bitmap_size = avctx->width * avctx->height; if (allocate_buffers(cin)) @@ -127,27 +129,30 @@ static av_cold int cinvideo_decode_init(AVCodecContext *avctx) return 0; } -static void cin_apply_delta_data(const unsigned char *src, unsigned char *dst, int size) +static void cin_apply_delta_data(const unsigned char *src, unsigned char *dst, + int size) { while (size--) *dst++ += *src++; } -static int cin_decode_huffman(const unsigned char *src, int src_size, unsigned char *dst, int dst_size) +static int cin_decode_huffman(const unsigned char *src, int src_size, + unsigned char *dst, int dst_size) { int b, huff_code = 0; unsigned char huff_code_table[15]; - unsigned char *dst_cur = dst; - unsigned char *dst_end = dst + dst_size; + unsigned char *dst_cur = dst; + unsigned char *dst_end = dst + dst_size; const unsigned char *src_end = src + src_size; - memcpy(huff_code_table, src, 15); src += 15; + memcpy(huff_code_table, src, 15); + src += 15; while (src < src_end) { huff_code = *src++; if ((huff_code >> 4) == 15) { - b = huff_code << 4; - huff_code = *src++; + b = huff_code << 4; + huff_code = *src++; *dst_cur++ = b | (huff_code >> 4); } else *dst_cur++ = huff_code_table[huff_code >> 4]; @@ -166,11 +171,12 @@ static int cin_decode_huffman(const unsigned char *src, int src_size, unsigned c return dst_cur - dst; } -static int cin_decode_lzss(const unsigned char *src, int src_size, unsigned char *dst, int dst_size) +static int cin_decode_lzss(const unsigned char *src, int src_size, + unsigned char *dst, int dst_size) { uint16_t cmd; int i, sz, offset, code; - unsigned char *dst_end = dst + dst_size, *dst_start = dst; + unsigned char *dst_end = dst + dst_size, *dst_start = dst; const unsigned char *src_end = src + src_size; while (src < src_end && dst < dst_end) { @@ -179,13 +185,15 @@ static int cin_decode_lzss(const unsigned char *src, int src_size, unsigned char if (code & (1 << i)) { *dst++ = *src++; } else { - cmd = AV_RL16(src); src += 2; + cmd = AV_RL16(src); + src += 2; offset = cmd >> 4; - if ((int) (dst - dst_start) < offset + 1) + if ((int)(dst - dst_start) < offset + 1) return AVERROR_INVALIDDATA; sz = (cmd & 0xF) + 2; - /* don't use memcpy/memmove here as the decoding routine (ab)uses */ - /* buffer overlappings to repeat bytes in the destination */ + /* don't use memcpy/memmove here as the decoding routine + * (ab)uses buffer overlappings to repeat bytes in the + * destination */ sz = FFMIN(sz, dst_end - dst); while (sz--) { *dst = *(dst - offset - 1); @@ -198,10 +206,11 @@ static int cin_decode_lzss(const unsigned char *src, int src_size, unsigned char return 0; } -static int cin_decode_rle(const unsigned char *src, int src_size, unsigned char *dst, int dst_size) +static int cin_decode_rle(const unsigned char *src, int src_size, + unsigned char *dst, int dst_size) { int len, code; - unsigned char *dst_end = dst + dst_size; + unsigned char *dst_end = dst + dst_size; const unsigned char *src_end = src + src_size; while (src + 1 < src_end && dst < dst_end) { @@ -215,7 +224,7 @@ static int cin_decode_rle(const unsigned char *src, int src_size, unsigned char av_log(NULL, AV_LOG_ERROR, "RLE overread\n"); return AVERROR_INVALIDDATA; } - memcpy(dst, src, FFMIN(len, dst_end - dst)); + memcpy(dst, src, FFMIN3(len, dst_end - dst, src_end - src)); src += len; } dst += len; @@ -227,15 +236,16 @@ static int cinvideo_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; CinVideoContext *cin = avctx->priv_data; - int i, y, palette_type, palette_colors_count, bitmap_frame_type, bitmap_frame_size, res = 0; + int i, y, palette_type, palette_colors_count, + bitmap_frame_type, bitmap_frame_size, res = 0; - palette_type = buf[0]; - palette_colors_count = AV_RL16(buf+1); - bitmap_frame_type = buf[3]; - buf += 4; + palette_type = buf[0]; + palette_colors_count = AV_RL16(buf + 1); + bitmap_frame_type = buf[3]; + buf += 4; bitmap_frame_size = buf_size - 4; @@ -246,46 +256,48 @@ static int cinvideo_decode_frame(AVCodecContext *avctx, if (palette_colors_count > 256) return AVERROR_INVALIDDATA; for (i = 0; i < palette_colors_count; ++i) { - cin->palette[i] = 0xFFU << 24 | bytestream_get_le24(&buf); + cin->palette[i] = 0xFFU << 24 | bytestream_get_le24(&buf); bitmap_frame_size -= 3; } } else { for (i = 0; i < palette_colors_count; ++i) { - cin->palette[buf[0]] = 0xFFU << 24 | AV_RL24(buf+1); - buf += 4; - bitmap_frame_size -= 4; + cin->palette[buf[0]] = 0xFFU << 24 | AV_RL24(buf + 1); + buf += 4; + bitmap_frame_size -= 4; } } - /* note: the decoding routines below assumes that surface.width = surface.pitch */ + /* note: the decoding routines below assumes that + * surface.width = surface.pitch */ switch (bitmap_frame_type) { case 9: cin_decode_rle(buf, bitmap_frame_size, - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); break; case 34: cin_decode_rle(buf, bitmap_frame_size, - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP], - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); break; case 35: bitmap_frame_size = cin_decode_huffman(buf, bitmap_frame_size, - cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size); + cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size); cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size, - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); break; case 36: bitmap_frame_size = cin_decode_huffman(buf, bitmap_frame_size, - cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size); + cin->bitmap_table[CIN_INT_BMP], + cin->bitmap_size); cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size, - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP], - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); break; case 37: cin_decode_huffman(buf, bitmap_frame_size, - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); break; case 38: res = cin_decode_lzss(buf, bitmap_frame_size, @@ -301,23 +313,24 @@ static int cinvideo_decode_frame(AVCodecContext *avctx, if (res < 0) return res; cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP], - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); break; } - if ((res = ff_reget_buffer(avctx, &cin->frame)) < 0) + if ((res = ff_reget_buffer(avctx, cin->frame)) < 0) return res; - memcpy(cin->frame.data[1], cin->palette, sizeof(cin->palette)); - cin->frame.palette_has_changed = 1; + memcpy(cin->frame->data[1], cin->palette, sizeof(cin->palette)); + cin->frame->palette_has_changed = 1; for (y = 0; y < cin->avctx->height; ++y) - memcpy(cin->frame.data[0] + (cin->avctx->height - 1 - y) * cin->frame.linesize[0], - cin->bitmap_table[CIN_CUR_BMP] + y * cin->avctx->width, - cin->avctx->width); + memcpy(cin->frame->data[0] + (cin->avctx->height - 1 - y) * cin->frame->linesize[0], + cin->bitmap_table[CIN_CUR_BMP] + y * cin->avctx->width, + cin->avctx->width); - FFSWAP(uint8_t *, cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_table[CIN_PRE_BMP]); + FFSWAP(uint8_t *, cin->bitmap_table[CIN_CUR_BMP], + cin->bitmap_table[CIN_PRE_BMP]); - if ((res = av_frame_ref(data, &cin->frame)) < 0) + if ((res = av_frame_ref(data, cin->frame)) < 0) return res; *got_frame = 1; @@ -329,7 +342,7 @@ static av_cold int cinvideo_decode_end(AVCodecContext *avctx) { CinVideoContext *cin = avctx->priv_data; - av_frame_unref(&cin->frame); + av_frame_free(&cin->frame); destroy_buffers(cin); @@ -352,9 +365,9 @@ static av_cold int cinaudio_decode_init(AVCodecContext *avctx) static int cinaudio_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { - AVFrame *frame = data; - const uint8_t *buf = avpkt->data; - CinAudioContext *cin = avctx->priv_data; + AVFrame *frame = data; + const uint8_t *buf = avpkt->data; + CinAudioContext *cin = avctx->priv_data; const uint8_t *buf_end = buf + avpkt->size; int16_t *samples; int delta, ret; @@ -368,13 +381,13 @@ static int cinaudio_decode_frame(AVCodecContext *avctx, void *data, delta = cin->delta; if (cin->initial_decode_frame) { cin->initial_decode_frame = 0; - delta = sign_extend(AV_RL16(buf), 16); - buf += 2; - *samples++ = delta; + delta = sign_extend(AV_RL16(buf), 16); + buf += 2; + *samples++ = delta; } while (buf < buf_end) { - delta += cinaudio_delta16_table[*buf++]; - delta = av_clip_int16(delta); + delta += cinaudio_delta16_table[*buf++]; + delta = av_clip_int16(delta); *samples++ = delta; } cin->delta = delta; @@ -384,9 +397,9 @@ static int cinaudio_decode_frame(AVCodecContext *avctx, void *data, return avpkt->size; } - AVCodec ff_dsicinvideo_decoder = { .name = "dsicinvideo", + .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_DSICINVIDEO, .priv_data_size = sizeof(CinVideoContext), @@ -394,16 +407,15 @@ AVCodec ff_dsicinvideo_decoder = { .close = cinvideo_decode_end, .decode = cinvideo_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN video"), }; AVCodec ff_dsicinaudio_decoder = { .name = "dsicinaudio", + .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN audio"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_DSICINAUDIO, .priv_data_size = sizeof(CinAudioContext), .init = cinaudio_decode_init, .decode = cinaudio_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN audio"), }; diff --git a/ffmpeg/libavcodec/dsputil.c b/ffmpeg/libavcodec/dsputil.c index b56af0e..0e9e347 100644 --- a/ffmpeg/libavcodec/dsputil.c +++ b/ffmpeg/libavcodec/dsputil.c @@ -27,6 +27,7 @@ * DSP utils */ +#include "libavutil/attributes.h" #include "libavutil/imgutils.h" #include "libavutil/internal.h" #include "avcodec.h" @@ -68,9 +69,6 @@ const uint8_t ff_zigzag248_direct[64] = { 53, 61, 54, 62, 39, 47, 55, 63, }; -/* not permutated inverse zigzag_direct + 1 for MMX quantizer */ -DECLARE_ALIGNED(16, uint16_t, ff_inv_zigzag_direct16)[64]; - const uint8_t ff_alternate_horizontal_scan[64] = { 0, 1, 2, 3, 8, 9, 16, 17, 10, 11, 4, 5, 6, 7, 15, 14, @@ -107,7 +105,9 @@ static const uint8_t simple_mmx_permutation[64]={ static const uint8_t idct_sse2_row_perm[8] = {0, 4, 1, 5, 2, 6, 3, 7}; -void ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *src_scantable){ +av_cold void ff_init_scantable(uint8_t *permutation, ScanTable *st, + const uint8_t *src_scantable) +{ int i; int end; @@ -128,8 +128,8 @@ void ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *src_s } } -void ff_init_scantable_permutation(uint8_t *idct_permutation, - int idct_permutation_type) +av_cold void ff_init_scantable_permutation(uint8_t *idct_permutation, + int idct_permutation_type) { int i; @@ -797,7 +797,7 @@ static inline void avg_tpel_pixels_mc22_c(uint8_t *dst, const uint8_t *src, int #define QPEL_MC(r, OPNAME, RND, OP) \ static void OPNAME ## mpeg4_qpel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h){\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ int i;\ for(i=0; i>31); - if(p2&256) p2= ~(p2>>31); - - src[x-1*stride] = p1; - src[x+0*stride] = p2; - - ad1= FFABS(d1)>>1; - - d2= av_clip((p0-p3)/4, -ad1, ad1); - - src[x-2*stride] = p0 - d2; - src[x+ stride] = p3 + d2; - } - } -} - -static void h263_h_loop_filter_c(uint8_t *src, int stride, int qscale){ - if(CONFIG_H263_DECODER || CONFIG_H263_ENCODER) { - int y; - const int strength= ff_h263_loop_filter_strength[qscale]; - - for(y=0; y<8; y++){ - int d1, d2, ad1; - int p0= src[y*stride-2]; - int p1= src[y*stride-1]; - int p2= src[y*stride+0]; - int p3= src[y*stride+1]; - int d = (p0 - p3 + 4*(p2 - p1)) / 8; - - if (d<-2*strength) d1= 0; - else if(d<- strength) d1=-2*strength - d; - else if(d< strength) d1= d; - else if(d< 2*strength) d1= 2*strength - d; - else d1= 0; - - p1 += d1; - p2 -= d1; - if(p1&256) p1= ~(p1>>31); - if(p2&256) p2= ~(p2>>31); - - src[y*stride-1] = p1; - src[y*stride+0] = p2; - - ad1= FFABS(d1)>>1; - - d2= av_clip((p0-p3)/4, -ad1, ad1); - - src[y*stride-2] = p0 - d2; - src[y*stride+1] = p3 + d2; - } - } -} - -static void h261_loop_filter_c(uint8_t *src, int stride){ - int x,y,xy,yz; - int temp[64]; - - for(x=0; x<8; x++){ - temp[x ] = 4*src[x ]; - temp[x + 7*8] = 4*src[x + 7*stride]; - } - for(y=1; y<7; y++){ - for(x=0; x<8; x++){ - xy = y * stride + x; - yz = y * 8 + x; - temp[yz] = src[xy - stride] + 2*src[xy] + src[xy + stride]; - } - } - - for(y=0; y<8; y++){ - src[ y*stride] = (temp[ y*8] + 2)>>2; - src[7+y*stride] = (temp[7+y*8] + 2)>>2; - for(x=1; x<7; x++){ - xy = y * stride + x; - yz = y * 8 + x; - src[xy] = (temp[yz-1] + 2*temp[yz] + temp[yz+1] + 8)>>4; - } - } -} - static inline int pix_abs16_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) { int s, i; @@ -1955,7 +1854,7 @@ void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type){ static void add_bytes_c(uint8_t *dst, uint8_t *src, int w){ long i; - for(i=0; i<=w-sizeof(long); i+=sizeof(long)){ + for (i = 0; i <= w - (int)sizeof(long); i += sizeof(long)) { long a = *(long*)(src+i); long b = *(long*)(dst+i); *(long*)(dst+i) = ((a&pb_7f) + (b&pb_7f)) ^ ((a^b)&pb_80); @@ -1980,7 +1879,7 @@ static void diff_bytes_c(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, } }else #endif - for(i=0; i<=w-sizeof(long); i+=sizeof(long)){ + for (i = 0; i <= w - (int)sizeof(long); i += sizeof(long)) { long a = *(long*)(src1+i); long b = *(long*)(src2+i); *(long*)(dst+i) = ((a|pb_80) - (b&pb_7f)) ^ ((a^b^pb_80)&pb_80); @@ -2596,19 +2495,6 @@ static int32_t scalarproduct_and_madd_int16_c(int16_t *v1, const int16_t *v2, co return res; } -static void apply_window_int16_c(int16_t *output, const int16_t *input, - const int16_t *window, unsigned int len) -{ - int i; - int len2 = len >> 1; - - for (i = 0; i < len2; i++) { - int16_t w = window[i]; - output[i] = (MUL16(input[i], w) + (1 << 14)) >> 15; - output[len-i-1] = (MUL16(input[len-i-1], w) + (1 << 14)) >> 15; - } -} - static void vector_clip_int32_c(int32_t *dst, const int32_t *src, int32_t min, int32_t max, unsigned int len) { @@ -2625,12 +2511,12 @@ static void vector_clip_int32_c(int32_t *dst, const int32_t *src, int32_t min, } while (len > 0); } -static void ff_jref_idct_put(uint8_t *dest, int line_size, int16_t *block) +static void jref_idct_put(uint8_t *dest, int line_size, int16_t *block) { ff_j_rev_dct (block); put_pixels_clamped_c(block, dest, line_size); } -static void ff_jref_idct_add(uint8_t *dest, int line_size, int16_t *block) +static void jref_idct_add(uint8_t *dest, int line_size, int16_t *block) { ff_j_rev_dct (block); add_pixels_clamped_c(block, dest, line_size); @@ -2675,8 +2561,6 @@ av_cold void ff_dsputil_static_init(void) for(i=0;i<512;i++) { ff_squareTbl[i] = (i - 256) * (i - 256); } - - for(i=0; i<64; i++) ff_inv_zigzag_direct16[ff_zigzag_direct[i]]= i+1; } int ff_check_alignment(void){ @@ -2744,10 +2628,15 @@ av_cold void ff_dsputil_init(DSPContext* c, AVCodecContext *avctx) c->idct_add = ff_simple_idct_add_10; c->idct = ff_simple_idct_10; c->idct_permutation_type = FF_NO_IDCT_PERM; + } else if (avctx->bits_per_raw_sample == 12) { + c->idct_put = ff_simple_idct_put_12; + c->idct_add = ff_simple_idct_add_12; + c->idct = ff_simple_idct_12; + c->idct_permutation_type = FF_NO_IDCT_PERM; } else { if(avctx->idct_algo==FF_IDCT_INT){ - c->idct_put= ff_jref_idct_put; - c->idct_add= ff_jref_idct_add; + c->idct_put= jref_idct_put; + c->idct_add= jref_idct_add; c->idct = ff_j_rev_dct; c->idct_permutation_type= FF_LIBMPEG2_IDCT_PERM; }else if(avctx->idct_algo==FF_IDCT_FAAN){ @@ -2891,20 +2780,12 @@ av_cold void ff_dsputil_init(DSPContext* c, AVCodecContext *avctx) c->bswap_buf= bswap_buf; c->bswap16_buf = bswap16_buf; - if (CONFIG_H263_DECODER || CONFIG_H263_ENCODER) { - c->h263_h_loop_filter= h263_h_loop_filter_c; - c->h263_v_loop_filter= h263_v_loop_filter_c; - } - - c->h261_loop_filter= h261_loop_filter_c; - c->try_8x8basis= try_8x8basis_c; c->add_8x8basis= add_8x8basis_c; c->vector_clipf = vector_clipf_c; c->scalarproduct_int16 = scalarproduct_int16_c; c->scalarproduct_and_madd_int16 = scalarproduct_and_madd_int16_c; - c->apply_window_int16 = apply_window_int16_c; c->vector_clip_int32 = vector_clip_int32_c; c->shrink[0]= av_image_copy_plane; @@ -2919,13 +2800,13 @@ av_cold void ff_dsputil_init(DSPContext* c, AVCodecContext *avctx) #define FUNC(f, depth) f ## _ ## depth #define FUNCC(f, depth) f ## _ ## depth ## _c -#define BIT_DEPTH_FUNCS(depth) \ - c->get_pixels = FUNCC(get_pixels, depth); - c->draw_edges = FUNCC(draw_edges, 8); c->clear_block = FUNCC(clear_block, 8); c->clear_blocks = FUNCC(clear_blocks, 8); +#define BIT_DEPTH_FUNCS(depth) \ + c->get_pixels = FUNCC(get_pixels, depth); + switch (avctx->bits_per_raw_sample) { case 9: case 10: @@ -2941,13 +2822,20 @@ av_cold void ff_dsputil_init(DSPContext* c, AVCodecContext *avctx) } - if (HAVE_MMX) ff_dsputil_init_mmx (c, avctx); - if (ARCH_ARM) ff_dsputil_init_arm (c, avctx); - if (HAVE_VIS) ff_dsputil_init_vis (c, avctx); - if (ARCH_ALPHA) ff_dsputil_init_alpha (c, avctx); - if (ARCH_PPC) ff_dsputil_init_ppc (c, avctx); - if (ARCH_SH4) ff_dsputil_init_sh4 (c, avctx); - if (ARCH_BFIN) ff_dsputil_init_bfin (c, avctx); + if (ARCH_ALPHA) + ff_dsputil_init_alpha(c, avctx); + if (ARCH_ARM) + ff_dsputil_init_arm(c, avctx); + if (ARCH_BFIN) + ff_dsputil_init_bfin(c, avctx); + if (ARCH_PPC) + ff_dsputil_init_ppc(c, avctx); + if (ARCH_SH4) + ff_dsputil_init_sh4(c, avctx); + if (HAVE_VIS) + ff_dsputil_init_vis(c, avctx); + if (ARCH_X86) + ff_dsputil_init_x86(c, avctx); ff_init_scantable_permutation(c->idct_permutation, c->idct_permutation_type); @@ -2957,3 +2845,8 @@ av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx) { ff_dsputil_init(c, avctx); } + +av_cold void avpriv_dsputil_init(DSPContext *c, AVCodecContext *avctx) +{ + ff_dsputil_init(c, avctx); +} diff --git a/ffmpeg/libavcodec/dsputil.h b/ffmpeg/libavcodec/dsputil.h index 75017ca..0897c56 100644 --- a/ffmpeg/libavcodec/dsputil.h +++ b/ffmpeg/libavcodec/dsputil.h @@ -34,9 +34,6 @@ #include "avcodec.h" #include "rnd_avg.h" - -//#define DEBUG - /* encoding scans */ extern const uint8_t ff_alternate_horizontal_scan[64]; extern const uint8_t ff_alternate_vertical_scan[64]; @@ -208,11 +205,6 @@ typedef struct DSPContext { void (*bswap_buf)(uint32_t *dst, const uint32_t *src, int w); void (*bswap16_buf)(uint16_t *dst, const uint16_t *src, int len); - void (*h263_v_loop_filter)(uint8_t *src, int stride, int qscale); - void (*h263_h_loop_filter)(uint8_t *src, int stride, int qscale); - - void (*h261_loop_filter)(uint8_t *src, int stride); - /* assume len is a multiple of 8, and arrays are 16-byte aligned */ void (*vector_clipf)(float *dst /* align 16 */, const float *src /* align 16 */, float min, float max, int len /* align 16 */); @@ -282,20 +274,6 @@ typedef struct DSPContext { */ int32_t (*scalarproduct_and_madd_int16)(int16_t *v1/*align 16*/, const int16_t *v2, const int16_t *v3, int len, int mul); - /** - * Apply symmetric window in 16-bit fixed-point. - * @param output destination array - * constraints: 16-byte aligned - * @param input source array - * constraints: 16-byte aligned - * @param window window array - * constraints: 16-byte aligned, at least len/2 elements - * @param len full window length - * constraints: multiple of ? greater than zero - */ - void (*apply_window_int16)(int16_t *output, const int16_t *input, - const int16_t *window, unsigned int len); - /** * Clip each element in an array of int32_t to a given minimum and maximum value. * @param dst destination array @@ -317,6 +295,7 @@ typedef struct DSPContext { void ff_dsputil_static_init(void); void ff_dsputil_init(DSPContext* p, AVCodecContext *avctx); +void avpriv_dsputil_init(DSPContext* p, AVCodecContext *avctx); attribute_deprecated void dsputil_init(DSPContext* c, AVCodecContext *avctx); int ff_check_alignment(void); @@ -326,10 +305,10 @@ void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type); void ff_dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx); void ff_dsputil_init_arm(DSPContext* c, AVCodecContext *avctx); void ff_dsputil_init_bfin(DSPContext* c, AVCodecContext *avctx); -void ff_dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx); void ff_dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx); void ff_dsputil_init_sh4(DSPContext* c, AVCodecContext *avctx); void ff_dsputil_init_vis(DSPContext* c, AVCodecContext *avctx); +void ff_dsputil_init_x86(DSPContext* c, AVCodecContext *avctx); void ff_dsputil_init_dwt(DSPContext *c); diff --git a/ffmpeg/libavcodec/dsputil_template.c b/ffmpeg/libavcodec/dsputil_template.c index 349da7d..96be7a6 100644 --- a/ffmpeg/libavcodec/dsputil_template.c +++ b/ffmpeg/libavcodec/dsputil_template.c @@ -87,9 +87,6 @@ static void FUNCC(clear_block)(int16_t *block) memset(block, 0, sizeof(int16_t)*64); } -/** - * memset(blocks, 0, sizeof(int16_t)*6*64) - */ static void FUNCC(clear_blocks)(int16_t *blocks) { memset(blocks, 0, sizeof(int16_t)*6*64); diff --git a/ffmpeg/libavcodec/dump_extradata_bsf.c b/ffmpeg/libavcodec/dump_extradata_bsf.c index 94b7b42..2dcbf8f 100644 --- a/ffmpeg/libavcodec/dump_extradata_bsf.c +++ b/ffmpeg/libavcodec/dump_extradata_bsf.c @@ -47,7 +47,6 @@ static int dump_extradata(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, } AVBitStreamFilter ff_dump_extradata_bsf={ - "dump_extra", - 0, - dump_extradata, + .name = "dump_extra", + .filter = dump_extradata, }; diff --git a/ffmpeg/libavcodec/dv.c b/ffmpeg/libavcodec/dv.c index 39a87a9..ea05e9d 100644 --- a/ffmpeg/libavcodec/dv.c +++ b/ffmpeg/libavcodec/dv.c @@ -46,7 +46,7 @@ #include "put_bits.h" #include "simple_idct.h" #include "dvdata.h" -#include "dv_tablegen.h" +#include "dv.h" /* XXX: also include quantization */ RL_VLC_ELEM ff_dv_rl_vlc[1184]; @@ -254,20 +254,20 @@ av_cold int ff_dvvideo_init(AVCodecContext *avctx) /* it's faster to include sign bit in a generic VLC parsing scheme */ for (i = 0, j = 0; i < NB_DV_VLC; i++, j++) { - new_dv_vlc_bits[j] = dv_vlc_bits[i]; - new_dv_vlc_len[j] = dv_vlc_len[i]; - new_dv_vlc_run[j] = dv_vlc_run[i]; - new_dv_vlc_level[j] = dv_vlc_level[i]; + new_dv_vlc_bits[j] = ff_dv_vlc_bits[i]; + new_dv_vlc_len[j] = ff_dv_vlc_len[i]; + new_dv_vlc_run[j] = ff_dv_vlc_run[i]; + new_dv_vlc_level[j] = ff_dv_vlc_level[i]; - if (dv_vlc_level[i]) { + if (ff_dv_vlc_level[i]) { new_dv_vlc_bits[j] <<= 1; new_dv_vlc_len[j]++; j++; - new_dv_vlc_bits[j] = (dv_vlc_bits[i] << 1) | 1; - new_dv_vlc_len[j] = dv_vlc_len[i] + 1; - new_dv_vlc_run[j] = dv_vlc_run[i]; - new_dv_vlc_level[j] = -dv_vlc_level[i]; + new_dv_vlc_bits[j] = (ff_dv_vlc_bits[i] << 1) | 1; + new_dv_vlc_len[j] = ff_dv_vlc_len[i] + 1; + new_dv_vlc_run[j] = ff_dv_vlc_run[i]; + new_dv_vlc_level[j] = -ff_dv_vlc_level[i]; } } @@ -320,684 +320,9 @@ av_cold int ff_dvvideo_init(AVCodecContext *avctx) }else memcpy(s->dv_zigzag[1], ff_zigzag248_direct, 64); - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame = &s->picture; s->avctx = avctx; avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT; return 0; } -static av_cold int dvvideo_init_encoder(AVCodecContext *avctx) -{ - if (!avpriv_dv_codec_profile(avctx)) { - av_log(avctx, AV_LOG_ERROR, "Found no DV profile for %ix%i %s video. " - "Valid DV profiles are:\n", - avctx->width, avctx->height, av_get_pix_fmt_name(avctx->pix_fmt)); - ff_dv_print_profiles(avctx, AV_LOG_ERROR); - return AVERROR(EINVAL); - } - if (avctx->height > 576) { - av_log(avctx, AV_LOG_ERROR, "DVCPRO HD encoding is not supported.\n"); - return AVERROR_PATCHWELCOME; - } - - dv_vlc_map_tableinit(); - - return ff_dvvideo_init(avctx); -} - -/* bit budget for AC only in 5 MBs */ -static const int vs_total_ac_bits = (100 * 4 + 68*2) * 5; -static const int mb_area_start[5] = { 1, 6, 21, 43, 64 }; - -static inline int put_bits_left(PutBitContext* s) -{ - return (s->buf_end - s->buf) * 8 - put_bits_count(s); -} - -#if CONFIG_SMALL -/* Converts run and level (where level != 0) pair into VLC, returning bit size */ -static av_always_inline int dv_rl2vlc(int run, int level, int sign, uint32_t* vlc) -{ - int size; - if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) { - *vlc = dv_vlc_map[run][level].vlc | sign; - size = dv_vlc_map[run][level].size; - } - else { - if (level < DV_VLC_MAP_LEV_SIZE) { - *vlc = dv_vlc_map[0][level].vlc | sign; - size = dv_vlc_map[0][level].size; - } else { - *vlc = 0xfe00 | (level << 1) | sign; - size = 16; - } - if (run) { - *vlc |= ((run < 16) ? dv_vlc_map[run-1][0].vlc : - (0x1f80 | (run - 1))) << size; - size += (run < 16) ? dv_vlc_map[run-1][0].size : 13; - } - } - - return size; -} - -static av_always_inline int dv_rl2vlc_size(int run, int level) -{ - int size; - - if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) { - size = dv_vlc_map[run][level].size; - } - else { - size = (level < DV_VLC_MAP_LEV_SIZE) ? dv_vlc_map[0][level].size : 16; - if (run) { - size += (run < 16) ? dv_vlc_map[run-1][0].size : 13; - } - } - return size; -} -#else -static av_always_inline int dv_rl2vlc(int run, int l, int sign, uint32_t* vlc) -{ - *vlc = dv_vlc_map[run][l].vlc | sign; - return dv_vlc_map[run][l].size; -} - -static av_always_inline int dv_rl2vlc_size(int run, int l) -{ - return dv_vlc_map[run][l].size; -} -#endif - -typedef struct EncBlockInfo { - int area_q[4]; - int bit_size[4]; - int prev[5]; - int cur_ac; - int cno; - int dct_mode; - int16_t mb[64]; - uint8_t next[64]; - uint8_t sign[64]; - uint8_t partial_bit_count; - uint32_t partial_bit_buffer; /* we can't use uint16_t here */ -} EncBlockInfo; - -static av_always_inline PutBitContext* dv_encode_ac(EncBlockInfo* bi, - PutBitContext* pb_pool, - PutBitContext* pb_end) -{ - int prev, bits_left; - PutBitContext* pb = pb_pool; - int size = bi->partial_bit_count; - uint32_t vlc = bi->partial_bit_buffer; - - bi->partial_bit_count = bi->partial_bit_buffer = 0; - for (;;){ - /* Find suitable storage space */ - for (; size > (bits_left = put_bits_left(pb)); pb++) { - if (bits_left) { - size -= bits_left; - put_bits(pb, bits_left, vlc >> size); - vlc = vlc & ((1 << size) - 1); - } - if (pb + 1 >= pb_end) { - bi->partial_bit_count = size; - bi->partial_bit_buffer = vlc; - return pb; - } - } - - /* Store VLC */ - put_bits(pb, size, vlc); - - if (bi->cur_ac >= 64) - break; - - /* Construct the next VLC */ - prev = bi->cur_ac; - bi->cur_ac = bi->next[prev]; - if (bi->cur_ac < 64){ - size = dv_rl2vlc(bi->cur_ac - prev - 1, bi->mb[bi->cur_ac], bi->sign[bi->cur_ac], &vlc); - } else { - size = 4; vlc = 6; /* End Of Block stamp */ - } - } - return pb; -} - -static av_always_inline int dv_guess_dct_mode(DVVideoContext *s, uint8_t *data, int linesize) { - if (s->avctx->flags & CODEC_FLAG_INTERLACED_DCT) { - int ps = s->ildct_cmp(NULL, data, NULL, linesize, 8) - 400; - if (ps > 0) { - int is = s->ildct_cmp(NULL, data , NULL, linesize<<1, 4) + - s->ildct_cmp(NULL, data + linesize, NULL, linesize<<1, 4); - return ps > is; - } - } - - return 0; -} - -static const int dv_weight_bits = 18; -static const int dv_weight_88[64] = { - 131072, 257107, 257107, 242189, 252167, 242189, 235923, 237536, - 237536, 235923, 229376, 231390, 223754, 231390, 229376, 222935, - 224969, 217965, 217965, 224969, 222935, 200636, 218652, 211916, - 212325, 211916, 218652, 200636, 188995, 196781, 205965, 206433, - 206433, 205965, 196781, 188995, 185364, 185364, 200636, 200704, - 200636, 185364, 185364, 174609, 180568, 195068, 195068, 180568, - 174609, 170091, 175557, 189591, 175557, 170091, 165371, 170627, - 170627, 165371, 160727, 153560, 160727, 144651, 144651, 136258, -}; -static const int dv_weight_248[64] = { - 131072, 242189, 257107, 237536, 229376, 200636, 242189, 223754, - 224969, 196781, 262144, 242189, 229376, 200636, 257107, 237536, - 211916, 185364, 235923, 217965, 229376, 211916, 206433, 180568, - 242189, 223754, 224969, 196781, 211916, 185364, 235923, 217965, - 200704, 175557, 222935, 205965, 200636, 185364, 195068, 170627, - 229376, 211916, 206433, 180568, 200704, 175557, 222935, 205965, - 175557, 153560, 188995, 174609, 165371, 144651, 200636, 185364, - 195068, 170627, 175557, 153560, 188995, 174609, 165371, 144651, -}; - -static av_always_inline int dv_init_enc_block(EncBlockInfo* bi, uint8_t *data, int linesize, DVVideoContext *s, int bias) -{ - const int *weight; - const uint8_t* zigzag_scan; - LOCAL_ALIGNED_16(int16_t, blk, [64]); - int i, area; - /* We offer two different methods for class number assignment: the - method suggested in SMPTE 314M Table 22, and an improved - method. The SMPTE method is very conservative; it assigns class - 3 (i.e. severe quantization) to any block where the largest AC - component is greater than 36. FFmpeg's DV encoder tracks AC bit - consumption precisely, so there is no need to bias most blocks - towards strongly lossy compression. Instead, we assign class 2 - to most blocks, and use class 3 only when strictly necessary - (for blocks whose largest AC component exceeds 255). */ - -#if 0 /* SMPTE spec method */ - static const int classes[] = {12, 24, 36, 0xffff}; -#else /* improved FFmpeg method */ - static const int classes[] = {-1, -1, 255, 0xffff}; -#endif - int max = classes[0]; - int prev = 0; - - av_assert2((((int)blk) & 15) == 0); - - bi->area_q[0] = bi->area_q[1] = bi->area_q[2] = bi->area_q[3] = 0; - bi->partial_bit_count = 0; - bi->partial_bit_buffer = 0; - bi->cur_ac = 0; - if (data) { - bi->dct_mode = dv_guess_dct_mode(s, data, linesize); - s->get_pixels(blk, data, linesize); - s->fdct[bi->dct_mode](blk); - } else { - /* We rely on the fact that encoding all zeros leads to an immediate EOB, - which is precisely what the spec calls for in the "dummy" blocks. */ - memset(blk, 0, 64*sizeof(*blk)); - bi->dct_mode = 0; - } - bi->mb[0] = blk[0]; - - zigzag_scan = bi->dct_mode ? ff_zigzag248_direct : ff_zigzag_direct; - weight = bi->dct_mode ? dv_weight_248 : dv_weight_88; - - for (area = 0; area < 4; area++) { - bi->prev[area] = prev; - bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :) - for (i = mb_area_start[area]; i < mb_area_start[area+1]; i++) { - int level = blk[zigzag_scan[i]]; - - if (level + 15 > 30U) { - bi->sign[i] = (level >> 31) & 1; - /* weight it and and shift down into range, adding for rounding */ - /* the extra division by a factor of 2^4 reverses the 8x expansion of the DCT - AND the 2x doubling of the weights */ - level = (FFABS(level) * weight[i] + (1 << (dv_weight_bits+3))) >> (dv_weight_bits+4); - bi->mb[i] = level; - if (level > max) - max = level; - bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, level); - bi->next[prev]= i; - prev = i; - } - } - } - bi->next[prev]= i; - for (bi->cno = 0; max > classes[bi->cno]; bi->cno++); - - bi->cno += bias; - - if (bi->cno >= 3) { - bi->cno = 3; - prev = 0; - i = bi->next[prev]; - for (area = 0; area < 4; area++) { - bi->prev[area] = prev; - bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :) - for (; i < mb_area_start[area+1]; i = bi->next[i]) { - bi->mb[i] >>= 1; - - if (bi->mb[i]) { - bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, bi->mb[i]); - bi->next[prev]= i; - prev = i; - } - } - } - bi->next[prev]= i; - } - - return bi->bit_size[0] + bi->bit_size[1] + bi->bit_size[2] + bi->bit_size[3]; -} - -static inline void dv_guess_qnos(EncBlockInfo* blks, int* qnos) -{ - int size[5]; - int i, j, k, a, prev, a2; - EncBlockInfo* b; - - size[0] = size[1] = size[2] = size[3] = size[4] = 1 << 24; - do { - b = blks; - for (i = 0; i < 5; i++) { - if (!qnos[i]) - continue; - - qnos[i]--; - size[i] = 0; - for (j = 0; j < 6; j++, b++) { - for (a = 0; a < 4; a++) { - if (b->area_q[a] != ff_dv_quant_shifts[qnos[i] + ff_dv_quant_offset[b->cno]][a]) { - b->bit_size[a] = 1; // 4 areas 4 bits for EOB :) - b->area_q[a]++; - prev = b->prev[a]; - av_assert2(b->next[prev] >= mb_area_start[a+1] || b->mb[prev]); - for (k = b->next[prev] ; k < mb_area_start[a+1]; k = b->next[k]) { - b->mb[k] >>= 1; - if (b->mb[k]) { - b->bit_size[a] += dv_rl2vlc_size(k - prev - 1, b->mb[k]); - prev = k; - } else { - if (b->next[k] >= mb_area_start[a+1] && b->next[k]<64){ - for (a2 = a + 1; b->next[k] >= mb_area_start[a2+1]; a2++) - b->prev[a2] = prev; - av_assert2(a2 < 4); - av_assert2(b->mb[b->next[k]]); - b->bit_size[a2] += dv_rl2vlc_size(b->next[k] - prev - 1, b->mb[b->next[k]]) - -dv_rl2vlc_size(b->next[k] - k - 1, b->mb[b->next[k]]); - av_assert2(b->prev[a2] == k && (a2 + 1 >= 4 || b->prev[a2+1] != k)); - b->prev[a2] = prev; - } - b->next[prev] = b->next[k]; - } - } - b->prev[a+1]= prev; - } - size[i] += b->bit_size[a]; - } - } - if (vs_total_ac_bits >= size[0] + size[1] + size[2] + size[3] + size[4]) - return; - } - } while (qnos[0]|qnos[1]|qnos[2]|qnos[3]|qnos[4]); - - - for (a = 2; a == 2 || vs_total_ac_bits < size[0]; a += a){ - b = blks; - size[0] = 5 * 6 * 4; //EOB - for (j = 0; j < 6 *5; j++, b++) { - prev = b->prev[0]; - for (k = b->next[prev]; k < 64; k = b->next[k]) { - if (b->mb[k] < a && b->mb[k] > -a){ - b->next[prev] = b->next[k]; - }else{ - size[0] += dv_rl2vlc_size(k - prev - 1, b->mb[k]); - prev = k; - } - } - } - } -} - -static int dv_encode_video_segment(AVCodecContext *avctx, void *arg) -{ - DVVideoContext *s = avctx->priv_data; - DVwork_chunk *work_chunk = arg; - int mb_index, i, j; - int mb_x, mb_y, c_offset, linesize, y_stride; - uint8_t* y_ptr; - uint8_t* dif; - LOCAL_ALIGNED_8(uint8_t, scratch, [128]); - EncBlockInfo enc_blks[5*DV_MAX_BPM]; - PutBitContext pbs[5*DV_MAX_BPM]; - PutBitContext* pb; - EncBlockInfo* enc_blk; - int vs_bit_size = 0; - int qnos[5] = {15, 15, 15, 15, 15}; /* No quantization */ - int* qnosp = &qnos[0]; - - dif = &s->buf[work_chunk->buf_offset*80]; - enc_blk = &enc_blks[0]; - for (mb_index = 0; mb_index < 5; mb_index++) { - dv_calculate_mb_xy(s, work_chunk, mb_index, &mb_x, &mb_y); - - /* initializing luminance blocks */ - if ((s->sys->pix_fmt == AV_PIX_FMT_YUV420P) || - (s->sys->pix_fmt == AV_PIX_FMT_YUV411P && mb_x >= (704 / 8)) || - (s->sys->height >= 720 && mb_y != 134)) { - y_stride = s->picture.linesize[0] << 3; - } else { - y_stride = 16; - } - y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x) << 3); - linesize = s->picture.linesize[0]; - - if (s->sys->video_stype == 4) { /* SD 422 */ - vs_bit_size += - dv_init_enc_block(enc_blk+0, y_ptr , linesize, s, 0) + - dv_init_enc_block(enc_blk+1, NULL , linesize, s, 0) + - dv_init_enc_block(enc_blk+2, y_ptr + 8 , linesize, s, 0) + - dv_init_enc_block(enc_blk+3, NULL , linesize, s, 0); - } else { - vs_bit_size += - dv_init_enc_block(enc_blk+0, y_ptr , linesize, s, 0) + - dv_init_enc_block(enc_blk+1, y_ptr + 8 , linesize, s, 0) + - dv_init_enc_block(enc_blk+2, y_ptr + y_stride, linesize, s, 0) + - dv_init_enc_block(enc_blk+3, y_ptr + 8 + y_stride, linesize, s, 0); - } - enc_blk += 4; - - /* initializing chrominance blocks */ - c_offset = (((mb_y >> (s->sys->pix_fmt == AV_PIX_FMT_YUV420P)) * s->picture.linesize[1] + - (mb_x >> ((s->sys->pix_fmt == AV_PIX_FMT_YUV411P) ? 2 : 1))) << 3); - for (j = 2; j; j--) { - uint8_t *c_ptr = s->picture.data[j] + c_offset; - linesize = s->picture.linesize[j]; - y_stride = (mb_y == 134) ? 8 : (s->picture.linesize[j] << 3); - if (s->sys->pix_fmt == AV_PIX_FMT_YUV411P && mb_x >= (704 / 8)) { - uint8_t* d; - uint8_t* b = scratch; - for (i = 0; i < 8; i++) { - d = c_ptr + (linesize << 3); - b[0] = c_ptr[0]; b[1] = c_ptr[1]; b[2] = c_ptr[2]; b[3] = c_ptr[3]; - b[4] = d[0]; b[5] = d[1]; b[6] = d[2]; b[7] = d[3]; - c_ptr += linesize; - b += 16; - } - c_ptr = scratch; - linesize = 16; - } - - vs_bit_size += dv_init_enc_block( enc_blk++, c_ptr , linesize, s, 1); - if (s->sys->bpm == 8) { - vs_bit_size += dv_init_enc_block(enc_blk++, c_ptr + y_stride, linesize, s, 1); - } - } - } - - if (vs_total_ac_bits < vs_bit_size) - dv_guess_qnos(&enc_blks[0], qnosp); - - /* DIF encoding process */ - for (j=0; j<5*s->sys->bpm;) { - int start_mb = j; - - dif[3] = *qnosp++; - dif += 4; - - /* First pass over individual cells only */ - for (i=0; isys->bpm; i++, j++) { - int sz = s->sys->block_sizes[i]>>3; - - init_put_bits(&pbs[j], dif, sz); - put_sbits(&pbs[j], 9, ((enc_blks[j].mb[0] >> 3) - 1024 + 2) >> 2); - put_bits(&pbs[j], 1, enc_blks[j].dct_mode); - put_bits(&pbs[j], 2, enc_blks[j].cno); - - dv_encode_ac(&enc_blks[j], &pbs[j], &pbs[j+1]); - dif += sz; - } - - /* Second pass over each MB space */ - pb = &pbs[start_mb]; - for (i=0; isys->bpm; i++) { - if (enc_blks[start_mb+i].partial_bit_count) - pb = dv_encode_ac(&enc_blks[start_mb+i], pb, &pbs[start_mb+s->sys->bpm]); - } - } - - /* Third and final pass over the whole video segment space */ - pb = &pbs[0]; - for (j=0; j<5*s->sys->bpm; j++) { - if (enc_blks[j].partial_bit_count) - pb = dv_encode_ac(&enc_blks[j], pb, &pbs[s->sys->bpm*5]); - if (enc_blks[j].partial_bit_count) - av_log(avctx, AV_LOG_ERROR, "ac bitstream overflow\n"); - } - - for (j=0; j<5*s->sys->bpm; j++) { - int pos; - int size = pbs[j].size_in_bits >> 3; - flush_put_bits(&pbs[j]); - pos = put_bits_count(&pbs[j]) >> 3; - if (pos > size) { - av_log(avctx, AV_LOG_ERROR, "bitstream written beyond buffer size\n"); - return -1; - } - memset(pbs[j].buf + pos, 0xff, size - pos); - } - - return 0; -} - -static inline int dv_write_pack(enum dv_pack_type pack_id, DVVideoContext *c, - uint8_t* buf) -{ - /* - * Here's what SMPTE314M says about these two: - * (page 6) APTn, AP1n, AP2n, AP3n: These data shall be identical - * as track application IDs (APTn = 001, AP1n = - * 001, AP2n = 001, AP3n = 001), if the source signal - * comes from a digital VCR. If the signal source is - * unknown, all bits for these data shall be set to 1. - * (page 12) STYPE: STYPE defines a signal type of video signal - * 00000b = 4:1:1 compression - * 00100b = 4:2:2 compression - * XXXXXX = Reserved - * Now, I've got two problems with these statements: - * 1. it looks like APT == 111b should be a safe bet, but it isn't. - * It seems that for PAL as defined in IEC 61834 we have to set - * APT to 000 and for SMPTE314M to 001. - * 2. It is not at all clear what STYPE is used for 4:2:0 PAL - * compression scheme (if any). - */ - int apt = (c->sys->pix_fmt == AV_PIX_FMT_YUV420P ? 0 : 1); - int fs = c->picture.top_field_first ? 0x00 : 0x40; - - uint8_t aspect = 0; - if ((int)(av_q2d(c->avctx->sample_aspect_ratio) * c->avctx->width / c->avctx->height * 10) >= 17) /* 16:9 */ - aspect = 0x02; - - buf[0] = (uint8_t)pack_id; - switch (pack_id) { - case dv_header525: /* I can't imagine why these two weren't defined as real */ - case dv_header625: /* packs in SMPTE314M -- they definitely look like ones */ - buf[1] = 0xf8 | /* reserved -- always 1 */ - (apt & 0x07); /* APT: Track application ID */ - buf[2] = (0 << 7) | /* TF1: audio data is 0 - valid; 1 - invalid */ - (0x0f << 3) | /* reserved -- always 1 */ - (apt & 0x07); /* AP1: Audio application ID */ - buf[3] = (0 << 7) | /* TF2: video data is 0 - valid; 1 - invalid */ - (0x0f << 3) | /* reserved -- always 1 */ - (apt & 0x07); /* AP2: Video application ID */ - buf[4] = (0 << 7) | /* TF3: subcode(SSYB) is 0 - valid; 1 - invalid */ - (0x0f << 3) | /* reserved -- always 1 */ - (apt & 0x07); /* AP3: Subcode application ID */ - break; - case dv_video_source: - buf[1] = 0xff; /* reserved -- always 1 */ - buf[2] = (1 << 7) | /* B/W: 0 - b/w, 1 - color */ - (1 << 6) | /* following CLF is valid - 0, invalid - 1 */ - (3 << 4) | /* CLF: color frames ID (see ITU-R BT.470-4) */ - 0xf; /* reserved -- always 1 */ - buf[3] = (3 << 6) | /* reserved -- always 1 */ - (c->sys->dsf << 5) | /* system: 60fields/50fields */ - c->sys->video_stype; /* signal type video compression */ - buf[4] = 0xff; /* VISC: 0xff -- no information */ - break; - case dv_video_control: - buf[1] = (0 << 6) | /* Copy generation management (CGMS) 0 -- free */ - 0x3f; /* reserved -- always 1 */ - buf[2] = 0xc8 | /* reserved -- always b11001xxx */ - aspect; - buf[3] = (1 << 7) | /* frame/field flag 1 -- frame, 0 -- field */ - fs | /* first/second field flag 0 -- field 2, 1 -- field 1 */ - (1 << 5) | /* frame change flag 0 -- same picture as before, 1 -- different */ - (1 << 4) | /* 1 - interlaced, 0 - noninterlaced */ - 0xc; /* reserved -- always b1100 */ - buf[4] = 0xff; /* reserved -- always 1 */ - break; - default: - buf[1] = buf[2] = buf[3] = buf[4] = 0xff; - } - return 5; -} - -#if CONFIG_DVVIDEO_ENCODER -static inline int dv_write_dif_id(enum dv_section_type t, uint8_t chan_num, - uint8_t seq_num, uint8_t dif_num, - uint8_t* buf) -{ - buf[0] = (uint8_t)t; /* Section type */ - buf[1] = (seq_num << 4) | /* DIF seq number 0-9 for 525/60; 0-11 for 625/50 */ - (chan_num << 3) | /* FSC: for 50Mb/s 0 - first channel; 1 - second */ - 7; /* reserved -- always 1 */ - buf[2] = dif_num; /* DIF block number Video: 0-134, Audio: 0-8 */ - return 3; -} - - -static inline int dv_write_ssyb_id(uint8_t syb_num, uint8_t fr, uint8_t* buf) -{ - if (syb_num == 0 || syb_num == 6) { - buf[0] = (fr << 7) | /* FR ID 1 - first half of each channel; 0 - second */ - (0 << 4) | /* AP3 (Subcode application ID) */ - 0x0f; /* reserved -- always 1 */ - } - else if (syb_num == 11) { - buf[0] = (fr << 7) | /* FR ID 1 - first half of each channel; 0 - second */ - 0x7f; /* reserved -- always 1 */ - } - else { - buf[0] = (fr << 7) | /* FR ID 1 - first half of each channel; 0 - second */ - (0 << 4) | /* APT (Track application ID) */ - 0x0f; /* reserved -- always 1 */ - } - buf[1] = 0xf0 | /* reserved -- always 1 */ - (syb_num & 0x0f); /* SSYB number 0 - 11 */ - buf[2] = 0xff; /* reserved -- always 1 */ - return 3; -} - -static void dv_format_frame(DVVideoContext* c, uint8_t* buf) -{ - int chan, i, j, k; - - for (chan = 0; chan < c->sys->n_difchan; chan++) { - for (i = 0; i < c->sys->difseg_size; i++) { - memset(buf, 0xff, 80 * 6); /* first 6 DIF blocks are for control data */ - - /* DV header: 1DIF */ - buf += dv_write_dif_id(dv_sect_header, chan, i, 0, buf); - buf += dv_write_pack((c->sys->dsf ? dv_header625 : dv_header525), c, buf); - buf += 72; /* unused bytes */ - - /* DV subcode: 2DIFs */ - for (j = 0; j < 2; j++) { - buf += dv_write_dif_id(dv_sect_subcode, chan, i, j, buf); - for (k = 0; k < 6; k++) - buf += dv_write_ssyb_id(k, (i < c->sys->difseg_size/2), buf) + 5; - buf += 29; /* unused bytes */ - } - - /* DV VAUX: 3DIFS */ - for (j = 0; j < 3; j++) { - buf += dv_write_dif_id(dv_sect_vaux, chan, i, j, buf); - buf += dv_write_pack(dv_video_source, c, buf); - buf += dv_write_pack(dv_video_control, c, buf); - buf += 7*5; - buf += dv_write_pack(dv_video_source, c, buf); - buf += dv_write_pack(dv_video_control, c, buf); - buf += 4*5 + 2; /* unused bytes */ - } - - /* DV Audio/Video: 135 Video DIFs + 9 Audio DIFs */ - for (j = 0; j < 135; j++) { - if (j%15 == 0) { - memset(buf, 0xff, 80); - buf += dv_write_dif_id(dv_sect_audio, chan, i, j/15, buf); - buf += 77; /* audio control & shuffled PCM audio */ - } - buf += dv_write_dif_id(dv_sect_video, chan, i, j, buf); - buf += 77; /* 1 video macroblock: 1 bytes control - 4 * 14 bytes Y 8x8 data - 10 bytes Cr 8x8 data - 10 bytes Cb 8x8 data */ - } - } - } -} - - -static int dvvideo_encode_frame(AVCodecContext *c, AVPacket *pkt, - const AVFrame *frame, int *got_packet) -{ - DVVideoContext *s = c->priv_data; - int ret; - - s->sys = avpriv_dv_codec_profile(c); - if (!s->sys || ff_dv_init_dynamic_tables(s->sys)) - return -1; - if ((ret = ff_alloc_packet2(c, pkt, s->sys->frame_size)) < 0) - return ret; - - c->pix_fmt = s->sys->pix_fmt; - s->picture = *frame; - s->picture.key_frame = 1; - s->picture.pict_type = AV_PICTURE_TYPE_I; - - s->buf = pkt->data; - c->execute(c, dv_encode_video_segment, s->sys->work_chunks, NULL, - dv_work_pool_size(s->sys), sizeof(DVwork_chunk)); - - emms_c(); - - dv_format_frame(s, pkt->data); - - pkt->flags |= AV_PKT_FLAG_KEY; - *got_packet = 1; - - return 0; -} - -AVCodec ff_dvvideo_encoder = { - .name = "dvvideo", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_DVVIDEO, - .priv_data_size = sizeof(DVVideoContext), - .init = dvvideo_init_encoder, - .encode2 = dvvideo_encode_frame, - .capabilities = CODEC_CAP_SLICE_THREADS, - .pix_fmts = (const enum AVPixelFormat[]) { - AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE - }, - .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"), -}; -#endif // CONFIG_DVVIDEO_ENCODER diff --git a/ffmpeg/libavcodec/dv_profile.c b/ffmpeg/libavcodec/dv_profile.c index a1d9881..e73af29 100644 --- a/ffmpeg/libavcodec/dv_profile.c +++ b/ffmpeg/libavcodec/dv_profile.c @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/dv_profile.h b/ffmpeg/libavcodec/dv_profile.h index 97edce9..8f0faf3 100644 --- a/ffmpeg/libavcodec/dv_profile.h +++ b/ffmpeg/libavcodec/dv_profile.h @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/dv_tablegen.c b/ffmpeg/libavcodec/dv_tablegen.c index 5d3793e..2579341 100644 --- a/ffmpeg/libavcodec/dv_tablegen.c +++ b/ffmpeg/libavcodec/dv_tablegen.c @@ -22,9 +22,6 @@ #include #define CONFIG_HARDCODED_TABLES 0 -#ifndef CONFIG_SMALL -#error CONFIG_SMALL must be defined to generate tables -#endif #include "dv_tablegen.h" #include "tableprint.h" #include diff --git a/ffmpeg/libavcodec/dv_tablegen.h b/ffmpeg/libavcodec/dv_tablegen.h index e8cdc21..c04b802 100644 --- a/ffmpeg/libavcodec/dv_tablegen.h +++ b/ffmpeg/libavcodec/dv_tablegen.h @@ -25,7 +25,7 @@ #include -#include "dv_vlc_data.h" +#include "dvdata.h" #if CONFIG_SMALL #define DV_VLC_MAP_RUN_SIZE 15 @@ -51,20 +51,20 @@ static void dv_vlc_map_tableinit(void) { int i, j; for (i = 0; i < NB_DV_VLC - 1; i++) { - if (dv_vlc_run[i] >= DV_VLC_MAP_RUN_SIZE) + if (ff_dv_vlc_run[i] >= DV_VLC_MAP_RUN_SIZE) continue; #if CONFIG_SMALL - if (dv_vlc_level[i] >= DV_VLC_MAP_LEV_SIZE) + if (ff_dv_vlc_level[i] >= DV_VLC_MAP_LEV_SIZE) continue; #endif - if (dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].size != 0) + if (dv_vlc_map[ff_dv_vlc_run[i]][ff_dv_vlc_level[i]].size != 0) continue; - dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].vlc = - dv_vlc_bits[i] << (!!dv_vlc_level[i]); - dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].size = - dv_vlc_len[i] + (!!dv_vlc_level[i]); + dv_vlc_map[ff_dv_vlc_run[i]][ff_dv_vlc_level[i]].vlc = + ff_dv_vlc_bits[i] << (!!ff_dv_vlc_level[i]); + dv_vlc_map[ff_dv_vlc_run[i]][ff_dv_vlc_level[i]].size = + ff_dv_vlc_len[i] + (!!ff_dv_vlc_level[i]); } for (i = 0; i < DV_VLC_MAP_RUN_SIZE; i++) { #if CONFIG_SMALL diff --git a/ffmpeg/libavcodec/dv_vlc_data.h b/ffmpeg/libavcodec/dv_vlc_data.h deleted file mode 100644 index be768e6..0000000 --- a/ffmpeg/libavcodec/dv_vlc_data.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - * VLC constants for DV codec - * Copyright (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * VLC constants for DV codec. - */ - -#ifndef AVCODEC_DV_VLC_DATA_H -#define AVCODEC_DV_VLC_DATA_H - -#include - -#define NB_DV_VLC 409 - -/* - * There's a catch about the following three tables: the mapping they establish - * between (run, level) and vlc is not 1-1. So you have to watch out for that - * when building misc. tables. E.g. (1, 0) can be either 0x7cf or 0x1f82. - */ -static const uint16_t dv_vlc_bits[NB_DV_VLC] = { - 0x0000, 0x0002, 0x0007, 0x0008, 0x0009, 0x0014, 0x0015, 0x0016, - 0x0017, 0x0030, 0x0031, 0x0032, 0x0033, 0x0068, 0x0069, 0x006a, - 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x00e0, 0x00e1, 0x00e2, - 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, - 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x01e0, 0x01e1, 0x01e2, - 0x01e3, 0x01e4, 0x01e5, 0x01e6, 0x01e7, 0x01e8, 0x01e9, 0x01ea, - 0x01eb, 0x01ec, 0x01ed, 0x01ee, 0x01ef, 0x03e0, 0x03e1, 0x03e2, - 0x03e3, 0x03e4, 0x03e5, 0x03e6, 0x07ce, 0x07cf, 0x07d0, 0x07d1, - 0x07d2, 0x07d3, 0x07d4, 0x07d5, 0x0fac, 0x0fad, 0x0fae, 0x0faf, - 0x0fb0, 0x0fb1, 0x0fb2, 0x0fb3, 0x0fb4, 0x0fb5, 0x0fb6, 0x0fb7, - 0x0fb8, 0x0fb9, 0x0fba, 0x0fbb, 0x0fbc, 0x0fbd, 0x0fbe, 0x0fbf, - 0x1f80, 0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86, 0x1f87, - 0x1f88, 0x1f89, 0x1f8a, 0x1f8b, 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f, - 0x1f90, 0x1f91, 0x1f92, 0x1f93, 0x1f94, 0x1f95, 0x1f96, 0x1f97, - 0x1f98, 0x1f99, 0x1f9a, 0x1f9b, 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f, - 0x1fa0, 0x1fa1, 0x1fa2, 0x1fa3, 0x1fa4, 0x1fa5, 0x1fa6, 0x1fa7, - 0x1fa8, 0x1fa9, 0x1faa, 0x1fab, 0x1fac, 0x1fad, 0x1fae, 0x1faf, - 0x1fb0, 0x1fb1, 0x1fb2, 0x1fb3, 0x1fb4, 0x1fb5, 0x1fb6, 0x1fb7, - 0x1fb8, 0x1fb9, 0x1fba, 0x1fbb, 0x1fbc, 0x1fbd, 0x1fbe, 0x1fbf, - 0x7f00, 0x7f01, 0x7f02, 0x7f03, 0x7f04, 0x7f05, 0x7f06, 0x7f07, - 0x7f08, 0x7f09, 0x7f0a, 0x7f0b, 0x7f0c, 0x7f0d, 0x7f0e, 0x7f0f, - 0x7f10, 0x7f11, 0x7f12, 0x7f13, 0x7f14, 0x7f15, 0x7f16, 0x7f17, - 0x7f18, 0x7f19, 0x7f1a, 0x7f1b, 0x7f1c, 0x7f1d, 0x7f1e, 0x7f1f, - 0x7f20, 0x7f21, 0x7f22, 0x7f23, 0x7f24, 0x7f25, 0x7f26, 0x7f27, - 0x7f28, 0x7f29, 0x7f2a, 0x7f2b, 0x7f2c, 0x7f2d, 0x7f2e, 0x7f2f, - 0x7f30, 0x7f31, 0x7f32, 0x7f33, 0x7f34, 0x7f35, 0x7f36, 0x7f37, - 0x7f38, 0x7f39, 0x7f3a, 0x7f3b, 0x7f3c, 0x7f3d, 0x7f3e, 0x7f3f, - 0x7f40, 0x7f41, 0x7f42, 0x7f43, 0x7f44, 0x7f45, 0x7f46, 0x7f47, - 0x7f48, 0x7f49, 0x7f4a, 0x7f4b, 0x7f4c, 0x7f4d, 0x7f4e, 0x7f4f, - 0x7f50, 0x7f51, 0x7f52, 0x7f53, 0x7f54, 0x7f55, 0x7f56, 0x7f57, - 0x7f58, 0x7f59, 0x7f5a, 0x7f5b, 0x7f5c, 0x7f5d, 0x7f5e, 0x7f5f, - 0x7f60, 0x7f61, 0x7f62, 0x7f63, 0x7f64, 0x7f65, 0x7f66, 0x7f67, - 0x7f68, 0x7f69, 0x7f6a, 0x7f6b, 0x7f6c, 0x7f6d, 0x7f6e, 0x7f6f, - 0x7f70, 0x7f71, 0x7f72, 0x7f73, 0x7f74, 0x7f75, 0x7f76, 0x7f77, - 0x7f78, 0x7f79, 0x7f7a, 0x7f7b, 0x7f7c, 0x7f7d, 0x7f7e, 0x7f7f, - 0x7f80, 0x7f81, 0x7f82, 0x7f83, 0x7f84, 0x7f85, 0x7f86, 0x7f87, - 0x7f88, 0x7f89, 0x7f8a, 0x7f8b, 0x7f8c, 0x7f8d, 0x7f8e, 0x7f8f, - 0x7f90, 0x7f91, 0x7f92, 0x7f93, 0x7f94, 0x7f95, 0x7f96, 0x7f97, - 0x7f98, 0x7f99, 0x7f9a, 0x7f9b, 0x7f9c, 0x7f9d, 0x7f9e, 0x7f9f, - 0x7fa0, 0x7fa1, 0x7fa2, 0x7fa3, 0x7fa4, 0x7fa5, 0x7fa6, 0x7fa7, - 0x7fa8, 0x7fa9, 0x7faa, 0x7fab, 0x7fac, 0x7fad, 0x7fae, 0x7faf, - 0x7fb0, 0x7fb1, 0x7fb2, 0x7fb3, 0x7fb4, 0x7fb5, 0x7fb6, 0x7fb7, - 0x7fb8, 0x7fb9, 0x7fba, 0x7fbb, 0x7fbc, 0x7fbd, 0x7fbe, 0x7fbf, - 0x7fc0, 0x7fc1, 0x7fc2, 0x7fc3, 0x7fc4, 0x7fc5, 0x7fc6, 0x7fc7, - 0x7fc8, 0x7fc9, 0x7fca, 0x7fcb, 0x7fcc, 0x7fcd, 0x7fce, 0x7fcf, - 0x7fd0, 0x7fd1, 0x7fd2, 0x7fd3, 0x7fd4, 0x7fd5, 0x7fd6, 0x7fd7, - 0x7fd8, 0x7fd9, 0x7fda, 0x7fdb, 0x7fdc, 0x7fdd, 0x7fde, 0x7fdf, - 0x7fe0, 0x7fe1, 0x7fe2, 0x7fe3, 0x7fe4, 0x7fe5, 0x7fe6, 0x7fe7, - 0x7fe8, 0x7fe9, 0x7fea, 0x7feb, 0x7fec, 0x7fed, 0x7fee, 0x7fef, - 0x7ff0, 0x7ff1, 0x7ff2, 0x7ff3, 0x7ff4, 0x7ff5, 0x7ff6, 0x7ff7, - 0x7ff8, 0x7ff9, 0x7ffa, 0x7ffb, 0x7ffc, 0x7ffd, 0x7ffe, 0x7fff, - 0x0006, -}; - -static const uint8_t dv_vlc_len[NB_DV_VLC] = { - 2, 3, 4, 4, 4, 5, 5, 5, - 5, 6, 6, 6, 6, 7, 7, 7, - 7, 7, 7, 7, 7, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 10, 10, 10, - 10, 10, 10, 10, 11, 11, 11, 11, - 11, 11, 11, 11, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 4, -}; - -static const uint8_t dv_vlc_run[NB_DV_VLC] = { - 0, 0, 1, 0, 0, 2, 1, 0, - 0, 3, 4, 0, 0, 5, 6, 2, - 1, 1, 0, 0, 0, 7, 8, 9, - 10, 3, 4, 2, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 11, 12, 13, - 14, 5, 6, 3, 4, 2, 2, 1, - 0, 0, 0, 0, 0, 5, 3, 3, - 2, 1, 1, 1, 0, 1, 6, 4, - 3, 1, 1, 1, 2, 3, 4, 5, - 7, 8, 9, 10, 7, 8, 4, 3, - 2, 2, 2, 2, 2, 1, 1, 1, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -127, -}; - -static const uint8_t dv_vlc_level[NB_DV_VLC] = { - 1, 2, 1, 3, 4, 1, 2, 5, - 6, 1, 1, 7, 8, 1, 1, 2, - 3, 4, 9, 10, 11, 1, 1, 1, - 1, 2, 2, 3, 5, 6, 7, 12, - 13, 14, 15, 16, 17, 1, 1, 1, - 1, 2, 2, 3, 3, 4, 5, 8, - 18, 19, 20, 21, 22, 3, 4, 5, - 6, 9, 10, 11, 0, 0, 3, 4, - 6, 12, 13, 14, 0, 0, 0, 0, - 2, 2, 2, 2, 3, 3, 5, 7, - 7, 8, 9, 10, 11, 15, 16, 17, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, - 184, 185, 186, 187, 188, 189, 190, 191, - 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 214, 215, - 216, 217, 218, 219, 220, 221, 222, 223, - 224, 225, 226, 227, 228, 229, 230, 231, - 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 253, 254, 255, - 0, -}; - -#endif /* AVCODEC_DV_VLC_DATA_H */ diff --git a/ffmpeg/libavcodec/dvbsub.c b/ffmpeg/libavcodec/dvbsub.c index 562db6a..f30b767 100644 --- a/ffmpeg/libavcodec/dvbsub.c +++ b/ffmpeg/libavcodec/dvbsub.c @@ -456,9 +456,9 @@ static int dvbsub_encode(AVCodecContext *avctx, AVCodec ff_dvbsub_encoder = { .name = "dvbsub", + .long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"), .type = AVMEDIA_TYPE_SUBTITLE, .id = AV_CODEC_ID_DVB_SUBTITLE, .priv_data_size = sizeof(DVBSubtitleContext), .encode_sub = dvbsub_encode, - .long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"), }; diff --git a/ffmpeg/libavcodec/dvbsubdec.c b/ffmpeg/libavcodec/dvbsubdec.c index 955925a..8f4e984 100644 --- a/ffmpeg/libavcodec/dvbsubdec.c +++ b/ffmpeg/libavcodec/dvbsubdec.c @@ -34,8 +34,6 @@ #define cm (ff_cropTbl + MAX_NEG_CROP) #ifdef DEBUG -#undef fprintf -#undef perror #if 0 static void png_save(const char *filename, uint8_t *bitmap, int w, int h, uint32_t *rgba_palette) @@ -933,7 +931,7 @@ static void dvbsub_parse_object_segment(AVCodecContext *avctx, } -static void dvbsub_parse_clut_segment(AVCodecContext *avctx, +static int dvbsub_parse_clut_segment(AVCodecContext *avctx, const uint8_t *buf, int buf_size) { DVBSubContext *ctx = avctx->priv_data; @@ -986,7 +984,7 @@ static void dvbsub_parse_clut_segment(AVCodecContext *avctx, if (depth == 0) { av_log(avctx, AV_LOG_ERROR, "Invalid clut depth 0x%x!\n", *buf); - return; + return 0; } full_range = (*buf++) & 1; @@ -1012,15 +1010,21 @@ static void dvbsub_parse_clut_segment(AVCodecContext *avctx, YUV_TO_RGB2_CCIR(r, g, b, y); av_dlog(avctx, "clut %d := (%d,%d,%d,%d)\n", entry_id, r, g, b, alpha); + if (!!(depth & 0x80) + !!(depth & 0x40) + !!(depth & 0x20) > 1) { + av_dlog(avctx, "More than one bit level marked: %x\n", depth); + if (avctx->strict_std_compliance > FF_COMPLIANCE_NORMAL) + return AVERROR_INVALIDDATA; + } if (depth & 0x80) clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha); - if (depth & 0x40) + else if (depth & 0x40) clut->clut16[entry_id] = RGBA(r,g,b,255 - alpha); - if (depth & 0x20) + else if (depth & 0x20) clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha); } } + return 0; } @@ -1353,8 +1357,8 @@ static void dvbsub_parse_display_definition_segment(AVCodecContext *avctx, if (info_byte & 1<<3) { // display_window_flag display_def->x = bytestream_get_be16(&buf); - display_def->y = bytestream_get_be16(&buf); display_def->width = bytestream_get_be16(&buf) - display_def->x + 1; + display_def->y = bytestream_get_be16(&buf); display_def->height = bytestream_get_be16(&buf) - display_def->y + 1; } } @@ -1456,6 +1460,7 @@ static int dvbsub_decode(AVCodecContext *avctx, int page_id; int segment_length; int i; + int ret; int got_segment = 0; av_dlog(avctx, "DVB sub packet:\n"); @@ -1502,7 +1507,8 @@ static int dvbsub_decode(AVCodecContext *avctx, got_segment |= 2; break; case DVBSUB_CLUT_SEGMENT: - dvbsub_parse_clut_segment(avctx, p, segment_length); + ret = dvbsub_parse_clut_segment(avctx, p, segment_length); + if (ret < 0) return ret; got_segment |= 4; break; case DVBSUB_OBJECT_SEGMENT: @@ -1536,11 +1542,11 @@ static int dvbsub_decode(AVCodecContext *avctx, AVCodec ff_dvbsub_decoder = { .name = "dvbsub", + .long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"), .type = AVMEDIA_TYPE_SUBTITLE, .id = AV_CODEC_ID_DVB_SUBTITLE, .priv_data_size = sizeof(DVBSubContext), .init = dvbsub_init_decoder, .close = dvbsub_close_decoder, .decode = dvbsub_decode, - .long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"), }; diff --git a/ffmpeg/libavcodec/dvdata.c b/ffmpeg/libavcodec/dvdata.c index a7e3d59..a3be7fd 100644 --- a/ffmpeg/libavcodec/dvdata.c +++ b/ffmpeg/libavcodec/dvdata.c @@ -24,7 +24,8 @@ * Constants for DV codec. */ -#include "avcodec.h" +#include + #include "dvdata.h" /* unquant tables (not used directly) */ @@ -120,3 +121,227 @@ const int ff_dv_iweight_720_c[64] = { 394, 406, 418, 438, 418, 464, 464, 492, }; +/* + * There's a catch about the following three tables: the mapping they establish + * between (run, level) and vlc is not 1-1. So you have to watch out for that + * when building misc. tables. E.g. (1, 0) can be either 0x7cf or 0x1f82. + */ +const uint16_t ff_dv_vlc_bits[NB_DV_VLC] = { + 0x0000, 0x0002, 0x0007, 0x0008, 0x0009, 0x0014, 0x0015, 0x0016, + 0x0017, 0x0030, 0x0031, 0x0032, 0x0033, 0x0068, 0x0069, 0x006a, + 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x00e0, 0x00e1, 0x00e2, + 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, + 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x01e0, 0x01e1, 0x01e2, + 0x01e3, 0x01e4, 0x01e5, 0x01e6, 0x01e7, 0x01e8, 0x01e9, 0x01ea, + 0x01eb, 0x01ec, 0x01ed, 0x01ee, 0x01ef, 0x03e0, 0x03e1, 0x03e2, + 0x03e3, 0x03e4, 0x03e5, 0x03e6, 0x07ce, 0x07cf, 0x07d0, 0x07d1, + 0x07d2, 0x07d3, 0x07d4, 0x07d5, 0x0fac, 0x0fad, 0x0fae, 0x0faf, + 0x0fb0, 0x0fb1, 0x0fb2, 0x0fb3, 0x0fb4, 0x0fb5, 0x0fb6, 0x0fb7, + 0x0fb8, 0x0fb9, 0x0fba, 0x0fbb, 0x0fbc, 0x0fbd, 0x0fbe, 0x0fbf, + 0x1f80, 0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86, 0x1f87, + 0x1f88, 0x1f89, 0x1f8a, 0x1f8b, 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f, + 0x1f90, 0x1f91, 0x1f92, 0x1f93, 0x1f94, 0x1f95, 0x1f96, 0x1f97, + 0x1f98, 0x1f99, 0x1f9a, 0x1f9b, 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f, + 0x1fa0, 0x1fa1, 0x1fa2, 0x1fa3, 0x1fa4, 0x1fa5, 0x1fa6, 0x1fa7, + 0x1fa8, 0x1fa9, 0x1faa, 0x1fab, 0x1fac, 0x1fad, 0x1fae, 0x1faf, + 0x1fb0, 0x1fb1, 0x1fb2, 0x1fb3, 0x1fb4, 0x1fb5, 0x1fb6, 0x1fb7, + 0x1fb8, 0x1fb9, 0x1fba, 0x1fbb, 0x1fbc, 0x1fbd, 0x1fbe, 0x1fbf, + 0x7f00, 0x7f01, 0x7f02, 0x7f03, 0x7f04, 0x7f05, 0x7f06, 0x7f07, + 0x7f08, 0x7f09, 0x7f0a, 0x7f0b, 0x7f0c, 0x7f0d, 0x7f0e, 0x7f0f, + 0x7f10, 0x7f11, 0x7f12, 0x7f13, 0x7f14, 0x7f15, 0x7f16, 0x7f17, + 0x7f18, 0x7f19, 0x7f1a, 0x7f1b, 0x7f1c, 0x7f1d, 0x7f1e, 0x7f1f, + 0x7f20, 0x7f21, 0x7f22, 0x7f23, 0x7f24, 0x7f25, 0x7f26, 0x7f27, + 0x7f28, 0x7f29, 0x7f2a, 0x7f2b, 0x7f2c, 0x7f2d, 0x7f2e, 0x7f2f, + 0x7f30, 0x7f31, 0x7f32, 0x7f33, 0x7f34, 0x7f35, 0x7f36, 0x7f37, + 0x7f38, 0x7f39, 0x7f3a, 0x7f3b, 0x7f3c, 0x7f3d, 0x7f3e, 0x7f3f, + 0x7f40, 0x7f41, 0x7f42, 0x7f43, 0x7f44, 0x7f45, 0x7f46, 0x7f47, + 0x7f48, 0x7f49, 0x7f4a, 0x7f4b, 0x7f4c, 0x7f4d, 0x7f4e, 0x7f4f, + 0x7f50, 0x7f51, 0x7f52, 0x7f53, 0x7f54, 0x7f55, 0x7f56, 0x7f57, + 0x7f58, 0x7f59, 0x7f5a, 0x7f5b, 0x7f5c, 0x7f5d, 0x7f5e, 0x7f5f, + 0x7f60, 0x7f61, 0x7f62, 0x7f63, 0x7f64, 0x7f65, 0x7f66, 0x7f67, + 0x7f68, 0x7f69, 0x7f6a, 0x7f6b, 0x7f6c, 0x7f6d, 0x7f6e, 0x7f6f, + 0x7f70, 0x7f71, 0x7f72, 0x7f73, 0x7f74, 0x7f75, 0x7f76, 0x7f77, + 0x7f78, 0x7f79, 0x7f7a, 0x7f7b, 0x7f7c, 0x7f7d, 0x7f7e, 0x7f7f, + 0x7f80, 0x7f81, 0x7f82, 0x7f83, 0x7f84, 0x7f85, 0x7f86, 0x7f87, + 0x7f88, 0x7f89, 0x7f8a, 0x7f8b, 0x7f8c, 0x7f8d, 0x7f8e, 0x7f8f, + 0x7f90, 0x7f91, 0x7f92, 0x7f93, 0x7f94, 0x7f95, 0x7f96, 0x7f97, + 0x7f98, 0x7f99, 0x7f9a, 0x7f9b, 0x7f9c, 0x7f9d, 0x7f9e, 0x7f9f, + 0x7fa0, 0x7fa1, 0x7fa2, 0x7fa3, 0x7fa4, 0x7fa5, 0x7fa6, 0x7fa7, + 0x7fa8, 0x7fa9, 0x7faa, 0x7fab, 0x7fac, 0x7fad, 0x7fae, 0x7faf, + 0x7fb0, 0x7fb1, 0x7fb2, 0x7fb3, 0x7fb4, 0x7fb5, 0x7fb6, 0x7fb7, + 0x7fb8, 0x7fb9, 0x7fba, 0x7fbb, 0x7fbc, 0x7fbd, 0x7fbe, 0x7fbf, + 0x7fc0, 0x7fc1, 0x7fc2, 0x7fc3, 0x7fc4, 0x7fc5, 0x7fc6, 0x7fc7, + 0x7fc8, 0x7fc9, 0x7fca, 0x7fcb, 0x7fcc, 0x7fcd, 0x7fce, 0x7fcf, + 0x7fd0, 0x7fd1, 0x7fd2, 0x7fd3, 0x7fd4, 0x7fd5, 0x7fd6, 0x7fd7, + 0x7fd8, 0x7fd9, 0x7fda, 0x7fdb, 0x7fdc, 0x7fdd, 0x7fde, 0x7fdf, + 0x7fe0, 0x7fe1, 0x7fe2, 0x7fe3, 0x7fe4, 0x7fe5, 0x7fe6, 0x7fe7, + 0x7fe8, 0x7fe9, 0x7fea, 0x7feb, 0x7fec, 0x7fed, 0x7fee, 0x7fef, + 0x7ff0, 0x7ff1, 0x7ff2, 0x7ff3, 0x7ff4, 0x7ff5, 0x7ff6, 0x7ff7, + 0x7ff8, 0x7ff9, 0x7ffa, 0x7ffb, 0x7ffc, 0x7ffd, 0x7ffe, 0x7fff, + 0x0006, +}; + +const uint8_t ff_dv_vlc_len[NB_DV_VLC] = { + 2, 3, 4, 4, 4, 5, 5, 5, + 5, 6, 6, 6, 6, 7, 7, 7, + 7, 7, 7, 7, 7, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 10, 10, 10, + 10, 10, 10, 10, 11, 11, 11, 11, + 11, 11, 11, 11, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 4, +}; + +const uint8_t ff_dv_vlc_run[NB_DV_VLC] = { + 0, 0, 1, 0, 0, 2, 1, 0, + 0, 3, 4, 0, 0, 5, 6, 2, + 1, 1, 0, 0, 0, 7, 8, 9, + 10, 3, 4, 2, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 11, 12, 13, + 14, 5, 6, 3, 4, 2, 2, 1, + 0, 0, 0, 0, 0, 5, 3, 3, + 2, 1, 1, 1, 0, 1, 6, 4, + 3, 1, 1, 1, 2, 3, 4, 5, + 7, 8, 9, 10, 7, 8, 4, 3, + 2, 2, 2, 2, 2, 1, 1, 1, + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +127, +}; + +const uint8_t ff_dv_vlc_level[NB_DV_VLC] = { + 1, 2, 1, 3, 4, 1, 2, 5, + 6, 1, 1, 7, 8, 1, 1, 2, + 3, 4, 9, 10, 11, 1, 1, 1, + 1, 2, 2, 3, 5, 6, 7, 12, + 13, 14, 15, 16, 17, 1, 1, 1, + 1, 2, 2, 3, 3, 4, 5, 8, + 18, 19, 20, 21, 22, 3, 4, 5, + 6, 9, 10, 11, 0, 0, 3, 4, + 6, 12, 13, 14, 0, 0, 0, 0, + 2, 2, 2, 2, 3, 3, 5, 7, + 7, 8, 9, 10, 11, 15, 16, 17, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, + 0, +}; diff --git a/ffmpeg/libavcodec/dvdata.h b/ffmpeg/libavcodec/dvdata.h index 97c20e3..8c120df 100644 --- a/ffmpeg/libavcodec/dvdata.h +++ b/ffmpeg/libavcodec/dvdata.h @@ -1,7 +1,4 @@ /* - * Constants for DV codec - * Copyright (c) 2002 Fabrice Bellard - * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -19,55 +16,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -/** - * @file - * Constants for DV codec. - */ - #ifndef AVCODEC_DVDATA_H #define AVCODEC_DVDATA_H -#include "avcodec.h" -#include "dsputil.h" -#include "get_bits.h" -#include "dv_profile.h" - -typedef struct DVVideoContext { - const DVprofile *sys; - AVFrame picture; - AVCodecContext *avctx; - uint8_t *buf; - - uint8_t dv_zigzag[2][64]; - - void (*get_pixels)(int16_t *block, const uint8_t *pixels, int line_size); - void (*fdct[2])(int16_t *block); - void (*idct_put[2])(uint8_t *dest, int line_size, int16_t *block); - me_cmp_func ildct_cmp; -} DVVideoContext; - -enum dv_section_type { - dv_sect_header = 0x1f, - dv_sect_subcode = 0x3f, - dv_sect_vaux = 0x56, - dv_sect_audio = 0x76, - dv_sect_video = 0x96, -}; - -enum dv_pack_type { - dv_header525 = 0x3f, /* see dv_write_pack for important details on */ - dv_header625 = 0xbf, /* these two packs */ - dv_timecode = 0x13, - dv_audio_source = 0x50, - dv_audio_control = 0x51, - dv_audio_recdate = 0x52, - dv_audio_rectime = 0x53, - dv_video_source = 0x60, - dv_video_control = 0x61, - dv_video_recdate = 0x62, - dv_video_rectime = 0x63, - dv_unknown_pack = 0xff, -}; +#include extern const uint8_t ff_dv_quant_shifts[22][4]; extern const uint8_t ff_dv_quant_offset[4]; @@ -79,46 +31,11 @@ extern const int ff_dv_iweight_1080_c[64]; extern const int ff_dv_iweight_720_y[64]; extern const int ff_dv_iweight_720_c[64]; -#define DV_PROFILE_IS_HD(p) ((p)->video_stype & 0x10) -#define DV_PROFILE_IS_1080i50(p) (((p)->video_stype == 0x14) && ((p)->dsf == 1)) -#define DV_PROFILE_IS_720p50(p) (((p)->video_stype == 0x18) && ((p)->dsf == 1)) - -/** - * largest possible DV frame, in bytes (1080i50) - */ -#define DV_MAX_FRAME_SIZE 576000 - -/** - * maximum number of blocks per macroblock in any DV format - */ -#define DV_MAX_BPM 8 - -#define TEX_VLC_BITS 9 - -extern RL_VLC_ELEM ff_dv_rl_vlc[1184]; - -int ff_dv_init_dynamic_tables(const DVprofile *d); -int ff_dvvideo_init(AVCodecContext *avctx); - -static inline int dv_work_pool_size(const DVprofile *d) -{ - int size = d->n_difchan*d->difseg_size*27; - if (DV_PROFILE_IS_1080i50(d)) - size -= 3*27; - if (DV_PROFILE_IS_720p50(d)) - size -= 4*27; - return size; -} - -static inline void dv_calculate_mb_xy(DVVideoContext *s, DVwork_chunk *work_chunk, int m, int *mb_x, int *mb_y) -{ - *mb_x = work_chunk->mb_coordinates[m] & 0xff; - *mb_y = work_chunk->mb_coordinates[m] >> 8; +#define NB_DV_VLC 409 - /* We work with 720p frames split in half. The odd half-frame (chan==2,3) is displaced :-( */ - if (s->sys->height == 720 && !(s->buf[1]&0x0C)) { - *mb_y -= (*mb_y>17)?18:-72; /* shifting the Y coordinate down by 72/2 macro blocks */ - } -} +extern const uint16_t ff_dv_vlc_bits[NB_DV_VLC]; +extern const uint8_t ff_dv_vlc_len[NB_DV_VLC]; +extern const uint8_t ff_dv_vlc_run[NB_DV_VLC]; +extern const uint8_t ff_dv_vlc_level[NB_DV_VLC]; #endif /* AVCODEC_DVDATA_H */ diff --git a/ffmpeg/libavcodec/dvdec.c b/ffmpeg/libavcodec/dvdec.c index 5cc205c..727f91d 100644 --- a/ffmpeg/libavcodec/dvdec.c +++ b/ffmpeg/libavcodec/dvdec.c @@ -44,6 +44,7 @@ #include "put_bits.h" #include "simple_idct.h" #include "dvdata.h" +#include "dv.h" typedef struct BlockInfo { const uint32_t *factor_table; @@ -237,7 +238,7 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg) flush_put_bits(&vs_pb); for (mb_index = 0; mb_index < 5; mb_index++) { for (j = 0; j < s->sys->bpm; j++) { - if (mb->pos < 64) { + if (mb->pos < 64 && get_bits_left(&gb) > 0) { av_dlog(avctx, "start %d:%d\n", mb_index, j); dv_decode_ac(&gb, mb, block); } @@ -258,12 +259,12 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg) if ((s->sys->pix_fmt == AV_PIX_FMT_YUV420P) || (s->sys->pix_fmt == AV_PIX_FMT_YUV411P && mb_x >= (704 / 8)) || (s->sys->height >= 720 && mb_y != 134)) { - y_stride = (s->picture.linesize[0] << ((!is_field_mode[mb_index]) * log2_blocksize)); + y_stride = (s->frame->linesize[0] << ((!is_field_mode[mb_index]) * log2_blocksize)); } else { y_stride = (2 << log2_blocksize); } - y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x) << log2_blocksize); - linesize = s->picture.linesize[0] << is_field_mode[mb_index]; + y_ptr = s->frame->data[0] + ((mb_y * s->frame->linesize[0] + mb_x) << log2_blocksize); + linesize = s->frame->linesize[0] << is_field_mode[mb_index]; mb[0] .idct_put(y_ptr , linesize, block + 0*64); if (s->sys->video_stype == 4) { /* SD 422 */ mb[2].idct_put(y_ptr + (1 << log2_blocksize) , linesize, block + 2*64); @@ -276,20 +277,20 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg) block += 4*64; /* idct_put'ting chrominance */ - c_offset = (((mb_y >> (s->sys->pix_fmt == AV_PIX_FMT_YUV420P)) * s->picture.linesize[1] + + c_offset = (((mb_y >> (s->sys->pix_fmt == AV_PIX_FMT_YUV420P)) * s->frame->linesize[1] + (mb_x >> ((s->sys->pix_fmt == AV_PIX_FMT_YUV411P) ? 2 : 1))) << log2_blocksize); for (j = 2; j; j--) { - uint8_t *c_ptr = s->picture.data[j] + c_offset; + uint8_t *c_ptr = s->frame->data[j] + c_offset; if (s->sys->pix_fmt == AV_PIX_FMT_YUV411P && mb_x >= (704 / 8)) { uint64_t aligned_pixels[64/8]; uint8_t *pixels = (uint8_t*)aligned_pixels; uint8_t *c_ptr1, *ptr1; int x, y; mb->idct_put(pixels, 8, block); - for (y = 0; y < (1 << log2_blocksize); y++, c_ptr += s->picture.linesize[j], pixels += 8) { - ptr1 = pixels + (1 << (log2_blocksize - 1)); - c_ptr1 = c_ptr + (s->picture.linesize[j] << log2_blocksize); - for (x = 0; x < (1 << (log2_blocksize - 1)); x++) { + for (y = 0; y < (1 << log2_blocksize); y++, c_ptr += s->frame->linesize[j], pixels += 8) { + ptr1 = pixels + ((1 << (log2_blocksize))>>1); + c_ptr1 = c_ptr + (s->frame->linesize[j] << log2_blocksize); + for (x = 0; x < (1 << FFMAX(log2_blocksize - 1, 0)); x++) { c_ptr[x] = pixels[x]; c_ptr1[x] = ptr1[x]; } @@ -297,8 +298,8 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg) block += 64; mb++; } else { y_stride = (mb_y == 134) ? (1 << log2_blocksize) : - s->picture.linesize[j] << ((!is_field_mode[mb_index]) * log2_blocksize); - linesize = s->picture.linesize[j] << is_field_mode[mb_index]; + s->frame->linesize[j] << ((!is_field_mode[mb_index]) * log2_blocksize); + linesize = s->frame->linesize[j] << is_field_mode[mb_index]; (mb++)-> idct_put(c_ptr , linesize, block); block += 64; if (s->sys->bpm == 8) { (mb++)->idct_put(c_ptr + y_stride, linesize, block); block += 64; @@ -319,7 +320,7 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, int buf_size = avpkt->size; DVVideoContext *s = avctx->priv_data; const uint8_t* vsc_pack; - int ret, apt, is16_9; + int apt, is16_9, ret; s->sys = avpriv_dv_frame_profile2(avctx, s->sys, buf, buf_size); if (!s->sys || buf_size < s->sys->frame_size || ff_dv_init_dynamic_tables(s->sys)) { @@ -327,15 +328,20 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, return -1; /* NOTE: we only accept several full frames */ } - s->picture.key_frame = 1; - s->picture.pict_type = AV_PICTURE_TYPE_I; + s->frame = data; + s->frame->key_frame = 1; + s->frame->pict_type = AV_PICTURE_TYPE_I; avctx->pix_fmt = s->sys->pix_fmt; avctx->time_base = s->sys->time_base; - avcodec_set_dimensions(avctx, s->sys->width, s->sys->height); - if ((ret = ff_get_buffer(avctx, &s->picture, 0)) < 0) + + ret = ff_set_dimensions(avctx, s->sys->width, s->sys->height); + if (ret < 0) + return ret; + + if ((ret = ff_get_buffer(avctx, s->frame, 0)) < 0) return ret; - s->picture.interlaced_frame = 1; - s->picture.top_field_first = 0; + s->frame->interlaced_frame = 1; + s->frame->top_field_first = 0; /* Determine the codec's sample_aspect ratio and field order from the packet */ vsc_pack = buf + 80*5 + 48 + 5; @@ -343,7 +349,7 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, apt = buf[4] & 0x07; is16_9 = (vsc_pack[2] & 0x07) == 0x02 || (!apt && (vsc_pack[2] & 0x07) == 0x07); avctx->sample_aspect_ratio = s->sys->sar[is16_9]; - s->picture.top_field_first = !(vsc_pack[3] & 0x40); + s->frame->top_field_first = !(vsc_pack[3] & 0x40); } s->buf = buf; @@ -354,29 +360,18 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, /* return image */ *got_frame = 1; - av_frame_move_ref(data, &s->picture); return s->sys->frame_size; } -static int dvvideo_close(AVCodecContext *c) -{ - DVVideoContext *s = c->priv_data; - - av_frame_unref(&s->picture); - - return 0; -} - AVCodec ff_dvvideo_decoder = { .name = "dvvideo", + .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_DVVIDEO, .priv_data_size = sizeof(DVVideoContext), .init = ff_dvvideo_init, - .close = dvvideo_close, .decode = dvvideo_decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS, .max_lowres = 3, - .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"), }; diff --git a/ffmpeg/libavcodec/dvdsubdec.c b/ffmpeg/libavcodec/dvdsubdec.c index cb268b8..637f3e6 100644 --- a/ffmpeg/libavcodec/dvdsubdec.c +++ b/ffmpeg/libavcodec/dvdsubdec.c @@ -21,13 +21,14 @@ #include "avcodec.h" #include "get_bits.h" #include "dsputil.h" +#include "internal.h" + +#include "libavutil/attributes.h" #include "libavutil/colorspace.h" #include "libavutil/opt.h" #include "libavutil/imgutils.h" #include "libavutil/avstring.h" -//#define DEBUG - typedef struct DVDSubContext { AVClass *class; @@ -36,11 +37,16 @@ typedef struct DVDSubContext int has_palette; uint8_t colormap[4]; uint8_t alpha[256]; + uint8_t *buf; + int buf_size; +#ifdef DEBUG + int sub_id; +#endif } DVDSubContext; static void yuv_a_to_rgba(const uint8_t *ycbcr, const uint8_t *alpha, uint32_t *rgba, int num_values) { - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; uint8_t r, g, b; int i, y, cb, cr; int r_add, g_add, b_add; @@ -185,6 +191,21 @@ static void guess_palette(DVDSubContext* ctx, } } +static void reset_rects(AVSubtitle *sub_header) +{ + int i; + + if (sub_header->rects != NULL) { + for (i = 0; i < sub_header->num_rects; i++) { + av_freep(&sub_header->rects[i]->pict.data[0]); + av_freep(&sub_header->rects[i]->pict.data[1]); + av_freep(&sub_header->rects[i]); + } + av_freep(&sub_header->rects); + sub_header->num_rects = 0; + } +} + #define READ_OFFSET(a) (big_offsets ? AV_RB32(a) : AV_RB16(a)) static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header, @@ -213,6 +234,9 @@ static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header, cmd_pos = READ_OFFSET(buf + cmd_pos); + if (cmd_pos < 0 || cmd_pos > buf_size - 2 - offset_size) + return AVERROR(EAGAIN); + while (cmd_pos > 0 && cmd_pos < buf_size - 2 - offset_size) { date = AV_RB16(buf + cmd_pos); next_cmd_pos = READ_OFFSET(buf + cmd_pos + 2); @@ -325,15 +349,7 @@ static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header, if (h < 0) h = 0; if (w > 0 && h > 0) { - if (sub_header->rects != NULL) { - for (i = 0; i < sub_header->num_rects; i++) { - av_freep(&sub_header->rects[i]->pict.data[0]); - av_freep(&sub_header->rects[i]->pict.data[1]); - av_freep(&sub_header->rects[i]); - } - av_freep(&sub_header->rects); - sub_header->num_rects = 0; - } + reset_rects(sub_header); bitmap = av_malloc(w * h); sub_header->rects = av_mallocz(sizeof(*sub_header->rects)); @@ -375,15 +391,7 @@ static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header, if (sub_header->num_rects > 0) return is_menu; fail: - if (sub_header->rects != NULL) { - for (i = 0; i < sub_header->num_rects; i++) { - av_freep(&sub_header->rects[i]->pict.data[0]); - av_freep(&sub_header->rects[i]->pict.data[1]); - av_freep(&sub_header->rects[i]); - } - av_freep(&sub_header->rects); - sub_header->num_rects = 0; - } + reset_rects(sub_header); return -1; } @@ -454,9 +462,6 @@ static int find_smallest_bounding_rectangle(AVSubtitle *s) } #ifdef DEBUG -#undef fprintf -#undef perror -#undef exit static void ppm_save(const char *filename, uint8_t *bitmap, int w, int h, uint32_t *rgba_palette) { @@ -466,7 +471,7 @@ static void ppm_save(const char *filename, uint8_t *bitmap, int w, int h, f = fopen(filename, "w"); if (!f) { perror(filename); - exit(1); + return; } fprintf(f, "P6\n" "%d %d\n" @@ -484,6 +489,25 @@ static void ppm_save(const char *filename, uint8_t *bitmap, int w, int h, } #endif +static int append_to_cached_buf(AVCodecContext *avctx, + const uint8_t *buf, int buf_size) +{ + DVDSubContext *ctx = avctx->priv_data; + + if (ctx->buf_size > 0xffff - buf_size) { + av_log(avctx, AV_LOG_WARNING, "Attempt to reconstruct " + "too large SPU packets aborted.\n"); + av_freep(&ctx->buf); + return AVERROR_INVALIDDATA; + } + ctx->buf = av_realloc(ctx->buf, ctx->buf_size + buf_size); + if (!ctx->buf) + return AVERROR(ENOMEM); + memcpy(ctx->buf + ctx->buf_size, buf, buf_size); + ctx->buf_size += buf_size; + return 0; +} + static int dvdsub_decode(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) @@ -494,7 +518,21 @@ static int dvdsub_decode(AVCodecContext *avctx, AVSubtitle *sub = data; int is_menu; + if (ctx->buf) { + int ret = append_to_cached_buf(avctx, buf, buf_size); + if (ret < 0) { + *data_size = 0; + return ret; + } + buf = ctx->buf; + buf_size = ctx->buf_size; + } + is_menu = decode_dvd_subtitles(ctx, sub, buf, buf_size); + if (is_menu == AVERROR(EAGAIN)) { + *data_size = 0; + return append_to_cached_buf(avctx, buf, buf_size); + } if (is_menu < 0) { no_subtitle: @@ -506,13 +544,20 @@ static int dvdsub_decode(AVCodecContext *avctx, goto no_subtitle; #if defined(DEBUG) + { + char ppm_name[32]; + + snprintf(ppm_name, sizeof(ppm_name), "/tmp/%05d.ppm", ctx->sub_id++); av_dlog(NULL, "start=%d ms end =%d ms\n", sub->start_display_time, sub->end_display_time); - ppm_save("/tmp/a.ppm", sub->rects[0]->pict.data[0], + ppm_save(ppm_name, sub->rects[0]->pict.data[0], sub->rects[0]->w, sub->rects[0]->h, sub->rects[0]->pict.data[1]); + } #endif + av_freep(&ctx->buf); + ctx->buf_size = 0; *data_size = 1; return buf_size; } @@ -552,9 +597,13 @@ static int dvdsub_parse_extradata(AVCodecContext *avctx) parse_palette(ctx, data + 8); } else if (strncmp("size:", data, 5) == 0) { int w, h; - if (sscanf(data + 5, "%dx%d", &w, &h) == 2 && - av_image_check_size(w, h, 0, avctx) >= 0) - avcodec_set_dimensions(avctx, w, h); + if (sscanf(data + 5, "%dx%d", &w, &h) == 2) { + int ret = ff_set_dimensions(avctx, w, h); + if (ret < 0) { + av_free(dataorig); + return ret; + } + } } data += pos; @@ -565,7 +614,7 @@ static int dvdsub_parse_extradata(AVCodecContext *avctx) return 1; } -static int dvdsub_init(AVCodecContext *avctx) +static av_cold int dvdsub_init(AVCodecContext *avctx) { DVDSubContext *ctx = avctx->priv_data; int ret; @@ -586,13 +635,21 @@ static int dvdsub_init(AVCodecContext *avctx) return 1; } +static av_cold int dvdsub_close(AVCodecContext *avctx) +{ + DVDSubContext *ctx = avctx->priv_data; + av_freep(&ctx->buf); + ctx->buf_size = 0; + return 0; +} + #define OFFSET(field) offsetof(DVDSubContext, field) #define VD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM static const AVOption options[] = { { "palette", "set the global palette", OFFSET(palette_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VD }, { NULL } }; -static const AVClass class = { +static const AVClass dvdsub_class = { .class_name = "dvdsubdec", .item_name = av_default_item_name, .option = options, @@ -601,11 +658,12 @@ static const AVClass class = { AVCodec ff_dvdsub_decoder = { .name = "dvdsub", + .long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"), .type = AVMEDIA_TYPE_SUBTITLE, .id = AV_CODEC_ID_DVD_SUBTITLE, .priv_data_size = sizeof(DVDSubContext), .init = dvdsub_init, .decode = dvdsub_decode, - .long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"), - .priv_class = &class, + .close = dvdsub_close, + .priv_class = &dvdsub_class, }; diff --git a/ffmpeg/libavcodec/dvdsubenc.c b/ffmpeg/libavcodec/dvdsubenc.c index 6e19623..8130b74 100644 --- a/ffmpeg/libavcodec/dvdsubenc.c +++ b/ffmpeg/libavcodec/dvdsubenc.c @@ -434,10 +434,10 @@ static int dvdsub_encode(AVCodecContext *avctx, AVCodec ff_dvdsub_encoder = { .name = "dvdsub", + .long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"), .type = AVMEDIA_TYPE_SUBTITLE, .id = AV_CODEC_ID_DVD_SUBTITLE, .init = dvdsub_init, .encode_sub = dvdsub_encode, - .long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"), .priv_data_size = sizeof(DVDSubtitleContext), }; diff --git a/ffmpeg/libavcodec/dxa.c b/ffmpeg/libavcodec/dxa.c index 2286f33..0f64b5e 100644 --- a/ffmpeg/libavcodec/dxa.c +++ b/ffmpeg/libavcodec/dxa.c @@ -39,9 +39,10 @@ * Decoder context */ typedef struct DxaDecContext { - AVFrame prev; + AVFrame *prev; int dsize; +#define DECOMP_BUF_PADDING 16 uint8_t *decomp_buf; uint32_t pal[256]; } DxaDecContext; @@ -50,13 +51,17 @@ static const int shift1[6] = { 0, 8, 8, 8, 4, 4 }; static const int shift2[6] = { 0, 0, 8, 4, 0, 4 }; static int decode_13(AVCodecContext *avctx, DxaDecContext *c, uint8_t* dst, - int stride, uint8_t *src, uint8_t *ref) + int stride, uint8_t *src, int srcsize, uint8_t *ref) { uint8_t *code, *data, *mv, *msk, *tmp, *tmp2; + uint8_t *src_end = src + srcsize; int i, j, k; int type, x, y, d, d2; uint32_t mask; + if (12ULL + ((avctx->width * avctx->height) >> 4) + AV_RB32(src + 0) + AV_RB32(src + 4) > srcsize) + return AVERROR_INVALIDDATA; + code = src + 12; data = code + ((avctx->width * avctx->height) >> 4); mv = data + AV_RB32(src + 0); @@ -64,6 +69,8 @@ static int decode_13(AVCodecContext *avctx, DxaDecContext *c, uint8_t* dst, for(j = 0; j < avctx->height; j += 4){ for(i = 0; i < avctx->width; i += 4){ + if (data > src_end || mv > src_end || msk > src_end) + return AVERROR_INVALIDDATA; tmp = dst + i; tmp2 = ref + i; type = *code++; @@ -71,6 +78,11 @@ static int decode_13(AVCodecContext *avctx, DxaDecContext *c, uint8_t* dst, case 4: // motion compensation x = (*mv) >> 4; if(x & 8) x = 8 - x; y = (*mv++) & 0xF; if(y & 8) y = 8 - y; + if (i < -x || avctx->width - i - 4 < x || + j < -y || avctx->height - j - 4 < y) { + av_log(avctx, AV_LOG_ERROR, "MV %d %d out of bounds\n", x,y); + return AVERROR_INVALIDDATA; + } tmp2 += x + y*stride; case 0: // skip case 5: // skip in method 12 @@ -128,6 +140,11 @@ static int decode_13(AVCodecContext *avctx, DxaDecContext *c, uint8_t* dst, case 0x80: // motion compensation x = (*mv) >> 4; if(x & 8) x = 8 - x; y = (*mv++) & 0xF; if(y & 8) y = 8 - y; + if (i + 2*(k & 1) < -x || avctx->width - i - 2*(k & 1) - 2 < x || + j + (k & 2) < -y || avctx->height - j - (k & 2) - 2 < y) { + av_log(avctx, AV_LOG_ERROR, "MV %d %d out of bounds\n", x,y); + return AVERROR_INVALIDDATA; + } tmp2 += x + y*stride; case 0x00: // skip tmp[d + 0 ] = tmp2[0]; @@ -219,7 +236,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac outptr = frame->data[0]; srcptr = c->decomp_buf; - tmpptr = c->prev.data[0]; + tmpptr = c->prev->data[0]; stride = frame->linesize[0]; if (bytestream2_get_le32(&gb) == MKTAG('N','U','L','L')) @@ -235,13 +252,18 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac av_log(avctx, AV_LOG_ERROR, "Uncompress failed!\n"); return AVERROR_UNKNOWN; } + memset(c->decomp_buf + dsize, 0, DECOMP_BUF_PADDING); } + + if (avctx->debug & FF_DEBUG_PICT_INFO) + av_log(avctx, AV_LOG_DEBUG, "compr:%2d, dsize:%d\n", compr, (int)dsize); + switch(compr){ case -1: frame->key_frame = 0; frame->pict_type = AV_PICTURE_TYPE_P; - if(c->prev.data[0]) - memcpy(frame->data[0], c->prev.data[0], frame->linesize[0] * avctx->height); + if (c->prev->data[0]) + memcpy(frame->data[0], c->prev->data[0], frame->linesize[0] * avctx->height); else{ // Should happen only when first frame is 'NULL' memset(frame->data[0], 0, frame->linesize[0] * avctx->height); frame->key_frame = 1; @@ -249,13 +271,26 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac } break; case 2: - case 3: case 4: + frame->key_frame = 1; + frame->pict_type = AV_PICTURE_TYPE_I; + for (j = 0; j < avctx->height; j++) { + memcpy(outptr, srcptr, avctx->width); + outptr += stride; + srcptr += avctx->width; + } + break; + case 3: case 5: - frame->key_frame = !(compr & 1); - frame->pict_type = (compr & 1) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I; - for(j = 0; j < avctx->height; j++){ - if((compr & 1) && tmpptr){ + if (!tmpptr) { + av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n"); + if (!(avctx->flags2 & CODEC_FLAG2_SHOW_ALL)) + return AVERROR_INVALIDDATA; + } + frame->key_frame = 0; + frame->pict_type = AV_PICTURE_TYPE_P; + for (j = 0; j < avctx->height; j++) { + if(tmpptr){ for(i = 0; i < avctx->width; i++) outptr[i] = srcptr[i] ^ tmpptr[i]; tmpptr += stride; @@ -269,19 +304,19 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac case 13: frame->key_frame = 0; frame->pict_type = AV_PICTURE_TYPE_P; - if (!c->prev.data[0]) { + if (!c->prev->data[0]) { av_log(avctx, AV_LOG_ERROR, "Missing reference frame\n"); return AVERROR_INVALIDDATA; } - decode_13(avctx, c, frame->data[0], frame->linesize[0], srcptr, c->prev.data[0]); + decode_13(avctx, c, frame->data[0], frame->linesize[0], srcptr, dsize, c->prev->data[0]); break; default: av_log(avctx, AV_LOG_ERROR, "Unknown/unsupported compression type %d\n", compr); return AVERROR_INVALIDDATA; } - av_frame_unref(&c->prev); - if ((ret = av_frame_ref(&c->prev, frame)) < 0) + av_frame_unref(c->prev); + if ((ret = av_frame_ref(c->prev, frame)) < 0) return ret; *got_frame = 1; @@ -294,13 +329,16 @@ static av_cold int decode_init(AVCodecContext *avctx) { DxaDecContext * const c = avctx->priv_data; - avctx->pix_fmt = AV_PIX_FMT_PAL8; + c->prev = av_frame_alloc(); + if (!c->prev) + return AVERROR(ENOMEM); - avcodec_get_frame_defaults(&c->prev); + avctx->pix_fmt = AV_PIX_FMT_PAL8; c->dsize = avctx->width * avctx->height * 2; - c->decomp_buf = av_malloc(c->dsize); + c->decomp_buf = av_malloc(c->dsize + DECOMP_BUF_PADDING); if (!c->decomp_buf) { + av_frame_free(&c->prev); av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); return AVERROR(ENOMEM); } @@ -313,13 +351,14 @@ static av_cold int decode_end(AVCodecContext *avctx) DxaDecContext * const c = avctx->priv_data; av_freep(&c->decomp_buf); - av_frame_unref(&c->prev); + av_frame_free(&c->prev); return 0; } AVCodec ff_dxa_decoder = { .name = "dxa", + .long_name = NULL_IF_CONFIG_SMALL("Feeble Files/ScummVM DXA"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_DXA, .priv_data_size = sizeof(DxaDecContext), @@ -327,5 +366,4 @@ AVCodec ff_dxa_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Feeble Files/ScummVM DXA"), }; diff --git a/ffmpeg/libavcodec/dxtory.c b/ffmpeg/libavcodec/dxtory.c index 28e66ba..21282b8 100644 --- a/ffmpeg/libavcodec/dxtory.c +++ b/ffmpeg/libavcodec/dxtory.c @@ -3,61 +3,48 @@ * * Copyright (c) 2011 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#define BITSTREAM_READER_LE #include "avcodec.h" +#include "bytestream.h" +#include "get_bits.h" #include "internal.h" +#include "unary.h" #include "libavutil/common.h" #include "libavutil/intreadwrite.h" -static av_cold int decode_init(AVCodecContext *avctx) -{ - avctx->pix_fmt = AV_PIX_FMT_YUV420P; - - return 0; -} - -static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, - AVPacket *avpkt) +static int dxtory_decode_v1(AVCodecContext *avctx, AVFrame *pic, + const uint8_t *src, int src_size) { int h, w; - AVFrame *pic = data; - const uint8_t *src = avpkt->data; uint8_t *Y1, *Y2, *U, *V; int ret; - if (avpkt->size < avctx->width * avctx->height * 3 / 2 + 16) { + if (src_size < avctx->width * avctx->height * 3 / 2) { av_log(avctx, AV_LOG_ERROR, "packet too small\n"); return AVERROR_INVALIDDATA; } + avctx->pix_fmt = AV_PIX_FMT_YUV420P; if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) return ret; - pic->pict_type = AV_PICTURE_TYPE_I; - pic->key_frame = 1; - - if (AV_RL32(src) != 0x01000002) { - avpriv_request_sample(avctx, "Frame header %X", AV_RL32(src)); - return AVERROR_PATCHWELCOME; - } - src += 16; - Y1 = pic->data[0]; Y2 = pic->data[0] + pic->linesize[0]; U = pic->data[1]; @@ -76,6 +63,154 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, V += pic->linesize[2]; } + return 0; +} + +static const uint8_t def_lru[8] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xFF }; + +static inline uint8_t decode_sym(GetBitContext *gb, uint8_t lru[8]) +{ + uint8_t c, val; + + c = get_unary(gb, 0, 8); + if (!c) { + val = get_bits(gb, 8); + memmove(lru + 1, lru, sizeof(*lru) * (8 - 1)); + } else { + val = lru[c - 1]; + memmove(lru + 1, lru, sizeof(*lru) * (c - 1)); + } + lru[0] = val; + + return val; +} + +static int dx2_decode_slice(GetBitContext *gb, int width, int height, + uint8_t *Y, uint8_t *U, uint8_t *V, + int ystride, int ustride, int vstride) +{ + int x, y, i; + uint8_t lru[3][8]; + + for (i = 0; i < 3; i++) + memcpy(lru[i], def_lru, 8 * sizeof(*def_lru)); + + for (y = 0; y < height; y+=2) { + for (x = 0; x < width; x += 2) { + Y[x + 0 + 0 * ystride] = decode_sym(gb, lru[0]); + Y[x + 1 + 0 * ystride] = decode_sym(gb, lru[0]); + Y[x + 0 + 1 * ystride] = decode_sym(gb, lru[0]); + Y[x + 1 + 1 * ystride] = decode_sym(gb, lru[0]); + U[x >> 1] = decode_sym(gb, lru[1]) ^ 0x80; + V[x >> 1] = decode_sym(gb, lru[2]) ^ 0x80; + } + + Y += ystride << 1; + U += ustride; + V += vstride; + } + + return 0; +} + +static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic, + const uint8_t *src, int src_size) +{ + GetByteContext gb; + GetBitContext gb2; + int nslices, slice, slice_height; + uint32_t off, slice_size; + uint8_t *Y, *U, *V; + int ret; + + bytestream2_init(&gb, src, src_size); + nslices = bytestream2_get_le16(&gb); + off = FFALIGN(nslices * 4 + 2, 16); + if (src_size < off) { + av_log(avctx, AV_LOG_ERROR, "no slice data\n"); + return AVERROR_INVALIDDATA; + } + + if (!nslices || avctx->height % nslices) { + avpriv_request_sample(avctx, "%d slices for %dx%d", nslices, + avctx->width, avctx->height); + return AVERROR(ENOSYS); + } + + slice_height = avctx->height / nslices; + if ((avctx->width & 1) || (slice_height & 1)) { + avpriv_request_sample(avctx, "slice dimensions %dx%d", + avctx->width, slice_height); + } + + avctx->pix_fmt = AV_PIX_FMT_YUV420P; + if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) + return ret; + + Y = pic->data[0]; + U = pic->data[1]; + V = pic->data[2]; + + for (slice = 0; slice < nslices; slice++) { + slice_size = bytestream2_get_le32(&gb); + if (slice_size > src_size - off) { + av_log(avctx, AV_LOG_ERROR, + "invalid slice size %d (only %d bytes left)\n", + slice_size, src_size - off); + return AVERROR_INVALIDDATA; + } + if (slice_size <= 16) { + av_log(avctx, AV_LOG_ERROR, "invalid slice size %d\n", slice_size); + return AVERROR_INVALIDDATA; + } + + if (AV_RL32(src + off) != slice_size - 16) { + av_log(avctx, AV_LOG_ERROR, + "Slice sizes mismatch: got %d instead of %d\n", + AV_RL32(src + off), slice_size - 16); + } + init_get_bits(&gb2, src + off + 16, (slice_size - 16) * 8); + dx2_decode_slice(&gb2, avctx->width, slice_height, Y, U, V, + pic->linesize[0], pic->linesize[1], pic->linesize[2]); + + Y += pic->linesize[0] * slice_height; + U += pic->linesize[1] * (slice_height >> 1); + V += pic->linesize[2] * (slice_height >> 1); + off += slice_size; + } + + return 0; +} + +static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, + AVPacket *avpkt) +{ + AVFrame *pic = data; + const uint8_t *src = avpkt->data; + int ret; + + if (avpkt->size < 16) { + av_log(avctx, AV_LOG_ERROR, "packet too small\n"); + return AVERROR_INVALIDDATA; + } + + switch (AV_RB32(src)) { + case 0x02000001: + ret = dxtory_decode_v1(avctx, pic, src + 16, avpkt->size - 16); + break; + case 0x02000009: + ret = dxtory_decode_v2(avctx, pic, src + 16, avpkt->size - 16); + break; + default: + avpriv_request_sample(avctx, "Frame header %X", AV_RB32(src)); + return AVERROR_PATCHWELCOME; + } + + if (ret) + return ret; + + pic->pict_type = AV_PICTURE_TYPE_I; + pic->key_frame = 1; *got_frame = 1; return avpkt->size; @@ -86,7 +221,6 @@ AVCodec ff_dxtory_decoder = { .long_name = NULL_IF_CONFIG_SMALL("Dxtory"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_DXTORY, - .init = decode_init, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, }; diff --git a/ffmpeg/libavcodec/dxva2_mpeg2.c b/ffmpeg/libavcodec/dxva2_mpeg2.c index 542f17c..1827dd5 100644 --- a/ffmpeg/libavcodec/dxva2_mpeg2.c +++ b/ffmpeg/libavcodec/dxva2_mpeg2.c @@ -139,8 +139,7 @@ static void fill_slice(AVCodecContext *avctx, init_get_bits(&gb, &buffer[4], 8 * (size - 4)); slice->wQuantizerScaleCode = get_bits(&gb, 5); - while (get_bits1(&gb)) - skip_bits(&gb, 8); + skip_1stop_8data_bits(&gb); slice->wMBbitOffset = 4 * 8 + get_bits_count(&gb); } diff --git a/ffmpeg/libavcodec/dxva2_vc1.c b/ffmpeg/libavcodec/dxva2_vc1.c index 92c78fd..2e9a00e 100644 --- a/ffmpeg/libavcodec/dxva2_vc1.c +++ b/ffmpeg/libavcodec/dxva2_vc1.c @@ -97,7 +97,7 @@ static void fill_picture_parameters(AVCodecContext *avctx, (v->vstransform ); pp->bPicOverflowBlocks = (v->quantizer_mode << 6) | (v->multires << 5) | - (s->resync_marker << 4) | + (v->resync_marker << 4) | (v->rangered << 3) | (s->max_b_frames ); pp->bPicExtrapolation = (!v->interlace || v->fcm == PROGRESSIVE) ? 1 : 2; diff --git a/ffmpeg/libavcodec/eac3enc.c b/ffmpeg/libavcodec/eac3enc.c index bb9ef4f..9944617 100644 --- a/ffmpeg/libavcodec/eac3enc.c +++ b/ffmpeg/libavcodec/eac3enc.c @@ -2,20 +2,20 @@ * E-AC-3 encoder * Copyright (c) 2011 Justin Ruggles * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -25,6 +25,8 @@ */ #define CONFIG_AC3ENC_FLOAT 1 + +#include "libavutil/attributes.h" #include "ac3enc.h" #include "eac3enc.h" #include "eac3_data.h" @@ -47,7 +49,7 @@ static const AVClass eac3enc_class = { static int8_t eac3_frame_expstr_index_tab[3][4][4][4][4][4]; -void ff_eac3_exponent_init(void) +av_cold void ff_eac3_exponent_init(void) { int i; @@ -252,6 +254,7 @@ void ff_eac3_output_frame_header(AC3EncodeContext *s) #if CONFIG_EAC3_ENCODER AVCodec ff_eac3_encoder = { .name = "eac3", + .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52 E-AC-3"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_EAC3, .priv_data_size = sizeof(AC3EncodeContext), @@ -260,7 +263,6 @@ AVCodec ff_eac3_encoder = { .close = ff_ac3_encode_close, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52 E-AC-3"), .priv_class = &eac3enc_class, .channel_layouts = ff_ac3_channel_layouts, .defaults = ac3_defaults, diff --git a/ffmpeg/libavcodec/eac3enc.h b/ffmpeg/libavcodec/eac3enc.h index a92a24c..7d61559 100644 --- a/ffmpeg/libavcodec/eac3enc.h +++ b/ffmpeg/libavcodec/eac3enc.h @@ -2,20 +2,20 @@ * E-AC-3 encoder * Copyright (c) 2011 Justin Ruggles * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/eacmv.c b/ffmpeg/libavcodec/eacmv.c index 4e96c1a..b3ffb3f 100644 --- a/ffmpeg/libavcodec/eacmv.c +++ b/ffmpeg/libavcodec/eacmv.c @@ -123,28 +123,30 @@ static void cmv_decode_inter(CmvContext *s, AVFrame *frame, const uint8_t *buf, int yoffset = ((buf[i] >> 4)) - 7; if (s->last_frame->data[0]) cmv_motcomp(frame->data[0], frame->linesize[0], - s->last_frame->data[0], s->last_frame->linesize[0], - x*4, y*4, xoffset, yoffset, s->avctx->width, s->avctx->height); + s->last_frame->data[0], s->last_frame->linesize[0], + x*4, y*4, xoffset, yoffset, s->avctx->width, s->avctx->height); } i++; } } -static void cmv_process_header(CmvContext *s, const uint8_t *buf, const uint8_t *buf_end) +static int cmv_process_header(CmvContext *s, const uint8_t *buf, const uint8_t *buf_end) { - int pal_start, pal_count, i; + int pal_start, pal_count, i, ret; if(buf_end - buf < 16) { av_log(s->avctx, AV_LOG_WARNING, "truncated header\n"); - return; + return AVERROR_INVALIDDATA; } s->width = AV_RL16(&buf[4]); s->height = AV_RL16(&buf[6]); if (s->avctx->width!=s->width || s->avctx->height!=s->height) { - avcodec_set_dimensions(s->avctx, s->width, s->height); av_frame_unref(s->last_frame); av_frame_unref(s->last2_frame); + ret = ff_set_dimensions(s->avctx, s->width, s->height); + if (ret < 0) + return ret; } s->avctx->time_base.num = 1; @@ -158,6 +160,8 @@ static void cmv_process_header(CmvContext *s, const uint8_t *buf, const uint8_t s->palette[i] = 0xFFU << 24 | AV_RB24(buf); buf += 3; } + + return 0; } #define EA_PREAMBLE_SIZE 8 @@ -179,7 +183,9 @@ static int cmv_decode_frame(AVCodecContext *avctx, if (AV_RL32(buf)==MVIh_TAG||AV_RB32(buf)==MVIh_TAG) { unsigned size = AV_RL32(buf + 4); - cmv_process_header(s, buf+EA_PREAMBLE_SIZE, buf_end); + ret = cmv_process_header(s, buf+EA_PREAMBLE_SIZE, buf_end); + if (ret < 0) + return ret; if (size > buf_end - buf - EA_PREAMBLE_SIZE) return -1; buf += size; @@ -225,6 +231,7 @@ static av_cold int cmv_decode_end(AVCodecContext *avctx){ AVCodec ff_eacmv_decoder = { .name = "eacmv", + .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts CMV video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_CMV, .priv_data_size = sizeof(CmvContext), @@ -232,5 +239,4 @@ AVCodec ff_eacmv_decoder = { .close = cmv_decode_end, .decode = cmv_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts CMV video"), }; diff --git a/ffmpeg/libavcodec/eamad.c b/ffmpeg/libavcodec/eamad.c index 58cdea6..2d34d35 100644 --- a/ffmpeg/libavcodec/eamad.c +++ b/ffmpeg/libavcodec/eamad.c @@ -45,7 +45,7 @@ typedef struct MadContext { AVCodecContext *avctx; DSPContext dsp; - AVFrame last_frame; + AVFrame *last_frame; GetBitContext gb; void *bitstream_buf; unsigned int bitstream_buf_size; @@ -65,6 +65,11 @@ static av_cold int decode_init(AVCodecContext *avctx) ff_init_scantable_permutation(s->dsp.idct_permutation, FF_NO_IDCT_PERM); ff_init_scantable(s->dsp.idct_permutation, &s->scantable, ff_zigzag_direct); ff_mpeg12_init_vlcs(); + + s->last_frame = av_frame_alloc(); + if (!s->last_frame) + return AVERROR(ENOMEM); + return 0; } @@ -82,22 +87,22 @@ static inline void comp_block(MadContext *t, AVFrame *frame, int j, int mv_x, int mv_y, int add) { if (j < 4) { - unsigned offset = (mb_y*16 + ((j&2)<<2) + mv_y)*t->last_frame.linesize[0] + mb_x*16 + ((j&1)<<3) + mv_x; - if (offset >= (t->avctx->height - 7) * t->last_frame.linesize[0] - 7) + unsigned offset = (mb_y*16 + ((j&2)<<2) + mv_y)*t->last_frame->linesize[0] + mb_x*16 + ((j&1)<<3) + mv_x; + if (offset >= (t->avctx->height - 7) * t->last_frame->linesize[0] - 7) return; comp(frame->data[0] + (mb_y*16 + ((j&2)<<2))*frame->linesize[0] + mb_x*16 + ((j&1)<<3), frame->linesize[0], - t->last_frame.data[0] + offset, - t->last_frame.linesize[0], add); + t->last_frame->data[0] + offset, + t->last_frame->linesize[0], add); } else if (!(t->avctx->flags & CODEC_FLAG_GRAY)) { int index = j - 3; - unsigned offset = (mb_y * 8 + (mv_y/2))*t->last_frame.linesize[index] + mb_x * 8 + (mv_x/2); - if (offset >= (t->avctx->height/2 - 7) * t->last_frame.linesize[index] - 7) + unsigned offset = (mb_y * 8 + (mv_y/2))*t->last_frame->linesize[index] + mb_x * 8 + (mv_x/2); + if (offset >= (t->avctx->height/2 - 7) * t->last_frame->linesize[index] - 7) return; comp(frame->data[index] + (mb_y*8)*frame->linesize[index] + mb_x * 8, frame->linesize[index], - t->last_frame.data[index] + offset, - t->last_frame.linesize[index], add); + t->last_frame->data[index] + offset, + t->last_frame->linesize[index], add); } } @@ -205,7 +210,7 @@ static int decode_mb(MadContext *s, AVFrame *frame, int inter) for (j=0; j<6; j++) { if (mv_map & (1<gb); - if (s->last_frame.data[0]) + if (s->last_frame->data[0]) comp_block(s, frame, s->mb_x, s->mb_y, j, mv_x, mv_y, add); } else { s->dsp.clear_block(s->block); @@ -257,29 +262,33 @@ static int decode_frame(AVCodecContext *avctx, calc_quant_matrix(s, buf[13]); buf += 16; + if (width < 16 || height < 16) { + av_log(avctx, AV_LOG_ERROR, "Dimensions too small\n"); + return AVERROR_INVALIDDATA; + } + if (avctx->width != width || avctx->height != height) { + av_frame_unref(s->last_frame); if((width * height)/2048*7 > buf_end-buf) return AVERROR_INVALIDDATA; - if ((ret = av_image_check_size(width, height, 0, avctx)) < 0) + if ((ret = ff_set_dimensions(avctx, width, height)) < 0) return ret; - avcodec_set_dimensions(avctx, width, height); - av_frame_unref(&s->last_frame); } if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; - if (inter && !s->last_frame.data[0]) { + if (inter && !s->last_frame->data[0]) { av_log(avctx, AV_LOG_WARNING, "Missing reference frame.\n"); - ret = ff_get_buffer(avctx, &s->last_frame, AV_GET_BUFFER_FLAG_REF); + ret = ff_get_buffer(avctx, s->last_frame, AV_GET_BUFFER_FLAG_REF); if (ret < 0) return ret; - memset(s->last_frame.data[0], 0, s->last_frame.height * - s->last_frame.linesize[0]); - memset(s->last_frame.data[1], 0x80, s->last_frame.height / 2 * - s->last_frame.linesize[1]); - memset(s->last_frame.data[2], 0x80, s->last_frame.height / 2 * - s->last_frame.linesize[2]); + memset(s->last_frame->data[0], 0, s->last_frame->height * + s->last_frame->linesize[0]); + memset(s->last_frame->data[1], 0x80, s->last_frame->height / 2 * + s->last_frame->linesize[1]); + memset(s->last_frame->data[2], 0x80, s->last_frame->height / 2 * + s->last_frame->linesize[2]); } av_fast_padded_malloc(&s->bitstream_buf, &s->bitstream_buf_size, @@ -298,8 +307,8 @@ static int decode_frame(AVCodecContext *avctx, *got_frame = 1; if (chunk_type != MADe_TAG) { - av_frame_unref(&s->last_frame); - if ((ret = av_frame_ref(&s->last_frame, frame)) < 0) + av_frame_unref(s->last_frame); + if ((ret = av_frame_ref(s->last_frame, frame)) < 0) return ret; } @@ -309,13 +318,14 @@ static int decode_frame(AVCodecContext *avctx, static av_cold int decode_end(AVCodecContext *avctx) { MadContext *t = avctx->priv_data; - av_frame_unref(&t->last_frame); + av_frame_free(&t->last_frame); av_free(t->bitstream_buf); return 0; } AVCodec ff_eamad_decoder = { .name = "eamad", + .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts Madcow Video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MAD, .priv_data_size = sizeof(MadContext), @@ -323,5 +333,4 @@ AVCodec ff_eamad_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts Madcow Video") }; diff --git a/ffmpeg/libavcodec/eatgq.c b/ffmpeg/libavcodec/eatgq.c index cf93c06..2950d05 100644 --- a/ffmpeg/libavcodec/eatgq.c +++ b/ffmpeg/libavcodec/eatgq.c @@ -157,7 +157,7 @@ static int tgq_decode_mb(TgqContext *s, AVFrame *frame, int mb_y, int mb_x) mode = bytestream2_get_byte(&s->gb); if (mode > 12) { GetBitContext gb; - init_get_bits(&gb, s->gb.buffer, FFMIN(bytestream2_get_bytes_left(&s->gb), mode) * 8); + init_get_bits8(&gb, s->gb.buffer, FFMIN(bytestream2_get_bytes_left(&s->gb), mode)); for (i = 0; i < 6; i++) tgq_decode_block(s, s->block[i], &gb); tgq_idct_put_mb(s, s->block, frame, mb_x, mb_y); @@ -219,9 +219,10 @@ static int tgq_decode_frame(AVCodecContext *avctx, s->height = bytestream2_get_le16u(&s->gb); } - if (s->avctx->width!=s->width || s->avctx->height!=s->height) { - avcodec_set_dimensions(s->avctx, s->width, s->height); - } + ret = ff_set_dimensions(s->avctx, s->width, s->height); + if (ret < 0) + return ret; + tgq_calculate_qtable(s, bytestream2_get_byteu(&s->gb)); bytestream2_skip(&s->gb, 3); @@ -242,11 +243,11 @@ static int tgq_decode_frame(AVCodecContext *avctx, AVCodec ff_eatgq_decoder = { .name = "eatgq", + .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TGQ video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_TGQ, .priv_data_size = sizeof(TgqContext), .init = tgq_decode_init, .decode = tgq_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TGQ video"), }; diff --git a/ffmpeg/libavcodec/eatgv.c b/ffmpeg/libavcodec/eatgv.c index 54074b3..f204a13 100644 --- a/ffmpeg/libavcodec/eatgv.c +++ b/ffmpeg/libavcodec/eatgv.c @@ -40,7 +40,7 @@ typedef struct TgvContext { AVCodecContext *avctx; - AVFrame last_frame; + AVFrame *last_frame; uint8_t *frame_buffer; int width,height; uint32_t palette[AVPALETTE_COUNT]; @@ -57,7 +57,11 @@ static av_cold int tgv_decode_init(AVCodecContext *avctx) s->avctx = avctx; avctx->time_base = (AVRational){1, 15}; avctx->pix_fmt = AV_PIX_FMT_PAL8; - avcodec_get_frame_defaults(&s->last_frame); + + s->last_frame = av_frame_alloc(); + if (!s->last_frame) + return AVERROR(ENOMEM); + return 0; } @@ -169,12 +173,19 @@ static int tgv_decode_inter(TgvContext *s, AVFrame *frame, /* allocate codebook buffers as necessary */ if (num_mvs > s->num_mvs) { - s->mv_codebook = av_realloc(s->mv_codebook, num_mvs*2*sizeof(int)); + if (av_reallocp_array(&s->mv_codebook, num_mvs, sizeof(*s->mv_codebook))) { + s->num_mvs = 0; + return AVERROR(ENOMEM); + } s->num_mvs = num_mvs; } if (num_blocks_packed > s->num_blocks_packed) { - s->block_codebook = av_realloc(s->block_codebook, num_blocks_packed*16); + int err; + if ((err = av_reallocp(&s->block_codebook, num_blocks_packed * 16)) < 0) { + s->num_blocks_packed = 0; + return err; + } s->num_blocks_packed = num_blocks_packed; } @@ -226,8 +237,8 @@ static int tgv_decode_inter(TgvContext *s, AVFrame *frame, continue; } - src = s->last_frame.data[0] + mx + my * s->last_frame.linesize[0]; - src_stride = s->last_frame.linesize[0]; + src = s->last_frame->data[0] + mx + my * s->last_frame->linesize[0]; + src_stride = s->last_frame->linesize[0]; } else { int offset = vector - num_mvs; if (offset < num_blocks_raw) @@ -275,9 +286,10 @@ static int tgv_decode_frame(AVCodecContext *avctx, s->width = AV_RL16(&buf[0]); s->height = AV_RL16(&buf[2]); if (s->avctx->width != s->width || s->avctx->height != s->height) { - avcodec_set_dimensions(s->avctx, s->width, s->height); av_freep(&s->frame_buffer); - av_frame_unref(&s->last_frame); + av_frame_unref(s->last_frame); + if ((ret = ff_set_dimensions(s->avctx, s->width, s->height)) < 0) + return ret; } pal_count = AV_RL16(&buf[6]); @@ -288,9 +300,6 @@ static int tgv_decode_frame(AVCodecContext *avctx, } } - if ((ret = av_image_check_size(s->width, s->height, 0, avctx)) < 0) - return ret; - if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; @@ -302,7 +311,7 @@ static int tgv_decode_frame(AVCodecContext *avctx, frame->pict_type = AV_PICTURE_TYPE_I; if (!s->frame_buffer && - !(s->frame_buffer = av_malloc(s->width * s->height))) + !(s->frame_buffer = av_mallocz(s->width * s->height))) return AVERROR(ENOMEM); if (unpack(buf, buf_end, s->frame_buffer, s->avctx->width, s->avctx->height) < 0) { @@ -314,7 +323,7 @@ static int tgv_decode_frame(AVCodecContext *avctx, s->frame_buffer + y * s->width, s->width); } else { - if (!s->last_frame.data[0]) { + if (!s->last_frame->data[0]) { av_log(avctx, AV_LOG_WARNING, "inter frame without corresponding intra frame\n"); return buf_size; } @@ -326,8 +335,8 @@ static int tgv_decode_frame(AVCodecContext *avctx, } } - av_frame_unref(&s->last_frame); - if ((ret = av_frame_ref(&s->last_frame, frame)) < 0) + av_frame_unref(s->last_frame); + if ((ret = av_frame_ref(s->last_frame, frame)) < 0) return ret; *got_frame = 1; @@ -338,7 +347,7 @@ static int tgv_decode_frame(AVCodecContext *avctx, static av_cold int tgv_decode_end(AVCodecContext *avctx) { TgvContext *s = avctx->priv_data; - av_frame_unref(&s->last_frame); + av_frame_free(&s->last_frame); av_freep(&s->frame_buffer); av_free(s->mv_codebook); av_free(s->block_codebook); @@ -347,12 +356,12 @@ static av_cold int tgv_decode_end(AVCodecContext *avctx) AVCodec ff_eatgv_decoder = { .name = "eatgv", + .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TGV video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_TGV, .priv_data_size = sizeof(TgvContext), .init = tgv_decode_init, .close = tgv_decode_end, .decode = tgv_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TGV video"), .capabilities = CODEC_CAP_DR1, }; diff --git a/ffmpeg/libavcodec/eatqi.c b/ffmpeg/libavcodec/eatqi.c index 1484ddc..387456a 100644 --- a/ffmpeg/libavcodec/eatqi.c +++ b/ffmpeg/libavcodec/eatqi.c @@ -111,8 +111,9 @@ static int tqi_decode_frame(AVCodecContext *avctx, tqi_calculate_qtable(s, buf[4]); buf += 8; - if (s->avctx->width!=s->width || s->avctx->height!=s->height) - avcodec_set_dimensions(s->avctx, s->width, s->height); + ret = ff_set_dimensions(s->avctx, s->width, s->height); + if (ret < 0) + return ret; if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; @@ -147,6 +148,7 @@ static av_cold int tqi_decode_end(AVCodecContext *avctx) AVCodec ff_eatqi_decoder = { .name = "eatqi", + .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TQI Video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_TQI, .priv_data_size = sizeof(TqiContext), @@ -154,5 +156,4 @@ AVCodec ff_eatqi_decoder = { .close = tqi_decode_end, .decode = tqi_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TQI Video"), }; diff --git a/ffmpeg/libavcodec/elbg.c b/ffmpeg/libavcodec/elbg.c index 2707599..5c7018b 100644 --- a/ffmpeg/libavcodec/elbg.c +++ b/ffmpeg/libavcodec/elbg.c @@ -324,7 +324,7 @@ static void do_shiftings(elbg_data *elbg) #define BIG_PRIME 433494437LL -void ff_init_elbg(int *points, int dim, int numpoints, int *codebook, +void avpriv_init_elbg(int *points, int dim, int numpoints, int *codebook, int numCB, int max_steps, int *closest_cb, AVLFG *rand_state) { @@ -339,8 +339,8 @@ void ff_init_elbg(int *points, int dim, int numpoints, int *codebook, memcpy(temp_points + i*dim, points + k*dim, dim*sizeof(int)); } - ff_init_elbg(temp_points, dim, numpoints/8, codebook, numCB, 2*max_steps, closest_cb, rand_state); - ff_do_elbg(temp_points, dim, numpoints/8, codebook, numCB, 2*max_steps, closest_cb, rand_state); + avpriv_init_elbg(temp_points, dim, numpoints/8, codebook, numCB, 2*max_steps, closest_cb, rand_state); + avpriv_do_elbg(temp_points, dim, numpoints/8, codebook, numCB, 2*max_steps, closest_cb, rand_state); av_free(temp_points); @@ -351,7 +351,7 @@ void ff_init_elbg(int *points, int dim, int numpoints, int *codebook, } -void ff_do_elbg(int *points, int dim, int numpoints, int *codebook, +void avpriv_do_elbg(int *points, int dim, int numpoints, int *codebook, int numCB, int max_steps, int *closest_cb, AVLFG *rand_state) { diff --git a/ffmpeg/libavcodec/elbg.h b/ffmpeg/libavcodec/elbg.h index e6f577e..22fb53f 100644 --- a/ffmpeg/libavcodec/elbg.h +++ b/ffmpeg/libavcodec/elbg.h @@ -37,7 +37,7 @@ * @param closest_cb Return the closest codebook to each point. Must be allocated. * @param rand_state A random number generator state. Should be already initialized by av_lfg_init(). */ -void ff_do_elbg(int *points, int dim, int numpoints, int *codebook, +void avpriv_do_elbg(int *points, int dim, int numpoints, int *codebook, int numCB, int num_steps, int *closest_cb, AVLFG *rand_state); @@ -45,10 +45,10 @@ void ff_do_elbg(int *points, int dim, int numpoints, int *codebook, * Initialize the **codebook vector for the elbg algorithm. If you have already * a codebook and you want to refine it, you shouldn't call this function. * If numpoints < 8*numCB this function fills **codebook with random numbers. - * If not, it calls ff_do_elbg for a (smaller) random sample of the points in - * **points. Get the same parameters as ff_do_elbg. + * If not, it calls avpriv_do_elbg for a (smaller) random sample of the points in + * **points. Get the same parameters as avpriv_do_elbg. */ -void ff_init_elbg(int *points, int dim, int numpoints, int *codebook, +void avpriv_init_elbg(int *points, int dim, int numpoints, int *codebook, int numCB, int num_steps, int *closest_cb, AVLFG *rand_state); diff --git a/ffmpeg/libavcodec/error_resilience.c b/ffmpeg/libavcodec/error_resilience.c index cdd28ab..ebd671a 100644 --- a/ffmpeg/libavcodec/error_resilience.c +++ b/ffmpeg/libavcodec/error_resilience.c @@ -27,11 +27,13 @@ #include +#include "libavutil/internal.h" #include "avcodec.h" #include "error_resilience.h" #include "mpegvideo.h" #include "rectangle.h" #include "thread.h" +#include "version.h" /** * @param stride the number of MVs to get to the next row @@ -236,7 +238,7 @@ static void h_block_filter(ERContext *s, uint8_t *dst, int w, int h, int stride, int is_luma) { int b_x, b_y, mvx_stride, mvy_stride; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; set_mv_strides(s, &mvx_stride, &mvy_stride); mvx_stride >>= is_luma; mvy_stride *= mvx_stride; @@ -304,7 +306,7 @@ static void v_block_filter(ERContext *s, uint8_t *dst, int w, int h, int stride, int is_luma) { int b_x, b_y, mvx_stride, mvy_stride; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; set_mv_strides(s, &mvx_stride, &mvy_stride); mvx_stride >>= is_luma; mvy_stride *= mvx_stride; @@ -698,8 +700,8 @@ static int is_intra_more_likely(ERContext *s) return 0; // almost all MBs damaged -> use temporal prediction // prevent dsp.sad() check, that requires access to the image - if (CONFIG_MPEG_XVMC_DECODER && - s->avctx->xvmc_acceleration && + if (CONFIG_XVMC && + s->avctx->hwaccel && s->avctx->hwaccel->decode_mb && s->cur_pic->f.pict_type == AV_PICTURE_TYPE_I) return 1; @@ -747,13 +749,13 @@ static int is_intra_more_likely(ERContext *s) } } } - // printf("is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type); +// av_log(NULL, AV_LOG_ERROR, "is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type); return is_intra_likely > 0; } void ff_er_frame_start(ERContext *s) { - if (!s->avctx->err_recognition) + if (!s->avctx->error_concealment) return; memset(s->error_status_table, ER_MB_ERROR | VP_START | ER_MB_END, @@ -762,6 +764,17 @@ void ff_er_frame_start(ERContext *s) s->error_occurred = 0; } +static int er_supported(ERContext *s) +{ + if(s->avctx->hwaccel && s->avctx->hwaccel->decode_slice || + s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU || + !s->cur_pic || + s->cur_pic->field_picture + ) + return 0; + return 1; +} + /** * Add a slice. * @param endx x component of the last macroblock, can be -1 @@ -778,7 +791,7 @@ void ff_er_add_slice(ERContext *s, int startx, int starty, const int end_xy = s->mb_index2xy[end_i]; int mask = -1; - if (s->avctx->hwaccel) + if (s->avctx->hwaccel && s->avctx->hwaccel->decode_slice) return; if (start_i > end_i || start_xy > end_xy) { @@ -787,7 +800,7 @@ void ff_er_add_slice(ERContext *s, int startx, int starty, return; } - if (!s->avctx->err_recognition) + if (!s->avctx->error_concealment) return; mask &= ~VP_START; @@ -828,7 +841,7 @@ void ff_er_add_slice(ERContext *s, int startx, int starty, s->error_status_table[start_xy] |= VP_START; if (start_xy > 0 && !(s->avctx->active_thread_type & FF_THREAD_SLICE) && - s->avctx->skip_top * s->mb_width < start_i) { + er_supported(s) && s->avctx->skip_top * s->mb_width < start_i) { int prev_status = s->error_status_table[s->mb_index2xy[start_i - 1]]; prev_status &= ~ VP_START; @@ -851,15 +864,28 @@ void ff_er_frame_end(ERContext *s) /* We do not support ER of field pictures yet, * though it should not crash if enabled. */ - if (!s->avctx->err_recognition || s->error_count == 0 || + if (!s->avctx->error_concealment || s->error_count == 0 || s->avctx->lowres || - s->avctx->hwaccel || - s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU || - !s->cur_pic || s->cur_pic->field_picture || + !er_supported(s) || s->error_count == 3 * s->mb_width * (s->avctx->skip_top + s->avctx->skip_bottom)) { return; } + for (mb_x = 0; mb_x < s->mb_width; mb_x++) { + int status = s->error_status_table[mb_x + (s->mb_height - 1) * s->mb_stride]; + if (status != 0x7F) + break; + } + + if ( mb_x == s->mb_width + && s->avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO + && (s->avctx->height&16) + && s->error_count == 3 * s->mb_width * (s->avctx->skip_top + s->avctx->skip_bottom + 1) + ) { + av_log(s->avctx, AV_LOG_DEBUG, "ignoring last missing slice\n"); + return; + } + if (s->last_pic) { if (s->last_pic->f.width != s->cur_pic->f.width || s->last_pic->f.height != s->cur_pic->f.height || @@ -1158,8 +1184,8 @@ void ff_er_frame_end(ERContext *s) } else guess_mv(s); - /* the filters below are not XvMC compatible, skip them */ - if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration) + /* the filters below manipulate raw image, skip them */ + if (CONFIG_XVMC && s->avctx->hwaccel && s->avctx->hwaccel->decode_mb) goto ec_clean; /* fill DC for inter blocks */ for (mb_y = 0; mb_y < s->mb_height; mb_y++) { diff --git a/ffmpeg/libavcodec/escape124.c b/ffmpeg/libavcodec/escape124.c index 3c83e58..bed1efb 100644 --- a/ffmpeg/libavcodec/escape124.c +++ b/ffmpeg/libavcodec/escape124.c @@ -42,17 +42,13 @@ typedef struct CodeBook { } CodeBook; typedef struct Escape124Context { - AVFrame frame; + AVFrame *frame; unsigned num_superblocks; CodeBook codebooks[3]; } Escape124Context; -static int can_safely_read(GetBitContext* gb, uint64_t bits) { - return get_bits_left(gb) >= bits; -} - /** * Initialize the decoder * @param avctx decoder context @@ -62,12 +58,15 @@ static av_cold int escape124_decode_init(AVCodecContext *avctx) { Escape124Context *s = avctx->priv_data; - avcodec_get_frame_defaults(&s->frame); avctx->pix_fmt = AV_PIX_FMT_RGB555; s->num_superblocks = ((unsigned)avctx->width / 8) * ((unsigned)avctx->height / 8); + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); + return 0; } @@ -79,7 +78,7 @@ static av_cold int escape124_decode_close(AVCodecContext *avctx) for (i = 0; i < 3; i++) av_free(s->codebooks[i].blocks); - av_frame_unref(&s->frame); + av_frame_free(&s->frame); return 0; } @@ -90,7 +89,7 @@ static CodeBook unpack_codebook(GetBitContext* gb, unsigned depth, unsigned i, j; CodeBook cb = { 0 }; - if (!can_safely_read(gb, (uint64_t)size * 34)) + if (size >= INT_MAX / 34 || get_bits_left(gb) < size * 34) return cb; if (size >= INT_MAX / sizeof(MacroBlock)) @@ -121,7 +120,7 @@ static unsigned decode_skip_count(GetBitContext* gb) unsigned value; // This function reads a maximum of 23 bits, // which is within the padding space - if (!can_safely_read(gb, 1)) + if (get_bits_left(gb) < 1) return -1; value = get_bits1(gb); if (!value) @@ -200,7 +199,6 @@ static int escape124_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; Escape124Context *s = avctx->priv_data; AVFrame *frame = data; @@ -218,11 +216,12 @@ static int escape124_decode_frame(AVCodecContext *avctx, int ret; - init_get_bits(&gb, buf, buf_size * 8); + if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0) + return ret; // This call also guards the potential depth reads for the // codebook unpacking. - if (!can_safely_read(&gb, 64)) + if (get_bits_left(&gb) < 64) return -1; frame_flags = get_bits_long(&gb, 32); @@ -231,13 +230,13 @@ static int escape124_decode_frame(AVCodecContext *avctx, // Leave last frame unchanged // FIXME: Is this necessary? I haven't seen it in any real samples if (!(frame_flags & 0x114) || !(frame_flags & 0x7800000)) { - if (!s->frame.data[0]) + if (!s->frame->data[0]) return AVERROR_INVALIDDATA; - av_log(NULL, AV_LOG_DEBUG, "Skipping frame\n"); + av_log(avctx, AV_LOG_DEBUG, "Skipping frame\n"); *got_frame = 1; - if ((ret = av_frame_ref(frame, &s->frame)) < 0) + if ((ret = av_frame_ref(frame, s->frame)) < 0) return ret; return frame_size; @@ -276,8 +275,8 @@ static int escape124_decode_frame(AVCodecContext *avctx, new_frame_data = (uint16_t*)frame->data[0]; new_stride = frame->linesize[0] / 2; - old_frame_data = (uint16_t*)s->frame.data[0]; - old_stride = s->frame.linesize[0] / 2; + old_frame_data = (uint16_t*)s->frame->data[0]; + old_stride = s->frame->linesize[0] / 2; for (superblock_index = 0; superblock_index < s->num_superblocks; superblock_index++) { @@ -298,7 +297,7 @@ static int escape124_decode_frame(AVCodecContext *avctx, copy_superblock(sb.pixels, 8, old_frame_data, old_stride); - while (can_safely_read(&gb, 1) && !get_bits1(&gb)) { + while (get_bits_left(&gb) >= 1 && !get_bits1(&gb)) { unsigned mask; mb = decode_macroblock(s, &gb, &cb_index, superblock_index); mask = get_bits(&gb, 16); @@ -310,7 +309,7 @@ static int escape124_decode_frame(AVCodecContext *avctx, } } - if (can_safely_read(&gb, 1) && !get_bits1(&gb)) { + if (!get_bits1(&gb)) { unsigned inv_mask = get_bits(&gb, 4); for (i = 0; i < 4; i++) { if (inv_mask & (1 << i)) { @@ -322,15 +321,13 @@ static int escape124_decode_frame(AVCodecContext *avctx, for (i = 0; i < 16; i++) { if (multi_mask & mask_matrix[i]) { - if (!can_safely_read(&gb, 1)) - break; mb = decode_macroblock(s, &gb, &cb_index, superblock_index); insert_mb_into_sb(&sb, mb, i); } } } else if (frame_flags & (1 << 16)) { - while (can_safely_read(&gb, 1) && !get_bits1(&gb)) { + while (get_bits_left(&gb) >= 1 && !get_bits1(&gb)) { mb = decode_macroblock(s, &gb, &cb_index, superblock_index); insert_mb_into_sb(&sb, mb, get_bits(&gb, 4)); } @@ -352,12 +349,12 @@ static int escape124_decode_frame(AVCodecContext *avctx, skip--; } - av_log(NULL, AV_LOG_DEBUG, + av_log(avctx, AV_LOG_DEBUG, "Escape sizes: %i, %i, %i\n", frame_size, buf_size, get_bits_count(&gb) / 8); - av_frame_unref(&s->frame); - if ((ret = av_frame_ref(&s->frame, frame)) < 0) + av_frame_unref(s->frame); + if ((ret = av_frame_ref(s->frame, frame)) < 0) return ret; *got_frame = 1; @@ -368,6 +365,7 @@ static int escape124_decode_frame(AVCodecContext *avctx, AVCodec ff_escape124_decoder = { .name = "escape124", + .long_name = NULL_IF_CONFIG_SMALL("Escape 124"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_ESCAPE124, .priv_data_size = sizeof(Escape124Context), @@ -375,5 +373,4 @@ AVCodec ff_escape124_decoder = { .close = escape124_decode_close, .decode = escape124_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Escape 124"), }; diff --git a/ffmpeg/libavcodec/escape130.c b/ffmpeg/libavcodec/escape130.c index d24af79..466b2b5 100644 --- a/ffmpeg/libavcodec/escape130.c +++ b/ffmpeg/libavcodec/escape130.c @@ -1,5 +1,5 @@ /* - * Escape 130 Video Decoder + * Escape 130 video decoder * Copyright (C) 2008 Eli Friedman (eli.friedman gmail.com) * * This file is part of FFmpeg. @@ -19,35 +19,134 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/attributes.h" +#include "libavutil/mem.h" #include "avcodec.h" - #define BITSTREAM_READER_LE #include "get_bits.h" #include "internal.h" - typedef struct Escape130Context { - AVFrame frame; - uint8_t *bases; + uint8_t *old_y_avg; + + uint8_t *new_y, *old_y; + uint8_t *new_u, *old_u; + uint8_t *new_v, *old_v; + + uint8_t *buf1, *buf2; + int linesize[3]; } Escape130Context; -/** - * Initialize the decoder - * @param avctx decoder context - * @return 0 success, negative on error - */ +static const uint8_t offset_table[] = { 2, 4, 10, 20 }; +static const int8_t sign_table[64][4] = { + { 0, 0, 0, 0 }, + { -1, 1, 0, 0 }, + { 1, -1, 0, 0 }, + { -1, 0, 1, 0 }, + { -1, 1, 1, 0 }, + { 0, -1, 1, 0 }, + { 1, -1, 1, 0 }, + { -1, -1, 1, 0 }, + { 1, 0, -1, 0 }, + { 0, 1, -1, 0 }, + { 1, 1, -1, 0 }, + { -1, 1, -1, 0 }, + { 1, -1, -1, 0 }, + { -1, 0, 0, 1 }, + { -1, 1, 0, 1 }, + { 0, -1, 0, 1 }, + + { 0, 0, 0, 0 }, + { 1, -1, 0, 1 }, + { -1, -1, 0, 1 }, + { -1, 0, 1, 1 }, + { -1, 1, 1, 1 }, + { 0, -1, 1, 1 }, + { 1, -1, 1, 1 }, + { -1, -1, 1, 1 }, + { 0, 0, -1, 1 }, + { 1, 0, -1, 1 }, + { -1, 0, -1, 1 }, + { 0, 1, -1, 1 }, + { 1, 1, -1, 1 }, + { -1, 1, -1, 1 }, + { 0, -1, -1, 1 }, + { 1, -1, -1, 1 }, + + { 0, 0, 0, 0 }, + { -1, -1, -1, 1 }, + { 1, 0, 0, -1 }, + { 0, 1, 0, -1 }, + { 1, 1, 0, -1 }, + { -1, 1, 0, -1 }, + { 1, -1, 0, -1 }, + { 0, 0, 1, -1 }, + { 1, 0, 1, -1 }, + { -1, 0, 1, -1 }, + { 0, 1, 1, -1 }, + { 1, 1, 1, -1 }, + { -1, 1, 1, -1 }, + { 0, -1, 1, -1 }, + { 1, -1, 1, -1 }, + { -1, -1, 1, -1 }, + + { 0, 0, 0, 0 }, + { 1, 0, -1, -1 }, + { 0, 1, -1, -1 }, + { 1, 1, -1, -1 }, + { -1, 1, -1, -1 }, + { 1, -1, -1, -1 } +}; + +static const int8_t luma_adjust[] = { -4, -3, -2, -1, 1, 2, 3, 4 }; + +static const int8_t chroma_adjust[2][8] = { + { 1, 1, 0, -1, -1, -1, 0, 1 }, + { 0, 1, 1, 1, 0, -1, -1, -1 } +}; + +static const uint8_t chroma_vals[] = { + 20, 28, 36, 44, 52, 60, 68, 76, + 84, 92, 100, 106, 112, 116, 120, 124, + 128, 132, 136, 140, 144, 150, 156, 164, + 172, 180, 188, 196, 204, 212, 220, 228 +}; + static av_cold int escape130_decode_init(AVCodecContext *avctx) { Escape130Context *s = avctx->priv_data; avctx->pix_fmt = AV_PIX_FMT_YUV420P; - avcodec_get_frame_defaults(&s->frame); - if((avctx->width&1) || (avctx->height&1)){ - av_log(avctx, AV_LOG_ERROR, "Dimensions are not a multiple of the block size\n"); - return AVERROR(EINVAL); + if ((avctx->width & 1) || (avctx->height & 1)) { + av_log(avctx, AV_LOG_ERROR, + "Dimensions should be a multiple of two.\n"); + return AVERROR_INVALIDDATA; } - s->bases= av_malloc(avctx->width * avctx->height /4); + s->old_y_avg = av_malloc(avctx->width * avctx->height / 4); + s->buf1 = av_malloc(avctx->width * avctx->height * 3 / 2); + s->buf2 = av_malloc(avctx->width * avctx->height * 3 / 2); + if (!s->old_y_avg || !s->buf1 || !s->buf2) { + av_freep(&s->old_y_avg); + av_freep(&s->buf1); + av_freep(&s->buf2); + av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n"); + return AVERROR(ENOMEM); + } + + s->linesize[0] = avctx->width; + s->linesize[1] = + s->linesize[2] = avctx->width / 2; + + s->new_y = s->buf1; + s->new_u = s->new_y + avctx->width * avctx->height; + s->new_v = s->new_u + avctx->width * avctx->height / 4; + s->old_y = s->buf2; + s->old_u = s->old_y + avctx->width * avctx->height; + s->old_v = s->old_u + avctx->width * avctx->height / 4; + memset(s->old_y, 0, avctx->width * avctx->height); + memset(s->old_u, 0x10, avctx->width * avctx->height / 4); + memset(s->old_v, 0x10, avctx->width * avctx->height / 4); return 0; } @@ -56,17 +155,17 @@ static av_cold int escape130_decode_close(AVCodecContext *avctx) { Escape130Context *s = avctx->priv_data; - av_frame_unref(&s->frame); - - av_freep(&s->bases); + av_freep(&s->old_y_avg); + av_freep(&s->buf1); + av_freep(&s->buf2); return 0; } -static unsigned decode_skip_count(GetBitContext* gb) { - unsigned value; - // This function reads a maximum of 27 bits, - // which is within the padding space +static int decode_skip_count(GetBitContext* gb) +{ + int value; + if (get_bits_left(gb) < 1+3) return -1; @@ -89,165 +188,88 @@ static unsigned decode_skip_count(GetBitContext* gb) { return -1; } -/** - * Decode a single frame - * @param avctx decoder context - * @param data decoded frame - * @param got_frame have decoded frame - * @param buf input buffer - * @param buf_size input buffer size - * @return 0 success, -1 on error - */ -static int escape130_decode_frame(AVCodecContext *avctx, - void *data, int *got_frame, - AVPacket *avpkt) +static int escape130_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame, AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; + int buf_size = avpkt->size; Escape130Context *s = avctx->priv_data; - + AVFrame *pic = data; GetBitContext gb; - unsigned i; int ret; uint8_t *old_y, *old_cb, *old_cr, *new_y, *new_cb, *new_cr; + uint8_t *dstY, *dstU, *dstV; unsigned old_y_stride, old_cb_stride, old_cr_stride, new_y_stride, new_cb_stride, new_cr_stride; unsigned total_blocks = avctx->width * avctx->height / 4, - block_index, row_index = 0; - unsigned y[4] = {0}, cb = 16, cr = 16; - unsigned skip = -1; - unsigned y_base = 0; - uint8_t *yb= s->bases; - - AVFrame *frame = data; - - init_get_bits(&gb, buf, buf_size * 8); - - if (get_bits_left(&gb) < 128) - return -1; - - // Header; no useful information in here - skip_bits_long(&gb, 128); + block_index, block_x = 0; + unsigned y[4] = { 0 }, cb = 0x10, cr = 0x10; + int skip = -1, y_avg = 0, i, j; + uint8_t *ya = s->old_y_avg; + + // first 16 bytes are header; no useful information in here + if (buf_size <= 16) { + av_log(avctx, AV_LOG_ERROR, "Insufficient frame data\n"); + return AVERROR_INVALIDDATA; + } - if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) + if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) return ret; - new_y = frame->data[0]; - new_cb = frame->data[1]; - new_cr = frame->data[2]; - new_y_stride = frame->linesize[0]; - new_cb_stride = frame->linesize[1]; - new_cr_stride = frame->linesize[2]; - old_y = s->frame.data[0]; - old_cb = s->frame.data[1]; - old_cr = s->frame.data[2]; - old_y_stride = s->frame.linesize[0]; - old_cb_stride = s->frame.linesize[1]; - old_cr_stride = s->frame.linesize[2]; - - av_log(avctx, AV_LOG_DEBUG, - "Strides: %i, %i\n", - new_y_stride, new_cb_stride); + if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0) + return ret; + skip_bits_long(&gb, 16 * 8); + + new_y = s->new_y; + new_cb = s->new_u; + new_cr = s->new_v; + new_y_stride = s->linesize[0]; + new_cb_stride = s->linesize[1]; + new_cr_stride = s->linesize[2]; + old_y = s->old_y; + old_cb = s->old_u; + old_cr = s->old_v; + old_y_stride = s->linesize[0]; + old_cb_stride = s->linesize[1]; + old_cr_stride = s->linesize[2]; for (block_index = 0; block_index < total_blocks; block_index++) { // Note that this call will make us skip the rest of the blocks - // if the frame prematurely ends + // if the frame ends prematurely. if (skip == -1) skip = decode_skip_count(&gb); + if (skip == -1) { + av_log(avctx, AV_LOG_ERROR, "Error decoding skip value\n"); + return AVERROR_INVALIDDATA; + } if (skip) { - if (old_y) { - y[0] = old_y[0] / 4; - y[1] = old_y[1] / 4; - y[2] = old_y[old_y_stride] / 4; - y[3] = old_y[old_y_stride+1] / 4; - y_base= yb[0]; - cb = old_cb[0] / 8; - cr = old_cr[0] / 8; - } else { - y_base=y[0] = y[1] = y[2] = y[3] = 0; - cb = cr = 16; - } + y[0] = old_y[0]; + y[1] = old_y[1]; + y[2] = old_y[old_y_stride]; + y[3] = old_y[old_y_stride + 1]; + y_avg = ya[0]; + cb = old_cb[0]; + cr = old_cr[0]; } else { if (get_bits1(&gb)) { - static const uint8_t offset_table[] = {2, 4, 10, 20}; - static const int8_t sign_table[64][4] = - { {0, 0, 0, 0}, - {-1, 1, 0, 0}, - {1, -1, 0, 0}, - {-1, 0, 1, 0}, - {-1, 1, 1, 0}, - {0, -1, 1, 0}, - {1, -1, 1, 0}, - {-1, -1, 1, 0}, - {1, 0, -1, 0}, - {0, 1, -1, 0}, - {1, 1, -1, 0}, - {-1, 1, -1, 0}, - {1, -1, -1, 0}, - {-1, 0, 0, 1}, - {-1, 1, 0, 1}, - {0, -1, 0, 1}, - - {0, 0, 0, 0}, - {1, -1, 0, 1}, - {-1, -1, 0, 1}, - {-1, 0, 1, 1}, - {-1, 1, 1, 1}, - {0, -1, 1, 1}, - {1, -1, 1, 1}, - {-1, -1, 1, 1}, - {0, 0, -1, 1}, - {1, 0, -1, 1}, - {-1, 0, -1, 1}, - {0, 1, -1, 1}, - {1, 1, -1, 1}, - {-1, 1, -1, 1}, - {0, -1, -1, 1}, - {1, -1, -1, 1}, - - {0, 0, 0, 0}, - {-1, -1, -1, 1}, - {1, 0, 0, -1}, - {0, 1, 0, -1}, - {1, 1, 0, -1}, - {-1, 1, 0, -1}, - {1, -1, 0, -1}, - {0, 0, 1, -1}, - {1, 0, 1, -1}, - {-1, 0, 1, -1}, - {0, 1, 1, -1}, - {1, 1, 1, -1}, - {-1, 1, 1, -1}, - {0, -1, 1, -1}, - {1, -1, 1, -1}, - {-1, -1, 1, -1}, - - {0, 0, 0, 0}, - {1, 0, -1, -1}, - {0, 1, -1, -1}, - {1, 1, -1, -1}, - {-1, 1, -1, -1}, - {1, -1, -1, -1} }; - unsigned sign_selector = get_bits(&gb, 6); + unsigned sign_selector = get_bits(&gb, 6); unsigned difference_selector = get_bits(&gb, 2); - y_base = 2 * get_bits(&gb, 5); + y_avg = 2 * get_bits(&gb, 5); for (i = 0; i < 4; i++) { - y[i] = av_clip((int)y_base + offset_table[difference_selector] * - sign_table[sign_selector][i], 0, 63); + y[i] = av_clip(y_avg + offset_table[difference_selector] * + sign_table[sign_selector][i], 0, 63); } } else if (get_bits1(&gb)) { if (get_bits1(&gb)) { - y_base = get_bits(&gb, 6); + y_avg = get_bits(&gb, 6); } else { unsigned adjust_index = get_bits(&gb, 3); - static const int8_t adjust[] = {-4, -3, -2, -1, 1, 2, 3, 4}; - y_base = (y_base + adjust[adjust_index]) & 63; + y_avg = (y_avg + luma_adjust[adjust_index]) & 63; } for (i = 0; i < 4; i++) - y[i] = y_base; + y[i] = y_avg; } if (get_bits1(&gb)) { @@ -256,58 +278,78 @@ static int escape130_decode_frame(AVCodecContext *avctx, cr = get_bits(&gb, 5); } else { unsigned adjust_index = get_bits(&gb, 3); - static const int8_t adjust[2][8] = - { { 1, 1, 0, -1, -1, -1, 0, 1 }, - { 0, 1, 1, 1, 0, -1, -1, -1 } }; - cb = (cb + adjust[0][adjust_index]) & 31; - cr = (cr + adjust[1][adjust_index]) & 31; + cb = (cb + chroma_adjust[0][adjust_index]) & 31; + cr = (cr + chroma_adjust[1][adjust_index]) & 31; } } } - *yb++= y_base; - - new_y[0] = y[0] * 4; - new_y[1] = y[1] * 4; - new_y[new_y_stride] = y[2] * 4; - new_y[new_y_stride + 1] = y[3] * 4; - *new_cb = cb * 8; - *new_cr = cr * 8; - - if (old_y) - old_y += 2, old_cb++, old_cr++; - new_y += 2, new_cb++, new_cr++; - row_index++; - if (avctx->width / 2 == row_index) { - row_index = 0; - if (old_y) { - old_y += old_y_stride * 2 - avctx->width; - old_cb += old_cb_stride - avctx->width / 2; - old_cr += old_cr_stride - avctx->width / 2; - } + *ya++ = y_avg; + + new_y[0] = y[0]; + new_y[1] = y[1]; + new_y[new_y_stride] = y[2]; + new_y[new_y_stride + 1] = y[3]; + *new_cb = cb; + *new_cr = cr; + + old_y += 2; + old_cb++; + old_cr++; + new_y += 2; + new_cb++; + new_cr++; + block_x++; + if (block_x * 2 == avctx->width) { + block_x = 0; + old_y += old_y_stride * 2 - avctx->width; + old_cb += old_cb_stride - avctx->width / 2; + old_cr += old_cr_stride - avctx->width / 2; new_y += new_y_stride * 2 - avctx->width; - new_cb += new_cb_stride - avctx->width / 2; - new_cr += new_cr_stride - avctx->width / 2; + new_cb += new_cb_stride - avctx->width / 2; + new_cr += new_cr_stride - avctx->width / 2; } skip--; } - av_log(avctx, AV_LOG_DEBUG, - "Escape sizes: %i, %i\n", - buf_size, get_bits_count(&gb) / 8); + new_y = s->new_y; + new_cb = s->new_u; + new_cr = s->new_v; + dstY = pic->data[0]; + dstU = pic->data[1]; + dstV = pic->data[2]; + for (j = 0; j < avctx->height; j++) { + for (i = 0; i < avctx->width; i++) + dstY[i] = new_y[i] << 2; + dstY += pic->linesize[0]; + new_y += new_y_stride; + } + for (j = 0; j < avctx->height / 2; j++) { + for (i = 0; i < avctx->width / 2; i++) { + dstU[i] = chroma_vals[new_cb[i]]; + dstV[i] = chroma_vals[new_cr[i]]; + } + dstU += pic->linesize[1]; + dstV += pic->linesize[2]; + new_cb += new_cb_stride; + new_cr += new_cr_stride; + } - av_frame_unref(&s->frame); - if ((ret = av_frame_ref(&s->frame, frame)) < 0) - return ret; + av_dlog(avctx, "Frame data: provided %d bytes, used %d bytes\n", + buf_size, get_bits_count(&gb) >> 3); + + FFSWAP(uint8_t*, s->old_y, s->new_y); + FFSWAP(uint8_t*, s->old_u, s->new_u); + FFSWAP(uint8_t*, s->old_v, s->new_v); *got_frame = 1; return buf_size; } - AVCodec ff_escape130_decoder = { .name = "escape130", + .long_name = NULL_IF_CONFIG_SMALL("Escape 130"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_ESCAPE130, .priv_data_size = sizeof(Escape130Context), @@ -315,5 +357,4 @@ AVCodec ff_escape130_decoder = { .close = escape130_decode_close, .decode = escape130_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Escape 130"), }; diff --git a/ffmpeg/libavcodec/evrcdec.c b/ffmpeg/libavcodec/evrcdec.c index 7691455..51ae9e2 100644 --- a/ffmpeg/libavcodec/evrcdec.c +++ b/ffmpeg/libavcodec/evrcdec.c @@ -374,7 +374,7 @@ static void bl_intrp(EVRCContext *e, float *ex, float delay) int offset, i, coef_idx; int16_t t; - offset = lrintf(fabs(delay)); + offset = lrintf(delay); t = (offset - delay + 0.5) * 8.0 + 0.5; if (t == 8) { @@ -640,7 +640,7 @@ static void postfilter(EVRCContext *e, float *in, const float *coeff, /* Short term postfilter */ synthesis_filter(temp, wcoef2, e->postfilter_iir, length, out); - memcpy(e->postfilter_residual, + memmove(e->postfilter_residual, e->postfilter_residual + length, ACB_SIZE * sizeof(float)); } @@ -714,7 +714,7 @@ static void frame_erasure(EVRCContext *e, float *samples) e->pitch[ACB_SIZE + j] = e->energy_vector[i]; } - memcpy(e->pitch, e->pitch + subframe_size, ACB_SIZE * sizeof(float)); + memmove(e->pitch, e->pitch + subframe_size, ACB_SIZE * sizeof(float)); if (e->bitrate != RATE_QUANT && e->avg_acb_gain < 0.4) { f = 0.1 * e->avg_fcb_gain; @@ -814,7 +814,7 @@ static int evrc_decode_frame(AVCodecContext *avctx, void *data, interpolate_delay(idelay, delay, e->prev_pitch_delay, i); acb_excitation(e, e->pitch + ACB_SIZE, e->avg_acb_gain, idelay, subframe_size); - memcpy(e->pitch, e->pitch + subframe_size, ACB_SIZE * sizeof(float)); + memmove(e->pitch, e->pitch + subframe_size, ACB_SIZE * sizeof(float)); } } @@ -872,7 +872,7 @@ static int evrc_decode_frame(AVCodecContext *avctx, void *data, e->pitch[ACB_SIZE + j] = e->energy_vector[i]; } - memcpy(e->pitch, e->pitch + subframe_size, ACB_SIZE * sizeof(float)); + memmove(e->pitch, e->pitch + subframe_size, ACB_SIZE * sizeof(float)); synthesis_filter(e->pitch + ACB_SIZE, ilpc, e->synthesis, subframe_size, tmp); @@ -907,11 +907,11 @@ erasure: AVCodec ff_evrc_decoder = { .name = "evrc", + .long_name = NULL_IF_CONFIG_SMALL("EVRC (Enhanced Variable Rate Codec)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_EVRC, .init = evrc_decode_init, .decode = evrc_decode_frame, .capabilities = CODEC_CAP_DR1, .priv_data_size = sizeof(EVRCContext), - .long_name = NULL_IF_CONFIG_SMALL("EVRC (Enhanced Variable Rate Codec)"), }; diff --git a/ffmpeg/libavcodec/exr.c b/ffmpeg/libavcodec/exr.c index af1bee0..f231b70 100644 --- a/ffmpeg/libavcodec/exr.c +++ b/ffmpeg/libavcodec/exr.c @@ -32,8 +32,10 @@ #include +#include "get_bits.h" #include "avcodec.h" #include "bytestream.h" +#include "internal.h" #include "mathops.h" #include "thread.h" #include "libavutil/imgutils.h" @@ -67,6 +69,9 @@ typedef struct EXRThreadData { uint8_t *tmp; int tmp_size; + + uint8_t *bitmap; + uint16_t *lut; } EXRThreadData; typedef struct EXRContext { @@ -277,6 +282,461 @@ static int rle_uncompress(const uint8_t *src, int compressed_size, return 0; } +#define USHORT_RANGE (1 << 16) +#define BITMAP_SIZE (1 << 13) + +static uint16_t reverse_lut(const uint8_t *bitmap, uint16_t *lut) +{ + int i, k = 0; + + for (i = 0; i < USHORT_RANGE; i++) { + if ((i == 0) || (bitmap[i >> 3] & (1 << (i & 7)))) + lut[k++] = i; + } + + i = k - 1; + + memset(lut + k, 0, (USHORT_RANGE - k) * 2); + + return i; +} + +static void apply_lut(const uint16_t *lut, uint16_t *dst, int dsize) +{ + int i; + + for (i = 0; i < dsize; ++i) + dst[i] = lut[dst[i]]; +} + +#define HUF_ENCBITS 16 // literal (value) bit length +#define HUF_DECBITS 14 // decoding bit size (>= 8) + +#define HUF_ENCSIZE ((1 << HUF_ENCBITS) + 1) // encoding table size +#define HUF_DECSIZE (1 << HUF_DECBITS) // decoding table size +#define HUF_DECMASK (HUF_DECSIZE - 1) + +typedef struct HufDec { + int len; + int lit; + int *p; +} HufDec; + +static void huf_canonical_code_table(uint64_t *hcode) +{ + uint64_t c, n[59] = { 0 }; + int i; + + for (i = 0; i < HUF_ENCSIZE; ++i) + n[hcode[i]] += 1; + + c = 0; + for (i = 58; i > 0; --i) { + uint64_t nc = ((c + n[i]) >> 1); + n[i] = c; + c = nc; + } + + for (i = 0; i < HUF_ENCSIZE; ++i) { + int l = hcode[i]; + + if (l > 0) + hcode[i] = l | (n[l]++ << 6); + } +} + +#define SHORT_ZEROCODE_RUN 59 +#define LONG_ZEROCODE_RUN 63 +#define SHORTEST_LONG_RUN (2 + LONG_ZEROCODE_RUN - SHORT_ZEROCODE_RUN) +#define LONGEST_LONG_RUN (255 + SHORTEST_LONG_RUN) + +static int huf_unpack_enc_table(GetByteContext *gb, + int32_t im, int32_t iM, uint64_t *hcode) +{ + GetBitContext gbit; + + init_get_bits8(&gbit, gb->buffer, bytestream2_get_bytes_left(gb)); + + for (; im <= iM; im++) { + uint64_t l = hcode[im] = get_bits(&gbit, 6); + + if (l == LONG_ZEROCODE_RUN) { + int zerun = get_bits(&gbit, 8) + SHORTEST_LONG_RUN; + + if (im + zerun > iM + 1) + return AVERROR_INVALIDDATA; + + while (zerun--) + hcode[im++] = 0; + + im--; + } else if (l >= (uint64_t) SHORT_ZEROCODE_RUN) { + int zerun = l - SHORT_ZEROCODE_RUN + 2; + + if (im + zerun > iM + 1) + return AVERROR_INVALIDDATA; + + while (zerun--) + hcode[im++] = 0; + + im--; + } + } + + bytestream2_skip(gb, (get_bits_count(&gbit) + 7) / 8); + huf_canonical_code_table(hcode); + + return 0; +} + +static int huf_build_dec_table(const uint64_t *hcode, int im, + int iM, HufDec *hdecod) +{ + for (; im <= iM; im++) { + uint64_t c = hcode[im] >> 6; + int i, l = hcode[im] & 63; + + if (c >> l) + return AVERROR_INVALIDDATA; + + if (l > HUF_DECBITS) { + HufDec *pl = hdecod + (c >> (l - HUF_DECBITS)); + if (pl->len) + return AVERROR_INVALIDDATA; + + pl->lit++; + + pl->p = av_realloc_f(pl->p, pl->lit, sizeof(int)); + if (!pl->p) + return AVERROR(ENOMEM); + + pl->p[pl->lit - 1] = im; + } else if (l) { + HufDec *pl = hdecod + (c << (HUF_DECBITS - l)); + + for (i = 1 << (HUF_DECBITS - l); i > 0; i--, pl++) { + if (pl->len || pl->p) + return AVERROR_INVALIDDATA; + pl->len = l; + pl->lit = im; + } + } + } + + return 0; +} + +#define get_char(c, lc, gb) { \ + c = (c << 8) | bytestream2_get_byte(gb); \ + lc += 8; \ +} + +#define get_code(po, rlc, c, lc, gb, out, oe) { \ + if (po == rlc) { \ + if (lc < 8) \ + get_char(c, lc, gb); \ + lc -= 8; \ + \ + cs = c >> lc; \ + \ + if (out + cs > oe) \ + return AVERROR_INVALIDDATA; \ + \ + s = out[-1]; \ + \ + while (cs-- > 0) \ + *out++ = s; \ + } else if (out < oe) { \ + *out++ = po; \ + } else { \ + return AVERROR_INVALIDDATA; \ + } \ +} + +static int huf_decode(const uint64_t *hcode, const HufDec *hdecod, + GetByteContext *gb, int nbits, + int rlc, int no, uint16_t *out) +{ + uint64_t c = 0; + uint16_t *outb = out; + uint16_t *oe = out + no; + const uint8_t *ie = gb->buffer + (nbits + 7) / 8; // input byte size + uint8_t cs, s; + int i, lc = 0; + + while (gb->buffer < ie) { + get_char(c, lc, gb); + + while (lc >= HUF_DECBITS) { + const HufDec pl = hdecod[(c >> (lc-HUF_DECBITS)) & HUF_DECMASK]; + + if (pl.len) { + lc -= pl.len; + get_code(pl.lit, rlc, c, lc, gb, out, oe); + } else { + int j; + + if (!pl.p) + return AVERROR_INVALIDDATA; + + for (j = 0; j < pl.lit; j++) { + int l = hcode[pl.p[j]] & 63; + + while (lc < l && bytestream2_get_bytes_left(gb) > 0) + get_char(c, lc, gb); + + if (lc >= l) { + if ((hcode[pl.p[j]] >> 6) == + ((c >> (lc - l)) & ((1LL << l) - 1))) { + lc -= l; + get_code(pl.p[j], rlc, c, lc, gb, out, oe); + break; + } + } + } + + if (j == pl.lit) + return AVERROR_INVALIDDATA; + } + } + } + + i = (8 - nbits) & 7; + c >>= i; + lc -= i; + + while (lc > 0) { + const HufDec pl = hdecod[(c << (HUF_DECBITS - lc)) & HUF_DECMASK]; + + if (pl.len) { + lc -= pl.len; + get_code(pl.lit, rlc, c, lc, gb, out, oe); + } else { + return AVERROR_INVALIDDATA; + } + } + + if (out - outb != no) + return AVERROR_INVALIDDATA; + return 0; +} + +static int huf_uncompress(GetByteContext *gb, + uint16_t *dst, int dst_size) +{ + int32_t src_size, im, iM; + uint32_t nBits; + uint64_t *freq; + HufDec *hdec; + int ret, i; + + src_size = bytestream2_get_le32(gb); + im = bytestream2_get_le32(gb); + iM = bytestream2_get_le32(gb); + bytestream2_skip(gb, 4); + nBits = bytestream2_get_le32(gb); + if (im < 0 || im >= HUF_ENCSIZE || + iM < 0 || iM >= HUF_ENCSIZE || + src_size < 0) + return AVERROR_INVALIDDATA; + + bytestream2_skip(gb, 4); + + freq = av_calloc(HUF_ENCSIZE, sizeof(*freq)); + hdec = av_calloc(HUF_DECSIZE, sizeof(*hdec)); + if (!freq || !hdec) { + ret = AVERROR(ENOMEM); + goto fail; + } + + if ((ret = huf_unpack_enc_table(gb, im, iM, freq)) < 0) + goto fail; + + if (nBits > 8 * bytestream2_get_bytes_left(gb)) { + ret = AVERROR_INVALIDDATA; + goto fail; + } + + if ((ret = huf_build_dec_table(freq, im, iM, hdec)) < 0) + goto fail; + ret = huf_decode(freq, hdec, gb, nBits, iM, dst_size, dst); + +fail: + for (i = 0; i < HUF_DECSIZE; i++) { + if (hdec) + av_freep(&hdec[i].p); + } + + av_free(freq); + av_free(hdec); + + return ret; +} + +static inline void wdec14(uint16_t l, uint16_t h, uint16_t *a, uint16_t *b) +{ + int16_t ls = l; + int16_t hs = h; + int hi = hs; + int ai = ls + (hi & 1) + (hi >> 1); + int16_t as = ai; + int16_t bs = ai - hi; + + *a = as; + *b = bs; +} + +#define NBITS 16 +#define A_OFFSET (1 << (NBITS - 1)) +#define MOD_MASK ((1 << NBITS) - 1) + +static inline void wdec16(uint16_t l, uint16_t h, uint16_t *a, uint16_t *b) +{ + int m = l; + int d = h; + int bb = (m - (d >> 1)) & MOD_MASK; + int aa = (d + bb - A_OFFSET) & MOD_MASK; + *b = bb; + *a = aa; +} + +static void wav_decode(uint16_t *in, int nx, int ox, + int ny, int oy, uint16_t mx) +{ + int w14 = (mx < (1 << 14)); + int n = (nx > ny) ? ny: nx; + int p = 1; + int p2; + + while (p <= n) + p <<= 1; + + p >>= 1; + p2 = p; + p >>= 1; + + while (p >= 1) { + uint16_t *py = in; + uint16_t *ey = in + oy * (ny - p2); + uint16_t i00, i01, i10, i11; + int oy1 = oy * p; + int oy2 = oy * p2; + int ox1 = ox * p; + int ox2 = ox * p2; + + for (; py <= ey; py += oy2) { + uint16_t *px = py; + uint16_t *ex = py + ox * (nx - p2); + + for (; px <= ex; px += ox2) { + uint16_t *p01 = px + ox1; + uint16_t *p10 = px + oy1; + uint16_t *p11 = p10 + ox1; + + if (w14) { + wdec14(*px, *p10, &i00, &i10); + wdec14(*p01, *p11, &i01, &i11); + wdec14(i00, i01, px, p01); + wdec14(i10, i11, p10, p11); + } else { + wdec16(*px, *p10, &i00, &i10); + wdec16(*p01, *p11, &i01, &i11); + wdec16(i00, i01, px, p01); + wdec16(i10, i11, p10, p11); + } + } + + if (nx & p) { + uint16_t *p10 = px + oy1; + + if (w14) + wdec14(*px, *p10, &i00, p10); + else + wdec16(*px, *p10, &i00, p10); + + *px = i00; + } + } + + if (ny & p) { + uint16_t *px = py; + uint16_t *ex = py + ox * (nx - p2); + + for (; px <= ex; px += ox2) { + uint16_t *p01 = px + ox1; + + if (w14) + wdec14(*px, *p01, &i00, p01); + else + wdec16(*px, *p01, &i00, p01); + + *px = i00; + } + } + + p2 = p; + p >>= 1; + } +} + +static int piz_uncompress(EXRContext *s, const uint8_t *src, int ssize, int dsize, EXRThreadData *td) +{ + GetByteContext gb; + uint16_t maxval, min_non_zero, max_non_zero; + uint16_t *ptr, *tmp = (uint16_t *)td->tmp; + int8_t *out; + int ret, i, j; + + if (!td->bitmap) + td->bitmap = av_malloc(BITMAP_SIZE); + if (!td->lut) + td->lut = av_malloc(1 << 17); + if (!td->bitmap || !td->lut) + return AVERROR(ENOMEM); + + bytestream2_init(&gb, src, ssize); + min_non_zero = bytestream2_get_le16(&gb); + max_non_zero = bytestream2_get_le16(&gb); + + if (max_non_zero >= BITMAP_SIZE) + return AVERROR_INVALIDDATA; + + memset(td->bitmap, 0, FFMIN(min_non_zero, BITMAP_SIZE)); + if (min_non_zero <= max_non_zero) + bytestream2_get_buffer(&gb, td->bitmap + min_non_zero, + max_non_zero - min_non_zero + 1); + memset(td->bitmap + max_non_zero, 0, BITMAP_SIZE - max_non_zero); + + maxval = reverse_lut(td->bitmap, td->lut); + + ret = huf_uncompress(&gb, tmp, dsize / sizeof(int16_t)); + if (ret) + return ret; + + ptr = tmp; + for (i = 0; i < s->nb_channels; i++) { + EXRChannel *channel = &s->channels[i]; + int size = channel->pixel_type; + + for (j = 0; j < size; j++) + wav_decode(ptr + j, s->xdelta, size, s->ysize, s->xdelta * size, maxval); + ptr += s->xdelta * s->ysize * size; + } + + apply_lut(td->lut, tmp, dsize / sizeof(int16_t)); + + out = td->uncompressed_data; + for (i = 0; i < s->ysize; i++) { + for (j = 0; j < s->nb_channels; j++) { + uint16_t *in = tmp + j * s->xdelta * s->ysize + i * s->xdelta; + memcpy(out, in, s->xdelta * 2); + out += s->xdelta * 2; + } + } + + return 0; +} + static int pxr24_uncompress(EXRContext *s, const uint8_t *src, int compressed_size, int uncompressed_size, EXRThreadData *td) @@ -385,6 +845,9 @@ static int decode_block(AVCodecContext *avctx, void *tdata, case EXR_ZIP16: ret = zip_uncompress(src, data_size, uncompressed_size, td); break; + case EXR_PIZ: + ret = piz_uncompress(s, src, data_size, uncompressed_size, td); + break; case EXR_PXR24: ret = pxr24_uncompress(s, src, data_size, uncompressed_size, td); break; @@ -501,13 +964,13 @@ static int decode_frame(AVCodecContext *avctx, version = bytestream_get_byte(&buf); if (version != 2) { - av_log(avctx, AV_LOG_ERROR, "Unsupported version %d\n", version); + avpriv_report_missing_feature(avctx, "Version %d", version); return AVERROR_PATCHWELCOME; } flags = bytestream_get_le24(&buf); if (flags & 0x2) { - av_log(avctx, AV_LOG_ERROR, "Tile based images are not supported\n"); + avpriv_report_missing_feature(avctx, "Tile support"); return AVERROR_PATCHWELCOME; } @@ -523,7 +986,7 @@ static int decode_frame(AVCodecContext *avctx, channel_list_end = buf + variable_buffer_data_size; while (channel_list_end - buf >= 19) { EXRChannel *channel; - int current_pixel_type = -1; + enum ExrPixelType current_pixel_type; int channel_index = -1; int xsub, ysub; @@ -556,7 +1019,7 @@ static int decode_frame(AVCodecContext *avctx, xsub = bytestream_get_le32(&buf); ysub = bytestream_get_le32(&buf); if (xsub != 1 || ysub != 1) { - av_log(avctx, AV_LOG_ERROR, "Unsupported subsampling %dx%d\n", xsub, ysub); + avpriv_report_missing_feature(avctx, "Subsampling %dx%d", xsub, ysub); return AVERROR_PATCHWELCOME; } @@ -714,14 +1177,14 @@ static int decode_frame(AVCodecContext *avctx, case EXR_ZIP16: s->scan_lines_per_block = 16; break; + case EXR_PIZ: + s->scan_lines_per_block = 32; + break; default: - av_log(avctx, AV_LOG_ERROR, "Compression type %d is not supported\n", s->compr); + avpriv_report_missing_feature(avctx, "Compression %d", s->compr); return AVERROR_PATCHWELCOME; } - if (av_image_check_size(w, h, 0, avctx)) - return AVERROR_INVALIDDATA; - // Verify the xmin, xmax, ymin, ymax and xdelta before setting the actual image size if (s->xmin > s->xmax || s->ymin > s->ymax || @@ -731,9 +1194,8 @@ static int decode_frame(AVCodecContext *avctx, return AVERROR_INVALIDDATA; } - if (w != avctx->width || h != avctx->height) { - avcodec_set_dimensions(avctx, w, h); - } + if ((ret = ff_set_dimensions(avctx, w, h)) < 0) + return ret; s->desc = av_pix_fmt_desc_get(avctx->pix_fmt); out_line_size = avctx->width * 2 * s->desc->nb_components; @@ -778,6 +1240,7 @@ static int decode_frame(AVCodecContext *avctx, ptr += picture->linesize[0]; } + picture->pict_type = AV_PICTURE_TYPE_I; *got_frame = 1; return buf_size; @@ -790,8 +1253,10 @@ static av_cold int decode_end(AVCodecContext *avctx) for (i = 0; i < s->thread_data_size / sizeof(EXRThreadData); i++) { EXRThreadData *td = &s->thread_data[i]; - av_free(td->uncompressed_data); - av_free(td->tmp); + av_freep(&td->uncompressed_data); + av_freep(&td->tmp); + av_freep(&td->bitmap); + av_freep(&td->lut); } av_freep(&s->thread_data); @@ -803,11 +1268,11 @@ static av_cold int decode_end(AVCodecContext *avctx) AVCodec ff_exr_decoder = { .name = "exr", + .long_name = NULL_IF_CONFIG_SMALL("OpenEXR image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_EXR, .priv_data_size = sizeof(EXRContext), .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS | CODEC_CAP_SLICE_THREADS, - .long_name = NULL_IF_CONFIG_SMALL("OpenEXR image"), }; diff --git a/ffmpeg/libavcodec/faxcompr.c b/ffmpeg/libavcodec/faxcompr.c index 86be977..900851b 100644 --- a/ffmpeg/libavcodec/faxcompr.c +++ b/ffmpeg/libavcodec/faxcompr.c @@ -103,13 +103,13 @@ av_cold void ff_ccitt_unpack_init(void) int i; static int initialized = 0; - if(initialized) + if (initialized) return; ccitt_vlc[0].table = code_table1; ccitt_vlc[0].table_allocated = 528; ccitt_vlc[1].table = code_table2; ccitt_vlc[1].table_allocated = 648; - for(i = 0; i < 2; i++){ + for (i = 0; i < 2; i++) { ff_init_vlc_sparse(&ccitt_vlc[i], 9, CCITT_SYMS, ccitt_codes_lens[i], 1, 1, ccitt_codes_bits[i], 1, 1, @@ -124,32 +124,33 @@ av_cold void ff_ccitt_unpack_init(void) static int decode_group3_1d_line(AVCodecContext *avctx, GetBitContext *gb, - unsigned int pix_left, int *runs, const int *runend) + unsigned int pix_left, int *runs, + const int *runend) { - int mode = 0; - unsigned int run=0; + int mode = 0; + unsigned int run = 0; unsigned int t; - for(;;){ - t = get_vlc2(gb, ccitt_vlc[mode].table, 9, 2); + for (;;) { + t = get_vlc2(gb, ccitt_vlc[mode].table, 9, 2); run += t; - if(t < 64){ + if (t < 64) { *runs++ = run; - if(runs >= runend){ + if (runs >= runend) { av_log(avctx, AV_LOG_ERROR, "Run overrun\n"); - return -1; + return AVERROR_INVALIDDATA; } - if(pix_left <= run){ - if(pix_left == run) + if (pix_left <= run) { + if (pix_left == run) break; av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n"); - return -1; + return AVERROR_INVALIDDATA; } pix_left -= run; - run = 0; - mode = !mode; - }else if((int)t == -1){ + run = 0; + mode = !mode; + } else if ((int)t == -1) { av_log(avctx, AV_LOG_ERROR, "Incorrect code\n"); - return -1; + return AVERROR_INVALIDDATA; } } *runs++ = 0; @@ -157,85 +158,86 @@ static int decode_group3_1d_line(AVCodecContext *avctx, GetBitContext *gb, } static int decode_group3_2d_line(AVCodecContext *avctx, GetBitContext *gb, - unsigned int width, int *runs, const int *runend, const int *ref) + unsigned int width, int *runs, + const int *runend, const int *ref) { - int mode = 0, saved_run = 0, t; - int run_off = *ref++; - unsigned int offs=0, run= 0; + int mode = 0, saved_run = 0, t; + int run_off = *ref++; + unsigned int offs = 0, run = 0; - while(offs < width){ + while (offs < width) { int cmode = get_vlc2(gb, ccitt_group3_2d_vlc.table, 9, 1); - if(cmode == -1){ + if (cmode == -1) { av_log(avctx, AV_LOG_ERROR, "Incorrect mode VLC\n"); - return -1; + return AVERROR_INVALIDDATA; } - if(!cmode){//pass mode - if(run_off < width) + if (!cmode) { //pass mode + if (run_off < width) run_off += *ref++; - run = run_off - offs; - offs= run_off; - if(run_off < width) + run = run_off - offs; + offs = run_off; + if (run_off < width) run_off += *ref++; - if(offs > width){ + if (offs > width) { av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n"); - return -1; + return AVERROR_INVALIDDATA; } saved_run += run; - }else if(cmode == 1){//horizontal mode + } else if (cmode == 1) { //horizontal mode int k; - for(k = 0; k < 2; k++){ + for (k = 0; k < 2; k++) { run = 0; - for(;;){ + for (;;) { t = get_vlc2(gb, ccitt_vlc[mode].table, 9, 2); - if(t == -1){ + if (t == -1) { av_log(avctx, AV_LOG_ERROR, "Incorrect code\n"); - return -1; + return AVERROR_INVALIDDATA; } run += t; - if(t < 64) + if (t < 64) break; } *runs++ = run + saved_run; - if(runs >= runend){ + if (runs >= runend) { av_log(avctx, AV_LOG_ERROR, "Run overrun\n"); - return -1; + return AVERROR_INVALIDDATA; } saved_run = 0; - offs += run; - if(offs > width || run > width){ + offs += run; + if (offs > width || run > width) { av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n"); - return -1; + return AVERROR_INVALIDDATA; } mode = !mode; } - }else if(cmode == 9 || cmode == 10){ - av_log(avctx, AV_LOG_ERROR, "Special modes are not supported (yet)\n"); - return -1; - }else{//vertical mode - run = run_off - offs + (cmode - 5); + } else if (cmode == 9 || cmode == 10) { + avpriv_report_missing_feature(avctx, "Special modes support"); + return AVERROR_PATCHWELCOME; + } else { //vertical mode + run = run_off - offs + (cmode - 5); run_off -= *--ref; - offs += run; - if(offs > width || run > width){ + offs += run; + if (offs > width || run > width) { av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n"); - return -1; + return AVERROR_INVALIDDATA; } *runs++ = run + saved_run; - if(runs >= runend){ + if (runs >= runend) { av_log(avctx, AV_LOG_ERROR, "Run overrun\n"); - return -1; + return AVERROR_INVALIDDATA; } saved_run = 0; - mode = !mode; + mode = !mode; } //sync line pointers - while(offs < width && run_off <= offs){ + while (offs < width && run_off <= offs) { run_off += *ref++; run_off += *ref++; } } *runs++ = saved_run; if (saved_run) { - if(runs >= runend){ + if (runs >= runend) { av_log(avctx, AV_LOG_ERROR, "Run overrun\n"); return -1; } @@ -249,14 +251,14 @@ static void put_line(uint8_t *dst, int size, int width, const int *runs) PutBitContext pb; int run, mode = ~0, pix_left = width, run_idx = 0; - init_put_bits(&pb, dst, size*8); - while(pix_left > 0){ - run = runs[run_idx++]; - mode = ~mode; + init_put_bits(&pb, dst, size * 8); + while (pix_left > 0) { + run = runs[run_idx++]; + mode = ~mode; pix_left -= run; - for(; run > 16; run -= 16) + for (; run > 16; run -= 16) put_sbits(&pb, 16, mode); - if(run) + if (run) put_sbits(&pb, run, mode); } flush_put_bits(&pb); @@ -266,16 +268,15 @@ static int find_group3_syncmarker(GetBitContext *gb, int srcsize) { unsigned int state = -1; srcsize -= get_bits_count(gb); - while(srcsize-- > 0){ - state+= state + get_bits1(gb); - if((state & 0xFFF) == 1) + while (srcsize-- > 0) { + state += state + get_bits1(gb); + if ((state & 0xFFF) == 1) return 0; } return -1; } -int ff_ccitt_unpack(AVCodecContext *avctx, - const uint8_t *src, int srcsize, +int ff_ccitt_unpack(AVCodecContext *avctx, const uint8_t *src, int srcsize, uint8_t *dst, int height, int stride, enum TiffCompr compr, int opts) { @@ -283,51 +284,57 @@ int ff_ccitt_unpack(AVCodecContext *avctx, GetBitContext gb; int *runs, *ref = NULL, *runend; int ret; - int runsize= avctx->width + 2; - int err = 0; + int runsize = avctx->width + 2; int has_eol; runs = av_malloc(runsize * sizeof(runs[0])); ref = av_malloc(runsize * sizeof(ref[0])); - if (!runs || ! ref) { - err = AVERROR(ENOMEM); + if (!runs || !ref) { + ret = AVERROR(ENOMEM); goto fail; } ref[0] = avctx->width; ref[1] = 0; ref[2] = 0; - init_get_bits(&gb, src, srcsize*8); + init_get_bits(&gb, src, srcsize * 8); has_eol = show_bits(&gb, 12) == 1 || show_bits(&gb, 16) == 1; - for(j = 0; j < height; j++){ + for (j = 0; j < height; j++) { runend = runs + runsize; - if(compr == TIFF_G4){ - ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, runend, ref); - if(ret < 0){ - err = -1; + if (compr == TIFF_G4) { + ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, runend, + ref); + if (ret < 0) goto fail; - } - }else{ + } else { int g3d1 = (compr == TIFF_G3) && !(opts & 1); - if(compr!=TIFF_CCITT_RLE && has_eol && find_group3_syncmarker(&gb, srcsize*8) < 0) + if (compr != TIFF_CCITT_RLE && + has_eol && + find_group3_syncmarker(&gb, srcsize * 8) < 0) break; - if(compr==TIFF_CCITT_RLE || g3d1 || get_bits1(&gb)) - ret = decode_group3_1d_line(avctx, &gb, avctx->width, runs, runend); + if (compr == TIFF_CCITT_RLE || g3d1 || get_bits1(&gb)) + ret = decode_group3_1d_line(avctx, &gb, avctx->width, runs, + runend); else - ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, runend, ref); - if(compr==TIFF_CCITT_RLE) + ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, + runend, ref); + if (compr == TIFF_CCITT_RLE) align_get_bits(&gb); } - if(ret < 0){ + if (avctx->err_recognition & AV_EF_EXPLODE && ret < 0) + goto fail; + + if (ret < 0) { put_line(dst, stride, avctx->width, ref); - }else{ + } else { put_line(dst, stride, avctx->width, runs); - FFSWAP(int*, runs, ref); + FFSWAP(int *, runs, ref); } dst += stride; } + ret = 0; fail: av_free(runs); av_free(ref); - return err; + return ret; } diff --git a/ffmpeg/libavcodec/fft-internal.h b/ffmpeg/libavcodec/fft-internal.h index d66731f..065eecc 100644 --- a/ffmpeg/libavcodec/fft-internal.h +++ b/ffmpeg/libavcodec/fft-internal.h @@ -36,12 +36,29 @@ #else +#define SCALE_FLOAT(a, bits) lrint((a) * (double)(1 << (bits))) + +#if CONFIG_FFT_FIXED_32 + +#define CMUL(dre, dim, are, aim, bre, bim) do { \ + int64_t accu; \ + (accu) = (int64_t)(bre) * (are); \ + (accu) -= (int64_t)(bim) * (aim); \ + (dre) = (int)(((accu) + 0x40000000) >> 31); \ + (accu) = (int64_t)(bre) * (aim); \ + (accu) += (int64_t)(bim) * (are); \ + (dim) = (int)(((accu) + 0x40000000) >> 31); \ + } while (0) + +#define FIX15(a) av_clip(SCALE_FLOAT(a, 31), -2147483647, 2147483647) + +#else /* CONFIG_FFT_FIXED_32 */ + #include "fft.h" #include "mathops.h" void ff_mdct_calcw_c(FFTContext *s, FFTDouble *output, const FFTSample *input); -#define SCALE_FLOAT(a, bits) lrint((a) * (double)(1 << (bits))) #define FIX15(a) av_clip(SCALE_FLOAT(a, 15), -32767, 32767) #define sqrthalf ((int16_t)((1<<15)*M_SQRT1_2)) @@ -62,6 +79,8 @@ void ff_mdct_calcw_c(FFTContext *s, FFTDouble *output, const FFTSample *input); #define CMULL(dre, dim, are, aim, bre, bim) \ CMULS(dre, dim, are, aim, bre, bim, 0) +#endif /* CONFIG_FFT_FIXED_32 */ + #endif /* CONFIG_FFT_FLOAT */ #define ff_imdct_calc_c FFT_NAME(ff_imdct_calc_c) diff --git a/ffmpeg/libavcodec/fft-test.c b/ffmpeg/libavcodec/fft-test.c index 66474ce..d650a10 100644 --- a/ffmpeg/libavcodec/fft-test.c +++ b/ffmpeg/libavcodec/fft-test.c @@ -37,6 +37,7 @@ #if HAVE_UNISTD_H #include #endif +#include #include #include @@ -54,6 +55,10 @@ # define RANGE 1.0 # define REF_SCALE(x, bits) (x) # define FMT "%10.6f" +#elif CONFIG_FFT_FIXED_32 +# define RANGE 8388608 +# define REF_SCALE(x, bits) (x) +# define FMT "%6d" #else # define RANGE 16384 # define REF_SCALE(x, bits) ((x) / (1<<(bits))) @@ -330,6 +335,7 @@ int main(int argc, char **argv) ff_rdft_init(r, fft_nbits, do_inverse ? IDFT_C2R : DFT_R2C); fft_ref_init(fft_nbits, do_inverse); break; +# if CONFIG_DCT case TRANSFORM_DCT: if (do_inverse) av_log(NULL, AV_LOG_INFO,"DCT_III"); @@ -337,6 +343,7 @@ int main(int argc, char **argv) av_log(NULL, AV_LOG_INFO,"DCT_II"); ff_dct_init(d, fft_nbits, do_inverse ? DCT_III : DCT_II); break; +# endif #endif default: av_log(NULL, AV_LOG_ERROR, "Requested transform not supported\n"); @@ -479,9 +486,11 @@ int main(int argc, char **argv) case TRANSFORM_RDFT: ff_rdft_end(r); break; +# if CONFIG_DCT case TRANSFORM_DCT: ff_dct_end(d); break; +# endif #endif } @@ -491,5 +500,8 @@ int main(int argc, char **argv) av_free(tab_ref); av_free(exptab); - return err; + if (err) + printf("Error: %d.\n", err); + + return !!err; } diff --git a/ffmpeg/libavcodec/fft.c b/ffmpeg/libavcodec/fft.c deleted file mode 100644 index 00c434a..0000000 --- a/ffmpeg/libavcodec/fft.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - * FFT/IFFT transforms - * Copyright (c) 2008 Loren Merritt - * Copyright (c) 2002 Fabrice Bellard - * Partly based on libdjbfft by D. J. Bernstein - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * FFT/IFFT transforms. - */ - -#include -#include -#include "libavutil/mathematics.h" -#include "fft.h" -#include "fft-internal.h" - -/* cos(2*pi*x/n) for 0<=x<=n/4, followed by its reverse */ -#if !CONFIG_HARDCODED_TABLES -COSTABLE(16); -COSTABLE(32); -COSTABLE(64); -COSTABLE(128); -COSTABLE(256); -COSTABLE(512); -COSTABLE(1024); -COSTABLE(2048); -COSTABLE(4096); -COSTABLE(8192); -COSTABLE(16384); -COSTABLE(32768); -COSTABLE(65536); -#endif -COSTABLE_CONST FFTSample * const FFT_NAME(ff_cos_tabs)[] = { - NULL, NULL, NULL, NULL, - FFT_NAME(ff_cos_16), - FFT_NAME(ff_cos_32), - FFT_NAME(ff_cos_64), - FFT_NAME(ff_cos_128), - FFT_NAME(ff_cos_256), - FFT_NAME(ff_cos_512), - FFT_NAME(ff_cos_1024), - FFT_NAME(ff_cos_2048), - FFT_NAME(ff_cos_4096), - FFT_NAME(ff_cos_8192), - FFT_NAME(ff_cos_16384), - FFT_NAME(ff_cos_32768), - FFT_NAME(ff_cos_65536), -}; - -static void ff_fft_permute_c(FFTContext *s, FFTComplex *z); -static void ff_fft_calc_c(FFTContext *s, FFTComplex *z); - -static int split_radix_permutation(int i, int n, int inverse) -{ - int m; - if(n <= 2) return i&1; - m = n >> 1; - if(!(i&m)) return split_radix_permutation(i, m, inverse)*2; - m >>= 1; - if(inverse == !(i&m)) return split_radix_permutation(i, m, inverse)*4 + 1; - else return split_radix_permutation(i, m, inverse)*4 - 1; -} - -av_cold void ff_init_ff_cos_tabs(int index) -{ -#if !CONFIG_HARDCODED_TABLES - int i; - int m = 1<= 16; - else if (i < n/2) - return is_second_half_of_fft32(i, n/2); - else if (i < 3*n/4) - return is_second_half_of_fft32(i - n/2, n/4); - else - return is_second_half_of_fft32(i - 3*n/4, n/4); -} - -static av_cold void fft_perm_avx(FFTContext *s) -{ - int i; - int n = 1 << s->nbits; - - for (i = 0; i < n; i += 16) { - int k; - if (is_second_half_of_fft32(i, n)) { - for (k = 0; k < 16; k++) - s->revtab[-split_radix_permutation(i + k, n, s->inverse) & (n - 1)] = - i + avx_tab[k]; - - } else { - for (k = 0; k < 16; k++) { - int j = i + k; - j = (j & ~7) | ((j >> 1) & 3) | ((j << 2) & 4); - s->revtab[-split_radix_permutation(i + k, n, s->inverse) & (n - 1)] = j; - } - } - } -} - -av_cold int ff_fft_init(FFTContext *s, int nbits, int inverse) -{ - int i, j, n; - - if (nbits < 2 || nbits > 16) - goto fail; - s->nbits = nbits; - n = 1 << nbits; - - s->revtab = av_malloc(n * sizeof(uint16_t)); - if (!s->revtab) - goto fail; - s->tmp_buf = av_malloc(n * sizeof(FFTComplex)); - if (!s->tmp_buf) - goto fail; - s->inverse = inverse; - s->fft_permutation = FF_FFT_PERM_DEFAULT; - - s->fft_permute = ff_fft_permute_c; - s->fft_calc = ff_fft_calc_c; -#if CONFIG_MDCT - s->imdct_calc = ff_imdct_calc_c; - s->imdct_half = ff_imdct_half_c; - s->mdct_calc = ff_mdct_calc_c; -#endif - -#if CONFIG_FFT_FLOAT - if (ARCH_ARM) ff_fft_init_arm(s); - if (HAVE_ALTIVEC) ff_fft_init_altivec(s); - if (ARCH_X86) ff_fft_init_x86(s); - if (CONFIG_MDCT) s->mdct_calcw = s->mdct_calc; - if (HAVE_MIPSFPU) ff_fft_init_mips(s); -#else - if (CONFIG_MDCT) s->mdct_calcw = ff_mdct_calcw_c; - if (ARCH_ARM) ff_fft_fixed_init_arm(s); -#endif - - for(j=4; j<=nbits; j++) { - ff_init_ff_cos_tabs(j); - } - - if (s->fft_permutation == FF_FFT_PERM_AVX) { - fft_perm_avx(s); - } else { - for(i=0; ifft_permutation == FF_FFT_PERM_SWAP_LSBS) - j = (j&~3) | ((j>>1)&1) | ((j<<1)&2); - s->revtab[-split_radix_permutation(i, n, s->inverse) & (n-1)] = j; - } - } - - return 0; - fail: - av_freep(&s->revtab); - av_freep(&s->tmp_buf); - return -1; -} - -static void ff_fft_permute_c(FFTContext *s, FFTComplex *z) -{ - int j, np; - const uint16_t *revtab = s->revtab; - np = 1 << s->nbits; - /* TODO: handle split-radix permute in a more optimal way, probably in-place */ - for(j=0;jtmp_buf[revtab[j]] = z[j]; - memcpy(z, s->tmp_buf, np * sizeof(FFTComplex)); -} - -av_cold void ff_fft_end(FFTContext *s) -{ - av_freep(&s->revtab); - av_freep(&s->tmp_buf); -} - -#define BUTTERFLIES(a0,a1,a2,a3) {\ - BF(t3, t5, t5, t1);\ - BF(a2.re, a0.re, a0.re, t5);\ - BF(a3.im, a1.im, a1.im, t3);\ - BF(t4, t6, t2, t6);\ - BF(a3.re, a1.re, a1.re, t4);\ - BF(a2.im, a0.im, a0.im, t6);\ -} - -// force loading all the inputs before storing any. -// this is slightly slower for small data, but avoids store->load aliasing -// for addresses separated by large powers of 2. -#define BUTTERFLIES_BIG(a0,a1,a2,a3) {\ - FFTSample r0=a0.re, i0=a0.im, r1=a1.re, i1=a1.im;\ - BF(t3, t5, t5, t1);\ - BF(a2.re, a0.re, r0, t5);\ - BF(a3.im, a1.im, i1, t3);\ - BF(t4, t6, t2, t6);\ - BF(a3.re, a1.re, r1, t4);\ - BF(a2.im, a0.im, i0, t6);\ -} - -#define TRANSFORM(a0,a1,a2,a3,wre,wim) {\ - CMUL(t1, t2, a2.re, a2.im, wre, -wim);\ - CMUL(t5, t6, a3.re, a3.im, wre, wim);\ - BUTTERFLIES(a0,a1,a2,a3)\ -} - -#define TRANSFORM_ZERO(a0,a1,a2,a3) {\ - t1 = a2.re;\ - t2 = a2.im;\ - t5 = a3.re;\ - t6 = a3.im;\ - BUTTERFLIES(a0,a1,a2,a3)\ -} - -/* z[0...8n-1], w[1...2n-1] */ -#define PASS(name)\ -static void name(FFTComplex *z, const FFTSample *wre, unsigned int n)\ -{\ - FFTDouble t1, t2, t3, t4, t5, t6;\ - int o1 = 2*n;\ - int o2 = 4*n;\ - int o3 = 6*n;\ - const FFTSample *wim = wre+o1;\ - n--;\ -\ - TRANSFORM_ZERO(z[0],z[o1],z[o2],z[o3]);\ - TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\ - do {\ - z += 2;\ - wre += 2;\ - wim -= 2;\ - TRANSFORM(z[0],z[o1],z[o2],z[o3],wre[0],wim[0]);\ - TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\ - } while(--n);\ -} - -PASS(pass) -#undef BUTTERFLIES -#define BUTTERFLIES BUTTERFLIES_BIG -PASS(pass_big) - -#define DECL_FFT(n,n2,n4)\ -static void fft##n(FFTComplex *z)\ -{\ - fft##n2(z);\ - fft##n4(z+n4*2);\ - fft##n4(z+n4*3);\ - pass(z,FFT_NAME(ff_cos_##n),n4/2);\ -} - -static void fft4(FFTComplex *z) -{ - FFTDouble t1, t2, t3, t4, t5, t6, t7, t8; - - BF(t3, t1, z[0].re, z[1].re); - BF(t8, t6, z[3].re, z[2].re); - BF(z[2].re, z[0].re, t1, t6); - BF(t4, t2, z[0].im, z[1].im); - BF(t7, t5, z[2].im, z[3].im); - BF(z[3].im, z[1].im, t4, t8); - BF(z[3].re, z[1].re, t3, t7); - BF(z[2].im, z[0].im, t2, t5); -} - -static void fft8(FFTComplex *z) -{ - FFTDouble t1, t2, t3, t4, t5, t6; - - fft4(z); - - BF(t1, z[5].re, z[4].re, -z[5].re); - BF(t2, z[5].im, z[4].im, -z[5].im); - BF(t5, z[7].re, z[6].re, -z[7].re); - BF(t6, z[7].im, z[6].im, -z[7].im); - - BUTTERFLIES(z[0],z[2],z[4],z[6]); - TRANSFORM(z[1],z[3],z[5],z[7],sqrthalf,sqrthalf); -} - -#if !CONFIG_SMALL -static void fft16(FFTComplex *z) -{ - FFTDouble t1, t2, t3, t4, t5, t6; - FFTSample cos_16_1 = FFT_NAME(ff_cos_16)[1]; - FFTSample cos_16_3 = FFT_NAME(ff_cos_16)[3]; - - fft8(z); - fft4(z+8); - fft4(z+12); - - TRANSFORM_ZERO(z[0],z[4],z[8],z[12]); - TRANSFORM(z[2],z[6],z[10],z[14],sqrthalf,sqrthalf); - TRANSFORM(z[1],z[5],z[9],z[13],cos_16_1,cos_16_3); - TRANSFORM(z[3],z[7],z[11],z[15],cos_16_3,cos_16_1); -} -#else -DECL_FFT(16,8,4) -#endif -DECL_FFT(32,16,8) -DECL_FFT(64,32,16) -DECL_FFT(128,64,32) -DECL_FFT(256,128,64) -DECL_FFT(512,256,128) -#if !CONFIG_SMALL -#define pass pass_big -#endif -DECL_FFT(1024,512,256) -DECL_FFT(2048,1024,512) -DECL_FFT(4096,2048,1024) -DECL_FFT(8192,4096,2048) -DECL_FFT(16384,8192,4096) -DECL_FFT(32768,16384,8192) -DECL_FFT(65536,32768,16384) - -static void (* const fft_dispatch[])(FFTComplex*) = { - fft4, fft8, fft16, fft32, fft64, fft128, fft256, fft512, fft1024, - fft2048, fft4096, fft8192, fft16384, fft32768, fft65536, -}; - -static void ff_fft_calc_c(FFTContext *s, FFTComplex *z) -{ - fft_dispatch[s->nbits-2](z); -} diff --git a/ffmpeg/libavcodec/fft.h b/ffmpeg/libavcodec/fft.h index 9d92b2c..217090c 100644 --- a/ffmpeg/libavcodec/fft.h +++ b/ffmpeg/libavcodec/fft.h @@ -26,6 +26,10 @@ #define CONFIG_FFT_FLOAT 1 #endif +#ifndef CONFIG_FFT_FIXED_32 +#define CONFIG_FFT_FIXED_32 0 +#endif + #include #include "config.h" #include "libavutil/mem.h" @@ -40,15 +44,26 @@ typedef float FFTDouble; #else +#if CONFIG_FFT_FIXED_32 + +#define Q31(x) (int)((x)*2147483648.0 + 0.5) +#define FFT_NAME(x) x ## _fixed_32 + +typedef int32_t FFTSample; + +#else /* CONFIG_FFT_FIXED_32 */ + #define FFT_NAME(x) x ## _fixed typedef int16_t FFTSample; -typedef int FFTDouble; + +#endif /* CONFIG_FFT_FIXED_32 */ typedef struct FFTComplex { - int16_t re, im; + FFTSample re, im; } FFTComplex; +typedef int FFTDouble; typedef struct FFTContext FFTContext; #endif /* CONFIG_FFT_FLOAT */ @@ -133,14 +148,12 @@ void ff_init_ff_cos_tabs(int index); */ int ff_fft_init(FFTContext *s, int nbits, int inverse); -#if CONFIG_FFT_FLOAT -void ff_fft_init_altivec(FFTContext *s); void ff_fft_init_x86(FFTContext *s); void ff_fft_init_arm(FFTContext *s); void ff_fft_init_mips(FFTContext *s); -#else +void ff_fft_init_ppc(FFTContext *s); + void ff_fft_fixed_init_arm(FFTContext *s); -#endif void ff_fft_end(FFTContext *s); diff --git a/ffmpeg/libavcodec/fft_fixed.c b/ffmpeg/libavcodec/fft_fixed.c index 3955efe..9e74b8c 100644 --- a/ffmpeg/libavcodec/fft_fixed.c +++ b/ffmpeg/libavcodec/fft_fixed.c @@ -17,4 +17,5 @@ */ #define CONFIG_FFT_FLOAT 0 -#include "fft.c" +#define CONFIG_FFT_FIXED_32 0 +#include "fft_template.c" diff --git a/ffmpeg/libavcodec/fft_float.c b/ffmpeg/libavcodec/fft_float.c index 2149646..93d3607 100644 --- a/ffmpeg/libavcodec/fft_float.c +++ b/ffmpeg/libavcodec/fft_float.c @@ -17,4 +17,5 @@ */ #define CONFIG_FFT_FLOAT 1 -#include "fft.c" +#define CONFIG_FFT_FIXED_32 0 +#include "fft_template.c" diff --git a/ffmpeg/libavcodec/ffv1.c b/ffmpeg/libavcodec/ffv1.c index 404b0e3..f8556b0 100644 --- a/ffmpeg/libavcodec/ffv1.c +++ b/ffmpeg/libavcodec/ffv1.c @@ -1,7 +1,7 @@ /* * FFV1 codec for libavcodec * - * Copyright (c) 2003-2012 Michael Niedermayer + * Copyright (c) 2003-2013 Michael Niedermayer * * This file is part of FFmpeg. * @@ -25,6 +25,7 @@ * FF Video Codec 1 (a lossless codec) */ +#include "libavutil/attributes.h" #include "libavutil/avassert.h" #include "libavutil/crc.h" #include "libavutil/opt.h" @@ -48,7 +49,10 @@ av_cold int ffv1_common_init(AVCodecContext *avctx) s->avctx = avctx; s->flags = avctx->flags; - avcodec_get_frame_defaults(&s->picture); + s->picture.f = av_frame_alloc(); + s->last_picture.f = av_frame_alloc(); + if (!s->picture.f || !s->last_picture.f) + return AVERROR(ENOMEM); ff_dsputil_init(&s->dsp, avctx); @@ -62,7 +66,7 @@ av_cold int ffv1_common_init(AVCodecContext *avctx) return 0; } -int ffv1_init_slice_state(FFV1Context *f, FFV1Context *fs) +av_cold int ffv1_init_slice_state(FFV1Context *f, FFV1Context *fs) { int j; @@ -96,7 +100,7 @@ int ffv1_init_slice_state(FFV1Context *f, FFV1Context *fs) return 0; } -int ffv1_init_slices_state(FFV1Context *f) +av_cold int ffv1_init_slices_state(FFV1Context *f) { int i, ret; for (i = 0; i < f->slice_count; i++) { @@ -191,7 +195,13 @@ av_cold int ffv1_close(AVCodecContext *avctx) FFV1Context *s = avctx->priv_data; int i, j; - av_frame_unref(&s->last_picture); + if (s->picture.f) + ff_thread_release_buffer(avctx, &s->picture); + av_frame_free(&s->picture.f); + + if (s->last_picture.f) + ff_thread_release_buffer(avctx, &s->last_picture); + av_frame_free(&s->last_picture.f); for (j = 0; j < s->slice_count; j++) { FFV1Context *fs = s->slice_context[j]; diff --git a/ffmpeg/libavcodec/ffv1.h b/ffmpeg/libavcodec/ffv1.h index 23633c9..9d8329f 100644 --- a/ffmpeg/libavcodec/ffv1.h +++ b/ffmpeg/libavcodec/ffv1.h @@ -41,6 +41,7 @@ #include "mathops.h" #include "put_bits.h" #include "rangecoder.h" +#include "thread.h" #ifdef __INTEL_COMPILER #undef av_flatten @@ -82,14 +83,15 @@ typedef struct FFV1Context { uint64_t rc_stat[256][2]; uint64_t (*rc_stat2[MAX_QUANT_TABLES])[32][2]; int version; - int minor_version; + int micro_version; int width, height; int chroma_planes; int chroma_h_shift, chroma_v_shift; int transparency; int flags; int picture_number; - AVFrame picture, last_picture; + ThreadFrame picture, last_picture; + struct FFV1Context *fsrc; AVFrame *cur; int plane_count; @@ -106,6 +108,7 @@ typedef struct FFV1Context { int16_t *sample_buffer; int ec; + int intra; int slice_damaged; int key_frame_ok; @@ -125,6 +128,10 @@ typedef struct FFV1Context { int slice_height; int slice_x; int slice_y; + int slice_reset_contexts; + int slice_coding_mode; + int slice_rct_by_coef; + int slice_rct_ry_coef; } FFV1Context; int ffv1_common_init(AVCodecContext *avctx); diff --git a/ffmpeg/libavcodec/ffv1dec.c b/ffmpeg/libavcodec/ffv1dec.c index 21afa1d..d7dd110 100644 --- a/ffmpeg/libavcodec/ffv1dec.c +++ b/ffmpeg/libavcodec/ffv1dec.c @@ -1,7 +1,7 @@ /* * FFV1 decoder * - * Copyright (c) 2003-2012 Michael Niedermayer + * Copyright (c) 2003-2013 Michael Niedermayer * * This file is part of FFmpeg. * @@ -34,7 +34,6 @@ #include "avcodec.h" #include "internal.h" #include "get_bits.h" -#include "put_bits.h" #include "rangecoder.h" #include "golomb.h" #include "mathops.h" @@ -106,6 +105,19 @@ static av_always_inline void decode_line(FFV1Context *s, int w, int run_mode = 0; int run_index = s->run_index; + if (s->slice_coding_mode == 1) { + int i; + for (x = 0; x < w; x++) { + int v = 0; + for (i=0; islice_coding_mode == 0) decode_line(s, w, sample[p], (p + 1)/2, 9); else - decode_line(s, w, sample[p], (p + 1)/2, bits + 1); + decode_line(s, w, sample[p], (p + 1)/2, bits + (s->slice_coding_mode != 1)); } for (x = 0; x < w; x++) { int g = sample[0][1][x]; @@ -245,11 +257,13 @@ static void decode_rgb_frame(FFV1Context *s, uint8_t *src[3], int w, int h, int int r = sample[2][1][x]; int a = sample[3][1][x]; - b -= offset; - r -= offset; - g -= (b + r) >> 2; - b += g; - r += g; + if (s->slice_coding_mode != 1) { + b -= offset; + r -= offset; + g -= (b * s->slice_rct_by_coef + r * s->slice_rct_ry_coef) >> 2; + b += g; + r += g; + } if (lbd) *((uint32_t*)(src[0] + x*4 + stride[0]*y)) = b + (g<<8) + (r<<16) + (a<<24); @@ -316,7 +330,18 @@ static int decode_slice_header(FFV1Context *f, FFV1Context *fs) } f->cur->sample_aspect_ratio.num = get_symbol(c, state, 0); f->cur->sample_aspect_ratio.den = get_symbol(c, state, 0); - + if (fs->version > 3) { + fs->slice_reset_contexts = get_rac(c, state); + fs->slice_coding_mode = get_symbol(c, state, 0); + if (fs->slice_coding_mode != 1) { + fs->slice_rct_by_coef = get_symbol(c, state, 0); + fs->slice_rct_ry_coef = get_symbol(c, state, 0); + if ((uint64_t)fs->slice_rct_by_coef + (uint64_t)fs->slice_rct_ry_coef > 4) { + av_log(f->avctx, AV_LOG_ERROR, "slice_rct_y_coef out of range\n"); + return AVERROR_INVALIDDATA; + } + } + } return 0; } @@ -327,6 +352,45 @@ static int decode_slice(AVCodecContext *c, void *arg) int width, height, x, y, ret; const int ps = av_pix_fmt_desc_get(c->pix_fmt)->comp[0].step_minus1 + 1; AVFrame * const p = f->cur; + int i, si; + + for( si=0; fs != f->slice_context[si]; si ++) + ; + + if(f->fsrc && !p->key_frame) + ff_thread_await_progress(&f->last_picture, si, 0); + + if(f->fsrc && !p->key_frame) { + FFV1Context *fssrc = f->fsrc->slice_context[si]; + FFV1Context *fsdst = f->slice_context[si]; + av_assert1(fsdst->plane_count == fssrc->plane_count); + av_assert1(fsdst == fs); + + if (!p->key_frame) + fsdst->slice_damaged |= fssrc->slice_damaged; + + for (i = 0; i < f->plane_count; i++) { + PlaneContext *psrc = &fssrc->plane[i]; + PlaneContext *pdst = &fsdst->plane[i]; + + av_free(pdst->state); + av_free(pdst->vlc_state); + memcpy(pdst, psrc, sizeof(*pdst)); + pdst->state = NULL; + pdst->vlc_state = NULL; + + if (fssrc->ac) { + pdst->state = av_malloc(CONTEXT_SIZE * psrc->context_count); + memcpy(pdst->state, psrc->state, CONTEXT_SIZE * psrc->context_count); + } else { + pdst->vlc_state = av_malloc(sizeof(*pdst->vlc_state) * psrc->context_count); + memcpy(pdst->vlc_state, psrc->vlc_state, sizeof(*pdst->vlc_state) * psrc->context_count); + } + } + } + + fs->slice_rct_by_coef = 1; + fs->slice_rct_ry_coef = 1; if (f->version > 2) { if (ffv1_init_slice_state(f, fs) < 0) @@ -338,7 +402,7 @@ static int decode_slice(AVCodecContext *c, void *arg) } if ((ret = ffv1_init_slice_state(f, fs)) < 0) return ret; - if (f->cur->key_frame) + if (f->cur->key_frame || fs->slice_reset_contexts) ffv1_clear_slice_state(f, fs); width = fs->slice_width; @@ -347,7 +411,7 @@ static int decode_slice(AVCodecContext *c, void *arg) y = fs->slice_y; if (!fs->ac) { - if (f->version == 3 && f->minor_version > 1 || f->version > 3) + if (f->version == 3 && f->micro_version > 1 || f->version > 3) get_rac(&fs->c, (uint8_t[]) { 129 }); fs->ac_byte_count = f->version > 2 || (!x && !y) ? fs->c.bytestream - fs->c.bytestream_start - 1 : 0; init_get_bits(&fs->gb, @@ -357,8 +421,8 @@ static int decode_slice(AVCodecContext *c, void *arg) av_assert1(width && height); if (f->colorspace == 0) { - const int chroma_width = -((-width) >> f->chroma_h_shift); - const int chroma_height = -((-height) >> f->chroma_v_shift); + const int chroma_width = FF_CEIL_RSHIFT(width, f->chroma_h_shift); + const int chroma_height = FF_CEIL_RSHIFT(height, f->chroma_v_shift); const int cx = x >> f->chroma_h_shift; const int cy = y >> f->chroma_v_shift; decode_plane(fs, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0); @@ -387,6 +451,8 @@ static int decode_slice(AVCodecContext *c, void *arg) emms_c(); + ff_thread_report_progress(&f->picture, si, 0); + return 0; } @@ -446,9 +512,13 @@ static int read_extra_header(FFV1Context *f) ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8); f->version = get_symbol(c, state, 0); + if (f->version < 2) { + av_log(f->avctx, AV_LOG_ERROR, "Invalid version in global header\n"); + return AVERROR_INVALIDDATA; + } if (f->version > 2) { c->bytestream_end -= 4; - f->minor_version = get_symbol(c, state, 0); + f->micro_version = get_symbol(c, state, 0); } f->ac = f->avctx->coder_type = get_symbol(c, state, 0); if (f->ac > 1) { @@ -462,7 +532,7 @@ static int read_extra_header(FFV1Context *f) f->chroma_h_shift = get_symbol(c, state, 0); f->chroma_v_shift = get_symbol(c, state, 0); f->transparency = get_rac(c, state); - f->plane_count = 2 + f->transparency; + f->plane_count = 1 + (f->chroma_planes || f->version<4) + f->transparency; f->num_h_slices = 1 + get_symbol(c, state, 0); f->num_v_slices = 1 + get_symbol(c, state, 0); @@ -499,6 +569,8 @@ static int read_extra_header(FFV1Context *f) if (f->version > 2) { f->ec = get_symbol(c, state, 0); + if (f->micro_version > 2) + f->intra = get_symbol(c, state, 0); } if (f->version > 2) { @@ -511,6 +583,20 @@ static int read_extra_header(FFV1Context *f) } } + if (f->avctx->debug & FF_DEBUG_PICT_INFO) + av_log(f->avctx, AV_LOG_DEBUG, + "global: ver:%d.%d, coder:%d, colorspace: %d bpr:%d chroma:%d(%d:%d), alpha:%d slices:%dx%d qtabs:%d ec:%d intra:%d\n", + f->version, f->micro_version, + f->ac, + f->colorspace, + f->avctx->bits_per_raw_sample, + f->chroma_planes, f->chroma_h_shift, f->chroma_v_shift, + f->transparency, + f->num_h_slices, f->num_v_slices, + f->quant_table_count, + f->ec, + f->intra + ); return 0; } @@ -523,6 +609,7 @@ static int read_header(FFV1Context *f) memset(state, 128, sizeof(state)); if (f->version < 2) { + int chroma_planes, chroma_h_shift, chroma_v_shift, transparency, colorspace, bits_per_raw_sample; unsigned v= get_symbol(c, state, 0); if (v >= 2) { av_log(f->avctx, AV_LOG_ERROR, "invalid version %d in ver01 header\n", v); @@ -535,19 +622,37 @@ static int read_header(FFV1Context *f) f->state_transition[i] = get_symbol(c, state, 1) + c->one_state[i]; } - f->colorspace = get_symbol(c, state, 0); //YUV cs type + colorspace = get_symbol(c, state, 0); //YUV cs type + bits_per_raw_sample = f->version > 0 ? get_symbol(c, state, 0) : f->avctx->bits_per_raw_sample; + chroma_planes = get_rac(c, state); + chroma_h_shift = get_symbol(c, state, 0); + chroma_v_shift = get_symbol(c, state, 0); + transparency = get_rac(c, state); + + if (f->plane_count) { + if ( colorspace != f->colorspace + || bits_per_raw_sample != f->avctx->bits_per_raw_sample + || chroma_planes != f->chroma_planes + || chroma_h_shift!= f->chroma_h_shift + || chroma_v_shift!= f->chroma_v_shift + || transparency != f->transparency) { + av_log(f->avctx, AV_LOG_ERROR, "Invalid change of global parameters\n"); + return AVERROR_INVALIDDATA; + } + } - if (f->version > 0) - f->avctx->bits_per_raw_sample = get_symbol(c, state, 0); + f->colorspace = colorspace; + f->avctx->bits_per_raw_sample = bits_per_raw_sample; + f->chroma_planes = chroma_planes; + f->chroma_h_shift = chroma_h_shift; + f->chroma_v_shift = chroma_v_shift; + f->transparency = transparency; - f->chroma_planes = get_rac(c, state); - f->chroma_h_shift = get_symbol(c, state, 0); - f->chroma_v_shift = get_symbol(c, state, 0); - f->transparency = get_rac(c, state); f->plane_count = 2 + f->transparency; } if (f->colorspace == 0) { + if (f->avctx->skip_alpha) f->transparency = 0; if (!f->transparency && !f->chroma_planes) { if (f->avctx->bits_per_raw_sample <= 8) f->avctx->pix_fmt = AV_PIX_FMT_GRAY8; @@ -561,47 +666,52 @@ static int read_header(FFV1Context *f) case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUV420P; break; case 0x20: f->avctx->pix_fmt = AV_PIX_FMT_YUV411P; break; case 0x22: f->avctx->pix_fmt = AV_PIX_FMT_YUV410P; break; - default: - av_log(f->avctx, AV_LOG_ERROR, "format not supported\n"); - return AVERROR(ENOSYS); } } else if (f->avctx->bits_per_raw_sample <= 8 && f->transparency) { switch(16*f->chroma_h_shift + f->chroma_v_shift) { case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUVA444P; break; case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUVA422P; break; case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUVA420P; break; - default: - av_log(f->avctx, AV_LOG_ERROR, "format not supported\n"); - return AVERROR(ENOSYS); } - } else if (f->avctx->bits_per_raw_sample == 9) { + } else if (f->avctx->bits_per_raw_sample == 9 && !f->transparency) { f->packed_at_lsb = 1; switch(16 * f->chroma_h_shift + f->chroma_v_shift) { case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUV444P9; break; case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUV422P9; break; case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUV420P9; break; - default: - av_log(f->avctx, AV_LOG_ERROR, "format not supported\n"); - return AVERROR(ENOSYS); } - } else if (f->avctx->bits_per_raw_sample == 10) { + } else if (f->avctx->bits_per_raw_sample == 9 && f->transparency) { + f->packed_at_lsb = 1; + switch(16 * f->chroma_h_shift + f->chroma_v_shift) { + case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUVA444P9; break; + case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUVA422P9; break; + case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUVA420P9; break; + } + } else if (f->avctx->bits_per_raw_sample == 10 && !f->transparency) { f->packed_at_lsb = 1; switch(16 * f->chroma_h_shift + f->chroma_v_shift) { case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUV444P10; break; case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUV422P10; break; case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUV420P10; break; - default: - av_log(f->avctx, AV_LOG_ERROR, "format not supported\n"); - return AVERROR(ENOSYS); } - } else { + } else if (f->avctx->bits_per_raw_sample == 10 && f->transparency) { + f->packed_at_lsb = 1; + switch(16 * f->chroma_h_shift + f->chroma_v_shift) { + case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUVA444P10; break; + case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUVA422P10; break; + case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUVA420P10; break; + } + } else if (f->avctx->bits_per_raw_sample == 16 && !f->transparency){ switch(16 * f->chroma_h_shift + f->chroma_v_shift) { case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUV444P16; break; case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUV422P16; break; case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUV420P16; break; - default: - av_log(f->avctx, AV_LOG_ERROR, "format not supported\n"); - return AVERROR(ENOSYS); + } + } else if (f->avctx->bits_per_raw_sample == 16 && f->transparency){ + switch(16 * f->chroma_h_shift + f->chroma_v_shift) { + case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUVA444P16; break; + case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUVA422P16; break; + case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUVA420P16; break; } } } else if (f->colorspace == 1) { @@ -625,6 +735,10 @@ static int read_header(FFV1Context *f) av_log(f->avctx, AV_LOG_ERROR, "colorspace not supported\n"); return AVERROR(ENOSYS); } + if (f->avctx->pix_fmt == AV_PIX_FMT_NONE) { + av_log(f->avctx, AV_LOG_ERROR, "format not supported\n"); + return AVERROR(ENOSYS); + } av_dlog(f->avctx, "%d %d %d\n", f->chroma_h_shift, f->chroma_v_shift, f->avctx->pix_fmt); @@ -723,6 +837,8 @@ static av_cold int decode_init(AVCodecContext *avctx) if ((ret = ffv1_init_slice_contexts(f)) < 0) return ret; + avctx->internal->allocate_progress = 1; + return 0; } @@ -735,10 +851,22 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac int i, ret; uint8_t keystate = 128; const uint8_t *buf_p; - AVFrame *const p = data; + AVFrame *p; + + if (f->last_picture.f) + ff_thread_release_buffer(avctx, &f->last_picture); + FFSWAP(ThreadFrame, f->picture, f->last_picture); - f->cur = p; + f->cur = p = f->picture.f; + if (f->version < 3 && avctx->field_order > AV_FIELD_PROGRESSIVE) { + /* we have interlaced material flagged in container */ + p->interlaced_frame = 1; + if (avctx->field_order == AV_FIELD_TT || avctx->field_order == AV_FIELD_TB) + p->top_field_first = 1; + } + + f->avctx = avctx; ff_init_range_decoder(c, buf, buf_size); ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8); @@ -758,13 +886,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac p->key_frame = 0; } - if ((ret = ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF)) < 0) + if ((ret = ff_thread_get_buffer(avctx, &f->picture, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; if (avctx->debug & FF_DEBUG_PICT_INFO) av_log(avctx, AV_LOG_DEBUG, "ver:%d keyframe:%d coder:%d ec:%d slices:%d bps:%d\n", f->version, p->key_frame, f->ac, f->ec, f->slice_count, f->avctx->bits_per_raw_sample); + ff_thread_finish_setup(avctx); + buf_p = buf + buf_size; for (i = f->slice_count - 1; i >= 0; i--) { FFV1Context *fs = f->slice_context[i]; @@ -800,6 +930,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac } else fs->c.bytestream_end = (uint8_t *)(buf_p + v); + fs->avctx = avctx; fs->cur = p; } @@ -813,46 +944,143 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac for (i = f->slice_count - 1; i >= 0; i--) { FFV1Context *fs = f->slice_context[i]; int j; - if (fs->slice_damaged && f->last_picture.data[0]) { + if (fs->slice_damaged && f->last_picture.f->data[0]) { const uint8_t *src[4]; uint8_t *dst[4]; + ff_thread_await_progress(&f->last_picture, INT_MAX, 0); for (j = 0; j < 4; j++) { - int sh = (j==1 || j==2) ? f->chroma_h_shift : 0; - int sv = (j==1 || j==2) ? f->chroma_v_shift : 0; - dst[j] = p->data[j] + p->linesize[j]* - (fs->slice_y>>sv) + (fs->slice_x>>sh); - src[j] = f->last_picture.data[j] + f->last_picture.linesize[j]* - (fs->slice_y>>sv) + (fs->slice_x>>sh); + int sh = (j == 1 || j == 2) ? f->chroma_h_shift : 0; + int sv = (j == 1 || j == 2) ? f->chroma_v_shift : 0; + dst[j] = p->data[j] + p->linesize[j] * + (fs->slice_y >> sv) + (fs->slice_x >> sh); + src[j] = f->last_picture.f->data[j] + f->last_picture.f->linesize[j] * + (fs->slice_y >> sv) + (fs->slice_x >> sh); } av_image_copy(dst, p->linesize, (const uint8_t **)src, - f->last_picture.linesize, + f->last_picture.f->linesize, avctx->pix_fmt, fs->slice_width, fs->slice_height); } } + ff_thread_report_progress(&f->picture, INT_MAX, 0); f->picture_number++; - av_frame_unref(&f->last_picture); - if ((ret = av_frame_ref(&f->last_picture, p)) < 0) - return ret; + if (f->last_picture.f) + ff_thread_release_buffer(avctx, &f->last_picture); f->cur = NULL; + if ((ret = av_frame_ref(data, f->picture.f)) < 0) + return ret; *got_frame = 1; return buf_size; } +static int init_thread_copy(AVCodecContext *avctx) +{ + FFV1Context *f = avctx->priv_data; + int i, ret; + + f->picture.f = NULL; + f->last_picture.f = NULL; + f->sample_buffer = NULL; + f->slice_count = 0; + + for (i = 0; i < f->quant_table_count; i++) { + av_assert0(f->version > 1); + f->initial_states[i] = av_memdup(f->initial_states[i], + f->context_count[i] * sizeof(*f->initial_states[i])); + } + + f->picture.f = av_frame_alloc(); + f->last_picture.f = av_frame_alloc(); + + if ((ret = ffv1_init_slice_contexts(f)) < 0) + return ret; + + return 0; +} + +static void copy_fields(FFV1Context *fsdst, FFV1Context *fssrc, FFV1Context *fsrc) +{ + fsdst->version = fsrc->version; + fsdst->micro_version = fsrc->micro_version; + fsdst->chroma_planes = fsrc->chroma_planes; + fsdst->chroma_h_shift = fsrc->chroma_h_shift; + fsdst->chroma_v_shift = fsrc->chroma_v_shift; + fsdst->transparency = fsrc->transparency; + fsdst->plane_count = fsrc->plane_count; + fsdst->ac = fsrc->ac; + fsdst->colorspace = fsrc->colorspace; + + fsdst->ec = fsrc->ec; + fsdst->intra = fsrc->intra; + fsdst->slice_damaged = fssrc->slice_damaged; + fsdst->key_frame_ok = fsrc->key_frame_ok; + + fsdst->bits_per_raw_sample = fsrc->bits_per_raw_sample; + fsdst->packed_at_lsb = fsrc->packed_at_lsb; + fsdst->slice_count = fsrc->slice_count; + if (fsrc->version<3){ + fsdst->slice_x = fssrc->slice_x; + fsdst->slice_y = fssrc->slice_y; + fsdst->slice_width = fssrc->slice_width; + fsdst->slice_height = fssrc->slice_height; + } +} + +static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) +{ + FFV1Context *fsrc = src->priv_data; + FFV1Context *fdst = dst->priv_data; + int i, ret; + + if (dst == src) + return 0; + + { + FFV1Context bak = *fdst; + memcpy(fdst, fsrc, sizeof(*fdst)); + memcpy(fdst->initial_states, bak.initial_states, sizeof(fdst->initial_states)); + memcpy(fdst->slice_context, bak.slice_context , sizeof(fdst->slice_context)); + fdst->picture = bak.picture; + fdst->last_picture = bak.last_picture; + for (i = 0; inum_h_slices * fdst->num_v_slices; i++) { + FFV1Context *fssrc = fsrc->slice_context[i]; + FFV1Context *fsdst = fdst->slice_context[i]; + copy_fields(fsdst, fssrc, fsrc); + } + av_assert0(!fdst->plane[0].state); + av_assert0(!fdst->sample_buffer); + } + + av_assert1(fdst->slice_count == fsrc->slice_count); + + + ff_thread_release_buffer(dst, &fdst->picture); + if (fsrc->picture.f->data[0]) { + if ((ret = ff_thread_ref_frame(&fdst->picture, &fsrc->picture)) < 0) + return ret; + } + + fdst->fsrc = fsrc; + + return 0; +} + AVCodec ff_ffv1_decoder = { .name = "ffv1", + .long_name = NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_FFV1, .priv_data_size = sizeof(FFV1Context), .init = decode_init, .close = ffv1_close, .decode = decode_frame, + .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy), + .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context), .capabilities = CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/ | - CODEC_CAP_SLICE_THREADS, - .long_name = NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"), + CODEC_CAP_FRAME_THREADS | CODEC_CAP_SLICE_THREADS, }; diff --git a/ffmpeg/libavcodec/ffv1enc.c b/ffmpeg/libavcodec/ffv1enc.c index 70fcd65..7f9f203 100644 --- a/ffmpeg/libavcodec/ffv1enc.c +++ b/ffmpeg/libavcodec/ffv1enc.c @@ -1,7 +1,7 @@ /* * FFV1 encoder * - * Copyright (c) 2003-2012 Michael Niedermayer + * Copyright (c) 2003-2013 Michael Niedermayer * * This file is part of FFmpeg. * @@ -25,6 +25,7 @@ * FF Video Codec 1 (a lossless codec) encoder */ +#include "libavutil/attributes.h" #include "libavutil/avassert.h" #include "libavutil/crc.h" #include "libavutil/opt.h" @@ -274,7 +275,7 @@ static av_always_inline int encode_line(FFV1Context *s, int w, int run_mode = 0; if (s->ac) { - if (c->bytestream_end - c->bytestream < w * 20) { + if (c->bytestream_end - c->bytestream < w * 35) { av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); return AVERROR_INVALIDDATA; } @@ -285,6 +286,18 @@ static av_always_inline int encode_line(FFV1Context *s, int w, } } + if (s->slice_coding_mode == 1) { + for (x = 0; x < w; x++) { + int i; + int v = sample[0][x]; + for (i = bits-1; i>=0; i--) { + uint8_t state = 128; + put_rac(c, &state, (v>>i) & 1); + } + } + return 0; + } + for (x = 0; x < w; x++) { int diff, context; @@ -352,10 +365,10 @@ static av_always_inline int encode_line(FFV1Context *s, int w, return 0; } -static void encode_plane(FFV1Context *s, uint8_t *src, int w, int h, +static int encode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, int plane_index) { - int x, y, i; + int x, y, i, ret; const int ring_size = s->avctx->context_model ? 3 : 2; int16_t *sample[3]; s->run_index = 0; @@ -372,7 +385,8 @@ static void encode_plane(FFV1Context *s, uint8_t *src, int w, int h, if (s->bits_per_raw_sample <= 8) { for (x = 0; x < w; x++) sample[0][x] = src[x + stride * y]; - encode_line(s, w, sample, plane_index, 8); + if((ret = encode_line(s, w, sample, plane_index, 8)) < 0) + return ret; } else { if (s->packed_at_lsb) { for (x = 0; x < w; x++) { @@ -383,13 +397,15 @@ static void encode_plane(FFV1Context *s, uint8_t *src, int w, int h, sample[0][x] = ((uint16_t*)(src + stride*y))[x] >> (16 - s->bits_per_raw_sample); } } - encode_line(s, w, sample, plane_index, s->bits_per_raw_sample); + if((ret = encode_line(s, w, sample, plane_index, s->bits_per_raw_sample)) < 0) + return ret; } // STOP_TIMER("encode line") } } + return 0; } -static void encode_rgb_frame(FFV1Context *s, uint8_t *src[3], int w, int h, int stride[3]) +static int encode_rgb_frame(FFV1Context *s, uint8_t *src[3], int w, int h, int stride[3]) { int x, y, p, i; const int ring_size = s->avctx->context_model ? 3 : 2; @@ -422,11 +438,13 @@ static void encode_rgb_frame(FFV1Context *s, uint8_t *src[3], int w, int h, int r = *((uint16_t*)(src[2] + x*2 + stride[2]*y)); } - b -= g; - r -= g; - g += (b + r) >> 2; - b += offset; - r += offset; + if (s->slice_coding_mode != 1) { + b -= g; + r -= g; + g += (b * s->slice_rct_by_coef + r * s->slice_rct_ry_coef) >> 2; + b += offset; + r += offset; + } sample[0][0][x] = g; sample[1][0][x] = b; @@ -434,14 +452,18 @@ static void encode_rgb_frame(FFV1Context *s, uint8_t *src[3], int w, int h, int sample[3][0][x] = a; } for (p = 0; p < 3 + s->transparency; p++) { + int ret; sample[p][0][-1] = sample[p][1][0 ]; sample[p][1][ w] = sample[p][1][w-1]; - if (lbd) - encode_line(s, w, sample[p], (p + 1) / 2, 9); + if (lbd && s->slice_coding_mode == 0) + ret = encode_line(s, w, sample[p], (p + 1) / 2, 9); else - encode_line(s, w, sample[p], (p + 1) / 2, bits + 1); + ret = encode_line(s, w, sample[p], (p + 1) / 2, bits + (s->slice_coding_mode != 1)); + if (ret < 0) + return ret; } } + return 0; } static void write_quant_table(RangeCoder *c, int16_t *quant_table) @@ -528,14 +550,18 @@ static int write_extradata(FFV1Context *f) f->avctx->extradata_size = 10000 + 4 + (11 * 11 * 5 * 5 * 5 + 11 * 11 * 11) * 32; f->avctx->extradata = av_malloc(f->avctx->extradata_size); + if (!f->avctx->extradata) + return AVERROR(ENOMEM); ff_init_range_encoder(c, f->avctx->extradata, f->avctx->extradata_size); ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8); put_symbol(c, state, f->version, 0); if (f->version > 2) { - if (f->version == 3) - f->minor_version = 2; - put_symbol(c, state, f->minor_version, 0); + if (f->version == 3) { + f->micro_version = 4; + } else if (f->version == 4) + f->micro_version = 2; + put_symbol(c, state, f->micro_version, 0); } put_symbol(c, state, f->ac, 0); @@ -575,6 +601,7 @@ static int write_extradata(FFV1Context *f) if (f->version > 2) { put_symbol(c, state, f->ec, 0); + put_symbol(c, state, f->intra = (f->avctx->gop_size < 2), 0); } f->avctx->extradata_size = ff_rac_terminate(c); @@ -639,22 +666,25 @@ static av_cold int encode_init(AVCodecContext *avctx) const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); int i, j, k, m, ret; - ffv1_common_init(avctx); + if ((ret = ffv1_common_init(avctx)) < 0) + return ret; s->version = 0; if ((avctx->flags & (CODEC_FLAG_PASS1|CODEC_FLAG_PASS2)) || avctx->slices>1) s->version = FFMAX(s->version, 2); - if (avctx->level == 3) { + if (avctx->level <= 0 && s->version == 2) { s->version = 3; } + if (avctx->level >= 0 && avctx->level <= 4) + s->version = FFMAX(s->version, avctx->level); if (s->ec < 0) { s->ec = (s->version >= 3); } - if (s->version >= 2 && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { + if ((s->version == 2 || s->version>3) && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { av_log(avctx, AV_LOG_ERROR, "Version 2 needed for requested features but version 2 is experimental and not enabled\n"); return AVERROR_INVALIDDATA; } @@ -666,11 +696,17 @@ static av_cold int encode_init(AVCodecContext *avctx) case AV_PIX_FMT_YUV444P9: case AV_PIX_FMT_YUV422P9: case AV_PIX_FMT_YUV420P9: + case AV_PIX_FMT_YUVA444P9: + case AV_PIX_FMT_YUVA422P9: + case AV_PIX_FMT_YUVA420P9: if (!avctx->bits_per_raw_sample) s->bits_per_raw_sample = 9; case AV_PIX_FMT_YUV444P10: case AV_PIX_FMT_YUV420P10: case AV_PIX_FMT_YUV422P10: + case AV_PIX_FMT_YUVA444P10: + case AV_PIX_FMT_YUVA422P10: + case AV_PIX_FMT_YUVA420P10: s->packed_at_lsb = 1; if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample) s->bits_per_raw_sample = 10; @@ -678,6 +714,9 @@ static av_cold int encode_init(AVCodecContext *avctx) case AV_PIX_FMT_YUV444P16: case AV_PIX_FMT_YUV422P16: case AV_PIX_FMT_YUV420P16: + case AV_PIX_FMT_YUVA444P16: + case AV_PIX_FMT_YUVA422P16: + case AV_PIX_FMT_YUVA420P16: if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample) { s->bits_per_raw_sample = 16; } else if (!s->bits_per_raw_sample) { @@ -703,22 +742,21 @@ static av_cold int encode_init(AVCodecContext *avctx) case AV_PIX_FMT_YUV420P: case AV_PIX_FMT_YUV411P: case AV_PIX_FMT_YUV410P: - s->chroma_planes = desc->nb_components < 3 ? 0 : 1; - s->colorspace = 0; - break; case AV_PIX_FMT_YUVA444P: case AV_PIX_FMT_YUVA422P: case AV_PIX_FMT_YUVA420P: - s->chroma_planes = 1; + s->chroma_planes = desc->nb_components < 3 ? 0 : 1; s->colorspace = 0; - s->transparency = 1; + s->transparency = desc->nb_components == 4; break; case AV_PIX_FMT_RGB32: s->colorspace = 1; s->transparency = 1; + s->chroma_planes = 1; break; case AV_PIX_FMT_0RGB32: s->colorspace = 1; + s->chroma_planes = 1; break; case AV_PIX_FMT_GBRP9: if (!avctx->bits_per_raw_sample) @@ -737,6 +775,10 @@ static av_cold int encode_init(AVCodecContext *avctx) s->colorspace = 1; s->chroma_planes = 1; s->version = FFMAX(s->version, 1); + if (!s->ac) { + av_log(avctx, AV_LOG_ERROR, "bits_per_raw_sample of more than 8 needs -coder 1 currently\n"); + return AVERROR(ENOSYS); + } break; default: av_log(avctx, AV_LOG_ERROR, "format not supported\n"); @@ -792,9 +834,17 @@ static av_cold int encode_init(AVCodecContext *avctx) if ((ret = ffv1_allocate_initial_states(s)) < 0) return ret; - avctx->coded_frame = &s->picture; + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + if (!s->transparency) s->plane_count = 2; + if (!s->chroma_planes && s->version > 3) + s->plane_count--; + avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift); s->picture_number = 0; @@ -895,7 +945,8 @@ static av_cold int encode_init(AVCodecContext *avctx) avctx->slices); return AVERROR(ENOSYS); slices_ok: - write_extradata(s); + if ((ret = write_extradata(s)) < 0) + return ret; } if ((ret = ffv1_init_slice_contexts(s)) < 0) @@ -937,12 +988,104 @@ static void encode_slice_header(FFV1Context *f, FFV1Context *fs) put_symbol(c, state, f->plane[j].quant_table_index, 0); av_assert0(f->plane[j].quant_table_index == f->avctx->context_model); } - if (!f->picture.interlaced_frame) + if (!f->picture.f->interlaced_frame) put_symbol(c, state, 3, 0); else - put_symbol(c, state, 1 + !f->picture.top_field_first, 0); - put_symbol(c, state, f->picture.sample_aspect_ratio.num, 0); - put_symbol(c, state, f->picture.sample_aspect_ratio.den, 0); + put_symbol(c, state, 1 + !f->picture.f->top_field_first, 0); + put_symbol(c, state, f->picture.f->sample_aspect_ratio.num, 0); + put_symbol(c, state, f->picture.f->sample_aspect_ratio.den, 0); + if (f->version > 3) { + put_rac(c, state, fs->slice_coding_mode == 1); + if (fs->slice_coding_mode == 1) + ffv1_clear_slice_state(f, fs); + put_symbol(c, state, fs->slice_coding_mode, 0); + if (fs->slice_coding_mode != 1) { + put_symbol(c, state, fs->slice_rct_by_coef, 0); + put_symbol(c, state, fs->slice_rct_ry_coef, 0); + } + } +} + +static void choose_rct_params(FFV1Context *fs, uint8_t *src[3], const int stride[3], int w, int h) +{ +#define NB_Y_COEFF 15 + static const int rct_y_coeff[15][2] = { + {0, 0}, // 4G + {1, 1}, // R + 2G + B + {2, 2}, // 2R + 2B + {0, 2}, // 2G + 2B + {2, 0}, // 2R + 2G + {4, 0}, // 4R + {0, 4}, // 4B + + {0, 3}, // 1G + 3B + {3, 0}, // 3R + 1G + {3, 1}, // 3R + B + {1, 3}, // R + 3B + {1, 2}, // R + G + 2B + {2, 1}, // 2R + G + B + {0, 1}, // 3G + B + {1, 0}, // R + 3G + }; + + int stat[NB_Y_COEFF] = {0}; + int x, y, i, p, best; + int16_t *sample[3]; + int lbd = fs->bits_per_raw_sample <= 8; + + for (y = 0; y < h; y++) { + int lastr=0, lastg=0, lastb=0; + for (p = 0; p < 3; p++) + sample[p] = fs->sample_buffer + p*w; + + for (x = 0; x < w; x++) { + int b, g, r; + int ab, ag, ar; + if (lbd) { + unsigned v = *((uint32_t*)(src[0] + x*4 + stride[0]*y)); + b = v & 0xFF; + g = (v >> 8) & 0xFF; + r = (v >> 16) & 0xFF; + } else { + b = *((uint16_t*)(src[0] + x*2 + stride[0]*y)); + g = *((uint16_t*)(src[1] + x*2 + stride[1]*y)); + r = *((uint16_t*)(src[2] + x*2 + stride[2]*y)); + } + + ar = r - lastr; + ag = g - lastg; + ab = b - lastb; + if (x && y) { + int bg = ag - sample[0][x]; + int bb = ab - sample[1][x]; + int br = ar - sample[2][x]; + + br -= bg; + bb -= bg; + + for (i = 0; i>2)); + } + + } + sample[0][x] = ag; + sample[1][x] = ab; + sample[2][x] = ar; + + lastr = r; + lastg = g; + lastb = b; + } + } + + best = 0; + for (i=1; islice_rct_by_coef = rct_y_coeff[best][1]; + fs->slice_rct_ry_coef = rct_y_coeff[best][0]; } static int encode_slice(AVCodecContext *c, void *arg) @@ -953,10 +1096,24 @@ static int encode_slice(AVCodecContext *c, void *arg) int height = fs->slice_height; int x = fs->slice_x; int y = fs->slice_y; - AVFrame *const p = &f->picture; + const AVFrame *const p = f->picture.f; const int ps = av_pix_fmt_desc_get(c->pix_fmt)->comp[0].step_minus1 + 1; + int ret; + RangeCoder c_bak = fs->c; + uint8_t *planes[3] = {p->data[0] + ps*x + y*p->linesize[0], + p->data[1] + ps*x + y*p->linesize[1], + p->data[2] + ps*x + y*p->linesize[2]}; + + fs->slice_coding_mode = 0; + if (f->version > 3) { + choose_rct_params(fs, planes, p->linesize, width, height); + } else { + fs->slice_rct_by_coef = 1; + fs->slice_rct_ry_coef = 1; + } - if (p->key_frame) +retry: + if (c->coded_frame->key_frame) ffv1_clear_slice_state(f, fs); if (f->version > 2) { encode_slice_header(f, fs); @@ -971,27 +1128,36 @@ static int encode_slice(AVCodecContext *c, void *arg) } if (f->colorspace == 0) { - const int chroma_width = -((-width) >> f->chroma_h_shift); - const int chroma_height = -((-height) >> f->chroma_v_shift); + const int chroma_width = FF_CEIL_RSHIFT(width, f->chroma_h_shift); + const int chroma_height = FF_CEIL_RSHIFT(height, f->chroma_v_shift); const int cx = x >> f->chroma_h_shift; const int cy = y >> f->chroma_v_shift; - encode_plane(fs, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0); + ret = encode_plane(fs, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0); if (f->chroma_planes) { - encode_plane(fs, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1); - encode_plane(fs, p->data[2] + ps*cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 1); + ret |= encode_plane(fs, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1); + ret |= encode_plane(fs, p->data[2] + ps*cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 1); } if (fs->transparency) - encode_plane(fs, p->data[3] + ps*x + y*p->linesize[3], width, height, p->linesize[3], 2); + ret |= encode_plane(fs, p->data[3] + ps*x + y*p->linesize[3], width, height, p->linesize[3], 2); } else { - uint8_t *planes[3] = {p->data[0] + ps*x + y*p->linesize[0], - p->data[1] + ps*x + y*p->linesize[1], - p->data[2] + ps*x + y*p->linesize[2]}; - encode_rgb_frame(fs, planes, width, height, p->linesize); + ret = encode_rgb_frame(fs, planes, width, height, p->linesize); } emms_c(); + if (ret < 0) { + av_assert0(fs->slice_coding_mode == 0); + if (fs->version < 4 || !fs->ac) { + av_log(c, AV_LOG_ERROR, "Buffer too small\n"); + return ret; + } + av_log(c, AV_LOG_DEBUG, "Coding slice as PCM\n"); + fs->slice_coding_mode = 1; + fs->c = c_bak; + goto retry; + } + return 0; } @@ -1000,30 +1166,81 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, { FFV1Context *f = avctx->priv_data; RangeCoder *const c = &f->slice_context[0]->c; - AVFrame *const p = &f->picture; + AVFrame *const p = f->picture.f; int used_count = 0; uint8_t keystate = 128; uint8_t *buf_p; int i, ret; + int64_t maxsize = FF_MIN_BUFFER_SIZE + + avctx->width*avctx->height*35LL*4; + + if(!pict) { + if (avctx->flags & CODEC_FLAG_PASS1) { + int j, k, m; + char *p = avctx->stats_out; + char *end = p + STATS_OUT_SIZE; + + memset(f->rc_stat, 0, sizeof(f->rc_stat)); + for (i = 0; i < f->quant_table_count; i++) + memset(f->rc_stat2[i], 0, f->context_count[i] * sizeof(*f->rc_stat2[i])); + + for (j = 0; j < f->slice_count; j++) { + FFV1Context *fs = f->slice_context[j]; + for (i = 0; i < 256; i++) { + f->rc_stat[i][0] += fs->rc_stat[i][0]; + f->rc_stat[i][1] += fs->rc_stat[i][1]; + } + for (i = 0; i < f->quant_table_count; i++) { + for (k = 0; k < f->context_count[i]; k++) + for (m = 0; m < 32; m++) { + f->rc_stat2[i][k][m][0] += fs->rc_stat2[i][k][m][0]; + f->rc_stat2[i][k][m][1] += fs->rc_stat2[i][k][m][1]; + } + } + } + + for (j = 0; j < 256; j++) { + snprintf(p, end - p, "%" PRIu64 " %" PRIu64 " ", + f->rc_stat[j][0], f->rc_stat[j][1]); + p += strlen(p); + } + snprintf(p, end - p, "\n"); + + for (i = 0; i < f->quant_table_count; i++) { + for (j = 0; j < f->context_count[i]; j++) + for (m = 0; m < 32; m++) { + snprintf(p, end - p, "%" PRIu64 " %" PRIu64 " ", + f->rc_stat2[i][j][m][0], f->rc_stat2[i][j][m][1]); + p += strlen(p); + } + } + snprintf(p, end - p, "%d\n", f->gob_count); + } + return 0; + } + + if (f->version > 3) + maxsize = FF_MIN_BUFFER_SIZE + avctx->width*avctx->height*3LL*4; - if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width*avctx->height*((8*2+1+1)*4)/8 - + FF_MIN_BUFFER_SIZE)) < 0) + if ((ret = ff_alloc_packet2(avctx, pkt, maxsize)) < 0) return ret; ff_init_range_encoder(c, pkt->data, pkt->size); ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8); - *p = *pict; - p->pict_type = AV_PICTURE_TYPE_I; + av_frame_unref(p); + if ((ret = av_frame_ref(p, pict)) < 0) + return ret; + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; if (avctx->gop_size == 0 || f->picture_number % avctx->gop_size == 0) { put_rac(c, &keystate, 1); - p->key_frame = 1; + avctx->coded_frame->key_frame = 1; f->gob_count++; write_header(f); } else { put_rac(c, &keystate, 0); - p->key_frame = 0; + avctx->coded_frame->key_frame = 0; } if (f->ac > 1) { @@ -1073,57 +1290,26 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, buf_p += bytes; } - if ((avctx->flags & CODEC_FLAG_PASS1) && (f->picture_number & 31) == 0) { - int j, k, m; - char *p = avctx->stats_out; - char *end = p + STATS_OUT_SIZE; - - memset(f->rc_stat, 0, sizeof(f->rc_stat)); - for (i = 0; i < f->quant_table_count; i++) - memset(f->rc_stat2[i], 0, f->context_count[i] * sizeof(*f->rc_stat2[i])); - - for (j = 0; j < f->slice_count; j++) { - FFV1Context *fs = f->slice_context[j]; - for (i = 0; i < 256; i++) { - f->rc_stat[i][0] += fs->rc_stat[i][0]; - f->rc_stat[i][1] += fs->rc_stat[i][1]; - } - for (i = 0; i < f->quant_table_count; i++) { - for (k = 0; k < f->context_count[i]; k++) - for (m = 0; m < 32; m++) { - f->rc_stat2[i][k][m][0] += fs->rc_stat2[i][k][m][0]; - f->rc_stat2[i][k][m][1] += fs->rc_stat2[i][k][m][1]; - } - } - } - - for (j = 0; j < 256; j++) { - snprintf(p, end - p, "%" PRIu64 " %" PRIu64 " ", - f->rc_stat[j][0], f->rc_stat[j][1]); - p += strlen(p); - } - snprintf(p, end - p, "\n"); - - for (i = 0; i < f->quant_table_count; i++) { - for (j = 0; j < f->context_count[i]; j++) - for (m = 0; m < 32; m++) { - snprintf(p, end - p, "%" PRIu64 " %" PRIu64 " ", - f->rc_stat2[i][j][m][0], f->rc_stat2[i][j][m][1]); - p += strlen(p); - } - } - snprintf(p, end - p, "%d\n", f->gob_count); - } else if (avctx->flags & CODEC_FLAG_PASS1) + if (avctx->flags & CODEC_FLAG_PASS1) avctx->stats_out[0] = '\0'; f->picture_number++; pkt->size = buf_p - pkt->data; - pkt->flags |= AV_PKT_FLAG_KEY * p->key_frame; + pkt->pts = + pkt->dts = pict->pts; + pkt->flags |= AV_PKT_FLAG_KEY * avctx->coded_frame->key_frame; *got_packet = 1; return 0; } +static av_cold int encode_close(AVCodecContext *avctx) +{ + av_frame_free(&avctx->coded_frame); + ffv1_close(avctx); + return 0; +} + #define OFFSET(x) offsetof(FFV1Context, x) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { @@ -1131,7 +1317,7 @@ static const AVOption options[] = { { NULL } }; -static const AVClass class = { +static const AVClass ffv1_class = { .class_name = "ffv1 encoder", .item_name = av_default_item_name, .option = options, @@ -1145,25 +1331,28 @@ static const AVCodecDefault ffv1_defaults[] = { AVCodec ff_ffv1_encoder = { .name = "ffv1", + .long_name = NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_FFV1, .priv_data_size = sizeof(FFV1Context), .init = encode_init, .encode2 = encode_frame, - .close = ffv1_close, - .capabilities = CODEC_CAP_SLICE_THREADS, + .close = encode_close, + .capabilities = CODEC_CAP_SLICE_THREADS | CODEC_CAP_DELAY, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_0RGB32, AV_PIX_FMT_RGB32, AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_YUVA444P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA420P16, + AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA420P10, + AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_GRAY16, AV_PIX_FMT_GRAY8, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"), .defaults = ffv1_defaults, - .priv_class = &class, + .priv_class = &ffv1_class, }; diff --git a/ffmpeg/libavcodec/ffwavesynth.c b/ffmpeg/libavcodec/ffwavesynth.c index 4f392f2..a62746d 100644 --- a/ffmpeg/libavcodec/ffwavesynth.c +++ b/ffmpeg/libavcodec/ffwavesynth.c @@ -473,6 +473,7 @@ static av_cold int wavesynth_close(AVCodecContext *avc) AVCodec ff_ffwavesynth_decoder = { .name = "wavesynth", + .long_name = NULL_IF_CONFIG_SMALL("Wave synthesis pseudo-codec"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_FFWAVESYNTH, .priv_data_size = sizeof(struct wavesynth_context), @@ -480,5 +481,4 @@ AVCodec ff_ffwavesynth_decoder = { .close = wavesynth_close, .decode = wavesynth_decode, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Wave synthesis pseudo-codec"), }; diff --git a/ffmpeg/libavcodec/flac.c b/ffmpeg/libavcodec/flac.c index a79a809..3874b6c 100644 --- a/ffmpeg/libavcodec/flac.c +++ b/ffmpeg/libavcodec/flac.c @@ -55,7 +55,7 @@ int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb, /* frame sync code */ if ((get_bits(gb, 15) & 0x7FFF) != 0x7FFC) { av_log(avctx, AV_LOG_ERROR + log_level_offset, "invalid sync code\n"); - return -1; + return AVERROR_INVALIDDATA; } /* variable block size stream code */ @@ -76,7 +76,7 @@ int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb, } else { av_log(avctx, AV_LOG_ERROR + log_level_offset, "invalid channel mode: %d\n", fi->ch_mode); - return -1; + return AVERROR_INVALIDDATA; } /* bits per sample */ @@ -85,7 +85,7 @@ int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb, av_log(avctx, AV_LOG_ERROR + log_level_offset, "invalid sample size code (%d)\n", bps_code); - return -1; + return AVERROR_INVALIDDATA; } fi->bps = sample_size_table[bps_code]; @@ -93,7 +93,7 @@ int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb, if (get_bits1(gb)) { av_log(avctx, AV_LOG_ERROR + log_level_offset, "broken stream, invalid padding\n"); - return -1; + return AVERROR_INVALIDDATA; } /* sample or frame count */ @@ -101,14 +101,14 @@ int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb, if (fi->frame_or_sample_num < 0) { av_log(avctx, AV_LOG_ERROR + log_level_offset, "sample/frame number invalid; utf8 fscked\n"); - return -1; + return AVERROR_INVALIDDATA; } /* blocksize */ if (bs_code == 0) { av_log(avctx, AV_LOG_ERROR + log_level_offset, "reserved blocksize code: 0\n"); - return -1; + return AVERROR_INVALIDDATA; } else if (bs_code == 6) { fi->blocksize = get_bits(gb, 8) + 1; } else if (bs_code == 7) { @@ -130,7 +130,7 @@ int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb, av_log(avctx, AV_LOG_ERROR + log_level_offset, "illegal sample rate code %d\n", sr_code); - return -1; + return AVERROR_INVALIDDATA; } /* header CRC-8 check */ @@ -139,7 +139,7 @@ int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb, get_bits_count(gb)/8)) { av_log(avctx, AV_LOG_ERROR + log_level_offset, "header crc mismatch\n"); - return -1; + return AVERROR_INVALIDDATA; } return 0; diff --git a/ffmpeg/libavcodec/flac_parser.c b/ffmpeg/libavcodec/flac_parser.c index e2c6744..ba1f060 100644 --- a/ffmpeg/libavcodec/flac_parser.c +++ b/ffmpeg/libavcodec/flac_parser.c @@ -27,11 +27,12 @@ * Each time it finds and verifies a CRC-8 header it sees which of the * FLAC_MAX_SEQUENTIAL_HEADERS that came before it have a valid CRC-16 footer * that ends at the newly found header. - * Headers are scored by FLAC_HEADER_BASE_SCORE plus the max of it's crc-verified + * Headers are scored by FLAC_HEADER_BASE_SCORE plus the max of its crc-verified * children, penalized by changes in sample rate, frame number, etc. * The parser returns the frame with the highest score. **/ +#include "libavutil/attributes.h" #include "libavutil/crc.h" #include "libavutil/fifo.h" #include "bytestream.h" @@ -86,6 +87,8 @@ typedef struct FLACParseContext { int end_padded; /**< specifies if fifo_buf's end is padded */ uint8_t *wrap_buf; /**< general fifo read buffer when wrapped */ int wrap_buf_allocated_size; /**< actual allocated size of the buffer */ + FLACFrameInfo last_fi; /**< last decoded frame header info */ + int last_fi_valid; /**< set if last_fi is valid */ } FLACParseContext; static int frame_header_is_valid(AVCodecContext *avctx, const uint8_t *buf, @@ -266,13 +269,12 @@ static int find_new_headers(FLACParseContext *fpc, int search_start) return size; } -static int check_header_mismatch(FLACParseContext *fpc, - FLACHeaderMarker *header, - FLACHeaderMarker *child, - int log_level_offset) +static int check_header_fi_mismatch(FLACParseContext *fpc, + FLACFrameInfo *header_fi, + FLACFrameInfo *child_fi, + int log_level_offset) { - FLACFrameInfo *header_fi = &header->fi, *child_fi = &child->fi; - int deduction = 0, deduction_expected = 0, i; + int deduction = 0; if (child_fi->samplerate != header_fi->samplerate) { deduction += FLAC_HEADER_CHANGED_PENALTY; av_log(fpc->avctx, AV_LOG_WARNING + log_level_offset, @@ -287,13 +289,25 @@ static int check_header_mismatch(FLACParseContext *fpc, /* Changing blocking strategy not allowed per the spec */ deduction += FLAC_HEADER_BASE_SCORE; av_log(fpc->avctx, AV_LOG_WARNING + log_level_offset, - "blocking strategy change detected in adjacent frames\n"); + "blocking strategy change detected in adjacent frames\n"); } if (child_fi->channels != header_fi->channels) { deduction += FLAC_HEADER_CHANGED_PENALTY; av_log(fpc->avctx, AV_LOG_WARNING + log_level_offset, - "number of channels change detected in adjacent frames\n"); + "number of channels change detected in adjacent frames\n"); } + return deduction; +} + +static int check_header_mismatch(FLACParseContext *fpc, + FLACHeaderMarker *header, + FLACHeaderMarker *child, + int log_level_offset) +{ + FLACFrameInfo *header_fi = &header->fi, *child_fi = &child->fi; + int deduction, deduction_expected = 0, i; + deduction = check_header_fi_mismatch(fpc, header_fi, child_fi, + log_level_offset); /* Check sample and frame numbers. */ if ((child_fi->frame_or_sample_num - header_fi->frame_or_sample_num != header_fi->blocksize) && @@ -398,11 +412,18 @@ static int score_header(FLACParseContext *fpc, FLACHeaderMarker *header) FLACHeaderMarker *child; int dist = 0; int child_score; - + int base_score = FLAC_HEADER_BASE_SCORE; if (header->max_score != FLAC_HEADER_NOT_SCORED_YET) return header->max_score; - header->max_score = FLAC_HEADER_BASE_SCORE; + /* Modify the base score with changes from the last output header */ + if (fpc->last_fi_valid) { + /* Silence the log since this will be repeated if selected */ + base_score -= check_header_fi_mismatch(fpc, &fpc->last_fi, &header->fi, + AV_LOG_DEBUG); + } + + header->max_score = base_score; /* Check and compute the children's scores. */ child = header->next; @@ -418,7 +439,7 @@ static int score_header(FLACParseContext *fpc, FLACHeaderMarker *header) if (FLAC_HEADER_BASE_SCORE + child_score > header->max_score) { /* Keep the child because the frame scoring is dynamic. */ header->best_child = child; - header->max_score = FLAC_HEADER_BASE_SCORE + child_score; + header->max_score = base_score + child_score; } child = child->next; } @@ -429,7 +450,7 @@ static int score_header(FLACParseContext *fpc, FLACHeaderMarker *header) static void score_sequences(FLACParseContext *fpc) { FLACHeaderMarker *curr; - int best_score = FLAC_HEADER_NOT_SCORED_YET; + int best_score = 0;//FLAC_HEADER_NOT_SCORED_YET; /* First pass to clear all old scores. */ for (curr = fpc->headers; curr; curr = curr->next) curr->max_score = FLAC_HEADER_NOT_SCORED_YET; @@ -469,6 +490,9 @@ static int get_best_header(FLACParseContext* fpc, const uint8_t **poutbuf, &fpc->wrap_buf_allocated_size); fpc->best_header_valid = 0; + fpc->last_fi_valid = 1; + fpc->last_fi = header->fi; + /* Return the negative overread index so the client can compute pos. This should be the amount overread to the beginning of the child */ if (child) @@ -488,8 +512,11 @@ static int flac_parse(AVCodecParserContext *s, AVCodecContext *avctx, if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { FLACFrameInfo fi; - if (frame_header_is_valid(avctx, buf, &fi)) + if (frame_header_is_valid(avctx, buf, &fi)) { s->duration = fi.blocksize; + if (!avctx->sample_rate) + avctx->sample_rate = fi.samplerate; + } *poutbuf = buf; *poutbuf_size = buf_size; return buf_size; @@ -628,9 +655,12 @@ static int flac_parse(AVCodecParserContext *s, AVCodecContext *avctx, } curr = fpc->headers; - for (curr = fpc->headers; curr; curr = curr->next) - if (!fpc->best_header || curr->max_score > fpc->best_header->max_score) + for (curr = fpc->headers; curr; curr = curr->next) { + if (curr->max_score > 0 && + (!fpc->best_header || curr->max_score > fpc->best_header->max_score)) { fpc->best_header = curr; + } + } if (fpc->best_header) { fpc->best_header_valid = 1; @@ -658,13 +688,15 @@ handle_error: return read_end - buf; } -static int flac_parse_init(AVCodecParserContext *c) +static av_cold int flac_parse_init(AVCodecParserContext *c) { FLACParseContext *fpc = c->priv_data; fpc->pc = c; /* There will generally be FLAC_MIN_HEADERS buffered in the fifo before it drains. This is allocated early to avoid slow reallocation. */ fpc->fifo_buf = av_fifo_alloc(FLAC_AVG_FRAME_SIZE * (FLAC_MIN_HEADERS + 3)); + if (!fpc->fifo_buf) + return AVERROR(ENOMEM); return 0; } diff --git a/ffmpeg/libavcodec/flacdata.c b/ffmpeg/libavcodec/flacdata.c index 6fcbe39..1954f32 100644 --- a/ffmpeg/libavcodec/flacdata.c +++ b/ffmpeg/libavcodec/flacdata.c @@ -27,7 +27,7 @@ const int ff_flac_sample_rate_table[16] = 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000, 0, 0, 0, 0 }; -const int16_t ff_flac_blocksize_table[16] = { +const int32_t ff_flac_blocksize_table[16] = { 0, 192, 576<<0, 576<<1, 576<<2, 576<<3, 0, 0, 256<<0, 256<<1, 256<<2, 256<<3, 256<<4, 256<<5, 256<<6, 256<<7 }; diff --git a/ffmpeg/libavcodec/flacdata.h b/ffmpeg/libavcodec/flacdata.h index 96a50b9..e2c1e5d 100644 --- a/ffmpeg/libavcodec/flacdata.h +++ b/ffmpeg/libavcodec/flacdata.h @@ -26,6 +26,6 @@ extern const int ff_flac_sample_rate_table[16]; -extern const int16_t ff_flac_blocksize_table[16]; +extern const int32_t ff_flac_blocksize_table[16]; #endif /* AVCODEC_FLACDATA_H */ diff --git a/ffmpeg/libavcodec/flacdec.c b/ffmpeg/libavcodec/flacdec.c index aaddd2d..596b24d 100644 --- a/ffmpeg/libavcodec/flacdec.c +++ b/ffmpeg/libavcodec/flacdec.c @@ -44,6 +44,9 @@ #include "flac.h" #include "flacdata.h" #include "flacdsp.h" +#include "thread.h" +#include "unary.h" + typedef struct FLACContext { FLACSTREAMINFO @@ -101,7 +104,7 @@ static av_cold int flac_decode_init(AVCodecContext *avctx) return 0; if (!avpriv_flac_is_extradata_valid(avctx, &format, &streaminfo)) - return -1; + return AVERROR_INVALIDDATA; /* initialize based on the demuxer-supplied streamdata header */ avpriv_flac_parse_streaminfo(avctx, (FLACStreaminfo *)s, streaminfo); @@ -212,7 +215,7 @@ static int decode_residuals(FLACContext *s, int32_t *decoded, int pred_order) if (method_type > 1) { av_log(s->avctx, AV_LOG_ERROR, "illegal residual coding method %d\n", method_type); - return -1; + return AVERROR_INVALIDDATA; } rice_order = get_bits(&s->gb, 4); @@ -221,7 +224,7 @@ static int decode_residuals(FLACContext *s, int32_t *decoded, int pred_order) if (pred_order > samples) { av_log(s->avctx, AV_LOG_ERROR, "invalid predictor order: %i > %i\n", pred_order, samples); - return -1; + return AVERROR_INVALIDDATA; } rice_bits = 4 + method_type; @@ -251,14 +254,15 @@ static int decode_subframe_fixed(FLACContext *s, int32_t *decoded, { const int blocksize = s->blocksize; int av_uninit(a), av_uninit(b), av_uninit(c), av_uninit(d), i; + int ret; /* warm up samples */ for (i = 0; i < pred_order; i++) { decoded[i] = get_sbits_long(&s->gb, bps); } - if (decode_residuals(s, decoded, pred_order) < 0) - return -1; + if ((ret = decode_residuals(s, decoded, pred_order)) < 0) + return ret; if (pred_order > 0) a = decoded[pred_order-1]; @@ -290,7 +294,7 @@ static int decode_subframe_fixed(FLACContext *s, int32_t *decoded, break; default: av_log(s->avctx, AV_LOG_ERROR, "illegal pred order %d\n", pred_order); - return -1; + return AVERROR_INVALIDDATA; } return 0; @@ -299,7 +303,7 @@ static int decode_subframe_fixed(FLACContext *s, int32_t *decoded, static int decode_subframe_lpc(FLACContext *s, int32_t *decoded, int pred_order, int bps) { - int i; + int i, ret; int coeff_prec, qlevel; int coeffs[32]; @@ -311,21 +315,21 @@ static int decode_subframe_lpc(FLACContext *s, int32_t *decoded, int pred_order, coeff_prec = get_bits(&s->gb, 4) + 1; if (coeff_prec == 16) { av_log(s->avctx, AV_LOG_ERROR, "invalid coeff precision\n"); - return -1; + return AVERROR_INVALIDDATA; } qlevel = get_sbits(&s->gb, 5); if (qlevel < 0) { av_log(s->avctx, AV_LOG_ERROR, "qlevel %d not supported, maybe buggy stream\n", qlevel); - return -1; + return AVERROR_INVALIDDATA; } for (i = 0; i < pred_order; i++) { coeffs[pred_order - i - 1] = get_sbits(&s->gb, coeff_prec); } - if (decode_residuals(s, decoded, pred_order) < 0) - return -1; + if ((ret = decode_residuals(s, decoded, pred_order)) < 0) + return ret; s->dsp.lpc(decoded, coeffs, pred_order, qlevel, s->blocksize); @@ -337,7 +341,7 @@ static inline int decode_subframe(FLACContext *s, int channel) int32_t *decoded = s->decoded[channel]; int type, wasted = 0; int bps = s->bps; - int i, tmp; + int i, tmp, ret; if (channel == 0) { if (s->ch_mode == FLAC_CHMODE_RIGHT_SIDE) @@ -349,13 +353,12 @@ static inline int decode_subframe(FLACContext *s, int channel) if (get_bits1(&s->gb)) { av_log(s->avctx, AV_LOG_ERROR, "invalid subframe padding\n"); - return -1; + return AVERROR_INVALIDDATA; } type = get_bits(&s->gb, 6); if (get_bits1(&s->gb)) { int left = get_bits_left(&s->gb); - wasted = 1; if ( left < 0 || (left < bps && !show_bits_long(&s->gb, left)) || !show_bits_long(&s->gb, bps)) { @@ -364,8 +367,7 @@ static inline int decode_subframe(FLACContext *s, int channel) bps, left); return AVERROR_INVALIDDATA; } - while (!get_bits1(&s->gb)) - wasted++; + wasted = 1 + get_unary(&s->gb, 1, get_bits_left(&s->gb)); bps -= wasted; } if (bps > 32) { @@ -382,14 +384,14 @@ static inline int decode_subframe(FLACContext *s, int channel) for (i = 0; i < s->blocksize; i++) decoded[i] = get_sbits_long(&s->gb, bps); } else if ((type >= 8) && (type <= 12)) { - if (decode_subframe_fixed(s, decoded, type & ~0x8, bps) < 0) - return -1; + if ((ret = decode_subframe_fixed(s, decoded, type & ~0x8, bps)) < 0) + return ret; } else if (type >= 32) { - if (decode_subframe_lpc(s, decoded, (type & ~0x20)+1, bps) < 0) - return -1; + if ((ret = decode_subframe_lpc(s, decoded, (type & ~0x20)+1, bps)) < 0) + return ret; } else { av_log(s->avctx, AV_LOG_ERROR, "invalid coding type\n"); - return -1; + return AVERROR_INVALIDDATA; } if (wasted) { @@ -407,9 +409,9 @@ static int decode_frame(FLACContext *s) GetBitContext *gb = &s->gb; FLACFrameInfo fi; - if (ff_flac_decode_frame_header(s->avctx, gb, &fi, 0)) { + if ((ret = ff_flac_decode_frame_header(s->avctx, gb, &fi, 0)) < 0) { av_log(s->avctx, AV_LOG_ERROR, "invalid frame header\n"); - return -1; + return ret; } if (s->channels && fi.channels != s->channels && s->got_streaminfo) { @@ -426,14 +428,14 @@ static int decode_frame(FLACContext *s) if (!s->bps && !fi.bps) { av_log(s->avctx, AV_LOG_ERROR, "bps not found in STREAMINFO or frame header\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!fi.bps) { fi.bps = s->bps; } else if (s->bps && fi.bps != s->bps) { av_log(s->avctx, AV_LOG_ERROR, "switching bps mid-stream is not " "supported\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!s->bps) { @@ -446,14 +448,14 @@ static int decode_frame(FLACContext *s) if (fi.blocksize > s->max_blocksize) { av_log(s->avctx, AV_LOG_ERROR, "blocksize %d > %d\n", fi.blocksize, s->max_blocksize); - return -1; + return AVERROR_INVALIDDATA; } s->blocksize = fi.blocksize; if (!s->samplerate && !fi.samplerate) { av_log(s->avctx, AV_LOG_ERROR, "sample rate not found in STREAMINFO" " or frame header\n"); - return -1; + return AVERROR_INVALIDDATA; } if (fi.samplerate == 0) fi.samplerate = s->samplerate; @@ -472,8 +474,8 @@ static int decode_frame(FLACContext *s) /* subframes */ for (i = 0; i < s->channels; i++) { - if (decode_subframe(s, i) < 0) - return -1; + if ((ret = decode_subframe(s, i)) < 0) + return ret; } align_get_bits(gb); @@ -488,6 +490,7 @@ static int flac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { AVFrame *frame = data; + ThreadFrame tframe = { .f = data }; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; FLACContext *s = avctx->priv_data; @@ -520,22 +523,23 @@ static int flac_decode_frame(AVCodecContext *avctx, void *data, /* check for inline header */ if (AV_RB32(buf) == MKBETAG('f','L','a','C')) { - if (!s->got_streaminfo && parse_streaminfo(s, buf, buf_size)) { + if (!s->got_streaminfo && (ret = parse_streaminfo(s, buf, buf_size))) { av_log(s->avctx, AV_LOG_ERROR, "invalid header\n"); - return -1; + return ret; } return get_metadata_size(buf, buf_size); } /* decode frame */ - init_get_bits(&s->gb, buf, buf_size*8); - if (decode_frame(s) < 0) { + if ((ret = init_get_bits8(&s->gb, buf, buf_size)) < 0) + return ret; + if ((ret = decode_frame(s)) < 0) { av_log(s->avctx, AV_LOG_ERROR, "decode_frame() failed\n"); - return -1; + return ret; } bytes_read = get_bits_count(&s->gb)/8; - if ((s->avctx->err_recognition & AV_EF_CRCCHECK) && + if ((s->avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_COMPLIANT)) && av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, buf, bytes_read)) { av_log(s->avctx, AV_LOG_ERROR, "CRC error at PTS %"PRId64"\n", avpkt->pts); @@ -545,7 +549,7 @@ static int flac_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = s->blocksize; - if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0) return ret; s->dsp.decorrelate[s->ch_mode](frame->data, s->decoded, s->channels, @@ -553,7 +557,7 @@ static int flac_decode_frame(AVCodecContext *avctx, void *data, if (bytes_read > buf_size) { av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", bytes_read - buf_size); - return -1; + return AVERROR_INVALIDDATA; } if (bytes_read < buf_size) { av_log(s->avctx, AV_LOG_DEBUG, "underread: %d orig size: %d\n", @@ -565,6 +569,17 @@ static int flac_decode_frame(AVCodecContext *avctx, void *data, return bytes_read; } +static int init_thread_copy(AVCodecContext *avctx) +{ + FLACContext *s = avctx->priv_data; + s->decoded_buffer = NULL; + s->decoded_buffer_size = 0; + s->avctx = avctx; + if (s->max_blocksize) + return allocate_buffers(s); + return 0; +} + static av_cold int flac_decode_close(AVCodecContext *avctx) { FLACContext *s = avctx->priv_data; @@ -576,14 +591,15 @@ static av_cold int flac_decode_close(AVCodecContext *avctx) AVCodec ff_flac_decoder = { .name = "flac", + .long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_FLAC, .priv_data_size = sizeof(FLACContext), .init = flac_decode_init, .close = flac_decode_close, .decode = flac_decode_frame, - .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"), + .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy), + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S32, diff --git a/ffmpeg/libavcodec/flacenc.c b/ffmpeg/libavcodec/flacenc.c index dc932c6..1fc8c4c 100644 --- a/ffmpeg/libavcodec/flacenc.c +++ b/ffmpeg/libavcodec/flacenc.c @@ -1259,7 +1259,7 @@ static int flac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, frame_bytes = encode_frame(s); - /* fallback to verbatim mode if the compressed frame is larger than it + /* Fall back on verbatim mode if the compressed frame is larger than it would be if encoded uncompressed. */ if (frame_bytes < 0 || frame_bytes > s->max_framesize) { s->frame.verbatim_only = 1; @@ -1343,6 +1343,7 @@ static const AVClass flac_encoder_class = { AVCodec ff_flac_encoder = { .name = "flac", + .long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_FLAC, .priv_data_size = sizeof(FlacEncodeContext), @@ -1353,6 +1354,5 @@ AVCodec ff_flac_encoder = { .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"), .priv_class = &flac_encoder_class, }; diff --git a/ffmpeg/libavcodec/flashsv.c b/ffmpeg/libavcodec/flashsv.c index 9982b5e..8791a2d 100644 --- a/ffmpeg/libavcodec/flashsv.c +++ b/ffmpeg/libavcodec/flashsv.c @@ -50,7 +50,7 @@ typedef struct BlockInfo { typedef struct FlashSVContext { AVCodecContext *avctx; - AVFrame frame; + AVFrame *frame; int image_width, image_height; int block_width, block_height; uint8_t *tmpblock; @@ -69,16 +69,17 @@ typedef struct FlashSVContext { int diff_start, diff_height; } FlashSVContext; - -static int decode_hybrid(const uint8_t *sptr, uint8_t *dptr, int dx, int dy, +static int decode_hybrid(const uint8_t *sptr, const uint8_t *sptr_end, uint8_t *dptr, int dx, int dy, int h, int w, int stride, const uint32_t *pal) { int x, y; const uint8_t *orig_src = sptr; - for (y = dx+h; y > dx; y--) { + for (y = dx + h; y > dx; y--) { uint8_t *dst = dptr + (y * stride) + dy * 3; for (x = 0; x < w; x++) { + if (sptr >= sptr_end) + return AVERROR_INVALIDDATA; if (*sptr & 0x80) { /* 15-bit color */ unsigned c = AV_RB16(sptr) & ~0x8000; @@ -100,6 +101,19 @@ static int decode_hybrid(const uint8_t *sptr, uint8_t *dptr, int dx, int dy, return sptr - orig_src; } +static av_cold int flashsv_decode_end(AVCodecContext *avctx) +{ + FlashSVContext *s = avctx->priv_data; + inflateEnd(&s->zstream); + /* release the frame if needed */ + av_frame_free(&s->frame); + + /* free the tmpblock */ + av_freep(&s->tmpblock); + + return 0; +} + static av_cold int flashsv_decode_init(AVCodecContext *avctx) { FlashSVContext *s = avctx->priv_data; @@ -115,12 +129,16 @@ static av_cold int flashsv_decode_init(AVCodecContext *avctx) return 1; } avctx->pix_fmt = AV_PIX_FMT_BGR24; - avcodec_get_frame_defaults(&s->frame); + + s->frame = av_frame_alloc(); + if (!s->frame) { + flashsv_decode_end(avctx); + return AVERROR(ENOMEM); + } return 0; } - static int flashsv2_prime(FlashSVContext *s, uint8_t *src, int size) { z_stream zs; @@ -198,25 +216,33 @@ static int flashsv_decode_block(AVCodecContext *avctx, AVPacket *avpkt, } if (s->is_keyframe) { - s->blocks[blk_idx].pos = s->keyframedata + (get_bits_count(gb) / 8); - s->blocks[blk_idx].size = block_size; + s->blocks[blk_idx].pos = s->keyframedata + (get_bits_count(gb) / 8); + s->blocks[blk_idx].size = block_size; } + + y_pos += s->diff_start; + if (!s->color_depth) { /* Flash Screen Video stores the image upside down, so copy * lines to destination in reverse order. */ for (k = 1; k <= s->diff_height; k++) { - memcpy(s->frame.data[0] + x_pos * 3 + - (s->image_height - y_pos - s->diff_start - k) * s->frame.linesize[0], + memcpy(s->frame->data[0] + x_pos * 3 + + (s->image_height - y_pos - k) * s->frame->linesize[0], line, width * 3); /* advance source pointer to next line */ line += width * 3; } } else { /* hybrid 15-bit/palette mode */ - decode_hybrid(s->tmpblock, s->frame.data[0], - s->image_height - (y_pos + 1 + s->diff_start + s->diff_height), + ret = decode_hybrid(s->tmpblock, s->zstream.next_out, + s->frame->data[0], + s->image_height - (y_pos + 1 + s->diff_height), x_pos, s->diff_height, width, - s->frame.linesize[0], s->pal); + s->frame->linesize[0], s->pal); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "decode_hybrid failed\n"); + return ret; + } } skip_bits_long(gb, 8 * block_size); /* skip the consumed bits */ return 0; @@ -241,8 +267,8 @@ static int calc_deflate_block_size(int tmpblock_size) static int flashsv_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { - int buf_size = avpkt->size; - FlashSVContext *s = avctx->priv_data; + int buf_size = avpkt->size; + FlashSVContext *s = avctx->priv_data; int h_blocks, v_blocks, h_part, v_part, i, j, ret; GetBitContext gb; int last_blockwidth = s->block_width; @@ -254,13 +280,14 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, if (buf_size < 4) return -1; - init_get_bits(&gb, avpkt->data, buf_size * 8); + if ((ret = init_get_bits8(&gb, avpkt->data, buf_size)) < 0) + return ret; /* start to parse the bitstream */ - s->block_width = 16 * (get_bits(&gb, 4) + 1); - s->image_width = get_bits(&gb, 12); - s->block_height = 16 * (get_bits(&gb, 4) + 1); - s->image_height = get_bits(&gb, 12); + s->block_width = 16 * (get_bits(&gb, 4) + 1); + s->image_width = get_bits(&gb, 12); + s->block_height = 16 * (get_bits(&gb, 4) + 1); + s->image_height = get_bits(&gb, 12); if ( last_blockwidth != s->block_width || last_blockheight!= s->block_height) @@ -287,23 +314,25 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, /* the block size could change between frames, make sure the buffer * is large enough, if not, get a larger one */ if (s->block_size < s->block_width * s->block_height) { - int tmpblock_size = 3 * s->block_width * s->block_height; + int tmpblock_size = 3 * s->block_width * s->block_height, err; - s->tmpblock = av_realloc(s->tmpblock, tmpblock_size); - if (!s->tmpblock) { - av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); - return AVERROR(ENOMEM); + if ((err = av_reallocp(&s->tmpblock, tmpblock_size)) < 0) { + s->block_size = 0; + av_log(avctx, AV_LOG_ERROR, + "Cannot allocate decompression buffer.\n"); + return err; } if (s->ver == 2) { s->deflate_block_size = calc_deflate_block_size(tmpblock_size); if (s->deflate_block_size <= 0) { - av_log(avctx, AV_LOG_ERROR, "Can't determine deflate buffer size.\n"); + av_log(avctx, AV_LOG_ERROR, + "Cannot determine deflate buffer size.\n"); return -1; } - s->deflate_block = av_realloc(s->deflate_block, s->deflate_block_size); - if (!s->deflate_block) { - av_log(avctx, AV_LOG_ERROR, "Can't allocate deflate buffer.\n"); - return AVERROR(ENOMEM); + if ((err = av_reallocp(&s->deflate_block, s->deflate_block_size)) < 0) { + s->block_size = 0; + av_log(avctx, AV_LOG_ERROR, "Cannot allocate deflate buffer.\n"); + return err; } } } @@ -311,7 +340,8 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, /* initialize the image size once */ if (avctx->width == 0 && avctx->height == 0) { - avcodec_set_dimensions(avctx, s->image_width, s->image_height); + if ((ret = ff_set_dimensions(avctx, s->image_width, s->image_height)) < 0) + return ret; } /* check for changes of image width and image height */ @@ -326,18 +356,20 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, /* we care for keyframes only in Screen Video v2 */ s->is_keyframe = (avpkt->flags & AV_PKT_FLAG_KEY) && (s->ver == 2); if (s->is_keyframe) { - s->keyframedata = av_realloc(s->keyframedata, avpkt->size); + int err; + if ((err = av_reallocp(&s->keyframedata, avpkt->size)) < 0) + return err; memcpy(s->keyframedata, avpkt->data, avpkt->size); } if(s->ver == 2 && !s->blocks) - s->blocks = av_mallocz((v_blocks + !!v_part) * (h_blocks + !!h_part) - * sizeof(s->blocks[0])); + s->blocks = av_mallocz((v_blocks + !!v_part) * (h_blocks + !!h_part) * + sizeof(s->blocks[0])); av_dlog(avctx, "image: %dx%d block: %dx%d num: %dx%d part: %dx%d\n", s->image_width, s->image_height, s->block_width, s->block_height, h_blocks, v_blocks, h_part, v_part); - if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) + if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) return ret; /* loop over all block columns */ @@ -362,7 +394,7 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, s->diff_height = cur_blk_height; if (8 * size > get_bits_left(&gb)) { - av_frame_unref(&s->frame); + av_frame_unref(s->frame); return AVERROR_INVALIDDATA; } @@ -375,18 +407,25 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, if (s->color_depth != 0 && s->color_depth != 2) { av_log(avctx, AV_LOG_ERROR, - "%dx%d invalid color depth %d\n", i, j, s->color_depth); + "%dx%d invalid color depth %d\n", + i, j, s->color_depth); return AVERROR_INVALIDDATA; } if (has_diff) { if (!s->keyframe) { av_log(avctx, AV_LOG_ERROR, - "inter frame without keyframe\n"); + "Inter frame without keyframe\n"); return AVERROR_INVALIDDATA; } s->diff_start = get_bits(&gb, 8); s->diff_height = get_bits(&gb, 8); + if (s->diff_start + s->diff_height > cur_blk_height) { + av_log(avctx, AV_LOG_ERROR, + "Block parameters invalid: %d + %d > %d\n", + s->diff_start, s->diff_height, cur_blk_height); + return AVERROR_INVALIDDATA; + } av_log(avctx, AV_LOG_DEBUG, "%dx%d diff start %d height %d\n", i, j, s->diff_start, s->diff_height); @@ -399,14 +438,15 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, if (s->zlibprime_curr) { int col = get_bits(&gb, 8); int row = get_bits(&gb, 8); - av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_curr %dx%d\n", i, j, col, row); + av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_curr %dx%d\n", + i, j, col, row); size -= 2; avpriv_request_sample(avctx, "zlibprime_curr"); return AVERROR_PATCHWELCOME; } if (!s->blocks && (s->zlibprime_curr || s->zlibprime_prev)) { - av_log(avctx, AV_LOG_ERROR, "no data available for zlib " - "priming\n"); + av_log(avctx, AV_LOG_ERROR, + "no data available for zlib priming\n"); return AVERROR_INVALIDDATA; } size--; // account for flags byte @@ -414,12 +454,13 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, if (has_diff) { int k; - int off = (s->image_height - y_pos - 1) * s->frame.linesize[0]; + int off = (s->image_height - y_pos - 1) * s->frame->linesize[0]; - for (k = 0; k < cur_blk_height; k++) - memcpy(s->frame.data[0] + off - k*s->frame.linesize[0] + x_pos*3, - s->keyframe + off - k*s->frame.linesize[0] + x_pos*3, + for (k = 0; k < cur_blk_height; k++) { + int x = off - k * s->frame->linesize[0] + x_pos * 3; + memcpy(s->frame->data[0] + x, s->keyframe + x, cur_blk_width * 3); + } } /* skip unchanged blocks, which have size 0 */ @@ -435,16 +476,17 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, } if (s->is_keyframe && s->ver == 2) { if (!s->keyframe) { - s->keyframe = av_malloc(s->frame.linesize[0] * avctx->height); + s->keyframe = av_malloc(s->frame->linesize[0] * avctx->height); if (!s->keyframe) { av_log(avctx, AV_LOG_ERROR, "Cannot allocate image data\n"); return AVERROR(ENOMEM); } } - memcpy(s->keyframe, s->frame.data[0], s->frame.linesize[0] * avctx->height); + memcpy(s->keyframe, s->frame->data[0], + s->frame->linesize[0] * avctx->height); } - if ((ret = av_frame_ref(data, &s->frame)) < 0) + if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; *got_frame = 1; @@ -457,24 +499,10 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, return buf_size; } - -static av_cold int flashsv_decode_end(AVCodecContext *avctx) -{ - FlashSVContext *s = avctx->priv_data; - inflateEnd(&s->zstream); - /* release the frame if needed */ - av_frame_unref(&s->frame); - - /* free the tmpblock */ - av_free(s->tmpblock); - - return 0; -} - - #if CONFIG_FLASHSV_DECODER AVCodec ff_flashsv_decoder = { .name = "flashsv", + .long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video v1"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_FLASHSV, .priv_data_size = sizeof(FlashSVContext), @@ -482,8 +510,7 @@ AVCodec ff_flashsv_decoder = { .close = flashsv_decode_end, .decode = flashsv_decode_frame, .capabilities = CODEC_CAP_DR1, - .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video v1"), + .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE }, }; #endif /* CONFIG_FLASHSV_DECODER */ @@ -538,6 +565,7 @@ static av_cold int flashsv2_decode_end(AVCodecContext *avctx) AVCodec ff_flashsv2_decoder = { .name = "flashsv2", + .long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video v2"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_FLASHSV2, .priv_data_size = sizeof(FlashSVContext), @@ -545,7 +573,6 @@ AVCodec ff_flashsv2_decoder = { .close = flashsv2_decode_end, .decode = flashsv_decode_frame, .capabilities = CODEC_CAP_DR1, - .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video v2"), + .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE }, }; #endif /* CONFIG_FLASHSV2_DECODER */ diff --git a/ffmpeg/libavcodec/flashsv2enc.c b/ffmpeg/libavcodec/flashsv2enc.c index 1d0d196..436daa4 100644 --- a/ffmpeg/libavcodec/flashsv2enc.c +++ b/ffmpeg/libavcodec/flashsv2enc.c @@ -87,7 +87,6 @@ typedef struct FlashSV2Context { AVCodecContext *avctx; uint8_t *current_frame; uint8_t *key_frame; - AVFrame frame; uint8_t *encbuffer; uint8_t *keybuffer; uint8_t *databuffer; @@ -849,15 +848,12 @@ static int reconfigure_at_keyframe(FlashSV2Context * s, const uint8_t * image, } static int flashsv2_encode_frame(AVCodecContext *avctx, AVPacket *pkt, - const AVFrame *pict, int *got_packet) + const AVFrame *p, int *got_packet) { FlashSV2Context *const s = avctx->priv_data; - AVFrame *const p = &s->frame; int res; int keyframe = 0; - *p = *pict; - if ((res = ff_alloc_packet2(avctx, pkt, s->frame_size + FF_MIN_BUFFER_SIZE)) < 0) return res; @@ -891,18 +887,11 @@ static int flashsv2_encode_frame(AVCodecContext *avctx, AVPacket *pkt, if (keyframe) { new_key_frame(s); - p->pict_type = AV_PICTURE_TYPE_I; - p->key_frame = 1; s->last_key_frame = avctx->frame_number; pkt->flags |= AV_PKT_FLAG_KEY; av_log(avctx, AV_LOG_DEBUG, "Inserting key frame at frame %d\n", avctx->frame_number); - } else { - p->pict_type = AV_PICTURE_TYPE_P; - p->key_frame = 0; } - avctx->coded_frame = p; - pkt->size = res; *got_packet = 1; @@ -920,6 +909,7 @@ static av_cold int flashsv2_encode_end(AVCodecContext * avctx) AVCodec ff_flashsv2_encoder = { .name = "flashsv2", + .long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video Version 2"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_FLASHSV2, .priv_data_size = sizeof(FlashSV2Context), @@ -927,5 +917,4 @@ AVCodec ff_flashsv2_encoder = { .encode2 = flashsv2_encode_frame, .close = flashsv2_encode_end, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video Version 2"), }; diff --git a/ffmpeg/libavcodec/flashsvenc.c b/ffmpeg/libavcodec/flashsvenc.c index e6b181f..7ad15f1 100644 --- a/ffmpeg/libavcodec/flashsvenc.c +++ b/ffmpeg/libavcodec/flashsvenc.c @@ -57,7 +57,6 @@ typedef struct FlashSVContext { AVCodecContext *avctx; uint8_t *previous_frame; - AVFrame frame; int image_width, image_height; int block_width, block_height; uint8_t *tmpblock; @@ -89,6 +88,21 @@ static int copy_region_enc(uint8_t *sptr, uint8_t *dptr, int dx, int dy, return 0; } +static av_cold int flashsv_encode_end(AVCodecContext *avctx) +{ + FlashSVContext *s = avctx->priv_data; + + deflateEnd(&s->zstream); + + av_free(s->encbuffer); + av_free(s->previous_frame); + av_free(s->tmpblock); + + av_frame_free(&avctx->coded_frame); + + return 0; +} + static av_cold int flashsv_encode_init(AVCodecContext *avctx) { FlashSVContext *s = avctx->priv_data; @@ -117,11 +131,17 @@ static av_cold int flashsv_encode_init(AVCodecContext *avctx) return AVERROR(ENOMEM); } + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) { + flashsv_encode_end(avctx); + return AVERROR(ENOMEM); + } + return 0; } -static int encode_bitstream(FlashSVContext *s, AVFrame *p, uint8_t *buf, +static int encode_bitstream(FlashSVContext *s, const AVFrame *p, uint8_t *buf, int buf_size, int block_width, int block_height, uint8_t *previous_frame, int *I_frame) { @@ -199,14 +219,12 @@ static int flashsv_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { FlashSVContext * const s = avctx->priv_data; - AVFrame * const p = &s->frame; + const AVFrame * const p = pict; uint8_t *pfptr; int res; int I_frame = 0; int opt_w = 4, opt_h = 4; - *p = *pict; - /* First frame needs to be a keyframe */ if (avctx->frame_number == 0) { s->previous_frame = av_mallocz(FFABS(p->linesize[0]) * s->image_height); @@ -244,39 +262,25 @@ static int flashsv_encode_frame(AVCodecContext *avctx, AVPacket *pkt, //mark the frame type so the muxer can mux it correctly if (I_frame) { - p->pict_type = AV_PICTURE_TYPE_I; - p->key_frame = 1; + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->key_frame = 1; s->last_key_frame = avctx->frame_number; av_dlog(avctx, "Inserting keyframe at frame %d\n", avctx->frame_number); } else { - p->pict_type = AV_PICTURE_TYPE_P; - p->key_frame = 0; + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P; + avctx->coded_frame->key_frame = 0; } - avctx->coded_frame = p; - - if (p->key_frame) + if (avctx->coded_frame->key_frame) pkt->flags |= AV_PKT_FLAG_KEY; *got_packet = 1; return 0; } -static av_cold int flashsv_encode_end(AVCodecContext *avctx) -{ - FlashSVContext *s = avctx->priv_data; - - deflateEnd(&s->zstream); - - av_free(s->encbuffer); - av_free(s->previous_frame); - av_free(s->tmpblock); - - return 0; -} - AVCodec ff_flashsv_encoder = { .name = "flashsv", + .long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_FLASHSV, .priv_data_size = sizeof(FlashSVContext), @@ -284,5 +288,4 @@ AVCodec ff_flashsv_encoder = { .encode2 = flashsv_encode_frame, .close = flashsv_encode_end, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video"), }; diff --git a/ffmpeg/libavcodec/flicvideo.c b/ffmpeg/libavcodec/flicvideo.c index 90885fc..a2d59e8 100644 --- a/ffmpeg/libavcodec/flicvideo.c +++ b/ffmpeg/libavcodec/flicvideo.c @@ -71,7 +71,7 @@ typedef struct FlicDecodeContext { AVCodecContext *avctx; - AVFrame frame; + AVFrame *frame; unsigned int palette[256]; int new_palette; @@ -134,14 +134,17 @@ static av_cold int flic_decode_init(AVCodecContext *avctx) case 15 : avctx->pix_fmt = AV_PIX_FMT_RGB555; break; case 16 : avctx->pix_fmt = AV_PIX_FMT_RGB565; break; case 24 : avctx->pix_fmt = AV_PIX_FMT_BGR24; /* Supposedly BGR, but havent any files to test with */ - av_log(avctx, AV_LOG_ERROR, "24Bpp FLC/FLX is unsupported due to no test files.\n"); + avpriv_request_sample(avctx, "24Bpp FLC/FLX"); return AVERROR_PATCHWELCOME; default : av_log(avctx, AV_LOG_ERROR, "Unknown FLC/FLX depth of %d Bpp is unsupported.\n",depth); return AVERROR_INVALIDDATA; } - avcodec_get_frame_defaults(&s->frame); + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); + s->new_palette = 0; return 0; @@ -185,11 +188,11 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, bytestream2_init(&g2, buf, buf_size); - if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) + if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) return ret; - pixels = s->frame.data[0]; - pixel_limit = s->avctx->height * s->frame.linesize[0]; + pixels = s->frame->data[0]; + pixel_limit = s->avctx->height * s->frame->linesize[0]; if (buf_size < 16 || buf_size > INT_MAX - (3 * 256 + FF_INPUT_BUFFER_PADDING_SIZE)) return AVERROR_INVALIDDATA; frame_size = bytestream2_get_le32(&g2); @@ -202,7 +205,8 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, frame_size -= 16; /* iterate through the chunks */ - while ((frame_size >= 6) && (num_chunks > 0)) { + while ((frame_size >= 6) && (num_chunks > 0) && + bytestream2_get_bytes_left(&g2) >= 4) { int stream_ptr_after_chunk; chunk_size = bytestream2_get_le32(&g2); if (chunk_size > frame_size) { @@ -272,12 +276,12 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, if ((line_packets & 0xC000) == 0xC000) { // line skip opcode line_packets = -line_packets; - y_ptr += line_packets * s->frame.linesize[0]; + y_ptr += line_packets * s->frame->linesize[0]; } else if ((line_packets & 0xC000) == 0x4000) { av_log(avctx, AV_LOG_ERROR, "Undefined opcode (%x) in DELTA_FLI\n", line_packets); } else if ((line_packets & 0xC000) == 0x8000) { // "last byte" opcode - pixel_ptr= y_ptr + s->frame.linesize[0] - 1; + pixel_ptr= y_ptr + s->frame->linesize[0] - 1; CHECK_PIXEL_PTR(0); pixels[pixel_ptr] = line_packets & 0xff; } else { @@ -312,7 +316,7 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, } } - y_ptr += s->frame.linesize[0]; + y_ptr += s->frame->linesize[0]; } } break; @@ -321,7 +325,7 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, /* line compressed */ starting_line = bytestream2_get_le16(&g2); y_ptr = 0; - y_ptr += starting_line * s->frame.linesize[0]; + y_ptr += starting_line * s->frame->linesize[0]; compressed_lines = bytestream2_get_le16(&g2); while (compressed_lines > 0) { @@ -358,7 +362,7 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, } } - y_ptr += s->frame.linesize[0]; + y_ptr += s->frame->linesize[0]; compressed_lines--; } break; @@ -366,7 +370,7 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, case FLI_BLACK: /* set the whole frame to color 0 (which is usually black) */ memset(pixels, 0, - s->frame.linesize[0] * s->avctx->height); + s->frame->linesize[0] * s->avctx->height); break; case FLI_BRUN: @@ -413,7 +417,7 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, } } - y_ptr += s->frame.linesize[0]; + y_ptr += s->frame->linesize[0]; } break; @@ -424,8 +428,8 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, "has incorrect size, skipping chunk\n", chunk_size - 6); bytestream2_skip(&g2, chunk_size - 6); } else { - for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height; - y_ptr += s->frame.linesize[0]) { + for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height; + y_ptr += s->frame->linesize[0]) { bytestream2_get_buffer(&g2, &pixels[y_ptr], s->avctx->width); } @@ -456,13 +460,13 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, buf_size - bytestream2_get_bytes_left(&g2)); /* make the palette available on the way out */ - memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); + memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE); if (s->new_palette) { - s->frame.palette_has_changed = 1; + s->frame->palette_has_changed = 1; s->new_palette = 0; } - if ((ret = av_frame_ref(data, &s->frame)) < 0) + if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; *got_frame = 1; @@ -503,11 +507,11 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, bytestream2_init(&g2, buf, buf_size); - if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) + if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) return ret; - pixels = s->frame.data[0]; - pixel_limit = s->avctx->height * s->frame.linesize[0]; + pixels = s->frame->data[0]; + pixel_limit = s->avctx->height * s->frame->linesize[0]; frame_size = bytestream2_get_le32(&g2); bytestream2_skip(&g2, 2); /* skip the magic number */ @@ -519,7 +523,8 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, frame_size -= 16; /* iterate through the chunks */ - while ((frame_size > 0) && (num_chunks > 0)) { + while ((frame_size > 0) && (num_chunks > 0) && + bytestream2_get_bytes_left(&g2) >= 4) { int stream_ptr_after_chunk; chunk_size = bytestream2_get_le32(&g2); if (chunk_size > frame_size) { @@ -554,7 +559,7 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, line_packets = bytestream2_get_le16(&g2); if (line_packets < 0) { line_packets = -line_packets; - y_ptr += line_packets * s->frame.linesize[0]; + y_ptr += line_packets * s->frame->linesize[0]; } else { compressed_lines--; pixel_ptr = y_ptr; @@ -587,20 +592,20 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, } } - y_ptr += s->frame.linesize[0]; + y_ptr += s->frame->linesize[0]; } } break; case FLI_LC: - av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-paletised FLC\n"); + av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-palettized FLC\n"); bytestream2_skip(&g2, chunk_size - 6); break; case FLI_BLACK: /* set the whole frame to 0x0000 which is black in both 15Bpp and 16Bpp modes. */ memset(pixels, 0x0000, - s->frame.linesize[0] * s->avctx->height); + s->frame->linesize[0] * s->avctx->height); break; case FLI_BRUN: @@ -655,7 +660,7 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, pixel_ptr += 2; } #endif - y_ptr += s->frame.linesize[0]; + y_ptr += s->frame->linesize[0]; } break; @@ -699,7 +704,7 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, } } - y_ptr += s->frame.linesize[0]; + y_ptr += s->frame->linesize[0]; } break; @@ -712,8 +717,8 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, bytestream2_skip(&g2, chunk_size - 6); } else { - for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height; - y_ptr += s->frame.linesize[0]) { + for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height; + y_ptr += s->frame->linesize[0]) { pixel_countdown = s->avctx->width; pixel_ptr = 0; @@ -746,7 +751,7 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \ "and final chunk ptr = %d\n", buf_size, bytestream2_tell(&g2)); - if ((ret = av_frame_ref(data, &s->frame)) < 0) + if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; *got_frame = 1; @@ -795,13 +800,14 @@ static av_cold int flic_decode_end(AVCodecContext *avctx) { FlicDecodeContext *s = avctx->priv_data; - av_frame_unref(&s->frame); + av_frame_free(&s->frame); return 0; } AVCodec ff_flic_decoder = { .name = "flic", + .long_name = NULL_IF_CONFIG_SMALL("Autodesk Animator Flic video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_FLIC, .priv_data_size = sizeof(FlicDecodeContext), @@ -809,5 +815,4 @@ AVCodec ff_flic_decoder = { .close = flic_decode_end, .decode = flic_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Autodesk Animator Flic video"), }; diff --git a/ffmpeg/libavcodec/flvdec.c b/ffmpeg/libavcodec/flvdec.c index bb693d7..f425f00 100644 --- a/ffmpeg/libavcodec/flvdec.c +++ b/ffmpeg/libavcodec/flvdec.c @@ -102,11 +102,13 @@ int ff_flv_decode_picture_header(MpegEncContext *s) s->h263_long_vectors = 0; /* PEI */ - while (get_bits1(&s->gb) != 0) { - skip_bits(&s->gb, 8); - } + if (skip_1stop_8data_bits(&s->gb) < 0) + return AVERROR_INVALIDDATA; s->f_code = 1; + if (s->ehc_mode) + s->avctx->sample_aspect_ratio= (AVRational){1,2}; + if(s->avctx->debug & FF_DEBUG_PICT_INFO){ av_log(s->avctx, AV_LOG_DEBUG, "%c esc_type:%d, qp:%d num:%d\n", s->droppable ? 'D' : av_get_picture_type_char(s->pict_type), @@ -121,6 +123,7 @@ int ff_flv_decode_picture_header(MpegEncContext *s) AVCodec ff_flv_decoder = { .name = "flv", + .long_name = NULL_IF_CONFIG_SMALL("FLV / Sorenson Spark / Sorenson H.263 (Flash Video)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_FLV1, .priv_data_size = sizeof(MpegEncContext), @@ -129,6 +132,5 @@ AVCodec ff_flv_decoder = { .decode = ff_h263_decode_frame, .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, .max_lowres = 3, - .long_name = NULL_IF_CONFIG_SMALL("FLV / Sorenson Spark / Sorenson H.263 (Flash Video)"), .pix_fmts = ff_pixfmt_list_420, }; diff --git a/ffmpeg/libavcodec/flvenc.c b/ffmpeg/libavcodec/flvenc.c index a68a6fa..9421955 100644 --- a/ffmpeg/libavcodec/flvenc.c +++ b/ffmpeg/libavcodec/flvenc.c @@ -88,6 +88,7 @@ FF_MPV_GENERIC_CLASS(flv) AVCodec ff_flv_encoder = { .name = "flv", + .long_name = NULL_IF_CONFIG_SMALL("FLV / Sorenson Spark / Sorenson H.263 (Flash Video)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_FLV1, .priv_data_size = sizeof(MpegEncContext), @@ -95,6 +96,5 @@ AVCodec ff_flv_encoder = { .encode2 = ff_MPV_encode_picture, .close = ff_MPV_encode_end, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("FLV / Sorenson Spark / Sorenson H.263 (Flash Video)"), .priv_class = &flv_class, }; diff --git a/ffmpeg/libavcodec/fmtconvert.c b/ffmpeg/libavcodec/fmtconvert.c index 79e9645..fb4302c 100644 --- a/ffmpeg/libavcodec/fmtconvert.c +++ b/ffmpeg/libavcodec/fmtconvert.c @@ -24,12 +24,23 @@ #include "fmtconvert.h" #include "libavutil/common.h" -static void int32_to_float_fmul_scalar_c(float *dst, const int *src, float mul, int len){ +static void int32_to_float_fmul_scalar_c(float *dst, const int32_t *src, + float mul, int len) +{ int i; for(i=0; iint32_to_float_fmul_scalar(&dst[i], &src[i], *mul++, 8); +} + static av_always_inline int float_to_int16_one(const float *src){ return av_clip_int16(lrintf(*src)); } @@ -79,12 +90,13 @@ void ff_float_interleave_c(float *dst, const float **src, unsigned int len, av_cold void ff_fmt_convert_init(FmtConvertContext *c, AVCodecContext *avctx) { c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_c; + c->int32_to_float_fmul_array8 = int32_to_float_fmul_array8_c; c->float_to_int16 = float_to_int16_c; c->float_to_int16_interleave = float_to_int16_interleave_c; c->float_interleave = ff_float_interleave_c; if (ARCH_ARM) ff_fmt_convert_init_arm(c, avctx); - if (HAVE_ALTIVEC) ff_fmt_convert_init_altivec(c, avctx); + if (ARCH_PPC) ff_fmt_convert_init_ppc(c, avctx); if (ARCH_X86) ff_fmt_convert_init_x86(c, avctx); if (HAVE_MIPSFPU) ff_fmt_convert_init_mips(c); } diff --git a/ffmpeg/libavcodec/fmtconvert.h b/ffmpeg/libavcodec/fmtconvert.h index 3fb9f4e..30abcc3 100644 --- a/ffmpeg/libavcodec/fmtconvert.h +++ b/ffmpeg/libavcodec/fmtconvert.h @@ -35,7 +35,24 @@ typedef struct FmtConvertContext { * @param len number of elements to convert. * constraints: multiple of 8 */ - void (*int32_to_float_fmul_scalar)(float *dst, const int *src, float mul, int len); + void (*int32_to_float_fmul_scalar)(float *dst, const int32_t *src, + float mul, int len); + + /** + * Convert an array of int32_t to float and multiply by a float value from another array, + * stepping along the float array once for each 8 integers. + * @param c pointer to FmtConvertContext. + * @param dst destination array of float. + * constraints: 16-byte aligned + * @param src source array of int32_t. + * constraints: 16-byte aligned + * @param mul source array of float multipliers. + * @param len number of elements to convert. + * constraints: multiple of 8 + */ + void (*int32_to_float_fmul_array8)(struct FmtConvertContext *c, + float *dst, const int32_t *src, + const float *mul, int len); /** * Convert an array of float to an array of int16_t. @@ -90,7 +107,7 @@ void ff_float_interleave_c(float *dst, const float **src, unsigned int len, void ff_fmt_convert_init(FmtConvertContext *c, AVCodecContext *avctx); void ff_fmt_convert_init_arm(FmtConvertContext *c, AVCodecContext *avctx); -void ff_fmt_convert_init_altivec(FmtConvertContext *c, AVCodecContext *avctx); +void ff_fmt_convert_init_ppc(FmtConvertContext *c, AVCodecContext *avctx); void ff_fmt_convert_init_x86(FmtConvertContext *c, AVCodecContext *avctx); void ff_fmt_convert_init_mips(FmtConvertContext *c); diff --git a/ffmpeg/libavcodec/frame_thread_encoder.c b/ffmpeg/libavcodec/frame_thread_encoder.c index b11a54a..b9acefc 100644 --- a/ffmpeg/libavcodec/frame_thread_encoder.c +++ b/ffmpeg/libavcodec/frame_thread_encoder.c @@ -30,9 +30,9 @@ #if HAVE_PTHREADS #include #elif HAVE_W32THREADS -#include "w32pthreads.h" +#include "compat/w32pthreads.h" #elif HAVE_OS2THREADS -#include "os2threads.h" +#include "compat/os2threads.h" #endif #define MAX_THREADS 64 @@ -126,7 +126,7 @@ int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){ return 0; if(!avctx->thread_count) { - avctx->thread_count = ff_get_logical_cpus(avctx); + avctx->thread_count = av_cpu_count(); avctx->thread_count = FFMIN(avctx->thread_count, MAX_THREADS); } diff --git a/ffmpeg/libavcodec/fraps.c b/ffmpeg/libavcodec/fraps.c index 00a38c6..225da11 100644 --- a/ffmpeg/libavcodec/fraps.c +++ b/ffmpeg/libavcodec/fraps.c @@ -40,6 +40,7 @@ #include "thread.h" #define FPS_TAG MKTAG('F', 'P', 'S', 'x') +#define VLC_BITS 11 /** * local variable storage @@ -94,7 +95,8 @@ static int fraps2_decode_plane(FrapsContext *s, uint8_t *dst, int stride, int w, for (i = 0; i < 256; i++) nodes[i].count = bytestream_get_le32(&src); size -= 1024; - if ((ret = ff_huff_build_tree(s->avctx, &vlc, 256, nodes, huff_cmp, + if ((ret = ff_huff_build_tree(s->avctx, &vlc, 256, VLC_BITS, + nodes, huff_cmp, FF_HUFFMAN_FLAG_ZERO_COUNT)) < 0) return ret; /* we have built Huffman table and are ready to decode plane */ @@ -105,7 +107,7 @@ static int fraps2_decode_plane(FrapsContext *s, uint8_t *dst, int stride, int w, init_get_bits(&gb, s->tmpbuf, size * 8); for (j = 0; j < h; j++) { for (i = 0; i < w*step; i += step) { - dst[i] = get_vlc2(&gb, vlc.table, 9, 3); + dst[i] = get_vlc2(&gb, vlc.table, VLC_BITS, 3); /* lines are stored as deltas between previous lines * and we need to add 0x80 to the first lines of chroma planes */ @@ -143,6 +145,11 @@ static int decode_frame(AVCodecContext *avctx, const int planes = 3; uint8_t *out; + if (buf_size < 4) { + av_log(avctx, AV_LOG_ERROR, "Packet is too short\n"); + return AVERROR_INVALIDDATA; + } + header = AV_RL32(buf); version = header & 0xff; header_size = (header & (1<<30))? 8 : 4; /* bit 30 means pad to 8 bytes */ @@ -200,6 +207,8 @@ static int decode_frame(AVCodecContext *avctx, f->key_frame = 1; avctx->pix_fmt = version & 1 ? AV_PIX_FMT_BGR24 : AV_PIX_FMT_YUVJ420P; + avctx->color_range = version & 1 ? AVCOL_RANGE_UNSPECIFIED : AVCOL_RANGE_JPEG; + avctx->colorspace = version & 1 ? AVCOL_SPC_UNSPECIFIED : AVCOL_SPC_BT709; if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) return ret; @@ -304,6 +313,7 @@ static av_cold int decode_end(AVCodecContext *avctx) AVCodec ff_fraps_decoder = { .name = "fraps", + .long_name = NULL_IF_CONFIG_SMALL("Fraps"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_FRAPS, .priv_data_size = sizeof(FrapsContext), @@ -311,5 +321,4 @@ AVCodec ff_fraps_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, - .long_name = NULL_IF_CONFIG_SMALL("Fraps"), }; diff --git a/ffmpeg/libavcodec/frwu.c b/ffmpeg/libavcodec/frwu.c index b1c7408..c778dbd 100644 --- a/ffmpeg/libavcodec/frwu.c +++ b/ffmpeg/libavcodec/frwu.c @@ -117,12 +117,12 @@ static const AVClass frwu_class = { AVCodec ff_frwu_decoder = { .name = "frwu", + .long_name = NULL_IF_CONFIG_SMALL("Forward Uncompressed"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_FRWU, .priv_data_size = sizeof(FRWUContext), .init = decode_init, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Forward Uncompressed"), .priv_class = &frwu_class, }; diff --git a/ffmpeg/libavcodec/g722.h b/ffmpeg/libavcodec/g722.h index 71d03fc..3f89827 100644 --- a/ffmpeg/libavcodec/g722.h +++ b/ffmpeg/libavcodec/g722.h @@ -5,20 +5,20 @@ * Copyright (c) 2009 Kenan Gillet * Copyright (c) 2010 Martin Storsjo * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/g722dec.c b/ffmpeg/libavcodec/g722dec.c index 1a489a7..470fbbf 100644 --- a/ffmpeg/libavcodec/g722dec.c +++ b/ffmpeg/libavcodec/g722dec.c @@ -44,7 +44,7 @@ #define OFFSET(x) offsetof(G722Context, x) #define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM static const AVOption options[] = { - { "bits_per_codeword", "Bits per G722 codeword", OFFSET(bits_per_codeword), AV_OPT_TYPE_FLAGS, { .i64 = 8 }, 6, 8, AD }, + { "bits_per_codeword", "Bits per G722 codeword", OFFSET(bits_per_codeword), AV_OPT_TYPE_INT, { .i64 = 8 }, 6, 8, AD }, { NULL } }; @@ -138,12 +138,12 @@ static int g722_decode_frame(AVCodecContext *avctx, void *data, AVCodec ff_adpcm_g722_decoder = { .name = "g722", + .long_name = NULL_IF_CONFIG_SMALL("G.722 ADPCM"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_ADPCM_G722, .priv_data_size = sizeof(G722Context), .init = g722_decode_init, .decode = g722_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("G.722 ADPCM"), .priv_class = &g722_decoder_class, }; diff --git a/ffmpeg/libavcodec/g722enc.c b/ffmpeg/libavcodec/g722enc.c index b276b4e..c4d6c7b 100644 --- a/ffmpeg/libavcodec/g722enc.c +++ b/ffmpeg/libavcodec/g722enc.c @@ -5,20 +5,20 @@ * Copyright (c) 2009 Kenan Gillet * Copyright (c) 2010 Martin Storsjo * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -381,6 +381,7 @@ static int g722_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, AVCodec ff_adpcm_g722_encoder = { .name = "g722", + .long_name = NULL_IF_CONFIG_SMALL("G.722 ADPCM"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_ADPCM_G722, .priv_data_size = sizeof(G722Context), @@ -388,7 +389,6 @@ AVCodec ff_adpcm_g722_encoder = { .close = g722_encode_close, .encode2 = g722_encode_frame, .capabilities = CODEC_CAP_SMALL_LAST_FRAME, - .long_name = NULL_IF_CONFIG_SMALL("G.722 ADPCM"), .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, }; diff --git a/ffmpeg/libavcodec/g723_1.c b/ffmpeg/libavcodec/g723_1.c index 6254c9a..09da766 100644 --- a/ffmpeg/libavcodec/g723_1.c +++ b/ffmpeg/libavcodec/g723_1.c @@ -30,7 +30,6 @@ #include "libavutil/mem.h" #include "libavutil/opt.h" #include "avcodec.h" -#include "internal.h" #include "get_bits.h" #include "acelp_vectors.h" #include "celp_filters.h" @@ -1332,12 +1331,12 @@ static const AVClass g723_1dec_class = { AVCodec ff_g723_1_decoder = { .name = "g723_1", + .long_name = NULL_IF_CONFIG_SMALL("G.723.1"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_G723_1, .priv_data_size = sizeof(G723_1_Context), .init = g723_1_decode_init, .decode = g723_1_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("G.723.1"), .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1, .priv_class = &g723_1dec_class, }; @@ -2466,12 +2465,12 @@ static int g723_1_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, AVCodec ff_g723_1_encoder = { .name = "g723_1", + .long_name = NULL_IF_CONFIG_SMALL("G.723.1"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_G723_1, .priv_data_size = sizeof(G723_1_Context), .init = g723_1_encode_init, .encode2 = g723_1_encode_frame, - .long_name = NULL_IF_CONFIG_SMALL("G.723.1"), .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE}, }; diff --git a/ffmpeg/libavcodec/g726.c b/ffmpeg/libavcodec/g726.c index 58d0468..b0331d8 100644 --- a/ffmpeg/libavcodec/g726.c +++ b/ffmpeg/libavcodec/g726.c @@ -96,6 +96,7 @@ typedef struct G726Context { int sez; /**< estimated second order prediction */ int y; /**< quantizer scaling factor for the next iteration */ int code_size; + int little_endian; /**< little-endian bitstream as used in aiff and Sun AU */ } G726Context; static const int quant_tbl16[] = /**< 16kbit/s 2bits per sample */ @@ -368,7 +369,7 @@ static const AVOption options[] = { { NULL }, }; -static const AVClass class = { +static const AVClass g726_class = { .class_name = "g726", .item_name = av_default_item_name, .option = options, @@ -382,6 +383,7 @@ static const AVCodecDefault defaults[] = { AVCodec ff_adpcm_g726_encoder = { .name = "g726", + .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_ADPCM_G726, .priv_data_size = sizeof(G726Context), @@ -390,20 +392,25 @@ AVCodec ff_adpcm_g726_encoder = { .capabilities = CODEC_CAP_SMALL_LAST_FRAME, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"), - .priv_class = &class, + .priv_class = &g726_class, .defaults = defaults, }; #endif -#if CONFIG_ADPCM_G726_DECODER +#if CONFIG_ADPCM_G726_DECODER || CONFIG_ADPCM_G726LE_DECODER static av_cold int g726_decode_init(AVCodecContext *avctx) { G726Context* c = avctx->priv_data; + if(avctx->channels > 1){ + avpriv_request_sample(avctx, "Decoding more than one channel"); + return AVERROR_PATCHWELCOME; + } avctx->channels = 1; avctx->channel_layout = AV_CH_LAYOUT_MONO; + c->little_endian = !strcmp(avctx->codec->name, "g726le"); + c->code_size = avctx->bits_per_coded_sample; if (c->code_size < 2 || c->code_size > 5) { av_log(avctx, AV_LOG_ERROR, "Invalid number of bits %d\n", c->code_size); @@ -438,7 +445,9 @@ static int g726_decode_frame(AVCodecContext *avctx, void *data, init_get_bits(&gb, buf, buf_size * 8); while (out_samples--) - *samples++ = g726_decode(c, get_bits(&gb, c->code_size)); + *samples++ = g726_decode(c, c->little_endian ? + get_bits_le(&gb, c->code_size) : + get_bits(&gb, c->code_size)); if (get_bits_left(&gb) > 0) av_log(avctx, AV_LOG_ERROR, "Frame invalidly split, missing parser?\n"); @@ -453,9 +462,12 @@ static void g726_decode_flush(AVCodecContext *avctx) G726Context *c = avctx->priv_data; g726_reset(c); } +#endif +#if CONFIG_ADPCM_G726_DECODER AVCodec ff_adpcm_g726_decoder = { .name = "g726", + .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_ADPCM_G726, .priv_data_size = sizeof(G726Context), @@ -463,6 +475,19 @@ AVCodec ff_adpcm_g726_decoder = { .decode = g726_decode_frame, .flush = g726_decode_flush, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"), +}; +#endif + +#if CONFIG_ADPCM_G726LE_DECODER +AVCodec ff_adpcm_g726le_decoder = { + .name = "g726le", + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_ADPCM_G726LE, + .priv_data_size = sizeof(G726Context), + .init = g726_decode_init, + .decode = g726_decode_frame, + .flush = g726_decode_flush, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM little-endian"), }; #endif diff --git a/ffmpeg/libavcodec/g729dec.c b/ffmpeg/libavcodec/g729dec.c index 440bf80..d29ad1f 100644 --- a/ffmpeg/libavcodec/g729dec.c +++ b/ffmpeg/libavcodec/g729dec.c @@ -101,7 +101,6 @@ typedef struct { typedef struct { DSPContext dsp; - AVFrame frame; /// past excitation signal buffer int16_t exc_base[2*SUBFRAME_SIZE+PITCH_DELAY_MAX+INTERPOL_LEN]; @@ -385,9 +384,6 @@ static av_cold int decoder_init(AVCodecContext * avctx) ff_dsputil_init(&ctx->dsp, avctx); ctx->dsp.scalarproduct_int16 = scalarproduct_int16_c; - avcodec_get_frame_defaults(&ctx->frame); - avctx->coded_frame = &ctx->frame; - return 0; } @@ -418,11 +414,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, int j, ret; int gain_before, gain_after; int is_periodic = 0; // whether one of the subframes is declared as periodic or not + AVFrame *frame = data; - ctx->frame.nb_samples = SUBFRAME_SIZE<<1; - if ((ret = ff_get_buffer(avctx, &ctx->frame, 0)) < 0) + frame->nb_samples = SUBFRAME_SIZE<<1; + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; - out_frame = (int16_t*) ctx->frame.data[0]; + out_frame = (int16_t*) frame->data[0]; if (buf_size == 10) { packet_type = FORMAT_G729_8K; @@ -714,17 +711,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, memmove(ctx->exc_base, ctx->exc_base + 2 * SUBFRAME_SIZE, (PITCH_DELAY_MAX+INTERPOL_LEN)*sizeof(int16_t)); *got_frame_ptr = 1; - *(AVFrame*)data = ctx->frame; return buf_size; } AVCodec ff_g729_decoder = { .name = "g729", + .long_name = NULL_IF_CONFIG_SMALL("G.729"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_G729, .priv_data_size = sizeof(G729Context), .init = decoder_init, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("G.729"), }; diff --git a/ffmpeg/libavcodec/get_bits.h b/ffmpeg/libavcodec/get_bits.h index f16a508..7824e5a 100644 --- a/ffmpeg/libavcodec/get_bits.h +++ b/ffmpeg/libavcodec/get_bits.h @@ -64,6 +64,7 @@ typedef struct VLC { int bits; VLC_TYPE (*table)[2]; ///< code, bits int table_size, table_allocated; + void * volatile init_state; } VLC; typedef struct RL_VLC_ELEM { @@ -139,27 +140,34 @@ typedef struct RL_VLC_ELEM { #define CLOSE_READER(name, gb) (gb)->index = name ## _index +# ifdef LONG_BITSTREAM_READER + +# define UPDATE_CACHE_LE(name, gb) name ## _cache = \ + AV_RL64((gb)->buffer + (name ## _index >> 3)) >> (name ## _index & 7) + +# define UPDATE_CACHE_BE(name, gb) name ## _cache = \ + AV_RB64((gb)->buffer + (name ## _index >> 3)) >> (32 - (name ## _index & 7)) + +#else + +# define UPDATE_CACHE_LE(name, gb) name ## _cache = \ + AV_RL32((gb)->buffer + (name ## _index >> 3)) >> (name ## _index & 7) + +# define UPDATE_CACHE_BE(name, gb) name ## _cache = \ + AV_RB32((gb)->buffer + (name ## _index >> 3)) << (name ## _index & 7) + +#endif + + #ifdef BITSTREAM_READER_LE -# ifdef LONG_BITSTREAM_READER -# define UPDATE_CACHE(name, gb) name ## _cache = \ - AV_RL64((gb)->buffer + (name ## _index >> 3)) >> (name ## _index & 7) -# else -# define UPDATE_CACHE(name, gb) name ## _cache = \ - AV_RL32((gb)->buffer + (name ## _index >> 3)) >> (name ## _index & 7) -# endif +# define UPDATE_CACHE(name, gb) UPDATE_CACHE_LE(name, gb) # define SKIP_CACHE(name, gb, num) name ## _cache >>= (num) #else -# ifdef LONG_BITSTREAM_READER -# define UPDATE_CACHE(name, gb) name ## _cache = \ - AV_RB64((gb)->buffer + (name ## _index >> 3)) >> (32 - (name ## _index & 7)) -# else -# define UPDATE_CACHE(name, gb) name ## _cache = \ - AV_RB32((gb)->buffer + (name ## _index >> 3)) << (name ## _index & 7) -# endif +# define UPDATE_CACHE(name, gb) UPDATE_CACHE_BE(name, gb) # define SKIP_CACHE(name, gb, num) name ## _cache <<= (num) @@ -180,12 +188,18 @@ typedef struct RL_VLC_ELEM { #define LAST_SKIP_BITS(name, gb, num) SKIP_COUNTER(name, gb, num) +#define SHOW_UBITS_LE(name, gb, num) zero_extend(name ## _cache, num) +#define SHOW_SBITS_LE(name, gb, num) sign_extend(name ## _cache, num) + +#define SHOW_UBITS_BE(name, gb, num) NEG_USR32(name ## _cache, num) +#define SHOW_SBITS_BE(name, gb, num) NEG_SSR32(name ## _cache, num) + #ifdef BITSTREAM_READER_LE -# define SHOW_UBITS(name, gb, num) zero_extend(name ## _cache, num) -# define SHOW_SBITS(name, gb, num) sign_extend(name ## _cache, num) +# define SHOW_UBITS(name, gb, num) SHOW_UBITS_LE(name, gb, num) +# define SHOW_SBITS(name, gb, num) SHOW_SBITS_LE(name, gb, num) #else -# define SHOW_UBITS(name, gb, num) NEG_USR32(name ## _cache, num) -# define SHOW_SBITS(name, gb, num) NEG_SSR32(name ## _cache, num) +# define SHOW_UBITS(name, gb, num) SHOW_UBITS_BE(name, gb, num) +# define SHOW_SBITS(name, gb, num) SHOW_SBITS_BE(name, gb, num) #endif #define GET_CACHE(name, gb) ((uint32_t) name ## _cache) @@ -214,6 +228,7 @@ static inline int get_xbits(GetBitContext *s, int n) register int sign; register int32_t cache; OPEN_READER(re, s); + av_assert2(n>0 && n<=25); UPDATE_CACHE(re, s); cache = GET_CACHE(re, s); sign = ~cache >> 31; @@ -249,6 +264,18 @@ static inline unsigned int get_bits(GetBitContext *s, int n) return tmp; } +static inline unsigned int get_bits_le(GetBitContext *s, int n) +{ + register int tmp; + OPEN_READER(re, s); + av_assert2(n>0 && n<=25); + UPDATE_CACHE_LE(re, s); + tmp = SHOW_UBITS_LE(re, s, n); + LAST_SKIP_BITS(re, s, n); + CLOSE_READER(re, s); + return tmp; +} + /** * Show 1-25 bits. */ @@ -265,7 +292,6 @@ static inline unsigned int show_bits(GetBitContext *s, int n) static inline void skip_bits(GetBitContext *s, int n) { OPEN_READER(re, s); - UPDATE_CACHE(re, s); LAST_SKIP_BITS(re, s, n); CLOSE_READER(re, s); } @@ -559,6 +585,20 @@ static inline int get_bits_left(GetBitContext *gb) return gb->size_in_bits - get_bits_count(gb); } +static inline int skip_1stop_8data_bits(GetBitContext *gb) +{ + if (get_bits_left(gb) <= 0) + return AVERROR_INVALIDDATA; + + while (get_bits1(gb)) { + skip_bits(gb, 8); + if (get_bits_left(gb) <= 0) + return AVERROR_INVALIDDATA; + } + + return 0; +} + //#define TRACE #ifdef TRACE diff --git a/ffmpeg/libavcodec/gif.c b/ffmpeg/libavcodec/gif.c index de3e576..27d054e 100644 --- a/ffmpeg/libavcodec/gif.c +++ b/ffmpeg/libavcodec/gif.c @@ -1,9 +1,10 @@ /* - * GIF encoder. * Copyright (c) 2000 Fabrice Bellard * Copyright (c) 2002 Francois Revol * Copyright (c) 2006 Baptiste Coudurier * + * first version by Francois Revol + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -21,101 +22,174 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -/* - * First version by Francois Revol revol@free.fr - * - * Features and limitations: - * - uses only a global standard palette - * - tested with IE 5.0, Opera for BeOS, NetPositive (BeOS), and Mozilla (BeOS). - * - * Reference documents: - * http://www.goice.co.jp/member/mo/formats/gif.html - * http://astronomy.swin.edu.au/pbourke/dataformats/gif/ - * http://www.dcs.ed.ac.uk/home/mxr/gfx/2d/GIF89a.txt +/** + * @file + * GIF encoder + * @see http://www.w3.org/Graphics/GIF/spec-gif89a.txt */ +#define BITSTREAM_WRITER_LE +#include "libavutil/opt.h" +#include "libavutil/imgutils.h" #include "avcodec.h" #include "bytestream.h" #include "internal.h" #include "lzw.h" - -/* The GIF format uses reversed order for bitstreams... */ -/* at least they don't use PDP_ENDIAN :) */ -#define BITSTREAM_WRITER_LE +#include "gif.h" #include "put_bits.h" typedef struct { - AVFrame picture; + const AVClass *class; LZWState *lzw; uint8_t *buf; + AVFrame *last_frame; + int flags; + uint32_t palette[AVPALETTE_COUNT]; ///< local reference palette for !pal8 + uint8_t *tmpl; ///< temporary line buffer } GIFContext; -/* GIF header */ -static int gif_image_write_header(AVCodecContext *avctx, - uint8_t **bytestream, uint32_t *palette) +enum { + GF_OFFSETTING = 1<<0, + GF_TRANSDIFF = 1<<1, +}; + +static int pick_palette_entry(const uint8_t *buf, int linesize, int w, int h) { - int i; - unsigned int v, smallest_alpha = 0xFF, alpha_component = 0; - - bytestream_put_buffer(bytestream, "GIF", 3); - bytestream_put_buffer(bytestream, "89a", 3); - bytestream_put_le16(bytestream, avctx->width); - bytestream_put_le16(bytestream, avctx->height); - - bytestream_put_byte(bytestream, 0xf7); /* flags: global clut, 256 entries */ - bytestream_put_byte(bytestream, 0x1f); /* background color index */ - bytestream_put_byte(bytestream, 0); /* aspect ratio */ - - /* the global palette */ - for(i=0;i<256;i++) { - v = palette[i]; - bytestream_put_be24(bytestream, v); - if (v >> 24 < smallest_alpha) { - smallest_alpha = v >> 24; - alpha_component = i; - } - } + int histogram[AVPALETTE_COUNT] = {0}; + int x, y, i; - if (smallest_alpha < 128) { - bytestream_put_byte(bytestream, 0x21); /* Extension Introducer */ - bytestream_put_byte(bytestream, 0xf9); /* Graphic Control Label */ - bytestream_put_byte(bytestream, 0x04); /* block length */ - bytestream_put_byte(bytestream, 0x01); /* Transparent Color Flag */ - bytestream_put_le16(bytestream, 0x00); /* no delay */ - bytestream_put_byte(bytestream, alpha_component); - bytestream_put_byte(bytestream, 0x00); + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) + histogram[buf[x]]++; + buf += linesize; } - - return 0; + for (i = 0; i < FF_ARRAY_ELEMS(histogram); i++) + if (!histogram[i]) + return i; + return -1; } static int gif_image_write_image(AVCodecContext *avctx, uint8_t **bytestream, uint8_t *end, - const uint8_t *buf, int linesize) + const uint32_t *palette, + const uint8_t *buf, const int linesize, + AVPacket *pkt) { GIFContext *s = avctx->priv_data; - int len = 0, height; + int len = 0, height = avctx->height, width = avctx->width, x, y; + int x_start = 0, y_start = 0, trans = -1; const uint8_t *ptr; + + /* Crop image */ + // TODO support with palette change + if ((s->flags & GF_OFFSETTING) && s->last_frame && !palette) { + const uint8_t *ref = s->last_frame->data[0]; + const int ref_linesize = s->last_frame->linesize[0]; + int x_end = avctx->width - 1, + y_end = avctx->height - 1; + + /* skip common lines */ + while (y_start < y_end) { + if (memcmp(ref + y_start*ref_linesize, buf + y_start*linesize, width)) + break; + y_start++; + } + while (y_end > y_start) { + if (memcmp(ref + y_end*ref_linesize, buf + y_end*linesize, width)) + break; + y_end--; + } + height = y_end + 1 - y_start; + + /* skip common columns */ + while (x_start < x_end) { + int same_column = 1; + for (y = y_start; y < y_end; y++) { + if (ref[y*ref_linesize + x_start] != buf[y*linesize + x_start]) { + same_column = 0; + break; + } + } + if (!same_column) + break; + x_start++; + } + while (x_end > x_start) { + int same_column = 1; + for (y = y_start; y < y_end; y++) { + if (ref[y*ref_linesize + x_end] != buf[y*linesize + x_end]) { + same_column = 0; + break; + } + } + if (!same_column) + break; + x_end--; + } + width = x_end + 1 - x_start; + + av_log(avctx, AV_LOG_DEBUG,"%dx%d image at pos (%d;%d) [area:%dx%d]\n", + width, height, x_start, y_start, avctx->width, avctx->height); + } + /* image block */ + bytestream_put_byte(bytestream, GIF_IMAGE_SEPARATOR); + bytestream_put_le16(bytestream, x_start); + bytestream_put_le16(bytestream, y_start); + bytestream_put_le16(bytestream, width); + bytestream_put_le16(bytestream, height); - bytestream_put_byte(bytestream, 0x2c); - bytestream_put_le16(bytestream, 0); - bytestream_put_le16(bytestream, 0); - bytestream_put_le16(bytestream, avctx->width); - bytestream_put_le16(bytestream, avctx->height); - bytestream_put_byte(bytestream, 0x00); /* flags */ - /* no local clut */ + if (!palette) { + bytestream_put_byte(bytestream, 0x00); /* flags */ + } else { + unsigned i; + bytestream_put_byte(bytestream, 1<<7 | 0x7); /* flags */ + for (i = 0; i < AVPALETTE_COUNT; i++) { + const uint32_t v = palette[i]; + bytestream_put_be24(bytestream, v); + } + } + + /* TODO: support with palette change (pal8) */ + if ((s->flags & GF_TRANSDIFF) && s->last_frame && !palette) { + trans = pick_palette_entry(buf + y_start*linesize + x_start, + linesize, width, height); + if (trans < 0) { // TODO, patch welcome + av_log(avctx, AV_LOG_DEBUG, "No available color, can not use transparency\n"); + } else { + uint8_t *pal_exdata = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE); + if (!pal_exdata) + return AVERROR(ENOMEM); + memcpy(pal_exdata, s->palette, AVPALETTE_SIZE); + pal_exdata[trans*4 + 3*!HAVE_BIGENDIAN] = 0x00; + } + } bytestream_put_byte(bytestream, 0x08); - ff_lzw_encode_init(s->lzw, s->buf, avctx->width*avctx->height, + ff_lzw_encode_init(s->lzw, s->buf, 2 * width * height, 12, FF_LZW_GIF, put_bits); - ptr = buf; - for (height = avctx->height; height--;) { - len += ff_lzw_encode(s->lzw, ptr, avctx->width); - ptr += linesize; + ptr = buf + y_start*linesize + x_start; + if (trans >= 0) { + const int ref_linesize = s->last_frame->linesize[0]; + const uint8_t *ref = s->last_frame->data[0] + y_start*ref_linesize + x_start; + + for (y = 0; y < height; y++) { + memcpy(s->tmpl, ptr, width); + for (x = 0; x < width; x++) + if (ref[x] == ptr[x]) + s->tmpl[x] = trans; + len += ff_lzw_encode(s->lzw, s->tmpl, width); + ptr += linesize; + ref += ref_linesize; + } + } else { + for (y = 0; y < height; y++) { + len += ff_lzw_encode(s->lzw, ptr, width); + ptr += linesize; + } } len += ff_lzw_encode_flush(s->lzw, flush_put_bits); @@ -130,7 +204,6 @@ static int gif_image_write_image(AVCodecContext *avctx, len -= size; } bytestream_put_byte(bytestream, 0x00); /* end of image block */ - bytestream_put_byte(bytestream, 0x3b); return 0; } @@ -140,26 +213,34 @@ static av_cold int gif_encode_init(AVCodecContext *avctx) if (avctx->width > 65535 || avctx->height > 65535) { av_log(avctx, AV_LOG_ERROR, "GIF does not support resolutions above 65535x65535\n"); - return -1; + return AVERROR(EINVAL); } - avctx->coded_frame = &s->picture; - s->lzw = av_mallocz(ff_lzw_encode_state_size); - if (!s->lzw) + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) return AVERROR(ENOMEM); + + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->key_frame = 1; + + s->lzw = av_mallocz(ff_lzw_encode_state_size); s->buf = av_malloc(avctx->width*avctx->height*2); - if (!s->buf) - return AVERROR(ENOMEM); + s->tmpl = av_malloc(avctx->width); + if (!s->tmpl || !s->buf || !s->lzw) + return AVERROR(ENOMEM); + + if (avpriv_set_systematic_pal2(s->palette, avctx->pix_fmt) < 0) + av_assert0(avctx->pix_fmt == AV_PIX_FMT_PAL8); + return 0; } -/* better than nothing gif encoder */ static int gif_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { GIFContext *s = avctx->priv_data; - AVFrame *const p = &s->picture; uint8_t *outbuf_ptr, *end; + const uint32_t *palette = NULL; int ret; if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width*avctx->height*7/5 + FF_MIN_BUFFER_SIZE)) < 0) @@ -167,11 +248,25 @@ static int gif_encode_frame(AVCodecContext *avctx, AVPacket *pkt, outbuf_ptr = pkt->data; end = pkt->data + pkt->size; - *p = *pict; - p->pict_type = AV_PICTURE_TYPE_I; - p->key_frame = 1; - gif_image_write_header(avctx, &outbuf_ptr, (uint32_t *)pict->data[1]); - gif_image_write_image(avctx, &outbuf_ptr, end, pict->data[0], pict->linesize[0]); + if (avctx->pix_fmt == AV_PIX_FMT_PAL8) { + uint8_t *pal_exdata = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE); + if (!pal_exdata) + return AVERROR(ENOMEM); + memcpy(pal_exdata, pict->data[1], AVPALETTE_SIZE); + palette = (uint32_t*)pict->data[1]; + } + + gif_image_write_image(avctx, &outbuf_ptr, end, palette, + pict->data[0], pict->linesize[0], pkt); + if (!s->last_frame) { + s->last_frame = av_frame_alloc(); + if (!s->last_frame) + return AVERROR(ENOMEM); + } + av_frame_unref(s->last_frame); + ret = av_frame_ref(s->last_frame, (AVFrame*)pict); + if (ret < 0) + return ret; pkt->size = outbuf_ptr - pkt->data; pkt->flags |= AV_PKT_FLAG_KEY; @@ -184,13 +279,34 @@ static int gif_encode_close(AVCodecContext *avctx) { GIFContext *s = avctx->priv_data; + av_frame_free(&avctx->coded_frame); + av_freep(&s->lzw); av_freep(&s->buf); + av_frame_free(&s->last_frame); + av_freep(&s->tmpl); return 0; } +#define OFFSET(x) offsetof(GIFContext, x) +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM +static const AVOption gif_options[] = { + { "gifflags", "set GIF flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = GF_OFFSETTING|GF_TRANSDIFF}, 0, INT_MAX, FLAGS, "flags" }, + { "offsetting", "enable picture offsetting", 0, AV_OPT_TYPE_CONST, {.i64=GF_OFFSETTING}, INT_MIN, INT_MAX, FLAGS, "flags" }, + { "transdiff", "enable transparency detection between frames", 0, AV_OPT_TYPE_CONST, {.i64=GF_TRANSDIFF}, INT_MIN, INT_MAX, FLAGS, "flags" }, + { NULL } +}; + +static const AVClass gif_class = { + .class_name = "GIF encoder", + .item_name = av_default_item_name, + .option = gif_options, + .version = LIBAVUTIL_VERSION_INT, +}; + AVCodec ff_gif_encoder = { .name = "gif", + .long_name = NULL_IF_CONFIG_SMALL("GIF (Graphics Interchange Format)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_GIF, .priv_data_size = sizeof(GIFContext), @@ -201,5 +317,5 @@ AVCodec ff_gif_encoder = { AV_PIX_FMT_RGB8, AV_PIX_FMT_BGR8, AV_PIX_FMT_RGB4_BYTE, AV_PIX_FMT_BGR4_BYTE, AV_PIX_FMT_GRAY8, AV_PIX_FMT_PAL8, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("GIF (Graphics Interchange Format)"), + .priv_class = &gif_class, }; diff --git a/ffmpeg/libavcodec/gif.h b/ffmpeg/libavcodec/gif.h index b557534..b4cf665 100644 --- a/ffmpeg/libavcodec/gif.h +++ b/ffmpeg/libavcodec/gif.h @@ -43,5 +43,7 @@ static const uint8_t gif89a_sig[6] = "GIF89a"; #define GIF_EXTENSION_INTRODUCER 0x21 #define GIF_IMAGE_SEPARATOR 0x2c #define GIF_GCE_EXT_LABEL 0xf9 +#define GIF_APP_EXT_LABEL 0xff +#define NETSCAPE_EXT_STR "NETSCAPE2.0" #endif /* AVCODEC_GIFDEFS_H */ diff --git a/ffmpeg/libavcodec/gifdec.c b/ffmpeg/libavcodec/gifdec.c index 27364c9..78c8900 100644 --- a/ffmpeg/libavcodec/gifdec.c +++ b/ffmpeg/libavcodec/gifdec.c @@ -21,8 +21,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -//#define DEBUG - #include "libavutil/imgutils.h" #include "libavutil/opt.h" #include "avcodec.h" @@ -66,7 +64,6 @@ typedef struct GifState { int stored_bg_color; GetByteContext gb; - /* LZW compatible decoder */ LZWState *lzw; /* aux buffers */ @@ -142,11 +139,11 @@ static int gif_read_image(GifState *s, AVFrame *frame) if (bytestream2_get_bytes_left(&s->gb) < 9) return AVERROR_INVALIDDATA; - left = bytestream2_get_le16u(&s->gb); - top = bytestream2_get_le16u(&s->gb); - width = bytestream2_get_le16u(&s->gb); + left = bytestream2_get_le16u(&s->gb); + top = bytestream2_get_le16u(&s->gb); + width = bytestream2_get_le16u(&s->gb); height = bytestream2_get_le16u(&s->gb); - flags = bytestream2_get_byteu(&s->gb); + flags = bytestream2_get_byteu(&s->gb); is_interleaved = flags & 0x40; has_local_palette = flags & 0x80; bits_per_pixel = (flags & 0x07) + 1; @@ -183,10 +180,14 @@ static int gif_read_image(GifState *s, AVFrame *frame) /* verify that all the image is inside the screen dimensions */ if (left + width > s->screen_width || - top + height > s->screen_height) + top + height > s->screen_height) { + av_log(s->avctx, AV_LOG_ERROR, "image is outside the screen dimensions.\n"); return AVERROR_INVALIDDATA; - if (width <= 0 || height <= 0) + } + if (width <= 0 || height <= 0) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid image dimensions.\n"); return AVERROR_INVALIDDATA; + } /* process disposal method */ if (s->gce_prev_disposal == GCE_DISPOSAL_BACKGROUND) { @@ -236,8 +237,12 @@ static int gif_read_image(GifState *s, AVFrame *frame) pass = 0; y1 = 0; for (y = 0; y < height; y++) { - if (ff_lzw_decode(s->lzw, s->idx_line, width) == 0) + int count = ff_lzw_decode(s->lzw, s->idx_line, width); + if (count != width) { + if (count) + av_log(s->avctx, AV_LOG_ERROR, "LZW decode failed\n"); goto decode_tail; + } pr = ptr + width; @@ -300,7 +305,7 @@ static int gif_read_extension(GifState *s) return AVERROR_INVALIDDATA; ext_code = bytestream2_get_byteu(&s->gb); - ext_len = bytestream2_get_byteu(&s->gb); + ext_len = bytestream2_get_byteu(&s->gb); av_dlog(s->avctx, "ext_code=0x%x len=%d\n", ext_code, ext_len); @@ -314,7 +319,7 @@ static int gif_read_extension(GifState *s) if (bytestream2_get_bytes_left(&s->gb) < 5) return AVERROR_INVALIDDATA; - gce_flags = bytestream2_get_byteu(&s->gb); + gce_flags = bytestream2_get_byteu(&s->gb); bytestream2_skipu(&s->gb, 2); // delay during which the frame is shown gce_transparent_index = bytestream2_get_byteu(&s->gb); if (gce_flags & 0x01) @@ -368,7 +373,7 @@ static int gif_read_header1(GifState *s) /* read screen header */ s->transparent_color_index = -1; - s->screen_width = bytestream2_get_le16u(&s->gb); + s->screen_width = bytestream2_get_le16u(&s->gb); s->screen_height = bytestream2_get_le16u(&s->gb); v = bytestream2_get_byteu(&s->gb); @@ -402,11 +407,11 @@ static int gif_read_header1(GifState *s) static int gif_parse_next_image(GifState *s, AVFrame *frame) { - while (bytestream2_get_bytes_left(&s->gb)) { + while (bytestream2_get_bytes_left(&s->gb) > 0) { int code = bytestream2_get_byte(&s->gb); int ret; - av_dlog(s->avctx, "code=%02x '%c'\n", code, code); + av_log(s->avctx, AV_LOG_DEBUG, "code=%02x '%c'\n", code, code); switch (code) { case GIF_IMAGE_SEPARATOR: @@ -461,12 +466,12 @@ static int gif_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, A if (s->keyframe) { s->keyframe_ok = 0; + s->gce_prev_disposal = GCE_DISPOSAL_NONE; if ((ret = gif_read_header1(s)) < 0) return ret; - if ((ret = av_image_check_size(s->screen_width, s->screen_height, 0, avctx)) < 0) + if ((ret = ff_set_dimensions(avctx, s->screen_width, s->screen_height)) < 0) return ret; - avcodec_set_dimensions(avctx, s->screen_width, s->screen_height); av_frame_unref(s->frame); if ((ret = ff_get_buffer(avctx, s->frame, 0)) < 0) @@ -500,7 +505,7 @@ static int gif_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, A return ret; *got_frame = 1; - return avpkt->size; + return bytestream2_tell(&s->gb); } static av_cold int gif_decode_close(AVCodecContext *avctx) @@ -533,6 +538,7 @@ static const AVClass decoder_class = { AVCodec ff_gif_decoder = { .name = "gif", + .long_name = NULL_IF_CONFIG_SMALL("GIF (Graphics Interchange Format)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_GIF, .priv_data_size = sizeof(GifState), @@ -540,6 +546,5 @@ AVCodec ff_gif_decoder = { .close = gif_decode_close, .decode = gif_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("GIF (Graphics Interchange Format)"), .priv_class = &decoder_class, }; diff --git a/ffmpeg/libavcodec/golomb.h b/ffmpeg/libavcodec/golomb.h index 66607ad..43875dc 100644 --- a/ffmpeg/libavcodec/golomb.h +++ b/ffmpeg/libavcodec/golomb.h @@ -31,6 +31,7 @@ #define AVCODEC_GOLOMB_H #include + #include "get_bits.h" #include "put_bits.h" @@ -46,33 +47,32 @@ extern const uint8_t ff_interleaved_ue_golomb_vlc_code[256]; extern const int8_t ff_interleaved_se_golomb_vlc_code[256]; extern const uint8_t ff_interleaved_dirac_golomb_vlc_code[256]; - - /** +/** * read unsigned exp golomb code. */ -static inline int get_ue_golomb(GetBitContext *gb){ +static inline int get_ue_golomb(GetBitContext *gb) +{ unsigned int buf; - int log; OPEN_READER(re, gb); UPDATE_CACHE(re, gb); - buf=GET_CACHE(re, gb); + buf = GET_CACHE(re, gb); - if(buf >= (1<<27)){ + if (buf >= (1 << 27)) { buf >>= 32 - 9; LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]); CLOSE_READER(re, gb); return ff_ue_golomb_vlc_code[buf]; - }else{ - log= 2*av_log2(buf) - 31; + } else { + int log = 2 * av_log2(buf) - 31; LAST_SKIP_BITS(re, gb, 32 - log); CLOSE_READER(re, gb); if (CONFIG_FTRAPV && log < 0) { av_log(0, AV_LOG_ERROR, "Invalid UE golomb code\n"); return AVERROR_INVALIDDATA; } - buf>>= log; + buf >>= log; buf--; return buf; @@ -93,16 +93,17 @@ static inline unsigned get_ue_golomb_long(GetBitContext *gb) return get_bits_long(gb, log + 1) - 1; } - /** +/** * read unsigned exp golomb code, constraint to a max of 31. * the return value is undefined if the stored value exceeds 31. */ -static inline int get_ue_golomb_31(GetBitContext *gb){ +static inline int get_ue_golomb_31(GetBitContext *gb) +{ unsigned int buf; OPEN_READER(re, gb); UPDATE_CACHE(re, gb); - buf=GET_CACHE(re, gb); + buf = GET_CACHE(re, gb); buf >>= 32 - 9; LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]); @@ -117,24 +118,25 @@ static inline unsigned svq3_get_ue_golomb(GetBitContext *gb) OPEN_READER(re, gb); UPDATE_CACHE(re, gb); - buf=GET_CACHE(re, gb); + buf = GET_CACHE(re, gb); - if(buf&0xAA800000){ + if (buf & 0xAA800000) { buf >>= 32 - 8; LAST_SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]); CLOSE_READER(re, gb); return ff_interleaved_ue_golomb_vlc_code[buf]; - }else{ + } else { unsigned ret = 1; do { buf >>= 32 - 8; - LAST_SKIP_BITS(re, gb, FFMIN(ff_interleaved_golomb_vlc_len[buf], 8)); + LAST_SKIP_BITS(re, gb, + FFMIN(ff_interleaved_golomb_vlc_len[buf], 8)); - if (ff_interleaved_golomb_vlc_len[buf] != 9){ + if (ff_interleaved_golomb_vlc_len[buf] != 9) { ret <<= (ff_interleaved_golomb_vlc_len[buf] - 1) >> 1; - ret |= ff_interleaved_dirac_golomb_vlc_code[buf]; + ret |= ff_interleaved_dirac_golomb_vlc_code[buf]; break; } ret = (ret << 4) | ff_interleaved_dirac_golomb_vlc_code[buf]; @@ -150,100 +152,107 @@ static inline unsigned svq3_get_ue_golomb(GetBitContext *gb) /** * read unsigned truncated exp golomb code. */ -static inline int get_te0_golomb(GetBitContext *gb, int range){ +static inline int get_te0_golomb(GetBitContext *gb, int range) +{ av_assert2(range >= 1); - if(range==1) return 0; - else if(range==2) return get_bits1(gb)^1; - else return get_ue_golomb(gb); + if (range == 1) + return 0; + else if (range == 2) + return get_bits1(gb) ^ 1; + else + return get_ue_golomb(gb); } /** * read unsigned truncated exp golomb code. */ -static inline int get_te_golomb(GetBitContext *gb, int range){ +static inline int get_te_golomb(GetBitContext *gb, int range) +{ av_assert2(range >= 1); - if(range==2) return get_bits1(gb)^1; - else return get_ue_golomb(gb); + if (range == 2) + return get_bits1(gb) ^ 1; + else + return get_ue_golomb(gb); } - /** * read signed exp golomb code. */ -static inline int get_se_golomb(GetBitContext *gb){ +static inline int get_se_golomb(GetBitContext *gb) +{ unsigned int buf; - int log; OPEN_READER(re, gb); UPDATE_CACHE(re, gb); - buf=GET_CACHE(re, gb); + buf = GET_CACHE(re, gb); - if(buf >= (1<<27)){ + if (buf >= (1 << 27)) { buf >>= 32 - 9; LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]); CLOSE_READER(re, gb); return ff_se_golomb_vlc_code[buf]; - }else{ - log = av_log2(buf); + } else { + int log = av_log2(buf); LAST_SKIP_BITS(re, gb, 31 - log); UPDATE_CACHE(re, gb); buf = GET_CACHE(re, gb); - buf>>= log; + buf >>= log; LAST_SKIP_BITS(re, gb, 32 - log); CLOSE_READER(re, gb); - if(buf&1) buf= -(buf>>1); - else buf= (buf>>1); + if (buf & 1) + buf = -(buf >> 1); + else + buf = (buf >> 1); return buf; } } -static inline int svq3_get_se_golomb(GetBitContext *gb){ +static inline int svq3_get_se_golomb(GetBitContext *gb) +{ unsigned int buf; - int log; OPEN_READER(re, gb); UPDATE_CACHE(re, gb); - buf=GET_CACHE(re, gb); + buf = GET_CACHE(re, gb); - if(buf&0xAA800000){ + if (buf & 0xAA800000) { buf >>= 32 - 8; LAST_SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]); CLOSE_READER(re, gb); return ff_interleaved_se_golomb_vlc_code[buf]; - }else{ + } else { + int log; LAST_SKIP_BITS(re, gb, 8); UPDATE_CACHE(re, gb); buf |= 1 | (GET_CACHE(re, gb) >> 8); - if((buf & 0xAAAAAAAA) == 0) + if ((buf & 0xAAAAAAAA) == 0) return INVALID_VLC; - for(log=31; (buf & 0x80000000) == 0; log--){ + for (log = 31; (buf & 0x80000000) == 0; log--) buf = (buf << 2) - ((buf << log) >> (log - 1)) + (buf >> 30); - } - LAST_SKIP_BITS(re, gb, 63 - 2*log - 8); + LAST_SKIP_BITS(re, gb, 63 - 2 * log - 8); CLOSE_READER(re, gb); return (signed) (((((buf << log) >> log) - 1) ^ -(buf & 0x1)) + 1) >> 1; } } -static inline int dirac_get_se_golomb(GetBitContext *gb){ - uint32_t buf; - uint32_t ret; - - ret = svq3_get_ue_golomb(gb); +static inline int dirac_get_se_golomb(GetBitContext *gb) +{ + uint32_t ret = svq3_get_ue_golomb(gb); if (ret) { + uint32_t buf; OPEN_READER(re, gb); UPDATE_CACHE(re, gb); buf = SHOW_SBITS(re, gb, 1); @@ -258,24 +267,26 @@ static inline int dirac_get_se_golomb(GetBitContext *gb){ /** * read unsigned golomb rice code (ffv1). */ -static inline int get_ur_golomb(GetBitContext *gb, int k, int limit, int esc_len){ +static inline int get_ur_golomb(GetBitContext *gb, int k, int limit, + int esc_len) +{ unsigned int buf; int log; OPEN_READER(re, gb); UPDATE_CACHE(re, gb); - buf=GET_CACHE(re, gb); + buf = GET_CACHE(re, gb); - log= av_log2(buf); + log = av_log2(buf); - if(log > 31-limit){ + if (log > 31 - limit) { buf >>= log - k; - buf += (30-log)<= 32-MIN_CACHE_BITS+(MIN_CACHE_BITS==32) && 32-log < limit){ + if (log - k >= 32 - MIN_CACHE_BITS + (MIN_CACHE_BITS == 32) && + 32 - log < limit) { buf >>= log - k; - buf += (30-log)<size_in_bits <= re_index) @@ -318,23 +332,23 @@ static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, int } SKIP_BITS(re, gb, 1); - if(i < limit - 1){ - if(k){ + if (i < limit - 1) { + if (k) { buf = SHOW_UBITS(re, gb, k); LAST_SKIP_BITS(re, gb, k); - }else{ - buf=0; + } else { + buf = 0; } CLOSE_READER(re, gb); - return buf + (i<>1; - else return -(v>>1); + if (v & 1) + return v >> 1; + else + return -(v >> 1); // return (v>>1) ^ -(v&1); } @@ -355,22 +373,25 @@ static inline int get_sr_golomb(GetBitContext *gb, int k, int limit, int esc_len /** * read signed golomb rice code (flac). */ -static inline int get_sr_golomb_flac(GetBitContext *gb, int k, int limit, int esc_len){ - int v= get_ur_golomb_jpegls(gb, k, limit, esc_len); - return (v>>1) ^ -(v&1); +static inline int get_sr_golomb_flac(GetBitContext *gb, int k, int limit, + int esc_len) +{ + int v = get_ur_golomb_jpegls(gb, k, limit, esc_len); + return (v >> 1) ^ -(v & 1); } /** * read unsigned golomb rice code (shorten). */ -static inline unsigned int get_ur_golomb_shorten(GetBitContext *gb, int k){ - return get_ur_golomb_jpegls(gb, k, INT_MAX, 0); +static inline unsigned int get_ur_golomb_shorten(GetBitContext *gb, int k) +{ + return get_ur_golomb_jpegls(gb, k, INT_MAX, 0); } /** * read signed golomb rice code (shorten). */ -static inline int get_sr_golomb_shorten(GetBitContext* gb, int k) +static inline int get_sr_golomb_shorten(GetBitContext *gb, int k) { int uvar = get_ur_golomb_jpegls(gb, k + 1, INT_MAX, 0); if (uvar & 1) @@ -379,22 +400,21 @@ static inline int get_sr_golomb_shorten(GetBitContext* gb, int k) return uvar >> 1; } - - #ifdef TRACE static inline int get_ue(GetBitContext *s, const char *file, const char *func, int line) { - int show= show_bits(s, 24); - int pos= get_bits_count(s); - int i= get_ue_golomb(s); - int len= get_bits_count(s) - pos; - int bits= show>>(24-len); + int show = show_bits(s, 24); + int pos = get_bits_count(s); + int i = get_ue_golomb(s); + int len = get_bits_count(s) - pos; + int bits = show >> (24 - len); print_bin(bits, len); - av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d ue @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line); + av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d ue @%5d in %s %s:%d\n", + bits, len, i, pos, file, func, line); return i; } @@ -402,87 +422,96 @@ static inline int get_ue(GetBitContext *s, const char *file, const char *func, static inline int get_se(GetBitContext *s, const char *file, const char *func, int line) { - int show= show_bits(s, 24); - int pos= get_bits_count(s); - int i= get_se_golomb(s); - int len= get_bits_count(s) - pos; - int bits= show>>(24-len); + int show = show_bits(s, 24); + int pos = get_bits_count(s); + int i = get_se_golomb(s); + int len = get_bits_count(s) - pos; + int bits = show >> (24 - len); print_bin(bits, len); - av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d se @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line); + av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d se @%5d in %s %s:%d\n", + bits, len, i, pos, file, func, line); return i; } -static inline int get_te(GetBitContext *s, int r, char *file, const char *func, int line){ - int show= show_bits(s, 24); - int pos= get_bits_count(s); - int i= get_te0_golomb(s, r); - int len= get_bits_count(s) - pos; - int bits= show>>(24-len); +static inline int get_te(GetBitContext *s, int r, char *file, const char *func, + int line) +{ + int show = show_bits(s, 24); + int pos = get_bits_count(s); + int i = get_te0_golomb(s, r); + int len = get_bits_count(s) - pos; + int bits = show >> (24 - len); print_bin(bits, len); - av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d te @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line); + av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d te @%5d in %s %s:%d\n", + bits, len, i, pos, file, func, line); return i; } #define get_ue_golomb(a) get_ue(a, __FILE__, __PRETTY_FUNCTION__, __LINE__) #define get_se_golomb(a) get_se(a, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#define get_te_golomb(a, r) get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__) +#define get_te_golomb(a, r) get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__) #define get_te0_golomb(a, r) get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#endif +#endif /* TRACE */ /** * write unsigned exp golomb code. */ -static inline void set_ue_golomb(PutBitContext *pb, int i){ - int e; - - av_assert2(i>=0); +static inline void set_ue_golomb(PutBitContext *pb, int i) +{ + av_assert2(i >= 0); #if 0 - if(i=0){ + if (i = 0) { put_bits(pb, 1, 1); return; } #endif - if(i<256) - put_bits(pb, ff_ue_golomb_len[i], i+1); - else{ - e= av_log2(i+1); - - put_bits(pb, 2*e+1, i+1); + if (i < 256) + put_bits(pb, ff_ue_golomb_len[i], i + 1); + else { + int e = av_log2(i + 1); + put_bits(pb, 2 * e + 1, i + 1); } } /** * write truncated unsigned exp golomb code. */ -static inline void set_te_golomb(PutBitContext *pb, int i, int range){ +static inline void set_te_golomb(PutBitContext *pb, int i, int range) +{ av_assert2(range >= 1); - av_assert2(i<=range); + av_assert2(i <= range); - if(range==2) put_bits(pb, 1, i^1); - else set_ue_golomb(pb, i); + if (range == 2) + put_bits(pb, 1, i ^ 1); + else + set_ue_golomb(pb, i); } /** * write signed exp golomb code. 16 bits at most. */ -static inline void set_se_golomb(PutBitContext *pb, int i){ +static inline void set_se_golomb(PutBitContext *pb, int i) +{ #if 0 - if(i<=0) i= -2*i; - else i= 2*i-1; + if (i <= 0) + i = -2 * i; + else + i = 2 * i - 1; #elif 1 - i= 2*i-1; - if(i<0) i^= -1; //FIXME check if gcc does the right thing + i = 2 * i - 1; + if (i < 0) + i ^= -1; //FIXME check if gcc does the right thing #else - i= 2*i-1; - i^= (i>>31); + i = 2 * i - 1; + i ^= (i >> 31); #endif set_ue_golomb(pb, i); } @@ -490,42 +519,45 @@ static inline void set_se_golomb(PutBitContext *pb, int i){ /** * write unsigned golomb rice code (ffv1). */ -static inline void set_ur_golomb(PutBitContext *pb, int i, int k, int limit, int esc_len){ +static inline void set_ur_golomb(PutBitContext *pb, int i, int k, int limit, + int esc_len) +{ int e; - av_assert2(i>=0); + av_assert2(i >= 0); - e= i>>k; - if(e> k; + if (e < limit) + put_bits(pb, e + k + 1, (1 << k) + (i & ((1 << k) - 1))); + else put_bits(pb, limit + esc_len, i - limit + 1); - } } /** * write unsigned golomb rice code (jpegls). */ -static inline void set_ur_golomb_jpegls(PutBitContext *pb, int i, int k, int limit, int esc_len){ +static inline void set_ur_golomb_jpegls(PutBitContext *pb, int i, int k, + int limit, int esc_len) +{ int e; - av_assert2(i>=0); + av_assert2(i >= 0); - e= (i>>k) + 1; - if(e 31) { + e = (i >> k) + 1; + if (e < limit) { + while (e > 31) { put_bits(pb, 31, 0); e -= 31; } put_bits(pb, e, 1); - if(k) + if (k) put_sbits(pb, k, i); - }else{ - while(limit > 31) { + } else { + while (limit > 31) { put_bits(pb, 31, 0); limit -= 31; } - put_bits(pb, limit , 1); + put_bits(pb, limit, 1); put_bits(pb, esc_len, i - 1); } } @@ -533,11 +565,13 @@ static inline void set_ur_golomb_jpegls(PutBitContext *pb, int i, int k, int lim /** * write signed golomb rice code (ffv1). */ -static inline void set_sr_golomb(PutBitContext *pb, int i, int k, int limit, int esc_len){ +static inline void set_sr_golomb(PutBitContext *pb, int i, int k, int limit, + int esc_len) +{ int v; - v = -2*i-1; - v ^= (v>>31); + v = -2 * i - 1; + v ^= (v >> 31); set_ur_golomb(pb, v, k, limit, esc_len); } @@ -545,11 +579,13 @@ static inline void set_sr_golomb(PutBitContext *pb, int i, int k, int limit, int /** * write signed golomb rice code (flac). */ -static inline void set_sr_golomb_flac(PutBitContext *pb, int i, int k, int limit, int esc_len){ +static inline void set_sr_golomb_flac(PutBitContext *pb, int i, int k, + int limit, int esc_len) +{ int v; - v = -2*i-1; - v ^= (v>>31); + v = -2 * i - 1; + v ^= (v >> 31); set_ur_golomb_jpegls(pb, v, k, limit, esc_len); } diff --git a/ffmpeg/libavcodec/gsm.h b/ffmpeg/libavcodec/gsm.h index e56f4cd..53d65c4 100644 --- a/ffmpeg/libavcodec/gsm.h +++ b/ffmpeg/libavcodec/gsm.h @@ -22,10 +22,24 @@ #define AVCODEC_GSM_H /* bytes per block */ -#define GSM_BLOCK_SIZE 33 -#define GSM_MS_BLOCK_SIZE 65 +#define GSM_BLOCK_SIZE 33 +#define GSM_MS_BLOCK_SIZE 65 +#define MSN_MIN_BLOCK_SIZE 41 /* samples per block */ #define GSM_FRAME_SIZE 160 +enum GSMModes { + GSM_13000 = 0, + MSN_12400, + MSN_11800, + MSN_11200, + MSN_10600, + MSN_10000, + MSN_9400, + MSN_8800, + MSN_8200, + NUM_GSM_MODES +}; + #endif /* AVCODEC_GSM_H */ diff --git a/ffmpeg/libavcodec/gsm_parser.c b/ffmpeg/libavcodec/gsm_parser.c index dd26f7d..9a3b94e 100644 --- a/ffmpeg/libavcodec/gsm_parser.c +++ b/ffmpeg/libavcodec/gsm_parser.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2012 Justin Ruggles * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -50,7 +50,8 @@ static int gsm_parse(AVCodecParserContext *s1, AVCodecContext *avctx, s->duration = GSM_FRAME_SIZE; break; case AV_CODEC_ID_GSM_MS: - s->block_size = GSM_MS_BLOCK_SIZE; + s->block_size = avctx->block_align ? avctx->block_align + : GSM_MS_BLOCK_SIZE; s->duration = GSM_FRAME_SIZE * 2; break; default: diff --git a/ffmpeg/libavcodec/gsmdec.c b/ffmpeg/libavcodec/gsmdec.c index dc64267..c4cde92 100644 --- a/ffmpeg/libavcodec/gsmdec.c +++ b/ffmpeg/libavcodec/gsmdec.c @@ -47,7 +47,16 @@ static av_cold int gsm_init(AVCodecContext *avctx) break; case AV_CODEC_ID_GSM_MS: avctx->frame_size = 2 * GSM_FRAME_SIZE; - avctx->block_align = GSM_MS_BLOCK_SIZE; + if (!avctx->block_align) + avctx->block_align = GSM_MS_BLOCK_SIZE; + else + if (avctx->block_align < MSN_MIN_BLOCK_SIZE || + avctx->block_align > GSM_MS_BLOCK_SIZE || + (avctx->block_align - MSN_MIN_BLOCK_SIZE) % 3) { + av_log(avctx, AV_LOG_ERROR, "Invalid block alignment %d\n", + avctx->block_align); + return AVERROR_INVALIDDATA; + } } return 0; @@ -79,12 +88,13 @@ static int gsm_decode_frame(AVCodecContext *avctx, void *data, init_get_bits(&gb, buf, buf_size * 8); if (get_bits(&gb, 4) != 0xd) av_log(avctx, AV_LOG_WARNING, "Missing GSM magic!\n"); - res = gsm_decode_block(avctx, samples, &gb); + res = gsm_decode_block(avctx, samples, &gb, GSM_13000); if (res < 0) return res; break; case AV_CODEC_ID_GSM_MS: - res = ff_msgsm_decode_block(avctx, samples, buf); + res = ff_msgsm_decode_block(avctx, samples, buf, + (GSM_MS_BLOCK_SIZE - avctx->block_align) / 3); if (res < 0) return res; } @@ -103,6 +113,7 @@ static void gsm_flush(AVCodecContext *avctx) #if CONFIG_GSM_DECODER AVCodec ff_gsm_decoder = { .name = "gsm", + .long_name = NULL_IF_CONFIG_SMALL("GSM"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_GSM, .priv_data_size = sizeof(GSMContext), @@ -110,12 +121,12 @@ AVCodec ff_gsm_decoder = { .decode = gsm_decode_frame, .flush = gsm_flush, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("GSM"), }; #endif #if CONFIG_GSM_MS_DECODER AVCodec ff_gsm_ms_decoder = { .name = "gsm_ms", + .long_name = NULL_IF_CONFIG_SMALL("GSM Microsoft variant"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_GSM_MS, .priv_data_size = sizeof(GSMContext), @@ -123,6 +134,5 @@ AVCodec ff_gsm_ms_decoder = { .decode = gsm_decode_frame, .flush = gsm_flush, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("GSM Microsoft variant"), }; #endif diff --git a/ffmpeg/libavcodec/gsmdec_data.c b/ffmpeg/libavcodec/gsmdec_data.c index 4324ea2..d90c69b 100644 --- a/ffmpeg/libavcodec/gsmdec_data.c +++ b/ffmpeg/libavcodec/gsmdec_data.c @@ -92,3 +92,29 @@ const int16_t ff_gsm_dequant_tab[64][8] = { {-26879, -19199, -11520, -3840, 3840, 11520, 19199, 26879}, {-28671, -20479, -12288, -4096, 4096, 12288, 20479, 28671} }; + +static const int apcm_bits[11][13] = { + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1 }, + { 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1 }, + { 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1 }, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, + { 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, + { 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, + { 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, + { 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, + { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 } +}; + +const int* const ff_gsm_apcm_bits[][4] = { + { apcm_bits[10], apcm_bits[10], apcm_bits[10], apcm_bits[10] }, // 13000 + { apcm_bits[10], apcm_bits[10], apcm_bits[10], apcm_bits[ 6] }, // 12400 + { apcm_bits[10], apcm_bits[10], apcm_bits[ 7], apcm_bits[ 5] }, // 11800 + { apcm_bits[10], apcm_bits[ 8], apcm_bits[ 5], apcm_bits[ 5] }, // 11200 + { apcm_bits[ 9], apcm_bits[ 5], apcm_bits[ 5], apcm_bits[ 5] }, // 10600 + { apcm_bits[ 5], apcm_bits[ 5], apcm_bits[ 5], apcm_bits[ 1] }, // 10000 + { apcm_bits[ 5], apcm_bits[ 5], apcm_bits[ 2], apcm_bits[ 0] }, // 9400 + { apcm_bits[ 5], apcm_bits[ 3], apcm_bits[ 0], apcm_bits[ 0] }, // 8800 + { apcm_bits[ 4], apcm_bits[ 0], apcm_bits[ 0], apcm_bits[ 0] }, // 8200 +}; diff --git a/ffmpeg/libavcodec/gsmdec_data.h b/ffmpeg/libavcodec/gsmdec_data.h index fd89ed6..b57194b 100644 --- a/ffmpeg/libavcodec/gsmdec_data.h +++ b/ffmpeg/libavcodec/gsmdec_data.h @@ -40,4 +40,6 @@ typedef struct GSMContext { extern const uint16_t ff_gsm_long_term_gain_tab[4]; extern const int16_t ff_gsm_dequant_tab[64][8]; +extern const int* const ff_gsm_apcm_bits[][4]; + #endif /* AVCODEC_GSMDEC_DATA_H */ diff --git a/ffmpeg/libavcodec/gsmdec_template.c b/ffmpeg/libavcodec/gsmdec_template.c index 0f55953..0c60813 100644 --- a/ffmpeg/libavcodec/gsmdec_template.c +++ b/ffmpeg/libavcodec/gsmdec_template.c @@ -28,13 +28,22 @@ #include "gsm.h" #include "gsmdec_data.h" -static void apcm_dequant_add(GetBitContext *gb, int16_t *dst) +static const int requant_tab[4][8] = { + { 0 }, + { 0, 7 }, + { 0, 2, 5, 7 }, + { 0, 1, 2, 3, 4, 5, 6, 7 } +}; + +static void apcm_dequant_add(GetBitContext *gb, int16_t *dst, const int *frame_bits) { - int i; + int i, val; int maxidx = get_bits(gb, 6); const int16_t *tab = ff_gsm_dequant_tab[maxidx]; - for (i = 0; i < 13; i++) - dst[3*i] += tab[get_bits(gb, 3)]; + for (i = 0; i < 13; i++) { + val = get_bits(gb, frame_bits[i]); + dst[3*i] += tab[requant_tab[frame_bits[i]][val]]; + } } static inline int gsm_mult(int a, int b) @@ -118,7 +127,7 @@ static int postprocess(int16_t *data, int msr) } static int gsm_decode_block(AVCodecContext *avctx, int16_t *samples, - GetBitContext *gb) + GetBitContext *gb, int mode) { GSMContext *ctx = avctx->priv_data; int i; @@ -139,7 +148,7 @@ static int gsm_decode_block(AVCodecContext *avctx, int16_t *samples, int offset = get_bits(gb, 2); lag = av_clip(lag, 40, 120); long_term_synth(ref_dst, lag, gain_idx); - apcm_dequant_add(gb, ref_dst + offset); + apcm_dequant_add(gb, ref_dst + offset, ff_gsm_apcm_bits[mode][i]); ref_dst += 40; } memcpy(ctx->ref_buf, ctx->ref_buf + 160, 120 * sizeof(*ctx->ref_buf)); diff --git a/ffmpeg/libavcodec/h261.c b/ffmpeg/libavcodec/h261.c index f89d5c7..9836905 100644 --- a/ffmpeg/libavcodec/h261.c +++ b/ffmpeg/libavcodec/h261.c @@ -28,25 +28,65 @@ #include "avcodec.h" #include "h261.h" -#define IS_FIL(a) ((a)&MB_TYPE_H261_FIL) +#define IS_FIL(a) ((a) & MB_TYPE_H261_FIL) -uint8_t ff_h261_rl_table_store[2][2*MAX_RUN + MAX_LEVEL + 3]; +uint8_t ff_h261_rl_table_store[2][2 * MAX_RUN + MAX_LEVEL + 3]; -void ff_h261_loop_filter(MpegEncContext *s){ - H261Context * h= (H261Context*)s; - const int linesize = s->linesize; - const int uvlinesize= s->uvlinesize; - uint8_t *dest_y = s->dest[0]; - uint8_t *dest_cb= s->dest[1]; - uint8_t *dest_cr= s->dest[2]; +static void h261_loop_filter(uint8_t *src, int stride) +{ + int x, y, xy, yz; + int temp[64]; - if(!(IS_FIL (h->mtype))) + for (x = 0; x < 8; x++) { + temp[x] = 4 * src[x]; + temp[x + 7 * 8] = 4 * src[x + 7 * stride]; + } + for (y = 1; y < 7; y++) { + for (x = 0; x < 8; x++) { + xy = y * stride + x; + yz = y * 8 + x; + temp[yz] = src[xy - stride] + 2 * src[xy] + src[xy + stride]; + } + } + + for (y = 0; y < 8; y++) { + src[y * stride] = (temp[y * 8] + 2) >> 2; + src[y * stride + 7] = (temp[y * 8 + 7] + 2) >> 2; + for (x = 1; x < 7; x++) { + xy = y * stride + x; + yz = y * 8 + x; + src[xy] = (temp[yz - 1] + 2 * temp[yz] + temp[yz + 1] + 8) >> 4; + } + } +} + +void ff_h261_loop_filter(MpegEncContext *s) +{ + H261Context *h = (H261Context *)s; + const int linesize = s->linesize; + const int uvlinesize = s->uvlinesize; + uint8_t *dest_y = s->dest[0]; + uint8_t *dest_cb = s->dest[1]; + uint8_t *dest_cr = s->dest[2]; + + if (!(IS_FIL(h->mtype))) + return; + + h261_loop_filter(dest_y, linesize); + h261_loop_filter(dest_y + 8, linesize); + h261_loop_filter(dest_y + 8 * linesize, linesize); + h261_loop_filter(dest_y + 8 * linesize + 8, linesize); + h261_loop_filter(dest_cb, uvlinesize); + h261_loop_filter(dest_cr, uvlinesize); +} + +av_cold void ff_h261_common_init(void) +{ + static int done = 0; + + if (done) return; - s->dsp.h261_loop_filter(dest_y , linesize); - s->dsp.h261_loop_filter(dest_y + 8, linesize); - s->dsp.h261_loop_filter(dest_y + 8 * linesize , linesize); - s->dsp.h261_loop_filter(dest_y + 8 * linesize + 8, linesize); - s->dsp.h261_loop_filter(dest_cb, uvlinesize); - s->dsp.h261_loop_filter(dest_cr, uvlinesize); + ff_init_rl(&ff_h261_rl_tcoeff, ff_h261_rl_table_store); + done = 1; } diff --git a/ffmpeg/libavcodec/h261.h b/ffmpeg/libavcodec/h261.h index 5b60dd6..5586462 100644 --- a/ffmpeg/libavcodec/h261.h +++ b/ffmpeg/libavcodec/h261.h @@ -29,23 +29,44 @@ #define AVCODEC_H261_H #include "mpegvideo.h" +#include "rl.h" /** * H261Context */ -typedef struct H261Context{ +typedef struct H261Context { MpegEncContext s; int current_mba; - int previous_mba; int mba_diff; int mtype; int current_mv_x; int current_mv_y; int gob_number; int gob_start_code_skipped; // 1 if gob start code is already read before gob header is read -}H261Context; +} H261Context; #define MB_TYPE_H261_FIL 0x800000 +extern uint8_t ff_h261_rl_table_store[2][2 * MAX_RUN + MAX_LEVEL + 3]; + +extern const uint8_t ff_h261_mba_code[35]; +extern const uint8_t ff_h261_mba_bits[35]; +extern const uint8_t ff_h261_mtype_code[10]; +extern const uint8_t ff_h261_mtype_bits[10]; +extern const int ff_h261_mtype_map[10]; +extern const uint8_t ff_h261_mv_tab[17][2]; +extern const uint8_t ff_h261_cbp_tab[63][2]; +extern RLTable ff_h261_rl_tcoeff; + +void ff_h261_loop_filter(MpegEncContext *s); +void ff_h261_common_init(void); + +int ff_h261_get_picture_format(int width, int height); +void ff_h261_reorder_mb_index(MpegEncContext *s); +void ff_h261_encode_mb(MpegEncContext *s, int16_t block[6][64], + int motion_x, int motion_y); +void ff_h261_encode_picture_header(MpegEncContext *s, int picture_number); +void ff_h261_encode_init(MpegEncContext *s); + #endif /* AVCODEC_H261_H */ diff --git a/ffmpeg/libavcodec/h261_parser.c b/ffmpeg/libavcodec/h261_parser.c index 753687a..9c31557 100644 --- a/ffmpeg/libavcodec/h261_parser.c +++ b/ffmpeg/libavcodec/h261_parser.c @@ -27,38 +27,39 @@ #include "parser.h" - -static int h261_find_frame_end(ParseContext *pc, AVCodecContext* avctx, const uint8_t *buf, int buf_size){ +static int h261_find_frame_end(ParseContext *pc, AVCodecContext *avctx, + const uint8_t *buf, int buf_size) +{ int vop_found, i, j; uint32_t state; - vop_found= pc->frame_start_found; - state= pc->state; + vop_found = pc->frame_start_found; + state = pc->state; - for(i=0; i>j)&0xFFFFF0) == 0x000100){ - vop_found=1; + for (i = 0; i < buf_size && !vop_found; i++) { + state = (state << 8) | buf[i]; + for (j = 0; j < 8; j++) { + if (((state >> j) & 0xFFFFF0) == 0x000100) { + vop_found = 1; break; } } } - if(vop_found){ - for(; i>j)&0xFFFFF0) == 0x000100){ - pc->frame_start_found=0; - pc->state= (state>>(3*8))+0xFF00; - return i-2; + if (vop_found) { + for (; i < buf_size; i++) { + state = (state << 8) | buf[i]; + for (j = 0; j < 8; j++) { + if (((state >> j) & 0xFFFFF0) == 0x000100) { + pc->frame_start_found = 0; + pc->state = (state >> (3 * 8)) + 0xFF00; + return i - 2; } } } } - pc->frame_start_found= vop_found; - pc->state= state; + pc->frame_start_found = vop_found; + pc->state = state; return END_NOT_FOUND; } @@ -73,14 +74,14 @@ static int h261_parse(AVCodecParserContext *s, if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { next = buf_size; } else { - next= h261_find_frame_end(pc,avctx, buf, buf_size); + next = h261_find_frame_end(pc, avctx, buf, buf_size); if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { - *poutbuf = NULL; + *poutbuf = NULL; *poutbuf_size = 0; return buf_size; } } - *poutbuf = buf; + *poutbuf = buf; *poutbuf_size = buf_size; return next; } diff --git a/ffmpeg/libavcodec/h261data.c b/ffmpeg/libavcodec/h261data.c index a05161f..0d1f305 100644 --- a/ffmpeg/libavcodec/h261data.c +++ b/ffmpeg/libavcodec/h261data.c @@ -25,8 +25,9 @@ */ #include + +#include "rl.h" #include "h261.h" -#include "h261data.h" // H.261 VLC table for macroblock addressing const uint8_t ff_h261_mba_code[35] = { @@ -39,8 +40,8 @@ const uint8_t ff_h261_mba_code[35] = { 32, 31, 30, 29, 28, 27, 26, 25, 24, - 15, //(MBA stuffing) - 1 //(start code) + 15, // (MBA stuffing) + 1 // (start code) }; const uint8_t ff_h261_mba_bits[35] = { @@ -53,97 +54,96 @@ const uint8_t ff_h261_mba_bits[35] = { 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, //(MBA stuffing) - 16 //(start code) + 11, // (MBA stuffing) + 16 // (start code) }; -//H.261 VLC table for macroblock type +// H.261 VLC table for macroblock type const uint8_t ff_h261_mtype_code[10] = { - 1, 1, 1, 1, - 1, 1, 1, 1, - 1, 1 + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1 }; const uint8_t ff_h261_mtype_bits[10] = { - 4, 7, 1, 5, - 9, 8, 10, 3, - 2, 6 + 4, 7, 1, 5, + 9, 8, 10, 3, + 2, 6 }; -const int ff_h261_mtype_map[10]= { - MB_TYPE_INTRA4x4, - MB_TYPE_INTRA4x4 | MB_TYPE_QUANT, - MB_TYPE_CBP, - MB_TYPE_QUANT | MB_TYPE_CBP, - MB_TYPE_16x16, - MB_TYPE_CBP | MB_TYPE_16x16, - MB_TYPE_QUANT | MB_TYPE_CBP | MB_TYPE_16x16, - MB_TYPE_16x16 | MB_TYPE_H261_FIL, - MB_TYPE_CBP | MB_TYPE_16x16 | MB_TYPE_H261_FIL, - MB_TYPE_QUANT | MB_TYPE_CBP | MB_TYPE_16x16 | MB_TYPE_H261_FIL +const int ff_h261_mtype_map[10] = { + MB_TYPE_INTRA4x4, + MB_TYPE_INTRA4x4 | MB_TYPE_QUANT, + MB_TYPE_CBP, + MB_TYPE_CBP | MB_TYPE_QUANT, + MB_TYPE_16x16, + MB_TYPE_16x16 | MB_TYPE_CBP, + MB_TYPE_16x16 | MB_TYPE_CBP | MB_TYPE_QUANT, + MB_TYPE_16x16 | MB_TYPE_H261_FIL, + MB_TYPE_16x16 | MB_TYPE_H261_FIL | MB_TYPE_CBP, + MB_TYPE_16x16 | MB_TYPE_H261_FIL | MB_TYPE_CBP | MB_TYPE_QUANT }; -//H.261 VLC table for motion vectors +// H.261 VLC table for motion vectors const uint8_t ff_h261_mv_tab[17][2] = { - {1,1}, {1,2}, {1,3}, {1,4}, {3,6}, {5,7}, {4,7}, {3,7}, - {11,9}, {10,9}, {9,9}, {17,10}, {16,10}, {15,10}, {14,10}, {13,10}, {12,10} + { 1, 1 }, { 1, 2 }, { 1, 3 }, { 1, 4 }, { 3, 6 }, { 5, 7 }, { 4, 7 }, { 3, 7 }, + { 11, 9 }, { 10, 9 }, { 9, 9 }, { 17, 10 }, { 16, 10 }, { 15, 10 }, { 14, 10 }, { 13, 10 }, { 12, 10 } }; -//H.261 VLC table for coded block pattern -const uint8_t ff_h261_cbp_tab[63][2] = -{ - {11,5}, {9,5}, {13,6}, {13,4}, {23,7}, {19,7}, {31,8}, {12,4}, - {22,7}, {18,7}, {30,8}, {19,5}, {27,8}, {23,8}, {19,8}, {11,4}, - {21,7}, {17,7}, {29,8}, {17,5}, {25,8}, {21,8}, {17,8}, {15,6}, - {15,8}, {13,8}, {3,9}, {15,5}, {11,8}, {7,8}, {7,9}, {10,4}, - {20,7}, {16,7}, {28,8}, {14,6}, {14,8}, {12,8}, {2,9}, {16,5}, - {24,8}, {20,8}, {16,8}, {14,5}, {10,8}, {6,8}, {6,9}, {18,5}, - {26,8}, {22,8}, {18,8}, {13,5}, {9,8}, {5,8}, {5,9}, {12,5}, - {8,8}, {4,8}, {4,9}, {7,3}, {10,5}, {8,5}, {12,6} +// H.261 VLC table for coded block pattern +const uint8_t ff_h261_cbp_tab[63][2] = { + { 11, 5 }, { 9, 5 }, { 13, 6 }, { 13, 4 }, { 23, 7 }, { 19, 7 }, { 31, 8 }, { 12, 4 }, + { 22, 7 }, { 18, 7 }, { 30, 8 }, { 19, 5 }, { 27, 8 }, { 23, 8 }, { 19, 8 }, { 11, 4 }, + { 21, 7 }, { 17, 7 }, { 29, 8 }, { 17, 5 }, { 25, 8 }, { 21, 8 }, { 17, 8 }, { 15, 6 }, + { 15, 8 }, { 13, 8 }, { 3, 9 }, { 15, 5 }, { 11, 8 }, { 7, 8 }, { 7, 9 }, { 10, 4 }, + { 20, 7 }, { 16, 7 }, { 28, 8 }, { 14, 6 }, { 14, 8 }, { 12, 8 }, { 2, 9 }, { 16, 5 }, + { 24, 8 }, { 20, 8 }, { 16, 8 }, { 14, 5 }, { 10, 8 }, { 6, 8 }, { 6, 9 }, { 18, 5 }, + { 26, 8 }, { 22, 8 }, { 18, 8 }, { 13, 5 }, { 9, 8 }, { 5, 8 }, { 5, 9 }, { 12, 5 }, + { 8, 8 }, { 4, 8 }, { 4, 9 }, { 7, 3 }, { 10, 5 }, { 8, 5 }, { 12, 6 } }; -//H.261 VLC table for transform coefficients +// H.261 VLC table for transform coefficients static const uint16_t h261_tcoeff_vlc[65][2] = { -{ 0x2, 2 }, { 0x3, 2 },{ 0x4, 4 },{ 0x5, 5 }, -{ 0x6, 7 },{ 0x26, 8 },{ 0x21, 8 },{ 0xa, 10 }, -{ 0x1d, 12 },{ 0x18, 12 },{ 0x13, 12 },{ 0x10 , 12 }, -{ 0x1a, 13},{ 0x19, 13 }, { 0x18, 13 }, { 0x17, 13 }, -{ 0x3, 3 }, { 0x6, 6 }, { 0x25 , 8 }, { 0xc, 10 }, -{ 0x1b, 12 }, { 0x16, 13 }, { 0x15, 13 }, { 0x5, 4}, -{ 0x4, 7}, { 0xb, 10 }, { 0x14, 12 }, { 0x14, 13 }, -{ 0x7, 5 }, { 0x24, 8 }, { 0x1c, 12 }, { 0x13, 13 }, -{ 0x6, 5 }, { 0xf, 10 }, { 0x12, 12}, { 0x7, 6}, -{ 0x9 , 10 }, { 0x12, 13 }, { 0x5, 6 }, { 0x1e, 12 }, -{ 0x4, 6 }, { 0x15, 12 }, { 0x7, 7 }, { 0x11, 12}, -{ 0x5, 7 }, { 0x11, 13 }, { 0x27, 8 }, { 0x10, 13 }, -{ 0x23, 8 }, { 0x22, 8 }, { 0x20, 8 }, { 0xe , 10 }, -{ 0xd, 10 }, { 0x8, 10 },{ 0x1f, 12 }, { 0x1a, 12 }, -{ 0x19, 12 }, { 0x17, 12 }, { 0x16, 12}, { 0x1f, 13}, -{ 0x1e, 13 }, { 0x1d, 13 }, { 0x1c, 13}, { 0x1b, 13}, -{ 0x1, 6 } //escape + { 0x2, 2 }, { 0x3, 2 }, { 0x4, 4 }, { 0x5, 5 }, + { 0x6, 7 }, { 0x26, 8 }, { 0x21, 8 }, { 0xa, 10 }, + { 0x1d, 12 }, { 0x18, 12 }, { 0x13, 12 }, { 0x10, 12 }, + { 0x1a, 13 }, { 0x19, 13 }, { 0x18, 13 }, { 0x17, 13 }, + { 0x3, 3 }, { 0x6, 6 }, { 0x25, 8 }, { 0xc, 10 }, + { 0x1b, 12 }, { 0x16, 13 }, { 0x15, 13 }, { 0x5, 4 }, + { 0x4, 7 }, { 0xb, 10 }, { 0x14, 12 }, { 0x14, 13 }, + { 0x7, 5 }, { 0x24, 8 }, { 0x1c, 12 }, { 0x13, 13 }, + { 0x6, 5 }, { 0xf, 10 }, { 0x12, 12 }, { 0x7, 6 }, + { 0x9, 10 }, { 0x12, 13 }, { 0x5, 6 }, { 0x1e, 12 }, + { 0x4, 6 }, { 0x15, 12 }, { 0x7, 7 }, { 0x11, 12 }, + { 0x5, 7 }, { 0x11, 13 }, { 0x27, 8 }, { 0x10, 13 }, + { 0x23, 8 }, { 0x22, 8 }, { 0x20, 8 }, { 0xe, 10 }, + { 0xd, 10 }, { 0x8, 10 }, { 0x1f, 12 }, { 0x1a, 12 }, + { 0x19, 12 }, { 0x17, 12 }, { 0x16, 12 }, { 0x1f, 13 }, + { 0x1e, 13 }, { 0x1d, 13 }, { 0x1c, 13 }, { 0x1b, 13 }, + { 0x1, 6 } // escape }; static const int8_t h261_tcoeff_level[64] = { - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 1, 2, 3, 4, 5, 6, 7, 1, - 2, 3, 4, 5, 1, 2, 3, 4, - 1, 2, 3, 1, 2, 3, 1, 2, - 1, 2, 1, 2, 1, 2, 1, 2, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1 + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 1, 2, 3, 4, 5, 6, 7, 1, + 2, 3, 4, 5, 1, 2, 3, 4, + 1, 2, 3, 1, 2, 3, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1 }; static const int8_t h261_tcoeff_run[64] = { - 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, - 1, 1, 1, 1, 1, 1, 2, 2, - 2, 2, 2, 3, 3, 3, 3, 4, - 4, 4, 5, 5, 5, 6, 6, 7, - 7, 8, 8, 9, 9, 10, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26 + 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 2, 2, + 2, 2, 2, 3, 3, 3, 3, 4, + 4, 4, 5, 5, 5, 6, 6, 7, + 7, 8, 8, 9, 9, 10, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26 }; RLTable ff_h261_rl_tcoeff = { diff --git a/ffmpeg/libavcodec/h261data.h b/ffmpeg/libavcodec/h261data.h deleted file mode 100644 index e9e5244..0000000 --- a/ffmpeg/libavcodec/h261data.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * copyright (c) 2002-2004 Michael Niedermayer - * copyright (c) 2004 Maarten Daniels - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.261 tables. - */ - -#ifndef AVCODEC_H261DATA_H -#define AVCODEC_H261DATA_H - -#include -#include "h261.h" - -extern const uint8_t ff_h261_mba_code[35]; -extern const uint8_t ff_h261_mba_bits[35]; -extern const uint8_t ff_h261_mtype_code[10]; -extern const uint8_t ff_h261_mtype_bits[10]; -extern const int ff_h261_mtype_map[10]; -extern const uint8_t ff_h261_mv_tab[17][2]; -extern const uint8_t ff_h261_cbp_tab[63][2]; -extern RLTable ff_h261_rl_tcoeff; - -#endif /* AVCODEC_H261DATA_H */ diff --git a/ffmpeg/libavcodec/h261dec.c b/ffmpeg/libavcodec/h261dec.c index 03770be..49f1b4a 100644 --- a/ffmpeg/libavcodec/h261dec.c +++ b/ffmpeg/libavcodec/h261dec.c @@ -30,7 +30,7 @@ #include "mpegvideo.h" #include "h263.h" #include "h261.h" -#include "h261data.h" +#include "internal.h" #define H261_MBA_VLC_BITS 9 #define H261_MTYPE_VLC_BITS 6 @@ -40,55 +40,50 @@ #define MBA_STUFFING 33 #define MBA_STARTCODE 34 -extern uint8_t ff_h261_rl_table_store[2][2*MAX_RUN + MAX_LEVEL + 3]; - static VLC h261_mba_vlc; static VLC h261_mtype_vlc; static VLC h261_mv_vlc; static VLC h261_cbp_vlc; -static int h261_decode_block(H261Context * h, int16_t * block, int n, int coded); - -static av_cold void h261_decode_init_vlc(H261Context *h){ +static av_cold void h261_decode_init_vlc(H261Context *h) +{ static int done = 0; - if(!done){ + if (!done) { done = 1; INIT_VLC_STATIC(&h261_mba_vlc, H261_MBA_VLC_BITS, 35, - ff_h261_mba_bits, 1, 1, - ff_h261_mba_code, 1, 1, 662); + ff_h261_mba_bits, 1, 1, + ff_h261_mba_code, 1, 1, 662); INIT_VLC_STATIC(&h261_mtype_vlc, H261_MTYPE_VLC_BITS, 10, - ff_h261_mtype_bits, 1, 1, - ff_h261_mtype_code, 1, 1, 80); + ff_h261_mtype_bits, 1, 1, + ff_h261_mtype_code, 1, 1, 80); INIT_VLC_STATIC(&h261_mv_vlc, H261_MV_VLC_BITS, 17, - &ff_h261_mv_tab[0][1], 2, 1, - &ff_h261_mv_tab[0][0], 2, 1, 144); + &ff_h261_mv_tab[0][1], 2, 1, + &ff_h261_mv_tab[0][0], 2, 1, 144); INIT_VLC_STATIC(&h261_cbp_vlc, H261_CBP_VLC_BITS, 63, - &ff_h261_cbp_tab[0][1], 2, 1, - &ff_h261_cbp_tab[0][0], 2, 1, 512); - ff_init_rl(&ff_h261_rl_tcoeff, ff_h261_rl_table_store); + &ff_h261_cbp_tab[0][1], 2, 1, + &ff_h261_cbp_tab[0][0], 2, 1, 512); INIT_VLC_RL(ff_h261_rl_tcoeff, 552); } } -static av_cold int h261_decode_init(AVCodecContext *avctx){ - H261Context *h= avctx->priv_data; - MpegEncContext * const s = &h->s; +static av_cold int h261_decode_init(AVCodecContext *avctx) +{ + H261Context *h = avctx->priv_data; + MpegEncContext *const s = &h->s; // set defaults ff_MPV_decode_defaults(s); - s->avctx = avctx; - - s->width = s->avctx->coded_width; - s->height = s->avctx->coded_height; - s->codec_id = s->avctx->codec->id; - - s->out_format = FMT_H261; - s->low_delay= 1; - avctx->pix_fmt= AV_PIX_FMT_YUV420P; - - s->codec_id= avctx->codec->id; - + s->avctx = avctx; + s->width = s->avctx->coded_width; + s->height = s->avctx->coded_height; + s->codec_id = s->avctx->codec->id; + s->out_format = FMT_H261; + s->low_delay = 1; + avctx->pix_fmt = AV_PIX_FMT_YUV420P; + s->codec_id = avctx->codec->id; + + ff_h261_common_init(); h261_decode_init_vlc(h); h->gob_start_code_skipped = 0; @@ -100,14 +95,15 @@ static av_cold int h261_decode_init(AVCodecContext *avctx){ * Decode the group of blocks header or slice header. * @return <0 if an error occurred */ -static int h261_decode_gob_header(H261Context *h){ +static int h261_decode_gob_header(H261Context *h) +{ unsigned int val; - MpegEncContext * const s = &h->s; + MpegEncContext *const s = &h->s; - if ( !h->gob_start_code_skipped ){ + if (!h->gob_start_code_skipped) { /* Check for GOB Start Code */ val = show_bits(&s->gb, 15); - if(val) + if (val) return -1; /* We have a GBSC */ @@ -117,34 +113,34 @@ static int h261_decode_gob_header(H261Context *h){ h->gob_start_code_skipped = 0; h->gob_number = get_bits(&s->gb, 4); /* GN */ - s->qscale = get_bits(&s->gb, 5); /* GQUANT */ + s->qscale = get_bits(&s->gb, 5); /* GQUANT */ /* Check if gob_number is valid */ - if (s->mb_height==18){ //cif - if ((h->gob_number<=0) || (h->gob_number>12)) + if (s->mb_height == 18) { // CIF + if ((h->gob_number <= 0) || (h->gob_number > 12)) return -1; - } - else{ //qcif - if ((h->gob_number!=1) && (h->gob_number!=3) && (h->gob_number!=5)) + } else { // QCIF + if ((h->gob_number != 1) && (h->gob_number != 3) && + (h->gob_number != 5)) return -1; } /* GEI */ - while (get_bits1(&s->gb) != 0) { - skip_bits(&s->gb, 8); - } + if (skip_1stop_8data_bits(&s->gb) < 0) + return AVERROR_INVALIDDATA; - if(s->qscale==0) { + if (s->qscale == 0) { av_log(s->avctx, AV_LOG_ERROR, "qscale has forbidden 0 value\n"); if (s->avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_COMPLIANT)) return -1; } - // For the first transmitted macroblock in a GOB, MBA is the absolute address. For - // subsequent macroblocks, MBA is the difference between the absolute addresses of - // the macroblock and the last transmitted macroblock. + /* For the first transmitted macroblock in a GOB, MBA is the absolute + * address. For subsequent macroblocks, MBA is the difference between + * the absolute addresses of the macroblock and the last transmitted + * macroblock. */ h->current_mba = 0; - h->mba_diff = 0; + h->mba_diff = 0; return 0; } @@ -153,35 +149,35 @@ static int h261_decode_gob_header(H261Context *h){ * Decode the group of blocks / video packet header. * @return <0 if no resync found */ -static int ff_h261_resync(H261Context *h){ - MpegEncContext * const s = &h->s; +static int h261_resync(H261Context *h) +{ + MpegEncContext *const s = &h->s; int left, ret; - if ( h->gob_start_code_skipped ){ - ret= h261_decode_gob_header(h); - if(ret>=0) + if (h->gob_start_code_skipped) { + ret = h261_decode_gob_header(h); + if (ret >= 0) return 0; - } - else{ - if(show_bits(&s->gb, 15)==0){ - ret= h261_decode_gob_header(h); - if(ret>=0) + } else { + if (show_bits(&s->gb, 15) == 0) { + ret = h261_decode_gob_header(h); + if (ret >= 0) return 0; } - //OK, it is not where it is supposed to be ... - s->gb= s->last_resync_gb; + // OK, it is not where it is supposed to be ... + s->gb = s->last_resync_gb; align_get_bits(&s->gb); - left= get_bits_left(&s->gb); + left = get_bits_left(&s->gb); - for(;left>15+1+4+5; left-=8){ - if(show_bits(&s->gb, 15)==0){ - GetBitContext bak= s->gb; + for (; left > 15 + 1 + 4 + 5; left -= 8) { + if (show_bits(&s->gb, 15) == 0) { + GetBitContext bak = s->gb; - ret= h261_decode_gob_header(h); - if(ret>=0) + ret = h261_decode_gob_header(h); + if (ret >= 0) return 0; - s->gb= bak; + s->gb = bak; } skip_bits(&s->gb, 8); } @@ -194,32 +190,32 @@ static int ff_h261_resync(H261Context *h){ * Decode skipped macroblocks. * @return 0 */ -static int h261_decode_mb_skipped(H261Context *h, int mba1, int mba2 ) +static int h261_decode_mb_skipped(H261Context *h, int mba1, int mba2) { - MpegEncContext * const s = &h->s; + MpegEncContext *const s = &h->s; int i; s->mb_intra = 0; - for(i=mba1; imb_x= ((h->gob_number-1) % 2) * 11 + i % 11; - s->mb_y= ((h->gob_number-1) / 2) * 3 + i / 11; - xy = s->mb_x + s->mb_y * s->mb_stride; + s->mb_x = ((h->gob_number - 1) % 2) * 11 + i % 11; + s->mb_y = ((h->gob_number - 1) / 2) * 3 + i / 11; + xy = s->mb_x + s->mb_y * s->mb_stride; ff_init_block_index(s); ff_update_block_index(s); - for(j=0;j<6;j++) + for (j = 0; j < 6; j++) s->block_last_index[j] = -1; - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_16X16; + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_16X16; s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; - s->mv[0][0][0] = 0; - s->mv[0][0][1] = 0; - s->mb_skipped = 1; - h->mtype &= ~MB_TYPE_H261_FIL; + s->mv[0][0][0] = 0; + s->mv[0][0][1] = 0; + s->mb_skipped = 1; + h->mtype &= ~MB_TYPE_H261_FIL; ff_MPV_decode_mb(s, s->block); } @@ -227,47 +223,140 @@ static int h261_decode_mb_skipped(H261Context *h, int mba1, int mba2 ) return 0; } -static int decode_mv_component(GetBitContext *gb, int v){ - static const int mvmap[17] = { - 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16 - }; +static const int mvmap[17] = { + 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16 +}; + +static int decode_mv_component(GetBitContext *gb, int v) +{ int mv_diff = get_vlc2(gb, h261_mv_vlc.table, H261_MV_VLC_BITS, 2); /* check if mv_diff is valid */ - if ( mv_diff < 0 ) + if (mv_diff < 0) return v; mv_diff = mvmap[mv_diff]; - if(mv_diff && !get_bits1(gb)) - mv_diff= -mv_diff; + if (mv_diff && !get_bits1(gb)) + mv_diff = -mv_diff; v += mv_diff; - if (v <=-16) v+= 32; - else if(v >= 16) v-= 32; + if (v <= -16) + v += 32; + else if (v >= 16) + v -= 32; return v; } -static int h261_decode_mb(H261Context *h){ - MpegEncContext * const s = &h->s; +/** + * Decode a macroblock. + * @return <0 if an error occurred + */ +static int h261_decode_block(H261Context *h, int16_t *block, int n, int coded) +{ + MpegEncContext *const s = &h->s; + int code, level, i, j, run; + RLTable *rl = &ff_h261_rl_tcoeff; + const uint8_t *scan_table; + + /* For the variable length encoding there are two code tables, one being + * used for the first transmitted LEVEL in INTER, INTER + MC and + * INTER + MC + FIL blocks, the second for all other LEVELs except the + * first one in INTRA blocks which is fixed length coded with 8 bits. + * NOTE: The two code tables only differ in one VLC so we handle that + * manually. */ + scan_table = s->intra_scantable.permutated; + if (s->mb_intra) { + /* DC coef */ + level = get_bits(&s->gb, 8); + // 0 (00000000b) and -128 (10000000b) are FORBIDDEN + if ((level & 0x7F) == 0) { + av_log(s->avctx, AV_LOG_ERROR, "illegal dc %d at %d %d\n", + level, s->mb_x, s->mb_y); + return -1; + } + /* The code 1000 0000 is not used, the reconstruction level of 1024 + * being coded as 1111 1111. */ + if (level == 255) + level = 128; + block[0] = level; + i = 1; + } else if (coded) { + // Run Level Code + // EOB Not possible for first level when cbp is available (that's why the table is different) + // 0 1 1s + // * * 0* + int check = show_bits(&s->gb, 2); + i = 0; + if (check & 0x2) { + skip_bits(&s->gb, 2); + block[0] = (check & 0x1) ? -1 : 1; + i = 1; + } + } else { + i = 0; + } + if (!coded) { + s->block_last_index[n] = i - 1; + return 0; + } + for (;;) { + code = get_vlc2(&s->gb, rl->vlc.table, TCOEFF_VLC_BITS, 2); + if (code < 0) { + av_log(s->avctx, AV_LOG_ERROR, "illegal ac vlc code at %dx%d\n", + s->mb_x, s->mb_y); + return -1; + } + if (code == rl->n) { + /* escape */ + /* The remaining combinations of (run, level) are encoded with a + * 20-bit word consisting of 6 bits escape, 6 bits run and 8 bits + * level. */ + run = get_bits(&s->gb, 6); + level = get_sbits(&s->gb, 8); + } else if (code == 0) { + break; + } else { + run = rl->table_run[code]; + level = rl->table_level[code]; + if (get_bits1(&s->gb)) + level = -level; + } + i += run; + if (i >= 64) { + av_log(s->avctx, AV_LOG_ERROR, "run overflow at %dx%d\n", + s->mb_x, s->mb_y); + return -1; + } + j = scan_table[i]; + block[j] = level; + i++; + } + s->block_last_index[n] = i - 1; + return 0; +} + +static int h261_decode_mb(H261Context *h) +{ + MpegEncContext *const s = &h->s; int i, cbp, xy; cbp = 63; // Read mba - do{ - h->mba_diff = get_vlc2(&s->gb, h261_mba_vlc.table, H261_MBA_VLC_BITS, 2); + do { + h->mba_diff = get_vlc2(&s->gb, h261_mba_vlc.table, + H261_MBA_VLC_BITS, 2); /* Check for slice end */ /* NOTE: GOB can be empty (no MB data) or exist only of MBA_stuffing */ - if (h->mba_diff == MBA_STARTCODE){ // start code + if (h->mba_diff == MBA_STARTCODE) { // start code h->gob_start_code_skipped = 1; return SLICE_END; } - } - while( h->mba_diff == MBA_STUFFING ); // stuffing + } while (h->mba_diff == MBA_STUFFING); // stuffing - if ( h->mba_diff < 0 ){ + if (h->mba_diff < 0) { if (get_bits_left(&s->gb) <= 7) return SLICE_END; @@ -275,85 +364,85 @@ static int h261_decode_mb(H261Context *h){ return SLICE_ERROR; } - h->mba_diff += 1; + h->mba_diff += 1; h->current_mba += h->mba_diff; - if ( h->current_mba > MBA_STUFFING ) + if (h->current_mba > MBA_STUFFING) return SLICE_ERROR; - s->mb_x= ((h->gob_number-1) % 2) * 11 + ((h->current_mba-1) % 11); - s->mb_y= ((h->gob_number-1) / 2) * 3 + ((h->current_mba-1) / 11); - xy = s->mb_x + s->mb_y * s->mb_stride; + s->mb_x = ((h->gob_number - 1) % 2) * 11 + ((h->current_mba - 1) % 11); + s->mb_y = ((h->gob_number - 1) / 2) * 3 + ((h->current_mba - 1) / 11); + xy = s->mb_x + s->mb_y * s->mb_stride; ff_init_block_index(s); ff_update_block_index(s); // Read mtype h->mtype = get_vlc2(&s->gb, h261_mtype_vlc.table, H261_MTYPE_VLC_BITS, 2); if (h->mtype < 0) { - av_log(s->avctx, AV_LOG_ERROR, "illegal mtype %d\n", h->mtype); + av_log(s->avctx, AV_LOG_ERROR, "Invalid mtype index %d\n", + h->mtype); return SLICE_ERROR; } + av_assert0(h->mtype < FF_ARRAY_ELEMS(ff_h261_mtype_map)); h->mtype = ff_h261_mtype_map[h->mtype]; // Read mquant - if ( IS_QUANT ( h->mtype ) ){ + if (IS_QUANT(h->mtype)) ff_set_qscale(s, get_bits(&s->gb, 5)); - } s->mb_intra = IS_INTRA4x4(h->mtype); // Read mv - if ( IS_16X16 ( h->mtype ) ){ - // Motion vector data is included for all MC macroblocks. MVD is obtained from the macroblock vector by subtracting the - // vector of the preceding macroblock. For this calculation the vector of the preceding macroblock is regarded as zero in the - // following three situations: - // 1) evaluating MVD for macroblocks 1, 12 and 23; - // 2) evaluating MVD for macroblocks in which MBA does not represent a difference of 1; - // 3) MTYPE of the previous macroblock was not MC. - if ( ( h->current_mba == 1 ) || ( h->current_mba == 12 ) || ( h->current_mba == 23 ) || - ( h->mba_diff != 1)) - { + if (IS_16X16(h->mtype)) { + /* Motion vector data is included for all MC macroblocks. MVD is + * obtained from the macroblock vector by subtracting the vector + * of the preceding macroblock. For this calculation the vector + * of the preceding macroblock is regarded as zero in the + * following three situations: + * 1) evaluating MVD for macroblocks 1, 12 and 23; + * 2) evaluating MVD for macroblocks in which MBA does not represent a difference of 1; + * 3) MTYPE of the previous macroblock was not MC. */ + if ((h->current_mba == 1) || (h->current_mba == 12) || + (h->current_mba == 23) || (h->mba_diff != 1)) { h->current_mv_x = 0; h->current_mv_y = 0; } - h->current_mv_x= decode_mv_component(&s->gb, h->current_mv_x); - h->current_mv_y= decode_mv_component(&s->gb, h->current_mv_y); - }else{ + h->current_mv_x = decode_mv_component(&s->gb, h->current_mv_x); + h->current_mv_y = decode_mv_component(&s->gb, h->current_mv_y); + } else { h->current_mv_x = 0; h->current_mv_y = 0; } // Read cbp - if ( HAS_CBP( h->mtype ) ){ + if (HAS_CBP(h->mtype)) cbp = get_vlc2(&s->gb, h261_cbp_vlc.table, H261_CBP_VLC_BITS, 2) + 1; - } - if(s->mb_intra){ + if (s->mb_intra) { s->current_picture.mb_type[xy] = MB_TYPE_INTRA; goto intra; } //set motion vectors - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_16X16; + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_16X16; s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0; - s->mv[0][0][0] = h->current_mv_x * 2;//gets divided by 2 in motion compensation - s->mv[0][0][1] = h->current_mv_y * 2; + s->mv[0][0][0] = h->current_mv_x * 2; // gets divided by 2 in motion compensation + s->mv[0][0][1] = h->current_mv_y * 2; intra: /* decode each block */ - if(s->mb_intra || HAS_CBP(h->mtype)){ + if (s->mb_intra || HAS_CBP(h->mtype)) { s->dsp.clear_blocks(s->block[0]); for (i = 0; i < 6; i++) { - if (h261_decode_block(h, s->block[i], i, cbp&32) < 0){ + if (h261_decode_block(h, s->block[i], i, cbp & 32) < 0) return SLICE_ERROR; - } - cbp+=cbp; + cbp += cbp; } - }else{ + } else { for (i = 0; i < 6; i++) - s->block_last_index[i]= -1; + s->block_last_index[i] = -1; } ff_MPV_decode_mb(s, s->block); @@ -361,118 +450,35 @@ intra: return SLICE_OK; } -/** - * Decode a macroblock. - * @return <0 if an error occurred - */ -static int h261_decode_block(H261Context * h, int16_t * block, - int n, int coded) -{ - MpegEncContext * const s = &h->s; - int code, level, i, j, run; - RLTable *rl = &ff_h261_rl_tcoeff; - const uint8_t *scan_table; - - // For the variable length encoding there are two code tables, one being used for - // the first transmitted LEVEL in INTER, INTER+MC and INTER+MC+FIL blocks, the second - // for all other LEVELs except the first one in INTRA blocks which is fixed length - // coded with 8 bits. - // NOTE: the two code tables only differ in one VLC so we handle that manually. - scan_table = s->intra_scantable.permutated; - if (s->mb_intra){ - /* DC coef */ - level = get_bits(&s->gb, 8); - // 0 (00000000b) and -128 (10000000b) are FORBIDDEN - if((level&0x7F) == 0){ - av_log(s->avctx, AV_LOG_ERROR, "illegal dc %d at %d %d\n", level, s->mb_x, s->mb_y); - return -1; - } - // The code 1000 0000 is not used, the reconstruction level of 1024 being coded as 1111 1111. - if (level == 255) - level = 128; - block[0] = level; - i = 1; - }else if(coded){ - // Run Level Code - // EOB Not possible for first level when cbp is available (that's why the table is different) - // 0 1 1s - // * * 0* - int check = show_bits(&s->gb, 2); - i = 0; - if ( check & 0x2 ){ - skip_bits(&s->gb, 2); - block[0] = ( check & 0x1 ) ? -1 : 1; - i = 1; - } - }else{ - i = 0; - } - if(!coded){ - s->block_last_index[n] = i - 1; - return 0; - } - for(;;){ - code = get_vlc2(&s->gb, rl->vlc.table, TCOEFF_VLC_BITS, 2); - if (code < 0){ - av_log(s->avctx, AV_LOG_ERROR, "illegal ac vlc code at %dx%d\n", s->mb_x, s->mb_y); - return -1; - } - if (code == rl->n) { - /* escape */ - // The remaining combinations of (run, level) are encoded with a 20-bit word consisting of 6 bits escape, 6 bits run and 8 bits level. - run = get_bits(&s->gb, 6); - level = get_sbits(&s->gb, 8); - }else if(code == 0){ - break; - }else{ - run = rl->table_run[code]; - level = rl->table_level[code]; - if (get_bits1(&s->gb)) - level = -level; - } - i += run; - if (i >= 64){ - av_log(s->avctx, AV_LOG_ERROR, "run overflow at %dx%d\n", s->mb_x, s->mb_y); - return -1; - } - j = scan_table[i]; - block[j] = level; - i++; - } - s->block_last_index[n] = i-1; - return 0; -} - /** * Decode the H.261 picture header. * @return <0 if no startcode found */ -static int h261_decode_picture_header(H261Context *h){ - MpegEncContext * const s = &h->s; +static int h261_decode_picture_header(H261Context *h) +{ + MpegEncContext *const s = &h->s; int format, i; - uint32_t startcode= 0; + uint32_t startcode = 0; - for(i= get_bits_left(&s->gb); i>24; i-=1){ + for (i = get_bits_left(&s->gb); i > 24; i -= 1) { startcode = ((startcode << 1) | get_bits(&s->gb, 1)) & 0x000FFFFF; - if(startcode == 0x10) + if (startcode == 0x10) break; } - if (startcode != 0x10){ + if (startcode != 0x10) { av_log(s->avctx, AV_LOG_ERROR, "Bad picture start code\n"); return -1; } /* temporal reference */ - i= get_bits(&s->gb, 5); /* picture timestamp */ - if(i < (s->picture_number&31)) + i = get_bits(&s->gb, 5); /* picture timestamp */ + if (i < (s->picture_number & 31)) i += 32; - s->picture_number = (s->picture_number&~31) + i; - - s->avctx->time_base= (AVRational){1001, 30000}; - s->current_picture.f.pts = s->picture_number; + s->picture_number = (s->picture_number & ~31) + i; + s->avctx->time_base = (AVRational) { 1001, 30000 }; /* PTYPE starts here */ skip_bits1(&s->gb); /* split screen off */ @@ -481,16 +487,16 @@ static int h261_decode_picture_header(H261Context *h){ format = get_bits1(&s->gb); - //only 2 formats possible - if (format == 0){//QCIF - s->width = 176; - s->height = 144; - s->mb_width = 11; + // only 2 formats possible + if (format == 0) { // QCIF + s->width = 176; + s->height = 144; + s->mb_width = 11; s->mb_height = 9; - }else{//CIF - s->width = 352; - s->height = 288; - s->mb_width = 22; + } else { // CIF + s->width = 352; + s->height = 288; + s->mb_width = 22; s->mb_height = 18; } @@ -500,39 +506,42 @@ static int h261_decode_picture_header(H261Context *h){ skip_bits1(&s->gb); /* Reserved */ /* PEI */ - while (get_bits1(&s->gb) != 0){ - skip_bits(&s->gb, 8); - } + if (skip_1stop_8data_bits(&s->gb) < 0) + return AVERROR_INVALIDDATA; - // h261 has no I-FRAMES, but if we pass AV_PICTURE_TYPE_I for the first frame, the codec crashes if it does - // not contain all I-blocks (e.g. when a packet is lost) + /* H.261 has no I-frames, but if we pass AV_PICTURE_TYPE_I for the first + * frame, the codec crashes if it does not contain all I-blocks + * (e.g. when a packet is lost). */ s->pict_type = AV_PICTURE_TYPE_P; h->gob_number = 0; return 0; } -static int h261_decode_gob(H261Context *h){ - MpegEncContext * const s = &h->s; +static int h261_decode_gob(H261Context *h) +{ + MpegEncContext *const s = &h->s; ff_set_qscale(s, s->qscale); /* decode mb's */ - while(h->current_mba <= MBA_STUFFING) - { + while (h->current_mba <= MBA_STUFFING) { int ret; /* DCT & quantize */ - ret= h261_decode_mb(h); - if(ret<0){ - if(ret==SLICE_END){ + ret = h261_decode_mb(h); + if (ret < 0) { + if (ret == SLICE_END) { h261_decode_mb_skipped(h, h->current_mba, 33); return 0; } - av_log(s->avctx, AV_LOG_ERROR, "Error at MB: %d\n", s->mb_x + s->mb_y*s->mb_stride); + av_log(s->avctx, AV_LOG_ERROR, "Error at MB: %d\n", + s->mb_x + s->mb_y * s->mb_stride); return -1; } - h261_decode_mb_skipped(h, h->current_mba-h->mba_diff, h->current_mba-1); + h261_decode_mb_skipped(h, + h->current_mba - h->mba_diff, + h->current_mba - 1); } return -1; @@ -541,65 +550,60 @@ static int h261_decode_gob(H261Context *h){ /** * returns the number of bytes consumed for building the current frame */ -static int get_consumed_bytes(MpegEncContext *s, int buf_size){ - int pos= get_bits_count(&s->gb)>>3; - if(pos==0) pos=1; //avoid infinite loops (i doubt that is needed but ...) - if(pos+10>buf_size) pos=buf_size; // oops ;) +static int get_consumed_bytes(MpegEncContext *s, int buf_size) +{ + int pos = get_bits_count(&s->gb) >> 3; + if (pos == 0) + pos = 1; // avoid infinite loops (i doubt that is needed but ...) + if (pos + 10 > buf_size) + pos = buf_size; // oops ;) return pos; } -static int h261_decode_frame(AVCodecContext *avctx, - void *data, int *got_frame, - AVPacket *avpkt) +static int h261_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - H261Context *h= avctx->priv_data; - MpegEncContext *s = &h->s; + int buf_size = avpkt->size; + H261Context *h = avctx->priv_data; + MpegEncContext *s = &h->s; int ret; AVFrame *pict = data; av_dlog(avctx, "*****frame %d size=%d\n", avctx->frame_number, buf_size); av_dlog(avctx, "bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]); - s->flags= avctx->flags; - s->flags2= avctx->flags2; + s->flags = avctx->flags; + s->flags2 = avctx->flags2; - h->gob_start_code_skipped=0; + h->gob_start_code_skipped = 0; retry: + init_get_bits(&s->gb, buf, buf_size * 8); - init_get_bits(&s->gb, buf, buf_size*8); - - if(!s->context_initialized){ - if (ff_MPV_common_init(s) < 0) //we need the idct permutaton for reading a custom matrix + if (!s->context_initialized) + // we need the IDCT permutaton for reading a custom matrix + if (ff_MPV_common_init(s) < 0) return -1; - } - - //we need to set current_picture_ptr before reading the header, otherwise we cannot store anyting im there - if (s->current_picture_ptr == NULL || s->current_picture_ptr->f.data[0]) { - int i= ff_find_unused_picture(s, 0); - if (i < 0) - return i; - s->current_picture_ptr= &s->picture[i]; - } ret = h261_decode_picture_header(h); /* skip if the header was thrashed */ - if (ret < 0){ + if (ret < 0) { av_log(s->avctx, AV_LOG_ERROR, "header damaged\n"); return -1; } - if (s->width != avctx->coded_width || s->height != avctx->coded_height){ - ParseContext pc= s->parse_context; //FIXME move this demuxing hack to libavformat - s->parse_context.buffer=0; + if (s->width != avctx->coded_width || s->height != avctx->coded_height) { + ParseContext pc = s->parse_context; // FIXME move this demuxing hack to libavformat + s->parse_context.buffer = 0; ff_MPV_common_end(s); - s->parse_context= pc; + s->parse_context = pc; } if (!s->context_initialized) { - avcodec_set_dimensions(avctx, s->width, s->height); + ret = ff_set_dimensions(avctx, s->width, s->height); + if (ret < 0) + return ret; goto retry; } @@ -608,22 +612,22 @@ retry: s->current_picture.f.pict_type = s->pict_type; s->current_picture.f.key_frame = s->pict_type == AV_PICTURE_TYPE_I; - if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==AV_PICTURE_TYPE_B) - ||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=AV_PICTURE_TYPE_I) - || avctx->skip_frame >= AVDISCARD_ALL) + if ((avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type == AV_PICTURE_TYPE_B) || + (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type != AV_PICTURE_TYPE_I) || + avctx->skip_frame >= AVDISCARD_ALL) return get_consumed_bytes(s, buf_size); - if(ff_MPV_frame_start(s, avctx) < 0) + if (ff_MPV_frame_start(s, avctx) < 0) return -1; ff_mpeg_er_frame_start(s); /* decode each macroblock */ - s->mb_x=0; - s->mb_y=0; + s->mb_x = 0; + s->mb_y = 0; - while(h->gob_number < (s->mb_height==18 ? 12 : 5)){ - if(ff_h261_resync(h)<0) + while (h->gob_number < (s->mb_height == 18 ? 12 : 5)) { + if (h261_resync(h) < 0) break; h261_decode_gob(h); } @@ -643,7 +647,7 @@ retry: static av_cold int h261_decode_end(AVCodecContext *avctx) { - H261Context *h= avctx->priv_data; + H261Context *h = avctx->priv_data; MpegEncContext *s = &h->s; ff_MPV_common_end(s); @@ -652,6 +656,7 @@ static av_cold int h261_decode_end(AVCodecContext *avctx) AVCodec ff_h261_decoder = { .name = "h261", + .long_name = NULL_IF_CONFIG_SMALL("H.261"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H261, .priv_data_size = sizeof(H261Context), @@ -660,5 +665,4 @@ AVCodec ff_h261_decoder = { .decode = h261_decode_frame, .capabilities = CODEC_CAP_DR1, .max_lowres = 3, - .long_name = NULL_IF_CONFIG_SMALL("H.261"), }; diff --git a/ffmpeg/libavcodec/h261enc.c b/ffmpeg/libavcodec/h261enc.c index c22100c..e185f5e 100644 --- a/ffmpeg/libavcodec/h261enc.c +++ b/ffmpeg/libavcodec/h261enc.c @@ -25,19 +25,18 @@ * H.261 encoder. */ +#include "libavutil/attributes.h" #include "libavutil/avassert.h" #include "avcodec.h" #include "mpegvideo.h" #include "h263.h" #include "h261.h" -#include "h261data.h" -extern uint8_t ff_h261_rl_table_store[2][2*MAX_RUN + MAX_LEVEL + 3]; +static uint8_t uni_h261_rl_len [64*64*2*2]; +#define UNI_ENC_INDEX(last,run,level) ((last)*128*64 + (run)*128 + (level)) -static void h261_encode_block(H261Context * h, int16_t * block, - int n); - -int ff_h261_get_picture_format(int width, int height){ +int ff_h261_get_picture_format(int width, int height) +{ // QCIF if (width == 176 && height == 144) return 0; @@ -49,8 +48,9 @@ int ff_h261_get_picture_format(int width, int height){ return -1; } -void ff_h261_encode_picture_header(MpegEncContext * s, int picture_number){ - H261Context * h = (H261Context *) s; +void ff_h261_encode_picture_header(MpegEncContext *s, int picture_number) +{ + H261Context *h = (H261Context *)s; int format, temp_ref; avpriv_align_put_bits(&s->pb); @@ -60,8 +60,8 @@ void ff_h261_encode_picture_header(MpegEncContext * s, int picture_number){ put_bits(&s->pb, 20, 0x10); /* PSC */ - temp_ref= s->picture_number * (int64_t)30000 * s->avctx->time_base.num / - (1001 * (int64_t)s->avctx->time_base.den); //FIXME maybe this should use a timestamp + temp_ref = s->picture_number * (int64_t)30000 * s->avctx->time_base.num / + (1001 * (int64_t)s->avctx->time_base.den); // FIXME maybe this should use a timestamp put_sbits(&s->pb, 5, temp_ref); /* TemporalReference */ put_bits(&s->pb, 1, 0); /* split screen off */ @@ -76,187 +76,97 @@ void ff_h261_encode_picture_header(MpegEncContext * s, int picture_number){ put_bits(&s->pb, 1, 0); /* reserved */ put_bits(&s->pb, 1, 0); /* no PEI */ - if(format == 0) + if (format == 0) h->gob_number = -1; else h->gob_number = 0; - h->current_mba = 0; + s->mb_skip_run = 0; } /** * Encode a group of blocks header. */ -static void h261_encode_gob_header(MpegEncContext * s, int mb_line){ - H261Context * h = (H261Context *)s; - if(ff_h261_get_picture_format(s->width, s->height) == 0){ - h->gob_number+=2; // QCIF - } - else{ - h->gob_number++; // CIF +static void h261_encode_gob_header(MpegEncContext *s, int mb_line) +{ + H261Context *h = (H261Context *)s; + if (ff_h261_get_picture_format(s->width, s->height) == 0) { + h->gob_number += 2; // QCIF + } else { + h->gob_number++; // CIF } - put_bits(&s->pb, 16, 1); /* GBSC */ + put_bits(&s->pb, 16, 1); /* GBSC */ put_bits(&s->pb, 4, h->gob_number); /* GN */ - put_bits(&s->pb, 5, s->qscale); /* GQUANT */ - put_bits(&s->pb, 1, 0); /* no GEI */ - h->current_mba = 0; - h->previous_mba = 0; - h->current_mv_x=0; - h->current_mv_y=0; + put_bits(&s->pb, 5, s->qscale); /* GQUANT */ + put_bits(&s->pb, 1, 0); /* no GEI */ + s->mb_skip_run = 0; + s->last_mv[0][0][0] = 0; + s->last_mv[0][0][1] = 0; } -void ff_h261_reorder_mb_index(MpegEncContext* s){ - int index= s->mb_x + s->mb_y*s->mb_width; +void ff_h261_reorder_mb_index(MpegEncContext *s) +{ + int index = s->mb_x + s->mb_y * s->mb_width; - if(index % 33 == 0) - h261_encode_gob_header(s,0); + if (index % 11 == 0) { + if (index % 33 == 0) + h261_encode_gob_header(s, 0); + s->last_mv[0][0][0] = 0; + s->last_mv[0][0][1] = 0; + } /* for CIF the GOB's are fragmented in the middle of a scanline - that's why we need to adjust the x and y index of the macroblocks */ - if(ff_h261_get_picture_format(s->width,s->height) == 1){ // CIF - s->mb_x = index % 11 ; index /= 11; - s->mb_y = index % 3 ; index /= 3; - s->mb_x+= 11*(index % 2); index /= 2; - s->mb_y+= 3*index; + * that's why we need to adjust the x and y index of the macroblocks */ + if (ff_h261_get_picture_format(s->width, s->height) == 1) { // CIF + s->mb_x = index % 11; + index /= 11; + s->mb_y = index % 3; + index /= 3; + s->mb_x += 11 * (index % 2); + index /= 2; + s->mb_y += 3 * index; ff_init_block_index(s); ff_update_block_index(s); } } -static void h261_encode_motion(H261Context * h, int val){ - MpegEncContext * const s = &h->s; +static void h261_encode_motion(H261Context *h, int val) +{ + MpegEncContext *const s = &h->s; int sign, code; - if(val==0){ + if (val == 0) { code = 0; - put_bits(&s->pb,ff_h261_mv_tab[code][1],ff_h261_mv_tab[code][0]); - } - else{ - if(val > 15) - val -=32; - if(val < -16) - val+=32; + put_bits(&s->pb, ff_h261_mv_tab[code][1], ff_h261_mv_tab[code][0]); + } else { + if (val > 15) + val -= 32; + if (val < -16) + val += 32; sign = val < 0; code = sign ? -val : val; - put_bits(&s->pb,ff_h261_mv_tab[code][1],ff_h261_mv_tab[code][0]); - put_bits(&s->pb,1,sign); + put_bits(&s->pb, ff_h261_mv_tab[code][1], ff_h261_mv_tab[code][0]); + put_bits(&s->pb, 1, sign); } } -static inline int get_cbp(MpegEncContext * s, - int16_t block[6][64]) +static inline int get_cbp(MpegEncContext *s, int16_t block[6][64]) { int i, cbp; - cbp= 0; - for (i = 0; i < 6; i++) { + cbp = 0; + for (i = 0; i < 6; i++) if (s->block_last_index[i] >= 0) cbp |= 1 << (5 - i); - } return cbp; } -void ff_h261_encode_mb(MpegEncContext * s, - int16_t block[6][64], - int motion_x, int motion_y) -{ - H261Context * h = (H261Context *)s; - int mvd, mv_diff_x, mv_diff_y, i, cbp; - cbp = 63; // avoid warning - mvd = 0; - - h->current_mba++; - h->mtype = 0; - - if (!s->mb_intra){ - /* compute cbp */ - cbp= get_cbp(s, block); - - /* mvd indicates if this block is motion compensated */ - mvd = motion_x | motion_y; - - if((cbp | mvd | s->dquant ) == 0) { - /* skip macroblock */ - s->skip_count++; - h->current_mv_x=0; - h->current_mv_y=0; - return; - } - } - - /* MB is not skipped, encode MBA */ - put_bits(&s->pb, ff_h261_mba_bits[(h->current_mba-h->previous_mba)-1], ff_h261_mba_code[(h->current_mba-h->previous_mba)-1]); - - /* calculate MTYPE */ - if(!s->mb_intra){ - h->mtype++; - - if(mvd || s->loop_filter) - h->mtype+=3; - if(s->loop_filter) - h->mtype+=3; - if(cbp || s->dquant) - h->mtype++; - av_assert1(h->mtype > 1); - } - - if(s->dquant) - h->mtype++; - - put_bits(&s->pb, ff_h261_mtype_bits[h->mtype], ff_h261_mtype_code[h->mtype]); - - h->mtype = ff_h261_mtype_map[h->mtype]; - - if(IS_QUANT(h->mtype)){ - ff_set_qscale(s,s->qscale+s->dquant); - put_bits(&s->pb, 5, s->qscale); - } - - if(IS_16X16(h->mtype)){ - mv_diff_x = (motion_x >> 1) - h->current_mv_x; - mv_diff_y = (motion_y >> 1) - h->current_mv_y; - h->current_mv_x = (motion_x >> 1); - h->current_mv_y = (motion_y >> 1); - h261_encode_motion(h,mv_diff_x); - h261_encode_motion(h,mv_diff_y); - } - - h->previous_mba = h->current_mba; - - if(HAS_CBP(h->mtype)){ - av_assert1(cbp>0); - put_bits(&s->pb,ff_h261_cbp_tab[cbp-1][1],ff_h261_cbp_tab[cbp-1][0]); - } - for(i=0; i<6; i++) { - /* encode each block */ - h261_encode_block(h, block[i], i); - } - - if ( ( h->current_mba == 11 ) || ( h->current_mba == 22 ) || ( h->current_mba == 33 ) || ( !IS_16X16 ( h->mtype ) )){ - h->current_mv_x=0; - h->current_mv_y=0; - } -} - -void ff_h261_encode_init(MpegEncContext *s){ - static int done = 0; - - if (!done) { - done = 1; - ff_init_rl(&ff_h261_rl_tcoeff, ff_h261_rl_table_store); - } - - s->min_qcoeff= -127; - s->max_qcoeff= 127; - s->y_dc_scale_table= - s->c_dc_scale_table= ff_mpeg1_dc_scale_table; -} - /** * Encode an 8x8 block. * @param block the 8x8 block * @param n block index (0-3 are luma, 4-5 are chroma) */ -static void h261_encode_block(H261Context * h, int16_t * block, int n){ - MpegEncContext * const s = &h->s; +static void h261_encode_block(H261Context *h, int16_t *block, int n) +{ + MpegEncContext *const s = &h->s; int level, run, i, j, last_index, last_non_zero, sign, slevel, code; RLTable *rl; @@ -266,12 +176,12 @@ static void h261_encode_block(H261Context * h, int16_t * block, int n){ level = block[0]; /* 255 cannot be represented, so we clamp */ if (level > 254) { - level = 254; + level = 254; block[0] = 254; } /* 0 cannot be represented also */ else if (level < 1) { - level = 1; + level = 1; block[0] = 1; } if (level == 128) @@ -279,31 +189,33 @@ static void h261_encode_block(H261Context * h, int16_t * block, int n){ else put_bits(&s->pb, 8, level); i = 1; - } else if((block[0]==1 || block[0] == -1) && (s->block_last_index[n] > -1)){ - //special case - put_bits(&s->pb,2,block[0]>0 ? 2 : 3 ); + } else if ((block[0] == 1 || block[0] == -1) && + (s->block_last_index[n] > -1)) { + // special case + put_bits(&s->pb, 2, block[0] > 0 ? 2 : 3); i = 1; } else { i = 0; } /* AC coefs */ - last_index = s->block_last_index[n]; + last_index = s->block_last_index[n]; last_non_zero = i - 1; for (; i <= last_index; i++) { - j = s->intra_scantable.permutated[i]; + j = s->intra_scantable.permutated[i]; level = block[j]; if (level) { - run = i - last_non_zero - 1; - sign = 0; + run = i - last_non_zero - 1; + sign = 0; slevel = level; if (level < 0) { - sign = 1; + sign = 1; level = -level; } - code = get_rl_index(rl, 0 /*no last in H.261, EOB is used*/, run, level); - if(run==0 && level < 16) - code+=1; + code = get_rl_index(rl, 0 /*no last in H.261, EOB is used*/, + run, level); + if (run == 0 && level < 16) + code += 1; put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); if (code == rl->n) { put_bits(&s->pb, 6, run); @@ -316,22 +228,163 @@ static void h261_encode_block(H261Context * h, int16_t * block, int n){ last_non_zero = i; } } - if(last_index > -1){ - put_bits(&s->pb, rl->table_vlc[0][1], rl->table_vlc[0][0]);// END OF BLOCK + if (last_index > -1) + put_bits(&s->pb, rl->table_vlc[0][1], rl->table_vlc[0][0]); // EOB +} + +void ff_h261_encode_mb(MpegEncContext *s, int16_t block[6][64], + int motion_x, int motion_y) +{ + H261Context *h = (H261Context *)s; + int mvd, mv_diff_x, mv_diff_y, i, cbp; + cbp = 63; // avoid warning + mvd = 0; + + h->mtype = 0; + + if (!s->mb_intra) { + /* compute cbp */ + cbp = get_cbp(s, block); + + /* mvd indicates if this block is motion compensated */ + mvd = motion_x | motion_y; + + if ((cbp | mvd | s->dquant) == 0) { + /* skip macroblock */ + s->skip_count++; + s->mb_skip_run++; + s->last_mv[0][0][0] = 0; + s->last_mv[0][0][1] = 0; + return; + } + } + + /* MB is not skipped, encode MBA */ + put_bits(&s->pb, + ff_h261_mba_bits[s->mb_skip_run], + ff_h261_mba_code[s->mb_skip_run]); + s->mb_skip_run = 0; + + /* calculate MTYPE */ + if (!s->mb_intra) { + h->mtype++; + + if (mvd || s->loop_filter) + h->mtype += 3; + if (s->loop_filter) + h->mtype += 3; + if (cbp || s->dquant) + h->mtype++; + av_assert1(h->mtype > 1); + } + + if (s->dquant) + h->mtype++; + + put_bits(&s->pb, + ff_h261_mtype_bits[h->mtype], + ff_h261_mtype_code[h->mtype]); + + h->mtype = ff_h261_mtype_map[h->mtype]; + + if (IS_QUANT(h->mtype)) { + ff_set_qscale(s, s->qscale + s->dquant); + put_bits(&s->pb, 5, s->qscale); + } + + if (IS_16X16(h->mtype)) { + mv_diff_x = (motion_x >> 1) - s->last_mv[0][0][0]; + mv_diff_y = (motion_y >> 1) - s->last_mv[0][0][1]; + s->last_mv[0][0][0] = (motion_x >> 1); + s->last_mv[0][0][1] = (motion_y >> 1); + h261_encode_motion(h, mv_diff_x); + h261_encode_motion(h, mv_diff_y); + } + + if (HAS_CBP(h->mtype)) { + av_assert1(cbp > 0); + put_bits(&s->pb, + ff_h261_cbp_tab[cbp - 1][1], + ff_h261_cbp_tab[cbp - 1][0]); + } + for (i = 0; i < 6; i++) + /* encode each block */ + h261_encode_block(h, block[i], i); + + if (!IS_16X16(h->mtype)) { + s->last_mv[0][0][0] = 0; + s->last_mv[0][0][1] = 0; + } +} + +static av_cold void init_uni_h261_rl_tab(RLTable *rl, uint32_t *bits_tab, + uint8_t *len_tab) +{ + int slevel, run, last; + + av_assert0(MAX_LEVEL >= 64); + av_assert0(MAX_RUN >= 63); + + for(slevel=-64; slevel<64; slevel++){ + if(slevel==0) continue; + for(run=0; run<64; run++){ + for(last=0; last<=1; last++){ + const int index= UNI_ENC_INDEX(last, run, slevel+64); + int level= slevel < 0 ? -slevel : slevel; + int len, code; + + len_tab[index]= 100; + + /* ESC0 */ + code= get_rl_index(rl, 0, run, level); + len= rl->table_vlc[code][1] + 1; + if(last) + len += 2; + + if(code!=rl->n && len < len_tab[index]){ + len_tab [index]= len; + } + /* ESC */ + len = rl->table_vlc[rl->n][1]; + if(last) + len += 2; + + if(len < len_tab[index]){ + len_tab [index]= len; + } + } + } } } +av_cold void ff_h261_encode_init(MpegEncContext *s) +{ + ff_h261_common_init(); + + s->min_qcoeff = -127; + s->max_qcoeff = 127; + s->y_dc_scale_table = + s->c_dc_scale_table = ff_mpeg1_dc_scale_table; + s->ac_esc_length = 6+6+8; + + init_uni_h261_rl_tab(&ff_h261_rl_tcoeff, NULL, uni_h261_rl_len); + + s->intra_ac_vlc_length = s->inter_ac_vlc_length = uni_h261_rl_len; + s->intra_ac_vlc_last_length = s->inter_ac_vlc_last_length = uni_h261_rl_len + 128*64; +} + FF_MPV_GENERIC_CLASS(h261) AVCodec ff_h261_encoder = { .name = "h261", + .long_name = NULL_IF_CONFIG_SMALL("H.261"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H261, .priv_data_size = sizeof(H261Context), .init = ff_MPV_encode_init, .encode2 = ff_MPV_encode_picture, .close = ff_MPV_encode_end, - .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("H.261"), + .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, + AV_PIX_FMT_NONE }, .priv_class = &h261_class, }; diff --git a/ffmpeg/libavcodec/h263.c b/ffmpeg/libavcodec/h263.c index e60e58e..dafc4ec 100644 --- a/ffmpeg/libavcodec/h263.c +++ b/ffmpeg/libavcodec/h263.c @@ -27,7 +27,6 @@ * h263/mpeg4 codec. */ -//#define DEBUG #include #include "avcodec.h" @@ -39,8 +38,6 @@ #include "flv.h" #include "mpeg4video.h" -//#undef NDEBUG -//#include uint8_t ff_h263_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; @@ -155,8 +152,8 @@ void ff_h263_loop_filter(MpegEncContext * s){ */ if (!IS_SKIP(s->current_picture.mb_type[xy])) { qp_c= s->qscale; - s->dsp.h263_v_loop_filter(dest_y+8*linesize , linesize, qp_c); - s->dsp.h263_v_loop_filter(dest_y+8*linesize+8, linesize, qp_c); + s->h263dsp.h263_v_loop_filter(dest_y + 8 * linesize, linesize, qp_c); + s->h263dsp.h263_v_loop_filter(dest_y + 8 * linesize + 8, linesize, qp_c); }else qp_c= 0; @@ -175,15 +172,15 @@ void ff_h263_loop_filter(MpegEncContext * s){ if(qp_tc){ const int chroma_qp= s->chroma_qscale_table[qp_tc]; - s->dsp.h263_v_loop_filter(dest_y , linesize, qp_tc); - s->dsp.h263_v_loop_filter(dest_y+8, linesize, qp_tc); + s->h263dsp.h263_v_loop_filter(dest_y, linesize, qp_tc); + s->h263dsp.h263_v_loop_filter(dest_y + 8, linesize, qp_tc); - s->dsp.h263_v_loop_filter(dest_cb , uvlinesize, chroma_qp); - s->dsp.h263_v_loop_filter(dest_cr , uvlinesize, chroma_qp); + s->h263dsp.h263_v_loop_filter(dest_cb, uvlinesize, chroma_qp); + s->h263dsp.h263_v_loop_filter(dest_cr, uvlinesize, chroma_qp); } if(qp_tt) - s->dsp.h263_h_loop_filter(dest_y-8*linesize+8 , linesize, qp_tt); + s->h263dsp.h263_h_loop_filter(dest_y - 8 * linesize + 8, linesize, qp_tt); if(s->mb_x){ if (qp_tt || IS_SKIP(s->current_picture.mb_type[xy - 1 - s->mb_stride])) @@ -193,17 +190,17 @@ void ff_h263_loop_filter(MpegEncContext * s){ if(qp_dt){ const int chroma_qp= s->chroma_qscale_table[qp_dt]; - s->dsp.h263_h_loop_filter(dest_y -8*linesize , linesize, qp_dt); - s->dsp.h263_h_loop_filter(dest_cb-8*uvlinesize, uvlinesize, chroma_qp); - s->dsp.h263_h_loop_filter(dest_cr-8*uvlinesize, uvlinesize, chroma_qp); + s->h263dsp.h263_h_loop_filter(dest_y - 8 * linesize, linesize, qp_dt); + s->h263dsp.h263_h_loop_filter(dest_cb - 8 * uvlinesize, uvlinesize, chroma_qp); + s->h263dsp.h263_h_loop_filter(dest_cr - 8 * uvlinesize, uvlinesize, chroma_qp); } } } if(qp_c){ - s->dsp.h263_h_loop_filter(dest_y +8, linesize, qp_c); + s->h263dsp.h263_h_loop_filter(dest_y + 8, linesize, qp_c); if(s->mb_y + 1 == s->mb_height) - s->dsp.h263_h_loop_filter(dest_y+8*linesize+8, linesize, qp_c); + s->h263dsp.h263_h_loop_filter(dest_y + 8 * linesize + 8, linesize, qp_c); } if(s->mb_x){ @@ -214,12 +211,12 @@ void ff_h263_loop_filter(MpegEncContext * s){ qp_lc = s->current_picture.qscale_table[xy - 1]; if(qp_lc){ - s->dsp.h263_h_loop_filter(dest_y, linesize, qp_lc); + s->h263dsp.h263_h_loop_filter(dest_y, linesize, qp_lc); if(s->mb_y + 1 == s->mb_height){ const int chroma_qp= s->chroma_qscale_table[qp_lc]; - s->dsp.h263_h_loop_filter(dest_y +8* linesize, linesize, qp_lc); - s->dsp.h263_h_loop_filter(dest_cb , uvlinesize, chroma_qp); - s->dsp.h263_h_loop_filter(dest_cr , uvlinesize, chroma_qp); + s->h263dsp.h263_h_loop_filter(dest_y + 8 * linesize, linesize, qp_lc); + s->h263dsp.h263_h_loop_filter(dest_cb, uvlinesize, chroma_qp); + s->h263dsp.h263_h_loop_filter(dest_cr, uvlinesize, chroma_qp); } } } diff --git a/ffmpeg/libavcodec/h263.h b/ffmpeg/libavcodec/h263.h index a95cfb0..962d44c 100644 --- a/ffmpeg/libavcodec/h263.h +++ b/ffmpeg/libavcodec/h263.h @@ -26,6 +26,10 @@ #include "mpegvideo.h" #include "rl.h" +#if !FF_API_ASPECT_EXTENDED +#define FF_ASPECT_EXTENDED 15 +#endif + // The defines below define the number of bits that are read at once for // reading vlc values. Changing these may improve speed and data cache needs // be aware though that decreasing them may need the number of stages that is @@ -53,6 +57,10 @@ extern VLC ff_h263_intra_MCBPC_vlc; extern VLC ff_h263_inter_MCBPC_vlc; extern VLC ff_h263_cbpy_vlc; +extern const uint16_t ff_inter_vlc[103][2]; +extern const int8_t ff_inter_level[102]; +extern const int8_t ff_inter_run[102]; + extern RLTable ff_h263_rl_inter; extern RLTable ff_rl_intra_aic; @@ -112,7 +120,6 @@ int av_const h263_get_picture_format(int width, int height); void ff_clean_h263_qscales(MpegEncContext *s); int ff_h263_resync(MpegEncContext *s); -const uint8_t *ff_h263_find_resync_marker(MpegEncContext *s, const uint8_t *p, const uint8_t *end); int ff_h263_get_gob_height(MpegEncContext *s); void ff_h263_encode_motion(MpegEncContext * s, int val, int f_code); diff --git a/ffmpeg/libavcodec/h263data.h b/ffmpeg/libavcodec/h263data.h index e245e2f..1cd965f 100644 --- a/ffmpeg/libavcodec/h263data.h +++ b/ffmpeg/libavcodec/h263data.h @@ -272,11 +272,6 @@ const uint8_t ff_mba_length[7]={ 6, 7, 9, 11, 13, 14, 14 }; -const uint8_t ff_h263_loop_filter_strength[32]={ -// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 - 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9,10,10,10,11,11,11,12,12,12 -}; - const AVRational ff_h263_pixel_aspect[16]={ {0, 1}, {1, 1}, diff --git a/ffmpeg/libavcodec/h263dec.c b/ffmpeg/libavcodec/h263dec.c index 66d00d4..6324e9b 100644 --- a/ffmpeg/libavcodec/h263dec.c +++ b/ffmpeg/libavcodec/h263dec.c @@ -28,81 +28,77 @@ #define UNCHECKED_BITSTREAM_READER 1 #include "libavutil/cpu.h" -#include "internal.h" #include "avcodec.h" #include "error_resilience.h" -#include "mpegvideo.h" +#include "flv.h" #include "h263.h" #include "h263_parser.h" +#include "internal.h" +#include "mpeg4video.h" #include "mpeg4video_parser.h" +#include "mpegvideo.h" #include "msmpeg4.h" #include "vdpau_internal.h" #include "thread.h" -#include "flv.h" -#include "mpeg4video.h" - -//#define DEBUG -//#define PRINT_FRAME_TIME av_cold int ff_h263_decode_init(AVCodecContext *avctx) { MpegEncContext *s = avctx->priv_data; int ret; - s->avctx = avctx; - s->out_format = FMT_H263; - - s->width = avctx->coded_width; - s->height = avctx->coded_height; - s->workaround_bugs= avctx->workaround_bugs; + s->avctx = avctx; + s->out_format = FMT_H263; + s->width = avctx->coded_width; + s->height = avctx->coded_height; + s->workaround_bugs = avctx->workaround_bugs; // set defaults ff_MPV_decode_defaults(s); - s->quant_precision=5; - s->decode_mb= ff_h263_decode_mb; - s->low_delay= 1; + s->quant_precision = 5; + s->decode_mb = ff_h263_decode_mb; + s->low_delay = 1; if (avctx->codec->id == AV_CODEC_ID_MSS2) avctx->pix_fmt = AV_PIX_FMT_YUV420P; else avctx->pix_fmt = avctx->get_format(avctx, avctx->codec->pix_fmts); - s->unrestricted_mv= 1; + s->unrestricted_mv = 1; /* select sub codec */ - switch(avctx->codec->id) { + switch (avctx->codec->id) { case AV_CODEC_ID_H263: case AV_CODEC_ID_H263P: - s->unrestricted_mv= 0; + s->unrestricted_mv = 0; avctx->chroma_sample_location = AVCHROMA_LOC_CENTER; break; case AV_CODEC_ID_MPEG4: break; case AV_CODEC_ID_MSMPEG4V1: - s->h263_pred = 1; - s->msmpeg4_version=1; + s->h263_pred = 1; + s->msmpeg4_version = 1; break; case AV_CODEC_ID_MSMPEG4V2: - s->h263_pred = 1; - s->msmpeg4_version=2; + s->h263_pred = 1; + s->msmpeg4_version = 2; break; case AV_CODEC_ID_MSMPEG4V3: - s->h263_pred = 1; - s->msmpeg4_version=3; + s->h263_pred = 1; + s->msmpeg4_version = 3; break; case AV_CODEC_ID_WMV1: - s->h263_pred = 1; - s->msmpeg4_version=4; + s->h263_pred = 1; + s->msmpeg4_version = 4; break; case AV_CODEC_ID_WMV2: - s->h263_pred = 1; - s->msmpeg4_version=5; + s->h263_pred = 1; + s->msmpeg4_version = 5; break; case AV_CODEC_ID_VC1: case AV_CODEC_ID_WMV3: case AV_CODEC_ID_VC1IMAGE: case AV_CODEC_ID_WMV3IMAGE: case AV_CODEC_ID_MSS2: - s->h263_pred = 1; - s->msmpeg4_version=6; + s->h263_pred = 1; + s->msmpeg4_version = 6; avctx->chroma_sample_location = AVCHROMA_LOC_LEFT; break; case AV_CODEC_ID_H263I: @@ -111,17 +107,25 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx) s->h263_flv = 1; break; default: - return AVERROR(EINVAL); + av_log(avctx, AV_LOG_ERROR, "Unsupported codec %d\n", + avctx->codec->id); + return AVERROR(ENOSYS); } - s->codec_id= avctx->codec->id; - avctx->hwaccel= ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt); + s->codec_id = avctx->codec->id; + avctx->hwaccel = ff_find_hwaccel(avctx); + + if (avctx->stream_codec_tag == AV_RL32("l263") && avctx->extradata_size == 56 && avctx->extradata[0] == 1) + s->ehc_mode = 1; /* for h263, we allocate the images after having read the header */ - if (avctx->codec->id != AV_CODEC_ID_H263 && avctx->codec->id != AV_CODEC_ID_H263P && avctx->codec->id != AV_CODEC_ID_MPEG4) + if (avctx->codec->id != AV_CODEC_ID_H263 && + avctx->codec->id != AV_CODEC_ID_H263P && + avctx->codec->id != AV_CODEC_ID_MPEG4) if ((ret = ff_MPV_common_init(s)) < 0) return ret; - ff_h263_decode_init_vlc(); + ff_h263dsp_init(&s->h263dsp); + ff_h263_decode_init_vlc(); return 0; } @@ -137,237 +141,251 @@ av_cold int ff_h263_decode_end(AVCodecContext *avctx) /** * Return the number of bytes consumed for building the current frame. */ -static int get_consumed_bytes(MpegEncContext *s, int buf_size){ - int pos= (get_bits_count(&s->gb)+7)>>3; +static int get_consumed_bytes(MpegEncContext *s, int buf_size) +{ + int pos = (get_bits_count(&s->gb) + 7) >> 3; - if(s->divx_packed || s->avctx->hwaccel){ - //we would have to scan through the whole buf to handle the weird reordering ... + if (s->divx_packed || s->avctx->hwaccel) { + /* We would have to scan through the whole buf to handle the weird + * reordering ... */ return buf_size; - }else if(s->flags&CODEC_FLAG_TRUNCATED){ + } else if (s->flags & CODEC_FLAG_TRUNCATED) { pos -= s->parse_context.last_index; - if(pos<0) pos=0; // padding is not really read so this might be -1 + // padding is not really read so this might be -1 + if (pos < 0) + pos = 0; return pos; - }else{ - if(pos==0) pos=1; //avoid infinite loops (i doubt that is needed but ...) - if(pos+10>buf_size) pos=buf_size; // oops ;) + } else { + // avoid infinite loops (maybe not needed...) + if (pos == 0) + pos = 1; + // oops ;) + if (pos + 10 > buf_size) + pos = buf_size; return pos; } } -static int decode_slice(MpegEncContext *s){ - const int part_mask= s->partitioned_frame ? (ER_AC_END|ER_AC_ERROR) : 0x7F; - const int mb_size= 16>>s->avctx->lowres; +static int decode_slice(MpegEncContext *s) +{ + const int part_mask = s->partitioned_frame + ? (ER_AC_END | ER_AC_ERROR) : 0x7F; + const int mb_size = 16 >> s->avctx->lowres; int ret; - s->last_resync_gb= s->gb; - s->first_slice_line= 1; - - s->resync_mb_x= s->mb_x; - s->resync_mb_y= s->mb_y; + s->last_resync_gb = s->gb; + s->first_slice_line = 1; + s->resync_mb_x = s->mb_x; + s->resync_mb_y = s->mb_y; ff_set_qscale(s, s->qscale); if (s->avctx->hwaccel) { - const uint8_t *start= s->gb.buffer + get_bits_count(&s->gb)/8; - const uint8_t *end = ff_h263_find_resync_marker(s, start + 1, s->gb.buffer_end); - skip_bits_long(&s->gb, 8*(end - start)); - return s->avctx->hwaccel->decode_slice(s->avctx, start, end - start); + const uint8_t *start = s->gb.buffer + get_bits_count(&s->gb) / 8; + ret = s->avctx->hwaccel->decode_slice(s->avctx, start, s->gb.buffer_end - start); + // ensure we exit decode loop + s->mb_y = s->mb_height; + return ret; } - if(s->partitioned_frame){ - const int qscale= s->qscale; + if (s->partitioned_frame) { + const int qscale = s->qscale; - if(CONFIG_MPEG4_DECODER && s->codec_id==AV_CODEC_ID_MPEG4){ - if ((ret = ff_mpeg4_decode_partitions(s)) < 0) + if (CONFIG_MPEG4_DECODER && s->codec_id == AV_CODEC_ID_MPEG4) + if ((ret = ff_mpeg4_decode_partitions(s->avctx->priv_data)) < 0) return ret; - } /* restore variables which were modified */ - s->first_slice_line=1; - s->mb_x= s->resync_mb_x; - s->mb_y= s->resync_mb_y; + s->first_slice_line = 1; + s->mb_x = s->resync_mb_x; + s->mb_y = s->resync_mb_y; ff_set_qscale(s, qscale); } - for(; s->mb_y < s->mb_height; s->mb_y++) { + for (; s->mb_y < s->mb_height; s->mb_y++) { /* per-row end of slice checks */ - if(s->msmpeg4_version){ - if(s->resync_mb_y + s->slice_height == s->mb_y){ - ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END); + if (s->msmpeg4_version) { + if (s->resync_mb_y + s->slice_height == s->mb_y) { + ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, + s->mb_x - 1, s->mb_y, ER_MB_END); return 0; } } - if(s->msmpeg4_version==1){ - s->last_dc[0]= - s->last_dc[1]= - s->last_dc[2]= 128; + if (s->msmpeg4_version == 1) { + s->last_dc[0] = + s->last_dc[1] = + s->last_dc[2] = 128; } ff_init_block_index(s); - for(; s->mb_x < s->mb_width; s->mb_x++) { + for (; s->mb_x < s->mb_width; s->mb_x++) { int ret; ff_update_block_index(s); - if(s->resync_mb_x == s->mb_x && s->resync_mb_y+1 == s->mb_y){ - s->first_slice_line=0; - } + if (s->resync_mb_x == s->mb_x && s->resync_mb_y + 1 == s->mb_y) + s->first_slice_line = 0; /* DCT & quantize */ - s->mv_dir = MV_DIR_FORWARD; + s->mv_dir = MV_DIR_FORWARD; s->mv_type = MV_TYPE_16X16; -// s->mb_skipped = 0; av_dlog(s, "%d %d %06X\n", ret, get_bits_count(&s->gb), show_bits(&s->gb, 24)); - ret= s->decode_mb(s, s->block); + ret = s->decode_mb(s, s->block); - if (s->pict_type!=AV_PICTURE_TYPE_B) + if (s->pict_type != AV_PICTURE_TYPE_B) ff_h263_update_motion_val(s); - if(ret<0){ - const int xy= s->mb_x + s->mb_y*s->mb_stride; - if(ret==SLICE_END){ + if (ret < 0) { + const int xy = s->mb_x + s->mb_y * s->mb_stride; + if (ret == SLICE_END) { ff_MPV_decode_mb(s, s->block); - if(s->loop_filter) + if (s->loop_filter) ff_h263_loop_filter(s); - ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_END&part_mask); + ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, + s->mb_x, s->mb_y, ER_MB_END & part_mask); s->padding_bug_score--; - if(++s->mb_x >= s->mb_width){ - s->mb_x=0; - ff_mpeg_draw_horiz_band(s, s->mb_y*mb_size, mb_size); + if (++s->mb_x >= s->mb_width) { + s->mb_x = 0; + ff_mpeg_draw_horiz_band(s, s->mb_y * mb_size, mb_size); ff_MPV_report_decode_progress(s); s->mb_y++; } return 0; - }else if(ret==SLICE_NOEND){ - av_log(s->avctx, AV_LOG_ERROR, "Slice mismatch at MB: %d\n", xy); - ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x+1, s->mb_y, ER_MB_END&part_mask); + } else if (ret == SLICE_NOEND) { + av_log(s->avctx, AV_LOG_ERROR, + "Slice mismatch at MB: %d\n", xy); + ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, + s->mb_x + 1, s->mb_y, + ER_MB_END & part_mask); return AVERROR_INVALIDDATA; } av_log(s->avctx, AV_LOG_ERROR, "Error at MB: %d\n", xy); - ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR&part_mask); + ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, + s->mb_x, s->mb_y, ER_MB_ERROR & part_mask); return AVERROR_INVALIDDATA; } ff_MPV_decode_mb(s, s->block); - if(s->loop_filter) + if (s->loop_filter) ff_h263_loop_filter(s); } - ff_mpeg_draw_horiz_band(s, s->mb_y*mb_size, mb_size); + ff_mpeg_draw_horiz_band(s, s->mb_y * mb_size, mb_size); ff_MPV_report_decode_progress(s); - s->mb_x= 0; + s->mb_x = 0; } - av_assert1(s->mb_x==0 && s->mb_y==s->mb_height); + av_assert1(s->mb_x == 0 && s->mb_y == s->mb_height); - if(s->codec_id==AV_CODEC_ID_MPEG4 - && (s->workaround_bugs&FF_BUG_AUTODETECT) - && get_bits_left(&s->gb) >= 48 - && show_bits(&s->gb, 24)==0x4010 - && !s->data_partitioning) - s->padding_bug_score+=32; + if (s->codec_id == AV_CODEC_ID_MPEG4 && + (s->workaround_bugs & FF_BUG_AUTODETECT) && + get_bits_left(&s->gb) >= 48 && + show_bits(&s->gb, 24) == 0x4010 && + !s->data_partitioning) + s->padding_bug_score += 32; /* try to detect the padding bug */ - if( s->codec_id==AV_CODEC_ID_MPEG4 - && (s->workaround_bugs&FF_BUG_AUTODETECT) - && get_bits_left(&s->gb) >=0 - && get_bits_left(&s->gb) < 137 -// && !s->resync_marker - && !s->data_partitioning){ - - const int bits_count= get_bits_count(&s->gb); - const int bits_left = s->gb.size_in_bits - bits_count; - - if(bits_left==0){ - s->padding_bug_score+=16; - } else if(bits_left != 1){ - int v= show_bits(&s->gb, 8); - v|= 0x7F >> (7-(bits_count&7)); - - if(v==0x7F && bits_left<=8) + if (s->codec_id == AV_CODEC_ID_MPEG4 && + (s->workaround_bugs & FF_BUG_AUTODETECT) && + get_bits_left(&s->gb) >= 0 && + get_bits_left(&s->gb) < 137 && + !s->data_partitioning) { + const int bits_count = get_bits_count(&s->gb); + const int bits_left = s->gb.size_in_bits - bits_count; + + if (bits_left == 0) { + s->padding_bug_score += 16; + } else if (bits_left != 1) { + int v = show_bits(&s->gb, 8); + v |= 0x7F >> (7 - (bits_count & 7)); + + if (v == 0x7F && bits_left <= 8) s->padding_bug_score--; - else if(v==0x7F && ((get_bits_count(&s->gb)+8)&8) && bits_left<=16) - s->padding_bug_score+= 4; + else if (v == 0x7F && ((get_bits_count(&s->gb) + 8) & 8) && + bits_left <= 16) + s->padding_bug_score += 4; else s->padding_bug_score++; } } - if(s->workaround_bugs&FF_BUG_AUTODETECT){ - if(s->padding_bug_score > -2 && !s->data_partitioning /*&& (s->divx_version>=0 || !s->resync_marker)*/) - s->workaround_bugs |= FF_BUG_NO_PADDING; + if (s->workaround_bugs & FF_BUG_AUTODETECT) { + if (s->padding_bug_score > -2 && !s->data_partitioning) + s->workaround_bugs |= FF_BUG_NO_PADDING; else s->workaround_bugs &= ~FF_BUG_NO_PADDING; } // handle formats which don't have unique end markers - if(s->msmpeg4_version || (s->workaround_bugs&FF_BUG_NO_PADDING)){ //FIXME perhaps solve this more cleanly - int left= get_bits_left(&s->gb); - int max_extra=7; + if (s->msmpeg4_version || (s->workaround_bugs & FF_BUG_NO_PADDING)) { // FIXME perhaps solve this more cleanly + int left = get_bits_left(&s->gb); + int max_extra = 7; /* no markers in M$ crap */ - if(s->msmpeg4_version && s->pict_type==AV_PICTURE_TYPE_I) - max_extra+= 17; - - /* buggy padding but the frame should still end approximately at the bitstream end */ - if((s->workaround_bugs&FF_BUG_NO_PADDING) && (s->err_recognition&(AV_EF_BUFFER|AV_EF_AGGRESSIVE))) - max_extra+= 48; - else if((s->workaround_bugs&FF_BUG_NO_PADDING)) - max_extra+= 256*256*256*64; - - if(left>max_extra){ - av_log(s->avctx, AV_LOG_ERROR, "discarding %d junk bits at end, next would be %X\n", left, show_bits(&s->gb, 24)); - } - else if(left<0){ + if (s->msmpeg4_version && s->pict_type == AV_PICTURE_TYPE_I) + max_extra += 17; + + /* buggy padding but the frame should still end approximately at + * the bitstream end */ + if ((s->workaround_bugs & FF_BUG_NO_PADDING) && + (s->err_recognition & (AV_EF_BUFFER|AV_EF_AGGRESSIVE))) + max_extra += 48; + else if ((s->workaround_bugs & FF_BUG_NO_PADDING)) + max_extra += 256 * 256 * 256 * 64; + + if (left > max_extra) + av_log(s->avctx, AV_LOG_ERROR, + "discarding %d junk bits at end, next would be %X\n", + left, show_bits(&s->gb, 24)); + else if (left < 0) av_log(s->avctx, AV_LOG_ERROR, "overreading %d bits\n", -left); - }else - ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END); + else + ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, + s->mb_x - 1, s->mb_y, ER_MB_END); return 0; } - av_log(s->avctx, AV_LOG_ERROR, "slice end not reached but screenspace end (%d left %06X, score= %d)\n", - get_bits_left(&s->gb), - show_bits(&s->gb, 24), s->padding_bug_score); + av_log(s->avctx, AV_LOG_ERROR, + "slice end not reached but screenspace end (%d left %06X, score= %d)\n", + get_bits_left(&s->gb), show_bits(&s->gb, 24), s->padding_bug_score); - ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_END&part_mask); + ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, + ER_MB_END & part_mask); return AVERROR_INVALIDDATA; } -int ff_h263_decode_frame(AVCodecContext *avctx, - void *data, int *got_frame, - AVPacket *avpkt) +int ff_h263_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, + AVPacket *avpkt) { const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - MpegEncContext *s = avctx->priv_data; + int buf_size = avpkt->size; + MpegEncContext *s = avctx->priv_data; int ret; + int slice_ret = 0; AVFrame *pict = data; -#ifdef PRINT_FRAME_TIME -uint64_t time= rdtsc(); -#endif - s->flags= avctx->flags; - s->flags2= avctx->flags2; + s->flags = avctx->flags; + s->flags2 = avctx->flags2; /* no supplementary picture */ if (buf_size == 0) { /* special case for last picture */ - if (s->low_delay==0 && s->next_picture_ptr) { + if (s->low_delay == 0 && s->next_picture_ptr) { if ((ret = av_frame_ref(pict, &s->next_picture_ptr->f)) < 0) return ret; - s->next_picture_ptr= NULL; + s->next_picture_ptr = NULL; *got_frame = 1; } @@ -375,72 +393,77 @@ uint64_t time= rdtsc(); return 0; } - if(s->flags&CODEC_FLAG_TRUNCATED){ + if (s->flags & CODEC_FLAG_TRUNCATED) { int next; - if(CONFIG_MPEG4_DECODER && s->codec_id==AV_CODEC_ID_MPEG4){ - next= ff_mpeg4_find_frame_end(&s->parse_context, buf, buf_size); - }else if(CONFIG_H263_DECODER && s->codec_id==AV_CODEC_ID_H263){ - next= ff_h263_find_frame_end(&s->parse_context, buf, buf_size); - }else if(CONFIG_H263P_DECODER && s->codec_id==AV_CODEC_ID_H263P){ - next= ff_h263_find_frame_end(&s->parse_context, buf, buf_size); - }else{ - av_log(s->avctx, AV_LOG_ERROR, "this codec does not support truncated bitstreams\n"); - return AVERROR(EINVAL); + if (CONFIG_MPEG4_DECODER && s->codec_id == AV_CODEC_ID_MPEG4) { + next = ff_mpeg4_find_frame_end(&s->parse_context, buf, buf_size); + } else if (CONFIG_H263_DECODER && s->codec_id == AV_CODEC_ID_H263) { + next = ff_h263_find_frame_end(&s->parse_context, buf, buf_size); + } else if (CONFIG_H263P_DECODER && s->codec_id == AV_CODEC_ID_H263P) { + next = ff_h263_find_frame_end(&s->parse_context, buf, buf_size); + } else { + av_log(s->avctx, AV_LOG_ERROR, + "this codec does not support truncated bitstreams\n"); + return AVERROR(ENOSYS); } - if( ff_combine_frame(&s->parse_context, next, (const uint8_t **)&buf, &buf_size) < 0 ) + if (ff_combine_frame(&s->parse_context, next, (const uint8_t **)&buf, + &buf_size) < 0) return buf_size; } - retry: - if(s->divx_packed && s->bitstream_buffer_size){ + if (s->divx_packed && s->bitstream_buffer_size) { int i; - for(i=0; iavctx, AV_LOG_WARNING, "Discarding excessive bitstream in packed xvid\n"); - s->bitstream_buffer_size=0; + s->bitstream_buffer_size = 0; } break; } } } - if(s->bitstream_buffer_size && (s->divx_packed || buf_size<20)){ //divx 5.01+/xvid frame reorder - init_get_bits(&s->gb, s->bitstream_buffer, s->bitstream_buffer_size*8); - }else - init_get_bits(&s->gb, buf, buf_size*8); - s->bitstream_buffer_size=0; + if (s->bitstream_buffer_size && (s->divx_packed || buf_size < 20)) // divx 5.01+/xvid frame reorder + ret = init_get_bits8(&s->gb, s->bitstream_buffer, + s->bitstream_buffer_size); + else + ret = init_get_bits8(&s->gb, buf, buf_size); + + s->bitstream_buffer_size = 0; + if (ret < 0) + return ret; - if (!s->context_initialized) { - if ((ret = ff_MPV_common_init(s)) < 0) //we need the idct permutaton for reading a custom matrix + if (!s->context_initialized) + // we need the idct permutaton for reading a custom matrix + if ((ret = ff_MPV_common_init(s)) < 0) return ret; - } /* We need to set current_picture_ptr before reading the header, * otherwise we cannot store anyting in there */ if (s->current_picture_ptr == NULL || s->current_picture_ptr->f.data[0]) { - int i= ff_find_unused_picture(s, 0); + int i = ff_find_unused_picture(s, 0); if (i < 0) return i; - s->current_picture_ptr= &s->picture[i]; + s->current_picture_ptr = &s->picture[i]; } /* let's go :-) */ - if (CONFIG_WMV2_DECODER && s->msmpeg4_version==5) { - ret= ff_wmv2_decode_picture_header(s); + if (CONFIG_WMV2_DECODER && s->msmpeg4_version == 5) { + ret = ff_wmv2_decode_picture_header(s); } else if (CONFIG_MSMPEG4_DECODER && s->msmpeg4_version) { ret = ff_msmpeg4_decode_picture_header(s); - } else if (CONFIG_MPEG4_DECODER && s->h263_pred) { - if(s->avctx->extradata_size && s->picture_number==0){ + } else if (CONFIG_MPEG4_DECODER && avctx->codec_id == AV_CODEC_ID_MPEG4) { + if (s->avctx->extradata_size && s->picture_number == 0) { GetBitContext gb; - init_get_bits(&gb, s->avctx->extradata, s->avctx->extradata_size*8); - ret = ff_mpeg4_decode_picture_header(s, &gb); + if (init_get_bits8(&gb, s->avctx->extradata, s->avctx->extradata_size) >= 0 ) + ff_mpeg4_decode_picture_header(avctx->priv_data, &gb); } - ret = ff_mpeg4_decode_picture_header(s, &s->gb); + ret = ff_mpeg4_decode_picture_header(avctx->priv_data, &s->gb); } else if (CONFIG_H263I_DECODER && s->codec_id == AV_CODEC_ID_H263I) { ret = ff_intel_h263_decode_picture_header(s); } else if (CONFIG_FLV_DECODER && s->h263_flv) { @@ -449,7 +472,7 @@ retry: ret = ff_h263_decode_picture_header(s); } - if (ret < 0 || ret==FRAME_SKIPPED) { + if (ret < 0 || ret == FRAME_SKIPPED) { if ( s->width != avctx->coded_width || s->height != avctx->coded_height) { av_log(s->avctx, AV_LOG_WARNING, "Reverting picture dimensions change due to header decoding failure\n"); @@ -457,171 +480,43 @@ retry: s->height= avctx->coded_height; } } - if(ret==FRAME_SKIPPED) return get_consumed_bytes(s, buf_size); + if (ret == FRAME_SKIPPED) + return get_consumed_bytes(s, buf_size); /* skip if the header was thrashed */ - if (ret < 0){ + if (ret < 0) { av_log(s->avctx, AV_LOG_ERROR, "header damaged\n"); return ret; } - avctx->has_b_frames= !s->low_delay; - - if(s->xvid_build==-1 && s->divx_version==-1 && s->lavc_build==-1){ - if(s->stream_codec_tag == AV_RL32("XVID") || - s->codec_tag == AV_RL32("XVID") || s->codec_tag == AV_RL32("XVIX") || - s->codec_tag == AV_RL32("RMP4") || s->codec_tag == AV_RL32("ZMP4") || - s->codec_tag == AV_RL32("SIPP") - ) - s->xvid_build= 0; -#if 0 - if(s->codec_tag == AV_RL32("DIVX") && s->vo_type==0 && s->vol_control_parameters==1 - && s->padding_bug_score > 0 && s->low_delay) // XVID with modified fourcc - s->xvid_build= 0; -#endif - } - - if(s->xvid_build==-1 && s->divx_version==-1 && s->lavc_build==-1){ - if(s->codec_tag == AV_RL32("DIVX") && s->vo_type==0 && s->vol_control_parameters==0) - s->divx_version= 400; //divx 4 - } - - if(s->xvid_build>=0 && s->divx_version>=0){ - s->divx_version= - s->divx_build= -1; - } - - if(s->workaround_bugs&FF_BUG_AUTODETECT){ - if(s->codec_tag == AV_RL32("XVIX")) - s->workaround_bugs|= FF_BUG_XVID_ILACE; - - if(s->codec_tag == AV_RL32("UMP4")){ - s->workaround_bugs|= FF_BUG_UMP4; - } - - if(s->divx_version>=500 && s->divx_build<1814){ - s->workaround_bugs|= FF_BUG_QPEL_CHROMA; - } - - if(s->divx_version>502 && s->divx_build<1814){ - s->workaround_bugs|= FF_BUG_QPEL_CHROMA2; - } - - if(s->xvid_build<=3U) - s->padding_bug_score= 256*256*256*64; - - if(s->xvid_build<=1U) - s->workaround_bugs|= FF_BUG_QPEL_CHROMA; - - if(s->xvid_build<=12U) - s->workaround_bugs|= FF_BUG_EDGE; - - if(s->xvid_build<=32U) - s->workaround_bugs|= FF_BUG_DC_CLIP; - -#define SET_QPEL_FUNC(postfix1, postfix2) \ - s->dsp.put_ ## postfix1 = ff_put_ ## postfix2;\ - s->dsp.put_no_rnd_ ## postfix1 = ff_put_no_rnd_ ## postfix2;\ - s->dsp.avg_ ## postfix1 = ff_avg_ ## postfix2; - - if(s->lavc_build<4653U) - s->workaround_bugs|= FF_BUG_STD_QPEL; - - if(s->lavc_build<4655U) - s->workaround_bugs|= FF_BUG_DIRECT_BLOCKSIZE; - - if(s->lavc_build<4670U){ - s->workaround_bugs|= FF_BUG_EDGE; - } - - if(s->lavc_build<=4712U) - s->workaround_bugs|= FF_BUG_DC_CLIP; - - if(s->divx_version>=0) - s->workaround_bugs|= FF_BUG_DIRECT_BLOCKSIZE; - if(s->divx_version==501 && s->divx_build==20020416) - s->padding_bug_score= 256*256*256*64; - - if(s->divx_version<500U){ - s->workaround_bugs|= FF_BUG_EDGE; - } - - if(s->divx_version>=0) - s->workaround_bugs|= FF_BUG_HPEL_CHROMA; -#if 0 - if(s->divx_version==500) - s->padding_bug_score= 256*256*256*64; - - /* very ugly XVID padding bug detection FIXME/XXX solve this differently - * Let us hope this at least works. - */ - if( s->resync_marker==0 && s->data_partitioning==0 && s->divx_version==-1 - && s->codec_id==AV_CODEC_ID_MPEG4 && s->vo_type==0) - s->workaround_bugs|= FF_BUG_NO_PADDING; - - if(s->lavc_build<4609U) //FIXME not sure about the version num but a 4609 file seems ok - s->workaround_bugs|= FF_BUG_NO_PADDING; -#endif - } - - if(s->workaround_bugs& FF_BUG_STD_QPEL){ - SET_QPEL_FUNC(qpel_pixels_tab[0][ 5], qpel16_mc11_old_c) - SET_QPEL_FUNC(qpel_pixels_tab[0][ 7], qpel16_mc31_old_c) - SET_QPEL_FUNC(qpel_pixels_tab[0][ 9], qpel16_mc12_old_c) - SET_QPEL_FUNC(qpel_pixels_tab[0][11], qpel16_mc32_old_c) - SET_QPEL_FUNC(qpel_pixels_tab[0][13], qpel16_mc13_old_c) - SET_QPEL_FUNC(qpel_pixels_tab[0][15], qpel16_mc33_old_c) - - SET_QPEL_FUNC(qpel_pixels_tab[1][ 5], qpel8_mc11_old_c) - SET_QPEL_FUNC(qpel_pixels_tab[1][ 7], qpel8_mc31_old_c) - SET_QPEL_FUNC(qpel_pixels_tab[1][ 9], qpel8_mc12_old_c) - SET_QPEL_FUNC(qpel_pixels_tab[1][11], qpel8_mc32_old_c) - SET_QPEL_FUNC(qpel_pixels_tab[1][13], qpel8_mc13_old_c) - SET_QPEL_FUNC(qpel_pixels_tab[1][15], qpel8_mc33_old_c) - } - - if(avctx->debug & FF_DEBUG_BUGS) - av_log(s->avctx, AV_LOG_DEBUG, "bugs: %X lavc_build:%d xvid_build:%d divx_version:%d divx_build:%d %s\n", - s->workaround_bugs, s->lavc_build, s->xvid_build, s->divx_version, s->divx_build, - s->divx_packed ? "p" : ""); - -#if HAVE_MMX - if (s->codec_id == AV_CODEC_ID_MPEG4 && s->xvid_build>=0 && avctx->idct_algo == FF_IDCT_AUTO && (av_get_cpu_flags() & AV_CPU_FLAG_MMX)) { - avctx->idct_algo= FF_IDCT_XVIDMMX; - ff_dct_common_init(s); - goto retry; - } -#endif - - /* After H263 & mpeg4 header decode we have the height, width,*/ - /* and other parameters. So then we could init the picture */ - /* FIXME: By the way H263 decoder is evolving it should have */ - /* an H263EncContext */ - - if ((!avctx->coded_width || !avctx->coded_height) && 0) { - ParseContext pc= s->parse_context; //FIXME move these demuxng hack to avformat + avctx->has_b_frames = !s->low_delay; - s->parse_context.buffer=0; - ff_MPV_common_end(s); - s->parse_context= pc; - avcodec_set_dimensions(avctx, s->width, s->height); - - goto retry; + if (CONFIG_MPEG4_DECODER && avctx->codec_id == AV_CODEC_ID_MPEG4) { + if (ff_mpeg4_workaround_bugs(avctx) == 1) + goto retry; } + /* After H263 & mpeg4 header decode we have the height, width, + * and other parameters. So then we could init the picture. + * FIXME: By the way H263 decoder is evolving it should have + * an H263EncContext */ if (s->width != avctx->coded_width || s->height != avctx->coded_height || s->context_reinit) { /* H.263 could change picture size any time */ s->context_reinit = 0; - avcodec_set_dimensions(avctx, s->width, s->height); + ret = ff_set_dimensions(avctx, s->width, s->height); + if (ret < 0) + return ret; if ((ret = ff_MPV_common_frame_size_change(s))) return ret; } - if((s->codec_id==AV_CODEC_ID_H263 || s->codec_id==AV_CODEC_ID_H263P || s->codec_id == AV_CODEC_ID_H263I)) + if (s->codec_id == AV_CODEC_ID_H263 || + s->codec_id == AV_CODEC_ID_H263P || + s->codec_id == AV_CODEC_ID_H263I) s->gob_index = ff_h263_get_gob_height(s); // for skipping the frame @@ -632,30 +527,33 @@ retry: if (s->last_picture_ptr == NULL && (s->pict_type == AV_PICTURE_TYPE_B || s->droppable)) return get_consumed_bytes(s, buf_size); - if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==AV_PICTURE_TYPE_B) - || (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=AV_PICTURE_TYPE_I) - || avctx->skip_frame >= AVDISCARD_ALL) + if ((avctx->skip_frame >= AVDISCARD_NONREF && + s->pict_type == AV_PICTURE_TYPE_B) || + (avctx->skip_frame >= AVDISCARD_NONKEY && + s->pict_type != AV_PICTURE_TYPE_I) || + avctx->skip_frame >= AVDISCARD_ALL) return get_consumed_bytes(s, buf_size); - if(s->next_p_frame_damaged){ - if(s->pict_type==AV_PICTURE_TYPE_B) + if (s->next_p_frame_damaged) { + if (s->pict_type == AV_PICTURE_TYPE_B) return get_consumed_bytes(s, buf_size); else - s->next_p_frame_damaged=0; + s->next_p_frame_damaged = 0; } - if((!s->no_rounding) || s->pict_type==AV_PICTURE_TYPE_B){ - s->me.qpel_put= s->dsp.put_qpel_pixels_tab; - s->me.qpel_avg= s->dsp.avg_qpel_pixels_tab; - }else{ - s->me.qpel_put= s->dsp.put_no_rnd_qpel_pixels_tab; - s->me.qpel_avg= s->dsp.avg_qpel_pixels_tab; + if ((!s->no_rounding) || s->pict_type == AV_PICTURE_TYPE_B) { + s->me.qpel_put = s->dsp.put_qpel_pixels_tab; + s->me.qpel_avg = s->dsp.avg_qpel_pixels_tab; + } else { + s->me.qpel_put = s->dsp.put_no_rnd_qpel_pixels_tab; + s->me.qpel_avg = s->dsp.avg_qpel_pixels_tab; } if ((ret = ff_MPV_frame_start(s, avctx)) < 0) return ret; - if (!s->divx_packed) ff_thread_finish_setup(avctx); + if (!s->divx_packed && !avctx->hwaccel) + ff_thread_finish_setup(avctx); if (CONFIG_MPEG4_VDPAU_DECODER && (s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)) { ff_vdpau_mpeg4_decode_picture(s, s->gb.buffer, s->gb.buffer_end - s->gb.buffer); @@ -663,89 +561,76 @@ retry: } if (avctx->hwaccel) { - if ((ret = avctx->hwaccel->start_frame(avctx, s->gb.buffer, s->gb.buffer_end - s->gb.buffer)) < 0) + ret = avctx->hwaccel->start_frame(avctx, s->gb.buffer, + s->gb.buffer_end - s->gb.buffer); + if (ret < 0 ) return ret; } ff_mpeg_er_frame_start(s); - //the second part of the wmv2 header contains the MB skip bits which are stored in current_picture->mb_type - //which is not available before ff_MPV_frame_start() - if (CONFIG_WMV2_DECODER && s->msmpeg4_version==5){ + /* the second part of the wmv2 header contains the MB skip bits which + * are stored in current_picture->mb_type which is not available before + * ff_MPV_frame_start() */ + if (CONFIG_WMV2_DECODER && s->msmpeg4_version == 5) { ret = ff_wmv2_decode_secondary_picture_header(s); - if(ret<0) return ret; - if(ret==1) goto intrax8_decoded; + if (ret < 0) + return ret; + if (ret == 1) + goto frame_end; } /* decode each macroblock */ - s->mb_x=0; - s->mb_y=0; - - ret = decode_slice(s); - while(s->mb_ymb_height){ - if(s->msmpeg4_version){ - if(s->slice_height==0 || s->mb_x!=0 || (s->mb_y%s->slice_height)!=0 || get_bits_left(&s->gb)<0) + s->mb_x = 0; + s->mb_y = 0; + + slice_ret = decode_slice(s); + while (s->mb_y < s->mb_height) { + if (s->msmpeg4_version) { + if (s->slice_height == 0 || s->mb_x != 0 || + (s->mb_y % s->slice_height) != 0 || get_bits_left(&s->gb) < 0) break; - }else{ - int prev_x=s->mb_x, prev_y=s->mb_y; - if(ff_h263_resync(s)<0) + } else { + int prev_x = s->mb_x, prev_y = s->mb_y; + if (ff_h263_resync(s) < 0) break; if (prev_y * s->mb_width + prev_x < s->mb_y * s->mb_width + s->mb_x) s->er.error_occurred = 1; } - if(s->msmpeg4_version<4 && s->h263_pred) + if (s->msmpeg4_version < 4 && s->h263_pred) ff_mpeg4_clean_buffers(s); - if (decode_slice(s) < 0) ret = AVERROR_INVALIDDATA; + if (decode_slice(s) < 0) + slice_ret = AVERROR_INVALIDDATA; } - if (s->msmpeg4_version && s->msmpeg4_version<4 && s->pict_type==AV_PICTURE_TYPE_I) - if(!CONFIG_MSMPEG4_DECODER || ff_msmpeg4_decode_ext_header(s, buf_size) < 0){ + if (s->msmpeg4_version && s->msmpeg4_version < 4 && + s->pict_type == AV_PICTURE_TYPE_I) + if (!CONFIG_MSMPEG4_DECODER || + ff_msmpeg4_decode_ext_header(s, buf_size) < 0) s->er.error_status_table[s->mb_num - 1] = ER_MB_ERROR; - } - av_assert1(s->bitstream_buffer_size==0); + av_assert1(s->bitstream_buffer_size == 0); frame_end: - /* divx 5.01+ bitstream reorder stuff */ - if(s->codec_id==AV_CODEC_ID_MPEG4 && s->divx_packed){ - int current_pos= s->gb.buffer == s->bitstream_buffer ? 0 : (get_bits_count(&s->gb)>>3); - int startcode_found=0; - - if(buf_size - current_pos > 7){ - int i; - for(i=current_pos; ibitstream_buffer, - &s->allocated_bitstream_buffer_size, - buf_size - current_pos + FF_INPUT_BUFFER_PADDING_SIZE); - if (!s->bitstream_buffer) - return AVERROR(ENOMEM); - memcpy(s->bitstream_buffer, buf + current_pos, buf_size - current_pos); - s->bitstream_buffer_size= buf_size - current_pos; - } - } - -intrax8_decoded: ff_er_frame_end(&s->er); if (avctx->hwaccel) { - if ((ret = avctx->hwaccel->end_frame(avctx)) < 0) + ret = avctx->hwaccel->end_frame(avctx); + if (ret < 0) return ret; } ff_MPV_frame_end(s); - assert(s->current_picture.f.pict_type == s->current_picture_ptr->f.pict_type); - assert(s->current_picture.f.pict_type == s->pict_type); + if (CONFIG_MPEG4_DECODER && avctx->codec_id == AV_CODEC_ID_MPEG4) + ff_mpeg4_frame_end(avctx, buf, buf_size); + + if (!s->divx_packed && avctx->hwaccel) + ff_thread_finish_setup(avctx); + + av_assert1(s->current_picture.f.pict_type == s->current_picture_ptr->f.pict_type); + av_assert1(s->current_picture.f.pict_type == s->pict_type); if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) { if ((ret = av_frame_ref(pict, &s->current_picture_ptr->f)) < 0) return ret; @@ -758,15 +643,29 @@ intrax8_decoded: ff_mpv_export_qp_table(s, pict, s->last_picture_ptr, FF_QSCALE_TYPE_MPEG1); } - if(s->last_picture_ptr || s->low_delay){ + if (s->last_picture_ptr || s->low_delay) { + if ( pict->format == AV_PIX_FMT_YUV420P + && (s->codec_tag == AV_RL32("GEOV") || s->codec_tag == AV_RL32("GEOX"))) { + int x, y, p; + av_frame_make_writable(pict); + for (p=0; p<3; p++) { + int w = FF_CEIL_RSHIFT(pict-> width, !!p); + int h = FF_CEIL_RSHIFT(pict->height, !!p); + int linesize = pict->linesize[p]; + for (y=0; y<(h>>1); y++) + for (x=0; xdata[p][x + y*linesize], + pict->data[p][x + (h-1-y)*linesize]); + } + } *got_frame = 1; } -#ifdef PRINT_FRAME_TIME -av_log(avctx, AV_LOG_DEBUG, "%"PRId64"\n", rdtsc()-time); -#endif - - return (ret && (avctx->err_recognition & AV_EF_EXPLODE))?ret:get_consumed_bytes(s, buf_size); + if (slice_ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) + return ret; + else + return get_consumed_bytes(s, buf_size); } const enum AVPixelFormat ff_h263_hwaccel_pixfmt_list_420[] = { @@ -782,6 +681,7 @@ const enum AVPixelFormat ff_h263_hwaccel_pixfmt_list_420[] = { AVCodec ff_h263_decoder = { .name = "h263", + .long_name = NULL_IF_CONFIG_SMALL("H.263 / H.263-1996, H.263+ / H.263-1998 / H.263 version 2"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H263, .priv_data_size = sizeof(MpegEncContext), @@ -792,12 +692,12 @@ AVCodec ff_h263_decoder = { CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY, .flush = ff_mpeg_flush, .max_lowres = 3, - .long_name = NULL_IF_CONFIG_SMALL("H.263 / H.263-1996, H.263+ / H.263-1998 / H.263 version 2"), .pix_fmts = ff_h263_hwaccel_pixfmt_list_420, }; AVCodec ff_h263p_decoder = { .name = "h263p", + .long_name = NULL_IF_CONFIG_SMALL("H.263 / H.263-1996, H.263+ / H.263-1998 / H.263 version 2"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H263P, .priv_data_size = sizeof(MpegEncContext), @@ -808,6 +708,5 @@ AVCodec ff_h263p_decoder = { CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY, .flush = ff_mpeg_flush, .max_lowres = 3, - .long_name = NULL_IF_CONFIG_SMALL("H.263 / H.263-1996, H.263+ / H.263-1998 / H.263 version 2"), .pix_fmts = ff_h263_hwaccel_pixfmt_list_420, }; diff --git a/ffmpeg/libavcodec/h264.c b/ffmpeg/libavcodec/h264.c index 87322a2..9dc9095 100644 --- a/ffmpeg/libavcodec/h264.c +++ b/ffmpeg/libavcodec/h264.c @@ -27,8 +27,10 @@ #define UNCHECKED_BITSTREAM_READER 1 +#include "libavutil/avassert.h" #include "libavutil/imgutils.h" #include "libavutil/opt.h" +#include "libavutil/stereo3d.h" #include "internal.h" #include "cabac.h" #include "cabac_functions.h" @@ -46,11 +48,11 @@ #include "svq3.h" #include "thread.h" #include "vdpau_internal.h" -#include "libavutil/avassert.h" -// #undef NDEBUG #include +static void flush_change(H264Context *h); + const uint16_t ff_h264_mb_sizes[4] = { 256, 384, 512, 768 }; static const uint8_t rem6[QP_MAX_NUM + 1] = { @@ -69,6 +71,93 @@ static const uint8_t div6[QP_MAX_NUM + 1] = { 14,14,14,14, }; +static const uint8_t field_scan[16+1] = { + 0 + 0 * 4, 0 + 1 * 4, 1 + 0 * 4, 0 + 2 * 4, + 0 + 3 * 4, 1 + 1 * 4, 1 + 2 * 4, 1 + 3 * 4, + 2 + 0 * 4, 2 + 1 * 4, 2 + 2 * 4, 2 + 3 * 4, + 3 + 0 * 4, 3 + 1 * 4, 3 + 2 * 4, 3 + 3 * 4, +}; + +static const uint8_t field_scan8x8[64+1] = { + 0 + 0 * 8, 0 + 1 * 8, 0 + 2 * 8, 1 + 0 * 8, + 1 + 1 * 8, 0 + 3 * 8, 0 + 4 * 8, 1 + 2 * 8, + 2 + 0 * 8, 1 + 3 * 8, 0 + 5 * 8, 0 + 6 * 8, + 0 + 7 * 8, 1 + 4 * 8, 2 + 1 * 8, 3 + 0 * 8, + 2 + 2 * 8, 1 + 5 * 8, 1 + 6 * 8, 1 + 7 * 8, + 2 + 3 * 8, 3 + 1 * 8, 4 + 0 * 8, 3 + 2 * 8, + 2 + 4 * 8, 2 + 5 * 8, 2 + 6 * 8, 2 + 7 * 8, + 3 + 3 * 8, 4 + 1 * 8, 5 + 0 * 8, 4 + 2 * 8, + 3 + 4 * 8, 3 + 5 * 8, 3 + 6 * 8, 3 + 7 * 8, + 4 + 3 * 8, 5 + 1 * 8, 6 + 0 * 8, 5 + 2 * 8, + 4 + 4 * 8, 4 + 5 * 8, 4 + 6 * 8, 4 + 7 * 8, + 5 + 3 * 8, 6 + 1 * 8, 6 + 2 * 8, 5 + 4 * 8, + 5 + 5 * 8, 5 + 6 * 8, 5 + 7 * 8, 6 + 3 * 8, + 7 + 0 * 8, 7 + 1 * 8, 6 + 4 * 8, 6 + 5 * 8, + 6 + 6 * 8, 6 + 7 * 8, 7 + 2 * 8, 7 + 3 * 8, + 7 + 4 * 8, 7 + 5 * 8, 7 + 6 * 8, 7 + 7 * 8, +}; + +static const uint8_t field_scan8x8_cavlc[64+1] = { + 0 + 0 * 8, 1 + 1 * 8, 2 + 0 * 8, 0 + 7 * 8, + 2 + 2 * 8, 2 + 3 * 8, 2 + 4 * 8, 3 + 3 * 8, + 3 + 4 * 8, 4 + 3 * 8, 4 + 4 * 8, 5 + 3 * 8, + 5 + 5 * 8, 7 + 0 * 8, 6 + 6 * 8, 7 + 4 * 8, + 0 + 1 * 8, 0 + 3 * 8, 1 + 3 * 8, 1 + 4 * 8, + 1 + 5 * 8, 3 + 1 * 8, 2 + 5 * 8, 4 + 1 * 8, + 3 + 5 * 8, 5 + 1 * 8, 4 + 5 * 8, 6 + 1 * 8, + 5 + 6 * 8, 7 + 1 * 8, 6 + 7 * 8, 7 + 5 * 8, + 0 + 2 * 8, 0 + 4 * 8, 0 + 5 * 8, 2 + 1 * 8, + 1 + 6 * 8, 4 + 0 * 8, 2 + 6 * 8, 5 + 0 * 8, + 3 + 6 * 8, 6 + 0 * 8, 4 + 6 * 8, 6 + 2 * 8, + 5 + 7 * 8, 6 + 4 * 8, 7 + 2 * 8, 7 + 6 * 8, + 1 + 0 * 8, 1 + 2 * 8, 0 + 6 * 8, 3 + 0 * 8, + 1 + 7 * 8, 3 + 2 * 8, 2 + 7 * 8, 4 + 2 * 8, + 3 + 7 * 8, 5 + 2 * 8, 4 + 7 * 8, 5 + 4 * 8, + 6 + 3 * 8, 6 + 5 * 8, 7 + 3 * 8, 7 + 7 * 8, +}; + +// zigzag_scan8x8_cavlc[i] = zigzag_scan8x8[(i/4) + 16*(i%4)] +static const uint8_t zigzag_scan8x8_cavlc[64+1] = { + 0 + 0 * 8, 1 + 1 * 8, 1 + 2 * 8, 2 + 2 * 8, + 4 + 1 * 8, 0 + 5 * 8, 3 + 3 * 8, 7 + 0 * 8, + 3 + 4 * 8, 1 + 7 * 8, 5 + 3 * 8, 6 + 3 * 8, + 2 + 7 * 8, 6 + 4 * 8, 5 + 6 * 8, 7 + 5 * 8, + 1 + 0 * 8, 2 + 0 * 8, 0 + 3 * 8, 3 + 1 * 8, + 3 + 2 * 8, 0 + 6 * 8, 4 + 2 * 8, 6 + 1 * 8, + 2 + 5 * 8, 2 + 6 * 8, 6 + 2 * 8, 5 + 4 * 8, + 3 + 7 * 8, 7 + 3 * 8, 4 + 7 * 8, 7 + 6 * 8, + 0 + 1 * 8, 3 + 0 * 8, 0 + 4 * 8, 4 + 0 * 8, + 2 + 3 * 8, 1 + 5 * 8, 5 + 1 * 8, 5 + 2 * 8, + 1 + 6 * 8, 3 + 5 * 8, 7 + 1 * 8, 4 + 5 * 8, + 4 + 6 * 8, 7 + 4 * 8, 5 + 7 * 8, 6 + 7 * 8, + 0 + 2 * 8, 2 + 1 * 8, 1 + 3 * 8, 5 + 0 * 8, + 1 + 4 * 8, 2 + 4 * 8, 6 + 0 * 8, 4 + 3 * 8, + 0 + 7 * 8, 4 + 4 * 8, 7 + 2 * 8, 3 + 6 * 8, + 5 + 5 * 8, 6 + 5 * 8, 6 + 6 * 8, 7 + 7 * 8, +}; + +static const uint8_t dequant4_coeff_init[6][3] = { + { 10, 13, 16 }, + { 11, 14, 18 }, + { 13, 16, 20 }, + { 14, 18, 23 }, + { 16, 20, 25 }, + { 18, 23, 29 }, +}; + +static const uint8_t dequant8_coeff_init_scan[16] = { + 0, 3, 4, 3, 3, 1, 5, 1, 4, 5, 2, 5, 3, 1, 5, 1 +}; + +static const uint8_t dequant8_coeff_init[6][6] = { + { 20, 18, 32, 19, 25, 24 }, + { 22, 19, 35, 21, 28, 26 }, + { 26, 23, 42, 24, 33, 31 }, + { 28, 25, 45, 26, 35, 33 }, + { 32, 28, 51, 30, 40, 38 }, + { 36, 32, 58, 34, 46, 43 }, +}; + static const enum AVPixelFormat h264_hwaccel_pixfmt_list_420[] = { #if CONFIG_H264_DXVA2_HWACCEL AV_PIX_FMT_DXVA2_VLD, @@ -113,7 +202,7 @@ static void h264_er_decode_mb(void *opaque, int ref, int mv_dir, int mv_type, int (*mv)[2][4][2], int mb_x, int mb_y, int mb_intra, int mb_skipped) { - H264Context *h = opaque; + H264Context *h = opaque; h->mb_x = mb_x; h->mb_y = mb_y; @@ -154,7 +243,7 @@ void ff_h264_draw_horiz_band(H264Context *h, int y, int height) const int field_pic = h->picture_structure != PICT_FRAME; if (field_pic) { height <<= 1; - y <<= 1; + y <<= 1; } height = FFMIN(height, avctx->height - y); @@ -168,7 +257,7 @@ void ff_h264_draw_horiz_band(H264Context *h, int y, int height) int i; if (cur->f.pict_type == AV_PICTURE_TYPE_B || h->low_delay || - (avctx->slice_flags & SLICE_FLAG_CODED_ORDER)) + (avctx->slice_flags & SLICE_FLAG_CODED_ORDER)) src = &cur->f; else if (last) src = &last->f; @@ -193,10 +282,9 @@ static void unref_picture(H264Context *h, Picture *pic) int off = offsetof(Picture, tf) + sizeof(pic->tf); int i; - if (!pic->f.data[0]) + if (!pic->f.buf[0]) return; - pic->period_since_free = 0; ff_thread_release_buffer(h->avctx, &pic->tf); av_buffer_unref(&pic->hwaccel_priv_buf); @@ -216,7 +304,7 @@ static void release_unused_pictures(H264Context *h, int remove_current) /* release non reference frames */ for (i = 0; i < MAX_PICTURE_COUNT; i++) { - if (h->DPB[i].f.data[0] && !h->DPB[i].reference && + if (h->DPB[i].f.buf[0] && !h->DPB[i].reference && (remove_current || &h->DPB[i] != h->cur_pic_ptr)) { unref_picture(h, &h->DPB[i]); } @@ -236,7 +324,6 @@ static int ref_picture(H264Context *h, Picture *dst, Picture *src) if (ret < 0) goto fail; - dst->qscale_table_buf = av_buffer_ref(src->qscale_table_buf); dst->mb_type_buf = av_buffer_ref(src->mb_type_buf); if (!dst->qscale_table_buf || !dst->mb_type_buf) @@ -244,7 +331,7 @@ static int ref_picture(H264Context *h, Picture *dst, Picture *src) dst->qscale_table = src->qscale_table; dst->mb_type = src->mb_type; - for (i = 0; i < 2; i ++) { + for (i = 0; i < 2; i++) { dst->motion_val_buf[i] = av_buffer_ref(src->motion_val_buf[i]); dst->ref_index_buf[i] = av_buffer_ref(src->ref_index_buf[i]); if (!dst->motion_val_buf[i] || !dst->ref_index_buf[i]) @@ -266,17 +353,19 @@ static int ref_picture(H264Context *h, Picture *dst, Picture *src) memcpy(dst->ref_poc, src->ref_poc, sizeof(src->ref_poc)); memcpy(dst->ref_count, src->ref_count, sizeof(src->ref_count)); - dst->poc = src->poc; - dst->frame_num = src->frame_num; - dst->mmco_reset = src->mmco_reset; - dst->pic_id = src->pic_id; - dst->long_ref = src->long_ref; - dst->mbaff = src->mbaff; - dst->field_picture = src->field_picture; - dst->needs_realloc = src->needs_realloc; - dst->reference = src->reference; - dst->sync = src->sync; - dst->period_since_free = src->period_since_free; + dst->poc = src->poc; + dst->frame_num = src->frame_num; + dst->mmco_reset = src->mmco_reset; + dst->pic_id = src->pic_id; + dst->long_ref = src->long_ref; + dst->mbaff = src->mbaff; + dst->field_picture = src->field_picture; + dst->needs_realloc = src->needs_realloc; + dst->reference = src->reference; + dst->crop = src->crop; + dst->crop_left = src->crop_left; + dst->crop_top = src->crop_top; + dst->recovered = src->recovered; return 0; fail: @@ -284,7 +373,6 @@ fail: return ret; } - static int alloc_scratch_buffers(H264Context *h, int linesize) { int alloc_size = FFALIGN(FFABS(linesize) + 32, 32); @@ -351,6 +439,9 @@ static int alloc_picture(H264Context *h, Picture *pic) h->linesize = pic->f.linesize[0]; h->uvlinesize = pic->f.linesize[1]; + pic->crop = h->sps.crop; + pic->crop_top = h->sps.crop_top; + pic->crop_left= h->sps.crop_left; if (h->avctx->hwaccel) { const AVHWAccel *hwaccel = h->avctx->hwaccel; @@ -395,11 +486,7 @@ fail: static inline int pic_is_unused(H264Context *h, Picture *pic) { - if ( (h->avctx->active_thread_type & FF_THREAD_FRAME) - && pic->f.qscale_table //check if the frame has anything allocated - && pic->period_since_free < h->avctx->thread_count) - return 0; - if (pic->f.data[0] == NULL) + if (!pic->f.buf[0]) return 1; if (pic->needs_realloc && !(pic->reference & DELAYED_PIC_REF)) return 1; @@ -446,7 +533,7 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h) av_log(h->avctx, AV_LOG_ERROR, "top block unavailable for requested intra4x4 mode %d at %d %d\n", status, h->mb_x, h->mb_y); - return -1; + return AVERROR_INVALIDDATA; } else if (status) { h->intra4x4_pred_mode_cache[scan8[0] + i] = status; } @@ -462,7 +549,7 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h) av_log(h->avctx, AV_LOG_ERROR, "left block unavailable for requested intra4x4 mode %d at %d %d\n", status, h->mb_x, h->mb_y); - return -1; + return AVERROR_INVALIDDATA; } else if (status) { h->intra4x4_pred_mode_cache[scan8[0] + 8 * i] = status; } @@ -478,14 +565,14 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h) */ int ff_h264_check_intra_pred_mode(H264Context *h, int mode, int is_chroma) { - static const int8_t top[7] = { LEFT_DC_PRED8x8, 1, -1, -1 }; - static const int8_t left[7] = { TOP_DC_PRED8x8, -1, 2, -1, DC_128_PRED8x8 }; + static const int8_t top[4] = { LEFT_DC_PRED8x8, 1, -1, -1 }; + static const int8_t left[5] = { TOP_DC_PRED8x8, -1, 2, -1, DC_128_PRED8x8 }; - if (mode > 6U) { + if (mode > 3U) { av_log(h->avctx, AV_LOG_ERROR, "out of range intra chroma pred mode at %d %d\n", h->mb_x, h->mb_y); - return -1; + return AVERROR_INVALIDDATA; } if (!(h->top_samples_available & 0x8000)) { @@ -494,7 +581,7 @@ int ff_h264_check_intra_pred_mode(H264Context *h, int mode, int is_chroma) av_log(h->avctx, AV_LOG_ERROR, "top block unavailable for requested intra mode at %d %d\n", h->mb_x, h->mb_y); - return -1; + return AVERROR_INVALIDDATA; } } @@ -510,7 +597,7 @@ int ff_h264_check_intra_pred_mode(H264Context *h, int mode, int is_chroma) av_log(h->avctx, AV_LOG_ERROR, "left block unavailable for requested intra mode at %d %d\n", h->mb_x, h->mb_y); - return -1; + return AVERROR_INVALIDDATA; } } @@ -532,19 +619,21 @@ const uint8_t *ff_h264_decode_nal(H264Context *h, const uint8_t *src, length--; #define STARTCODE_TEST \ - if (i + 2 < length && src[i + 1] == 0 && src[i + 2] <= 3) { \ - if (src[i + 2] != 3) { \ - /* startcode, so we must be past the end */ \ - length = i; \ - } \ - break; \ - } + if (i + 2 < length && src[i + 1] == 0 && src[i + 2] <= 3) { \ + if (src[i + 2] != 3) { \ + /* startcode, so we must be past the end */ \ + length = i; \ + } \ + break; \ + } + #if HAVE_FAST_UNALIGNED #define FIND_FIRST_ZERO \ - if (i > 0 && !src[i]) \ - i--; \ - while (src[i]) \ - i++ + if (i > 0 && !src[i]) \ + i--; \ + while (src[i]) \ + i++ + #if HAVE_FAST_64BIT for (i = 0; i + 1 < length; i += 9) { if (!((~AV_RN64A(src + i) & @@ -618,8 +707,8 @@ const uint8_t *ff_h264_decode_nal(H264Context *h, const uint8_t *src, } while (si < length) dst[di++] = src[si++]; -nsc: +nsc: memset(dst + di, 0, FF_INPUT_BUFFER_PADDING_SIZE); *dst_length = di; @@ -651,10 +740,10 @@ static int decode_rbsp_trailing(H264Context *h, const uint8_t *src) static inline int get_lowest_part_list_y(H264Context *h, Picture *pic, int n, int height, int y_offset, int list) { - int raw_my = h->mv_cache[list][scan8[n]][1]; + int raw_my = h->mv_cache[list][scan8[n]][1]; int filter_height_down = (raw_my & 3) ? 3 : 0; - int full_my = (raw_my >> 2) + y_offset; - int bottom = full_my + filter_height_down + height; + int full_my = (raw_my >> 2) + y_offset; + int bottom = full_my + filter_height_down + height; av_assert2(height >= 0); @@ -676,7 +765,7 @@ static inline void get_lowest_part_y(H264Context *h, int refs[2][48], int n, // Error resilience puts the current picture in the ref list. // Don't try to wait on these as it will cause a deadlock. // Fields can wait on each other, though. - if (ref->tf.progress->data != h->cur_pic.tf.progress->data || + if (ref->tf.progress->data != h->cur_pic.tf.progress->data || (ref->reference & 3) != h->picture_structure) { my = get_lowest_part_list_y(h, ref, n, height, y_offset, 0); if (refs[0][ref_n] < 0) @@ -825,7 +914,7 @@ static av_always_inline void mc_dir_part(H264Context *h, Picture *pic, const int mx = h->mv_cache[list][scan8[n]][0] + src_x_offset * 8; int my = h->mv_cache[list][scan8[n]][1] + src_y_offset * 8; const int luma_xy = (mx & 3) + ((my & 3) << 2); - int offset = ((mx >> 2) << pixel_shift) + (my >> 2) * h->mb_linesize; + ptrdiff_t offset = ((mx >> 2) << pixel_shift) + (my >> 2) * h->mb_linesize; uint8_t *src_y = pic->f.data[0] + offset; uint8_t *src_cb, *src_cr; int extra_width = 0; @@ -848,7 +937,7 @@ static av_always_inline void mc_dir_part(H264Context *h, Picture *pic, full_my + 16 /*FIXME*/ > pic_height + extra_height) { h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_y - (2 << pixel_shift) - 2 * h->mb_linesize, - h->mb_linesize, + h->mb_linesize, h->mb_linesize, 16 + 5, 16 + 5 /*FIXME*/, full_mx - 2, full_my - 2, pic_width, pic_height); src_y = h->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize; @@ -867,7 +956,7 @@ static av_always_inline void mc_dir_part(H264Context *h, Picture *pic, if (emu) { h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cb - (2 << pixel_shift) - 2 * h->mb_linesize, - h->mb_linesize, + h->mb_linesize, h->mb_linesize, 16 + 5, 16 + 5 /*FIXME*/, full_mx - 2, full_my - 2, pic_width, pic_height); @@ -881,7 +970,7 @@ static av_always_inline void mc_dir_part(H264Context *h, Picture *pic, if (emu) { h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cr - (2 << pixel_shift) - 2 * h->mb_linesize, - h->mb_linesize, + h->mb_linesize, h->mb_linesize, 16 + 5, 16 + 5 /*FIXME*/, full_mx - 2, full_my - 2, pic_width, pic_height); @@ -906,7 +995,8 @@ static av_always_inline void mc_dir_part(H264Context *h, Picture *pic, (my >> ysh) * h->mb_uvlinesize; if (emu) { - h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cb, h->mb_uvlinesize, + h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cb, + h->mb_uvlinesize, h->mb_uvlinesize, 9, 8 * chroma_idc + 1, (mx >> 3), (my >> ysh), pic_width >> 1, pic_height >> (chroma_idc == 1 /* yuv420 */)); src_cb = h->edge_emu_buffer; @@ -916,7 +1006,8 @@ static av_always_inline void mc_dir_part(H264Context *h, Picture *pic, mx & 7, (my << (chroma_idc == 2 /* yuv422 */)) & 7); if (emu) { - h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cr, h->mb_uvlinesize, + h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cr, + h->mb_uvlinesize, h->mb_uvlinesize, 9, 8 * chroma_idc + 1, (mx >> 3), (my >> ysh), pic_width >> 1, pic_height >> (chroma_idc == 1 /* yuv420 */)); src_cr = h->edge_emu_buffer; @@ -1122,9 +1213,6 @@ static void free_tables(H264Context *h, int free_rbsp) av_freep(&h->mb2b_xy); av_freep(&h->mb2br_xy); - for (i = 0; i < 3; i++) - av_freep(&h->visualization_buffer[i]); - av_buffer_pool_uninit(&h->qscale_table_pool); av_buffer_pool_uninit(&h->mb_type_pool); av_buffer_pool_uninit(&h->motion_val_pool); @@ -1240,8 +1328,8 @@ static void init_dequant_tables(H264Context *h) int ff_h264_alloc_tables(H264Context *h) { - const int big_mb_num = h->mb_stride * (h->mb_height + 1); - const int row_mb_num = 2*h->mb_stride*FFMAX(h->avctx->thread_count, 1); + const int big_mb_num = h->mb_stride * (h->mb_height + 1); + const int row_mb_num = 2*h->mb_stride*FFMAX(h->avctx->thread_count, 1); int x, y, i; FF_ALLOCZ_OR_GOTO(h->avctx, h->intra4x4_pred_mode, @@ -1288,15 +1376,15 @@ int ff_h264_alloc_tables(H264Context *h) if (!h->DPB) return AVERROR(ENOMEM); for (i = 0; i < MAX_PICTURE_COUNT; i++) - avcodec_get_frame_defaults(&h->DPB[i].f); - avcodec_get_frame_defaults(&h->cur_pic.f); + av_frame_unref(&h->DPB[i].f); + av_frame_unref(&h->cur_pic.f); } return 0; fail: free_tables(h, 1); - return -1; + return AVERROR(ENOMEM); } /** @@ -1351,51 +1439,51 @@ static int context_init(H264Context *h) h->ref_cache[1][scan8[13] + 1] = PART_NOT_AVAILABLE; if (CONFIG_ERROR_RESILIENCE) { - /* init ER */ - er->avctx = h->avctx; - er->dsp = &h->dsp; - er->decode_mb = h264_er_decode_mb; - er->opaque = h; - er->quarter_sample = 1; - - er->mb_num = h->mb_num; - er->mb_width = h->mb_width; - er->mb_height = h->mb_height; - er->mb_stride = h->mb_stride; - er->b8_stride = h->mb_width * 2 + 1; - - FF_ALLOCZ_OR_GOTO(h->avctx, er->mb_index2xy, (h->mb_num + 1) * sizeof(int), - fail); // error ressilience code looks cleaner with this - for (y = 0; y < h->mb_height; y++) - for (x = 0; x < h->mb_width; x++) - er->mb_index2xy[x + y * h->mb_width] = x + y * h->mb_stride; + /* init ER */ + er->avctx = h->avctx; + er->dsp = &h->dsp; + er->decode_mb = h264_er_decode_mb; + er->opaque = h; + er->quarter_sample = 1; + + er->mb_num = h->mb_num; + er->mb_width = h->mb_width; + er->mb_height = h->mb_height; + er->mb_stride = h->mb_stride; + er->b8_stride = h->mb_width * 2 + 1; - er->mb_index2xy[h->mb_height * h->mb_width] = (h->mb_height - 1) * - h->mb_stride + h->mb_width; + FF_ALLOCZ_OR_GOTO(h->avctx, er->mb_index2xy, (h->mb_num + 1) * sizeof(int), + fail); // error ressilience code looks cleaner with this + for (y = 0; y < h->mb_height; y++) + for (x = 0; x < h->mb_width; x++) + er->mb_index2xy[x + y * h->mb_width] = x + y * h->mb_stride; - FF_ALLOCZ_OR_GOTO(h->avctx, er->error_status_table, - mb_array_size * sizeof(uint8_t), fail); + er->mb_index2xy[h->mb_height * h->mb_width] = (h->mb_height - 1) * + h->mb_stride + h->mb_width; - FF_ALLOC_OR_GOTO(h->avctx, er->mbintra_table, mb_array_size, fail); - memset(er->mbintra_table, 1, mb_array_size); + FF_ALLOCZ_OR_GOTO(h->avctx, er->error_status_table, + mb_array_size * sizeof(uint8_t), fail); - FF_ALLOCZ_OR_GOTO(h->avctx, er->mbskip_table, mb_array_size + 2, fail); + FF_ALLOC_OR_GOTO(h->avctx, er->mbintra_table, mb_array_size, fail); + memset(er->mbintra_table, 1, mb_array_size); - FF_ALLOC_OR_GOTO(h->avctx, er->er_temp_buffer, h->mb_height * h->mb_stride, - fail); + FF_ALLOCZ_OR_GOTO(h->avctx, er->mbskip_table, mb_array_size + 2, fail); - FF_ALLOCZ_OR_GOTO(h->avctx, h->dc_val_base, yc_size * sizeof(int16_t), fail); - er->dc_val[0] = h->dc_val_base + h->mb_width * 2 + 2; - er->dc_val[1] = h->dc_val_base + y_size + h->mb_stride + 1; - er->dc_val[2] = er->dc_val[1] + c_size; - for (i = 0; i < yc_size; i++) - h->dc_val_base[i] = 1024; + FF_ALLOC_OR_GOTO(h->avctx, er->er_temp_buffer, h->mb_height * h->mb_stride, + fail); + + FF_ALLOCZ_OR_GOTO(h->avctx, h->dc_val_base, yc_size * sizeof(int16_t), fail); + er->dc_val[0] = h->dc_val_base + h->mb_width * 2 + 2; + er->dc_val[1] = h->dc_val_base + y_size + h->mb_stride + 1; + er->dc_val[2] = er->dc_val[1] + c_size; + for (i = 0; i < yc_size; i++) + h->dc_val_base[i] = 1024; } return 0; fail: - return -1; // free_tables will clean up for us + return AVERROR(ENOMEM); // free_tables will clean up for us } static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size, @@ -1404,6 +1492,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size, int ff_h264_decode_extradata(H264Context *h, const uint8_t *buf, int size) { AVCodecContext *avctx = h->avctx; + int ret; if (!buf || size <= 0) return -1; @@ -1416,7 +1505,7 @@ int ff_h264_decode_extradata(H264Context *h, const uint8_t *buf, int size) if (size < 7) { av_log(avctx, AV_LOG_ERROR, "avcC too short\n"); - return -1; + return AVERROR_INVALIDDATA; } /* sps and pps in the avcC always have length coded with 2 bytes, * so put a fake nal_length_size = 2 while parsing them */ @@ -1427,11 +1516,12 @@ int ff_h264_decode_extradata(H264Context *h, const uint8_t *buf, int size) for (i = 0; i < cnt; i++) { nalsize = AV_RB16(p) + 2; if(nalsize > size - (p-buf)) - return -1; - if (decode_nal_units(h, p, nalsize, 1) < 0) { + return AVERROR_INVALIDDATA; + ret = decode_nal_units(h, p, nalsize, 1); + if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Decoding sps %d from avcC failed\n", i); - return -1; + return ret; } p += nalsize; } @@ -1440,11 +1530,12 @@ int ff_h264_decode_extradata(H264Context *h, const uint8_t *buf, int size) for (i = 0; i < cnt; i++) { nalsize = AV_RB16(p) + 2; if(nalsize > size - (p-buf)) - return -1; - if (decode_nal_units(h, p, nalsize, 1) < 0) { + return AVERROR_INVALIDDATA; + ret = decode_nal_units(h, p, nalsize, 1); + if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Decoding pps %d from avcC failed\n", i); - return -1; + return ret; } p += nalsize; } @@ -1452,8 +1543,9 @@ int ff_h264_decode_extradata(H264Context *h, const uint8_t *buf, int size) h->nal_length_size = (buf[4] & 0x03) + 1; } else { h->is_avc = 0; - if (decode_nal_units(h, buf, size, 1) < 0) - return -1; + ret = decode_nal_units(h, buf, size, 1); + if (ret < 0) + return ret; } return size; } @@ -1462,12 +1554,10 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx) { H264Context *h = avctx->priv_data; int i; + int ret; h->avctx = avctx; - h->width = h->avctx->width; - h->height = h->avctx->height; - h->bit_depth_luma = 8; h->chroma_format_idc = 1; @@ -1481,11 +1571,11 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx) ff_h264_pred_init(&h->hpc, h->avctx->codec_id, 8, 1); h->dequant_coeff_pps = -1; + h->current_sps_id = -1; - if (CONFIG_ERROR_RESILIENCE) { - /* needed so that IDCT permutation is known early */ + /* needed so that IDCT permutation is known early */ + if (CONFIG_ERROR_RESILIENCE) ff_dsputil_init(&h->dsp, h->avctx); - } ff_videodsp_init(&h->vdsp, 8); memset(h->pps.scaling_matrix4, 16, 6 * 16 * sizeof(uint8_t)); @@ -1505,7 +1595,9 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx) ff_h264_decode_init_vlc(); - h->pixel_shift = 0; + ff_init_cabac_states(); + + h->pixel_shift = 0; h->sps.bit_depth_luma = avctx->bits_per_raw_sample = 8; h->thread_context[0] = h; @@ -1515,6 +1607,7 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx) h->prev_poc_msb = 1 << 16; h->prev_frame_num = -1; h->x264_build = -1; + h->sei_fpa.frame_packing_arrangement_cancel_flag = -1; ff_h264_reset_sei(h); if (avctx->codec_id == AV_CODEC_ID_H264) { if (avctx->ticks_per_frame == 1) { @@ -1526,10 +1619,12 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx) avctx->ticks_per_frame = 2; } - if (avctx->extradata_size > 0 && avctx->extradata && - ff_h264_decode_extradata(h, avctx->extradata, avctx->extradata_size) < 0) { - ff_h264_free_context(h); - return -1; + if (avctx->extradata_size > 0 && avctx->extradata) { + ret = ff_h264_decode_extradata(h, avctx->extradata, avctx->extradata_size); + if (ret < 0) { + ff_h264_free_context(h); + return ret; + } } if (h->sps.bitstream_restriction_flag && @@ -1538,9 +1633,10 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx) h->low_delay = 0; } - ff_init_cabac_states(); avctx->internal->allocate_progress = 1; + flush_change(h); + return 0; } @@ -1548,8 +1644,8 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx) #undef REBASE_PICTURE #define REBASE_PICTURE(pic, new_ctx, old_ctx) \ ((pic && pic >= old_ctx->DPB && \ - pic < old_ctx->DPB + MAX_PICTURE_COUNT) ? \ - &new_ctx->DPB[pic - old_ctx->DPB] : NULL) + pic < old_ctx->DPB + MAX_PICTURE_COUNT) ? \ + &new_ctx->DPB[pic - old_ctx->DPB] : NULL) static void copy_picture_range(Picture **to, Picture **from, int count, H264Context *new_base, @@ -1566,19 +1662,24 @@ static void copy_picture_range(Picture **to, Picture **from, int count, } } -static void copy_parameter_set(void **to, void **from, int count, int size) +static int copy_parameter_set(void **to, void **from, int count, int size) { int i; for (i = 0; i < count; i++) { - if (to[i] && !from[i]) + if (to[i] && !from[i]) { av_freep(&to[i]); - else if (from[i] && !to[i]) + } else if (from[i] && !to[i]) { to[i] = av_malloc(size); + if (!to[i]) + return AVERROR(ENOMEM); + } if (from[i]) memcpy(to[i], from[i], size); } + + return 0; } static int decode_init_thread_copy(AVCodecContext *avctx) @@ -1590,6 +1691,10 @@ static int decode_init_thread_copy(AVCodecContext *avctx) memset(h->sps_buffers, 0, sizeof(h->sps_buffers)); memset(h->pps_buffers, 0, sizeof(h->pps_buffers)); + h->rbsp_buffer[0] = NULL; + h->rbsp_buffer[1] = NULL; + h->rbsp_buffer_size[0] = 0; + h->rbsp_buffer_size[1] = 0; h->context_initialized = 0; return 0; @@ -1615,10 +1720,10 @@ static int decode_update_thread_context(AVCodecContext *dst, return 0; if (inited && - (h->width != h1->width || - h->height != h1->height || - h->mb_width != h1->mb_width || - h->mb_height != h1->mb_height || + (h->width != h1->width || + h->height != h1->height || + h->mb_width != h1->mb_width || + h->mb_height != h1->mb_height || h->sps.bit_depth_luma != h1->sps.bit_depth_luma || h->sps.chroma_format_idc != h1->sps.chroma_format_idc || h->sps.colorspace != h1->sps.colorspace)) { @@ -1638,11 +1743,15 @@ static int decode_update_thread_context(AVCodecContext *dst, h->mb_stride = h1->mb_stride; h->b_stride = h1->b_stride; // SPS/PPS - copy_parameter_set((void **)h->sps_buffers, (void **)h1->sps_buffers, - MAX_SPS_COUNT, sizeof(SPS)); + if ((ret = copy_parameter_set((void **)h->sps_buffers, + (void **)h1->sps_buffers, + MAX_SPS_COUNT, sizeof(SPS))) < 0) + return ret; h->sps = h1->sps; - copy_parameter_set((void **)h->pps_buffers, (void **)h1->pps_buffers, - MAX_PPS_COUNT, sizeof(PPS)); + if ((ret = copy_parameter_set((void **)h->pps_buffers, + (void **)h1->pps_buffers, + MAX_PPS_COUNT, sizeof(PPS))) < 0) + return ret; h->pps = h1->pps; if ((err = h264_slice_header_init(h, 1)) < 0) { @@ -1672,6 +1781,8 @@ static int decode_update_thread_context(AVCodecContext *dst, for (i = 0; i < MAX_PPS_COUNT; i++) av_freep(h->pps_buffers + i); + av_freep(&h->rbsp_buffer[0]); + av_freep(&h->rbsp_buffer[1]); memcpy(h, h1, offsetof(H264Context, intra_pcm_ptr)); memcpy(&h->cabac, &h1->cabac, sizeof(H264Context) - offsetof(H264Context, cabac)); @@ -1682,31 +1793,40 @@ static int decode_update_thread_context(AVCodecContext *dst, memset(&h->er, 0, sizeof(h->er)); memset(&h->me, 0, sizeof(h->me)); - h->avctx = dst; - h->DPB = NULL; + memset(&h->mb, 0, sizeof(h->mb)); + memset(&h->mb_luma_dc, 0, sizeof(h->mb_luma_dc)); + memset(&h->mb_padding, 0, sizeof(h->mb_padding)); + + h->avctx = dst; + h->DPB = NULL; h->qscale_table_pool = NULL; - h->mb_type_pool = NULL; - h->ref_index_pool = NULL; - h->motion_val_pool = NULL; + h->mb_type_pool = NULL; + h->ref_index_pool = NULL; + h->motion_val_pool = NULL; + for (i = 0; i < 2; i++) { + h->rbsp_buffer[i] = NULL; + h->rbsp_buffer_size[i] = 0; + } if (h1->context_initialized) { h->context_initialized = 0; memset(&h->cur_pic, 0, sizeof(h->cur_pic)); - avcodec_get_frame_defaults(&h->cur_pic.f); + av_frame_unref(&h->cur_pic.f); h->cur_pic.tf.f = &h->cur_pic.f; - if (ff_h264_alloc_tables(h) < 0) { + ret = ff_h264_alloc_tables(h); + if (ret < 0) { av_log(dst, AV_LOG_ERROR, "Could not allocate memory for h264\n"); - return AVERROR(ENOMEM); + return ret; + } + ret = context_init(h); + if (ret < 0) { + av_log(dst, AV_LOG_ERROR, "context_init() failed.\n"); + return ret; } - context_init(h); } - for (i = 0; i < 2; i++) { - h->rbsp_buffer[i] = NULL; - h->rbsp_buffer_size[i] = 0; - } h->bipred_scratchpad = NULL; h->edge_emu_buffer = NULL; @@ -1727,14 +1847,13 @@ static int decode_update_thread_context(AVCodecContext *dst, h->low_delay = h1->low_delay; for (i = 0; h->DPB && i < MAX_PICTURE_COUNT; i++) { - h->DPB[i].period_since_free ++; unref_picture(h, &h->DPB[i]); - if (h1->DPB[i].f.data[0] && + if (h1->DPB && h1->DPB[i].f.buf[0] && (ret = ref_picture(h, &h->DPB[i], &h1->DPB[i])) < 0) return ret; } - h->cur_pic_ptr = REBASE_PICTURE(h1->cur_pic_ptr, h, h1); + h->cur_pic_ptr = REBASE_PICTURE(h1->cur_pic_ptr, h, h1); unref_picture(h, &h->cur_pic); if (h1->cur_pic.f.buf[0] && (ret = ref_picture(h, &h->cur_pic, &h1->cur_pic)) < 0) return ret; @@ -1747,11 +1866,15 @@ static int decode_update_thread_context(AVCodecContext *dst, h->is_avc = h1->is_avc; // SPS/PPS - copy_parameter_set((void **)h->sps_buffers, (void **)h1->sps_buffers, - MAX_SPS_COUNT, sizeof(SPS)); + if ((ret = copy_parameter_set((void **)h->sps_buffers, + (void **)h1->sps_buffers, + MAX_SPS_COUNT, sizeof(SPS))) < 0) + return ret; h->sps = h1->sps; - copy_parameter_set((void **)h->pps_buffers, (void **)h1->pps_buffers, - MAX_PPS_COUNT, sizeof(PPS)); + if ((ret = copy_parameter_set((void **)h->pps_buffers, + (void **)h1->pps_buffers, + MAX_PPS_COUNT, sizeof(PPS))) < 0) + return ret; h->pps = h1->pps; // Dequantization matrices @@ -1779,9 +1902,7 @@ static int decode_update_thread_context(AVCodecContext *dst, copy_picture_range(h->delayed_pic, h1->delayed_pic, MAX_DELAYED_PIC_COUNT + 2, h, h1); - h->last_slice_type = h1->last_slice_type; - h->sync = h1->sync; - memcpy(h->last_ref_count, h1->last_ref_count, sizeof(h->last_ref_count)); + h->frame_recovered = h1->frame_recovered; if (context_reinitialized) h264_set_parameter_from_sps(h); @@ -1798,6 +1919,8 @@ static int decode_update_thread_context(AVCodecContext *dst, h->prev_frame_num = h->frame_num; h->outputed_poc = h->next_outputed_poc; + h->recovery_frame = h1->recovery_frame; + return err; } @@ -1828,7 +1951,7 @@ static int h264_frame_start(H264Context *h) } pic = &h->DPB[i]; - pic->reference = h->droppable ? 0 : h->picture_structure; + pic->reference = h->droppable ? 0 : h->picture_structure; pic->f.coded_picture_number = h->coded_picture_number++; pic->field_picture = h->picture_structure != PICT_FRAME; @@ -1838,12 +1961,12 @@ static int h264_frame_start(H264Context *h) * See decode_nal_units(). */ pic->f.key_frame = 0; - pic->sync = 0; pic->mmco_reset = 0; + pic->recovered = 0; if ((ret = alloc_picture(h, pic)) < 0) return ret; - if(!h->sync && !h->avctx->hwaccel && + if(!h->frame_recovered && !h->avctx->hwaccel && !(h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)) avpriv_color_frame(&pic->f, c); @@ -1871,11 +1994,6 @@ static int h264_frame_start(H264Context *h) h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3); } - /* Some macroblocks can be accessed before they're available in case - * of lost slices, MBAFF or threading. */ - memset(h->slice_table, -1, - (h->mb_height * h->mb_stride - 1) * sizeof(*h->slice_table)); - // s->decode = (h->flags & CODEC_FLAG_PSNR) || !s->encoding || // h->cur_pic.reference /* || h->contains_intra */ || 1; @@ -1908,7 +2026,7 @@ static void decode_postinit(H264Context *h, int setup_finished) Picture *cur = h->cur_pic_ptr; int i, pics, out_of_order, out_idx; - h->cur_pic_ptr->f.pict_type = h->pict_type; + h->cur_pic_ptr->f.pict_type = h->pict_type; if (h->next_output_pic) return; @@ -1988,8 +2106,49 @@ static void decode_postinit(H264Context *h, int setup_finished) } } + if (h->sei_frame_packing_present && + h->frame_packing_arrangement_type >= 0 && + h->frame_packing_arrangement_type <= 6 && + h->content_interpretation_type > 0 && + h->content_interpretation_type < 3) { + AVStereo3D *stereo = av_stereo3d_create_side_data(&cur->f); + if (!stereo) + return; + + switch (h->frame_packing_arrangement_type) { + case 0: + stereo->type = AV_STEREO3D_CHECKERBOARD; + break; + case 1: + stereo->type = AV_STEREO3D_LINES; + break; + case 2: + stereo->type = AV_STEREO3D_COLUMNS; + break; + case 3: + if (h->quincunx_subsampling) + stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX; + else + stereo->type = AV_STEREO3D_SIDEBYSIDE; + break; + case 4: + stereo->type = AV_STEREO3D_TOPBOTTOM; + break; + case 5: + stereo->type = AV_STEREO3D_FRAMESEQUENCE; + break; + case 6: + stereo->type = AV_STEREO3D_2D; + break; + } + + if (h->content_interpretation_type == 2) + stereo->flags = AV_STEREO3D_FLAG_INVERT; + } + cur->mmco_reset = h->mmco_reset; h->mmco_reset = 0; + // FIXME do something with unavailable reference frames /* Sort B-frames into display order */ @@ -2041,7 +2200,7 @@ static void decode_postinit(H264Context *h, int setup_finished) if (cur->reference == 0) cur->reference = DELAYED_PIC_REF; - out = h->delayed_pic[0]; + out = h->delayed_pic[0]; out_idx = 0; for (i = 1; h->delayed_pic[i] && !h->delayed_pic[i]->f.key_frame && @@ -2073,11 +2232,16 @@ static void decode_postinit(H264Context *h, int setup_finished) av_log(h->avctx, AV_LOG_DEBUG, "no picture %s\n", out_of_order ? "ooo" : ""); } - if (h->next_output_pic && h->next_output_pic->sync) { - h->sync |= 2; + if (h->next_output_pic) { + if (h->next_output_pic->recovered) { + // We have reached an recovery point and all frames after it in + // display order are "recovered". + h->frame_recovered |= FRAME_RECOVERED_SEI; + } + h->next_output_pic->recovered |= !!(h->frame_recovered & FRAME_RECOVERED_SEI); } - if (setup_finished) + if (setup_finished && !h->avctx->hwaccel) ff_thread_finish_setup(h->avctx); } @@ -2089,8 +2253,8 @@ static av_always_inline void backup_mb_border(H264Context *h, uint8_t *src_y, uint8_t *top_border; int top_idx = 1; const int pixel_shift = h->pixel_shift; - int chroma444 = CHROMA444; - int chroma422 = CHROMA422; + int chroma444 = CHROMA444(h); + int chroma422 = CHROMA422(h); src_y -= linesize; src_cb -= uvlinesize; @@ -2237,23 +2401,21 @@ static av_always_inline void xchg_mb_border(H264Context *h, uint8_t *src_y, XCHG(h->top_borders[top_idx][h->mb_x + 1], src_y + (17 << pixel_shift), 1); } - } - if (simple || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) { - if (chroma444) { - if (deblock_topleft) { - XCHG(top_border_m1 + (24 << pixel_shift), src_cb - (7 << pixel_shift), 1); - XCHG(top_border_m1 + (40 << pixel_shift), src_cr - (7 << pixel_shift), 1); - } - XCHG(top_border + (16 << pixel_shift), src_cb + (1 << pixel_shift), xchg); - XCHG(top_border + (24 << pixel_shift), src_cb + (9 << pixel_shift), 1); - XCHG(top_border + (32 << pixel_shift), src_cr + (1 << pixel_shift), xchg); - XCHG(top_border + (40 << pixel_shift), src_cr + (9 << pixel_shift), 1); - if (h->mb_x + 1 < h->mb_width) { - XCHG(h->top_borders[top_idx][h->mb_x + 1] + (16 << pixel_shift), src_cb + (17 << pixel_shift), 1); - XCHG(h->top_borders[top_idx][h->mb_x + 1] + (32 << pixel_shift), src_cr + (17 << pixel_shift), 1); - } - } else { - if (deblock_top) { + if (simple || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) { + if (chroma444) { + if (deblock_topleft) { + XCHG(top_border_m1 + (24 << pixel_shift), src_cb - (7 << pixel_shift), 1); + XCHG(top_border_m1 + (40 << pixel_shift), src_cr - (7 << pixel_shift), 1); + } + XCHG(top_border + (16 << pixel_shift), src_cb + (1 << pixel_shift), xchg); + XCHG(top_border + (24 << pixel_shift), src_cb + (9 << pixel_shift), 1); + XCHG(top_border + (32 << pixel_shift), src_cr + (1 << pixel_shift), xchg); + XCHG(top_border + (40 << pixel_shift), src_cr + (9 << pixel_shift), 1); + if (h->mb_x + 1 < h->mb_width) { + XCHG(h->top_borders[top_idx][h->mb_x + 1] + (16 << pixel_shift), src_cb + (17 << pixel_shift), 1); + XCHG(h->top_borders[top_idx][h->mb_x + 1] + (32 << pixel_shift), src_cr + (17 << pixel_shift), 1); + } + } else { if (deblock_topleft) { XCHG(top_border_m1 + (16 << pixel_shift), src_cb - (7 << pixel_shift), 1); XCHG(top_border_m1 + (24 << pixel_shift), src_cr - (7 << pixel_shift), 1); @@ -2300,8 +2462,8 @@ static av_always_inline void hl_decode_mb_predict_luma(H264Context *h, if (IS_INTRA4x4(mb_type)) { if (IS_8x8DCT(mb_type)) { if (transform_bypass) { - idct_dc_add = - idct_add = h->h264dsp.h264_add_pixels8_clear; + idct_dc_add = + idct_add = h->h264dsp.h264_add_pixels8_clear; } else { idct_dc_add = h->h264dsp.h264_idct8_dc_add; idct_add = h->h264dsp.h264_idct8_add; @@ -2384,7 +2546,8 @@ static av_always_inline void hl_decode_mb_predict_luma(H264Context *h, 0 * 16, 1 * 16, 4 * 16, 5 * 16, 2 * 16, 3 * 16, 6 * 16, 7 * 16, 8 * 16, 9 * 16, 12 * 16, 13 * 16, - 10 * 16, 11 * 16, 14 * 16, 15 * 16 }; + 10 * 16, 11 * 16, 14 * 16, 15 * 16 + }; for (i = 0; i < 16; i++) dctcoef_set(h->mb + (p * 256 << pixel_shift), pixel_shift, dc_mapping[i], @@ -2484,9 +2647,10 @@ void ff_h264_hl_decode_mb(H264Context *h) { const int mb_xy = h->mb_xy; const int mb_type = h->cur_pic.mb_type[mb_xy]; - int is_complex = CONFIG_SMALL || h->is_complex || IS_INTRA_PCM(mb_type) || h->qscale == 0; + int is_complex = CONFIG_SMALL || h->is_complex || + IS_INTRA_PCM(mb_type) || h->qscale == 0; - if (CHROMA444) { + if (CHROMA444(h)) { if (is_complex || h->pixel_shift) hl_decode_mb_444_complex(h); else @@ -2499,7 +2663,7 @@ void ff_h264_hl_decode_mb(H264Context *h) hl_decode_mb_simple_8(h); } -static int pred_weight_table(H264Context *h) +int ff_pred_weight_table(H264Context *h) { int list, i; int luma_def, chroma_def; @@ -2541,7 +2705,7 @@ static int pred_weight_table(H264Context *h) h->chroma_weight[i][list][j][1] = get_se_golomb(&h->gb); if (h->chroma_weight[i][list][j][0] != chroma_def || h->chroma_weight[i][list][j][1] != 0) { - h->use_weight_chroma = 1; + h->use_weight_chroma = 1; h->chroma_weight_flag[list] = 1; } } @@ -2583,7 +2747,7 @@ static void implicit_weight_table(H264Context *h, int field) } if (h->ref_count[0] == 1 && h->ref_count[1] == 1 && !FRAME_MBAFF(h) && h->ref_list[0][0].poc + h->ref_list[1][0].poc == 2 * cur_poc) { - h->use_weight = 0; + h->use_weight = 0; h->use_weight_chroma = 0; return; } @@ -2647,7 +2811,7 @@ static void flush_change(H264Context *h) { int i, j; - h->outputed_poc = h->next_outputed_poc = INT_MIN; + h->outputed_poc = h->next_outputed_poc = INT_MIN; h->prev_interlaced_frame = 1; idr(h); @@ -2665,10 +2829,11 @@ static void flush_change(H264Context *h) memset(h->default_ref_list[0], 0, sizeof(h->default_ref_list[0])); memset(h->default_ref_list[1], 0, sizeof(h->default_ref_list[1])); ff_h264_reset_sei(h); - h->recovery_frame= -1; - h->sync= 0; + h->recovery_frame = -1; + h->frame_recovered = 0; h->list_count = 0; h->current_slice = 0; + h->mmco_reset = 1; } /* forget old pics after a seek */ @@ -2699,13 +2864,15 @@ static void flush_dpb(AVCodecContext *avctx) h->parse_context.overread_index = 0; h->parse_context.index = 0; h->parse_context.last_index = 0; + + free_tables(h, 1); + h->context_initialized = 0; } -static int init_poc(H264Context *h) +int ff_init_poc(H264Context *h, int pic_field_poc[2], int *pic_poc) { const int max_frame_num = 1 << h->sps.log2_max_frame_num; int field_poc[2]; - Picture *cur = h->cur_pic_ptr; h->frame_num_offset = h->prev_frame_num_offset; if (h->frame_num < h->prev_frame_num) @@ -2714,9 +2881,11 @@ static int init_poc(H264Context *h) if (h->sps.poc_type == 0) { const int max_poc_lsb = 1 << h->sps.log2_max_poc_lsb; - if (h->poc_lsb < h->prev_poc_lsb && h->prev_poc_lsb - h->poc_lsb >= max_poc_lsb / 2) + if (h->poc_lsb < h->prev_poc_lsb && + h->prev_poc_lsb - h->poc_lsb >= max_poc_lsb / 2) h->poc_msb = h->prev_poc_msb + max_poc_lsb; - else if (h->poc_lsb > h->prev_poc_lsb && h->prev_poc_lsb - h->poc_lsb < -max_poc_lsb / 2) + else if (h->poc_lsb > h->prev_poc_lsb && + h->prev_poc_lsb - h->poc_lsb < -max_poc_lsb / 2) h->poc_msb = h->prev_poc_msb - max_poc_lsb; else h->poc_msb = h->prev_poc_msb; @@ -2770,10 +2939,10 @@ static int init_poc(H264Context *h) } if (h->picture_structure != PICT_BOTTOM_FIELD) - h->cur_pic_ptr->field_poc[0] = field_poc[0]; + pic_field_poc[0] = field_poc[0]; if (h->picture_structure != PICT_TOP_FIELD) - h->cur_pic_ptr->field_poc[1] = field_poc[1]; - cur->poc = FFMIN(cur->field_poc[0], cur->field_poc[1]); + pic_field_poc[1] = field_poc[1]; + *pic_poc = FFMIN(pic_field_poc[0], pic_field_poc[1]); return 0; } @@ -2821,10 +2990,6 @@ static int field_end(H264Context *h, int in_setup) int err = 0; h->mb_y = 0; - if (!in_setup && !h->droppable) - ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, - h->picture_structure == PICT_BOTTOM_FIELD); - if (CONFIG_H264_VDPAU_DECODER && h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) ff_vdpau_h264_set_reference_frames(h); @@ -2862,11 +3027,13 @@ static int field_end(H264Context *h, int in_setup) * past end by one (callers fault) and resync_mb_y != 0 * causes problems for the first MB line, too. */ - if (CONFIG_ERROR_RESILIENCE && - !FIELD_PICTURE(h) && h->current_slice && !h->sps.new) { + if (CONFIG_ERROR_RESILIENCE && !FIELD_PICTURE(h) && h->current_slice && !h->sps.new) { h->er.cur_pic = h->cur_pic_ptr; ff_er_frame_end(&h->er); } + if (!in_setup && !h->droppable) + ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, + h->picture_structure == PICT_BOTTOM_FIELD); emms_c(); h->current_slice = 0; @@ -2971,9 +3138,9 @@ static int h264_set_parameter_from_sps(H264Context *h) ff_h264qpel_init(&h->h264qpel, h->sps.bit_depth_luma); ff_h264_pred_init(&h->hpc, h->avctx->codec_id, h->sps.bit_depth_luma, h->sps.chroma_format_idc); - if (CONFIG_ERROR_RESILIENCE) { + + if (CONFIG_ERROR_RESILIENCE) ff_dsputil_init(&h->dsp, h->avctx); - } ff_videodsp_init(&h->vdsp, h->sps.bit_depth_luma); } else { av_log(h->avctx, AV_LOG_ERROR, "Unsupported bit depth: %d\n", @@ -2988,51 +3155,51 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback) { switch (h->sps.bit_depth_luma) { case 9: - if (CHROMA444) { + if (CHROMA444(h)) { if (h->avctx->colorspace == AVCOL_SPC_RGB) { return AV_PIX_FMT_GBRP9; } else return AV_PIX_FMT_YUV444P9; - } else if (CHROMA422) + } else if (CHROMA422(h)) return AV_PIX_FMT_YUV422P9; else return AV_PIX_FMT_YUV420P9; break; case 10: - if (CHROMA444) { + if (CHROMA444(h)) { if (h->avctx->colorspace == AVCOL_SPC_RGB) { return AV_PIX_FMT_GBRP10; } else return AV_PIX_FMT_YUV444P10; - } else if (CHROMA422) + } else if (CHROMA422(h)) return AV_PIX_FMT_YUV422P10; else return AV_PIX_FMT_YUV420P10; break; case 12: - if (CHROMA444) { + if (CHROMA444(h)) { if (h->avctx->colorspace == AVCOL_SPC_RGB) { return AV_PIX_FMT_GBRP12; } else return AV_PIX_FMT_YUV444P12; - } else if (CHROMA422) + } else if (CHROMA422(h)) return AV_PIX_FMT_YUV422P12; else return AV_PIX_FMT_YUV420P12; break; case 14: - if (CHROMA444) { + if (CHROMA444(h)) { if (h->avctx->colorspace == AVCOL_SPC_RGB) { return AV_PIX_FMT_GBRP14; } else return AV_PIX_FMT_YUV444P14; - } else if (CHROMA422) + } else if (CHROMA422(h)) return AV_PIX_FMT_YUV422P14; else return AV_PIX_FMT_YUV420P14; break; case 8: - if (CHROMA444) { + if (CHROMA444(h)) { if (h->avctx->colorspace == AVCOL_SPC_RGB) { av_log(h->avctx, AV_LOG_DEBUG, "Detected GBR colorspace.\n"); return AV_PIX_FMT_GBR24P; @@ -3041,7 +3208,7 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback) } return h->avctx->color_range == AVCOL_RANGE_JPEG ? AV_PIX_FMT_YUVJ444P : AV_PIX_FMT_YUV444P; - } else if (CHROMA422) { + } else if (CHROMA422(h)) { return h->avctx->color_range == AVCOL_RANGE_JPEG ? AV_PIX_FMT_YUVJ422P : AV_PIX_FMT_YUV422P; } else { @@ -3055,7 +3222,7 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback) for (i=0; fmt[i] != AV_PIX_FMT_NONE; i++) if (fmt[i] == h->avctx->pix_fmt && !force_callback) return fmt[i]; - return h->avctx->get_format(h->avctx, fmt); + return ff_thread_get_format(h->avctx, fmt); } break; default: @@ -3065,26 +3232,50 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback) } } +/* export coded and cropped frame dimensions to AVCodecContext */ +static int init_dimensions(H264Context *h) +{ + int width = h->width - (h->sps.crop_right + h->sps.crop_left); + int height = h->height - (h->sps.crop_top + h->sps.crop_bottom); + av_assert0(h->sps.crop_right + h->sps.crop_left < (unsigned)h->width); + av_assert0(h->sps.crop_top + h->sps.crop_bottom < (unsigned)h->height); + + /* handle container cropping */ + if (!h->sps.crop && + FFALIGN(h->avctx->width, 16) == h->width && + FFALIGN(h->avctx->height, 16) == h->height) { + width = h->avctx->width; + height = h->avctx->height; + } + + if (width <= 0 || height <= 0) { + av_log(h->avctx, AV_LOG_ERROR, "Invalid cropped dimensions: %dx%d.\n", + width, height); + if (h->avctx->err_recognition & AV_EF_EXPLODE) + return AVERROR_INVALIDDATA; + + av_log(h->avctx, AV_LOG_WARNING, "Ignoring cropping information.\n"); + h->sps.crop_bottom = h->sps.crop_top = h->sps.crop_right = h->sps.crop_left = 0; + h->sps.crop = 0; + + width = h->width; + height = h->height; + } + + h->avctx->coded_width = h->width; + h->avctx->coded_height = h->height; + h->avctx->width = width; + h->avctx->height = height; + + return 0; +} + static int h264_slice_header_init(H264Context *h, int reinit) { int nb_slices = (HAVE_THREADS && h->avctx->active_thread_type & FF_THREAD_SLICE) ? h->avctx->thread_count : 1; - int i; - - if( FFALIGN(h->avctx->width , 16 ) == h->width - && FFALIGN(h->avctx->height, 16*(2 - h->sps.frame_mbs_only_flag)) == h->height - && !h->sps.crop_right && !h->sps.crop_bottom - && (h->avctx->width != h->width || h->avctx->height && h->height) - ) { - av_log(h->avctx, AV_LOG_DEBUG, "Using externally provided dimensions\n"); - h->avctx->coded_width = h->width; - h->avctx->coded_height = h->height; - } else{ - avcodec_set_dimensions(h->avctx, h->width, h->height); - h->avctx->width -= (2>>CHROMA444)*FFMIN(h->sps.crop_right, (8<avctx->height -= (1<chroma_y_shift)*FFMIN(h->sps.crop_bottom, (16>>h->chroma_y_shift)-1) * (2 - h->sps.frame_mbs_only_flag); - } + int i, ret; h->avctx->sample_aspect_ratio = h->sps.sar; av_assert0(h->avctx->sample_aspect_ratio.den); @@ -3099,18 +3290,19 @@ static int h264_slice_header_init(H264Context *h, int reinit) h->sps.num_units_in_tick, den, 1 << 30); } - h->avctx->hwaccel = ff_find_hwaccel(h->avctx->codec->id, h->avctx->pix_fmt); + h->avctx->hwaccel = ff_find_hwaccel(h->avctx); if (reinit) free_tables(h, 0); - h->first_field = 0; + h->first_field = 0; h->prev_interlaced_frame = 1; init_scan_tables(h); - if (ff_h264_alloc_tables(h) < 0) { + ret = ff_h264_alloc_tables(h); + if (ret < 0) { av_log(h->avctx, AV_LOG_ERROR, "Could not allocate memory for h264\n"); - return AVERROR(ENOMEM); + return ret; } if (nb_slices > MAX_THREADS || (nb_slices > h->mb_height && h->mb_height)) { @@ -3126,43 +3318,46 @@ static int h264_slice_header_init(H264Context *h, int reinit) h->slice_context_count = nb_slices; if (!HAVE_THREADS || !(h->avctx->active_thread_type & FF_THREAD_SLICE)) { - if (context_init(h) < 0) { + ret = context_init(h); + if (ret < 0) { av_log(h->avctx, AV_LOG_ERROR, "context_init() failed.\n"); - return -1; + return ret; } } else { for (i = 1; i < h->slice_context_count; i++) { H264Context *c; - c = h->thread_context[i] = av_mallocz(sizeof(H264Context)); - c->avctx = h->avctx; + c = h->thread_context[i] = av_mallocz(sizeof(H264Context)); + if (!c) + return AVERROR(ENOMEM); + c->avctx = h->avctx; if (CONFIG_ERROR_RESILIENCE) { - c->dsp = h->dsp; + c->dsp = h->dsp; } - c->vdsp = h->vdsp; - c->h264dsp = h->h264dsp; - c->h264qpel = h->h264qpel; - c->h264chroma = h->h264chroma; - c->sps = h->sps; - c->pps = h->pps; - c->pixel_shift = h->pixel_shift; + c->vdsp = h->vdsp; + c->h264dsp = h->h264dsp; + c->h264qpel = h->h264qpel; + c->h264chroma = h->h264chroma; + c->sps = h->sps; + c->pps = h->pps; + c->pixel_shift = h->pixel_shift; c->cur_chroma_format_idc = h->cur_chroma_format_idc; - c->width = h->width; - c->height = h->height; - c->linesize = h->linesize; - c->uvlinesize = h->uvlinesize; - c->chroma_x_shift = h->chroma_x_shift; - c->chroma_y_shift = h->chroma_y_shift; - c->qscale = h->qscale; - c->droppable = h->droppable; + c->width = h->width; + c->height = h->height; + c->linesize = h->linesize; + c->uvlinesize = h->uvlinesize; + c->chroma_x_shift = h->chroma_x_shift; + c->chroma_y_shift = h->chroma_y_shift; + c->qscale = h->qscale; + c->droppable = h->droppable; c->data_partitioning = h->data_partitioning; - c->low_delay = h->low_delay; - c->mb_width = h->mb_width; - c->mb_height = h->mb_height; - c->mb_stride = h->mb_stride; - c->mb_num = h->mb_num; - c->flags = h->flags; - c->workaround_bugs = h->workaround_bugs; - c->pict_type = h->pict_type; + c->low_delay = h->low_delay; + c->mb_width = h->mb_width; + c->mb_height = h->mb_height; + c->mb_stride = h->mb_stride; + c->mb_num = h->mb_num; + c->flags = h->flags; + c->workaround_bugs = h->workaround_bugs; + c->pict_type = h->pict_type; init_scan_tables(c); clone_tables(c, h, i); @@ -3170,9 +3365,9 @@ static int h264_slice_header_init(H264Context *h, int reinit) } for (i = 0; i < h->slice_context_count; i++) - if (context_init(h->thread_context[i]) < 0) { + if ((ret = context_init(h->thread_context[i])) < 0) { av_log(h->avctx, AV_LOG_ERROR, "context_init() failed.\n"); - return -1; + return ret; } } @@ -3181,6 +3376,49 @@ static int h264_slice_header_init(H264Context *h, int reinit) return 0; } +int ff_set_ref_count(H264Context *h) +{ + int num_ref_idx_active_override_flag; + + // set defaults, might be overridden a few lines later + h->ref_count[0] = h->pps.ref_count[0]; + h->ref_count[1] = h->pps.ref_count[1]; + + if (h->slice_type_nos != AV_PICTURE_TYPE_I) { + unsigned max[2]; + max[0] = max[1] = h->picture_structure == PICT_FRAME ? 15 : 31; + + if (h->slice_type_nos == AV_PICTURE_TYPE_B) + h->direct_spatial_mv_pred = get_bits1(&h->gb); + num_ref_idx_active_override_flag = get_bits1(&h->gb); + + if (num_ref_idx_active_override_flag) { + h->ref_count[0] = get_ue_golomb(&h->gb) + 1; + if (h->slice_type_nos == AV_PICTURE_TYPE_B) { + h->ref_count[1] = get_ue_golomb(&h->gb) + 1; + } else + // full range is spec-ok in this case, even for frames + h->ref_count[1] = 1; + } + + if (h->ref_count[0]-1 > max[0] || h->ref_count[1]-1 > max[1]){ + av_log(h->avctx, AV_LOG_ERROR, "reference overflow %u > %u or %u > %u\n", h->ref_count[0]-1, max[0], h->ref_count[1]-1, max[1]); + h->ref_count[0] = h->ref_count[1] = 0; + return AVERROR_INVALIDDATA; + } + + if (h->slice_type_nos == AV_PICTURE_TYPE_B) + h->list_count = 2; + else + h->list_count = 1; + } else { + h->list_count = 0; + h->ref_count[0] = h->ref_count[1] = 0; + } + + return 0; +} + /** * Decode a slice header. * This will also call ff_MPV_common_init() and frame_start() as needed. @@ -3195,12 +3433,12 @@ static int decode_slice_header(H264Context *h, H264Context *h0) { unsigned int first_mb_in_slice; unsigned int pps_id; - int num_ref_idx_active_override_flag, ret; + int ret; unsigned int slice_type, tmp, i, j; - int default_ref_list_done = 0; int last_pic_structure, last_pic_droppable; int must_reinit; int needs_reinit = 0; + int field_pic_flag, bottom_field_flag; h->me.qpel_put = h->h264qpel.put_h264_qpel_pixels_tab; h->me.qpel_avg = h->h264qpel.avg_h264_qpel_pixels_tab; @@ -3227,7 +3465,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) av_log(h->avctx, AV_LOG_ERROR, "slice type too large (%d) at %d %d\n", slice_type, h->mb_x, h->mb_y); - return -1; + return AVERROR_INVALIDDATA; } if (slice_type > 4) { slice_type -= 5; @@ -3236,12 +3474,6 @@ static int decode_slice_header(H264Context *h, H264Context *h0) h->slice_type_fixed = 0; slice_type = golomb_to_pict_type[slice_type]; - if (slice_type == AV_PICTURE_TYPE_I || - (h0->current_slice != 0 && - slice_type == h0->last_slice_type && - !memcmp(h0->last_ref_count, h0->ref_count, sizeof(h0->ref_count)))) { - default_ref_list_done = 1; - } h->slice_type = slice_type; h->slice_type_nos = slice_type & 3; @@ -3251,13 +3483,13 @@ static int decode_slice_header(H264Context *h, H264Context *h0) pps_id = get_ue_golomb(&h->gb); if (pps_id >= MAX_PPS_COUNT) { av_log(h->avctx, AV_LOG_ERROR, "pps_id %d out of range\n", pps_id); - return -1; + return AVERROR_INVALIDDATA; } if (!h0->pps_buffers[pps_id]) { av_log(h->avctx, AV_LOG_ERROR, "non-existing PPS %u referenced\n", pps_id); - return -1; + return AVERROR_INVALIDDATA; } h->pps = *h0->pps_buffers[pps_id]; @@ -3265,7 +3497,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) av_log(h->avctx, AV_LOG_ERROR, "non-existing SPS %u referenced\n", h->pps.sps_id); - return -1; + return AVERROR_INVALIDDATA; } if (h->pps.sps_id != h->current_sps_id || @@ -3301,7 +3533,10 @@ static int decode_slice_header(H264Context *h, H264Context *h0) || 16*h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag) != h->avctx->coded_height || h->avctx->bits_per_raw_sample != h->sps.bit_depth_luma || h->cur_chroma_format_idc != h->sps.chroma_format_idc - || av_cmp_q(h->sps.sar, h->avctx->sample_aspect_ratio))); + || av_cmp_q(h->sps.sar, h->avctx->sample_aspect_ratio) + || h->mb_width != h->sps.mb_width + || h->mb_height != h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag) + )); if (h0->avctx->pix_fmt != get_pixel_format(h0, 0)) must_reinit = 1; @@ -3317,6 +3552,10 @@ static int decode_slice_header(H264Context *h, H264Context *h0) h->width = 16 * h->mb_width; h->height = 16 * h->mb_height; + ret = init_dimensions(h); + if (ret < 0) + return ret; + if (h->sps.video_signal_type_present_flag) { h->avctx->color_range = h->sps.full_range>0 ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; @@ -3330,10 +3569,10 @@ static int decode_slice_header(H264Context *h, H264Context *h0) } if (h->context_initialized && - ( - needs_reinit || - must_reinit)) { - + (h->width != h->avctx->coded_width || + h->height != h->avctx->coded_height || + must_reinit || + needs_reinit)) { if (h != h0) { av_log(h->avctx, AV_LOG_ERROR, "changing width/height on " "slice %d\n", h0->current_slice + 1); @@ -3347,7 +3586,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) h->avctx->pix_fmt = ret; av_log(h->avctx, AV_LOG_INFO, "Reinit context to %dx%d, " - "pix_fmt: %d\n", h->width, h->height, h->avctx->pix_fmt); + "pix_fmt: %s\n", h->width, h->height, av_get_pix_fmt_name(h->avctx->pix_fmt)); if ((ret = h264_slice_header_init(h, 1)) < 0) { av_log(h->avctx, AV_LOG_ERROR, @@ -3359,7 +3598,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) if (h != h0) { av_log(h->avctx, AV_LOG_ERROR, "Cannot (re-)initialize context during parallel decoding.\n"); - return -1; + return AVERROR_PATCHWELCOME; } if ((ret = get_pixel_format(h, 1)) < 0) @@ -3392,8 +3631,10 @@ static int decode_slice_header(H264Context *h, H264Context *h0) av_log(h->avctx, AV_LOG_ERROR, "This stream was generated by a broken encoder, invalid 8x8 inference\n"); return -1; } - if (get_bits1(&h->gb)) { // field_pic_flag - h->picture_structure = PICT_TOP_FIELD + get_bits1(&h->gb); // bottom_field_flag + field_pic_flag = get_bits1(&h->gb); + if (field_pic_flag) { + bottom_field_flag = get_bits1(&h->gb); + h->picture_structure = PICT_TOP_FIELD + bottom_field_flag; } else { h->picture_structure = PICT_FRAME; h->mb_aff_frame = h->sps.mb_aff; @@ -3419,7 +3660,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) } else { /* Shorten frame num gaps so we don't have to allocate reference * frames just to throw them away */ - if (h->frame_num != h->prev_frame_num && h->prev_frame_num >= 0) { + if (h->frame_num != h->prev_frame_num) { int unwrap_prev_frame_num = h->prev_frame_num; int max_frame_num = 1 << h->sps.log2_max_frame_num; @@ -3442,11 +3683,11 @@ static int decode_slice_header(H264Context *h, H264Context *h0) * since that can modify h->cur_pic_ptr. */ if (h0->first_field) { assert(h0->cur_pic_ptr); - assert(h0->cur_pic_ptr->f.data[0]); + assert(h0->cur_pic_ptr->f.buf[0]); assert(h0->cur_pic_ptr->reference != DELAYED_PIC_REF); /* Mark old field/frame as completed */ - if (!last_pic_droppable && h0->cur_pic_ptr->tf.owner == h0->avctx) { + if (h0->cur_pic_ptr->tf.owner == h0->avctx) { ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX, last_pic_structure == PICT_BOTTOM_FIELD); } @@ -3455,7 +3696,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) if (!FIELD_PICTURE(h) || h->picture_structure == last_pic_structure) { /* Previous field is unmatched. Don't display it, but let it * remain for reference if marked as such. */ - if (!last_pic_droppable && last_pic_structure != PICT_FRAME) { + if (last_pic_structure != PICT_FRAME) { ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX, last_pic_structure == PICT_TOP_FIELD); } @@ -3465,7 +3706,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) * different frame_nums. Consider this field first in * pair. Throw away previous field except for reference * purposes. */ - if (!last_pic_droppable && last_pic_structure != PICT_FRAME) { + if (last_pic_structure != PICT_FRAME) { ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX, last_pic_structure == PICT_TOP_FIELD); } @@ -3492,7 +3733,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) } } - while (h->frame_num != h->prev_frame_num && h->prev_frame_num >= 0 && !h0->first_field && + while (h->frame_num != h->prev_frame_num && !h0->first_field && h->frame_num != (h->prev_frame_num + 1) % (1 << h->sps.log2_max_frame_num)) { Picture *prev = h->short_ref_count ? h->short_ref[0] : NULL; av_log(h->avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n", @@ -3500,30 +3741,36 @@ static int decode_slice_header(H264Context *h, H264Context *h0) if (!h->sps.gaps_in_frame_num_allowed_flag) for(i=0; ilast_pocs); i++) h->last_pocs[i] = INT_MIN; - if (h264_frame_start(h) < 0) - return -1; + ret = h264_frame_start(h); + if (ret < 0) + return ret; h->prev_frame_num++; - h->prev_frame_num %= 1 << h->sps.log2_max_frame_num; + h->prev_frame_num %= 1 << h->sps.log2_max_frame_num; h->cur_pic_ptr->frame_num = h->prev_frame_num; ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 0); ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 1); - if ((ret = ff_generate_sliding_window_mmcos(h, 1)) < 0 && - h->avctx->err_recognition & AV_EF_EXPLODE) + ret = ff_generate_sliding_window_mmcos(h, 1); + if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) return ret; - if (ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index) < 0 && - (h->avctx->err_recognition & AV_EF_EXPLODE)) - return AVERROR_INVALIDDATA; - /* Error concealment: if a ref is missing, copy the previous ref in its place. - * FIXME: avoiding a memcpy would be nice, but ref handling makes many assumptions - * about there being no actual duplicates. - * FIXME: this doesn't copy padding for out-of-frame motion vectors. Given we're - * concealing a lost frame, this probably isn't noticeable by comparison, but it should - * be fixed. */ + ret = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index); + if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) + return ret; + /* Error concealment: If a ref is missing, copy the previous ref + * in its place. + * FIXME: Avoiding a memcpy would be nice, but ref handling makes + * many assumptions about there being no actual duplicates. + * FIXME: This does not copy padding for out-of-frame motion + * vectors. Given we are concealing a lost frame, this probably + * is not noticeable by comparison, but it should be fixed. */ if (h->short_ref_count) { if (prev) { - av_image_copy(h->short_ref[0]->f.data, h->short_ref[0]->f.linesize, - (const uint8_t **)prev->f.data, prev->f.linesize, - h->avctx->pix_fmt, h->mb_width * 16, h->mb_height * 16); + av_image_copy(h->short_ref[0]->f.data, + h->short_ref[0]->f.linesize, + (const uint8_t **)prev->f.data, + prev->f.linesize, + h->avctx->pix_fmt, + h->mb_width * 16, + h->mb_height * 16); h->short_ref[0]->poc = prev->poc + 2; } h->short_ref[0]->frame_num = h->prev_frame_num; @@ -3535,7 +3782,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) * frame, or to allocate a new one. */ if (h0->first_field) { assert(h0->cur_pic_ptr); - assert(h0->cur_pic_ptr->f.data[0]); + assert(h0->cur_pic_ptr->f.buf[0]); assert(h0->cur_pic_ptr->reference != DELAYED_PIC_REF); /* figure out if we have a complementary field pair */ @@ -3566,11 +3813,21 @@ static int decode_slice_header(H264Context *h, H264Context *h0) if (!FIELD_PICTURE(h) || h0->first_field) { if (h264_frame_start(h) < 0) { h0->first_field = 0; - return -1; + return AVERROR_INVALIDDATA; } } else { release_unused_pictures(h, 0); } + /* Some macroblocks can be accessed before they're available in case + * of lost slices, MBAFF or threading. */ + if (FIELD_PICTURE(h)) { + for(i = (h->picture_structure == PICT_BOTTOM_FIELD); imb_height; i++) + memset(h->slice_table + i*h->mb_stride, -1, (h->mb_stride - (i+1==h->mb_height)) * sizeof(*h->slice_table)); + } else { + memset(h->slice_table, -1, + (h->mb_height * h->mb_stride - 1) * sizeof(*h->slice_table)); + } + h0->last_slice_type = -1; } if (h != h0 && (ret = clone_slice(h, h0)) < 0) return ret; @@ -3590,10 +3847,11 @@ static int decode_slice_header(H264Context *h, H264Context *h0) if (first_mb_in_slice << FIELD_OR_MBAFF_PICTURE(h) >= h->mb_num || first_mb_in_slice >= h->mb_num) { av_log(h->avctx, AV_LOG_ERROR, "first_mb_in_slice overflow\n"); - return -1; + return AVERROR_INVALIDDATA; } h->resync_mb_x = h->mb_x = first_mb_in_slice % h->mb_width; - h->resync_mb_y = h->mb_y = (first_mb_in_slice / h->mb_width) << FIELD_OR_MBAFF_PICTURE(h); + h->resync_mb_y = h->mb_y = (first_mb_in_slice / h->mb_width) << + FIELD_OR_MBAFF_PICTURE(h); if (h->picture_structure == PICT_BOTTOM_FIELD) h->resync_mb_y = h->mb_y = h->mb_y + 1; av_assert1(h->mb_y < h->mb_height); @@ -3623,60 +3881,35 @@ static int decode_slice_header(H264Context *h, H264Context *h0) h->delta_poc[1] = get_se_golomb(&h->gb); } - init_poc(h); + ff_init_poc(h, h->cur_pic_ptr->field_poc, &h->cur_pic_ptr->poc); if (h->pps.redundant_pic_cnt_present) h->redundant_pic_count = get_ue_golomb(&h->gb); - // set defaults, might be overridden a few lines later - h->ref_count[0] = h->pps.ref_count[0]; - h->ref_count[1] = h->pps.ref_count[1]; - - if (h->slice_type_nos != AV_PICTURE_TYPE_I) { - unsigned max[2]; - max[0] = max[1] = h->picture_structure == PICT_FRAME ? 15 : 31; - - if (h->slice_type_nos == AV_PICTURE_TYPE_B) - h->direct_spatial_mv_pred = get_bits1(&h->gb); - num_ref_idx_active_override_flag = get_bits1(&h->gb); - - if (num_ref_idx_active_override_flag) { - h->ref_count[0] = get_ue_golomb(&h->gb) + 1; - if (h->slice_type_nos == AV_PICTURE_TYPE_B) { - h->ref_count[1] = get_ue_golomb(&h->gb) + 1; - } else - // full range is spec-ok in this case, even for frames - h->ref_count[1] = 1; - } + ret = ff_set_ref_count(h); + if (ret < 0) + return ret; - if (h->ref_count[0]-1 > max[0] || h->ref_count[1]-1 > max[1]){ - av_log(h->avctx, AV_LOG_ERROR, "reference overflow %u > %u or %u > %u\n", h->ref_count[0]-1, max[0], h->ref_count[1]-1, max[1]); - h->ref_count[0] = h->ref_count[1] = 0; - return AVERROR_INVALIDDATA; - } + if (slice_type != AV_PICTURE_TYPE_I && + (h0->current_slice == 0 || + slice_type != h0->last_slice_type || + memcmp(h0->last_ref_count, h0->ref_count, sizeof(h0->ref_count)))) { - if (h->slice_type_nos == AV_PICTURE_TYPE_B) - h->list_count = 2; - else - h->list_count = 1; - } else { - h->list_count = 0; - h->ref_count[0] = h->ref_count[1] = 0; - } - - if (!default_ref_list_done) ff_h264_fill_default_ref_list(h); + } - if (h->slice_type_nos != AV_PICTURE_TYPE_I && - ff_h264_decode_ref_pic_list_reordering(h) < 0) { - h->ref_count[1] = h->ref_count[0] = 0; - return -1; + if (h->slice_type_nos != AV_PICTURE_TYPE_I) { + ret = ff_h264_decode_ref_pic_list_reordering(h); + if (ret < 0) { + h->ref_count[1] = h->ref_count[0] = 0; + return ret; + } } if ((h->pps.weighted_pred && h->slice_type_nos == AV_PICTURE_TYPE_P) || (h->pps.weighted_bipred_idc == 1 && h->slice_type_nos == AV_PICTURE_TYPE_B)) - pred_weight_table(h); + ff_pred_weight_table(h); else if (h->pps.weighted_bipred_idc == 2 && h->slice_type_nos == AV_PICTURE_TYPE_B) { implicit_weight_table(h, -1); @@ -3693,12 +3926,13 @@ static int decode_slice_header(H264Context *h, H264Context *h0) // or h->mmco, which will cause ref list mix-ups and decoding errors // further down the line. This may break decoding if the first slice is // corrupt, thus we only do this if frame-mt is enabled. - if (h->nal_ref_idc && - ff_h264_decode_ref_pic_marking(h0, &h->gb, - !(h->avctx->active_thread_type & FF_THREAD_FRAME) || - h0->current_slice == 0) < 0 && - (h->avctx->err_recognition & AV_EF_EXPLODE)) - return AVERROR_INVALIDDATA; + if (h->nal_ref_idc) { + ret = ff_h264_decode_ref_pic_marking(h0, &h->gb, + !(h->avctx->active_thread_type & FF_THREAD_FRAME) || + h0->current_slice == 0); + if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) + return AVERROR_INVALIDDATA; + } if (FRAME_MBAFF(h)) { ff_h264_fill_mbaff_ref_list(h); @@ -3717,7 +3951,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) tmp = get_ue_golomb_31(&h->gb); if (tmp > 2) { av_log(h->avctx, AV_LOG_ERROR, "cabac_init_idc overflow\n"); - return -1; + return AVERROR_INVALIDDATA; } h->cabac_init_idc = tmp; } @@ -3726,7 +3960,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) tmp = h->pps.init_qp + get_se_golomb(&h->gb); if (tmp > 51 + 6 * (h->sps.bit_depth_luma - 8)) { av_log(h->avctx, AV_LOG_ERROR, "QP %u out of range\n", tmp); - return -1; + return AVERROR_INVALIDDATA; } h->qscale = tmp; h->chroma_qp[0] = get_chroma_qp(h, 0, h->qscale); @@ -3746,7 +3980,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) if (tmp > 2) { av_log(h->avctx, AV_LOG_ERROR, "deblocking_filter_idc %u out of range\n", tmp); - return -1; + return AVERROR_INVALIDDATA; } h->deblocking_filter = tmp; if (h->deblocking_filter < 2) @@ -3760,7 +3994,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) av_log(h->avctx, AV_LOG_ERROR, "deblocking filter parameters %d %d out of range\n", h->slice_alpha_c0_offset, h->slice_beta_offset); - return -1; + return AVERROR_INVALIDDATA; } } } @@ -3802,7 +4036,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) h0->last_slice_type = slice_type; memcpy(h0->last_ref_count, h0->ref_count, sizeof(h0->last_ref_count)); - h->slice_num = ++h0->current_slice; + h->slice_num = ++h0->current_slice; if (h->slice_num) h0->slice_row[(h->slice_num-1)&(MAX_SLICES-1)]= h->resync_mb_y; @@ -3818,7 +4052,8 @@ static int decode_slice_header(H264Context *h, H264Context *h0) int *ref2frm = h->ref2frm[h->slice_num & (MAX_SLICES - 1)][j]; for (i = 0; i < 16; i++) { id_list[i] = 60; - if (j < h->list_count && i < h->ref_count[j] && h->ref_list[j][i].f.buf[0]) { + if (j < h->list_count && i < h->ref_count[j] && + h->ref_list[j][i].f.buf[0]) { int k; AVBuffer *buf = h->ref_list[j][i].f.buf[0]->buffer; for (k = 0; k < h->short_ref_count; k++) @@ -3834,13 +4069,12 @@ static int decode_slice_header(H264Context *h, H264Context *h0) } } - ref2frm[0] = - ref2frm[1] = -1; + ref2frm[0] = + ref2frm[1] = -1; for (i = 0; i < 16; i++) - ref2frm[i + 2] = 4 * id_list[i] + - (h->ref_list[j][i].reference & 3); - ref2frm[18 + 0] = - ref2frm[18 + 1] = -1; + ref2frm[i + 2] = 4 * id_list[i] + (h->ref_list[j][i].reference & 3); + ref2frm[18 + 0] = + ref2frm[18 + 1] = -1; for (i = 16; i < 48; i++) ref2frm[i + 4] = 4 * id_list[(i - 16) >> 1] + (h->ref_list[j][i].reference & 3); @@ -3848,6 +4082,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) if (h->ref_count[0]) h->er.last_pic = &h->ref_list[0][0]; if (h->ref_count[1]) h->er.next_pic = &h->ref_list[1][0]; + h->er.ref_count = h->ref_count[0]; if (h->avctx->debug & FF_DEBUG_PICT_INFO) { av_log(h->avctx, AV_LOG_DEBUG, @@ -3887,7 +4122,7 @@ int ff_h264_get_slice_type(const H264Context *h) case AV_PICTURE_TYPE_SI: return 4; default: - return -1; + return AVERROR_INVALIDDATA; } } @@ -3998,7 +4233,7 @@ static int fill_filter_caches(H264Context *h, int mb_type) } else { if (curr_mb_field_flag) top_xy += h->mb_stride & - (((h->cur_pic.mb_type[top_xy] >> 7) & 1) - 1); + (((h->cur_pic.mb_type[top_xy] >> 7) & 1) - 1); if (left_mb_field_flag != curr_mb_field_flag) left_xy[LBOT] += h->mb_stride; } @@ -4080,18 +4315,18 @@ static int fill_filter_caches(H264Context *h, int mb_type) * from what the loop filter needs */ if (!CABAC(h) && h->pps.transform_8x8_mode) { if (IS_8x8DCT(top_type)) { - nnz_cache[4 + 8 * 0] = - nnz_cache[5 + 8 * 0] = (h->cbp_table[top_xy] & 0x4000) >> 12; - nnz_cache[6 + 8 * 0] = - nnz_cache[7 + 8 * 0] = (h->cbp_table[top_xy] & 0x8000) >> 12; + nnz_cache[4 + 8 * 0] = + nnz_cache[5 + 8 * 0] = (h->cbp_table[top_xy] & 0x4000) >> 12; + nnz_cache[6 + 8 * 0] = + nnz_cache[7 + 8 * 0] = (h->cbp_table[top_xy] & 0x8000) >> 12; } if (IS_8x8DCT(left_type[LTOP])) { - nnz_cache[3 + 8 * 1] = - nnz_cache[3 + 8 * 2] = (h->cbp_table[left_xy[LTOP]] & 0x2000) >> 12; // FIXME check MBAFF + nnz_cache[3 + 8 * 1] = + nnz_cache[3 + 8 * 2] = (h->cbp_table[left_xy[LTOP]] & 0x2000) >> 12; // FIXME check MBAFF } if (IS_8x8DCT(left_type[LBOT])) { - nnz_cache[3 + 8 * 3] = - nnz_cache[3 + 8 * 4] = (h->cbp_table[left_xy[LBOT]] & 0x8000) >> 12; // FIXME check MBAFF + nnz_cache[3 + 8 * 3] = + nnz_cache[3 + 8 * 4] = (h->cbp_table[left_xy[LBOT]] & 0x8000) >> 12; // FIXME check MBAFF } if (IS_8x8DCT(mb_type)) { @@ -4147,10 +4382,10 @@ static void loop_filter(H264Context *h, int start_x, int end_x) dest_y = h->cur_pic.f.data[0] + ((mb_x << pixel_shift) + mb_y * h->linesize) * 16; dest_cb = h->cur_pic.f.data[1] + - (mb_x << pixel_shift) * (8 << CHROMA444) + + (mb_x << pixel_shift) * (8 << CHROMA444(h)) + mb_y * h->uvlinesize * block_h; dest_cr = h->cur_pic.f.data[2] + - (mb_x << pixel_shift) * (8 << CHROMA444) + + (mb_x << pixel_shift) * (8 << CHROMA444(h)) + mb_y * h->uvlinesize * block_h; // FIXME simplify above @@ -4226,7 +4461,7 @@ static void decode_finish_row(H264Context *h) ff_h264_draw_horiz_band(h, top, height); - if (h->droppable) + if (h->droppable || h->er.error_occurred) return; ff_thread_report_progress(&h->cur_pic_ptr->tf, top + height - 1, @@ -4239,7 +4474,6 @@ static void er_add_slice(H264Context *h, int startx, int starty, if (CONFIG_ERROR_RESILIENCE) { ERContext *er = &h->er; - er->ref_count = h->ref_count[0]; ff_er_add_slice(er, startx, starty, endx, endy, status); } } @@ -4257,6 +4491,16 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg) avctx->codec_id != AV_CODEC_ID_H264 || (CONFIG_GRAY && (h->flags & CODEC_FLAG_GRAY)); + if (!(h->avctx->active_thread_type & FF_THREAD_SLICE) && h->picture_structure == PICT_FRAME && h->er.error_status_table) { + const int start_i = av_clip(h->resync_mb_x + h->resync_mb_y * h->mb_width, 0, h->mb_num - 1); + if (start_i) { + int prev_status = h->er.error_status_table[h->er.mb_index2xy[start_i - 1]]; + prev_status &= ~ VP_START; + if (prev_status != (ER_MV_END | ER_DC_END | ER_AC_END)) + h->er.error_occurred = 1; + } + } + if (h->pps.cabac) { /* realign */ align_get_bits(&h->gb); @@ -4292,7 +4536,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg) if ((h->workaround_bugs & FF_BUG_TRUNCATED) && h->cabac.bytestream > h->cabac.bytestream_end + 2) { er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x - 1, - h->mb_y, ER_MB_END); + h->mb_y, ER_MB_END); if (h->mb_x >= lf_x_start) loop_filter(h, lf_x_start, h->mb_x + 1); return 0; @@ -4305,8 +4549,8 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg) h->mb_x, h->mb_y, h->cabac.bytestream_end - h->cabac.bytestream); er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x, - h->mb_y, ER_MB_ERROR); - return -1; + h->mb_y, ER_MB_ERROR); + return AVERROR_INVALIDDATA; } if (++h->mb_x >= h->mb_width) { @@ -4325,7 +4569,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg) tprintf(h->avctx, "slice end %d %d\n", get_bits_count(&h->gb), h->gb.size_in_bits); er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x - 1, - h->mb_y, ER_MB_END); + h->mb_y, ER_MB_END); if (h->mb_x > lf_x_start) loop_filter(h, lf_x_start, h->mb_x); return 0; @@ -4352,8 +4596,8 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg) av_log(h->avctx, AV_LOG_ERROR, "error while decoding MB %d %d\n", h->mb_x, h->mb_y); er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x, - h->mb_y, ER_MB_ERROR); - return -1; + h->mb_y, ER_MB_ERROR); + return ret; } if (++h->mb_x >= h->mb_width) { @@ -4373,16 +4617,16 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg) if ( get_bits_left(&h->gb) == 0 || get_bits_left(&h->gb) > 0 && !(h->avctx->err_recognition & AV_EF_AGGRESSIVE)) { er_add_slice(h, h->resync_mb_x, h->resync_mb_y, - h->mb_x - 1, h->mb_y, - ER_MB_END); + h->mb_x - 1, h->mb_y, + ER_MB_END); return 0; } else { er_add_slice(h, h->resync_mb_x, h->resync_mb_y, - h->mb_x, h->mb_y, - ER_MB_END); + h->mb_x, h->mb_y, + ER_MB_END); - return -1; + return AVERROR_INVALIDDATA; } } } @@ -4390,19 +4634,20 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg) if (get_bits_left(&h->gb) <= 0 && h->mb_skip_run <= 0) { tprintf(h->avctx, "slice end %d %d\n", get_bits_count(&h->gb), h->gb.size_in_bits); + if (get_bits_left(&h->gb) == 0) { er_add_slice(h, h->resync_mb_x, h->resync_mb_y, - h->mb_x - 1, h->mb_y, - ER_MB_END); + h->mb_x - 1, h->mb_y, + ER_MB_END); if (h->mb_x > lf_x_start) loop_filter(h, lf_x_start, h->mb_x); return 0; } else { er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x, - h->mb_y, ER_MB_ERROR); + h->mb_y, ER_MB_ERROR); - return -1; + return AVERROR_INVALIDDATA; } } } @@ -4429,11 +4674,11 @@ static int execute_decode_slices(H264Context *h, int context_count) } else { av_assert0(context_count > 0); for (i = 1; i < context_count; i++) { - hx = h->thread_context[i]; + hx = h->thread_context[i]; if (CONFIG_ERROR_RESILIENCE) { hx->er.error_count = 0; } - hx->x264_build = h->x264_build; + hx->x264_build = h->x264_build; } avctx->execute(avctx, decode_slice, h->thread_context, @@ -4454,6 +4699,8 @@ static int execute_decode_slices(H264Context *h, int context_count) return 0; } +static const uint8_t start_code[] = { 0x00, 0x00, 0x01 }; + static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size, int parse_extradata) { @@ -4467,6 +4714,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size, int nal_index; int idr_cleared=0; int first_slice = 0; + int ret = 0; h->nal_unit_type= 0; @@ -4536,7 +4784,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size, ptr = ff_h264_decode_nal(hx, buf + buf_index, &dst_length, &consumed, next_avc - buf_index); if (ptr == NULL || dst_length < 0) { - buf_index = -1; + ret = -1; goto end; } i = buf_index + consumed; @@ -4546,14 +4794,16 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size, h->workaround_bugs |= FF_BUG_TRUNCATED; if (!(h->workaround_bugs & FF_BUG_TRUNCATED)) - while(dst_length > 0 && ptr[dst_length - 1] == 0) + while (dst_length > 0 && ptr[dst_length - 1] == 0) dst_length--; bit_length = !dst_length ? 0 : (8 * dst_length - decode_rbsp_trailing(h, ptr + dst_length - 1)); if (h->avctx->debug & FF_DEBUG_STARTCODE) - av_log(h->avctx, AV_LOG_DEBUG, "NAL %d/%d at %d/%d length %d pass %d\n", hx->nal_unit_type, hx->nal_ref_idc, buf_index, buf_size, dst_length, pass); + av_log(h->avctx, AV_LOG_DEBUG, + "NAL %d/%d at %d/%d length %d pass %d\n", + hx->nal_unit_type, hx->nal_ref_idc, buf_index, buf_size, dst_length, pass); if (h->is_avc && (nalsize != consumed) && nalsize) av_log(h->avctx, AV_LOG_DEBUG, @@ -4593,8 +4843,9 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size, first_slice = hx->nal_unit_type; } - // FIXME do not discard SEI id - if (avctx->skip_frame >= AVDISCARD_NONREF && h->nal_ref_idc == 0) + if (avctx->skip_frame >= AVDISCARD_NONREF && + h->nal_ref_idc == 0 && + h->nal_unit_type != NAL_SEI) continue; again: @@ -4608,8 +4859,11 @@ again: case NAL_DPA: case NAL_DPB: case NAL_DPC: + av_log(h->avctx, AV_LOG_WARNING, + "Ignoring NAL %d in global header/extradata\n", + hx->nal_unit_type); + // fall through to next case case NAL_AUXILIARY_SLICE: - av_log(h->avctx, AV_LOG_WARNING, "Ignoring NAL %d in global header/extradata\n", hx->nal_unit_type); hx->nal_unit_type = NAL_FF_IGNORE; } } @@ -4621,7 +4875,7 @@ again: if (first_slice != NAL_IDR_SLICE) { av_log(h->avctx, AV_LOG_ERROR, "Invalid mix of idr and non-idr slices\n"); - buf_index = -1; + ret = -1; goto end; } if(!idr_cleared) @@ -4629,45 +4883,54 @@ again: idr_cleared = 1; case NAL_SLICE: init_get_bits(&hx->gb, ptr, bit_length); - hx->intra_gb_ptr = - hx->inter_gb_ptr = &hx->gb; + hx->intra_gb_ptr = + hx->inter_gb_ptr = &hx->gb; hx->data_partitioning = 0; if ((err = decode_slice_header(hx, h))) break; - if (h->sei_recovery_frame_cnt >= 0 && (h->frame_num != h->sei_recovery_frame_cnt || hx->slice_type_nos != AV_PICTURE_TYPE_I)) - h->valid_recovery_point = 1; + if (h->sei_recovery_frame_cnt >= 0) { + if (h->frame_num != h->sei_recovery_frame_cnt || hx->slice_type_nos != AV_PICTURE_TYPE_I) + h->valid_recovery_point = 1; - if ( h->sei_recovery_frame_cnt >= 0 - && ( h->recovery_frame<0 - || ((h->recovery_frame - h->frame_num) & ((1 << h->sps.log2_max_frame_num)-1)) > h->sei_recovery_frame_cnt)) { - h->recovery_frame = (h->frame_num + h->sei_recovery_frame_cnt) % - (1 << h->sps.log2_max_frame_num); + if ( h->recovery_frame < 0 + || ((h->recovery_frame - h->frame_num) & ((1 << h->sps.log2_max_frame_num)-1)) > h->sei_recovery_frame_cnt) { + h->recovery_frame = (h->frame_num + h->sei_recovery_frame_cnt) & + ((1 << h->sps.log2_max_frame_num) - 1); - if (!h->valid_recovery_point) - h->recovery_frame = h->frame_num; + if (!h->valid_recovery_point) + h->recovery_frame = h->frame_num; + } } h->cur_pic_ptr->f.key_frame |= - (hx->nal_unit_type == NAL_IDR_SLICE); + (hx->nal_unit_type == NAL_IDR_SLICE); - if (h->recovery_frame == h->frame_num) { - h->cur_pic_ptr->sync |= 1; - h->recovery_frame = -1; + if (hx->nal_unit_type == NAL_IDR_SLICE || + h->recovery_frame == h->frame_num) { + h->recovery_frame = -1; + h->cur_pic_ptr->recovered = 1; } - - h->sync |= !!h->cur_pic_ptr->f.key_frame; - h->sync |= 3*!!(avctx->flags2 & CODEC_FLAG2_SHOW_ALL); - h->cur_pic_ptr->sync |= h->sync; + // If we have an IDR, all frames after it in decoded order are + // "recovered". + if (hx->nal_unit_type == NAL_IDR_SLICE) + h->frame_recovered |= FRAME_RECOVERED_IDR; + h->frame_recovered |= 3*!!(avctx->flags2 & CODEC_FLAG2_SHOW_ALL); + h->frame_recovered |= 3*!!(avctx->flags & CODEC_FLAG_OUTPUT_CORRUPT); +#if 1 + h->cur_pic_ptr->recovered |= h->frame_recovered; +#else + h->cur_pic_ptr->recovered |= !!(h->frame_recovered & FRAME_RECOVERED_IDR); +#endif if (h->current_slice == 1) { if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS)) decode_postinit(h, nal_index >= nals_needed); if (h->avctx->hwaccel && - h->avctx->hwaccel->start_frame(h->avctx, NULL, 0) < 0) - return -1; + (ret = h->avctx->hwaccel->start_frame(h->avctx, NULL, 0)) < 0) + return ret; if (CONFIG_H264_VDPAU_DECODER && h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) ff_vdpau_h264_picture_start(h); @@ -4682,17 +4945,18 @@ again: hx->slice_type_nos == AV_PICTURE_TYPE_I) && avctx->skip_frame < AVDISCARD_ALL) { if (avctx->hwaccel) { - if (avctx->hwaccel->decode_slice(avctx, - &buf[buf_index - consumed], - consumed) < 0) - return -1; + ret = avctx->hwaccel->decode_slice(avctx, + &buf[buf_index - consumed], + consumed); + if (ret < 0) + return ret; } else if (CONFIG_H264_VDPAU_DECODER && h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) { - static const uint8_t start_code[] = { - 0x00, 0x00, 0x01 }; - ff_vdpau_add_data_chunk(h->cur_pic_ptr->f.data[0], start_code, + ff_vdpau_add_data_chunk(h->cur_pic_ptr->f.data[0], + start_code, sizeof(start_code)); - ff_vdpau_add_data_chunk(h->cur_pic_ptr->f.data[0], &buf[buf_index - consumed], + ff_vdpau_add_data_chunk(h->cur_pic_ptr->f.data[0], + &buf[buf_index - consumed], consumed); } else context_count++; @@ -4737,7 +5001,7 @@ again: break; case NAL_SPS: init_get_bits(&h->gb, ptr, bit_length); - if (ff_h264_decode_seq_parameter_set(h) < 0 && (h->is_avc ? (nalsize != consumed) && nalsize : 1)) { + if (ff_h264_decode_seq_parameter_set(h) < 0 && (h->is_avc ? nalsize : 1)) { av_log(h->avctx, AV_LOG_DEBUG, "SPS decoding failure, trying again with the complete NAL\n"); if (h->is_avc) @@ -4797,7 +5061,7 @@ end: h->picture_structure == PICT_BOTTOM_FIELD); } - return buf_index; + return (ret < 0) ? ret : buf_index; } /** @@ -4813,6 +5077,29 @@ static int get_consumed_bytes(int pos, int buf_size) return pos; } +static int output_frame(H264Context *h, AVFrame *dst, Picture *srcp) +{ + AVFrame *src = &srcp->f; + int i; + int ret = av_frame_ref(dst, src); + if (ret < 0) + return ret; + + av_dict_set(&dst->metadata, "stereo_mode", ff_h264_sei_stereo_mode(h), 0); + + if (!srcp->crop) + return 0; + + for (i = 0; i < 3; i++) { + int hshift = (i > 0) ? h->chroma_x_shift : 0; + int vshift = (i > 0) ? h->chroma_y_shift : 0; + int off = ((srcp->crop_left >> hshift) << h->pixel_shift) + + (srcp->crop_top >> vshift) * dst->linesize[i]; + dst->data[i] += off; + } + return 0; +} + static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { @@ -4825,7 +5112,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int i, out_idx; int ret; - h->flags = avctx->flags; + h->flags = avctx->flags; /* end of stream, output what is still in the buffers */ if (buf_size == 0) { @@ -4852,7 +5139,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, if (out) { out->reference &= ~DELAYED_PIC_REF; - if ((ret = av_frame_ref(pict, &out->f)) < 0) + ret = output_frame(h, pict, out); + if (ret < 0) return ret; *got_frame = 1; } @@ -4884,7 +5172,7 @@ not_extra: buf_index = decode_nal_units(h, buf, buf_size, 0); if (buf_index < 0) - return -1; + return AVERROR_INVALIDDATA; if (!h->cur_pic_ptr && h->nal_unit_type == NAL_END_SEQUENCE) { av_assert0(buf_index <= buf_size); @@ -4896,7 +5184,7 @@ not_extra: buf_size >= 4 && !memcmp("Q264", buf, 4)) return buf_size; av_log(avctx, AV_LOG_ERROR, "no frame!\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS) || @@ -4908,8 +5196,13 @@ not_extra: /* Wait for second field. */ *got_frame = 0; - if (h->next_output_pic && (h->next_output_pic->sync || h->sync>1)) { - if ((ret = av_frame_ref(pict, &h->next_output_pic->f)) < 0) + if (h->next_output_pic && ( + h->next_output_pic->recovered)) { + if (!h->next_output_pic->recovered) + h->next_output_pic->f.flags |= AV_FRAME_FLAG_CORRUPT; + + ret = output_frame(h, pict, h->next_output_pic); + if (ret < 0) return ret; *got_frame = 1; if (CONFIG_MPEGVIDEO) { @@ -4920,7 +5213,7 @@ not_extra: } } - assert(pict->data[0] || !*got_frame); + assert(pict->buf[0] || !*got_frame); return get_consumed_bytes(buf_index, buf_size); } @@ -4940,19 +5233,11 @@ av_cold void ff_h264_free_context(H264Context *h) static av_cold int h264_decode_end(AVCodecContext *avctx) { - H264Context *h = avctx->priv_data; - int i; + H264Context *h = avctx->priv_data; ff_h264_remove_all_refs(h); ff_h264_free_context(h); - if (h->DPB) { - for (i = 0; i < MAX_PICTURE_COUNT; i++) { - unref_picture(h, &h->DPB[i]); - } - } - av_freep(&h->DPB); - unref_picture(h, &h->cur_pic); return 0; @@ -4997,6 +5282,7 @@ static const AVClass h264_vdpau_class = { AVCodec ff_h264_decoder = { .name = "h264", + .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, .priv_data_size = sizeof(H264Context), @@ -5007,7 +5293,6 @@ AVCodec ff_h264_decoder = { CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS | CODEC_CAP_FRAME_THREADS, .flush = flush_dpb, - .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"), .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(decode_update_thread_context), .profiles = NULL_IF_CONFIG_SMALL(profiles), @@ -5017,6 +5302,7 @@ AVCodec ff_h264_decoder = { #if CONFIG_H264_VDPAU_DECODER AVCodec ff_h264_vdpau_decoder = { .name = "h264_vdpau", + .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (VDPAU acceleration)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, .priv_data_size = sizeof(H264Context), @@ -5025,9 +5311,8 @@ AVCodec ff_h264_vdpau_decoder = { .decode = decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU, .flush = flush_dpb, - .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (VDPAU acceleration)"), .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_VDPAU_H264, - AV_PIX_FMT_NONE}, + AV_PIX_FMT_NONE}, .profiles = NULL_IF_CONFIG_SMALL(profiles), .priv_class = &h264_vdpau_class, }; diff --git a/ffmpeg/libavcodec/h264.h b/ffmpeg/libavcodec/h264.h index f20401d..916f104 100644 --- a/ffmpeg/libavcodec/h264.h +++ b/ffmpeg/libavcodec/h264.h @@ -87,9 +87,9 @@ #define CABAC(h) h->pps.cabac #endif -#define CHROMA (h->sps.chroma_format_idc) -#define CHROMA422 (h->sps.chroma_format_idc == 2) -#define CHROMA444 (h->sps.chroma_format_idc == 3) +#define CHROMA(h) (h->sps.chroma_format_idc) +#define CHROMA422(h) (h->sps.chroma_format_idc == 2) +#define CHROMA444(h) (h->sps.chroma_format_idc == 3) #define EXTENDED_SAR 255 @@ -127,7 +127,8 @@ typedef enum { SEI_TYPE_PIC_TIMING = 1, ///< picture timing SEI_TYPE_USER_DATA_ITU_T_T35 = 4, ///< user data registered by ITU-T Recommendation T.35 SEI_TYPE_USER_DATA_UNREGISTERED = 5, ///< unregistered user data - SEI_TYPE_RECOVERY_POINT = 6 ///< recovery point (frame # to decoder sync) + SEI_TYPE_RECOVERY_POINT = 6, ///< recovery point (frame # to decoder sync) + SEI_TYPE_FRAME_PACKING = 45, ///< frame packing arrangement } SEI_Type; /** @@ -145,6 +146,19 @@ typedef enum { SEI_PIC_STRUCT_FRAME_TRIPLING = 8 ///< 8: %frame tripling } SEI_PicStructType; +/** + * frame_packing_arrangement types + */ +typedef enum { + SEI_FPA_TYPE_CHECKERBOARD = 0, + SEI_FPA_TYPE_INTERLEAVE_COLUMN = 1, + SEI_FPA_TYPE_INTERLEAVE_ROW = 2, + SEI_FPA_TYPE_SIDE_BY_SIDE = 3, + SEI_FPA_TYPE_TOP_BOTTOM = 4, + SEI_FPA_TYPE_INTERLEAVE_TEMPORAL = 5, + SEI_FPA_TYPE_2D = 6, +} SEI_FpaType; + /** * Sequence parameter set */ @@ -168,6 +182,8 @@ typedef struct SPS { int mb_aff; ///< mb_adaptive_frame_field_flag int direct_8x8_inference_flag; int crop; ///< frame_cropping_flag + + /* those 4 are already in luma samples */ unsigned int crop_left; ///< frame_cropping_rect_left_offset unsigned int crop_right; ///< frame_cropping_rect_right_offset unsigned int crop_top; ///< frame_cropping_rect_top_offset @@ -230,6 +246,18 @@ typedef struct PPS { int chroma_qp_diff; } PPS; +/** + * Frame Packing Arrangement Type + */ +typedef struct FPA { + int frame_packing_arrangement_id; + int frame_packing_arrangement_cancel_flag; ///< is previous arrangement canceled, -1 if never received + SEI_FpaType frame_packing_arrangement_type; + int frame_packing_arrangement_repetition_period; + int content_interpretation_type; + int quincunx_sampling_flag; +} FPA; + /** * Memory management control operation opcode. */ @@ -276,8 +304,9 @@ typedef struct H264Context { int qp_thresh; ///< QP threshold to skip loopfilter + /* coded dimensions -- 16 * mb w/h */ int width, height; - int linesize, uvlinesize; + ptrdiff_t linesize, uvlinesize; int chroma_x_shift, chroma_y_shift; int qscale; @@ -350,8 +379,8 @@ typedef struct H264Context { uint32_t *mb2br_xy; int b_stride; // FIXME use s->b4_stride - int mb_linesize; ///< may be equal to s->linesize or s->linesize * 2, for mbaff - int mb_uvlinesize; + ptrdiff_t mb_linesize; ///< may be equal to s->linesize or s->linesize * 2, for mbaff + ptrdiff_t mb_uvlinesize; unsigned current_sps_id; ///< id of the current SPS SPS sps; ///< current sps @@ -587,6 +616,14 @@ typedef struct H264Context { */ int prev_interlaced_frame; + /** + * frame_packing_arrangment SEI message + */ + int sei_frame_packing_present; + int frame_packing_arrangement_type; + int content_interpretation_type; + int quincunx_subsampling; + /** * Bit set of clock types for fields/frames in picture timing SEI message. * For each found ct_type, appropriate bit is set (e.g., bit 1 for @@ -612,6 +649,14 @@ typedef struct H264Context { * frames. */ int sei_recovery_frame_cnt; + + /** + * Are the SEI recovery points looking valid. + */ + int valid_recovery_point; + + FPA sei_fpa; + /** * recovery_frame is the frame_num at which the next frame should * be fully constructed. @@ -620,10 +665,18 @@ typedef struct H264Context { */ int recovery_frame; - /** - * Are the SEI recovery points looking valid. - */ - int valid_recovery_point; +/** + * We have seen an IDR, so all the following frames in coded order are correctly + * decodable. + */ +#define FRAME_RECOVERED_IDR (1 << 0) +/** + * Sufficient number of frames have been decoded since a SEI recovery point, + * so all the following frames in presentation order are correct. + */ +#define FRAME_RECOVERED_SEI (1 << 1) + + int frame_recovered; ///< Initial frame has been completely recovered int luma_weight_flag[2]; ///< 7.4.3.2 luma_weight_lX_flag int chroma_weight_flag[2]; ///< 7.4.3.2 chroma_weight_lX_flag @@ -637,16 +690,12 @@ typedef struct H264Context { int16_t slice_row[MAX_SLICES]; ///< to detect when MAX_SLICES is too low - int sync; ///< did we had a keyframe or recovery point - uint8_t parse_history[4]; int parse_history_count; int parse_last_mb; uint8_t *edge_emu_buffer; int16_t *dc_val_base; - uint8_t *visualization_buffer[3]; ///< temporary buffer vor MV visualization - AVBufferPool *qscale_table_pool; AVBufferPool *mb_type_pool; AVBufferPool *motion_val_pool; @@ -772,6 +821,12 @@ void ff_h264_filter_mb(H264Context *h, int mb_x, int mb_y, */ void ff_h264_reset_sei(H264Context *h); +/** + * Get stereo_mode string from the h264 frame_packing_arrangement + * @param h H.264 context. + */ +const char* ff_h264_sei_stereo_mode(H264Context *h); + /* * o-o o-o * / / / @@ -973,5 +1028,8 @@ static av_always_inline int get_dct8x8_allowed(H264Context *h) } void ff_h264_draw_horiz_band(H264Context *h, int y, int height); +int ff_init_poc(H264Context *h, int pic_field_poc[2], int *pic_poc); +int ff_pred_weight_table(H264Context *h); +int ff_set_ref_count(H264Context *h); #endif /* AVCODEC_H264_H */ diff --git a/ffmpeg/libavcodec/h264_cabac.c b/ffmpeg/libavcodec/h264_cabac.c index 6f7224e..c0ca154 100644 --- a/ffmpeg/libavcodec/h264_cabac.c +++ b/ffmpeg/libavcodec/h264_cabac.c @@ -28,6 +28,7 @@ #define CABAC(h) 1 #define UNCHECKED_BITSTREAM_READER 1 +#include "libavutil/attributes.h" #include "config.h" #include "cabac.h" #include "cabac_functions.h" @@ -1683,7 +1684,6 @@ decode_cabac_residual_internal(H264Context *h, int16_t *block, } } - #define STORE_BLOCK(type) \ do { \ uint8_t *ctx = coeff_abs_level1_ctx[node_ctx] + abs_level_m1_ctx_base; \ @@ -1727,11 +1727,11 @@ decode_cabac_residual_internal(H264Context *h, int16_t *block, } \ } while ( coeff_count ); - if (h->pixel_shift) { - STORE_BLOCK(int32_t) - } else { - STORE_BLOCK(int16_t) - } + if (h->pixel_shift) { + STORE_BLOCK(int32_t) + } else { + STORE_BLOCK(int16_t) + } #ifdef CABAC_ON_STACK h->cabac.range = cc.range ; h->cabac.low = cc.low ; @@ -1740,26 +1740,30 @@ decode_cabac_residual_internal(H264Context *h, int16_t *block, } -static void decode_cabac_residual_dc_internal(H264Context *h, int16_t *block, - int cat, int n, - const uint8_t *scantable, - int max_coeff) +static av_noinline void decode_cabac_residual_dc_internal(H264Context *h, + int16_t *block, + int cat, int n, + const uint8_t *scantable, + int max_coeff) { decode_cabac_residual_internal(h, block, cat, n, scantable, NULL, max_coeff, 1, 0); } -static void decode_cabac_residual_dc_internal_422(H264Context *h, int16_t *block, - int cat, int n, const uint8_t *scantable, - int max_coeff) +static av_noinline void decode_cabac_residual_dc_internal_422(H264Context *h, + int16_t *block, + int cat, int n, + const uint8_t *scantable, + int max_coeff) { decode_cabac_residual_internal(h, block, cat, n, scantable, NULL, max_coeff, 1, 1); } -static void decode_cabac_residual_nondc_internal(H264Context *h, int16_t *block, - int cat, int n, - const uint8_t *scantable, - const uint32_t *qmul, - int max_coeff) +static av_noinline void decode_cabac_residual_nondc_internal(H264Context *h, + int16_t *block, + int cat, int n, + const uint8_t *scantable, + const uint32_t *qmul, + int max_coeff) { decode_cabac_residual_internal(h, block, cat, n, scantable, qmul, max_coeff, 0, 0); } @@ -1811,7 +1815,7 @@ static av_always_inline void decode_cabac_residual_nondc(H264Context *h, int max_coeff) { /* read coded block flag */ - if( (cat != 5 || CHROMA444) && get_cabac( &h->cabac, &h->cabac_state[get_cabac_cbf_ctx( h, cat, n, max_coeff, 0 ) ] ) == 0 ) { + if( (cat != 5 || CHROMA444(h)) && get_cabac( &h->cabac, &h->cabac_state[get_cabac_cbf_ctx( h, cat, n, max_coeff, 0 ) ] ) == 0 ) { if( max_coeff == 64 ) { fill_rectangle(&h->non_zero_count_cache[scan8[n]], 2, 2, 8, 0, 1); } else { @@ -2296,7 +2300,7 @@ decode_intra_mb: /* It would be better to do this in fill_decode_caches, but we don't know * the transform mode of the current macroblock there. */ - if (CHROMA444 && IS_8x8DCT(mb_type)){ + if (CHROMA444(h) && IS_8x8DCT(mb_type)){ int i; uint8_t *nnz_cache = h->non_zero_count_cache; for (i = 0; i < 2; i++){ @@ -2361,10 +2365,10 @@ decode_intra_mb: h->last_qscale_diff=0; decode_cabac_luma_residual(h, scan, scan8x8, pixel_shift, mb_type, cbp, 0); - if(CHROMA444){ + if (CHROMA444(h)) { decode_cabac_luma_residual(h, scan, scan8x8, pixel_shift, mb_type, cbp, 1); decode_cabac_luma_residual(h, scan, scan8x8, pixel_shift, mb_type, cbp, 2); - } else if (CHROMA422) { + } else if (CHROMA422(h)) { if( cbp&0x30 ){ int c; for (c = 0; c < 2; c++) diff --git a/ffmpeg/libavcodec/h264_cavlc.c b/ffmpeg/libavcodec/h264_cavlc.c index 63f8d78..a06203b 100644 --- a/ffmpeg/libavcodec/h264_cavlc.c +++ b/ffmpeg/libavcodec/h264_cavlc.c @@ -549,9 +549,15 @@ static int decode_residual(H264Context *h, GetBitContext *gb, int16_t *block, in if(prefix<15){ level_code = (prefix<=16) + level_code = 15<=16) { + if(prefix > 25+3){ + av_log(h->avctx, AV_LOG_ERROR, "Invalid level prefix\n"); + return AVERROR_INVALIDDATA; + } level_code += (1<<(prefix-3))-4096; + } + level_code += get_bits(gb, prefix-3); } mask= -(level_code&1); level_code= (((2+level_code)>>1) ^ mask) - mask; @@ -706,7 +712,7 @@ int ff_h264_decode_mb_cavlc(H264Context *h){ down the code */ if(h->slice_type_nos != AV_PICTURE_TYPE_I){ if(h->mb_skip_run==-1) - h->mb_skip_run= get_ue_golomb(&h->gb); + h->mb_skip_run= get_ue_golomb_long(&h->gb); if (h->mb_skip_run--) { if(FRAME_MBAFF(h) && (h->mb_y&1) == 0){ @@ -767,6 +773,10 @@ decode_intra_mb: // We assume these blocks are very rare so we do not optimize it. h->intra_pcm_ptr = align_get_bits(&h->gb); + if (get_bits_left(&h->gb) < mb_size) { + av_log(h->avctx, AV_LOG_ERROR, "Not enough data for an intra PCM block.\n"); + return AVERROR_INVALIDDATA; + } skip_bits_long(&h->gb, mb_size); // In deblocking, the quantizer is 0 @@ -860,7 +870,7 @@ decode_intra_mb: } for(list=0; listlist_count; list++){ - int ref_count= IS_REF0(mb_type) ? 1 : local_ref_count[list]; + int ref_count = IS_REF0(mb_type) ? 1 : local_ref_count[list]; for(i=0; i<4; i++){ if(IS_DIRECT(h->sub_mb_type[i])) continue; if(IS_DIR(h->sub_mb_type[i], 0, list)){ @@ -942,11 +952,11 @@ decode_intra_mb: if(IS_DIR(mb_type, 0, list)){ if(local_ref_count[list]==1){ val= 0; - }else if(local_ref_count[list]==2){ + } else if(local_ref_count[list]==2){ val= get_bits1(&h->gb)^1; }else{ val= get_ue_golomb_31(&h->gb); - if(val >= local_ref_count[list]){ + if (val >= local_ref_count[list]){ av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val); return -1; } @@ -970,13 +980,13 @@ decode_intra_mb: for(i=0; i<2; i++){ unsigned int val; if(IS_DIR(mb_type, i, list)){ - if(local_ref_count[list] == 1){ + if(local_ref_count[list] == 1) { val= 0; - }else if(local_ref_count[list] == 2){ + } else if(local_ref_count[list] == 2) { val= get_bits1(&h->gb)^1; }else{ val= get_ue_golomb_31(&h->gb); - if(val >= local_ref_count[list]){ + if (val >= local_ref_count[list]){ av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val); return -1; } @@ -1009,11 +1019,11 @@ decode_intra_mb: if(IS_DIR(mb_type, i, list)){ //FIXME optimize if(local_ref_count[list]==1){ val= 0; - }else if(local_ref_count[list]==2){ + } else if(local_ref_count[list]==2){ val= get_bits1(&h->gb)^1; }else{ val= get_ue_golomb_31(&h->gb); - if(val >= local_ref_count[list]){ + if (val >= local_ref_count[list]){ av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val); return -1; } @@ -1112,7 +1122,7 @@ decode_intra_mb: return -1; } h->cbp_table[mb_xy] |= ret << 12; - if(CHROMA444){ + if (CHROMA444(h)) { if( decode_luma_residual(h, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 1) < 0 ){ return -1; } @@ -1126,7 +1136,7 @@ decode_intra_mb: for(chroma_idx=0; chroma_idx<2; chroma_idx++) if (decode_residual(h, gb, h->mb + ((256 + 16*16*chroma_idx) << pixel_shift), CHROMA_DC_BLOCK_INDEX+chroma_idx, - CHROMA422 ? chroma422_dc_scan : chroma_dc_scan, + CHROMA422(h) ? chroma422_dc_scan : chroma_dc_scan, NULL, 4*num_c8x8) < 0) { return -1; } @@ -1136,12 +1146,12 @@ decode_intra_mb: for(chroma_idx=0; chroma_idx<2; chroma_idx++){ const uint32_t *qmul = h->dequant4_coeff[chroma_idx+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[chroma_idx]]; int16_t *mb = h->mb + (16*(16 + 16*chroma_idx) << pixel_shift); - for (i8x8=0; i8x8 @@ -209,6 +208,7 @@ static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){ mv[list]= AV_RN32A(C); } } + av_assert2(ref[list] < (h->ref_count[list] << !!FRAME_MBAFF(h))); }else{ int mask= ~(MB_TYPE_L0 << (2*list)); mv[list] = 0; diff --git a/ffmpeg/libavcodec/h264_loopfilter.c b/ffmpeg/libavcodec/h264_loopfilter.c index e617588..475070a 100644 --- a/ffmpeg/libavcodec/h264_loopfilter.c +++ b/ffmpeg/libavcodec/h264_loopfilter.c @@ -241,9 +241,9 @@ static av_always_inline void h264_filter_mb_fast_internal(H264Context *h, unsigned int uvlinesize, int pixel_shift) { - int chroma = CHROMA && !(CONFIG_GRAY && (h->flags&CODEC_FLAG_GRAY)); - int chroma444 = CHROMA444; - int chroma422 = CHROMA422; + int chroma = CHROMA(h) && !(CONFIG_GRAY && (h->flags&CODEC_FLAG_GRAY)); + int chroma444 = CHROMA444(h); + int chroma422 = CHROMA422(h); int mb_xy = h->mb_xy; int left_type= h->left_type[LTOP]; @@ -463,8 +463,8 @@ static int check_mv(H264Context *h, long b_idx, long bn_idx, int mvy_limit){ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize, int mb_xy, int mb_type, int mvy_limit, int first_vertical_edge_done, int a, int b, int chroma, int dir) { int edge; int chroma_qp_avg[2]; - int chroma444 = CHROMA444; - int chroma422 = CHROMA422; + int chroma444 = CHROMA444(h); + int chroma422 = CHROMA422(h); const int mbm_xy = dir == 0 ? mb_xy -1 : h->top_mb_xy; const int mbm_type = dir == 0 ? h->left_type[LTOP] : h->top_type; @@ -707,7 +707,7 @@ void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint const int mvy_limit = IS_INTERLACED(mb_type) ? 2 : 4; int first_vertical_edge_done = 0; av_unused int dir; - int chroma = CHROMA && !(CONFIG_GRAY && (h->flags&CODEC_FLAG_GRAY)); + int chroma = CHROMA(h) && !(CONFIG_GRAY && (h->flags&CODEC_FLAG_GRAY)); int qp_bd_offset = 6 * (h->sps.bit_depth_luma - 8); int a = h->slice_alpha_c0_offset - qp_bd_offset; int b = h->slice_beta_offset - qp_bd_offset; @@ -780,12 +780,12 @@ void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint filter_mb_mbaff_edgev ( h, img_y , linesize, bS , 1, qp [0], a, b, 1 ); filter_mb_mbaff_edgev ( h, img_y + 8* linesize, linesize, bS+4, 1, qp [1], a, b, 1 ); if (chroma){ - if (CHROMA444) { + if (CHROMA444(h)) { filter_mb_mbaff_edgev ( h, img_cb, uvlinesize, bS , 1, bqp[0], a, b, 1 ); filter_mb_mbaff_edgev ( h, img_cb + 8*uvlinesize, uvlinesize, bS+4, 1, bqp[1], a, b, 1 ); filter_mb_mbaff_edgev ( h, img_cr, uvlinesize, bS , 1, rqp[0], a, b, 1 ); filter_mb_mbaff_edgev ( h, img_cr + 8*uvlinesize, uvlinesize, bS+4, 1, rqp[1], a, b, 1 ); - } else if (CHROMA422) { + } else if (CHROMA422(h)) { filter_mb_mbaff_edgecv(h, img_cb, uvlinesize, bS , 1, bqp[0], a, b, 1); filter_mb_mbaff_edgecv(h, img_cb + 8*uvlinesize, uvlinesize, bS+4, 1, bqp[1], a, b, 1); filter_mb_mbaff_edgecv(h, img_cr, uvlinesize, bS , 1, rqp[0], a, b, 1); @@ -801,7 +801,7 @@ void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint filter_mb_mbaff_edgev ( h, img_y , 2* linesize, bS , 2, qp [0], a, b, 1 ); filter_mb_mbaff_edgev ( h, img_y + linesize, 2* linesize, bS+1, 2, qp [1], a, b, 1 ); if (chroma){ - if (CHROMA444) { + if (CHROMA444(h)) { filter_mb_mbaff_edgev ( h, img_cb, 2*uvlinesize, bS , 2, bqp[0], a, b, 1 ); filter_mb_mbaff_edgev ( h, img_cb + uvlinesize, 2*uvlinesize, bS+1, 2, bqp[1], a, b, 1 ); filter_mb_mbaff_edgev ( h, img_cr, 2*uvlinesize, bS , 2, rqp[0], a, b, 1 ); diff --git a/ffmpeg/libavcodec/h264_mb_template.c b/ffmpeg/libavcodec/h264_mb_template.c index 8ef93a1..da3a926 100644 --- a/ffmpeg/libavcodec/h264_mb_template.c +++ b/ffmpeg/libavcodec/h264_mb_template.c @@ -53,7 +53,7 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h) const int is_h264 = !CONFIG_SVQ3_DECODER || SIMPLE || h->avctx->codec_id == AV_CODEC_ID_H264; void (*idct_add)(uint8_t *dst, int16_t *block, int stride); const int block_h = 16 >> h->chroma_y_shift; - const int chroma422 = CHROMA422; + const int chroma422 = CHROMA422(h); dest_y = h->cur_pic.f.data[0] + ((mb_x << PIXEL_SHIFT) + mb_y * h->linesize) * 16; dest_cb = h->cur_pic.f.data[1] + (mb_x << PIXEL_SHIFT) * 8 + mb_y * h->uvlinesize * block_h; @@ -138,8 +138,8 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h) if (SIMPLE || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) { if (!h->sps.chroma_format_idc) { for (i = 0; i < 8; i++) { - memset(dest_cb + i*uvlinesize, 1 << (bit_depth - 1), 8); - memset(dest_cr + i*uvlinesize, 1 << (bit_depth - 1), 8); + memset(dest_cb + i * uvlinesize, 1 << (bit_depth - 1), 8); + memset(dest_cr + i * uvlinesize, 1 << (bit_depth - 1), 8); } } else { const uint8_t *src_cb = h->intra_pcm_ptr + 256; diff --git a/ffmpeg/libavcodec/h264_mp4toannexb_bsf.c b/ffmpeg/libavcodec/h264_mp4toannexb_bsf.c index 2dea933..8c0fbb3 100644 --- a/ffmpeg/libavcodec/h264_mp4toannexb_bsf.c +++ b/ffmpeg/libavcodec/h264_mp4toannexb_bsf.c @@ -31,114 +31,135 @@ typedef struct H264BSFContext { int extradata_parsed; } H264BSFContext; -static int alloc_and_copy(uint8_t **poutbuf, int *poutbuf_size, +static int alloc_and_copy(uint8_t **poutbuf, int *poutbuf_size, const uint8_t *sps_pps, uint32_t sps_pps_size, - const uint8_t *in, uint32_t in_size) { - uint32_t offset = *poutbuf_size; + const uint8_t *in, uint32_t in_size) +{ + uint32_t offset = *poutbuf_size; uint8_t nal_header_size = offset ? 3 : 4; - void *tmp; + int err; - *poutbuf_size += sps_pps_size+in_size+nal_header_size; - tmp = av_realloc(*poutbuf, *poutbuf_size); - if (!tmp) - return AVERROR(ENOMEM); - *poutbuf = tmp; + *poutbuf_size += sps_pps_size + in_size + nal_header_size; + if ((err = av_reallocp(poutbuf, + *poutbuf_size + FF_INPUT_BUFFER_PADDING_SIZE)) < 0) { + *poutbuf_size = 0; + return err; + } if (sps_pps) - memcpy(*poutbuf+offset, sps_pps, sps_pps_size); - memcpy(*poutbuf+sps_pps_size+nal_header_size+offset, in, in_size); + memcpy(*poutbuf + offset, sps_pps, sps_pps_size); + memcpy(*poutbuf + sps_pps_size + nal_header_size + offset, in, in_size); if (!offset) { - AV_WB32(*poutbuf+sps_pps_size, 1); + AV_WB32(*poutbuf + sps_pps_size, 1); } else { - (*poutbuf+offset+sps_pps_size)[0] = (*poutbuf+offset+sps_pps_size)[1] = 0; - (*poutbuf+offset+sps_pps_size)[2] = 1; + (*poutbuf + offset + sps_pps_size)[0] = + (*poutbuf + offset + sps_pps_size)[1] = 0; + (*poutbuf + offset + sps_pps_size)[2] = 1; } return 0; } +static int h264_extradata_to_annexb(AVCodecContext *avctx, const int padding) +{ + uint16_t unit_size; + uint64_t total_size = 0; + uint8_t *out = NULL, unit_nb, sps_done = 0, + sps_seen = 0, pps_seen = 0; + const uint8_t *extradata = avctx->extradata + 4; + static const uint8_t nalu_header[4] = { 0, 0, 0, 1 }; + int length_size = (*extradata++ & 0x3) + 1; // retrieve length coded size + + /* retrieve sps and pps unit(s) */ + unit_nb = *extradata++ & 0x1f; /* number of sps unit(s) */ + if (!unit_nb) { + goto pps; + } else { + sps_seen = 1; + } + + while (unit_nb--) { + int err; + + unit_size = AV_RB16(extradata); + total_size += unit_size + 4; + if (total_size > INT_MAX - padding) { + av_log(avctx, AV_LOG_ERROR, + "Too big extradata size, corrupted stream or invalid MP4/AVCC bitstream\n"); + av_free(out); + return AVERROR(EINVAL); + } + if (extradata + 2 + unit_size > avctx->extradata + avctx->extradata_size) { + av_log(avctx, AV_LOG_ERROR, "Packet header is not contained in global extradata, " + "corrupted stream or invalid MP4/AVCC bitstream\n"); + av_free(out); + return AVERROR(EINVAL); + } + if ((err = av_reallocp(&out, total_size + padding)) < 0) + return err; + memcpy(out + total_size - unit_size - 4, nalu_header, 4); + memcpy(out + total_size - unit_size, extradata + 2, unit_size); + extradata += 2 + unit_size; +pps: + if (!unit_nb && !sps_done++) { + unit_nb = *extradata++; /* number of pps unit(s) */ + if (unit_nb) + pps_seen = 1; + } + } + + if (out) + memset(out + total_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); + + if (!sps_seen) + av_log(avctx, AV_LOG_WARNING, + "Warning: SPS NALU missing or invalid. " + "The resulting stream may not play.\n"); + + if (!pps_seen) + av_log(avctx, AV_LOG_WARNING, + "Warning: PPS NALU missing or invalid. " + "The resulting stream may not play.\n"); + + av_free(avctx->extradata); + avctx->extradata = out; + avctx->extradata_size = total_size; + + return length_size; +} + static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, - int keyframe) { + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, + int keyframe) +{ H264BSFContext *ctx = bsfc->priv_data; int i; uint8_t unit_type; int32_t nal_size; - uint32_t cumul_size = 0; + uint32_t cumul_size = 0; const uint8_t *buf_end = buf + buf_size; - int ret = AVERROR(EINVAL); + int ret = 0; /* nothing to filter */ if (!avctx->extradata || avctx->extradata_size < 6) { - *poutbuf = (uint8_t*) buf; + *poutbuf = (uint8_t *)buf; *poutbuf_size = buf_size; return 0; } /* retrieve sps and pps NAL units from extradata */ if (!ctx->extradata_parsed) { - uint16_t unit_size; - uint64_t total_size = 0; - uint8_t *out = NULL, unit_nb, sps_done = 0, sps_seen = 0, pps_seen = 0; - const uint8_t *extradata = avctx->extradata+4; - static const uint8_t nalu_header[4] = {0, 0, 0, 1}; - - /* retrieve length coded size */ - ctx->length_size = (*extradata++ & 0x3) + 1; - - /* retrieve sps and pps unit(s) */ - unit_nb = *extradata++ & 0x1f; /* number of sps unit(s) */ - if (!unit_nb) { - goto pps; - } else { - sps_seen = 1; - } - - while (unit_nb--) { - void *tmp; - - unit_size = AV_RB16(extradata); - total_size += unit_size+4; - if (total_size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE || - extradata+2+unit_size > avctx->extradata+avctx->extradata_size) { - av_free(out); - return AVERROR(EINVAL); - } - tmp = av_realloc(out, total_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!tmp) { - av_free(out); - return AVERROR(ENOMEM); - } - out = tmp; - memcpy(out+total_size-unit_size-4, nalu_header, 4); - memcpy(out+total_size-unit_size, extradata+2, unit_size); - extradata += 2+unit_size; -pps: - if (!unit_nb && !sps_done++) { - unit_nb = *extradata++; /* number of pps unit(s) */ - if (unit_nb) - pps_seen = 1; - } - } - - if(out) - memset(out + total_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); - - if (!sps_seen) - av_log(avctx, AV_LOG_WARNING, "Warning: SPS NALU missing or invalid. The resulting stream may not play.\n"); - if (!pps_seen) - av_log(avctx, AV_LOG_WARNING, "Warning: PPS NALU missing or invalid. The resulting stream may not play.\n"); - - av_free(avctx->extradata); - avctx->extradata = out; - avctx->extradata_size = total_size; + ret = h264_extradata_to_annexb(avctx, FF_INPUT_BUFFER_PADDING_SIZE); + if (ret < 0) + return ret; + ctx->length_size = ret; ctx->first_idr = 1; ctx->extradata_parsed = 1; } *poutbuf_size = 0; - *poutbuf = NULL; + *poutbuf = NULL; do { ret= AVERROR(EINVAL); if (buf + ctx->length_size > buf_end) @@ -147,7 +168,7 @@ pps: for (nal_size = 0, i = 0; ilength_size; i++) nal_size = (nal_size << 8) | buf[i]; - buf += ctx->length_size; + buf += ctx->length_size; unit_type = *buf & 0x1f; if (buf + nal_size > buf_end || nal_size < 0) @@ -162,14 +183,13 @@ pps: ctx->first_idr = 0; } else { if ((ret=alloc_and_copy(poutbuf, poutbuf_size, - NULL, 0, - buf, nal_size)) < 0) + NULL, 0, buf, nal_size)) < 0) goto fail; if (!ctx->first_idr && unit_type == 1) ctx->first_idr = 1; } - buf += nal_size; + buf += nal_size; cumul_size += nal_size + ctx->length_size; } while (cumul_size < buf_size); @@ -182,7 +202,7 @@ fail: } AVBitStreamFilter ff_h264_mp4toannexb_bsf = { - "h264_mp4toannexb", - sizeof(H264BSFContext), - h264_mp4toannexb_filter, + .name = "h264_mp4toannexb", + .priv_data_size = sizeof(H264BSFContext), + .filter = h264_mp4toannexb_filter, }; diff --git a/ffmpeg/libavcodec/h264_mvpred.h b/ffmpeg/libavcodec/h264_mvpred.h index 361c1d7..afe327c 100644 --- a/ffmpeg/libavcodec/h264_mvpred.h +++ b/ffmpeg/libavcodec/h264_mvpred.h @@ -555,12 +555,12 @@ static void fill_decode_caches(H264Context *h, int mb_type) nnz = h->non_zero_count[left_xy[LEFT(i)]]; nnz_cache[3 + 8 * 1 + 2 * 8 * i] = nnz[left_block[8 + 0 + 2 * i]]; nnz_cache[3 + 8 * 2 + 2 * 8 * i] = nnz[left_block[8 + 1 + 2 * i]]; - if (CHROMA444) { + if (CHROMA444(h)) { nnz_cache[3 + 8 * 6 + 2 * 8 * i] = nnz[left_block[8 + 0 + 2 * i] + 4 * 4]; nnz_cache[3 + 8 * 7 + 2 * 8 * i] = nnz[left_block[8 + 1 + 2 * i] + 4 * 4]; nnz_cache[3 + 8 * 11 + 2 * 8 * i] = nnz[left_block[8 + 0 + 2 * i] + 8 * 4]; nnz_cache[3 + 8 * 12 + 2 * 8 * i] = nnz[left_block[8 + 1 + 2 * i] + 8 * 4]; - } else if (CHROMA422) { + } else if (CHROMA422(h)) { nnz_cache[3 + 8 * 6 + 2 * 8 * i] = nnz[left_block[8 + 0 + 2 * i] - 2 + 4 * 4]; nnz_cache[3 + 8 * 7 + 2 * 8 * i] = nnz[left_block[8 + 1 + 2 * i] - 2 + 4 * 4]; nnz_cache[3 + 8 * 11 + 2 * 8 * i] = nnz[left_block[8 + 0 + 2 * i] - 2 + 8 * 4]; @@ -663,7 +663,7 @@ static void fill_decode_caches(H264Context *h, int mb_type) ref_cache[4 - 1 * 8] = topright_type ? LIST_NOT_USED : PART_NOT_AVAILABLE; } - if(ref_cache[2 - 1*8] < 0 || ref_cache[4 - 1*8] < 0){ + if(ref_cache[2 - 1*8] < 0 || ref_cache[4 - 1 * 8] < 0) { if (USES_LIST(topleft_type, list)) { const int b_xy = h->mb2b_xy[topleft_xy] + 3 + b_stride + (h->topleft_partition & 2 * b_stride); diff --git a/ffmpeg/libavcodec/h264_parser.c b/ffmpeg/libavcodec/h264_parser.c index 44b92b7..0c426dd 100644 --- a/ffmpeg/libavcodec/h264_parser.c +++ b/ffmpeg/libavcodec/h264_parser.c @@ -27,12 +27,15 @@ #define UNCHECKED_BITSTREAM_READER 1 +#include "libavutil/attributes.h" #include "parser.h" #include "h264data.h" #include "golomb.h" +#include "internal.h" -static int ff_h264_find_frame_end(H264Context *h, const uint8_t *buf, int buf_size) +static int h264_find_frame_end(H264Context *h, const uint8_t *buf, + int buf_size) { int i, j; uint32_t state; @@ -40,65 +43,53 @@ static int ff_h264_find_frame_end(H264Context *h, const uint8_t *buf, int buf_si int next_avc= h->is_avc ? 0 : buf_size; // mb_addr= pc->mb_addr - 1; - state= pc->state; - if(state>13) - state= 7; + state = pc->state; + if (state > 13) + state = 7; - if(h->is_avc && !h->nal_length_size) + if (h->is_avc && !h->nal_length_size) av_log(h->avctx, AV_LOG_ERROR, "AVC-parser: nal length size invalid\n"); - for(i=0; i= next_avc) { + for (i = 0; i < buf_size; i++) { + if (i >= next_avc) { int nalsize = 0; i = next_avc; - for(j = 0; j < h->nal_length_size; j++) + for (j = 0; j < h->nal_length_size; j++) nalsize = (nalsize << 8) | buf[i++]; - if(nalsize <= 0 || nalsize > buf_size - i){ + if (nalsize <= 0 || nalsize > buf_size - i) { av_log(h->avctx, AV_LOG_ERROR, "AVC-parser: nal size %d remaining %d\n", nalsize, buf_size - i); return buf_size; } - next_avc= i + nalsize; - state= 5; + next_avc = i + nalsize; + state = 5; } - if(state==7){ -#if HAVE_FAST_UNALIGNED - /* we check i7, 1->4, 0->5 - else if(buf[i]) state = 7; - else state>>=1; //2->1, 1->0, 0->0 - }else if(state<=5){ - int v= buf[i] & 0x1F; - if(v==6 || v==7 || v==8 || v==9){ - if(pc->frame_start_found){ + if (state == 7) { + i += h->h264dsp.h264_find_start_code_candidate(buf + i, next_avc - i); + if (i < next_avc) + state = 2; + } else if (state <= 2) { + if (buf[i] == 1) + state ^= 5; // 2->7, 1->4, 0->5 + else if (buf[i]) + state = 7; + else + state >>= 1; // 2->1, 1->0, 0->0 + } else if (state <= 5) { + int v = buf[i] & 0x1F; + if (v == 6 || v == 7 || v == 8 || v == 9) { + if (pc->frame_start_found) { i++; goto found; } - }else if(v==1 || v==2 || v==5){ - state+=8; + } else if (v == 1 || v == 2 || v == 5) { + state += 8; continue; } - state= 7; - }else{ + state = 7; + } else { h->parse_history[h->parse_history_count++]= buf[i]; - if(h->parse_history_count>3){ + if (h->parse_history_count>3) { unsigned int mb, last_mb= h->parse_last_mb; GetBitContext gb; @@ -107,26 +98,95 @@ static int ff_h264_find_frame_end(H264Context *h, const uint8_t *buf, int buf_si mb= get_ue_golomb_long(&gb); last_mb= h->parse_last_mb; h->parse_last_mb= mb; - if(pc->frame_start_found){ - if(mb <= last_mb) + if (pc->frame_start_found) { + if (mb <= last_mb) goto found; - }else + } else pc->frame_start_found = 1; - state= 7; + state = 7; } } } - pc->state= state; - if(h->is_avc) + pc->state = state; + if (h->is_avc) return next_avc; return END_NOT_FOUND; found: - pc->state=7; - pc->frame_start_found= 0; - if(h->is_avc) + pc->state = 7; + pc->frame_start_found = 0; + if (h->is_avc) return next_avc; - return i-(state&5) - 3*(state>7); + return i - (state & 5) - 3 * (state > 7); +} + +static int scan_mmco_reset(AVCodecParserContext *s) +{ + H264Context *h = s->priv_data; + + h->slice_type_nos = s->pict_type & 3; + + if (h->pps.redundant_pic_cnt_present) + get_ue_golomb(&h->gb); // redundant_pic_count + + if (ff_set_ref_count(h) < 0) + return AVERROR_INVALIDDATA; + + if (h->slice_type_nos != AV_PICTURE_TYPE_I) { + int list; + for (list = 0; list < h->list_count; list++) { + if (get_bits1(&h->gb)) { + int index; + for (index = 0; ; index++) { + unsigned int reordering_of_pic_nums_idc = get_ue_golomb_31(&h->gb); + + if (reordering_of_pic_nums_idc < 3) + get_ue_golomb(&h->gb); + else if (reordering_of_pic_nums_idc > 3) { + av_log(h->avctx, AV_LOG_ERROR, + "illegal reordering_of_pic_nums_idc %d\n", + reordering_of_pic_nums_idc); + return AVERROR_INVALIDDATA; + } else + break; + + if (index >= h->ref_count[list]) { + av_log(h->avctx, AV_LOG_ERROR, "reference count overflow\n"); + return AVERROR_INVALIDDATA; + } + } + } + } + } + + if ((h->pps.weighted_pred && h->slice_type_nos == AV_PICTURE_TYPE_P) || + (h->pps.weighted_bipred_idc == 1 && h->slice_type_nos == AV_PICTURE_TYPE_B)) + ff_pred_weight_table(h); + + if (get_bits1(&h->gb)) { // adaptive_ref_pic_marking_mode_flag + int i; + for (i = 0; i < MAX_MMCO_COUNT; i++) { + MMCOOpcode opcode = get_ue_golomb_31(&h->gb); + if (opcode > (unsigned) MMCO_LONG) { + av_log(h->avctx, AV_LOG_ERROR, + "illegal memory management control operation %d\n", + opcode); + return AVERROR_INVALIDDATA; + } + if (opcode == MMCO_END) + return 0; + else if (opcode == MMCO_RESET) + return 1; + + if (opcode == MMCO_SHORT2UNUSED || opcode == MMCO_SHORT2LONG) + get_ue_golomb(&h->gb); + if (opcode == MMCO_SHORT2LONG || opcode == MMCO_LONG2UNUSED || + opcode == MMCO_LONG || opcode == MMCO_SET_MAX_LONG) + get_ue_golomb_31(&h->gb); + } + } + + return 0; } /** @@ -141,28 +201,28 @@ static inline int parse_nal_units(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t *buf, int buf_size) { - H264Context *h = s->priv_data; + H264Context *h = s->priv_data; const uint8_t *buf_end = buf + buf_size; unsigned int pps_id; unsigned int slice_type; - int state = -1; + int state = -1, got_reset = 0; const uint8_t *ptr; int q264 = buf_size >=4 && !memcmp("Q264", buf, 4); + int field_poc[2]; /* set some sane default values */ - s->pict_type = AV_PICTURE_TYPE_I; - s->key_frame = 0; + s->pict_type = AV_PICTURE_TYPE_I; + s->key_frame = 0; + s->picture_structure = AV_PICTURE_STRUCTURE_UNKNOWN; - h->avctx= avctx; - h->sei_recovery_frame_cnt = -1; - h->sei_dpb_output_delay = 0; - h->sei_cpb_removal_delay = -1; - h->sei_buffering_period_present = 0; + h->avctx = avctx; + ff_h264_reset_sei(h); + h->sei_fpa.frame_packing_arrangement_cancel_flag = -1; if (!buf_size) return 0; - for(;;) { + for (;;) { int src_length, dst_length, consumed, nalsize = 0; if (h->is_avc) { int i; @@ -176,8 +236,8 @@ static inline int parse_nal_units(AVCodecParserContext *s, } src_length = nalsize; } else { - buf = avpriv_mpv_find_start_code(buf, buf_end, &state); - if(buf >= buf_end) + buf = avpriv_find_start_code(buf, buf_end, &state); + if (buf >= buf_end) break; --buf; src_length = buf_end - buf; @@ -186,16 +246,24 @@ static inline int parse_nal_units(AVCodecParserContext *s, case NAL_SLICE: case NAL_IDR_SLICE: // Do not walk the whole buffer just to decode slice header - if (src_length > 20) - src_length = 20; + if ((state & 0x1f) == NAL_IDR_SLICE || ((state >> 5) & 0x3) == 0) { + /* IDR or disposable slice + * No need to decode many bytes because MMCOs shall not be present. */ + if (src_length > 60) + src_length = 60; + } else { + /* To decode up to MMCOs */ + if (src_length > 1000) + src_length = 1000; + } break; } - ptr= ff_h264_decode_nal(h, buf, &dst_length, &consumed, src_length); - if (ptr==NULL || dst_length < 0) + ptr = ff_h264_decode_nal(h, buf, &dst_length, &consumed, src_length); + if (ptr == NULL || dst_length < 0) break; - init_get_bits(&h->gb, ptr, 8*dst_length); - switch(h->nal_unit_type) { + init_get_bits(&h->gb, ptr, 8 * dst_length); + switch (h->nal_unit_type) { case NAL_SPS: ff_h264_decode_seq_parameter_set(h); break; @@ -207,72 +275,163 @@ static inline int parse_nal_units(AVCodecParserContext *s, break; case NAL_IDR_SLICE: s->key_frame = 1; - /* fall through */ + + h->prev_frame_num = 0; + h->prev_frame_num_offset = 0; + h->prev_poc_msb = + h->prev_poc_lsb = 0; + /* fall through */ case NAL_SLICE: get_ue_golomb_long(&h->gb); // skip first_mb_in_slice - slice_type = get_ue_golomb_31(&h->gb); + slice_type = get_ue_golomb_31(&h->gb); s->pict_type = golomb_to_pict_type[slice_type % 5]; if (h->sei_recovery_frame_cnt >= 0) { /* key frame, since recovery_frame_cnt is set */ s->key_frame = 1; } - pps_id= get_ue_golomb(&h->gb); - if(pps_id>=MAX_PPS_COUNT) { - av_log(h->avctx, AV_LOG_ERROR, "pps_id out of range\n"); + pps_id = get_ue_golomb(&h->gb); + if (pps_id >= MAX_PPS_COUNT) { + av_log(h->avctx, AV_LOG_ERROR, + "pps_id out of range\n"); return -1; } - if(!h->pps_buffers[pps_id]) { - av_log(h->avctx, AV_LOG_ERROR, "non-existing PPS referenced\n"); + if (!h->pps_buffers[pps_id]) { + av_log(h->avctx, AV_LOG_ERROR, + "non-existing PPS referenced\n"); return -1; } - h->pps= *h->pps_buffers[pps_id]; - if(!h->sps_buffers[h->pps.sps_id]) { - av_log(h->avctx, AV_LOG_ERROR, "non-existing SPS referenced\n"); + h->pps = *h->pps_buffers[pps_id]; + if (!h->sps_buffers[h->pps.sps_id]) { + av_log(h->avctx, AV_LOG_ERROR, + "non-existing SPS referenced\n"); return -1; } - h->sps = *h->sps_buffers[h->pps.sps_id]; + h->sps = *h->sps_buffers[h->pps.sps_id]; h->frame_num = get_bits(&h->gb, h->sps.log2_max_frame_num); + if(h->sps.ref_frame_count <= 1 && h->pps.ref_count[0] <= 1 && s->pict_type == AV_PICTURE_TYPE_I) + s->key_frame = 1; + avctx->profile = ff_h264_get_profile(&h->sps); avctx->level = h->sps.level_idc; - if(h->sps.frame_mbs_only_flag){ - h->picture_structure= PICT_FRAME; - }else{ - if(get_bits1(&h->gb)) { //field_pic_flag - h->picture_structure= PICT_TOP_FIELD + get_bits1(&h->gb); //bottom_field_flag + if (h->sps.frame_mbs_only_flag) { + h->picture_structure = PICT_FRAME; + } else { + if (get_bits1(&h->gb)) { // field_pic_flag + h->picture_structure = PICT_TOP_FIELD + get_bits1(&h->gb); // bottom_field_flag } else { - h->picture_structure= PICT_FRAME; + h->picture_structure = PICT_FRAME; } } - if(h->sps.pic_struct_present_flag) { + if (h->nal_unit_type == NAL_IDR_SLICE) + get_ue_golomb(&h->gb); /* idr_pic_id */ + if (h->sps.poc_type == 0) { + h->poc_lsb = get_bits(&h->gb, h->sps.log2_max_poc_lsb); + + if (h->pps.pic_order_present == 1 && + h->picture_structure == PICT_FRAME) + h->delta_poc_bottom = get_se_golomb(&h->gb); + } + + if (h->sps.poc_type == 1 && + !h->sps.delta_pic_order_always_zero_flag) { + h->delta_poc[0] = get_se_golomb(&h->gb); + + if (h->pps.pic_order_present == 1 && + h->picture_structure == PICT_FRAME) + h->delta_poc[1] = get_se_golomb(&h->gb); + } + + /* Decode POC of this picture. + * The prev_ values needed for decoding POC of the next picture are not set here. */ + field_poc[0] = field_poc[1] = INT_MAX; + ff_init_poc(h, field_poc, &s->output_picture_number); + + /* Continue parsing to check if MMCO_RESET is present. + * FIXME: MMCO_RESET could appear in non-first slice. + * Maybe, we should parse all undisposable non-IDR slice of this + * picture until encountering MMCO_RESET in a slice of it. */ + if (h->nal_ref_idc && h->nal_unit_type != NAL_IDR_SLICE) { + got_reset = scan_mmco_reset(s); + if (got_reset < 0) + return got_reset; + } + + /* Set up the prev_ values for decoding POC of the next picture. */ + h->prev_frame_num = got_reset ? 0 : h->frame_num; + h->prev_frame_num_offset = got_reset ? 0 : h->frame_num_offset; + if (h->nal_ref_idc != 0) { + if (!got_reset) { + h->prev_poc_msb = h->poc_msb; + h->prev_poc_lsb = h->poc_lsb; + } else { + h->prev_poc_msb = 0; + h->prev_poc_lsb = + h->picture_structure == PICT_BOTTOM_FIELD ? 0 : field_poc[0]; + } + } + + if (h->sps.pic_struct_present_flag) { switch (h->sei_pic_struct) { - case SEI_PIC_STRUCT_TOP_FIELD: - case SEI_PIC_STRUCT_BOTTOM_FIELD: - s->repeat_pict = 0; - break; - case SEI_PIC_STRUCT_FRAME: + case SEI_PIC_STRUCT_TOP_FIELD: + case SEI_PIC_STRUCT_BOTTOM_FIELD: + s->repeat_pict = 0; + break; + case SEI_PIC_STRUCT_FRAME: + case SEI_PIC_STRUCT_TOP_BOTTOM: + case SEI_PIC_STRUCT_BOTTOM_TOP: + s->repeat_pict = 1; + break; + case SEI_PIC_STRUCT_TOP_BOTTOM_TOP: + case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM: + s->repeat_pict = 2; + break; + case SEI_PIC_STRUCT_FRAME_DOUBLING: + s->repeat_pict = 3; + break; + case SEI_PIC_STRUCT_FRAME_TRIPLING: + s->repeat_pict = 5; + break; + default: + s->repeat_pict = h->picture_structure == PICT_FRAME ? 1 : 0; + break; + } + } else { + s->repeat_pict = h->picture_structure == PICT_FRAME ? 1 : 0; + } + + if (h->picture_structure == PICT_FRAME) { + s->picture_structure = AV_PICTURE_STRUCTURE_FRAME; + if (h->sps.pic_struct_present_flag) { + switch (h->sei_pic_struct) { case SEI_PIC_STRUCT_TOP_BOTTOM: - case SEI_PIC_STRUCT_BOTTOM_TOP: - s->repeat_pict = 1; - break; case SEI_PIC_STRUCT_TOP_BOTTOM_TOP: - case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM: - s->repeat_pict = 2; - break; - case SEI_PIC_STRUCT_FRAME_DOUBLING: - s->repeat_pict = 3; + s->field_order = AV_FIELD_TT; break; - case SEI_PIC_STRUCT_FRAME_TRIPLING: - s->repeat_pict = 5; + case SEI_PIC_STRUCT_BOTTOM_TOP: + case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM: + s->field_order = AV_FIELD_BB; break; default: - s->repeat_pict = h->picture_structure == PICT_FRAME ? 1 : 0; + s->field_order = AV_FIELD_PROGRESSIVE; break; + } + } else { + if (field_poc[0] < field_poc[1]) + s->field_order = AV_FIELD_TT; + else if (field_poc[0] > field_poc[1]) + s->field_order = AV_FIELD_BB; + else + s->field_order = AV_FIELD_PROGRESSIVE; } } else { - s->repeat_pict = h->picture_structure == PICT_FRAME ? 1 : 0; + if (h->picture_structure == PICT_TOP_FIELD) + s->picture_structure = AV_PICTURE_STRUCTURE_TOP_FIELD; + else + s->picture_structure = AV_PICTURE_STRUCTURE_BOTTOM_FIELD; + s->field_order = AV_FIELD_UNKNOWN; } return 0; /* no need to evaluate the rest */ @@ -291,7 +450,7 @@ static int h264_parse(AVCodecParserContext *s, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size) { - H264Context *h = s->priv_data; + H264Context *h = s->priv_data; ParseContext *pc = &h->parse_context; int next; @@ -309,20 +468,20 @@ static int h264_parse(AVCodecParserContext *s, } } - if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ - next= buf_size; - }else{ - next= ff_h264_find_frame_end(h, buf, buf_size); + if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { + next = buf_size; + } else { + next = h264_find_frame_end(h, buf, buf_size); if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { - *poutbuf = NULL; + *poutbuf = NULL; *poutbuf_size = 0; return buf_size; } - if(next<0 && next != END_NOT_FOUND){ - av_assert1(pc->last_index + next >= 0 ); - ff_h264_find_frame_end(h, &pc->buffer[pc->last_index + next], -next); //update state + if (next < 0 && next != END_NOT_FOUND) { + av_assert1(pc->last_index + next >= 0); + h264_find_frame_end(h, &pc->buffer[pc->last_index + next], -next); // update state } } @@ -342,7 +501,7 @@ static int h264_parse(AVCodecParserContext *s, s->flags &= PARSER_FLAG_COMPLETE_FRAMES; } - *poutbuf = buf; + *poutbuf = buf; *poutbuf_size = buf_size; return next; } @@ -352,39 +511,45 @@ static int h264_split(AVCodecContext *avctx, { int i; uint32_t state = -1; - int has_sps= 0; - - for(i=0; i<=buf_size; i++){ - if((state&0xFFFFFF1F) == 0x107) - has_sps=1; -/* if((state&0xFFFFFF1F) == 0x101 || (state&0xFFFFFF1F) == 0x102 || (state&0xFFFFFF1F) == 0x105){ - }*/ - if((state&0xFFFFFF00) == 0x100 && (state&0xFFFFFF1F) != 0x107 && (state&0xFFFFFF1F) != 0x108 && (state&0xFFFFFF1F) != 0x109){ - if(has_sps){ - while(i>4 && buf[i-5]==0) i--; - return i-4; + int has_sps = 0; + + for (i = 0; i <= buf_size; i++) { + if ((state & 0xFFFFFF1F) == 0x107) + has_sps = 1; + /* if ((state&0xFFFFFF1F) == 0x101 || + * (state&0xFFFFFF1F) == 0x102 || + * (state&0xFFFFFF1F) == 0x105) { + * } + */ + if ((state & 0xFFFFFF00) == 0x100 && (state & 0xFFFFFF1F) != 0x107 && + (state & 0xFFFFFF1F) != 0x108 && (state & 0xFFFFFF1F) != 0x109) { + if (has_sps) { + while (i > 4 && buf[i - 5] == 0) + i--; + return i - 4; } } - if (ipriv_data; + H264Context *h = s->priv_data; ParseContext *pc = &h->parse_context; av_free(pc->buffer); ff_h264_free_context(h); } -static int init(AVCodecParserContext *s) +static av_cold int init(AVCodecParserContext *s) { H264Context *h = s->priv_data; - h->thread_context[0] = h; + h->thread_context[0] = h; h->slice_context_count = 1; + ff_h264dsp_init(&h->h264dsp, 8, 1); return 0; } diff --git a/ffmpeg/libavcodec/h264_ps.c b/ffmpeg/libavcodec/h264_ps.c index 8638ce2..a06e3dd 100644 --- a/ffmpeg/libavcodec/h264_ps.c +++ b/ffmpeg/libavcodec/h264_ps.c @@ -32,245 +32,234 @@ #include "h264data.h" //FIXME FIXME FIXME (just for zigzag_scan) #include "golomb.h" - -//#undef NDEBUG -#include - #define MAX_LOG2_MAX_FRAME_NUM (12 + 4) #define MIN_LOG2_MAX_FRAME_NUM 4 -static const AVRational pixel_aspect[17]={ - {0, 1}, - {1, 1}, - {12, 11}, - {10, 11}, - {16, 11}, - {40, 33}, - {24, 11}, - {20, 11}, - {32, 11}, - {80, 33}, - {18, 11}, - {15, 11}, - {64, 33}, - {160,99}, - {4, 3}, - {3, 2}, - {2, 1}, +static const AVRational pixel_aspect[17] = { + { 0, 1 }, + { 1, 1 }, + { 12, 11 }, + { 10, 11 }, + { 16, 11 }, + { 40, 33 }, + { 24, 11 }, + { 20, 11 }, + { 32, 11 }, + { 80, 33 }, + { 18, 11 }, + { 15, 11 }, + { 64, 33 }, + { 160, 99 }, + { 4, 3 }, + { 3, 2 }, + { 2, 1 }, +}; + +#define QP(qP, depth) ((qP) + 6 * ((depth) - 8)) + +#define CHROMA_QP_TABLE_END(d) \ + QP(0, d), QP(1, d), QP(2, d), QP(3, d), QP(4, d), QP(5, d), \ + QP(6, d), QP(7, d), QP(8, d), QP(9, d), QP(10, d), QP(11, d), \ + QP(12, d), QP(13, d), QP(14, d), QP(15, d), QP(16, d), QP(17, d), \ + QP(18, d), QP(19, d), QP(20, d), QP(21, d), QP(22, d), QP(23, d), \ + QP(24, d), QP(25, d), QP(26, d), QP(27, d), QP(28, d), QP(29, d), \ + QP(29, d), QP(30, d), QP(31, d), QP(32, d), QP(32, d), QP(33, d), \ + QP(34, d), QP(34, d), QP(35, d), QP(35, d), QP(36, d), QP(36, d), \ + QP(37, d), QP(37, d), QP(37, d), QP(38, d), QP(38, d), QP(38, d), \ + QP(39, d), QP(39, d), QP(39, d), QP(39, d) + +const uint8_t ff_h264_chroma_qp[7][QP_MAX_NUM + 1] = { + { CHROMA_QP_TABLE_END(8) }, + { 0, 1, 2, 3, 4, 5, + CHROMA_QP_TABLE_END(9) }, + { 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, + CHROMA_QP_TABLE_END(10) }, + { 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, + 12,13,14,15, 16, 17, + CHROMA_QP_TABLE_END(11) }, + { 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, + 12,13,14,15, 16, 17, + 18,19,20,21, 22, 23, + CHROMA_QP_TABLE_END(12) }, + { 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, + 12,13,14,15, 16, 17, + 18,19,20,21, 22, 23, + 24,25,26,27, 28, 29, + CHROMA_QP_TABLE_END(13) }, + { 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, + 12,13,14,15, 16, 17, + 18,19,20,21, 22, 23, + 24,25,26,27, 28, 29, + 30,31,32,33, 34, 35, + CHROMA_QP_TABLE_END(14) }, +}; + +static const uint8_t default_scaling4[2][16] = { + { 6, 13, 20, 28, 13, 20, 28, 32, + 20, 28, 32, 37, 28, 32, 37, 42 }, + { 10, 14, 20, 24, 14, 20, 24, 27, + 20, 24, 27, 30, 24, 27, 30, 34 } }; -#define QP(qP,depth) ( (qP)+6*((depth)-8) ) - -#define CHROMA_QP_TABLE_END(d) \ - QP(0,d), QP(1,d), QP(2,d), QP(3,d), QP(4,d), QP(5,d),\ - QP(6,d), QP(7,d), QP(8,d), QP(9,d), QP(10,d), QP(11,d),\ - QP(12,d), QP(13,d), QP(14,d), QP(15,d), QP(16,d), QP(17,d),\ - QP(18,d), QP(19,d), QP(20,d), QP(21,d), QP(22,d), QP(23,d),\ - QP(24,d), QP(25,d), QP(26,d), QP(27,d), QP(28,d), QP(29,d),\ - QP(29,d), QP(30,d), QP(31,d), QP(32,d), QP(32,d), QP(33,d),\ - QP(34,d), QP(34,d), QP(35,d), QP(35,d), QP(36,d), QP(36,d),\ - QP(37,d), QP(37,d), QP(37,d), QP(38,d), QP(38,d), QP(38,d),\ - QP(39,d), QP(39,d), QP(39,d), QP(39,d) - -const uint8_t ff_h264_chroma_qp[7][QP_MAX_NUM+1] = { - { - CHROMA_QP_TABLE_END(8) - }, - { - 0, 1, 2, 3, 4, 5, - CHROMA_QP_TABLE_END(9) - }, - { - 0, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 11, - CHROMA_QP_TABLE_END(10) - }, - { - 0, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 11, - 12,13,14,15, 16, 17, - CHROMA_QP_TABLE_END(11) - }, - { - 0, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 11, - 12,13,14,15, 16, 17, - 18,19,20,21, 22, 23, - CHROMA_QP_TABLE_END(12) - }, - { - 0, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 11, - 12,13,14,15, 16, 17, - 18,19,20,21, 22, 23, - 24,25,26,27, 28, 29, - CHROMA_QP_TABLE_END(13) - }, - { - 0, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 11, - 12,13,14,15, 16, 17, - 18,19,20,21, 22, 23, - 24,25,26,27, 28, 29, - 30,31,32,33, 34, 35, - CHROMA_QP_TABLE_END(14) - }, +static const uint8_t default_scaling8[2][64] = { + { 6, 10, 13, 16, 18, 23, 25, 27, + 10, 11, 16, 18, 23, 25, 27, 29, + 13, 16, 18, 23, 25, 27, 29, 31, + 16, 18, 23, 25, 27, 29, 31, 33, + 18, 23, 25, 27, 29, 31, 33, 36, + 23, 25, 27, 29, 31, 33, 36, 38, + 25, 27, 29, 31, 33, 36, 38, 40, + 27, 29, 31, 33, 36, 38, 40, 42 }, + { 9, 13, 15, 17, 19, 21, 22, 24, + 13, 13, 17, 19, 21, 22, 24, 25, + 15, 17, 19, 21, 22, 24, 25, 27, + 17, 19, 21, 22, 24, 25, 27, 28, + 19, 21, 22, 24, 25, 27, 28, 30, + 21, 22, 24, 25, 27, 28, 30, 32, + 22, 24, 25, 27, 28, 30, 32, 33, + 24, 25, 27, 28, 30, 32, 33, 35 } }; -static const uint8_t default_scaling4[2][16]={ -{ 6,13,20,28, - 13,20,28,32, - 20,28,32,37, - 28,32,37,42 -},{ - 10,14,20,24, - 14,20,24,27, - 20,24,27,30, - 24,27,30,34 -}}; - -static const uint8_t default_scaling8[2][64]={ -{ 6,10,13,16,18,23,25,27, - 10,11,16,18,23,25,27,29, - 13,16,18,23,25,27,29,31, - 16,18,23,25,27,29,31,33, - 18,23,25,27,29,31,33,36, - 23,25,27,29,31,33,36,38, - 25,27,29,31,33,36,38,40, - 27,29,31,33,36,38,40,42 -},{ - 9,13,15,17,19,21,22,24, - 13,13,17,19,21,22,24,25, - 15,17,19,21,22,24,25,27, - 17,19,21,22,24,25,27,28, - 19,21,22,24,25,27,28,30, - 21,22,24,25,27,28,30,32, - 22,24,25,27,28,30,32,33, - 24,25,27,28,30,32,33,35 -}}; - -static inline int decode_hrd_parameters(H264Context *h, SPS *sps){ +static inline int decode_hrd_parameters(H264Context *h, SPS *sps) +{ int cpb_count, i; cpb_count = get_ue_golomb_31(&h->gb) + 1; - if(cpb_count > 32U){ + if (cpb_count > 32U) { av_log(h->avctx, AV_LOG_ERROR, "cpb_count %d invalid\n", cpb_count); - return -1; + return AVERROR_INVALIDDATA; } get_bits(&h->gb, 4); /* bit_rate_scale */ get_bits(&h->gb, 4); /* cpb_size_scale */ - for(i=0; igb); /* bit_rate_value_minus1 */ get_ue_golomb_long(&h->gb); /* cpb_size_value_minus1 */ - get_bits1(&h->gb); /* cbr_flag */ + get_bits1(&h->gb); /* cbr_flag */ } sps->initial_cpb_removal_delay_length = get_bits(&h->gb, 5) + 1; - sps->cpb_removal_delay_length = get_bits(&h->gb, 5) + 1; - sps->dpb_output_delay_length = get_bits(&h->gb, 5) + 1; - sps->time_offset_length = get_bits(&h->gb, 5); - sps->cpb_cnt = cpb_count; + sps->cpb_removal_delay_length = get_bits(&h->gb, 5) + 1; + sps->dpb_output_delay_length = get_bits(&h->gb, 5) + 1; + sps->time_offset_length = get_bits(&h->gb, 5); + sps->cpb_cnt = cpb_count; return 0; } -static inline int decode_vui_parameters(H264Context *h, SPS *sps){ +static inline int decode_vui_parameters(H264Context *h, SPS *sps) +{ int aspect_ratio_info_present_flag; unsigned int aspect_ratio_idc; - aspect_ratio_info_present_flag= get_bits1(&h->gb); + aspect_ratio_info_present_flag = get_bits1(&h->gb); - if( aspect_ratio_info_present_flag ) { - aspect_ratio_idc= get_bits(&h->gb, 8); - if( aspect_ratio_idc == EXTENDED_SAR ) { - sps->sar.num= get_bits(&h->gb, 16); - sps->sar.den= get_bits(&h->gb, 16); - }else if(aspect_ratio_idc < FF_ARRAY_ELEMS(pixel_aspect)){ - sps->sar= pixel_aspect[aspect_ratio_idc]; - }else{ + if (aspect_ratio_info_present_flag) { + aspect_ratio_idc = get_bits(&h->gb, 8); + if (aspect_ratio_idc == EXTENDED_SAR) { + sps->sar.num = get_bits(&h->gb, 16); + sps->sar.den = get_bits(&h->gb, 16); + } else if (aspect_ratio_idc < FF_ARRAY_ELEMS(pixel_aspect)) { + sps->sar = pixel_aspect[aspect_ratio_idc]; + } else { av_log(h->avctx, AV_LOG_ERROR, "illegal aspect ratio\n"); - return -1; + return AVERROR_INVALIDDATA; } - }else{ - sps->sar.num= - sps->sar.den= 0; + } else { + sps->sar.num = + sps->sar.den = 0; } -// s->avctx->aspect_ratio= sar_width*s->width / (float)(s->height*sar_height); - if(get_bits1(&h->gb)){ /* overscan_info_present_flag */ + if (get_bits1(&h->gb)) /* overscan_info_present_flag */ get_bits1(&h->gb); /* overscan_appropriate_flag */ - } sps->video_signal_type_present_flag = get_bits1(&h->gb); - if(sps->video_signal_type_present_flag){ - get_bits(&h->gb, 3); /* video_format */ + if (sps->video_signal_type_present_flag) { + get_bits(&h->gb, 3); /* video_format */ sps->full_range = get_bits1(&h->gb); /* video_full_range_flag */ sps->colour_description_present_flag = get_bits1(&h->gb); - if(sps->colour_description_present_flag){ + if (sps->colour_description_present_flag) { sps->color_primaries = get_bits(&h->gb, 8); /* colour_primaries */ sps->color_trc = get_bits(&h->gb, 8); /* transfer_characteristics */ sps->colorspace = get_bits(&h->gb, 8); /* matrix_coefficients */ if (sps->color_primaries >= AVCOL_PRI_NB) - sps->color_primaries = AVCOL_PRI_UNSPECIFIED; + sps->color_primaries = AVCOL_PRI_UNSPECIFIED; if (sps->color_trc >= AVCOL_TRC_NB) - sps->color_trc = AVCOL_TRC_UNSPECIFIED; + sps->color_trc = AVCOL_TRC_UNSPECIFIED; if (sps->colorspace >= AVCOL_SPC_NB) - sps->colorspace = AVCOL_SPC_UNSPECIFIED; + sps->colorspace = AVCOL_SPC_UNSPECIFIED; } } - if(get_bits1(&h->gb)){ /* chroma_location_info_present_flag */ - h->avctx->chroma_sample_location = get_ue_golomb(&h->gb)+1; /* chroma_sample_location_type_top_field */ + /* chroma_location_info_present_flag */ + if (get_bits1(&h->gb)) { + /* chroma_sample_location_type_top_field */ + h->avctx->chroma_sample_location = get_ue_golomb(&h->gb) + 1; get_ue_golomb(&h->gb); /* chroma_sample_location_type_bottom_field */ } + if (show_bits1(&h->gb) && get_bits_left(&h->gb) < 10) { + av_log(h->avctx, AV_LOG_WARNING, "Truncated VUI\n"); + return 0; + } + sps->timing_info_present_flag = get_bits1(&h->gb); - if(sps->timing_info_present_flag){ + if (sps->timing_info_present_flag) { sps->num_units_in_tick = get_bits_long(&h->gb, 32); - sps->time_scale = get_bits_long(&h->gb, 32); - if(!sps->num_units_in_tick || !sps->time_scale){ - av_log(h->avctx, AV_LOG_ERROR, "time_scale/num_units_in_tick invalid or unsupported (%d/%d)\n", sps->time_scale, sps->num_units_in_tick); - return -1; + sps->time_scale = get_bits_long(&h->gb, 32); + if (!sps->num_units_in_tick || !sps->time_scale) { + av_log(h->avctx, AV_LOG_ERROR, + "time_scale/num_units_in_tick invalid or unsupported (%d/%d)\n", + sps->time_scale, sps->num_units_in_tick); + return AVERROR_INVALIDDATA; } sps->fixed_frame_rate_flag = get_bits1(&h->gb); } sps->nal_hrd_parameters_present_flag = get_bits1(&h->gb); - if(sps->nal_hrd_parameters_present_flag) - if(decode_hrd_parameters(h, sps) < 0) - return -1; + if (sps->nal_hrd_parameters_present_flag) + if (decode_hrd_parameters(h, sps) < 0) + return AVERROR_INVALIDDATA; sps->vcl_hrd_parameters_present_flag = get_bits1(&h->gb); - if(sps->vcl_hrd_parameters_present_flag) - if(decode_hrd_parameters(h, sps) < 0) - return -1; - if(sps->nal_hrd_parameters_present_flag || sps->vcl_hrd_parameters_present_flag) + if (sps->vcl_hrd_parameters_present_flag) + if (decode_hrd_parameters(h, sps) < 0) + return AVERROR_INVALIDDATA; + if (sps->nal_hrd_parameters_present_flag || + sps->vcl_hrd_parameters_present_flag) get_bits1(&h->gb); /* low_delay_hrd_flag */ sps->pic_struct_present_flag = get_bits1(&h->gb); - if(!get_bits_left(&h->gb)) + if (!get_bits_left(&h->gb)) return 0; sps->bitstream_restriction_flag = get_bits1(&h->gb); - if(sps->bitstream_restriction_flag){ + if (sps->bitstream_restriction_flag) { get_bits1(&h->gb); /* motion_vectors_over_pic_boundaries_flag */ get_ue_golomb(&h->gb); /* max_bytes_per_pic_denom */ get_ue_golomb(&h->gb); /* max_bits_per_mb_denom */ get_ue_golomb(&h->gb); /* log2_max_mv_length_horizontal */ get_ue_golomb(&h->gb); /* log2_max_mv_length_vertical */ - sps->num_reorder_frames= get_ue_golomb(&h->gb); + sps->num_reorder_frames = get_ue_golomb(&h->gb); get_ue_golomb(&h->gb); /*max_dec_frame_buffering*/ if (get_bits_left(&h->gb) < 0) { - sps->num_reorder_frames=0; - sps->bitstream_restriction_flag= 0; + sps->num_reorder_frames = 0; + sps->bitstream_restriction_flag = 0; } - if(sps->num_reorder_frames > 16U /*max_dec_frame_buffering || max_dec_frame_buffering > 16*/){ - av_log(h->avctx, AV_LOG_ERROR, "illegal num_reorder_frames %d\n", sps->num_reorder_frames); - return -1; + if (sps->num_reorder_frames > 16U + /* max_dec_frame_buffering || max_dec_frame_buffering > 16 */) { + av_log(h->avctx, AV_LOG_ERROR, + "illegal num_reorder_frames %d\n", sps->num_reorder_frames); + return AVERROR_INVALIDDATA; } } if (get_bits_left(&h->gb) < 0) { - av_log(h->avctx, AV_LOG_ERROR, "Overread VUI by %d bits\n", -get_bits_left(&h->gb)); + av_log(h->avctx, AV_LOG_ERROR, + "Overread VUI by %d bits\n", -get_bits_left(&h->gb)); return AVERROR_INVALIDDATA; } @@ -278,25 +267,30 @@ static inline int decode_vui_parameters(H264Context *h, SPS *sps){ } static void decode_scaling_list(H264Context *h, uint8_t *factors, int size, - const uint8_t *jvt_list, const uint8_t *fallback_list){ + const uint8_t *jvt_list, + const uint8_t *fallback_list) +{ int i, last = 8, next = 8; const uint8_t *scan = size == 16 ? zigzag_scan : ff_zigzag_direct; - if(!get_bits1(&h->gb)) /* matrix not written, we use the predicted one */ - memcpy(factors, fallback_list, size*sizeof(uint8_t)); + if (!get_bits1(&h->gb)) /* matrix not written, we use the predicted one */ + memcpy(factors, fallback_list, size * sizeof(uint8_t)); else - for(i=0;igb)) & 0xff; - if(!i && !next){ /* matrix not written, we use the preset one */ - memcpy(factors, jvt_list, size*sizeof(uint8_t)); - break; + for (i = 0; i < size; i++) { + if (next) + next = (last + get_se_golomb(&h->gb)) & 0xff; + if (!i && !next) { /* matrix not written, we use the preset one */ + memcpy(factors, jvt_list, size * sizeof(uint8_t)); + break; + } + last = factors[scan[i]] = next ? next : last; } - last = factors[scan[i]] = next ? next : last; - } } -static void decode_scaling_matrices(H264Context *h, SPS *sps, PPS *pps, int is_sps, - uint8_t (*scaling_matrix4)[16], uint8_t (*scaling_matrix8)[64]){ +static void decode_scaling_matrices(H264Context *h, SPS *sps, + PPS *pps, int is_sps, + uint8_t(*scaling_matrix4)[16], + uint8_t(*scaling_matrix8)[64]) +{ int fallback_sps = !is_sps && sps->scaling_matrix_present; const uint8_t *fallback[4] = { fallback_sps ? sps->scaling_matrix4[0] : default_scaling4[0], @@ -304,57 +298,58 @@ static void decode_scaling_matrices(H264Context *h, SPS *sps, PPS *pps, int is_s fallback_sps ? sps->scaling_matrix8[0] : default_scaling8[0], fallback_sps ? sps->scaling_matrix8[3] : default_scaling8[1] }; - if(get_bits1(&h->gb)){ + if (get_bits1(&h->gb)) { sps->scaling_matrix_present |= is_sps; - decode_scaling_list(h,scaling_matrix4[0],16,default_scaling4[0],fallback[0]); // Intra, Y - decode_scaling_list(h,scaling_matrix4[1],16,default_scaling4[0],scaling_matrix4[0]); // Intra, Cr - decode_scaling_list(h,scaling_matrix4[2],16,default_scaling4[0],scaling_matrix4[1]); // Intra, Cb - decode_scaling_list(h,scaling_matrix4[3],16,default_scaling4[1],fallback[1]); // Inter, Y - decode_scaling_list(h,scaling_matrix4[4],16,default_scaling4[1],scaling_matrix4[3]); // Inter, Cr - decode_scaling_list(h,scaling_matrix4[5],16,default_scaling4[1],scaling_matrix4[4]); // Inter, Cb - if(is_sps || pps->transform_8x8_mode){ - decode_scaling_list(h,scaling_matrix8[0],64,default_scaling8[0],fallback[2]); // Intra, Y - decode_scaling_list(h,scaling_matrix8[3],64,default_scaling8[1],fallback[3]); // Inter, Y - if(sps->chroma_format_idc == 3){ - decode_scaling_list(h,scaling_matrix8[1],64,default_scaling8[0],scaling_matrix8[0]); // Intra, Cr - decode_scaling_list(h,scaling_matrix8[4],64,default_scaling8[1],scaling_matrix8[3]); // Inter, Cr - decode_scaling_list(h,scaling_matrix8[2],64,default_scaling8[0],scaling_matrix8[1]); // Intra, Cb - decode_scaling_list(h,scaling_matrix8[5],64,default_scaling8[1],scaling_matrix8[4]); // Inter, Cb + decode_scaling_list(h, scaling_matrix4[0], 16, default_scaling4[0], fallback[0]); // Intra, Y + decode_scaling_list(h, scaling_matrix4[1], 16, default_scaling4[0], scaling_matrix4[0]); // Intra, Cr + decode_scaling_list(h, scaling_matrix4[2], 16, default_scaling4[0], scaling_matrix4[1]); // Intra, Cb + decode_scaling_list(h, scaling_matrix4[3], 16, default_scaling4[1], fallback[1]); // Inter, Y + decode_scaling_list(h, scaling_matrix4[4], 16, default_scaling4[1], scaling_matrix4[3]); // Inter, Cr + decode_scaling_list(h, scaling_matrix4[5], 16, default_scaling4[1], scaling_matrix4[4]); // Inter, Cb + if (is_sps || pps->transform_8x8_mode) { + decode_scaling_list(h, scaling_matrix8[0], 64, default_scaling8[0], fallback[2]); // Intra, Y + decode_scaling_list(h, scaling_matrix8[3], 64, default_scaling8[1], fallback[3]); // Inter, Y + if (sps->chroma_format_idc == 3) { + decode_scaling_list(h, scaling_matrix8[1], 64, default_scaling8[0], scaling_matrix8[0]); // Intra, Cr + decode_scaling_list(h, scaling_matrix8[4], 64, default_scaling8[1], scaling_matrix8[3]); // Inter, Cr + decode_scaling_list(h, scaling_matrix8[2], 64, default_scaling8[0], scaling_matrix8[1]); // Intra, Cb + decode_scaling_list(h, scaling_matrix8[5], 64, default_scaling8[1], scaling_matrix8[4]); // Inter, Cb } } } } -int ff_h264_decode_seq_parameter_set(H264Context *h){ +int ff_h264_decode_seq_parameter_set(H264Context *h) +{ int profile_idc, level_idc, constraint_set_flags = 0; unsigned int sps_id; int i, log2_max_frame_num_minus4; SPS *sps; - profile_idc= get_bits(&h->gb, 8); - constraint_set_flags |= get_bits1(&h->gb) << 0; //constraint_set0_flag - constraint_set_flags |= get_bits1(&h->gb) << 1; //constraint_set1_flag - constraint_set_flags |= get_bits1(&h->gb) << 2; //constraint_set2_flag - constraint_set_flags |= get_bits1(&h->gb) << 3; //constraint_set3_flag - constraint_set_flags |= get_bits1(&h->gb) << 4; //constraint_set4_flag - constraint_set_flags |= get_bits1(&h->gb) << 5; //constraint_set5_flag + profile_idc = get_bits(&h->gb, 8); + constraint_set_flags |= get_bits1(&h->gb) << 0; // constraint_set0_flag + constraint_set_flags |= get_bits1(&h->gb) << 1; // constraint_set1_flag + constraint_set_flags |= get_bits1(&h->gb) << 2; // constraint_set2_flag + constraint_set_flags |= get_bits1(&h->gb) << 3; // constraint_set3_flag + constraint_set_flags |= get_bits1(&h->gb) << 4; // constraint_set4_flag + constraint_set_flags |= get_bits1(&h->gb) << 5; // constraint_set5_flag get_bits(&h->gb, 2); // reserved - level_idc= get_bits(&h->gb, 8); - sps_id= get_ue_golomb_31(&h->gb); + level_idc = get_bits(&h->gb, 8); + sps_id = get_ue_golomb_31(&h->gb); - if(sps_id >= MAX_SPS_COUNT) { + if (sps_id >= MAX_SPS_COUNT) { av_log(h->avctx, AV_LOG_ERROR, "sps_id (%d) out of range\n", sps_id); - return -1; + return AVERROR_INVALIDDATA; } - sps= av_mallocz(sizeof(SPS)); - if(sps == NULL) - return -1; + sps = av_mallocz(sizeof(SPS)); + if (!sps) + return AVERROR(ENOMEM); - sps->time_offset_length = 24; - sps->profile_idc= profile_idc; + sps->time_offset_length = 24; + sps->profile_idc = profile_idc; sps->constraint_set_flags = constraint_set_flags; - sps->level_idc= level_idc; - sps->full_range = -1; + sps->level_idc = level_idc; + sps->full_range = -1; memset(sps->scaling_matrix4, 16, sizeof(sps->scaling_matrix4)); memset(sps->scaling_matrix8, 16, sizeof(sps->scaling_matrix8)); @@ -366,13 +361,15 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ sps->profile_idc == 44 || sps->profile_idc == 83 || sps->profile_idc == 86 || sps->profile_idc == 118 || sps->profile_idc == 128 || sps->profile_idc == 144) { - sps->chroma_format_idc= get_ue_golomb_31(&h->gb); + sps->chroma_format_idc = get_ue_golomb_31(&h->gb); if (sps->chroma_format_idc > 3U) { - av_log(h->avctx, AV_LOG_ERROR, "chroma_format_idc %d is illegal\n", sps->chroma_format_idc); + av_log(h->avctx, AV_LOG_ERROR, + "chroma_format_idc %d is illegal\n", + sps->chroma_format_idc); goto fail; - } else if(sps->chroma_format_idc == 3) { + } else if (sps->chroma_format_idc == 3) { sps->residual_color_transform_flag = get_bits1(&h->gb); - if(sps->residual_color_transform_flag) { + if (sps->residual_color_transform_flag) { av_log(h->avctx, AV_LOG_ERROR, "separate color planes are not supported\n"); goto fail; } @@ -385,11 +382,12 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ goto fail; } sps->transform_bypass = get_bits1(&h->gb); - decode_scaling_matrices(h, sps, NULL, 1, sps->scaling_matrix4, sps->scaling_matrix8); - }else{ - sps->chroma_format_idc= 1; - sps->bit_depth_luma = 8; - sps->bit_depth_chroma = 8; + decode_scaling_matrices(h, sps, NULL, 1, + sps->scaling_matrix4, sps->scaling_matrix8); + } else { + sps->chroma_format_idc = 1; + sps->bit_depth_luma = 8; + sps->bit_depth_chroma = 8; } log2_max_frame_num_minus4 = get_ue_golomb(&h->gb); @@ -402,114 +400,139 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ } sps->log2_max_frame_num = log2_max_frame_num_minus4 + 4; - sps->poc_type= get_ue_golomb_31(&h->gb); + sps->poc_type = get_ue_golomb_31(&h->gb); - if(sps->poc_type == 0){ //FIXME #define + if (sps->poc_type == 0) { // FIXME #define unsigned t = get_ue_golomb(&h->gb); - if(t>12){ + if (t>12) { av_log(h->avctx, AV_LOG_ERROR, "log2_max_poc_lsb (%d) is out of range\n", t); goto fail; } - sps->log2_max_poc_lsb= t + 4; - } else if(sps->poc_type == 1){//FIXME #define - sps->delta_pic_order_always_zero_flag= get_bits1(&h->gb); - sps->offset_for_non_ref_pic= get_se_golomb(&h->gb); - sps->offset_for_top_to_bottom_field= get_se_golomb(&h->gb); - sps->poc_cycle_length = get_ue_golomb(&h->gb); - - if((unsigned)sps->poc_cycle_length >= FF_ARRAY_ELEMS(sps->offset_for_ref_frame)){ - av_log(h->avctx, AV_LOG_ERROR, "poc_cycle_length overflow %u\n", sps->poc_cycle_length); + sps->log2_max_poc_lsb = t + 4; + } else if (sps->poc_type == 1) { // FIXME #define + sps->delta_pic_order_always_zero_flag = get_bits1(&h->gb); + sps->offset_for_non_ref_pic = get_se_golomb(&h->gb); + sps->offset_for_top_to_bottom_field = get_se_golomb(&h->gb); + sps->poc_cycle_length = get_ue_golomb(&h->gb); + + if ((unsigned)sps->poc_cycle_length >= + FF_ARRAY_ELEMS(sps->offset_for_ref_frame)) { + av_log(h->avctx, AV_LOG_ERROR, + "poc_cycle_length overflow %u\n", sps->poc_cycle_length); goto fail; } - for(i=0; ipoc_cycle_length; i++) - sps->offset_for_ref_frame[i]= get_se_golomb(&h->gb); - }else if(sps->poc_type != 2){ + for (i = 0; i < sps->poc_cycle_length; i++) + sps->offset_for_ref_frame[i] = get_se_golomb(&h->gb); + } else if (sps->poc_type != 2) { av_log(h->avctx, AV_LOG_ERROR, "illegal POC type %d\n", sps->poc_type); goto fail; } - sps->ref_frame_count= get_ue_golomb_31(&h->gb); + sps->ref_frame_count = get_ue_golomb_31(&h->gb); if (h->avctx->codec_tag == MKTAG('S', 'M', 'V', '2')) - sps->ref_frame_count= FFMAX(2, sps->ref_frame_count); - if(sps->ref_frame_count > MAX_PICTURE_COUNT-2 || sps->ref_frame_count > 16U){ + sps->ref_frame_count = FFMAX(2, sps->ref_frame_count); + if (sps->ref_frame_count > MAX_PICTURE_COUNT - 2 || + sps->ref_frame_count > 16U) { av_log(h->avctx, AV_LOG_ERROR, "too many reference frames\n"); goto fail; } - sps->gaps_in_frame_num_allowed_flag= get_bits1(&h->gb); - sps->mb_width = get_ue_golomb(&h->gb) + 1; - sps->mb_height= get_ue_golomb(&h->gb) + 1; - if((unsigned)sps->mb_width >= INT_MAX/16 || (unsigned)sps->mb_height >= INT_MAX/16 || - av_image_check_size(16*sps->mb_width, 16*sps->mb_height, 0, h->avctx)){ + sps->gaps_in_frame_num_allowed_flag = get_bits1(&h->gb); + sps->mb_width = get_ue_golomb(&h->gb) + 1; + sps->mb_height = get_ue_golomb(&h->gb) + 1; + if ((unsigned)sps->mb_width >= INT_MAX / 16 || + (unsigned)sps->mb_height >= INT_MAX / 16 || + av_image_check_size(16 * sps->mb_width, + 16 * sps->mb_height, 0, h->avctx)) { av_log(h->avctx, AV_LOG_ERROR, "mb_width/height overflow\n"); goto fail; } - sps->frame_mbs_only_flag= get_bits1(&h->gb); - if(!sps->frame_mbs_only_flag) - sps->mb_aff= get_bits1(&h->gb); + sps->frame_mbs_only_flag = get_bits1(&h->gb); + if (!sps->frame_mbs_only_flag) + sps->mb_aff = get_bits1(&h->gb); else - sps->mb_aff= 0; + sps->mb_aff = 0; - sps->direct_8x8_inference_flag= get_bits1(&h->gb); + sps->direct_8x8_inference_flag = get_bits1(&h->gb); #ifndef ALLOW_INTERLACE - if(sps->mb_aff) - av_log(h->avctx, AV_LOG_ERROR, "MBAFF support not included; enable it at compile-time.\n"); + if (sps->mb_aff) + av_log(h->avctx, AV_LOG_ERROR, + "MBAFF support not included; enable it at compile-time.\n"); #endif - sps->crop= get_bits1(&h->gb); - if(sps->crop){ - int crop_vertical_limit = sps->chroma_format_idc & 2 ? 16 : 8; - int crop_horizontal_limit = sps->chroma_format_idc == 3 ? 16 : 8; - sps->crop_left = get_ue_golomb(&h->gb); - sps->crop_right = get_ue_golomb(&h->gb); - sps->crop_top = get_ue_golomb(&h->gb); - sps->crop_bottom= get_ue_golomb(&h->gb); + sps->crop = get_bits1(&h->gb); + if (sps->crop) { + int crop_left = get_ue_golomb(&h->gb); + int crop_right = get_ue_golomb(&h->gb); + int crop_top = get_ue_golomb(&h->gb); + int crop_bottom = get_ue_golomb(&h->gb); + int width = 16 * sps->mb_width; + int height = 16 * sps->mb_height * (2 - sps->frame_mbs_only_flag); + if (h->avctx->flags2 & CODEC_FLAG2_IGNORE_CROP) { - av_log(h->avctx, AV_LOG_DEBUG, - "discarding sps cropping, " - "original values are l:%u r:%u t:%u b:%u\n", - sps->crop_left, - sps->crop_right, - sps->crop_top, - sps->crop_bottom); + av_log(h->avctx, AV_LOG_DEBUG, "discarding sps cropping, original " + "values are l:%u r:%u t:%u b:%u\n", + crop_left, crop_right, crop_top, crop_bottom); sps->crop_left = sps->crop_right = sps->crop_top = sps->crop_bottom = 0; + } else { + int vsub = (sps->chroma_format_idc == 1) ? 1 : 0; + int hsub = (sps->chroma_format_idc == 1 || + sps->chroma_format_idc == 2) ? 1 : 0; + int step_x = 1 << hsub; + int step_y = (2 - sps->frame_mbs_only_flag) << vsub; + + if (crop_left & (0x1F >> (sps->bit_depth_luma > 8)) && + !(h->avctx->flags & CODEC_FLAG_UNALIGNED)) { + crop_left &= ~(0x1F >> (sps->bit_depth_luma > 8)); + av_log(h->avctx, AV_LOG_WARNING, + "Reducing left cropping to %d " + "chroma samples to preserve alignment.\n", + crop_left); + } + + if (crop_left > (unsigned)INT_MAX / 4 / step_x || + crop_right > (unsigned)INT_MAX / 4 / step_x || + crop_top > (unsigned)INT_MAX / 4 / step_y || + crop_bottom> (unsigned)INT_MAX / 4 / step_y || + (crop_left + crop_right ) * step_x >= width || + (crop_top + crop_bottom) * step_y >= height + ) { + av_log(h->avctx, AV_LOG_ERROR, "crop values invalid %d %d %d %d / %d %d\n", crop_left, crop_right, crop_top, crop_bottom, width, height); + goto fail; + } + + sps->crop_left = crop_left * step_x; + sps->crop_right = crop_right * step_x; + sps->crop_top = crop_top * step_y; + sps->crop_bottom = crop_bottom * step_y; } - if(sps->crop_left || sps->crop_top){ - av_log(h->avctx, AV_LOG_ERROR, "insane cropping not completely supported, this could look slightly wrong ... (left: %d, top: %d)\n", sps->crop_left, sps->crop_top); - } - if(sps->crop_right >= crop_horizontal_limit || sps->crop_bottom >= crop_vertical_limit){ - av_log(h->avctx, AV_LOG_ERROR, "brainfart cropping not supported, cropping disabled (right: %d, bottom: %d)\n", sps->crop_right, sps->crop_bottom); - /* It is very unlikely that partial cropping will make anybody happy. - * Not cropping at all fixes for example playback of Sisvel 3D streams - * in applications supporting Sisvel 3D. */ - sps->crop_left = - sps->crop_right = - sps->crop_top = - sps->crop_bottom= 0; - } - }else{ - sps->crop_left = - sps->crop_right = - sps->crop_top = - sps->crop_bottom= 0; + } else { + sps->crop_left = + sps->crop_right = + sps->crop_top = + sps->crop_bottom = + sps->crop = 0; } - sps->vui_parameters_present_flag= get_bits1(&h->gb); - if( sps->vui_parameters_present_flag ) - if (decode_vui_parameters(h, sps) < 0) + sps->vui_parameters_present_flag = get_bits1(&h->gb); + if (sps->vui_parameters_present_flag) { + int ret = decode_vui_parameters(h, sps); + if (ret < 0) goto fail; + } - if(!sps->sar.den) - sps->sar.den= 1; + if (!sps->sar.den) + sps->sar.den = 1; - if(h->avctx->debug&FF_DEBUG_PICT_INFO){ + if (h->avctx->debug & FF_DEBUG_PICT_INFO) { static const char csp[4][5] = { "Gray", "420", "422", "444" }; - av_log(h->avctx, AV_LOG_DEBUG, "sps:%u profile:%d/%d poc:%d ref:%d %dx%d %s %s crop:%d/%d/%d/%d %s %s %d/%d b%d reo:%d\n", + av_log(h->avctx, AV_LOG_DEBUG, + "sps:%u profile:%d/%d poc:%d ref:%d %dx%d %s %s crop:%d/%d/%d/%d %s %s %d/%d b%d reo:%d\n", sps_id, sps->profile_idc, sps->level_idc, sps->poc_type, sps->ref_frame_count, @@ -530,22 +553,21 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ av_free(h->sps_buffers[sps_id]); h->sps_buffers[sps_id] = sps; - h->sps = *sps; - h->current_sps_id = sps_id; return 0; + fail: av_free(sps); return -1; } -static void -build_qp_table(PPS *pps, int t, int index, const int depth) +static void build_qp_table(PPS *pps, int t, int index, const int depth) { int i; - const int max_qp = 51 + 6*(depth-8); - for(i = 0; i < max_qp+1; i++) - pps->chroma_qp_table[t][i] = ff_h264_chroma_qp[depth-8][av_clip(i + index, 0, max_qp)]; + const int max_qp = 51 + 6 * (depth - 8); + for (i = 0; i < max_qp + 1; i++) + pps->chroma_qp_table[t][i] = + ff_h264_chroma_qp[depth - 8][av_clip(i + index, 0, max_qp)]; } static int more_rbsp_data_in_pps(H264Context *h, PPS *pps) @@ -563,109 +585,123 @@ static int more_rbsp_data_in_pps(H264Context *h, PPS *pps) return 1; } -int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length){ - unsigned int pps_id= get_ue_golomb(&h->gb); +int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length) +{ + unsigned int pps_id = get_ue_golomb(&h->gb); PPS *pps; - const int qp_bd_offset = 6*(h->sps.bit_depth_luma-8); + SPS *sps; + int qp_bd_offset; int bits_left; - if(pps_id >= MAX_PPS_COUNT) { + if (pps_id >= MAX_PPS_COUNT) { av_log(h->avctx, AV_LOG_ERROR, "pps_id (%d) out of range\n", pps_id); - return -1; - } else if (h->sps.bit_depth_luma > 14) { - av_log(h->avctx, AV_LOG_ERROR, "Invalid luma bit depth=%d\n", h->sps.bit_depth_luma); return AVERROR_INVALIDDATA; - } else if (h->sps.bit_depth_luma == 11 || h->sps.bit_depth_luma == 13) { - av_log(h->avctx, AV_LOG_ERROR, "Unimplemented luma bit depth=%d\n", h->sps.bit_depth_luma); - return AVERROR_PATCHWELCOME; } - pps= av_mallocz(sizeof(PPS)); - if(pps == NULL) - return -1; - pps->sps_id= get_ue_golomb_31(&h->gb); - if((unsigned)pps->sps_id>=MAX_SPS_COUNT || h->sps_buffers[pps->sps_id] == NULL){ + pps = av_mallocz(sizeof(PPS)); + if (!pps) + return AVERROR(ENOMEM); + pps->sps_id = get_ue_golomb_31(&h->gb); + if ((unsigned)pps->sps_id >= MAX_SPS_COUNT || + h->sps_buffers[pps->sps_id] == NULL) { av_log(h->avctx, AV_LOG_ERROR, "sps_id out of range\n"); goto fail; } + sps = h->sps_buffers[pps->sps_id]; + qp_bd_offset = 6 * (sps->bit_depth_luma - 8); + if (sps->bit_depth_luma > 14) { + av_log(h->avctx, AV_LOG_ERROR, + "Invalid luma bit depth=%d\n", + sps->bit_depth_luma); + goto fail; + } else if (sps->bit_depth_luma == 11 || sps->bit_depth_luma == 13) { + av_log(h->avctx, AV_LOG_ERROR, + "Unimplemented luma bit depth=%d\n", + sps->bit_depth_luma); + goto fail; + } - pps->cabac= get_bits1(&h->gb); - pps->pic_order_present= get_bits1(&h->gb); - pps->slice_group_count= get_ue_golomb(&h->gb) + 1; - if(pps->slice_group_count > 1 ){ - pps->mb_slice_group_map_type= get_ue_golomb(&h->gb); + pps->cabac = get_bits1(&h->gb); + pps->pic_order_present = get_bits1(&h->gb); + pps->slice_group_count = get_ue_golomb(&h->gb) + 1; + if (pps->slice_group_count > 1) { + pps->mb_slice_group_map_type = get_ue_golomb(&h->gb); av_log(h->avctx, AV_LOG_ERROR, "FMO not supported\n"); - switch(pps->mb_slice_group_map_type){ + switch (pps->mb_slice_group_map_type) { case 0: #if 0 -| for( i = 0; i <= num_slice_groups_minus1; i++ ) | | | -| run_length[ i ] |1 |ue(v) | + | for (i = 0; i <= num_slice_groups_minus1; i++) | | | + | run_length[i] |1 |ue(v) | #endif break; case 2: #if 0 -| for( i = 0; i < num_slice_groups_minus1; i++ ) | | | -|{ | | | -| top_left_mb[ i ] |1 |ue(v) | -| bottom_right_mb[ i ] |1 |ue(v) | -| } | | | + | for (i = 0; i < num_slice_groups_minus1; i++) { | | | + | top_left_mb[i] |1 |ue(v) | + | bottom_right_mb[i] |1 |ue(v) | + | } | | | #endif break; case 3: case 4: case 5: #if 0 -| slice_group_change_direction_flag |1 |u(1) | -| slice_group_change_rate_minus1 |1 |ue(v) | + | slice_group_change_direction_flag |1 |u(1) | + | slice_group_change_rate_minus1 |1 |ue(v) | #endif break; case 6: #if 0 -| slice_group_id_cnt_minus1 |1 |ue(v) | -| for( i = 0; i <= slice_group_id_cnt_minus1; i++ | | | -|) | | | -| slice_group_id[ i ] |1 |u(v) | + | slice_group_id_cnt_minus1 |1 |ue(v) | + | for (i = 0; i <= slice_group_id_cnt_minus1; i++)| | | + | slice_group_id[i] |1 |u(v) | #endif break; } } - pps->ref_count[0]= get_ue_golomb(&h->gb) + 1; - pps->ref_count[1]= get_ue_golomb(&h->gb) + 1; - if(pps->ref_count[0]-1 > 32-1 || pps->ref_count[1]-1 > 32-1){ + pps->ref_count[0] = get_ue_golomb(&h->gb) + 1; + pps->ref_count[1] = get_ue_golomb(&h->gb) + 1; + if (pps->ref_count[0] - 1 > 32 - 1 || pps->ref_count[1] - 1 > 32 - 1) { av_log(h->avctx, AV_LOG_ERROR, "reference overflow (pps)\n"); goto fail; } - pps->weighted_pred= get_bits1(&h->gb); - pps->weighted_bipred_idc= get_bits(&h->gb, 2); - pps->init_qp= get_se_golomb(&h->gb) + 26 + qp_bd_offset; - pps->init_qs= get_se_golomb(&h->gb) + 26 + qp_bd_offset; - pps->chroma_qp_index_offset[0]= get_se_golomb(&h->gb); - pps->deblocking_filter_parameters_present= get_bits1(&h->gb); - pps->constrained_intra_pred= get_bits1(&h->gb); - pps->redundant_pic_cnt_present = get_bits1(&h->gb); - - pps->transform_8x8_mode= 0; - h->dequant_coeff_pps= -1; //contents of sps/pps can change even if id doesn't, so reinit - memcpy(pps->scaling_matrix4, h->sps_buffers[pps->sps_id]->scaling_matrix4, sizeof(pps->scaling_matrix4)); - memcpy(pps->scaling_matrix8, h->sps_buffers[pps->sps_id]->scaling_matrix8, sizeof(pps->scaling_matrix8)); + pps->weighted_pred = get_bits1(&h->gb); + pps->weighted_bipred_idc = get_bits(&h->gb, 2); + pps->init_qp = get_se_golomb(&h->gb) + 26 + qp_bd_offset; + pps->init_qs = get_se_golomb(&h->gb) + 26 + qp_bd_offset; + pps->chroma_qp_index_offset[0] = get_se_golomb(&h->gb); + pps->deblocking_filter_parameters_present = get_bits1(&h->gb); + pps->constrained_intra_pred = get_bits1(&h->gb); + pps->redundant_pic_cnt_present = get_bits1(&h->gb); + + pps->transform_8x8_mode = 0; + // contents of sps/pps can change even if id doesn't, so reinit + h->dequant_coeff_pps = -1; + memcpy(pps->scaling_matrix4, h->sps_buffers[pps->sps_id]->scaling_matrix4, + sizeof(pps->scaling_matrix4)); + memcpy(pps->scaling_matrix8, h->sps_buffers[pps->sps_id]->scaling_matrix8, + sizeof(pps->scaling_matrix8)); bits_left = bit_length - get_bits_count(&h->gb); - if(bits_left > 0 && more_rbsp_data_in_pps(h, pps)){ - pps->transform_8x8_mode= get_bits1(&h->gb); - decode_scaling_matrices(h, h->sps_buffers[pps->sps_id], pps, 0, pps->scaling_matrix4, pps->scaling_matrix8); - pps->chroma_qp_index_offset[1]= get_se_golomb(&h->gb); //second_chroma_qp_index_offset + if (bits_left > 0 && more_rbsp_data_in_pps(h, pps)) { + pps->transform_8x8_mode = get_bits1(&h->gb); + decode_scaling_matrices(h, h->sps_buffers[pps->sps_id], pps, 0, + pps->scaling_matrix4, pps->scaling_matrix8); + // second_chroma_qp_index_offset + pps->chroma_qp_index_offset[1] = get_se_golomb(&h->gb); } else { - pps->chroma_qp_index_offset[1]= pps->chroma_qp_index_offset[0]; + pps->chroma_qp_index_offset[1] = pps->chroma_qp_index_offset[0]; } - build_qp_table(pps, 0, pps->chroma_qp_index_offset[0], h->sps.bit_depth_luma); - build_qp_table(pps, 1, pps->chroma_qp_index_offset[1], h->sps.bit_depth_luma); - if(pps->chroma_qp_index_offset[0] != pps->chroma_qp_index_offset[1]) - pps->chroma_qp_diff= 1; + build_qp_table(pps, 0, pps->chroma_qp_index_offset[0], sps->bit_depth_luma); + build_qp_table(pps, 1, pps->chroma_qp_index_offset[1], sps->bit_depth_luma); + if (pps->chroma_qp_index_offset[0] != pps->chroma_qp_index_offset[1]) + pps->chroma_qp_diff = 1; - if(h->avctx->debug&FF_DEBUG_PICT_INFO){ - av_log(h->avctx, AV_LOG_DEBUG, "pps:%u sps:%u %s slice_groups:%d ref:%d/%d %s qp:%d/%d/%d/%d %s %s %s %s\n", + if (h->avctx->debug & FF_DEBUG_PICT_INFO) { + av_log(h->avctx, AV_LOG_DEBUG, + "pps:%u sps:%u %s slice_groups:%d ref:%d/%d %s qp:%d/%d/%d/%d %s %s %s %s\n", pps_id, pps->sps_id, pps->cabac ? "CABAC" : "CAVLC", pps->slice_group_count, @@ -675,13 +711,13 @@ int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length){ pps->deblocking_filter_parameters_present ? "LPAR" : "", pps->constrained_intra_pred ? "CONSTR" : "", pps->redundant_pic_cnt_present ? "REDU" : "", - pps->transform_8x8_mode ? "8x8DCT" : "" - ); + pps->transform_8x8_mode ? "8x8DCT" : ""); } av_free(h->pps_buffers[pps_id]); - h->pps_buffers[pps_id]= pps; + h->pps_buffers[pps_id] = pps; return 0; + fail: av_free(pps); return -1; diff --git a/ffmpeg/libavcodec/h264_refs.c b/ffmpeg/libavcodec/h264_refs.c index c3e7b7c..7eb1f9e 100644 --- a/ffmpeg/libavcodec/h264_refs.c +++ b/ffmpeg/libavcodec/h264_refs.c @@ -31,7 +31,6 @@ #include "h264.h" #include "golomb.h" -//#undef NDEBUG #include #define COPY_PICTURE(dst, src) \ @@ -69,7 +68,8 @@ static int split_field_copy(Picture *dest, Picture *src, int parity, int id_add) return match; } -static int build_def_list(Picture *def, Picture **in, int len, int is_long, int sel) +static int build_def_list(Picture *def, int def_len, + Picture **in, int len, int is_long, int sel) { int i[2] = { 0 }; int index = 0; @@ -80,10 +80,12 @@ static int build_def_list(Picture *def, Picture **in, int len, int is_long, int while (i[1] < len && !(in[i[1]] && (in[i[1]]->reference & (sel ^ 3)))) i[1]++; if (i[0] < len) { + av_assert0(index < def_len); in[i[0]]->pic_id = is_long ? i[0] : in[i[0]]->frame_num; split_field_copy(&def[index++], in[i[0]++], sel, 1); } if (i[1] < len) { + av_assert0(index < def_len); in[i[1]]->pic_id = is_long ? i[1] : in[i[1]]->frame_num; split_field_copy(&def[index++], in[i[1]++], sel ^ 3, 0); } @@ -132,8 +134,12 @@ int ff_h264_fill_default_ref_list(H264Context *h) len = add_sorted(sorted, h->short_ref, h->short_ref_count, cur_poc, 1 ^ list); len += add_sorted(sorted + len, h->short_ref, h->short_ref_count, cur_poc, 0 ^ list); av_assert0(len <= 32); - len = build_def_list(h->default_ref_list[list], sorted, len, 0, h->picture_structure); - len += build_def_list(h->default_ref_list[list] + len, h->long_ref, 16, 1, h->picture_structure); + + len = build_def_list(h->default_ref_list[list], FF_ARRAY_ELEMS(h->default_ref_list[0]), + sorted, len, 0, h->picture_structure); + len += build_def_list(h->default_ref_list[list] + len, + FF_ARRAY_ELEMS(h->default_ref_list[0]) - len, + h->long_ref, 16, 1, h->picture_structure); av_assert0(len <= 32); if (len < h->ref_count[list]) @@ -142,7 +148,9 @@ int ff_h264_fill_default_ref_list(H264Context *h) } if (lens[0] == lens[1] && lens[1] > 1) { - for (i = 0; h->default_ref_list[0][i].f.data[0] == h->default_ref_list[1][i].f.data[0] && i < lens[0]; i++); + for (i = 0; i < lens[0] && + h->default_ref_list[0][i].f.buf[0]->buffer == + h->default_ref_list[1][i].f.buf[0]->buffer; i++); if (i == lens[0]) { Picture tmp; COPY_PICTURE(&tmp, &h->default_ref_list[1][0]); @@ -151,9 +159,13 @@ int ff_h264_fill_default_ref_list(H264Context *h) } } } else { - len = build_def_list(h->default_ref_list[0], h->short_ref, h->short_ref_count, 0, h->picture_structure); - len += build_def_list(h->default_ref_list[0] + len, h-> long_ref, 16, 1, h->picture_structure); + len = build_def_list(h->default_ref_list[0], FF_ARRAY_ELEMS(h->default_ref_list[0]), + h->short_ref, h->short_ref_count, 0, h->picture_structure); + len += build_def_list(h->default_ref_list[0] + len, + FF_ARRAY_ELEMS(h->default_ref_list[0]) - len, + h-> long_ref, 16, 1, h->picture_structure); av_assert0(len <= 32); + if (len < h->ref_count[0]) memset(&h->default_ref_list[0][len], 0, sizeof(Picture) * (h->ref_count[0] - len)); } @@ -305,18 +317,19 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h) } for (list = 0; list < h->list_count; list++) { for (index = 0; index < h->ref_count[list]; index++) { - if ( !h->ref_list[list][index].f.data[0] + if ( !h->ref_list[list][index].f.buf[0] || (!FIELD_PICTURE(h) && (h->ref_list[list][index].reference&3) != 3)) { int i; av_log(h->avctx, AV_LOG_ERROR, "Missing reference picture, default is %d\n", h->default_ref_list[list][0].poc); for (i = 0; i < FF_ARRAY_ELEMS(h->last_pocs); i++) h->last_pocs[i] = INT_MIN; - if (h->default_ref_list[list][0].f.data[0] + if (h->default_ref_list[list][0].f.buf[0] && !(!FIELD_PICTURE(h) && (h->default_ref_list[list][0].reference&3) != 3)) COPY_PICTURE(&h->ref_list[list][index], &h->default_ref_list[list][0]); else return -1; } + av_assert0(av_buffer_get_ref_count(h->ref_list[list][index].f.buf[0]) > 0); } } @@ -562,6 +575,7 @@ int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice) int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count) { int i, av_uninit(j); + int pps_count; int current_ref_assigned = 0, err = 0; Picture *av_uninit(pic); @@ -582,7 +596,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count) if (mmco[i].opcode != MMCO_SHORT2LONG || !h->long_ref[mmco[i].long_arg] || h->long_ref[mmco[i].long_arg]->frame_num != frame_num) { - av_log(h->avctx, AV_LOG_ERROR, "mmco: unref short failure\n"); + av_log(h->avctx, h->short_ref_count ? AV_LOG_ERROR : AV_LOG_DEBUG, "mmco: unref short failure\n"); err = AVERROR_INVALIDDATA; } continue; @@ -625,7 +639,19 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count) */ if (h->long_ref[mmco[i].long_arg] != h->cur_pic_ptr) { + if (h->cur_pic_ptr->long_ref) { + for(j=0; j<16; j++) { + if(h->long_ref[j] == h->cur_pic_ptr) { + remove_long(h, j, 0); + av_log(h->avctx, AV_LOG_ERROR, "mmco: cannot assign current picture to 2 long term references\n"); + } + } + } + av_assert0(!h->cur_pic_ptr->long_ref); remove_long(h, mmco[i].long_arg, 0); + if (remove_short(h, h->cur_pic_ptr->frame_num, 0)) { + av_log(h->avctx, AV_LOG_ERROR, "mmco: cannot assign current picture to short and long at the same time\n"); + } h->long_ref[mmco[i].long_arg] = h->cur_pic_ptr; h->long_ref[mmco[i].long_arg]->long_ref = 1; @@ -720,10 +746,18 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count) print_short_term(h); print_long_term(h); - if(err >= 0 && h->long_ref_count==0 && h->short_ref_count<=2 && h->pps.ref_count[0]<=1 + (h->picture_structure != PICT_FRAME) && h->cur_pic_ptr->f.pict_type == AV_PICTURE_TYPE_I){ - h->cur_pic_ptr->sync |= 1; + pps_count = 0; + for (i = 0; i < FF_ARRAY_ELEMS(h->pps_buffers); i++) + pps_count += !!h->pps_buffers[i]; + + if ( err >= 0 + && h->long_ref_count==0 + && (h->short_ref_count<=2 || h->pps.ref_count[0] <= 1 && h->pps.ref_count[1] <= 1 && pps_count == 1) + && h->pps.ref_count[0]<=2 + (h->picture_structure != PICT_FRAME) + && h->cur_pic_ptr->f.pict_type == AV_PICTURE_TYPE_I){ + h->cur_pic_ptr->recovered |= 1; if(!h->avctx->has_b_frames) - h->sync = 2; + h->frame_recovered |= FRAME_RECOVERED_SEI; } return (h->avctx->err_recognition & AV_EF_EXPLODE) ? err : 0; @@ -733,7 +767,7 @@ int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb, int first_slice) { int i, ret; - MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = first_slice ? h->mmco : mmco_temp; + MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = mmco_temp; int mmco_index = 0; if (h->nal_unit_type == NAL_IDR_SLICE) { // FIXME fields @@ -799,10 +833,11 @@ int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb, } if (first_slice && mmco_index != -1) { + memcpy(h->mmco, mmco_temp, sizeof(h->mmco)); h->mmco_index = mmco_index; } else if (!first_slice && mmco_index >= 0 && (mmco_index != h->mmco_index || - (i = check_opcodes(h->mmco, mmco_temp, mmco_index)))) { + check_opcodes(h->mmco, mmco_temp, mmco_index))) { av_log(h->avctx, AV_LOG_ERROR, "Inconsistent MMCO state between slices [%d, %d]\n", mmco_index, h->mmco_index); diff --git a/ffmpeg/libavcodec/h264_sei.c b/ffmpeg/libavcodec/h264_sei.c index be6cb58..12d709b 100644 --- a/ffmpeg/libavcodec/h264_sei.c +++ b/ffmpeg/libavcodec/h264_sei.c @@ -30,71 +30,87 @@ #include "h264.h" #include "golomb.h" -//#undef NDEBUG #include -static const uint8_t sei_num_clock_ts_table[9]={ - 1, 1, 1, 2, 2, 3, 3, 2, 3 +static const uint8_t sei_num_clock_ts_table[9] = { + 1, 1, 1, 2, 2, 3, 3, 2, 3 }; -void ff_h264_reset_sei(H264Context *h) { +void ff_h264_reset_sei(H264Context *h) +{ h->sei_recovery_frame_cnt = -1; h->sei_dpb_output_delay = 0; h->sei_cpb_removal_delay = -1; h->sei_buffering_period_present = 0; + h->sei_frame_packing_present = 0; } -static int decode_picture_timing(H264Context *h){ - if(h->sps.nal_hrd_parameters_present_flag || h->sps.vcl_hrd_parameters_present_flag){ - h->sei_cpb_removal_delay = get_bits_long(&h->gb, h->sps.cpb_removal_delay_length); - h->sei_dpb_output_delay = get_bits_long(&h->gb, h->sps.dpb_output_delay_length); +static int decode_picture_timing(H264Context *h) +{ + SPS *sps = &h->sps; + int i; + + for (i = 0; ilog2_max_frame_num && h->sps_buffers[i]) + sps = h->sps_buffers[i]; + + if (sps->nal_hrd_parameters_present_flag || sps->vcl_hrd_parameters_present_flag) { + h->sei_cpb_removal_delay = get_bits_long(&h->gb, + sps->cpb_removal_delay_length); + h->sei_dpb_output_delay = get_bits_long(&h->gb, + sps->dpb_output_delay_length); } - if(h->sps.pic_struct_present_flag){ + if (sps->pic_struct_present_flag) { unsigned int i, num_clock_ts; + h->sei_pic_struct = get_bits(&h->gb, 4); h->sei_ct_type = 0; if (h->sei_pic_struct > SEI_PIC_STRUCT_FRAME_TRIPLING) - return -1; + return AVERROR_INVALIDDATA; num_clock_ts = sei_num_clock_ts_table[h->sei_pic_struct]; - for (i = 0 ; i < num_clock_ts ; i++){ - if(get_bits(&h->gb, 1)){ /* clock_timestamp_flag */ + for (i = 0; i < num_clock_ts; i++) { + if (get_bits(&h->gb, 1)) { /* clock_timestamp_flag */ unsigned int full_timestamp_flag; - h->sei_ct_type |= 1<gb, 2); + + h->sei_ct_type |= 1 << get_bits(&h->gb, 2); skip_bits(&h->gb, 1); /* nuit_field_based_flag */ skip_bits(&h->gb, 5); /* counting_type */ full_timestamp_flag = get_bits(&h->gb, 1); skip_bits(&h->gb, 1); /* discontinuity_flag */ skip_bits(&h->gb, 1); /* cnt_dropped_flag */ skip_bits(&h->gb, 8); /* n_frames */ - if(full_timestamp_flag){ + if (full_timestamp_flag) { skip_bits(&h->gb, 6); /* seconds_value 0..59 */ skip_bits(&h->gb, 6); /* minutes_value 0..59 */ skip_bits(&h->gb, 5); /* hours_value 0..23 */ - }else{ - if(get_bits(&h->gb, 1)){ /* seconds_flag */ + } else { + if (get_bits(&h->gb, 1)) { /* seconds_flag */ skip_bits(&h->gb, 6); /* seconds_value range 0..59 */ - if(get_bits(&h->gb, 1)){ /* minutes_flag */ + if (get_bits(&h->gb, 1)) { /* minutes_flag */ skip_bits(&h->gb, 6); /* minutes_value 0..59 */ - if(get_bits(&h->gb, 1)) /* hours_flag */ + if (get_bits(&h->gb, 1)) /* hours_flag */ skip_bits(&h->gb, 5); /* hours_value 0..23 */ } } } - if(h->sps.time_offset_length > 0) - skip_bits(&h->gb, h->sps.time_offset_length); /* time_offset */ + if (sps->time_offset_length > 0) + skip_bits(&h->gb, + sps->time_offset_length); /* time_offset */ } } - if(h->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(h->avctx, AV_LOG_DEBUG, "ct_type:%X pic_struct:%d\n", h->sei_ct_type, h->sei_pic_struct); + if (h->avctx->debug & FF_DEBUG_PICT_INFO) + av_log(h->avctx, AV_LOG_DEBUG, "ct_type:%X pic_struct:%d\n", + h->sei_ct_type, h->sei_pic_struct); } return 0; } -static int decode_user_data_itu_t_t35(H264Context *h, int size) { +static int decode_user_data_itu_t_t35(H264Context *h, int size) +{ uint32_t user_identifier; int dtg_active_format; @@ -130,66 +146,77 @@ static int decode_user_data_itu_t_t35(H264Context *h, int size) { return 0; } -static int decode_unregistered_user_data(H264Context *h, int size){ - uint8_t user_data[16+256]; +static int decode_unregistered_user_data(H264Context *h, int size) +{ + uint8_t user_data[16 + 256]; int e, build, i; - if(size<16) - return -1; + if (size < 16) + return AVERROR_INVALIDDATA; - for(i=0; igb, 8); - } + for (i = 0; i < sizeof(user_data) - 1 && i < size; i++) + user_data[i] = get_bits(&h->gb, 8); - user_data[i]= 0; - e= sscanf(user_data+16, "x264 - core %d"/*%s - H.264/MPEG-4 AVC codec - Copyleft 2005 - http://www.videolan.org/x264.html*/, &build); - if(e==1 && build>0) - h->x264_build= build; - if(e==1 && build==1 && !strncmp(user_data+16, "x264 - core 0000", 16)) + user_data[i] = 0; + e = sscanf(user_data + 16, "x264 - core %d", &build); + if (e == 1 && build > 0) + h->x264_build = build; + if (e == 1 && build == 1 && !strncmp(user_data+16, "x264 - core 0000", 16)) h->x264_build = 67; - if(h->avctx->debug & FF_DEBUG_BUGS) - av_log(h->avctx, AV_LOG_DEBUG, "user data:\"%s\"\n", user_data+16); + if (h->avctx->debug & FF_DEBUG_BUGS) + av_log(h->avctx, AV_LOG_DEBUG, "user data:\"%s\"\n", user_data + 16); - for(; igb, 8); return 0; } -static int decode_recovery_point(H264Context *h){ +static int decode_recovery_point(H264Context *h) +{ h->sei_recovery_frame_cnt = get_ue_golomb(&h->gb); - skip_bits(&h->gb, 4); /* 1b exact_match_flag, 1b broken_link_flag, 2b changing_slice_group_idc */ - if(h->avctx->debug & FF_DEBUG_PICT_INFO) + /* 1b exact_match_flag, + * 1b broken_link_flag, + * 2b changing_slice_group_idc */ + skip_bits(&h->gb, 4); + + if (h->avctx->debug & FF_DEBUG_PICT_INFO) av_log(h->avctx, AV_LOG_DEBUG, "sei_recovery_frame_cnt: %d\n", h->sei_recovery_frame_cnt); return 0; } -static int decode_buffering_period(H264Context *h){ +static int decode_buffering_period(H264Context *h) +{ unsigned int sps_id; int sched_sel_idx; SPS *sps; sps_id = get_ue_golomb_31(&h->gb); - if(sps_id > 31 || !h->sps_buffers[sps_id]) { - av_log(h->avctx, AV_LOG_ERROR, "non-existing SPS %d referenced in buffering period\n", sps_id); - return -1; + if (sps_id > 31 || !h->sps_buffers[sps_id]) { + av_log(h->avctx, AV_LOG_ERROR, + "non-existing SPS %d referenced in buffering period\n", sps_id); + return AVERROR_INVALIDDATA; } sps = h->sps_buffers[sps_id]; // NOTE: This is really so duplicated in the standard... See H.264, D.1.1 if (sps->nal_hrd_parameters_present_flag) { for (sched_sel_idx = 0; sched_sel_idx < sps->cpb_cnt; sched_sel_idx++) { - h->initial_cpb_removal_delay[sched_sel_idx] = get_bits_long(&h->gb, sps->initial_cpb_removal_delay_length); - skip_bits(&h->gb, sps->initial_cpb_removal_delay_length); // initial_cpb_removal_delay_offset + h->initial_cpb_removal_delay[sched_sel_idx] = + get_bits_long(&h->gb, sps->initial_cpb_removal_delay_length); + // initial_cpb_removal_delay_offset + skip_bits(&h->gb, sps->initial_cpb_removal_delay_length); } } if (sps->vcl_hrd_parameters_present_flag) { for (sched_sel_idx = 0; sched_sel_idx < sps->cpb_cnt; sched_sel_idx++) { - h->initial_cpb_removal_delay[sched_sel_idx] = get_bits_long(&h->gb, sps->initial_cpb_removal_delay_length); - skip_bits(&h->gb, sps->initial_cpb_removal_delay_length); // initial_cpb_removal_delay_offset + h->initial_cpb_removal_delay[sched_sel_idx] = + get_bits_long(&h->gb, sps->initial_cpb_removal_delay_length); + // initial_cpb_removal_delay_offset + skip_bits(&h->gb, sps->initial_cpb_removal_delay_length); } } @@ -197,55 +224,157 @@ static int decode_buffering_period(H264Context *h){ return 0; } -int ff_h264_decode_sei(H264Context *h){ +static int decode_frame_packing_arrangement(H264Context *h) +{ + h->sei_fpa.frame_packing_arrangement_id = get_ue_golomb(&h->gb); + h->sei_fpa.frame_packing_arrangement_cancel_flag = get_bits1(&h->gb); + h->sei_frame_packing_present = !h->sei_fpa.frame_packing_arrangement_cancel_flag; + + if (h->sei_frame_packing_present) { + h->sei_fpa.frame_packing_arrangement_type = + h->frame_packing_arrangement_type = get_bits(&h->gb, 7); + h->sei_fpa.quincunx_sampling_flag = + h->quincunx_subsampling = get_bits1(&h->gb); + h->sei_fpa.content_interpretation_type = + h->content_interpretation_type = get_bits(&h->gb, 6); + + // the following skips: spatial_flipping_flag, frame0_flipped_flag, + // field_views_flag, current_frame_is_frame0_flag, + // frame0_self_contained_flag, frame1_self_contained_flag + skip_bits(&h->gb, 6); + + if (!h->quincunx_subsampling && h->frame_packing_arrangement_type != 5) + skip_bits(&h->gb, 16); // frame[01]_grid_position_[xy] + skip_bits(&h->gb, 8); // frame_packing_arrangement_reserved_byte + h->sei_fpa.frame_packing_arrangement_repetition_period = get_ue_golomb(&h->gb) /* frame_packing_arrangement_repetition_period */; + } + skip_bits1(&h->gb); // frame_packing_arrangement_extension_flag + + if (h->avctx->debug & FF_DEBUG_PICT_INFO) + av_log(h->avctx, AV_LOG_DEBUG, "SEI FPA %d %d %d %d %d %d\n", + h->sei_fpa.frame_packing_arrangement_id, + h->sei_fpa.frame_packing_arrangement_cancel_flag, + h->sei_fpa.frame_packing_arrangement_type, + h->sei_fpa.quincunx_sampling_flag, + h->sei_fpa.content_interpretation_type, + h->sei_fpa.frame_packing_arrangement_repetition_period); + + return 0; +} + +int ff_h264_decode_sei(H264Context *h) +{ while (get_bits_left(&h->gb) > 16) { - int size, type; + int type = 0; + unsigned size = 0; + unsigned next; + int ret = 0; - type=0; - do{ + do { if (get_bits_left(&h->gb) < 8) - return -1; - type+= show_bits(&h->gb, 8); - }while(get_bits(&h->gb, 8) == 255); + return AVERROR_INVALIDDATA; + type += show_bits(&h->gb, 8); + } while (get_bits(&h->gb, 8) == 255); - size=0; - do{ + do { if (get_bits_left(&h->gb) < 8) - return -1; - size+= show_bits(&h->gb, 8); - }while(get_bits(&h->gb, 8) == 255); + return AVERROR_INVALIDDATA; + size += show_bits(&h->gb, 8); + } while (get_bits(&h->gb, 8) == 255); - if(h->avctx->debug&FF_DEBUG_STARTCODE) + if (h->avctx->debug&FF_DEBUG_STARTCODE) av_log(h->avctx, AV_LOG_DEBUG, "SEI %d len:%d\n", type, size); - switch(type){ + if (size > get_bits_left(&h->gb) / 8) { + av_log(h->avctx, AV_LOG_ERROR, "SEI type %d size %d truncated at %d\n", + type, 8*size, get_bits_left(&h->gb)); + return AVERROR_INVALIDDATA; + } + next = get_bits_count(&h->gb) + 8 * size; + + switch (type) { case SEI_TYPE_PIC_TIMING: // Picture timing SEI - if(decode_picture_timing(h) < 0) - return -1; + ret = decode_picture_timing(h); + if (ret < 0) + return ret; break; case SEI_TYPE_USER_DATA_ITU_T_T35: - if(decode_user_data_itu_t_t35(h, size) < 0) + if (decode_user_data_itu_t_t35(h, size) < 0) return -1; break; case SEI_TYPE_USER_DATA_UNREGISTERED: - if(decode_unregistered_user_data(h, size) < 0) - return -1; + ret = decode_unregistered_user_data(h, size); + if (ret < 0) + return ret; break; case SEI_TYPE_RECOVERY_POINT: - if(decode_recovery_point(h) < 0) - return -1; + ret = decode_recovery_point(h); + if (ret < 0) + return ret; break; case SEI_BUFFERING_PERIOD: - if(decode_buffering_period(h) < 0) - return -1; + ret = decode_buffering_period(h); + if (ret < 0) + return ret; + break; + case SEI_TYPE_FRAME_PACKING: + ret = decode_frame_packing_arrangement(h); + if (ret < 0) + return ret; break; default: - skip_bits(&h->gb, 8*size); + av_log(h->avctx, AV_LOG_DEBUG, "unknown SEI type %d\n", type); } + skip_bits_long(&h->gb, next - get_bits_count(&h->gb)); - //FIXME check bits here + // FIXME check bits here align_get_bits(&h->gb); } return 0; } + +const char* ff_h264_sei_stereo_mode(H264Context *h) +{ + if (h->sei_fpa.frame_packing_arrangement_cancel_flag == 0) { + switch (h->sei_fpa.frame_packing_arrangement_type) { + case SEI_FPA_TYPE_CHECKERBOARD: + if (h->sei_fpa.content_interpretation_type == 2) + return "checkerboard_rl"; + else + return "checkerboard_lr"; + case SEI_FPA_TYPE_INTERLEAVE_COLUMN: + if (h->sei_fpa.content_interpretation_type == 2) + return "col_interleaved_rl"; + else + return "col_interleaved_lr"; + case SEI_FPA_TYPE_INTERLEAVE_ROW: + if (h->sei_fpa.content_interpretation_type == 2) + return "row_interleaved_rl"; + else + return "row_interleaved_lr"; + case SEI_FPA_TYPE_SIDE_BY_SIDE: + if (h->sei_fpa.content_interpretation_type == 2) + return "right_left"; + else + return "left_right"; + case SEI_FPA_TYPE_TOP_BOTTOM: + if (h->sei_fpa.content_interpretation_type == 2) + return "bottom_top"; + else + return "top_bottom"; + case SEI_FPA_TYPE_INTERLEAVE_TEMPORAL: + if (h->sei_fpa.content_interpretation_type == 2) + return "block_rl"; + else + return "block_lr"; + case SEI_FPA_TYPE_2D: + default: + return "mono"; + } + } else if (h->sei_fpa.frame_packing_arrangement_cancel_flag == 1) { + return "mono"; + } else { + return NULL; + } +} diff --git a/ffmpeg/libavcodec/h264chroma.c b/ffmpeg/libavcodec/h264chroma.c index 3b780a0..5f8ed91 100644 --- a/ffmpeg/libavcodec/h264chroma.c +++ b/ffmpeg/libavcodec/h264chroma.c @@ -17,6 +17,7 @@ */ #include "config.h" +#include "libavutil/attributes.h" #include "h264chroma.h" #define BIT_DEPTH 8 @@ -31,11 +32,13 @@ c->put_h264_chroma_pixels_tab[0] = put_h264_chroma_mc8_ ## depth ## _c; \ c->put_h264_chroma_pixels_tab[1] = put_h264_chroma_mc4_ ## depth ## _c; \ c->put_h264_chroma_pixels_tab[2] = put_h264_chroma_mc2_ ## depth ## _c; \ + c->put_h264_chroma_pixels_tab[3] = put_h264_chroma_mc1_ ## depth ## _c; \ c->avg_h264_chroma_pixels_tab[0] = avg_h264_chroma_mc8_ ## depth ## _c; \ c->avg_h264_chroma_pixels_tab[1] = avg_h264_chroma_mc4_ ## depth ## _c; \ c->avg_h264_chroma_pixels_tab[2] = avg_h264_chroma_mc2_ ## depth ## _c; \ + c->avg_h264_chroma_pixels_tab[3] = avg_h264_chroma_mc1_ ## depth ## _c; \ -void ff_h264chroma_init(H264ChromaContext *c, int bit_depth) +av_cold void ff_h264chroma_init(H264ChromaContext *c, int bit_depth) { if (bit_depth > 8 && bit_depth <= 16) { SET_CHROMA(16); @@ -47,8 +50,6 @@ void ff_h264chroma_init(H264ChromaContext *c, int bit_depth) ff_h264chroma_init_arm(c, bit_depth); if (ARCH_PPC) ff_h264chroma_init_ppc(c, bit_depth); - if (ARCH_SH4) - ff_h264chroma_init_sh4(c, bit_depth); if (ARCH_X86) ff_h264chroma_init_x86(c, bit_depth); } diff --git a/ffmpeg/libavcodec/h264chroma.h b/ffmpeg/libavcodec/h264chroma.h index 4e035b0..45bbc7d 100644 --- a/ffmpeg/libavcodec/h264chroma.h +++ b/ffmpeg/libavcodec/h264chroma.h @@ -24,15 +24,14 @@ typedef void (*h264_chroma_mc_func)(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int srcStride, int h, int x, int y); typedef struct H264ChromaContext { - h264_chroma_mc_func put_h264_chroma_pixels_tab[3]; - h264_chroma_mc_func avg_h264_chroma_pixels_tab[3]; + h264_chroma_mc_func put_h264_chroma_pixels_tab[4]; + h264_chroma_mc_func avg_h264_chroma_pixels_tab[4]; } H264ChromaContext; void ff_h264chroma_init(H264ChromaContext *c, int bit_depth); void ff_h264chroma_init_arm(H264ChromaContext *c, int bit_depth); void ff_h264chroma_init_ppc(H264ChromaContext *c, int bit_depth); -void ff_h264chroma_init_sh4(H264ChromaContext *c, int bit_depth); void ff_h264chroma_init_x86(H264ChromaContext *c, int bit_depth); #endif /* AVCODEC_H264CHROMA_H */ diff --git a/ffmpeg/libavcodec/h264chroma_template.c b/ffmpeg/libavcodec/h264chroma_template.c index 93559d7..b64172a 100644 --- a/ffmpeg/libavcodec/h264chroma_template.c +++ b/ffmpeg/libavcodec/h264chroma_template.c @@ -24,6 +24,34 @@ #include "bit_depth_template.c" #define H264_CHROMA_MC(OPNAME, OP)\ +static void FUNCC(OPNAME ## h264_chroma_mc1)(uint8_t *_dst/*align 8*/, uint8_t *_src/*align 1*/, int stride, int h, int x, int y){\ + pixel *dst = (pixel*)_dst;\ + pixel *src = (pixel*)_src;\ + const int A=(8-x)*(8-y);\ + const int B=( x)*(8-y);\ + const int C=(8-x)*( y);\ + const int D=( x)*( y);\ + int i;\ + stride >>= sizeof(pixel)-1;\ + \ + av_assert2(x<8 && y<8 && x>=0 && y>=0);\ +\ + if(D){\ + for(i=0; i + +#include "libavutil/attributes.h" #include "libavutil/avassert.h" + #include "avcodec.h" #include "h264dsp.h" #include "h264idct.h" @@ -60,7 +63,36 @@ #include "h264addpx_template.c" #undef BIT_DEPTH -void ff_h264dsp_init(H264DSPContext *c, const int bit_depth, const int chroma_format_idc) +static int h264_find_start_code_candidate_c(const uint8_t *buf, int size) +{ + int i = 0; +#if HAVE_FAST_UNALIGNED + /* we check i < size instead of i + 3 / 7 because it is + * simpler and there must be FF_INPUT_BUFFER_PADDING_SIZE + * bytes at the end. + */ +# if HAVE_FAST_64BIT + while (i < size && + !((~*(const uint64_t *)(buf + i) & + (*(const uint64_t *)(buf + i) - 0x0101010101010101ULL)) & + 0x8080808080808080ULL)) + i += 8; +# else + while (i < size && + !((~*(const uint32_t *)(buf + i) & + (*(const uint32_t *)(buf + i) - 0x01010101U)) & + 0x80808080U)) + i += 4; +# endif +#endif + for (; i < size; i++) + if (!buf[i]) + break; + return i; +} + +av_cold void ff_h264dsp_init(H264DSPContext *c, const int bit_depth, + const int chroma_format_idc) { #undef FUNC #define FUNC(a, depth) a ## _ ## depth ## _c @@ -146,8 +178,9 @@ void ff_h264dsp_init(H264DSPContext *c, const int bit_depth, const int chroma_fo H264_DSP(8); break; } + c->h264_find_start_code_candidate = h264_find_start_code_candidate_c; if (ARCH_ARM) ff_h264dsp_init_arm(c, bit_depth, chroma_format_idc); - if (HAVE_ALTIVEC) ff_h264dsp_init_ppc(c, bit_depth, chroma_format_idc); + if (ARCH_PPC) ff_h264dsp_init_ppc(c, bit_depth, chroma_format_idc); if (ARCH_X86) ff_h264dsp_init_x86(c, bit_depth, chroma_format_idc); } diff --git a/ffmpeg/libavcodec/h264dsp.h b/ffmpeg/libavcodec/h264dsp.h index 98ea15c..1be4804 100644 --- a/ffmpeg/libavcodec/h264dsp.h +++ b/ffmpeg/libavcodec/h264dsp.h @@ -105,6 +105,15 @@ typedef struct H264DSPContext { /* bypass-transform */ void (*h264_add_pixels8_clear)(uint8_t *dst, int16_t *block, int stride); void (*h264_add_pixels4_clear)(uint8_t *dst, int16_t *block, int stride); + + /** + * Search buf from the start for up to size bytes. Return the index + * of a zero byte, or >= size if not found. Ideally, use lookahead + * to filter out any zero bytes that are known to not be followed by + * one or more further zero bytes and a one byte. Better still, filter + * out any bytes that form the trailing_zero_8bits syntax element too. + */ + int (*h264_find_start_code_candidate)(const uint8_t *buf, int size); } H264DSPContext; void ff_h264dsp_init(H264DSPContext *c, const int bit_depth, diff --git a/ffmpeg/libavcodec/h264idct_template.c b/ffmpeg/libavcodec/h264idct_template.c index 9f16e1d..42c32d1 100644 --- a/ffmpeg/libavcodec/h264idct_template.c +++ b/ffmpeg/libavcodec/h264idct_template.c @@ -145,7 +145,7 @@ void FUNCC(ff_h264_idct_dc_add)(uint8_t *_dst, int16_t *_block, int stride){ pixel *dst = (pixel*)_dst; dctcoef *block = (dctcoef*)_block; int dc = (block[0] + 32) >> 6; - stride >>= sizeof(pixel)-1; + stride /= sizeof(pixel); block[0] = 0; for( j = 0; j < 4; j++ ) { @@ -161,7 +161,7 @@ void FUNCC(ff_h264_idct8_dc_add)(uint8_t *_dst, int16_t *_block, int stride){ dctcoef *block = (dctcoef*)_block; int dc = (block[0] + 32) >> 6; block[0] = 0; - stride >>= sizeof(pixel)-1; + stride /= sizeof(pixel); for( j = 0; j < 8; j++ ) { for( i = 0; i < 8; i++ ) diff --git a/ffmpeg/libavcodec/h264pred.c b/ffmpeg/libavcodec/h264pred.c index e5f1f5a..3a96654 100644 --- a/ffmpeg/libavcodec/h264pred.c +++ b/ffmpeg/libavcodec/h264pred.c @@ -25,6 +25,7 @@ * @author Michael Niedermayer */ +#include "libavutil/attributes.h" #include "libavutil/avassert.h" #include "dsputil.h" #include "h264pred.h" @@ -278,12 +279,12 @@ static void pred4x4_horizontal_up_rv40_nodown_c(uint8_t *src, static void pred4x4_tm_vp8_c(uint8_t *src, const uint8_t *topright, ptrdiff_t stride) { - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP - src[-1-stride]; + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP - src[-1-stride]; uint8_t *top = src-stride; int y; for (y = 0; y < 4; y++) { - uint8_t *cm_in = cm + src[-1]; + const uint8_t *cm_in = cm + src[-1]; src[0] = cm_in[top[0]]; src[1] = cm_in[top[1]]; src[2] = cm_in[top[2]]; @@ -304,12 +305,12 @@ static void pred16x16_plane_rv40_c(uint8_t *src, ptrdiff_t stride) static void pred16x16_tm_vp8_c(uint8_t *src, ptrdiff_t stride) { - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP - src[-1-stride]; + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP - src[-1-stride]; uint8_t *top = src-stride; int y; for (y = 0; y < 16; y++) { - uint8_t *cm_in = cm + src[-1]; + const uint8_t *cm_in = cm + src[-1]; src[0] = cm_in[top[0]]; src[1] = cm_in[top[1]]; src[2] = cm_in[top[2]]; @@ -386,12 +387,12 @@ static void pred8x8_dc_rv40_c(uint8_t *src, ptrdiff_t stride) static void pred8x8_tm_vp8_c(uint8_t *src, ptrdiff_t stride) { - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP - src[-1-stride]; + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP - src[-1-stride]; uint8_t *top = src-stride; int y; for (y = 0; y < 8; y++) { - uint8_t *cm_in = cm + src[-1]; + const uint8_t *cm_in = cm + src[-1]; src[0] = cm_in[top[0]]; src[1] = cm_in[top[1]]; src[2] = cm_in[top[2]]; @@ -407,8 +408,9 @@ static void pred8x8_tm_vp8_c(uint8_t *src, ptrdiff_t stride) /** * Set the intra prediction function pointers. */ -void ff_h264_pred_init(H264PredContext *h, int codec_id, const int bit_depth, - int chroma_format_idc) +av_cold void ff_h264_pred_init(H264PredContext *h, int codec_id, + const int bit_depth, + int chroma_format_idc) { #undef FUNC #undef FUNCC diff --git a/ffmpeg/libavcodec/h264qpel.c b/ffmpeg/libavcodec/h264qpel.c index f46da8f..7c86d2a 100644 --- a/ffmpeg/libavcodec/h264qpel.c +++ b/ffmpeg/libavcodec/h264qpel.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/attributes.h" #include "h264qpel.h" #define pixeltmp int16_t @@ -45,7 +46,7 @@ #undef BIT_DEPTH -void ff_h264qpel_init(H264QpelContext *c, int bit_depth) +av_cold void ff_h264qpel_init(H264QpelContext *c, int bit_depth) { #undef FUNCC #define FUNCC(f, depth) f ## _ ## depth ## _c diff --git a/ffmpeg/libavcodec/hpeldsp.c b/ffmpeg/libavcodec/hpeldsp.c index a9139bf..473102d 100644 --- a/ffmpeg/libavcodec/hpeldsp.c +++ b/ffmpeg/libavcodec/hpeldsp.c @@ -28,12 +28,13 @@ */ #include "libavutil/attributes.h" +#include "libavutil/intreadwrite.h" #include "hpeldsp.h" #define BIT_DEPTH 8 #include "hpeldsp_template.c" -av_cold void ff_hpeldsp_init(HpelDSPContext* c, int flags) +av_cold void ff_hpeldsp_init(HpelDSPContext *c, int flags) { #define hpel_funcs(prefix, idx, num) \ c->prefix ## _pixels_tab idx [0] = prefix ## _pixels ## num ## _8_c; \ @@ -53,11 +54,16 @@ av_cold void ff_hpeldsp_init(HpelDSPContext* c, int flags) hpel_funcs(avg, [3], 2); hpel_funcs(avg_no_rnd,, 16); - if (ARCH_X86) ff_hpeldsp_init_x86 (c, flags); - if (ARCH_ARM) ff_hpeldsp_init_arm (c, flags); - if (HAVE_VIS) ff_hpeldsp_init_vis (c, flags); - if (ARCH_ALPHA) ff_hpeldsp_init_alpha (c, flags); - if (ARCH_PPC) ff_hpeldsp_init_ppc (c, flags); - if (ARCH_SH4) ff_hpeldsp_init_sh4 (c, flags); - if (ARCH_BFIN) ff_hpeldsp_init_bfin (c, flags); + if (ARCH_ALPHA) + ff_hpeldsp_init_alpha(c, flags); + if (ARCH_ARM) + ff_hpeldsp_init_arm(c, flags); + if (ARCH_BFIN) + ff_hpeldsp_init_bfin(c, flags); + if (ARCH_PPC) + ff_hpeldsp_init_ppc(c, flags); + if (HAVE_VIS) + ff_hpeldsp_init_vis(c, flags); + if (ARCH_X86) + ff_hpeldsp_init_x86(c, flags); } diff --git a/ffmpeg/libavcodec/hpeldsp.h b/ffmpeg/libavcodec/hpeldsp.h index 57a4cc1..ec9006c 100644 --- a/ffmpeg/libavcodec/hpeldsp.h +++ b/ffmpeg/libavcodec/hpeldsp.h @@ -32,8 +32,8 @@ #include /* add and put pixel (decoding) */ -// blocksizes for op_pixels_func are 8x4,8x8 16x8 16x16 -// h for op_pixels_func is limited to {width/2, width} but never larger +// blocksizes for hpel_pixels_func are 8x4,8x8 16x8 16x16 +// h for hpel_pixels_func is limited to {width/2, width} but never larger // than 16 and never smaller than 4 typedef void (*op_pixels_func)(uint8_t *block /*align width (8 or 16)*/, const uint8_t *pixels /*align 1*/, @@ -92,14 +92,13 @@ typedef struct HpelDSPContext { op_pixels_func avg_no_rnd_pixels_tab[4]; } HpelDSPContext; -void ff_hpeldsp_init(HpelDSPContext* p, int flags); +void ff_hpeldsp_init(HpelDSPContext *c, int flags); -void ff_hpeldsp_init_alpha(HpelDSPContext* c, int flags); -void ff_hpeldsp_init_arm(HpelDSPContext* c, int flags); -void ff_hpeldsp_init_bfin(HpelDSPContext* c, int flags); -void ff_hpeldsp_init_x86(HpelDSPContext* c, int flags); -void ff_hpeldsp_init_ppc(HpelDSPContext* c, int flags); -void ff_hpeldsp_init_sh4(HpelDSPContext* c, int flags); -void ff_hpeldsp_init_vis(HpelDSPContext* c, int flags); +void ff_hpeldsp_init_alpha(HpelDSPContext *c, int flags); +void ff_hpeldsp_init_arm(HpelDSPContext *c, int flags); +void ff_hpeldsp_init_bfin(HpelDSPContext *c, int flags); +void ff_hpeldsp_init_ppc(HpelDSPContext *c, int flags); +void ff_hpeldsp_init_vis(HpelDSPContext *c, int flags); +void ff_hpeldsp_init_x86(HpelDSPContext *c, int flags); #endif /* AVCODEC_HPELDSP_H */ diff --git a/ffmpeg/libavcodec/huffman.c b/ffmpeg/libavcodec/huffman.c index 27fed9f..8dd356d 100644 --- a/ffmpeg/libavcodec/huffman.c +++ b/ffmpeg/libavcodec/huffman.c @@ -24,6 +24,8 @@ * huffman tree builder and VLC generator */ +#include + #include "avcodec.h" #include "get_bits.h" #include "huffman.h" @@ -112,7 +114,7 @@ static void get_tree_codes(uint32_t *bits, int16_t *lens, uint8_t *xlat, } } -static int build_huff_tree(VLC *vlc, Node *nodes, int head, int flags) +static int build_huff_tree(VLC *vlc, Node *nodes, int head, int flags, int nb_bits) { int no_zero_count = !(flags & FF_HUFFMAN_FLAG_ZERO_COUNT); uint32_t bits[256]; @@ -122,7 +124,7 @@ static int build_huff_tree(VLC *vlc, Node *nodes, int head, int flags) get_tree_codes(bits, lens, xlat, nodes, head, 0, 0, &pos, no_zero_count); - return ff_init_vlc_sparse(vlc, 9, pos, lens, 2, 2, bits, 4, 4, xlat, 1, 1, 0); + return ff_init_vlc_sparse(vlc, nb_bits, pos, lens, 2, 2, bits, 4, 4, xlat, 1, 1, 0); } @@ -130,7 +132,7 @@ static int build_huff_tree(VLC *vlc, Node *nodes, int head, int flags) * nodes size must be 2*nb_codes * first nb_codes nodes.count must be set */ -int ff_huff_build_tree(AVCodecContext *avctx, VLC *vlc, int nb_codes, +int ff_huff_build_tree(AVCodecContext *avctx, VLC *vlc, int nb_codes, int nb_bits, Node *nodes, HuffCmp cmp, int flags) { int i, j; @@ -168,7 +170,7 @@ int ff_huff_build_tree(AVCodecContext *avctx, VLC *vlc, int nb_codes, nodes[j].n0 = i; cur_node++; } - if (build_huff_tree(vlc, nodes, nb_codes * 2 - 2, flags) < 0) { + if (build_huff_tree(vlc, nodes, nb_codes * 2 - 2, flags, nb_bits) < 0) { av_log(avctx, AV_LOG_ERROR, "Error building tree\n"); return -1; } diff --git a/ffmpeg/libavcodec/huffman.h b/ffmpeg/libavcodec/huffman.h index 4f9ccba..cec9537 100644 --- a/ffmpeg/libavcodec/huffman.h +++ b/ffmpeg/libavcodec/huffman.h @@ -37,9 +37,10 @@ typedef struct Node { #define FF_HUFFMAN_FLAG_HNODE_FIRST 0x01 #define FF_HUFFMAN_FLAG_ZERO_COUNT 0x02 +#define FF_HUFFMAN_BITS 10 typedef int (*HuffCmp)(const void *va, const void *vb); -int ff_huff_build_tree(AVCodecContext *avctx, VLC *vlc, int nb_codes, +int ff_huff_build_tree(AVCodecContext *avctx, VLC *vlc, int nb_codes, int nb_bits, Node *nodes, HuffCmp cmp, int flags); void ff_huff_gen_len_table(uint8_t *dst, const uint64_t *stats); diff --git a/ffmpeg/libavcodec/huffyuv.h b/ffmpeg/libavcodec/huffyuv.h index e34b562..e2cacc1 100644 --- a/ffmpeg/libavcodec/huffyuv.h +++ b/ffmpeg/libavcodec/huffyuv.h @@ -78,7 +78,6 @@ typedef struct HYuvContext { uint32_t bits[3][256]; uint32_t pix_bgr_map[1<vlc, 0, 3 * sizeof(VLC)); - avcodec_get_frame_defaults(&s->picture); s->interlaced = s->height > 288; s->bgr32 = 1; @@ -407,6 +406,9 @@ static void decode_422_bitstream(HYuvContext *s, int count) READ_2PIX(s->temp[0][2 * i ], s->temp[1][i], 1); READ_2PIX(s->temp[0][2 * i + 1], s->temp[2][i], 2); } + for (; i < count; i++) + s->temp[0][2 * i ] = s->temp[1][i] = + s->temp[0][2 * i + 1] = s->temp[2][i] = 128; } else { for (i = 0; i < count; i++) { READ_2PIX(s->temp[0][2 * i ], s->temp[1][i], 1); @@ -767,6 +769,7 @@ static av_cold int decode_end(AVCodecContext *avctx) #if CONFIG_HUFFYUV_DECODER AVCodec ff_huffyuv_decoder = { .name = "huffyuv", + .long_name = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_HUFFYUV, .priv_data_size = sizeof(HYuvContext), @@ -776,13 +779,13 @@ AVCodec ff_huffyuv_decoder = { .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_FRAME_THREADS, .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy), - .long_name = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"), }; #endif #if CONFIG_FFVHUFF_DECODER AVCodec ff_ffvhuff_decoder = { .name = "ffvhuff", + .long_name = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_FFVHUFF, .priv_data_size = sizeof(HYuvContext), @@ -792,6 +795,5 @@ AVCodec ff_ffvhuff_decoder = { .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_FRAME_THREADS, .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy), - .long_name = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"), }; #endif diff --git a/ffmpeg/libavcodec/huffyuvenc.c b/ffmpeg/libavcodec/huffyuvenc.c index 95dcb88..3a55d54 100644 --- a/ffmpeg/libavcodec/huffyuvenc.c +++ b/ffmpeg/libavcodec/huffyuvenc.c @@ -56,14 +56,16 @@ static inline int sub_left_prediction(HYuvContext *s, uint8_t *dst, static inline void sub_left_prediction_bgr32(HYuvContext *s, uint8_t *dst, const uint8_t *src, int w, - int *red, int *green, int *blue, int *alpha) + int *red, int *green, int *blue, + int *alpha) { int i; - int r,g,b,a; + int r, g, b, a; r = *red; g = *green; b = *blue; a = *alpha; + for (i = 0; i < FFMIN(w, 4); i++) { const int rt = src[i * 4 + R]; const int gt = src[i * 4 + G]; @@ -87,29 +89,32 @@ static inline void sub_left_prediction_bgr32(HYuvContext *s, uint8_t *dst, *alpha = src[(w - 1) * 4 + A]; } -static inline void sub_left_prediction_rgb24(HYuvContext *s, uint8_t *dst, const uint8_t *src, int w, int *red, int *green, int *blue){ +static inline void sub_left_prediction_rgb24(HYuvContext *s, uint8_t *dst, + uint8_t *src, int w, + int *red, int *green, int *blue) +{ int i; - int r,g,b; + int r, g, b; r = *red; g = *green; b = *blue; - for (i = 0; i < FFMIN(w,16); i++) { - const int rt = src[i*3 + 0]; - const int gt = src[i*3 + 1]; - const int bt = src[i*3 + 2]; - dst[i*3 + 0] = rt - r; - dst[i*3 + 1] = gt - g; - dst[i*3 + 2] = bt - b; + for (i = 0; i < FFMIN(w, 16); i++) { + const int rt = src[i * 3 + 0]; + const int gt = src[i * 3 + 1]; + const int bt = src[i * 3 + 2]; + dst[i * 3 + 0] = rt - r; + dst[i * 3 + 1] = gt - g; + dst[i * 3 + 2] = bt - b; r = rt; g = gt; b = bt; } - s->dsp.diff_bytes(dst + 48, src + 48, src + 48 - 3, w*3 - 48); + s->dsp.diff_bytes(dst + 48, src + 48, src + 48 - 3, w * 3 - 48); - *red = src[(w - 1)*3 + 0]; - *green = src[(w - 1)*3 + 1]; - *blue = src[(w - 1)*3 + 2]; + *red = src[(w - 1) * 3 + 0]; + *green = src[(w - 1) * 3 + 1]; + *blue = src[(w - 1) * 3 + 2]; } static int store_table(HYuvContext *s, const uint8_t *len, uint8_t *buf) @@ -151,13 +156,18 @@ static av_cold int encode_init(AVCodecContext *avctx) } s->version = 2; - avctx->coded_frame = &s->picture; + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->key_frame = 1; switch (avctx->pix_fmt) { case AV_PIX_FMT_YUV420P: case AV_PIX_FMT_YUV422P: if (s->width & 1) { - av_log(avctx, AV_LOG_ERROR, "width must be even for this colorspace\n"); + av_log(avctx, AV_LOG_ERROR, "Width must be even for this colorspace.\n"); return AVERROR(EINVAL); } s->bitstream_bpp = avctx->pix_fmt == AV_PIX_FMT_YUV420P ? 12 : 16; @@ -384,43 +394,48 @@ static inline int encode_bgra_bitstream(HYuvContext *s, int count, int planes) { int i; - if (s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 4*planes*count) { + if (s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb) >> 3) < + 4 * planes * count) { av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); return -1; } -#define LOAD3\ - int g = s->temp[0][planes==3 ? 3*i + 1 : 4*i + G];\ - int b = (s->temp[0][planes==3 ? 3*i + 2 : 4*i + B] - g) & 0xff;\ - int r = (s->temp[0][planes==3 ? 3*i + 0 : 4*i + R] - g) & 0xff;\ - int a = s->temp[0][planes*i + A]; -#define STAT3\ - s->stats[0][b]++;\ - s->stats[1][g]++;\ - s->stats[2][r]++;\ - if(planes==4) s->stats[2][a]++; -#define WRITE3\ - put_bits(&s->pb, s->len[1][g], s->bits[1][g]);\ - put_bits(&s->pb, s->len[0][b], s->bits[0][b]);\ - put_bits(&s->pb, s->len[2][r], s->bits[2][r]);\ - if(planes==4) put_bits(&s->pb, s->len[2][a], s->bits[2][a]); +#define LOAD_GBRA \ + int g = s->temp[0][planes == 3 ? 3 * i + 1 : 4 * i + G]; \ + int b =(s->temp[0][planes == 3 ? 3 * i + 2 : 4 * i + B] - g) & 0xFF;\ + int r =(s->temp[0][planes == 3 ? 3 * i + 0 : 4 * i + R] - g) & 0xFF;\ + int a = s->temp[0][planes * i + A]; + +#define STAT_BGRA \ + s->stats[0][b]++; \ + s->stats[1][g]++; \ + s->stats[2][r]++; \ + if (planes == 4) \ + s->stats[2][a]++; + +#define WRITE_GBRA \ + put_bits(&s->pb, s->len[1][g], s->bits[1][g]); \ + put_bits(&s->pb, s->len[0][b], s->bits[0][b]); \ + put_bits(&s->pb, s->len[2][r], s->bits[2][r]); \ + if (planes == 4) \ + put_bits(&s->pb, s->len[2][a], s->bits[2][a]); if ((s->flags & CODEC_FLAG_PASS1) && (s->avctx->flags2 & CODEC_FLAG2_NO_OUTPUT)) { for (i = 0; i < count; i++) { - LOAD3; - STAT3; + LOAD_GBRA; + STAT_BGRA; } } else if (s->context || (s->flags & CODEC_FLAG_PASS1)) { for (i = 0; i < count; i++) { - LOAD3; - STAT3; - WRITE3; + LOAD_GBRA; + STAT_BGRA; + WRITE_GBRA; } } else { for (i = 0; i < count; i++) { - LOAD3; - WRITE3; + LOAD_GBRA; + WRITE_GBRA; } } return 0; @@ -436,16 +451,12 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const int fake_ystride = s->interlaced ? pict->linesize[0]*2 : pict->linesize[0]; const int fake_ustride = s->interlaced ? pict->linesize[1]*2 : pict->linesize[1]; const int fake_vstride = s->interlaced ? pict->linesize[2]*2 : pict->linesize[2]; - AVFrame * const p = &s->picture; + const AVFrame * const p = pict; int i, j, size = 0, ret; if ((ret = ff_alloc_packet2(avctx, pkt, width * height * 3 * 4 + FF_MIN_BUFFER_SIZE)) < 0) return ret; - *p = *pict; - p->pict_type = AV_PICTURE_TYPE_I; - p->key_frame = 1; - if (s->context) { for (i = 0; i < 3; i++) { ff_huff_gen_len_table(s->len[i], s->stats[i]); @@ -578,41 +589,48 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, put_bits(&s->pb, 8, leftg = data[G]); put_bits(&s->pb, 8, leftb = data[B]); - sub_left_prediction_bgr32(s, s->temp[0], data + 4, width - 1, &leftr, &leftg, &leftb, &lefta); + sub_left_prediction_bgr32(s, s->temp[0], data + 4, width - 1, + &leftr, &leftg, &leftb, &lefta); encode_bgra_bitstream(s, width - 1, 4); for (y = 1; y < s->height; y++) { uint8_t *dst = data + y*stride; if (s->predictor == PLANE && s->interlaced < y) { s->dsp.diff_bytes(s->temp[1], dst, dst - fake_stride, width * 4); - sub_left_prediction_bgr32(s, s->temp[0], s->temp[1], width, &leftr, &leftg, &leftb, &lefta); + sub_left_prediction_bgr32(s, s->temp[0], s->temp[1], width, + &leftr, &leftg, &leftb, &lefta); } else { - sub_left_prediction_bgr32(s, s->temp[0], dst, width, &leftr, &leftg, &leftb, &lefta); + sub_left_prediction_bgr32(s, s->temp[0], dst, width, + &leftr, &leftg, &leftb, &lefta); } encode_bgra_bitstream(s, width, 4); } - }else if(avctx->pix_fmt == AV_PIX_FMT_RGB24){ - uint8_t *data = p->data[0] + (height-1)*p->linesize[0]; + } else if (avctx->pix_fmt == AV_PIX_FMT_RGB24) { + uint8_t *data = p->data[0] + (height - 1) * p->linesize[0]; const int stride = -p->linesize[0]; const int fake_stride = -fake_ystride; int y; int leftr, leftg, leftb; - put_bits(&s->pb, 8, leftr= data[0]); - put_bits(&s->pb, 8, leftg= data[1]); - put_bits(&s->pb, 8, leftb= data[2]); + put_bits(&s->pb, 8, leftr = data[0]); + put_bits(&s->pb, 8, leftg = data[1]); + put_bits(&s->pb, 8, leftb = data[2]); put_bits(&s->pb, 8, 0); - sub_left_prediction_rgb24(s, s->temp[0], data+3, width-1, &leftr, &leftg, &leftb); + sub_left_prediction_rgb24(s, s->temp[0], data + 3, width - 1, + &leftr, &leftg, &leftb); encode_bgra_bitstream(s, width-1, 3); - for(y=1; yheight; y++){ - uint8_t *dst = data + y*stride; - if(s->predictor == PLANE && s->interlaced < y){ - s->dsp.diff_bytes(s->temp[1], dst, dst - fake_stride, width*3); - sub_left_prediction_rgb24(s, s->temp[0], s->temp[1], width, &leftr, &leftg, &leftb); - }else{ - sub_left_prediction_rgb24(s, s->temp[0], dst, width, &leftr, &leftg, &leftb); + for (y = 1; y < s->height; y++) { + uint8_t *dst = data + y * stride; + if (s->predictor == PLANE && s->interlaced < y) { + s->dsp.diff_bytes(s->temp[1], dst, dst - fake_stride, + width * 3); + sub_left_prediction_rgb24(s, s->temp[0], s->temp[1], width, + &leftr, &leftg, &leftb); + } else { + sub_left_prediction_rgb24(s, s->temp[0], dst, width, + &leftr, &leftg, &leftb); } encode_bgra_bitstream(s, width, 3); } @@ -664,12 +682,15 @@ static av_cold int encode_end(AVCodecContext *avctx) av_freep(&avctx->extradata); av_freep(&avctx->stats_out); + av_frame_free(&avctx->coded_frame); + return 0; } #if CONFIG_HUFFYUV_ENCODER AVCodec ff_huffyuv_encoder = { .name = "huffyuv", + .long_name = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_HUFFYUV, .priv_data_size = sizeof(HYuvContext), @@ -677,15 +698,16 @@ AVCodec ff_huffyuv_encoder = { .encode2 = encode_frame, .close = encode_end, .pix_fmts = (const enum AVPixelFormat[]){ - AV_PIX_FMT_YUV422P, AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE + AV_PIX_FMT_YUV422P, AV_PIX_FMT_RGB24, + AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"), }; #endif #if CONFIG_FFVHUFF_ENCODER AVCodec ff_ffvhuff_encoder = { .name = "ffvhuff", + .long_name = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_FFVHUFF, .priv_data_size = sizeof(HYuvContext), @@ -693,8 +715,8 @@ AVCodec ff_ffvhuff_encoder = { .encode2 = encode_frame, .close = encode_end, .pix_fmts = (const enum AVPixelFormat[]){ - AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE + AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_RGB24, + AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"), }; #endif diff --git a/ffmpeg/libavcodec/idcinvideo.c b/ffmpeg/libavcodec/idcinvideo.c index 3596080..80c7d07 100644 --- a/ffmpeg/libavcodec/idcinvideo.c +++ b/ffmpeg/libavcodec/idcinvideo.c @@ -243,11 +243,11 @@ static int idcin_decode_frame(AVCodecContext *avctx, AVCodec ff_idcin_decoder = { .name = "idcinvideo", + .long_name = NULL_IF_CONFIG_SMALL("id Quake II CIN video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_IDCIN, .priv_data_size = sizeof(IdcinContext), .init = idcin_decode_init, .decode = idcin_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("id Quake II CIN video"), }; diff --git a/ffmpeg/libavcodec/iff.c b/ffmpeg/libavcodec/iff.c index 716a731..4bde0a8 100644 --- a/ffmpeg/libavcodec/iff.c +++ b/ffmpeg/libavcodec/iff.c @@ -25,6 +25,8 @@ * IFF ACBM/DEEP/ILBM/PBM bitmap decoder */ +#include + #include "libavutil/imgutils.h" #include "bytestream.h" #include "avcodec.h" @@ -155,9 +157,8 @@ static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal) // If extradata is smaller than actually needed, fill the remaining with black. count = FFMIN(palette_size / 3, count); if (count) { - for (i=0; i < count; i++) { + for (i = 0; i < count; i++) pal[i] = 0xFF000000 | AV_RB24(palette + i*3); - } if (s->flags && count >= 32) { // EHB for (i = 0; i < 32; i++) pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1; @@ -166,9 +167,8 @@ static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal) } else { // Create gray-scale color palette for bps < 8 count = 1 << avctx->bits_per_coded_sample; - for (i=0; i < count; i++) { + for (i = 0; i < count; i++) pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample); - } } if (s->masking == MASK_HAS_MASK) { memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4); @@ -186,7 +186,7 @@ static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal) * * @param avctx the AVCodecContext where to extract extra context to * @param avpkt the AVPacket to extract extra context from or NULL to use avctx - * @return 0 in case of success, a negative error code otherwise + * @return >= 0 in case of success, a negative error code otherwise */ static int extract_header(AVCodecContext *const avctx, const AVPacket *const avpkt) { @@ -320,6 +320,16 @@ static int extract_header(AVCodecContext *const avctx, return 0; } +static av_cold int decode_end(AVCodecContext *avctx) +{ + IffContext *s = avctx->priv_data; + av_frame_free(&s->frame); + av_freep(&s->planebuf); + av_freep(&s->ham_buf); + av_freep(&s->ham_palbuf); + return 0; +} + static av_cold int decode_init(AVCodecContext *avctx) { IffContext *s = avctx->priv_data; @@ -335,11 +345,11 @@ static av_cold int decode_init(AVCodecContext *avctx) avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) || (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8; } else if (avctx->bits_per_coded_sample <= 32) { - if (avctx->codec_tag == MKTAG('R','G','B','8')) { + if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8')) { avctx->pix_fmt = AV_PIX_FMT_RGB32; - } else if (avctx->codec_tag == MKTAG('R','G','B','N')) { + } else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N')) { avctx->pix_fmt = AV_PIX_FMT_RGB444; - } else if (avctx->codec_tag != MKTAG('D','E','E','P')) { + } else if (avctx->codec_tag != MKTAG('D', 'E', 'E', 'P')) { if (avctx->bits_per_coded_sample == 24) { avctx->pix_fmt = AV_PIX_FMT_0BGR32; } else if (avctx->bits_per_coded_sample == 32) { @@ -356,14 +366,16 @@ static av_cold int decode_init(AVCodecContext *avctx) if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx))) return err; s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary - s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE); + s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE); if (!s->planebuf) return AVERROR(ENOMEM); s->bpp = avctx->bits_per_coded_sample; s->frame = av_frame_alloc(); - if (!s->frame) + if (!s->frame) { + decode_end(avctx); return AVERROR(ENOMEM); + } if ((err = extract_header(avctx, NULL)) < 0) return err; @@ -408,12 +420,12 @@ static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int p dst[1] |= lut[mask++]; dst[2] |= lut[mask++]; dst[3] |= lut[mask]; - mask = (*buf++ << 2) & 0x3F; + mask = (*buf++ << 2) & 0x3F; dst[4] |= lut[mask++]; dst[5] |= lut[mask++]; dst[6] |= lut[mask++]; dst[7] |= lut[mask]; - dst += 8; + dst += 8; } while (--buf_size); } @@ -466,9 +478,10 @@ static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf, * @param buf the source byterun1 compressed bitstream * @param buf_end the EOF of source byterun1 compressed bitstream * @return number of consumed bytes in byterun1 compressed bitstream -*/ + */ static int decode_byterun(uint8_t *dst, int dst_size, - const uint8_t *buf, const uint8_t *const buf_end) { + const uint8_t *buf, const uint8_t *const buf_end) +{ const uint8_t *const buf_start = buf; unsigned x; for (x = 0; x < dst_size && buf < buf_end;) { @@ -486,6 +499,10 @@ static int decode_byterun(uint8_t *dst, int dst_size, } x += length; } + if (x < dst_size) { + av_log(NULL, AV_LOG_WARNING, "decode_byterun ended before plane size\n"); + memset(dst+x, 0, dst_size - x); + } return buf - buf_start; } @@ -651,13 +668,13 @@ static int unsupported(AVCodecContext *avctx) } static int decode_frame(AVCodecContext *avctx, - void *data, int *got_frame, - AVPacket *avpkt) + void *data, int *got_frame, + AVPacket *avpkt) { - IffContext *s = avctx->priv_data; - const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL; - const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0; - const uint8_t *buf_end = buf+buf_size; + IffContext *s = avctx->priv_data; + const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL; + const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0; + const uint8_t *buf_end = buf + buf_size; int y, plane, res; GetByteContext gb; @@ -667,7 +684,7 @@ static int decode_frame(AVCodecContext *avctx, return res; if (!s->init && avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt == AV_PIX_FMT_PAL8) { - if ((res = cmap_read_palette(avctx, (uint32_t*)s->frame->data[1])) < 0) + if ((res = cmap_read_palette(avctx, (uint32_t *)s->frame->data[1])) < 0) return res; } else if (!s->init && avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt == AV_PIX_FMT_RGB32) { @@ -678,19 +695,19 @@ static int decode_frame(AVCodecContext *avctx, switch (s->compression) { case 0: - if (avctx->codec_tag == MKTAG('A','C','B','M')) { + if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) { if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) { memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]); for (plane = 0; plane < s->bpp; plane++) { - for(y = 0; y < avctx->height && buf < buf_end; y++ ) { - uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ]; + for (y = 0; y < avctx->height && buf < buf_end; y++) { + uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]]; decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane); buf += s->planesize; } } } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32 memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]); - for(y = 0; y < avctx->height; y++) { + for (y = 0; y < avctx->height; y++) { uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]]; memset(s->ham_buf, 0, s->planesize * 8); for (plane = 0; plane < s->bpp; plane++) { @@ -699,27 +716,27 @@ static int decode_frame(AVCodecContext *avctx, break; decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane); } - decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize); + decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize); } } else return unsupported(avctx); - } else if (avctx->codec_tag == MKTAG('D','E','E','P')) { + } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3); int x; - for(y = 0; y < avctx->height && buf < buf_end; y++ ) { + for (y = 0; y < avctx->height && buf < buf_end; y++) { uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]]; memcpy(row, buf, FFMIN(raw_width, buf_end - buf)); buf += raw_width; if (avctx->pix_fmt == AV_PIX_FMT_BGR32) { - for(x = 0; x < avctx->width; x++) + for (x = 0; x < avctx->width; x++) row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4); } } - } else if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved + } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) { - for(y = 0; y < avctx->height; y++ ) { - uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ]; + for (y = 0; y < avctx->height; y++) { + uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]]; memset(row, 0, avctx->width); for (plane = 0; plane < s->bpp && buf < buf_end; plane++) { decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane); @@ -728,47 +745,48 @@ static int decode_frame(AVCodecContext *avctx, } } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32 for (y = 0; y < avctx->height; y++) { - uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ]; + uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]]; memset(s->ham_buf, 0, s->planesize * 8); for (plane = 0; plane < s->bpp && buf < buf_end; plane++) { decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane); buf += s->planesize; } - decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize); + decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize); } } else { // AV_PIX_FMT_BGR32 - for(y = 0; y < avctx->height; y++ ) { - uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]]; + for (y = 0; y < avctx->height; y++) { + uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]]; memset(row, 0, avctx->width << 2); for (plane = 0; plane < s->bpp && buf < buf_end; plane++) { - decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane); + decodeplane32((uint32_t *)row, buf, + FFMIN(s->planesize, buf_end - buf), plane); buf += s->planesize; } } } - } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM + } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) { - for(y = 0; y < avctx->height && buf_end > buf; y++ ) { + for (y = 0; y < avctx->height && buf_end > buf; y++) { uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]]; memcpy(row, buf, FFMIN(avctx->width, buf_end - buf)); buf += avctx->width + (avctx->width % 2); // padding if odd } } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32 for (y = 0; y < avctx->height && buf_end > buf; y++) { - uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ]; + uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]]; memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf)); buf += avctx->width + (avctx->width & 1); // padding if odd - decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize); + decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize); } } else return unsupported(avctx); } break; case 1: - if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved + if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) { - for(y = 0; y < avctx->height ; y++ ) { - uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ]; + for (y = 0; y < avctx->height; y++) { + uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]]; memset(row, 0, avctx->width); for (plane = 0; plane < s->bpp; plane++) { buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end); @@ -776,50 +794,50 @@ static int decode_frame(AVCodecContext *avctx, } } } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32 - for (y = 0; y < avctx->height ; y++ ) { - uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]]; + for (y = 0; y < avctx->height; y++) { + uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]]; memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t)); for (plane = 0; plane < s->bpp; plane++) { buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end); decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane); } - lookup_pal_indicies((uint32_t *) row, s->mask_buf, s->mask_palbuf, avctx->width); + lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width); } } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32 - for (y = 0; y < avctx->height ; y++) { - uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]]; + for (y = 0; y < avctx->height; y++) { + uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]]; memset(s->ham_buf, 0, s->planesize * 8); for (plane = 0; plane < s->bpp; plane++) { buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end); decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane); } - decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize); + decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize); } - } else { //AV_PIX_FMT_BGR32 - for(y = 0; y < avctx->height ; y++ ) { - uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]]; + } else { // AV_PIX_FMT_BGR32 + for (y = 0; y < avctx->height; y++) { + uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]]; memset(row, 0, avctx->width << 2); for (plane = 0; plane < s->bpp; plane++) { buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end); - decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane); + decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane); } } } - } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM + } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) { - for(y = 0; y < avctx->height ; y++ ) { - uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]]; + for (y = 0; y < avctx->height; y++) { + uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]]; buf += decode_byterun(row, avctx->width, buf, buf_end); } } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32 - for (y = 0; y < avctx->height ; y++) { - uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]]; + for (y = 0; y < avctx->height; y++) { + uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]]; buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end); - decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize); + decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize); } } else return unsupported(avctx); - } else if (avctx->codec_tag == MKTAG('D','E','E','P')) { // IFF-DEEP + } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); if (av_get_bits_per_pixel(desc) == 32) decode_deep_rle32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0]); @@ -829,15 +847,15 @@ static int decode_frame(AVCodecContext *avctx, break; case 4: bytestream2_init(&gb, buf, buf_size); - if (avctx->codec_tag == MKTAG('R','G','B','8')) + if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8')) decode_rgb8(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]); - else if (avctx->codec_tag == MKTAG('R','G','B','N')) + else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N')) decode_rgbn(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]); else return unsupported(avctx); break; case 5: - if (avctx->codec_tag == MKTAG('D','E','E','P')) { + if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); if (av_get_bits_per_pixel(desc) == 32) decode_deep_tvdc32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0], s->tvdc); @@ -858,19 +876,10 @@ static int decode_frame(AVCodecContext *avctx, return buf_size; } -static av_cold int decode_end(AVCodecContext *avctx) -{ - IffContext *s = avctx->priv_data; - av_frame_free(&s->frame); - av_freep(&s->planebuf); - av_freep(&s->ham_buf); - av_freep(&s->ham_palbuf); - return 0; -} - #if CONFIG_IFF_ILBM_DECODER AVCodec ff_iff_ilbm_decoder = { .name = "iff", + .long_name = NULL_IF_CONFIG_SMALL("IFF"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_IFF_ILBM, .priv_data_size = sizeof(IffContext), @@ -878,12 +887,12 @@ AVCodec ff_iff_ilbm_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("IFF"), }; #endif #if CONFIG_IFF_BYTERUN1_DECODER AVCodec ff_iff_byterun1_decoder = { .name = "iff", + .long_name = NULL_IF_CONFIG_SMALL("IFF"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_IFF_BYTERUN1, .priv_data_size = sizeof(IffContext), @@ -891,6 +900,5 @@ AVCodec ff_iff_byterun1_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("IFF"), }; #endif diff --git a/ffmpeg/libavcodec/iirfilter.c b/ffmpeg/libavcodec/iirfilter.c index 049150e..a2d9d11 100644 --- a/ffmpeg/libavcodec/iirfilter.c +++ b/ffmpeg/libavcodec/iirfilter.c @@ -26,6 +26,7 @@ #include "iirfilter.h" #include +#include "libavutil/attributes.h" #include "libavutil/common.h" /** @@ -48,10 +49,11 @@ typedef struct FFIIRFilterState{ /// maximum supported filter order #define MAXORDER 30 -static int butterworth_init_coeffs(void *avc, struct FFIIRFilterCoeffs *c, - enum IIRFilterMode filt_mode, - int order, float cutoff_ratio, - float stopband) +static av_cold int butterworth_init_coeffs(void *avc, + struct FFIIRFilterCoeffs *c, + enum IIRFilterMode filt_mode, + int order, float cutoff_ratio, + float stopband) { int i, j; double wa; @@ -113,9 +115,9 @@ static int butterworth_init_coeffs(void *avc, struct FFIIRFilterCoeffs *c, return 0; } -static int biquad_init_coeffs(void *avc, struct FFIIRFilterCoeffs *c, - enum IIRFilterMode filt_mode, int order, - float cutoff_ratio, float stopband) +static av_cold int biquad_init_coeffs(void *avc, struct FFIIRFilterCoeffs *c, + enum IIRFilterMode filt_mode, int order, + float cutoff_ratio, float stopband) { double cos_w0, sin_w0; double a0, x0, x1; diff --git a/ffmpeg/libavcodec/imc.c b/ffmpeg/libavcodec/imc.c index eb7c255..cbd7041 100644 --- a/ffmpeg/libavcodec/imc.c +++ b/ffmpeg/libavcodec/imc.c @@ -101,6 +101,8 @@ typedef struct { DECLARE_ALIGNED(32, FFTComplex, samples)[COEFFS / 2]; float *out_samples; + int coef0_pos; + int8_t cyclTab[32], cyclTab2[32]; float weights1[31], weights2[31]; } IMCContext; @@ -337,6 +339,17 @@ static void imc_read_level_coeffs(IMCContext *q, int stream_format_code, } } +static void imc_read_level_coeffs_raw(IMCContext *q, int stream_format_code, + int *levlCoeffs) +{ + int i; + + q->coef0_pos = get_bits(&q->gb, 5); + levlCoeffs[0] = get_bits(&q->gb, 7); + for (i = 1; i < BANDS; i++) + levlCoeffs[i] = get_bits(&q->gb, 4); +} + static void imc_decode_level_coefficients(IMCContext *q, int *levlCoeffBuf, float *flcoeffs1, float *flcoeffs2) { @@ -391,6 +404,28 @@ static void imc_decode_level_coefficients2(IMCContext *q, int *levlCoeffBuf, } } +static void imc_decode_level_coefficients_raw(IMCContext *q, int *levlCoeffBuf, + float *flcoeffs1, float *flcoeffs2) +{ + int i, level, pos; + float tmp, tmp2; + + pos = q->coef0_pos; + flcoeffs1[pos] = 20000.0 / pow (2, levlCoeffBuf[0] * 0.18945); // 0.18945 = log2(10) * 0.05703125 + flcoeffs2[pos] = log2f(flcoeffs1[0]); + tmp = flcoeffs1[pos]; + tmp2 = flcoeffs2[pos]; + + levlCoeffBuf++; + for (i = 0; i < BANDS; i++) { + if (i == pos) + continue; + level = *levlCoeffBuf++; + flcoeffs1[i] = tmp * powf(10.0, -level * 0.4375); //todo tab + flcoeffs2[i] = tmp2 - 1.4533435415 * level; // 1.4533435415 = log2(10) * 0.4375 + } +} + /** * Perform bit allocation depending on bits available */ @@ -416,8 +451,13 @@ static int bit_allocation(IMCContext *q, IMCChannel *chctx, for (i = 0; i < BANDS; i++) highest = FFMAX(highest, chctx->flcoeffs1[i]); - for (i = 0; i < BANDS - 1; i++) + for (i = 0; i < BANDS - 1; i++) { + if (chctx->flcoeffs5[i] <= 0) { + av_log(NULL, AV_LOG_ERROR, "flcoeffs5 %f invalid\n", chctx->flcoeffs5[i]); + return AVERROR_INVALIDDATA; + } chctx->flcoeffs4[i] = chctx->flcoeffs3[i] - log2f(chctx->flcoeffs5[i]); + } chctx->flcoeffs4[BANDS - 1] = limit; highest = highest * 0.25; @@ -450,6 +490,10 @@ static int bit_allocation(IMCContext *q, IMCChannel *chctx, iacc += chctx->bandWidthT[i]; summa += chctx->bandWidthT[i] * chctx->flcoeffs4[i]; } + + if (!iacc) + return AVERROR_INVALIDDATA; + chctx->bandWidthT[BANDS - 1] = 0; summa = (summa * 0.5 - freebits) / iacc; @@ -759,12 +803,56 @@ static int imc_get_coeffs(IMCContext *q, IMCChannel *chctx) return 0; } +static void imc_refine_bit_allocation(IMCContext *q, IMCChannel *chctx) +{ + int i, j; + int bits, summer; + + for (i = 0; i < BANDS; i++) { + chctx->sumLenArr[i] = 0; + chctx->skipFlagRaw[i] = 0; + for (j = band_tab[i]; j < band_tab[i + 1]; j++) + chctx->sumLenArr[i] += chctx->CWlengthT[j]; + if (chctx->bandFlagsBuf[i]) + if ((((band_tab[i + 1] - band_tab[i]) * 1.5) > chctx->sumLenArr[i]) && (chctx->sumLenArr[i] > 0)) + chctx->skipFlagRaw[i] = 1; + } + + imc_get_skip_coeff(q, chctx); + + for (i = 0; i < BANDS; i++) { + chctx->flcoeffs6[i] = chctx->flcoeffs1[i]; + /* band has flag set and at least one coded coefficient */ + if (chctx->bandFlagsBuf[i] && (band_tab[i + 1] - band_tab[i]) != chctx->skipFlagCount[i]) { + chctx->flcoeffs6[i] *= q->sqrt_tab[ band_tab[i + 1] - band_tab[i]] / + q->sqrt_tab[(band_tab[i + 1] - band_tab[i] - chctx->skipFlagCount[i])]; + } + } + + /* calculate bits left, bits needed and adjust bit allocation */ + bits = summer = 0; + + for (i = 0; i < BANDS; i++) { + if (chctx->bandFlagsBuf[i]) { + for (j = band_tab[i]; j < band_tab[i + 1]; j++) { + if (chctx->skipFlags[j]) { + summer += chctx->CWlengthT[j]; + chctx->CWlengthT[j] = 0; + } + } + bits += chctx->skipFlagBits[i]; + summer -= chctx->skipFlagBits[i]; + } + } + imc_adjust_bit_allocation(q, chctx, summer); +} + static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch) { int stream_format_code; int imc_hdr, i, j, ret; int flag; - int bits, summer; + int bits; int counter, bitscount; IMCChannel *chctx = q->chctx + ch; @@ -778,11 +866,6 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch) } stream_format_code = get_bits(&q->gb, 3); - if (stream_format_code & 1) { - avpriv_request_sample(avctx, "Stream format %X", stream_format_code); - return AVERROR_PATCHWELCOME; - } - if (stream_format_code & 0x04) chctx->decoder_reset = 1; @@ -795,7 +878,13 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch) } flag = get_bits1(&q->gb); - imc_read_level_coeffs(q, stream_format_code, chctx->levlCoeffBuf); + if (stream_format_code & 0x1) + imc_decode_level_coefficients_raw(q, chctx->levlCoeffBuf, + chctx->flcoeffs1, chctx->flcoeffs2); + else if (stream_format_code & 0x1) + imc_read_level_coeffs_raw(q, stream_format_code, chctx->levlCoeffBuf); + else + imc_read_level_coeffs(q, stream_format_code, chctx->levlCoeffBuf); if (stream_format_code & 0x4) imc_decode_level_coefficients(q, chctx->levlCoeffBuf, @@ -814,20 +903,31 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch) memcpy(chctx->old_floor, chctx->flcoeffs1, 32 * sizeof(float)); counter = 0; - for (i = 0; i < BANDS; i++) { - if (chctx->levlCoeffBuf[i] == 16) { - chctx->bandWidthT[i] = 0; - counter++; - } else - chctx->bandWidthT[i] = band_tab[i + 1] - band_tab[i]; - } - memset(chctx->bandFlagsBuf, 0, BANDS * sizeof(int)); - for (i = 0; i < BANDS - 1; i++) { - if (chctx->bandWidthT[i]) - chctx->bandFlagsBuf[i] = get_bits1(&q->gb); - } + if (stream_format_code & 0x1) { + for (i = 0; i < BANDS; i++) { + chctx->bandWidthT[i] = band_tab[i + 1] - band_tab[i]; + chctx->bandFlagsBuf[i] = 0; + chctx->flcoeffs3[i] = chctx->flcoeffs2[i] * 2; + chctx->flcoeffs5[i] = 1.0; + } + } else { + for (i = 0; i < BANDS; i++) { + if (chctx->levlCoeffBuf[i] == 16) { + chctx->bandWidthT[i] = 0; + counter++; + } else + chctx->bandWidthT[i] = band_tab[i + 1] - band_tab[i]; + } + + memset(chctx->bandFlagsBuf, 0, BANDS * sizeof(int)); + for (i = 0; i < BANDS - 1; i++) + if (chctx->bandWidthT[i]) + chctx->bandFlagsBuf[i] = get_bits1(&q->gb); - imc_calculate_coeffs(q, chctx->flcoeffs1, chctx->flcoeffs2, chctx->bandWidthT, chctx->flcoeffs3, chctx->flcoeffs5); + imc_calculate_coeffs(q, chctx->flcoeffs1, chctx->flcoeffs2, + chctx->bandWidthT, chctx->flcoeffs3, + chctx->flcoeffs5); + } bitscount = 0; /* first 4 bands will be assigned 5 bits per coefficient */ @@ -839,7 +939,10 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch) chctx->CWlengthT[1] = 5; chctx->CWlengthT[2] = 5; for (i = 1; i < 4; i++) { - bits = (chctx->levlCoeffBuf[i] == 16) ? 0 : 5; + if (stream_format_code & 0x1) + bits = 5; + else + bits = (chctx->levlCoeffBuf[i] == 16) ? 0 : 5; chctx->bitsBandT[i] = bits; for (j = band_tab[i]; j < band_tab[i + 1]; j++) { chctx->CWlengthT[j] = bits; @@ -861,43 +964,12 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch) return ret; } - for (i = 0; i < BANDS; i++) { - chctx->sumLenArr[i] = 0; - chctx->skipFlagRaw[i] = 0; - for (j = band_tab[i]; j < band_tab[i + 1]; j++) - chctx->sumLenArr[i] += chctx->CWlengthT[j]; - if (chctx->bandFlagsBuf[i]) - if ((((band_tab[i + 1] - band_tab[i]) * 1.5) > chctx->sumLenArr[i]) && (chctx->sumLenArr[i] > 0)) - chctx->skipFlagRaw[i] = 1; - } - - imc_get_skip_coeff(q, chctx); - - for (i = 0; i < BANDS; i++) { - chctx->flcoeffs6[i] = chctx->flcoeffs1[i]; - /* band has flag set and at least one coded coefficient */ - if (chctx->bandFlagsBuf[i] && (band_tab[i + 1] - band_tab[i]) != chctx->skipFlagCount[i]) { - chctx->flcoeffs6[i] *= q->sqrt_tab[ band_tab[i + 1] - band_tab[i]] / - q->sqrt_tab[(band_tab[i + 1] - band_tab[i] - chctx->skipFlagCount[i])]; - } - } - - /* calculate bits left, bits needed and adjust bit allocation */ - bits = summer = 0; - - for (i = 0; i < BANDS; i++) { - if (chctx->bandFlagsBuf[i]) { - for (j = band_tab[i]; j < band_tab[i + 1]; j++) { - if (chctx->skipFlags[j]) { - summer += chctx->CWlengthT[j]; - chctx->CWlengthT[j] = 0; - } - } - bits += chctx->skipFlagBits[i]; - summer -= chctx->skipFlagBits[i]; - } + if (stream_format_code & 0x1) { + for (i = 0; i < BANDS; i++) + chctx->skipFlags[i] = 0; + } else { + imc_refine_bit_allocation(q, chctx); } - imc_adjust_bit_allocation(q, chctx, summer); for (i = 0; i < BANDS; i++) { chctx->sumLenArr[i] = 0; @@ -994,6 +1066,7 @@ static av_cold void flush(AVCodecContext *avctx) #if CONFIG_IMC_DECODER AVCodec ff_imc_decoder = { .name = "imc", + .long_name = NULL_IF_CONFIG_SMALL("IMC (Intel Music Coder)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_IMC, .priv_data_size = sizeof(IMCContext), @@ -1002,7 +1075,6 @@ AVCodec ff_imc_decoder = { .decode = imc_decode_frame, .flush = flush, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("IMC (Intel Music Coder)"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, }; @@ -1010,6 +1082,7 @@ AVCodec ff_imc_decoder = { #if CONFIG_IAC_DECODER AVCodec ff_iac_decoder = { .name = "iac", + .long_name = NULL_IF_CONFIG_SMALL("IAC (Indeo Audio Coder)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_IAC, .priv_data_size = sizeof(IMCContext), @@ -1018,7 +1091,6 @@ AVCodec ff_iac_decoder = { .decode = imc_decode_frame, .flush = flush, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("IAC (Indeo Audio Coder)"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, }; diff --git a/ffmpeg/libavcodec/imgconvert.c b/ffmpeg/libavcodec/imgconvert.c index cf3c967..ee58cfb 100644 --- a/ffmpeg/libavcodec/imgconvert.c +++ b/ffmpeg/libavcodec/imgconvert.c @@ -41,7 +41,7 @@ #include "libavutil/imgutils.h" #if HAVE_MMX_EXTERNAL -#include "x86/dsputil_mmx.h" +#include "x86/dsputil_x86.h" #endif #define FF_COLOR_NA -1 @@ -59,7 +59,7 @@ #endif #define pixdesc_has_alpha(pixdesc) \ - ((pixdesc)->nb_components == 2 || (pixdesc)->nb_components == 4 || (pixdesc)->flags & PIX_FMT_PAL) + ((pixdesc)->nb_components == 2 || (pixdesc)->nb_components == 4 || (pixdesc)->flags & AV_PIX_FMT_FLAG_PAL) void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift) @@ -71,13 +71,16 @@ void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int } static int get_color_type(const AVPixFmtDescriptor *desc) { + if (desc->flags & AV_PIX_FMT_FLAG_PAL) + return FF_COLOR_RGB; + if(desc->nb_components == 1 || desc->nb_components == 2) return FF_COLOR_GRAY; if(desc->name && !strncmp(desc->name, "yuvj", 4)) return FF_COLOR_YUV_JPEG; - if(desc->flags & PIX_FMT_RGB) + if(desc->flags & AV_PIX_FMT_FLAG_RGB) return FF_COLOR_RGB; if(desc->nb_components == 0) @@ -113,7 +116,7 @@ static int get_pix_fmt_score(enum AVPixelFormat dst_pix_fmt, int src_color, dst_color; int src_min_depth, src_max_depth, dst_min_depth, dst_max_depth; int ret, loss, i, nb_components; - int score = INT_MAX; + int score = INT_MAX - 1; if (dst_pix_fmt >= AV_PIX_FMT_NB || dst_pix_fmt <= AV_PIX_FMT_NONE) return ~0; @@ -148,7 +151,7 @@ static int get_pix_fmt_score(enum AVPixelFormat dst_pix_fmt, loss |= FF_LOSS_RESOLUTION; score -= 256 << dst_desc->log2_chroma_h; } - // dont favor 422 over 420 if downsampling is needed, because 420 has much better support on the decoder side + // don't favor 422 over 420 if downsampling is needed, because 420 has much better support on the decoder side if (dst_desc->log2_chroma_w == 1 && src_desc->log2_chroma_w == 0 && dst_desc->log2_chroma_h == 1 && src_desc->log2_chroma_h == 0 ) { score += 512; @@ -247,8 +250,8 @@ enum AVPixelFormat avcodec_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt return dst_pix_fmt; } -#if AV_HAVE_INCOMPATIBLE_FORK_ABI -enum AVPixelFormat avcodec_find_best_pix_fmt2(enum AVPixelFormat *pix_fmt_list, +#if AV_HAVE_INCOMPATIBLE_LIBAV_ABI +enum AVPixelFormat avcodec_find_best_pix_fmt2(const enum AVPixelFormat *pix_fmt_list, enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr){ return avcodec_find_best_pix_fmt_of_list(pix_fmt_list, src_pix_fmt, has_alpha, loss_ptr); @@ -261,7 +264,7 @@ enum AVPixelFormat avcodec_find_best_pix_fmt2(enum AVPixelFormat dst_pix_fmt1, e } #endif -enum AVPixelFormat avcodec_find_best_pix_fmt_of_list(enum AVPixelFormat *pix_fmt_list, +enum AVPixelFormat avcodec_find_best_pix_fmt_of_list(const enum AVPixelFormat *pix_fmt_list, enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr){ int i; @@ -366,8 +369,8 @@ static inline int is_yuv_planar(const AVPixFmtDescriptor *desc) int i; int planes[4] = { 0 }; - if ( desc->flags & PIX_FMT_RGB - || !(desc->flags & PIX_FMT_PLANAR)) + if ( desc->flags & AV_PIX_FMT_FLAG_RGB + || !(desc->flags & AV_PIX_FMT_FLAG_PLANAR)) return 0; /* set the used planes */ @@ -483,7 +486,7 @@ static void deinterlace_line_c(uint8_t *dst, const uint8_t *lum, int size) { - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; int sum; for(;size > 0;size--) { @@ -506,7 +509,7 @@ static void deinterlace_line_inplace_c(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum, int size) { - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; int sum; for(;size > 0;size--) { @@ -644,7 +647,7 @@ int main(void){ int skip = 0; for (i=0; iname) { skip ++; continue; @@ -654,7 +657,7 @@ int main(void){ skip = 0; } av_log(NULL, AV_LOG_INFO, "pix fmt %s yuv_plan:%d avg_bpp:%d colortype:%d\n", desc->name, is_yuv_planar(desc), av_get_padded_bits_per_pixel(desc), get_color_type(desc)); - if ((!(desc->flags & PIX_FMT_ALPHA)) != (desc->nb_components != 2 && desc->nb_components != 4)) { + if ((!(desc->flags & AV_PIX_FMT_FLAG_ALPHA)) != (desc->nb_components != 2 && desc->nb_components != 4)) { av_log(NULL, AV_LOG_ERROR, "Alpha flag mismatch\n"); err = 1; } diff --git a/ffmpeg/libavcodec/imx_dump_header_bsf.c b/ffmpeg/libavcodec/imx_dump_header_bsf.c index 9f276bc..be43fbc 100644 --- a/ffmpeg/libavcodec/imx_dump_header_bsf.c +++ b/ffmpeg/libavcodec/imx_dump_header_bsf.c @@ -53,7 +53,6 @@ static int imx_dump_header(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx } AVBitStreamFilter ff_imx_dump_header_bsf = { - "imxdump", - 0, - imx_dump_header, + .name = "imxdump", + .filter = imx_dump_header, }; diff --git a/ffmpeg/libavcodec/indeo2.c b/ffmpeg/libavcodec/indeo2.c index f8e7415..aabe348 100644 --- a/ffmpeg/libavcodec/indeo2.c +++ b/ffmpeg/libavcodec/indeo2.c @@ -34,7 +34,7 @@ typedef struct Ir2Context{ AVCodecContext *avctx; - AVFrame picture; + AVFrame *picture; GetBitContext gb; int decode_delta; } Ir2Context; @@ -146,7 +146,7 @@ static int ir2_decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; AVFrame *picture = data; - AVFrame * const p = &s->picture; + AVFrame * const p = s->picture; int start, ret; if ((ret = ff_reget_buffer(avctx, p)) < 0) @@ -171,36 +171,36 @@ static int ir2_decode_frame(AVCodecContext *avctx, if (s->decode_delta) { /* intraframe */ if ((ret = ir2_decode_plane(s, avctx->width, avctx->height, - s->picture.data[0], s->picture.linesize[0], + p->data[0], p->linesize[0], ir2_luma_table)) < 0) return ret; /* swapped U and V */ if ((ret = ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2, - s->picture.data[2], s->picture.linesize[2], + p->data[2], p->linesize[2], ir2_luma_table)) < 0) return ret; if ((ret = ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2, - s->picture.data[1], s->picture.linesize[1], + p->data[1], p->linesize[1], ir2_luma_table)) < 0) return ret; } else { /* interframe */ if ((ret = ir2_decode_plane_inter(s, avctx->width, avctx->height, - s->picture.data[0], s->picture.linesize[0], + p->data[0], p->linesize[0], ir2_luma_table)) < 0) return ret; /* swapped U and V */ if ((ret = ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2, - s->picture.data[2], s->picture.linesize[2], + p->data[2], p->linesize[2], ir2_luma_table)) < 0) return ret; if ((ret = ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2, - s->picture.data[1], s->picture.linesize[1], + p->data[1], p->linesize[1], ir2_luma_table)) < 0) return ret; } - if ((ret = av_frame_ref(picture, &s->picture)) < 0) + if ((ret = av_frame_ref(picture, p)) < 0) return ret; *got_frame = 1; @@ -213,12 +213,13 @@ static av_cold int ir2_decode_init(AVCodecContext *avctx) Ir2Context * const ic = avctx->priv_data; static VLC_TYPE vlc_tables[1 << CODE_VLC_BITS][2]; - avcodec_get_frame_defaults(&ic->picture); ic->avctx = avctx; avctx->pix_fmt= AV_PIX_FMT_YUV410P; - avcodec_get_frame_defaults(&ic->picture); + ic->picture = av_frame_alloc(); + if (!ic->picture) + return AVERROR(ENOMEM); ir2_vlc.table = vlc_tables; ir2_vlc.table_allocated = 1 << CODE_VLC_BITS; @@ -238,15 +239,15 @@ static av_cold int ir2_decode_init(AVCodecContext *avctx) static av_cold int ir2_decode_end(AVCodecContext *avctx) { Ir2Context * const ic = avctx->priv_data; - AVFrame *pic = &ic->picture; - av_frame_unref(pic); + av_frame_free(&ic->picture); return 0; } AVCodec ff_indeo2_decoder = { .name = "indeo2", + .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 2"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_INDEO2, .priv_data_size = sizeof(Ir2Context), @@ -254,5 +255,4 @@ AVCodec ff_indeo2_decoder = { .close = ir2_decode_end, .decode = ir2_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 2"), }; diff --git a/ffmpeg/libavcodec/indeo3.c b/ffmpeg/libavcodec/indeo3.c index a8b6e64..aa9c30a 100644 --- a/ffmpeg/libavcodec/indeo3.c +++ b/ffmpeg/libavcodec/indeo3.c @@ -148,6 +148,20 @@ static av_cold void build_requant_tab(void) } +static av_cold void free_frame_buffers(Indeo3DecodeContext *ctx) +{ + int p; + + ctx->width = ctx->height = 0; + + for (p = 0; p < 3; p++) { + av_freep(&ctx->planes[p].buffers[0]); + av_freep(&ctx->planes[p].buffers[1]); + ctx->planes[p].pixels[0] = ctx->planes[p].pixels[1] = 0; + } +} + + static av_cold int allocate_frame_buffers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, int luma_width, int luma_height) { @@ -188,6 +202,11 @@ static av_cold int allocate_frame_buffers(Indeo3DecodeContext *ctx, ctx->planes[p].buffers[0] = av_malloc(!p ? luma_size : chroma_size); ctx->planes[p].buffers[1] = av_malloc(!p ? luma_size : chroma_size); + if (!ctx->planes[p].buffers[0] || !ctx->planes[p].buffers[1]) { + free_frame_buffers(ctx); + return AVERROR(ENOMEM); + } + /* fill the INTRA prediction lines with the middle pixel value = 64 */ memset(ctx->planes[p].buffers[0], 0x40, ctx->planes[p].pitch); memset(ctx->planes[p].buffers[1], 0x40, ctx->planes[p].pitch); @@ -202,22 +221,6 @@ static av_cold int allocate_frame_buffers(Indeo3DecodeContext *ctx, return 0; } - -static av_cold void free_frame_buffers(Indeo3DecodeContext *ctx) -{ - int p; - - ctx->width= - ctx->height= 0; - - for (p = 0; p < 3; p++) { - av_freep(&ctx->planes[p].buffers[0]); - av_freep(&ctx->planes[p].buffers[1]); - ctx->planes[p].pixels[0] = ctx->planes[p].pixels[1] = 0; - } -} - - /** * Copy pixels of the cell(x + mv_x, y + mv_y) from the previous frame into * the cell(x, y) in the current frame. @@ -226,7 +229,7 @@ static av_cold void free_frame_buffers(Indeo3DecodeContext *ctx) * @param plane pointer to the plane descriptor * @param cell pointer to the cell descriptor */ -static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell) +static int copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell) { int h, w, mv_x, mv_y, offset, offset_dst; uint8_t *src, *dst; @@ -239,6 +242,16 @@ static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell) mv_x = cell->mv_ptr[1]; }else mv_x= mv_y= 0; + + /* -1 because there is an extra line on top for prediction */ + if ((cell->ypos << 2) + mv_y < -1 || (cell->xpos << 2) + mv_x < 0 || + ((cell->ypos + cell->height) << 2) + mv_y > plane->height || + ((cell->xpos + cell->width) << 2) + mv_x > plane->width) { + av_log(ctx->avctx, AV_LOG_ERROR, + "Motion vectors point out of the frame.\n"); + return AVERROR_INVALIDDATA; + } + offset = offset_dst + mv_y * plane->pitch + mv_x; src = plane->pixels[ctx->buf_sel ^ 1] + offset; @@ -248,33 +261,33 @@ static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell) /* copy using 16xH blocks */ if (!((cell->xpos << 2) & 15) && w >= 4) { for (; w >= 4; src += 16, dst += 16, w -= 4) - ctx->hdsp.put_no_rnd_pixels_tab[0][0](dst, src, plane->pitch, h); + ctx->hdsp.put_pixels_tab[0][0](dst, src, plane->pitch, h); } /* copy using 8xH blocks */ if (!((cell->xpos << 2) & 7) && w >= 2) { - ctx->hdsp.put_no_rnd_pixels_tab[1][0](dst, src, plane->pitch, h); + ctx->hdsp.put_pixels_tab[1][0](dst, src, plane->pitch, h); w -= 2; src += 8; dst += 8; - } - - if (w >= 1) { - copy_block4(dst, src, plane->pitch, plane->pitch, h); + } else if (w >= 1) { + ctx->hdsp.put_pixels_tab[2][0](dst, src, plane->pitch, h); w--; src += 4; dst += 4; } } + + return 0; } /* Average 4/8 pixels at once without rounding using SWAR */ #define AVG_32(dst, src, ref) \ - AV_WN32A(dst, ((AV_RN32A(src) + AV_RN32A(ref)) >> 1) & 0x7F7F7F7FUL) + AV_WN32A(dst, ((AV_RN32(src) + AV_RN32(ref)) >> 1) & 0x7F7F7F7FUL) #define AVG_64(dst, src, ref) \ - AV_WN64A(dst, ((AV_RN64A(src) + AV_RN64A(ref)) >> 1) & 0x7F7F7F7F7F7F7F7FULL) + AV_WN64A(dst, ((AV_RN64(src) + AV_RN64(ref)) >> 1) & 0x7F7F7F7F7F7F7F7FULL) /* @@ -333,7 +346,7 @@ if (*data_ptr >= last_ptr) \ copy_block4(dst, ref, row_offset, row_offset, 4 << v_zoom) #define RLE_BLOCK_COPY_8 \ - pix64 = AV_RN64A(ref);\ + pix64 = AV_RN64(ref);\ if (is_first_row) {/* special prediction case: top line of a cell */\ pix64 = replicate64(pix64);\ fill_64(dst + row_offset, pix64, 7, row_offset);\ @@ -345,7 +358,7 @@ if (*data_ptr >= last_ptr) \ copy_block4(dst, ref, row_offset, row_offset, num_lines << v_zoom) #define RLE_LINES_COPY_M10 \ - pix64 = AV_RN64A(ref);\ + pix64 = AV_RN64(ref);\ if (is_top_of_cell) {\ pix64 = replicate64(pix64);\ fill_64(dst + row_offset, pix64, (num_lines << 1) - 1, row_offset);\ @@ -355,12 +368,12 @@ if (*data_ptr >= last_ptr) \ #define APPLY_DELTA_4 \ AV_WN16A(dst + line_offset ,\ - (AV_RN16A(ref ) + delta_tab->deltas[dyad1]) & 0x7F7F);\ + (AV_RN16(ref ) + delta_tab->deltas[dyad1]) & 0x7F7F);\ AV_WN16A(dst + line_offset + 2,\ - (AV_RN16A(ref + 2) + delta_tab->deltas[dyad2]) & 0x7F7F);\ + (AV_RN16(ref + 2) + delta_tab->deltas[dyad2]) & 0x7F7F);\ if (mode >= 3) {\ if (is_top_of_cell && !cell->ypos) {\ - AV_COPY32(dst, dst + row_offset);\ + AV_COPY32U(dst, dst + row_offset);\ } else {\ AVG_32(dst, ref, dst + row_offset);\ }\ @@ -370,20 +383,20 @@ if (*data_ptr >= last_ptr) \ /* apply two 32-bit VQ deltas to next even line */\ if (is_top_of_cell) { \ AV_WN32A(dst + row_offset , \ - (replicate32(AV_RN32A(ref )) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\ + (replicate32(AV_RN32(ref )) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\ AV_WN32A(dst + row_offset + 4, \ - (replicate32(AV_RN32A(ref + 4)) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\ + (replicate32(AV_RN32(ref + 4)) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\ } else { \ AV_WN32A(dst + row_offset , \ - (AV_RN32A(ref ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\ + (AV_RN32(ref ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\ AV_WN32A(dst + row_offset + 4, \ - (AV_RN32A(ref + 4) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\ + (AV_RN32(ref + 4) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\ } \ /* odd lines are not coded but rather interpolated/replicated */\ /* first line of the cell on the top of image? - replicate */\ /* otherwise - interpolate */\ if (is_top_of_cell && !cell->ypos) {\ - AV_COPY64(dst, dst + row_offset);\ + AV_COPY64U(dst, dst + row_offset);\ } else \ AVG_64(dst, ref, dst + row_offset); @@ -391,22 +404,22 @@ if (*data_ptr >= last_ptr) \ #define APPLY_DELTA_1011_INTER \ if (mode == 10) { \ AV_WN32A(dst , \ - (AV_RN32A(dst ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\ + (AV_RN32(dst ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\ AV_WN32A(dst + 4 , \ - (AV_RN32A(dst + 4 ) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\ + (AV_RN32(dst + 4 ) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\ AV_WN32A(dst + row_offset , \ - (AV_RN32A(dst + row_offset ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\ + (AV_RN32(dst + row_offset ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\ AV_WN32A(dst + row_offset + 4, \ - (AV_RN32A(dst + row_offset + 4) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\ + (AV_RN32(dst + row_offset + 4) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\ } else { \ AV_WN16A(dst , \ - (AV_RN16A(dst ) + delta_tab->deltas[dyad1]) & 0x7F7F);\ + (AV_RN16(dst ) + delta_tab->deltas[dyad1]) & 0x7F7F);\ AV_WN16A(dst + 2 , \ - (AV_RN16A(dst + 2 ) + delta_tab->deltas[dyad2]) & 0x7F7F);\ + (AV_RN16(dst + 2 ) + delta_tab->deltas[dyad2]) & 0x7F7F);\ AV_WN16A(dst + row_offset , \ - (AV_RN16A(dst + row_offset ) + delta_tab->deltas[dyad1]) & 0x7F7F);\ + (AV_RN16(dst + row_offset ) + delta_tab->deltas[dyad1]) & 0x7F7F);\ AV_WN16A(dst + row_offset + 2, \ - (AV_RN16A(dst + row_offset + 2) + delta_tab->deltas[dyad2]) & 0x7F7F);\ + (AV_RN16(dst + row_offset + 2) + delta_tab->deltas[dyad2]) & 0x7F7F);\ } @@ -587,29 +600,29 @@ static int decode_cell(Indeo3DecodeContext *ctx, AVCodecContext *avctx, offset = (cell->ypos << 2) * plane->pitch + (cell->xpos << 2); block = plane->pixels[ctx->buf_sel] + offset; - if (cell->mv_ptr) { - mv_y = cell->mv_ptr[0]; - mv_x = cell->mv_ptr[1]; - if ( mv_x + 4*cell->xpos < 0 - || mv_y + 4*cell->ypos < 0 - || mv_x + 4*cell->xpos + 4*cell->width > plane->width - || mv_y + 4*cell->ypos + 4*cell->height > plane->height) { - av_log(avctx, AV_LOG_ERROR, "motion vector %d %d outside reference\n", mv_x + 4*cell->xpos, mv_y + 4*cell->ypos); - return AVERROR_INVALIDDATA; - } - } - if (!cell->mv_ptr) { /* use previous line as reference for INTRA cells */ ref_block = block - plane->pitch; } else if (mode >= 10) { /* for mode 10 and 11 INTER first copy the predicted cell into the current one */ /* so we don't need to do data copying for each RLE code later */ - copy_cell(ctx, plane, cell); + int ret = copy_cell(ctx, plane, cell); + if (ret < 0) + return ret; } else { /* set the pointer to the reference pixels for modes 0-4 INTER */ mv_y = cell->mv_ptr[0]; mv_x = cell->mv_ptr[1]; + + /* -1 because there is an extra line on top for prediction */ + if ((cell->ypos << 2) + mv_y < -1 || (cell->xpos << 2) + mv_x < 0 || + ((cell->ypos + cell->height) << 2) + mv_y > plane->height || + ((cell->xpos + cell->width) << 2) + mv_x > plane->width) { + av_log(ctx->avctx, AV_LOG_ERROR, + "Motion vectors point out of the frame.\n"); + return AVERROR_INVALIDDATA; + } + offset += mv_y * plane->pitch + mv_x; ref_block = plane->pixels[ctx->buf_sel ^ 1] + offset; } @@ -743,8 +756,7 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, const int depth, const int strip_width) { Cell curr_cell; - int bytes_used; - int mv_x, mv_y; + int bytes_used, ret; if (depth <= 0) { av_log(avctx, AV_LOG_ERROR, "Stack overflow (corrupted binary tree)!\n"); @@ -796,18 +808,8 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, if (!curr_cell.mv_ptr) return AVERROR_INVALIDDATA; - mv_y = curr_cell.mv_ptr[0]; - mv_x = curr_cell.mv_ptr[1]; - if ( mv_x + 4*curr_cell.xpos < 0 - || mv_y + 4*curr_cell.ypos < 0 - || mv_x + 4*curr_cell.xpos + 4*curr_cell.width > plane->width - || mv_y + 4*curr_cell.ypos + 4*curr_cell.height > plane->height) { - av_log(avctx, AV_LOG_ERROR, "motion vector %d %d outside reference\n", mv_x + 4*curr_cell.xpos, mv_y + 4*curr_cell.ypos); - return AVERROR_INVALIDDATA; - } - - copy_cell(ctx, plane, &curr_cell); - return 0; + ret = copy_cell(ctx, plane, &curr_cell); + return ret; } break; case INTER_DATA: @@ -894,17 +896,20 @@ static int decode_plane(Indeo3DecodeContext *ctx, AVCodecContext *avctx, static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, const uint8_t *buf, int buf_size) { - const uint8_t *buf_ptr = buf, *bs_hdr; + GetByteContext gb; + const uint8_t *bs_hdr; uint32_t frame_num, word2, check_sum, data_size; uint32_t y_offset, u_offset, v_offset, starts[3], ends[3]; uint16_t height, width; int i, j; + bytestream2_init(&gb, buf, buf_size); + /* parse and check the OS header */ - frame_num = bytestream_get_le32(&buf_ptr); - word2 = bytestream_get_le32(&buf_ptr); - check_sum = bytestream_get_le32(&buf_ptr); - data_size = bytestream_get_le32(&buf_ptr); + frame_num = bytestream2_get_le32(&gb); + word2 = bytestream2_get_le32(&gb); + check_sum = bytestream2_get_le32(&gb); + data_size = bytestream2_get_le32(&gb); if ((frame_num ^ word2 ^ data_size ^ OS_HDR_ID) != check_sum) { av_log(avctx, AV_LOG_ERROR, "OS header checksum mismatch!\n"); @@ -912,29 +917,27 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, } /* parse the bitstream header */ - bs_hdr = buf_ptr; - buf_size -= 16; + bs_hdr = gb.buffer; - if (bytestream_get_le16(&buf_ptr) != 32) { + if (bytestream2_get_le16(&gb) != 32) { av_log(avctx, AV_LOG_ERROR, "Unsupported codec version!\n"); return AVERROR_INVALIDDATA; } ctx->frame_num = frame_num; - ctx->frame_flags = bytestream_get_le16(&buf_ptr); - ctx->data_size = (bytestream_get_le32(&buf_ptr) + 7) >> 3; - ctx->cb_offset = *buf_ptr++; + ctx->frame_flags = bytestream2_get_le16(&gb); + ctx->data_size = (bytestream2_get_le32(&gb) + 7) >> 3; + ctx->cb_offset = bytestream2_get_byte(&gb); if (ctx->data_size == 16) return 4; - if (ctx->data_size > buf_size) - ctx->data_size = buf_size; + ctx->data_size = FFMIN(ctx->data_size, buf_size - 16); - buf_ptr += 3; // skip reserved byte and checksum + bytestream2_skip(&gb, 3); // skip reserved byte and checksum /* check frame dimensions */ - height = bytestream_get_le16(&buf_ptr); - width = bytestream_get_le16(&buf_ptr); + height = bytestream2_get_le16(&gb); + width = bytestream2_get_le16(&gb); if (av_image_check_size(width, height, 0, avctx)) return AVERROR_INVALIDDATA; @@ -953,12 +956,14 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, free_frame_buffers(ctx); if ((res = allocate_frame_buffers(ctx, avctx, width, height)) < 0) return res; - avcodec_set_dimensions(avctx, width, height); + if ((res = ff_set_dimensions(avctx, width, height)) < 0) + return res; } - y_offset = bytestream_get_le32(&buf_ptr); - v_offset = bytestream_get_le32(&buf_ptr); - u_offset = bytestream_get_le32(&buf_ptr); + y_offset = bytestream2_get_le32(&gb); + v_offset = bytestream2_get_le32(&gb); + u_offset = bytestream2_get_le32(&gb); + bytestream2_skip(&gb, 4); /* unfortunately there is no common order of planes in the buffer */ /* so we use that sorting algo for determining planes data sizes */ @@ -977,6 +982,7 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, ctx->v_data_size = ends[1] - starts[1]; ctx->u_data_size = ends[2] - starts[2]; if (FFMAX3(y_offset, v_offset, u_offset) >= ctx->data_size - 16 || + FFMIN3(y_offset, v_offset, u_offset) < gb.buffer - bs_hdr + 16 || FFMIN3(ctx->y_data_size, ctx->v_data_size, ctx->u_data_size) <= 0) { av_log(avctx, AV_LOG_ERROR, "One of the y/u/v offsets is invalid\n"); return AVERROR_INVALIDDATA; @@ -985,7 +991,7 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, ctx->y_data_ptr = bs_hdr + y_offset; ctx->v_data_ptr = bs_hdr + v_offset; ctx->u_data_ptr = bs_hdr + u_offset; - ctx->alt_quant = buf_ptr + sizeof(uint32_t); + ctx->alt_quant = gb.buffer; if (ctx->data_size == 16) { av_log(avctx, AV_LOG_DEBUG, "Sync frame encountered!\n"); @@ -1127,12 +1133,12 @@ static av_cold int decode_close(AVCodecContext *avctx) AVCodec ff_indeo3_decoder = { .name = "indeo3", + .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 3"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_INDEO3, .priv_data_size = sizeof(Indeo3DecodeContext), .init = decode_init, .close = decode_close, .decode = decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 3"), .capabilities = CODEC_CAP_DR1, }; diff --git a/ffmpeg/libavcodec/indeo4.c b/ffmpeg/libavcodec/indeo4.c index a958b50..0774f82 100644 --- a/ffmpeg/libavcodec/indeo4.c +++ b/ffmpeg/libavcodec/indeo4.c @@ -2,20 +2,20 @@ * Indeo Video Interactive v4 compatible decoder * Copyright (c) 2009-2011 Maxim Poliakovski * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -56,8 +56,8 @@ static const struct { int is_2d_trans; } transforms[18] = { { ff_ivi_inverse_haar_8x8, ff_ivi_dc_haar_2d, 1 }, - { NULL, NULL, 0 }, /* inverse Haar 8x1 */ - { NULL, NULL, 0 }, /* inverse Haar 1x8 */ + { ff_ivi_row_haar8, ff_ivi_dc_haar_2d, 0 }, + { ff_ivi_col_haar8, ff_ivi_dc_haar_2d, 0 }, { ff_ivi_put_pixels_8x8, ff_ivi_put_dc_pixel_8x8, 1 }, { ff_ivi_inverse_slant_8x8, ff_ivi_dc_slant_2d, 1 }, { ff_ivi_row_slant8, ff_ivi_dc_row_slant, 1 }, @@ -65,13 +65,13 @@ static const struct { { NULL, NULL, 0 }, /* inverse DCT 8x8 */ { NULL, NULL, 0 }, /* inverse DCT 8x1 */ { NULL, NULL, 0 }, /* inverse DCT 1x8 */ - { NULL, NULL, 0 }, /* inverse Haar 4x4 */ + { ff_ivi_inverse_haar_4x4, ff_ivi_dc_haar_2d, 1 }, { ff_ivi_inverse_slant_4x4, ff_ivi_dc_slant_2d, 1 }, { NULL, NULL, 0 }, /* no transform 4x4 */ - { NULL, NULL, 0 }, /* inverse Haar 1x4 */ - { NULL, NULL, 0 }, /* inverse Haar 4x1 */ - { NULL, NULL, 0 }, /* inverse slant 1x4 */ - { NULL, NULL, 0 }, /* inverse slant 4x1 */ + { ff_ivi_row_haar4, ff_ivi_dc_haar_2d, 0 }, + { ff_ivi_col_haar4, ff_ivi_dc_haar_2d, 0 }, + { ff_ivi_row_slant4, ff_ivi_dc_row_slant, 0 }, + { ff_ivi_col_slant4, ff_ivi_dc_col_slant, 0 }, { NULL, NULL, 0 }, /* inverse DCT 4x4 */ }; @@ -210,6 +210,7 @@ static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx) if (ivi_pic_config_cmp(&pic_conf, &ctx->pic_conf)) { if (ff_ivi_init_planes(ctx->planes, &pic_conf)) { av_log(avctx, AV_LOG_ERROR, "Couldn't reallocate color planes!\n"); + ctx->pic_conf.luma_bands = 0; return AVERROR(ENOMEM); } @@ -294,6 +295,7 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, band->is_empty = get_bits1(&ctx->gb); if (!band->is_empty) { + int old_blk_size = band->blk_size; /* skip header size * If header size is not given, header size is 4 bytes. */ if (get_bits1(&ctx->gb)) @@ -352,17 +354,32 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, band->inv_transform = transforms[transform_id].inv_trans; band->dc_transform = transforms[transform_id].dc_trans; band->is_2d_trans = transforms[transform_id].is_2d_trans; - band->transform_size= (transform_id < 10) ? 8 : 4; - scan_indx = get_bits(&ctx->gb, 4); - if ((scan_indx>4 && scan_indx<10) != (band->blk_size==4)) { - av_log(avctx, AV_LOG_ERROR, "mismatching scan table!\n"); + if (transform_id < 10) + band->transform_size = 8; + else + band->transform_size = 4; + + if (band->blk_size != band->transform_size) { + av_log(avctx, AV_LOG_ERROR, "transform and block size mismatch (%d != %d)\n", band->transform_size, band->blk_size); return AVERROR_INVALIDDATA; } + + scan_indx = get_bits(&ctx->gb, 4); if (scan_indx == 15) { av_log(avctx, AV_LOG_ERROR, "Custom scan pattern encountered!\n"); return AVERROR_INVALIDDATA; } + if (scan_indx > 4 && scan_indx < 10) { + if (band->blk_size != 4) { + av_log(avctx, AV_LOG_ERROR, "mismatching scan table!\n"); + return AVERROR_INVALIDDATA; + } + } else if (band->blk_size != 8) { + av_log(avctx, AV_LOG_ERROR, "mismatching scan table!\n"); + return AVERROR_INVALIDDATA; + } + band->scan = scan_index_to_tab[scan_indx]; band->scan_size = band->blk_size; @@ -371,11 +388,19 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, av_log(avctx, AV_LOG_ERROR, "Custom quant matrix encountered!\n"); return AVERROR_INVALIDDATA; } - if (quant_mat > 21) { - av_log(avctx, AV_LOG_ERROR, "Invalid quant matrix encountered!\n"); + if (quant_mat >= FF_ARRAY_ELEMS(quant_index_to_tab)) { + avpriv_request_sample(avctx, "Quantization matrix %d", + quant_mat); return AVERROR_INVALIDDATA; } band->quant_mat = quant_mat; + } else { + if (old_blk_size != band->blk_size) { + av_log(avctx, AV_LOG_ERROR, + "The band block size does not match the configuration " + "inherited\n"); + return AVERROR_INVALIDDATA; + } } if (quant_index_to_tab[band->quant_mat] > 4 && band->blk_size == 4) { av_log(avctx, AV_LOG_ERROR, "Invalid quant matrix for 4x4 block encountered!\n"); @@ -392,9 +417,12 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, } /* decode block huffman codebook */ - if (ff_ivi_dec_huff_desc(&ctx->gb, get_bits1(&ctx->gb), IVI_BLK_HUFF, - &band->blk_vlc, avctx)) - return AVERROR_INVALIDDATA; + if (!get_bits1(&ctx->gb)) + band->blk_vlc.tab = ctx->blk_vlc.tab; + else + if (ff_ivi_dec_huff_desc(&ctx->gb, 1, IVI_BLK_HUFF, + &band->blk_vlc, avctx)) + return AVERROR_INVALIDDATA; /* select appropriate rvmap table for this band */ band->rvmap_sel = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 3) : 8; @@ -507,8 +535,13 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, } } } else { - if (band->inherit_mv && ref_mb) { - mb->type = ref_mb->type; /* copy mb_type from corresponding reference mb */ + if (band->inherit_mv) { + /* copy mb_type from corresponding reference mb */ + if (!ref_mb) { + av_log(avctx, AV_LOG_ERROR, "ref_mb unavailable\n"); + return AVERROR_INVALIDDATA; + } + mb->type = ref_mb->type; } else if (ctx->frame_type == FRAMETYPE_INTRA || ctx->frame_type == FRAMETYPE_INTRA1) { mb->type = 0; /* mb_type is always INTRA for intra-frames */ @@ -531,15 +564,16 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, if (!mb->type) { mb->mv_x = mb->mv_y = 0; /* there is no motion vector in intra-macroblocks */ } else { - if (band->inherit_mv && ref_mb) { - /* motion vector inheritance */ - if (mv_scale) { - mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale); - mb->mv_y = ivi_scale_mv(ref_mb->mv_y, mv_scale); - } else { - mb->mv_x = ref_mb->mv_x; - mb->mv_y = ref_mb->mv_y; - } + if (band->inherit_mv) { + if (ref_mb) + /* motion vector inheritance */ + if (mv_scale) { + mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale); + mb->mv_y = ivi_scale_mv(ref_mb->mv_y, mv_scale); + } else { + mb->mv_x = ref_mb->mv_x; + mb->mv_y = ref_mb->mv_y; + } } else { /* decode motion vector deltas */ mv_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table, @@ -648,12 +682,12 @@ static av_cold int decode_init(AVCodecContext *avctx) AVCodec ff_indeo4_decoder = { .name = "indeo4", + .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 4"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_INDEO4, .priv_data_size = sizeof(IVI45DecContext), .init = decode_init, .close = ff_ivi_decode_close, .decode = ff_ivi_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 4"), .capabilities = CODEC_CAP_DR1, }; diff --git a/ffmpeg/libavcodec/indeo4data.h b/ffmpeg/libavcodec/indeo4data.h index 9b8945a..0ea4f40 100644 --- a/ffmpeg/libavcodec/indeo4data.h +++ b/ffmpeg/libavcodec/indeo4data.h @@ -2,20 +2,20 @@ * Indeo Video Interactive 4 compatible decoder * Copyright (c) 2009-2010 Maxim Poliakovski * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/indeo5.c b/ffmpeg/libavcodec/indeo5.c index 65bd9f2..e48cb43 100644 --- a/ffmpeg/libavcodec/indeo5.c +++ b/ffmpeg/libavcodec/indeo5.c @@ -74,7 +74,7 @@ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx) tile_size = (ctx->gop_flags & 0x40) ? 64 << get_bits(&ctx->gb, 2) : 0; if (tile_size > 256) { av_log(avctx, AV_LOG_ERROR, "Invalid tile size: %d\n", tile_size); - return -1; + return AVERROR_INVALIDDATA; } /* decode number of wavelet bands */ @@ -85,7 +85,7 @@ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx) if (is_scalable && (pic_conf.luma_bands != 4 || pic_conf.chroma_bands != 1)) { av_log(avctx, AV_LOG_ERROR, "Scalability: unsupported subdivision! Luma bands: %d, chroma bands: %d\n", pic_conf.luma_bands, pic_conf.chroma_bands); - return -1; + return AVERROR_INVALIDDATA; } pic_size_indx = get_bits(&ctx->gb, 4); @@ -98,8 +98,8 @@ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx) } if (ctx->gop_flags & 2) { - av_log(avctx, AV_LOG_ERROR, "YV12 picture format not supported!\n"); - return -1; + avpriv_report_missing_feature(avctx, "YV12 picture format"); + return AVERROR_PATCHWELCOME; } pic_conf.chroma_height = (pic_conf.pic_height + 3) >> 2; @@ -113,11 +113,11 @@ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx) } /* check if picture layout was changed and reallocate buffers */ - if (ivi_pic_config_cmp(&pic_conf, &ctx->pic_conf)) { + if (ivi_pic_config_cmp(&pic_conf, &ctx->pic_conf) || ctx->gop_invalid) { result = ff_ivi_init_planes(ctx->planes, &pic_conf); - if (result) { + if (result < 0) { av_log(avctx, AV_LOG_ERROR, "Couldn't reallocate color planes!\n"); - return -1; + return result; } ctx->pic_conf = pic_conf; ctx->is_scalable = is_scalable; @@ -146,51 +146,56 @@ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx) } if (get_bits1(&ctx->gb)) { - av_log(avctx, AV_LOG_ERROR, "Extended transform info encountered!\n"); - return -1; + avpriv_report_missing_feature(avctx, "Extended transform info"); + return AVERROR_PATCHWELCOME; } /* select transform function and scan pattern according to plane and band number */ switch ((p << 2) + i) { case 0: - band->inv_transform = ff_ivi_inverse_slant_8x8; - band->dc_transform = ff_ivi_dc_slant_2d; - band->scan = ff_zigzag_direct; - band->transform_size= 8; + band->inv_transform = ff_ivi_inverse_slant_8x8; + band->dc_transform = ff_ivi_dc_slant_2d; + band->scan = ff_zigzag_direct; + band->transform_size = 8; break; case 1: - band->inv_transform = ff_ivi_row_slant8; - band->dc_transform = ff_ivi_dc_row_slant; - band->scan = ff_ivi_vertical_scan_8x8; - band->transform_size= 8; + band->inv_transform = ff_ivi_row_slant8; + band->dc_transform = ff_ivi_dc_row_slant; + band->scan = ff_ivi_vertical_scan_8x8; + band->transform_size = 8; break; case 2: - band->inv_transform = ff_ivi_col_slant8; - band->dc_transform = ff_ivi_dc_col_slant; - band->scan = ff_ivi_horizontal_scan_8x8; - band->transform_size= 8; + band->inv_transform = ff_ivi_col_slant8; + band->dc_transform = ff_ivi_dc_col_slant; + band->scan = ff_ivi_horizontal_scan_8x8; + band->transform_size = 8; break; case 3: - band->inv_transform = ff_ivi_put_pixels_8x8; - band->dc_transform = ff_ivi_put_dc_pixel_8x8; - band->scan = ff_ivi_horizontal_scan_8x8; - band->transform_size= 8; + band->inv_transform = ff_ivi_put_pixels_8x8; + band->dc_transform = ff_ivi_put_dc_pixel_8x8; + band->scan = ff_ivi_horizontal_scan_8x8; + band->transform_size = 8; break; case 4: - band->inv_transform = ff_ivi_inverse_slant_4x4; - band->dc_transform = ff_ivi_dc_slant_2d; - band->scan = ff_ivi_direct_scan_4x4; - band->transform_size= 4; + band->inv_transform = ff_ivi_inverse_slant_4x4; + band->dc_transform = ff_ivi_dc_slant_2d; + band->scan = ff_ivi_direct_scan_4x4; + band->transform_size = 4; break; } band->is_2d_trans = band->inv_transform == ff_ivi_inverse_slant_8x8 || band->inv_transform == ff_ivi_inverse_slant_4x4; + if (band->transform_size != band->blk_size) { + av_log(avctx, AV_LOG_ERROR, "transform and block size mismatch (%d != %d)\n", band->transform_size, band->blk_size); + return AVERROR_INVALIDDATA; + } + /* select dequant matrix according to plane and band number */ if (!p) { quant_mat = (pic_conf.luma_bands > 1) ? i+1 : 0; @@ -216,7 +221,7 @@ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx) if (get_bits(&ctx->gb, 2)) { av_log(avctx, AV_LOG_ERROR, "End marker missing!\n"); - return -1; + return AVERROR_INVALIDDATA; } } } @@ -246,17 +251,17 @@ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx) if (blk_size_changed) { result = ff_ivi_init_tiles(ctx->planes, pic_conf.tile_width, pic_conf.tile_height); - if (result) { + if (result < 0) { av_log(avctx, AV_LOG_ERROR, "Couldn't reallocate internal structures!\n"); - return -1; + return result; } } if (ctx->gop_flags & 8) { if (get_bits(&ctx->gb, 3)) { av_log(avctx, AV_LOG_ERROR, "Alignment bits are not zero!\n"); - return -1; + return AVERROR_INVALIDDATA; } if (get_bits1(&ctx->gb)) @@ -305,25 +310,27 @@ static inline void skip_hdr_extension(GetBitContext *gb) */ static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx) { + int ret; + if (get_bits(&ctx->gb, 5) != 0x1F) { av_log(avctx, AV_LOG_ERROR, "Invalid picture start code!\n"); - return -1; + return AVERROR_INVALIDDATA; } ctx->prev_frame_type = ctx->frame_type; ctx->frame_type = get_bits(&ctx->gb, 3); if (ctx->frame_type >= 5) { av_log(avctx, AV_LOG_ERROR, "Invalid frame type: %d \n", ctx->frame_type); - return -1; + return AVERROR_INVALIDDATA; } ctx->frame_num = get_bits(&ctx->gb, 8); if (ctx->frame_type == FRAMETYPE_INTRA) { - ctx->gop_invalid = 1; - if (decode_gop_header(ctx, avctx)) { + if ((ret = decode_gop_header(ctx, avctx)) < 0) { av_log(avctx, AV_LOG_ERROR, "Invalid GOP header, skipping frames.\n"); - return AVERROR_INVALIDDATA; + ctx->gop_invalid = 1; + return ret; } ctx->gop_invalid = 0; } @@ -346,8 +353,10 @@ static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx) skip_hdr_extension(&ctx->gb); /* XXX: untested */ /* decode macroblock huffman codebook */ - if (ff_ivi_dec_huff_desc(&ctx->gb, ctx->frame_flags & 0x40, IVI_MB_HUFF, &ctx->mb_vlc, avctx)) - return -1; + ret = ff_ivi_dec_huff_desc(&ctx->gb, ctx->frame_flags & 0x40, + IVI_MB_HUFF, &ctx->mb_vlc, avctx); + if (ret < 0) + return ret; skip_bits(&ctx->gb, 3); /* FIXME: unknown meaning! */ } @@ -369,7 +378,7 @@ static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx) static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, AVCodecContext *avctx) { - int i; + int i, ret; uint8_t band_flags; band_flags = get_bits(&ctx->gb, 8); @@ -393,7 +402,7 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, if (band->num_corr > 61) { av_log(avctx, AV_LOG_ERROR, "Too many corrections: %d\n", band->num_corr); - return -1; + return AVERROR_INVALIDDATA; } /* read correction pairs */ @@ -405,8 +414,10 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, band->rvmap_sel = (band_flags & 0x40) ? get_bits(&ctx->gb, 3) : 8; /* decode block huffman codebook */ - if (ff_ivi_dec_huff_desc(&ctx->gb, band_flags & 0x80, IVI_BLK_HUFF, &band->blk_vlc, avctx)) - return -1; + ret = ff_ivi_dec_huff_desc(&ctx->gb, band_flags & 0x80, IVI_BLK_HUFF, + &band->blk_vlc, avctx); + if (ret < 0) + return ret; band->checksum_present = get_bits1(&ctx->gb); if (band->checksum_present) @@ -473,7 +484,7 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, if (get_bits1(&ctx->gb)) { if (ctx->frame_type == FRAMETYPE_INTRA) { av_log(avctx, AV_LOG_ERROR, "Empty macroblock in an INTRA picture!\n"); - return -1; + return AVERROR_INVALIDDATA; } mb->type = 1; /* empty macroblocks are always INTER */ mb->cbp = 0; /* all blocks are empty */ @@ -646,7 +657,7 @@ static av_cold int decode_init(AVCodecContext *avctx) result = ff_ivi_init_planes(ctx->planes, &ctx->pic_conf); if (result) { av_log(avctx, AV_LOG_ERROR, "Couldn't allocate color planes!\n"); - return -1; + return AVERROR_INVALIDDATA; } ctx->buf_switch = 0; @@ -665,12 +676,12 @@ static av_cold int decode_init(AVCodecContext *avctx) AVCodec ff_indeo5_decoder = { .name = "indeo5", + .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 5"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_INDEO5, .priv_data_size = sizeof(IVI45DecContext), .init = decode_init, .close = ff_ivi_decode_close, .decode = ff_ivi_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 5"), .capabilities = CODEC_CAP_DR1, }; diff --git a/ffmpeg/libavcodec/intelh263dec.c b/ffmpeg/libavcodec/intelh263dec.c index ac2695e..5da4202 100644 --- a/ffmpeg/libavcodec/intelh263dec.c +++ b/ffmpeg/libavcodec/intelh263dec.c @@ -111,9 +111,8 @@ int ff_intel_h263_decode_picture_header(MpegEncContext *s) } /* PEI */ - while (get_bits1(&s->gb) != 0) { - skip_bits(&s->gb, 8); - } + if (skip_1stop_8data_bits(&s->gb) < 0) + return AVERROR_INVALIDDATA; s->f_code = 1; s->y_dc_scale_table= @@ -126,6 +125,7 @@ int ff_intel_h263_decode_picture_header(MpegEncContext *s) AVCodec ff_h263i_decoder = { .name = "h263i", + .long_name = NULL_IF_CONFIG_SMALL("Intel H.263"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H263I, .priv_data_size = sizeof(MpegEncContext), @@ -133,6 +133,5 @@ AVCodec ff_h263i_decoder = { .close = ff_h263_decode_end, .decode = ff_h263_decode_frame, .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Intel H.263"), .pix_fmts = ff_pixfmt_list_420, }; diff --git a/ffmpeg/libavcodec/internal.h b/ffmpeg/libavcodec/internal.h index e51757f..35bfcd4 100644 --- a/ffmpeg/libavcodec/internal.h +++ b/ffmpeg/libavcodec/internal.h @@ -30,6 +30,7 @@ #include "libavutil/mathematics.h" #include "libavutil/pixfmt.h" #include "avcodec.h" +#include "config.h" #define FF_SANE_NB_CHANNELS 63U @@ -81,7 +82,7 @@ typedef struct AVCodecInternal { * Internal sample count used by avcodec_encode_audio() to fabricate pts. * Can be removed along with avcodec_encode_audio(). */ - int sample_count; + int64_t sample_count; #endif /** @@ -90,10 +91,18 @@ typedef struct AVCodecInternal { */ int last_audio_frame; - AVFrame to_free; + AVFrame *to_free; FramePool *pool; + void *thread_ctx; + + /** + * Current packet as passed into the decoder, to avoid having to pass the + * packet into every function. + */ + AVPacket *pkt; + /** * temporary buffer used for encoders to store their bitstream */ @@ -117,11 +126,10 @@ struct AVCodecDefault { * Return the hardware accelerated codec for codec codec_id and * pixel format pix_fmt. * - * @param codec_id the codec to match - * @param pix_fmt the pixel format to match + * @param avctx The codec context containing the codec_id and pixel format. * @return the hardware accelerated codec, or NULL if none was found. */ -AVHWAccel *ff_find_hwaccel(enum AVCodecID codec_id, enum AVPixelFormat pix_fmt); +AVHWAccel *ff_find_hwaccel(AVCodecContext *avctx); /** * Return the index into tab at which {a,b} match elements {[0],[1]} of tab. @@ -139,11 +147,6 @@ int ff_init_buffer_info(AVCodecContext *s, AVFrame *frame); void avpriv_color_frame(AVFrame *frame, const int color[4]); -/** - * Remove and free all side data from packet. - */ -void ff_packet_free_side_data(AVPacket *pkt); - extern volatile int ff_avcodec_locked; int ff_lock_avcodec(AVCodecContext *log_ctx); int ff_unlock_avcodec(void); @@ -175,7 +178,7 @@ int avpriv_unlock_avformat(void); * @param size the minimum required packet size * @return 0 on success, negative error code on failure */ -int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int size); +int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int64_t size); int ff_alloc_packet(AVPacket *avpkt, int size); @@ -206,8 +209,6 @@ int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame); int ff_thread_can_start_frame(AVCodecContext *avctx); -int ff_get_logical_cpus(AVCodecContext *avctx); - int avpriv_h264_has_num_reorder_frames(AVCodecContext *avctx); /** @@ -227,4 +228,14 @@ int ff_codec_close_recursive(AVCodecContext *avctx); */ int avpriv_bprint_to_extradata(AVCodecContext *avctx, struct AVBPrint *buf); +const uint8_t *avpriv_find_start_code(const uint8_t *p, + const uint8_t *end, + uint32_t *state); + +/** + * Check that the provided frame dimensions are valid and set them on the codec + * context. + */ +int ff_set_dimensions(AVCodecContext *s, int width, int height); + #endif /* AVCODEC_INTERNAL_H */ diff --git a/ffmpeg/libavcodec/interplayvideo.c b/ffmpeg/libavcodec/interplayvideo.c index 4f710b8..542fefe 100644 --- a/ffmpeg/libavcodec/interplayvideo.c +++ b/ffmpeg/libavcodec/interplayvideo.c @@ -197,6 +197,11 @@ static int ipvideo_decode_block_opcode_0x7(IpvideoContext *s, AVFrame *frame) unsigned char P[2]; unsigned int flags; + if (bytestream2_get_bytes_left(&s->stream_ptr) < 4) { + av_log(s->avctx, AV_LOG_ERROR, "too little data for opcode 0x7\n"); + return AVERROR_INVALIDDATA; + } + /* 2-color encoding */ P[0] = bytestream2_get_byte(&s->stream_ptr); P[1] = bytestream2_get_byte(&s->stream_ptr); @@ -236,6 +241,11 @@ static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s, AVFrame *frame) unsigned char P[4]; unsigned int flags = 0; + if (bytestream2_get_bytes_left(&s->stream_ptr) < 12) { + av_log(s->avctx, AV_LOG_ERROR, "too little data for opcode 0x8\n"); + return AVERROR_INVALIDDATA; + } + /* 2-color encoding for each 4x4 quadrant, or 2-color encoding on * either top and bottom or left and right halves */ P[0] = bytestream2_get_byte(&s->stream_ptr); @@ -308,6 +318,11 @@ static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s, AVFrame *frame) int x, y; unsigned char P[4]; + if (bytestream2_get_bytes_left(&s->stream_ptr) < 8) { + av_log(s->avctx, AV_LOG_ERROR, "too little data for opcode 0x9\n"); + return AVERROR_INVALIDDATA; + } + /* 4-color encoding */ bytestream2_get_buffer(&s->stream_ptr, P, 4); @@ -374,6 +389,11 @@ static int ipvideo_decode_block_opcode_0xA(IpvideoContext *s, AVFrame *frame) unsigned char P[8]; int flags = 0; + if (bytestream2_get_bytes_left(&s->stream_ptr) < 16) { + av_log(s->avctx, AV_LOG_ERROR, "too little data for opcode 0xA\n"); + return AVERROR_INVALIDDATA; + } + bytestream2_get_buffer(&s->stream_ptr, P, 4); /* 4-color encoding for each 4x4 quadrant, or 4-color encoding on @@ -467,6 +487,11 @@ static int ipvideo_decode_block_opcode_0xD(IpvideoContext *s, AVFrame *frame) int y; unsigned char P[2]; + if (bytestream2_get_bytes_left(&s->stream_ptr) < 4) { + av_log(s->avctx, AV_LOG_ERROR, "too little data for opcode 0xD\n"); + return AVERROR_INVALIDDATA; + } + /* 4-color block encoding: each 4x4 block is a different color */ for (y = 0; y < 8; y++) { if (!(y & 3)) { @@ -1016,6 +1041,7 @@ static av_cold int ipvideo_decode_end(AVCodecContext *avctx) AVCodec ff_interplay_video_decoder = { .name = "interplayvideo", + .long_name = NULL_IF_CONFIG_SMALL("Interplay MVE video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_INTERPLAY_VIDEO, .priv_data_size = sizeof(IpvideoContext), @@ -1023,5 +1049,4 @@ AVCodec ff_interplay_video_decoder = { .close = ipvideo_decode_end, .decode = ipvideo_decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_PARAM_CHANGE, - .long_name = NULL_IF_CONFIG_SMALL("Interplay MVE video"), }; diff --git a/ffmpeg/libavcodec/intrax8.c b/ffmpeg/libavcodec/intrax8.c index 67e16ab..ffdfb07 100644 --- a/ffmpeg/libavcodec/intrax8.c +++ b/ffmpeg/libavcodec/intrax8.c @@ -437,7 +437,7 @@ lut2[q>12][c]={ static void x8_ac_compensation(IntraX8Context * const w, int const direction, int const dc_level){ MpegEncContext * const s= w->s; int t; -#define B(x,y) s->block[0][s->dsp.idct_permutation[(x)+(y)*8]] +#define B(x,y) s->block[0][w->idct_permutation[(x)+(y)*8]] #define T(x) ((x) * dc_level + 0x8000) >> 16; switch(direction){ case 0: @@ -643,7 +643,7 @@ static int x8_decode_intra_mb(IntraX8Context* const w, const int chroma){ s->current_picture.f.linesize[!!chroma] ); } if(!zeros_only) - s->dsp.idct_add ( s->dest[chroma], + w->wdsp.idct_add (s->dest[chroma], s->current_picture.f.linesize[!!chroma], s->block[0] ); @@ -695,9 +695,13 @@ av_cold void ff_intrax8_common_init(IntraX8Context * w, MpegEncContext * const s av_assert0(s->mb_width>0); w->prediction_table=av_mallocz(s->mb_width*2*2);//two rows, 2 blocks per cannon mb - ff_init_scantable(s->dsp.idct_permutation, &w->scantable[0], ff_wmv1_scantable[0]); - ff_init_scantable(s->dsp.idct_permutation, &w->scantable[1], ff_wmv1_scantable[2]); - ff_init_scantable(s->dsp.idct_permutation, &w->scantable[2], ff_wmv1_scantable[3]); + ff_wmv2dsp_init(&w->wdsp); + ff_init_scantable_permutation(w->idct_permutation, + w->wdsp.idct_perm); + + ff_init_scantable(w->idct_permutation, &w->scantable[0], ff_wmv1_scantable[0]); + ff_init_scantable(w->idct_permutation, &w->scantable[1], ff_wmv1_scantable[2]); + ff_init_scantable(w->idct_permutation, &w->scantable[2], ff_wmv1_scantable[3]); ff_intrax8dsp_init(&w->dsp); } @@ -722,7 +726,6 @@ av_cold void ff_intrax8_common_end(IntraX8Context * w) * @param dquant doubled quantizer, it would be odd in case of VC-1 halfpq==1. * @param quant_offset offset away from zero */ -//FIXME extern uint8_t ff_wmv3_dc_scale_table[32]; int ff_intrax8_decode_picture(IntraX8Context * const w, int dquant, int quant_offset){ MpegEncContext * const s= w->s; int mb_xy; diff --git a/ffmpeg/libavcodec/intrax8.h b/ffmpeg/libavcodec/intrax8.h index 40d689a..9981785 100644 --- a/ffmpeg/libavcodec/intrax8.h +++ b/ffmpeg/libavcodec/intrax8.h @@ -22,6 +22,7 @@ #include "get_bits.h" #include "mpegvideo.h" #include "intrax8dsp.h" +#include "wmv2dsp.h" typedef struct IntraX8Context { VLC * j_ac_vlc[4];//they point to the static j_mb_vlc @@ -32,6 +33,8 @@ typedef struct IntraX8Context { //set by ff_intrax8_common_init uint8_t * prediction_table;//2*(mb_w*2) ScanTable scantable[3]; + WMV2DSPContext wdsp; + uint8_t idct_permutation[64]; //set by the caller codec MpegEncContext * s; IntraX8DSPContext dsp; diff --git a/ffmpeg/libavcodec/ituh263dec.c b/ffmpeg/libavcodec/ituh263dec.c index 5d604ef..71e36c1 100644 --- a/ffmpeg/libavcodec/ituh263dec.c +++ b/ffmpeg/libavcodec/ituh263dec.c @@ -28,10 +28,9 @@ */ #define UNCHECKED_BITSTREAM_READER 1 - -//#define DEBUG #include +#include "libavutil/attributes.h" #include "libavutil/internal.h" #include "libavutil/mathematics.h" #include "avcodec.h" @@ -100,7 +99,7 @@ static VLC cbpc_b_vlc; /* init vlcs */ /* XXX: find a better solution to handle static init */ -void ff_h263_decode_init_vlc(void) +av_cold void ff_h263_decode_init_vlc(void) { static volatile int done = 0; @@ -200,30 +199,6 @@ static int h263_decode_gob_header(MpegEncContext *s) return 0; } -/** - * Find the next resync_marker. - * @param p pointer to buffer to scan - * @param end pointer to the end of the buffer - * @return pointer to the next resync_marker, or end if none was found - */ -const uint8_t *ff_h263_find_resync_marker(MpegEncContext *s, const uint8_t *av_restrict p, const uint8_t *av_restrict end) -{ - av_assert2(p < end); - - end-=2; - p++; - if(s->resync_marker){ - int prefix_len = ff_mpeg4_get_video_packet_prefix_length(s); - for(;p> (23-prefix_len)) == 1)) return p - 1; - else if (!p[ 1] && ((p[2] >> (23-prefix_len)) == 1)) return p; - } - } - } - return end+2; -} - /** * Decode the group of blocks / video packet header. * @return bit position of the resync_marker, or <0 if none was found @@ -239,7 +214,7 @@ int ff_h263_resync(MpegEncContext *s){ if(show_bits(&s->gb, 16)==0){ pos= get_bits_count(&s->gb); if(CONFIG_MPEG4_DECODER && s->codec_id==AV_CODEC_ID_MPEG4) - ret= ff_mpeg4_decode_video_packet_header(s); + ret= ff_mpeg4_decode_video_packet_header(s->avctx->priv_data); else ret= h263_decode_gob_header(s); if(ret>=0) @@ -256,7 +231,7 @@ int ff_h263_resync(MpegEncContext *s){ pos= get_bits_count(&s->gb); if(CONFIG_MPEG4_DECODER && s->codec_id==AV_CODEC_ID_MPEG4) - ret= ff_mpeg4_decode_video_packet_header(s); + ret= ff_mpeg4_decode_video_packet_header(s->avctx->priv_data); else ret= h263_decode_gob_header(s); if(ret>=0) @@ -875,6 +850,10 @@ int ff_h263_decode_picture_header(MpegEncContext *s) align_get_bits(&s->gb); + if (show_bits(&s->gb, 2) == 2 && s->avctx->frame_number == 0) { + av_log(s->avctx, AV_LOG_WARNING, "Header looks like RTP instead of H.263\n"); + } + startcode= get_bits(&s->gb, 22-8); for(i= get_bits_left(&s->gb); i>24; i-=8) { @@ -892,7 +871,6 @@ int ff_h263_decode_picture_header(MpegEncContext *s) i = get_bits(&s->gb, 8); /* picture timestamp */ if( (s->picture_number&~0xFF)+i < s->picture_number) i+= 256; - s->current_picture_ptr->f.pts = s->picture_number= (s->picture_number&~0xFF) + i; /* PTYPE starts here */ @@ -1034,6 +1012,7 @@ int ff_h263_decode_picture_header(MpegEncContext *s) height = ff_h263_format[format][1]; s->avctx->sample_aspect_ratio= (AVRational){12,11}; } + s->avctx->sample_aspect_ratio.den <<= s->ehc_mode; if ((width == 0) || (height == 0)) return -1; s->width = width; @@ -1110,9 +1089,8 @@ int ff_h263_decode_picture_header(MpegEncContext *s) } /* PEI */ - while (get_bits1(&s->gb) != 0) { - skip_bits(&s->gb, 8); - } + if (skip_1stop_8data_bits(&s->gb) < 0) + return AVERROR_INVALIDDATA; if(s->h263_slice_structured){ if (get_bits1(&s->gb) != 1) { diff --git a/ffmpeg/libavcodec/ituh263enc.c b/ffmpeg/libavcodec/ituh263enc.c index 9a03f02..2db9581 100644 --- a/ffmpeg/libavcodec/ituh263enc.c +++ b/ffmpeg/libavcodec/ituh263enc.c @@ -27,9 +27,9 @@ * h263 bitstream encoder. */ -//#define DEBUG #include +#include "libavutil/attributes.h" #include "avcodec.h" #include "mpegvideo.h" #include "h263.h" @@ -679,7 +679,7 @@ void ff_h263_encode_motion(MpegEncContext * s, int val, int f_code) } } -static void init_mv_penalty_and_fcode(MpegEncContext *s) +static av_cold void init_mv_penalty_and_fcode(MpegEncContext *s) { int f_code; int mv; @@ -721,7 +721,9 @@ static void init_mv_penalty_and_fcode(MpegEncContext *s) } } -static void init_uni_h263_rl_tab(RLTable *rl, uint32_t *bits_tab, uint8_t *len_tab){ +static av_cold void init_uni_h263_rl_tab(RLTable *rl, uint32_t *bits_tab, + uint8_t *len_tab) +{ int slevel, run, last; av_assert0(MAX_LEVEL >= 64); @@ -764,7 +766,7 @@ static void init_uni_h263_rl_tab(RLTable *rl, uint32_t *bits_tab, uint8_t *len_t } } -void ff_h263_encode_init(MpegEncContext *s) +av_cold void ff_h263_encode_init(MpegEncContext *s) { static int done = 0; diff --git a/ffmpeg/libavcodec/ivi_common.c b/ffmpeg/libavcodec/ivi_common.c index 265c645..a4d2434 100644 --- a/ffmpeg/libavcodec/ivi_common.c +++ b/ffmpeg/libavcodec/ivi_common.c @@ -35,12 +35,59 @@ #include "ivi_common.h" #include "ivi_dsp.h" -extern const IVIHuffDesc ff_ivi_mb_huff_desc[8]; ///< static macroblock huffman tables -extern const IVIHuffDesc ff_ivi_blk_huff_desc[8]; ///< static block huffman tables +/** + * These are 2x8 predefined Huffman codebooks for coding macroblock/block + * signals. They are specified using "huffman descriptors" in order to + * avoid huge static tables. The decoding tables will be generated at + * startup from these descriptors. + */ +/** static macroblock huffman tables */ +static const IVIHuffDesc ivi_mb_huff_desc[8] = { + {8, {0, 4, 5, 4, 4, 4, 6, 6}}, + {12, {0, 2, 2, 3, 3, 3, 3, 5, 3, 2, 2, 2}}, + {12, {0, 2, 3, 4, 3, 3, 3, 3, 4, 3, 2, 2}}, + {12, {0, 3, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2}}, + {13, {0, 4, 4, 3, 3, 3, 3, 2, 3, 3, 2, 1, 1}}, + {9, {0, 4, 4, 4, 4, 3, 3, 3, 2}}, + {10, {0, 4, 4, 4, 4, 3, 3, 2, 2, 2}}, + {12, {0, 4, 4, 4, 3, 3, 2, 3, 2, 2, 2, 2}} +}; + +/** static block huffman tables */ +static const IVIHuffDesc ivi_blk_huff_desc[8] = { + {10, {1, 2, 3, 4, 4, 7, 5, 5, 4, 1}}, + {11, {2, 3, 4, 4, 4, 7, 5, 4, 3, 3, 2}}, + {12, {2, 4, 5, 5, 5, 5, 6, 4, 4, 3, 1, 1}}, + {13, {3, 3, 4, 4, 5, 6, 6, 4, 4, 3, 2, 1, 1}}, + {11, {3, 4, 4, 5, 5, 5, 6, 5, 4, 2, 2}}, + {13, {3, 4, 5, 5, 5, 5, 6, 4, 3, 3, 2, 1, 1}}, + {13, {3, 4, 5, 5, 5, 6, 5, 4, 3, 3, 2, 1, 1}}, + {9, {3, 4, 4, 5, 5, 5, 6, 5, 5}} +}; static VLC ivi_mb_vlc_tabs [8]; ///< static macroblock Huffman tables static VLC ivi_blk_vlc_tabs[8]; ///< static block Huffman tables +typedef void (*ivi_mc_func) (int16_t *buf, const int16_t *ref_buf, + uint32_t pitch, int mc_type); + +static int ivi_mc(IVIBandDesc *band, ivi_mc_func mc, + int offs, int mv_x, int mv_y, int mc_type) +{ + int ref_offs = offs + mv_y * band->pitch + mv_x; + int buf_size = band->pitch * band->aheight; + int min_size = band->pitch * (band->blk_size - 1) + band->blk_size; + int ref_size = (mc_type > 1) * band->pitch + (mc_type & 1); + + av_assert0(offs >= 0 && ref_offs >= 0 && band->ref_buf); + av_assert0(buf_size - min_size >= offs); + av_assert0(buf_size - min_size - ref_size >= ref_offs); + + mc(band->buf + offs, band->ref_buf + ref_offs, band->pitch, mc_type); + + return 0; +} + /** * Reverse "nbits" bits of the value "val" and return the result * in the least significant bits. @@ -50,9 +97,10 @@ static uint16_t inv_bits(uint16_t val, int nbits) uint16_t res; if (nbits <= 8) { - res = ff_reverse[val] >> (8-nbits); + res = ff_reverse[val] >> (8 - nbits); } else - res = ((ff_reverse[val & 0xFF] << 8) + (ff_reverse[val >> 8])) >> (16-nbits); + res = ((ff_reverse[val & 0xFF] << 8) + + (ff_reverse[val >> 8])) >> (16 - nbits); return res; } @@ -85,7 +133,7 @@ static int ivi_create_huff_from_desc(const IVIHuffDesc *cb, VLC *vlc, int flag) bits[pos] = i + cb->xbits[i] + not_last_row; if (bits[pos] > IVI_VLC_BITS) - return -1; /* invalid descriptor */ + return AVERROR_INVALIDDATA; /* invalid descriptor */ codewords[pos] = inv_bits((prefix | j), bits[pos]); if (!bits[pos]) @@ -100,7 +148,7 @@ static int ivi_create_huff_from_desc(const IVIHuffDesc *cb, VLC *vlc, int flag) (flag ? INIT_VLC_USE_NEW_STATIC : 0) | INIT_VLC_LE); } -void ff_ivi_init_static_vlc(void) +av_cold void ff_ivi_init_static_vlc(void) { int i; static VLC_TYPE table_data[8192 * 16][2]; @@ -111,10 +159,12 @@ void ff_ivi_init_static_vlc(void) for (i = 0; i < 8; i++) { ivi_mb_vlc_tabs[i].table = table_data + i * 2 * 8192; ivi_mb_vlc_tabs[i].table_allocated = 8192; - ivi_create_huff_from_desc(&ff_ivi_mb_huff_desc[i], &ivi_mb_vlc_tabs[i], 1); + ivi_create_huff_from_desc(&ivi_mb_huff_desc[i], + &ivi_mb_vlc_tabs[i], 1); ivi_blk_vlc_tabs[i].table = table_data + (i * 2 + 1) * 8192; ivi_blk_vlc_tabs[i].table_allocated = 8192; - ivi_create_huff_from_desc(&ff_ivi_blk_huff_desc[i], &ivi_blk_vlc_tabs[i], 1); + ivi_create_huff_from_desc(&ivi_blk_huff_desc[i], + &ivi_blk_vlc_tabs[i], 1); } initialized_vlcs = 1; } @@ -138,56 +188,59 @@ static void ivi_huff_desc_copy(IVIHuffDesc *dst, const IVIHuffDesc *src) * @param[in] desc2 ptr to the 2nd descriptor to compare * @return comparison result: 0 - equal, 1 - not equal */ -static int ivi_huff_desc_cmp(const IVIHuffDesc *desc1, const IVIHuffDesc *desc2) +static int ivi_huff_desc_cmp(const IVIHuffDesc *desc1, + const IVIHuffDesc *desc2) { - return desc1->num_rows != desc2->num_rows - || memcmp(desc1->xbits, desc2->xbits, desc1->num_rows); + return desc1->num_rows != desc2->num_rows || + memcmp(desc1->xbits, desc2->xbits, desc1->num_rows); } int ff_ivi_dec_huff_desc(GetBitContext *gb, int desc_coded, int which_tab, IVIHuffTab *huff_tab, AVCodecContext *avctx) { - int i, result; + int i, result; IVIHuffDesc new_huff; if (!desc_coded) { /* select default table */ huff_tab->tab = (which_tab) ? &ivi_blk_vlc_tabs[7] - : &ivi_mb_vlc_tabs [7]; - } else { - huff_tab->tab_sel = get_bits(gb, 3); - if (huff_tab->tab_sel == 7) { - /* custom huffman table (explicitly encoded) */ - new_huff.num_rows = get_bits(gb, 4); - if (!new_huff.num_rows) { - av_log(avctx, AV_LOG_ERROR, "Empty custom Huffman table!\n"); - return AVERROR_INVALIDDATA; - } - - for (i = 0; i < new_huff.num_rows; i++) - new_huff.xbits[i] = get_bits(gb, 4); + : &ivi_mb_vlc_tabs [7]; + return 0; + } - /* Have we got the same custom table? Rebuild if not. */ - if (ivi_huff_desc_cmp(&new_huff, &huff_tab->cust_desc) || !huff_tab->cust_tab.table) { - ivi_huff_desc_copy(&huff_tab->cust_desc, &new_huff); + huff_tab->tab_sel = get_bits(gb, 3); + if (huff_tab->tab_sel == 7) { + /* custom huffman table (explicitly encoded) */ + new_huff.num_rows = get_bits(gb, 4); + if (!new_huff.num_rows) { + av_log(avctx, AV_LOG_ERROR, "Empty custom Huffman table!\n"); + return AVERROR_INVALIDDATA; + } - if (huff_tab->cust_tab.table) - ff_free_vlc(&huff_tab->cust_tab); - result = ivi_create_huff_from_desc(&huff_tab->cust_desc, - &huff_tab->cust_tab, 0); - if (result) { - huff_tab->cust_desc.num_rows = 0; // reset faulty description - av_log(avctx, AV_LOG_ERROR, - "Error while initializing custom vlc table!\n"); - return result; - } + for (i = 0; i < new_huff.num_rows; i++) + new_huff.xbits[i] = get_bits(gb, 4); + + /* Have we got the same custom table? Rebuild if not. */ + if (ivi_huff_desc_cmp(&new_huff, &huff_tab->cust_desc) || !huff_tab->cust_tab.table) { + ivi_huff_desc_copy(&huff_tab->cust_desc, &new_huff); + + if (huff_tab->cust_tab.table) + ff_free_vlc(&huff_tab->cust_tab); + result = ivi_create_huff_from_desc(&huff_tab->cust_desc, + &huff_tab->cust_tab, 0); + if (result) { + // reset faulty description + huff_tab->cust_desc.num_rows = 0; + av_log(avctx, AV_LOG_ERROR, + "Error while initializing custom vlc table!\n"); + return result; } - huff_tab->tab = &huff_tab->cust_tab; - } else { - /* select one of predefined tables */ - huff_tab->tab = (which_tab) ? &ivi_blk_vlc_tabs[huff_tab->tab_sel] - : &ivi_mb_vlc_tabs [huff_tab->tab_sel]; } + huff_tab->tab = &huff_tab->cust_tab; + } else { + /* select one of predefined tables */ + huff_tab->tab = (which_tab) ? &ivi_blk_vlc_tabs[huff_tab->tab_sel] + : &ivi_mb_vlc_tabs [huff_tab->tab_sel]; } return 0; @@ -216,17 +269,23 @@ static av_cold void ivi_free_buffers(IVIPlaneDesc *planes) av_freep(&planes[p].bands[b].tiles); } av_freep(&planes[p].bands); + planes[p].num_bands = 0; } } av_cold int ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg) { - int p, b; - uint32_t b_width, b_height, align_fac, width_aligned, height_aligned, buf_size; + int p, b; + uint32_t b_width, b_height, align_fac, width_aligned, + height_aligned, buf_size; IVIBandDesc *band; ivi_free_buffers(planes); + if (cfg->pic_width < 1 || cfg->pic_height < 1 || + cfg->luma_bands < 1 || cfg->chroma_bands < 1) + return AVERROR_INVALIDDATA; + /* fill in the descriptor of the luminance plane */ planes[0].width = cfg->pic_width; planes[0].height = cfg->pic_height; @@ -245,8 +304,10 @@ av_cold int ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg) /* select band dimensions: if there is only one band then it * has the full size, if there are several bands each of them * has only half size */ - b_width = planes[p].num_bands == 1 ? planes[p].width : (planes[p].width + 1) >> 1; - b_height = planes[p].num_bands == 1 ? planes[p].height : (planes[p].height + 1) >> 1; + b_width = planes[p].num_bands == 1 ? planes[p].width + : (planes[p].width + 1) >> 1; + b_height = planes[p].num_bands == 1 ? planes[p].height + : (planes[p].height + 1) >> 1; /* luma band buffers will be aligned on 16x16 (max macroblock size) */ /* chroma band buffers will be aligned on 8x8 (max macroblock size) */ @@ -275,19 +336,58 @@ av_cold int ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg) if (!band->bufs[2]) return AVERROR(ENOMEM); } + /* reset custom vlc */ + planes[p].bands[0].blk_vlc.cust_desc.num_rows = 0; + } + } + + return 0; +} + +static int ivi_init_tiles(IVIBandDesc *band, IVITile *ref_tile, + int p, int b, int t_height, int t_width) +{ + int x, y; + IVITile *tile = band->tiles; + + for (y = 0; y < band->height; y += t_height) { + for (x = 0; x < band->width; x += t_width) { + tile->xpos = x; + tile->ypos = y; + tile->mb_size = band->mb_size; + tile->width = FFMIN(band->width - x, t_width); + tile->height = FFMIN(band->height - y, t_height); + tile->is_empty = tile->data_size = 0; + /* calculate number of macroblocks */ + tile->num_MBs = IVI_MBs_PER_TILE(tile->width, tile->height, + band->mb_size); + + av_freep(&tile->mbs); + tile->mbs = av_mallocz(tile->num_MBs * sizeof(IVIMbInfo)); + if (!tile->mbs) + return AVERROR(ENOMEM); - planes[p].bands[0].blk_vlc.cust_desc.num_rows = 0; /* reset custom vlc */ + tile->ref_mbs = 0; + if (p || b) { + if (tile->num_MBs != ref_tile->num_MBs) { + av_log(NULL, AV_LOG_DEBUG, "ref_tile mismatch\n"); + return AVERROR_INVALIDDATA; + } + tile->ref_mbs = ref_tile->mbs; + ref_tile++; + } + tile++; } } return 0; } -av_cold int ff_ivi_init_tiles(IVIPlaneDesc *planes, int tile_width, int tile_height) +av_cold int ff_ivi_init_tiles(IVIPlaneDesc *planes, + int tile_width, int tile_height) { - int p, b, x, y, x_tiles, y_tiles, t_width, t_height; + int p, b, x_tiles, y_tiles, t_width, t_height, ret; IVIBandDesc *band; - IVITile *tile, *ref_tile; for (p = 0; p < 3; p++) { t_width = !p ? tile_width : (tile_width + 3) >> 2; @@ -311,44 +411,14 @@ av_cold int ff_ivi_init_tiles(IVIPlaneDesc *planes, int tile_width, int tile_hei if (!band->tiles) return AVERROR(ENOMEM); - tile = band->tiles; - /* use the first luma band as reference for motion vectors * and quant */ - ref_tile = planes[0].bands[0].tiles; - - for (y = 0; y < band->height; y += t_height) { - for (x = 0; x < band->width; x += t_width) { - tile->xpos = x; - tile->ypos = y; - tile->mb_size = band->mb_size; - tile->width = FFMIN(band->width - x, t_width); - tile->height = FFMIN(band->height - y, t_height); - tile->is_empty = tile->data_size = 0; - /* calculate number of macroblocks */ - tile->num_MBs = IVI_MBs_PER_TILE(tile->width, tile->height, - band->mb_size); - - av_freep(&tile->mbs); - tile->mbs = av_malloc(tile->num_MBs * sizeof(IVIMbInfo)); - if (!tile->mbs) - return AVERROR(ENOMEM); - - tile->ref_mbs = 0; - if (p || b) { - if (tile->num_MBs <= ref_tile->num_MBs) { - tile->ref_mbs = ref_tile->mbs; - }else - av_log(NULL, AV_LOG_DEBUG, "Cannot use ref_tile, too few mbs\n"); - ref_tile++; - } - - tile++; - } - } - - }// for b - }// for p + ret = ivi_init_tiles(band, planes[0].bands[0].tiles, + p, b, t_height, t_width); + if (ret < 0) + return ret; + } + } return 0; } @@ -380,6 +450,117 @@ static int ivi_dec_tile_data_size(GetBitContext *gb) return len; } +static int ivi_dc_transform(IVIBandDesc *band, int *prev_dc, int buf_offs, + int blk_size) +{ + int buf_size = band->pitch * band->aheight - buf_offs; + int min_size = (blk_size - 1) * band->pitch + blk_size; + + if (min_size > buf_size) + return AVERROR_INVALIDDATA; + + band->dc_transform(prev_dc, band->buf + buf_offs, + band->pitch, blk_size); + + return 0; +} + +static int ivi_decode_coded_blocks(GetBitContext *gb, IVIBandDesc *band, + ivi_mc_func mc, int mv_x, int mv_y, + int *prev_dc, int is_intra, int mc_type, + uint32_t quant, int offs, + AVCodecContext *avctx) +{ + const uint16_t *base_tab = is_intra ? band->intra_base : band->inter_base; + RVMapDesc *rvmap = band->rv_map; + uint8_t col_flags[8]; + int32_t trvec[64]; + uint32_t sym = 0, lo, hi, q; + int pos, run, val; + int blk_size = band->blk_size; + int num_coeffs = blk_size * blk_size; + int col_mask = blk_size - 1; + int scan_pos = -1; + int min_size = band->pitch * (band->transform_size - 1) + + band->transform_size; + int buf_size = band->pitch * band->aheight - offs; + + if (min_size > buf_size) + return AVERROR_INVALIDDATA; + + if (!band->scan) { + av_log(avctx, AV_LOG_ERROR, "Scan pattern is not set.\n"); + return AVERROR_INVALIDDATA; + } + + /* zero transform vector */ + memset(trvec, 0, num_coeffs * sizeof(trvec[0])); + /* zero column flags */ + memset(col_flags, 0, sizeof(col_flags)); + while (scan_pos <= num_coeffs) { + sym = get_vlc2(gb, band->blk_vlc.tab->table, + IVI_VLC_BITS, 1); + if (sym == rvmap->eob_sym) + break; /* End of block */ + + /* Escape - run/val explicitly coded using 3 vlc codes */ + if (sym == rvmap->esc_sym) { + run = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1) + 1; + lo = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1); + hi = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1); + /* merge them and convert into signed val */ + val = IVI_TOSIGNED((hi << 6) | lo); + } else { + if (sym >= 256U) { + av_log(avctx, AV_LOG_ERROR, "Invalid sym encountered: %d.\n", sym); + return AVERROR_INVALIDDATA; + } + run = rvmap->runtab[sym]; + val = rvmap->valtab[sym]; + } + + /* de-zigzag and dequantize */ + scan_pos += run; + if (scan_pos >= num_coeffs || scan_pos < 0) + break; + pos = band->scan[scan_pos]; + + if (!val) + av_dlog(avctx, "Val = 0 encountered!\n"); + + q = (base_tab[pos] * quant) >> 9; + if (q > 1) + val = val * q + FFSIGN(val) * (((q ^ 1) - 1) >> 1); + trvec[pos] = val; + /* track columns containing non-zero coeffs */ + col_flags[pos & col_mask] |= !!val; + } + + if (scan_pos < 0 || scan_pos >= num_coeffs && sym != rvmap->eob_sym) + return AVERROR_INVALIDDATA; /* corrupt block data */ + + /* undoing DC coeff prediction for intra-blocks */ + if (is_intra && band->is_2d_trans) { + *prev_dc += trvec[0]; + trvec[0] = *prev_dc; + col_flags[0] |= !!*prev_dc; + } + + if(band->transform_size > band->blk_size){ + av_log(NULL, AV_LOG_ERROR, "Too large transform\n"); + return AVERROR_INVALIDDATA; + } + + /* apply inverse transform */ + band->inv_transform(trvec, band->buf + offs, + band->pitch, col_flags); + + /* apply motion compensation */ + if (!is_intra) + return ivi_mc(band, mc, offs, mv_x, mv_y, mc_type); + + return 0; +} /* * Decode block data: * extract huffman-coded transform coefficients from the bitstream, @@ -391,27 +572,22 @@ static int ivi_dec_tile_data_size(GetBitContext *gb) * @param[in] tile pointer to the tile descriptor * @return result code: 0 - OK, -1 = error (corrupted blocks data) */ -static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile, - AVCodecContext *avctx) +static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, + IVITile *tile, AVCodecContext *avctx) { - int mbn, blk, num_blocks, num_coeffs, blk_size, scan_pos, run, val, - pos, is_intra, mc_type = 0, av_uninit(mv_x), av_uninit(mv_y), col_mask; - uint8_t col_flags[8]; - int32_t prev_dc, trvec[64]; - uint32_t cbp, av_uninit(sym), lo, hi, quant, buf_offs, q; - IVIMbInfo *mb; - RVMapDesc *rvmap = band->rv_map; - void (*mc_with_delta_func)(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type); - void (*mc_no_delta_func) (int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type); - const uint16_t *base_tab; - const uint8_t *scale_tab; - - prev_dc = 0; /* init intra prediction for the DC coefficient */ - + int mbn, blk, num_blocks, blk_size, ret, is_intra, mc_type = 0; + int mv_x = 0, mv_y = 0; + int32_t prev_dc; + uint32_t cbp, quant, buf_offs; + IVIMbInfo *mb; + ivi_mc_func mc_with_delta_func, mc_no_delta_func; + const uint8_t *scale_tab; + + /* init intra prediction for the DC coefficient */ + prev_dc = 0; blk_size = band->blk_size; - col_mask = blk_size - 1; /* column mask for tracking non-zero coeffs */ - num_blocks = (band->mb_size != blk_size) ? 4 : 1; /* number of blocks per mb */ - num_coeffs = blk_size * blk_size; + /* number of blocks per mb */ + num_blocks = (band->mb_size != blk_size) ? 4 : 1; if (blk_size == 8) { mc_with_delta_func = ff_ivi_mc_8x8_delta; mc_no_delta_func = ff_ivi_mc_8x8_no_delta; @@ -425,9 +601,12 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile cbp = mb->cbp; buf_offs = mb->buf_offs; - quant = av_clip(band->glob_quant + mb->q_delta, 0, 23); + quant = band->glob_quant + mb->q_delta; + if (avctx->codec_id == AV_CODEC_ID_INDEO4) + quant = av_clip(quant, 0, 31); + else + quant = av_clip(quant, 0, 23); - base_tab = is_intra ? band->intra_base : band->inter_base; scale_tab = is_intra ? band->intra_scale : band->inter_scale; if (scale_tab) quant = scale_tab[quant]; @@ -448,10 +627,10 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile cx = mb->mv_x & band->is_halfpel; cy = mb->mv_y & band->is_halfpel; - if ( mb->xpos + dmv_x < 0 - || mb->xpos + dmv_x + band->mb_size + cx > band->pitch - || mb->ypos + dmv_y < 0 - || mb->ypos + dmv_y + band->mb_size + cy > band->aheight) { + if (mb->xpos + dmv_x < 0 || + mb->xpos + dmv_x + band->mb_size + cx > band->pitch || + mb->ypos + dmv_y < 0 || + mb->ypos + dmv_y + band->mb_size + cy > band->aheight) { return AVERROR_INVALIDDATA; } } @@ -467,83 +646,25 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile } if (cbp & 1) { /* block coded ? */ - if (!band->scan) { - av_log(avctx, AV_LOG_ERROR, "Scan pattern is not set.\n"); - return AVERROR_INVALIDDATA; - } - - scan_pos = -1; - memset(trvec, 0, num_coeffs*sizeof(trvec[0])); /* zero transform vector */ - memset(col_flags, 0, sizeof(col_flags)); /* zero column flags */ - - while (scan_pos <= num_coeffs) { - sym = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1); - if (sym == rvmap->eob_sym) - break; /* End of block */ - - if (sym == rvmap->esc_sym) { /* Escape - run/val explicitly coded using 3 vlc codes */ - run = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1) + 1; - lo = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1); - hi = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1); - val = IVI_TOSIGNED((hi << 6) | lo); /* merge them and convert into signed val */ - } else { - if (sym >= 256U) { - av_log(avctx, AV_LOG_ERROR, "Invalid sym encountered: %d.\n", sym); - return -1; - } - run = rvmap->runtab[sym]; - val = rvmap->valtab[sym]; - } - - /* de-zigzag and dequantize */ - scan_pos += run; - if (scan_pos >= (unsigned)num_coeffs) - break; - pos = band->scan[scan_pos]; - - if (!val) - av_dlog(avctx, "Val = 0 encountered!\n"); - - q = (base_tab[pos] * quant) >> 9; - if (q > 1) - val = val * q + FFSIGN(val) * (((q ^ 1) - 1) >> 1); - trvec[pos] = val; - col_flags[pos & col_mask] |= !!val; /* track columns containing non-zero coeffs */ - }// while - - if (scan_pos >= num_coeffs && sym != rvmap->eob_sym) - return -1; /* corrupt block data */ - - /* undoing DC coeff prediction for intra-blocks */ - if (is_intra && band->is_2d_trans) { - prev_dc += trvec[0]; - trvec[0] = prev_dc; - col_flags[0] |= !!prev_dc; - } - if(band->transform_size > band->blk_size){ - av_log(NULL, AV_LOG_ERROR, "Too large transform\n"); - return AVERROR_INVALIDDATA; - } - /* apply inverse transform */ - band->inv_transform(trvec, band->buf + buf_offs, - band->pitch, col_flags); - - /* apply motion compensation */ - if (!is_intra) - mc_with_delta_func(band->buf + buf_offs, - band->ref_buf + buf_offs + mv_y * band->pitch + mv_x, - band->pitch, mc_type); + ret = ivi_decode_coded_blocks(gb, band, mc_with_delta_func, + mv_x, mv_y, &prev_dc, is_intra, + mc_type, quant, buf_offs, avctx); + if (ret < 0) + return ret; } else { /* block not coded */ /* for intra blocks apply the dc slant transform */ /* for inter - perform the motion compensation without delta */ if (is_intra) { - band->dc_transform(&prev_dc, band->buf + buf_offs, - band->pitch, blk_size); - } else - mc_no_delta_func(band->buf + buf_offs, - band->ref_buf + buf_offs + mv_y * band->pitch + mv_x, - band->pitch, mc_type); + ret = ivi_dc_transform(band, &prev_dc, buf_offs, blk_size); + if (ret < 0) + return ret; + } else { + ret = ivi_mc(band, mc_no_delta_func, buf_offs, + mv_x, mv_y, mc_type); + if (ret < 0) + return ret; + } } cbp >>= 1; @@ -568,12 +689,11 @@ static int ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, IVITile *tile, int32_t mv_scale) { int x, y, need_mc, mbn, blk, num_blocks, mv_x, mv_y, mc_type; - int offs, mb_offset, row_offset; + int offs, mb_offset, row_offset, ret; IVIMbInfo *mb, *ref_mb; const int16_t *src; int16_t *dst; - void (*mc_no_delta_func)(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, - int mc_type); + ivi_mc_func mc_no_delta_func; if (tile->num_MBs != IVI_MBs_PER_TILE(tile->width, tile->height, band->mb_size)) { av_log(avctx, AV_LOG_ERROR, "Allocated tile size %d mismatches " @@ -663,9 +783,10 @@ static int ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, for (blk = 0; blk < num_blocks; blk++) { /* adjust block position in the buffer according with its number */ offs = mb->buf_offs + band->blk_size * ((blk & 1) + !!(blk & 2) * band->pitch); - mc_no_delta_func(band->buf + offs, - band->ref_buf + offs + mv_y * band->pitch + mv_x, - band->pitch, mc_type); + ret = ivi_mc(band, mc_no_delta_func, offs, + mv_x, mv_y, mc_type); + if (ret < 0) + return ret; } } } else { @@ -804,8 +925,16 @@ static int decode_band(IVI45DecContext *ctx, break; result = ivi_decode_blocks(&ctx->gb, band, tile, avctx); - if (result < 0 || ((get_bits_count(&ctx->gb) - pos) >> 3) != tile->data_size) { - av_log(avctx, AV_LOG_ERROR, "Corrupted tile data encountered!\n"); + if (result < 0) { + av_log(avctx, AV_LOG_ERROR, + "Corrupted tile data encountered!\n"); + break; + } + + if (((get_bits_count(&ctx->gb) - pos) >> 3) != tile->data_size) { + av_log(avctx, AV_LOG_ERROR, + "Tile data_size mismatch!\n"); + result = AVERROR_INVALIDDATA; break; } @@ -813,7 +942,8 @@ static int decode_band(IVI45DecContext *ctx, } } - /* restore the selected rvmap table by applying its corrections in reverse order */ + /* restore the selected rvmap table by applying its corrections in + * reverse order */ for (i = band->num_corr-1; i >= 0; i--) { idx1 = band->corr[i*2]; idx2 = band->corr[i*2+1]; @@ -830,7 +960,8 @@ static int decode_band(IVI45DecContext *ctx, uint16_t chksum = ivi_calc_band_checksum(band); if (chksum != band->checksum) { av_log(avctx, AV_LOG_ERROR, - "Band checksum mismatch! Plane %d, band %d, received: %x, calculated: %x\n", + "Band checksum mismatch! Plane %d, band %d, " + "received: %x, calculated: %x\n", band->plane, band->band_num, band->checksum, chksum); } } @@ -858,14 +989,19 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (result) { av_log(avctx, AV_LOG_ERROR, "Error while decoding picture header: %d\n", result); - return -1; + return result; } if (ctx->gop_invalid) return AVERROR_INVALIDDATA; if (ctx->gop_flags & IVI5_IS_PROTECTED) { - av_log(avctx, AV_LOG_ERROR, "Password-protected clip!\n"); - return -1; + avpriv_report_missing_feature(avctx, "Password-protected clip!\n"); + return AVERROR_PATCHWELCOME; + } + + if (!ctx->planes[0].bands) { + av_log(avctx, AV_LOG_ERROR, "Color planes not initialized yet\n"); + return AVERROR_INVALIDDATA; } ctx->switch_buffers(ctx); @@ -877,25 +1013,41 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, for (p = 0; p < 3; p++) { for (b = 0; b < ctx->planes[p].num_bands; b++) { result = decode_band(ctx, &ctx->planes[p].bands[b], avctx); - if (result) { + if (result < 0) { av_log(avctx, AV_LOG_ERROR, "Error while decoding band: %d, plane: %d\n", b, p); - return -1; + return result; } } } ctx->buf_invalid[ctx->dst_buf] = 0; + } else { + if (ctx->is_scalable) + return AVERROR_INVALIDDATA; + + for (p = 0; p < 3; p++) { + if (!ctx->planes[p].bands[0].buf) + return AVERROR_INVALIDDATA; + } } if (ctx->buf_invalid[ctx->dst_buf]) return -1; //STOP_TIMER("decode_planes"); } - /* If the bidirectional mode is enabled, next I and the following P frame will */ - /* be sent together. Unfortunately the approach below seems to be the only way */ - /* to handle the B-frames mode. That's exactly the same Intel decoders do. */ - if (avctx->codec_id == AV_CODEC_ID_INDEO4 && ctx->frame_type == 0/*FRAMETYPE_INTRA*/) { - while (get_bits(&ctx->gb, 8)); // skip version string + /* If the bidirectional mode is enabled, next I and the following P + * frame will be sent together. Unfortunately the approach below seems + * to be the only way to handle the B-frames mode. + * That's exactly the same Intel decoders do. + */ + if (avctx->codec_id == AV_CODEC_ID_INDEO4 && + ctx->frame_type == 0/*FRAMETYPE_INTRA*/) { + // skip version string + while (get_bits(&ctx->gb, 8)) { + if (get_bits_left(&ctx->gb) < 8) + return AVERROR_INVALIDDATA; + } + skip_bits_long(&ctx->gb, 64); // skip padding, TODO: implement correct 8-bytes alignment if (get_bits_left(&ctx->gb) > 18 && show_bits(&ctx->gb, 18) == 0x3FFF8) av_log(avctx, AV_LOG_ERROR, "Buffer contains IP frames!\n"); @@ -904,7 +1056,10 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (!ctx->is_nonnull_frame(ctx)) return buf_size; - avcodec_set_dimensions(avctx, ctx->planes[0].width, ctx->planes[0].height); + result = ff_set_dimensions(avctx, ctx->planes[0].width, ctx->planes[0].height); + if (result < 0) + return result; + if ((result = ff_get_buffer(avctx, frame, 0)) < 0) return result; @@ -958,35 +1113,6 @@ av_cold int ff_ivi_decode_close(AVCodecContext *avctx) } -/** - * These are 2x8 predefined Huffman codebooks for coding macroblock/block - * signals. They are specified using "huffman descriptors" in order to - * avoid huge static tables. The decoding tables will be generated at - * startup from these descriptors. - */ -const IVIHuffDesc ff_ivi_mb_huff_desc[8] = { - {8, {0, 4, 5, 4, 4, 4, 6, 6}}, - {12, {0, 2, 2, 3, 3, 3, 3, 5, 3, 2, 2, 2}}, - {12, {0, 2, 3, 4, 3, 3, 3, 3, 4, 3, 2, 2}}, - {12, {0, 3, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2}}, - {13, {0, 4, 4, 3, 3, 3, 3, 2, 3, 3, 2, 1, 1}}, - {9, {0, 4, 4, 4, 4, 3, 3, 3, 2}}, - {10, {0, 4, 4, 4, 4, 3, 3, 2, 2, 2}}, - {12, {0, 4, 4, 4, 3, 3, 2, 3, 2, 2, 2, 2}} -}; - -const IVIHuffDesc ff_ivi_blk_huff_desc[8] = { - {10, {1, 2, 3, 4, 4, 7, 5, 5, 4, 1}}, - {11, {2, 3, 4, 4, 4, 7, 5, 4, 3, 3, 2}}, - {12, {2, 4, 5, 5, 5, 5, 6, 4, 4, 3, 1, 1}}, - {13, {3, 3, 4, 4, 5, 6, 6, 4, 4, 3, 2, 1, 1}}, - {11, {3, 4, 4, 5, 5, 5, 6, 5, 4, 2, 2}}, - {13, {3, 4, 5, 5, 5, 5, 6, 4, 3, 3, 2, 1, 1}}, - {13, {3, 4, 5, 5, 5, 6, 5, 4, 3, 3, 2, 1, 1}}, - {9, {3, 4, 4, 5, 5, 5, 6, 5, 5}} -}; - - /** * Scan patterns shared between indeo4 and indeo5 */ diff --git a/ffmpeg/libavcodec/ivi_common.h b/ffmpeg/libavcodec/ivi_common.h index 130fd12..72ab54f 100644 --- a/ffmpeg/libavcodec/ivi_common.h +++ b/ffmpeg/libavcodec/ivi_common.h @@ -160,9 +160,9 @@ typedef struct IVIBandDesc { int num_tiles; ///< number of tiles in this band IVITile *tiles; ///< array of tile descriptors InvTransformPtr *inv_transform; + int transform_size; DCTransformPtr *dc_transform; int is_2d_trans; ///< 1 indicates that the two-dimensional inverse transform is used - int transform_size; ///< block size of the transform int32_t checksum; ///< for debug purposes int checksum_present; int bufsize; ///< band buffer size in bytes diff --git a/ffmpeg/libavcodec/ivi_dsp.c b/ffmpeg/libavcodec/ivi_dsp.c index 84e2436..f5e5e6b 100644 --- a/ffmpeg/libavcodec/ivi_dsp.c +++ b/ffmpeg/libavcodec/ivi_dsp.c @@ -258,12 +258,14 @@ void ff_ivi_recompose_haar(const IVIPlaneDesc *plane, uint8_t *dst, d8 = COMPENSATE(t8); } /** inverse 4-point Haar transform */ -#define INV_HAAR4(s1, s3, s5, s7) {\ - HAAR_BFLY(s1, s5); HAAR_BFLY(s1, s3); HAAR_BFLY(s5, s7);\ - s1 = COMPENSATE(s1);\ - s3 = COMPENSATE(s3);\ - s5 = COMPENSATE(s5);\ - s7 = COMPENSATE(s7); } +#define INV_HAAR4(s1, s3, s5, s7, d1, d2, d3, d4, t0, t1, t2, t3, t4) {\ + IVI_HAAR_BFLY(s1, s3, t0, t1, t4);\ + IVI_HAAR_BFLY(t0, s5, t2, t3, t4);\ + d1 = COMPENSATE(t2);\ + d2 = COMPENSATE(t3);\ + IVI_HAAR_BFLY(t1, s7, t2, t3, t4);\ + d3 = COMPENSATE(t2);\ + d4 = COMPENSATE(t3); } void ff_ivi_inverse_haar_8x8(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags) @@ -320,6 +322,153 @@ void ff_ivi_inverse_haar_8x8(const int32_t *in, int16_t *out, uint32_t pitch, #undef COMPENSATE } +void ff_ivi_row_haar8(const int32_t *in, int16_t *out, uint32_t pitch, + const uint8_t *flags) +{ + int i; + int t0, t1, t2, t3, t4, t5, t6, t7, t8; + + /* apply the InvHaar8 to all rows */ +#define COMPENSATE(x) (x) + for (i = 0; i < 8; i++) { + if ( !in[0] && !in[1] && !in[2] && !in[3] + && !in[4] && !in[5] && !in[6] && !in[7]) { + memset(out, 0, 8 * sizeof(out[0])); + } else { + INV_HAAR8(in[0], in[1], in[2], in[3], + in[4], in[5], in[6], in[7], + out[0], out[1], out[2], out[3], + out[4], out[5], out[6], out[7], + t0, t1, t2, t3, t4, t5, t6, t7, t8); + } + in += 8; + out += pitch; + } +#undef COMPENSATE +} + +void ff_ivi_col_haar8(const int32_t *in, int16_t *out, uint32_t pitch, + const uint8_t *flags) +{ + int i; + int t0, t1, t2, t3, t4, t5, t6, t7, t8; + + /* apply the InvHaar8 to all columns */ +#define COMPENSATE(x) (x) + for (i = 0; i < 8; i++) { + if (flags[i]) { + INV_HAAR8(in[ 0], in[ 8], in[16], in[24], + in[32], in[40], in[48], in[56], + out[0 * pitch], out[1 * pitch], + out[2 * pitch], out[3 * pitch], + out[4 * pitch], out[5 * pitch], + out[6 * pitch], out[7 * pitch], + t0, t1, t2, t3, t4, t5, t6, t7, t8); + } else + out[0 * pitch] = out[1 * pitch] = + out[2 * pitch] = out[3 * pitch] = + out[4 * pitch] = out[5 * pitch] = + out[6 * pitch] = out[7 * pitch] = 0; + + in++; + out++; + } +#undef COMPENSATE +} + +void ff_ivi_inverse_haar_4x4(const int32_t *in, int16_t *out, uint32_t pitch, + const uint8_t *flags) +{ + int i, shift, sp1, sp2; + const int32_t *src; + int32_t *dst; + int tmp[16]; + int t0, t1, t2, t3, t4; + + /* apply the InvHaar4 to all columns */ +#define COMPENSATE(x) (x) + src = in; + dst = tmp; + for (i = 0; i < 4; i++) { + if (flags[i]) { + /* pre-scaling */ + shift = !(i & 2); + sp1 = src[0] << shift; + sp2 = src[4] << shift; + INV_HAAR4( sp1, sp2, src[8], src[12], + dst[0], dst[4], dst[8], dst[12], + t0, t1, t2, t3, t4); + } else + dst[0] = dst[4] = dst[8] = dst[12] = 0; + + src++; + dst++; + } +#undef COMPENSATE + + /* apply the InvHaar8 to all rows */ +#define COMPENSATE(x) (x) + src = tmp; + for (i = 0; i < 4; i++) { + if (!src[0] && !src[1] && !src[2] && !src[3]) { + memset(out, 0, 4 * sizeof(out[0])); + } else { + INV_HAAR4(src[0], src[1], src[2], src[3], + out[0], out[1], out[2], out[3], + t0, t1, t2, t3, t4); + } + src += 4; + out += pitch; + } +#undef COMPENSATE +} + +void ff_ivi_row_haar4(const int32_t *in, int16_t *out, uint32_t pitch, + const uint8_t *flags) +{ + int i; + int t0, t1, t2, t3, t4; + + /* apply the InvHaar4 to all rows */ +#define COMPENSATE(x) (x) + for (i = 0; i < 4; i++) { + if (!in[0] && !in[1] && !in[2] && !in[3]) { + memset(out, 0, 4 * sizeof(out[0])); + } else { + INV_HAAR4(in[0], in[1], in[2], in[3], + out[0], out[1], out[2], out[3], + t0, t1, t2, t3, t4); + } + in += 4; + out += pitch; + } +#undef COMPENSATE +} + +void ff_ivi_col_haar4(const int32_t *in, int16_t *out, uint32_t pitch, + const uint8_t *flags) +{ + int i; + int t0, t1, t2, t3, t4; + + /* apply the InvHaar8 to all columns */ +#define COMPENSATE(x) (x) + for (i = 0; i < 4; i++) { + if (flags[i]) { + INV_HAAR4(in[0], in[4], in[8], in[12], + out[0 * pitch], out[1 * pitch], + out[2 * pitch], out[3 * pitch], + t0, t1, t2, t3, t4); + } else + out[0 * pitch] = out[1 * pitch] = + out[2 * pitch] = out[3 * pitch] = 0; + + in++; + out++; + } +#undef COMPENSATE +} + void ff_ivi_dc_haar_2d(const int32_t *in, int16_t *out, uint32_t pitch, int blk_size) { @@ -556,6 +705,49 @@ void ff_ivi_dc_col_slant(const int32_t *in, int16_t *out, uint32_t pitch, int bl } } +void ff_ivi_row_slant4(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags) +{ + int i; + int t0, t1, t2, t3, t4; + +#define COMPENSATE(x) ((x + 1)>>1) + for (i = 0; i < 4; i++) { + if (!in[0] && !in[1] && !in[2] && !in[3]) { + memset(out, 0, 4*sizeof(out[0])); + } else { + IVI_INV_SLANT4( in[0], in[1], in[2], in[3], + out[0], out[1], out[2], out[3], + t0, t1, t2, t3, t4); + } + in += 4; + out += pitch; + } +#undef COMPENSATE +} + +void ff_ivi_col_slant4(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags) +{ + int i, row2; + int t0, t1, t2, t3, t4; + + row2 = pitch << 1; + +#define COMPENSATE(x) ((x + 1)>>1) + for (i = 0; i < 4; i++) { + if (flags[i]) { + IVI_INV_SLANT4(in[0], in[4], in[8], in[12], + out[0], out[pitch], out[row2], out[row2 + pitch], + t0, t1, t2, t3, t4); + } else { + out[0] = out[pitch] = out[row2] = out[row2 + pitch] = 0; + } + + in++; + out++; + } +#undef COMPENSATE +} + void ff_ivi_put_pixels_8x8(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags) { diff --git a/ffmpeg/libavcodec/ivi_dsp.h b/ffmpeg/libavcodec/ivi_dsp.h index e95bb11..245f01d 100644 --- a/ffmpeg/libavcodec/ivi_dsp.h +++ b/ffmpeg/libavcodec/ivi_dsp.h @@ -64,6 +64,75 @@ void ff_ivi_recompose_haar(const IVIPlaneDesc *plane, uint8_t *dst, */ void ff_ivi_inverse_haar_8x8(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags); +void ff_ivi_inverse_haar_8x1(const int32_t *in, int16_t *out, uint32_t pitch, + const uint8_t *flags); +void ff_ivi_inverse_haar_1x8(const int32_t *in, int16_t *out, uint32_t pitch, + const uint8_t *flags); + +/** + * one-dimensional inverse 8-point Haar transform on rows for Indeo 4 + * + * @param[in] in pointer to the vector of transform coefficients + * @param[out] out pointer to the output buffer (frame) + * @param[in] pitch pitch to move to the next y line + * @param[in] flags pointer to the array of column flags: + * != 0 - non_empty column, 0 - empty one + * (this array must be filled by caller) + */ +void ff_ivi_row_haar8(const int32_t *in, int16_t *out, uint32_t pitch, + const uint8_t *flags); + +/** + * one-dimensional inverse 8-point Haar transform on columns for Indeo 4 + * + * @param[in] in pointer to the vector of transform coefficients + * @param[out] out pointer to the output buffer (frame) + * @param[in] pitch pitch to move to the next y line + * @param[in] flags pointer to the array of column flags: + * != 0 - non_empty column, 0 - empty one + * (this array must be filled by caller) + */ +void ff_ivi_col_haar8(const int32_t *in, int16_t *out, uint32_t pitch, + const uint8_t *flags); + +/** + * two-dimensional inverse Haar 4x4 transform for Indeo 4 + * + * @param[in] in pointer to the vector of transform coefficients + * @param[out] out pointer to the output buffer (frame) + * @param[in] pitch pitch to move to the next y line + * @param[in] flags pointer to the array of column flags: + * != 0 - non_empty column, 0 - empty one + * (this array must be filled by caller) + */ +void ff_ivi_inverse_haar_4x4(const int32_t *in, int16_t *out, uint32_t pitch, + const uint8_t *flags); + +/** + * one-dimensional inverse 4-point Haar transform on rows for Indeo 4 + * + * @param[in] in pointer to the vector of transform coefficients + * @param[out] out pointer to the output buffer (frame) + * @param[in] pitch pitch to move to the next y line + * @param[in] flags pointer to the array of column flags: + * != 0 - non_empty column, 0 - empty one + * (this array must be filled by caller) + */ +void ff_ivi_row_haar4(const int32_t *in, int16_t *out, uint32_t pitch, + const uint8_t *flags); + +/** + * one-dimensional inverse 4-point Haar transform on columns for Indeo 4 + * + * @param[in] in pointer to the vector of transform coefficients + * @param[out] out pointer to the output buffer (frame) + * @param[in] pitch pitch to move to the next y line + * @param[in] flags pointer to the array of column flags: + * != 0 - non_empty column, 0 - empty one + * (this array must be filled by caller) + */ +void ff_ivi_col_haar4(const int32_t *in, int16_t *out, uint32_t pitch, + const uint8_t *flags); /** * DC-only two-dimensional inverse Haar transform for Indeo 4. @@ -141,6 +210,30 @@ void ff_ivi_row_slant8(const int32_t *in, int16_t *out, uint32_t pitch, void ff_ivi_col_slant8(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags); +/** + * inverse 1D row slant transform + * + * @param[in] in pointer to the vector of transform coefficients + * @param[out] out pointer to the output buffer (frame) + * @param[in] pitch pitch to move to the next y line + * @param[in] flags pointer to the array of column flags (unused here) + */ +void ff_ivi_row_slant4(const int32_t *in, int16_t *out, uint32_t pitch, + const uint8_t *flags); + +/** + * inverse 1D column slant transform + * + * @param[in] in pointer to the vector of transform coefficients + * @param[out] out pointer to the output buffer (frame) + * @param[in] pitch pitch to move to the next y line + * @param[in] flags pointer to the array of column flags: + * != 0 - non_empty column, 0 - empty one + * (this array must be filled by caller) + */ +void ff_ivi_col_slant4(const int32_t *in, int16_t *out, uint32_t pitch, + const uint8_t *flags); + /** * DC-only inverse row slant transform */ diff --git a/ffmpeg/libavcodec/j2k.c b/ffmpeg/libavcodec/j2k.c deleted file mode 100644 index e3c0c13..0000000 --- a/ffmpeg/libavcodec/j2k.c +++ /dev/null @@ -1,391 +0,0 @@ -/* - * JPEG2000 encoder and decoder common functions - * Copyright (c) 2007 Kamil Nowosad - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * JPEG2000 image encoder and decoder common functions - * @file - * @author Kamil Nowosad - */ - - -#include "avcodec.h" -#include "j2k.h" - -#define SHL(a, n) ((n)>=0 ? (a) << (n) : (a) >> -(n)) - -#if 0 -void ff_j2k_printv(int *tab, int l) -{ - int i; - for (i = 0; i < l; i++) - av_log(NULL, AV_LOG_DEBUG, "%.3d ", tab[i]); - av_log(NULL, AV_LOG_DEBUG, "\n"); -} - -void ff_j2k_printu(uint8_t *tab, int l) -{ - int i; - for (i = 0; i < l; i++) - av_log(NULL, AV_LOG_DEBUG, "%.3hd ", tab[i]); - av_log(NULL, AV_LOG_DEBUG, "\n"); -} -#endif - -/* tag tree routines */ - -/** allocate the memory for tag tree */ - -static int tag_tree_size(int w, int h) -{ - int res = 0; - while (w > 1 || h > 1){ - res += w * h; - w = (w+1) >> 1; - h = (h+1) >> 1; - } - return res + 1; -} - -J2kTgtNode *ff_j2k_tag_tree_init(int w, int h) -{ - int pw = w, ph = h; - J2kTgtNode *res, *t, *t2; - - t = res = av_mallocz(tag_tree_size(w, h)*sizeof(J2kTgtNode)); - - if (res == NULL) - return NULL; - - while (w > 1 || h > 1){ - int i, j; - pw = w; - ph = h; - - w = (w+1) >> 1; - h = (h+1) >> 1; - t2 = t + pw*ph; - - for (i = 0; i < ph; i++) - for (j = 0; j < pw; j++){ - t[i*pw + j].parent = &t2[(i>>1)*w + (j>>1)]; - } - t = t2; - } - t[0].parent = NULL; - return res; -} - -static void tag_tree_zero(J2kTgtNode *t, int w, int h) -{ - int i, siz = tag_tree_size(w, h); - - for (i = 0; i < siz; i++){ - t[i].val = 0; - t[i].vis = 0; - } -} - -uint8_t ff_j2k_nbctxno_lut[256][4]; - -static int getnbctxno(int flag, int bandno, int vert_causal_ctx_csty_symbol) -{ - int h, v, d; - - h = ((flag & J2K_T1_SIG_E) ? 1:0)+ - ((flag & J2K_T1_SIG_W) ? 1:0); - v = ((flag & J2K_T1_SIG_N) ? 1:0); - if (!vert_causal_ctx_csty_symbol) - v = v + ((flag & J2K_T1_SIG_S) ? 1:0); - d = ((flag & J2K_T1_SIG_NE) ? 1:0)+ - ((flag & J2K_T1_SIG_NW) ? 1:0); - if (!vert_causal_ctx_csty_symbol) - d = d + ((flag & J2K_T1_SIG_SE) ? 1:0)+ - ((flag & J2K_T1_SIG_SW) ? 1:0); - if (bandno < 3){ - if (bandno == 1) - FFSWAP(int, h, v); - if (h == 2) return 8; - if (h == 1){ - if (v >= 1) return 7; - if (d >= 1) return 6; - return 5; - } - if (v == 2) return 4; - if (v == 1) return 3; - if (d >= 2) return 2; - if (d == 1) return 1; - return 0; - } else{ - if (d >= 3) return 8; - if (d == 2){ - if (h+v >= 1) return 7; - return 6; - } - if (d == 1){ - if (h+v >= 2) return 5; - if (h+v == 1) return 4; - return 3; - } - if (h+v >= 2) return 2; - if (h+v == 1) return 1; - return 0; - } -} - -uint8_t ff_j2k_sgnctxno_lut[16][16], ff_j2k_xorbit_lut[16][16]; - -static int getsgnctxno(int flag, uint8_t *xorbit) -{ - int vcontrib, hcontrib; - static const int contribtab[3][3] = {{0, -1, 1}, {-1, -1, 0}, {1, 0, 1}}; - static const int ctxlbltab[3][3] = {{13, 12, 11}, {10, 9, 10}, {11, 12, 13}}; - static const int xorbittab[3][3] = {{1, 1, 1,}, {1, 0, 0}, {0, 0, 0}}; - - hcontrib = contribtab[flag & J2K_T1_SIG_E ? flag & J2K_T1_SGN_E ? 1:2:0] - [flag & J2K_T1_SIG_W ? flag & J2K_T1_SGN_W ? 1:2:0]+1; - vcontrib = contribtab[flag & J2K_T1_SIG_S ? flag & J2K_T1_SGN_S ? 1:2:0] - [flag & J2K_T1_SIG_N ? flag & J2K_T1_SGN_N ? 1:2:0]+1; - *xorbit = xorbittab[hcontrib][vcontrib]; - return ctxlbltab[hcontrib][vcontrib]; -} - -void ff_j2k_init_tier1_luts(void) -{ - int i, j; - for (i = 0; i < 256; i++) - for (j = 0; j < 4; j++) - ff_j2k_nbctxno_lut[i][j] = getnbctxno(i, j, 0); - for (i = 0; i < 16; i++) - for (j = 0; j < 16; j++) - ff_j2k_sgnctxno_lut[i][j] = getsgnctxno(i + (j << 8), &ff_j2k_xorbit_lut[i][j]); -} - -void ff_j2k_set_significant(J2kT1Context *t1, int x, int y, int negative) -{ - x++; y++; - t1->flags[y][x] |= J2K_T1_SIG; - if (negative){ - t1->flags[y][x+1] |= J2K_T1_SIG_W | J2K_T1_SGN_W; - t1->flags[y][x-1] |= J2K_T1_SIG_E | J2K_T1_SGN_E; - t1->flags[y+1][x] |= J2K_T1_SIG_N | J2K_T1_SGN_N; - t1->flags[y-1][x] |= J2K_T1_SIG_S | J2K_T1_SGN_S; - } else{ - t1->flags[y][x+1] |= J2K_T1_SIG_W; - t1->flags[y][x-1] |= J2K_T1_SIG_E; - t1->flags[y+1][x] |= J2K_T1_SIG_N; - t1->flags[y-1][x] |= J2K_T1_SIG_S; - } - t1->flags[y+1][x+1] |= J2K_T1_SIG_NW; - t1->flags[y+1][x-1] |= J2K_T1_SIG_NE; - t1->flags[y-1][x+1] |= J2K_T1_SIG_SW; - t1->flags[y-1][x-1] |= J2K_T1_SIG_SE; -} - -int ff_j2k_init_component(J2kComponent *comp, J2kCodingStyle *codsty, J2kQuantStyle *qntsty, int cbps, int dx, int dy) -{ - int reslevelno, bandno, gbandno = 0, ret, i, j, csize = 1; - - if (ret=ff_j2k_dwt_init(&comp->dwt, comp->coord, codsty->nreslevels-1, codsty->transform)) - return ret; - for (i = 0; i < 2; i++) - csize *= comp->coord[i][1] - comp->coord[i][0]; - - comp->data = av_malloc(csize * sizeof(int)); - if (!comp->data) - return AVERROR(ENOMEM); - comp->reslevel = av_malloc(codsty->nreslevels * sizeof(J2kResLevel)); - - if (!comp->reslevel) - return AVERROR(ENOMEM); - for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ - int declvl = codsty->nreslevels - reslevelno; - J2kResLevel *reslevel = comp->reslevel + reslevelno; - - for (i = 0; i < 2; i++) - for (j = 0; j < 2; j++) - reslevel->coord[i][j] = - ff_j2k_ceildivpow2(comp->coord[i][j], declvl - 1); - - if (reslevelno == 0) - reslevel->nbands = 1; - else - reslevel->nbands = 3; - - if (reslevel->coord[0][1] == reslevel->coord[0][0]) - reslevel->num_precincts_x = 0; - else - reslevel->num_precincts_x = ff_j2k_ceildivpow2(reslevel->coord[0][1], codsty->log2_prec_width) - - (reslevel->coord[0][0] >> codsty->log2_prec_width); - - if (reslevel->coord[1][1] == reslevel->coord[1][0]) - reslevel->num_precincts_y = 0; - else - reslevel->num_precincts_y = ff_j2k_ceildivpow2(reslevel->coord[1][1], codsty->log2_prec_height) - - (reslevel->coord[1][0] >> codsty->log2_prec_height); - - reslevel->band = av_malloc(reslevel->nbands * sizeof(J2kBand)); - if (!reslevel->band) - return AVERROR(ENOMEM); - for (bandno = 0; bandno < reslevel->nbands; bandno++, gbandno++){ - J2kBand *band = reslevel->band + bandno; - int cblkno, precx, precy, precno; - int x0, y0, x1, y1; - int xi0, yi0, xi1, yi1; - int cblkperprecw, cblkperprech; - - if (qntsty->quantsty != J2K_QSTY_NONE){ - static const uint8_t lut_gain[2][4] = {{0, 0, 0, 0}, {0, 1, 1, 2}}; - int numbps; - - numbps = cbps + lut_gain[codsty->transform][bandno + reslevelno>0]; - band->stepsize = SHL(2048 + qntsty->mant[gbandno], 2 + numbps - qntsty->expn[gbandno]); - } else - band->stepsize = 1 << 13; - - if (reslevelno == 0){ // the same everywhere - band->codeblock_width = 1 << FFMIN(codsty->log2_cblk_width, codsty->log2_prec_width-1); - band->codeblock_height = 1 << FFMIN(codsty->log2_cblk_height, codsty->log2_prec_height-1); - for (i = 0; i < 2; i++) - for (j = 0; j < 2; j++) - band->coord[i][j] = ff_j2k_ceildivpow2(comp->coord[i][j], declvl-1); - } else{ - band->codeblock_width = 1 << FFMIN(codsty->log2_cblk_width, codsty->log2_prec_width); - band->codeblock_height = 1 << FFMIN(codsty->log2_cblk_height, codsty->log2_prec_height); - - for (i = 0; i < 2; i++) - for (j = 0; j < 2; j++) - band->coord[i][j] = ff_j2k_ceildivpow2(comp->coord[i][j] - (((bandno+1>>i)&1) << declvl-1), declvl); - } - band->cblknx = ff_j2k_ceildiv(band->coord[0][1], band->codeblock_width) - band->coord[0][0] / band->codeblock_width; - band->cblkny = ff_j2k_ceildiv(band->coord[1][1], band->codeblock_height) - band->coord[1][0] / band->codeblock_height; - - for (j = 0; j < 2; j++) - band->coord[0][j] = ff_j2k_ceildiv(band->coord[0][j], dx); - for (j = 0; j < 2; j++) - band->coord[1][j] = ff_j2k_ceildiv(band->coord[1][j], dy); - - band->cblknx = ff_j2k_ceildiv(band->cblknx, dx); - band->cblkny = ff_j2k_ceildiv(band->cblkny, dy); - - band->cblk = av_malloc(sizeof(J2kCblk) * band->cblknx * band->cblkny); - if (!band->cblk) - return AVERROR(ENOMEM); - band->prec = av_malloc(sizeof(J2kCblk) * reslevel->num_precincts_x * reslevel->num_precincts_y); - if (!band->prec) - return AVERROR(ENOMEM); - - for (cblkno = 0; cblkno < band->cblknx * band->cblkny; cblkno++){ - J2kCblk *cblk = band->cblk + cblkno; - cblk->zero = 0; - cblk->lblock = 3; - cblk->length = 0; - cblk->lengthinc = 0; - cblk->npasses = 0; - } - - y0 = band->coord[1][0]; - y1 = ((band->coord[1][0] + (1<log2_prec_height)) & ~((1<log2_prec_height)-1)) - y0; - yi0 = 0; - yi1 = ff_j2k_ceildivpow2(y1 - y0, codsty->log2_cblk_height) << codsty->log2_cblk_height; - yi1 = FFMIN(yi1, band->cblkny); - cblkperprech = 1<<(codsty->log2_prec_height - codsty->log2_cblk_height); - for (precy = 0, precno = 0; precy < reslevel->num_precincts_y; precy++){ - for (precx = 0; precx < reslevel->num_precincts_x; precx++, precno++){ - band->prec[precno].yi0 = yi0; - band->prec[precno].yi1 = yi1; - } - yi1 += cblkperprech; - yi0 = yi1 - cblkperprech; - yi1 = FFMIN(yi1, band->cblkny); - } - x0 = band->coord[0][0]; - x1 = ((band->coord[0][0] + (1<log2_prec_width)) & ~((1<log2_prec_width)-1)) - x0; - xi0 = 0; - xi1 = ff_j2k_ceildivpow2(x1 - x0, codsty->log2_cblk_width) << codsty->log2_cblk_width; - xi1 = FFMIN(xi1, band->cblknx); - - cblkperprecw = 1<<(codsty->log2_prec_width - codsty->log2_cblk_width); - for (precx = 0, precno = 0; precx < reslevel->num_precincts_x; precx++){ - for (precy = 0; precy < reslevel->num_precincts_y; precy++, precno = 0){ - J2kPrec *prec = band->prec + precno; - prec->xi0 = xi0; - prec->xi1 = xi1; - prec->cblkincl = ff_j2k_tag_tree_init(prec->xi1 - prec->xi0, - prec->yi1 - prec->yi0); - prec->zerobits = ff_j2k_tag_tree_init(prec->xi1 - prec->xi0, - prec->yi1 - prec->yi0); - if (!prec->cblkincl || !prec->zerobits) - return AVERROR(ENOMEM); - - } - xi1 += cblkperprecw; - xi0 = xi1 - cblkperprecw; - xi1 = FFMIN(xi1, band->cblknx); - } - } - } - return 0; -} - -void ff_j2k_reinit(J2kComponent *comp, J2kCodingStyle *codsty) -{ - int reslevelno, bandno, cblkno, precno; - for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ - J2kResLevel *rlevel = comp->reslevel + reslevelno; - for (bandno = 0; bandno < rlevel->nbands; bandno++){ - J2kBand *band = rlevel->band + bandno; - for(precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++){ - J2kPrec *prec = band->prec + precno; - tag_tree_zero(prec->zerobits, prec->xi1 - prec->xi0, prec->yi1 - prec->yi0); - tag_tree_zero(prec->cblkincl, prec->xi1 - prec->xi0, prec->yi1 - prec->yi0); - } - for (cblkno = 0; cblkno < band->cblknx * band->cblkny; cblkno++){ - J2kCblk *cblk = band->cblk + cblkno; - cblk->length = 0; - cblk->lblock = 3; - } - } - } -} - -void ff_j2k_cleanup(J2kComponent *comp, J2kCodingStyle *codsty) -{ - int reslevelno, bandno, precno; - for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ - J2kResLevel *reslevel = comp->reslevel + reslevelno; - - for (bandno = 0; bandno < reslevel->nbands ; bandno++){ - J2kBand *band = reslevel->band + bandno; - for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){ - J2kPrec *prec = band->prec + precno; - av_freep(&prec->zerobits); - av_freep(&prec->cblkincl); - } - av_freep(&band->cblk); - av_freep(&band->prec); - } - av_freep(&reslevel->band); - } - - ff_j2k_dwt_destroy(&comp->dwt); - av_freep(&comp->reslevel); - av_freep(&comp->data); -} diff --git a/ffmpeg/libavcodec/j2k.h b/ffmpeg/libavcodec/j2k.h deleted file mode 100644 index 85d5cd0..0000000 --- a/ffmpeg/libavcodec/j2k.h +++ /dev/null @@ -1,234 +0,0 @@ -/* - * JPEG2000 tables - * Copyright (c) 2007 Kamil Nowosad - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_J2K_H -#define AVCODEC_J2K_H - -/** - * JPEG2000 tables - * @file - * @author Kamil Nowosad - */ - -#include "mqc.h" -#include "j2k_dwt.h" - -enum J2kMarkers{ - J2K_SOC = 0xff4f, ///< start of codestream - J2K_SIZ = 0xff51, ///< image and tile size - J2K_COD, ///< coding style default - J2K_COC, ///< coding style component - J2K_TLM = 0xff55, ///< packed packet headers, tile-part header - J2K_PLM = 0xff57, ///< tile-part lengths - J2K_PLT, ///< packet length, main header - J2K_QCD = 0xff5c, ///< quantization default - J2K_QCC, ///< quantization component - J2K_RGN, ///< region of interest - J2K_POC, ///< progression order change - J2K_PPM, ///< packet length, tile-part header - J2K_PPT, ///< packed packet headers, main header - J2K_CRG = 0xff63, ///< component registration - J2K_COM, ///< comment - J2K_SOT = 0xff90, ///< start of tile-part - J2K_SOP, ///< start of packet - J2K_EPH, ///< end of packet header - J2K_SOD, ///< start of data - J2K_EOC = 0xffd9, ///< end of codestream -}; - -enum J2kQuantsty{ ///< quantization style - J2K_QSTY_NONE, ///< no quantization - J2K_QSTY_SI, ///< scalar derived - J2K_QSTY_SE ///< scalar expoounded -}; - -#define J2K_MAX_CBLKW 64 -#define J2K_MAX_CBLKH 64 - -// T1 flags -// flags determining significance of neighbour coefficients -#define J2K_T1_SIG_N 0x0001 -#define J2K_T1_SIG_E 0x0002 -#define J2K_T1_SIG_W 0x0004 -#define J2K_T1_SIG_S 0x0008 -#define J2K_T1_SIG_NE 0x0010 -#define J2K_T1_SIG_NW 0x0020 -#define J2K_T1_SIG_SE 0x0040 -#define J2K_T1_SIG_SW 0x0080 -#define J2K_T1_SIG_NB (J2K_T1_SIG_N | J2K_T1_SIG_E | J2K_T1_SIG_S | J2K_T1_SIG_W \ - |J2K_T1_SIG_NE | J2K_T1_SIG_NW | J2K_T1_SIG_SE | J2K_T1_SIG_SW) -// flags determining sign bit of neighbour coefficients -#define J2K_T1_SGN_N 0x0100 -#define J2K_T1_SGN_S 0x0200 -#define J2K_T1_SGN_W 0x0400 -#define J2K_T1_SGN_E 0x0800 - -#define J2K_T1_VIS 0x1000 -#define J2K_T1_SIG 0x2000 -#define J2K_T1_REF 0x4000 - -#define J2K_T1_SGN 0x8000 - -// Codeblock coding styles -#define J2K_CBLK_BYPASS 0x01 // Selective arithmetic coding bypass -#define J2K_CBLK_RESET 0x02 // Reset context probabilities -#define J2K_CBLK_TERMALL 0x04 // Terminate after each coding pass -#define J2K_CBLK_VSC 0x08 // Vertical stripe causal context formation -#define J2K_CBLK_PREDTERM 0x10 // Predictable termination -#define J2K_CBLK_SEGSYM 0x20 // Segmentation symbols present - -// Coding styles -#define J2K_CSTY_PREC 0x01 // Precincts defined in coding style -#define J2K_CSTY_SOP 0x02 // SOP marker present -#define J2K_CSTY_EPH 0x04 // EPH marker present - -typedef struct { - int data[J2K_MAX_CBLKW][J2K_MAX_CBLKH]; - int flags[J2K_MAX_CBLKW+2][J2K_MAX_CBLKH+2]; - MqcState mqc; -} J2kT1Context; - -typedef struct J2kTgtNode { - uint8_t val; - uint8_t vis; - struct J2kTgtNode *parent; -} J2kTgtNode; - -typedef struct { - uint8_t nreslevels; ///< number of resolution levels - uint8_t log2_cblk_width, - log2_cblk_height; ///< exponent of codeblock size - uint8_t transform; ///< DWT type - uint8_t csty; ///< coding style - uint8_t log2_prec_width, - log2_prec_height; ///< precinct size - uint8_t nlayers; ///< number of layers - uint8_t mct; ///< multiple component transformation - uint8_t cblk_style; ///< codeblock coding style -} J2kCodingStyle; - -typedef struct { - uint8_t expn[32 * 3]; ///< quantization exponent - uint16_t mant[32 * 3]; ///< quantization mantissa - uint8_t quantsty; ///< quantization style - uint8_t nguardbits; ///< number of guard bits -} J2kQuantStyle; - -typedef struct { - uint16_t rate; - int64_t disto; -} J2kPass; - -typedef struct { - uint8_t npasses; - uint8_t ninclpasses; ///< number coding of passes included in codestream - uint8_t nonzerobits; - uint16_t length; - uint16_t lengthinc; - uint8_t lblock; - uint8_t zero; - uint8_t data[8192]; - J2kPass passes[100]; -} J2kCblk; ///< code block - -typedef struct { - uint16_t xi0, xi1, yi0, yi1; ///< codeblock indexes ([xi0, xi1)) - J2kTgtNode *zerobits; - J2kTgtNode *cblkincl; -} J2kPrec; ///< precinct - -typedef struct { - uint16_t coord[2][2]; ///< border coordinates {{x0, x1}, {y0, y1}} - uint16_t codeblock_width, codeblock_height; - uint16_t cblknx, cblkny; - uint32_t stepsize; ///< quantization stepsize (* 2^13) - J2kPrec *prec; - J2kCblk *cblk; -} J2kBand; ///< subband - -typedef struct { - uint8_t nbands; - uint16_t coord[2][2]; ///< border coordinates {{x0, x1}, {y0, y1}} - uint16_t num_precincts_x, num_precincts_y; ///< number of precincts in x/y direction - uint8_t log2_prec_width, log2_prec_height; ///< exponent of precinct size - J2kBand *band; -} J2kResLevel; ///< resolution level - -typedef struct { - J2kResLevel *reslevel; - DWTContext dwt; - int *data; - uint16_t coord[2][2]; ///< border coordinates {{x0, x1}, {y0, y1}} -} J2kComponent; - -/* debug routines */ -#if 0 -#undef fprintf -#undef printf -void ff_j2k_printv(int *tab, int l); -void ff_j2k_printu(uint8_t *tab, int l); -#endif - -/* misc tools */ -static inline int ff_j2k_ceildivpow2(int a, int b) -{ - return (a + (1 << b) - 1)>> b; -} - -static inline int ff_j2k_ceildiv(int a, int b) -{ - return (a + b - 1) / b; -} - -/* tag tree routines */ -J2kTgtNode *ff_j2k_tag_tree_init(int w, int h); - -/* TIER-1 routines */ -void ff_j2k_init_tier1_luts(void); - -void ff_j2k_set_significant(J2kT1Context *t1, int x, int y, int negative); - -extern uint8_t ff_j2k_nbctxno_lut[256][4]; - -static inline int ff_j2k_getnbctxno(int flag, int bandno, int vert_causal_ctx_csty_symbol) -{ - return ff_j2k_nbctxno_lut[flag&255][bandno]; -} - -static inline int ff_j2k_getrefctxno(int flag) -{ - static const uint8_t refctxno_lut[2][2] = {{14, 15}, {16, 16}}; - return refctxno_lut[(flag>>14)&1][(flag & 255) != 0]; -} - -extern uint8_t ff_j2k_sgnctxno_lut[16][16], ff_j2k_xorbit_lut[16][16]; - -static inline int ff_j2k_getsgnctxno(int flag, int *xorbit) -{ - *xorbit = ff_j2k_xorbit_lut[flag&15][(flag>>8)&15]; - return ff_j2k_sgnctxno_lut[flag&15][(flag>>8)&15]; -} - -int ff_j2k_init_component(J2kComponent *comp, J2kCodingStyle *codsty, J2kQuantStyle *qntsty, int cbps, int dx, int dy); -void ff_j2k_reinit(J2kComponent *comp, J2kCodingStyle *codsty); -void ff_j2k_cleanup(J2kComponent *comp, J2kCodingStyle *codsty); - -#endif /* AVCODEC_J2K_H */ diff --git a/ffmpeg/libavcodec/j2k_dwt.c b/ffmpeg/libavcodec/j2k_dwt.c deleted file mode 100644 index 6f1457f..0000000 --- a/ffmpeg/libavcodec/j2k_dwt.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Discrete wavelet transform - * Copyright (c) 2007 Kamil Nowosad - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * Discrete wavelet transform - * @file - * @author Kamil Nowosad - */ - -#include "j2k_dwt.h" - -static const float scale97[] = {1.625786, 1.230174}; - -static inline void extend53(int *p, int i0, int i1) -{ - p[i0 - 1] = p[i0 + 1]; - p[i1 ] = p[i1 - 2]; - p[i0 - 2] = p[i0 + 2]; - p[i1 + 1] = p[i1 - 3]; -} - -static inline void extend97(float *p, int i0, int i1) -{ - int i; - - for (i = 1; i <= 4; i++){ - p[i0 - i] = p[i0 + i]; - p[i1 + i - 1] = p[i1 - i - 1]; - } -} - -static void sd_1d53(int *p, int i0, int i1) -{ - int i; - - if (i1 == i0 + 1) - return; - - extend53(p, i0, i1); - - for (i = (i0+1)/2 - 1; i < (i1+1)/2; i++) - p[2*i+1] -= (p[2*i] + p[2*i+2]) >> 1; - for (i = (i0+1)/2; i < (i1+1)/2; i++) - p[2*i] += (p[2*i-1] + p[2*i+1] + 2) >> 2; -} - -static void dwt_encode53(DWTContext *s, int *t) -{ - int lev, - w = s->linelen[s->ndeclevels-1][0]; - int *line = s->linebuf; - line += 3; - - for (lev = s->ndeclevels-1; lev >= 0; lev--){ - int lh = s->linelen[lev][0], - lv = s->linelen[lev][1], - mh = s->mod[lev][0], - mv = s->mod[lev][1], - lp; - int *l; - - // HOR_SD - l = line + mh; - for (lp = 0; lp < lv; lp++){ - int i, j = 0; - - for (i = 0; i < lh; i++) - l[i] = t[w*lp + i]; - - sd_1d53(line, mh, mh + lh); - - // copy back and deinterleave - for (i = mh; i < lh; i+=2, j++) - t[w*lp + j] = l[i]; - for (i = 1-mh; i < lh; i+=2, j++) - t[w*lp + j] = l[i]; - } - - // VER_SD - l = line + mv; - for (lp = 0; lp < lh; lp++) { - int i, j = 0; - - for (i = 0; i < lv; i++) - l[i] = t[w*i + lp]; - - sd_1d53(line, mv, mv + lv); - - // copy back and deinterleave - for (i = mv; i < lv; i+=2, j++) - t[w*j + lp] = l[i]; - for (i = 1-mv; i < lv; i+=2, j++) - t[w*j + lp] = l[i]; - } - } -} - -static void sd_1d97(float *p, int i0, int i1) -{ - int i; - - if (i1 == i0 + 1) - return; - - extend97(p, i0, i1); - i0++; i1++; - - for (i = i0/2 - 2; i < i1/2 + 1; i++) - p[2*i+1] -= 1.586134 * (p[2*i] + p[2*i+2]); - for (i = i0/2 - 1; i < i1/2 + 1; i++) - p[2*i] -= 0.052980 * (p[2*i-1] + p[2*i+1]); - for (i = i0/2 - 1; i < i1/2; i++) - p[2*i+1] += 0.882911 * (p[2*i] + p[2*i+2]); - for (i = i0/2; i < i1/2; i++) - p[2*i] += 0.443506 * (p[2*i-1] + p[2*i+1]); -} - -static void dwt_encode97(DWTContext *s, int *t) -{ - int lev, - w = s->linelen[s->ndeclevels-1][0]; - float *line = s->linebuf; - line += 5; - - for (lev = s->ndeclevels-1; lev >= 0; lev--){ - int lh = s->linelen[lev][0], - lv = s->linelen[lev][1], - mh = s->mod[lev][0], - mv = s->mod[lev][1], - lp; - float *l; - - // HOR_SD - l = line + mh; - for (lp = 0; lp < lv; lp++){ - int i, j = 0; - - for (i = 0; i < lh; i++) - l[i] = t[w*lp + i]; - - sd_1d97(line, mh, mh + lh); - - // copy back and deinterleave - for (i = mh; i < lh; i+=2, j++) - t[w*lp + j] = scale97[mh] * l[i] / 2; - for (i = 1-mh; i < lh; i+=2, j++) - t[w*lp + j] = scale97[mh] * l[i] / 2; - } - - // VER_SD - l = line + mv; - for (lp = 0; lp < lh; lp++) { - int i, j = 0; - - for (i = 0; i < lv; i++) - l[i] = t[w*i + lp]; - - sd_1d97(line, mv, mv + lv); - - // copy back and deinterleave - for (i = mv; i < lv; i+=2, j++) - t[w*j + lp] = scale97[mv] * l[i] / 2; - for (i = 1-mv; i < lv; i+=2, j++) - t[w*j + lp] = scale97[mv] * l[i] / 2; - } - } -} - -static void sr_1d53(int *p, int i0, int i1) -{ - int i; - - if (i1 == i0 + 1) - return; - - extend53(p, i0, i1); - - for (i = i0/2; i < i1/2 + 1; i++) - p[2*i] -= (p[2*i-1] + p[2*i+1] + 2) >> 2; - for (i = i0/2; i < i1/2; i++) - p[2*i+1] += (p[2*i] + p[2*i+2]) >> 1; -} - -static void dwt_decode53(DWTContext *s, int *t) -{ - int lev, - w = s->linelen[s->ndeclevels-1][0]; - int *line = s->linebuf; - line += 3; - - for (lev = 0; lev < s->ndeclevels; lev++){ - int lh = s->linelen[lev][0], - lv = s->linelen[lev][1], - mh = s->mod[lev][0], - mv = s->mod[lev][1], - lp; - int *l; - - // HOR_SD - l = line + mh; - for (lp = 0; lp < lv; lp++){ - int i, j = 0; - // copy with interleaving - for (i = mh; i < lh; i+=2, j++) - l[i] = t[w*lp + j]; - for (i = 1-mh; i < lh; i+=2, j++) - l[i] = t[w*lp + j]; - - sr_1d53(line, mh, mh + lh); - - for (i = 0; i < lh; i++) - t[w*lp + i] = l[i]; - } - - // VER_SD - l = line + mv; - for (lp = 0; lp < lh; lp++){ - int i, j = 0; - // copy with interleaving - for (i = mv; i < lv; i+=2, j++) - l[i] = t[w*j + lp]; - for (i = 1-mv; i < lv; i+=2, j++) - l[i] = t[w*j + lp]; - - sr_1d53(line, mv, mv + lv); - - for (i = 0; i < lv; i++) - t[w*i + lp] = l[i]; - } - } -} - -static void sr_1d97(float *p, int i0, int i1) -{ - int i; - - if (i1 == i0 + 1) - return; - - extend97(p, i0, i1); - - for (i = i0/2 - 1; i < i1/2 + 2; i++) - p[2*i] -= 0.443506 * (p[2*i-1] + p[2*i+1]); - for (i = i0/2 - 1; i < i1/2 + 1; i++) - p[2*i+1] -= 0.882911 * (p[2*i] + p[2*i+2]); - for (i = i0/2; i < i1/2 + 1; i++) - p[2*i] += 0.052980 * (p[2*i-1] + p[2*i+1]); - for (i = i0/2; i < i1/2; i++) - p[2*i+1] += 1.586134 * (p[2*i] + p[2*i+2]); -} - -static void dwt_decode97(DWTContext *s, int *t) -{ - int lev, - w = s->linelen[s->ndeclevels-1][0]; - float *line = s->linebuf; - line += 5; - - for (lev = 0; lev < s->ndeclevels; lev++){ - int lh = s->linelen[lev][0], - lv = s->linelen[lev][1], - mh = s->mod[lev][0], - mv = s->mod[lev][1], - lp; - float *l; - - // HOR_SD - l = line + mh; - for (lp = 0; lp < lv; lp++){ - int i, j = 0; - // copy with interleaving - for (i = mh; i < lh; i+=2, j++) - l[i] = scale97[1-mh] * t[w*lp + j]; - for (i = 1-mh; i < lh; i+=2, j++) - l[i] = scale97[1-mh] * t[w*lp + j]; - - sr_1d97(line, mh, mh + lh); - - for (i = 0; i < lh; i++) - t[w*lp + i] = l[i]; - } - - // VER_SD - l = line + mv; - for (lp = 0; lp < lh; lp++){ - int i, j = 0; - // copy with interleaving - for (i = mv; i < lv; i+=2, j++) - l[i] = scale97[1-mv] * t[w*j + lp]; - for (i = 1-mv; i < lv; i+=2, j++) - l[i] = scale97[1-mv] * t[w*j + lp]; - - sr_1d97(line, mv, mv + lv); - - for (i = 0; i < lv; i++) - t[w*i + lp] = l[i]; - } - } -} - -int ff_j2k_dwt_init(DWTContext *s, uint16_t border[2][2], int decomp_levels, int type) -{ - int i, j, lev = decomp_levels, maxlen, - b[2][2]; - - if ((unsigned)decomp_levels >= FF_DWT_MAX_DECLVLS) - return AVERROR_INVALIDDATA; - s->ndeclevels = decomp_levels; - s->type = type; - - for (i = 0; i < 2; i++) - for(j = 0; j < 2; j++) - b[i][j] = border[i][j]; - - maxlen = FFMAX(b[0][1] - b[0][0], - b[1][1] - b[1][0]); - - while(--lev >= 0){ - for (i = 0; i < 2; i++){ - s->linelen[lev][i] = b[i][1] - b[i][0]; - s->mod[lev][i] = b[i][0] & 1; - for (j = 0; j < 2; j++) - b[i][j] = (b[i][j] + 1) >> 1; - } - } - if (type == FF_DWT97) - s->linebuf = av_malloc((maxlen + 12) * sizeof(float)); - else if (type == FF_DWT53) - s->linebuf = av_malloc((maxlen + 6) * sizeof(int)); - else - return -1; - - if (!s->linebuf) - return AVERROR(ENOMEM); - - return 0; -} - -int ff_j2k_dwt_encode(DWTContext *s, int *t) -{ - switch(s->type){ - case FF_DWT97: - dwt_encode97(s, t); break; - case FF_DWT53: - dwt_encode53(s, t); break; - default: - return -1; - } - return 0; -} - -int ff_j2k_dwt_decode(DWTContext *s, int *t) -{ - switch(s->type){ - case FF_DWT97: - dwt_decode97(s, t); break; - case FF_DWT53: - dwt_decode53(s, t); break; - default: - return -1; - } - return 0; -} - -void ff_j2k_dwt_destroy(DWTContext *s) -{ - av_freep(&s->linebuf); -} diff --git a/ffmpeg/libavcodec/j2k_dwt.h b/ffmpeg/libavcodec/j2k_dwt.h deleted file mode 100644 index a2a25a6..0000000 --- a/ffmpeg/libavcodec/j2k_dwt.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Discrete wavelet transform - * Copyright (c) 2007 Kamil Nowosad - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_DWT_H -#define AVCODEC_DWT_H - -/** - * Discrete wavelet transform - * @file - * @author Kamil Nowosad - */ - -#include "avcodec.h" - -#define FF_DWT_MAX_DECLVLS 32 ///< max number of decomposition levels - -enum DWTType{ - FF_DWT97, - FF_DWT53 -}; - -typedef struct { - ///line lengths {horizontal, vertical} in consecutive decomposition levels - uint16_t linelen[FF_DWT_MAX_DECLVLS][2]; - uint8_t mod[FF_DWT_MAX_DECLVLS][2]; ///< coordinates (x0, y0) of decomp. levels mod 2 - uint8_t ndeclevels; ///< number of decomposition levels - uint8_t type; ///< 0 for 9/7; 1 for 5/3 - void *linebuf; ///< buffer used by transform (int or float) -} DWTContext; - -/** - * initialize DWT - * @param s DWT context - * @param border coordinates of transformed region {{x0, x1}, {y0, y1}} - * @param decomp_levels number of decomposition levels - * @param type 0 for DWT 9/7; 1 for DWT 5/3 - */ -int ff_j2k_dwt_init(DWTContext *s, uint16_t border[2][2], int decomp_levels, int type); - -int ff_j2k_dwt_encode(DWTContext *s, int *t); -int ff_j2k_dwt_decode(DWTContext *s, int *t); - -void ff_j2k_dwt_destroy(DWTContext *s); - -#endif /* AVCODEC_DWT_H */ diff --git a/ffmpeg/libavcodec/j2kdec.c b/ffmpeg/libavcodec/j2kdec.c deleted file mode 100644 index 6dcaf73..0000000 --- a/ffmpeg/libavcodec/j2kdec.c +++ /dev/null @@ -1,1093 +0,0 @@ -/* - * JPEG2000 image decoder - * Copyright (c) 2007 Kamil Nowosad - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * JPEG2000 image decoder - * @file - * @author Kamil Nowosad - */ - -// #define DEBUG - -#include "avcodec.h" -#include "bytestream.h" -#include "internal.h" -#include "j2k.h" -#include "libavutil/common.h" - -#define JP2_SIG_TYPE 0x6A502020 -#define JP2_SIG_VALUE 0x0D0A870A -#define JP2_CODESTREAM 0x6A703263 - -#define HAD_COC 0x01 -#define HAD_QCC 0x02 - -typedef struct { - J2kComponent *comp; - uint8_t properties[4]; - J2kCodingStyle codsty[4]; - J2kQuantStyle qntsty[4]; -} J2kTile; - -typedef struct { - AVCodecContext *avctx; - AVFrame *picture; - GetByteContext g; - - int width, height; ///< image width and height - int image_offset_x, image_offset_y; - int tile_offset_x, tile_offset_y; - uint8_t cbps[4]; ///< bits per sample in particular components - uint8_t sgnd[4]; ///< if a component is signed - uint8_t properties[4]; - int cdx[4], cdy[4]; - int precision; - int ncomponents; - int tile_width, tile_height; ///< tile size - int numXtiles, numYtiles; - int maxtilelen; - - J2kCodingStyle codsty[4]; - J2kQuantStyle qntsty[4]; - - int bit_index; - - int curtileno; - - J2kTile *tile; -} J2kDecoderContext; - -static int get_bits(J2kDecoderContext *s, int n) -{ - int res = 0; - - while (--n >= 0){ - res <<= 1; - if (s->bit_index == 0) { - s->bit_index = 7 + (bytestream2_get_byte(&s->g) != 0xFFu); - } - s->bit_index--; - res |= (bytestream2_peek_byte(&s->g) >> s->bit_index) & 1; - } - return res; -} - -static void j2k_flush(J2kDecoderContext *s) -{ - if (bytestream2_get_byte(&s->g) == 0xff) - bytestream2_skip(&s->g, 1); - s->bit_index = 8; -} -#if 0 -void printcomp(J2kComponent *comp) -{ - int i; - for (i = 0; i < comp->y1 - comp->y0; i++) - ff_j2k_printv(comp->data + i * (comp->x1 - comp->x0), comp->x1 - comp->x0); -} - -static void nspaces(FILE *fd, int n) -{ - while(n--) putc(' ', fd); -} - -static void dump(J2kDecoderContext *s, FILE *fd) -{ - int tileno, compno, reslevelno, bandno, precno; - fprintf(fd, "XSiz = %d, YSiz = %d, tile_width = %d, tile_height = %d\n" - "numXtiles = %d, numYtiles = %d, ncomponents = %d\n" - "tiles:\n", - s->width, s->height, s->tile_width, s->tile_height, - s->numXtiles, s->numYtiles, s->ncomponents); - for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ - J2kTile *tile = s->tile + tileno; - nspaces(fd, 2); - fprintf(fd, "tile %d:\n", tileno); - for(compno = 0; compno < s->ncomponents; compno++){ - J2kComponent *comp = tile->comp + compno; - nspaces(fd, 4); - fprintf(fd, "component %d:\n", compno); - nspaces(fd, 4); - fprintf(fd, "x0 = %d, x1 = %d, y0 = %d, y1 = %d\n", - comp->x0, comp->x1, comp->y0, comp->y1); - for(reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ - J2kResLevel *reslevel = comp->reslevel + reslevelno; - nspaces(fd, 6); - fprintf(fd, "reslevel %d:\n", reslevelno); - nspaces(fd, 6); - fprintf(fd, "x0 = %d, x1 = %d, y0 = %d, y1 = %d, nbands = %d\n", - reslevel->x0, reslevel->x1, reslevel->y0, - reslevel->y1, reslevel->nbands); - for(bandno = 0; bandno < reslevel->nbands; bandno++){ - J2kBand *band = reslevel->band + bandno; - nspaces(fd, 8); - fprintf(fd, "band %d:\n", bandno); - nspaces(fd, 8); - fprintf(fd, "x0 = %d, x1 = %d, y0 = %d, y1 = %d," - "codeblock_width = %d, codeblock_height = %d cblknx = %d cblkny = %d\n", - band->x0, band->x1, - band->y0, band->y1, - band->codeblock_width, band->codeblock_height, - band->cblknx, band->cblkny); - for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){ - J2kPrec *prec = band->prec + precno; - nspaces(fd, 10); - fprintf(fd, "prec %d:\n", precno); - nspaces(fd, 10); - fprintf(fd, "xi0 = %d, xi1 = %d, yi0 = %d, yi1 = %d\n", - prec->xi0, prec->xi1, prec->yi0, prec->yi1); - } - } - } - } - } -} -#endif - -/** decode the value stored in node */ -static int tag_tree_decode(J2kDecoderContext *s, J2kTgtNode *node, int threshold) -{ - J2kTgtNode *stack[30]; - int sp = -1, curval = 0; - - if(!node) - return AVERROR(EINVAL); - - while(node && !node->vis){ - stack[++sp] = node; - node = node->parent; - } - - if (node) - curval = node->val; - else - curval = stack[sp]->val; - - while(curval < threshold && sp >= 0){ - if (curval < stack[sp]->val) - curval = stack[sp]->val; - while (curval < threshold){ - int ret; - if ((ret = get_bits(s, 1)) > 0){ - stack[sp]->vis++; - break; - } else if (!ret) - curval++; - else - return ret; - } - stack[sp]->val = curval; - sp--; - } - return curval; -} - -/* marker segments */ -/** get sizes and offsets of image, tiles; number of components */ -static int get_siz(J2kDecoderContext *s) -{ - int i, ret; - - if (bytestream2_get_bytes_left(&s->g) < 36) - return AVERROR(EINVAL); - - bytestream2_get_be16u(&s->g); // Rsiz (skipped) - s->width = bytestream2_get_be32u(&s->g); // width - s->height = bytestream2_get_be32u(&s->g); // height - s->image_offset_x = bytestream2_get_be32u(&s->g); // X0Siz - s->image_offset_y = bytestream2_get_be32u(&s->g); // Y0Siz - - s->tile_width = bytestream2_get_be32u(&s->g); // XTSiz - s->tile_height = bytestream2_get_be32u(&s->g); // YTSiz - s->tile_offset_x = bytestream2_get_be32u(&s->g); // XT0Siz - s->tile_offset_y = bytestream2_get_be32u(&s->g); // YT0Siz - s->ncomponents = bytestream2_get_be16u(&s->g); // CSiz - - if(s->ncomponents <= 0 || s->ncomponents > 4) { - av_log(s->avctx, AV_LOG_ERROR, "unsupported/invalid ncomponents: %d\n", s->ncomponents); - return AVERROR(EINVAL); - } - if(s->tile_width<=0 || s->tile_height<=0) - return AVERROR(EINVAL); - - if (bytestream2_get_bytes_left(&s->g) < 3 * s->ncomponents) - return AVERROR(EINVAL); - - for (i = 0; i < s->ncomponents; i++){ // Ssiz_i XRsiz_i, YRsiz_i - uint8_t x = bytestream2_get_byteu(&s->g); - s->cbps[i] = (x & 0x7f) + 1; - s->precision = FFMAX(s->cbps[i], s->precision); - s->sgnd[i] = !!(x & 0x80); - s->cdx[i] = bytestream2_get_byteu(&s->g); - s->cdy[i] = bytestream2_get_byteu(&s->g); - } - - s->numXtiles = ff_j2k_ceildiv(s->width - s->tile_offset_x, s->tile_width); - s->numYtiles = ff_j2k_ceildiv(s->height - s->tile_offset_y, s->tile_height); - - if(s->numXtiles * (uint64_t)s->numYtiles > INT_MAX/sizeof(J2kTile)) - return AVERROR(EINVAL); - - s->tile = av_mallocz(s->numXtiles * s->numYtiles * sizeof(J2kTile)); - if (!s->tile) - return AVERROR(ENOMEM); - - for (i = 0; i < s->numXtiles * s->numYtiles; i++){ - J2kTile *tile = s->tile + i; - - tile->comp = av_mallocz(s->ncomponents * sizeof(J2kComponent)); - if (!tile->comp) - return AVERROR(ENOMEM); - } - - s->avctx->width = s->width - s->image_offset_x; - s->avctx->height = s->height - s->image_offset_y; - - switch(s->ncomponents){ - case 1: - if (s->precision > 8) { - s->avctx->pix_fmt = AV_PIX_FMT_GRAY16; - } else { - s->avctx->pix_fmt = AV_PIX_FMT_GRAY8; - } - break; - case 3: - if (s->precision > 8) { - s->avctx->pix_fmt = AV_PIX_FMT_RGB48; - } else { - s->avctx->pix_fmt = AV_PIX_FMT_RGB24; - } - break; - case 4: - s->avctx->pix_fmt = AV_PIX_FMT_RGBA; - break; - } - - - if ((ret = ff_get_buffer(s->avctx, s->picture, 0)) < 0) - return ret; - - s->picture->pict_type = AV_PICTURE_TYPE_I; - s->picture->key_frame = 1; - - return 0; -} - -/** get common part for COD and COC segments */ -static int get_cox(J2kDecoderContext *s, J2kCodingStyle *c) -{ - if (bytestream2_get_bytes_left(&s->g) < 5) - return AVERROR(EINVAL); - c->nreslevels = bytestream2_get_byteu(&s->g) + 1; // num of resolution levels - 1 - c->log2_cblk_width = bytestream2_get_byteu(&s->g) + 2; // cblk width - c->log2_cblk_height = bytestream2_get_byteu(&s->g) + 2; // cblk height - - c->cblk_style = bytestream2_get_byteu(&s->g); - if (c->cblk_style != 0){ // cblk style - av_log(s->avctx, AV_LOG_WARNING, "extra cblk styles %X\n", c->cblk_style); - } - c->transform = bytestream2_get_byteu(&s->g); // transformation - if (c->csty & J2K_CSTY_PREC) { - int i; - - for (i = 0; i < c->nreslevels; i++) - bytestream2_get_byte(&s->g); - } - return 0; -} - -/** get coding parameters for a particular tile or whole image*/ -static int get_cod(J2kDecoderContext *s, J2kCodingStyle *c, uint8_t *properties) -{ - J2kCodingStyle tmp; - int compno; - - if (bytestream2_get_bytes_left(&s->g) < 5) - return AVERROR(EINVAL); - - tmp.log2_prec_width = - tmp.log2_prec_height = 15; - - tmp.csty = bytestream2_get_byteu(&s->g); - - if (bytestream2_get_byteu(&s->g)){ // progression level - av_log(s->avctx, AV_LOG_ERROR, "only LRCP progression supported\n"); - return -1; - } - - tmp.nlayers = bytestream2_get_be16u(&s->g); - tmp.mct = bytestream2_get_byteu(&s->g); // multiple component transformation - - get_cox(s, &tmp); - for (compno = 0; compno < s->ncomponents; compno++){ - if (!(properties[compno] & HAD_COC)) - memcpy(c + compno, &tmp, sizeof(J2kCodingStyle)); - } - return 0; -} - -/** get coding parameters for a component in the whole image on a particular tile */ -static int get_coc(J2kDecoderContext *s, J2kCodingStyle *c, uint8_t *properties) -{ - int compno; - - if (bytestream2_get_bytes_left(&s->g) < 2) - return AVERROR(EINVAL); - - compno = bytestream2_get_byteu(&s->g); - - c += compno; - c->csty = bytestream2_get_byte(&s->g); - get_cox(s, c); - - properties[compno] |= HAD_COC; - return 0; -} - -/** get common part for QCD and QCC segments */ -static int get_qcx(J2kDecoderContext *s, int n, J2kQuantStyle *q) -{ - int i, x; - - if (bytestream2_get_bytes_left(&s->g) < 1) - return AVERROR(EINVAL); - - x = bytestream2_get_byteu(&s->g); // Sqcd - - q->nguardbits = x >> 5; - q->quantsty = x & 0x1f; - - if (q->quantsty == J2K_QSTY_NONE){ - n -= 3; - if (bytestream2_get_bytes_left(&s->g) < n || 32*3 < n) - return AVERROR(EINVAL); - for (i = 0; i < n; i++) - q->expn[i] = bytestream2_get_byteu(&s->g) >> 3; - } else if (q->quantsty == J2K_QSTY_SI){ - if (bytestream2_get_bytes_left(&s->g) < 2) - return AVERROR(EINVAL); - x = bytestream2_get_be16u(&s->g); - q->expn[0] = x >> 11; - q->mant[0] = x & 0x7ff; - for (i = 1; i < 32 * 3; i++){ - int curexpn = FFMAX(0, q->expn[0] - (i-1)/3); - q->expn[i] = curexpn; - q->mant[i] = q->mant[0]; - } - } else{ - n = (n - 3) >> 1; - if (bytestream2_get_bytes_left(&s->g) < 2 * n || 32*3 < n) - return AVERROR(EINVAL); - for (i = 0; i < n; i++){ - x = bytestream2_get_be16u(&s->g); - q->expn[i] = x >> 11; - q->mant[i] = x & 0x7ff; - } - } - return 0; -} - -/** get quantization parameters for a particular tile or a whole image */ -static int get_qcd(J2kDecoderContext *s, int n, J2kQuantStyle *q, uint8_t *properties) -{ - J2kQuantStyle tmp; - int compno; - - if (get_qcx(s, n, &tmp)) - return -1; - for (compno = 0; compno < s->ncomponents; compno++) - if (!(properties[compno] & HAD_QCC)) - memcpy(q + compno, &tmp, sizeof(J2kQuantStyle)); - return 0; -} - -/** get quantization parameters for a component in the whole image on in a particular tile */ -static int get_qcc(J2kDecoderContext *s, int n, J2kQuantStyle *q, uint8_t *properties) -{ - int compno; - - if (bytestream2_get_bytes_left(&s->g) < 1) - return AVERROR(EINVAL); - - compno = bytestream2_get_byteu(&s->g); - properties[compno] |= HAD_QCC; - return get_qcx(s, n-1, q+compno); -} - -/** get start of tile segment */ -static uint8_t get_sot(J2kDecoderContext *s) -{ - if (bytestream2_get_bytes_left(&s->g) < 8) - return AVERROR(EINVAL); - - s->curtileno = bytestream2_get_be16u(&s->g); ///< Isot - if((unsigned)s->curtileno >= s->numXtiles * s->numYtiles){ - s->curtileno=0; - return AVERROR(EINVAL); - } - - bytestream2_skipu(&s->g, 4); ///< Psot (ignored) - - if (!bytestream2_get_byteu(&s->g)){ ///< TPsot - J2kTile *tile = s->tile + s->curtileno; - - /* copy defaults */ - memcpy(tile->codsty, s->codsty, s->ncomponents * sizeof(J2kCodingStyle)); - memcpy(tile->qntsty, s->qntsty, s->ncomponents * sizeof(J2kQuantStyle)); - } - bytestream2_get_byteu(&s->g); ///< TNsot - - return 0; -} - -static int init_tile(J2kDecoderContext *s, int tileno) -{ - int compno, - tilex = tileno % s->numXtiles, - tiley = tileno / s->numXtiles; - J2kTile *tile = s->tile + tileno; - - if (!tile->comp) - return AVERROR(ENOMEM); - for (compno = 0; compno < s->ncomponents; compno++){ - J2kComponent *comp = tile->comp + compno; - J2kCodingStyle *codsty = tile->codsty + compno; - J2kQuantStyle *qntsty = tile->qntsty + compno; - int ret; // global bandno - - comp->coord[0][0] = FFMAX(tilex * s->tile_width + s->tile_offset_x, s->image_offset_x); - comp->coord[0][1] = FFMIN((tilex+1)*s->tile_width + s->tile_offset_x, s->width); - comp->coord[1][0] = FFMAX(tiley * s->tile_height + s->tile_offset_y, s->image_offset_y); - comp->coord[1][1] = FFMIN((tiley+1)*s->tile_height + s->tile_offset_y, s->height); - - if (ret = ff_j2k_init_component(comp, codsty, qntsty, s->cbps[compno], s->cdx[compno], s->cdy[compno])) - return ret; - } - return 0; -} - -/** read the number of coding passes */ -static int getnpasses(J2kDecoderContext *s) -{ - int num; - if (!get_bits(s, 1)) - return 1; - if (!get_bits(s, 1)) - return 2; - if ((num = get_bits(s, 2)) != 3) - return num < 0 ? num : 3 + num; - if ((num = get_bits(s, 5)) != 31) - return num < 0 ? num : 6 + num; - num = get_bits(s, 7); - return num < 0 ? num : 37 + num; -} - -static int getlblockinc(J2kDecoderContext *s) -{ - int res = 0, ret; - while (ret = get_bits(s, 1)){ - if (ret < 0) - return ret; - res++; - } - return res; -} - -static int decode_packet(J2kDecoderContext *s, J2kCodingStyle *codsty, J2kResLevel *rlevel, int precno, - int layno, uint8_t *expn, int numgbits) -{ - int bandno, cblkny, cblknx, cblkno, ret; - - if (!(ret = get_bits(s, 1))){ - j2k_flush(s); - return 0; - } else if (ret < 0) - return ret; - - for (bandno = 0; bandno < rlevel->nbands; bandno++){ - J2kBand *band = rlevel->band + bandno; - J2kPrec *prec = band->prec + precno; - int pos = 0; - - if (band->coord[0][0] == band->coord[0][1] - || band->coord[1][0] == band->coord[1][1]) - continue; - - for (cblkny = prec->yi0; cblkny < prec->yi1; cblkny++) - for(cblknx = prec->xi0, cblkno = cblkny * band->cblknx + cblknx; cblknx < prec->xi1; cblknx++, cblkno++, pos++){ - J2kCblk *cblk = band->cblk + cblkno; - int incl, newpasses, llen; - - if (cblk->npasses) - incl = get_bits(s, 1); - else - incl = tag_tree_decode(s, prec->cblkincl + pos, layno+1) == layno; - if (!incl) - continue; - else if (incl < 0) - return incl; - - if (!cblk->npasses) - cblk->nonzerobits = expn[bandno] + numgbits - 1 - tag_tree_decode(s, prec->zerobits + pos, 100); - if ((newpasses = getnpasses(s)) < 0) - return newpasses; - if ((llen = getlblockinc(s)) < 0) - return llen; - cblk->lblock += llen; - if ((ret = get_bits(s, av_log2(newpasses) + cblk->lblock)) < 0) - return ret; - cblk->lengthinc = ret; - cblk->npasses += newpasses; - } - } - j2k_flush(s); - - if (codsty->csty & J2K_CSTY_EPH) { - if (bytestream2_peek_be16(&s->g) == J2K_EPH) { - bytestream2_skip(&s->g, 2); - } else { - av_log(s->avctx, AV_LOG_ERROR, "EPH marker not found.\n"); - } - } - - for (bandno = 0; bandno < rlevel->nbands; bandno++){ - J2kBand *band = rlevel->band + bandno; - int yi, cblknw = band->prec[precno].xi1 - band->prec[precno].xi0; - for (yi = band->prec[precno].yi0; yi < band->prec[precno].yi1; yi++){ - int xi; - for (xi = band->prec[precno].xi0; xi < band->prec[precno].xi1; xi++){ - J2kCblk *cblk = band->cblk + yi * cblknw + xi; - if (bytestream2_get_bytes_left(&s->g) < cblk->lengthinc) - return AVERROR(EINVAL); - bytestream2_get_bufferu(&s->g, cblk->data, cblk->lengthinc); - cblk->length += cblk->lengthinc; - cblk->lengthinc = 0; - } - } - } - return 0; -} - -static int decode_packets(J2kDecoderContext *s, J2kTile *tile) -{ - int layno, reslevelno, compno, precno, ok_reslevel; - s->bit_index = 8; - for (layno = 0; layno < tile->codsty[0].nlayers; layno++){ - ok_reslevel = 1; - for (reslevelno = 0; ok_reslevel; reslevelno++){ - ok_reslevel = 0; - for (compno = 0; compno < s->ncomponents; compno++){ - J2kCodingStyle *codsty = tile->codsty + compno; - J2kQuantStyle *qntsty = tile->qntsty + compno; - if (reslevelno < codsty->nreslevels){ - J2kResLevel *rlevel = tile->comp[compno].reslevel + reslevelno; - ok_reslevel = 1; - for (precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++){ - if (decode_packet(s, codsty, rlevel, precno, layno, qntsty->expn + - (reslevelno ? 3*(reslevelno-1)+1 : 0), qntsty->nguardbits)) - return -1; - } - } - } - } - } - return 0; -} - -/* TIER-1 routines */ -static void decode_sigpass(J2kT1Context *t1, int width, int height, int bpno, int bandno, int bpass_csty_symbol, - int vert_causal_ctx_csty_symbol) -{ - int mask = 3 << (bpno - 1), y0, x, y; - - for (y0 = 0; y0 < height; y0 += 4) - for (x = 0; x < width; x++) - for (y = y0; y < height && y < y0+4; y++){ - if ((t1->flags[y+1][x+1] & J2K_T1_SIG_NB) - && !(t1->flags[y+1][x+1] & (J2K_T1_SIG | J2K_T1_VIS))){ - int vert_causal_ctx_csty_loc_symbol = vert_causal_ctx_csty_symbol && (x == 3 && y == 3); - if (ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ff_j2k_getnbctxno(t1->flags[y+1][x+1], bandno, - vert_causal_ctx_csty_loc_symbol))){ - int xorbit, ctxno = ff_j2k_getsgnctxno(t1->flags[y+1][x+1], &xorbit); - if (bpass_csty_symbol) - t1->data[y][x] = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ? -mask : mask; - else - t1->data[y][x] = (ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ^ xorbit) ? - -mask : mask; - - ff_j2k_set_significant(t1, x, y, t1->data[y][x] < 0); - } - t1->flags[y+1][x+1] |= J2K_T1_VIS; - } - } -} - -static void decode_refpass(J2kT1Context *t1, int width, int height, int bpno) -{ - int phalf, nhalf; - int y0, x, y; - - phalf = 1 << (bpno - 1); - nhalf = -phalf; - - for (y0 = 0; y0 < height; y0 += 4) - for (x = 0; x < width; x++) - for (y = y0; y < height && y < y0+4; y++){ - if ((t1->flags[y+1][x+1] & (J2K_T1_SIG | J2K_T1_VIS)) == J2K_T1_SIG){ - int ctxno = ff_j2k_getrefctxno(t1->flags[y+1][x+1]); - int r = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ? phalf : nhalf; - t1->data[y][x] += t1->data[y][x] < 0 ? -r : r; - t1->flags[y+1][x+1] |= J2K_T1_REF; - } - } -} - -static void decode_clnpass(J2kDecoderContext *s, J2kT1Context *t1, int width, int height, - int bpno, int bandno, int seg_symbols) -{ - int mask = 3 << (bpno - 1), y0, x, y, runlen, dec; - - for (y0 = 0; y0 < height; y0 += 4) { - for (x = 0; x < width; x++){ - if (y0 + 3 < height && !( - (t1->flags[y0+1][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)) || - (t1->flags[y0+2][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)) || - (t1->flags[y0+3][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)) || - (t1->flags[y0+4][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)))){ - if (!ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_RL)) - continue; - runlen = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI); - runlen = (runlen << 1) | ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI); - dec = 1; - } else{ - runlen = 0; - dec = 0; - } - - for (y = y0 + runlen; y < y0 + 4 && y < height; y++){ - if (!dec){ - if (!(t1->flags[y+1][x+1] & (J2K_T1_SIG | J2K_T1_VIS))) - dec = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ff_j2k_getnbctxno(t1->flags[y+1][x+1], - bandno, 0)); - } - if (dec){ - int xorbit, ctxno = ff_j2k_getsgnctxno(t1->flags[y+1][x+1], &xorbit); - t1->data[y][x] = (ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ^ xorbit) ? -mask : mask; - ff_j2k_set_significant(t1, x, y, t1->data[y][x] < 0); - } - dec = 0; - t1->flags[y+1][x+1] &= ~J2K_T1_VIS; - } - } - } - if (seg_symbols) { - int val; - val = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI); - val = (val << 1) + ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI); - val = (val << 1) + ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI); - val = (val << 1) + ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI); - if (val != 0xa) { - av_log(s->avctx, AV_LOG_ERROR,"Segmentation symbol value incorrect\n"); - } - } -} - -static int decode_cblk(J2kDecoderContext *s, J2kCodingStyle *codsty, J2kT1Context *t1, J2kCblk *cblk, - int width, int height, int bandpos) -{ - int passno = cblk->npasses, pass_t = 2, bpno = cblk->nonzerobits - 1, y, clnpass_cnt = 0; - int bpass_csty_symbol = J2K_CBLK_BYPASS & codsty->cblk_style; - int vert_causal_ctx_csty_symbol = J2K_CBLK_VSC & codsty->cblk_style; - - for (y = 0; y < height+2; y++) - memset(t1->flags[y], 0, (width+2)*sizeof(int)); - - for (y = 0; y < height; y++) - memset(t1->data[y], 0, width*sizeof(int)); - - cblk->data[cblk->length] = 0xff; - cblk->data[cblk->length+1] = 0xff; - ff_mqc_initdec(&t1->mqc, cblk->data); - - while(passno--){ - switch(pass_t){ - case 0: decode_sigpass(t1, width, height, bpno+1, bandpos, - bpass_csty_symbol && (clnpass_cnt >= 4), vert_causal_ctx_csty_symbol); - break; - case 1: decode_refpass(t1, width, height, bpno+1); - if (bpass_csty_symbol && clnpass_cnt >= 4) - ff_mqc_initdec(&t1->mqc, cblk->data); - break; - case 2: decode_clnpass(s, t1, width, height, bpno+1, bandpos, - codsty->cblk_style & J2K_CBLK_SEGSYM); - clnpass_cnt = clnpass_cnt + 1; - if (bpass_csty_symbol && clnpass_cnt >= 4) - ff_mqc_initdec(&t1->mqc, cblk->data); - break; - } - - pass_t++; - if (pass_t == 3){ - bpno--; - pass_t = 0; - } - } - return 0; -} - -static void mct_decode(J2kDecoderContext *s, J2kTile *tile) -{ - int i, *src[3], i0, i1, i2, csize = 1; - - for (i = 0; i < 3; i++) - src[i] = tile->comp[i].data; - - for (i = 0; i < 2; i++) - csize *= tile->comp[0].coord[i][1] - tile->comp[0].coord[i][0]; - - if (tile->codsty[0].transform == FF_DWT97){ - for (i = 0; i < csize; i++){ - i0 = *src[0] + (*src[2] * 46802 >> 16); - i1 = *src[0] - (*src[1] * 22553 + *src[2] * 46802 >> 16); - i2 = *src[0] + (116130 * *src[1] >> 16); - *src[0]++ = i0; - *src[1]++ = i1; - *src[2]++ = i2; - } - } else{ - for (i = 0; i < csize; i++){ - i1 = *src[0] - (*src[2] + *src[1] >> 2); - i0 = i1 + *src[2]; - i2 = i1 + *src[1]; - *src[0]++ = i0; - *src[1]++ = i1; - *src[2]++ = i2; - } - } -} - -static int decode_tile(J2kDecoderContext *s, J2kTile *tile) -{ - int compno, reslevelno, bandno; - int x, y, *src[4]; - uint8_t *line; - J2kT1Context t1; - - for (compno = 0; compno < s->ncomponents; compno++){ - J2kComponent *comp = tile->comp + compno; - J2kCodingStyle *codsty = tile->codsty + compno; - - for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ - J2kResLevel *rlevel = comp->reslevel + reslevelno; - for (bandno = 0; bandno < rlevel->nbands; bandno++){ - J2kBand *band = rlevel->band + bandno; - int cblkx, cblky, cblkno=0, xx0, x0, xx1, y0, yy0, yy1, bandpos; - - bandpos = bandno + (reslevelno > 0); - - yy0 = bandno == 0 ? 0 : comp->reslevel[reslevelno-1].coord[1][1] - comp->reslevel[reslevelno-1].coord[1][0]; - y0 = yy0; - yy1 = FFMIN(ff_j2k_ceildiv(band->coord[1][0] + 1, band->codeblock_height) * band->codeblock_height, - band->coord[1][1]) - band->coord[1][0] + yy0; - - if (band->coord[0][0] == band->coord[0][1] || band->coord[1][0] == band->coord[1][1]) - continue; - - for (cblky = 0; cblky < band->cblkny; cblky++){ - if (reslevelno == 0 || bandno == 1) - xx0 = 0; - else - xx0 = comp->reslevel[reslevelno-1].coord[0][1] - comp->reslevel[reslevelno-1].coord[0][0]; - x0 = xx0; - xx1 = FFMIN(ff_j2k_ceildiv(band->coord[0][0] + 1, band->codeblock_width) * band->codeblock_width, - band->coord[0][1]) - band->coord[0][0] + xx0; - - for (cblkx = 0; cblkx < band->cblknx; cblkx++, cblkno++){ - int y, x; - decode_cblk(s, codsty, &t1, band->cblk + cblkno, xx1 - xx0, yy1 - yy0, bandpos); - if (codsty->transform == FF_DWT53){ - for (y = yy0; y < yy1; y+=s->cdy[compno]){ - int *ptr = t1.data[y-yy0]; - for (x = xx0; x < xx1; x+=s->cdx[compno]){ - comp->data[(comp->coord[0][1] - comp->coord[0][0]) * y + x] = *ptr++ >> 1; - } - } - } else{ - for (y = yy0; y < yy1; y+=s->cdy[compno]){ - int *ptr = t1.data[y-yy0]; - for (x = xx0; x < xx1; x+=s->cdx[compno]){ - int tmp = ((int64_t)*ptr++) * ((int64_t)band->stepsize) >> 13, tmp2; - tmp2 = FFABS(tmp>>1) + (tmp&1); - comp->data[(comp->coord[0][1] - comp->coord[0][0]) * y + x] = tmp < 0 ? -tmp2 : tmp2; - } - } - } - xx0 = xx1; - xx1 = FFMIN(xx1 + band->codeblock_width, band->coord[0][1] - band->coord[0][0] + x0); - } - yy0 = yy1; - yy1 = FFMIN(yy1 + band->codeblock_height, band->coord[1][1] - band->coord[1][0] + y0); - } - } - } - ff_j2k_dwt_decode(&comp->dwt, comp->data); - src[compno] = comp->data; - } - if (tile->codsty[0].mct) - mct_decode(s, tile); - - if (s->precision <= 8) { - for (compno = 0; compno < s->ncomponents; compno++){ - y = tile->comp[compno].coord[1][0] - s->image_offset_y; - line = s->picture->data[0] + y * s->picture->linesize[0]; - for (; y < tile->comp[compno].coord[1][1] - s->image_offset_y; y += s->cdy[compno]){ - uint8_t *dst; - - x = tile->comp[compno].coord[0][0] - s->image_offset_x; - dst = line + x * s->ncomponents + compno; - - for (; x < tile->comp[compno].coord[0][1] - s->image_offset_x; x += s->cdx[compno]) { - *src[compno] += 1 << (s->cbps[compno]-1); - if (*src[compno] < 0) - *src[compno] = 0; - else if (*src[compno] >= (1 << s->cbps[compno])) - *src[compno] = (1 << s->cbps[compno]) - 1; - *dst = *src[compno]++; - dst += s->ncomponents; - } - line += s->picture->linesize[0]; - } - } - } else { - for (compno = 0; compno < s->ncomponents; compno++) { - y = tile->comp[compno].coord[1][0] - s->image_offset_y; - line = s->picture->data[0] + y * s->picture->linesize[0]; - for (; y < tile->comp[compno].coord[1][1] - s->image_offset_y; y += s->cdy[compno]) { - uint16_t *dst; - - x = tile->comp[compno].coord[0][0] - s->image_offset_x; - dst = (uint16_t *)(line + (x * s->ncomponents + compno) * 2); - for (; x < tile->comp[compno].coord[0][1] - s->image_offset_x; x += s-> cdx[compno]) { - int32_t val; - - val = *src[compno]++ << (16 - s->cbps[compno]); - val += 1 << 15; - val = av_clip(val, 0, (1 << 16) - 1); - *dst = val; - dst += s->ncomponents; - } - line += s->picture->linesize[0]; - } - } - } - return 0; -} - -static void cleanup(J2kDecoderContext *s) -{ - int tileno, compno; - for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ - for (compno = 0; compno < s->ncomponents; compno++){ - J2kComponent *comp = s->tile[tileno].comp + compno; - J2kCodingStyle *codsty = s->tile[tileno].codsty + compno; - - ff_j2k_cleanup(comp, codsty); - } - av_freep(&s->tile[tileno].comp); - } - av_freep(&s->tile); -} - -static int decode_codestream(J2kDecoderContext *s) -{ - J2kCodingStyle *codsty = s->codsty; - J2kQuantStyle *qntsty = s->qntsty; - uint8_t *properties = s->properties; - - for (;;){ - int oldpos, marker, len, ret = 0; - - if (bytestream2_get_bytes_left(&s->g) < 2){ - av_log(s->avctx, AV_LOG_ERROR, "Missing EOC\n"); - break; - } - - marker = bytestream2_get_be16u(&s->g); - av_dlog(s->avctx, "marker 0x%.4X at pos 0x%x\n", marker, bytestream2_tell(&s->g) - 4); - oldpos = bytestream2_tell(&s->g); - - if (marker == J2K_SOD){ - J2kTile *tile = s->tile + s->curtileno; - if (ret = init_tile(s, s->curtileno)) { - av_log(s->avctx, AV_LOG_ERROR, "tile initialization failed\n"); - return ret; - } - if (ret = decode_packets(s, tile)) { - av_log(s->avctx, AV_LOG_ERROR, "packets decoding failed\n"); - return ret; - } - continue; - } - if (marker == J2K_EOC) - break; - - if (bytestream2_get_bytes_left(&s->g) < 2) - return AVERROR(EINVAL); - len = bytestream2_get_be16u(&s->g); - switch (marker){ - case J2K_SIZ: - ret = get_siz(s); - break; - case J2K_COC: - ret = get_coc(s, codsty, properties); - break; - case J2K_COD: - ret = get_cod(s, codsty, properties); - break; - case J2K_QCC: - ret = get_qcc(s, len, qntsty, properties); - break; - case J2K_QCD: - ret = get_qcd(s, len, qntsty, properties); - break; - case J2K_SOT: - if (!(ret = get_sot(s))){ - codsty = s->tile[s->curtileno].codsty; - qntsty = s->tile[s->curtileno].qntsty; - properties = s->tile[s->curtileno].properties; - } - break; - case J2K_COM: - // the comment is ignored - bytestream2_skip(&s->g, len - 2); - break; - default: - av_log(s->avctx, AV_LOG_ERROR, "unsupported marker 0x%.4X at pos 0x%x\n", marker, bytestream2_tell(&s->g) - 4); - bytestream2_skip(&s->g, len - 2); - break; - } - if (bytestream2_tell(&s->g) - oldpos != len || ret){ - av_log(s->avctx, AV_LOG_ERROR, "error during processing marker segment %.4x\n", marker); - return ret ? ret : -1; - } - } - return 0; -} - -static int jp2_find_codestream(J2kDecoderContext *s) -{ - uint32_t atom_size, atom; - int found_codestream = 0, search_range = 10; - - while(!found_codestream && search_range && bytestream2_get_bytes_left(&s->g) >= 8) { - atom_size = bytestream2_get_be32u(&s->g); - atom = bytestream2_get_be32u(&s->g); - if (atom == JP2_CODESTREAM) { - found_codestream = 1; - } else { - if (bytestream2_get_bytes_left(&s->g) < atom_size - 8) - return 0; - bytestream2_skipu(&s->g, atom_size - 8); - search_range--; - } - } - - if (found_codestream) - return 1; - return 0; -} - -static int decode_frame(AVCodecContext *avctx, - void *data, int *got_frame, - AVPacket *avpkt) -{ - J2kDecoderContext *s = avctx->priv_data; - AVFrame *picture = data; - int tileno, ret; - - s->picture = picture; - - bytestream2_init(&s->g, avpkt->data, avpkt->size); - s->curtileno = -1; - - if (bytestream2_get_bytes_left(&s->g) < 2) { - ret = AVERROR(EINVAL); - goto err_out; - } - - // check if the image is in jp2 format - if (bytestream2_get_bytes_left(&s->g) >= 12 && - (bytestream2_get_be32u(&s->g) == 12) && - (bytestream2_get_be32u(&s->g) == JP2_SIG_TYPE) && - (bytestream2_get_be32u(&s->g) == JP2_SIG_VALUE)) { - if(!jp2_find_codestream(s)) { - av_log(avctx, AV_LOG_ERROR, "couldn't find jpeg2k codestream atom\n"); - ret = -1; - goto err_out; - } - } else { - bytestream2_seek(&s->g, 0, SEEK_SET); - } - - if (bytestream2_get_be16u(&s->g) != J2K_SOC){ - av_log(avctx, AV_LOG_ERROR, "SOC marker not present\n"); - ret = -1; - goto err_out; - } - if (ret = decode_codestream(s)) - goto err_out; - - for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++) - if (ret = decode_tile(s, s->tile + tileno)) - goto err_out; - - cleanup(s); - - *got_frame = 1; - - return bytestream2_tell(&s->g); - -err_out: - cleanup(s); - return ret; -} - -static av_cold int j2kdec_init(AVCodecContext *avctx) -{ - J2kDecoderContext *s = avctx->priv_data; - - s->avctx = avctx; - - ff_j2k_init_tier1_luts(); - - return 0; -} - -AVCodec ff_jpeg2000_decoder = { - .name = "j2k", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_JPEG2000, - .priv_data_size = sizeof(J2kDecoderContext), - .init = j2kdec_init, - .decode = decode_frame, - .capabilities = CODEC_CAP_EXPERIMENTAL, - .long_name = NULL_IF_CONFIG_SMALL("JPEG 2000"), -}; diff --git a/ffmpeg/libavcodec/j2kenc.c b/ffmpeg/libavcodec/j2kenc.c index 5d447ed..498c7c0 100644 --- a/ffmpeg/libavcodec/j2kenc.c +++ b/ffmpeg/libavcodec/j2kenc.c @@ -29,7 +29,7 @@ #include "avcodec.h" #include "internal.h" #include "bytestream.h" -#include "j2k.h" +#include "jpeg2000.h" #include "libavutil/common.h" #define NMSEDEC_BITS 7 @@ -55,12 +55,12 @@ static const int dwt_norms[2][4][10] = { // [dwt_type][band][rlevel] (multiplied }; typedef struct { - J2kComponent *comp; -} J2kTile; + Jpeg2000Component *comp; +} Jpeg2000Tile; typedef struct { AVCodecContext *avctx; - AVFrame picture; + const AVFrame *picture; int width, height; ///< image width and height uint8_t cbps[4]; ///< bits per sample in particular components @@ -77,11 +77,11 @@ typedef struct { int64_t lambda; - J2kCodingStyle codsty; - J2kQuantStyle qntsty; + Jpeg2000CodingStyle codsty; + Jpeg2000QuantStyle qntsty; - J2kTile *tile; -} J2kEncoderContext; + Jpeg2000Tile *tile; +} Jpeg2000EncoderContext; /* debug */ @@ -94,14 +94,14 @@ static void nspaces(FILE *fd, int n) while(n--) putc(' ', fd); } -static void printcomp(J2kComponent *comp) +static void printcomp(Jpeg2000Component *comp) { int i; for (i = 0; i < comp->y1 - comp->y0; i++) - ff_j2k_printv(comp->data + i * (comp->x1 - comp->x0), comp->x1 - comp->x0); + ff_jpeg2000_printv(comp->i_data + i * (comp->x1 - comp->x0), comp->x1 - comp->x0); } -static void dump(J2kEncoderContext *s, FILE *fd) +static void dump(Jpeg2000EncoderContext *s, FILE *fd) { int tileno, compno, reslevelno, bandno, precno; fprintf(fd, "XSiz = %d, YSiz = %d, tile_width = %d, tile_height = %d\n" @@ -110,18 +110,18 @@ static void dump(J2kEncoderContext *s, FILE *fd) s->width, s->height, s->tile_width, s->tile_height, s->numXtiles, s->numYtiles, s->ncomponents); for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ - J2kTile *tile = s->tile + tileno; + Jpeg2000Tile *tile = s->tile + tileno; nspaces(fd, 2); fprintf(fd, "tile %d:\n", tileno); for(compno = 0; compno < s->ncomponents; compno++){ - J2kComponent *comp = tile->comp + compno; + Jpeg2000Component *comp = tile->comp + compno; nspaces(fd, 4); fprintf(fd, "component %d:\n", compno); nspaces(fd, 4); fprintf(fd, "x0 = %d, x1 = %d, y0 = %d, y1 = %d\n", comp->x0, comp->x1, comp->y0, comp->y1); for(reslevelno = 0; reslevelno < s->nreslevels; reslevelno++){ - J2kResLevel *reslevel = comp->reslevel + reslevelno; + Jpeg2000ResLevel *reslevel = comp->reslevel + reslevelno; nspaces(fd, 6); fprintf(fd, "reslevel %d:\n", reslevelno); nspaces(fd, 6); @@ -129,7 +129,7 @@ static void dump(J2kEncoderContext *s, FILE *fd) reslevel->x0, reslevel->x1, reslevel->y0, reslevel->y1, reslevel->nbands); for(bandno = 0; bandno < reslevel->nbands; bandno++){ - J2kBand *band = reslevel->band + bandno; + Jpeg2000Band *band = reslevel->band + bandno; nspaces(fd, 8); fprintf(fd, "band %d:\n", bandno); nspaces(fd, 8); @@ -140,7 +140,7 @@ static void dump(J2kEncoderContext *s, FILE *fd) band->codeblock_width, band->codeblock_height, band->cblknx, band->cblkny); for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){ - J2kPrec *prec = band->prec + precno; + Jpeg2000Prec *prec = band->prec + precno; nspaces(fd, 10); fprintf(fd, "prec %d:\n", precno); nspaces(fd, 10); @@ -157,7 +157,7 @@ static void dump(J2kEncoderContext *s, FILE *fd) /* bitstream routines */ /** put n times val bit */ -static void put_bits(J2kEncoderContext *s, int val, int n) // TODO: optimize +static void put_bits(Jpeg2000EncoderContext *s, int val, int n) // TODO: optimize { while (n-- > 0){ if (s->bit_index == 8) @@ -170,14 +170,14 @@ static void put_bits(J2kEncoderContext *s, int val, int n) // TODO: optimize } /** put n least significant bits of a number num */ -static void put_num(J2kEncoderContext *s, int num, int n) +static void put_num(Jpeg2000EncoderContext *s, int num, int n) { while(--n >= 0) put_bits(s, (num >> n) & 1, 1); } /** flush the bitstream */ -static void j2k_flush(J2kEncoderContext *s) +static void j2k_flush(Jpeg2000EncoderContext *s) { if (s->bit_index){ s->bit_index = 0; @@ -188,9 +188,9 @@ static void j2k_flush(J2kEncoderContext *s) /* tag tree routines */ /** code the value stored in node */ -static void tag_tree_code(J2kEncoderContext *s, J2kTgtNode *node, int threshold) +static void tag_tree_code(Jpeg2000EncoderContext *s, Jpeg2000TgtNode *node, int threshold) { - J2kTgtNode *stack[30]; + Jpeg2000TgtNode *stack[30]; int sp = 1, curval = 0; stack[0] = node; @@ -216,7 +216,7 @@ static void tag_tree_code(J2kEncoderContext *s, J2kTgtNode *node, int threshold) } /** update the value in node */ -static void tag_tree_update(J2kTgtNode *node) +static void tag_tree_update(Jpeg2000TgtNode *node) { int lev = 0; while (node->parent){ @@ -228,14 +228,14 @@ static void tag_tree_update(J2kTgtNode *node) } } -static int put_siz(J2kEncoderContext *s) +static int put_siz(Jpeg2000EncoderContext *s) { int i; if (s->buf_end - s->buf < 40 + 3 * s->ncomponents) return -1; - bytestream_put_be16(&s->buf, J2K_SIZ); + bytestream_put_be16(&s->buf, JPEG2000_SIZ); bytestream_put_be16(&s->buf, 38 + 3 * s->ncomponents); // Lsiz bytestream_put_be16(&s->buf, 0); // Rsiz bytestream_put_be32(&s->buf, s->width); // width @@ -257,14 +257,14 @@ static int put_siz(J2kEncoderContext *s) return 0; } -static int put_cod(J2kEncoderContext *s) +static int put_cod(Jpeg2000EncoderContext *s) { - J2kCodingStyle *codsty = &s->codsty; + Jpeg2000CodingStyle *codsty = &s->codsty; if (s->buf_end - s->buf < 14) return -1; - bytestream_put_be16(&s->buf, J2K_COD); + bytestream_put_be16(&s->buf, JPEG2000_COD); bytestream_put_be16(&s->buf, 12); // Lcod bytestream_put_byte(&s->buf, 0); // Scod // SGcod @@ -280,17 +280,17 @@ static int put_cod(J2kEncoderContext *s) bytestream_put_byte(&s->buf, codsty->log2_cblk_width-2); // cblk width bytestream_put_byte(&s->buf, codsty->log2_cblk_height-2); // cblk height bytestream_put_byte(&s->buf, 0); // cblk style - bytestream_put_byte(&s->buf, codsty->transform); // transformation + bytestream_put_byte(&s->buf, codsty->transform == FF_DWT53); // transformation return 0; } -static int put_qcd(J2kEncoderContext *s, int compno) +static int put_qcd(Jpeg2000EncoderContext *s, int compno) { int i, size; - J2kCodingStyle *codsty = &s->codsty; - J2kQuantStyle *qntsty = &s->qntsty; + Jpeg2000CodingStyle *codsty = &s->codsty; + Jpeg2000QuantStyle *qntsty = &s->qntsty; - if (qntsty->quantsty == J2K_QSTY_NONE) + if (qntsty->quantsty == JPEG2000_QSTY_NONE) size = 4 + 3 * (codsty->nreslevels-1); else // QSTY_SE size = 5 + 6 * (codsty->nreslevels-1); @@ -298,10 +298,10 @@ static int put_qcd(J2kEncoderContext *s, int compno) if (s->buf_end - s->buf < size + 2) return -1; - bytestream_put_be16(&s->buf, J2K_QCD); + bytestream_put_be16(&s->buf, JPEG2000_QCD); bytestream_put_be16(&s->buf, size); // LQcd bytestream_put_byte(&s->buf, (qntsty->nguardbits << 5) | qntsty->quantsty); // Sqcd - if (qntsty->quantsty == J2K_QSTY_NONE) + if (qntsty->quantsty == JPEG2000_QSTY_NONE) for (i = 0; i < codsty->nreslevels * 3 - 2; i++) bytestream_put_byte(&s->buf, qntsty->expn[i] << 3); else // QSTY_SE @@ -310,14 +310,14 @@ static int put_qcd(J2kEncoderContext *s, int compno) return 0; } -static uint8_t *put_sot(J2kEncoderContext *s, int tileno) +static uint8_t *put_sot(Jpeg2000EncoderContext *s, int tileno) { uint8_t *psotptr; if (s->buf_end - s->buf < 12) return NULL; - bytestream_put_be16(&s->buf, J2K_SOT); + bytestream_put_be16(&s->buf, JPEG2000_SOT); bytestream_put_be16(&s->buf, 10); // Lsot bytestream_put_be16(&s->buf, tileno); // Isot @@ -334,67 +334,74 @@ static uint8_t *put_sot(J2kEncoderContext *s, int tileno) * allocate memory for them * divide the input image into tile-components */ -static int init_tiles(J2kEncoderContext *s) +static int init_tiles(Jpeg2000EncoderContext *s) { int tileno, tilex, tiley, compno; - J2kCodingStyle *codsty = &s->codsty; - J2kQuantStyle *qntsty = &s->qntsty; + Jpeg2000CodingStyle *codsty = &s->codsty; + Jpeg2000QuantStyle *qntsty = &s->qntsty; - s->numXtiles = ff_j2k_ceildiv(s->width, s->tile_width); - s->numYtiles = ff_j2k_ceildiv(s->height, s->tile_height); + s->numXtiles = ff_jpeg2000_ceildiv(s->width, s->tile_width); + s->numYtiles = ff_jpeg2000_ceildiv(s->height, s->tile_height); - s->tile = av_malloc(s->numXtiles * s->numYtiles * sizeof(J2kTile)); + s->tile = av_malloc(s->numXtiles * s->numYtiles * sizeof(Jpeg2000Tile)); if (!s->tile) return AVERROR(ENOMEM); for (tileno = 0, tiley = 0; tiley < s->numYtiles; tiley++) for (tilex = 0; tilex < s->numXtiles; tilex++, tileno++){ - J2kTile *tile = s->tile + tileno; + Jpeg2000Tile *tile = s->tile + tileno; - tile->comp = av_malloc(s->ncomponents * sizeof(J2kComponent)); + tile->comp = av_mallocz(s->ncomponents * sizeof(Jpeg2000Component)); if (!tile->comp) return AVERROR(ENOMEM); for (compno = 0; compno < s->ncomponents; compno++){ - J2kComponent *comp = tile->comp + compno; + Jpeg2000Component *comp = tile->comp + compno; int ret, i, j; - comp->coord[0][0] = tilex * s->tile_width; - comp->coord[0][1] = FFMIN((tilex+1)*s->tile_width, s->width); - comp->coord[1][0] = tiley * s->tile_height; - comp->coord[1][1] = FFMIN((tiley+1)*s->tile_height, s->height); + comp->coord[0][0] = comp->coord_o[0][0] = tilex * s->tile_width; + comp->coord[0][1] = comp->coord_o[0][1] = FFMIN((tilex+1)*s->tile_width, s->width); + comp->coord[1][0] = comp->coord_o[1][0] = tiley * s->tile_height; + comp->coord[1][1] = comp->coord_o[1][1] = FFMIN((tiley+1)*s->tile_height, s->height); if (compno > 0) for (i = 0; i < 2; i++) for (j = 0; j < 2; j++) - comp->coord[i][j] = ff_j2k_ceildivpow2(comp->coord[i][j], s->chroma_shift[i]); - - if (ret = ff_j2k_init_component(comp, codsty, qntsty, s->cbps[compno], compno?1<chroma_shift[0]:1, compno?1<chroma_shift[1]:1)) + comp->coord[i][j] = comp->coord_o[i][j] = ff_jpeg2000_ceildivpow2(comp->coord[i][j], s->chroma_shift[i]); + + if (ret = ff_jpeg2000_init_component(comp, + codsty, + qntsty, + s->cbps[compno], + compno?1<chroma_shift[0]:1, + compno?1<chroma_shift[1]:1, + s->avctx + )) return ret; } } return 0; } -static void copy_frame(J2kEncoderContext *s) +static void copy_frame(Jpeg2000EncoderContext *s) { int tileno, compno, i, y, x; uint8_t *line; for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ - J2kTile *tile = s->tile + tileno; + Jpeg2000Tile *tile = s->tile + tileno; if (s->planar){ for (compno = 0; compno < s->ncomponents; compno++){ - J2kComponent *comp = tile->comp + compno; - int *dst = comp->data; - line = s->picture.data[compno] - + comp->coord[1][0] * s->picture.linesize[compno] + Jpeg2000Component *comp = tile->comp + compno; + int *dst = comp->i_data; + line = s->picture->data[compno] + + comp->coord[1][0] * s->picture->linesize[compno] + comp->coord[0][0]; for (y = comp->coord[1][0]; y < comp->coord[1][1]; y++){ uint8_t *ptr = line; for (x = comp->coord[0][0]; x < comp->coord[0][1]; x++) *dst++ = *ptr++ - (1 << 7); - line += s->picture.linesize[compno]; + line += s->picture->linesize[compno]; } } } else{ - line = s->picture.data[0] + tile->comp[0].coord[1][0] * s->picture.linesize[0] + line = s->picture->data[0] + tile->comp[0].coord[1][0] * s->picture->linesize[0] + tile->comp[0].coord[0][0] * s->ncomponents; i = 0; @@ -402,20 +409,20 @@ static void copy_frame(J2kEncoderContext *s) uint8_t *ptr = line; for (x = tile->comp[0].coord[0][0]; x < tile->comp[0].coord[0][1]; x++, i++){ for (compno = 0; compno < s->ncomponents; compno++){ - tile->comp[compno].data[i] = *ptr++ - (1 << 7); + tile->comp[compno].i_data[i] = *ptr++ - (1 << 7); } } - line += s->picture.linesize[0]; + line += s->picture->linesize[0]; } } } } -static void init_quantization(J2kEncoderContext *s) +static void init_quantization(Jpeg2000EncoderContext *s) { int compno, reslevelno, bandno; - J2kQuantStyle *qntsty = &s->qntsty; - J2kCodingStyle *codsty = &s->codsty; + Jpeg2000QuantStyle *qntsty = &s->qntsty; + Jpeg2000CodingStyle *codsty = &s->codsty; for (compno = 0; compno < s->ncomponents; compno++){ int gbandno = 0; @@ -425,7 +432,7 @@ static void init_quantization(J2kEncoderContext *s) for (bandno = 0; bandno < nbands; bandno++, gbandno++){ int expn, mant; - if (codsty->transform == FF_DWT97){ + if (codsty->transform == FF_DWT97_INT){ int bandpos = bandno + (reslevelno>0), ss = 81920000 / dwt_norms[0][bandpos][lev], log = av_log2(ss); @@ -473,54 +480,52 @@ static int getnmsedec_ref(int x, int bpno) return lut_nmsedec_ref0[x & ((1 << NMSEDEC_BITS) - 1)]; } -static void encode_sigpass(J2kT1Context *t1, int width, int height, int bandno, int *nmsedec, int bpno) +static void encode_sigpass(Jpeg2000T1Context *t1, int width, int height, int bandno, int *nmsedec, int bpno) { int y0, x, y, mask = 1 << (bpno + NMSEDEC_FRACBITS); - int vert_causal_ctx_csty_loc_symbol; for (y0 = 0; y0 < height; y0 += 4) for (x = 0; x < width; x++) for (y = y0; y < height && y < y0+4; y++){ - if (!(t1->flags[y+1][x+1] & J2K_T1_SIG) && (t1->flags[y+1][x+1] & J2K_T1_SIG_NB)){ - int ctxno = ff_j2k_getnbctxno(t1->flags[y+1][x+1], bandno, vert_causal_ctx_csty_loc_symbol), + if (!(t1->flags[y+1][x+1] & JPEG2000_T1_SIG) && (t1->flags[y+1][x+1] & JPEG2000_T1_SIG_NB)){ + int ctxno = ff_jpeg2000_getsigctxno(t1->flags[y+1][x+1], bandno), bit = t1->data[y][x] & mask ? 1 : 0; ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, bit); if (bit){ int xorbit; - int ctxno = ff_j2k_getsgnctxno(t1->flags[y+1][x+1], &xorbit); + int ctxno = ff_jpeg2000_getsgnctxno(t1->flags[y+1][x+1], &xorbit); ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, (t1->flags[y+1][x+1] >> 15) ^ xorbit); *nmsedec += getnmsedec_sig(t1->data[y][x], bpno + NMSEDEC_FRACBITS); - ff_j2k_set_significant(t1, x, y, t1->flags[y+1][x+1] >> 15); + ff_jpeg2000_set_significance(t1, x, y, t1->flags[y+1][x+1] >> 15); } - t1->flags[y+1][x+1] |= J2K_T1_VIS; + t1->flags[y+1][x+1] |= JPEG2000_T1_VIS; } } } -static void encode_refpass(J2kT1Context *t1, int width, int height, int *nmsedec, int bpno) +static void encode_refpass(Jpeg2000T1Context *t1, int width, int height, int *nmsedec, int bpno) { int y0, x, y, mask = 1 << (bpno + NMSEDEC_FRACBITS); for (y0 = 0; y0 < height; y0 += 4) for (x = 0; x < width; x++) for (y = y0; y < height && y < y0+4; y++) - if ((t1->flags[y+1][x+1] & (J2K_T1_SIG | J2K_T1_VIS)) == J2K_T1_SIG){ - int ctxno = ff_j2k_getrefctxno(t1->flags[y+1][x+1]); + if ((t1->flags[y+1][x+1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS)) == JPEG2000_T1_SIG){ + int ctxno = ff_jpeg2000_getrefctxno(t1->flags[y+1][x+1]); *nmsedec += getnmsedec_ref(t1->data[y][x], bpno + NMSEDEC_FRACBITS); ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, t1->data[y][x] & mask ? 1:0); - t1->flags[y+1][x+1] |= J2K_T1_REF; + t1->flags[y+1][x+1] |= JPEG2000_T1_REF; } } -static void encode_clnpass(J2kT1Context *t1, int width, int height, int bandno, int *nmsedec, int bpno) +static void encode_clnpass(Jpeg2000T1Context *t1, int width, int height, int bandno, int *nmsedec, int bpno) { int y0, x, y, mask = 1 << (bpno + NMSEDEC_FRACBITS); - int vert_causal_ctx_csty_loc_symbol; for (y0 = 0; y0 < height; y0 += 4) for (x = 0; x < width; x++){ if (y0 + 3 < height && !( - (t1->flags[y0+1][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)) || - (t1->flags[y0+2][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)) || - (t1->flags[y0+3][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)) || - (t1->flags[y0+4][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)))) + (t1->flags[y0+1][x+1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) || + (t1->flags[y0+2][x+1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) || + (t1->flags[y0+3][x+1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) || + (t1->flags[y0+4][x+1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)))) { // aggregation mode int rlen; @@ -533,40 +538,40 @@ static void encode_clnpass(J2kT1Context *t1, int width, int height, int bandno, ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI, rlen >> 1); ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI, rlen & 1); for (y = y0 + rlen; y < y0 + 4; y++){ - if (!(t1->flags[y+1][x+1] & (J2K_T1_SIG | J2K_T1_VIS))){ - int ctxno = ff_j2k_getnbctxno(t1->flags[y+1][x+1], bandno, vert_causal_ctx_csty_loc_symbol); + if (!(t1->flags[y+1][x+1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS))){ + int ctxno = ff_jpeg2000_getsigctxno(t1->flags[y+1][x+1], bandno); if (y > y0 + rlen) ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, t1->data[y][x] & mask ? 1:0); if (t1->data[y][x] & mask){ // newly significant int xorbit; - int ctxno = ff_j2k_getsgnctxno(t1->flags[y+1][x+1], &xorbit); + int ctxno = ff_jpeg2000_getsgnctxno(t1->flags[y+1][x+1], &xorbit); *nmsedec += getnmsedec_sig(t1->data[y][x], bpno + NMSEDEC_FRACBITS); ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, (t1->flags[y+1][x+1] >> 15) ^ xorbit); - ff_j2k_set_significant(t1, x, y, t1->flags[y+1][x+1] >> 15); + ff_jpeg2000_set_significance(t1, x, y, t1->flags[y+1][x+1] >> 15); } } - t1->flags[y+1][x+1] &= ~J2K_T1_VIS; + t1->flags[y+1][x+1] &= ~JPEG2000_T1_VIS; } } else{ for (y = y0; y < y0 + 4 && y < height; y++){ - if (!(t1->flags[y+1][x+1] & (J2K_T1_SIG | J2K_T1_VIS))){ - int ctxno = ff_j2k_getnbctxno(t1->flags[y+1][x+1], bandno, vert_causal_ctx_csty_loc_symbol); + if (!(t1->flags[y+1][x+1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS))){ + int ctxno = ff_jpeg2000_getsigctxno(t1->flags[y+1][x+1], bandno); ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, t1->data[y][x] & mask ? 1:0); if (t1->data[y][x] & mask){ // newly significant int xorbit; - int ctxno = ff_j2k_getsgnctxno(t1->flags[y+1][x+1], &xorbit); + int ctxno = ff_jpeg2000_getsgnctxno(t1->flags[y+1][x+1], &xorbit); *nmsedec += getnmsedec_sig(t1->data[y][x], bpno + NMSEDEC_FRACBITS); ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, (t1->flags[y+1][x+1] >> 15) ^ xorbit); - ff_j2k_set_significant(t1, x, y, t1->flags[y+1][x+1] >> 15); + ff_jpeg2000_set_significance(t1, x, y, t1->flags[y+1][x+1] >> 15); } } - t1->flags[y+1][x+1] &= ~J2K_T1_VIS; + t1->flags[y+1][x+1] &= ~JPEG2000_T1_VIS; } } } } -static void encode_cblk(J2kEncoderContext *s, J2kT1Context *t1, J2kCblk *cblk, J2kTile *tile, +static void encode_cblk(Jpeg2000EncoderContext *s, Jpeg2000T1Context *t1, Jpeg2000Cblk *cblk, Jpeg2000Tile *tile, int width, int height, int bandpos, int lev) { int pass_t = 2, passno, x, y, max=0, nmsedec, bpno; @@ -578,7 +583,7 @@ static void encode_cblk(J2kEncoderContext *s, J2kT1Context *t1, J2kCblk *cblk, J for (y = 0; y < height; y++){ for (x = 0; x < width; x++){ if (t1->data[y][x] < 0){ - t1->flags[y+1][x+1] |= J2K_T1_SGN; + t1->flags[y+1][x+1] |= JPEG2000_T1_SGN; t1->data[y][x] = -t1->data[y][x]; } max = FFMAX(max, t1->data[y][x]); @@ -625,7 +630,7 @@ static void encode_cblk(J2kEncoderContext *s, J2kT1Context *t1, J2kCblk *cblk, J /* tier-2 routines: */ -static void putnumpasses(J2kEncoderContext *s, int n) +static void putnumpasses(Jpeg2000EncoderContext *s, int n) { if (n == 1) put_num(s, 0, 1); @@ -640,7 +645,7 @@ static void putnumpasses(J2kEncoderContext *s, int n) } -static int encode_packet(J2kEncoderContext *s, J2kResLevel *rlevel, int precno, +static int encode_packet(Jpeg2000EncoderContext *s, Jpeg2000ResLevel *rlevel, int precno, uint8_t *expn, int numgbits) { int bandno, empty = 1; @@ -667,28 +672,28 @@ static int encode_packet(J2kEncoderContext *s, J2kResLevel *rlevel, int precno, } for (bandno = 0; bandno < rlevel->nbands; bandno++){ - J2kBand *band = rlevel->band + bandno; - J2kPrec *prec = band->prec + precno; + Jpeg2000Band *band = rlevel->band + bandno; + Jpeg2000Prec *prec = band->prec + precno; int yi, xi, pos; - int cblknw = prec->xi1 - prec->xi0; + int cblknw = prec->nb_codeblocks_width; if (band->coord[0][0] == band->coord[0][1] || band->coord[1][0] == band->coord[1][1]) continue; - for (pos=0, yi = prec->yi0; yi < prec->yi1; yi++){ - for (xi = prec->xi0; xi < prec->xi1; xi++, pos++){ - prec->cblkincl[pos].val = band->cblk[yi * cblknw + xi].ninclpasses == 0; + for (pos=0, yi = 0; yi < prec->nb_codeblocks_height; yi++){ + for (xi = 0; xi < cblknw; xi++, pos++){ + prec->cblkincl[pos].val = prec->cblk[yi * cblknw + xi].ninclpasses == 0; tag_tree_update(prec->cblkincl + pos); - prec->zerobits[pos].val = expn[bandno] + numgbits - 1 - band->cblk[yi * cblknw + xi].nonzerobits; + prec->zerobits[pos].val = expn[bandno] + numgbits - 1 - prec->cblk[yi * cblknw + xi].nonzerobits; tag_tree_update(prec->zerobits + pos); } } - for (pos=0, yi = prec->yi0; yi < prec->yi1; yi++){ - for (xi = prec->xi0; xi < prec->xi1; xi++, pos++){ + for (pos=0, yi = 0; yi < prec->nb_codeblocks_height; yi++){ + for (xi = 0; xi < cblknw; xi++, pos++){ int pad = 0, llen, length; - J2kCblk *cblk = band->cblk + yi * cblknw + xi; + Jpeg2000Cblk *cblk = prec->cblk + yi * cblknw + xi; if (s->buf_end - s->buf < 20) // approximately return -1; @@ -717,13 +722,13 @@ static int encode_packet(J2kEncoderContext *s, J2kResLevel *rlevel, int precno, } j2k_flush(s); for (bandno = 0; bandno < rlevel->nbands; bandno++){ - J2kBand *band = rlevel->band + bandno; - J2kPrec *prec = band->prec + precno; - int yi, cblknw = prec->xi1 - prec->xi0; - for (yi = prec->yi0; yi < prec->yi1; yi++){ + Jpeg2000Band *band = rlevel->band + bandno; + Jpeg2000Prec *prec = band->prec + precno; + int yi, cblknw = prec->nb_codeblocks_width; + for (yi =0; yi < prec->nb_codeblocks_height; yi++){ int xi; - for (xi = prec->xi0; xi < prec->xi1; xi++){ - J2kCblk *cblk = band->cblk + yi * cblknw + xi; + for (xi = 0; xi < cblknw; xi++){ + Jpeg2000Cblk *cblk = prec->cblk + yi * cblknw + xi; if (cblk->ninclpasses){ if (s->buf_end - s->buf < cblk->passes[cblk->ninclpasses-1].rate) return -1; @@ -735,18 +740,18 @@ static int encode_packet(J2kEncoderContext *s, J2kResLevel *rlevel, int precno, return 0; } -static int encode_packets(J2kEncoderContext *s, J2kTile *tile, int tileno) +static int encode_packets(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int tileno) { int compno, reslevelno, ret; - J2kCodingStyle *codsty = &s->codsty; - J2kQuantStyle *qntsty = &s->qntsty; + Jpeg2000CodingStyle *codsty = &s->codsty; + Jpeg2000QuantStyle *qntsty = &s->qntsty; av_log(s->avctx, AV_LOG_DEBUG, "tier2\n"); // lay-rlevel-comp-pos progression for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ for (compno = 0; compno < s->ncomponents; compno++){ int precno; - J2kResLevel *reslevel = s->tile[tileno].comp[compno].reslevel + reslevelno; + Jpeg2000ResLevel *reslevel = s->tile[tileno].comp[compno].reslevel + reslevelno; for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){ if (ret = encode_packet(s, reslevel, precno, qntsty->expn + (reslevelno ? 3*reslevelno-2 : 0), qntsty->nguardbits)) @@ -758,7 +763,7 @@ static int encode_packets(J2kEncoderContext *s, J2kTile *tile, int tileno) return 0; } -static int getcut(J2kCblk *cblk, int64_t lambda, int dwt_norm) +static int getcut(Jpeg2000Cblk *cblk, int64_t lambda, int dwt_norm) { int passno, res = 0; for (passno = 0; passno < cblk->npasses; passno++){ @@ -776,54 +781,58 @@ static int getcut(J2kCblk *cblk, int64_t lambda, int dwt_norm) return res; } -static void truncpasses(J2kEncoderContext *s, J2kTile *tile) +static void truncpasses(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile) { - int compno, reslevelno, bandno, cblkno, lev; - J2kCodingStyle *codsty = &s->codsty; + int precno, compno, reslevelno, bandno, cblkno, lev; + Jpeg2000CodingStyle *codsty = &s->codsty; for (compno = 0; compno < s->ncomponents; compno++){ - J2kComponent *comp = tile->comp + compno; + Jpeg2000Component *comp = tile->comp + compno; for (reslevelno = 0, lev = codsty->nreslevels-1; reslevelno < codsty->nreslevels; reslevelno++, lev--){ - J2kResLevel *reslevel = comp->reslevel + reslevelno; + Jpeg2000ResLevel *reslevel = comp->reslevel + reslevelno; - for (bandno = 0; bandno < reslevel->nbands ; bandno++){ - int bandpos = bandno + (reslevelno > 0); - J2kBand *band = reslevel->band + bandno; + for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){ + for (bandno = 0; bandno < reslevel->nbands ; bandno++){ + int bandpos = bandno + (reslevelno > 0); + Jpeg2000Band *band = reslevel->band + bandno; + Jpeg2000Prec *prec = band->prec + precno; - for (cblkno = 0; cblkno < band->cblknx * band->cblkny; cblkno++){ - J2kCblk *cblk = band->cblk + cblkno; + for (cblkno = 0; cblkno < prec->nb_codeblocks_height * prec->nb_codeblocks_width; cblkno++){ + Jpeg2000Cblk *cblk = prec->cblk + cblkno; - cblk->ninclpasses = getcut(cblk, s->lambda, - (int64_t)dwt_norms[codsty->transform][bandpos][lev] * (int64_t)band->stepsize >> 13); + cblk->ninclpasses = getcut(cblk, s->lambda, + (int64_t)dwt_norms[codsty->transform == FF_DWT53][bandpos][lev] * (int64_t)band->i_stepsize >> 15); + } } } } } } -static int encode_tile(J2kEncoderContext *s, J2kTile *tile, int tileno) +static int encode_tile(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int tileno) { int compno, reslevelno, bandno, ret; - J2kT1Context t1; - J2kCodingStyle *codsty = &s->codsty; + Jpeg2000T1Context t1; + Jpeg2000CodingStyle *codsty = &s->codsty; for (compno = 0; compno < s->ncomponents; compno++){ - J2kComponent *comp = s->tile[tileno].comp + compno; + Jpeg2000Component *comp = s->tile[tileno].comp + compno; av_log(s->avctx, AV_LOG_DEBUG,"dwt\n"); - if (ret = ff_j2k_dwt_encode(&comp->dwt, comp->data)) + if (ret = ff_dwt_encode(&comp->dwt, comp->i_data)) return ret; av_log(s->avctx, AV_LOG_DEBUG,"after dwt -> tier1\n"); for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ - J2kResLevel *reslevel = comp->reslevel + reslevelno; + Jpeg2000ResLevel *reslevel = comp->reslevel + reslevelno; for (bandno = 0; bandno < reslevel->nbands ; bandno++){ - J2kBand *band = reslevel->band + bandno; + Jpeg2000Band *band = reslevel->band + bandno; + Jpeg2000Prec *prec = band->prec; // we support only 1 precinct per band ATM in the encoder int cblkx, cblky, cblkno=0, xx0, x0, xx1, y0, yy0, yy1, bandpos; yy0 = bandno == 0 ? 0 : comp->reslevel[reslevelno-1].coord[1][1] - comp->reslevel[reslevelno-1].coord[1][0]; y0 = yy0; - yy1 = FFMIN(ff_j2k_ceildiv(band->coord[1][0] + 1, band->codeblock_height) * band->codeblock_height, + yy1 = FFMIN(ff_jpeg2000_ceildivpow2(band->coord[1][0] + 1, band->log2_cblk_height) << band->log2_cblk_height, band->coord[1][1]) - band->coord[1][0] + yy0; if (band->coord[0][0] == band->coord[0][1] || band->coord[1][0] == band->coord[1][1]) @@ -831,41 +840,41 @@ static int encode_tile(J2kEncoderContext *s, J2kTile *tile, int tileno) bandpos = bandno + (reslevelno > 0); - for (cblky = 0; cblky < band->cblkny; cblky++){ + for (cblky = 0; cblky < prec->nb_codeblocks_height; cblky++){ if (reslevelno == 0 || bandno == 1) xx0 = 0; else xx0 = comp->reslevel[reslevelno-1].coord[0][1] - comp->reslevel[reslevelno-1].coord[0][0]; x0 = xx0; - xx1 = FFMIN(ff_j2k_ceildiv(band->coord[0][0] + 1, band->codeblock_width) * band->codeblock_width, + xx1 = FFMIN(ff_jpeg2000_ceildivpow2(band->coord[0][0] + 1, band->log2_cblk_width) << band->log2_cblk_width, band->coord[0][1]) - band->coord[0][0] + xx0; - for (cblkx = 0; cblkx < band->cblknx; cblkx++, cblkno++){ + for (cblkx = 0; cblkx < prec->nb_codeblocks_width; cblkx++, cblkno++){ int y, x; if (codsty->transform == FF_DWT53){ for (y = yy0; y < yy1; y++){ int *ptr = t1.data[y-yy0]; for (x = xx0; x < xx1; x++){ - *ptr++ = comp->data[(comp->coord[0][1] - comp->coord[0][0]) * y + x] << NMSEDEC_FRACBITS; + *ptr++ = comp->i_data[(comp->coord[0][1] - comp->coord[0][0]) * y + x] << NMSEDEC_FRACBITS; } } } else{ for (y = yy0; y < yy1; y++){ int *ptr = t1.data[y-yy0]; for (x = xx0; x < xx1; x++){ - *ptr = (comp->data[(comp->coord[0][1] - comp->coord[0][0]) * y + x]); - *ptr = (int64_t)*ptr * (int64_t)(8192 * 8192 / band->stepsize) >> 13 - NMSEDEC_FRACBITS; + *ptr = (comp->i_data[(comp->coord[0][1] - comp->coord[0][0]) * y + x]); + *ptr = (int64_t)*ptr * (int64_t)(16384 * 65536 / band->i_stepsize) >> 15 - NMSEDEC_FRACBITS; ptr++; } } } - encode_cblk(s, &t1, band->cblk + cblkno, tile, xx1 - xx0, yy1 - yy0, + encode_cblk(s, &t1, prec->cblk + cblkno, tile, xx1 - xx0, yy1 - yy0, bandpos, codsty->nreslevels - reslevelno - 1); xx0 = xx1; - xx1 = FFMIN(xx1 + band->codeblock_width, band->coord[0][1] - band->coord[0][0] + x0); + xx1 = FFMIN(xx1 + (1 << band->log2_cblk_width), band->coord[0][1] - band->coord[0][0] + x0); } yy0 = yy1; - yy1 = FFMIN(yy1 + band->codeblock_height, band->coord[1][1] - band->coord[1][0] + y0); + yy1 = FFMIN(yy1 + (1 << band->log2_cblk_height), band->coord[1][1] - band->coord[1][0] + y0); } } } @@ -880,28 +889,28 @@ static int encode_tile(J2kEncoderContext *s, J2kTile *tile, int tileno) return 0; } -static void cleanup(J2kEncoderContext *s) +static void cleanup(Jpeg2000EncoderContext *s) { int tileno, compno; - J2kCodingStyle *codsty = &s->codsty; + Jpeg2000CodingStyle *codsty = &s->codsty; for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ for (compno = 0; compno < s->ncomponents; compno++){ - J2kComponent *comp = s->tile[tileno].comp + compno; - ff_j2k_cleanup(comp, codsty); + Jpeg2000Component *comp = s->tile[tileno].comp + compno; + ff_jpeg2000_cleanup(comp, codsty); } av_freep(&s->tile[tileno].comp); } av_freep(&s->tile); } -static void reinit(J2kEncoderContext *s) +static void reinit(Jpeg2000EncoderContext *s) { int tileno, compno; for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ - J2kTile *tile = s->tile + tileno; + Jpeg2000Tile *tile = s->tile + tileno; for (compno = 0; compno < s->ncomponents; compno++) - ff_j2k_reinit(tile->comp + compno, &s->codsty); + ff_jpeg2000_reinit(tile->comp + compno, &s->codsty); } } @@ -909,7 +918,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { int tileno, ret; - J2kEncoderContext *s = avctx->priv_data; + Jpeg2000EncoderContext *s = avctx->priv_data; if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width*avctx->height*9 + FF_MIN_BUFFER_SIZE)) < 0) return ret; @@ -918,17 +927,16 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, s->buf = s->buf_start = pkt->data; s->buf_end = pkt->data + pkt->size; - s->picture = *pict; - avctx->coded_frame= &s->picture; + s->picture = pict; - s->lambda = s->picture.quality * LAMBDA_SCALE; + s->lambda = s->picture->quality * LAMBDA_SCALE; copy_frame(s); reinit(s); if (s->buf_end - s->buf < 2) return -1; - bytestream_put_be16(&s->buf, J2K_SOC); + bytestream_put_be16(&s->buf, JPEG2000_SOC); if (ret = put_siz(s)) return ret; if (ret = put_cod(s)) @@ -942,14 +950,14 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, return -1; if (s->buf_end - s->buf < 2) return -1; - bytestream_put_be16(&s->buf, J2K_SOD); + bytestream_put_be16(&s->buf, JPEG2000_SOD); if (ret = encode_tile(s, s->tile + tileno, tileno)) return ret; bytestream_put_be32(&psotptr, s->buf - psotptr + 6); } if (s->buf_end - s->buf < 2) return -1; - bytestream_put_be16(&s->buf, J2K_EOC); + bytestream_put_be16(&s->buf, JPEG2000_EOC); av_log(s->avctx, AV_LOG_DEBUG, "end\n"); pkt->size = s->buf - s->buf_start; @@ -962,21 +970,22 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, static av_cold int j2kenc_init(AVCodecContext *avctx) { int i, ret; - J2kEncoderContext *s = avctx->priv_data; - J2kCodingStyle *codsty = &s->codsty; - J2kQuantStyle *qntsty = &s->qntsty; + Jpeg2000EncoderContext *s = avctx->priv_data; + Jpeg2000CodingStyle *codsty = &s->codsty; + Jpeg2000QuantStyle *qntsty = &s->qntsty; s->avctx = avctx; av_log(s->avctx, AV_LOG_DEBUG, "init\n"); // defaults: // TODO: implement setting non-standard precinct size - codsty->log2_prec_width = 15; - codsty->log2_prec_height = 15; + memset(codsty->log2_prec_widths , 15, sizeof(codsty->log2_prec_widths )); + memset(codsty->log2_prec_heights, 15, sizeof(codsty->log2_prec_heights)); + codsty->nreslevels2decode= codsty->nreslevels = 7; codsty->log2_cblk_width = 4; codsty->log2_cblk_height = 4; - codsty->transform = 1; + codsty->transform = avctx->prediction_method ? FF_DWT53 : FF_DWT97_INT; qntsty->nguardbits = 1; @@ -984,9 +993,9 @@ static av_cold int j2kenc_init(AVCodecContext *avctx) s->tile_height = 256; if (codsty->transform == FF_DWT53) - qntsty->quantsty = J2K_QSTY_NONE; + qntsty->quantsty = JPEG2000_QSTY_NONE; else - qntsty->quantsty = J2K_QSTY_SE; + qntsty->quantsty = JPEG2000_QSTY_SE; s->width = avctx->width; s->height = avctx->height; @@ -1005,8 +1014,8 @@ static av_cold int j2kenc_init(AVCodecContext *avctx) s->chroma_shift, s->chroma_shift + 1); } - ff_j2k_init_tier1_luts(); - + ff_jpeg2000_init_tier1_luts(); + ff_mqc_init_context_tables(); init_luts(); init_quantization(s); @@ -1020,22 +1029,22 @@ static av_cold int j2kenc_init(AVCodecContext *avctx) static int j2kenc_destroy(AVCodecContext *avctx) { - J2kEncoderContext *s = avctx->priv_data; + Jpeg2000EncoderContext *s = avctx->priv_data; cleanup(s); return 0; } AVCodec ff_jpeg2000_encoder = { - .name = "j2k", + .name = "jpeg2000", + .long_name = NULL_IF_CONFIG_SMALL("JPEG 2000"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_JPEG2000, - .priv_data_size = sizeof(J2kEncoderContext), + .priv_data_size = sizeof(Jpeg2000EncoderContext), .init = j2kenc_init, .encode2 = encode_frame, .close = j2kenc_destroy, .capabilities = CODEC_CAP_EXPERIMENTAL, - .long_name = NULL_IF_CONFIG_SMALL("JPEG 2000"), .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB24, AV_PIX_FMT_YUV444P, AV_PIX_FMT_GRAY8, /* AV_PIX_FMT_YUV420P, diff --git a/ffmpeg/libavcodec/jfdctint.c b/ffmpeg/libavcodec/jfdctint.c index ed6b7ff..6a39578 100644 --- a/ffmpeg/libavcodec/jfdctint.c +++ b/ffmpeg/libavcodec/jfdctint.c @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/jpegls.c b/ffmpeg/libavcodec/jpegls.c index dc5c9cf..216c486 100644 --- a/ffmpeg/libavcodec/jpegls.c +++ b/ffmpeg/libavcodec/jpegls.c @@ -27,61 +27,74 @@ #include "jpegls.h" -void ff_jpegls_init_state(JLSState *state){ +void ff_jpegls_init_state(JLSState *state) +{ int i; state->twonear = state->near * 2 + 1; - state->range = ((state->maxval + state->twonear - 1) / state->twonear) + 1; + state->range = (state->maxval + state->twonear - 1) / state->twonear + 1; // QBPP = ceil(log2(RANGE)) - for(state->qbpp = 0; (1 << state->qbpp) < state->range; state->qbpp++); + for (state->qbpp = 0; (1 << state->qbpp) < state->range; state->qbpp++) + ; - state->bpp = FFMAX(av_log2(state->maxval)+1, 2); + state->bpp = FFMAX(av_log2(state->maxval) + 1, 2); state->limit = 2*(state->bpp + FFMAX(state->bpp, 8)) - state->qbpp; - for(i = 0; i < 367; i++) { - state->A[i] = FFMAX((state->range + 32) >> 6, 2); + for (i = 0; i < 367; i++) { + state->A[i] = FFMAX(state->range + 32 >> 6, 2); state->N[i] = 1; } - } /** * Custom value clipping function used in T1, T2, T3 calculation */ -static inline int iso_clip(int v, int vmin, int vmax){ - if(v > vmax || v < vmin) return vmin; - else return v; +static inline int iso_clip(int v, int vmin, int vmax) +{ + if (v > vmax || v < vmin) + return vmin; + else + return v; } -void ff_jpegls_reset_coding_parameters(JLSState *s, int reset_all){ - const int basic_t1= 3; - const int basic_t2= 7; - const int basic_t3= 21; +void ff_jpegls_reset_coding_parameters(JLSState *s, int reset_all) +{ + const int basic_t1 = 3; + const int basic_t2 = 7; + const int basic_t3 = 21; int factor; - if(s->maxval==0 || reset_all) s->maxval= (1 << s->bpp) - 1; + if (s->maxval == 0 || reset_all) + s->maxval = (1 << s->bpp) - 1; - if(s->maxval >=128){ - factor= (FFMIN(s->maxval, 4095) + 128)>>8; + if (s->maxval >= 128) { + factor = FFMIN(s->maxval, 4095) + 128 >> 8; - if(s->T1==0 || reset_all) - s->T1= iso_clip(factor*(basic_t1-2) + 2 + 3*s->near, s->near+1, s->maxval); - if(s->T2==0 || reset_all) - s->T2= iso_clip(factor*(basic_t2-3) + 3 + 5*s->near, s->T1, s->maxval); - if(s->T3==0 || reset_all) - s->T3= iso_clip(factor*(basic_t3-4) + 4 + 7*s->near, s->T2, s->maxval); - }else{ - factor= 256 / (s->maxval + 1); + if (s->T1 == 0 || reset_all) + s->T1 = iso_clip(factor * (basic_t1 - 2) + 2 + 3 * s->near, + s->near + 1, s->maxval); + if (s->T2 == 0 || reset_all) + s->T2 = iso_clip(factor * (basic_t2 - 3) + 3 + 5 * s->near, + s->T1, s->maxval); + if (s->T3 == 0 || reset_all) + s->T3 = iso_clip(factor * (basic_t3 - 4) + 4 + 7 * s->near, + s->T2, s->maxval); + } else { + factor = 256 / (s->maxval + 1); - if(s->T1==0 || reset_all) - s->T1= iso_clip(FFMAX(2, basic_t1/factor + 3*s->near), s->near+1, s->maxval); - if(s->T2==0 || reset_all) - s->T2= iso_clip(FFMAX(3, basic_t2/factor + 5*s->near), s->T1, s->maxval); - if(s->T3==0 || reset_all) - s->T3= iso_clip(FFMAX(4, basic_t3/factor + 7*s->near), s->T2, s->maxval); + if (s->T1 == 0 || reset_all) + s->T1 = iso_clip(FFMAX(2, basic_t1 / factor + 3 * s->near), + s->near + 1, s->maxval); + if (s->T2 == 0 || reset_all) + s->T2 = iso_clip(FFMAX(3, basic_t2 / factor + 5 * s->near), + s->T1, s->maxval); + if (s->T3 == 0 || reset_all) + s->T3 = iso_clip(FFMAX(4, basic_t3 / factor + 7 * s->near), + s->T2, s->maxval); } - if(s->reset==0 || reset_all) s->reset= 64; + if (s->reset == 0 || reset_all) + s->reset = 64; av_dlog(NULL, "[JPEG-LS RESET] T=%i,%i,%i\n", s->T1, s->T2, s->T3); } diff --git a/ffmpeg/libavcodec/jpegls.h b/ffmpeg/libavcodec/jpegls.h index 0a6ead3..10ae054 100644 --- a/ffmpeg/libavcodec/jpegls.h +++ b/ffmpeg/libavcodec/jpegls.h @@ -28,21 +28,20 @@ #ifndef AVCODEC_JPEGLS_H #define AVCODEC_JPEGLS_H -#include "avcodec.h" #include "libavutil/common.h" +#include "avcodec.h" -typedef struct JpeglsContext{ +typedef struct JpeglsContext { AVCodecContext *avctx; - AVFrame picture; -}JpeglsContext; +} JpeglsContext; -typedef struct JLSState{ +typedef struct JLSState { int T1, T2, T3; int A[367], B[367], C[365], N[367]; int limit, reset, bpp, qbpp, maxval, range; int near, twonear; int run_index[4]; -}JLSState; +} JLSState; extern const uint8_t ff_log2_run[32]; @@ -54,19 +53,29 @@ void ff_jpegls_init_state(JLSState *state); /** * Calculate quantized gradient value, used for context determination */ -static inline int ff_jpegls_quantize(JLSState *s, int v){ //FIXME optimize - if(v==0) return 0; - if(v < 0){ - if(v <= -s->T3) return -4; - if(v <= -s->T2) return -3; - if(v <= -s->T1) return -2; - if(v < -s->near) return -1; +static inline int ff_jpegls_quantize(JLSState *s, int v) +{ + if (v == 0) return 0; - }else{ - if(v <= s->near) return 0; - if(v < s->T1) return 1; - if(v < s->T2) return 2; - if(v < s->T3) return 3; + if (v < 0) { + if (v <= -s->T3) + return -4; + if (v <= -s->T2) + return -3; + if (v <= -s->T1) + return -2; + if (v < -s->near) + return -1; + return 0; + } else { + if (v <= s->near) + return 0; + if (v < s->T1) + return 1; + if (v < s->T2) + return 2; + if (v < s->T3) + return 3; return 4; } } @@ -76,39 +85,41 @@ static inline int ff_jpegls_quantize(JLSState *s, int v){ //FIXME optimize */ void ff_jpegls_reset_coding_parameters(JLSState *s, int reset_all); - -static inline void ff_jpegls_downscale_state(JLSState *state, int Q){ - if(state->N[Q] == state->reset){ - state->A[Q] >>=1; - state->B[Q] >>=1; - state->N[Q] >>=1; +static inline void ff_jpegls_downscale_state(JLSState *state, int Q) +{ + if (state->N[Q] == state->reset) { + state->A[Q] >>= 1; + state->B[Q] >>= 1; + state->N[Q] >>= 1; } state->N[Q]++; } -static inline int ff_jpegls_update_state_regular(JLSState *state, int Q, int err){ +static inline int ff_jpegls_update_state_regular(JLSState *state, + int Q, int err) +{ if(FFABS(err) > 0xFFFF) return -0x10000; state->A[Q] += FFABS(err); - err *= state->twonear; + err *= state->twonear; state->B[Q] += err; ff_jpegls_downscale_state(state, Q); - if(state->B[Q] <= -state->N[Q]) { - state->B[Q]= FFMAX(state->B[Q] + state->N[Q], 1-state->N[Q]); - if(state->C[Q] > -128) + if (state->B[Q] <= -state->N[Q]) { + state->B[Q] = FFMAX(state->B[Q] + state->N[Q], 1 - state->N[Q]); + if (state->C[Q] > -128) state->C[Q]--; - }else if(state->B[Q] > 0){ - state->B[Q]= FFMIN(state->B[Q] - state->N[Q], 0); - if(state->C[Q] < 127) + } else if (state->B[Q] > 0) { + state->B[Q] = FFMIN(state->B[Q] - state->N[Q], 0); + if (state->C[Q] < 127) state->C[Q]++; } return err; } -#define R(a, i ) (bits == 8 ? ((uint8_t*)(a))[i] : ((uint16_t*)(a))[i] ) -#define W(a, i, v) (bits == 8 ? (((uint8_t*)(a))[i]=v) : (((uint16_t*)(a))[i]=v)) +#define R(a, i) (bits == 8 ? ((uint8_t *)(a))[i] : ((uint16_t *)(a))[i]) +#define W(a, i, v) (bits == 8 ? (((uint8_t *)(a))[i] = v) : (((uint16_t *)(a))[i] = v)) #endif /* AVCODEC_JPEGLS_H */ diff --git a/ffmpeg/libavcodec/jpeglsdec.c b/ffmpeg/libavcodec/jpeglsdec.c index 516a82f..190b9b6 100644 --- a/ffmpeg/libavcodec/jpeglsdec.c +++ b/ffmpeg/libavcodec/jpeglsdec.c @@ -34,18 +34,16 @@ #include "jpegls.h" #include "jpeglsdec.h" - /* -* Uncomment this to significantly speed up decoding of broken JPEG-LS -* (or test broken JPEG-LS decoder) and slow down ordinary decoding a bit. -* -* There is no Golomb code with length >= 32 bits possible, so check and -* avoid situation of 32 zeros, FFmpeg Golomb decoder is painfully slow -* on this errors. -*/ + * Uncomment this to significantly speed up decoding of broken JPEG-LS + * (or test broken JPEG-LS decoder) and slow down ordinary decoding a bit. + * + * There is no Golomb code with length >= 32 bits possible, so check and + * avoid situation of 32 zeros, FFmpeg Golomb decoder is painfully slow + * on this errors. + */ //#define JLS_BROKEN - /** * Decode LSE block with initialization parameters */ @@ -56,13 +54,13 @@ int ff_jpegls_decode_lse(MJpegDecodeContext *s) skip_bits(&s->gb, 16); /* length: FIXME: verify field validity */ id = get_bits(&s->gb, 8); - switch(id){ + switch (id) { case 1: - s->maxval= get_bits(&s->gb, 16); - s->t1= get_bits(&s->gb, 16); - s->t2= get_bits(&s->gb, 16); - s->t3= get_bits(&s->gb, 16); - s->reset= get_bits(&s->gb, 16); + s->maxval = get_bits(&s->gb, 16); + s->t1 = get_bits(&s->gb, 16); + s->t2 = get_bits(&s->gb, 16); + s->t3 = get_bits(&s->gb, 16); + s->reset = get_bits(&s->gb, 16); // ff_jpegls_reset_coding_parameters(s, 0); //FIXME quant table? @@ -70,13 +68,13 @@ int ff_jpegls_decode_lse(MJpegDecodeContext *s) case 2: case 3: av_log(s->avctx, AV_LOG_ERROR, "palette not supported\n"); - return -1; + return AVERROR(ENOSYS); case 4: av_log(s->avctx, AV_LOG_ERROR, "oversize image not supported\n"); - return -1; + return AVERROR(ENOSYS); default: av_log(s->avctx, AV_LOG_ERROR, "invalid id %d\n", id); - return -1; + return AVERROR_INVALIDDATA; } av_dlog(s->avctx, "ID=%i, T=%i,%i,%i\n", id, s->t1, s->t2, s->t3); @@ -86,27 +84,30 @@ int ff_jpegls_decode_lse(MJpegDecodeContext *s) /** * Get context-dependent Golomb code, decode it and update context */ -static inline int ls_get_code_regular(GetBitContext *gb, JLSState *state, int Q){ +static inline int ls_get_code_regular(GetBitContext *gb, JLSState *state, int Q) +{ int k, ret; - for(k = 0; (state->N[Q] << k) < state->A[Q]; k++); + for (k = 0; (state->N[Q] << k) < state->A[Q]; k++) + ; #ifdef JLS_BROKEN - if(!show_bits_long(gb, 32))return -1; + if (!show_bits_long(gb, 32)) + return -1; #endif ret = get_ur_golomb_jpegls(gb, k, state->limit, state->qbpp); /* decode mapped error */ - if(ret & 1) - ret = -((ret + 1) >> 1); + if (ret & 1) + ret = -(ret + 1 >> 1); else ret >>= 1; /* for NEAR=0, k=0 and 2*B[Q] <= - N[Q] mapping is reversed */ - if(!state->near && !k && (2 * state->B[Q] <= -state->N[Q])) + if (!state->near && !k && (2 * state->B[Q] <= -state->N[Q])) ret = -(ret + 1); - ret= ff_jpegls_update_state_regular(state, Q, ret); + ret = ff_jpegls_update_state_regular(state, Q, ret); return ret; } @@ -114,37 +115,44 @@ static inline int ls_get_code_regular(GetBitContext *gb, JLSState *state, int Q) /** * Get Golomb code, decode it and update state for run termination */ -static inline int ls_get_code_runterm(GetBitContext *gb, JLSState *state, int RItype, int limit_add){ +static inline int ls_get_code_runterm(GetBitContext *gb, JLSState *state, + int RItype, int limit_add) +{ int k, ret, temp, map; int Q = 365 + RItype; - temp= state->A[Q]; - if(RItype) + temp = state->A[Q]; + if (RItype) temp += state->N[Q] >> 1; - for(k = 0; (state->N[Q] << k) < temp; k++); + for (k = 0; (state->N[Q] << k) < temp; k++) + ; #ifdef JLS_BROKEN - if(!show_bits_long(gb, 32))return -1; + if (!show_bits_long(gb, 32)) + return -1; #endif - ret = get_ur_golomb_jpegls(gb, k, state->limit - limit_add - 1, state->qbpp); + ret = get_ur_golomb_jpegls(gb, k, state->limit - limit_add - 1, + state->qbpp); /* decode mapped error */ map = 0; - if(!k && (RItype || ret) && (2 * state->B[Q] < state->N[Q])) + if (!k && (RItype || ret) && (2 * state->B[Q] < state->N[Q])) map = 1; ret += RItype + map; - if(ret & 1){ - ret = map - ((ret + 1) >> 1); + if (ret & 1) { + ret = map - (ret + 1 >> 1); state->B[Q]++; } else { ret = ret >> 1; } + if(FFABS(ret) > 0xFFFF) + return -0x10000; /* update state */ state->A[Q] += FFABS(ret) - RItype; - ret *= state->twonear; + ret *= state->twonear; ff_jpegls_downscale_state(state, Q); return ret; @@ -153,12 +161,15 @@ static inline int ls_get_code_runterm(GetBitContext *gb, JLSState *state, int RI /** * Decode one line of image */ -static inline void ls_decode_line(JLSState *state, MJpegDecodeContext *s, void *last, void *dst, int last2, int w, int stride, int comp, int bits){ +static inline void ls_decode_line(JLSState *state, MJpegDecodeContext *s, + void *last, void *dst, int last2, int w, + int stride, int comp, int bits) +{ int i, x = 0; int Ra, Rb, Rc, Rd; int D0, D1, D2; - while(x < w) { + while (x < w) { int err, pred; /* compute gradients */ @@ -170,52 +181,54 @@ static inline void ls_decode_line(JLSState *state, MJpegDecodeContext *s, void * D1 = Rb - Rc; D2 = Rc - Ra; /* run mode */ - if((FFABS(D0) <= state->near) && (FFABS(D1) <= state->near) && (FFABS(D2) <= state->near)) { + if ((FFABS(D0) <= state->near) && + (FFABS(D1) <= state->near) && + (FFABS(D2) <= state->near)) { int r; int RItype; /* decode full runs while available */ - while(get_bits1(&s->gb)) { + while (get_bits1(&s->gb)) { int r; r = 1 << ff_log2_run[state->run_index[comp]]; - if(x + r * stride > w) { + if (x + r * stride > w) r = (w - x) / stride; - } - for(i = 0; i < r; i++) { + for (i = 0; i < r; i++) { W(dst, x, Ra); x += stride; } /* if EOL reached, we stop decoding */ - if(r != (1 << ff_log2_run[state->run_index[comp]])) + if (r != 1 << ff_log2_run[state->run_index[comp]]) return; - if(state->run_index[comp] < 31) + if (state->run_index[comp] < 31) state->run_index[comp]++; - if(x + stride > w) + if (x + stride > w) return; } /* decode aborted run */ r = ff_log2_run[state->run_index[comp]]; - if(r) + if (r) r = get_bits_long(&s->gb, r); - if(x + r * stride > w) { + if (x + r * stride > w) { r = (w - x) / stride; } - for(i = 0; i < r; i++) { + for (i = 0; i < r; i++) { W(dst, x, Ra); x += stride; } /* decode run termination value */ - Rb = R(last, x); + Rb = R(last, x); RItype = (FFABS(Ra - Rb) <= state->near) ? 1 : 0; - err = ls_get_code_runterm(&s->gb, state, RItype, ff_log2_run[state->run_index[comp]]); - if(state->run_index[comp]) + err = ls_get_code_runterm(&s->gb, state, RItype, + ff_log2_run[state->run_index[comp]]); + if (state->run_index[comp]) state->run_index[comp]--; - if(state->near && RItype){ + if (state->near && RItype) { pred = Ra + err; } else { - if(Rb < Ra) + if (Rb < Ra) pred = Rb - err; else pred = Rb + err; @@ -223,31 +236,33 @@ static inline void ls_decode_line(JLSState *state, MJpegDecodeContext *s, void * } else { /* regular mode */ int context, sign; - context = ff_jpegls_quantize(state, D0) * 81 + ff_jpegls_quantize(state, D1) * 9 + ff_jpegls_quantize(state, D2); - pred = mid_pred(Ra, Ra + Rb - Rc, Rb); + context = ff_jpegls_quantize(state, D0) * 81 + + ff_jpegls_quantize(state, D1) * 9 + + ff_jpegls_quantize(state, D2); + pred = mid_pred(Ra, Ra + Rb - Rc, Rb); - if(context < 0){ + if (context < 0) { context = -context; - sign = 1; - }else{ + sign = 1; + } else { sign = 0; } - if(sign){ + if (sign) { pred = av_clip(pred - state->C[context], 0, state->maxval); - err = -ls_get_code_regular(&s->gb, state, context); + err = -ls_get_code_regular(&s->gb, state, context); } else { pred = av_clip(pred + state->C[context], 0, state->maxval); - err = ls_get_code_regular(&s->gb, state, context); + err = ls_get_code_regular(&s->gb, state, context); } /* we have to do something more for near-lossless coding */ pred += err; } - if(state->near){ - if(pred < -state->near) + if (state->near) { + if (pred < -state->near) pred += state->range * state->twonear; - else if(pred > state->maxval + state->near) + else if (pred > state->maxval + state->near) pred -= state->range * state->twonear; pred = av_clip(pred, 0, state->maxval); } @@ -258,71 +273,80 @@ static inline void ls_decode_line(JLSState *state, MJpegDecodeContext *s, void * } } -int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transform, int ilv){ +int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, + int point_transform, int ilv) +{ int i, t = 0; uint8_t *zero, *last, *cur; JLSState *state; - int off = 0, stride = 1, width, shift; + int off = 0, stride = 1, width, shift, ret = 0; - zero = av_mallocz(s->picture.linesize[0]); + zero = av_mallocz(s->picture_ptr->linesize[0]); last = zero; - cur = s->picture.data[0]; + cur = s->picture_ptr->data[0]; state = av_mallocz(sizeof(JLSState)); /* initialize JPEG-LS state from JPEG parameters */ - state->near = near; - state->bpp = (s->bits < 2) ? 2 : s->bits; + state->near = near; + state->bpp = (s->bits < 2) ? 2 : s->bits; state->maxval = s->maxval; - state->T1 = s->t1; - state->T2 = s->t2; - state->T3 = s->t3; - state->reset = s->reset; + state->T1 = s->t1; + state->T2 = s->t2; + state->T3 = s->t3; + state->reset = s->reset; ff_jpegls_reset_coding_parameters(state, 0); ff_jpegls_init_state(state); - if(s->bits <= 8) + if (s->bits <= 8) shift = point_transform + (8 - s->bits); else shift = point_transform + (16 - s->bits); if (s->avctx->debug & FF_DEBUG_PICT_INFO) { - av_log(s->avctx, AV_LOG_DEBUG, "JPEG-LS params: %ix%i NEAR=%i MV=%i T(%i,%i,%i) RESET=%i, LIMIT=%i, qbpp=%i, RANGE=%i\n", + av_log(s->avctx, AV_LOG_DEBUG, + "JPEG-LS params: %ix%i NEAR=%i MV=%i T(%i,%i,%i) " + "RESET=%i, LIMIT=%i, qbpp=%i, RANGE=%i\n", s->width, s->height, state->near, state->maxval, state->T1, state->T2, state->T3, state->reset, state->limit, state->qbpp, state->range); av_log(s->avctx, AV_LOG_DEBUG, "JPEG params: ILV=%i Pt=%i BPP=%i, scan = %i\n", ilv, point_transform, s->bits, s->cur_scan); } - if(ilv == 0) { /* separate planes */ + if (ilv == 0) { /* separate planes */ + if (s->cur_scan > s->nb_components) { + ret = AVERROR_INVALIDDATA; + goto end; + } stride = (s->nb_components > 1) ? 3 : 1; - off = av_clip(s->cur_scan - 1, 0, stride - 1); - width = s->width * stride; - cur += off; - for(i = 0; i < s->height; i++) { - if(s->bits <= 8){ - ls_decode_line(state, s, last, cur, t, width, stride, off, 8); + off = av_clip(s->cur_scan - 1, 0, stride - 1); + width = s->width * stride; + cur += off; + for (i = 0; i < s->height; i++) { + if (s->bits <= 8) { + ls_decode_line(state, s, last, cur, t, width, stride, off, 8); t = last[0]; - }else{ + } else { ls_decode_line(state, s, last, cur, t, width, stride, off, 16); - t = *((uint16_t*)last); + t = *((uint16_t *)last); } last = cur; - cur += s->picture.linesize[0]; + cur += s->picture_ptr->linesize[0]; if (s->restart_interval && !--s->restart_count) { align_get_bits(&s->gb); skip_bits(&s->gb, 16); /* skip RSTn */ } } - } else if(ilv == 1) { /* line interleaving */ + } else if (ilv == 1) { /* line interleaving */ int j; - int Rc[3] = {0, 0, 0}; + int Rc[3] = { 0, 0, 0 }; stride = (s->nb_components > 1) ? 3 : 1; - memset(cur, 0, s->picture.linesize[0]); + memset(cur, 0, s->picture_ptr->linesize[0]); width = s->width * stride; - for(i = 0; i < s->height; i++) { - for(j = 0; j < stride; j++) { - ls_decode_line(state, s, last + j, cur + j, Rc[j], width, stride, j, 8); + for (i = 0; i < s->height; i++) { + for (j = 0; j < stride; j++) { + ls_decode_line(state, s, last + j, cur + j, + Rc[j], width, stride, j, 8); Rc[j] = last[j]; if (s->restart_interval && !--s->restart_count) { @@ -331,49 +355,95 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transfor } } last = cur; - cur += s->picture.linesize[0]; + cur += s->picture_ptr->linesize[0]; } - } else if(ilv == 2) { /* sample interleaving */ - av_log(s->avctx, AV_LOG_ERROR, "Sample interleaved images are not supported.\n"); - av_free(state); - av_free(zero); - return -1; + } else if (ilv == 2) { /* sample interleaving */ + avpriv_report_missing_feature(s->avctx, "Sample interleaved images"); + ret = AVERROR_PATCHWELCOME; + goto end; + } + + if (s->xfrm && s->nb_components == 3) { + int x, w; + + w = s->width * s->nb_components; + + if (s->bits <= 8) { + uint8_t *src = s->picture_ptr->data[0]; + + for (i = 0; i < s->height; i++) { + switch(s->xfrm) { + case 1: + for (x = off; x < w; x += 3) { + src[x ] += src[x+1] + 128; + src[x+2] += src[x+1] + 128; + } + break; + case 2: + for (x = off; x < w; x += 3) { + src[x ] += src[x+1] + 128; + src[x+2] += ((src[x ] + src[x+1])>>1) + 128; + } + break; + case 3: + for (x = off; x < w; x += 3) { + int g = src[x+0] - ((src[x+2]+src[x+1])>>2) + 64; + src[x+0] = src[x+2] + g + 128; + src[x+2] = src[x+1] + g + 128; + src[x+1] = g; + } + break; + case 4: + for (x = off; x < w; x += 3) { + int r = src[x+0] - (( 359 * (src[x+2]-128) + 490) >> 8); + int g = src[x+0] - (( 88 * (src[x+1]-128) - 183 * (src[x+2]-128) + 30) >> 8); + int b = src[x+0] + ((454 * (src[x+1]-128) + 574) >> 8); + src[x+0] = av_clip_uint8(r); + src[x+1] = av_clip_uint8(g); + src[x+2] = av_clip_uint8(b); + } + break; + } + src += s->picture_ptr->linesize[0]; + } + }else + avpriv_report_missing_feature(s->avctx, "16bit xfrm"); } - if(shift){ /* we need to do point transform or normalize samples */ + if (shift) { /* we need to do point transform or normalize samples */ int x, w; w = s->width * s->nb_components; - if(s->bits <= 8){ - uint8_t *src = s->picture.data[0]; + if (s->bits <= 8) { + uint8_t *src = s->picture_ptr->data[0]; - for(i = 0; i < s->height; i++){ - for(x = off; x < w; x+= stride){ + for (i = 0; i < s->height; i++) { + for (x = off; x < w; x += stride) src[x] <<= shift; - } - src += s->picture.linesize[0]; + src += s->picture_ptr->linesize[0]; } - }else{ - uint16_t *src = (uint16_t*) s->picture.data[0]; + } else { + uint16_t *src = (uint16_t *)s->picture_ptr->data[0]; - for(i = 0; i < s->height; i++){ - for(x = 0; x < w; x++){ + for (i = 0; i < s->height; i++) { + for (x = 0; x < w; x++) src[x] <<= shift; - } - src += s->picture.linesize[0]/2; + src += s->picture_ptr->linesize[0] / 2; } } } + +end: av_free(state); av_free(zero); - return 0; + return ret; } - AVCodec ff_jpegls_decoder = { .name = "jpegls", + .long_name = NULL_IF_CONFIG_SMALL("JPEG-LS"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_JPEGLS, .priv_data_size = sizeof(MJpegDecodeContext), @@ -381,5 +451,4 @@ AVCodec ff_jpegls_decoder = { .close = ff_mjpeg_decode_end, .decode = ff_mjpeg_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("JPEG-LS"), }; diff --git a/ffmpeg/libavcodec/jpeglsdec.h b/ffmpeg/libavcodec/jpeglsdec.h index 5204ecb..0cafaba 100644 --- a/ffmpeg/libavcodec/jpeglsdec.h +++ b/ffmpeg/libavcodec/jpeglsdec.h @@ -36,6 +36,7 @@ */ int ff_jpegls_decode_lse(MJpegDecodeContext *s); -int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transform, int ilv); +int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, + int point_transform, int ilv); #endif /* AVCODEC_JPEGLSDEC_H */ diff --git a/ffmpeg/libavcodec/jpeglsenc.c b/ffmpeg/libavcodec/jpeglsenc.c index be979aa..030178f 100644 --- a/ffmpeg/libavcodec/jpeglsenc.c +++ b/ffmpeg/libavcodec/jpeglsenc.c @@ -34,24 +34,26 @@ #include "mjpeg.h" #include "jpegls.h" - /** * Encode error from regular symbol */ -static inline void ls_encode_regular(JLSState *state, PutBitContext *pb, int Q, int err){ +static inline void ls_encode_regular(JLSState *state, PutBitContext *pb, int Q, + int err) +{ int k; int val; int map; - for(k = 0; (state->N[Q] << k) < state->A[Q]; k++); + for (k = 0; (state->N[Q] << k) < state->A[Q]; k++) + ; map = !state->near && !k && (2 * state->B[Q] <= -state->N[Q]); - if(err < 0) + if (err < 0) err += state->range; - if(err >= ((state->range + 1) >> 1)) { + if (err >= (state->range + 1 >> 1)) { err -= state->range; - val = 2 * FFABS(err) - 1 - map; + val = 2 * FFABS(err) - 1 - map; } else val = 2 * err + map; @@ -63,27 +65,30 @@ static inline void ls_encode_regular(JLSState *state, PutBitContext *pb, int Q, /** * Encode error from run termination */ -static inline void ls_encode_runterm(JLSState *state, PutBitContext *pb, int RItype, int err, int limit_add){ +static inline void ls_encode_runterm(JLSState *state, PutBitContext *pb, + int RItype, int err, int limit_add) +{ int k; int val, map; int Q = 365 + RItype; int temp; temp = state->A[Q]; - if(RItype) + if (RItype) temp += state->N[Q] >> 1; - for(k = 0; (state->N[Q] << k) < temp; k++); + for (k = 0; (state->N[Q] << k) < temp; k++) + ; map = 0; - if(!k && err && (2 * state->B[Q] < state->N[Q])) + if (!k && err && (2 * state->B[Q] < state->N[Q])) map = 1; - if(err < 0) - val = - (2 * err) - 1 - RItype + map; + if (err < 0) + val = -(2 * err) - 1 - RItype + map; else val = 2 * err - RItype - map; set_ur_golomb_jpegls(pb, val, k, state->limit - limit_add - 1, state->qbpp); - if(err < 0) + if (err < 0) state->B[Q]++; state->A[Q] += (val + 1 - RItype) >> 1; @@ -93,19 +98,21 @@ static inline void ls_encode_runterm(JLSState *state, PutBitContext *pb, int RIt /** * Encode run value as specified by JPEG-LS standard */ -static inline void ls_encode_run(JLSState *state, PutBitContext *pb, int run, int comp, int trail){ - while(run >= (1 << ff_log2_run[state->run_index[comp]])){ +static inline void ls_encode_run(JLSState *state, PutBitContext *pb, int run, + int comp, int trail) +{ + while (run >= (1 << ff_log2_run[state->run_index[comp]])) { put_bits(pb, 1, 1); run -= 1 << ff_log2_run[state->run_index[comp]]; - if(state->run_index[comp] < 31) + if (state->run_index[comp] < 31) state->run_index[comp]++; } /* if hit EOL, encode another full run, else encode aborted run */ - if(!trail && run) { + if (!trail && run) { put_bits(pb, 1, 1); - }else if(trail){ + } else if (trail) { put_bits(pb, 1, 0); - if(ff_log2_run[state->run_index[comp]]) + if (ff_log2_run[state->run_index[comp]]) put_bits(pb, ff_log2_run[state->run_index[comp]], run); } } @@ -113,12 +120,15 @@ static inline void ls_encode_run(JLSState *state, PutBitContext *pb, int run, in /** * Encode one line of image */ -static inline void ls_encode_line(JLSState *state, PutBitContext *pb, void *last, void *cur, int last2, int w, int stride, int comp, int bits){ +static inline void ls_encode_line(JLSState *state, PutBitContext *pb, + void *last, void *cur, int last2, int w, + int stride, int comp, int bits) +{ int x = 0; int Ra, Rb, Rc, Rd; int D0, D1, D2; - while(x < w) { + while (x < w) { int err, pred, sign; /* compute gradients */ @@ -131,71 +141,76 @@ static inline void ls_encode_line(JLSState *state, PutBitContext *pb, void *last D2 = Rc - Ra; /* run mode */ - if((FFABS(D0) <= state->near) && (FFABS(D1) <= state->near) && (FFABS(D2) <= state->near)) { + if ((FFABS(D0) <= state->near) && + (FFABS(D1) <= state->near) && + (FFABS(D2) <= state->near)) { int RUNval, RItype, run; - run = 0; + run = 0; RUNval = Ra; - while(x < w && (FFABS(R(cur, x) - RUNval) <= state->near)){ + while (x < w && (FFABS(R(cur, x) - RUNval) <= state->near)) { run++; W(cur, x, Ra); x += stride; } ls_encode_run(state, pb, run, comp, x < w); - if(x >= w) + if (x >= w) return; - Rb = R(last, x); - RItype = (FFABS(Ra - Rb) <= state->near); - pred = RItype ? Ra : Rb; - err = R(cur, x) - pred; + Rb = R(last, x); + RItype = FFABS(Ra - Rb) <= state->near; + pred = RItype ? Ra : Rb; + err = R(cur, x) - pred; - if(!RItype && Ra > Rb) + if (!RItype && Ra > Rb) err = -err; - if(state->near){ - if(err > 0) - err = (state->near + err) / state->twonear; + if (state->near) { + if (err > 0) + err = (state->near + err) / state->twonear; else err = -(state->near - err) / state->twonear; - if(RItype || (Rb >= Ra)) + if (RItype || (Rb >= Ra)) Ra = av_clip(pred + err * state->twonear, 0, state->maxval); else Ra = av_clip(pred - err * state->twonear, 0, state->maxval); W(cur, x, Ra); } - if(err < 0) + if (err < 0) err += state->range; - if(err >= ((state->range + 1) >> 1)) + if (err >= state->range + 1 >> 1) err -= state->range; - ls_encode_runterm(state, pb, RItype, err, ff_log2_run[state->run_index[comp]]); + ls_encode_runterm(state, pb, RItype, err, + ff_log2_run[state->run_index[comp]]); - if(state->run_index[comp] > 0) + if (state->run_index[comp] > 0) state->run_index[comp]--; } else { /* regular mode */ int context; - context = ff_jpegls_quantize(state, D0) * 81 + ff_jpegls_quantize(state, D1) * 9 + ff_jpegls_quantize(state, D2); - pred = mid_pred(Ra, Ra + Rb - Rc, Rb); + context = ff_jpegls_quantize(state, D0) * 81 + + ff_jpegls_quantize(state, D1) * 9 + + ff_jpegls_quantize(state, D2); + pred = mid_pred(Ra, Ra + Rb - Rc, Rb); - if(context < 0){ + if (context < 0) { context = -context; - sign = 1; - pred = av_clip(pred - state->C[context], 0, state->maxval); - err = pred - R(cur, x); - }else{ + sign = 1; + pred = av_clip(pred - state->C[context], 0, state->maxval); + err = pred - R(cur, x); + } else { sign = 0; pred = av_clip(pred + state->C[context], 0, state->maxval); - err = R(cur, x) - pred; + err = R(cur, x) - pred; } - if(state->near){ - if(err > 0) - err = (state->near + err) / state->twonear; + if (state->near) { + if (err > 0) + err = (state->near + err) / state->twonear; else err = -(state->near - err) / state->twonear; - if(!sign) + if (!sign) Ra = av_clip(pred + err * state->twonear, 0, state->maxval); else Ra = av_clip(pred - err * state->twonear, 0, state->maxval); @@ -208,18 +223,22 @@ static inline void ls_encode_line(JLSState *state, PutBitContext *pb, void *last } } -static void ls_store_lse(JLSState *state, PutBitContext *pb){ +static void ls_store_lse(JLSState *state, PutBitContext *pb) +{ /* Test if we have default params and don't need to store LSE */ JLSState state2 = { 0 }; - state2.bpp = state->bpp; + state2.bpp = state->bpp; state2.near = state->near; ff_jpegls_reset_coding_parameters(&state2, 1); - if(state->T1 == state2.T1 && state->T2 == state2.T2 && state->T3 == state2.T3 && state->reset == state2.reset) + if (state->T1 == state2.T1 && + state->T2 == state2.T2 && + state->T3 == state2.T3 && + state->reset == state2.reset) return; /* store LSE type 1 */ put_marker(pb, LSE); put_bits(pb, 16, 13); - put_bits(pb, 8, 1); + put_bits(pb, 8, 1); put_bits(pb, 16, state->maxval); put_bits(pb, 16, state->T1); put_bits(pb, 16, state->T2); @@ -230,9 +249,8 @@ static void ls_store_lse(JLSState *state, PutBitContext *pb){ static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { - JpeglsContext * const s = avctx->priv_data; - AVFrame * const p = &s->picture; - const int near = avctx->prediction_method; + const AVFrame *const p = pict; + const int near = avctx->prediction_method; PutBitContext pb, pb2; GetBitContext gb; uint8_t *buf2, *zero, *cur, *last; @@ -240,17 +258,14 @@ static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt, int i, size, ret; int comps; - *p = *pict; - p->pict_type= AV_PICTURE_TYPE_I; - p->key_frame= 1; - - if(avctx->pix_fmt == AV_PIX_FMT_GRAY8 || avctx->pix_fmt == AV_PIX_FMT_GRAY16) + if (avctx->pix_fmt == AV_PIX_FMT_GRAY8 || + avctx->pix_fmt == AV_PIX_FMT_GRAY16) comps = 1; else comps = 3; - if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width*avctx->height*comps*4 + - FF_MIN_BUFFER_SIZE)) < 0) + if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width *avctx->height * comps * 4 + + FF_MIN_BUFFER_SIZE)) < 0) return ret; buf2 = av_malloc(pkt->size); @@ -262,31 +277,31 @@ static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt, put_marker(&pb, SOI); put_marker(&pb, SOF48); put_bits(&pb, 16, 8 + comps * 3); // header size depends on components - put_bits(&pb, 8, (avctx->pix_fmt == AV_PIX_FMT_GRAY16) ? 16 : 8); // bpp + put_bits(&pb, 8, (avctx->pix_fmt == AV_PIX_FMT_GRAY16) ? 16 : 8); // bpp put_bits(&pb, 16, avctx->height); put_bits(&pb, 16, avctx->width); - put_bits(&pb, 8, comps); // components - for(i = 1; i <= comps; i++) { - put_bits(&pb, 8, i); // component ID - put_bits(&pb, 8, 0x11); // subsampling: none - put_bits(&pb, 8, 0); // Tiq, used by JPEG-LS ext + put_bits(&pb, 8, comps); // components + for (i = 1; i <= comps; i++) { + put_bits(&pb, 8, i); // component ID + put_bits(&pb, 8, 0x11); // subsampling: none + put_bits(&pb, 8, 0); // Tiq, used by JPEG-LS ext } put_marker(&pb, SOS); put_bits(&pb, 16, 6 + comps * 2); - put_bits(&pb, 8, comps); - for(i = 1; i <= comps; i++) { - put_bits(&pb, 8, i); // component ID - put_bits(&pb, 8, 0); // mapping index: none + put_bits(&pb, 8, comps); + for (i = 1; i <= comps; i++) { + put_bits(&pb, 8, i); // component ID + put_bits(&pb, 8, 0); // mapping index: none } - put_bits(&pb, 8, near); - put_bits(&pb, 8, (comps > 1) ? 1 : 0); // interleaving: 0 - plane, 1 - line - put_bits(&pb, 8, 0); // point transform: none + put_bits(&pb, 8, near); + put_bits(&pb, 8, (comps > 1) ? 1 : 0); // interleaving: 0 - plane, 1 - line + put_bits(&pb, 8, 0); // point transform: none state = av_mallocz(sizeof(JLSState)); /* initialize JPEG-LS state from JPEG parameters */ state->near = near; - state->bpp = (avctx->pix_fmt == AV_PIX_FMT_GRAY16) ? 16 : 8; + state->bpp = (avctx->pix_fmt == AV_PIX_FMT_GRAY16) ? 16 : 8; ff_jpegls_reset_coding_parameters(state, 0); ff_jpegls_init_state(state); @@ -298,70 +313,72 @@ static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt, return AVERROR(ENOMEM); } last = zero; - cur = p->data[0]; - if(avctx->pix_fmt == AV_PIX_FMT_GRAY8){ + cur = p->data[0]; + if (avctx->pix_fmt == AV_PIX_FMT_GRAY8) { int t = 0; - for(i = 0; i < avctx->height; i++) { - ls_encode_line(state, &pb2, last, cur, t, avctx->width, 1, 0, 8); - t = last[0]; + for (i = 0; i < avctx->height; i++) { + ls_encode_line(state, &pb2, last, cur, t, avctx->width, 1, 0, 8); + t = last[0]; last = cur; cur += p->linesize[0]; } - }else if(avctx->pix_fmt == AV_PIX_FMT_GRAY16){ + } else if (avctx->pix_fmt == AV_PIX_FMT_GRAY16) { int t = 0; - for(i = 0; i < avctx->height; i++) { + for (i = 0; i < avctx->height; i++) { ls_encode_line(state, &pb2, last, cur, t, avctx->width, 1, 0, 16); - t = *((uint16_t*)last); + t = *((uint16_t *)last); last = cur; cur += p->linesize[0]; } - }else if(avctx->pix_fmt == AV_PIX_FMT_RGB24){ + } else if (avctx->pix_fmt == AV_PIX_FMT_RGB24) { int j, width; - int Rc[3] = {0, 0, 0}; + int Rc[3] = { 0, 0, 0 }; width = avctx->width * 3; - for(i = 0; i < avctx->height; i++) { - for(j = 0; j < 3; j++) { - ls_encode_line(state, &pb2, last + j, cur + j, Rc[j], width, 3, j, 8); + for (i = 0; i < avctx->height; i++) { + for (j = 0; j < 3; j++) { + ls_encode_line(state, &pb2, last + j, cur + j, Rc[j], + width, 3, j, 8); Rc[j] = last[j]; } last = cur; - cur += s->picture.linesize[0]; + cur += p->linesize[0]; } - }else if(avctx->pix_fmt == AV_PIX_FMT_BGR24){ + } else if (avctx->pix_fmt == AV_PIX_FMT_BGR24) { int j, width; - int Rc[3] = {0, 0, 0}; + int Rc[3] = { 0, 0, 0 }; width = avctx->width * 3; - for(i = 0; i < avctx->height; i++) { - for(j = 2; j >= 0; j--) { - ls_encode_line(state, &pb2, last + j, cur + j, Rc[j], width, 3, j, 8); + for (i = 0; i < avctx->height; i++) { + for (j = 2; j >= 0; j--) { + ls_encode_line(state, &pb2, last + j, cur + j, Rc[j], + width, 3, j, 8); Rc[j] = last[j]; } last = cur; - cur += s->picture.linesize[0]; + cur += p->linesize[0]; } } av_freep(&zero); av_freep(&state); - // the specification says that after doing 0xff escaping unused bits in the - // last byte must be set to 0, so just append 7 "optional" zero-bits to - // avoid special-casing. + /* the specification says that after doing 0xff escaping unused bits in + * the last byte must be set to 0, so just append 7 "optional" zero-bits + * to avoid special-casing. */ put_bits(&pb2, 7, 0); size = put_bits_count(&pb2); flush_put_bits(&pb2); /* do escape coding */ init_get_bits(&gb, buf2, size); size -= 7; - while(get_bits_count(&gb) < size){ + while (get_bits_count(&gb) < size) { int v; v = get_bits(&gb, 8); put_bits(&pb, 8, v); - if(v == 0xFF){ + if (v == 0xFF) { v = get_bits(&gb, 7); put_bits(&pb, 8, v); } @@ -381,14 +398,27 @@ static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt, return 0; } -static av_cold int encode_init_ls(AVCodecContext *ctx) { - JpeglsContext *c = (JpeglsContext*)ctx->priv_data; +static av_cold int encode_close(AVCodecContext *avctx) +{ + av_frame_free(&avctx->coded_frame); + return 0; +} + +static av_cold int encode_init_ls(AVCodecContext *ctx) +{ + ctx->coded_frame = av_frame_alloc(); + if (!ctx->coded_frame) + return AVERROR(ENOMEM); - c->avctx = ctx; - ctx->coded_frame = &c->picture; + ctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + ctx->coded_frame->key_frame = 1; - if(ctx->pix_fmt != AV_PIX_FMT_GRAY8 && ctx->pix_fmt != AV_PIX_FMT_GRAY16 && ctx->pix_fmt != AV_PIX_FMT_RGB24 && ctx->pix_fmt != AV_PIX_FMT_BGR24){ - av_log(ctx, AV_LOG_ERROR, "Only grayscale and RGB24/BGR24 images are supported\n"); + if (ctx->pix_fmt != AV_PIX_FMT_GRAY8 && + ctx->pix_fmt != AV_PIX_FMT_GRAY16 && + ctx->pix_fmt != AV_PIX_FMT_RGB24 && + ctx->pix_fmt != AV_PIX_FMT_BGR24) { + av_log(ctx, AV_LOG_ERROR, + "Only grayscale and RGB24/BGR24 images are supported\n"); return -1; } return 0; @@ -396,14 +426,15 @@ static av_cold int encode_init_ls(AVCodecContext *ctx) { AVCodec ff_jpegls_encoder = { .name = "jpegls", + .long_name = NULL_IF_CONFIG_SMALL("JPEG-LS"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_JPEGLS, - .priv_data_size = sizeof(JpeglsContext), .init = encode_init_ls, + .close = encode_close, .encode2 = encode_picture_ls, - .pix_fmts = (const enum AVPixelFormat[]){ - AV_PIX_FMT_BGR24, AV_PIX_FMT_RGB24, AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16, + .pix_fmts = (const enum AVPixelFormat[]) { + AV_PIX_FMT_BGR24, AV_PIX_FMT_RGB24, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("JPEG-LS"), }; diff --git a/ffmpeg/libavcodec/jvdec.c b/ffmpeg/libavcodec/jvdec.c index 18cc73f..cad0532 100644 --- a/ffmpeg/libavcodec/jvdec.c +++ b/ffmpeg/libavcodec/jvdec.c @@ -33,7 +33,7 @@ typedef struct JvContext { DSPContext dsp; - AVFrame frame; + AVFrame *frame; uint32_t palette[AVPALETTE_COUNT]; int palette_has_changed; } JvContext; @@ -41,9 +41,13 @@ typedef struct JvContext { static av_cold int decode_init(AVCodecContext *avctx) { JvContext *s = avctx->priv_data; + + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); + avctx->pix_fmt = AV_PIX_FMT_PAL8; ff_dsputil_init(&s->dsp, avctx); - avcodec_get_frame_defaults(&s->frame); return 0; } @@ -151,7 +155,7 @@ static int decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "video size %d invalid\n", video_size); return AVERROR_INVALIDDATA; } - if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) + if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) return ret; if (video_type == 0 || video_type == 1) { @@ -160,14 +164,14 @@ static int decode_frame(AVCodecContext *avctx, for (j = 0; j < avctx->height; j += 8) for (i = 0; i < avctx->width; i += 8) - decode8x8(&gb, s->frame.data[0] + j*s->frame.linesize[0] + i, - s->frame.linesize[0], &s->dsp); + decode8x8(&gb, s->frame->data[0] + j * s->frame->linesize[0] + i, + s->frame->linesize[0], &s->dsp); buf += video_size; } else if (video_type == 2) { int v = *buf++; for (j = 0; j < avctx->height; j++) - memset(s->frame.data[0] + j*s->frame.linesize[0], v, avctx->width); + memset(s->frame->data[0] + j * s->frame->linesize[0], v, avctx->width); } else { av_log(avctx, AV_LOG_WARNING, "unsupported frame type %i\n", video_type); return AVERROR_INVALIDDATA; @@ -184,13 +188,13 @@ static int decode_frame(AVCodecContext *avctx, } if (video_size) { - s->frame.key_frame = 1; - s->frame.pict_type = AV_PICTURE_TYPE_I; - s->frame.palette_has_changed = s->palette_has_changed; + s->frame->key_frame = 1; + s->frame->pict_type = AV_PICTURE_TYPE_I; + s->frame->palette_has_changed = s->palette_has_changed; s->palette_has_changed = 0; - memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); + memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE); - if ((ret = av_frame_ref(data, &s->frame)) < 0) + if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; *got_frame = 1; } @@ -202,7 +206,7 @@ static av_cold int decode_close(AVCodecContext *avctx) { JvContext *s = avctx->priv_data; - av_frame_unref(&s->frame); + av_frame_free(&s->frame); return 0; } diff --git a/ffmpeg/libavcodec/kgv1dec.c b/ffmpeg/libavcodec/kgv1dec.c index 9c48239..5528c6f 100644 --- a/ffmpeg/libavcodec/kgv1dec.c +++ b/ffmpeg/libavcodec/kgv1dec.c @@ -31,15 +31,14 @@ #include "internal.h" typedef struct { - AVCodecContext *avctx; - AVFrame prev; + AVFrame *prev; } KgvContext; static void decode_flush(AVCodecContext *avctx) { KgvContext * const c = avctx->priv_data; - av_frame_unref(&c->prev); + av_frame_free(&c->prev); } static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, @@ -61,12 +60,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, h = (buf[1] + 1) * 8; buf += 2; - if ((res = av_image_check_size(w, h, 0, avctx)) < 0) - return res; - if (w != avctx->width || h != avctx->height) { - av_frame_unref(&c->prev); - avcodec_set_dimensions(avctx, w, h); + av_frame_unref(c->prev); + if ((res = ff_set_dimensions(avctx, w, h)) < 0) + return res; } maxcnt = w * h; @@ -74,8 +71,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if ((res = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) return res; out = frame->data[0]; - if (c->prev.data[0]) { - prev = c->prev.data[0]; + if (c->prev->data[0]) { + prev = c->prev->data[0]; } else { prev = NULL; } @@ -145,8 +142,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (outcnt - maxcnt) av_log(avctx, AV_LOG_DEBUG, "frame finished with %d diff\n", outcnt - maxcnt); - av_frame_unref(&c->prev); - if ((res = av_frame_ref(&c->prev, frame)) < 0) + av_frame_unref(c->prev); + if ((res = av_frame_ref(c->prev, frame)) < 0) return res; *got_frame = 1; @@ -158,7 +155,10 @@ static av_cold int decode_init(AVCodecContext *avctx) { KgvContext * const c = avctx->priv_data; - c->avctx = avctx; + c->prev = av_frame_alloc(); + if (!c->prev) + return AVERROR(ENOMEM); + avctx->pix_fmt = AV_PIX_FMT_RGB555; avctx->flags |= CODEC_FLAG_EMU_EDGE; @@ -167,12 +167,14 @@ static av_cold int decode_init(AVCodecContext *avctx) static av_cold int decode_end(AVCodecContext *avctx) { - decode_flush(avctx); + KgvContext * const c = avctx->priv_data; + av_frame_free(&c->prev); return 0; } AVCodec ff_kgv1_decoder = { .name = "kgv1", + .long_name = NULL_IF_CONFIG_SMALL("Kega Game Video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_KGV1, .priv_data_size = sizeof(KgvContext), @@ -180,6 +182,5 @@ AVCodec ff_kgv1_decoder = { .close = decode_end, .decode = decode_frame, .flush = decode_flush, - .long_name = NULL_IF_CONFIG_SMALL("Kega Game Video"), .capabilities = CODEC_CAP_DR1, }; diff --git a/ffmpeg/libavcodec/kmvc.c b/ffmpeg/libavcodec/kmvc.c index 20aae67..f879c35 100644 --- a/ffmpeg/libavcodec/kmvc.c +++ b/ffmpeg/libavcodec/kmvc.c @@ -30,6 +30,7 @@ #include "avcodec.h" #include "bytestream.h" #include "internal.h" +#include "libavutil/common.h" #define KMVC_KEYFRAME 0x80 #define KMVC_PALETTE 0x40 @@ -46,7 +47,7 @@ typedef struct KmvcContext { int palsize; uint32_t pal[MAX_PALSIZE]; uint8_t *cur, *prev; - uint8_t *frm0, *frm1; + uint8_t frm0[320 * 200], frm1[320 * 200]; GetByteContext g; } KmvcContext; @@ -55,7 +56,7 @@ typedef struct BitBuf { int bitbuf; } BitBuf; -#define BLK(data, x, y) data[(x) + (y) * 320] +#define BLK(data, x, y) data[av_clip((x) + (y) * 320, 0, 320 * 200 -1)] #define kmvc_init_getbits(bb, g) bb.bits = 7; bb.bitbuf = bytestream2_get_byte(g); @@ -106,7 +107,7 @@ static int kmvc_decode_intra_8x8(KmvcContext * ctx, int w, int h) val = bytestream2_get_byte(&ctx->g); mx = val & 0xF; my = val >> 4; - if ((l0x-mx) + 320*(l0y-my) < 0 || (l0x-mx) + 320*(l0y-my) > 316*196) { + if ((l0x-mx) + 320*(l0y-my) < 0 || (l0x-mx) + 320*(l0y-my) > 320*197 - 4) { av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n"); return AVERROR_INVALIDDATA; } @@ -131,7 +132,7 @@ static int kmvc_decode_intra_8x8(KmvcContext * ctx, int w, int h) val = bytestream2_get_byte(&ctx->g); mx = val & 0xF; my = val >> 4; - if ((l1x-mx) + 320*(l1y-my) < 0 || (l1x-mx) + 320*(l1y-my) > 318*198) { + if ((l1x-mx) + 320*(l1y-my) < 0 || (l1x-mx) + 320*(l1y-my) > 320*199 - 2) { av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n"); return AVERROR_INVALIDDATA; } @@ -206,7 +207,7 @@ static int kmvc_decode_inter_8x8(KmvcContext * ctx, int w, int h) val = bytestream2_get_byte(&ctx->g); mx = (val & 0xF) - 8; my = (val >> 4) - 8; - if ((l0x+mx) + 320*(l0y+my) < 0 || (l0x+mx) + 320*(l0y+my) > 318*198) { + if ((l0x+mx) + 320*(l0y+my) < 0 || (l0x+mx) + 320*(l0y+my) > 320*197 - 4) { av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n"); return AVERROR_INVALIDDATA; } @@ -231,7 +232,7 @@ static int kmvc_decode_inter_8x8(KmvcContext * ctx, int w, int h) val = bytestream2_get_byte(&ctx->g); mx = (val & 0xF) - 8; my = (val >> 4) - 8; - if ((l1x+mx) + 320*(l1y+my) < 0 || (l1x+mx) + 320*(l1y+my) > 318*198) { + if ((l1x+mx) + 320*(l1y+my) < 0 || (l1x+mx) + 320*(l1y+my) > 320*199 - 2) { av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n"); return AVERROR_INVALIDDATA; } @@ -378,8 +379,6 @@ static av_cold int decode_init(AVCodecContext * avctx) return AVERROR(EINVAL); } - c->frm0 = av_mallocz(320 * 200); - c->frm1 = av_mallocz(320 * 200); c->cur = c->frm0; c->prev = c->frm1; @@ -414,29 +413,13 @@ static av_cold int decode_init(AVCodecContext * avctx) return 0; } - - -/* - * Uninit kmvc decoder - */ -static av_cold int decode_end(AVCodecContext * avctx) -{ - KmvcContext *const c = avctx->priv_data; - - av_freep(&c->frm0); - av_freep(&c->frm1); - - return 0; -} - AVCodec ff_kmvc_decoder = { .name = "kmvc", + .long_name = NULL_IF_CONFIG_SMALL("Karl Morton's video codec"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_KMVC, .priv_data_size = sizeof(KmvcContext), .init = decode_init, - .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Karl Morton's video codec"), }; diff --git a/ffmpeg/libavcodec/lagarith.c b/ffmpeg/libavcodec/lagarith.c index 8599784..0a4d23e 100644 --- a/ffmpeg/libavcodec/lagarith.c +++ b/ffmpeg/libavcodec/lagarith.c @@ -174,7 +174,15 @@ static int lag_read_prob_header(lag_rac *rac, GetBitContext *gb) if (cumul_prob & (cumul_prob - 1)) { uint64_t mul = softfloat_reciprocal(cumul_prob); - for (i = 1; i < 257; i++) { + for (i = 1; i <= 128; i++) { + rac->prob[i] = softfloat_mul(rac->prob[i], mul); + scaled_cumul_prob += rac->prob[i]; + } + if (scaled_cumul_prob <= 0) { + av_log(rac->avctx, AV_LOG_ERROR, "Scaled probabilities invalid\n"); + return AVERROR_INVALIDDATA; + } + for (; i < 257; i++) { rac->prob[i] = softfloat_mul(rac->prob[i], mul); scaled_cumul_prob += rac->prob[i]; } @@ -556,6 +564,28 @@ static int lag_decode_frame(AVCodecContext *avctx, } } break; + case FRAME_SOLID_COLOR: + if (avctx->bits_per_coded_sample == 24) { + avctx->pix_fmt = AV_PIX_FMT_RGB24; + } else { + avctx->pix_fmt = AV_PIX_FMT_RGB32; + offset_gu |= 0xFFU << 24; + } + + if ((ret = ff_thread_get_buffer(avctx, &frame,0)) < 0) + return ret; + + dst = p->data[0]; + for (j = 0; j < avctx->height; j++) { + for (i = 0; i < avctx->width; i++) + if (avctx->bits_per_coded_sample == 24) { + AV_WB24(dst + i * 3, offset_gu); + } else { + AV_WN32(dst + i * 4, offset_gu); + } + dst += p->linesize[0]; + } + break; case FRAME_ARITH_RGBA: avctx->pix_fmt = AV_PIX_FMT_RGB32; planes = 4; @@ -703,6 +733,7 @@ static av_cold int lag_decode_end(AVCodecContext *avctx) AVCodec ff_lagarith_decoder = { .name = "lagarith", + .long_name = NULL_IF_CONFIG_SMALL("Lagarith lossless"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_LAGARITH, .priv_data_size = sizeof(LagarithContext), @@ -710,5 +741,4 @@ AVCodec ff_lagarith_decoder = { .close = lag_decode_end, .decode = lag_decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, - .long_name = NULL_IF_CONFIG_SMALL("Lagarith lossless"), }; diff --git a/ffmpeg/libavcodec/lcldec.c b/ffmpeg/libavcodec/lcldec.c index 7948199..57519ea 100644 --- a/ffmpeg/libavcodec/lcldec.c +++ b/ffmpeg/libavcodec/lcldec.c @@ -42,6 +42,7 @@ #include #include "libavutil/mem.h" +#include "libavutil/pixdesc.h" #include "avcodec.h" #include "bytestream.h" #include "internal.h" @@ -482,6 +483,7 @@ static av_cold int decode_init(AVCodecContext *avctx) unsigned int max_basesize = FFALIGN(avctx->width, 4) * FFALIGN(avctx->height, 4); unsigned int max_decomp_size; + int subsample_h, subsample_v; if (avctx->extradata_size < 8) { av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n"); @@ -507,6 +509,10 @@ static av_cold int decode_init(AVCodecContext *avctx) max_decomp_size = max_basesize * 2; avctx->pix_fmt = AV_PIX_FMT_YUV422P; av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:2:2.\n"); + if (avctx->width % 4) { + avpriv_request_sample(avctx, "Unsupported dimensions\n"); + return AVERROR_INVALIDDATA; + } break; case IMGTYPE_RGB24: c->decomp_size = basesize * 3; @@ -537,6 +543,12 @@ static av_cold int decode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } + av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &subsample_h, &subsample_v); + if (avctx->width % (1<height % (1<compression = (int8_t)avctx->extradata[5]; switch (avctx->codec_id) { @@ -639,6 +651,7 @@ static av_cold int decode_end(AVCodecContext *avctx) #if CONFIG_MSZH_DECODER AVCodec ff_mszh_decoder = { .name = "mszh", + .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) MSZH"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MSZH, .priv_data_size = sizeof(LclDecContext), @@ -646,13 +659,13 @@ AVCodec ff_mszh_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) MSZH"), }; #endif #if CONFIG_ZLIB_DECODER AVCodec ff_zlib_decoder = { .name = "zlib", + .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_ZLIB, .priv_data_size = sizeof(LclDecContext), @@ -660,6 +673,5 @@ AVCodec ff_zlib_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"), }; #endif diff --git a/ffmpeg/libavcodec/lclenc.c b/ffmpeg/libavcodec/lclenc.c index 09beb98..0afe553 100644 --- a/ffmpeg/libavcodec/lclenc.c +++ b/ffmpeg/libavcodec/lclenc.c @@ -56,7 +56,6 @@ typedef struct LclEncContext { AVCodecContext *avctx; - AVFrame pic; // Image type int imgtype; @@ -73,20 +72,15 @@ typedef struct LclEncContext { * */ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, - const AVFrame *pict, int *got_packet) + const AVFrame *p, int *got_packet) { LclEncContext *c = avctx->priv_data; - AVFrame * const p = &c->pic; int i, ret; int zret; // Zlib return code int max_size = deflateBound(&c->zstream, avctx->width * avctx->height * 3); if ((ret = ff_alloc_packet2(avctx, pkt, max_size)) < 0) - return ret; - - *p = *pict; - p->pict_type= AV_PICTURE_TYPE_I; - p->key_frame= 1; + return ret; if(avctx->pix_fmt != AV_PIX_FMT_BGR24){ av_log(avctx, AV_LOG_ERROR, "Format not supported!\n"); @@ -137,8 +131,16 @@ static av_cold int encode_init(AVCodecContext *avctx) av_assert0(avctx->width && avctx->height); - avctx->extradata= av_mallocz(8); - avctx->coded_frame= &c->pic; + avctx->extradata = av_mallocz(8 + FF_INPUT_BUFFER_PADDING_SIZE); + if (!avctx->extradata) + return AVERROR(ENOMEM); + + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->key_frame = 1; c->compression = avctx->compression_level == FF_COMPRESSION_DEFAULT ? COMP_ZLIB_NORMAL : @@ -181,11 +183,14 @@ static av_cold int encode_end(AVCodecContext *avctx) av_freep(&avctx->extradata); deflateEnd(&c->zstream); + av_frame_free(&avctx->coded_frame); + return 0; } AVCodec ff_zlib_encoder = { .name = "zlib", + .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_ZLIB, .priv_data_size = sizeof(LclEncContext), @@ -193,5 +198,4 @@ AVCodec ff_zlib_encoder = { .encode2 = encode_frame, .close = encode_end, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"), }; diff --git a/ffmpeg/libavcodec/libaacplus.c b/ffmpeg/libavcodec/libaacplus.c index 05c9e38..545e240 100644 --- a/ffmpeg/libavcodec/libaacplus.c +++ b/ffmpeg/libavcodec/libaacplus.c @@ -43,42 +43,35 @@ static av_cold int aacPlus_encode_init(AVCodecContext *avctx) /* number of channels */ if (avctx->channels < 1 || avctx->channels > 2) { av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed\n", avctx->channels); - return -1; + return AVERROR(EINVAL); + } + + if (avctx->profile != FF_PROFILE_AAC_LOW && avctx->profile != FF_PROFILE_UNKNOWN) { + av_log(avctx, AV_LOG_ERROR, "invalid AAC profile: %d, only LC supported\n", avctx->profile); + return AVERROR(EINVAL); } s->aacplus_handle = aacplusEncOpen(avctx->sample_rate, avctx->channels, &s->samples_input, &s->max_output_bytes); - if(!s->aacplus_handle) { - av_log(avctx, AV_LOG_ERROR, "can't open encoder\n"); - return -1; + if (!s->aacplus_handle) { + av_log(avctx, AV_LOG_ERROR, "can't open encoder\n"); + return AVERROR(EINVAL); } /* check aacplus version */ aacplus_cfg = aacplusEncGetCurrentConfiguration(s->aacplus_handle); - /* put the options in the configuration struct */ - if(avctx->profile != FF_PROFILE_AAC_LOW && avctx->profile != FF_PROFILE_UNKNOWN) { - av_log(avctx, AV_LOG_ERROR, "invalid AAC profile: %d, only LC supported\n", avctx->profile); - aacplusEncClose(s->aacplus_handle); - return -1; - } - aacplus_cfg->bitRate = avctx->bit_rate; aacplus_cfg->bandWidth = avctx->cutoff; aacplus_cfg->outputFormat = !(avctx->flags & CODEC_FLAG_GLOBAL_HEADER); - aacplus_cfg->inputFormat = AACPLUS_INPUT_16BIT; + aacplus_cfg->inputFormat = avctx->sample_fmt == AV_SAMPLE_FMT_FLT ? AACPLUS_INPUT_FLOAT : AACPLUS_INPUT_16BIT; if (!aacplusEncSetConfiguration(s->aacplus_handle, aacplus_cfg)) { av_log(avctx, AV_LOG_ERROR, "libaacplus doesn't support this output format!\n"); - return -1; + return AVERROR(EINVAL); } avctx->frame_size = s->samples_input / avctx->channels; -#if FF_API_OLD_ENCODE_AUDIO - avctx->coded_frame= avcodec_alloc_frame(); - avctx->coded_frame->key_frame= 1; -#endif - /* Set decoder specific info */ avctx->extradata_size = 0; if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) { @@ -118,17 +111,20 @@ static av_cold int aacPlus_encode_close(AVCodecContext *avctx) { aacPlusAudioContext *s = avctx->priv_data; -#if FF_API_OLD_ENCODE_AUDIO - av_freep(&avctx->coded_frame); -#endif av_freep(&avctx->extradata); - aacplusEncClose(s->aacplus_handle); + return 0; } +static const AVProfile profiles[] = { + { FF_PROFILE_AAC_LOW, "LC" }, + { FF_PROFILE_UNKNOWN }, +}; + AVCodec ff_libaacplus_encoder = { .name = "libaacplus", + .long_name = NULL_IF_CONFIG_SMALL("libaacplus AAC+ (Advanced Audio Codec with SBR+PS)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_AAC, .priv_data_size = sizeof(aacPlusAudioContext), @@ -136,6 +132,10 @@ AVCodec ff_libaacplus_encoder = { .encode2 = aacPlus_encode_frame, .close = aacPlus_encode_close, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, + AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("libaacplus AAC+ (Advanced Audio Codec with SBR+PS)"), + .profiles = profiles, + .channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO, + AV_CH_LAYOUT_STEREO, + 0 }, }; diff --git a/ffmpeg/libavcodec/libavcodec.pc b/ffmpeg/libavcodec/libavcodec.pc index 7f192c8..5851cfb 100644 --- a/ffmpeg/libavcodec/libavcodec.pc +++ b/ffmpeg/libavcodec/libavcodec.pc @@ -5,10 +5,10 @@ includedir=${prefix}/include Name: libavcodec Description: FFmpeg codec library -Version: 55.1.100 +Version: 55.46.100 Requires: -Requires.private: libavutil = 52.22.100 +Requires.private: libavutil = 52.59.100 Conflicts: -Libs: -L${libdir} -lavcodec -Libs.private: -ldl -lXfixes -lXext -lX11 -ljack -lasound -lxvidcore -lx264 -lvorbisenc -lvorbis -logg -ltheoraenc -ltheoradec -logg -lschroedinger-1.0 -lmp3lame -lfaac -lm -pthread -lz -lrt +Libs: -L${libdir} -lavcodec +Libs.private: -lXfixes -lXext -lX11 -lx264 -lmp3lame -lm -lz -pthread Cflags: -I${includedir} diff --git a/ffmpeg/libavcodec/libavcodec.v b/ffmpeg/libavcodec/libavcodec.v index 826a547..69e653c 100644 --- a/ffmpeg/libavcodec/libavcodec.v +++ b/ffmpeg/libavcodec/libavcodec.v @@ -25,8 +25,6 @@ LIBAVCODEC_$MAJOR { ff_mmxext_idct; ff_idct_xvid*; ff_jpeg_fdct*; - #XBMC's configure checks for ff_vdpau_vc1_decode_picture() - ff_vdpau_vc1_decode_picture; ff_dnxhd_get_cid_table; ff_dnxhd_cid_table; local: *; diff --git a/ffmpeg/libavcodec/libcelt_dec.c b/ffmpeg/libavcodec/libcelt_dec.c index 53bbb72..4e62fe5 100644 --- a/ffmpeg/libavcodec/libcelt_dec.c +++ b/ffmpeg/libavcodec/libcelt_dec.c @@ -129,6 +129,7 @@ static int libcelt_dec_decode(AVCodecContext *c, void *data, AVCodec ff_libcelt_decoder = { .name = "libcelt", + .long_name = NULL_IF_CONFIG_SMALL("Xiph CELT decoder using libcelt"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_CELT, .priv_data_size = sizeof(struct libcelt_context), @@ -136,5 +137,4 @@ AVCodec ff_libcelt_decoder = { .close = libcelt_dec_close, .decode = libcelt_dec_decode, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Xiph CELT decoder using libcelt"), }; diff --git a/ffmpeg/libavcodec/libfaac.c b/ffmpeg/libavcodec/libfaac.c index ac18fe2..477669a 100644 --- a/ffmpeg/libavcodec/libfaac.c +++ b/ffmpeg/libavcodec/libfaac.c @@ -151,9 +151,20 @@ static av_cold int Faac_encode_init(AVCodecContext *avctx) } if (!faacEncSetConfiguration(s->faac_handle, faac_cfg)) { - av_log(avctx, AV_LOG_ERROR, "libfaac doesn't support this output format!\n"); - ret = AVERROR(EINVAL); - goto error; + int i; + for (i = avctx->bit_rate/1000; i ; i--) { + faac_cfg->bitRate = 1000*i / avctx->channels; + if (faacEncSetConfiguration(s->faac_handle, faac_cfg)) + break; + } + if (!i) { + av_log(avctx, AV_LOG_ERROR, "libfaac doesn't support this output format!\n"); + ret = AVERROR(EINVAL); + goto error; + } else { + avctx->bit_rate = 1000*i; + av_log(avctx, AV_LOG_WARNING, "libfaac doesn't support the specified bitrate, using %dkbit/s instead\n", i); + } } avctx->delay = FAAC_DELAY_SAMPLES; @@ -222,6 +233,7 @@ static const uint64_t faac_channel_layouts[] = { AVCodec ff_libfaac_encoder = { .name = "libfaac", + .long_name = NULL_IF_CONFIG_SMALL("libfaac AAC (Advanced Audio Coding)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_AAC, .priv_data_size = sizeof(FaacAudioContext), @@ -231,7 +243,6 @@ AVCodec ff_libfaac_encoder = { .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("libfaac AAC (Advanced Audio Coding)"), .profiles = NULL_IF_CONFIG_SMALL(profiles), .channel_layouts = faac_channel_layouts, }; diff --git a/ffmpeg/libavcodec/libfdk-aacenc.c b/ffmpeg/libavcodec/libfdk-aacenc.c index e3992e1..755b76f 100644 --- a/ffmpeg/libavcodec/libfdk-aacenc.c +++ b/ffmpeg/libavcodec/libfdk-aacenc.c @@ -197,6 +197,7 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) avctx->bit_rate = (96*sce + 128*cpe) * avctx->sample_rate / 44; if (avctx->profile == FF_PROFILE_AAC_HE || avctx->profile == FF_PROFILE_AAC_HE_V2 || + avctx->profile == FF_PROFILE_MPEG2_AAC_HE || s->eld_sbr) avctx->bit_rate /= 2; } @@ -393,6 +394,7 @@ static const int aac_sample_rates[] = { AVCodec ff_libfdk_aac_encoder = { .name = "libfdk_aac", + .long_name = NULL_IF_CONFIG_SMALL("Fraunhofer FDK AAC"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_AAC, .priv_data_size = sizeof(AACContext), @@ -402,7 +404,6 @@ AVCodec ff_libfdk_aac_encoder = { .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Fraunhofer FDK AAC"), .priv_class = &aac_enc_class, .defaults = aac_encode_defaults, .profiles = profiles, diff --git a/ffmpeg/libavcodec/libgsm.c b/ffmpeg/libavcodec/libgsm.c index 8250a15..5107bfe 100644 --- a/ffmpeg/libavcodec/libgsm.c +++ b/ffmpeg/libavcodec/libgsm.c @@ -118,6 +118,7 @@ static int libgsm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, #if CONFIG_LIBGSM_ENCODER AVCodec ff_libgsm_encoder = { .name = "libgsm", + .long_name = NULL_IF_CONFIG_SMALL("libgsm GSM"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_GSM, .init = libgsm_encode_init, @@ -125,12 +126,12 @@ AVCodec ff_libgsm_encoder = { .close = libgsm_encode_close, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("libgsm GSM"), }; #endif #if CONFIG_LIBGSM_MS_ENCODER AVCodec ff_libgsm_ms_encoder = { .name = "libgsm_ms", + .long_name = NULL_IF_CONFIG_SMALL("libgsm GSM Microsoft variant"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_GSM_MS, .init = libgsm_encode_init, @@ -138,7 +139,6 @@ AVCodec ff_libgsm_ms_encoder = { .close = libgsm_encode_close, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("libgsm GSM Microsoft variant"), }; #endif @@ -227,6 +227,7 @@ static void libgsm_flush(AVCodecContext *avctx) { #if CONFIG_LIBGSM_DECODER AVCodec ff_libgsm_decoder = { .name = "libgsm", + .long_name = NULL_IF_CONFIG_SMALL("libgsm GSM"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_GSM, .priv_data_size = sizeof(LibGSMDecodeContext), @@ -235,12 +236,12 @@ AVCodec ff_libgsm_decoder = { .decode = libgsm_decode_frame, .flush = libgsm_flush, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("libgsm GSM"), }; #endif #if CONFIG_LIBGSM_MS_DECODER AVCodec ff_libgsm_ms_decoder = { .name = "libgsm_ms", + .long_name = NULL_IF_CONFIG_SMALL("libgsm GSM Microsoft variant"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_GSM_MS, .priv_data_size = sizeof(LibGSMDecodeContext), @@ -249,6 +250,5 @@ AVCodec ff_libgsm_ms_decoder = { .decode = libgsm_decode_frame, .flush = libgsm_flush, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("libgsm GSM Microsoft variant"), }; #endif diff --git a/ffmpeg/libavcodec/libilbc.c b/ffmpeg/libavcodec/libilbc.c index b4163c6..898fe83 100644 --- a/ffmpeg/libavcodec/libilbc.c +++ b/ffmpeg/libavcodec/libilbc.c @@ -106,13 +106,13 @@ static int ilbc_decode_frame(AVCodecContext *avctx, void *data, AVCodec ff_libilbc_decoder = { .name = "libilbc", + .long_name = NULL_IF_CONFIG_SMALL("iLBC (Internet Low Bitrate Codec)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_ILBC, .priv_data_size = sizeof(ILBCDecContext), .init = ilbc_decode_init, .decode = ilbc_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("iLBC (Internet Low Bitrate Codec)"), .priv_class = &ilbc_dec_class, }; @@ -184,6 +184,7 @@ static const AVCodecDefault ilbc_encode_defaults[] = { AVCodec ff_libilbc_encoder = { .name = "libilbc", + .long_name = NULL_IF_CONFIG_SMALL("iLBC (Internet Low Bitrate Codec)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_ILBC, .priv_data_size = sizeof(ILBCEncContext), @@ -191,7 +192,6 @@ AVCodec ff_libilbc_encoder = { .encode2 = ilbc_encode_frame, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("iLBC (Internet Low Bitrate Codec)"), .defaults = ilbc_encode_defaults, .priv_class = &ilbc_enc_class, }; diff --git a/ffmpeg/libavcodec/libmp3lame.c b/ffmpeg/libavcodec/libmp3lame.c index 94e3582..e6cb64b 100644 --- a/ffmpeg/libavcodec/libmp3lame.c +++ b/ffmpeg/libavcodec/libmp3lame.c @@ -48,6 +48,8 @@ typedef struct LAMEContext { int buffer_index; int buffer_size; int reservoir; + int joint_stereo; + int abr; float *samples_flt[2]; AudioFrameQueue afq; AVFloatDSPContext fdsp; @@ -57,18 +59,14 @@ typedef struct LAMEContext { static int realloc_buffer(LAMEContext *s) { if (!s->buffer || s->buffer_size - s->buffer_index < BUFFER_SIZE) { - uint8_t *tmp; - int new_size = s->buffer_index + 2 * BUFFER_SIZE; + int new_size = s->buffer_index + 2 * BUFFER_SIZE, err; av_dlog(s->avctx, "resizing output buffer: %d -> %d\n", s->buffer_size, new_size); - tmp = av_realloc(s->buffer, new_size); - if (!tmp) { - av_freep(&s->buffer); + if ((err = av_reallocp(&s->buffer, new_size)) < 0) { s->buffer_size = s->buffer_index = 0; - return AVERROR(ENOMEM); + return err; } - s->buffer = tmp; s->buffer_size = new_size; } return 0; @@ -101,7 +99,7 @@ static av_cold int mp3lame_encode_init(AVCodecContext *avctx) lame_set_num_channels(s->gfp, avctx->channels); - lame_set_mode(s->gfp, avctx->channels > 1 ? JOINT_STEREO : MONO); + lame_set_mode(s->gfp, avctx->channels > 1 ? s->joint_stereo ? JOINT_STEREO : STEREO : MONO); /* sample rate */ lame_set_in_samplerate (s->gfp, avctx->sample_rate); @@ -114,12 +112,17 @@ static av_cold int mp3lame_encode_init(AVCodecContext *avctx) lame_set_quality(s->gfp, avctx->compression_level); /* rate control */ - if (avctx->flags & CODEC_FLAG_QSCALE) { + if (avctx->flags & CODEC_FLAG_QSCALE) { // VBR lame_set_VBR(s->gfp, vbr_default); lame_set_VBR_quality(s->gfp, avctx->global_quality / (float)FF_QP2LAMBDA); } else { - if (avctx->bit_rate) - lame_set_brate(s->gfp, avctx->bit_rate / 1000); + if (avctx->bit_rate) { + if (s->abr) { // ABR + lame_set_VBR(s->gfp, vbr_abr); + lame_set_VBR_mean_bitrate_kbps(s->gfp, avctx->bit_rate / 1000); + } else // CBR + lame_set_brate(s->gfp, avctx->bit_rate / 1000); + } } /* do not get a Xing VBR header frame from LAME */ @@ -262,7 +265,9 @@ static int mp3lame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, #define OFFSET(x) offsetof(LAMEContext, x) #define AE AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { - { "reservoir", "Use bit reservoir.", OFFSET(reservoir), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, AE }, + { "reservoir", "use bit reservoir", OFFSET(reservoir), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, AE }, + { "joint_stereo", "use joint stereo", OFFSET(joint_stereo), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, AE }, + { "abr", "use ABR", OFFSET(abr), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AE }, { NULL }, }; @@ -284,6 +289,7 @@ static const int libmp3lame_sample_rates[] = { AVCodec ff_libmp3lame_encoder = { .name = "libmp3lame", + .long_name = NULL_IF_CONFIG_SMALL("libmp3lame MP3 (MPEG audio layer 3)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_MP3, .priv_data_size = sizeof(LAMEContext), @@ -299,7 +305,6 @@ AVCodec ff_libmp3lame_encoder = { .channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO, AV_CH_LAYOUT_STEREO, 0 }, - .long_name = NULL_IF_CONFIG_SMALL("libmp3lame MP3 (MPEG audio layer 3)"), .priv_class = &libmp3lame_class, .defaults = libmp3lame_defaults, }; diff --git a/ffmpeg/libavcodec/libopencore-amr.c b/ffmpeg/libavcodec/libopencore-amr.c index c991106..3a8787b 100644 --- a/ffmpeg/libavcodec/libopencore-amr.c +++ b/ffmpeg/libavcodec/libopencore-amr.c @@ -128,6 +128,7 @@ static int amr_nb_decode_frame(AVCodecContext *avctx, void *data, AVCodec ff_libopencore_amrnb_decoder = { .name = "libopencore_amrnb", + .long_name = NULL_IF_CONFIG_SMALL("OpenCORE AMR-NB (Adaptive Multi-Rate Narrow-Band)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_AMR_NB, .priv_data_size = sizeof(AMRContext), @@ -135,7 +136,6 @@ AVCodec ff_libopencore_amrnb_decoder = { .close = amr_nb_decode_close, .decode = amr_nb_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("OpenCORE AMR-NB (Adaptive Multi-Rate Narrow-Band)"), }; #endif /* CONFIG_LIBOPENCORE_AMRNB_DECODER */ @@ -180,7 +180,7 @@ static const AVOption options[] = { { NULL } }; -static const AVClass class = { +static const AVClass amrnb_class = { "libopencore_amrnb", av_default_item_name, options, LIBAVUTIL_VERSION_INT }; @@ -205,7 +205,6 @@ static av_cold int amr_nb_encode_init(AVCodecContext *avctx) s->enc_state = Encoder_Interface_init(s->enc_dtx); if (!s->enc_state) { av_log(avctx, AV_LOG_ERROR, "Encoder_Interface_init error\n"); - av_freep(&avctx->coded_frame); return -1; } @@ -281,6 +280,7 @@ static int amr_nb_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, AVCodec ff_libopencore_amrnb_encoder = { .name = "libopencore_amrnb", + .long_name = NULL_IF_CONFIG_SMALL("OpenCORE AMR-NB (Adaptive Multi-Rate Narrow-Band)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_AMR_NB, .priv_data_size = sizeof(AMRContext), @@ -290,8 +290,7 @@ AVCodec ff_libopencore_amrnb_encoder = { .capabilities = CODEC_CAP_DELAY | CODEC_CAP_SMALL_LAST_FRAME, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("OpenCORE AMR-NB (Adaptive Multi-Rate Narrow-Band)"), - .priv_class = &class, + .priv_class = &amrnb_class, }; #endif /* CONFIG_LIBOPENCORE_AMRNB_ENCODER */ @@ -366,6 +365,7 @@ static int amr_wb_decode_close(AVCodecContext *avctx) AVCodec ff_libopencore_amrwb_decoder = { .name = "libopencore_amrwb", + .long_name = NULL_IF_CONFIG_SMALL("OpenCORE AMR-WB (Adaptive Multi-Rate Wide-Band)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_AMR_WB, .priv_data_size = sizeof(AMRWBContext), @@ -373,7 +373,6 @@ AVCodec ff_libopencore_amrwb_decoder = { .close = amr_wb_decode_close, .decode = amr_wb_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("OpenCORE AMR-WB (Adaptive Multi-Rate Wide-Band)"), }; #endif /* CONFIG_LIBOPENCORE_AMRWB_DECODER */ diff --git a/ffmpeg/libavcodec/libopenjpegdec.c b/ffmpeg/libavcodec/libopenjpegdec.c index f8b6165..0543e3a 100644 --- a/ffmpeg/libavcodec/libopenjpegdec.c +++ b/ffmpeg/libavcodec/libopenjpegdec.c @@ -32,6 +32,7 @@ #include "libavutil/pixfmt.h" #include "libavutil/opt.h" #include "avcodec.h" +#include "internal.h" #include "thread.h" #if HAVE_OPENJPEG_1_5_OPENJPEG_H @@ -59,10 +60,15 @@ AV_PIX_FMT_YUV420P16,AV_PIX_FMT_YUV422P16,AV_PIX_FMT_YUV444P16, \ AV_PIX_FMT_YUVA420P16,AV_PIX_FMT_YUVA422P16,AV_PIX_FMT_YUVA444P16 +#define XYZ_PIXEL_FORMATS AV_PIX_FMT_XYZ12 + static const enum AVPixelFormat libopenjpeg_rgb_pix_fmts[] = {RGB_PIXEL_FORMATS}; static const enum AVPixelFormat libopenjpeg_gray_pix_fmts[] = {GRAY_PIXEL_FORMATS}; static const enum AVPixelFormat libopenjpeg_yuv_pix_fmts[] = {YUV_PIXEL_FORMATS}; -static const enum AVPixelFormat libopenjpeg_all_pix_fmts[] = {RGB_PIXEL_FORMATS,GRAY_PIXEL_FORMATS,YUV_PIXEL_FORMATS}; +static const enum AVPixelFormat libopenjpeg_all_pix_fmts[] = {RGB_PIXEL_FORMATS, + GRAY_PIXEL_FORMATS, + YUV_PIXEL_FORMATS, + XYZ_PIXEL_FORMATS}; typedef struct { AVClass *class; @@ -202,12 +208,16 @@ static inline void libopenjpeg_copyto16(AVFrame *picture, opj_image_t *image) { int *comp_data; uint16_t *img_ptr; int index, x, y; + int adjust[4]; + for (x = 0; x < image->numcomps; x++) + adjust[x] = FFMAX(FFMIN(16 - image->comps[x].prec, 8), 0); + for (index = 0; index < image->numcomps; index++) { comp_data = image->comps[index].data; for (y = 0; y < image->comps[index].h; y++) { img_ptr = (uint16_t*) (picture->data[index] + y * picture->linesize[index]); for (x = 0; x < image->comps[index].w; x++) { - *img_ptr = *comp_data; + *img_ptr = *comp_data << adjust[index]; img_ptr++; comp_data++; } @@ -236,7 +246,7 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx, opj_dinfo_t *dec; opj_cio_t *stream; opj_image_t *image; - int width, height, ret = -1; + int width, height, ret; int pixel_size = 0; int ispacked = 0; int i; @@ -258,7 +268,7 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx, if (!dec) { av_log(avctx, AV_LOG_ERROR, "Error initializing decoder.\n"); - return -1; + return AVERROR_UNKNOWN; } opj_set_event_mgr((opj_common_ptr)dec, NULL, NULL); ctx->dec_params.cp_limit_decoding = LIMIT_TO_MAIN_HEADER; @@ -271,7 +281,7 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "Codestream could not be opened for reading.\n"); opj_destroy_decompress(dec); - return -1; + return AVERROR_UNKNOWN; } // Decode the header only. @@ -281,19 +291,15 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx, if (!image) { av_log(avctx, AV_LOG_ERROR, "Error decoding codestream.\n"); opj_destroy_decompress(dec); - return -1; + return AVERROR_UNKNOWN; } width = image->x1 - image->x0; height = image->y1 - image->y0; - if (av_image_check_size(width, height, 0, avctx) < 0) { - av_log(avctx, AV_LOG_ERROR, - "%dx%d dimension invalid.\n", width, height); + ret = ff_set_dimensions(avctx, width, height); + if (ret < 0) goto done; - } - - avcodec_set_dimensions(avctx, width, height); if (avctx->pix_fmt != AV_PIX_FMT_NONE) if (!libopenjpeg_matches_pix_fmt(image, avctx->pix_fmt)) @@ -310,7 +316,7 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx, if (image->comps[i].prec > avctx->bits_per_raw_sample) avctx->bits_per_raw_sample = image->comps[i].prec; - if (ff_thread_get_buffer(avctx, &frame, 0) < 0) + if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) goto done; ctx->dec_params.cp_limit_decoding = NO_LIMITATION; @@ -321,6 +327,7 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx, if (!stream) { av_log(avctx, AV_LOG_ERROR, "Codestream could not be opened for reading.\n"); + ret = AVERROR_UNKNOWN; goto done; } @@ -331,6 +338,7 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx, if (!image) { av_log(avctx, AV_LOG_ERROR, "Error decoding codestream.\n"); + ret = AVERROR_UNKNOWN; goto done; } @@ -367,6 +375,7 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx, break; default: av_log(avctx, AV_LOG_ERROR, "unsupported pixel size %d\n", pixel_size); + ret = AVERROR_PATCHWELCOME; goto done; } @@ -387,7 +396,7 @@ static const AVOption options[] = { { NULL }, }; -static const AVClass class = { +static const AVClass openjpeg_class = { .class_name = "libopenjpeg", .item_name = av_default_item_name, .option = options, @@ -396,6 +405,7 @@ static const AVClass class = { AVCodec ff_libopenjpeg_decoder = { .name = "libopenjpeg", + .long_name = NULL_IF_CONFIG_SMALL("OpenJPEG JPEG 2000"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_JPEG2000, .priv_data_size = sizeof(LibOpenJPEGContext), @@ -403,6 +413,5 @@ AVCodec ff_libopenjpeg_decoder = { .decode = libopenjpeg_decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, .max_lowres = 31, - .long_name = NULL_IF_CONFIG_SMALL("OpenJPEG JPEG 2000"), - .priv_class = &class, + .priv_class = &openjpeg_class, }; diff --git a/ffmpeg/libavcodec/libopenjpegenc.c b/ffmpeg/libavcodec/libopenjpegenc.c index c355083..0205c7d 100644 --- a/ffmpeg/libavcodec/libopenjpegenc.c +++ b/ffmpeg/libavcodec/libopenjpegenc.c @@ -43,6 +43,7 @@ typedef struct { AVClass *avclass; opj_image_t *image; + opj_cio_t *stream; opj_cparameters_t enc_params; opj_cinfo_t *compress; opj_event_mgr_t event_mgr; @@ -75,7 +76,7 @@ static void info_callback(const char *msg, void *data) static opj_image_t *mj2_create_image(AVCodecContext *avctx, opj_cparameters_t *parameters) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); - opj_image_cmptparm_t *cmptparm; + opj_image_cmptparm_t cmptparm[4] = {{0}}; opj_image_t *img; int i; int sub_dx[4]; @@ -106,6 +107,7 @@ static opj_image_t *mj2_create_image(AVCodecContext *avctx, opj_cparameters_t *p case AV_PIX_FMT_GBRP12: case AV_PIX_FMT_GBRP14: case AV_PIX_FMT_GBRP16: + case AV_PIX_FMT_XYZ12: color_space = CLRSPC_SRGB; break; case AV_PIX_FMT_YUV410P: @@ -150,23 +152,25 @@ static opj_image_t *mj2_create_image(AVCodecContext *avctx, opj_cparameters_t *p return NULL; } - cmptparm = av_mallocz(numcomps * sizeof(*cmptparm)); - if (!cmptparm) { - av_log(avctx, AV_LOG_ERROR, "Not enough memory\n"); - return NULL; - } for (i = 0; i < numcomps; i++) { cmptparm[i].prec = desc->comp[i].depth_minus1 + 1; cmptparm[i].bpp = desc->comp[i].depth_minus1 + 1; cmptparm[i].sgnd = 0; cmptparm[i].dx = sub_dx[i]; cmptparm[i].dy = sub_dy[i]; - cmptparm[i].w = avctx->width / sub_dx[i]; - cmptparm[i].h = avctx->height / sub_dy[i]; + cmptparm[i].w = (avctx->width + sub_dx[i] - 1) / sub_dx[i]; + cmptparm[i].h = (avctx->height + sub_dy[i] - 1) / sub_dy[i]; } img = opj_image_create(numcomps, cmptparm, color_space); - av_freep(&cmptparm); + + // x0, y0 is the top left corner of the image + // x1, y1 is the width, height of the reference grid + img->x0 = 0; + img->y0 = 0; + img->x1 = (avctx->width - 1) * parameters->subsampling_dx + 1; + img->y1 = (avctx->height - 1) * parameters->subsampling_dy + 1; + return img; } @@ -223,18 +227,26 @@ static av_cold int libopenjpeg_encode_init(AVCodecContext *avctx) return AVERROR(ENOMEM); } - avctx->coded_frame = avcodec_alloc_frame(); - if (!avctx->coded_frame) { - av_log(avctx, AV_LOG_ERROR, "Error allocating coded frame\n"); - goto fail; - } - ctx->image = mj2_create_image(avctx, &ctx->enc_params); if (!ctx->image) { av_log(avctx, AV_LOG_ERROR, "Error creating the mj2 image\n"); err = AVERROR(EINVAL); goto fail; } + opj_setup_encoder(ctx->compress, &ctx->enc_params, ctx->image); + + ctx->stream = opj_cio_open((opj_common_ptr)ctx->compress, NULL, 0); + if (!ctx->stream) { + av_log(avctx, AV_LOG_ERROR, "Error creating the cio stream\n"); + err = AVERROR(ENOMEM); + goto fail; + } + + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) { + av_log(avctx, AV_LOG_ERROR, "Error allocating coded frame\n"); + goto fail; + } memset(&ctx->event_mgr, 0, sizeof(opj_event_mgr_t)); ctx->event_mgr.info_handler = info_callback; @@ -245,7 +257,12 @@ static av_cold int libopenjpeg_encode_init(AVCodecContext *avctx) return 0; fail: - av_freep(&ctx->compress); + opj_cio_close(ctx->stream); + ctx->stream = NULL; + opj_destroy_compress(ctx->compress); + ctx->compress = NULL; + opj_image_destroy(ctx->image); + ctx->image = NULL; av_freep(&avctx->coded_frame); return err; } @@ -255,7 +272,7 @@ static int libopenjpeg_copy_packed8(AVCodecContext *avctx, const AVFrame *frame, int compno; int x; int y; - int image_index; + int *image_line; int frame_index; const int numcomps = image->numcomps; @@ -268,12 +285,62 @@ static int libopenjpeg_copy_packed8(AVCodecContext *avctx, const AVFrame *frame, for (compno = 0; compno < numcomps; ++compno) { for (y = 0; y < avctx->height; ++y) { - image_index = y * avctx->width; + image_line = image->comps[compno].data + y * image->comps[compno].w; frame_index = y * frame->linesize[0] + compno; for (x = 0; x < avctx->width; ++x) { - image->comps[compno].data[image_index++] = frame->data[0][frame_index]; + image_line[x] = frame->data[0][frame_index]; + frame_index += numcomps; + } + for (; x < image->comps[compno].w; ++x) { + image_line[x] = image_line[x - 1]; + } + } + for (; y < image->comps[compno].h; ++y) { + image_line = image->comps[compno].data + y * image->comps[compno].w; + for (x = 0; x < image->comps[compno].w; ++x) { + image_line[x] = image_line[x - image->comps[compno].w]; + } + } + } + + return 1; +} + +// for XYZ 12 bit +static int libopenjpeg_copy_packed12(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image) +{ + int compno; + int x; + int y; + int *image_line; + int frame_index; + const int numcomps = image->numcomps; + uint16_t *frame_ptr = (uint16_t*)frame->data[0]; + + for (compno = 0; compno < numcomps; ++compno) { + if (image->comps[compno].w > frame->linesize[0] / numcomps) { + av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n"); + return 0; + } + } + + for (compno = 0; compno < numcomps; ++compno) { + for (y = 0; y < avctx->height; ++y) { + image_line = image->comps[compno].data + y * image->comps[compno].w; + frame_index = y * (frame->linesize[0] / 2) + compno; + for (x = 0; x < avctx->width; ++x) { + image_line[x] = frame_ptr[frame_index] >> 4; frame_index += numcomps; } + for (; x < image->comps[compno].w; ++x) { + image_line[x] = image_line[x - 1]; + } + } + for (; y < image->comps[compno].h; ++y) { + image_line = image->comps[compno].data + y * image->comps[compno].w; + for (x = 0; x < image->comps[compno].w; ++x) { + image_line[x] = image_line[x - image->comps[compno].w]; + } } } @@ -285,7 +352,7 @@ static int libopenjpeg_copy_packed16(AVCodecContext *avctx, const AVFrame *frame int compno; int x; int y; - int image_index; + int *image_line; int frame_index; const int numcomps = image->numcomps; uint16_t *frame_ptr = (uint16_t*)frame->data[0]; @@ -299,12 +366,21 @@ static int libopenjpeg_copy_packed16(AVCodecContext *avctx, const AVFrame *frame for (compno = 0; compno < numcomps; ++compno) { for (y = 0; y < avctx->height; ++y) { - image_index = y * avctx->width; + image_line = image->comps[compno].data + y * image->comps[compno].w; frame_index = y * (frame->linesize[0] / 2) + compno; for (x = 0; x < avctx->width; ++x) { - image->comps[compno].data[image_index++] = frame_ptr[frame_index]; + image_line[x] = frame_ptr[frame_index]; frame_index += numcomps; } + for (; x < image->comps[compno].w; ++x) { + image_line[x] = image_line[x - 1]; + } + } + for (; y < image->comps[compno].h; ++y) { + image_line = image->comps[compno].data + y * image->comps[compno].w; + for (x = 0; x < image->comps[compno].w; ++x) { + image_line[x] = image_line[x - image->comps[compno].w]; + } } } @@ -318,7 +394,7 @@ static int libopenjpeg_copy_unpacked8(AVCodecContext *avctx, const AVFrame *fram int y; int width; int height; - int image_index; + int *image_line; int frame_index; const int numcomps = image->numcomps; @@ -333,10 +409,19 @@ static int libopenjpeg_copy_unpacked8(AVCodecContext *avctx, const AVFrame *fram width = avctx->width / image->comps[compno].dx; height = avctx->height / image->comps[compno].dy; for (y = 0; y < height; ++y) { - image_index = y * width; + image_line = image->comps[compno].data + y * image->comps[compno].w; frame_index = y * frame->linesize[compno]; for (x = 0; x < width; ++x) - image->comps[compno].data[image_index++] = frame->data[compno][frame_index++]; + image_line[x] = frame->data[compno][frame_index++]; + for (; x < image->comps[compno].w; ++x) { + image_line[x] = image_line[x - 1]; + } + } + for (; y < image->comps[compno].h; ++y) { + image_line = image->comps[compno].data + y * image->comps[compno].w; + for (x = 0; x < image->comps[compno].w; ++x) { + image_line[x] = image_line[x - image->comps[compno].w]; + } } } @@ -350,7 +435,7 @@ static int libopenjpeg_copy_unpacked16(AVCodecContext *avctx, const AVFrame *fra int y; int width; int height; - int image_index; + int *image_line; int frame_index; const int numcomps = image->numcomps; uint16_t *frame_ptr; @@ -367,10 +452,19 @@ static int libopenjpeg_copy_unpacked16(AVCodecContext *avctx, const AVFrame *fra height = avctx->height / image->comps[compno].dy; frame_ptr = (uint16_t*)frame->data[compno]; for (y = 0; y < height; ++y) { - image_index = y * width; + image_line = image->comps[compno].data + y * image->comps[compno].w; frame_index = y * (frame->linesize[compno] / 2); for (x = 0; x < width; ++x) - image->comps[compno].data[image_index++] = frame_ptr[frame_index++]; + image_line[x] = frame_ptr[frame_index++]; + for (; x < image->comps[compno].w; ++x) { + image_line[x] = image_line[x - 1]; + } + } + for (; y < image->comps[compno].h; ++y) { + image_line = image->comps[compno].data + y * image->comps[compno].w; + for (x = 0; x < image->comps[compno].w; ++x) { + image_line[x] = image_line[x - image->comps[compno].w]; + } } } @@ -383,17 +477,10 @@ static int libopenjpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt, LibOpenJPEGContext *ctx = avctx->priv_data; opj_cinfo_t *compress = ctx->compress; opj_image_t *image = ctx->image; - opj_cio_t *stream; + opj_cio_t *stream = ctx->stream; int cpyresult = 0; int ret, len; - AVFrame gbrframe; - - // x0, y0 is the top left corner of the image - // x1, y1 is the width, height of the reference grid - image->x0 = 0; - image->y0 = 0; - image->x1 = (avctx->width - 1) * ctx->enc_params.subsampling_dx + 1; - image->y1 = (avctx->height - 1) * ctx->enc_params.subsampling_dy + 1; + AVFrame *gbrframe; switch (avctx->pix_fmt) { case AV_PIX_FMT_RGB24: @@ -401,6 +488,9 @@ static int libopenjpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt, case AV_PIX_FMT_GRAY8A: cpyresult = libopenjpeg_copy_packed8(avctx, frame, image); break; + case AV_PIX_FMT_XYZ12: + cpyresult = libopenjpeg_copy_packed12(avctx, frame, image); + break; case AV_PIX_FMT_RGB48: case AV_PIX_FMT_RGBA64: cpyresult = libopenjpeg_copy_packed16(avctx, frame, image); @@ -411,18 +501,20 @@ static int libopenjpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt, case AV_PIX_FMT_GBRP12: case AV_PIX_FMT_GBRP14: case AV_PIX_FMT_GBRP16: - gbrframe = *frame; - gbrframe.data[0] = frame->data[2]; // swap to be rgb - gbrframe.data[1] = frame->data[0]; - gbrframe.data[2] = frame->data[1]; - gbrframe.linesize[0] = frame->linesize[2]; - gbrframe.linesize[1] = frame->linesize[0]; - gbrframe.linesize[2] = frame->linesize[1]; + gbrframe = av_frame_alloc(); + av_frame_ref(gbrframe, frame); + gbrframe->data[0] = frame->data[2]; // swap to be rgb + gbrframe->data[1] = frame->data[0]; + gbrframe->data[2] = frame->data[1]; + gbrframe->linesize[0] = frame->linesize[2]; + gbrframe->linesize[1] = frame->linesize[0]; + gbrframe->linesize[2] = frame->linesize[1]; if (avctx->pix_fmt == AV_PIX_FMT_GBR24P) { - cpyresult = libopenjpeg_copy_unpacked8(avctx, &gbrframe, image); + cpyresult = libopenjpeg_copy_unpacked8(avctx, gbrframe, image); } else { - cpyresult = libopenjpeg_copy_unpacked16(avctx, &gbrframe, image); + cpyresult = libopenjpeg_copy_unpacked16(avctx, gbrframe, image); } + av_frame_free(&gbrframe); break; case AV_PIX_FMT_GRAY8: case AV_PIX_FMT_YUV410P: @@ -477,29 +569,20 @@ static int libopenjpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return -1; } - opj_setup_encoder(compress, &ctx->enc_params, image); - stream = opj_cio_open((opj_common_ptr)compress, NULL, 0); - if (!stream) { - av_log(avctx, AV_LOG_ERROR, "Error creating the cio stream\n"); - return AVERROR(ENOMEM); - } - + cio_seek(stream, 0); if (!opj_encode(compress, stream, image, NULL)) { - opj_cio_close(stream); av_log(avctx, AV_LOG_ERROR, "Error during the opj encode\n"); return -1; } len = cio_tell(stream); if ((ret = ff_alloc_packet2(avctx, pkt, len)) < 0) { - opj_cio_close(stream); return ret; } memcpy(pkt->data, stream->buffer, len); pkt->flags |= AV_PKT_FLAG_KEY; *got_packet = 1; - opj_cio_close(stream); return 0; } @@ -507,8 +590,12 @@ static av_cold int libopenjpeg_encode_close(AVCodecContext *avctx) { LibOpenJPEGContext *ctx = avctx->priv_data; + opj_cio_close(ctx->stream); + ctx->stream = NULL; opj_destroy_compress(ctx->compress); + ctx->compress = NULL; opj_image_destroy(ctx->image); + ctx->image = NULL; av_freep(&avctx->coded_frame); return 0; } @@ -542,7 +629,7 @@ static const AVOption options[] = { { NULL }, }; -static const AVClass class = { +static const AVClass openjpeg_class = { .class_name = "libopenjpeg", .item_name = av_default_item_name, .option = options, @@ -551,6 +638,7 @@ static const AVClass class = { AVCodec ff_libopenjpeg_encoder = { .name = "libopenjpeg", + .long_name = NULL_IF_CONFIG_SMALL("OpenJPEG JPEG 2000"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_JPEG2000, .priv_data_size = sizeof(LibOpenJPEGContext), @@ -574,8 +662,8 @@ AVCodec ff_libopenjpeg_encoder = { AV_PIX_FMT_YUV420P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV444P14, AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA444P16, + AV_PIX_FMT_XYZ12, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("OpenJPEG JPEG 2000"), - .priv_class = &class, + .priv_class = &openjpeg_class, }; diff --git a/ffmpeg/libavcodec/libopusdec.c b/ffmpeg/libavcodec/libopusdec.c index 9b5cfe7..8436302 100644 --- a/ffmpeg/libavcodec/libopusdec.c +++ b/ffmpeg/libavcodec/libopusdec.c @@ -108,8 +108,8 @@ static av_cold int libopus_decode_init(AVCodecContext *avc) } #endif - avc->internal->skip_samples = opus->pre_skip; - avc->delay = 3840; /* Decoder delay (in samples) at 48kHz */ + /* Decoder delay (in samples) at 48kHz */ + avc->delay = avc->internal->skip_samples = opus->pre_skip; return 0; } @@ -183,6 +183,7 @@ static void libopus_flush(AVCodecContext *avc) AVCodec ff_libopus_decoder = { .name = "libopus", + .long_name = NULL_IF_CONFIG_SMALL("libopus Opus"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_OPUS, .priv_data_size = sizeof(struct libopus_context), @@ -191,7 +192,6 @@ AVCodec ff_libopus_decoder = { .decode = libopus_decode, .flush = libopus_flush, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("libopus Opus"), .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, diff --git a/ffmpeg/libavcodec/libopusenc.c b/ffmpeg/libavcodec/libopusenc.c index 04c297d..8ceb877 100644 --- a/ffmpeg/libavcodec/libopusenc.c +++ b/ffmpeg/libavcodec/libopusenc.c @@ -156,7 +156,7 @@ static int libopus_configure_encoder(AVCodecContext *avctx, OpusMSEncoder *enc, return OPUS_OK; } -static int av_cold libopus_encode_init(AVCodecContext *avctx) +static av_cold int libopus_encode_init(AVCodecContext *avctx) { LibopusEncContext *opus = avctx->priv_data; const uint8_t *channel_mapping; @@ -313,6 +313,7 @@ static int libopus_encode(AVCodecContext *avctx, AVPacket *avpkt, av_get_bytes_per_sample(avctx->sample_fmt); uint8_t *audio; int ret; + int discard_padding; if (frame) { ff_af_queue_add(&opus->afq, frame); @@ -354,12 +355,31 @@ static int libopus_encode(AVCodecContext *avctx, AVPacket *avpkt, ff_af_queue_remove(&opus->afq, opus->opts.packet_size, &avpkt->pts, &avpkt->duration); + discard_padding = opus->opts.packet_size - avpkt->duration; + // Check if subtraction resulted in an overflow + if ((discard_padding < opus->opts.packet_size) != (avpkt->duration > 0)) { + av_free_packet(avpkt); + av_free(avpkt); + return AVERROR(EINVAL); + } + if (discard_padding > 0) { + uint8_t* side_data = av_packet_new_side_data(avpkt, + AV_PKT_DATA_SKIP_SAMPLES, + 10); + if(side_data == NULL) { + av_free_packet(avpkt); + av_free(avpkt); + return AVERROR(ENOMEM); + } + AV_WL32(side_data + 4, discard_padding); + } + *got_packet_ptr = 1; return 0; } -static int av_cold libopus_encode_close(AVCodecContext *avctx) +static av_cold int libopus_encode_close(AVCodecContext *avctx) { LibopusEncContext *opus = avctx->priv_data; @@ -380,7 +400,7 @@ static const AVOption libopus_options[] = { { "voip", "Favor improved speech intelligibility", 0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_VOIP }, 0, 0, FLAGS, "application" }, { "audio", "Favor faithfulness to the input", 0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_AUDIO }, 0, 0, FLAGS, "application" }, { "lowdelay", "Restrict to only the lowest delay modes", 0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_RESTRICTED_LOWDELAY }, 0, 0, FLAGS, "application" }, - { "frame_duration", "Duration of a frame in milliseconds", OFFSET(frame_duration), AV_OPT_TYPE_FLOAT, { .dbl = 10.0 }, 2.5, 60.0, FLAGS }, + { "frame_duration", "Duration of a frame in milliseconds", OFFSET(frame_duration), AV_OPT_TYPE_FLOAT, { .dbl = 20.0 }, 2.5, 60.0, FLAGS }, { "packet_loss", "Expected packet loss percentage", OFFSET(packet_loss), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, FLAGS }, { "vbr", "Variable bit rate mode", OFFSET(vbr), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 2, FLAGS, "vbr" }, { "off", "Use constant bit rate", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FLAGS, "vbr" }, @@ -408,6 +428,7 @@ static const int libopus_sample_rates[] = { AVCodec ff_libopus_encoder = { .name = "libopus", + .long_name = NULL_IF_CONFIG_SMALL("libopus Opus"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_OPUS, .priv_data_size = sizeof(LibopusEncContext), @@ -420,7 +441,6 @@ AVCodec ff_libopus_encoder = { AV_SAMPLE_FMT_NONE }, .channel_layouts = ff_vorbis_channel_layouts, .supported_samplerates = libopus_sample_rates, - .long_name = NULL_IF_CONFIG_SMALL("libopus Opus"), .priv_class = &libopus_class, .defaults = libopus_defaults, }; diff --git a/ffmpeg/libavcodec/libschroedinger.c b/ffmpeg/libavcodec/libschroedinger.c index f452d70..9f0b25c 100644 --- a/ffmpeg/libavcodec/libschroedinger.c +++ b/ffmpeg/libavcodec/libschroedinger.c @@ -23,8 +23,9 @@ * function definitions common to libschroedinger decoder and encoder */ -#include "libschroedinger.h" +#include "libavutil/attributes.h" #include "libavutil/mem.h" +#include "libschroedinger.h" static const SchroVideoFormatInfo ff_schro_video_format_info[] = { { 640, 480, 24000, 1001}, @@ -66,7 +67,7 @@ static unsigned int get_video_format_idx(AVCodecContext *avctx) return ret_idx; } -void ff_schro_queue_init(FFSchroQueue *queue) +av_cold void ff_schro_queue_init(FFSchroQueue *queue) { queue->p_head = queue->p_tail = NULL; queue->size = 0; diff --git a/ffmpeg/libavcodec/libschroedingerdec.c b/ffmpeg/libavcodec/libschroedingerdec.c index 2e0ce5d..f20633a 100644 --- a/ffmpeg/libavcodec/libschroedingerdec.c +++ b/ffmpeg/libavcodec/libschroedingerdec.c @@ -374,6 +374,7 @@ static void libschroedinger_flush(AVCodecContext *avctx) AVCodec ff_libschroedinger_decoder = { .name = "libschroedinger", + .long_name = NULL_IF_CONFIG_SMALL("libschroedinger Dirac 2.2"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_DIRAC, .priv_data_size = sizeof(SchroDecoderParams), @@ -382,5 +383,4 @@ AVCodec ff_libschroedinger_decoder = { .decode = libschroedinger_decode_frame, .capabilities = CODEC_CAP_DELAY, .flush = libschroedinger_flush, - .long_name = NULL_IF_CONFIG_SMALL("libschroedinger Dirac 2.2"), }; diff --git a/ffmpeg/libavcodec/libschroedingerenc.c b/ffmpeg/libavcodec/libschroedingerenc.c index 297c6c5..294fb06 100644 --- a/ffmpeg/libavcodec/libschroedingerenc.c +++ b/ffmpeg/libavcodec/libschroedingerenc.c @@ -31,6 +31,7 @@ #include #include +#include "libavutil/attributes.h" #include "libavutil/avassert.h" #include "avcodec.h" #include "internal.h" @@ -46,9 +47,6 @@ typedef struct SchroEncoderParams { /** Schroedinger frame format */ SchroFrameFormat frame_format; - /** frame being encoded */ - AVFrame picture; - /** frame size */ int frame_size; @@ -100,7 +98,7 @@ static int set_chroma_format(AVCodecContext *avctx) return -1; } -static int libschroedinger_encode_init(AVCodecContext *avctx) +static av_cold int libschroedinger_encode_init(AVCodecContext *avctx) { SchroEncoderParams *p_schro_params = avctx->priv_data; SchroVideoFormatEnum preset; @@ -161,7 +159,9 @@ static int libschroedinger_encode_init(AVCodecContext *avctx) avctx->width, avctx->height); - avctx->coded_frame = &p_schro_params->picture; + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); if (!avctx->gop_size) { schro_encoder_setting_set_double(p_schro_params->encoder, @@ -293,21 +293,27 @@ static int libschroedinger_encode_frame(AVCodecContext *avctx, AVPacket *pkt, /* Now check to see if we have any output from the encoder. */ while (go) { + int err; SchroStateEnum state; state = schro_encoder_wait(encoder); switch (state) { case SCHRO_STATE_HAVE_BUFFER: case SCHRO_STATE_END_OF_STREAM: enc_buf = schro_encoder_pull(encoder, &presentation_frame); - av_assert0(enc_buf->length > 0); + if (enc_buf->length <= 0) + return AVERROR_BUG; parse_code = enc_buf->data[4]; /* All non-frame data is prepended to actual frame data to * be able to set the pts correctly. So we don't write data * to the frame output queue until we actually have a frame */ - p_schro_params->enc_buf = av_realloc(p_schro_params->enc_buf, - p_schro_params->enc_buf_size + enc_buf->length); + if ((err = av_reallocp(&p_schro_params->enc_buf, + p_schro_params->enc_buf_size + + enc_buf->length)) < 0) { + p_schro_params->enc_buf_size = 0; + return err; + } memcpy(p_schro_params->enc_buf + p_schro_params->enc_buf_size, enc_buf->data, enc_buf->length); @@ -426,12 +432,15 @@ static int libschroedinger_encode_close(AVCodecContext *avctx) /* Free the video format structure. */ av_freep(&p_schro_params->format); + av_frame_free(&avctx->coded_frame); + return 0; } AVCodec ff_libschroedinger_encoder = { .name = "libschroedinger", + .long_name = NULL_IF_CONFIG_SMALL("libschroedinger Dirac 2.2"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_DIRAC, .priv_data_size = sizeof(SchroEncoderParams), @@ -442,5 +451,4 @@ AVCodec ff_libschroedinger_encoder = { .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("libschroedinger Dirac 2.2"), }; diff --git a/ffmpeg/libavcodec/libspeexdec.c b/ffmpeg/libavcodec/libspeexdec.c index 7c1ffa6..afe1176 100644 --- a/ffmpeg/libavcodec/libspeexdec.c +++ b/ffmpeg/libavcodec/libspeexdec.c @@ -50,7 +50,17 @@ static av_cold int libspeex_decode_init(AVCodecContext *avctx) if (!header) av_log(avctx, AV_LOG_WARNING, "Invalid Speex header\n"); } - if (header) { + if (avctx->codec_tag == MKTAG('S', 'P', 'X', 'N')) { + if (!avctx->extradata || avctx->extradata && avctx->extradata_size < 47) { + av_log(avctx, AV_LOG_ERROR, "Missing or invalid extradata.\n"); + return AVERROR_INVALIDDATA; + } + if (avctx->extradata[37] != 10) { + av_log(avctx, AV_LOG_ERROR, "Unsupported quality mode.\n"); + return AVERROR_PATCHWELCOME; + } + spx_mode = 0; + } else if (header) { avctx->sample_rate = header->rate; avctx->channels = header->nb_channels; spx_mode = header->mode; @@ -170,6 +180,7 @@ static av_cold void libspeex_decode_flush(AVCodecContext *avctx) AVCodec ff_libspeex_decoder = { .name = "libspeex", + .long_name = NULL_IF_CONFIG_SMALL("libspeex Speex"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_SPEEX, .priv_data_size = sizeof(LibSpeexContext), @@ -178,5 +189,4 @@ AVCodec ff_libspeex_decoder = { .decode = libspeex_decode_frame, .flush = libspeex_decode_flush, .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DELAY | CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("libspeex Speex"), }; diff --git a/ffmpeg/libavcodec/libspeexenc.c b/ffmpeg/libavcodec/libspeexenc.c index b96ca1b..aba4618 100644 --- a/ffmpeg/libavcodec/libspeexenc.c +++ b/ffmpeg/libavcodec/libspeexenc.c @@ -334,7 +334,7 @@ static const AVOption options[] = { { NULL }, }; -static const AVClass class = { +static const AVClass speex_class = { .class_name = "libspeex", .item_name = av_default_item_name, .option = options, @@ -349,6 +349,7 @@ static const AVCodecDefault defaults[] = { AVCodec ff_libspeex_encoder = { .name = "libspeex", + .long_name = NULL_IF_CONFIG_SMALL("libspeex Speex"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_SPEEX, .priv_data_size = sizeof(LibSpeexEncContext), @@ -362,7 +363,6 @@ AVCodec ff_libspeex_encoder = { AV_CH_LAYOUT_STEREO, 0 }, .supported_samplerates = (const int[]){ 8000, 16000, 32000, 0 }, - .long_name = NULL_IF_CONFIG_SMALL("libspeex Speex"), - .priv_class = &class, + .priv_class = &speex_class, .defaults = defaults, }; diff --git a/ffmpeg/libavcodec/libstagefright.cpp b/ffmpeg/libavcodec/libstagefright.cpp index a6fd1b9..bb49d8a 100644 --- a/ffmpeg/libavcodec/libstagefright.cpp +++ b/ffmpeg/libavcodec/libstagefright.cpp @@ -36,6 +36,7 @@ extern "C" { #include "avcodec.h" #include "libavutil/imgutils.h" +#include "internal.h" } #define OMX_QCOM_COLOR_FormatYVU420SemiPlanar 0x7FA30C00 @@ -185,7 +186,7 @@ void* decode_thread(void *arg) buffer->release(); goto push_frame; } - ret = ff_get_buffer(avctx, frame->vframe); + ret = ff_get_buffer(avctx, frame->vframe, AV_GET_BUFFER_FLAG_REF); if (ret < 0) { frame->status = ret; decode_done = 1; @@ -456,10 +457,8 @@ static int Stagefright_decode_frame(AVCodecContext *avctx, void *data, return -1; } - if (s->prev_frame) { - avctx->release_buffer(avctx, s->prev_frame); - av_freep(&s->prev_frame); - } + if (s->prev_frame) + av_frame_free(&s->prev_frame); s->prev_frame = ret_frame; *got_frame = 1; @@ -481,10 +480,8 @@ static av_cold int Stagefright_close(AVCodecContext *avctx) while (!s->out_queue->empty()) { frame = *s->out_queue->begin(); s->out_queue->erase(s->out_queue->begin()); - if (frame->vframe) { - avctx->release_buffer(avctx, frame->vframe); - av_freep(&frame->vframe); - } + if (frame->vframe) + av_frame_free(&frame->vframe); av_freep(&frame); } pthread_mutex_unlock(&s->out_mutex); @@ -514,10 +511,8 @@ static av_cold int Stagefright_close(AVCodecContext *avctx) pthread_join(s->decode_thread_id, NULL); - if (s->prev_frame) { - avctx->release_buffer(avctx, s->prev_frame); - av_freep(&s->prev_frame); - } + if (s->prev_frame) + av_frame_free(&s->prev_frame); s->thread_started = false; } @@ -533,10 +528,8 @@ static av_cold int Stagefright_close(AVCodecContext *avctx) while (!s->out_queue->empty()) { frame = *s->out_queue->begin(); s->out_queue->erase(s->out_queue->begin()); - if (frame->vframe) { - avctx->release_buffer(avctx, frame->vframe); - av_freep(&frame->vframe); - } + if (frame->vframe) + av_frame_free(&frame->vframe); av_freep(&frame); } diff --git a/ffmpeg/libavcodec/libtheoraenc.c b/ffmpeg/libavcodec/libtheoraenc.c index 893370f..4c90822 100644 --- a/ffmpeg/libavcodec/libtheoraenc.c +++ b/ffmpeg/libavcodec/libtheoraenc.c @@ -58,31 +58,26 @@ static int concatenate_packet(unsigned int* offset, const ogg_packet* packet) { const char* message = NULL; - uint8_t* newdata = NULL; int newsize = avc_context->extradata_size + 2 + packet->bytes; - int ret; + int err = AVERROR_INVALIDDATA; if (packet->bytes < 0) { message = "ogg_packet has negative size"; - ret = AVERROR_INVALIDDATA; } else if (packet->bytes > 0xffff) { message = "ogg_packet is larger than 65535 bytes"; - ret = AVERROR_INVALIDDATA; } else if (newsize < avc_context->extradata_size) { message = "extradata_size would overflow"; - ret = AVERROR_INVALIDDATA; } else { - newdata = av_realloc(avc_context->extradata, newsize); - if (!newdata) + if ((err = av_reallocp(&avc_context->extradata, newsize)) < 0) { + avc_context->extradata_size = 0; message = "av_realloc failed"; - ret = AVERROR(ENOMEM); + } } if (message) { av_log(avc_context, AV_LOG_ERROR, "concatenate_packet failed: %s\n", message); - return ret; + return err; } - avc_context->extradata = newdata; avc_context->extradata_size = newsize; AV_WB16(avc_context->extradata + (*offset), packet->bytes); *offset += 2; @@ -207,11 +202,11 @@ static av_cold int encode_init(AVCodecContext* avc_context) avcodec_get_chroma_sub_sample(avc_context->pix_fmt, &h->uv_hshift, &h->uv_vshift); if (avc_context->flags & CODEC_FLAG_QSCALE) { - /* to be constant with the libvorbis implementation, clip global_quality to 0 - 10 - Theora accepts a quality parameter p, which is: - * 0 <= p <=63 - * an int value - */ + /* Clip global_quality in QP units to the [0 - 10] range + to be consistent with the libvorbis implementation. + Theora accepts a quality parameter which is an int value in + the [0 - 63] range. + */ t_info.quality = av_clipf(avc_context->global_quality / (float)FF_QP2LAMBDA, 0, 10) * 6.3; t_info.target_bitrate = 0; } else { @@ -264,7 +259,7 @@ static av_cold int encode_init(AVCodecContext* avc_context) th_comment_clear(&t_comment); /* Set up the output AVFrame */ - avc_context->coded_frame= avcodec_alloc_frame(); + avc_context->coded_frame = av_frame_alloc(); return 0; } @@ -368,6 +363,7 @@ static av_cold int encode_close(AVCodecContext* avc_context) /** AVCodec struct exposed to libavcodec */ AVCodec ff_libtheora_encoder = { .name = "libtheora", + .long_name = NULL_IF_CONFIG_SMALL("libtheora Theora"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_THEORA, .priv_data_size = sizeof(TheoraContext), @@ -378,5 +374,4 @@ AVCodec ff_libtheora_encoder = { .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("libtheora Theora"), }; diff --git a/ffmpeg/libavcodec/libtwolame.c b/ffmpeg/libavcodec/libtwolame.c index 8858714..dc4efe5 100644 --- a/ffmpeg/libavcodec/libtwolame.c +++ b/ffmpeg/libavcodec/libtwolame.c @@ -67,6 +67,8 @@ static av_cold int twolame_encode_init(AVCodecContext *avctx) twolame_set_psymodel(s->glopts, s->psymodel); twolame_set_energy_levels(s->glopts, s->energy); twolame_set_error_protection(s->glopts, s->error_protection); + twolame_set_copyright(s->glopts, s->copyright); + twolame_set_original(s->glopts, s->original); twolame_set_num_channels(s->glopts, avctx->channels); twolame_set_in_samplerate(s->glopts, avctx->sample_rate); @@ -175,6 +177,7 @@ static const AVClass libtwolame_class = { AVCodec ff_libtwolame_encoder = { .name = "libtwolame", + .long_name = NULL_IF_CONFIG_SMALL("libtwolame MP2 (MPEG audio layer 2)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_MP2, .priv_data_size = sizeof(TWOLAMEContext), @@ -191,6 +194,5 @@ AVCodec ff_libtwolame_encoder = { AV_CH_LAYOUT_STEREO, 0 }, .supported_samplerates = (const int[]){ 16000, 22050, 24000, 32000, 44100, 48000, 0 }, - .long_name = NULL_IF_CONFIG_SMALL("libtwolame MP2 (MPEG audio layer 2)"), .priv_class = &libtwolame_class, }; diff --git a/ffmpeg/libavcodec/libutvideo.h b/ffmpeg/libavcodec/libutvideo.h index b35d19c..5fb1174 100644 --- a/ffmpeg/libavcodec/libutvideo.h +++ b/ffmpeg/libavcodec/libutvideo.h @@ -21,7 +21,8 @@ /** * @file * Known FOURCCs: - * 'ULY0' (YCbCr 4:2:0), 'ULY2' (YCbCr 4:2:2), 'ULRG' (RGB), 'ULRA' (RGBA) + * 'ULY0' (YCbCr 4:2:0), 'ULY2' (YCbCr 4:2:2), 'ULRG' (RGB), 'ULRA' (RGBA), + * 'ULH0' (YCbCr 4:2:0 BT.709), 'ULH2' (YCbCr 4:2:2 BT.709) */ #ifndef AVCODEC_LIBUTVIDEO_H @@ -45,6 +46,14 @@ #define UTVF_NFCC_BGRA_BU UTVF_RGB32_WIN #endif +/* + * Ut Video version 13.0.1 introduced new BT.709 variants. + * Special-case these and only use them if v13 is detected. + */ +#if defined(UTVF_HDYC) +#define UTV_BT709 +#endif + typedef struct { uint32_t version; uint32_t original_format; diff --git a/ffmpeg/libavcodec/libutvideodec.cpp b/ffmpeg/libavcodec/libutvideodec.cpp index bc491e2..60dbd15 100644 --- a/ffmpeg/libavcodec/libutvideodec.cpp +++ b/ffmpeg/libavcodec/libutvideodec.cpp @@ -21,7 +21,8 @@ /** * @file * Known FOURCCs: - * 'ULY0' (YCbCr 4:2:0), 'ULY2' (YCbCr 4:2:2), 'ULRG' (RGB), 'ULRA' (RGBA) + * 'ULY0' (YCbCr 4:2:0), 'ULY2' (YCbCr 4:2:2), 'ULRG' (RGB), 'ULRA' (RGBA), + * 'ULH0' (YCbCr 4:2:0 BT.709), 'ULH2' (YCbCr 4:2:2 BT.709) */ extern "C" { @@ -51,6 +52,18 @@ static av_cold int utvideo_decode_init(AVCodecContext *avctx) /* Pick format based on FOURCC */ switch (avctx->codec_tag) { +#ifdef UTV_BT709 + case MKTAG('U', 'L', 'H', '0'): + avctx->pix_fmt = AV_PIX_FMT_YUV420P; + avctx->colorspace = AVCOL_SPC_BT709; + format = UTVF_YV12; + break; + case MKTAG('U', 'L', 'H', '2'): + avctx->pix_fmt = AV_PIX_FMT_YUYV422; + avctx->colorspace = AVCOL_SPC_BT709; + format = UTVF_YUY2; + break; +#endif case MKTAG('U', 'L', 'Y', '0'): avctx->pix_fmt = AV_PIX_FMT_YUV420P; format = UTVF_YV12; @@ -83,7 +96,7 @@ static av_cold int utvideo_decode_init(AVCodecContext *avctx) } /* Allocate the output frame */ - avctx->coded_frame = avcodec_alloc_frame(); + avctx->coded_frame = av_frame_alloc(); /* Ut Video only supports 8-bit */ avctx->bits_per_raw_sample = 8; @@ -151,7 +164,7 @@ static int utvideo_decode_frame(AVCodecContext *avctx, void *data, } *got_frame = 1; - *(AVFrame *)data = *pic; + av_frame_move_ref((AVFrame*)data, pic); return avpkt->size; } @@ -161,7 +174,7 @@ static av_cold int utvideo_decode_close(AVCodecContext *avctx) UtVideoContext *utv = (UtVideoContext *)avctx->priv_data; /* Free output */ - av_freep(&avctx->coded_frame); + av_frame_free(&avctx->coded_frame); av_freep(&utv->buffer); /* Finish decoding and clean up the instance */ diff --git a/ffmpeg/libavcodec/libutvideoenc.cpp b/ffmpeg/libavcodec/libutvideoenc.cpp index 07205f7..ad70669 100644 --- a/ffmpeg/libavcodec/libutvideoenc.cpp +++ b/ffmpeg/libavcodec/libutvideoenc.cpp @@ -21,7 +21,8 @@ /** * @file * Known FOURCCs: - * 'ULY0' (YCbCr 4:2:0), 'ULY2' (YCbCr 4:2:2), 'ULRG' (RGB), 'ULRA' (RGBA) + * 'ULY0' (YCbCr 4:2:0), 'ULY2' (YCbCr 4:2:2), 'ULRG' (RGB), 'ULRA' (RGBA), + * 'ULH0' (YCbCr 4:2:0 BT.709), 'ULH2' (YCbCr 4:2:2 BT.709) */ extern "C" { @@ -73,7 +74,7 @@ static av_cold int utvideo_encode_init(AVCodecContext *avctx) flags = ((avctx->prediction_method + 1) << 8) | (avctx->thread_count - 1); avctx->priv_data = utv; - avctx->coded_frame = avcodec_alloc_frame(); + avctx->coded_frame = av_frame_alloc(); /* Alloc extradata buffer */ info = (UtVideoExtra *)av_malloc(sizeof(*info)); diff --git a/ffmpeg/libavcodec/libvo-aacenc.c b/ffmpeg/libavcodec/libvo-aacenc.c index 4f4cbe7..04f9902 100644 --- a/ffmpeg/libavcodec/libvo-aacenc.c +++ b/ffmpeg/libavcodec/libvo-aacenc.c @@ -186,6 +186,7 @@ static const int mpeg4audio_sample_rates[16] = { AVCodec ff_libvo_aacenc_encoder = { .name = "libvo_aacenc", + .long_name = NULL_IF_CONFIG_SMALL("Android VisualOn AAC (Advanced Audio Coding)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_AAC, .priv_data_size = sizeof(AACContext), @@ -196,5 +197,4 @@ AVCodec ff_libvo_aacenc_encoder = { .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Android VisualOn AAC (Advanced Audio Coding)"), }; diff --git a/ffmpeg/libavcodec/libvo-amrwbenc.c b/ffmpeg/libavcodec/libvo-amrwbenc.c index a068cd0..4216a41 100644 --- a/ffmpeg/libavcodec/libvo-amrwbenc.c +++ b/ffmpeg/libavcodec/libvo-amrwbenc.c @@ -45,7 +45,7 @@ static const AVOption options[] = { { NULL } }; -static const AVClass class = { +static const AVClass amrwb_class = { "libvo_amrwbenc", av_default_item_name, options, LIBAVUTIL_VERSION_INT }; @@ -138,6 +138,8 @@ static int amr_wb_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, AVCodec ff_libvo_amrwbenc_encoder = { .name = "libvo_amrwbenc", + .long_name = NULL_IF_CONFIG_SMALL("Android VisualOn AMR-WB " + "(Adaptive Multi-Rate Wide-Band)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_AMR_WB, .priv_data_size = sizeof(AMRWBContext), @@ -146,7 +148,5 @@ AVCodec ff_libvo_amrwbenc_encoder = { .close = amr_wb_encode_close, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Android VisualOn AMR-WB " - "(Adaptive Multi-Rate Wide-Band)"), - .priv_class = &class, + .priv_class = &amrwb_class, }; diff --git a/ffmpeg/libavcodec/libvorbisdec.c b/ffmpeg/libavcodec/libvorbisdec.c index c4142cd..b703b65 100644 --- a/ffmpeg/libavcodec/libvorbisdec.c +++ b/ffmpeg/libavcodec/libvorbisdec.c @@ -171,7 +171,7 @@ static int oggvorbis_decode_frame(AVCodecContext *avccontext, void *data, } frame->nb_samples = total_samples; - *got_frame_ptr = 1; + *got_frame_ptr = total_samples > 0; return avpkt->size; } @@ -188,6 +188,7 @@ static int oggvorbis_decode_close(AVCodecContext *avccontext) { AVCodec ff_libvorbis_decoder = { .name = "libvorbis", + .long_name = NULL_IF_CONFIG_SMALL("libvorbis"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_VORBIS, .priv_data_size = sizeof(OggVorbisDecContext), @@ -195,5 +196,4 @@ AVCodec ff_libvorbis_decoder = { .decode = oggvorbis_decode_frame, .close = oggvorbis_decode_close, .capabilities = CODEC_CAP_DELAY, - .long_name = NULL_IF_CONFIG_SMALL("libvorbis"), }; diff --git a/ffmpeg/libavcodec/libvorbisenc.c b/ffmpeg/libavcodec/libvorbisenc.c index d3f86cc..fd788b7 100644 --- a/ffmpeg/libavcodec/libvorbisenc.c +++ b/ffmpeg/libavcodec/libvorbisenc.c @@ -41,7 +41,6 @@ typedef struct OggVorbisEncContext { AVClass *av_class; /**< class for AVOptions */ - AVFrame frame; vorbis_info vi; /**< vorbis_info used during init */ vorbis_dsp_state vd; /**< DSP state used for analysis */ vorbis_block vb; /**< vorbis_block used for analysis */ @@ -64,7 +63,7 @@ static const AVCodecDefault defaults[] = { { NULL }, }; -static const AVClass class = { +static const AVClass vorbis_class = { .class_name = "libvorbis", .item_name = av_default_item_name, .option = options, @@ -363,6 +362,7 @@ static int oggvorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, AVCodec ff_libvorbis_encoder = { .name = "libvorbis", + .long_name = NULL_IF_CONFIG_SMALL("libvorbis"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_VORBIS, .priv_data_size = sizeof(OggVorbisEncContext), @@ -372,7 +372,6 @@ AVCodec ff_libvorbis_encoder = { .capabilities = CODEC_CAP_DELAY, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("libvorbis"), - .priv_class = &class, + .priv_class = &vorbis_class, .defaults = defaults, }; diff --git a/ffmpeg/libavcodec/libvpxdec.c b/ffmpeg/libavcodec/libvpxdec.c index 5e80a9f..94e1e4d 100644 --- a/ffmpeg/libavcodec/libvpxdec.c +++ b/ffmpeg/libavcodec/libvpxdec.c @@ -31,6 +31,7 @@ #include "libavutil/imgutils.h" #include "avcodec.h" #include "internal.h" +#include "libvpx.h" typedef struct VP8DecoderContext { struct vpx_codec_ctx decoder; @@ -90,13 +91,13 @@ static int vp8_decode(AVCodecContext *avctx, if ((int) img->d_w != avctx->width || (int) img->d_h != avctx->height) { av_log(avctx, AV_LOG_INFO, "dimension change! %dx%d -> %dx%d\n", avctx->width, avctx->height, img->d_w, img->d_h); - if (av_image_check_size(img->d_w, img->d_h, 0, avctx)) - return AVERROR_INVALIDDATA; - avcodec_set_dimensions(avctx, img->d_w, img->d_h); + ret = ff_set_dimensions(avctx, img->d_w, img->d_h); + if (ret < 0) + return ret; } if ((ret = ff_get_buffer(avctx, picture, 0)) < 0) return ret; - av_image_copy(picture->data, picture->linesize, img->planes, + av_image_copy(picture->data, picture->linesize, (const uint8_t **)img->planes, img->stride, avctx->pix_fmt, img->d_w, img->d_h); *got_frame = 1; } @@ -118,6 +119,7 @@ static av_cold int vp8_init(AVCodecContext *avctx) AVCodec ff_libvpx_vp8_decoder = { .name = "libvpx", + .long_name = NULL_IF_CONFIG_SMALL("libvpx VP8"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VP8, .priv_data_size = sizeof(VP8Context), @@ -125,7 +127,6 @@ AVCodec ff_libvpx_vp8_decoder = { .close = vp8_free, .decode = vp8_decode, .capabilities = CODEC_CAP_AUTO_THREADS | CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("libvpx VP8"), }; #endif /* CONFIG_LIBVPX_VP8_DECODER */ @@ -137,13 +138,14 @@ static av_cold int vp9_init(AVCodecContext *avctx) AVCodec ff_libvpx_vp9_decoder = { .name = "libvpx-vp9", + .long_name = NULL_IF_CONFIG_SMALL("libvpx VP9"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VP9, .priv_data_size = sizeof(VP8Context), .init = vp9_init, .close = vp8_free, .decode = vp8_decode, - .capabilities = CODEC_CAP_AUTO_THREADS | CODEC_CAP_EXPERIMENTAL, - .long_name = NULL_IF_CONFIG_SMALL("libvpx VP9"), + .capabilities = CODEC_CAP_AUTO_THREADS | CODEC_CAP_DR1, + .init_static_data = ff_vp9_init_static, }; #endif /* CONFIG_LIBVPX_VP9_DECODER */ diff --git a/ffmpeg/libavcodec/libvpxenc.c b/ffmpeg/libavcodec/libvpxenc.c index 4f1adb8..869c8fe 100644 --- a/ffmpeg/libavcodec/libvpxenc.c +++ b/ffmpeg/libavcodec/libvpxenc.c @@ -31,8 +31,10 @@ #include "avcodec.h" #include "internal.h" #include "libavutil/avassert.h" +#include "libvpx.h" #include "libavutil/base64.h" #include "libavutil/common.h" +#include "libavutil/intreadwrite.h" #include "libavutil/mathematics.h" #include "libavutil/opt.h" @@ -43,6 +45,8 @@ struct FrameListData { void *buf; /**< compressed data buffer */ size_t sz; /**< length of compressed data */ + void *buf_alpha; + size_t sz_alpha; int64_t pts; /**< time stamp to show frame (in timebase units) */ unsigned long duration; /**< duration to show frame @@ -58,6 +62,9 @@ typedef struct VP8EncoderContext { AVClass *class; struct vpx_codec_ctx encoder; struct vpx_image rawimg; + struct vpx_codec_ctx encoder_alpha; + struct vpx_image rawimg_alpha; + uint8_t is_alpha; struct vpx_fixed_buf twopass_stats; int deadline; //i.e., RT/GOOD/BEST uint64_t sse[4]; @@ -83,6 +90,12 @@ typedef struct VP8EncoderContext { int error_resilient; int crf; int max_intra_rate; + + // VP9-only + int lossless; + int tile_columns; + int tile_rows; + int frame_parallel; } VP8Context; /** String mappings for enum vp8e_enc_control_id */ @@ -105,6 +118,12 @@ static const char *const ctlidstr[] = { [VP8E_SET_ARNR_TYPE] = "VP8E_SET_ARNR_TYPE", [VP8E_SET_CQ_LEVEL] = "VP8E_SET_CQ_LEVEL", [VP8E_SET_MAX_INTRA_BITRATE_PCT] = "VP8E_SET_MAX_INTRA_BITRATE_PCT", +#if CONFIG_LIBVPX_VP9_ENCODER + [VP9E_SET_LOSSLESS] = "VP9E_SET_LOSSLESS", + [VP9E_SET_TILE_COLUMNS] = "VP9E_SET_TILE_COLUMNS", + [VP9E_SET_TILE_ROWS] = "VP9E_SET_TILE_ROWS", + [VP9E_SET_FRAME_PARALLEL_DECODING] = "VP9E_SET_FRAME_PARALLEL_DECODING", +#endif }; static av_cold void log_encoder_error(AVCodecContext *avctx, const char *desc) @@ -186,6 +205,8 @@ static void coded_frame_add(void *list, struct FrameListData *cx_frame) static av_cold void free_coded_frame(struct FrameListData *cx_frame) { av_freep(&cx_frame->buf); + if (cx_frame->buf_alpha) + av_freep(&cx_frame->buf_alpha); av_freep(&cx_frame); } @@ -226,6 +247,8 @@ static av_cold int vp8_free(AVCodecContext *avctx) VP8Context *ctx = avctx->priv_data; vpx_codec_destroy(&ctx->encoder); + if (ctx->is_alpha) + vpx_codec_destroy(&ctx->encoder_alpha); av_freep(&ctx->twopass_stats.buf); av_freep(&avctx->coded_frame); av_freep(&avctx->stats_out); @@ -238,12 +261,16 @@ static av_cold int vpx_init(AVCodecContext *avctx, { VP8Context *ctx = avctx->priv_data; struct vpx_codec_enc_cfg enccfg; + struct vpx_codec_enc_cfg enccfg_alpha; vpx_codec_flags_t flags = (avctx->flags & CODEC_FLAG_PSNR) ? VPX_CODEC_USE_PSNR : 0; int res; av_log(avctx, AV_LOG_INFO, "%s\n", vpx_codec_version_str()); av_log(avctx, AV_LOG_VERBOSE, "%s\n", vpx_codec_build_config()); + if (avctx->pix_fmt == AV_PIX_FMT_YUVA420P) + ctx->is_alpha = 1; + if ((res = vpx_codec_enc_config_default(iface, &enccfg, 0)) != VPX_CODEC_OK) { av_log(avctx, AV_LOG_ERROR, "Failed to get config: %s\n", vpx_codec_err_to_string(res)); @@ -294,7 +321,7 @@ static av_cold int vpx_init(AVCodecContext *avctx, if (avctx->qmin >= 0) enccfg.rc_min_quantizer = avctx->qmin; - if (avctx->qmax > 0) + if (avctx->qmax >= 0) enccfg.rc_max_quantizer = avctx->qmax; if (enccfg.rc_end_usage == VPX_CQ) { @@ -377,6 +404,15 @@ static av_cold int vpx_init(AVCodecContext *avctx, return AVERROR(EINVAL); } + if (ctx->is_alpha) { + enccfg_alpha = enccfg; + res = vpx_codec_enc_init(&ctx->encoder_alpha, iface, &enccfg_alpha, flags); + if (res != VPX_CODEC_OK) { + log_encoder_error(avctx, "Failed to initialize alpha encoder"); + return AVERROR(EINVAL); + } + } + //codec control failures are currently treated only as warnings av_log(avctx, AV_LOG_DEBUG, "vpx_codec_control\n"); if (ctx->cpu_used != INT_MIN) @@ -392,19 +428,37 @@ static av_cold int vpx_init(AVCodecContext *avctx, if (ctx->arnr_type >= 0) codecctl_int(avctx, VP8E_SET_ARNR_TYPE, ctx->arnr_type); codecctl_int(avctx, VP8E_SET_NOISE_SENSITIVITY, avctx->noise_reduction); - codecctl_int(avctx, VP8E_SET_TOKEN_PARTITIONS, av_log2(avctx->slices)); + if (avctx->codec_id == AV_CODEC_ID_VP8) + codecctl_int(avctx, VP8E_SET_TOKEN_PARTITIONS, av_log2(avctx->slices)); codecctl_int(avctx, VP8E_SET_STATIC_THRESHOLD, avctx->mb_threshold); codecctl_int(avctx, VP8E_SET_CQ_LEVEL, ctx->crf); if (ctx->max_intra_rate >= 0) codecctl_int(avctx, VP8E_SET_MAX_INTRA_BITRATE_PCT, ctx->max_intra_rate); +#if CONFIG_LIBVPX_VP9_ENCODER + if (avctx->codec_id == AV_CODEC_ID_VP9) { + if (ctx->lossless >= 0) + codecctl_int(avctx, VP9E_SET_LOSSLESS, ctx->lossless); + if (ctx->tile_columns >= 0) + codecctl_int(avctx, VP9E_SET_TILE_COLUMNS, ctx->tile_columns); + if (ctx->tile_rows >= 0) + codecctl_int(avctx, VP9E_SET_TILE_ROWS, ctx->tile_rows); + if (ctx->frame_parallel >= 0) + codecctl_int(avctx, VP9E_SET_FRAME_PARALLEL_DECODING, ctx->frame_parallel); + } +#endif + av_log(avctx, AV_LOG_DEBUG, "Using deadline: %d\n", ctx->deadline); //provide dummy value to initialize wrapper, values will be updated each _encode() vpx_img_wrap(&ctx->rawimg, VPX_IMG_FMT_I420, avctx->width, avctx->height, 1, (unsigned char*)1); - avctx->coded_frame = avcodec_alloc_frame(); + if (ctx->is_alpha) + vpx_img_wrap(&ctx->rawimg_alpha, VPX_IMG_FMT_I420, avctx->width, avctx->height, 1, + (unsigned char*)1); + + avctx->coded_frame = av_frame_alloc(); if (!avctx->coded_frame) { av_log(avctx, AV_LOG_ERROR, "Error allocating coded frame\n"); vp8_free(avctx); @@ -415,6 +469,7 @@ static av_cold int vpx_init(AVCodecContext *avctx, static inline void cx_pktcpy(struct FrameListData *dst, const struct vpx_codec_cx_pkt *src, + const struct vpx_codec_cx_pkt *src_alpha, VP8Context *ctx) { dst->pts = src->data.frame.pts; @@ -438,6 +493,14 @@ static inline void cx_pktcpy(struct FrameListData *dst, } else { dst->frame_number = -1; /* sanity marker */ } + if (src_alpha) { + dst->buf_alpha = src_alpha->data.frame.buf; + dst->sz_alpha = src_alpha->data.frame.sz; + } + else { + dst->buf_alpha = NULL; + dst->sz_alpha = 0; + } } /** @@ -451,6 +514,7 @@ static int storeframe(AVCodecContext *avctx, struct FrameListData *cx_frame, AVPacket *pkt, AVFrame *coded_frame) { int ret = ff_alloc_packet2(avctx, pkt, cx_frame->sz); + uint8_t *side_data; if (ret >= 0) { memcpy(pkt->data, cx_frame->buf, pkt->size); pkt->pts = pkt->dts = cx_frame->pts; @@ -475,6 +539,18 @@ static int storeframe(AVCodecContext *avctx, struct FrameListData *cx_frame, } cx_frame->have_sse = 0; } + if (cx_frame->sz_alpha > 0) { + side_data = av_packet_new_side_data(pkt, + AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, + cx_frame->sz_alpha + 8); + if(side_data == NULL) { + av_free_packet(pkt); + av_free(pkt); + return AVERROR(ENOMEM); + } + AV_WB64(side_data, 1); + memcpy(side_data + 8, cx_frame->buf_alpha, cx_frame->sz_alpha); + } } else { return ret; } @@ -494,7 +570,9 @@ static int queue_frames(AVCodecContext *avctx, AVPacket *pkt_out, { VP8Context *ctx = avctx->priv_data; const struct vpx_codec_cx_pkt *pkt; + const struct vpx_codec_cx_pkt *pkt_alpha = NULL; const void *iter = NULL; + const void *iter_alpha = NULL; int size = 0; if (ctx->coded_frame_list) { @@ -509,7 +587,9 @@ static int queue_frames(AVCodecContext *avctx, AVPacket *pkt_out, /* consume all available output from the encoder before returning. buffers are only good through the next vpx_codec call */ - while ((pkt = vpx_codec_get_cx_data(&ctx->encoder, &iter))) { + while ((pkt = vpx_codec_get_cx_data(&ctx->encoder, &iter)) && + (!ctx->is_alpha || + (ctx->is_alpha && (pkt_alpha = vpx_codec_get_cx_data(&ctx->encoder_alpha, &iter_alpha))))) { switch (pkt->kind) { case VPX_CODEC_CX_FRAME_PKT: if (!size) { @@ -518,7 +598,7 @@ static int queue_frames(AVCodecContext *avctx, AVPacket *pkt_out, /* avoid storing the frame when the list is empty and we haven't yet provided a frame for output */ av_assert0(!ctx->coded_frame_list); - cx_pktcpy(&cx_frame, pkt, ctx); + cx_pktcpy(&cx_frame, pkt, pkt_alpha, ctx); size = storeframe(avctx, &cx_frame, pkt_out, coded_frame); if (size < 0) return size; @@ -531,7 +611,7 @@ static int queue_frames(AVCodecContext *avctx, AVPacket *pkt_out, "Frame queue element alloc failed\n"); return AVERROR(ENOMEM); } - cx_pktcpy(cx_frame, pkt, ctx); + cx_pktcpy(cx_frame, pkt, pkt_alpha, ctx); cx_frame->buf = av_malloc(cx_frame->sz); if (!cx_frame->buf) { @@ -542,16 +622,29 @@ static int queue_frames(AVCodecContext *avctx, AVPacket *pkt_out, return AVERROR(ENOMEM); } memcpy(cx_frame->buf, pkt->data.frame.buf, pkt->data.frame.sz); + if (ctx->is_alpha) { + cx_frame->buf_alpha = av_malloc(cx_frame->sz_alpha); + if (!cx_frame->buf_alpha) { + av_log(avctx, AV_LOG_ERROR, + "Data buffer alloc (%zu bytes) failed\n", + cx_frame->sz_alpha); + av_free(cx_frame); + return AVERROR(ENOMEM); + } + memcpy(cx_frame->buf_alpha, pkt_alpha->data.frame.buf, pkt_alpha->data.frame.sz); + } coded_frame_add(&ctx->coded_frame_list, cx_frame); } break; case VPX_CODEC_STATS_PKT: { struct vpx_fixed_buf *stats = &ctx->twopass_stats; - stats->buf = av_realloc_f(stats->buf, 1, - stats->sz + pkt->data.twopass_stats.sz); - if (!stats->buf) { + int err; + if ((err = av_reallocp(&stats->buf, + stats->sz + + pkt->data.twopass_stats.sz)) < 0) { + stats->sz = 0; av_log(avctx, AV_LOG_ERROR, "Stat buffer realloc failed\n"); - return AVERROR(ENOMEM); + return err; } memcpy((uint8_t*)stats->buf + stats->sz, pkt->data.twopass_stats.buf, pkt->data.twopass_stats.sz); @@ -580,6 +673,7 @@ static int vp8_encode(AVCodecContext *avctx, AVPacket *pkt, { VP8Context *ctx = avctx->priv_data; struct vpx_image *rawimg = NULL; + struct vpx_image *rawimg_alpha = NULL; int64_t timestamp = 0; int res, coded_size; vpx_enc_frame_flags_t flags = 0; @@ -592,6 +686,20 @@ static int vp8_encode(AVCodecContext *avctx, AVPacket *pkt, rawimg->stride[VPX_PLANE_Y] = frame->linesize[0]; rawimg->stride[VPX_PLANE_U] = frame->linesize[1]; rawimg->stride[VPX_PLANE_V] = frame->linesize[2]; + if (ctx->is_alpha) { + uint8_t *u_plane, *v_plane; + rawimg_alpha = &ctx->rawimg_alpha; + rawimg_alpha->planes[VPX_PLANE_Y] = frame->data[3]; + u_plane = av_malloc(frame->linesize[1] * frame->height); + memset(u_plane, 0x80, frame->linesize[1] * frame->height); + rawimg_alpha->planes[VPX_PLANE_U] = u_plane; + v_plane = av_malloc(frame->linesize[2] * frame->height); + memset(v_plane, 0x80, frame->linesize[2] * frame->height); + rawimg_alpha->planes[VPX_PLANE_V] = v_plane; + rawimg_alpha->stride[VPX_PLANE_Y] = frame->linesize[0]; + rawimg_alpha->stride[VPX_PLANE_U] = frame->linesize[1]; + rawimg_alpha->stride[VPX_PLANE_V] = frame->linesize[2]; + } timestamp = frame->pts; if (frame->pict_type == AV_PICTURE_TYPE_I) flags |= VPX_EFLAG_FORCE_KF; @@ -603,6 +711,16 @@ static int vp8_encode(AVCodecContext *avctx, AVPacket *pkt, log_encoder_error(avctx, "Error encoding frame"); return AVERROR_INVALIDDATA; } + + if (ctx->is_alpha) { + res = vpx_codec_encode(&ctx->encoder_alpha, rawimg_alpha, timestamp, + avctx->ticks_per_frame, flags, ctx->deadline); + if (res != VPX_CODEC_OK) { + log_encoder_error(avctx, "Error encoding alpha frame"); + return AVERROR_INVALIDDATA; + } + } + coded_size = queue_frames(avctx, pkt, avctx->coded_frame); if (!frame && avctx->flags & CODEC_FLAG_PASS1) { @@ -618,49 +736,81 @@ static int vp8_encode(AVCodecContext *avctx, AVPacket *pkt, ctx->twopass_stats.sz); } + if (rawimg_alpha) { + av_free(rawimg_alpha->planes[VPX_PLANE_U]); + av_free(rawimg_alpha->planes[VPX_PLANE_V]); + } + *got_packet = !!coded_size; return 0; } #define OFFSET(x) offsetof(VP8Context, x) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM -static const AVOption options[] = { - { "cpu-used", "Quality/Speed ratio modifier", OFFSET(cpu_used), AV_OPT_TYPE_INT, {.i64 = INT_MIN}, INT_MIN, INT_MAX, VE}, - { "auto-alt-ref", "Enable use of alternate reference " - "frames (2-pass only)", OFFSET(auto_alt_ref), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, VE}, - { "lag-in-frames", "Number of frames to look ahead for " - "alternate reference frame selection", OFFSET(lag_in_frames), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE}, - { "arnr-maxframes", "altref noise reduction max frame count", OFFSET(arnr_max_frames), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE}, - { "arnr-strength", "altref noise reduction filter strength", OFFSET(arnr_strength), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE}, - { "arnr-type", "altref noise reduction filter type", OFFSET(arnr_type), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE, "arnr_type"}, - { "backward", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 0, VE, "arnr_type" }, - { "forward", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 0, VE, "arnr_type" }, - { "centered", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 3}, 0, 0, VE, "arnr_type" }, - { "deadline", "Time to spend encoding, in microseconds.", OFFSET(deadline), AV_OPT_TYPE_INT, {.i64 = VPX_DL_GOOD_QUALITY}, INT_MIN, INT_MAX, VE, "quality"}, - { "best", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VPX_DL_BEST_QUALITY}, 0, 0, VE, "quality"}, - { "good", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VPX_DL_GOOD_QUALITY}, 0, 0, VE, "quality"}, - { "realtime", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VPX_DL_REALTIME}, 0, 0, VE, "quality"}, - { "error-resilient", "Error resilience configuration", OFFSET(error_resilient), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, VE, "er"}, - { "max-intra-rate", "Maximum I-frame bitrate (pct) 0=unlimited", OFFSET(max_intra_rate), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE}, -#ifdef VPX_ERROR_RESILIENT_DEFAULT - { "default", "Improve resiliency against losses of whole frames", 0, AV_OPT_TYPE_CONST, {.i64 = VPX_ERROR_RESILIENT_DEFAULT}, 0, 0, VE, "er"}, - { "partitions", "The frame partitions are independently decodable " - "by the bool decoder, meaning that partitions can be decoded even " - "though earlier partitions have been lost. Note that intra predicition" - " is still done over the partition boundary.", 0, AV_OPT_TYPE_CONST, {.i64 = VPX_ERROR_RESILIENT_PARTITIONS}, 0, 0, VE, "er"}, + +#ifndef VPX_ERROR_RESILIENT_DEFAULT +#define VPX_ERROR_RESILIENT_DEFAULT 1 +#define VPX_ERROR_RESILIENT_PARTITIONS 2 +#endif + +#define COMMON_OPTIONS \ + { "cpu-used", "Quality/Speed ratio modifier", OFFSET(cpu_used), AV_OPT_TYPE_INT, {.i64 = INT_MIN}, INT_MIN, INT_MAX, VE}, \ + { "auto-alt-ref", "Enable use of alternate reference " \ + "frames (2-pass only)", OFFSET(auto_alt_ref), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, VE}, \ + { "lag-in-frames", "Number of frames to look ahead for " \ + "alternate reference frame selection", OFFSET(lag_in_frames), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE}, \ + { "arnr-maxframes", "altref noise reduction max frame count", OFFSET(arnr_max_frames), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE}, \ + { "arnr-strength", "altref noise reduction filter strength", OFFSET(arnr_strength), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE}, \ + { "arnr-type", "altref noise reduction filter type", OFFSET(arnr_type), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE, "arnr_type"}, \ + { "backward", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 0, VE, "arnr_type" }, \ + { "forward", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 0, VE, "arnr_type" }, \ + { "centered", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 3}, 0, 0, VE, "arnr_type" }, \ + { "deadline", "Time to spend encoding, in microseconds.", OFFSET(deadline), AV_OPT_TYPE_INT, {.i64 = VPX_DL_GOOD_QUALITY}, INT_MIN, INT_MAX, VE, "quality"}, \ + { "best", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VPX_DL_BEST_QUALITY}, 0, 0, VE, "quality"}, \ + { "good", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VPX_DL_GOOD_QUALITY}, 0, 0, VE, "quality"}, \ + { "realtime", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VPX_DL_REALTIME}, 0, 0, VE, "quality"}, \ + { "error-resilient", "Error resilience configuration", OFFSET(error_resilient), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, VE, "er"}, \ + { "max-intra-rate", "Maximum I-frame bitrate (pct) 0=unlimited", OFFSET(max_intra_rate), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE}, \ + { "default", "Improve resiliency against losses of whole frames", 0, AV_OPT_TYPE_CONST, {.i64 = VPX_ERROR_RESILIENT_DEFAULT}, 0, 0, VE, "er"}, \ + { "partitions", "The frame partitions are independently decodable " \ + "by the bool decoder, meaning that partitions can be decoded even " \ + "though earlier partitions have been lost. Note that intra predicition" \ + " is still done over the partition boundary.", 0, AV_OPT_TYPE_CONST, {.i64 = VPX_ERROR_RESILIENT_PARTITIONS}, 0, 0, VE, "er"}, \ + { "crf", "Select the quality for constant quality mode", offsetof(VP8Context, crf), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 63, VE }, \ + +#define LEGACY_OPTIONS \ + {"speed", "", offsetof(VP8Context, cpu_used), AV_OPT_TYPE_INT, {.i64 = 1}, -16, 16, VE}, \ + {"quality", "", offsetof(VP8Context, deadline), AV_OPT_TYPE_INT, {.i64 = VPX_DL_GOOD_QUALITY}, INT_MIN, INT_MAX, VE, "quality"}, \ + {"vp8flags", "", offsetof(VP8Context, flags), FF_OPT_TYPE_FLAGS, {.i64 = 0}, 0, UINT_MAX, VE, "flags"}, \ + {"error_resilient", "enable error resilience", 0, FF_OPT_TYPE_CONST, {.dbl = VP8F_ERROR_RESILIENT}, INT_MIN, INT_MAX, VE, "flags"}, \ + {"altref", "enable use of alternate reference frames (VP8/2-pass only)", 0, FF_OPT_TYPE_CONST, {.dbl = VP8F_AUTO_ALT_REF}, INT_MIN, INT_MAX, VE, "flags"}, \ + {"arnr_max_frames", "altref noise reduction max frame count", offsetof(VP8Context, arnr_max_frames), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 15, VE}, \ + {"arnr_strength", "altref noise reduction filter strength", offsetof(VP8Context, arnr_strength), AV_OPT_TYPE_INT, {.i64 = 3}, 0, 6, VE}, \ + {"arnr_type", "altref noise reduction filter type", offsetof(VP8Context, arnr_type), AV_OPT_TYPE_INT, {.i64 = 3}, 1, 3, VE}, \ + {"rc_lookahead", "Number of frames to look ahead for alternate reference frame selection", offsetof(VP8Context, lag_in_frames), AV_OPT_TYPE_INT, {.i64 = 25}, 0, 25, VE}, \ + +#if CONFIG_LIBVPX_VP8_ENCODER +static const AVOption vp8_options[] = { + COMMON_OPTIONS + LEGACY_OPTIONS + { NULL } +}; #endif -{"speed", "", offsetof(VP8Context, cpu_used), AV_OPT_TYPE_INT, {.i64 = 3}, -16, 16, VE}, -{"quality", "", offsetof(VP8Context, deadline), AV_OPT_TYPE_INT, {.i64 = VPX_DL_GOOD_QUALITY}, INT_MIN, INT_MAX, VE, "quality"}, -{"vp8flags", "", offsetof(VP8Context, flags), FF_OPT_TYPE_FLAGS, {.i64 = 0}, 0, UINT_MAX, VE, "flags"}, -{"error_resilient", "enable error resilience", 0, FF_OPT_TYPE_CONST, {.dbl = VP8F_ERROR_RESILIENT}, INT_MIN, INT_MAX, VE, "flags"}, -{"altref", "enable use of alternate reference frames (VP8/2-pass only)", 0, FF_OPT_TYPE_CONST, {.dbl = VP8F_AUTO_ALT_REF}, INT_MIN, INT_MAX, VE, "flags"}, -{"arnr_max_frames", "altref noise reduction max frame count", offsetof(VP8Context, arnr_max_frames), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 15, VE}, -{"arnr_strength", "altref noise reduction filter strength", offsetof(VP8Context, arnr_strength), AV_OPT_TYPE_INT, {.i64 = 3}, 0, 6, VE}, -{"arnr_type", "altref noise reduction filter type", offsetof(VP8Context, arnr_type), AV_OPT_TYPE_INT, {.i64 = 3}, 1, 3, VE}, -{"rc_lookahead", "Number of frames to look ahead for alternate reference frame selection", offsetof(VP8Context, lag_in_frames), AV_OPT_TYPE_INT, {.i64 = 25}, 0, 25, VE}, - { "crf", "Select the quality for constant quality mode", offsetof(VP8Context, crf), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 63, VE }, + +#if CONFIG_LIBVPX_VP9_ENCODER +static const AVOption vp9_options[] = { + COMMON_OPTIONS + { "lossless", "Lossless mode", OFFSET(lossless), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, VE}, + { "tile-columns", "Number of tile columns to use, log2", OFFSET(tile_columns), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 6, VE}, + { "tile-rows", "Number of tile rows to use, log2", OFFSET(tile_rows), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 2, VE}, + { "frame-parallel", "Enable frame parallel decodability features", OFFSET(frame_parallel), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, VE}, + LEGACY_OPTIONS { NULL } }; +#endif + +#undef COMMON_OPTIONS +#undef LEGACY_OPTIONS static const AVCodecDefault defaults[] = { { "qmin", "-1" }, @@ -677,14 +827,15 @@ static av_cold int vp8_init(AVCodecContext *avctx) } static const AVClass class_vp8 = { - .class_name = "libvpx encoder", + .class_name = "libvpx-vp8 encoder", .item_name = av_default_item_name, - .option = options, + .option = vp8_options, .version = LIBAVUTIL_VERSION_INT, }; AVCodec ff_libvpx_vp8_encoder = { .name = "libvpx", + .long_name = NULL_IF_CONFIG_SMALL("libvpx VP8"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VP8, .priv_data_size = sizeof(VP8Context), @@ -692,8 +843,7 @@ AVCodec ff_libvpx_vp8_encoder = { .encode2 = vp8_encode, .close = vp8_free, .capabilities = CODEC_CAP_DELAY | CODEC_CAP_AUTO_THREADS, - .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("libvpx VP8"), + .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_NONE }, .priv_class = &class_vp8, .defaults = defaults, }; @@ -706,24 +856,25 @@ static av_cold int vp9_init(AVCodecContext *avctx) } static const AVClass class_vp9 = { - .class_name = "libvpx encoder", + .class_name = "libvpx-vp9 encoder", .item_name = av_default_item_name, - .option = options, + .option = vp9_options, .version = LIBAVUTIL_VERSION_INT, }; AVCodec ff_libvpx_vp9_encoder = { .name = "libvpx-vp9", + .long_name = NULL_IF_CONFIG_SMALL("libvpx VP9"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VP9, .priv_data_size = sizeof(VP8Context), .init = vp9_init, .encode2 = vp8_encode, .close = vp8_free, - .capabilities = CODEC_CAP_DELAY | CODEC_CAP_AUTO_THREADS | CODEC_CAP_EXPERIMENTAL, + .capabilities = CODEC_CAP_DELAY | CODEC_CAP_AUTO_THREADS, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("libvpx VP9"), .priv_class = &class_vp9, .defaults = defaults, + .init_static_data = ff_vp9_init_static, }; #endif /* CONFIG_LIBVPX_VP9_ENCODER */ diff --git a/ffmpeg/libavcodec/libx264.c b/ffmpeg/libavcodec/libx264.c index 7e8fa65..8da1870 100644 --- a/ffmpeg/libavcodec/libx264.c +++ b/ffmpeg/libavcodec/libx264.c @@ -23,8 +23,14 @@ #include "libavutil/opt.h" #include "libavutil/mem.h" #include "libavutil/pixdesc.h" +#include "libavutil/stereo3d.h" #include "avcodec.h" #include "internal.h" + +#if defined(_MSC_VER) +#define X264_API_IMPORTS 1 +#endif + #include #include #include @@ -39,7 +45,6 @@ typedef struct X264Context { x264_picture_t pic; uint8_t *sei; int sei_size; - AVFrame out_pic; char *preset; char *tune; char *profile; @@ -59,6 +64,7 @@ typedef struct X264Context { int weightb; int ssim; int intra_refresh; + int bluray_compat; int b_bias; int b_pyramid; int mixed_refs; @@ -155,7 +161,8 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, X264Context *x4 = ctx->priv_data; x264_nal_t *nal; int nnal, i, ret; - x264_picture_t pic_out; + x264_picture_t pic_out = {0}; + AVFrameSideData *side_data; x264_picture_init( &x4->pic ); x4->pic.img.i_csp = x4->params.i_csp; @@ -185,8 +192,42 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, x4->params.vui.i_sar_width = ctx->sample_aspect_ratio.num; x264_encoder_reconfig(x4->enc, &x4->params); } - } + side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_STEREO3D); + if (side_data) { + AVStereo3D *stereo = (AVStereo3D *)side_data->data; + int fpa_type; + + switch (stereo->type) { + case AV_STEREO3D_CHECKERBOARD: + fpa_type = 0; + break; + case AV_STEREO3D_LINES: + fpa_type = 1; + break; + case AV_STEREO3D_COLUMNS: + fpa_type = 2; + break; + case AV_STEREO3D_SIDEBYSIDE: + fpa_type = 3; + break; + case AV_STEREO3D_TOPBOTTOM: + fpa_type = 4; + break; + case AV_STEREO3D_FRAMESEQUENCE: + fpa_type = 5; + break; + default: + fpa_type = -1; + break; + } + + if (fpa_type != x4->params.i_frame_packing) { + x4->params.i_frame_packing = fpa_type; + x264_encoder_reconfig(x4->enc, &x4->params); + } + } + } do { if (x264_encoder_encode(x4->enc, &nal, &nnal, frame? &x4->pic: NULL, &pic_out) < 0) return -1; @@ -202,20 +243,20 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, switch (pic_out.i_type) { case X264_TYPE_IDR: case X264_TYPE_I: - x4->out_pic.pict_type = AV_PICTURE_TYPE_I; + ctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; break; case X264_TYPE_P: - x4->out_pic.pict_type = AV_PICTURE_TYPE_P; + ctx->coded_frame->pict_type = AV_PICTURE_TYPE_P; break; case X264_TYPE_B: case X264_TYPE_BREF: - x4->out_pic.pict_type = AV_PICTURE_TYPE_B; + ctx->coded_frame->pict_type = AV_PICTURE_TYPE_B; break; } pkt->flags |= AV_PKT_FLAG_KEY*pic_out.b_keyframe; if (ret) - x4->out_pic.quality = (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA; + ctx->coded_frame->quality = (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA; *got_packet = ret; return 0; @@ -231,13 +272,15 @@ static av_cold int X264_close(AVCodecContext *avctx) if (x4->enc) x264_encoder_close(x4->enc); + av_frame_free(&avctx->coded_frame); + return 0; } #define OPT_STR(opt, param) \ do { \ int ret; \ - if (param && (ret = x264_param_parse(&x4->params, opt, param)) < 0) { \ + if (param!=NULL && (ret = x264_param_parse(&x4->params, opt, param)) < 0) { \ if(ret == X264_PARAM_BAD_NAME) \ av_log(avctx, AV_LOG_ERROR, \ "bad option '%s': '%s'\n", opt, param); \ @@ -256,8 +299,10 @@ static int convert_pix_fmt(enum AVPixelFormat pix_fmt) case AV_PIX_FMT_YUV420P9: case AV_PIX_FMT_YUV420P10: return X264_CSP_I420; case AV_PIX_FMT_YUV422P: + case AV_PIX_FMT_YUVJ422P: case AV_PIX_FMT_YUV422P10: return X264_CSP_I422; case AV_PIX_FMT_YUV444P: + case AV_PIX_FMT_YUVJ444P: case AV_PIX_FMT_YUV444P9: case AV_PIX_FMT_YUV444P10: return X264_CSP_I444; #ifdef X264_CSP_BGR @@ -267,6 +312,9 @@ static int convert_pix_fmt(enum AVPixelFormat pix_fmt) case AV_PIX_FMT_RGB24: return X264_CSP_RGB; #endif + case AV_PIX_FMT_NV12: return X264_CSP_NV12; + case AV_PIX_FMT_NV16: + case AV_PIX_FMT_NV20: return X264_CSP_NV16; }; return 0; } @@ -428,6 +476,10 @@ static av_cold int X264_init(AVCodecContext *avctx) x4->params.analyse.b_ssim = x4->ssim; if (x4->intra_refresh >= 0) x4->params.b_intra_refresh = x4->intra_refresh; + if (x4->bluray_compat >= 0) { + x4->params.b_bluray_compat = x4->bluray_compat; + x4->params.b_vfr_input = 0; + } if (x4->b_bias != INT_MIN) x4->params.i_bframe_bias = x4->b_bias; if (x4->b_pyramid >= 0) @@ -520,7 +572,17 @@ static av_cold int X264_init(AVCodecContext *avctx) x4->params.i_slice_count = avctx->slices; - x4->params.vui.b_fullrange = avctx->pix_fmt == AV_PIX_FMT_YUVJ420P; + x4->params.vui.b_fullrange = avctx->pix_fmt == AV_PIX_FMT_YUVJ420P || + avctx->pix_fmt == AV_PIX_FMT_YUVJ422P || + avctx->pix_fmt == AV_PIX_FMT_YUVJ444P || + avctx->color_range == AVCOL_RANGE_JPEG; + + if (avctx->colorspace != AVCOL_SPC_UNSPECIFIED) + x4->params.vui.i_colmatrix = avctx->colorspace; + if (avctx->color_primaries != AVCOL_PRI_UNSPECIFIED) + x4->params.vui.i_colorprim = avctx->color_primaries; + if (avctx->color_trc != AVCOL_TRC_UNSPECIFIED) + x4->params.vui.i_transfer = avctx->color_trc; if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) x4->params.b_repeat_headers = 0; @@ -553,7 +615,9 @@ static av_cold int X264_init(AVCodecContext *avctx) if (!x4->enc) return -1; - avctx->coded_frame = &x4->out_pic; + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) { x264_nal_t *nal; @@ -585,7 +649,11 @@ static const enum AVPixelFormat pix_fmts_8bit[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUV422P, + AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_YUVJ444P, + AV_PIX_FMT_NV12, + AV_PIX_FMT_NV16, AV_PIX_FMT_NONE }; static const enum AVPixelFormat pix_fmts_9bit[] = { @@ -597,6 +665,7 @@ static const enum AVPixelFormat pix_fmts_10bit[] = { AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_NV20, AV_PIX_FMT_NONE }; static const enum AVPixelFormat pix_fmts_8bit_rgb[] = { @@ -646,6 +715,7 @@ static const AVOption options[] = { { "smart", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_WEIGHTP_SMART}, INT_MIN, INT_MAX, VE, "weightp" }, { "ssim", "Calculate and print SSIM stats.", OFFSET(ssim), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, { "intra-refresh", "Use Periodic Intra Refresh instead of IDR frames.",OFFSET(intra_refresh),AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, + { "bluray-compat", "Bluray compatibility workarounds.", OFFSET(bluray_compat) ,AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, { "b-bias", "Influences how often B-frames are used", OFFSET(b_bias), AV_OPT_TYPE_INT, { .i64 = INT_MIN}, INT_MIN, INT_MAX, VE }, { "b-pyramid", "Keep some B-frames as references.", OFFSET(b_pyramid), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE, "b_pyramid" }, { "none", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_B_PYRAMID_NONE}, INT_MIN, INT_MAX, VE, "b_pyramid" }, @@ -676,7 +746,7 @@ static const AVOption options[] = { { NULL }, }; -static const AVClass class = { +static const AVClass x264_class = { .class_name = "libx264", .item_name = av_default_item_name, .option = options, @@ -722,6 +792,7 @@ static const AVCodecDefault x264_defaults[] = { AVCodec ff_libx264_encoder = { .name = "libx264", + .long_name = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, .priv_data_size = sizeof(X264Context), @@ -729,22 +800,21 @@ AVCodec ff_libx264_encoder = { .encode2 = X264_frame, .close = X264_close, .capabilities = CODEC_CAP_DELAY | CODEC_CAP_AUTO_THREADS, - .long_name = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"), - .priv_class = &class, + .priv_class = &x264_class, .defaults = x264_defaults, .init_static_data = X264_init_static, }; AVCodec ff_libx264rgb_encoder = { .name = "libx264rgb", + .long_name = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 RGB"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, .priv_data_size = sizeof(X264Context), .init = X264_init, .encode2 = X264_frame, .close = X264_close, - .capabilities = CODEC_CAP_DELAY, - .long_name = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 RGB"), + .capabilities = CODEC_CAP_DELAY | CODEC_CAP_AUTO_THREADS, .priv_class = &rgbclass, .defaults = x264_defaults, .pix_fmts = pix_fmts_8bit_rgb, diff --git a/ffmpeg/libavcodec/libxavs.c b/ffmpeg/libavcodec/libxavs.c index 442fc0e..ffe3411 100644 --- a/ffmpeg/libavcodec/libxavs.c +++ b/ffmpeg/libavcodec/libxavs.c @@ -45,7 +45,6 @@ typedef struct XavsContext { xavs_picture_t pic; uint8_t *sei; int sei_size; - AVFrame out_pic; int end_of_stream; float crf; int cqp; @@ -111,10 +110,10 @@ static int encode_nals(AVCodecContext *ctx, AVPacket *pkt, return 1; } -static int XAVS_frame(AVCodecContext *ctx, AVPacket *pkt, +static int XAVS_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet) { - XavsContext *x4 = ctx->priv_data; + XavsContext *x4 = avctx->priv_data; xavs_nal_t *nal; int nnal, i, ret; xavs_picture_t pic_out; @@ -130,67 +129,67 @@ static int XAVS_frame(AVCodecContext *ctx, AVPacket *pkt, x4->pic.i_pts = frame->pts; x4->pic.i_type = XAVS_TYPE_AUTO; - x4->pts_buffer[ctx->frame_number % (ctx->max_b_frames+1)] = frame->pts; + x4->pts_buffer[avctx->frame_number % (avctx->max_b_frames+1)] = frame->pts; } if (xavs_encoder_encode(x4->enc, &nal, &nnal, frame? &x4->pic: NULL, &pic_out) < 0) return -1; - ret = encode_nals(ctx, pkt, nal, nnal); + ret = encode_nals(avctx, pkt, nal, nnal); if (ret < 0) return -1; if (!ret) { if (!frame && !(x4->end_of_stream)) { - if ((ret = ff_alloc_packet2(ctx, pkt, 4)) < 0) + if ((ret = ff_alloc_packet2(avctx, pkt, 4)) < 0) return ret; pkt->data[0] = 0x0; pkt->data[1] = 0x0; pkt->data[2] = 0x01; pkt->data[3] = 0xb1; - pkt->dts = 2*x4->pts_buffer[(x4->out_frame_count-1)%(ctx->max_b_frames+1)] - - x4->pts_buffer[(x4->out_frame_count-2)%(ctx->max_b_frames+1)]; + pkt->dts = 2*x4->pts_buffer[(x4->out_frame_count-1)%(avctx->max_b_frames+1)] - + x4->pts_buffer[(x4->out_frame_count-2)%(avctx->max_b_frames+1)]; x4->end_of_stream = END_OF_STREAM; *got_packet = 1; } return 0; } - x4->out_pic.pts = pic_out.i_pts; + avctx->coded_frame->pts = pic_out.i_pts; pkt->pts = pic_out.i_pts; - if (ctx->has_b_frames) { + if (avctx->has_b_frames) { if (!x4->out_frame_count) pkt->dts = pkt->pts - (x4->pts_buffer[1] - x4->pts_buffer[0]); else - pkt->dts = x4->pts_buffer[(x4->out_frame_count-1)%(ctx->max_b_frames+1)]; + pkt->dts = x4->pts_buffer[(x4->out_frame_count-1)%(avctx->max_b_frames+1)]; } else pkt->dts = pkt->pts; switch (pic_out.i_type) { case XAVS_TYPE_IDR: case XAVS_TYPE_I: - x4->out_pic.pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; break; case XAVS_TYPE_P: - x4->out_pic.pict_type = AV_PICTURE_TYPE_P; + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P; break; case XAVS_TYPE_B: case XAVS_TYPE_BREF: - x4->out_pic.pict_type = AV_PICTURE_TYPE_B; + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B; break; } /* There is no IDR frame in AVS JiZhun */ /* Sequence header is used as a flag */ if (pic_out.i_type == XAVS_TYPE_I) { - x4->out_pic.key_frame = 1; + avctx->coded_frame->key_frame = 1; pkt->flags |= AV_PKT_FLAG_KEY; } - x4->out_pic.quality = (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA; + avctx->coded_frame->quality = (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA; x4->out_frame_count++; *got_packet = ret; @@ -208,6 +207,8 @@ static av_cold int XAVS_close(AVCodecContext *avctx) if (x4->enc) xavs_encoder_close(x4->enc); + av_frame_free(&avctx->coded_frame); + return 0; } @@ -355,7 +356,10 @@ static av_cold int XAVS_init(AVCodecContext *avctx) if (!(x4->pts_buffer = av_mallocz((avctx->max_b_frames+1) * sizeof(*x4->pts_buffer)))) return AVERROR(ENOMEM); - avctx->coded_frame = &x4->out_pic; + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + /* TAG: Do we have GLOBAL HEADER in AVS */ /* We Have PPS and SPS in AVS */ if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) { @@ -404,7 +408,7 @@ static const AVOption options[] = { { NULL }, }; -static const AVClass class = { +static const AVClass xavs_class = { .class_name = "libxavs", .item_name = av_default_item_name, .option = options, @@ -418,6 +422,7 @@ static const AVCodecDefault xavs_defaults[] = { AVCodec ff_libxavs_encoder = { .name = "libxavs", + .long_name = NULL_IF_CONFIG_SMALL("libxavs Chinese AVS (Audio Video Standard)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_CAVS, .priv_data_size = sizeof(XavsContext), @@ -426,7 +431,6 @@ AVCodec ff_libxavs_encoder = { .close = XAVS_close, .capabilities = CODEC_CAP_DELAY | CODEC_CAP_AUTO_THREADS, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("libxavs Chinese AVS (Audio Video Standard)"), - .priv_class = &class, + .priv_class = &xavs_class, .defaults = xavs_defaults, }; diff --git a/ffmpeg/libavcodec/libxvid.c b/ffmpeg/libavcodec/libxvid.c index 05a12db..40b3bff 100644 --- a/ffmpeg/libavcodec/libxvid.c +++ b/ffmpeg/libavcodec/libxvid.c @@ -56,13 +56,16 @@ struct xvid_context { int me_flags; /**< Motion Estimation flags */ int qscale; /**< Do we use constant scale? */ int quicktime_format; /**< Are we in a QT-based format? */ - AVFrame encoded_picture; /**< Encoded frame information */ char *twopassbuffer; /**< Character buffer for two-pass */ char *old_twopassbuffer; /**< Old character buffer (two-pass) */ char *twopassfile; /**< second pass temp file name */ int twopassfd; unsigned char *intra_matrix; /**< P-Frame Quant Matrix */ unsigned char *inter_matrix; /**< I-Frame Quant Matrix */ + int lumi_aq; /**< Lumi masking as an aq method */ + int variance_aq; /**< Variance adaptive quantization */ + int ssim; /**< SSIM information display mode */ + int ssim_acc; /**< SSIM accuracy. 0: accurate. 4: fast. */ }; /** @@ -352,45 +355,47 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) { uint16_t *intra, *inter; int fd; - xvid_plugin_single_t single = { 0 }; - struct xvid_ff_pass1 rc2pass1 = { 0 }; - xvid_plugin_2pass2_t rc2pass2 = { 0 }; - xvid_gbl_init_t xvid_gbl_init = { 0 }; - xvid_enc_create_t xvid_enc_create = { 0 }; - xvid_enc_plugin_t plugins[7]; + xvid_plugin_single_t single = { 0 }; + struct xvid_ff_pass1 rc2pass1 = { 0 }; + xvid_plugin_2pass2_t rc2pass2 = { 0 }; + xvid_plugin_lumimasking_t masking_l = { 0 }; /* For lumi masking */ + xvid_plugin_lumimasking_t masking_v = { 0 }; /* For variance AQ */ + xvid_plugin_ssim_t ssim = { 0 }; + xvid_gbl_init_t xvid_gbl_init = { 0 }; + xvid_enc_create_t xvid_enc_create = { 0 }; + xvid_enc_plugin_t plugins[4]; x->twopassfd = -1; /* Bring in VOP flags from ffmpeg command-line */ - x->vop_flags = XVID_VOP_HALFPEL; /* Bare minimum quality */ + x->vop_flags = XVID_VOP_HALFPEL; /* Bare minimum quality */ if( xvid_flags & CODEC_FLAG_4MV ) - x->vop_flags |= XVID_VOP_INTER4V; /* Level 3 */ - if( avctx->trellis - ) - x->vop_flags |= XVID_VOP_TRELLISQUANT; /* Level 5 */ + x->vop_flags |= XVID_VOP_INTER4V; /* Level 3 */ + if( avctx->trellis) + x->vop_flags |= XVID_VOP_TRELLISQUANT; /* Level 5 */ if( xvid_flags & CODEC_FLAG_AC_PRED ) - x->vop_flags |= XVID_VOP_HQACPRED; /* Level 6 */ + x->vop_flags |= XVID_VOP_HQACPRED; /* Level 6 */ if( xvid_flags & CODEC_FLAG_GRAY ) - x->vop_flags |= XVID_VOP_GREYSCALE; + x->vop_flags |= XVID_VOP_GREYSCALE; /* Decide which ME quality setting to use */ x->me_flags = 0; switch( avctx->me_method ) { case ME_FULL: /* Quality 6 */ - x->me_flags |= XVID_ME_EXTSEARCH16 - | XVID_ME_EXTSEARCH8; + x->me_flags |= XVID_ME_EXTSEARCH16 + | XVID_ME_EXTSEARCH8; case ME_EPZS: /* Quality 4 */ - x->me_flags |= XVID_ME_ADVANCEDDIAMOND8 - | XVID_ME_HALFPELREFINE8 - | XVID_ME_CHROMA_PVOP - | XVID_ME_CHROMA_BVOP; + x->me_flags |= XVID_ME_ADVANCEDDIAMOND8 + | XVID_ME_HALFPELREFINE8 + | XVID_ME_CHROMA_PVOP + | XVID_ME_CHROMA_BVOP; case ME_LOG: /* Quality 2 */ case ME_PHODS: case ME_X1: - x->me_flags |= XVID_ME_ADVANCEDDIAMOND16 - | XVID_ME_HALFPELREFINE16; + x->me_flags |= XVID_ME_ADVANCEDDIAMOND16 + | XVID_ME_HALFPELREFINE16; case ME_ZERO: /* Quality 0 */ default: @@ -401,15 +406,15 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) { switch( avctx->mb_decision ) { case 2: x->vop_flags |= XVID_VOP_MODEDECISION_RD; - x->me_flags |= XVID_ME_HALFPELREFINE8_RD - | XVID_ME_QUARTERPELREFINE8_RD - | XVID_ME_EXTSEARCH_RD - | XVID_ME_CHECKPREDICTION_RD; + x->me_flags |= XVID_ME_HALFPELREFINE8_RD + | XVID_ME_QUARTERPELREFINE8_RD + | XVID_ME_EXTSEARCH_RD + | XVID_ME_CHECKPREDICTION_RD; case 1: if( !(x->vop_flags & XVID_VOP_MODEDECISION_RD) ) x->vop_flags |= XVID_VOP_FAST_MODEDECISION_RD; - x->me_flags |= XVID_ME_HALFPELREFINE16_RD - | XVID_ME_QUARTERPELREFINE16_RD; + x->me_flags |= XVID_ME_HALFPELREFINE16_RD + | XVID_ME_QUARTERPELREFINE16_RD; default: break; @@ -418,12 +423,12 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) { /* Bring in VOL flags from ffmpeg command-line */ x->vol_flags = 0; if( xvid_flags & CODEC_FLAG_GMC ) { - x->vol_flags |= XVID_VOL_GMC; - x->me_flags |= XVID_ME_GME_REFINE; + x->vol_flags |= XVID_VOL_GMC; + x->me_flags |= XVID_ME_GME_REFINE; } if( xvid_flags & CODEC_FLAG_QPEL ) { - x->vol_flags |= XVID_VOL_QUARTERPEL; - x->me_flags |= XVID_ME_QUARTERPELREFINE16; + x->vol_flags |= XVID_VOL_QUARTERPEL; + x->me_flags |= XVID_ME_QUARTERPELREFINE16; if( x->vop_flags & XVID_VOP_INTER4V ) x->me_flags |= XVID_ME_QUARTERPELREFINE8; } @@ -525,10 +530,41 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) { xvid_enc_create.num_plugins++; } + if ( avctx->lumi_masking != 0.0) + x->lumi_aq = 1; + /* Luminance Masking */ - if( 0.0 != avctx->lumi_masking ) { + if( x->lumi_aq ) { + masking_l.method = 0; plugins[xvid_enc_create.num_plugins].func = xvid_plugin_lumimasking; - plugins[xvid_enc_create.num_plugins].param = NULL; + + /* The old behavior is that when avctx->lumi_masking is specified, + * plugins[...].param = NULL. Trying to keep the old behavior here. */ + plugins[xvid_enc_create.num_plugins].param = avctx->lumi_masking ? NULL : &masking_l ; + xvid_enc_create.num_plugins++; + } + + /* Variance AQ */ + if( x->variance_aq ) { + masking_v.method = 1; + plugins[xvid_enc_create.num_plugins].func = xvid_plugin_lumimasking; + plugins[xvid_enc_create.num_plugins].param = &masking_v ; + xvid_enc_create.num_plugins++; + } + + if( x->lumi_aq && x->variance_aq ) + av_log(avctx, AV_LOG_INFO, + "Both lumi_aq and variance_aq are enabled. The resulting quality" + "will be the worse one of the two effects made by the AQ.\n"); + + /* SSIM */ + if( x->ssim ) { + plugins[xvid_enc_create.num_plugins].func = xvid_plugin_ssim; + ssim.b_printstat = ( x->ssim == 2 ); + ssim.acc = x->ssim_acc; + ssim.cpu_flags = xvid_gbl_init.cpu_flags; + ssim.b_visualize = 0; + plugins[xvid_enc_create.num_plugins].param = &ssim; xvid_enc_create.num_plugins++; } @@ -604,6 +640,8 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) { xvid_enc_create.bquant_ratio = 100 * avctx->b_quant_factor; if( avctx->max_b_frames > 0 && !x->quicktime_format ) xvid_enc_create.global |= XVID_GLOBAL_PACKED; + av_assert0(xvid_enc_create.num_plugins + (!!x->ssim) + (!!x->variance_aq) + (!!x->lumi_aq) <= FF_ARRAY_ELEMS(plugins)); + /* Create encoder context */ xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL); if( xerr ) { @@ -612,7 +650,9 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) { } x->encoder_handle = xvid_enc_create.handle; - avctx->coded_frame = &x->encoded_picture; + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); return 0; fail: @@ -626,7 +666,7 @@ static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt, int xerr, i, ret, user_packet = !!pkt->data; char *tmp; struct xvid_context *x = avctx->priv_data; - AVFrame *p = &x->encoded_picture; + AVFrame *p = avctx->coded_frame; int mb_width = (avctx->width + 15) / 16; int mb_height = (avctx->height + 15) / 16; @@ -639,7 +679,6 @@ static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt, /* Start setting up the frame */ xvid_enc_frame.version = XVID_VERSION; xvid_enc_stats.version = XVID_VERSION; - *p = *picture; /* Let Xvid know where to put the frame. */ xvid_enc_frame.bitstream = pkt->data; @@ -671,9 +710,11 @@ static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt, /* Pixel aspect ratio setting */ if (avctx->sample_aspect_ratio.num < 0 || avctx->sample_aspect_ratio.num > 255 || avctx->sample_aspect_ratio.den < 0 || avctx->sample_aspect_ratio.den > 255) { - av_log(avctx, AV_LOG_ERROR, "Invalid pixel aspect ratio %i/%i\n", + av_log(avctx, AV_LOG_WARNING, + "Invalid pixel aspect ratio %i/%i, limit is 255/255 reducing\n", avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den); - return -1; + av_reduce(&avctx->sample_aspect_ratio.num, &avctx->sample_aspect_ratio.den, + avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den, 255); } xvid_enc_frame.par = XVID_PAR_EXT; xvid_enc_frame.par_width = avctx->sample_aspect_ratio.num; @@ -762,8 +803,29 @@ static av_cold int xvid_encode_close(AVCodecContext *avctx) { return 0; } +#define OFFSET(x) offsetof(struct xvid_context, x) +#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM +static const AVOption options[] = { + { "lumi_aq", "Luminance masking AQ", OFFSET(lumi_aq), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, + { "variance_aq", "Variance AQ", OFFSET(variance_aq), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, + { "ssim", "Show SSIM information to stdout", OFFSET(ssim), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, VE, "ssim" }, + { "off", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "ssim" }, + { "avg", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "ssim" }, + { "frame", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, VE, "ssim" }, + { "ssim_acc", "SSIM accuracy", OFFSET(ssim_acc), AV_OPT_TYPE_INT, { .i64 = 2 }, 0, 4, VE }, + { NULL }, +}; + +static const AVClass xvid_class = { + .class_name = "libxvid", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + AVCodec ff_libxvid_encoder = { .name = "libxvid", + .long_name = NULL_IF_CONFIG_SMALL("libxvidcore MPEG-4 part 2"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MPEG4, .priv_data_size = sizeof(struct xvid_context), @@ -771,5 +833,5 @@ AVCodec ff_libxvid_encoder = { .encode2 = xvid_encode_frame, .close = xvid_encode_close, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("libxvidcore MPEG-4 part 2"), + .priv_class = &xvid_class, }; diff --git a/ffmpeg/libavcodec/libxvid_rc.c b/ffmpeg/libavcodec/libxvid_rc.c index 4a5842f..5da435b 100644 --- a/ffmpeg/libavcodec/libxvid_rc.c +++ b/ffmpeg/libavcodec/libxvid_rc.c @@ -23,6 +23,7 @@ #include "config.h" #include #include +#include "libavutil/attributes.h" #include "libavutil/file.h" #include "avcodec.h" #include "libxvid.h" @@ -31,7 +32,8 @@ #undef NDEBUG #include -int ff_xvid_rate_control_init(MpegEncContext *s){ +av_cold int ff_xvid_rate_control_init(MpegEncContext *s) +{ char *tmp_name; int fd, i; xvid_plg_create_t xvid_plg_create = { 0 }; @@ -134,7 +136,8 @@ float ff_xvid_rate_estimate_qscale(MpegEncContext *s, int dry_run){ return xvid_plg_data.quant * FF_QP2LAMBDA; } -void ff_xvid_rate_control_uninit(MpegEncContext *s){ +av_cold void ff_xvid_rate_control_uninit(MpegEncContext *s) +{ xvid_plg_destroy_t xvid_plg_destroy; xvid_plugin_2pass2(s->rc_context.non_lavc_opaque, XVID_PLG_DESTROY, &xvid_plg_destroy, NULL); diff --git a/ffmpeg/libavcodec/ljpegenc.c b/ffmpeg/libavcodec/ljpegenc.c index 76c3cb9..35b82fd 100644 --- a/ffmpeg/libavcodec/ljpegenc.c +++ b/ffmpeg/libavcodec/ljpegenc.c @@ -30,207 +30,297 @@ * lossless JPEG encoder. */ +#include "libavutil/frame.h" +#include "libavutil/mem.h" +#include "libavutil/pixdesc.h" + #include "avcodec.h" +#include "dsputil.h" #include "internal.h" #include "mpegvideo.h" #include "mjpeg.h" #include "mjpegenc.h" +typedef struct LJpegEncContext { + DSPContext dsp; + ScanTable scantable; + uint16_t matrix[64]; -static int encode_picture_lossless(AVCodecContext *avctx, AVPacket *pkt, - const AVFrame *pict, int *got_packet) -{ - MpegEncContext * const s = avctx->priv_data; - MJpegContext * const m = s->mjpeg_ctx; - const int width= s->width; - const int height= s->height; - AVFrame * const p = &s->current_picture.f; - const int predictor= avctx->prediction_method+1; - const int mb_width = (width + s->mjpeg_hsample[0] - 1) / s->mjpeg_hsample[0]; - const int mb_height = (height + s->mjpeg_vsample[0] - 1) / s->mjpeg_vsample[0]; - int ret, max_pkt_size = FF_MIN_BUFFER_SIZE; - - if (avctx->pix_fmt == AV_PIX_FMT_BGRA) - max_pkt_size += width * height * 3 * 4; - else { - max_pkt_size += mb_width * mb_height * 3 * 4 - * s->mjpeg_hsample[0] * s->mjpeg_vsample[0]; - } + int vsample[3]; + int hsample[3]; - if (!s->edge_emu_buffer && - (ret = ff_mpv_frame_size_alloc(s, pict->linesize[0])) < 0) { - av_log(avctx, AV_LOG_ERROR, "failed to allocate context scratch buffers.\n"); - return ret; - } + uint16_t huff_code_dc_luminance[12]; + uint16_t huff_code_dc_chrominance[12]; + uint8_t huff_size_dc_luminance[12]; + uint8_t huff_size_dc_chrominance[12]; - if ((ret = ff_alloc_packet2(avctx, pkt, max_pkt_size)) < 0) - return ret; + uint16_t (*scratch)[4]; +} LJpegEncContext; - init_put_bits(&s->pb, pkt->data, pkt->size); +static int ljpeg_encode_bgr(AVCodecContext *avctx, PutBitContext *pb, + const AVFrame *frame) +{ + LJpegEncContext *s = avctx->priv_data; + const int width = frame->width; + const int height = frame->height; + const int linesize = frame->linesize[0]; + uint16_t (*buffer)[4] = s->scratch; + const int predictor = avctx->prediction_method+1; + int left[3], top[3], topleft[3]; + int x, y, i; + + for (i = 0; i < 3; i++) + buffer[0][i] = 1 << (9 - 1); + + for (y = 0; y < height; y++) { + const int modified_predictor = y ? predictor : 1; + uint8_t *ptr = frame->data[0] + (linesize * y); + + if (pb->buf_end - pb->buf - (put_bits_count(pb) >> 3) < width * 3 * 4) { + av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n"); + return -1; + } - av_frame_unref(p); - ret = av_frame_ref(p, pict); - if (ret < 0) - return ret; - p->pict_type= AV_PICTURE_TYPE_I; - p->key_frame= 1; + for (i = 0; i < 3; i++) + top[i]= left[i]= topleft[i]= buffer[0][i]; + + for (x = 0; x < width; x++) { + if(avctx->pix_fmt == AV_PIX_FMT_BGR24){ + buffer[x][1] = ptr[3 * x + 0] - ptr[3 * x + 1] + 0x100; + buffer[x][2] = ptr[3 * x + 2] - ptr[3 * x + 1] + 0x100; + buffer[x][0] = (ptr[3 * x + 0] + 2 * ptr[3 * x + 1] + ptr[3 * x + 2]) >> 2; + }else{ + buffer[x][1] = ptr[4 * x + 0] - ptr[4 * x + 1] + 0x100; + buffer[x][2] = ptr[4 * x + 2] - ptr[4 * x + 1] + 0x100; + buffer[x][0] = (ptr[4 * x + 0] + 2 * ptr[4 * x + 1] + ptr[4 * x + 2]) >> 2; + } - ff_mjpeg_encode_picture_header(s); + for (i = 0; i < 3; i++) { + int pred, diff; - s->header_bits= put_bits_count(&s->pb); + PREDICT(pred, topleft[i], top[i], left[i], modified_predictor); - if(avctx->pix_fmt == AV_PIX_FMT_BGR0 - || avctx->pix_fmt == AV_PIX_FMT_BGRA - || avctx->pix_fmt == AV_PIX_FMT_BGR24){ - int x, y, i; - const int linesize= p->linesize[0]; - uint16_t (*buffer)[4]= (void *) s->rd_scratchpad; - int left[3], top[3], topleft[3]; - - for(i=0; i<3; i++){ - buffer[0][i]= 1 << (9 - 1); - } + topleft[i] = top[i]; + top[i] = buffer[x+1][i]; - for(y = 0; y < height; y++) { - const int modified_predictor= y ? predictor : 1; - uint8_t *ptr = p->data[0] + (linesize * y); + left[i] = buffer[x][i]; - if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < width*3*4){ - av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); - return -1; - } + diff = ((left[i] - pred + 0x100) & 0x1FF) - 0x100; - for(i=0; i<3; i++){ - top[i]= left[i]= topleft[i]= buffer[0][i]; + if (i == 0) + ff_mjpeg_encode_dc(pb, diff, s->huff_size_dc_luminance, s->huff_code_dc_luminance); //FIXME ugly + else + ff_mjpeg_encode_dc(pb, diff, s->huff_size_dc_chrominance, s->huff_code_dc_chrominance); } - for(x = 0; x < width; x++) { - if(avctx->pix_fmt == AV_PIX_FMT_BGR24){ - buffer[x][1] = ptr[3*x+0] - ptr[3*x+1] + 0x100; - buffer[x][2] = ptr[3*x+2] - ptr[3*x+1] + 0x100; - buffer[x][0] = (ptr[3*x+0] + 2*ptr[3*x+1] + ptr[3*x+2])>>2; - }else{ - buffer[x][1] = ptr[4*x+0] - ptr[4*x+1] + 0x100; - buffer[x][2] = ptr[4*x+2] - ptr[4*x+1] + 0x100; - buffer[x][0] = (ptr[4*x+0] + 2*ptr[4*x+1] + ptr[4*x+2])>>2; - } - - for(i=0;i<3;i++) { - int pred, diff; - - PREDICT(pred, topleft[i], top[i], left[i], modified_predictor); - - topleft[i]= top[i]; - top[i]= buffer[x+1][i]; + } + } - left[i]= buffer[x][i]; + return 0; +} - diff= ((left[i] - pred + 0x100)&0x1FF) - 0x100; +static inline void ljpeg_encode_yuv_mb(LJpegEncContext *s, PutBitContext *pb, + const AVFrame *frame, int predictor, + int mb_x, int mb_y) +{ + int i; + + if (mb_x == 0 || mb_y == 0) { + for (i = 0; i < 3; i++) { + uint8_t *ptr; + int x, y, h, v, linesize; + h = s->hsample[i]; + v = s->vsample[i]; + linesize = frame->linesize[i]; + + for (y = 0; y < v; y++) { + for (x = 0; x < h; x++) { + int pred; + + ptr = frame->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap + if (y == 0 && mb_y == 0) { + if (x == 0 && mb_x == 0) + pred = 128; + else + pred = ptr[-1]; + } else { + if (x == 0 && mb_x == 0) { + pred = ptr[-linesize]; + } else { + PREDICT(pred, ptr[-linesize - 1], ptr[-linesize], + ptr[-1], predictor); + } + } - if(i==0) - ff_mjpeg_encode_dc(s, diff, m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly + if (i == 0) + ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_luminance, s->huff_code_dc_luminance); //FIXME ugly else - ff_mjpeg_encode_dc(s, diff, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); + ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_chrominance, s->huff_code_dc_chrominance); } } } - }else{ - int mb_x, mb_y, i; - - for(mb_y = 0; mb_y < mb_height; mb_y++) { - if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < mb_width * 4 * 3 * s->mjpeg_hsample[0] * s->mjpeg_vsample[0]){ - av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); - return -1; - } - for(mb_x = 0; mb_x < mb_width; mb_x++) { - if(mb_x==0 || mb_y==0){ - for(i=0;i<3;i++) { - uint8_t *ptr; - int x, y, h, v, linesize; - h = s->mjpeg_hsample[i]; - v = s->mjpeg_vsample[i]; - linesize= p->linesize[i]; - - for(y=0; ydata[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap - if(y==0 && mb_y==0){ - if(x==0 && mb_x==0){ - pred= 128; - }else{ - pred= ptr[-1]; - } - }else{ - if(x==0 && mb_x==0){ - pred= ptr[-linesize]; - }else{ - PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor); - } - } - - if(i==0) - ff_mjpeg_encode_dc(s, *ptr - pred, m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly - else - ff_mjpeg_encode_dc(s, *ptr - pred, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); - } - } - } - }else{ - for(i=0;i<3;i++) { - uint8_t *ptr; - int x, y, h, v, linesize; - h = s->mjpeg_hsample[i]; - v = s->mjpeg_vsample[i]; - linesize= p->linesize[i]; - - for(y=0; ydata[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap - PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor); - - if(i==0) - ff_mjpeg_encode_dc(s, *ptr - pred, m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly - else - ff_mjpeg_encode_dc(s, *ptr - pred, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); - } - } - } + } else { + for (i = 0; i < 3; i++) { + uint8_t *ptr; + int x, y, h, v, linesize; + h = s->hsample[i]; + v = s->vsample[i]; + linesize = frame->linesize[i]; + + for (y = 0; y < v; y++) { + for (x = 0; x < h; x++) { + int pred; + + ptr = frame->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap + PREDICT(pred, ptr[-linesize - 1], ptr[-linesize], ptr[-1], predictor); + + if (i == 0) + ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_luminance, s->huff_code_dc_luminance); //FIXME ugly + else + ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_chrominance, s->huff_code_dc_chrominance); } } } } +} + +static int ljpeg_encode_yuv(AVCodecContext *avctx, PutBitContext *pb, + const AVFrame *frame) +{ + const int predictor = avctx->prediction_method + 1; + LJpegEncContext *s = avctx->priv_data; + const int mb_width = (avctx->width + s->hsample[0] - 1) / s->hsample[0]; + const int mb_height = (avctx->height + s->vsample[0] - 1) / s->vsample[0]; + int mb_x, mb_y; + + for (mb_y = 0; mb_y < mb_height; mb_y++) { + if (pb->buf_end - pb->buf - (put_bits_count(pb) >> 3) < + mb_width * 4 * 3 * s->hsample[0] * s->vsample[0]) { + av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n"); + return -1; + } + + for (mb_x = 0; mb_x < mb_width; mb_x++) + ljpeg_encode_yuv_mb(s, pb, frame, predictor, mb_x, mb_y); + } + + return 0; +} + +static int ljpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt, + const AVFrame *pict, int *got_packet) +{ + LJpegEncContext *s = avctx->priv_data; + PutBitContext pb; + const int width = avctx->width; + const int height = avctx->height; + const int mb_width = (width + s->hsample[0] - 1) / s->hsample[0]; + const int mb_height = (height + s->vsample[0] - 1) / s->vsample[0]; + int max_pkt_size = FF_MIN_BUFFER_SIZE; + int ret, header_bits; + + if( avctx->pix_fmt == AV_PIX_FMT_BGR0 + || avctx->pix_fmt == AV_PIX_FMT_BGRA + || avctx->pix_fmt == AV_PIX_FMT_BGR24) + max_pkt_size += width * height * 3 * 4; + else { + max_pkt_size += mb_width * mb_height * 3 * 4 + * s->hsample[0] * s->vsample[0]; + } + + if ((ret = ff_alloc_packet2(avctx, pkt, max_pkt_size)) < 0) + return ret; + + init_put_bits(&pb, pkt->data, pkt->size); + + ff_mjpeg_encode_picture_header(avctx, &pb, &s->scantable, + s->matrix); + + header_bits = put_bits_count(&pb); + + if( avctx->pix_fmt == AV_PIX_FMT_BGR0 + || avctx->pix_fmt == AV_PIX_FMT_BGRA + || avctx->pix_fmt == AV_PIX_FMT_BGR24) + ret = ljpeg_encode_bgr(avctx, &pb, pict); + else + ret = ljpeg_encode_yuv(avctx, &pb, pict); + if (ret < 0) + return ret; emms_c(); - av_assert0(s->esc_pos == s->header_bits >> 3); - ff_mjpeg_encode_stuffing(s); - ff_mjpeg_encode_picture_trailer(s); - s->picture_number++; - flush_put_bits(&s->pb); - pkt->size = put_bits_ptr(&s->pb) - s->pb.buf; + ff_mjpeg_escape_FF(&pb, header_bits >> 3); + ff_mjpeg_encode_picture_trailer(&pb, header_bits); + + flush_put_bits(&pb); + pkt->size = put_bits_ptr(&pb) - pb.buf; pkt->flags |= AV_PKT_FLAG_KEY; *got_packet = 1; return 0; -// return (put_bits_count(&f->pb)+7)/8; } +static av_cold int ljpeg_encode_close(AVCodecContext *avctx) +{ + LJpegEncContext *s = avctx->priv_data; + + av_frame_free(&avctx->coded_frame); + av_freep(&s->scratch); + + return 0; +} + +static av_cold int ljpeg_encode_init(AVCodecContext *avctx) +{ + LJpegEncContext *s = avctx->priv_data; + + if ((avctx->pix_fmt == AV_PIX_FMT_YUV420P || + avctx->pix_fmt == AV_PIX_FMT_YUV422P || + avctx->pix_fmt == AV_PIX_FMT_YUV444P) && + avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) { + av_log(avctx, AV_LOG_ERROR, + "Limited range YUV is non-standard, set strict_std_compliance to " + "at least unofficial to use it.\n"); + return AVERROR(EINVAL); + } + + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); -AVCodec ff_ljpeg_encoder = { //FIXME avoid MPV_* lossless JPEG should not need them + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->key_frame = 1; + + s->scratch = av_malloc_array(avctx->width + 1, sizeof(*s->scratch)); + + ff_dsputil_init(&s->dsp, avctx); + ff_init_scantable(s->dsp.idct_permutation, &s->scantable, ff_zigzag_direct); + + ff_mjpeg_init_hvsample(avctx, s->hsample, s->vsample); + + ff_mjpeg_build_huffman_codes(s->huff_size_dc_luminance, + s->huff_code_dc_luminance, + avpriv_mjpeg_bits_dc_luminance, + avpriv_mjpeg_val_dc); + ff_mjpeg_build_huffman_codes(s->huff_size_dc_chrominance, + s->huff_code_dc_chrominance, + avpriv_mjpeg_bits_dc_chrominance, + avpriv_mjpeg_val_dc); + + return 0; +} + +AVCodec ff_ljpeg_encoder = { .name = "ljpeg", + .long_name = NULL_IF_CONFIG_SMALL("Lossless JPEG"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_LJPEG, - .priv_data_size = sizeof(MpegEncContext), - .init = ff_MPV_encode_init, - .encode2 = encode_picture_lossless, - .close = ff_MPV_encode_end, + .priv_data_size = sizeof(LJpegEncContext), + .init = ljpeg_encode_init, + .encode2 = ljpeg_encode_frame, + .close = ljpeg_encode_close, .pix_fmts = (const enum AVPixelFormat[]){ - AV_PIX_FMT_BGR24, AV_PIX_FMT_BGRA, AV_PIX_FMT_BGR0, + AV_PIX_FMT_BGR24 , AV_PIX_FMT_BGRA , AV_PIX_FMT_BGR0, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P, - AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P, + AV_PIX_FMT_YUV420P , AV_PIX_FMT_YUV444P , AV_PIX_FMT_YUV422P, AV_PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("Lossless JPEG"), }; diff --git a/ffmpeg/libavcodec/loco.c b/ffmpeg/libavcodec/loco.c index ffb9742..bf52c49 100644 --- a/ffmpeg/libavcodec/loco.c +++ b/ffmpeg/libavcodec/loco.c @@ -135,7 +135,7 @@ static int loco_decode_plane(LOCOContext *l, uint8_t *data, int width, int heigh if(buf_size<=0) return -1; - init_get_bits(&rc.gb, buf, buf_size*8); + init_get_bits8(&rc.gb, buf, buf_size); rc.save = 0; rc.run = 0; rc.run2 = 0; @@ -302,11 +302,11 @@ static av_cold int decode_init(AVCodecContext *avctx) AVCodec ff_loco_decoder = { .name = "loco", + .long_name = NULL_IF_CONFIG_SMALL("LOCO"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_LOCO, .priv_data_size = sizeof(LOCOContext), .init = decode_init, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("LOCO"), }; diff --git a/ffmpeg/libavcodec/lpc.c b/ffmpeg/libavcodec/lpc.c index 4149135..a6f2377 100644 --- a/ffmpeg/libavcodec/lpc.c +++ b/ffmpeg/libavcodec/lpc.c @@ -20,7 +20,7 @@ */ #include "libavutil/common.h" -#include "libavutil/lls.h" +#include "libavutil/lls2.h" #define LPC_USE_DOUBLE #include "lpc.h" @@ -177,11 +177,12 @@ int ff_lpc_calc_coefs(LPCContext *s, double autoc[MAX_LPC_ORDER+1]; double ref[MAX_LPC_ORDER]; double lpc[MAX_LPC_ORDER][MAX_LPC_ORDER]; - int i, j, pass; + int i, j, pass = 0; int opt_order; av_assert2(max_order >= MIN_LPC_ORDER && max_order <= MAX_LPC_ORDER && lpc_type > FF_LPC_TYPE_FIXED); + av_assert0(lpc_type == FF_LPC_TYPE_CHOLESKY || lpc_type == FF_LPC_TYPE_LEVINSON); /* reinit LPC context if parameters have changed */ if (blocksize != s->blocksize || max_order != s->max_order || @@ -190,7 +191,10 @@ int ff_lpc_calc_coefs(LPCContext *s, ff_lpc_init(s, blocksize, max_order, lpc_type); } - if (lpc_type == FF_LPC_TYPE_LEVINSON) { + if(lpc_passes <= 0) + lpc_passes = 2; + + if (lpc_type == FF_LPC_TYPE_LEVINSON || (lpc_type == FF_LPC_TYPE_CHOLESKY && lpc_passes > 1)) { s->lpc_apply_welch_window(samples, blocksize, s->windowed_samples); s->lpc_compute_autocorr(s->windowed_samples, blocksize, max_order, autoc); @@ -199,15 +203,21 @@ int ff_lpc_calc_coefs(LPCContext *s, for(i=0; i>pass) + fabs(eval - var[0]); inv = 1/eval; rinv = sqrt(inv); @@ -226,9 +236,9 @@ int ff_lpc_calc_coefs(LPCContext *s, }else weight++; - avpriv_update_lls(&m[pass&1], var, 1.0); + m[pass&1].update_lls(&m[pass&1], var); } - avpriv_solve_lls(&m[pass&1], 0.001, 0); + avpriv_solve_lls2(&m[pass&1], 0.001, 0); } for(i=0; i0; i--) ref[i] = ref[i-1] - ref[i]; - } else - av_assert0(0); + } + opt_order = max_order; if(omethod == ORDER_METHOD_EST) { @@ -262,15 +272,11 @@ av_cold int ff_lpc_init(LPCContext *s, int blocksize, int max_order, s->max_order = max_order; s->lpc_type = lpc_type; - if (lpc_type == FF_LPC_TYPE_LEVINSON) { - s->windowed_buffer = av_mallocz((blocksize + 2 + FFALIGN(max_order, 4)) * - sizeof(*s->windowed_samples)); - if (!s->windowed_buffer) - return AVERROR(ENOMEM); - s->windowed_samples = s->windowed_buffer + FFALIGN(max_order, 4); - } else { - s->windowed_samples = NULL; - } + s->windowed_buffer = av_mallocz((blocksize + 2 + FFALIGN(max_order, 4)) * + sizeof(*s->windowed_samples)); + if (!s->windowed_buffer) + return AVERROR(ENOMEM); + s->windowed_samples = s->windowed_buffer + FFALIGN(max_order, 4); s->lpc_apply_welch_window = lpc_apply_welch_window_c; s->lpc_compute_autocorr = lpc_compute_autocorr_c; diff --git a/ffmpeg/libavcodec/lpc.h b/ffmpeg/libavcodec/lpc.h index 8fa56ad..c323230 100644 --- a/ffmpeg/libavcodec/lpc.h +++ b/ffmpeg/libavcodec/lpc.h @@ -67,7 +67,7 @@ typedef struct LPCContext { /** * Perform autocorrelation on input samples with delay of 0 to lag. * @param data input samples. - * constraints: no alignment needed, but must have have at + * constraints: no alignment needed, but must have at * least lag*sizeof(double) valid bytes preceding it, and * size must be at least (len+1)*sizeof(double) if data is * 16-byte aligned or (len+2)*sizeof(double) if data is diff --git a/ffmpeg/libavcodec/lzwenc.c b/ffmpeg/libavcodec/lzwenc.c index 7e30765..d5a07bc 100644 --- a/ffmpeg/libavcodec/lzwenc.c +++ b/ffmpeg/libavcodec/lzwenc.c @@ -111,7 +111,7 @@ static inline int hashOffset(const int head) */ static inline void writeCode(LZWEncodeState * s, int c) { - assert(0 <= c && c < 1 << s->bits); + av_assert2(0 <= c && c < 1 << s->bits); s->put_bits(&s->pb, s->bits, c); } @@ -207,7 +207,7 @@ void ff_lzw_encode_init(LZWEncodeState *s, uint8_t *outbuf, int outsize, s->maxbits = maxbits; init_put_bits(&s->pb, outbuf, outsize); s->bufsize = outsize; - assert(s->maxbits >= 9 && s->maxbits <= LZW_MAXBITS); + av_assert0(s->maxbits >= 9 && s->maxbits <= LZW_MAXBITS); s->maxcode = 1 << s->maxbits; s->output_bytes = 0; s->last_code = LZW_PREFIX_EMPTY; @@ -262,6 +262,9 @@ int ff_lzw_encode_flush(LZWEncodeState *s, if (s->last_code != -1) writeCode(s, s->last_code); writeCode(s, s->end_code); + if (s->mode == FF_LZW_GIF) + s->put_bits(&s->pb, 1, 0); + lzw_flush_put_bits(&s->pb); s->last_code = -1; diff --git a/ffmpeg/libavcodec/mace.c b/ffmpeg/libavcodec/mace.c index 94bf2e7..fbd932e 100644 --- a/ffmpeg/libavcodec/mace.c +++ b/ffmpeg/libavcodec/mace.c @@ -226,8 +226,8 @@ static void chomp6(ChannelData *chd, int16_t *output, uint8_t val, int tab_idx) static av_cold int mace_decode_init(AVCodecContext * avctx) { - if (avctx->channels > 2 || avctx->channels <= 0) - return -1; + if (avctx->channels > 2 || avctx->channels < 1) + return AVERROR(EINVAL); avctx->sample_fmt = AV_SAMPLE_FMT_S16P; return 0; @@ -279,26 +279,26 @@ static int mace_decode_frame(AVCodecContext *avctx, void *data, AVCodec ff_mace3_decoder = { .name = "mace3", + .long_name = NULL_IF_CONFIG_SMALL("MACE (Macintosh Audio Compression/Expansion) 3:1"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_MACE3, .priv_data_size = sizeof(MACEContext), .init = mace_decode_init, .decode = mace_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("MACE (Macintosh Audio Compression/Expansion) 3:1"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_NONE }, }; AVCodec ff_mace6_decoder = { .name = "mace6", + .long_name = NULL_IF_CONFIG_SMALL("MACE (Macintosh Audio Compression/Expansion) 6:1"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_MACE6, .priv_data_size = sizeof(MACEContext), .init = mace_decode_init, .decode = mace_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("MACE (Macintosh Audio Compression/Expansion) 6:1"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_NONE }, }; diff --git a/ffmpeg/libavcodec/mathops.h b/ffmpeg/libavcodec/mathops.h index 592f5a5..bad25af 100644 --- a/ffmpeg/libavcodec/mathops.h +++ b/ffmpeg/libavcodec/mathops.h @@ -195,6 +195,15 @@ if ((y) < (x)) {\ # define FASTDIV(a,b) ((uint32_t)((((uint64_t)a) * ff_inverse[b]) >> 32)) #endif /* FASTDIV */ +#ifndef MOD_UNLIKELY +# define MOD_UNLIKELY(modulus, dividend, divisor, prev_dividend) \ + do { \ + if ((prev_dividend) == 0 || (dividend) - (prev_dividend) != (divisor)) \ + (modulus) = (dividend) % (divisor); \ + (prev_dividend) = (dividend); \ + } while (0) +#endif + static inline av_const unsigned int ff_sqrt(unsigned int a) { unsigned int b; @@ -215,4 +224,14 @@ static inline av_const unsigned int ff_sqrt(unsigned int a) return b - (a < b * b); } +static inline int8_t ff_u8_to_s8(uint8_t a) +{ + union { + uint8_t u8; + int8_t s8; + } b; + b.u8 = a; + return b.s8; +} + #endif /* AVCODEC_MATHOPS_H */ diff --git a/ffmpeg/libavcodec/mathtables.c b/ffmpeg/libavcodec/mathtables.c index 126b05f..ec5ba79 100644 --- a/ffmpeg/libavcodec/mathtables.c +++ b/ffmpeg/libavcodec/mathtables.c @@ -89,9 +89,10 @@ const uint8_t ff_reverse[256] = { }; #define times4(x) x, x, x, x +#define times256(x) times4(times4(times4(times4(times4(x))))) const uint8_t ff_cropTbl[256 + 2 * 1024] = { -times4(times4(times4(times4(times4(0x00))))), +times256(0x00), 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -108,15 +109,16 @@ times4(times4(times4(times4(times4(0x00))))), 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, -times4(times4(times4(times4(times4(0xFF)))))}; +times256(0xFF) +}; const uint8_t ff_zigzag_direct[64] = { - 0, 1, 8, 16, 9, 2, 3, 10, - 17, 24, 32, 25, 18, 11, 4, 5, - 12, 19, 26, 33, 40, 48, 41, 34, - 27, 20, 13, 6, 7, 14, 21, 28, - 35, 42, 49, 56, 57, 50, 43, 36, - 29, 22, 15, 23, 30, 37, 44, 51, - 58, 59, 52, 45, 38, 31, 39, 46, - 53, 60, 61, 54, 47, 55, 62, 63 + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63 }; diff --git a/ffmpeg/libavcodec/mdct.c b/ffmpeg/libavcodec/mdct.c deleted file mode 100644 index 2232024..0000000 --- a/ffmpeg/libavcodec/mdct.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * MDCT/IMDCT transforms - * Copyright (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include "libavutil/common.h" -#include "libavutil/mathematics.h" -#include "fft.h" -#include "fft-internal.h" - -/** - * @file - * MDCT/IMDCT transforms. - */ - -#if CONFIG_FFT_FLOAT -# define RSCALE(x) (x) -#else -# define RSCALE(x) ((x) >> 1) -#endif - -/** - * init MDCT or IMDCT computation. - */ -av_cold int ff_mdct_init(FFTContext *s, int nbits, int inverse, double scale) -{ - int n, n4, i; - double alpha, theta; - int tstep; - - memset(s, 0, sizeof(*s)); - n = 1 << nbits; - s->mdct_bits = nbits; - s->mdct_size = n; - n4 = n >> 2; - s->mdct_permutation = FF_MDCT_PERM_NONE; - - if (ff_fft_init(s, s->mdct_bits - 2, inverse) < 0) - goto fail; - - s->tcos = av_malloc(n/2 * sizeof(FFTSample)); - if (!s->tcos) - goto fail; - - switch (s->mdct_permutation) { - case FF_MDCT_PERM_NONE: - s->tsin = s->tcos + n4; - tstep = 1; - break; - case FF_MDCT_PERM_INTERLEAVE: - s->tsin = s->tcos + 1; - tstep = 2; - break; - default: - goto fail; - } - - theta = 1.0 / 8.0 + (scale < 0 ? n4 : 0); - scale = sqrt(fabs(scale)); - for(i=0;itcos[i*tstep] = FIX15(-cos(alpha) * scale); - s->tsin[i*tstep] = FIX15(-sin(alpha) * scale); - } - return 0; - fail: - ff_mdct_end(s); - return -1; -} - -/** - * Compute the middle half of the inverse MDCT of size N = 2^nbits, - * thus excluding the parts that can be derived by symmetry - * @param output N/2 samples - * @param input N/2 samples - */ -void ff_imdct_half_c(FFTContext *s, FFTSample *output, const FFTSample *input) -{ - int k, n8, n4, n2, n, j; - const uint16_t *revtab = s->revtab; - const FFTSample *tcos = s->tcos; - const FFTSample *tsin = s->tsin; - const FFTSample *in1, *in2; - FFTComplex *z = (FFTComplex *)output; - - n = 1 << s->mdct_bits; - n2 = n >> 1; - n4 = n >> 2; - n8 = n >> 3; - - /* pre rotation */ - in1 = input; - in2 = input + n2 - 1; - for(k = 0; k < n4; k++) { - j=revtab[k]; - CMUL(z[j].re, z[j].im, *in2, *in1, tcos[k], tsin[k]); - in1 += 2; - in2 -= 2; - } - s->fft_calc(s, z); - - /* post rotation + reordering */ - for(k = 0; k < n8; k++) { - FFTSample r0, i0, r1, i1; - CMUL(r0, i1, z[n8-k-1].im, z[n8-k-1].re, tsin[n8-k-1], tcos[n8-k-1]); - CMUL(r1, i0, z[n8+k ].im, z[n8+k ].re, tsin[n8+k ], tcos[n8+k ]); - z[n8-k-1].re = r0; - z[n8-k-1].im = i0; - z[n8+k ].re = r1; - z[n8+k ].im = i1; - } -} - -/** - * Compute inverse MDCT of size N = 2^nbits - * @param output N samples - * @param input N/2 samples - */ -void ff_imdct_calc_c(FFTContext *s, FFTSample *output, const FFTSample *input) -{ - int k; - int n = 1 << s->mdct_bits; - int n2 = n >> 1; - int n4 = n >> 2; - - ff_imdct_half_c(s, output+n4, input); - - for(k = 0; k < n4; k++) { - output[k] = -output[n2-k-1]; - output[n-k-1] = output[n2+k]; - } -} - -/** - * Compute MDCT of size N = 2^nbits - * @param input N samples - * @param out N/2 samples - */ -void ff_mdct_calc_c(FFTContext *s, FFTSample *out, const FFTSample *input) -{ - int i, j, n, n8, n4, n2, n3; - FFTDouble re, im; - const uint16_t *revtab = s->revtab; - const FFTSample *tcos = s->tcos; - const FFTSample *tsin = s->tsin; - FFTComplex *x = (FFTComplex *)out; - - n = 1 << s->mdct_bits; - n2 = n >> 1; - n4 = n >> 2; - n8 = n >> 3; - n3 = 3 * n4; - - /* pre rotation */ - for(i=0;ifft_calc(s, x); - - /* post rotation */ - for(i=0;itcos); - ff_fft_end(s); -} diff --git a/ffmpeg/libavcodec/mdct_fixed.c b/ffmpeg/libavcodec/mdct_fixed.c index 794a3e0..2ee29b6 100644 --- a/ffmpeg/libavcodec/mdct_fixed.c +++ b/ffmpeg/libavcodec/mdct_fixed.c @@ -17,7 +17,8 @@ */ #define CONFIG_FFT_FLOAT 0 -#include "mdct.c" +#define CONFIG_FFT_FIXED_32 0 +#include "mdct_template.c" /* same as ff_mdct_calcw_c with double-width unscaled output */ void ff_mdct_calcw_c(FFTContext *s, FFTDouble *out, const FFTSample *input) diff --git a/ffmpeg/libavcodec/mdct_float.c b/ffmpeg/libavcodec/mdct_float.c index ec4f486..75b5f0d 100644 --- a/ffmpeg/libavcodec/mdct_float.c +++ b/ffmpeg/libavcodec/mdct_float.c @@ -17,4 +17,5 @@ */ #define CONFIG_FFT_FLOAT 1 -#include "mdct.c" +#define CONFIG_FFT_FIXED_32 0 +#include "mdct_template.c" diff --git a/ffmpeg/libavcodec/mdec.c b/ffmpeg/libavcodec/mdec.c index 8fb29ce..1567e14 100644 --- a/ffmpeg/libavcodec/mdec.c +++ b/ffmpeg/libavcodec/mdec.c @@ -121,7 +121,7 @@ static inline int mdec_decode_block_intra(MDECContext *a, int16_t *block, int n) static inline int decode_mb(MDECContext *a, int16_t block[6][64]) { int i, ret; - const int block_index[6] = { 5, 4, 0, 1, 2, 3 }; + static const int block_index[6] = { 5, 4, 0, 1, 2, 3 }; a->dsp.clear_blocks(block[0]); @@ -163,21 +163,19 @@ static int decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; ThreadFrame frame = { .f = data }; - int i, ret; + int ret; if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) return ret; frame.f->pict_type = AV_PICTURE_TYPE_I; frame.f->key_frame = 1; - av_fast_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + av_fast_padded_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size, buf_size); if (!a->bitstream_buffer) return AVERROR(ENOMEM); - for (i = 0; i < buf_size; i += 2) { - a->bitstream_buffer[i] = buf[i + 1]; - a->bitstream_buffer[i + 1] = buf[i]; - } - init_get_bits(&a->gb, a->bitstream_buffer, buf_size * 8); + a->dsp.bswap16_buf((uint16_t *)a->bitstream_buffer, (uint16_t *)buf, (buf_size + 1) / 2); + if ((ret = init_get_bits8(&a->gb, a->bitstream_buffer, buf_size)) < 0) + return ret; /* skip over 4 preamble bytes in stream (typically 0xXX 0xXX 0x00 0x38) */ skip_bits(&a->gb, 32); @@ -242,6 +240,7 @@ static av_cold int decode_end(AVCodecContext *avctx) AVCodec ff_mdec_decoder = { .name = "mdec", + .long_name = NULL_IF_CONFIG_SMALL("Sony PlayStation MDEC (Motion DECoder)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MDEC, .priv_data_size = sizeof(MDECContext), @@ -249,6 +248,5 @@ AVCodec ff_mdec_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, - .long_name = NULL_IF_CONFIG_SMALL("Sony PlayStation MDEC (Motion DECoder)"), .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy) }; diff --git a/ffmpeg/libavcodec/mimic.c b/ffmpeg/libavcodec/mimic.c index 85c6a1a..31d6393 100644 --- a/ffmpeg/libavcodec/mimic.c +++ b/ffmpeg/libavcodec/mimic.c @@ -116,7 +116,8 @@ static av_cold int mimic_decode_end(AVCodecContext *avctx) MimicContext *ctx = avctx->priv_data; int i; - av_free(ctx->swap_buf); + av_freep(&ctx->swap_buf); + ctx->swap_buf_size = 0; for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) { if (ctx->frames[i].f) @@ -175,7 +176,7 @@ static int mimic_decode_update_thread_context(AVCodecContext *avctx, const AVCod for (i = 0; i < FF_ARRAY_ELEMS(dst->frames); i++) { ff_thread_release_buffer(avctx, &dst->frames[i]); - if (src->frames[i].f->data[0]) { + if (i != src->next_cur_index && src->frames[i].f->data[0]) { ret = ff_thread_ref_frame(&dst->frames[i], &src->frames[i]); if (ret < 0) return ret; @@ -388,8 +389,8 @@ static int mimic_decode_frame(AVCodecContext *avctx, void *data, avctx->height = height; avctx->pix_fmt = AV_PIX_FMT_YUV420P; for (i = 0; i < 3; i++) { - ctx->num_vblocks[i] = -((-height) >> (3 + !!i)); - ctx->num_hblocks[i] = width >> (3 + !!i); + ctx->num_vblocks[i] = FF_CEIL_RSHIFT(height, 3 + !!i); + ctx->num_hblocks[i] = width >> (3 + !!i); } } else if (width != ctx->avctx->width || height != ctx->avctx->height) { avpriv_request_sample(avctx, "Resolution changing"); @@ -465,6 +466,7 @@ static av_cold int mimic_init_thread_copy(AVCodecContext *avctx) AVCodec ff_mimic_decoder = { .name = "mimic", + .long_name = NULL_IF_CONFIG_SMALL("Mimic"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MIMIC, .priv_data_size = sizeof(MimicContext), @@ -472,7 +474,6 @@ AVCodec ff_mimic_decoder = { .close = mimic_decode_end, .decode = mimic_decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, - .long_name = NULL_IF_CONFIG_SMALL("Mimic"), .update_thread_context = ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context), .init_thread_copy = ONLY_IF_THREADS_ENABLED(mimic_init_thread_copy), }; diff --git a/ffmpeg/libavcodec/mips/Makefile b/ffmpeg/libavcodec/mips/Makefile index a2ea412..6537b43 100644 --- a/ffmpeg/libavcodec/mips/Makefile +++ b/ffmpeg/libavcodec/mips/Makefile @@ -9,7 +9,6 @@ MIPSFPU-OBJS-$(CONFIG_AMRWB_DECODER) += mips/acelp_filters_mips.o \ mips/acelp_vectors_mips.o MIPSFPU-OBJS-$(CONFIG_MPEGAUDIODSP) += mips/mpegaudiodsp_mips_float.o MIPSDSPR1-OBJS-$(CONFIG_MPEGAUDIODSP) += mips/mpegaudiodsp_mips_fixed.o -OBJS-$(CONFIG_FFT) += mips/fft_init_table.o MIPSFPU-OBJS-$(CONFIG_FFT) += mips/fft_mips.o MIPSFPU-OBJS += mips/fmtconvert_mips.o OBJS-$(CONFIG_AC3DSP) += mips/ac3dsp_mips.o diff --git a/ffmpeg/libavcodec/mips/fft_init_table.c b/ffmpeg/libavcodec/mips/fft_init_table.c deleted file mode 100644 index 9c2e998..0000000 --- a/ffmpeg/libavcodec/mips/fft_init_table.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2012 - * MIPS Technologies, Inc., California. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Author: Stanislav Ocovaj (socovaj@mips.com) - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * definitions and initialization of LUT table for MIPS FFT - */ -#include "fft_table.h" - -uint16_t fft_offsets_lut[0x2aab]; - -void ff_fft_lut_init(uint16_t *table, int off, int size, int *index) -{ - if (size < 16) { - table[*index] = off >> 2; - (*index)++; - } - else { - ff_fft_lut_init(table, off, size>>1, index); - ff_fft_lut_init(table, off+(size>>1), size>>2, index); - ff_fft_lut_init(table, off+3*(size>>2), size>>2, index); - } -} diff --git a/ffmpeg/libavcodec/mips/fft_mips.c b/ffmpeg/libavcodec/mips/fft_mips.c index ae4ed30..d240f1f 100644 --- a/ffmpeg/libavcodec/mips/fft_mips.c +++ b/ffmpeg/libavcodec/mips/fft_mips.c @@ -49,7 +49,7 @@ */ #include "config.h" #include "libavcodec/fft.h" -#include "fft_table.h" +#include "libavcodec/fft_table.h" /** * FFT transform diff --git a/ffmpeg/libavcodec/mips/fft_table.h b/ffmpeg/libavcodec/mips/fft_table.h deleted file mode 100644 index dd52eaf..0000000 --- a/ffmpeg/libavcodec/mips/fft_table.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2012 - * MIPS Technologies, Inc., California. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Author: Stanislav Ocovaj (socovaj@mips.com) - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * definitions and LUT table for MIPS FFT - */ -#ifndef AVCODEC_MIPS_FFT_TABLE_H -#define AVCODEC_MIPS_FFT_TABLE_H - -#include "libavcodec/fft.h" - -#define MAX_LOG2_NFFT 16 //!< Specifies maxiumum allowed fft size -#define MAX_FFT_SIZE (1 << MAX_LOG2_NFFT) - -extern uint16_t fft_offsets_lut[]; -void ff_fft_lut_init(uint16_t *table, int off, int size, int *index); - -#endif /* AVCODEC_MIPS_FFT_TABLE_H */ diff --git a/ffmpeg/libavcodec/mjpeg.c b/ffmpeg/libavcodec/mjpeg.c index a5b1a80..bdd7b19 100644 --- a/ffmpeg/libavcodec/mjpeg.c +++ b/ffmpeg/libavcodec/mjpeg.c @@ -38,7 +38,7 @@ * The spec says that the values given produce "good" quality, and * when divided by 2, "very good" quality. */ -const unsigned char std_luminance_quant_tbl[64] = { +static const unsigned char std_luminance_quant_tbl[64] = { 16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55, 14, 13, 16, 24, 40, 57, 69, 56, @@ -48,7 +48,7 @@ const unsigned char std_luminance_quant_tbl[64] = { 49, 64, 78, 87, 103, 121, 120, 101, 72, 92, 95, 98, 112, 100, 103, 99 }; -const unsigned char std_chrominance_quant_tbl[64] = { +static const unsigned char std_chrominance_quant_tbl[64] = { 17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, 24, 26, 56, 99, 99, 99, 99, 99, diff --git a/ffmpeg/libavcodec/mjpega_dump_header_bsf.c b/ffmpeg/libavcodec/mjpega_dump_header_bsf.c index 9de6ac3..3947c82 100644 --- a/ffmpeg/libavcodec/mjpega_dump_header_bsf.c +++ b/ffmpeg/libavcodec/mjpega_dump_header_bsf.c @@ -88,7 +88,6 @@ static int mjpega_dump_header(AVBitStreamFilterContext *bsfc, AVCodecContext *av } AVBitStreamFilter ff_mjpega_dump_header_bsf = { - "mjpegadump", - 0, - mjpega_dump_header, + .name = "mjpegadump", + .filter = mjpega_dump_header, }; diff --git a/ffmpeg/libavcodec/mjpegbdec.c b/ffmpeg/libavcodec/mjpegbdec.c index 4327c10..f061f0b 100644 --- a/ffmpeg/libavcodec/mjpegbdec.c +++ b/ffmpeg/libavcodec/mjpegbdec.c @@ -155,6 +155,7 @@ read_header: AVCodec ff_mjpegb_decoder = { .name = "mjpegb", + .long_name = NULL_IF_CONFIG_SMALL("Apple MJPEG-B"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MJPEGB, .priv_data_size = sizeof(MJpegDecodeContext), @@ -163,5 +164,4 @@ AVCodec ff_mjpegb_decoder = { .decode = mjpegb_decode_frame, .capabilities = CODEC_CAP_DR1, .max_lowres = 3, - .long_name = NULL_IF_CONFIG_SMALL("Apple MJPEG-B"), }; diff --git a/ffmpeg/libavcodec/mjpegdec.c b/ffmpeg/libavcodec/mjpegdec.c index 5880fec..e86e093 100644 --- a/ffmpeg/libavcodec/mjpegdec.c +++ b/ffmpeg/libavcodec/mjpegdec.c @@ -39,6 +39,9 @@ #include "mjpeg.h" #include "mjpegdec.h" #include "jpeglsdec.h" +#include "tiff.h" +#include "exif.h" +#include "bytestream.h" static int build_vlc(VLC *vlc, const uint8_t *bits_table, @@ -84,9 +87,12 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx) { MJpegDecodeContext *s = avctx->priv_data; - if (!s->picture_ptr) - s->picture_ptr = &s->picture; - avcodec_get_frame_defaults(&s->picture); + if (!s->picture_ptr) { + s->picture = av_frame_alloc(); + if (!s->picture) + return AVERROR(ENOMEM); + s->picture_ptr = s->picture; + } s->avctx = avctx; ff_hpeldsp_init(&s->hdsp, avctx->flags); @@ -212,7 +218,7 @@ int ff_mjpeg_decode_dht(MJpegDecodeContext *s) int ff_mjpeg_decode_sof(MJpegDecodeContext *s) { - int len, nb_components, i, width, height, pix_fmt_id; + int len, nb_components, i, width, height, pix_fmt_id, ret; int h_count[MAX_COMPONENTS]; int v_count[MAX_COMPONENTS]; @@ -221,6 +227,7 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) /* XXX: verify len field validity */ len = get_bits(&s->gb, 16); + s->avctx->bits_per_raw_sample = s->bits = get_bits(&s->gb, 8); if (s->pegasus_rct) @@ -228,11 +235,6 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) if (s->bits == 9 && !s->pegasus_rct) s->rct = 1; // FIXME ugly - if (s->bits != 8 && !s->lossless) { - av_log(s->avctx, AV_LOG_ERROR, "only 8 bits/component accepted\n"); - return -1; - } - if(s->lossless && s->avctx->lowres){ av_log(s->avctx, AV_LOG_ERROR, "lowres is not possible with lossless jpeg\n"); return -1; @@ -255,7 +257,8 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) return -1; if (s->interlaced && (s->bottom_field == !s->interlace_polarity)) { if (nb_components != s->nb_components) { - av_log(s->avctx, AV_LOG_ERROR, "nb_components changing in interlaced picture\n"); + av_log(s->avctx, AV_LOG_ERROR, + "nb_components changing in interlaced picture\n"); return AVERROR_INVALIDDATA; } } @@ -280,15 +283,18 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) s->h_max = h_count[i]; if (v_count[i] > s->v_max) s->v_max = v_count[i]; - if (!h_count[i] || !v_count[i]) { - av_log(s->avctx, AV_LOG_ERROR, "h/v_count is 0\n"); - return -1; - } s->quant_index[i] = get_bits(&s->gb, 8); if (s->quant_index[i] >= 4) { av_log(s->avctx, AV_LOG_ERROR, "quant_index is invalid\n"); return AVERROR_INVALIDDATA; } + if (!h_count[i] || !v_count[i]) { + av_log(s->avctx, AV_LOG_ERROR, + "Invalid sampling factor in component %d %d:%d\n", + i, h_count[i], v_count[i]); + return AVERROR_INVALIDDATA; + } + av_log(s->avctx, AV_LOG_DEBUG, "component %d %d:%d id: %d quant:%d\n", i, h_count[i], v_count[i], s->component_id[i], s->quant_index[i]); @@ -323,7 +329,9 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) height *= 2; } - avcodec_set_dimensions(s->avctx, width, height); + ret = ff_set_dimensions(s->avctx, width, height); + if (ret < 0) + return ret; s->first_picture = 0; } @@ -334,7 +342,7 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) return AVERROR_INVALIDDATA; } } else{ - if (s->v_max == 1 && s->h_max == 1 && s->lossless==1 && nb_components==3) + if (s->v_max == 1 && s->h_max == 1 && s->lossless==1 && (nb_components==3 || nb_components==4)) s->rgb = 1; else if (!s->lossless) s->rgb = 0; @@ -354,20 +362,32 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) switch (pix_fmt_id) { case 0x11111100: if (s->rgb) - s->avctx->pix_fmt = AV_PIX_FMT_BGR24; + s->avctx->pix_fmt = s->bits <= 9 ? AV_PIX_FMT_BGR24 : AV_PIX_FMT_BGR48; else { if (s->component_id[0] == 'Q' && s->component_id[1] == 'F' && s->component_id[2] == 'A') { - s->avctx->pix_fmt = AV_PIX_FMT_GBR24P; + s->avctx->pix_fmt = s->bits <= 8 ? AV_PIX_FMT_GBRP : AV_PIX_FMT_GBRP16; } else { - s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P; + if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P; + else s->avctx->pix_fmt = AV_PIX_FMT_YUV444P16; s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; } } av_assert0(s->nb_components == 3); break; + case 0x11111111: + if (s->rgb) + s->avctx->pix_fmt = s->bits <= 9 ? AV_PIX_FMT_ABGR : AV_PIX_FMT_RGBA64; + else { + s->avctx->pix_fmt = s->bits <= 8 ? AV_PIX_FMT_YUVA444P : AV_PIX_FMT_YUVA444P16; + s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; + } + av_assert0(s->nb_components == 4); + break; case 0x12121100: case 0x22122100: - s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P; + if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P; + else + goto unk_pixfmt; s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; s->upscale_v = 2; s->upscale_h = (pix_fmt_id == 0x22122100); @@ -375,14 +395,18 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) break; case 0x21211100: case 0x22211200: - s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P; + if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P; + else + goto unk_pixfmt; s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; s->upscale_v = (pix_fmt_id == 0x22211200); s->upscale_h = 2; s->chroma_height = s->height; break; case 0x22221100: - s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P; + if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P; + else + goto unk_pixfmt; s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; s->upscale_v = 2; s->upscale_h = 2; @@ -405,26 +429,39 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) case 0x12111100: case 0x22211100: case 0x22112100: - s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV440P : AV_PIX_FMT_YUVJ440P; + if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV440P : AV_PIX_FMT_YUVJ440P; + else + goto unk_pixfmt; s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; s->upscale_h = (pix_fmt_id == 0x22211100) * 2 + (pix_fmt_id == 0x22112100); s->chroma_height = s->height / 2; break; case 0x21111100: - s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV422P : AV_PIX_FMT_YUVJ422P; + if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV422P : AV_PIX_FMT_YUVJ422P; + else s->avctx->pix_fmt = AV_PIX_FMT_YUV422P16; s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; break; case 0x22121100: case 0x22111200: - s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV422P : AV_PIX_FMT_YUVJ422P; + if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV422P : AV_PIX_FMT_YUVJ422P; + else + goto unk_pixfmt; s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; s->upscale_v = (pix_fmt_id == 0x22121100) + 1; break; case 0x22111100: - s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_YUVJ420P; + if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_YUVJ420P; + else s->avctx->pix_fmt = AV_PIX_FMT_YUV420P16; + s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; + break; + case 0x41111100: + if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV411P : AV_PIX_FMT_YUVJ411P; + else + goto unk_pixfmt; s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; break; default: +unk_pixfmt: av_log(s->avctx, AV_LOG_ERROR, "Unhandled pixel format 0x%x\n", pix_fmt_id); return AVERROR_PATCHWELCOME; } @@ -473,8 +510,10 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) int size = bw * bh * s->h_count[i] * s->v_count[i]; av_freep(&s->blocks[i]); av_freep(&s->last_nnz[i]); - s->blocks[i] = av_malloc(size * sizeof(**s->blocks)); + s->blocks[i] = av_mallocz(size * sizeof(**s->blocks)); s->last_nnz[i] = av_mallocz(size * sizeof(**s->last_nnz)); + if (!s->blocks[i] || !s->last_nnz[i]) + return AVERROR(ENOMEM); s->block_stride[i] = bw * s->h_count[i]; } memset(s->coefs_finished, 0, sizeof(s->coefs_finished)); @@ -486,11 +525,11 @@ static inline int mjpeg_decode_dc(MJpegDecodeContext *s, int dc_index) { int code; code = get_vlc2(&s->gb, s->vlcs[0][dc_index].table, 9, 2); - if (code < 0) { + if (code < 0 || code > 16) { av_log(s->avctx, AV_LOG_WARNING, "mjpeg_decode_dc: bad vlc: %d:%d (%p)\n", 0, dc_index, &s->vlcs[0][dc_index]); - return 0xffff; + return 0xfffff; } if (code) @@ -507,7 +546,7 @@ static int decode_block(MJpegDecodeContext *s, int16_t *block, int component, /* DC coef */ val = mjpeg_decode_dc(s, dc_index); - if (val == 0xffff) { + if (val == 0xfffff) { av_log(s->avctx, AV_LOG_ERROR, "error dc\n"); return AVERROR_INVALIDDATA; } @@ -555,7 +594,7 @@ static int decode_dc_progressive(MJpegDecodeContext *s, int16_t *block, int val; s->dsp.clear_block(block); val = mjpeg_decode_dc(s, dc_index); - if (val == 0xffff) { + if (val == 0xfffff) { av_log(s->avctx, AV_LOG_ERROR, "error dc\n"); return AVERROR_INVALIDDATA; } @@ -729,15 +768,17 @@ static int decode_block_refinement(MJpegDecodeContext *s, int16_t *block, #undef REFINE_BIT #undef ZERO_RUN -static void handle_rstn(MJpegDecodeContext *s, int nb_components) +static int handle_rstn(MJpegDecodeContext *s, int nb_components) { int i; + int reset = 0; + if (s->restart_interval) { s->restart_count--; if(s->restart_count == 0 && s->avctx->codec_id == AV_CODEC_ID_THP){ align_get_bits(&s->gb); for (i = 0; i < nb_components; i++) /* reset dc */ - s->last_dc[i] = 1024; + s->last_dc[i] = (4 << s->bits); } i = 8 + ((-get_bits_count(&s->gb)) & 7); @@ -751,40 +792,48 @@ static void handle_rstn(MJpegDecodeContext *s, int nb_components) skip_bits(&s->gb, 8); if (get_bits_left(&s->gb) >= 8 && (get_bits(&s->gb, 8) & 0xF8) == 0xD0) { for (i = 0; i < nb_components; i++) /* reset dc */ - s->last_dc[i] = 1024; + s->last_dc[i] = (4 << s->bits); + reset = 1; } else skip_bits_long(&s->gb, pos - get_bits_count(&s->gb)); } } } + return reset; } static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int predictor, int point_transform) { int i, mb_x, mb_y; uint16_t (*buffer)[4]; - int left[3], top[3], topleft[3]; + int left[4], top[4], topleft[4]; const int linesize = s->linesize[0]; - const int mask = (1 << s->bits) - 1; + const int mask = ((1 << s->bits) - 1) << point_transform; int resync_mb_y = 0; int resync_mb_x = 0; + if (s->nb_components != 3 && s->nb_components != 4) + return AVERROR_INVALIDDATA; + if (s->v_max != 1 || s->h_max != 1 || !s->lossless) + return AVERROR_INVALIDDATA; + + s->restart_count = s->restart_interval; av_fast_malloc(&s->ljpeg_buffer, &s->ljpeg_buffer_size, (unsigned)s->mb_width * 4 * sizeof(s->ljpeg_buffer[0][0])); buffer = s->ljpeg_buffer; - for (i = 0; i < 3; i++) + for (i = 0; i < 4; i++) buffer[0][i] = 1 << (s->bits - 1); for (mb_y = 0; mb_y < s->mb_height; mb_y++) { - uint8_t *ptr = s->picture.data[0] + (linesize * mb_y); + uint8_t *ptr = s->picture_ptr->data[0] + (linesize * mb_y); if (s->interlaced && s->bottom_field) ptr += linesize >> 1; - for (i = 0; i < 3; i++) + for (i = 0; i < 4; i++) top[i] = left[i] = topleft[i] = buffer[0][i]; for (mb_x = 0; mb_x < s->mb_width; mb_x++) { @@ -794,7 +843,7 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int p s->restart_count = s->restart_interval; resync_mb_x = mb_x; resync_mb_y = mb_y; - for(i=0; i<3; i++) + for(i=0; i<4; i++) top[i] = left[i]= topleft[i]= 1 << (s->bits - 1); } if (mb_y == resync_mb_y || mb_y == resync_mb_y+1 && mb_x < resync_mb_x || !mb_x) @@ -809,7 +858,7 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int p PREDICT(pred, topleft[i], top[i], left[i], modified_predictor); dc = mjpeg_decode_dc(s, s->dc_index[i]); - if(dc == 0xFFFF) + if(dc == 0xFFFFF) return -1; left[i] = buffer[mb_x][i] = @@ -821,8 +870,22 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int p skip_bits(&s->gb, 16); /* skip RSTn */ } } - - if (s->rct) { + if (s->nb_components == 4) { + for(i=0; icomp_index[i]; + if (s->bits <= 8) { + for(mb_x = 0; mb_x < s->mb_width; mb_x++) { + ptr[4*mb_x+3-c] = buffer[mb_x][i]; + } + } else if(s->bits == 9) { + return AVERROR_PATCHWELCOME; + } else { + for(mb_x = 0; mb_x < s->mb_width; mb_x++) { + ((uint16_t*)ptr)[4*mb_x+c] = buffer[mb_x][i]; + } + } + } + } else if (s->rct) { for (mb_x = 0; mb_x < s->mb_width; mb_x++) { ptr[3*mb_x + 1] = buffer[mb_x][0] - ((buffer[mb_x][1] + buffer[mb_x][2] - 0x200) >> 2); ptr[3*mb_x + 0] = buffer[mb_x][1] + ptr[3*mb_x + 1]; @@ -837,8 +900,16 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int p } else { for(i=0; icomp_index[i]; - for(mb_x = 0; mb_x < s->mb_width; mb_x++) { - ptr[3*mb_x+2-c] = buffer[mb_x][i]; + if (s->bits <= 8) { + for(mb_x = 0; mb_x < s->mb_width; mb_x++) { + ptr[3*mb_x+2-c] = buffer[mb_x][i]; + } + } else if(s->bits == 9) { + return AVERROR_PATCHWELCOME; + } else { + for(mb_x = 0; mb_x < s->mb_width; mb_x++) { + ((uint16_t*)ptr)[3*mb_x+2-c] = buffer[mb_x][i]; + } } } } @@ -846,17 +917,18 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int p return 0; } -static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int nb_components, int predictor, - int point_transform) +static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor, + int point_transform, int nb_components) { - int i, mb_x, mb_y; + int i, mb_x, mb_y, mask; int bits= (s->bits+7)&~7; int resync_mb_y = 0; int resync_mb_x = 0; point_transform += bits - s->bits; + mask = ((1 << s->bits) - 1) << point_transform; - av_assert0(nb_components>=1 && nb_components<=3); + av_assert0(nb_components>=1 && nb_components<=4); for (mb_y = 0; mb_y < s->mb_height; mb_y++) { for (mb_x = 0; mb_x < s->mb_width; mb_x++) { @@ -887,10 +959,10 @@ static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int nb_components, int p int pred, dc; dc = mjpeg_decode_dc(s, s->dc_index[i]); - if(dc == 0xFFFF) + if(dc == 0xFFFFF) return -1; if(bits<=8){ - ptr = s->picture.data[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap + ptr = s->picture_ptr->data[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap if(y==0 && toprow){ if(x==0 && leftcol){ pred= 1 << (bits - 1); @@ -907,10 +979,10 @@ static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int nb_components, int p if (s->interlaced && s->bottom_field) ptr += linesize >> 1; - pred &= (-1)<<(8-s->bits); + pred &= mask; *ptr= pred + (dc << point_transform); }else{ - ptr16 = (uint16_t*)(s->picture.data[c] + 2*(linesize * (v * mb_y + y)) + 2*(h * mb_x + x)); //FIXME optimize this crap + ptr16 = (uint16_t*)(s->picture_ptr->data[c] + 2*(linesize * (v * mb_y + y)) + 2*(h * mb_x + x)); //FIXME optimize this crap if(y==0 && toprow){ if(x==0 && leftcol){ pred= 1 << (bits - 1); @@ -927,7 +999,7 @@ static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int nb_components, int p if (s->interlaced && s->bottom_field) ptr16 += linesize >> 1; - pred &= (-1)<<(16-s->bits); + pred &= mask; *ptr16= pred + (dc << point_transform); } if (++x == h) { @@ -955,21 +1027,21 @@ static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int nb_components, int p int pred; dc = mjpeg_decode_dc(s, s->dc_index[i]); - if(dc == 0xFFFF) + if(dc == 0xFFFFF) return -1; if(bits<=8){ - ptr = s->picture.data[c] + + ptr = s->picture_ptr->data[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor); - pred &= (-1)<<(8-s->bits); + pred &= mask; *ptr = pred + (dc << point_transform); }else{ - ptr16 = (uint16_t*)(s->picture.data[c] + 2*(linesize * (v * mb_y + y)) + 2*(h * mb_x + x)); //FIXME optimize this crap + ptr16 = (uint16_t*)(s->picture_ptr->data[c] + 2*(linesize * (v * mb_y + y)) + 2*(h * mb_x + x)); //FIXME optimize this crap PREDICT(pred, ptr16[-linesize-1], ptr16[-linesize], ptr16[-1], predictor); - pred &= (-1)<<(16-s->bits); + pred &= mask; *ptr16= pred + (dc << point_transform); } @@ -1005,6 +1077,21 @@ static av_always_inline void mjpeg_copy_block(MJpegDecodeContext *s, } } +static void shift_output(MJpegDecodeContext *s, uint8_t *ptr, int linesize) +{ + int block_x, block_y; + int size = 8 >> s->avctx->lowres; + if (s->bits > 8) { + for (block_y=0; block_ybits; + } else { + for (block_y=0; block_ybits; + } +} + static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, int Al, const uint8_t *mb_bitmask, const AVFrame *reference) @@ -1014,6 +1101,7 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, const uint8_t *reference_data[MAX_COMPONENTS]; int linesize[MAX_COMPONENTS]; GetBitContext mb_bitmask_gb; + int bytes_per_pixel = 1 + (s->bits > 8); if (mb_bitmask) init_get_bits(&mb_bitmask_gb, mb_bitmask, s->mb_width * s->mb_height); @@ -1022,7 +1110,7 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, av_log(s->avctx, AV_LOG_ERROR, "Can not flip image with lowres\n"); s->flipped = 0; } - + s->restart_count = 0; for (i = 0; i < nb_components; i++) { int c = s->comp_index[i]; data[c] = s->picture_ptr->data[c]; @@ -1063,7 +1151,7 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, y = 0; for (j = 0; j < n; j++) { block_offset = (((linesize[c] * (v * mb_y + y) * 8) + - (h * mb_x + x) * 8) >> s->avctx->lowres); + (h * mb_x + x) * 8 * bytes_per_pixel) >> s->avctx->lowres); if (s->interlaced && s->bottom_field) block_offset += linesize[c] >> 1; @@ -1077,12 +1165,14 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, s->dsp.clear_block(s->block); if (decode_block(s, s->block, i, s->dc_index[i], s->ac_index[i], - s->quant_matrixes[s->quant_index[c]]) < 0) { + s->quant_matrixes[s->quant_sindex[i]]) < 0) { av_log(s->avctx, AV_LOG_ERROR, "error y=%d x=%d\n", mb_y, mb_x); return AVERROR_INVALIDDATA; } s->dsp.idct_put(ptr, linesize[c], s->block); + if (s->bits & 7) + shift_output(s, ptr, linesize[c]); } } else { int block_idx = s->block_stride[c] * (v * mb_y + y) + @@ -1090,9 +1180,9 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, int16_t *block = s->blocks[c][block_idx]; if (Ah) block[0] += get_bits1(&s->gb) * - s->quant_matrixes[s->quant_index[c]][0] << Al; + s->quant_matrixes[s->quant_sindex[i]][0] << Al; else if (decode_dc_progressive(s, block, i, s->dc_index[i], - s->quant_matrixes[s->quant_index[c]], + s->quant_matrixes[s->quant_sindex[i]], Al) < 0) { av_log(s->avctx, AV_LOG_ERROR, "error y=%d x=%d\n", mb_y, mb_x); @@ -1122,13 +1212,15 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss, int mb_x, mb_y; int EOBRUN = 0; int c = s->comp_index[0]; - uint8_t *data = s->picture.data[c]; + uint8_t *data = s->picture_ptr->data[c]; int linesize = s->linesize[c]; int last_scan = 0; - int16_t *quant_matrix = s->quant_matrixes[s->quant_index[c]]; + int16_t *quant_matrix = s->quant_matrixes[s->quant_sindex[0]]; + int bytes_per_pixel = 1 + (s->bits > 8); - if (se > 63) { - av_log(s->avctx, AV_LOG_ERROR, "SE %d is too large\n", se); + av_assert0(ss>=0 && Ah>=0 && Al>=0); + if (se < ss || se > 63) { + av_log(s->avctx, AV_LOG_ERROR, "SS/SE %d/%d is invalid\n", ss, se); return AVERROR_INVALIDDATA; } @@ -1166,9 +1258,12 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss, if (last_scan) { s->dsp.idct_put(ptr, linesize, *block); - ptr += 8 >> s->avctx->lowres; + if (s->bits & 7) + shift_output(s, ptr, linesize); + ptr += bytes_per_pixel*8 >> s->avctx->lowres; } - handle_rstn(s, 0); + if (handle_rstn(s, 0)) + EOBRUN = 0; } } return 0; @@ -1218,6 +1313,11 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask, && nb_components == 3 && s->nb_components == 3 && i) index = 3 - i; + s->quant_sindex[i] = s->quant_index[index]; + s->nb_blocks[i] = s->h_count[index] * s->v_count[index]; + s->h_scount[i] = s->h_count[index]; + s->v_scount[i] = s->v_count[index]; + if(nb_components == 3 && s->nb_components == 3 && s->avctx->pix_fmt == AV_PIX_FMT_GBR24P) index = (i+2)%3; if(nb_components == 1 && s->nb_components == 3 && s->avctx->pix_fmt == AV_PIX_FMT_GBR24P) @@ -1225,10 +1325,6 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask, s->comp_index[i] = index; - s->nb_blocks[i] = s->h_count[index] * s->v_count[index]; - s->h_scount[i] = s->h_count[index]; - s->v_scount[i] = s->v_count[index]; - s->dc_index[i] = get_bits(&s->gb, 4); s->ac_index[i] = get_bits(&s->gb, 4); @@ -1274,10 +1370,10 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask, next_field: for (i = 0; i < nb_components; i++) - s->last_dc[i] = 1024; + s->last_dc[i] = (4 << s->bits); if (s->lossless) { - av_assert0(s->picture_ptr == &s->picture); + av_assert0(s->picture_ptr == s->picture); if (CONFIG_JPEGLS_DECODER && s->ls) { // for () { // reset_ls_coding_parameters(s, 0); @@ -1290,13 +1386,15 @@ next_field: if ((ret = ljpeg_decode_rgb_scan(s, nb_components, predictor, point_transform)) < 0) return ret; } else { - if ((ret = ljpeg_decode_yuv_scan(s, nb_components, predictor, point_transform)) < 0) + if ((ret = ljpeg_decode_yuv_scan(s, predictor, + point_transform, + nb_components)) < 0) return ret; } } } else { if (s->progressive && predictor) { - av_assert0(s->picture_ptr == &s->picture); + av_assert0(s->picture_ptr == s->picture); if ((ret = mjpeg_decode_scan_progressive_ac(s, predictor, ilv, prev_shift, point_transform)) < 0) @@ -1348,7 +1446,7 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) int len, id, i; len = get_bits(&s->gb, 16); - if (len < 5) + if (len < 6) return AVERROR_INVALIDDATA; if (8 * len > get_bits_left(&s->gb)) return AVERROR_INVALIDDATA; @@ -1357,7 +1455,7 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) len -= 6; if (s->avctx->debug & FF_DEBUG_STARTCODE) - av_log(s->avctx, AV_LOG_DEBUG, "APPx %8X\n", id); + av_log(s->avctx, AV_LOG_DEBUG, "APPx %8X len=%d\n", id, len); /* Buggy AVID, it puts EOI only at every 10th frame. */ /* Also, this fourcc is used by non-avid files too, it holds some @@ -1431,7 +1529,7 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) skip_bits(&s->gb, 16); /* unknown always 0? */ skip_bits(&s->gb, 16); /* unknown always 0? */ skip_bits(&s->gb, 16); /* unknown always 0? */ - switch (get_bits(&s->gb, 8)) { + switch (i=get_bits(&s->gb, 8)) { case 1: s->rgb = 1; s->pegasus_rct = 0; @@ -1441,11 +1539,62 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) s->pegasus_rct = 1; break; default: - av_log(s->avctx, AV_LOG_ERROR, "unknown colorspace\n"); + av_log(s->avctx, AV_LOG_ERROR, "unknown colorspace %d\n", i); } len -= 9; goto out; } + if (id == AV_RL32("colr") && len > 0) { + s->colr = get_bits(&s->gb, 8); + if (s->avctx->debug & FF_DEBUG_PICT_INFO) + av_log(s->avctx, AV_LOG_INFO, "COLR %d\n", s->colr); + len --; + goto out; + } + if (id == AV_RL32("xfrm") && len > 0) { + s->xfrm = get_bits(&s->gb, 8); + if (s->avctx->debug & FF_DEBUG_PICT_INFO) + av_log(s->avctx, AV_LOG_INFO, "XFRM %d\n", s->xfrm); + len --; + goto out; + } + + /* EXIF metadata */ + if (s->start_code == APP1 && id == AV_RB32("Exif") && len >= 2) { + GetByteContext gbytes; + int ret, le, ifd_offset, bytes_read; + const uint8_t *aligned; + + skip_bits(&s->gb, 16); // skip padding + len -= 2; + + // init byte wise reading + aligned = align_get_bits(&s->gb); + bytestream2_init(&gbytes, aligned, len); + + // read TIFF header + ret = ff_tdecode_header(&gbytes, &le, &ifd_offset); + if (ret) { + av_log(s->avctx, AV_LOG_ERROR, "mjpeg: invalid TIFF header in EXIF data\n"); + return ret; + } + + bytestream2_seek(&gbytes, ifd_offset, SEEK_SET); + + // read 0th IFD and store the metadata + // (return values > 0 indicate the presence of subimage metadata) + ret = ff_exif_decode_ifd(s->avctx, &gbytes, le, 0, &s->exif_metadata); + if (ret < 0) { + av_log(s->avctx, AV_LOG_ERROR, "mjpeg: error decoding EXIF data\n"); + return ret; + } + + bytes_read = bytestream2_tell(&gbytes); + skip_bits(&s->gb, bytes_read << 3); + len -= bytes_read; + + goto out; + } /* Apple MJPEG-A */ if ((s->start_code == APP1) && (len > (0x28 - 8))) { @@ -1497,12 +1646,14 @@ static int mjpeg_decode_com(MJpegDecodeContext *s) av_log(s->avctx, AV_LOG_INFO, "comment: '%s'\n", cbuf); /* buggy avid, it puts EOI only at every 10th frame */ - if (!strcmp(cbuf, "AVID")) { + if (!strncmp(cbuf, "AVID", 4)) { s->buggy_avid = 1; + if (len > 14 && cbuf[12] == 1) /* 1 - NTSC, 2 - PAL */ + s->interlace_polarity = 1; } else if (!strcmp(cbuf, "CS=ITU601")) s->cs_itu601 = 1; - else if ((len > 31 && !strncmp(cbuf, "Intel(R) JPEG Library, version 1", 32)) || - (len > 19 && !strncmp(cbuf, "Metasoft MJPEG Codec", 20))) + else if ((!strncmp(cbuf, "Intel(R) JPEG Library, version 1", 32)) || + (!strncmp(cbuf, "Metasoft MJPEG Codec", 20))) s->flipped = 1; av_free(cbuf); @@ -1522,7 +1673,7 @@ static int find_marker(const uint8_t **pbuf_ptr, const uint8_t *buf_end) int skipped = 0; buf_ptr = *pbuf_ptr; - while (buf_ptr < buf_end) { + while (buf_end - buf_ptr > 1) { v = *buf_ptr++; v2 = *buf_ptr; if ((v == 0xff) && (v2 >= 0xc0) && (v2 <= 0xfe) && buf_ptr < buf_end) { @@ -1531,6 +1682,7 @@ static int find_marker(const uint8_t **pbuf_ptr, const uint8_t *buf_end) } skipped++; } + buf_ptr = buf_end; val = -1; found: av_dlog(NULL, "find_marker skipped %d bytes\n", skipped); @@ -1634,11 +1786,14 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, MJpegDecodeContext *s = avctx->priv_data; const uint8_t *buf_end, *buf_ptr; const uint8_t *unescaped_buf_ptr; + int hshift, vshift; int unescaped_buf_size; int start_code; int i, index; int ret = 0; + av_dict_free(&s->exif_metadata); + buf_ptr = buf; buf_end = buf + buf_size; while (buf_ptr < buf_end) { @@ -1649,145 +1804,157 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, /* EOF */ if (start_code < 0) { goto the_end; - } else if (unescaped_buf_size > (1U<<28)) { - av_log(avctx, AV_LOG_ERROR, "MJPEG packet 0x%x too big (0x%x/0x%x), corrupt data?\n", + } else if (unescaped_buf_size > INT_MAX / 8) { + av_log(avctx, AV_LOG_ERROR, + "MJPEG packet 0x%x too big (%d/%d), corrupt data?\n", start_code, unescaped_buf_size, buf_size); return AVERROR_INVALIDDATA; - } else { - av_log(avctx, AV_LOG_DEBUG, "marker=%x avail_size_in_buf=%td\n", - start_code, buf_end - buf_ptr); - - init_get_bits(&s->gb, unescaped_buf_ptr, unescaped_buf_size * 8); - - s->start_code = start_code; - if (s->avctx->debug & FF_DEBUG_STARTCODE) - av_log(avctx, AV_LOG_DEBUG, "startcode: %X\n", start_code); - - /* process markers */ - if (start_code >= 0xd0 && start_code <= 0xd7) - av_log(avctx, AV_LOG_DEBUG, - "restart marker: %d\n", start_code & 0x0f); - /* APP fields */ - else if (start_code >= APP0 && start_code <= APP15) - mjpeg_decode_app(s); - /* Comment */ - else if (start_code == COM) - mjpeg_decode_com(s); - - ret = -1; - switch (start_code) { - case SOI: - s->restart_interval = 0; - s->restart_count = 0; - /* nothing to do on SOI */ - break; - case DQT: - ff_mjpeg_decode_dqt(s); - break; - case DHT: - if ((ret = ff_mjpeg_decode_dht(s)) < 0) { - av_log(avctx, AV_LOG_ERROR, "huffman table decode error\n"); - goto fail; - } - break; - case SOF0: - case SOF1: - s->lossless = 0; - s->ls = 0; - s->progressive = 0; - if ((ret = ff_mjpeg_decode_sof(s)) < 0) - goto fail; - break; - case SOF2: - s->lossless = 0; - s->ls = 0; - s->progressive = 1; - if ((ret = ff_mjpeg_decode_sof(s)) < 0) - goto fail; - break; - case SOF3: - s->lossless = 1; - s->ls = 0; - s->progressive = 0; - if ((ret = ff_mjpeg_decode_sof(s)) < 0) - goto fail; - break; - case SOF48: - s->lossless = 1; - s->ls = 1; - s->progressive = 0; - if ((ret = ff_mjpeg_decode_sof(s)) < 0) - goto fail; - break; - case LSE: - if (!CONFIG_JPEGLS_DECODER || - (ret = ff_jpegls_decode_lse(s)) < 0) - goto fail; - break; - case EOI: + } + av_log(avctx, AV_LOG_DEBUG, "marker=%x avail_size_in_buf=%td\n", + start_code, buf_end - buf_ptr); + + ret = init_get_bits8(&s->gb, unescaped_buf_ptr, unescaped_buf_size); + + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "invalid buffer\n"); + goto fail; + } + + s->start_code = start_code; + if (s->avctx->debug & FF_DEBUG_STARTCODE) + av_log(avctx, AV_LOG_DEBUG, "startcode: %X\n", start_code); + + /* process markers */ + if (start_code >= 0xd0 && start_code <= 0xd7) + av_log(avctx, AV_LOG_DEBUG, + "restart marker: %d\n", start_code & 0x0f); + /* APP fields */ + else if (start_code >= APP0 && start_code <= APP15) + mjpeg_decode_app(s); + /* Comment */ + else if (start_code == COM) + mjpeg_decode_com(s); + + ret = -1; + + if (!CONFIG_JPEGLS_DECODER && + (start_code == SOF48 || start_code == LSE)) { + av_log(avctx, AV_LOG_ERROR, "JPEG-LS support not enabled.\n"); + return AVERROR(ENOSYS); + } + + switch (start_code) { + case SOI: + s->restart_interval = 0; + s->restart_count = 0; + /* nothing to do on SOI */ + break; + case DQT: + ff_mjpeg_decode_dqt(s); + break; + case DHT: + if ((ret = ff_mjpeg_decode_dht(s)) < 0) { + av_log(avctx, AV_LOG_ERROR, "huffman table decode error\n"); + goto fail; + } + break; + case SOF0: + case SOF1: + s->lossless = 0; + s->ls = 0; + s->progressive = 0; + if ((ret = ff_mjpeg_decode_sof(s)) < 0) + goto fail; + break; + case SOF2: + s->lossless = 0; + s->ls = 0; + s->progressive = 1; + if ((ret = ff_mjpeg_decode_sof(s)) < 0) + goto fail; + break; + case SOF3: + s->lossless = 1; + s->ls = 0; + s->progressive = 0; + if ((ret = ff_mjpeg_decode_sof(s)) < 0) + goto fail; + break; + case SOF48: + s->lossless = 1; + s->ls = 1; + s->progressive = 0; + if ((ret = ff_mjpeg_decode_sof(s)) < 0) + goto fail; + break; + case LSE: + if (!CONFIG_JPEGLS_DECODER || + (ret = ff_jpegls_decode_lse(s)) < 0) + goto fail; + break; + case EOI: eoi_parser: - s->cur_scan = 0; - if (!s->got_picture) { - av_log(avctx, AV_LOG_WARNING, - "Found EOI before any SOF, ignoring\n"); + s->cur_scan = 0; + if (!s->got_picture) { + av_log(avctx, AV_LOG_WARNING, + "Found EOI before any SOF, ignoring\n"); + break; + } + if (s->interlaced) { + s->bottom_field ^= 1; + /* if not bottom field, do not output image yet */ + if (s->bottom_field == !s->interlace_polarity) break; - } - if (s->interlaced) { - s->bottom_field ^= 1; - /* if not bottom field, do not output image yet */ - if (s->bottom_field == !s->interlace_polarity) - break; - } - if ((ret = av_frame_ref(data, s->picture_ptr)) < 0) - return ret; - *got_frame = 1; - s->got_picture = 0; - - if (!s->lossless) { - int qp = FFMAX3(s->qscale[0], - s->qscale[1], - s->qscale[2]); - int qpw = (s->width + 15) / 16; - AVBufferRef *qp_table_buf = av_buffer_alloc(qpw); - if (qp_table_buf) { - memset(qp_table_buf->data, qp, qpw); - av_frame_set_qp_table(data, qp_table_buf, 0, FF_QSCALE_TYPE_MPEG1); - } - - if(avctx->debug & FF_DEBUG_QP) - av_log(avctx, AV_LOG_DEBUG, "QP: %d\n", qp); + } + if ((ret = av_frame_ref(data, s->picture_ptr)) < 0) + return ret; + *got_frame = 1; + s->got_picture = 0; + + if (!s->lossless) { + int qp = FFMAX3(s->qscale[0], + s->qscale[1], + s->qscale[2]); + int qpw = (s->width + 15) / 16; + AVBufferRef *qp_table_buf = av_buffer_alloc(qpw); + if (qp_table_buf) { + memset(qp_table_buf->data, qp, qpw); + av_frame_set_qp_table(data, qp_table_buf, 0, FF_QSCALE_TYPE_MPEG1); } - goto the_end; - case SOS: - if ((ret = ff_mjpeg_decode_sos(s, NULL, NULL)) < 0 && - (avctx->err_recognition & AV_EF_EXPLODE)) - goto fail; - break; - case DRI: - mjpeg_decode_dri(s); - break; - case SOF5: - case SOF6: - case SOF7: - case SOF9: - case SOF10: - case SOF11: - case SOF13: - case SOF14: - case SOF15: - case JPG: - av_log(avctx, AV_LOG_ERROR, - "mjpeg: unsupported coding type (%x)\n", start_code); - break; + if(avctx->debug & FF_DEBUG_QP) + av_log(avctx, AV_LOG_DEBUG, "QP: %d\n", qp); } - /* eof process start code */ - buf_ptr += (get_bits_count(&s->gb) + 7) / 8; - av_log(avctx, AV_LOG_DEBUG, - "marker parser used %d bytes (%d bits)\n", - (get_bits_count(&s->gb) + 7) / 8, get_bits_count(&s->gb)); + goto the_end; + case SOS: + if ((ret = ff_mjpeg_decode_sos(s, NULL, NULL)) < 0 && + (avctx->err_recognition & AV_EF_EXPLODE)) + goto fail; + break; + case DRI: + mjpeg_decode_dri(s); + break; + case SOF5: + case SOF6: + case SOF7: + case SOF9: + case SOF10: + case SOF11: + case SOF13: + case SOF14: + case SOF15: + case JPG: + av_log(avctx, AV_LOG_ERROR, + "mjpeg: unsupported coding type (%x)\n", start_code); + break; } + + /* eof process start code */ + buf_ptr += (get_bits_count(&s->gb) + 7) / 8; + av_log(avctx, AV_LOG_DEBUG, + "marker parser used %d bytes (%d bits)\n", + (get_bits_count(&s->gb) + 7) / 8, get_bits_count(&s->gb)); } if (s->got_picture) { av_log(avctx, AV_LOG_WARNING, "EOI missing, emulating\n"); @@ -1813,6 +1980,9 @@ the_end: } if (s->upscale_v) { uint8_t *dst = &((uint8_t *)s->picture_ptr->data[s->upscale_v])[(s->height - 1) * s->linesize[s->upscale_v]]; + int w; + avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &hshift, &vshift); + w = s->width >> hshift; av_assert0(avctx->pix_fmt == AV_PIX_FMT_YUVJ444P || avctx->pix_fmt == AV_PIX_FMT_YUV444P || avctx->pix_fmt == AV_PIX_FMT_YUVJ422P || @@ -1821,24 +1991,24 @@ the_end: uint8_t *src1 = &((uint8_t *)s->picture_ptr->data[s->upscale_v])[i / 2 * s->linesize[s->upscale_v]]; uint8_t *src2 = &((uint8_t *)s->picture_ptr->data[s->upscale_v])[(i + 1) / 2 * s->linesize[s->upscale_v]]; if (src1 == src2) { - memcpy(dst, src1, s->width); + memcpy(dst, src1, w); } else { - for (index = 0; index < s->width; index++) + for (index = 0; index < w; index++) dst[index] = (src1[index] + src2[index]) >> 1; } dst -= s->linesize[s->upscale_v]; } } if (s->flipped && (s->avctx->flags & CODEC_FLAG_EMU_EDGE)) { - int hshift, vshift, j; + int j; avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &hshift, &vshift); for (index=0; index<4; index++) { uint8_t *dst = s->picture_ptr->data[index]; int w = s->width; int h = s->height; if(index && index<3){ - w = -((-w) >> hshift); - h = -((-h) >> vshift); + w = FF_CEIL_RSHIFT(w, hshift); + h = FF_CEIL_RSHIFT(h, vshift); } if(dst){ uint8_t *dst2 = dst + s->linesize[index]*(h-1); @@ -1852,6 +2022,9 @@ the_end: } } + av_dict_copy(avpriv_frame_get_metadatap(data), s->exif_metadata, 0); + av_dict_free(&s->exif_metadata); + av_log(avctx, AV_LOG_DEBUG, "decode frame unused %td bytes\n", buf_end - buf_ptr); // return buf_end - buf_ptr; @@ -1863,7 +2036,14 @@ av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx) MJpegDecodeContext *s = avctx->priv_data; int i, j; - if (s->picture_ptr) + if (s->interlaced && s->bottom_field == !s->interlace_polarity && s->got_picture && !avctx->frame_number) { + av_log(avctx, AV_LOG_INFO, "Single field\n"); + } + + if (s->picture) { + av_frame_free(&s->picture); + s->picture_ptr = NULL; + } else if (s->picture_ptr) av_frame_unref(s->picture_ptr); av_free(s->buffer); @@ -1878,6 +2058,7 @@ av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx) av_freep(&s->blocks[i]); av_freep(&s->last_nnz[i]); } + av_dict_free(&s->exif_metadata); return 0; } @@ -1905,6 +2086,7 @@ static const AVClass mjpegdec_class = { AVCodec ff_mjpeg_decoder = { .name = "mjpeg", + .long_name = NULL_IF_CONFIG_SMALL("MJPEG (Motion JPEG)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MJPEG, .priv_data_size = sizeof(MJpegDecodeContext), @@ -1914,13 +2096,13 @@ AVCodec ff_mjpeg_decoder = { .flush = decode_flush, .capabilities = CODEC_CAP_DR1, .max_lowres = 3, - .long_name = NULL_IF_CONFIG_SMALL("MJPEG (Motion JPEG)"), .priv_class = &mjpegdec_class, }; #endif #if CONFIG_THP_DECODER AVCodec ff_thp_decoder = { .name = "thp", + .long_name = NULL_IF_CONFIG_SMALL("Nintendo Gamecube THP video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_THP, .priv_data_size = sizeof(MJpegDecodeContext), @@ -1930,6 +2112,5 @@ AVCodec ff_thp_decoder = { .flush = decode_flush, .capabilities = CODEC_CAP_DR1, .max_lowres = 3, - .long_name = NULL_IF_CONFIG_SMALL("Nintendo Gamecube THP video"), }; #endif diff --git a/ffmpeg/libavcodec/mjpegdec.h b/ffmpeg/libavcodec/mjpegdec.h index 17665e4..1335c66 100644 --- a/ffmpeg/libavcodec/mjpegdec.h +++ b/ffmpeg/libavcodec/mjpegdec.h @@ -65,6 +65,8 @@ typedef struct MJpegDecodeContext { int rct; /* standard rct */ int pegasus_rct; /* pegasus reversible colorspace transform */ int bits; /* bits per component */ + int colr; + int xfrm; int maxval; int near; ///< near lossless bound (si 0 for lossless) @@ -84,10 +86,11 @@ typedef struct MJpegDecodeContext { int nb_blocks[MAX_COMPONENTS]; int h_scount[MAX_COMPONENTS]; int v_scount[MAX_COMPONENTS]; + int quant_sindex[MAX_COMPONENTS]; int h_max, v_max; /* maximum h and v counts */ int quant_index[4]; /* quant table index for each component */ int last_dc[MAX_COMPONENTS]; /* last DEQUANTIZED dc (XXX: am I right to do that ?) */ - AVFrame picture; /* picture structure */ + AVFrame *picture; /* picture structure */ AVFrame *picture_ptr; /* pointer to picture structure */ int got_picture; ///< we found a SOF and picture is valid, too. int linesize[MAX_COMPONENTS]; ///< linesize << interlaced @@ -116,6 +119,7 @@ typedef struct MJpegDecodeContext { unsigned int ljpeg_buffer_size; int extern_huff; + AVDictionary *exif_metadata; } MJpegDecodeContext; int ff_mjpeg_decode_init(AVCodecContext *avctx); diff --git a/ffmpeg/libavcodec/mjpegenc.c b/ffmpeg/libavcodec/mjpegenc.c index 80a4022..f23343a 100644 --- a/ffmpeg/libavcodec/mjpegenc.c +++ b/ffmpeg/libavcodec/mjpegenc.c @@ -30,6 +30,8 @@ * MJPEG encoder. */ +#include "libavutil/pixdesc.h" + #include "avcodec.h" #include "mpegvideo.h" #include "mjpeg.h" @@ -84,10 +86,9 @@ void ff_mjpeg_encode_close(MpegEncContext *s) } /* table_class: 0 = DC coef, 1 = AC coefs */ -static int put_huffman_table(MpegEncContext *s, int table_class, int table_id, +static int put_huffman_table(PutBitContext *p, int table_class, int table_id, const uint8_t *bits_table, const uint8_t *value_table) { - PutBitContext *p = &s->pb; int n, i; put_bits(p, 4, table_class); @@ -105,12 +106,15 @@ static int put_huffman_table(MpegEncContext *s, int table_class, int table_id, return n + 17; } -static void jpeg_table_header(MpegEncContext *s) +static void jpeg_table_header(AVCodecContext *avctx, PutBitContext *p, + ScanTable *intra_scantable, + uint16_t intra_matrix[64], + int hsample[3]) { - PutBitContext *p = &s->pb; int i, j, size; uint8_t *ptr; + if (avctx->codec_id != AV_CODEC_ID_LJPEG) { /* quant matrixes */ put_marker(p, DQT); #ifdef TWOMATRIXES @@ -121,8 +125,8 @@ static void jpeg_table_header(MpegEncContext *s) put_bits(p, 4, 0); /* 8 bit precision */ put_bits(p, 4, 0); /* table 0 */ for(i=0;i<64;i++) { - j = s->intra_scantable.permutated[i]; - put_bits(p, 8, s->intra_matrix[j]); + j = intra_scantable->permutated[i]; + put_bits(p, 8, intra_matrix[j]); } #ifdef TWOMATRIXES put_bits(p, 4, 0); /* 8 bit precision */ @@ -132,11 +136,12 @@ static void jpeg_table_header(MpegEncContext *s) put_bits(p, 8, s->chroma_intra_matrix[j]); } #endif + } - if(s->avctx->active_thread_type & FF_THREAD_SLICE){ + if(avctx->active_thread_type & FF_THREAD_SLICE){ put_marker(p, DRI); put_bits(p, 16, 4); - put_bits(p, 16, (s->width-1)/(8*s->mjpeg_hsample[0]) + 1); + put_bits(p, 16, (avctx->width-1)/(8*hsample[0]) + 1); } /* huffman table */ @@ -145,40 +150,38 @@ static void jpeg_table_header(MpegEncContext *s) ptr = put_bits_ptr(p); put_bits(p, 16, 0); /* patched later */ size = 2; - size += put_huffman_table(s, 0, 0, avpriv_mjpeg_bits_dc_luminance, + size += put_huffman_table(p, 0, 0, avpriv_mjpeg_bits_dc_luminance, avpriv_mjpeg_val_dc); - size += put_huffman_table(s, 0, 1, avpriv_mjpeg_bits_dc_chrominance, + size += put_huffman_table(p, 0, 1, avpriv_mjpeg_bits_dc_chrominance, avpriv_mjpeg_val_dc); - size += put_huffman_table(s, 1, 0, avpriv_mjpeg_bits_ac_luminance, + size += put_huffman_table(p, 1, 0, avpriv_mjpeg_bits_ac_luminance, avpriv_mjpeg_val_ac_luminance); - size += put_huffman_table(s, 1, 1, avpriv_mjpeg_bits_ac_chrominance, + size += put_huffman_table(p, 1, 1, avpriv_mjpeg_bits_ac_chrominance, avpriv_mjpeg_val_ac_chrominance); AV_WB16(ptr, size); } -static void jpeg_put_comments(MpegEncContext *s) +static void jpeg_put_comments(AVCodecContext *avctx, PutBitContext *p) { - PutBitContext *p = &s->pb; int size; uint8_t *ptr; - if (s->avctx->sample_aspect_ratio.num /* && !lossless */) - { - /* JFIF header */ - put_marker(p, APP0); - put_bits(p, 16, 16); - avpriv_put_string(p, "JFIF", 1); /* this puts the trailing zero-byte too */ - put_bits(p, 16, 0x0102); /* v 1.02 */ - put_bits(p, 8, 0); /* units type: 0 - aspect ratio */ - put_bits(p, 16, s->avctx->sample_aspect_ratio.num); - put_bits(p, 16, s->avctx->sample_aspect_ratio.den); - put_bits(p, 8, 0); /* thumbnail width */ - put_bits(p, 8, 0); /* thumbnail height */ + if (avctx->sample_aspect_ratio.num > 0 && avctx->sample_aspect_ratio.den > 0) { + /* JFIF header */ + put_marker(p, APP0); + put_bits(p, 16, 16); + avpriv_put_string(p, "JFIF", 1); /* this puts the trailing zero-byte too */ + put_bits(p, 16, 0x0102); /* v 1.02 */ + put_bits(p, 8, 0); /* units type: 0 - aspect ratio */ + put_bits(p, 16, avctx->sample_aspect_ratio.num); + put_bits(p, 16, avctx->sample_aspect_ratio.den); + put_bits(p, 8, 0); /* thumbnail width */ + put_bits(p, 8, 0); /* thumbnail height */ } /* comment */ - if(!(s->flags & CODEC_FLAG_BITEXACT)){ + if (!(avctx->flags & CODEC_FLAG_BITEXACT)) { put_marker(p, COM); flush_put_bits(p); ptr = put_bits_ptr(p); @@ -188,9 +191,9 @@ static void jpeg_put_comments(MpegEncContext *s) AV_WB16(ptr, size); } - if( s->avctx->pix_fmt == AV_PIX_FMT_YUV420P - ||s->avctx->pix_fmt == AV_PIX_FMT_YUV422P - ||s->avctx->pix_fmt == AV_PIX_FMT_YUV444P){ + if (avctx->pix_fmt == AV_PIX_FMT_YUV420P || + avctx->pix_fmt == AV_PIX_FMT_YUV422P || + avctx->pix_fmt == AV_PIX_FMT_YUV444P) { put_marker(p, COM); flush_put_bits(p); ptr = put_bits_ptr(p); @@ -201,105 +204,148 @@ static void jpeg_put_comments(MpegEncContext *s) } } -void ff_mjpeg_encode_picture_header(MpegEncContext *s) +void ff_mjpeg_init_hvsample(AVCodecContext *avctx, int hsample[3], int vsample[3]) +{ + int chroma_h_shift, chroma_v_shift; + + av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &chroma_h_shift, + &chroma_v_shift); + if (avctx->codec->id == AV_CODEC_ID_LJPEG && + ( avctx->pix_fmt == AV_PIX_FMT_BGR0 + || avctx->pix_fmt == AV_PIX_FMT_BGRA + || avctx->pix_fmt == AV_PIX_FMT_BGR24)) { + vsample[0] = hsample[0] = + vsample[1] = hsample[1] = + vsample[2] = hsample[2] = 1; + } else if (avctx->pix_fmt == AV_PIX_FMT_YUV444P || avctx->pix_fmt == AV_PIX_FMT_YUVJ444P) { + vsample[0] = vsample[1] = vsample[2] = 2; + hsample[0] = hsample[1] = hsample[2] = 1; + } else { + vsample[0] = 2; + vsample[1] = 2 >> chroma_v_shift; + vsample[2] = 2 >> chroma_v_shift; + hsample[0] = 2; + hsample[1] = 2 >> chroma_h_shift; + hsample[2] = 2 >> chroma_h_shift; + } +} + +void ff_mjpeg_encode_picture_header(AVCodecContext *avctx, PutBitContext *pb, + ScanTable *intra_scantable, + uint16_t intra_matrix[64]) { - const int lossless= s->avctx->codec_id != AV_CODEC_ID_MJPEG; + const int lossless = avctx->codec_id != AV_CODEC_ID_MJPEG && avctx->codec_id != AV_CODEC_ID_AMV; + int hsample[3], vsample[3]; int i; - put_marker(&s->pb, SOI); + ff_mjpeg_init_hvsample(avctx, hsample, vsample); + + put_marker(pb, SOI); // hack for AMV mjpeg format - if(s->avctx->codec_id == AV_CODEC_ID_AMV) goto end; + if(avctx->codec_id == AV_CODEC_ID_AMV) goto end; - jpeg_put_comments(s); + jpeg_put_comments(avctx, pb); - jpeg_table_header(s); + jpeg_table_header(avctx, pb, intra_scantable, intra_matrix, hsample); - switch(s->avctx->codec_id){ - case AV_CODEC_ID_MJPEG: put_marker(&s->pb, SOF0 ); break; - case AV_CODEC_ID_LJPEG: put_marker(&s->pb, SOF3 ); break; + switch (avctx->codec_id) { + case AV_CODEC_ID_MJPEG: put_marker(pb, SOF0 ); break; + case AV_CODEC_ID_LJPEG: put_marker(pb, SOF3 ); break; default: av_assert0(0); } - put_bits(&s->pb, 16, 17); - if(lossless && (s->avctx->pix_fmt == AV_PIX_FMT_BGR0 - || s->avctx->pix_fmt == AV_PIX_FMT_BGRA - || s->avctx->pix_fmt == AV_PIX_FMT_BGR24)) - put_bits(&s->pb, 8, 9); /* 9 bits/component RCT */ + put_bits(pb, 16, 17); + if (lossless && ( avctx->pix_fmt == AV_PIX_FMT_BGR0 + || avctx->pix_fmt == AV_PIX_FMT_BGRA + || avctx->pix_fmt == AV_PIX_FMT_BGR24)) + put_bits(pb, 8, 9); /* 9 bits/component RCT */ else - put_bits(&s->pb, 8, 8); /* 8 bits/component */ - put_bits(&s->pb, 16, s->height); - put_bits(&s->pb, 16, s->width); - put_bits(&s->pb, 8, 3); /* 3 components */ + put_bits(pb, 8, 8); /* 8 bits/component */ + put_bits(pb, 16, avctx->height); + put_bits(pb, 16, avctx->width); + put_bits(pb, 8, 3); /* 3 components */ /* Y component */ - put_bits(&s->pb, 8, 1); /* component number */ - put_bits(&s->pb, 4, s->mjpeg_hsample[0]); /* H factor */ - put_bits(&s->pb, 4, s->mjpeg_vsample[0]); /* V factor */ - put_bits(&s->pb, 8, 0); /* select matrix */ + put_bits(pb, 8, 1); /* component number */ + put_bits(pb, 4, hsample[0]); /* H factor */ + put_bits(pb, 4, vsample[0]); /* V factor */ + put_bits(pb, 8, 0); /* select matrix */ /* Cb component */ - put_bits(&s->pb, 8, 2); /* component number */ - put_bits(&s->pb, 4, s->mjpeg_hsample[1]); /* H factor */ - put_bits(&s->pb, 4, s->mjpeg_vsample[1]); /* V factor */ + put_bits(pb, 8, 2); /* component number */ + put_bits(pb, 4, hsample[1]); /* H factor */ + put_bits(pb, 4, vsample[1]); /* V factor */ #ifdef TWOMATRIXES - put_bits(&s->pb, 8, lossless ? 0 : 1); /* select matrix */ + put_bits(pb, 8, lossless ? 0 : 1); /* select matrix */ #else - put_bits(&s->pb, 8, 0); /* select matrix */ + put_bits(pb, 8, 0); /* select matrix */ #endif /* Cr component */ - put_bits(&s->pb, 8, 3); /* component number */ - put_bits(&s->pb, 4, s->mjpeg_hsample[2]); /* H factor */ - put_bits(&s->pb, 4, s->mjpeg_vsample[2]); /* V factor */ + put_bits(pb, 8, 3); /* component number */ + put_bits(pb, 4, hsample[2]); /* H factor */ + put_bits(pb, 4, vsample[2]); /* V factor */ #ifdef TWOMATRIXES - put_bits(&s->pb, 8, lossless ? 0 : 1); /* select matrix */ + put_bits(pb, 8, lossless ? 0 : 1); /* select matrix */ #else - put_bits(&s->pb, 8, 0); /* select matrix */ + put_bits(pb, 8, 0); /* select matrix */ #endif /* scan header */ - put_marker(&s->pb, SOS); - put_bits(&s->pb, 16, 12); /* length */ - put_bits(&s->pb, 8, 3); /* 3 components */ + put_marker(pb, SOS); + put_bits(pb, 16, 12); /* length */ + put_bits(pb, 8, 3); /* 3 components */ /* Y component */ - put_bits(&s->pb, 8, 1); /* index */ - put_bits(&s->pb, 4, 0); /* DC huffman table index */ - put_bits(&s->pb, 4, 0); /* AC huffman table index */ + put_bits(pb, 8, 1); /* index */ + put_bits(pb, 4, 0); /* DC huffman table index */ + put_bits(pb, 4, 0); /* AC huffman table index */ /* Cb component */ - put_bits(&s->pb, 8, 2); /* index */ - put_bits(&s->pb, 4, 1); /* DC huffman table index */ - put_bits(&s->pb, 4, lossless ? 0 : 1); /* AC huffman table index */ + put_bits(pb, 8, 2); /* index */ + put_bits(pb, 4, 1); /* DC huffman table index */ + put_bits(pb, 4, lossless ? 0 : 1); /* AC huffman table index */ /* Cr component */ - put_bits(&s->pb, 8, 3); /* index */ - put_bits(&s->pb, 4, 1); /* DC huffman table index */ - put_bits(&s->pb, 4, lossless ? 0 : 1); /* AC huffman table index */ + put_bits(pb, 8, 3); /* index */ + put_bits(pb, 4, 1); /* DC huffman table index */ + put_bits(pb, 4, lossless ? 0 : 1); /* AC huffman table index */ - put_bits(&s->pb, 8, lossless ? s->avctx->prediction_method+1 : 0); /* Ss (not used) */ + put_bits(pb, 8, lossless ? avctx->prediction_method + 1 : 0); /* Ss (not used) */ - switch(s->avctx->codec_id){ - case AV_CODEC_ID_MJPEG: put_bits(&s->pb, 8, 63); break; /* Se (not used) */ - case AV_CODEC_ID_LJPEG: put_bits(&s->pb, 8, 0); break; /* not used */ + switch (avctx->codec_id) { + case AV_CODEC_ID_MJPEG: put_bits(pb, 8, 63); break; /* Se (not used) */ + case AV_CODEC_ID_LJPEG: put_bits(pb, 8, 0); break; /* not used */ default: av_assert0(0); } - put_bits(&s->pb, 8, 0); /* Ah/Al (not used) */ + put_bits(pb, 8, 0); /* Ah/Al (not used) */ end: - s->esc_pos = put_bits_count(&s->pb) >> 3; - for(i=1; islice_context_count; i++) - s->thread_context[i]->esc_pos = 0; + if (!lossless) { + MpegEncContext *s = avctx->priv_data; + av_assert0(avctx->codec->priv_data_size == sizeof(MpegEncContext)); + + s->esc_pos = put_bits_count(pb) >> 3; + for(i=1; islice_context_count; i++) + s->thread_context[i]->esc_pos = 0; + } } -static void escape_FF(MpegEncContext *s, int start) +void ff_mjpeg_escape_FF(PutBitContext *pb, int start) { - int size= put_bits_count(&s->pb) - start*8; + int size; int i, ff_count; - uint8_t *buf= s->pb.buf + start; + uint8_t *buf = pb->buf + start; int align= (-(size_t)(buf))&3; + int pad = (-put_bits_count(pb))&7; + + if (pad) + put_bits(pb, pad, (1<>= 3; @@ -331,8 +377,8 @@ static void escape_FF(MpegEncContext *s, int start) if(ff_count==0) return; - flush_put_bits(&s->pb); - skip_put_bytes(&s->pb, ff_count); + flush_put_bits(pb); + skip_put_bytes(pb, ff_count); for(i=size-1; ff_count; i--){ int v= buf[i]; @@ -348,14 +394,11 @@ static void escape_FF(MpegEncContext *s, int start) void ff_mjpeg_encode_stuffing(MpegEncContext *s) { - int length, i; + int i; PutBitContext *pbc = &s->pb; int mb_y = s->mb_y - !s->mb_x; - length= (-put_bits_count(pbc))&7; - if(length) put_bits(pbc, length, (1<pb); - escape_FF(s, s->esc_pos); + ff_mjpeg_escape_FF(pbc, s->esc_pos); if((s->avctx->active_thread_type & FF_THREAD_SLICE) && mb_y < s->mb_height) put_marker(pbc, RST0 + (mb_y&7)); @@ -365,22 +408,20 @@ void ff_mjpeg_encode_stuffing(MpegEncContext *s) s->last_dc[i] = 128 << s->intra_dc_precision; } -void ff_mjpeg_encode_picture_trailer(MpegEncContext *s) +void ff_mjpeg_encode_picture_trailer(PutBitContext *pb, int header_bits) { + av_assert1((header_bits & 7) == 0); - av_assert1((s->header_bits&7)==0); - - - put_marker(&s->pb, EOI); + put_marker(pb, EOI); } -void ff_mjpeg_encode_dc(MpegEncContext *s, int val, +void ff_mjpeg_encode_dc(PutBitContext *pb, int val, uint8_t *huff_size, uint16_t *huff_code) { int mant, nbits; if (val == 0) { - put_bits(&s->pb, huff_size[0], huff_code[0]); + put_bits(pb, huff_size[0], huff_code[0]); } else { mant = val; if (val < 0) { @@ -390,9 +431,9 @@ void ff_mjpeg_encode_dc(MpegEncContext *s, int val, nbits= av_log2_16bit(val) + 1; - put_bits(&s->pb, huff_size[nbits], huff_code[nbits]); + put_bits(pb, huff_size[nbits], huff_code[nbits]); - put_sbits(&s->pb, nbits, mant); + put_sbits(pb, nbits, mant); } } @@ -409,11 +450,11 @@ static void encode_block(MpegEncContext *s, int16_t *block, int n) dc = block[0]; /* overflow is impossible */ val = dc - s->last_dc[component]; if (n < 4) { - ff_mjpeg_encode_dc(s, val, m->huff_size_dc_luminance, m->huff_code_dc_luminance); + ff_mjpeg_encode_dc(&s->pb, val, m->huff_size_dc_luminance, m->huff_code_dc_luminance); huff_size_ac = m->huff_size_ac_luminance; huff_code_ac = m->huff_code_ac_luminance; } else { - ff_mjpeg_encode_dc(s, val, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); + ff_mjpeg_encode_dc(&s->pb, val, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); huff_size_ac = m->huff_size_ac_chrominance; huff_code_ac = m->huff_code_ac_chrominance; } @@ -439,7 +480,7 @@ static void encode_block(MpegEncContext *s, int16_t *block, int n) mant--; } - nbits= av_log2(val) + 1; + nbits= av_log2_16bit(val) + 1; code = (run << 4) | nbits; put_bits(&s->pb, huff_size_ac[code], huff_code_ac[code]); @@ -496,24 +537,33 @@ static int amv_encode_picture(AVCodecContext *avctx, AVPacket *pkt, { MpegEncContext *s = avctx->priv_data; - AVFrame pic = *pic_arg; - int i; + AVFrame *pic; + int i, ret; + int chroma_h_shift, chroma_v_shift; + + av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &chroma_h_shift, &chroma_v_shift); //CODEC_FLAG_EMU_EDGE have to be cleared if(s->avctx->flags & CODEC_FLAG_EMU_EDGE) return -1; + pic = av_frame_alloc(); + av_frame_ref(pic, pic_arg); //picture should be flipped upside-down for(i=0; i < 3; i++) { - pic.data[i] += (pic.linesize[i] * (s->mjpeg_vsample[i] * (8 * s->mb_height -((s->height/V_MAX)&7)) - 1 )); - pic.linesize[i] *= -1; + int vsample = i ? 2 >> chroma_v_shift : 2; + pic->data[i] += (pic->linesize[i] * (vsample * (8 * s->mb_height -((s->height/V_MAX)&7)) - 1 )); + pic->linesize[i] *= -1; } - return ff_MPV_encode_picture(avctx, pkt, &pic, got_packet); + ret = ff_MPV_encode_picture(avctx, pkt, pic, got_packet); + av_frame_free(&pic); + return ret; } #if CONFIG_MJPEG_ENCODER AVCodec ff_mjpeg_encoder = { .name = "mjpeg", + .long_name = NULL_IF_CONFIG_SMALL("MJPEG (Motion JPEG)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MJPEG, .priv_data_size = sizeof(MpegEncContext), @@ -524,12 +574,12 @@ AVCodec ff_mjpeg_encoder = { .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("MJPEG (Motion JPEG)"), }; #endif #if CONFIG_AMV_ENCODER AVCodec ff_amv_encoder = { .name = "amv", + .long_name = NULL_IF_CONFIG_SMALL("AMV Video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_AMV, .priv_data_size = sizeof(MpegEncContext), @@ -539,6 +589,5 @@ AVCodec ff_amv_encoder = { .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("AMV Video"), }; #endif diff --git a/ffmpeg/libavcodec/mjpegenc.h b/ffmpeg/libavcodec/mjpegenc.h index ce0c1cc..4b19e21 100644 --- a/ffmpeg/libavcodec/mjpegenc.h +++ b/ffmpeg/libavcodec/mjpegenc.h @@ -51,10 +51,14 @@ typedef struct MJpegContext { int ff_mjpeg_encode_init(MpegEncContext *s); void ff_mjpeg_encode_close(MpegEncContext *s); -void ff_mjpeg_encode_picture_header(MpegEncContext *s); -void ff_mjpeg_encode_picture_trailer(MpegEncContext *s); +void ff_mjpeg_encode_picture_header(AVCodecContext *avctx, PutBitContext *pb, + ScanTable *intra_scantable, + uint16_t intra_matrix[64]); +void ff_mjpeg_encode_picture_trailer(PutBitContext *pb, int header_bits); +void ff_mjpeg_escape_FF(PutBitContext *pb, int start); void ff_mjpeg_encode_stuffing(MpegEncContext *s); -void ff_mjpeg_encode_dc(MpegEncContext *s, int val, +void ff_mjpeg_init_hvsample(AVCodecContext *avctx, int hsample[3], int vsample[3]); +void ff_mjpeg_encode_dc(PutBitContext *pb, int val, uint8_t *huff_size, uint16_t *huff_code); void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[6][64]); diff --git a/ffmpeg/libavcodec/mlp_parser.c b/ffmpeg/libavcodec/mlp_parser.c index 2cc4b91..fcd1168 100644 --- a/ffmpeg/libavcodec/mlp_parser.c +++ b/ffmpeg/libavcodec/mlp_parser.c @@ -28,6 +28,7 @@ #include "libavutil/channel_layout.h" #include "libavutil/crc.h" +#include "libavutil/internal.h" #include "get_bits.h" #include "parser.h" #include "mlp_parser.h" @@ -331,10 +332,12 @@ static int mlp_parse(AVCodecParserContext *s, if (mh.stream_type == 0xbb) { /* MLP stream */ #if FF_API_REQUEST_CHANNELS +FF_DISABLE_DEPRECATION_WARNINGS if (avctx->request_channels > 0 && avctx->request_channels <= 2 && mh.num_substreams > 1) { avctx->channels = 2; avctx->channel_layout = AV_CH_LAYOUT_STEREO; +FF_ENABLE_DEPRECATION_WARNINGS } else #endif if (avctx->request_channel_layout == AV_CH_LAYOUT_STEREO && @@ -348,6 +351,7 @@ static int mlp_parse(AVCodecParserContext *s, } else { /* mh.stream_type == 0xba */ /* TrueHD stream */ #if FF_API_REQUEST_CHANNELS +FF_DISABLE_DEPRECATION_WARNINGS if (avctx->request_channels > 0 && avctx->request_channels <= 2 && mh.num_substreams > 1) { avctx->channels = 2; @@ -356,6 +360,7 @@ static int mlp_parse(AVCodecParserContext *s, avctx->request_channels <= mh.channels_thd_stream1) { avctx->channels = mh.channels_thd_stream1; avctx->channel_layout = mh.channel_layout_thd_stream1; +FF_ENABLE_DEPRECATION_WARNINGS } else #endif if (avctx->request_channel_layout == AV_CH_LAYOUT_STEREO && diff --git a/ffmpeg/libavcodec/mlpdec.c b/ffmpeg/libavcodec/mlpdec.c index a7c79a4..88cafc2 100644 --- a/ffmpeg/libavcodec/mlpdec.c +++ b/ffmpeg/libavcodec/mlpdec.c @@ -27,6 +27,7 @@ #include #include "avcodec.h" +#include "libavutil/internal.h" #include "libavutil/intreadwrite.h" #include "libavutil/channel_layout.h" #include "get_bits.h" @@ -362,10 +363,22 @@ static int read_major_sync(MLPDecodeContext *m, GetBitContext *gb) * substream is Stereo. Subsequent substreams' layouts are indicated in the * major sync. */ if (m->avctx->codec_id == AV_CODEC_ID_MLP) { + if (mh.stream_type != 0xbb) { + avpriv_request_sample(m->avctx, + "unexpected stream_type %X in MLP", + mh.stream_type); + return AVERROR_PATCHWELCOME; + } if ((substr = (mh.num_substreams > 1))) m->substream[0].ch_layout = AV_CH_LAYOUT_STEREO; m->substream[substr].ch_layout = mh.channel_layout_mlp; } else { + if (mh.stream_type != 0xba) { + avpriv_request_sample(m->avctx, + "unexpected stream_type %X in !MLP", + mh.stream_type); + return AVERROR_PATCHWELCOME; + } if ((substr = (mh.num_substreams > 1))) m->substream[0].ch_layout = AV_CH_LAYOUT_STEREO; if (mh.num_substreams > 2) @@ -401,10 +414,10 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, uint8_t checksum; uint8_t lossless_check; int start_count = get_bits_count(gbp); - const int max_matrix_channel = m->avctx->codec_id == AV_CODEC_ID_MLP - ? MAX_MATRIX_CHANNEL_MLP - : MAX_MATRIX_CHANNEL_TRUEHD; - int max_channel, min_channel, matrix_channel; + int min_channel, max_channel, max_matrix_channel; + const int std_max_matrix_channel = m->avctx->codec_id == AV_CODEC_ID_MLP + ? MAX_MATRIX_CHANNEL_MLP + : MAX_MATRIX_CHANNEL_TRUEHD; sync_word = get_bits(gbp, 13); @@ -423,18 +436,18 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, skip_bits(gbp, 16); /* Output timestamp */ - min_channel = get_bits(gbp, 4); - max_channel = get_bits(gbp, 4); - matrix_channel = get_bits(gbp, 4); + min_channel = get_bits(gbp, 4); + max_channel = get_bits(gbp, 4); + max_matrix_channel = get_bits(gbp, 4); - if (matrix_channel > max_matrix_channel) { + if (max_matrix_channel > std_max_matrix_channel) { av_log(m->avctx, AV_LOG_ERROR, "Max matrix channel cannot be greater than %d.\n", - max_matrix_channel); + std_max_matrix_channel); return AVERROR_INVALIDDATA; } - if (max_channel != matrix_channel) { + if (max_channel != max_matrix_channel) { av_log(m->avctx, AV_LOG_ERROR, "Max channel must be equal max matrix channel.\n"); return AVERROR_INVALIDDATA; @@ -456,11 +469,12 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, return AVERROR_INVALIDDATA; } - s->min_channel = min_channel; - s->max_channel = max_channel; - s->max_matrix_channel = matrix_channel; + s->min_channel = min_channel; + s->max_channel = max_channel; + s->max_matrix_channel = max_matrix_channel; #if FF_API_REQUEST_CHANNELS +FF_DISABLE_DEPRECATION_WARNINGS if (m->avctx->request_channels > 0 && m->avctx->request_channels <= s->max_channel + 1 && m->max_decoded_substream > substr) { @@ -469,6 +483,7 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, "Further substreams will be skipped.\n", s->max_channel + 1, substr); m->max_decoded_substream = substr; +FF_ENABLE_DEPRECATION_WARNINGS } else #endif if (m->avctx->request_channel_layout == s->ch_layout && @@ -635,7 +650,7 @@ static int read_filter_params(MLPDecodeContext *m, GetBitContext *gbp, /* TODO: Check validity of state data. */ for (i = 0; i < order; i++) - fp->state[i] = get_sbits(gbp, state_bits) << state_shift; + fp->state[i] = state_bits ? get_sbits(gbp, state_bits) << state_shift : 0; } } @@ -1067,7 +1082,7 @@ static int read_access_unit(AVCodecContext *avctx, void* data, int ret; if (buf_size < 4) - return 0; + return AVERROR_INVALIDDATA; length = (AV_RB16(buf) & 0xfff) * 2; @@ -1249,24 +1264,24 @@ error: #if CONFIG_MLP_DECODER AVCodec ff_mlp_decoder = { .name = "mlp", + .long_name = NULL_IF_CONFIG_SMALL("MLP (Meridian Lossless Packing)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_MLP, .priv_data_size = sizeof(MLPDecodeContext), .init = mlp_decode_init, .decode = read_access_unit, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("MLP (Meridian Lossless Packing)"), }; #endif #if CONFIG_TRUEHD_DECODER AVCodec ff_truehd_decoder = { .name = "truehd", + .long_name = NULL_IF_CONFIG_SMALL("TrueHD"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_TRUEHD, .priv_data_size = sizeof(MLPDecodeContext), .init = mlp_decode_init, .decode = read_access_unit, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("TrueHD"), }; #endif /* CONFIG_TRUEHD_DECODER */ diff --git a/ffmpeg/libavcodec/mlpdsp.c b/ffmpeg/libavcodec/mlpdsp.c index 9a376e2..b413e86 100644 --- a/ffmpeg/libavcodec/mlpdsp.c +++ b/ffmpeg/libavcodec/mlpdsp.c @@ -20,13 +20,14 @@ */ #include "config.h" +#include "libavutil/attributes.h" #include "mlpdsp.h" #include "mlp.h" -static void ff_mlp_filter_channel(int32_t *state, const int32_t *coeff, - int firorder, int iirorder, - unsigned int filter_shift, int32_t mask, int blocksize, - int32_t *sample_buffer) +static void mlp_filter_channel(int32_t *state, const int32_t *coeff, + int firorder, int iirorder, + unsigned int filter_shift, int32_t mask, + int blocksize, int32_t *sample_buffer) { int32_t *firbuf = state; int32_t *iirbuf = state + MAX_BLOCKSIZE + MAX_FIR_ORDER; @@ -56,9 +57,9 @@ static void ff_mlp_filter_channel(int32_t *state, const int32_t *coeff, } } -void ff_mlpdsp_init(MLPDSPContext *c) +av_cold void ff_mlpdsp_init(MLPDSPContext *c) { - c->mlp_filter_channel = ff_mlp_filter_channel; + c->mlp_filter_channel = mlp_filter_channel; if (ARCH_X86) ff_mlpdsp_init_x86(c); } diff --git a/ffmpeg/libavcodec/mmvideo.c b/ffmpeg/libavcodec/mmvideo.c index bf47f65..ab59b58 100644 --- a/ffmpeg/libavcodec/mmvideo.c +++ b/ffmpeg/libavcodec/mmvideo.c @@ -48,7 +48,7 @@ typedef struct MmContext { AVCodecContext *avctx; - AVFrame frame; + AVFrame *frame; int palette[AVPALETTE_COUNT]; GetByteContext gb; } MmContext; @@ -61,7 +61,9 @@ static av_cold int mm_decode_init(AVCodecContext *avctx) avctx->pix_fmt = AV_PIX_FMT_PAL8; - avcodec_get_frame_defaults(&s->frame); + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); return 0; } @@ -104,10 +106,13 @@ static int mm_decode_intra(MmContext * s, int half_horiz, int half_vert) if (half_horiz) run_length *=2; + if (run_length > s->avctx->width - x) + return AVERROR_INVALIDDATA; + if (color) { - memset(s->frame.data[0] + y*s->frame.linesize[0] + x, color, run_length); + memset(s->frame->data[0] + y*s->frame->linesize[0] + x, color, run_length); if (half_vert) - memset(s->frame.data[0] + (y+1)*s->frame.linesize[0] + x, color, run_length); + memset(s->frame->data[0] + (y+1)*s->frame->linesize[0] + x, color, run_length); } x+= run_length; @@ -126,7 +131,8 @@ static int mm_decode_intra(MmContext * s, int half_horiz, int half_vert) */ static int mm_decode_inter(MmContext * s, int half_horiz, int half_vert) { - int data_off = bytestream2_get_le16(&s->gb), y = 0; + int data_off = bytestream2_get_le16(&s->gb); + int y = 0; GetByteContext data_ptr; if (bytestream2_get_bytes_left(&s->gb) < data_off) @@ -151,15 +157,17 @@ static int mm_decode_inter(MmContext * s, int half_horiz, int half_vert) int replace_array = bytestream2_get_byte(&s->gb); for(j=0; j<8; j++) { int replace = (replace_array >> (7-j)) & 1; + if (x + half_horiz >= s->avctx->width) + return AVERROR_INVALIDDATA; if (replace) { int color = bytestream2_get_byte(&data_ptr); - s->frame.data[0][y*s->frame.linesize[0] + x] = color; + s->frame->data[0][y*s->frame->linesize[0] + x] = color; if (half_horiz) - s->frame.data[0][y*s->frame.linesize[0] + x + 1] = color; + s->frame->data[0][y*s->frame->linesize[0] + x + 1] = color; if (half_vert) { - s->frame.data[0][(y+1)*s->frame.linesize[0] + x] = color; + s->frame->data[0][(y+1)*s->frame->linesize[0] + x] = color; if (half_horiz) - s->frame.data[0][(y+1)*s->frame.linesize[0] + x + 1] = color; + s->frame->data[0][(y+1)*s->frame->linesize[0] + x + 1] = color; } } x += 1 + half_horiz; @@ -188,7 +196,7 @@ static int mm_decode_frame(AVCodecContext *avctx, buf_size -= MM_PREAMBLE_SIZE; bytestream2_init(&s->gb, buf, buf_size); - if ((res = ff_reget_buffer(avctx, &s->frame)) < 0) + if ((res = ff_reget_buffer(avctx, s->frame)) < 0) return res; switch(type) { @@ -206,9 +214,9 @@ static int mm_decode_frame(AVCodecContext *avctx, if (res < 0) return res; - memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); + memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE); - if ((res = av_frame_ref(data, &s->frame)) < 0) + if ((res = av_frame_ref(data, s->frame)) < 0) return res; *got_frame = 1; @@ -220,13 +228,14 @@ static av_cold int mm_decode_end(AVCodecContext *avctx) { MmContext *s = avctx->priv_data; - av_frame_unref(&s->frame); + av_frame_free(&s->frame); return 0; } AVCodec ff_mmvideo_decoder = { .name = "mmvideo", + .long_name = NULL_IF_CONFIG_SMALL("American Laser Games MM Video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MMVIDEO, .priv_data_size = sizeof(MmContext), @@ -234,5 +243,4 @@ AVCodec ff_mmvideo_decoder = { .close = mm_decode_end, .decode = mm_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("American Laser Games MM Video"), }; diff --git a/ffmpeg/libavcodec/motion_est.c b/ffmpeg/libavcodec/motion_est.c index dc8e39b..f4d217b 100644 --- a/ffmpeg/libavcodec/motion_est.c +++ b/ffmpeg/libavcodec/motion_est.c @@ -338,9 +338,11 @@ int ff_init_me(MpegEncContext *s){ else c->sub_motion_search= hpel_motion_search; } - c->hpel_avg= s->hdsp.avg_pixels_tab; - if(s->no_rounding) c->hpel_put= s->hdsp.put_no_rnd_pixels_tab; - else c->hpel_put= s->hdsp.put_pixels_tab; + c->hpel_avg = s->hdsp.avg_pixels_tab; + if (s->no_rounding) + c->hpel_put = s->hdsp.put_no_rnd_pixels_tab; + else + c->hpel_put = s->hdsp.put_pixels_tab; if(s->linesize){ c->stride = s->linesize; @@ -1121,8 +1123,8 @@ int ff_pre_estimate_p_frame_motion(MpegEncContext * s, return dmin; } -static int ff_estimate_motion_b(MpegEncContext * s, - int mb_x, int mb_y, int16_t (*mv_table)[2], int ref_index, int f_code) +static int estimate_motion_b(MpegEncContext *s, int mb_x, int mb_y, + int16_t (*mv_table)[2], int ref_index, int f_code) { MotionEstContext * const c= &s->me; int mx, my, dmin; @@ -1539,10 +1541,12 @@ void ff_estimate_b_frame_motion(MpegEncContext * s, dmin= INT_MAX; //FIXME penalty stuff for non mpeg4 c->skip=0; - fmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, 0, s->f_code) + 3*penalty_factor; + fmin = estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, 0, s->f_code) + + 3 * penalty_factor; c->skip=0; - bmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, 2, s->b_code) + 2*penalty_factor; + bmin = estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, 2, s->b_code) + + 2 * penalty_factor; av_dlog(s, " %d %d ", s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]); c->skip=0; diff --git a/ffmpeg/libavcodec/motionpixels.c b/ffmpeg/libavcodec/motionpixels.c index 00c1148..089909a 100644 --- a/ffmpeg/libavcodec/motionpixels.c +++ b/ffmpeg/libavcodec/motionpixels.c @@ -36,7 +36,7 @@ typedef struct HuffCode { typedef struct MotionPixelsContext { AVCodecContext *avctx; - AVFrame frame; + AVFrame *frame; DSPContext dsp; uint8_t *changes_map; int offset_bits_len; @@ -50,6 +50,19 @@ typedef struct MotionPixelsContext { int bswapbuf_size; } MotionPixelsContext; +static av_cold int mp_decode_end(AVCodecContext *avctx) +{ + MotionPixelsContext *mp = avctx->priv_data; + + av_freep(&mp->changes_map); + av_freep(&mp->vpt); + av_freep(&mp->hpt); + av_freep(&mp->bswapbuf); + av_frame_free(&mp->frame); + + return 0; +} + static av_cold int mp_decode_init(AVCodecContext *avctx) { MotionPixelsContext *mp = avctx->priv_data; @@ -68,8 +81,20 @@ static av_cold int mp_decode_init(AVCodecContext *avctx) mp->offset_bits_len = av_log2(avctx->width * avctx->height) + 1; mp->vpt = av_mallocz(avctx->height * sizeof(YuvPixel)); mp->hpt = av_mallocz(h4 * w4 / 16 * sizeof(YuvPixel)); + if (!mp->changes_map || !mp->vpt || !mp->hpt) { + av_freep(&mp->changes_map); + av_freep(&mp->vpt); + av_freep(&mp->hpt); + return AVERROR(ENOMEM); + } avctx->pix_fmt = AV_PIX_FMT_RGB555; - avcodec_get_frame_defaults(&mp->frame); + + mp->frame = av_frame_alloc(); + if (!mp->frame) { + mp_decode_end(avctx); + return AVERROR(ENOMEM); + } + return 0; } @@ -90,14 +115,14 @@ static void mp_read_changes_map(MotionPixelsContext *mp, GetBitContext *gb, int continue; w = FFMIN(w, mp->avctx->width - x); h = FFMIN(h, mp->avctx->height - y); - pixels = (uint16_t *)&mp->frame.data[0][y * mp->frame.linesize[0] + x * 2]; + pixels = (uint16_t *)&mp->frame->data[0][y * mp->frame->linesize[0] + x * 2]; while (h--) { mp->changes_map[offset] = w; if (read_color) for (i = 0; i < w; ++i) pixels[i] = color; offset += mp->avctx->width; - pixels += mp->frame.linesize[0] / 2; + pixels += mp->frame->linesize[0] / 2; } } } @@ -159,7 +184,7 @@ static YuvPixel mp_get_yuv_from_rgb(MotionPixelsContext *mp, int x, int y) { int color; - color = *(uint16_t *)&mp->frame.data[0][y * mp->frame.linesize[0] + x * 2]; + color = *(uint16_t *)&mp->frame->data[0][y * mp->frame->linesize[0] + x * 2]; return mp_rgb_yuv_table[color]; } @@ -168,7 +193,7 @@ static void mp_set_rgb_from_yuv(MotionPixelsContext *mp, int x, int y, const Yuv int color; color = mp_yuv_to_rgb(p->y, p->v, p->u, 1); - *(uint16_t *)&mp->frame.data[0][y * mp->frame.linesize[0] + x * 2] = color; + *(uint16_t *)&mp->frame->data[0][y * mp->frame->linesize[0] + x * 2] = color; } static int mp_get_vlc(MotionPixelsContext *mp, GetBitContext *gb) @@ -265,17 +290,16 @@ static int mp_decode_frame(AVCodecContext *avctx, GetBitContext gb; int i, count1, count2, sz, ret; - if ((ret = ff_reget_buffer(avctx, &mp->frame)) < 0) + if ((ret = ff_reget_buffer(avctx, mp->frame)) < 0) return ret; /* le32 bitstream msb first */ - av_fast_malloc(&mp->bswapbuf, &mp->bswapbuf_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + av_fast_padded_malloc(&mp->bswapbuf, &mp->bswapbuf_size, buf_size); if (!mp->bswapbuf) return AVERROR(ENOMEM); mp->dsp.bswap_buf((uint32_t *)mp->bswapbuf, (const uint32_t *)buf, buf_size / 4); if (buf_size & 3) memcpy(mp->bswapbuf + (buf_size & ~3), buf + (buf_size & ~3), buf_size & 3); - memset(mp->bswapbuf + buf_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); init_get_bits(&gb, mp->bswapbuf, buf_size * 8); memset(mp->changes_map, 0, avctx->width * avctx->height); @@ -291,7 +315,7 @@ static int mp_decode_frame(AVCodecContext *avctx, goto end; if (mp->changes_map[0] == 0) { - *(uint16_t *)mp->frame.data[0] = get_bits(&gb, 15); + *(uint16_t *)mp->frame->data[0] = get_bits(&gb, 15); mp->changes_map[0] = 1; } if (mp_read_codes_table(mp, &gb) < 0) @@ -311,27 +335,15 @@ static int mp_decode_frame(AVCodecContext *avctx, ff_free_vlc(&mp->vlc); end: - if ((ret = av_frame_ref(data, &mp->frame)) < 0) + if ((ret = av_frame_ref(data, mp->frame)) < 0) return ret; *got_frame = 1; return buf_size; } -static av_cold int mp_decode_end(AVCodecContext *avctx) -{ - MotionPixelsContext *mp = avctx->priv_data; - - av_freep(&mp->changes_map); - av_freep(&mp->vpt); - av_freep(&mp->hpt); - av_freep(&mp->bswapbuf); - av_frame_unref(&mp->frame); - - return 0; -} - AVCodec ff_motionpixels_decoder = { .name = "motionpixels", + .long_name = NULL_IF_CONFIG_SMALL("Motion Pixels video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MOTIONPIXELS, .priv_data_size = sizeof(MotionPixelsContext), @@ -339,5 +351,4 @@ AVCodec ff_motionpixels_decoder = { .close = mp_decode_end, .decode = mp_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Motion Pixels video"), }; diff --git a/ffmpeg/libavcodec/movsub_bsf.c b/ffmpeg/libavcodec/movsub_bsf.c index a745190..123c7a5 100644 --- a/ffmpeg/libavcodec/movsub_bsf.c +++ b/ffmpeg/libavcodec/movsub_bsf.c @@ -35,9 +35,8 @@ static int text2movsub(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, co } AVBitStreamFilter ff_text2movsub_bsf={ - "text2movsub", - 0, - text2movsub, + .name = "text2movsub", + .filter = text2movsub, }; static int mov2textsub(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, @@ -51,7 +50,6 @@ static int mov2textsub(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, co } AVBitStreamFilter ff_mov2textsub_bsf={ - "mov2textsub", - 0, - mov2textsub, + .name = "mov2textsub", + .filter = mov2textsub, }; diff --git a/ffmpeg/libavcodec/mp3_header_compress_bsf.c b/ffmpeg/libavcodec/mp3_header_compress_bsf.c deleted file mode 100644 index 3c5e2fb..0000000 --- a/ffmpeg/libavcodec/mp3_header_compress_bsf.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/common.h" -#include "libavutil/intreadwrite.h" -#include "avcodec.h" -#include "mpegaudiodecheader.h" - - -static int mp3_header_compress(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe){ - uint32_t header, extraheader; - int mode_extension, header_size; - - if(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){ - av_log(avctx, AV_LOG_ERROR, "not standards compliant\n"); - return -1; - } - - header = AV_RB32(buf); - mode_extension= (header>>4)&3; - - if(ff_mpa_check_header(header) < 0 || (header&0x60000) != 0x20000){ -output_unchanged: - *poutbuf= (uint8_t *) buf; - *poutbuf_size= buf_size; - - av_log(avctx, AV_LOG_INFO, "cannot compress %08X\n", header); - return 0; - } - - if(avctx->extradata_size == 0){ - avctx->extradata_size=15; - avctx->extradata= av_malloc(avctx->extradata_size); - strcpy(avctx->extradata, "FFCMP3 0.0"); - memcpy(avctx->extradata+11, buf, 4); - } - if(avctx->extradata_size != 15){ - av_log(avctx, AV_LOG_ERROR, "Extradata invalid\n"); - return -1; - } - extraheader = AV_RB32(avctx->extradata+11); - if((extraheader&MP3_MASK) != (header&MP3_MASK)) - goto output_unchanged; - - header_size= (header&0x10000) ? 4 : 6; - - *poutbuf_size= buf_size - header_size; - *poutbuf= av_malloc(buf_size - header_size + FF_INPUT_BUFFER_PADDING_SIZE); - memcpy(*poutbuf, buf + header_size, buf_size - header_size + FF_INPUT_BUFFER_PADDING_SIZE); - - if(avctx->channels==2){ - if((header & (3<<19)) != 3<<19){ - (*poutbuf)[1] &= 0x3F; - (*poutbuf)[1] |= mode_extension<<6; - FFSWAP(int, (*poutbuf)[1], (*poutbuf)[2]); - }else{ - (*poutbuf)[1] &= 0x8F; - (*poutbuf)[1] |= mode_extension<<4; - } - } - - return 1; -} - -AVBitStreamFilter ff_mp3_header_compress_bsf={ - "mp3comp", - 0, - mp3_header_compress, -}; diff --git a/ffmpeg/libavcodec/mp3_header_decompress_bsf.c b/ffmpeg/libavcodec/mp3_header_decompress_bsf.c index adf5a7f..df45532 100644 --- a/ffmpeg/libavcodec/mp3_header_decompress_bsf.c +++ b/ffmpeg/libavcodec/mp3_header_decompress_bsf.c @@ -92,7 +92,6 @@ static int mp3_header_decompress(AVBitStreamFilterContext *bsfc, AVCodecContext } AVBitStreamFilter ff_mp3_header_decompress_bsf={ - "mp3decomp", - 0, - mp3_header_decompress, + .name = "mp3decomp", + .filter = mp3_header_decompress, }; diff --git a/ffmpeg/libavcodec/mpc.c b/ffmpeg/libavcodec/mpc.c index 3bd2d35..7af30bd 100644 --- a/ffmpeg/libavcodec/mpc.c +++ b/ffmpeg/libavcodec/mpc.c @@ -26,6 +26,7 @@ * divided into 32 subbands. */ +#include "libavutil/attributes.h" #include "avcodec.h" #include "get_bits.h" #include "mpegaudiodsp.h" @@ -34,7 +35,7 @@ #include "mpc.h" #include "mpcdata.h" -void ff_mpc_init(void) +av_cold void ff_mpc_init(void) { ff_mpa_synth_init_fixed(ff_mpa_synth_window_fixed); } diff --git a/ffmpeg/libavcodec/mpc7.c b/ffmpeg/libavcodec/mpc7.c index 85d4e09..86aca63 100644 --- a/ffmpeg/libavcodec/mpc7.c +++ b/ffmpeg/libavcodec/mpc7.c @@ -329,6 +329,7 @@ static av_cold int mpc7_decode_close(AVCodecContext *avctx) AVCodec ff_mpc7_decoder = { .name = "mpc7", + .long_name = NULL_IF_CONFIG_SMALL("Musepack SV7"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_MUSEPACK7, .priv_data_size = sizeof(MPCContext), @@ -337,7 +338,6 @@ AVCodec ff_mpc7_decoder = { .decode = mpc7_decode_frame, .flush = mpc7_decode_flush, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Musepack SV7"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_NONE }, }; diff --git a/ffmpeg/libavcodec/mpc8.c b/ffmpeg/libavcodec/mpc8.c index 4d6ca89..2f58805 100644 --- a/ffmpeg/libavcodec/mpc8.c +++ b/ffmpeg/libavcodec/mpc8.c @@ -435,6 +435,7 @@ static av_cold void mpc8_decode_flush(AVCodecContext *avctx) AVCodec ff_mpc8_decoder = { .name = "mpc8", + .long_name = NULL_IF_CONFIG_SMALL("Musepack SV8"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_MUSEPACK8, .priv_data_size = sizeof(MPCContext), @@ -442,7 +443,6 @@ AVCodec ff_mpc8_decoder = { .decode = mpc8_decode_frame, .flush = mpc8_decode_flush, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Musepack SV8"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_NONE }, }; diff --git a/ffmpeg/libavcodec/mpeg12.c b/ffmpeg/libavcodec/mpeg12.c index ebabd73..09b1f19 100644 --- a/ffmpeg/libavcodec/mpeg12.c +++ b/ffmpeg/libavcodec/mpeg12.c @@ -27,7 +27,7 @@ #define UNCHECKED_BITSTREAM_READER 1 -//#define DEBUG +#include "libavutil/attributes.h" #include "libavutil/avassert.h" #include "libavutil/timecode.h" @@ -38,576 +38,35 @@ #include "error_resilience.h" #include "mpeg12.h" #include "mpeg12data.h" -#include "mpeg12decdata.h" #include "bytestream.h" #include "vdpau_internal.h" -#include "xvmc_internal.h" #include "thread.h" +uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; -#define MV_VLC_BITS 9 -#define MBINCR_VLC_BITS 9 -#define MB_PAT_VLC_BITS 9 -#define MB_PTYPE_VLC_BITS 6 -#define MB_BTYPE_VLC_BITS 6 - -static VLC mv_vlc; - -/* as H.263, but only 17 codes */ -static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred) -{ - int code, sign, val, shift; - - code = get_vlc2(&s->gb, mv_vlc.table, MV_VLC_BITS, 2); - if (code == 0) { - return pred; - } - if (code < 0) { - return 0xffff; - } - - sign = get_bits1(&s->gb); - shift = fcode - 1; - val = code; - if (shift) { - val = (val - 1) << shift; - val |= get_bits(&s->gb, shift); - val++; - } - if (sign) - val = -val; - val += pred; - - /* modulo decoding */ - return sign_extend(val, 5 + shift); -} - -static inline int mpeg1_decode_block_intra(MpegEncContext *s, int16_t *block, int n) -{ - int level, dc, diff, i, j, run; - int component; - RLTable *rl = &ff_rl_mpeg1; - uint8_t * const scantable = s->intra_scantable.permutated; - const uint16_t *quant_matrix = s->intra_matrix; - const int qscale = s->qscale; - - /* DC coefficient */ - component = (n <= 3 ? 0 : n - 4 + 1); - diff = decode_dc(&s->gb, component); - if (diff >= 0xffff) - return -1; - dc = s->last_dc[component]; - dc += diff; - s->last_dc[component] = dc; - block[0] = dc * quant_matrix[0]; - av_dlog(s->avctx, "dc=%d diff=%d\n", dc, diff); - i = 0; - { - OPEN_READER(re, &s->gb); - /* now quantify & encode AC coefficients */ - for (;;) { - UPDATE_CACHE(re, &s->gb); - GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0); - - if (level == 127) { - break; - } else if (level != 0) { - i += run; - j = scantable[i]; - level = (level * qscale * quant_matrix[j]) >> 4; - level = (level - 1) | 1; - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - LAST_SKIP_BITS(re, &s->gb, 1); - } else { - /* escape */ - run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6); - UPDATE_CACHE(re, &s->gb); - level = SHOW_SBITS(re, &s->gb, 8); SKIP_BITS(re, &s->gb, 8); - if (level == -128) { - level = SHOW_UBITS(re, &s->gb, 8) - 256; LAST_SKIP_BITS(re, &s->gb, 8); - } else if (level == 0) { - level = SHOW_UBITS(re, &s->gb, 8) ; LAST_SKIP_BITS(re, &s->gb, 8); - } - i += run; - j = scantable[i]; - if (level < 0) { - level = -level; - level = (level * qscale * quant_matrix[j]) >> 4; - level = (level - 1) | 1; - level = -level; - } else { - level = (level * qscale * quant_matrix[j]) >> 4; - level = (level - 1) | 1; - } - } - if (i > 63) { - av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - - block[j] = level; - } - CLOSE_READER(re, &s->gb); - } - s->block_last_index[n] = i; - return 0; -} - -int ff_mpeg1_decode_block_intra(MpegEncContext *s, int16_t *block, int n) -{ - return mpeg1_decode_block_intra(s, block, n); -} - -static inline int mpeg1_decode_block_inter(MpegEncContext *s, int16_t *block, int n) -{ - int level, i, j, run; - RLTable *rl = &ff_rl_mpeg1; - uint8_t * const scantable = s->intra_scantable.permutated; - const uint16_t *quant_matrix = s->inter_matrix; - const int qscale = s->qscale; - - { - OPEN_READER(re, &s->gb); - i = -1; - // special case for first coefficient, no need to add second VLC table - UPDATE_CACHE(re, &s->gb); - if (((int32_t)GET_CACHE(re, &s->gb)) < 0) { - level = (3 * qscale * quant_matrix[0]) >> 5; - level = (level - 1) | 1; - if (GET_CACHE(re, &s->gb) & 0x40000000) - level = -level; - block[0] = level; - i++; - SKIP_BITS(re, &s->gb, 2); - if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) - goto end; - } - /* now quantify & encode AC coefficients */ - for (;;) { - GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0); - - if (level != 0) { - i += run; - j = scantable[i]; - level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5; - level = (level - 1) | 1; - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - SKIP_BITS(re, &s->gb, 1); - } else { - /* escape */ - run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6); - UPDATE_CACHE(re, &s->gb); - level = SHOW_SBITS(re, &s->gb, 8); SKIP_BITS(re, &s->gb, 8); - if (level == -128) { - level = SHOW_UBITS(re, &s->gb, 8) - 256; SKIP_BITS(re, &s->gb, 8); - } else if (level == 0) { - level = SHOW_UBITS(re, &s->gb, 8) ; SKIP_BITS(re, &s->gb, 8); - } - i += run; - j = scantable[i]; - if (level < 0) { - level = -level; - level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5; - level = (level - 1) | 1; - level = -level; - } else { - level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5; - level = (level - 1) | 1; - } - } - if (i > 63) { - av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - - block[j] = level; - if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) - break; - UPDATE_CACHE(re, &s->gb); - } -end: - LAST_SKIP_BITS(re, &s->gb, 2); - CLOSE_READER(re, &s->gb); - } - s->block_last_index[n] = i; - return 0; -} - -/** - * Note: this function can read out of range and crash for corrupt streams. - * Changing this would eat up any speed benefits it has. - * Do not use "fast" flag if you need the code to be robust. - */ -static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, int16_t *block, int n) -{ - int level, i, j, run; - RLTable *rl = &ff_rl_mpeg1; - uint8_t * const scantable = s->intra_scantable.permutated; - const int qscale = s->qscale; - - { - OPEN_READER(re, &s->gb); - i = -1; - // special case for first coefficient, no need to add second VLC table - UPDATE_CACHE(re, &s->gb); - if (((int32_t)GET_CACHE(re, &s->gb)) < 0) { - level = (3 * qscale) >> 1; - level = (level - 1) | 1; - if (GET_CACHE(re, &s->gb) & 0x40000000) - level = -level; - block[0] = level; - i++; - SKIP_BITS(re, &s->gb, 2); - if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) - goto end; - } - - /* now quantify & encode AC coefficients */ - for (;;) { - GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0); - - if (level != 0) { - i += run; - j = scantable[i]; - level = ((level * 2 + 1) * qscale) >> 1; - level = (level - 1) | 1; - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - SKIP_BITS(re, &s->gb, 1); - } else { - /* escape */ - run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6); - UPDATE_CACHE(re, &s->gb); - level = SHOW_SBITS(re, &s->gb, 8); SKIP_BITS(re, &s->gb, 8); - if (level == -128) { - level = SHOW_UBITS(re, &s->gb, 8) - 256; SKIP_BITS(re, &s->gb, 8); - } else if (level == 0) { - level = SHOW_UBITS(re, &s->gb, 8) ; SKIP_BITS(re, &s->gb, 8); - } - i += run; - j = scantable[i]; - if (level < 0) { - level = -level; - level = ((level * 2 + 1) * qscale) >> 1; - level = (level - 1) | 1; - level = -level; - } else { - level = ((level * 2 + 1) * qscale) >> 1; - level = (level - 1) | 1; - } - } - - block[j] = level; - if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) - break; - UPDATE_CACHE(re, &s->gb); - } -end: - LAST_SKIP_BITS(re, &s->gb, 2); - CLOSE_READER(re, &s->gb); - } - s->block_last_index[n] = i; - return 0; -} - - -static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, int16_t *block, int n) -{ - int level, i, j, run; - RLTable *rl = &ff_rl_mpeg1; - uint8_t * const scantable = s->intra_scantable.permutated; - const uint16_t *quant_matrix; - const int qscale = s->qscale; - int mismatch; - - mismatch = 1; - - { - OPEN_READER(re, &s->gb); - i = -1; - if (n < 4) - quant_matrix = s->inter_matrix; - else - quant_matrix = s->chroma_inter_matrix; - - // special case for first coefficient, no need to add second VLC table - UPDATE_CACHE(re, &s->gb); - if (((int32_t)GET_CACHE(re, &s->gb)) < 0) { - level= (3 * qscale * quant_matrix[0]) >> 5; - if (GET_CACHE(re, &s->gb) & 0x40000000) - level = -level; - block[0] = level; - mismatch ^= level; - i++; - SKIP_BITS(re, &s->gb, 2); - if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) - goto end; - } - - /* now quantify & encode AC coefficients */ - for (;;) { - GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0); - - if (level != 0) { - i += run; - j = scantable[i]; - level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5; - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - SKIP_BITS(re, &s->gb, 1); - } else { - /* escape */ - run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6); - UPDATE_CACHE(re, &s->gb); - level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12); - - i += run; - j = scantable[i]; - if (level < 0) { - level = ((-level * 2 + 1) * qscale * quant_matrix[j]) >> 5; - level = -level; - } else { - level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5; - } - } - if (i > 63) { - av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - - mismatch ^= level; - block[j] = level; - if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) - break; - UPDATE_CACHE(re, &s->gb); - } -end: - LAST_SKIP_BITS(re, &s->gb, 2); - CLOSE_READER(re, &s->gb); - } - block[63] ^= (mismatch & 1); - - s->block_last_index[n] = i; - return 0; -} - -/** - * Note: this function can read out of range and crash for corrupt streams. - * Changing this would eat up any speed benefits it has. - * Do not use "fast" flag if you need the code to be robust. - */ -static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s, - int16_t *block, int n) -{ - int level, i, j, run; - RLTable *rl = &ff_rl_mpeg1; - uint8_t * const scantable = s->intra_scantable.permutated; - const int qscale = s->qscale; - OPEN_READER(re, &s->gb); - i = -1; - - // special case for first coefficient, no need to add second VLC table - UPDATE_CACHE(re, &s->gb); - if (((int32_t)GET_CACHE(re, &s->gb)) < 0) { - level = (3 * qscale) >> 1; - if (GET_CACHE(re, &s->gb) & 0x40000000) - level = -level; - block[0] = level; - i++; - SKIP_BITS(re, &s->gb, 2); - if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) - goto end; - } - - /* now quantify & encode AC coefficients */ - for (;;) { - GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0); - - if (level != 0) { - i += run; - j = scantable[i]; - level = ((level * 2 + 1) * qscale) >> 1; - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - SKIP_BITS(re, &s->gb, 1); - } else { - /* escape */ - run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6); - UPDATE_CACHE(re, &s->gb); - level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12); - - i += run; - j = scantable[i]; - if (level < 0) { - level = ((-level * 2 + 1) * qscale) >> 1; - level = -level; - } else { - level = ((level * 2 + 1) * qscale) >> 1; - } - } - - block[j] = level; - if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) - break; - UPDATE_CACHE(re, &s->gb); - } -end: - LAST_SKIP_BITS(re, &s->gb, 2); - CLOSE_READER(re, &s->gb); - s->block_last_index[n] = i; - return 0; -} - - -static inline int mpeg2_decode_block_intra(MpegEncContext *s, int16_t *block, int n) -{ - int level, dc, diff, i, j, run; - int component; - RLTable *rl; - uint8_t * const scantable = s->intra_scantable.permutated; - const uint16_t *quant_matrix; - const int qscale = s->qscale; - int mismatch; - - /* DC coefficient */ - if (n < 4) { - quant_matrix = s->intra_matrix; - component = 0; - } else { - quant_matrix = s->chroma_intra_matrix; - component = (n & 1) + 1; - } - diff = decode_dc(&s->gb, component); - if (diff >= 0xffff) - return -1; - dc = s->last_dc[component]; - dc += diff; - s->last_dc[component] = dc; - block[0] = dc << (3 - s->intra_dc_precision); - av_dlog(s->avctx, "dc=%d\n", block[0]); - mismatch = block[0] ^ 1; - i = 0; - if (s->intra_vlc_format) - rl = &ff_rl_mpeg2; - else - rl = &ff_rl_mpeg1; - - { - OPEN_READER(re, &s->gb); - /* now quantify & encode AC coefficients */ - for (;;) { - UPDATE_CACHE(re, &s->gb); - GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0); - - if (level == 127) { - break; - } else if (level != 0) { - i += run; - j = scantable[i]; - level = (level * qscale * quant_matrix[j]) >> 4; - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - LAST_SKIP_BITS(re, &s->gb, 1); - } else { - /* escape */ - run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6); - UPDATE_CACHE(re, &s->gb); - level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12); - i += run; - j = scantable[i]; - if (level < 0) { - level = (-level * qscale * quant_matrix[j]) >> 4; - level = -level; - } else { - level = (level * qscale * quant_matrix[j]) >> 4; - } - } - if (i > 63) { - av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - - mismatch ^= level; - block[j] = level; - } - CLOSE_READER(re, &s->gb); - } - block[63] ^= mismatch & 1; - - s->block_last_index[n] = i; - return 0; -} - -/** - * Note: this function can read out of range and crash for corrupt streams. - * Changing this would eat up any speed benefits it has. - * Do not use "fast" flag if you need the code to be robust. - */ -static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, int16_t *block, int n) -{ - int level, dc, diff, j, run; - int component; - RLTable *rl; - uint8_t * scantable = s->intra_scantable.permutated; - const uint16_t *quant_matrix; - const int qscale = s->qscale; - - /* DC coefficient */ - if (n < 4) { - quant_matrix = s->intra_matrix; - component = 0; - } else { - quant_matrix = s->chroma_intra_matrix; - component = (n & 1) + 1; - } - diff = decode_dc(&s->gb, component); - if (diff >= 0xffff) - return -1; - dc = s->last_dc[component]; - dc += diff; - s->last_dc[component] = dc; - block[0] = dc << (3 - s->intra_dc_precision); - if (s->intra_vlc_format) - rl = &ff_rl_mpeg2; - else - rl = &ff_rl_mpeg1; - - { - OPEN_READER(re, &s->gb); - /* now quantify & encode AC coefficients */ - for (;;) { - UPDATE_CACHE(re, &s->gb); - GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0); - - if (level == 127) { - break; - } else if (level != 0) { - scantable += run; - j = *scantable; - level = (level * qscale * quant_matrix[j]) >> 4; - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - LAST_SKIP_BITS(re, &s->gb, 1); - } else { - /* escape */ - run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6); - UPDATE_CACHE(re, &s->gb); - level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12); - scantable += run; - j = *scantable; - if (level < 0) { - level = (-level * qscale * quant_matrix[j]) >> 4; - level = -level; - } else { - level = (level * qscale * quant_matrix[j]) >> 4; - } - } - - block[j] = level; - } - CLOSE_READER(re, &s->gb); - } - - s->block_last_index[n] = scantable - s->intra_scantable.permutated; - return 0; -} +static const uint8_t table_mb_ptype[7][2] = { + { 3, 5 }, // 0x01 MB_INTRA + { 1, 2 }, // 0x02 MB_PAT + { 1, 3 }, // 0x08 MB_FOR + { 1, 1 }, // 0x0A MB_FOR|MB_PAT + { 1, 6 }, // 0x11 MB_QUANT|MB_INTRA + { 1, 5 }, // 0x12 MB_QUANT|MB_PAT + { 2, 5 }, // 0x1A MB_QUANT|MB_FOR|MB_PAT +}; -uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; +static const uint8_t table_mb_btype[11][2] = { + { 3, 5 }, // 0x01 MB_INTRA + { 2, 3 }, // 0x04 MB_BACK + { 3, 3 }, // 0x06 MB_BACK|MB_PAT + { 2, 4 }, // 0x08 MB_FOR + { 3, 4 }, // 0x0A MB_FOR|MB_PAT + { 2, 2 }, // 0x0C MB_FOR|MB_BACK + { 3, 2 }, // 0x0E MB_FOR|MB_BACK|MB_PAT + { 1, 6 }, // 0x11 MB_QUANT|MB_INTRA + { 2, 6 }, // 0x16 MB_QUANT|MB_BACK|MB_PAT + { 3, 6 }, // 0x1A MB_QUANT|MB_FOR|MB_PAT + { 2, 5 }, // 0x1E MB_QUANT|MB_FOR|MB_BACK|MB_PAT +}; #define INIT_2D_VLC_RL(rl, static_size)\ {\ @@ -620,7 +79,7 @@ uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; init_2d_vlc_rl(&rl);\ } -static void init_2d_vlc_rl(RLTable *rl) +static av_cold void init_2d_vlc_rl(RLTable *rl) { int i; @@ -653,7 +112,7 @@ static void init_2d_vlc_rl(RLTable *rl) } } -void ff_mpeg12_common_init(MpegEncContext *s) +av_cold void ff_mpeg12_common_init(MpegEncContext *s) { s->y_dc_scale_table = @@ -673,13 +132,15 @@ void ff_mpeg1_clean_buffers(MpegEncContext *s) /******************************************/ /* decoding */ +VLC ff_mv_vlc; + VLC ff_dc_lum_vlc; VLC ff_dc_chroma_vlc; -static VLC mbincr_vlc; -static VLC mb_ptype_vlc; -static VLC mb_btype_vlc; -static VLC mb_pat_vlc; +VLC ff_mbincr_vlc; +VLC ff_mb_ptype_vlc; +VLC ff_mb_btype_vlc; +VLC ff_mb_pat_vlc; av_cold void ff_mpeg12_init_vlcs(void) { @@ -694,20 +155,20 @@ av_cold void ff_mpeg12_init_vlcs(void) INIT_VLC_STATIC(&ff_dc_chroma_vlc, DC_VLC_BITS, 12, ff_mpeg12_vlc_dc_chroma_bits, 1, 1, ff_mpeg12_vlc_dc_chroma_code, 2, 2, 514); - INIT_VLC_STATIC(&mv_vlc, MV_VLC_BITS, 17, + INIT_VLC_STATIC(&ff_mv_vlc, MV_VLC_BITS, 17, &ff_mpeg12_mbMotionVectorTable[0][1], 2, 1, &ff_mpeg12_mbMotionVectorTable[0][0], 2, 1, 518); - INIT_VLC_STATIC(&mbincr_vlc, MBINCR_VLC_BITS, 36, + INIT_VLC_STATIC(&ff_mbincr_vlc, MBINCR_VLC_BITS, 36, &ff_mpeg12_mbAddrIncrTable[0][1], 2, 1, &ff_mpeg12_mbAddrIncrTable[0][0], 2, 1, 538); - INIT_VLC_STATIC(&mb_pat_vlc, MB_PAT_VLC_BITS, 64, + INIT_VLC_STATIC(&ff_mb_pat_vlc, MB_PAT_VLC_BITS, 64, &ff_mpeg12_mbPatTable[0][1], 2, 1, &ff_mpeg12_mbPatTable[0][0], 2, 1, 512); - INIT_VLC_STATIC(&mb_ptype_vlc, MB_PTYPE_VLC_BITS, 7, + INIT_VLC_STATIC(&ff_mb_ptype_vlc, MB_PTYPE_VLC_BITS, 7, &table_mb_ptype[0][1], 2, 1, &table_mb_ptype[0][0], 2, 1, 64); - INIT_VLC_STATIC(&mb_btype_vlc, MB_BTYPE_VLC_BITS, 11, + INIT_VLC_STATIC(&ff_mb_btype_vlc, MB_BTYPE_VLC_BITS, 11, &table_mb_btype[0][1], 2, 1, &table_mb_btype[0][0], 2, 1, 64); ff_init_rl(&ff_rl_mpeg1, ff_mpeg12_static_rl_table_store[0]); @@ -718,2057 +179,67 @@ av_cold void ff_mpeg12_init_vlcs(void) } } -static inline int get_dmv(MpegEncContext *s) -{ - if (get_bits1(&s->gb)) - return 1 - (get_bits1(&s->gb) << 1); - else - return 0; -} - -static inline int get_qscale(MpegEncContext *s) -{ - int qscale = get_bits(&s->gb, 5); - if (s->q_scale_type) { - return non_linear_qscale[qscale]; - } else { - return qscale << 1; - } -} - -static void exchange_uv(MpegEncContext *s) -{ - int16_t (*tmp)[64]; - - tmp = s->pblocks[4]; - s->pblocks[4] = s->pblocks[5]; - s->pblocks[5] = tmp; -} - -/* motion type (for MPEG-2) */ -#define MT_FIELD 1 -#define MT_FRAME 2 -#define MT_16X8 2 -#define MT_DMV 3 - -static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64]) +/** + * Find the end of the current frame in the bitstream. + * @return the position of the first byte of the next frame, or -1 + */ +int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, AVCodecParserContext *s) { - int i, j, k, cbp, val, mb_type, motion_type; - const int mb_block_count = 4 + (1 << s->chroma_format); - - av_dlog(s->avctx, "decode_mb: x=%d y=%d\n", s->mb_x, s->mb_y); - - av_assert2(s->mb_skipped == 0); - - if (s->mb_skip_run-- != 0) { - if (s->pict_type == AV_PICTURE_TYPE_P) { - s->mb_skipped = 1; - s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride] = MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16; - } else { - int mb_type; - - if (s->mb_x) - mb_type = s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1]; - else - mb_type = s->current_picture.mb_type[s->mb_width + (s->mb_y - 1) * s->mb_stride - 1]; // FIXME not sure if this is allowed in MPEG at all - if (IS_INTRA(mb_type)) { - av_log(s->avctx, AV_LOG_ERROR, "skip with previntra\n"); - return -1; - } - s->current_picture.mb_type[s->mb_x + s->mb_y*s->mb_stride] = - mb_type | MB_TYPE_SKIP; - -// assert(s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1] & (MB_TYPE_16x16 | MB_TYPE_16x8)); - - if ((s->mv[0][0][0] | s->mv[0][0][1] | s->mv[1][0][0] | s->mv[1][0][1]) == 0) - s->mb_skipped = 1; - } + int i; + uint32_t state = pc->state; + /* EOF considered as end of frame */ + if (buf_size == 0) return 0; - } - switch (s->pict_type) { - default: - case AV_PICTURE_TYPE_I: - if (get_bits1(&s->gb) == 0) { - if (get_bits1(&s->gb) == 0) { - av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in I Frame at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - mb_type = MB_TYPE_QUANT | MB_TYPE_INTRA; - } else { - mb_type = MB_TYPE_INTRA; - } - break; - case AV_PICTURE_TYPE_P: - mb_type = get_vlc2(&s->gb, mb_ptype_vlc.table, MB_PTYPE_VLC_BITS, 1); - if (mb_type < 0) { - av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in P Frame at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - mb_type = ptype2mb_type[mb_type]; - break; - case AV_PICTURE_TYPE_B: - mb_type = get_vlc2(&s->gb, mb_btype_vlc.table, MB_BTYPE_VLC_BITS, 1); - if (mb_type < 0) { - av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in B Frame at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - mb_type = btype2mb_type[mb_type]; - break; - } - av_dlog(s->avctx, "mb_type=%x\n", mb_type); -// motion_type = 0; /* avoid warning */ - if (IS_INTRA(mb_type)) { - s->dsp.clear_blocks(s->block[0]); - - if (!s->chroma_y_shift) { - s->dsp.clear_blocks(s->block[6]); - } - - /* compute DCT type */ - if (s->picture_structure == PICT_FRAME && // FIXME add an interlaced_dct coded var? - !s->frame_pred_frame_dct) { - s->interlaced_dct = get_bits1(&s->gb); - } - - if (IS_QUANT(mb_type)) - s->qscale = get_qscale(s); - - if (s->concealment_motion_vectors) { - /* just parse them */ - if (s->picture_structure != PICT_FRAME) - skip_bits1(&s->gb); /* field select */ - - s->mv[0][0][0]= s->last_mv[0][0][0]= s->last_mv[0][1][0] = - mpeg_decode_motion(s, s->mpeg_f_code[0][0], s->last_mv[0][0][0]); - s->mv[0][0][1]= s->last_mv[0][0][1]= s->last_mv[0][1][1] = - mpeg_decode_motion(s, s->mpeg_f_code[0][1], s->last_mv[0][0][1]); - - skip_bits1(&s->gb); /* marker */ - } else - memset(s->last_mv, 0, sizeof(s->last_mv)); /* reset mv prediction */ - s->mb_intra = 1; - // if 1, we memcpy blocks in xvmcvideo - if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1) { - ff_xvmc_pack_pblocks(s, -1); // inter are always full blocks - if (s->swap_uv) { - exchange_uv(s); - } - } - - if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO) { - if (s->flags2 & CODEC_FLAG2_FAST) { - for (i = 0; i < 6; i++) { - mpeg2_fast_decode_block_intra(s, *s->pblocks[i], i); - } - } else { - for (i = 0; i < mb_block_count; i++) { - if (mpeg2_decode_block_intra(s, *s->pblocks[i], i) < 0) - return -1; - } - } - } else { - for (i = 0; i < 6; i++) { - if (mpeg1_decode_block_intra(s, *s->pblocks[i], i) < 0) - return -1; - } - } - } else { - if (mb_type & MB_TYPE_ZERO_MV) { - av_assert2(mb_type & MB_TYPE_CBP); +/* + 0 frame start -> 1/4 + 1 first_SEQEXT -> 0/2 + 2 first field start -> 3/0 + 3 second_SEQEXT -> 2/0 + 4 searching end +*/ - s->mv_dir = MV_DIR_FORWARD; - if (s->picture_structure == PICT_FRAME) { - if (s->picture_structure == PICT_FRAME - && !s->frame_pred_frame_dct) - s->interlaced_dct = get_bits1(&s->gb); - s->mv_type = MV_TYPE_16X16; - } else { - s->mv_type = MV_TYPE_FIELD; - mb_type |= MB_TYPE_INTERLACED; - s->field_select[0][0] = s->picture_structure - 1; + for (i = 0; i < buf_size; i++) { + av_assert1(pc->frame_start_found >= 0 && pc->frame_start_found <= 4); + if (pc->frame_start_found & 1) { + if (state == EXT_START_CODE && (buf[i] & 0xF0) != 0x80) + pc->frame_start_found--; + else if (state == EXT_START_CODE + 2) { + if ((buf[i] & 3) == 3) + pc->frame_start_found = 0; + else + pc->frame_start_found = (pc->frame_start_found + 1) & 3; } - - if (IS_QUANT(mb_type)) - s->qscale = get_qscale(s); - - s->last_mv[0][0][0] = 0; - s->last_mv[0][0][1] = 0; - s->last_mv[0][1][0] = 0; - s->last_mv[0][1][1] = 0; - s->mv[0][0][0] = 0; - s->mv[0][0][1] = 0; + state++; } else { - av_assert2(mb_type & MB_TYPE_L0L1); - // FIXME decide if MBs in field pictures are MB_TYPE_INTERLACED - /* get additional motion vector type */ - if (s->picture_structure == PICT_FRAME && s->frame_pred_frame_dct) - motion_type = MT_FRAME; - else { - motion_type = get_bits(&s->gb, 2); - if (s->picture_structure == PICT_FRAME && HAS_CBP(mb_type)) - s->interlaced_dct = get_bits1(&s->gb); - } - - if (IS_QUANT(mb_type)) - s->qscale = get_qscale(s); - - /* motion vectors */ - s->mv_dir = (mb_type >> 13) & 3; - av_dlog(s->avctx, "motion_type=%d\n", motion_type); - switch (motion_type) { - case MT_FRAME: /* or MT_16X8 */ - if (s->picture_structure == PICT_FRAME) { - mb_type |= MB_TYPE_16x16; - s->mv_type = MV_TYPE_16X16; - for (i = 0; i < 2; i++) { - if (USES_LIST(mb_type, i)) { - /* MT_FRAME */ - s->mv[i][0][0]= s->last_mv[i][0][0]= s->last_mv[i][1][0] = - mpeg_decode_motion(s, s->mpeg_f_code[i][0], s->last_mv[i][0][0]); - s->mv[i][0][1]= s->last_mv[i][0][1]= s->last_mv[i][1][1] = - mpeg_decode_motion(s, s->mpeg_f_code[i][1], s->last_mv[i][0][1]); - /* full_pel: only for MPEG-1 */ - if (s->full_pel[i]) { - s->mv[i][0][0] <<= 1; - s->mv[i][0][1] <<= 1; - } - } - } - } else { - mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED; - s->mv_type = MV_TYPE_16X8; - for (i = 0; i < 2; i++) { - if (USES_LIST(mb_type, i)) { - /* MT_16X8 */ - for (j = 0; j < 2; j++) { - s->field_select[i][j] = get_bits1(&s->gb); - for (k = 0; k < 2; k++) { - val = mpeg_decode_motion(s, s->mpeg_f_code[i][k], - s->last_mv[i][j][k]); - s->last_mv[i][j][k] = val; - s->mv[i][j][k] = val; - } - } - } - } - } - break; - case MT_FIELD: - s->mv_type = MV_TYPE_FIELD; - if (s->picture_structure == PICT_FRAME) { - mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED; - for (i = 0; i < 2; i++) { - if (USES_LIST(mb_type, i)) { - for (j = 0; j < 2; j++) { - s->field_select[i][j] = get_bits1(&s->gb); - val = mpeg_decode_motion(s, s->mpeg_f_code[i][0], - s->last_mv[i][j][0]); - s->last_mv[i][j][0] = val; - s->mv[i][j][0] = val; - av_dlog(s->avctx, "fmx=%d\n", val); - val = mpeg_decode_motion(s, s->mpeg_f_code[i][1], - s->last_mv[i][j][1] >> 1); - s->last_mv[i][j][1] = val << 1; - s->mv[i][j][1] = val; - av_dlog(s->avctx, "fmy=%d\n", val); - } - } - } - } else { - av_assert0(!s->progressive_sequence); - mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED; - for (i = 0; i < 2; i++) { - if (USES_LIST(mb_type, i)) { - s->field_select[i][0] = get_bits1(&s->gb); - for (k = 0; k < 2; k++) { - val = mpeg_decode_motion(s, s->mpeg_f_code[i][k], - s->last_mv[i][0][k]); - s->last_mv[i][0][k] = val; - s->last_mv[i][1][k] = val; - s->mv[i][0][k] = val; - } - } - } - } - break; - case MT_DMV: - if(s->progressive_sequence){ - av_log(s->avctx, AV_LOG_ERROR, "MT_DMV in progressive_sequence\n"); - return -1; - } - s->mv_type = MV_TYPE_DMV; - for (i = 0; i < 2; i++) { - if (USES_LIST(mb_type, i)) { - int dmx, dmy, mx, my, m; - const int my_shift = s->picture_structure == PICT_FRAME; - - mx = mpeg_decode_motion(s, s->mpeg_f_code[i][0], - s->last_mv[i][0][0]); - s->last_mv[i][0][0] = mx; - s->last_mv[i][1][0] = mx; - dmx = get_dmv(s); - my = mpeg_decode_motion(s, s->mpeg_f_code[i][1], - s->last_mv[i][0][1] >> my_shift); - dmy = get_dmv(s); - - - s->last_mv[i][0][1] = my << my_shift; - s->last_mv[i][1][1] = my << my_shift; - - s->mv[i][0][0] = mx; - s->mv[i][0][1] = my; - s->mv[i][1][0] = mx; // not used - s->mv[i][1][1] = my; // not used - - if (s->picture_structure == PICT_FRAME) { - mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED; - - // m = 1 + 2 * s->top_field_first; - m = s->top_field_first ? 1 : 3; - - /* top -> top pred */ - s->mv[i][2][0] = ((mx * m + (mx > 0)) >> 1) + dmx; - s->mv[i][2][1] = ((my * m + (my > 0)) >> 1) + dmy - 1; - m = 4 - m; - s->mv[i][3][0] = ((mx * m + (mx > 0)) >> 1) + dmx; - s->mv[i][3][1] = ((my * m + (my > 0)) >> 1) + dmy + 1; - } else { - mb_type |= MB_TYPE_16x16; - - s->mv[i][2][0] = ((mx + (mx > 0)) >> 1) + dmx; - s->mv[i][2][1] = ((my + (my > 0)) >> 1) + dmy; - if (s->picture_structure == PICT_TOP_FIELD) - s->mv[i][2][1]--; - else - s->mv[i][2][1]++; - } - } - } - break; - default: - av_log(s->avctx, AV_LOG_ERROR, "00 motion_type at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - } - - s->mb_intra = 0; - if (HAS_CBP(mb_type)) { - s->dsp.clear_blocks(s->block[0]); - - cbp = get_vlc2(&s->gb, mb_pat_vlc.table, MB_PAT_VLC_BITS, 1); - if (mb_block_count > 6) { - cbp <<= mb_block_count - 6; - cbp |= get_bits(&s->gb, mb_block_count - 6); - s->dsp.clear_blocks(s->block[6]); + i = avpriv_find_start_code(buf + i, buf + buf_size, &state) - buf - 1; + if (pc->frame_start_found == 0 && state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE) { + i++; + pc->frame_start_found = 4; } - if (cbp <= 0) { - av_log(s->avctx, AV_LOG_ERROR, "invalid cbp %d at %d %d\n", cbp, s->mb_x, s->mb_y); - return -1; + if (state == SEQ_END_CODE) { + pc->frame_start_found = 0; + pc->state=-1; + return i+1; } - - //if 1, we memcpy blocks in xvmcvideo - if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1) { - ff_xvmc_pack_pblocks(s, cbp); - if (s->swap_uv) { - exchange_uv(s); + if (pc->frame_start_found == 2 && state == SEQ_START_CODE) + pc->frame_start_found = 0; + if (pc->frame_start_found < 4 && state == EXT_START_CODE) + pc->frame_start_found++; + if (pc->frame_start_found == 4 && (state & 0xFFFFFF00) == 0x100) { + if (state < SLICE_MIN_START_CODE || state > SLICE_MAX_START_CODE) { + pc->frame_start_found = 0; + pc->state = -1; + return i - 3; } } - - if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO) { - if (s->flags2 & CODEC_FLAG2_FAST) { - for (i = 0; i < 6; i++) { - if (cbp & 32) { - mpeg2_fast_decode_block_non_intra(s, *s->pblocks[i], i); - } else { - s->block_last_index[i] = -1; - } - cbp += cbp; - } - } else { - cbp <<= 12-mb_block_count; - - for (i = 0; i < mb_block_count; i++) { - if (cbp & (1 << 11)) { - if (mpeg2_decode_block_non_intra(s, *s->pblocks[i], i) < 0) - return -1; - } else { - s->block_last_index[i] = -1; - } - cbp += cbp; - } - } - } else { - if (s->flags2 & CODEC_FLAG2_FAST) { - for (i = 0; i < 6; i++) { - if (cbp & 32) { - mpeg1_fast_decode_block_inter(s, *s->pblocks[i], i); - } else { - s->block_last_index[i] = -1; - } - cbp += cbp; - } - } else { - for (i = 0; i < 6; i++) { - if (cbp & 32) { - if (mpeg1_decode_block_inter(s, *s->pblocks[i], i) < 0) - return -1; - } else { - s->block_last_index[i] = -1; - } - cbp += cbp; - } - } + if (pc->frame_start_found == 0 && s && state == PICTURE_START_CODE) { + ff_fetch_timestamp(s, i - 3, 1); } - } else { - for (i = 0; i < 12; i++) - s->block_last_index[i] = -1; } } - - s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride] = mb_type; - - return 0; + pc->state = state; + return END_NOT_FOUND; } -static av_cold int mpeg_decode_init(AVCodecContext *avctx) -{ - Mpeg1Context *s = avctx->priv_data; - MpegEncContext *s2 = &s->mpeg_enc_ctx; - int i; - - /* we need some permutation to store matrices, - * until MPV_common_init() sets the real permutation. */ - for (i = 0; i < 64; i++) - s2->dsp.idct_permutation[i]=i; - - ff_MPV_decode_defaults(s2); - - s->mpeg_enc_ctx.avctx = avctx; - s->mpeg_enc_ctx.flags = avctx->flags; - s->mpeg_enc_ctx.flags2 = avctx->flags2; - ff_mpeg12_common_init(&s->mpeg_enc_ctx); - ff_mpeg12_init_vlcs(); - - s->mpeg_enc_ctx_allocated = 0; - s->mpeg_enc_ctx.picture_number = 0; - s->repeat_field = 0; - s->mpeg_enc_ctx.codec_id = avctx->codec->id; - avctx->color_range = AVCOL_RANGE_MPEG; - if (avctx->codec->id == AV_CODEC_ID_MPEG1VIDEO) - avctx->chroma_sample_location = AVCHROMA_LOC_CENTER; - else - avctx->chroma_sample_location = AVCHROMA_LOC_LEFT; - return 0; -} - -static int mpeg_decode_update_thread_context(AVCodecContext *avctx, const AVCodecContext *avctx_from) -{ - Mpeg1Context *ctx = avctx->priv_data, *ctx_from = avctx_from->priv_data; - MpegEncContext *s = &ctx->mpeg_enc_ctx, *s1 = &ctx_from->mpeg_enc_ctx; - int err; - - if (avctx == avctx_from || !ctx_from->mpeg_enc_ctx_allocated || !s1->context_initialized) - return 0; - - err = ff_mpeg_update_thread_context(avctx, avctx_from); - if (err) return err; - - if (!ctx->mpeg_enc_ctx_allocated) - memcpy(s + 1, s1 + 1, sizeof(Mpeg1Context) - sizeof(MpegEncContext)); - - if (!(s->pict_type == AV_PICTURE_TYPE_B || s->low_delay)) - s->picture_number++; - - return 0; -} - -static void quant_matrix_rebuild(uint16_t *matrix, const uint8_t *old_perm, - const uint8_t *new_perm) -{ - uint16_t temp_matrix[64]; - int i; - - memcpy(temp_matrix, matrix, 64 * sizeof(uint16_t)); - - for (i = 0; i < 64; i++) { - matrix[new_perm[i]] = temp_matrix[old_perm[i]]; - } -} - -static const enum AVPixelFormat mpeg1_hwaccel_pixfmt_list_420[] = { -#if CONFIG_MPEG_XVMC_DECODER - AV_PIX_FMT_XVMC_MPEG2_IDCT, - AV_PIX_FMT_XVMC_MPEG2_MC, -#endif -#if CONFIG_MPEG1_VDPAU_HWACCEL - AV_PIX_FMT_VDPAU_MPEG1, -#endif - AV_PIX_FMT_YUV420P, - AV_PIX_FMT_NONE -}; - -static const enum AVPixelFormat mpeg2_hwaccel_pixfmt_list_420[] = { -#if CONFIG_MPEG_XVMC_DECODER - AV_PIX_FMT_XVMC_MPEG2_IDCT, - AV_PIX_FMT_XVMC_MPEG2_MC, -#endif -#if CONFIG_MPEG2_VDPAU_HWACCEL - AV_PIX_FMT_VDPAU_MPEG2, -#endif -#if CONFIG_MPEG2_DXVA2_HWACCEL - AV_PIX_FMT_DXVA2_VLD, -#endif -#if CONFIG_MPEG2_VAAPI_HWACCEL - AV_PIX_FMT_VAAPI_VLD, -#endif - AV_PIX_FMT_YUV420P, - AV_PIX_FMT_NONE -}; - -static inline int uses_vdpau(AVCodecContext *avctx) { - return avctx->pix_fmt == AV_PIX_FMT_VDPAU_MPEG1 || avctx->pix_fmt == AV_PIX_FMT_VDPAU_MPEG2; -} - -static enum AVPixelFormat mpeg_get_pixelformat(AVCodecContext *avctx) -{ - Mpeg1Context *s1 = avctx->priv_data; - MpegEncContext *s = &s1->mpeg_enc_ctx; - - if(s->chroma_format < 2) { - return avctx->get_format(avctx, - avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO ? - mpeg1_hwaccel_pixfmt_list_420 : - mpeg2_hwaccel_pixfmt_list_420); - } else if(s->chroma_format == 2) - return AV_PIX_FMT_YUV422P; - else - return AV_PIX_FMT_YUV444P; -} - -static void setup_hwaccel_for_pixfmt(AVCodecContext *avctx) -{ - if (avctx->pix_fmt != AV_PIX_FMT_XVMC_MPEG2_IDCT && avctx->pix_fmt != AV_PIX_FMT_XVMC_MPEG2_MC) { - avctx->xvmc_acceleration = 0; - } else if (!avctx->xvmc_acceleration) { - avctx->xvmc_acceleration = 2; - } - avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt); - // until then pix_fmt may be changed right after codec init - if (avctx->pix_fmt == AV_PIX_FMT_XVMC_MPEG2_IDCT || - avctx->hwaccel || uses_vdpau(avctx)) - if (avctx->idct_algo == FF_IDCT_AUTO) - avctx->idct_algo = FF_IDCT_SIMPLE; -} - -/* Call this function when we know all parameters. - * It may be called in different places for MPEG-1 and MPEG-2. */ -static int mpeg_decode_postinit(AVCodecContext *avctx) -{ - Mpeg1Context *s1 = avctx->priv_data; - MpegEncContext *s = &s1->mpeg_enc_ctx; - uint8_t old_permutation[64]; - - if ((s1->mpeg_enc_ctx_allocated == 0) || - avctx->coded_width != s->width || - avctx->coded_height != s->height || - s1->save_width != s->width || - s1->save_height != s->height || - s1->save_aspect_info != s->aspect_ratio_info || - s1->save_progressive_seq != s->progressive_sequence || - 0) - { - - if (s1->mpeg_enc_ctx_allocated) { - ParseContext pc = s->parse_context; - s->parse_context.buffer = 0; - ff_MPV_common_end(s); - s->parse_context = pc; - } - - if ((s->width == 0) || (s->height == 0)) - return -2; - - avcodec_set_dimensions(avctx, s->width, s->height); - if (avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO && s->bit_rate) { - avctx->rc_max_rate = s->bit_rate; - } else if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO && s->bit_rate && - (s->bit_rate != 0x3FFFF*400 || s->vbv_delay != 0xFFFF)) { - avctx->bit_rate = s->bit_rate; - } - s1->save_aspect_info = s->aspect_ratio_info; - s1->save_width = s->width; - s1->save_height = s->height; - s1->save_progressive_seq = s->progressive_sequence; - - /* low_delay may be forced, in this case we will have B-frames - * that behave like P-frames. */ - avctx->has_b_frames = !s->low_delay; - - if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO) { - //MPEG-1 fps - avctx->time_base.den = ff_mpeg12_frame_rate_tab[s->frame_rate_index].num; - avctx->time_base.num = ff_mpeg12_frame_rate_tab[s->frame_rate_index].den; - //MPEG-1 aspect - avctx->sample_aspect_ratio = av_d2q(1.0/ff_mpeg1_aspect[s->aspect_ratio_info], 255); - avctx->ticks_per_frame=1; - } else {//MPEG-2 - //MPEG-2 fps - av_reduce(&s->avctx->time_base.den, - &s->avctx->time_base.num, - ff_mpeg12_frame_rate_tab[s->frame_rate_index].num * s1->frame_rate_ext.num*2, - ff_mpeg12_frame_rate_tab[s->frame_rate_index].den * s1->frame_rate_ext.den, - 1 << 30); - avctx->ticks_per_frame = 2; - //MPEG-2 aspect - if (s->aspect_ratio_info > 1) { - AVRational dar = - av_mul_q(av_div_q(ff_mpeg2_aspect[s->aspect_ratio_info], - (AVRational) {s1->pan_scan.width, s1->pan_scan.height}), - (AVRational) {s->width, s->height}); - - // we ignore the spec here and guess a bit as reality does not match the spec, see for example - // res_change_ffmpeg_aspect.ts and sequence-display-aspect.mpg - // issue1613, 621, 562 - if ((s1->pan_scan.width == 0) || (s1->pan_scan.height == 0) || - (av_cmp_q(dar, (AVRational) {4, 3}) && av_cmp_q(dar, (AVRational) {16, 9}))) { - s->avctx->sample_aspect_ratio = - av_div_q(ff_mpeg2_aspect[s->aspect_ratio_info], - (AVRational) {s->width, s->height}); - } else { - s->avctx->sample_aspect_ratio = - av_div_q(ff_mpeg2_aspect[s->aspect_ratio_info], - (AVRational) {s1->pan_scan.width, s1->pan_scan.height}); -//issue1613 4/3 16/9 -> 16/9 -//res_change_ffmpeg_aspect.ts 4/3 225/44 ->4/3 -//widescreen-issue562.mpg 4/3 16/9 -> 16/9 -// s->avctx->sample_aspect_ratio = av_mul_q(s->avctx->sample_aspect_ratio, (AVRational) {s->width, s->height}); - av_dlog(avctx, "A %d/%d\n", - ff_mpeg2_aspect[s->aspect_ratio_info].num, ff_mpeg2_aspect[s->aspect_ratio_info].den); - av_dlog(avctx, "B %d/%d\n", s->avctx->sample_aspect_ratio.num, - s->avctx->sample_aspect_ratio.den); - } - } else { - s->avctx->sample_aspect_ratio = - ff_mpeg2_aspect[s->aspect_ratio_info]; - } - } // MPEG-2 - - avctx->pix_fmt = mpeg_get_pixelformat(avctx); - setup_hwaccel_for_pixfmt(avctx); - - /* Quantization matrices may need reordering - * if DCT permutation is changed. */ - memcpy(old_permutation, s->dsp.idct_permutation, 64 * sizeof(uint8_t)); - - if (ff_MPV_common_init(s) < 0) - return -2; - - quant_matrix_rebuild(s->intra_matrix, old_permutation, s->dsp.idct_permutation); - quant_matrix_rebuild(s->inter_matrix, old_permutation, s->dsp.idct_permutation); - quant_matrix_rebuild(s->chroma_intra_matrix, old_permutation, s->dsp.idct_permutation); - quant_matrix_rebuild(s->chroma_inter_matrix, old_permutation, s->dsp.idct_permutation); - - s1->mpeg_enc_ctx_allocated = 1; - } - return 0; -} - -static int mpeg1_decode_picture(AVCodecContext *avctx, - const uint8_t *buf, int buf_size) -{ - Mpeg1Context *s1 = avctx->priv_data; - MpegEncContext *s = &s1->mpeg_enc_ctx; - int ref, f_code, vbv_delay; - - init_get_bits(&s->gb, buf, buf_size*8); - - ref = get_bits(&s->gb, 10); /* temporal ref */ - s->pict_type = get_bits(&s->gb, 3); - if (s->pict_type == 0 || s->pict_type > 3) - return -1; - - vbv_delay = get_bits(&s->gb, 16); - s->vbv_delay = vbv_delay; - if (s->pict_type == AV_PICTURE_TYPE_P || s->pict_type == AV_PICTURE_TYPE_B) { - s->full_pel[0] = get_bits1(&s->gb); - f_code = get_bits(&s->gb, 3); - if (f_code == 0 && (avctx->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT))) - return -1; - f_code += !f_code; - s->mpeg_f_code[0][0] = f_code; - s->mpeg_f_code[0][1] = f_code; - } - if (s->pict_type == AV_PICTURE_TYPE_B) { - s->full_pel[1] = get_bits1(&s->gb); - f_code = get_bits(&s->gb, 3); - if (f_code == 0 && (avctx->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT))) - return -1; - f_code += !f_code; - s->mpeg_f_code[1][0] = f_code; - s->mpeg_f_code[1][1] = f_code; - } - s->current_picture.f.pict_type = s->pict_type; - s->current_picture.f.key_frame = s->pict_type == AV_PICTURE_TYPE_I; - - if (avctx->debug & FF_DEBUG_PICT_INFO) - av_log(avctx, AV_LOG_DEBUG, "vbv_delay %d, ref %d type:%d\n", vbv_delay, ref, s->pict_type); - - s->y_dc_scale = 8; - s->c_dc_scale = 8; - return 0; -} - -static void mpeg_decode_sequence_extension(Mpeg1Context *s1) -{ - MpegEncContext *s= &s1->mpeg_enc_ctx; - int horiz_size_ext, vert_size_ext; - int bit_rate_ext; - - skip_bits(&s->gb, 1); /* profile and level esc*/ - s->avctx->profile = get_bits(&s->gb, 3); - s->avctx->level = get_bits(&s->gb, 4); - s->progressive_sequence = get_bits1(&s->gb); /* progressive_sequence */ - s->chroma_format = get_bits(&s->gb, 2); /* chroma_format 1=420, 2=422, 3=444 */ - horiz_size_ext = get_bits(&s->gb, 2); - vert_size_ext = get_bits(&s->gb, 2); - s->width |= (horiz_size_ext << 12); - s->height |= (vert_size_ext << 12); - bit_rate_ext = get_bits(&s->gb, 12); /* XXX: handle it */ - s->bit_rate += (bit_rate_ext << 18) * 400; - skip_bits1(&s->gb); /* marker */ - s->avctx->rc_buffer_size += get_bits(&s->gb, 8) * 1024 * 16 << 10; - - s->low_delay = get_bits1(&s->gb); - if (s->flags & CODEC_FLAG_LOW_DELAY) - s->low_delay = 1; - - s1->frame_rate_ext.num = get_bits(&s->gb, 2) + 1; - s1->frame_rate_ext.den = get_bits(&s->gb, 5) + 1; - - av_dlog(s->avctx, "sequence extension\n"); - s->codec_id = s->avctx->codec_id = AV_CODEC_ID_MPEG2VIDEO; - - if (s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_DEBUG, "profile: %d, level: %d vbv buffer: %d, bitrate:%d\n", - s->avctx->profile, s->avctx->level, s->avctx->rc_buffer_size, s->bit_rate); - -} - -static void mpeg_decode_sequence_display_extension(Mpeg1Context *s1) -{ - MpegEncContext *s = &s1->mpeg_enc_ctx; - int color_description, w, h; - - skip_bits(&s->gb, 3); /* video format */ - color_description = get_bits1(&s->gb); - if (color_description) { - s->avctx->color_primaries = get_bits(&s->gb, 8); - s->avctx->color_trc = get_bits(&s->gb, 8); - s->avctx->colorspace = get_bits(&s->gb, 8); - } - w = get_bits(&s->gb, 14); - skip_bits(&s->gb, 1); //marker - h = get_bits(&s->gb, 14); - // remaining 3 bits are zero padding - - s1->pan_scan.width = 16 * w; - s1->pan_scan.height = 16 * h; - - if (s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_DEBUG, "sde w:%d, h:%d\n", w, h); -} - -static void mpeg_decode_picture_display_extension(Mpeg1Context *s1) -{ - MpegEncContext *s = &s1->mpeg_enc_ctx; - int i, nofco; - - nofco = 1; - if (s->progressive_sequence) { - if (s->repeat_first_field) { - nofco++; - if (s->top_field_first) - nofco++; - } - } else { - if (s->picture_structure == PICT_FRAME) { - nofco++; - if (s->repeat_first_field) - nofco++; - } - } - for (i = 0; i < nofco; i++) { - s1->pan_scan.position[i][0] = get_sbits(&s->gb, 16); - skip_bits(&s->gb, 1); // marker - s1->pan_scan.position[i][1] = get_sbits(&s->gb, 16); - skip_bits(&s->gb, 1); // marker - } - - if (s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_DEBUG, "pde (%d,%d) (%d,%d) (%d,%d)\n", - s1->pan_scan.position[0][0], s1->pan_scan.position[0][1], - s1->pan_scan.position[1][0], s1->pan_scan.position[1][1], - s1->pan_scan.position[2][0], s1->pan_scan.position[2][1]); -} - -static int load_matrix(MpegEncContext *s, uint16_t matrix0[64], uint16_t matrix1[64], int intra) -{ - int i; - - for (i = 0; i < 64; i++) { - int j = s->dsp.idct_permutation[ff_zigzag_direct[i]]; - int v = get_bits(&s->gb, 8); - if (v == 0) { - av_log(s->avctx, AV_LOG_ERROR, "matrix damaged\n"); - return -1; - } - if (intra && i == 0 && v != 8) { - av_log(s->avctx, AV_LOG_DEBUG, "intra matrix specifies invalid DC quantizer %d, ignoring\n", v); - v = 8; // needed by pink.mpg / issue1046 - } - matrix0[j] = v; - if (matrix1) - matrix1[j] = v; - } - return 0; -} - -static void mpeg_decode_quant_matrix_extension(MpegEncContext *s) -{ - av_dlog(s->avctx, "matrix extension\n"); - - if (get_bits1(&s->gb)) load_matrix(s, s->chroma_intra_matrix, s->intra_matrix, 1); - if (get_bits1(&s->gb)) load_matrix(s, s->chroma_inter_matrix, s->inter_matrix, 0); - if (get_bits1(&s->gb)) load_matrix(s, s->chroma_intra_matrix, NULL , 1); - if (get_bits1(&s->gb)) load_matrix(s, s->chroma_inter_matrix, NULL , 0); -} - -static void mpeg_decode_picture_coding_extension(Mpeg1Context *s1) -{ - MpegEncContext *s = &s1->mpeg_enc_ctx; - - s->full_pel[0] = s->full_pel[1] = 0; - s->mpeg_f_code[0][0] = get_bits(&s->gb, 4); - s->mpeg_f_code[0][1] = get_bits(&s->gb, 4); - s->mpeg_f_code[1][0] = get_bits(&s->gb, 4); - s->mpeg_f_code[1][1] = get_bits(&s->gb, 4); - if (!s->pict_type && s1->mpeg_enc_ctx_allocated) { - av_log(s->avctx, AV_LOG_ERROR, "Missing picture start code, guessing missing values\n"); - if (s->mpeg_f_code[1][0] == 15 && s->mpeg_f_code[1][1] == 15) { - if (s->mpeg_f_code[0][0] == 15 && s->mpeg_f_code[0][1] == 15) - s->pict_type = AV_PICTURE_TYPE_I; - else - s->pict_type = AV_PICTURE_TYPE_P; - } else - s->pict_type = AV_PICTURE_TYPE_B; - s->current_picture.f.pict_type = s->pict_type; - s->current_picture.f.key_frame = s->pict_type == AV_PICTURE_TYPE_I; - } - s->mpeg_f_code[0][0] += !s->mpeg_f_code[0][0]; - s->mpeg_f_code[0][1] += !s->mpeg_f_code[0][1]; - s->mpeg_f_code[1][0] += !s->mpeg_f_code[1][0]; - s->mpeg_f_code[1][1] += !s->mpeg_f_code[1][1]; - - s->intra_dc_precision = get_bits(&s->gb, 2); - s->picture_structure = get_bits(&s->gb, 2); - s->top_field_first = get_bits1(&s->gb); - s->frame_pred_frame_dct = get_bits1(&s->gb); - s->concealment_motion_vectors = get_bits1(&s->gb); - s->q_scale_type = get_bits1(&s->gb); - s->intra_vlc_format = get_bits1(&s->gb); - s->alternate_scan = get_bits1(&s->gb); - s->repeat_first_field = get_bits1(&s->gb); - s->chroma_420_type = get_bits1(&s->gb); - s->progressive_frame = get_bits1(&s->gb); - - - if (s->alternate_scan) { - ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable, ff_alternate_vertical_scan); - ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable, ff_alternate_vertical_scan); - } else { - ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable, ff_zigzag_direct); - ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct); - } - - /* composite display not parsed */ - av_dlog(s->avctx, "intra_dc_precision=%d\n", s->intra_dc_precision); - av_dlog(s->avctx, "picture_structure=%d\n", s->picture_structure); - av_dlog(s->avctx, "top field first=%d\n", s->top_field_first); - av_dlog(s->avctx, "repeat first field=%d\n", s->repeat_first_field); - av_dlog(s->avctx, "conceal=%d\n", s->concealment_motion_vectors); - av_dlog(s->avctx, "intra_vlc_format=%d\n", s->intra_vlc_format); - av_dlog(s->avctx, "alternate_scan=%d\n", s->alternate_scan); - av_dlog(s->avctx, "frame_pred_frame_dct=%d\n", s->frame_pred_frame_dct); - av_dlog(s->avctx, "progressive_frame=%d\n", s->progressive_frame); -} - -static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size) -{ - AVCodecContext *avctx = s->avctx; - Mpeg1Context *s1 = (Mpeg1Context*)s; - - /* start frame decoding */ - if (s->first_field || s->picture_structure == PICT_FRAME) { - AVFrameSideData *pan_scan; - - if (ff_MPV_frame_start(s, avctx) < 0) - return -1; - - ff_mpeg_er_frame_start(s); - - /* first check if we must repeat the frame */ - s->current_picture_ptr->f.repeat_pict = 0; - if (s->repeat_first_field) { - if (s->progressive_sequence) { - if (s->top_field_first) - s->current_picture_ptr->f.repeat_pict = 4; - else - s->current_picture_ptr->f.repeat_pict = 2; - } else if (s->progressive_frame) { - s->current_picture_ptr->f.repeat_pict = 1; - } - } - - pan_scan = av_frame_new_side_data(&s->current_picture_ptr->f, - AV_FRAME_DATA_PANSCAN, - sizeof(s1->pan_scan)); - if (!pan_scan) - return AVERROR(ENOMEM); - memcpy(pan_scan->data, &s1->pan_scan, sizeof(s1->pan_scan)); - - if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_FRAME)) - ff_thread_finish_setup(avctx); - } else { // second field - int i; - - if (!s->current_picture_ptr) { - av_log(s->avctx, AV_LOG_ERROR, "first field missing\n"); - return -1; - } - - if (s->avctx->hwaccel && - (s->avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD)) { - if (s->avctx->hwaccel->end_frame(s->avctx) < 0) - av_log(avctx, AV_LOG_ERROR, "hardware accelerator failed to decode first field\n"); - } - - for (i = 0; i < 4; i++) { - s->current_picture.f.data[i] = s->current_picture_ptr->f.data[i]; - if (s->picture_structure == PICT_BOTTOM_FIELD) { - s->current_picture.f.data[i] += s->current_picture_ptr->f.linesize[i]; - } - } - } - - if (avctx->hwaccel) { - if (avctx->hwaccel->start_frame(avctx, buf, buf_size) < 0) - return -1; - } - -// MPV_frame_start will call this function too, -// but we need to call it on every field - if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration) - if (ff_xvmc_field_start(s, avctx) < 0) - return -1; - - return 0; -} - -#define DECODE_SLICE_ERROR -1 -#define DECODE_SLICE_OK 0 - -/** - * Decode a slice. - * MpegEncContext.mb_y must be set to the MB row from the startcode. - * @return DECODE_SLICE_ERROR if the slice is damaged, - * DECODE_SLICE_OK if this slice is OK - */ -static int mpeg_decode_slice(MpegEncContext *s, int mb_y, - const uint8_t **buf, int buf_size) -{ - AVCodecContext *avctx = s->avctx; - const int lowres = s->avctx->lowres; - const int field_pic = s->picture_structure != PICT_FRAME; - - s->resync_mb_x = - s->resync_mb_y = -1; - - av_assert0(mb_y < s->mb_height); - - init_get_bits(&s->gb, *buf, buf_size * 8); - if(s->codec_id != AV_CODEC_ID_MPEG1VIDEO && s->mb_height > 2800/16) - skip_bits(&s->gb, 3); - - ff_mpeg1_clean_buffers(s); - s->interlaced_dct = 0; - - s->qscale = get_qscale(s); - - if (s->qscale == 0) { - av_log(s->avctx, AV_LOG_ERROR, "qscale == 0\n"); - return -1; - } - - /* extra slice info */ - while (get_bits1(&s->gb) != 0) { - skip_bits(&s->gb, 8); - } - - s->mb_x = 0; - - if (mb_y == 0 && s->codec_tag == AV_RL32("SLIF")) { - skip_bits1(&s->gb); - } else { - while (get_bits_left(&s->gb) > 0) { - int code = get_vlc2(&s->gb, mbincr_vlc.table, MBINCR_VLC_BITS, 2); - if (code < 0) { - av_log(s->avctx, AV_LOG_ERROR, "first mb_incr damaged\n"); - return -1; - } - if (code >= 33) { - if (code == 33) { - s->mb_x += 33; - } - /* otherwise, stuffing, nothing to do */ - } else { - s->mb_x += code; - break; - } - } - } - - if (s->mb_x >= (unsigned)s->mb_width) { - av_log(s->avctx, AV_LOG_ERROR, "initial skip overflow\n"); - return -1; - } - - if (avctx->hwaccel) { - const uint8_t *buf_end, *buf_start = *buf - 4; /* include start_code */ - int start_code = -1; - buf_end = avpriv_mpv_find_start_code(buf_start + 2, *buf + buf_size, &start_code); - if (buf_end < *buf + buf_size) - buf_end -= 4; - s->mb_y = mb_y; - if (avctx->hwaccel->decode_slice(avctx, buf_start, buf_end - buf_start) < 0) - return DECODE_SLICE_ERROR; - *buf = buf_end; - return DECODE_SLICE_OK; - } - - s->resync_mb_x = s->mb_x; - s->resync_mb_y = s->mb_y = mb_y; - s->mb_skip_run = 0; - ff_init_block_index(s); - - if (s->mb_y == 0 && s->mb_x == 0 && (s->first_field || s->picture_structure == PICT_FRAME)) { - if (s->avctx->debug & FF_DEBUG_PICT_INFO) { - av_log(s->avctx, AV_LOG_DEBUG, "qp:%d fc:%2d%2d%2d%2d %s %s %s %s %s dc:%d pstruct:%d fdct:%d cmv:%d qtype:%d ivlc:%d rff:%d %s\n", - s->qscale, s->mpeg_f_code[0][0], s->mpeg_f_code[0][1], s->mpeg_f_code[1][0], s->mpeg_f_code[1][1], - s->pict_type == AV_PICTURE_TYPE_I ? "I" : (s->pict_type == AV_PICTURE_TYPE_P ? "P" : (s->pict_type == AV_PICTURE_TYPE_B ? "B" : "S")), - s->progressive_sequence ? "ps" :"", s->progressive_frame ? "pf" : "", s->alternate_scan ? "alt" :"", s->top_field_first ? "top" :"", - s->intra_dc_precision, s->picture_structure, s->frame_pred_frame_dct, s->concealment_motion_vectors, - s->q_scale_type, s->intra_vlc_format, s->repeat_first_field, s->chroma_420_type ? "420" :""); - } - } - - for (;;) { - // If 1, we memcpy blocks in xvmcvideo. - if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1) - ff_xvmc_init_block(s); // set s->block - - if (mpeg_decode_mb(s, s->block) < 0) - return -1; - - if (s->current_picture.motion_val[0] && !s->encoding) { // note motion_val is normally NULL unless we want to extract the MVs - const int wrap = s->b8_stride; - int xy = s->mb_x * 2 + s->mb_y * 2 * wrap; - int b8_xy = 4 * (s->mb_x + s->mb_y * s->mb_stride); - int motion_x, motion_y, dir, i; - - for (i = 0; i < 2; i++) { - for (dir = 0; dir < 2; dir++) { - if (s->mb_intra || (dir == 1 && s->pict_type != AV_PICTURE_TYPE_B)) { - motion_x = motion_y = 0; - } else if (s->mv_type == MV_TYPE_16X16 || (s->mv_type == MV_TYPE_FIELD && field_pic)) { - motion_x = s->mv[dir][0][0]; - motion_y = s->mv[dir][0][1]; - } else /*if ((s->mv_type == MV_TYPE_FIELD) || (s->mv_type == MV_TYPE_16X8))*/ { - motion_x = s->mv[dir][i][0]; - motion_y = s->mv[dir][i][1]; - } - - s->current_picture.motion_val[dir][xy ][0] = motion_x; - s->current_picture.motion_val[dir][xy ][1] = motion_y; - s->current_picture.motion_val[dir][xy + 1][0] = motion_x; - s->current_picture.motion_val[dir][xy + 1][1] = motion_y; - s->current_picture.ref_index [dir][b8_xy ] = - s->current_picture.ref_index [dir][b8_xy + 1] = s->field_select[dir][i]; - av_assert2(s->field_select[dir][i] == 0 || s->field_select[dir][i] == 1); - } - xy += wrap; - b8_xy +=2; - } - } - - s->dest[0] += 16 >> lowres; - s->dest[1] +=(16 >> lowres) >> s->chroma_x_shift; - s->dest[2] +=(16 >> lowres) >> s->chroma_x_shift; - - ff_MPV_decode_mb(s, s->block); - - if (++s->mb_x >= s->mb_width) { - const int mb_size = 16 >> s->avctx->lowres; - - ff_mpeg_draw_horiz_band(s, mb_size*(s->mb_y >> field_pic), mb_size); - ff_MPV_report_decode_progress(s); - - s->mb_x = 0; - s->mb_y += 1 << field_pic; - - if (s->mb_y >= s->mb_height) { - int left = get_bits_left(&s->gb); - int is_d10 = s->chroma_format == 2 && s->pict_type == AV_PICTURE_TYPE_I && avctx->profile == 0 && avctx->level == 5 - && s->intra_dc_precision == 2 && s->q_scale_type == 1 && s->alternate_scan == 0 - && s->progressive_frame == 0 /* vbv_delay == 0xBBB || 0xE10*/; - - if (left >= 32 && !is_d10) { - GetBitContext gb = s->gb; - align_get_bits(&gb); - if (show_bits(&gb, 24) == 0x060E2B) { - av_log(avctx, AV_LOG_DEBUG, "Invalid MXF data found in video stream\n"); - is_d10 = 1; - } - } - - if (left < 0 || (left && show_bits(&s->gb, FFMIN(left, 23)) && !is_d10) - || ((avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_AGGRESSIVE)) && left > 8)) { - av_log(avctx, AV_LOG_ERROR, "end mismatch left=%d %0X\n", left, show_bits(&s->gb, FFMIN(left, 23))); - return -1; - } else - goto eos; - } - - ff_init_block_index(s); - } - - /* skip mb handling */ - if (s->mb_skip_run == -1) { - /* read increment again */ - s->mb_skip_run = 0; - for (;;) { - int code = get_vlc2(&s->gb, mbincr_vlc.table, MBINCR_VLC_BITS, 2); - if (code < 0) { - av_log(s->avctx, AV_LOG_ERROR, "mb incr damaged\n"); - return -1; - } - if (code >= 33) { - if (code == 33) { - s->mb_skip_run += 33; - } else if (code == 35) { - if (s->mb_skip_run != 0 || show_bits(&s->gb, 15) != 0) { - av_log(s->avctx, AV_LOG_ERROR, "slice mismatch\n"); - return -1; - } - goto eos; /* end of slice */ - } - /* otherwise, stuffing, nothing to do */ - } else { - s->mb_skip_run += code; - break; - } - } - if (s->mb_skip_run) { - int i; - if (s->pict_type == AV_PICTURE_TYPE_I) { - av_log(s->avctx, AV_LOG_ERROR, "skipped MB in I frame at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - - /* skip mb */ - s->mb_intra = 0; - for (i = 0; i < 12; i++) - s->block_last_index[i] = -1; - if (s->picture_structure == PICT_FRAME) - s->mv_type = MV_TYPE_16X16; - else - s->mv_type = MV_TYPE_FIELD; - if (s->pict_type == AV_PICTURE_TYPE_P) { - /* if P type, zero motion vector is implied */ - s->mv_dir = MV_DIR_FORWARD; - s->mv[0][0][0] = s->mv[0][0][1] = 0; - s->last_mv[0][0][0] = s->last_mv[0][0][1] = 0; - s->last_mv[0][1][0] = s->last_mv[0][1][1] = 0; - s->field_select[0][0] = (s->picture_structure - 1) & 1; - } else { - /* if B type, reuse previous vectors and directions */ - s->mv[0][0][0] = s->last_mv[0][0][0]; - s->mv[0][0][1] = s->last_mv[0][0][1]; - s->mv[1][0][0] = s->last_mv[1][0][0]; - s->mv[1][0][1] = s->last_mv[1][0][1]; - } - } - } - } -eos: // end of slice - *buf += (get_bits_count(&s->gb)-1)/8; - av_dlog(s, "y %d %d %d %d\n", s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y); - return 0; -} - -static int slice_decode_thread(AVCodecContext *c, void *arg) -{ - MpegEncContext *s = *(void**)arg; - const uint8_t *buf = s->gb.buffer; - int mb_y = s->start_mb_y; - const int field_pic = s->picture_structure != PICT_FRAME; - - s->er.error_count = (3 * (s->end_mb_y - s->start_mb_y) * s->mb_width) >> field_pic; - - for (;;) { - uint32_t start_code; - int ret; - - ret = mpeg_decode_slice(s, mb_y, &buf, s->gb.buffer_end - buf); - emms_c(); - av_dlog(c, "ret:%d resync:%d/%d mb:%d/%d ts:%d/%d ec:%d\n", - ret, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, - s->start_mb_y, s->end_mb_y, s->er.error_count); - if (ret < 0) { - if (c->err_recognition & AV_EF_EXPLODE) - return ret; - if (s->resync_mb_x >= 0 && s->resync_mb_y >= 0) - ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_AC_ERROR | ER_DC_ERROR | ER_MV_ERROR); - } else { - ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_AC_END | ER_DC_END | ER_MV_END); - } - - if (s->mb_y == s->end_mb_y) - return 0; - - start_code = -1; - buf = avpriv_mpv_find_start_code(buf, s->gb.buffer_end, &start_code); - mb_y= start_code - SLICE_MIN_START_CODE; - if(s->codec_id != AV_CODEC_ID_MPEG1VIDEO && s->mb_height > 2800/16) - mb_y += (*buf&0xE0)<<2; - mb_y <<= field_pic; - if (s->picture_structure == PICT_BOTTOM_FIELD) - mb_y++; - if (mb_y < 0 || mb_y >= s->end_mb_y) - return -1; - } -} - -/** - * Handle slice ends. - * @return 1 if it seems to be the last slice - */ -static int slice_end(AVCodecContext *avctx, AVFrame *pict) -{ - Mpeg1Context *s1 = avctx->priv_data; - MpegEncContext *s = &s1->mpeg_enc_ctx; - - if (!s1->mpeg_enc_ctx_allocated || !s->current_picture_ptr) - return 0; - - if (s->avctx->hwaccel) { - if (s->avctx->hwaccel->end_frame(s->avctx) < 0) - av_log(avctx, AV_LOG_ERROR, "hardware accelerator failed to decode picture\n"); - } - - if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration) - ff_xvmc_field_end(s); - - /* end of slice reached */ - if (/*s->mb_y << field_pic == s->mb_height &&*/ !s->first_field && !s->first_slice) { - /* end of image */ - - ff_er_frame_end(&s->er); - - ff_MPV_frame_end(s); - - if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) { - int ret = av_frame_ref(pict, &s->current_picture_ptr->f); - if (ret < 0) - return ret; - ff_print_debug_info(s, s->current_picture_ptr, pict); - ff_mpv_export_qp_table(s, pict, s->current_picture_ptr, FF_QSCALE_TYPE_MPEG2); - } else { - if (avctx->active_thread_type & FF_THREAD_FRAME) - s->picture_number++; - /* latency of 1 frame for I- and P-frames */ - /* XXX: use another variable than picture_number */ - if (s->last_picture_ptr != NULL) { - int ret = av_frame_ref(pict, &s->last_picture_ptr->f); - if (ret < 0) - return ret; - ff_print_debug_info(s, s->last_picture_ptr, pict); - ff_mpv_export_qp_table(s, pict, s->last_picture_ptr, FF_QSCALE_TYPE_MPEG2); - } - } - - return 1; - } else { - return 0; - } -} - -static int mpeg1_decode_sequence(AVCodecContext *avctx, - const uint8_t *buf, int buf_size) -{ - Mpeg1Context *s1 = avctx->priv_data; - MpegEncContext *s = &s1->mpeg_enc_ctx; - int width, height; - int i, v, j; - - init_get_bits(&s->gb, buf, buf_size*8); - - width = get_bits(&s->gb, 12); - height = get_bits(&s->gb, 12); - if (width == 0 || height == 0) { - av_log(avctx, AV_LOG_WARNING, "Invalid horizontal or vertical size " - "value.\n"); - if (avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_COMPLIANT)) - return AVERROR_INVALIDDATA; - } - s->aspect_ratio_info = get_bits(&s->gb, 4); - if (s->aspect_ratio_info == 0) { - av_log(avctx, AV_LOG_ERROR, "aspect ratio has forbidden 0 value\n"); - if (avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_COMPLIANT)) - return -1; - } - s->frame_rate_index = get_bits(&s->gb, 4); - if (s->frame_rate_index == 0 || s->frame_rate_index > 13) - return -1; - s->bit_rate = get_bits(&s->gb, 18) * 400; - if (get_bits1(&s->gb) == 0) /* marker */ - return -1; - s->width = width; - s->height = height; - - s->avctx->rc_buffer_size = get_bits(&s->gb, 10) * 1024 * 16; - skip_bits(&s->gb, 1); - - /* get matrix */ - if (get_bits1(&s->gb)) { - load_matrix(s, s->chroma_intra_matrix, s->intra_matrix, 1); - } else { - for (i = 0; i < 64; i++) { - j = s->dsp.idct_permutation[i]; - v = ff_mpeg1_default_intra_matrix[i]; - s->intra_matrix[j] = v; - s->chroma_intra_matrix[j] = v; - } - } - if (get_bits1(&s->gb)) { - load_matrix(s, s->chroma_inter_matrix, s->inter_matrix, 0); - } else { - for (i = 0; i < 64; i++) { - int j = s->dsp.idct_permutation[i]; - v = ff_mpeg1_default_non_intra_matrix[i]; - s->inter_matrix[j] = v; - s->chroma_inter_matrix[j] = v; - } - } - - if (show_bits(&s->gb, 23) != 0) { - av_log(s->avctx, AV_LOG_ERROR, "sequence header damaged\n"); - return -1; - } - - /* we set MPEG-2 parameters so that it emulates MPEG-1 */ - s->progressive_sequence = 1; - s->progressive_frame = 1; - s->picture_structure = PICT_FRAME; - s->first_field = 0; - s->frame_pred_frame_dct = 1; - s->chroma_format = 1; - s->codec_id = s->avctx->codec_id = AV_CODEC_ID_MPEG1VIDEO; - s->out_format = FMT_MPEG1; - s->swap_uv = 0; // AFAIK VCR2 does not have SEQ_HEADER - if (s->flags & CODEC_FLAG_LOW_DELAY) - s->low_delay = 1; - - if (s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_DEBUG, "vbv buffer: %d, bitrate:%d\n", - s->avctx->rc_buffer_size, s->bit_rate); - - return 0; -} - -static int vcr2_init_sequence(AVCodecContext *avctx) -{ - Mpeg1Context *s1 = avctx->priv_data; - MpegEncContext *s = &s1->mpeg_enc_ctx; - int i, v; - - /* start new MPEG-1 context decoding */ - s->out_format = FMT_MPEG1; - if (s1->mpeg_enc_ctx_allocated) { - ff_MPV_common_end(s); - } - s->width = avctx->coded_width; - s->height = avctx->coded_height; - avctx->has_b_frames = 0; // true? - s->low_delay = 1; - - avctx->pix_fmt = mpeg_get_pixelformat(avctx); - setup_hwaccel_for_pixfmt(avctx); - - if (ff_MPV_common_init(s) < 0) - return -1; - s1->mpeg_enc_ctx_allocated = 1; - - for (i = 0; i < 64; i++) { - int j = s->dsp.idct_permutation[i]; - v = ff_mpeg1_default_intra_matrix[i]; - s->intra_matrix[j] = v; - s->chroma_intra_matrix[j] = v; - - v = ff_mpeg1_default_non_intra_matrix[i]; - s->inter_matrix[j] = v; - s->chroma_inter_matrix[j] = v; - } - - s->progressive_sequence = 1; - s->progressive_frame = 1; - s->picture_structure = PICT_FRAME; - s->first_field = 0; - s->frame_pred_frame_dct = 1; - s->chroma_format = 1; - if (s->codec_tag == AV_RL32("BW10")) { - s->codec_id = s->avctx->codec_id = AV_CODEC_ID_MPEG1VIDEO; - } else { - exchange_uv(s); // common init reset pblocks, so we swap them here - s->swap_uv = 1; // in case of xvmc we need to swap uv for each MB - s->codec_id = s->avctx->codec_id = AV_CODEC_ID_MPEG2VIDEO; - } - s1->save_width = s->width; - s1->save_height = s->height; - s1->save_progressive_seq = s->progressive_sequence; - return 0; -} - - -static void mpeg_decode_user_data(AVCodecContext *avctx, - const uint8_t *p, int buf_size) -{ - Mpeg1Context *s = avctx->priv_data; - const uint8_t *buf_end = p + buf_size; - - if(buf_size > 29){ - int i; - for(i=0; i<20; i++) - if(!memcmp(p+i, "\0TMPGEXS\0", 9)){ - s->tmpgexs= 1; - } - -/* for(i=0; !(!p[i-2] && !p[i-1] && p[i]==1) && i= 5 && - p[0] == 'D' && p[1] == 'T' && p[2] == 'G' && p[3] == '1') { - int flags = p[4]; - p += 5; - if (flags & 0x80) { - /* skip event id */ - p += 2; - } - if (flags & 0x40) { - if (buf_end - p < 1) - return; - avctx->dtg_active_format = p[0] & 0x0f; - } - } -} - -static void mpeg_decode_gop(AVCodecContext *avctx, - const uint8_t *buf, int buf_size) -{ - Mpeg1Context *s1 = avctx->priv_data; - MpegEncContext *s = &s1->mpeg_enc_ctx; - int broken_link; - int64_t tc; - - init_get_bits(&s->gb, buf, buf_size*8); - - tc = avctx->timecode_frame_start = get_bits(&s->gb, 25); - - s->closed_gop = get_bits1(&s->gb); - /*broken_link indicate that after editing the - reference frames of the first B-Frames after GOP I-Frame - are missing (open gop)*/ - broken_link = get_bits1(&s->gb); - - if (s->avctx->debug & FF_DEBUG_PICT_INFO) { - char tcbuf[AV_TIMECODE_STR_SIZE]; - av_timecode_make_mpeg_tc_string(tcbuf, tc); - av_log(s->avctx, AV_LOG_DEBUG, - "GOP (%s) closed_gop=%d broken_link=%d\n", - tcbuf, s->closed_gop, broken_link); - } -} -/** - * Find the end of the current frame in the bitstream. - * @return the position of the first byte of the next frame, or -1 - */ -int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, AVCodecParserContext *s) -{ - int i; - uint32_t state = pc->state; - - /* EOF considered as end of frame */ - if (buf_size == 0) - return 0; - -/* - 0 frame start -> 1/4 - 1 first_SEQEXT -> 0/2 - 2 first field start -> 3/0 - 3 second_SEQEXT -> 2/0 - 4 searching end -*/ - - for (i = 0; i < buf_size; i++) { - av_assert1(pc->frame_start_found >= 0 && pc->frame_start_found <= 4); - if (pc->frame_start_found & 1) { - if (state == EXT_START_CODE && (buf[i] & 0xF0) != 0x80) - pc->frame_start_found--; - else if (state == EXT_START_CODE + 2) { - if ((buf[i] & 3) == 3) - pc->frame_start_found = 0; - else - pc->frame_start_found = (pc->frame_start_found + 1) & 3; - } - state++; - } else { - i = avpriv_mpv_find_start_code(buf + i, buf + buf_size, &state) - buf - 1; - if (pc->frame_start_found == 0 && state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE) { - i++; - pc->frame_start_found = 4; - } - if (state == SEQ_END_CODE) { - pc->frame_start_found = 0; - pc->state=-1; - return i+1; - } - if (pc->frame_start_found == 2 && state == SEQ_START_CODE) - pc->frame_start_found = 0; - if (pc->frame_start_found < 4 && state == EXT_START_CODE) - pc->frame_start_found++; - if (pc->frame_start_found == 4 && (state & 0xFFFFFF00) == 0x100) { - if (state < SLICE_MIN_START_CODE || state > SLICE_MAX_START_CODE) { - pc->frame_start_found = 0; - pc->state = -1; - return i - 3; - } - } - if (pc->frame_start_found == 0 && s && state == PICTURE_START_CODE) { - ff_fetch_timestamp(s, i - 3, 1); - } - } - } - pc->state = state; - return END_NOT_FOUND; -} - -static int decode_chunks(AVCodecContext *avctx, - AVFrame *picture, int *got_output, - const uint8_t *buf, int buf_size) -{ - Mpeg1Context *s = avctx->priv_data; - MpegEncContext *s2 = &s->mpeg_enc_ctx; - const uint8_t *buf_ptr = buf; - const uint8_t *buf_end = buf + buf_size; - int ret, input_size; - int last_code = 0; - int picture_start_code_seen = 0; - - for (;;) { - /* find next start code */ - uint32_t start_code = -1; - buf_ptr = avpriv_mpv_find_start_code(buf_ptr, buf_end, &start_code); - if (start_code > 0x1ff) { - if (s2->pict_type != AV_PICTURE_TYPE_B || avctx->skip_frame <= AVDISCARD_DEFAULT) { - if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE)) { - int i; - av_assert0(avctx->thread_count > 1); - - avctx->execute(avctx, slice_decode_thread, &s2->thread_context[0], NULL, s->slice_count, sizeof(void*)); - for (i = 0; i < s->slice_count; i++) - s2->er.error_count += s2->thread_context[i]->er.error_count; - } - - if (CONFIG_VDPAU && uses_vdpau(avctx)) - ff_vdpau_mpeg_picture_complete(s2, buf, buf_size, s->slice_count); - - ret = slice_end(avctx, picture); - if (ret < 0) - return ret; - else if (ret) { - if (s2->last_picture_ptr || s2->low_delay) //FIXME merge with the stuff in mpeg_decode_slice - *got_output = 1; - } - } - s2->pict_type = 0; - return FFMAX(0, buf_ptr - buf - s2->parse_context.last_index); - } - - input_size = buf_end - buf_ptr; - - if (avctx->debug & FF_DEBUG_STARTCODE) { - av_log(avctx, AV_LOG_DEBUG, "%3X at %td left %d\n", start_code, buf_ptr-buf, input_size); - } - - /* prepare data for next start code */ - switch (start_code) { - case SEQ_START_CODE: - if (last_code == 0) { - mpeg1_decode_sequence(avctx, buf_ptr, input_size); - if(buf != avctx->extradata) - s->sync=1; - } else { - av_log(avctx, AV_LOG_ERROR, "ignoring SEQ_START_CODE after %X\n", last_code); - if (avctx->err_recognition & AV_EF_EXPLODE) - return AVERROR_INVALIDDATA; - } - break; - - case PICTURE_START_CODE: - if (picture_start_code_seen && s2->picture_structure == PICT_FRAME) { - /* If it's a frame picture, there can't be more than one picture header. - Yet, it does happen and we need to handle it. */ - av_log(avctx, AV_LOG_WARNING, "ignoring extra picture following a frame-picture\n"); - break; - } - picture_start_code_seen = 1; - - if (s2->width <= 0 || s2->height <= 0) { - av_log(avctx, AV_LOG_ERROR, "Invalid frame dimensions %dx%d.\n", - s2->width, s2->height); - return AVERROR_INVALIDDATA; - } - - if(s->tmpgexs){ - s2->intra_dc_precision= 3; - s2->intra_matrix[0]= 1; - } - if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE) && s->slice_count) { - int i; - - avctx->execute(avctx, slice_decode_thread, - s2->thread_context, NULL, - s->slice_count, sizeof(void*)); - for (i = 0; i < s->slice_count; i++) - s2->er.error_count += s2->thread_context[i]->er.error_count; - s->slice_count = 0; - } - if (last_code == 0 || last_code == SLICE_MIN_START_CODE) { - ret = mpeg_decode_postinit(avctx); - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "mpeg_decode_postinit() failure\n"); - return ret; - } - - /* we have a complete image: we try to decompress it */ - if (mpeg1_decode_picture(avctx, buf_ptr, input_size) < 0) - s2->pict_type = 0; - s2->first_slice = 1; - last_code = PICTURE_START_CODE; - } else { - av_log(avctx, AV_LOG_ERROR, "ignoring pic after %X\n", last_code); - if (avctx->err_recognition & AV_EF_EXPLODE) - return AVERROR_INVALIDDATA; - } - break; - case EXT_START_CODE: - init_get_bits(&s2->gb, buf_ptr, input_size*8); - - switch (get_bits(&s2->gb, 4)) { - case 0x1: - if (last_code == 0) { - mpeg_decode_sequence_extension(s); - } else { - av_log(avctx, AV_LOG_ERROR, "ignoring seq ext after %X\n", last_code); - if (avctx->err_recognition & AV_EF_EXPLODE) - return AVERROR_INVALIDDATA; - } - break; - case 0x2: - mpeg_decode_sequence_display_extension(s); - break; - case 0x3: - mpeg_decode_quant_matrix_extension(s2); - break; - case 0x7: - mpeg_decode_picture_display_extension(s); - break; - case 0x8: - if (last_code == PICTURE_START_CODE) { - mpeg_decode_picture_coding_extension(s); - } else { - av_log(avctx, AV_LOG_ERROR, "ignoring pic cod ext after %X\n", last_code); - if (avctx->err_recognition & AV_EF_EXPLODE) - return AVERROR_INVALIDDATA; - } - break; - } - break; - case USER_START_CODE: - mpeg_decode_user_data(avctx, buf_ptr, input_size); - break; - case GOP_START_CODE: - if (last_code == 0) { - s2->first_field=0; - mpeg_decode_gop(avctx, buf_ptr, input_size); - s->sync=1; - } else { - av_log(avctx, AV_LOG_ERROR, "ignoring GOP_START_CODE after %X\n", last_code); - if (avctx->err_recognition & AV_EF_EXPLODE) - return AVERROR_INVALIDDATA; - } - break; - default: - if (start_code >= SLICE_MIN_START_CODE && - start_code <= SLICE_MAX_START_CODE && last_code == PICTURE_START_CODE) { - - if (s2->progressive_sequence && !s2->progressive_frame) { - s2->progressive_frame = 1; - av_log(s2->avctx, AV_LOG_ERROR, "interlaced frame in progressive sequence, ignoring\n"); - } - - if (s2->picture_structure == 0 || (s2->progressive_frame && s2->picture_structure != PICT_FRAME)) { - av_log(s2->avctx, AV_LOG_ERROR, "picture_structure %d invalid, ignoring\n", s2->picture_structure); - s2->picture_structure = PICT_FRAME; - } - - if (s2->progressive_sequence && !s2->frame_pred_frame_dct) { - av_log(s2->avctx, AV_LOG_WARNING, "invalid frame_pred_frame_dct\n"); - } - - if (s2->picture_structure == PICT_FRAME) { - s2->first_field = 0; - s2->v_edge_pos = 16 * s2->mb_height; - } else { - s2->first_field ^= 1; - s2->v_edge_pos = 8 * s2->mb_height; - memset(s2->mbskip_table, 0, s2->mb_stride * s2->mb_height); - } - } - if (start_code >= SLICE_MIN_START_CODE && - start_code <= SLICE_MAX_START_CODE && last_code != 0) { - const int field_pic = s2->picture_structure != PICT_FRAME; - int mb_y = start_code - SLICE_MIN_START_CODE; - last_code = SLICE_MIN_START_CODE; - if(s2->codec_id != AV_CODEC_ID_MPEG1VIDEO && s2->mb_height > 2800/16) - mb_y += (*buf_ptr&0xE0)<<2; - - mb_y <<= field_pic; - if (s2->picture_structure == PICT_BOTTOM_FIELD) - mb_y++; - - if (mb_y >= s2->mb_height) { - av_log(s2->avctx, AV_LOG_ERROR, "slice below image (%d >= %d)\n", mb_y, s2->mb_height); - return -1; - } - - if (s2->last_picture_ptr == NULL) { - /* Skip B-frames if we do not have reference frames and gop is not closed */ - if (s2->pict_type == AV_PICTURE_TYPE_B) { - if (!s2->closed_gop) - break; - } - } - if (s2->pict_type == AV_PICTURE_TYPE_I || (s2->flags2 & CODEC_FLAG2_SHOW_ALL)) - s->sync=1; - if (s2->next_picture_ptr == NULL) { - /* Skip P-frames if we do not have a reference frame or we have an invalid header. */ - if (s2->pict_type == AV_PICTURE_TYPE_P && !s->sync) break; - } - if ((avctx->skip_frame >= AVDISCARD_NONREF && s2->pict_type == AV_PICTURE_TYPE_B) || - (avctx->skip_frame >= AVDISCARD_NONKEY && s2->pict_type != AV_PICTURE_TYPE_I) || - avctx->skip_frame >= AVDISCARD_ALL) - break; - - if (!s->mpeg_enc_ctx_allocated) - break; - - if (s2->codec_id == AV_CODEC_ID_MPEG2VIDEO) { - if (mb_y < avctx->skip_top || mb_y >= s2->mb_height - avctx->skip_bottom) - break; - } - - if (!s2->pict_type) { - av_log(avctx, AV_LOG_ERROR, "Missing picture start code\n"); - if (avctx->err_recognition & AV_EF_EXPLODE) - return AVERROR_INVALIDDATA; - break; - } - - if (s2->first_slice) { - s2->first_slice = 0; - if (mpeg_field_start(s2, buf, buf_size) < 0) - return -1; - } - if (!s2->current_picture_ptr) { - av_log(avctx, AV_LOG_ERROR, "current_picture not initialized\n"); - return AVERROR_INVALIDDATA; - } - - if (uses_vdpau(avctx)) { - s->slice_count++; - break; - } - - if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE)) { - int threshold = (s2->mb_height * s->slice_count + - s2->slice_context_count / 2) / - s2->slice_context_count; - av_assert0(avctx->thread_count > 1); - if (threshold <= mb_y) { - MpegEncContext *thread_context = s2->thread_context[s->slice_count]; - - thread_context->start_mb_y = mb_y; - thread_context->end_mb_y = s2->mb_height; - if (s->slice_count) { - s2->thread_context[s->slice_count-1]->end_mb_y = mb_y; - ret = ff_update_duplicate_context(thread_context, - s2); - if (ret < 0) - return ret; - } - init_get_bits(&thread_context->gb, buf_ptr, input_size*8); - s->slice_count++; - } - buf_ptr += 2; // FIXME add minimum number of bytes per slice - } else { - ret = mpeg_decode_slice(s2, mb_y, &buf_ptr, input_size); - emms_c(); - - if (ret < 0) { - if (avctx->err_recognition & AV_EF_EXPLODE) - return ret; - if (s2->resync_mb_x >= 0 && s2->resync_mb_y >= 0) - ff_er_add_slice(&s2->er, s2->resync_mb_x, s2->resync_mb_y, s2->mb_x, s2->mb_y, ER_AC_ERROR | ER_DC_ERROR | ER_MV_ERROR); - } else { - ff_er_add_slice(&s2->er, s2->resync_mb_x, s2->resync_mb_y, s2->mb_x-1, s2->mb_y, ER_AC_END | ER_DC_END | ER_MV_END); - } - } - } - break; - } - } -} - -static int mpeg_decode_frame(AVCodecContext *avctx, - void *data, int *got_output, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int ret; - int buf_size = avpkt->size; - Mpeg1Context *s = avctx->priv_data; - AVFrame *picture = data; - MpegEncContext *s2 = &s->mpeg_enc_ctx; - av_dlog(avctx, "fill_buffer\n"); - - if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == SEQ_END_CODE)) { - /* special case for last picture */ - if (s2->low_delay == 0 && s2->next_picture_ptr) { - int ret = av_frame_ref(picture, &s2->next_picture_ptr->f); - if (ret < 0) - return ret; - - s2->next_picture_ptr = NULL; - - *got_output = 1; - } - return buf_size; - } - - if (s2->flags & CODEC_FLAG_TRUNCATED) { - int next = ff_mpeg1_find_frame_end(&s2->parse_context, buf, buf_size, NULL); - - if (ff_combine_frame(&s2->parse_context, next, (const uint8_t **)&buf, &buf_size) < 0) - return buf_size; - } - - s2->codec_tag = avpriv_toupper4(avctx->codec_tag); - if (s->mpeg_enc_ctx_allocated == 0 && ( s2->codec_tag == AV_RL32("VCR2") - || s2->codec_tag == AV_RL32("BW10") - )) - vcr2_init_sequence(avctx); - - s->slice_count = 0; - - if (avctx->extradata && !s->extradata_decoded) { - ret = decode_chunks(avctx, picture, got_output, avctx->extradata, avctx->extradata_size); - if(*got_output) { - av_log(avctx, AV_LOG_ERROR, "picture in extradata\n"); - *got_output = 0; - } - s->extradata_decoded = 1; - if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) { - s2->current_picture_ptr = NULL; - return ret; - } - } - - ret = decode_chunks(avctx, picture, got_output, buf, buf_size); - if (ret<0 || *got_output) - s2->current_picture_ptr = NULL; - - return ret; -} - - -static void flush(AVCodecContext *avctx) -{ - Mpeg1Context *s = avctx->priv_data; - - s->sync=0; - - ff_mpeg_flush(avctx); -} - -static int mpeg_decode_end(AVCodecContext *avctx) -{ - Mpeg1Context *s = avctx->priv_data; - - if (s->mpeg_enc_ctx_allocated) - ff_MPV_common_end(&s->mpeg_enc_ctx); - return 0; -} - -static const AVProfile mpeg2_video_profiles[] = { - { FF_PROFILE_MPEG2_422, "4:2:2" }, - { FF_PROFILE_MPEG2_HIGH, "High" }, - { FF_PROFILE_MPEG2_SS, "Spatially Scalable" }, - { FF_PROFILE_MPEG2_SNR_SCALABLE, "SNR Scalable" }, - { FF_PROFILE_MPEG2_MAIN, "Main" }, - { FF_PROFILE_MPEG2_SIMPLE, "Simple" }, - { FF_PROFILE_RESERVED, "Reserved" }, - { FF_PROFILE_RESERVED, "Reserved" }, - { FF_PROFILE_UNKNOWN }, -}; - - -AVCodec ff_mpeg1video_decoder = { - .name = "mpeg1video", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_MPEG1VIDEO, - .priv_data_size = sizeof(Mpeg1Context), - .init = mpeg_decode_init, - .close = mpeg_decode_end, - .decode = mpeg_decode_frame, - .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | - CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY | - CODEC_CAP_SLICE_THREADS, - .flush = flush, - .max_lowres = 3, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video"), - .update_thread_context = ONLY_IF_THREADS_ENABLED(mpeg_decode_update_thread_context) -}; - -AVCodec ff_mpeg2video_decoder = { - .name = "mpeg2video", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_MPEG2VIDEO, - .priv_data_size = sizeof(Mpeg1Context), - .init = mpeg_decode_init, - .close = mpeg_decode_end, - .decode = mpeg_decode_frame, - .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | - CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY | - CODEC_CAP_SLICE_THREADS, - .flush = flush, - .max_lowres = 3, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 video"), - .profiles = NULL_IF_CONFIG_SMALL(mpeg2_video_profiles), -}; - -//legacy decoder -AVCodec ff_mpegvideo_decoder = { - .name = "mpegvideo", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_MPEG2VIDEO, - .priv_data_size = sizeof(Mpeg1Context), - .init = mpeg_decode_init, - .close = mpeg_decode_end, - .decode = mpeg_decode_frame, - .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS, - .flush = flush, - .max_lowres = 3, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video"), -}; - -#if CONFIG_MPEG_XVMC_DECODER -static av_cold int mpeg_mc_decode_init(AVCodecContext *avctx) -{ - if (avctx->active_thread_type & FF_THREAD_SLICE) - return -1; - if (!(avctx->slice_flags & SLICE_FLAG_CODED_ORDER)) - return -1; - if (!(avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD)) { - av_dlog(avctx, "mpeg12.c: XvMC decoder will work better if SLICE_FLAG_ALLOW_FIELD is set\n"); - } - mpeg_decode_init(avctx); - - avctx->pix_fmt = AV_PIX_FMT_XVMC_MPEG2_IDCT; - avctx->xvmc_acceleration = 2; // 2 - the blocks are packed! - - return 0; -} - -AVCodec ff_mpeg_xvmc_decoder = { - .name = "mpegvideo_xvmc", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_MPEG2VIDEO_XVMC, - .priv_data_size = sizeof(Mpeg1Context), - .init = mpeg_mc_decode_init, - .close = mpeg_decode_end, - .decode = mpeg_decode_frame, - .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | - CODEC_CAP_TRUNCATED| CODEC_CAP_HWACCEL | CODEC_CAP_DELAY, - .flush = flush, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video XvMC (X-Video Motion Compensation)"), -}; - -#endif - -#if CONFIG_MPEG_VDPAU_DECODER -AVCodec ff_mpeg_vdpau_decoder = { - .name = "mpegvideo_vdpau", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_MPEG2VIDEO, - .priv_data_size = sizeof(Mpeg1Context), - .init = mpeg_decode_init, - .close = mpeg_decode_end, - .decode = mpeg_decode_frame, - .capabilities = CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | - CODEC_CAP_HWACCEL_VDPAU | CODEC_CAP_DELAY, - .flush = flush, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video (VDPAU acceleration)"), -}; -#endif - -#if CONFIG_MPEG1_VDPAU_DECODER -AVCodec ff_mpeg1_vdpau_decoder = { - .name = "mpeg1video_vdpau", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_MPEG1VIDEO, - .priv_data_size = sizeof(Mpeg1Context), - .init = mpeg_decode_init, - .close = mpeg_decode_end, - .decode = mpeg_decode_frame, - .capabilities = CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | - CODEC_CAP_HWACCEL_VDPAU | CODEC_CAP_DELAY, - .flush = flush, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video (VDPAU acceleration)"), -}; -#endif diff --git a/ffmpeg/libavcodec/mpeg12.h b/ffmpeg/libavcodec/mpeg12.h index 1f36917..b4ebd23 100644 --- a/ffmpeg/libavcodec/mpeg12.h +++ b/ffmpeg/libavcodec/mpeg12.h @@ -25,25 +25,21 @@ #include "mpegvideo.h" #define DC_VLC_BITS 9 +#define MV_VLC_BITS 9 #define TEX_VLC_BITS 9 +#define MBINCR_VLC_BITS 9 +#define MB_PAT_VLC_BITS 9 +#define MB_PTYPE_VLC_BITS 6 +#define MB_BTYPE_VLC_BITS 6 + extern VLC ff_dc_lum_vlc; extern VLC ff_dc_chroma_vlc; - -typedef struct Mpeg1Context { - MpegEncContext mpeg_enc_ctx; - int mpeg_enc_ctx_allocated; /* true if decoding context allocated */ - int repeat_field; /* true if we must repeat the field */ - AVPanScan pan_scan; /**< some temporary storage for the panscan */ - int slice_count; - int swap_uv;//indicate VCR2 - int save_aspect_info; - int save_width, save_height, save_progressive_seq; - AVRational frame_rate_ext; ///< MPEG-2 specific framerate modificator - int sync; ///< Did we reach a sync point like a GOP/SEQ/KEYFrame? - int tmpgexs; - int extradata_decoded; -} Mpeg1Context; +extern VLC ff_mbincr_vlc; +extern VLC ff_mb_ptype_vlc; +extern VLC ff_mb_btype_vlc; +extern VLC ff_mb_pat_vlc; +extern VLC ff_mv_vlc; extern uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; @@ -71,6 +67,8 @@ static inline int decode_dc(GetBitContext *gb, int component) return diff; } -extern int ff_mpeg1_decode_block_intra(MpegEncContext *s, int16_t *block, int n); +int ff_mpeg1_decode_block_intra(MpegEncContext *s, int16_t *block, int n); +void ff_mpeg1_clean_buffers(MpegEncContext *s); +int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, AVCodecParserContext *s); #endif /* AVCODEC_MPEG12_H */ diff --git a/ffmpeg/libavcodec/mpeg12decdata.h b/ffmpeg/libavcodec/mpeg12decdata.h deleted file mode 100644 index 66ca5c4..0000000 --- a/ffmpeg/libavcodec/mpeg12decdata.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * MPEG1/2 decoder tables - * copyright (c) 2000,2001 Fabrice Bellard - * copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MPEG1/2 decoder tables. - */ - -#ifndef AVCODEC_MPEG12DECDATA_H -#define AVCODEC_MPEG12DECDATA_H - -#include -#include "mpegvideo.h" - - -#define MB_TYPE_ZERO_MV 0x20000000 -#define IS_ZERO_MV(a) ((a)&MB_TYPE_ZERO_MV) - -static const uint8_t table_mb_ptype[7][2] = { - { 3, 5 }, // 0x01 MB_INTRA - { 1, 2 }, // 0x02 MB_PAT - { 1, 3 }, // 0x08 MB_FOR - { 1, 1 }, // 0x0A MB_FOR|MB_PAT - { 1, 6 }, // 0x11 MB_QUANT|MB_INTRA - { 1, 5 }, // 0x12 MB_QUANT|MB_PAT - { 2, 5 }, // 0x1A MB_QUANT|MB_FOR|MB_PAT -}; - -static const uint32_t ptype2mb_type[7] = { - MB_TYPE_INTRA, - MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_ZERO_MV | MB_TYPE_16x16, - MB_TYPE_L0, - MB_TYPE_L0 | MB_TYPE_CBP, - MB_TYPE_QUANT | MB_TYPE_INTRA, - MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_ZERO_MV | MB_TYPE_16x16, - MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP, -}; - -static const uint8_t table_mb_btype[11][2] = { - { 3, 5 }, // 0x01 MB_INTRA - { 2, 3 }, // 0x04 MB_BACK - { 3, 3 }, // 0x06 MB_BACK|MB_PAT - { 2, 4 }, // 0x08 MB_FOR - { 3, 4 }, // 0x0A MB_FOR|MB_PAT - { 2, 2 }, // 0x0C MB_FOR|MB_BACK - { 3, 2 }, // 0x0E MB_FOR|MB_BACK|MB_PAT - { 1, 6 }, // 0x11 MB_QUANT|MB_INTRA - { 2, 6 }, // 0x16 MB_QUANT|MB_BACK|MB_PAT - { 3, 6 }, // 0x1A MB_QUANT|MB_FOR|MB_PAT - { 2, 5 }, // 0x1E MB_QUANT|MB_FOR|MB_BACK|MB_PAT -}; - -static const uint32_t btype2mb_type[11] = { - MB_TYPE_INTRA, - MB_TYPE_L1, - MB_TYPE_L1 | MB_TYPE_CBP, - MB_TYPE_L0, - MB_TYPE_L0 | MB_TYPE_CBP, - MB_TYPE_L0L1, - MB_TYPE_L0L1 | MB_TYPE_CBP, - MB_TYPE_QUANT | MB_TYPE_INTRA, - MB_TYPE_QUANT | MB_TYPE_L1 | MB_TYPE_CBP, - MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP, - MB_TYPE_QUANT | MB_TYPE_L0L1 | MB_TYPE_CBP, -}; - -static const uint8_t non_linear_qscale[32] = { - 0, 1, 2, 3, 4, 5, 6, 7, - 8,10,12,14,16,18,20,22, - 24,28,32,36,40,44,48,52, - 56,64,72,80,88,96,104,112, -}; - -#endif /* AVCODEC_MPEG12DECDATA_H */ diff --git a/ffmpeg/libavcodec/mpeg12enc.c b/ffmpeg/libavcodec/mpeg12enc.c index c8e7b45..22f9fcb 100644 --- a/ffmpeg/libavcodec/mpeg12enc.c +++ b/ffmpeg/libavcodec/mpeg12enc.c @@ -25,116 +25,115 @@ * MPEG1/2 encoder */ -#include "avcodec.h" -#include "mathops.h" -#include "mpegvideo.h" +#include -#include "mpeg12.h" -#include "mpeg12data.h" -#include "bytestream.h" +#include "libavutil/attributes.h" +#include "libavutil/avassert.h" #include "libavutil/log.h" #include "libavutil/opt.h" -#include "libavutil/avassert.h" #include "libavutil/timecode.h" +#include "libavutil/stereo3d.h" -static const uint8_t inv_non_linear_qscale[13] = { - 0, 2, 4, 6, 8, - 9,10,11,12,13,14,15,16, -}; +#include "avcodec.h" +#include "bytestream.h" +#include "mathops.h" +#include "mpeg12.h" +#include "mpeg12data.h" +#include "mpegvideo.h" -static const uint8_t svcd_scan_offset_placeholder[14] = { - 0x10, 0x0E, - 0x00, 0x80, 0x81, - 0x00, 0x80, 0x81, - 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, + +static const uint8_t inv_non_linear_qscale[] = { + 0, 2, 4, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, }; -static void mpeg1_encode_block(MpegEncContext *s, - int16_t *block, - int component); -static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code); // RAL: f_code parameter added +static const uint8_t svcd_scan_offset_placeholder[] = { + 0x10, 0x0E, 0x00, 0x80, 0x81, 0x00, 0x80, + 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +}; -static uint8_t mv_penalty[MAX_FCODE+1][MAX_MV*2+1]; -static uint8_t fcode_tab[MAX_MV*2+1]; +static uint8_t mv_penalty[MAX_FCODE + 1][MAX_MV * 2 + 1]; +static uint8_t fcode_tab[MAX_MV * 2 + 1]; -static uint8_t uni_mpeg1_ac_vlc_len [64*64*2]; -static uint8_t uni_mpeg2_ac_vlc_len [64*64*2]; +static uint8_t uni_mpeg1_ac_vlc_len[64 * 64 * 2]; +static uint8_t uni_mpeg2_ac_vlc_len[64 * 64 * 2]; -/* simple include everything table for dc, first byte is bits number next 3 are code*/ +/* simple include everything table for dc, first byte is bits + * number next 3 are code */ static uint32_t mpeg1_lum_dc_uni[512]; static uint32_t mpeg1_chr_dc_uni[512]; static uint8_t mpeg1_index_run[2][64]; -static int8_t mpeg1_max_level[2][64]; +static int8_t mpeg1_max_level[2][64]; -static void init_uni_ac_vlc(RLTable *rl, uint8_t *uni_ac_vlc_len){ +static av_cold void init_uni_ac_vlc(RLTable *rl, uint8_t *uni_ac_vlc_len) +{ int i; - for(i=0; i<128; i++){ - int level= i-64; + for (i = 0; i < 128; i++) { + int level = i - 64; int run; if (!level) continue; - for(run=0; run<64; run++){ + for (run = 0; run < 64; run++) { int len, code; - - int alevel= FFABS(level); + int alevel = FFABS(level); if (alevel > rl->max_level[0][run]) - code= 111; /*rl->n*/ + code = 111; /* rl->n */ else - code= rl->index_run[0][run] + alevel - 1; + code = rl->index_run[0][run] + alevel - 1; - if (code < 111 /* rl->n */) { - /* length of vlc and sign */ - len= rl->table_vlc[code][1]+1; + if (code < 111) { /* rl->n */ + /* length of VLC and sign */ + len = rl->table_vlc[code][1] + 1; } else { - len= rl->table_vlc[111/*rl->n*/][1]+6; + len = rl->table_vlc[111 /* rl->n */][1] + 6; - if (alevel < 128) { + if (alevel < 128) len += 8; - } else { + else len += 16; - } } - uni_ac_vlc_len [UNI_AC_ENC_INDEX(run, i)]= len; + uni_ac_vlc_len[UNI_AC_ENC_INDEX(run, i)] = len; } } } - -static int find_frame_rate_index(MpegEncContext *s){ +static int find_frame_rate_index(MpegEncContext *s) +{ int i; - AVRational bestq= (AVRational){0, 0}; + AVRational bestq = (AVRational) {0, 0}; AVRational ext; AVRational target = av_inv_q(s->avctx->time_base); - for(i=1;i<14;i++) { - if(s->avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL && i>=9) break; + for (i = 1; i < 14; i++) { + if (s->avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL && + i >= 9) + break; for (ext.num=1; ext.num <= 4; ext.num++) { for (ext.den=1; ext.den <= 32; ext.den++) { AVRational q = av_mul_q(ext, ff_mpeg12_frame_rate_tab[i]); - if(s->codec_id != AV_CODEC_ID_MPEG2VIDEO && (ext.den!=1 || ext.num!=1)) + if (s->codec_id != AV_CODEC_ID_MPEG2VIDEO && (ext.den!=1 || ext.num!=1)) continue; - if(av_gcd(ext.den, ext.num) != 1) + if (av_gcd(ext.den, ext.num) != 1) continue; - if( bestq.num==0 + if ( bestq.num==0 || av_nearer_q(target, bestq, q) < 0 - || ext.num==1 && ext.den==1 && av_nearer_q(target, bestq, q) == 0){ - bestq = q; - s->frame_rate_index= i; + || ext.num==1 && ext.den==1 && av_nearer_q(target, bestq, q) == 0) { + bestq = q; + s->frame_rate_index = i; s->mpeg2_frame_rate_ext.num = ext.num; s->mpeg2_frame_rate_ext.den = ext.den; } } } } - if(av_cmp_q(target, bestq)) + + if (av_cmp_q(target, bestq)) return -1; else return 0; @@ -147,38 +146,48 @@ static av_cold int encode_init(AVCodecContext *avctx) if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO && avctx->height > 2800) avctx->thread_count = 1; - if(ff_MPV_encode_init(avctx) < 0) + if (ff_MPV_encode_init(avctx) < 0) return -1; - if(find_frame_rate_index(s) < 0){ - if(s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){ - av_log(avctx, AV_LOG_ERROR, "MPEG1/2 does not support %d/%d fps\n", avctx->time_base.den, avctx->time_base.num); + if (find_frame_rate_index(s) < 0) { + if (s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { + av_log(avctx, AV_LOG_ERROR, "MPEG1/2 does not support %d/%d fps\n", + avctx->time_base.den, avctx->time_base.num); return -1; - }else{ - av_log(avctx, AV_LOG_INFO, "MPEG1/2 does not support %d/%d fps, there may be AV sync issues\n", avctx->time_base.den, avctx->time_base.num); + } else { + av_log(avctx, AV_LOG_INFO, + "MPEG1/2 does not support %d/%d fps, there may be AV sync issues\n", + avctx->time_base.den, avctx->time_base.num); } } - if(avctx->profile == FF_PROFILE_UNKNOWN){ - if(avctx->level != FF_LEVEL_UNKNOWN){ + if (avctx->profile == FF_PROFILE_UNKNOWN) { + if (avctx->level != FF_LEVEL_UNKNOWN) { av_log(avctx, AV_LOG_ERROR, "Set profile and level\n"); return -1; } - avctx->profile = s->chroma_format == CHROMA_420 ? 4 : 0; /* Main or 4:2:2 */ + /* Main or 4:2:2 */ + avctx->profile = s->chroma_format == CHROMA_420 ? 4 : 0; } - if(avctx->level == FF_LEVEL_UNKNOWN){ - if(avctx->profile == 0){ /* 4:2:2 */ - if(avctx->width <= 720 && avctx->height <= 608) avctx->level = 5; /* Main */ - else avctx->level = 2; /* High */ - }else{ - if(avctx->profile != 1 && s->chroma_format != CHROMA_420){ - av_log(avctx, AV_LOG_ERROR, "Only High(1) and 4:2:2(0) profiles support 4:2:2 color sampling\n"); + if (avctx->level == FF_LEVEL_UNKNOWN) { + if (avctx->profile == 0) { /* 4:2:2 */ + if (avctx->width <= 720 && avctx->height <= 608) + avctx->level = 5; /* Main */ + else + avctx->level = 2; /* High */ + } else { + if (avctx->profile != 1 && s->chroma_format != CHROMA_420) { + av_log(avctx, AV_LOG_ERROR, + "Only High(1) and 4:2:2(0) profiles support 4:2:2 color sampling\n"); return -1; } - if(avctx->width <= 720 && avctx->height <= 576) avctx->level = 8; /* Main */ - else if(avctx->width <= 1440) avctx->level = 6; /* High 1440 */ - else avctx->level = 4; /* High */ + if (avctx->width <= 720 && avctx->height <= 576) + avctx->level = 8; /* Main */ + else if (avctx->width <= 1440) + avctx->level = 6; /* High 1440 */ + else + avctx->level = 4; /* High */ } } @@ -199,7 +208,8 @@ static av_cold int encode_init(AVCodecContext *avctx) if (s->drop_frame_timecode) s->tc.flags |= AV_TIMECODE_FLAG_DROPFRAME; if (s->drop_frame_timecode && s->frame_rate_index != 4) { - av_log(avctx, AV_LOG_ERROR, "Drop frame time code only allowed with 1001/30000 fps\n"); + av_log(avctx, AV_LOG_ERROR, + "Drop frame time code only allowed with 1001/30000 fps\n"); return -1; } @@ -219,127 +229,133 @@ static av_cold int encode_init(AVCodecContext *avctx) static void put_header(MpegEncContext *s, int header) { avpriv_align_put_bits(&s->pb); - put_bits(&s->pb, 16, header>>16); + put_bits(&s->pb, 16, header >> 16); put_sbits(&s->pb, 16, header); } /* put sequence header if needed */ static void mpeg1_encode_sequence_header(MpegEncContext *s) { - unsigned int vbv_buffer_size; - unsigned int fps, v; - int i; - uint64_t time_code; - float best_aspect_error= 1E10; - float aspect_ratio= av_q2d(s->avctx->sample_aspect_ratio); - int constraint_parameter_flag; + unsigned int vbv_buffer_size, fps, v; + int i, constraint_parameter_flag; + uint64_t time_code; + float best_aspect_error = 1E10; + float aspect_ratio = av_q2d(s->avctx->sample_aspect_ratio); - if(aspect_ratio==0.0) aspect_ratio= 1.0; //pixel aspect 1:1 (VGA) + if (aspect_ratio == 0.0) + aspect_ratio = 1.0; // pixel aspect 1.1 (VGA) - if (s->current_picture.f.key_frame) { - AVRational framerate = ff_mpeg12_frame_rate_tab[s->frame_rate_index]; + if (s->current_picture.f.key_frame) { + AVRational framerate = ff_mpeg12_frame_rate_tab[s->frame_rate_index]; - /* mpeg1 header repeated every gop */ - put_header(s, SEQ_START_CODE); + /* mpeg1 header repeated every gop */ + put_header(s, SEQ_START_CODE); - put_sbits(&s->pb, 12, s->width & 0xFFF); - put_sbits(&s->pb, 12, s->height & 0xFFF); + put_sbits(&s->pb, 12, s->width & 0xFFF); + put_sbits(&s->pb, 12, s->height & 0xFFF); - for(i=1; i<15; i++){ - float error= aspect_ratio; - if(s->codec_id == AV_CODEC_ID_MPEG1VIDEO || i <=1) - error-= 1.0/ff_mpeg1_aspect[i]; - else - error-= av_q2d(ff_mpeg2_aspect[i])*s->height/s->width; + for (i = 1; i < 15; i++) { + float error = aspect_ratio; + if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO || i <= 1) + error -= 1.0 / ff_mpeg1_aspect[i]; + else + error -= av_q2d(ff_mpeg2_aspect[i]) * s->height / s->width; - error= FFABS(error); + error = FFABS(error); - if(error < best_aspect_error){ - best_aspect_error= error; - s->aspect_ratio_info= i; - } + if (error < best_aspect_error) { + best_aspect_error = error; + s->aspect_ratio_info = i; } + } - put_bits(&s->pb, 4, s->aspect_ratio_info); - put_bits(&s->pb, 4, s->frame_rate_index); - - if(s->avctx->rc_max_rate){ - v = (s->avctx->rc_max_rate + 399) / 400; - if (v > 0x3ffff && s->codec_id == AV_CODEC_ID_MPEG1VIDEO) - v = 0x3ffff; - }else{ - v= 0x3FFFF; - } + put_bits(&s->pb, 4, s->aspect_ratio_info); + put_bits(&s->pb, 4, s->frame_rate_index); - if(s->avctx->rc_buffer_size) - vbv_buffer_size = s->avctx->rc_buffer_size; - else - /* VBV calculation: Scaled so that a VCD has the proper VBV size of 40 kilobytes */ - vbv_buffer_size = (( 20 * s->bit_rate) / (1151929 / 2)) * 8 * 1024; - vbv_buffer_size= (vbv_buffer_size + 16383) / 16384; - - put_sbits(&s->pb, 18, v); - put_bits(&s->pb, 1, 1); /* marker */ - put_sbits(&s->pb, 10, vbv_buffer_size); - - constraint_parameter_flag= - s->width <= 768 && s->height <= 576 && - s->mb_width * s->mb_height <= 396 && - s->mb_width * s->mb_height * framerate.num <= framerate.den*396*25 && - framerate.num <= framerate.den*30 && - s->avctx->me_range && s->avctx->me_range < 128 && - vbv_buffer_size <= 20 && - v <= 1856000/400 && - s->codec_id == AV_CODEC_ID_MPEG1VIDEO; - - put_bits(&s->pb, 1, constraint_parameter_flag); - - ff_write_quant_matrix(&s->pb, s->avctx->intra_matrix); - ff_write_quant_matrix(&s->pb, s->avctx->inter_matrix); - - if(s->codec_id == AV_CODEC_ID_MPEG2VIDEO){ - put_header(s, EXT_START_CODE); - put_bits(&s->pb, 4, 1); //seq ext - - put_bits(&s->pb, 1, s->avctx->profile == 0); //escx 1 for 4:2:2 profile */ - - put_bits(&s->pb, 3, s->avctx->profile); //profile - put_bits(&s->pb, 4, s->avctx->level); //level - - put_bits(&s->pb, 1, s->progressive_sequence); - put_bits(&s->pb, 2, s->chroma_format); - put_bits(&s->pb, 2, s->width >>12); - put_bits(&s->pb, 2, s->height>>12); - put_bits(&s->pb, 12, v>>18); //bitrate ext - put_bits(&s->pb, 1, 1); //marker - put_bits(&s->pb, 8, vbv_buffer_size >>10); //vbv buffer ext - put_bits(&s->pb, 1, s->low_delay); - put_bits(&s->pb, 2, s->mpeg2_frame_rate_ext.num-1); // frame_rate_ext_n - put_bits(&s->pb, 5, s->mpeg2_frame_rate_ext.den-1); // frame_rate_ext_d - } + if (s->avctx->rc_max_rate) { + v = (s->avctx->rc_max_rate + 399) / 400; + if (v > 0x3ffff && s->codec_id == AV_CODEC_ID_MPEG1VIDEO) + v = 0x3ffff; + } else { + v = 0x3FFFF; + } - put_header(s, GOP_START_CODE); - put_bits(&s->pb, 1, s->drop_frame_timecode); /* drop frame flag */ - /* time code : we must convert from the real frame rate to a - fake mpeg frame rate in case of low frame rate */ - fps = (framerate.num + framerate.den/2)/ framerate.den; - time_code = s->current_picture_ptr->f.coded_picture_number + s->avctx->timecode_frame_start; - - s->gop_picture_number = s->current_picture_ptr->f.coded_picture_number; - av_assert0(s->drop_frame_timecode == !!(s->tc.flags & AV_TIMECODE_FLAG_DROPFRAME)); - if (s->drop_frame_timecode) - time_code = av_timecode_adjust_ntsc_framenum2(time_code, fps); - put_bits(&s->pb, 5, (uint32_t)((time_code / (fps * 3600)) % 24)); - put_bits(&s->pb, 6, (uint32_t)((time_code / (fps * 60)) % 60)); - put_bits(&s->pb, 1, 1); - put_bits(&s->pb, 6, (uint32_t)((time_code / fps) % 60)); - put_bits(&s->pb, 6, (uint32_t)((time_code % fps))); - put_bits(&s->pb, 1, !!(s->flags & CODEC_FLAG_CLOSED_GOP)); - put_bits(&s->pb, 1, 0); /* broken link */ + if (s->avctx->rc_buffer_size) + vbv_buffer_size = s->avctx->rc_buffer_size; + else + /* VBV calculation: Scaled so that a VCD has the proper + * VBV size of 40 kilobytes */ + vbv_buffer_size = ((20 * s->bit_rate) / (1151929 / 2)) * 8 * 1024; + vbv_buffer_size = (vbv_buffer_size + 16383) / 16384; + + put_sbits(&s->pb, 18, v); + put_bits(&s->pb, 1, 1); // marker + put_sbits(&s->pb, 10, vbv_buffer_size); + + constraint_parameter_flag = + s->width <= 768 && + s->height <= 576 && + s->mb_width * s->mb_height <= 396 && + s->mb_width * s->mb_height * framerate.num <= 396 * 25 * framerate.den && + framerate.num <= framerate.den * 30 && + s->avctx->me_range && + s->avctx->me_range < 128 && + vbv_buffer_size <= 20 && + v <= 1856000 / 400 && + s->codec_id == AV_CODEC_ID_MPEG1VIDEO; + + put_bits(&s->pb, 1, constraint_parameter_flag); + + ff_write_quant_matrix(&s->pb, s->avctx->intra_matrix); + ff_write_quant_matrix(&s->pb, s->avctx->inter_matrix); + + if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO) { + put_header(s, EXT_START_CODE); + put_bits(&s->pb, 4, 1); // seq ext + + put_bits(&s->pb, 1, s->avctx->profile == 0); // escx 1 for 4:2:2 profile + + put_bits(&s->pb, 3, s->avctx->profile); // profile + put_bits(&s->pb, 4, s->avctx->level); // level + + put_bits(&s->pb, 1, s->progressive_sequence); + put_bits(&s->pb, 2, s->chroma_format); + put_bits(&s->pb, 2, s->width >> 12); + put_bits(&s->pb, 2, s->height >> 12); + put_bits(&s->pb, 12, v >> 18); // bitrate ext + put_bits(&s->pb, 1, 1); // marker + put_bits(&s->pb, 8, vbv_buffer_size >> 10); // vbv buffer ext + put_bits(&s->pb, 1, s->low_delay); + put_bits(&s->pb, 2, s->mpeg2_frame_rate_ext.num-1); // frame_rate_ext_n + put_bits(&s->pb, 5, s->mpeg2_frame_rate_ext.den-1); // frame_rate_ext_d } + + put_header(s, GOP_START_CODE); + put_bits(&s->pb, 1, s->drop_frame_timecode); // drop frame flag + /* time code: we must convert from the real frame rate to a + * fake MPEG frame rate in case of low frame rate */ + fps = (framerate.num + framerate.den / 2) / framerate.den; + time_code = s->current_picture_ptr->f.coded_picture_number + + s->avctx->timecode_frame_start; + + s->gop_picture_number = s->current_picture_ptr->f.coded_picture_number; + + av_assert0(s->drop_frame_timecode == !!(s->tc.flags & AV_TIMECODE_FLAG_DROPFRAME)); + if (s->drop_frame_timecode) + time_code = av_timecode_adjust_ntsc_framenum2(time_code, fps); + + put_bits(&s->pb, 5, (uint32_t)((time_code / (fps * 3600)) % 24)); + put_bits(&s->pb, 6, (uint32_t)((time_code / (fps * 60)) % 60)); + put_bits(&s->pb, 1, 1); + put_bits(&s->pb, 6, (uint32_t)((time_code / fps) % 60)); + put_bits(&s->pb, 6, (uint32_t)((time_code % fps))); + put_bits(&s->pb, 1, !!(s->flags & CODEC_FLAG_CLOSED_GOP)); + put_bits(&s->pb, 1, 0); // broken link + } } -static inline void encode_mb_skip_run(MpegEncContext *s, int run){ +static inline void encode_mb_skip_run(MpegEncContext *s, int run) +{ while (run >= 33) { put_bits(&s->pb, 11, 0x008); run -= 33; @@ -350,27 +366,31 @@ static inline void encode_mb_skip_run(MpegEncContext *s, int run){ static av_always_inline void put_qscale(MpegEncContext *s) { - if(s->q_scale_type){ - av_assert2(s->qscale>=1 && s->qscale <=12); + if (s->q_scale_type) { + av_assert2(s->qscale >= 1 && s->qscale <= 12); put_bits(&s->pb, 5, inv_non_linear_qscale[s->qscale]); - }else{ + } else { put_bits(&s->pb, 5, s->qscale); } } -void ff_mpeg1_encode_slice_header(MpegEncContext *s){ +void ff_mpeg1_encode_slice_header(MpegEncContext *s) +{ if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO && s->height > 2800) { put_header(s, SLICE_MIN_START_CODE + (s->mb_y & 127)); - put_bits(&s->pb, 3, s->mb_y >> 7); /* slice_vertical_position_extension */ + /* slice_vertical_position_extension */ + put_bits(&s->pb, 3, s->mb_y >> 7); } else { put_header(s, SLICE_MIN_START_CODE + s->mb_y); } put_qscale(s); - put_bits(&s->pb, 1, 0); /* slice extra information */ + /* slice extra information */ + put_bits(&s->pb, 1, 0); } void ff_mpeg1_encode_picture_header(MpegEncContext *s, int picture_number) { + AVFrameSideData *side_data; mpeg1_encode_sequence_header(s); /* mpeg1 picture header */ @@ -378,60 +398,60 @@ void ff_mpeg1_encode_picture_header(MpegEncContext *s, int picture_number) /* temporal reference */ // RAL: s->picture_number instead of s->fake_picture_number - put_bits(&s->pb, 10, (s->picture_number - - s->gop_picture_number) & 0x3ff); + put_bits(&s->pb, 10, + (s->picture_number - s->gop_picture_number) & 0x3ff); put_bits(&s->pb, 3, s->pict_type); - s->vbv_delay_ptr= s->pb.buf + put_bits_count(&s->pb)/8; - put_bits(&s->pb, 16, 0xFFFF); /* vbv_delay */ + s->vbv_delay_ptr = s->pb.buf + put_bits_count(&s->pb) / 8; + put_bits(&s->pb, 16, 0xFFFF); /* vbv_delay */ - // RAL: Forward f_code also needed for B frames - if (s->pict_type == AV_PICTURE_TYPE_P || s->pict_type == AV_PICTURE_TYPE_B) { - put_bits(&s->pb, 1, 0); /* half pel coordinates */ - if(s->codec_id == AV_CODEC_ID_MPEG1VIDEO) - put_bits(&s->pb, 3, s->f_code); /* forward_f_code */ + // RAL: Forward f_code also needed for B-frames + if (s->pict_type == AV_PICTURE_TYPE_P || + s->pict_type == AV_PICTURE_TYPE_B) { + put_bits(&s->pb, 1, 0); /* half pel coordinates */ + if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO) + put_bits(&s->pb, 3, s->f_code); /* forward_f_code */ else - put_bits(&s->pb, 3, 7); /* forward_f_code */ + put_bits(&s->pb, 3, 7); /* forward_f_code */ } - // RAL: Backward f_code necessary for B frames + // RAL: Backward f_code necessary for B-frames if (s->pict_type == AV_PICTURE_TYPE_B) { - put_bits(&s->pb, 1, 0); /* half pel coordinates */ - if(s->codec_id == AV_CODEC_ID_MPEG1VIDEO) - put_bits(&s->pb, 3, s->b_code); /* backward_f_code */ + put_bits(&s->pb, 1, 0); /* half pel coordinates */ + if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO) + put_bits(&s->pb, 3, s->b_code); /* backward_f_code */ else - put_bits(&s->pb, 3, 7); /* backward_f_code */ + put_bits(&s->pb, 3, 7); /* backward_f_code */ } - put_bits(&s->pb, 1, 0); /* extra bit picture */ + put_bits(&s->pb, 1, 0); /* extra bit picture */ s->frame_pred_frame_dct = 1; - if(s->codec_id == AV_CODEC_ID_MPEG2VIDEO){ + if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO) { put_header(s, EXT_START_CODE); - put_bits(&s->pb, 4, 8); //pic ext - if (s->pict_type == AV_PICTURE_TYPE_P || s->pict_type == AV_PICTURE_TYPE_B) { + put_bits(&s->pb, 4, 8); /* pic ext */ + if (s->pict_type == AV_PICTURE_TYPE_P || + s->pict_type == AV_PICTURE_TYPE_B) { put_bits(&s->pb, 4, s->f_code); put_bits(&s->pb, 4, s->f_code); - }else{ + } else { put_bits(&s->pb, 8, 255); } if (s->pict_type == AV_PICTURE_TYPE_B) { put_bits(&s->pb, 4, s->b_code); put_bits(&s->pb, 4, s->b_code); - }else{ + } else { put_bits(&s->pb, 8, 255); } put_bits(&s->pb, 2, s->intra_dc_precision); av_assert0(s->picture_structure == PICT_FRAME); put_bits(&s->pb, 2, s->picture_structure); - if (s->progressive_sequence) { - put_bits(&s->pb, 1, 0); /* no repeat */ - } else { + if (s->progressive_sequence) + put_bits(&s->pb, 1, 0); /* no repeat */ + else put_bits(&s->pb, 1, s->current_picture_ptr->f.top_field_first); - } - /* XXX: optimize the generation of this flag with entropy - measures */ + /* XXX: optimize the generation of this flag with entropy measures */ s->frame_pred_frame_dct = s->progressive_sequence; put_bits(&s->pb, 1, s->frame_pred_frame_dct); @@ -441,20 +461,59 @@ void ff_mpeg1_encode_picture_header(MpegEncContext *s, int picture_number) put_bits(&s->pb, 1, s->alternate_scan); put_bits(&s->pb, 1, s->repeat_first_field); s->progressive_frame = s->progressive_sequence; - put_bits(&s->pb, 1, s->chroma_format == CHROMA_420 ? s->progressive_frame : 0); /* chroma_420_type */ + /* chroma_420_type */ + put_bits(&s->pb, 1, s->chroma_format == + CHROMA_420 ? s->progressive_frame : 0); put_bits(&s->pb, 1, s->progressive_frame); - put_bits(&s->pb, 1, 0); //composite_display_flag + put_bits(&s->pb, 1, 0); /* composite_display_flag */ } if (s->scan_offset) { int i; put_header(s, USER_START_CODE); - for(i=0; ipb, 8, svcd_scan_offset_placeholder[i]); + } + side_data = av_frame_get_side_data(&s->current_picture_ptr->f, + AV_FRAME_DATA_STEREO3D); + if (side_data) { + AVStereo3D *stereo = (AVStereo3D *)side_data->data; + uint8_t fpa_type; + + switch (stereo->type) { + case AV_STEREO3D_SIDEBYSIDE: + fpa_type = 0x03; + break; + case AV_STEREO3D_TOPBOTTOM: + fpa_type = 0x04; + break; + case AV_STEREO3D_2D: + fpa_type = 0x08; + break; + case AV_STEREO3D_SIDEBYSIDE_QUINCUNX: + fpa_type = 0x23; + break; + default: + fpa_type = 0; + break; + } + + if (fpa_type != 0) { + put_header(s, USER_START_CODE); + put_bits(&s->pb, 8, 'J'); // S3D_video_format_signaling_identifier + put_bits(&s->pb, 8, 'P'); + put_bits(&s->pb, 8, '3'); + put_bits(&s->pb, 8, 'D'); + put_bits(&s->pb, 8, 0x03); // S3D_video_format_length + + put_bits(&s->pb, 1, 1); // reserved_bit + put_bits(&s->pb, 7, fpa_type); // S3D_video_format_type + put_bits(&s->pb, 8, 0x04); // reserved_data[0] + put_bits(&s->pb, 8, 0xFF); // reserved_data[1] } } - s->mb_y=0; + s->mb_y = 0; ff_mpeg1_encode_slice_header(s); } @@ -464,505 +523,560 @@ static inline void put_mb_modes(MpegEncContext *s, int n, int bits, put_bits(&s->pb, n, bits); if (!s->frame_pred_frame_dct) { if (has_mv) - put_bits(&s->pb, 2, 2 - field_motion); /* motion_type: frame/field */ + /* motion_type: frame/field */ + put_bits(&s->pb, 2, 2 - field_motion); put_bits(&s->pb, 1, s->interlaced_dct); } } +// RAL: Parameter added: f_or_b_code +static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code) +{ + if (val == 0) { + /* zero vector */ + put_bits(&s->pb, + ff_mpeg12_mbMotionVectorTable[0][1], + ff_mpeg12_mbMotionVectorTable[0][0]); + } else { + int code, sign, bits; + int bit_size = f_or_b_code - 1; + int range = 1 << bit_size; + /* modulo encoding */ + val = sign_extend(val, 5 + bit_size); + + if (val >= 0) { + val--; + code = (val >> bit_size) + 1; + bits = val & (range - 1); + sign = 0; + } else { + val = -val; + val--; + code = (val >> bit_size) + 1; + bits = val & (range - 1); + sign = 1; + } + + av_assert2(code > 0 && code <= 16); + + put_bits(&s->pb, + ff_mpeg12_mbMotionVectorTable[code][1], + ff_mpeg12_mbMotionVectorTable[code][0]); + + put_bits(&s->pb, 1, sign); + if (bit_size > 0) + put_bits(&s->pb, bit_size, bits); + } +} + +static inline void encode_dc(MpegEncContext *s, int diff, int component) +{ + if (((unsigned) (diff + 255)) >= 511) { + int index; + + if (diff < 0) { + index = av_log2_16bit(-2 * diff); + diff--; + } else { + index = av_log2_16bit(2 * diff); + } + if (component == 0) + put_bits(&s->pb, + ff_mpeg12_vlc_dc_lum_bits[index] + index, + (ff_mpeg12_vlc_dc_lum_code[index] << index) + + (diff & ((1 << index) - 1))); + else + put_bits(&s->pb, + ff_mpeg12_vlc_dc_chroma_bits[index] + index, + (ff_mpeg12_vlc_dc_chroma_code[index] << index) + + (diff & ((1 << index) - 1))); + } else { + if (component == 0) + put_bits(&s->pb, + mpeg1_lum_dc_uni[diff + 255] & 0xFF, + mpeg1_lum_dc_uni[diff + 255] >> 8); + else + put_bits(&s->pb, + mpeg1_chr_dc_uni[diff + 255] & 0xFF, + mpeg1_chr_dc_uni[diff + 255] >> 8); + } +} + +static void mpeg1_encode_block(MpegEncContext *s, int16_t *block, int n) +{ + int alevel, level, last_non_zero, dc, diff, i, j, run, last_index, sign; + int code, component; + const uint16_t (*table_vlc)[2] = ff_rl_mpeg1.table_vlc; + + last_index = s->block_last_index[n]; + + /* DC coef */ + if (s->mb_intra) { + component = (n <= 3 ? 0 : (n & 1) + 1); + dc = block[0]; /* overflow is impossible */ + diff = dc - s->last_dc[component]; + encode_dc(s, diff, component); + s->last_dc[component] = dc; + i = 1; + if (s->intra_vlc_format) + table_vlc = ff_rl_mpeg2.table_vlc; + } else { + /* encode the first coefficient: needs to be done here because + * it is handled slightly differently */ + level = block[0]; + if (abs(level) == 1) { + code = ((uint32_t)level >> 31); /* the sign bit */ + put_bits(&s->pb, 2, code | 0x02); + i = 1; + } else { + i = 0; + last_non_zero = -1; + goto next_coef; + } + } + + /* now quantify & encode AC coefs */ + last_non_zero = i - 1; + + for (; i <= last_index; i++) { + j = s->intra_scantable.permutated[i]; + level = block[j]; + +next_coef: + /* encode using VLC */ + if (level != 0) { + run = i - last_non_zero - 1; + + alevel = level; + MASK_ABS(sign, alevel); + sign &= 1; + + if (alevel <= mpeg1_max_level[0][run]) { + code = mpeg1_index_run[0][run] + alevel - 1; + /* store the VLC & sign at once */ + put_bits(&s->pb, table_vlc[code][1] + 1, + (table_vlc[code][0] << 1) + sign); + } else { + /* escape seems to be pretty rare <5% so I do not optimize it */ + put_bits(&s->pb, table_vlc[111][1], table_vlc[111][0]); + /* escape: only clip in this case */ + put_bits(&s->pb, 6, run); + if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO) { + if (alevel < 128) { + put_sbits(&s->pb, 8, level); + } else { + if (level < 0) + put_bits(&s->pb, 16, 0x8001 + level + 255); + else + put_sbits(&s->pb, 16, level); + } + } else { + put_sbits(&s->pb, 12, level); + } + } + last_non_zero = i; + } + } + /* end of block */ + put_bits(&s->pb, table_vlc[112][1], table_vlc[112][0]); +} + static av_always_inline void mpeg1_encode_mb_internal(MpegEncContext *s, - int16_t block[6][64], - int motion_x, int motion_y, - int mb_block_count) + int16_t block[6][64], + int motion_x, int motion_y, + int mb_block_count) { int i, cbp; - const int mb_x = s->mb_x; - const int mb_y = s->mb_y; - const int first_mb= mb_x == s->resync_mb_x && mb_y == s->resync_mb_y; + const int mb_x = s->mb_x; + const int mb_y = s->mb_y; + const int first_mb = mb_x == s->resync_mb_x && mb_y == s->resync_mb_y; /* compute cbp */ cbp = 0; - for(i=0;iblock_last_index[i] >= 0) cbp |= 1 << (mb_block_count - 1 - i); - } if (cbp == 0 && !first_mb && s->mv_type == MV_TYPE_16X16 && - (mb_x != s->mb_width - 1 || (mb_y != s->end_mb_y - 1 && s->codec_id == AV_CODEC_ID_MPEG1VIDEO)) && + (mb_x != s->mb_width - 1 || + (mb_y != s->end_mb_y - 1 && s->codec_id == AV_CODEC_ID_MPEG1VIDEO)) && ((s->pict_type == AV_PICTURE_TYPE_P && (motion_x | motion_y) == 0) || - (s->pict_type == AV_PICTURE_TYPE_B && s->mv_dir == s->last_mv_dir && (((s->mv_dir & MV_DIR_FORWARD) ? ((s->mv[0][0][0] - s->last_mv[0][0][0])|(s->mv[0][0][1] - s->last_mv[0][0][1])) : 0) | - ((s->mv_dir & MV_DIR_BACKWARD) ? ((s->mv[1][0][0] - s->last_mv[1][0][0])|(s->mv[1][0][1] - s->last_mv[1][0][1])) : 0)) == 0))) { + (s->pict_type == AV_PICTURE_TYPE_B && s->mv_dir == s->last_mv_dir && + (((s->mv_dir & MV_DIR_FORWARD) + ? ((s->mv[0][0][0] - s->last_mv[0][0][0]) | + (s->mv[0][0][1] - s->last_mv[0][0][1])) : 0) | + ((s->mv_dir & MV_DIR_BACKWARD) + ? ((s->mv[1][0][0] - s->last_mv[1][0][0]) | + (s->mv[1][0][1] - s->last_mv[1][0][1])) : 0)) == 0))) { s->mb_skip_run++; s->qscale -= s->dquant; s->skip_count++; s->misc_bits++; s->last_bits++; - if(s->pict_type == AV_PICTURE_TYPE_P){ - s->last_mv[0][1][0]= s->last_mv[0][0][0]= - s->last_mv[0][1][1]= s->last_mv[0][0][1]= 0; + if (s->pict_type == AV_PICTURE_TYPE_P) { + s->last_mv[0][0][0] = + s->last_mv[0][0][1] = + s->last_mv[0][1][0] = + s->last_mv[0][1][1] = 0; } } else { - if(first_mb){ + if (first_mb) { av_assert0(s->mb_skip_run == 0); encode_mb_skip_run(s, s->mb_x); - }else{ + } else { encode_mb_skip_run(s, s->mb_skip_run); } if (s->pict_type == AV_PICTURE_TYPE_I) { - if(s->dquant && cbp){ - put_mb_modes(s, 2, 1, 0, 0); /* macroblock_type : macroblock_quant = 1 */ + if (s->dquant && cbp) { + /* macroblock_type: macroblock_quant = 1 */ + put_mb_modes(s, 2, 1, 0, 0); put_qscale(s); - }else{ - put_mb_modes(s, 1, 1, 0, 0); /* macroblock_type : macroblock_quant = 0 */ + } else { + /* macroblock_type: macroblock_quant = 0 */ + put_mb_modes(s, 1, 1, 0, 0); s->qscale -= s->dquant; } - s->misc_bits+= get_bits_diff(s); + s->misc_bits += get_bits_diff(s); s->i_count++; } else if (s->mb_intra) { - if(s->dquant && cbp){ + if (s->dquant && cbp) { put_mb_modes(s, 6, 0x01, 0, 0); put_qscale(s); - }else{ + } else { put_mb_modes(s, 5, 0x03, 0, 0); s->qscale -= s->dquant; } - s->misc_bits+= get_bits_diff(s); + s->misc_bits += get_bits_diff(s); s->i_count++; memset(s->last_mv, 0, sizeof(s->last_mv)); } else if (s->pict_type == AV_PICTURE_TYPE_P) { - if(s->mv_type == MV_TYPE_16X16){ + if (s->mv_type == MV_TYPE_16X16) { if (cbp != 0) { - if ((motion_x|motion_y) == 0) { - if(s->dquant){ - put_mb_modes(s, 5, 1, 0, 0); /* macroblock_pattern & quant */ + if ((motion_x | motion_y) == 0) { + if (s->dquant) { + /* macroblock_pattern & quant */ + put_mb_modes(s, 5, 1, 0, 0); put_qscale(s); - }else{ - put_mb_modes(s, 2, 1, 0, 0); /* macroblock_pattern only */ + } else { + /* macroblock_pattern only */ + put_mb_modes(s, 2, 1, 0, 0); } - s->misc_bits+= get_bits_diff(s); + s->misc_bits += get_bits_diff(s); } else { - if(s->dquant){ - put_mb_modes(s, 5, 2, 1, 0); /* motion + cbp */ + if (s->dquant) { + put_mb_modes(s, 5, 2, 1, 0); /* motion + cbp */ put_qscale(s); - }else{ - put_mb_modes(s, 1, 1, 1, 0); /* motion + cbp */ + } else { + put_mb_modes(s, 1, 1, 1, 0); /* motion + cbp */ } - s->misc_bits+= get_bits_diff(s); - mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); // RAL: f_code parameter added - mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); // RAL: f_code parameter added - s->mv_bits+= get_bits_diff(s); + s->misc_bits += get_bits_diff(s); + // RAL: f_code parameter added + mpeg1_encode_motion(s, + motion_x - s->last_mv[0][0][0], + s->f_code); + // RAL: f_code parameter added + mpeg1_encode_motion(s, + motion_y - s->last_mv[0][0][1], + s->f_code); + s->mv_bits += get_bits_diff(s); } } else { - put_bits(&s->pb, 3, 1); /* motion only */ + put_bits(&s->pb, 3, 1); /* motion only */ if (!s->frame_pred_frame_dct) - put_bits(&s->pb, 2, 2); /* motion_type: frame */ - s->misc_bits+= get_bits_diff(s); - mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); // RAL: f_code parameter added - mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); // RAL: f_code parameter added - s->qscale -= s->dquant; - s->mv_bits+= get_bits_diff(s); + put_bits(&s->pb, 2, 2); /* motion_type: frame */ + s->misc_bits += get_bits_diff(s); + // RAL: f_code parameter added + mpeg1_encode_motion(s, + motion_x - s->last_mv[0][0][0], + s->f_code); + // RAL: f_code parameter added + mpeg1_encode_motion(s, + motion_y - s->last_mv[0][0][1], + s->f_code); + s->qscale -= s->dquant; + s->mv_bits += get_bits_diff(s); } - s->last_mv[0][1][0]= s->last_mv[0][0][0]= motion_x; - s->last_mv[0][1][1]= s->last_mv[0][0][1]= motion_y; - }else{ + s->last_mv[0][1][0] = s->last_mv[0][0][0] = motion_x; + s->last_mv[0][1][1] = s->last_mv[0][0][1] = motion_y; + } else { av_assert2(!s->frame_pred_frame_dct && s->mv_type == MV_TYPE_FIELD); if (cbp) { - if(s->dquant){ - put_mb_modes(s, 5, 2, 1, 1); /* motion + cbp */ + if (s->dquant) { + put_mb_modes(s, 5, 2, 1, 1); /* motion + cbp */ put_qscale(s); - }else{ - put_mb_modes(s, 1, 1, 1, 1); /* motion + cbp */ + } else { + put_mb_modes(s, 1, 1, 1, 1); /* motion + cbp */ } } else { - put_bits(&s->pb, 3, 1); /* motion only */ - put_bits(&s->pb, 2, 1); /* motion_type: field */ + put_bits(&s->pb, 3, 1); /* motion only */ + put_bits(&s->pb, 2, 1); /* motion_type: field */ s->qscale -= s->dquant; } - s->misc_bits+= get_bits_diff(s); - for(i=0; i<2; i++){ + s->misc_bits += get_bits_diff(s); + for (i = 0; i < 2; i++) { put_bits(&s->pb, 1, s->field_select[0][i]); - mpeg1_encode_motion(s, s->mv[0][i][0] - s->last_mv[0][i][0] , s->f_code); - mpeg1_encode_motion(s, s->mv[0][i][1] - (s->last_mv[0][i][1]>>1), s->f_code); - s->last_mv[0][i][0]= s->mv[0][i][0]; - s->last_mv[0][i][1]= 2*s->mv[0][i][1]; + mpeg1_encode_motion(s, + s->mv[0][i][0] - s->last_mv[0][i][0], + s->f_code); + mpeg1_encode_motion(s, + s->mv[0][i][1] - (s->last_mv[0][i][1] >> 1), + s->f_code); + s->last_mv[0][i][0] = s->mv[0][i][0]; + s->last_mv[0][i][1] = 2 * s->mv[0][i][1]; } - s->mv_bits+= get_bits_diff(s); + s->mv_bits += get_bits_diff(s); } - if(cbp) { + if (cbp) { if (s->chroma_y_shift) { - put_bits(&s->pb, ff_mpeg12_mbPatTable[cbp][1], ff_mpeg12_mbPatTable[cbp][0]); + put_bits(&s->pb, + ff_mpeg12_mbPatTable[cbp][1], + ff_mpeg12_mbPatTable[cbp][0]); } else { - put_bits(&s->pb, ff_mpeg12_mbPatTable[cbp>>2][1], ff_mpeg12_mbPatTable[cbp>>2][0]); + put_bits(&s->pb, + ff_mpeg12_mbPatTable[cbp >> 2][1], + ff_mpeg12_mbPatTable[cbp >> 2][0]); put_sbits(&s->pb, 2, cbp); } } s->f_count++; - } else{ - if(s->mv_type == MV_TYPE_16X16){ - if (cbp){ // With coded bloc pattern + } else { + if (s->mv_type == MV_TYPE_16X16) { + if (cbp) { // With coded bloc pattern if (s->dquant) { - if(s->mv_dir == MV_DIR_FORWARD) + if (s->mv_dir == MV_DIR_FORWARD) put_mb_modes(s, 6, 3, 1, 0); else - put_mb_modes(s, 8-s->mv_dir, 2, 1, 0); + put_mb_modes(s, 8 - s->mv_dir, 2, 1, 0); put_qscale(s); } else { - put_mb_modes(s, 5-s->mv_dir, 3, 1, 0); + put_mb_modes(s, 5 - s->mv_dir, 3, 1, 0); } - }else{ // No coded bloc pattern - put_bits(&s->pb, 5-s->mv_dir, 2); + } else { // No coded bloc pattern + put_bits(&s->pb, 5 - s->mv_dir, 2); if (!s->frame_pred_frame_dct) put_bits(&s->pb, 2, 2); /* motion_type: frame */ s->qscale -= s->dquant; } s->misc_bits += get_bits_diff(s); - if (s->mv_dir&MV_DIR_FORWARD){ - mpeg1_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code); - mpeg1_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code); - s->last_mv[0][0][0]=s->last_mv[0][1][0]= s->mv[0][0][0]; - s->last_mv[0][0][1]=s->last_mv[0][1][1]= s->mv[0][0][1]; + if (s->mv_dir & MV_DIR_FORWARD) { + mpeg1_encode_motion(s, + s->mv[0][0][0] - s->last_mv[0][0][0], + s->f_code); + mpeg1_encode_motion(s, + s->mv[0][0][1] - s->last_mv[0][0][1], + s->f_code); + s->last_mv[0][0][0] = + s->last_mv[0][1][0] = s->mv[0][0][0]; + s->last_mv[0][0][1] = + s->last_mv[0][1][1] = s->mv[0][0][1]; s->f_count++; } - if (s->mv_dir&MV_DIR_BACKWARD){ - mpeg1_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code); - mpeg1_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code); - s->last_mv[1][0][0]=s->last_mv[1][1][0]= s->mv[1][0][0]; - s->last_mv[1][0][1]=s->last_mv[1][1][1]= s->mv[1][0][1]; + if (s->mv_dir & MV_DIR_BACKWARD) { + mpeg1_encode_motion(s, + s->mv[1][0][0] - s->last_mv[1][0][0], + s->b_code); + mpeg1_encode_motion(s, + s->mv[1][0][1] - s->last_mv[1][0][1], + s->b_code); + s->last_mv[1][0][0] = + s->last_mv[1][1][0] = s->mv[1][0][0]; + s->last_mv[1][0][1] = + s->last_mv[1][1][1] = s->mv[1][0][1]; s->b_count++; } - }else{ + } else { av_assert2(s->mv_type == MV_TYPE_FIELD); av_assert2(!s->frame_pred_frame_dct); - if (cbp){ // With coded bloc pattern + if (cbp) { // With coded bloc pattern if (s->dquant) { - if(s->mv_dir == MV_DIR_FORWARD) + if (s->mv_dir == MV_DIR_FORWARD) put_mb_modes(s, 6, 3, 1, 1); else - put_mb_modes(s, 8-s->mv_dir, 2, 1, 1); + put_mb_modes(s, 8 - s->mv_dir, 2, 1, 1); put_qscale(s); } else { - put_mb_modes(s, 5-s->mv_dir, 3, 1, 1); + put_mb_modes(s, 5 - s->mv_dir, 3, 1, 1); } - }else{ // No coded bloc pattern - put_bits(&s->pb, 5-s->mv_dir, 2); - put_bits(&s->pb, 2, 1); /* motion_type: field */ + } else { // No coded bloc pattern + put_bits(&s->pb, 5 - s->mv_dir, 2); + put_bits(&s->pb, 2, 1); /* motion_type: field */ s->qscale -= s->dquant; } s->misc_bits += get_bits_diff(s); - if (s->mv_dir&MV_DIR_FORWARD){ - for(i=0; i<2; i++){ + if (s->mv_dir & MV_DIR_FORWARD) { + for (i = 0; i < 2; i++) { put_bits(&s->pb, 1, s->field_select[0][i]); - mpeg1_encode_motion(s, s->mv[0][i][0] - s->last_mv[0][i][0] , s->f_code); - mpeg1_encode_motion(s, s->mv[0][i][1] - (s->last_mv[0][i][1]>>1), s->f_code); - s->last_mv[0][i][0]= s->mv[0][i][0]; - s->last_mv[0][i][1]= 2*s->mv[0][i][1]; + mpeg1_encode_motion(s, + s->mv[0][i][0] - s->last_mv[0][i][0], + s->f_code); + mpeg1_encode_motion(s, + s->mv[0][i][1] - (s->last_mv[0][i][1] >> 1), + s->f_code); + s->last_mv[0][i][0] = s->mv[0][i][0]; + s->last_mv[0][i][1] = s->mv[0][i][1] * 2; } s->f_count++; } - if (s->mv_dir&MV_DIR_BACKWARD){ - for(i=0; i<2; i++){ + if (s->mv_dir & MV_DIR_BACKWARD) { + for (i = 0; i < 2; i++) { put_bits(&s->pb, 1, s->field_select[1][i]); - mpeg1_encode_motion(s, s->mv[1][i][0] - s->last_mv[1][i][0] , s->b_code); - mpeg1_encode_motion(s, s->mv[1][i][1] - (s->last_mv[1][i][1]>>1), s->b_code); - s->last_mv[1][i][0]= s->mv[1][i][0]; - s->last_mv[1][i][1]= 2*s->mv[1][i][1]; + mpeg1_encode_motion(s, + s->mv[1][i][0] - s->last_mv[1][i][0], + s->b_code); + mpeg1_encode_motion(s, + s->mv[1][i][1] - (s->last_mv[1][i][1] >> 1), + s->b_code); + s->last_mv[1][i][0] = s->mv[1][i][0]; + s->last_mv[1][i][1] = s->mv[1][i][1] * 2; } s->b_count++; } } s->mv_bits += get_bits_diff(s); - if(cbp) { + if (cbp) { if (s->chroma_y_shift) { - put_bits(&s->pb, ff_mpeg12_mbPatTable[cbp][1], ff_mpeg12_mbPatTable[cbp][0]); + put_bits(&s->pb, + ff_mpeg12_mbPatTable[cbp][1], + ff_mpeg12_mbPatTable[cbp][0]); } else { - put_bits(&s->pb, ff_mpeg12_mbPatTable[cbp>>2][1], ff_mpeg12_mbPatTable[cbp>>2][0]); + put_bits(&s->pb, + ff_mpeg12_mbPatTable[cbp >> 2][1], + ff_mpeg12_mbPatTable[cbp >> 2][0]); put_sbits(&s->pb, 2, cbp); } } } - for(i=0;imb_skip_run = 0; - if(s->mb_intra) - s->i_tex_bits+= get_bits_diff(s); + if (s->mb_intra) + s->i_tex_bits += get_bits_diff(s); else - s->p_tex_bits+= get_bits_diff(s); + s->p_tex_bits += get_bits_diff(s); } } -void ff_mpeg1_encode_mb(MpegEncContext *s, int16_t block[6][64], int motion_x, int motion_y) +void ff_mpeg1_encode_mb(MpegEncContext *s, int16_t block[6][64], + int motion_x, int motion_y) { - if (s->chroma_format == CHROMA_420) mpeg1_encode_mb_internal(s, block, motion_x, motion_y, 6); - else mpeg1_encode_mb_internal(s, block, motion_x, motion_y, 8); -} - -// RAL: Parameter added: f_or_b_code -static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code) -{ - if (val == 0) { - /* zero vector */ - put_bits(&s->pb, - ff_mpeg12_mbMotionVectorTable[0][1], - ff_mpeg12_mbMotionVectorTable[0][0]); - } else { - int code, sign, bits; - int bit_size = f_or_b_code - 1; - int range = 1 << bit_size; - /* modulo encoding */ - val = sign_extend(val, 5 + bit_size); - - if (val >= 0) { - val--; - code = (val >> bit_size) + 1; - bits = val & (range - 1); - sign = 0; - } else { - val = -val; - val--; - code = (val >> bit_size) + 1; - bits = val & (range - 1); - sign = 1; - } - - av_assert2(code > 0 && code <= 16); - - put_bits(&s->pb, - ff_mpeg12_mbMotionVectorTable[code][1], - ff_mpeg12_mbMotionVectorTable[code][0]); - - put_bits(&s->pb, 1, sign); - if (bit_size > 0) { - put_bits(&s->pb, bit_size, bits); - } - } + if (s->chroma_format == CHROMA_420) + mpeg1_encode_mb_internal(s, block, motion_x, motion_y, 6); + else + mpeg1_encode_mb_internal(s, block, motion_x, motion_y, 8); } -void ff_mpeg1_encode_init(MpegEncContext *s) +av_cold void ff_mpeg1_encode_init(MpegEncContext *s) { - static int done=0; + static int done = 0; ff_mpeg12_common_init(s); - if(!done){ + if (!done) { int f_code; int mv; int i; - done=1; + done = 1; ff_init_rl(&ff_rl_mpeg1, ff_mpeg12_static_rl_table_store[0]); ff_init_rl(&ff_rl_mpeg2, ff_mpeg12_static_rl_table_store[1]); - for(i=0; i<64; i++) - { - mpeg1_max_level[0][i]= ff_rl_mpeg1.max_level[0][i]; - mpeg1_index_run[0][i]= ff_rl_mpeg1.index_run[0][i]; + for (i = 0; i < 64; i++) { + mpeg1_max_level[0][i] = ff_rl_mpeg1.max_level[0][i]; + mpeg1_index_run[0][i] = ff_rl_mpeg1.index_run[0][i]; } init_uni_ac_vlc(&ff_rl_mpeg1, uni_mpeg1_ac_vlc_len); - if(s->intra_vlc_format) + if (s->intra_vlc_format) init_uni_ac_vlc(&ff_rl_mpeg2, uni_mpeg2_ac_vlc_len); /* build unified dc encoding tables */ - for(i=-255; i<256; i++) - { - int adiff, index; - int bits, code; - int diff=i; - - adiff = FFABS(diff); - if(diff<0) diff--; - index = av_log2(2*adiff); - - bits= ff_mpeg12_vlc_dc_lum_bits[index] + index; - code= (ff_mpeg12_vlc_dc_lum_code[index]<> bit_size) + 1; - if(code<17){ - len= ff_mpeg12_mbMotionVectorTable[code][1] + 1 + bit_size; - }else{ - len= ff_mpeg12_mbMotionVectorTable[16][1] + 2 + bit_size; - } + if (code < 17) + len = ff_mpeg12_mbMotionVectorTable[code][1] + + 1 + bit_size; + else + len = ff_mpeg12_mbMotionVectorTable[16][1] + + 2 + bit_size; } - mv_penalty[f_code][mv+MAX_MV]= len; + mv_penalty[f_code][mv + MAX_MV] = len; } - } - for(f_code=MAX_FCODE; f_code>0; f_code--){ - for(mv=-(8<me.mv_penalty= mv_penalty; - s->fcode_tab= fcode_tab; - if(s->codec_id == AV_CODEC_ID_MPEG1VIDEO){ - s->min_qcoeff=-255; - s->max_qcoeff= 255; - }else{ - s->min_qcoeff=-2047; - s->max_qcoeff= 2047; + for (f_code = MAX_FCODE; f_code > 0; f_code--) + for (mv = -(8 << f_code); mv < (8 << f_code); mv++) + fcode_tab[mv + MAX_MV] = f_code; } - if (s->intra_vlc_format) { - s->intra_ac_vlc_length= - s->intra_ac_vlc_last_length= uni_mpeg2_ac_vlc_len; + s->me.mv_penalty = mv_penalty; + s->fcode_tab = fcode_tab; + if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO) { + s->min_qcoeff = -255; + s->max_qcoeff = 255; } else { - s->intra_ac_vlc_length= - s->intra_ac_vlc_last_length= uni_mpeg1_ac_vlc_len; + s->min_qcoeff = -2047; + s->max_qcoeff = 2047; } - s->inter_ac_vlc_length= - s->inter_ac_vlc_last_length= uni_mpeg1_ac_vlc_len; -} - -static inline void encode_dc(MpegEncContext *s, int diff, int component) -{ - if(((unsigned) (diff+255)) >= 511){ - int index; - - if(diff<0){ - index= av_log2_16bit(-2*diff); - diff--; - }else{ - index= av_log2_16bit(2*diff); - } - if (component == 0) { - put_bits( - &s->pb, - ff_mpeg12_vlc_dc_lum_bits[index] + index, - (ff_mpeg12_vlc_dc_lum_code[index]<pb, - ff_mpeg12_vlc_dc_chroma_bits[index] + index, - (ff_mpeg12_vlc_dc_chroma_code[index]<pb, - mpeg1_lum_dc_uni[diff+255]&0xFF, - mpeg1_lum_dc_uni[diff+255]>>8); - } else { - put_bits( - &s->pb, - mpeg1_chr_dc_uni[diff+255]&0xFF, - mpeg1_chr_dc_uni[diff+255]>>8); - } - } -} - -static void mpeg1_encode_block(MpegEncContext *s, - int16_t *block, - int n) -{ - int alevel, level, last_non_zero, dc, diff, i, j, run, last_index, sign; - int code, component; - const uint16_t (*table_vlc)[2] = ff_rl_mpeg1.table_vlc; - - last_index = s->block_last_index[n]; - - /* DC coef */ - if (s->mb_intra) { - component = (n <= 3 ? 0 : (n&1) + 1); - dc = block[0]; /* overflow is impossible */ - diff = dc - s->last_dc[component]; - encode_dc(s, diff, component); - s->last_dc[component] = dc; - i = 1; - if (s->intra_vlc_format) - table_vlc = ff_rl_mpeg2.table_vlc; + if (s->intra_vlc_format) { + s->intra_ac_vlc_length = + s->intra_ac_vlc_last_length = uni_mpeg2_ac_vlc_len; } else { - /* encode the first coefficient : needs to be done here because - it is handled slightly differently */ - level = block[0]; - if (abs(level) == 1) { - code = ((uint32_t)level >> 31); /* the sign bit */ - put_bits(&s->pb, 2, code | 0x02); - i = 1; - } else { - i = 0; - last_non_zero = -1; - goto next_coef; - } + s->intra_ac_vlc_length = + s->intra_ac_vlc_last_length = uni_mpeg1_ac_vlc_len; } - - /* now quantify & encode AC coefs */ - last_non_zero = i - 1; - - for(;i<=last_index;i++) { - j = s->intra_scantable.permutated[i]; - level = block[j]; - next_coef: - /* encode using VLC */ - if (level != 0) { - run = i - last_non_zero - 1; - - alevel= level; - MASK_ABS(sign, alevel); - sign&=1; - - if (alevel <= mpeg1_max_level[0][run]){ - code= mpeg1_index_run[0][run] + alevel - 1; - /* store the vlc & sign at once */ - put_bits(&s->pb, table_vlc[code][1]+1, (table_vlc[code][0]<<1) + sign); - } else { - /* escape seems to be pretty rare <5% so I do not optimize it */ - put_bits(&s->pb, table_vlc[111][1], table_vlc[111][0]); - /* escape: only clip in this case */ - put_bits(&s->pb, 6, run); - if(s->codec_id == AV_CODEC_ID_MPEG1VIDEO){ - if (alevel < 128) { - put_sbits(&s->pb, 8, level); - } else { - if (level < 0) { - put_bits(&s->pb, 16, 0x8001 + level + 255); - } else { - put_sbits(&s->pb, 16, level); - } - } - }else{ - put_sbits(&s->pb, 12, level); - } - } - last_non_zero = i; - } - } - /* end of block */ - put_bits(&s->pb, table_vlc[112][1], table_vlc[112][0]); + s->inter_ac_vlc_length = + s->inter_ac_vlc_last_length = uni_mpeg1_ac_vlc_len; } #define OFFSET(x) offsetof(MpegEncContext, x) #define VE AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM -#define COMMON_OPTS\ - { "gop_timecode", "MPEG GOP Timecode in hh:mm:ss[:;.]ff format", OFFSET(tc_opt_str), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, VE },\ - { "intra_vlc", "Use MPEG-2 intra VLC table.", OFFSET(intra_vlc_format), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },\ - { "drop_frame_timecode", "Timecode is in drop frame format.", OFFSET(drop_frame_timecode), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE}, \ - { "scan_offset", "Reserve space for SVCD scan offset user data.", OFFSET(scan_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, +#define COMMON_OPTS \ + { "gop_timecode", "MPEG GOP Timecode in hh:mm:ss[:;.]ff format", \ + OFFSET(tc_opt_str), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, VE },\ + { "intra_vlc", "Use MPEG-2 intra VLC table.", \ + OFFSET(intra_vlc_format), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, \ + { "drop_frame_timecode", "Timecode is in drop frame format.", \ + OFFSET(drop_frame_timecode), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, \ + { "scan_offset", "Reserve space for SVCD scan offset user data.", \ + OFFSET(scan_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, static const AVOption mpeg1_options[] = { COMMON_OPTS @@ -972,18 +1086,18 @@ static const AVOption mpeg1_options[] = { static const AVOption mpeg2_options[] = { COMMON_OPTS - { "non_linear_quant", "Use nonlinear quantizer.", OFFSET(q_scale_type), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, - { "alternate_scan", "Enable alternate scantable.", OFFSET(alternate_scan), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, + { "non_linear_quant", "Use nonlinear quantizer.", OFFSET(q_scale_type), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, + { "alternate_scan", "Enable alternate scantable.", OFFSET(alternate_scan), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, FF_MPV_COMMON_OPTS { NULL }, }; -#define mpeg12_class(x)\ -static const AVClass mpeg## x ##_class = {\ - .class_name = "mpeg" #x "video encoder",\ - .item_name = av_default_item_name,\ - .option = mpeg## x ##_options,\ - .version = LIBAVUTIL_VERSION_INT,\ +#define mpeg12_class(x) \ +static const AVClass mpeg ## x ## _class = { \ + .class_name = "mpeg" # x "video encoder", \ + .item_name = av_default_item_name, \ + .option = mpeg ## x ## _options, \ + .version = LIBAVUTIL_VERSION_INT, \ }; mpeg12_class(1) @@ -991,6 +1105,7 @@ mpeg12_class(2) AVCodec ff_mpeg1video_encoder = { .name = "mpeg1video", + .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MPEG1VIDEO, .priv_data_size = sizeof(MpegEncContext), @@ -998,15 +1113,15 @@ AVCodec ff_mpeg1video_encoder = { .encode2 = ff_MPV_encode_picture, .close = ff_MPV_encode_end, .supported_framerates = ff_mpeg12_frame_rate_tab + 1, - .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, - AV_PIX_FMT_NONE }, + .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, + AV_PIX_FMT_NONE }, .capabilities = CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video"), .priv_class = &mpeg1_class, }; AVCodec ff_mpeg2video_encoder = { .name = "mpeg2video", + .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MPEG2VIDEO, .priv_data_size = sizeof(MpegEncContext), @@ -1014,10 +1129,9 @@ AVCodec ff_mpeg2video_encoder = { .encode2 = ff_MPV_encode_picture, .close = ff_MPV_encode_end, .supported_framerates = ff_mpeg2_frame_rate_tab, - .pix_fmts = (const enum AVPixelFormat[]){ - AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_NONE - }, + .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, + AV_PIX_FMT_YUV422P, + AV_PIX_FMT_NONE }, .capabilities = CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 video"), .priv_class = &mpeg2_class, }; diff --git a/ffmpeg/libavcodec/mpeg4video.c b/ffmpeg/libavcodec/mpeg4video.c index 9b86997..3f92ba5 100644 --- a/ffmpeg/libavcodec/mpeg4video.c +++ b/ffmpeg/libavcodec/mpeg4video.c @@ -24,19 +24,20 @@ #include "mpeg4video.h" #include "mpeg4data.h" -uint8_t ff_mpeg4_static_rl_table_store[3][2][2*MAX_RUN + MAX_LEVEL + 3]; - -int ff_mpeg4_get_video_packet_prefix_length(MpegEncContext *s){ - switch(s->pict_type){ - case AV_PICTURE_TYPE_I: - return 16; - case AV_PICTURE_TYPE_P: - case AV_PICTURE_TYPE_S: - return s->f_code+15; - case AV_PICTURE_TYPE_B: - return FFMAX3(s->f_code, s->b_code, 2) + 15; - default: - return -1; +uint8_t ff_mpeg4_static_rl_table_store[3][2][2 * MAX_RUN + MAX_LEVEL + 3]; + +int ff_mpeg4_get_video_packet_prefix_length(MpegEncContext *s) +{ + switch (s->pict_type) { + case AV_PICTURE_TYPE_I: + return 16; + case AV_PICTURE_TYPE_P: + case AV_PICTURE_TYPE_S: + return s->f_code + 15; + case AV_PICTURE_TYPE_B: + return FFMAX3(s->f_code, s->b_code, 2) + 15; + default: + return -1; } } @@ -44,70 +45,75 @@ void ff_mpeg4_clean_buffers(MpegEncContext *s) { int c_wrap, c_xy, l_wrap, l_xy; - l_wrap= s->b8_stride; - l_xy= (2*s->mb_y-1)*l_wrap + s->mb_x*2 - 1; - c_wrap= s->mb_stride; - c_xy= (s->mb_y-1)*c_wrap + s->mb_x - 1; + l_wrap = s->b8_stride; + l_xy = (2 * s->mb_y - 1) * l_wrap + s->mb_x * 2 - 1; + c_wrap = s->mb_stride; + c_xy = (s->mb_y - 1) * c_wrap + s->mb_x - 1; #if 0 /* clean DC */ - memsetw(s->dc_val[0] + l_xy, 1024, l_wrap*2+1); - memsetw(s->dc_val[1] + c_xy, 1024, c_wrap+1); - memsetw(s->dc_val[2] + c_xy, 1024, c_wrap+1); + memsetw(s->dc_val[0] + l_xy, 1024, l_wrap * 2 + 1); + memsetw(s->dc_val[1] + c_xy, 1024, c_wrap + 1); + memsetw(s->dc_val[2] + c_xy, 1024, c_wrap + 1); #endif /* clean AC */ - memset(s->ac_val[0] + l_xy, 0, (l_wrap*2+1)*16*sizeof(int16_t)); - memset(s->ac_val[1] + c_xy, 0, (c_wrap +1)*16*sizeof(int16_t)); - memset(s->ac_val[2] + c_xy, 0, (c_wrap +1)*16*sizeof(int16_t)); + memset(s->ac_val[0] + l_xy, 0, (l_wrap * 2 + 1) * 16 * sizeof(int16_t)); + memset(s->ac_val[1] + c_xy, 0, (c_wrap + 1) * 16 * sizeof(int16_t)); + memset(s->ac_val[2] + c_xy, 0, (c_wrap + 1) * 16 * sizeof(int16_t)); /* clean MV */ // we can't clear the MVs as they might be needed by a b frame -// memset(s->motion_val + l_xy, 0, (l_wrap*2+1)*2*sizeof(int16_t)); -// memset(s->motion_val, 0, 2*sizeof(int16_t)*(2 + s->mb_width*2)*(2 + s->mb_height*2)); - s->last_mv[0][0][0]= - s->last_mv[0][0][1]= - s->last_mv[1][0][0]= - s->last_mv[1][0][1]= 0; +// memset(s->motion_val + l_xy, 0, (l_wrap * 2 + 1) * 2 * sizeof(int16_t)); +// memset(s->motion_val, 0, 2 * sizeof(int16_t) * (2 + s->mb_width * 2) * +// (2 + s->mb_height * 2)); + s->last_mv[0][0][0] = + s->last_mv[0][0][1] = + s->last_mv[1][0][0] = + s->last_mv[1][0][1] = 0; } #define tab_size ((signed)FF_ARRAY_ELEMS(s->direct_scale_mv[0])) -#define tab_bias (tab_size/2) +#define tab_bias (tab_size / 2) -//used by mpeg4 and rv10 decoder -void ff_mpeg4_init_direct_mv(MpegEncContext *s){ +// used by mpeg4 and rv10 decoder +void ff_mpeg4_init_direct_mv(MpegEncContext *s) +{ int i; - for(i=0; idirect_scale_mv[0][i] = (i-tab_bias)*s->pb_time/s->pp_time; - s->direct_scale_mv[1][i] = (i-tab_bias)*(s->pb_time-s->pp_time)/s->pp_time; + for (i = 0; i < tab_size; i++) { + s->direct_scale_mv[0][i] = (i - tab_bias) * s->pb_time / s->pp_time; + s->direct_scale_mv[1][i] = (i - tab_bias) * (s->pb_time - s->pp_time) / + s->pp_time; } } -static inline void ff_mpeg4_set_one_direct_mv(MpegEncContext *s, int mx, int my, int i){ - int xy= s->block_index[i]; - uint16_t time_pp= s->pp_time; - uint16_t time_pb= s->pb_time; +static inline void ff_mpeg4_set_one_direct_mv(MpegEncContext *s, int mx, + int my, int i) +{ + int xy = s->block_index[i]; + uint16_t time_pp = s->pp_time; + uint16_t time_pb = s->pb_time; int p_mx, p_my; p_mx = s->next_picture.motion_val[0][xy][0]; - if((unsigned)(p_mx + tab_bias) < tab_size){ + if ((unsigned)(p_mx + tab_bias) < tab_size) { s->mv[0][i][0] = s->direct_scale_mv[0][p_mx + tab_bias] + mx; s->mv[1][i][0] = mx ? s->mv[0][i][0] - p_mx : s->direct_scale_mv[1][p_mx + tab_bias]; - }else{ - s->mv[0][i][0] = p_mx*time_pb/time_pp + mx; + } else { + s->mv[0][i][0] = p_mx * time_pb / time_pp + mx; s->mv[1][i][0] = mx ? s->mv[0][i][0] - p_mx - : p_mx*(time_pb - time_pp)/time_pp; + : p_mx * (time_pb - time_pp) / time_pp; } p_my = s->next_picture.motion_val[0][xy][1]; - if((unsigned)(p_my + tab_bias) < tab_size){ + if ((unsigned)(p_my + tab_bias) < tab_size) { s->mv[0][i][1] = s->direct_scale_mv[0][p_my + tab_bias] + my; s->mv[1][i][1] = my ? s->mv[0][i][1] - p_my : s->direct_scale_mv[1][p_my + tab_bias]; - }else{ - s->mv[0][i][1] = p_my*time_pb/time_pp + my; + } else { + s->mv[0][i][1] = p_my * time_pb / time_pp + my; s->mv[1][i][1] = my ? s->mv[0][i][1] - p_my - : p_my*(time_pb - time_pp)/time_pp; + : p_my * (time_pb - time_pp) / time_pp; } } @@ -115,56 +121,72 @@ static inline void ff_mpeg4_set_one_direct_mv(MpegEncContext *s, int mx, int my, #undef tab_bias /** - * * @return the mb_type */ -int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my){ - const int mb_index= s->mb_x + s->mb_y*s->mb_stride; +int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my) +{ + const int mb_index = s->mb_x + s->mb_y * s->mb_stride; const int colocated_mb_type = s->next_picture.mb_type[mb_index]; uint16_t time_pp; uint16_t time_pb; int i; - //FIXME avoid divides + // FIXME avoid divides // try special case with shifts for 1 and 3 B-frames? - if(IS_8X8(colocated_mb_type)){ + if (IS_8X8(colocated_mb_type)) { s->mv_type = MV_TYPE_8X8; - for(i=0; i<4; i++){ + for (i = 0; i < 4; i++) ff_mpeg4_set_one_direct_mv(s, mx, my, i); - } return MB_TYPE_DIRECT2 | MB_TYPE_8x8 | MB_TYPE_L0L1; - } else if(IS_INTERLACED(colocated_mb_type)){ + } else if (IS_INTERLACED(colocated_mb_type)) { s->mv_type = MV_TYPE_FIELD; - for(i=0; i<2; i++){ + for (i = 0; i < 2; i++) { int field_select = s->next_picture.ref_index[0][4 * mb_index + 2 * i]; - s->field_select[0][i]= field_select; - s->field_select[1][i]= i; - if(s->top_field_first){ - time_pp= s->pp_field_time - field_select + i; - time_pb= s->pb_field_time - field_select + i; - }else{ - time_pp= s->pp_field_time + field_select - i; - time_pb= s->pb_field_time + field_select - i; + s->field_select[0][i] = field_select; + s->field_select[1][i] = i; + if (s->top_field_first) { + time_pp = s->pp_field_time - field_select + i; + time_pb = s->pb_field_time - field_select + i; + } else { + time_pp = s->pp_field_time + field_select - i; + time_pb = s->pb_field_time + field_select - i; } - s->mv[0][i][0] = s->p_field_mv_table[i][0][mb_index][0]*time_pb/time_pp + mx; - s->mv[0][i][1] = s->p_field_mv_table[i][0][mb_index][1]*time_pb/time_pp + my; - s->mv[1][i][0] = mx ? s->mv[0][i][0] - s->p_field_mv_table[i][0][mb_index][0] - : s->p_field_mv_table[i][0][mb_index][0]*(time_pb - time_pp)/time_pp; - s->mv[1][i][1] = my ? s->mv[0][i][1] - s->p_field_mv_table[i][0][mb_index][1] - : s->p_field_mv_table[i][0][mb_index][1]*(time_pb - time_pp)/time_pp; + s->mv[0][i][0] = s->p_field_mv_table[i][0][mb_index][0] * + time_pb / time_pp + mx; + s->mv[0][i][1] = s->p_field_mv_table[i][0][mb_index][1] * + time_pb / time_pp + my; + s->mv[1][i][0] = mx ? s->mv[0][i][0] - + s->p_field_mv_table[i][0][mb_index][0] + : s->p_field_mv_table[i][0][mb_index][0] * + (time_pb - time_pp) / time_pp; + s->mv[1][i][1] = my ? s->mv[0][i][1] - + s->p_field_mv_table[i][0][mb_index][1] + : s->p_field_mv_table[i][0][mb_index][1] * + (time_pb - time_pp) / time_pp; } - return MB_TYPE_DIRECT2 | MB_TYPE_16x8 | MB_TYPE_L0L1 | MB_TYPE_INTERLACED; - }else{ + return MB_TYPE_DIRECT2 | MB_TYPE_16x8 | + MB_TYPE_L0L1 | MB_TYPE_INTERLACED; + } else { ff_mpeg4_set_one_direct_mv(s, mx, my, 0); - s->mv[0][1][0] = s->mv[0][2][0] = s->mv[0][3][0] = s->mv[0][0][0]; - s->mv[0][1][1] = s->mv[0][2][1] = s->mv[0][3][1] = s->mv[0][0][1]; - s->mv[1][1][0] = s->mv[1][2][0] = s->mv[1][3][0] = s->mv[1][0][0]; - s->mv[1][1][1] = s->mv[1][2][1] = s->mv[1][3][1] = s->mv[1][0][1]; - if((s->avctx->workaround_bugs & FF_BUG_DIRECT_BLOCKSIZE) || !s->quarter_sample) - s->mv_type= MV_TYPE_16X16; + s->mv[0][1][0] = + s->mv[0][2][0] = + s->mv[0][3][0] = s->mv[0][0][0]; + s->mv[0][1][1] = + s->mv[0][2][1] = + s->mv[0][3][1] = s->mv[0][0][1]; + s->mv[1][1][0] = + s->mv[1][2][0] = + s->mv[1][3][0] = s->mv[1][0][0]; + s->mv[1][1][1] = + s->mv[1][2][1] = + s->mv[1][3][1] = s->mv[1][0][1]; + if ((s->avctx->workaround_bugs & FF_BUG_DIRECT_BLOCKSIZE) || + !s->quarter_sample) + s->mv_type = MV_TYPE_16X16; else - s->mv_type= MV_TYPE_8X8; - return MB_TYPE_DIRECT2 | MB_TYPE_16x16 | MB_TYPE_L0L1; //Note see prev line + s->mv_type = MV_TYPE_8X8; + // Note see prev line + return MB_TYPE_DIRECT2 | MB_TYPE_16x16 | MB_TYPE_L0L1; } } diff --git a/ffmpeg/libavcodec/mpeg4video.h b/ffmpeg/libavcodec/mpeg4video.h index 400ce4d..5320b0b 100644 --- a/ffmpeg/libavcodec/mpeg4video.h +++ b/ffmpeg/libavcodec/mpeg4video.h @@ -24,6 +24,7 @@ #define AVCODEC_MPEG4VIDEO_H #include + #include "get_bits.h" #include "mpegvideo.h" #include "rl.h" @@ -34,13 +35,13 @@ #define BIN_ONLY_SHAPE 2 #define GRAY_SHAPE 3 -#define SIMPLE_VO_TYPE 1 -#define CORE_VO_TYPE 3 -#define MAIN_VO_TYPE 4 -#define NBIT_VO_TYPE 5 -#define ARTS_VO_TYPE 10 -#define ACE_VO_TYPE 12 -#define ADV_SIMPLE_VO_TYPE 17 +#define SIMPLE_VO_TYPE 1 +#define CORE_VO_TYPE 3 +#define MAIN_VO_TYPE 4 +#define NBIT_VO_TYPE 5 +#define ARTS_VO_TYPE 10 +#define ACE_VO_TYPE 12 +#define ADV_SIMPLE_VO_TYPE 17 // aspect_ratio_info #define EXTENDED_PAR 15 @@ -58,11 +59,57 @@ #define VISUAL_OBJ_STARTCODE 0x1B5 #define VOP_STARTCODE 0x1B6 +typedef struct Mpeg4DecContext { + MpegEncContext m; + + /// number of bits to represent the fractional part of time + int time_increment_bits; + int shape; + int vol_sprite_usage; + int sprite_brightness_change; + int num_sprite_warping_points; + /// sprite trajectory points + uint16_t sprite_traj[4][2]; + /// sprite shift [isChroma] + int sprite_shift[2]; + + // reversible vlc + int rvlc; + /// could this stream contain resync markers + int resync_marker; + /// time distance of first I -> B, used for interlaced b frames + int t_frame; + + int new_pred; + int enhancement_type; + int scalability; + int use_intra_dc_vlc; + + /// QP above whch the ac VLC should be used for intra dc + int intra_dc_threshold; + + /* bug workarounds */ + int divx_version; + int divx_build; + int xvid_build; + int lavc_build; + + /// flag for having shown the warning about divxs invalid b frames + int showed_packed_warning; + + int cplx_estimation_trash_i; + int cplx_estimation_trash_p; + int cplx_estimation_trash_b; +} Mpeg4DecContext; + /* dc encoding for mpeg4 */ extern const uint8_t ff_mpeg4_DCtab_lum[13][2]; extern const uint8_t ff_mpeg4_DCtab_chrom[13][2]; extern const uint16_t ff_mpeg4_intra_vlc[103][2]; +extern const int8_t ff_mpeg4_intra_level[102]; +extern const int8_t ff_mpeg4_intra_run[102]; + extern RLTable ff_mpeg4_rl_intra; /* Note this is identical to the intra rvlc except that it is reordered. */ @@ -85,23 +132,25 @@ extern const uint8_t ff_mpeg4_dc_threshold[8]; void ff_mpeg4_encode_mb(MpegEncContext *s, int16_t block[6][64], int motion_x, int motion_y); -void ff_mpeg4_pred_ac(MpegEncContext * s, int16_t *block, int n, +void ff_mpeg4_pred_ac(MpegEncContext *s, int16_t *block, int n, int dir); -void ff_set_mpeg4_time(MpegEncContext * s); +void ff_set_mpeg4_time(MpegEncContext *s); void ff_mpeg4_encode_picture_header(MpegEncContext *s, int picture_number); -int ff_mpeg4_decode_picture_header(MpegEncContext * s, GetBitContext *gb); +int ff_mpeg4_decode_picture_header(Mpeg4DecContext *ctx, GetBitContext *gb); void ff_mpeg4_encode_video_packet_header(MpegEncContext *s); void ff_mpeg4_clean_buffers(MpegEncContext *s); -void ff_mpeg4_stuffing(PutBitContext * pbc); +void ff_mpeg4_stuffing(PutBitContext *pbc); void ff_mpeg4_init_partitions(MpegEncContext *s); void ff_mpeg4_merge_partitions(MpegEncContext *s); void ff_clean_mpeg4_qscales(MpegEncContext *s); -int ff_mpeg4_decode_partitions(MpegEncContext *s); +int ff_mpeg4_decode_partitions(Mpeg4DecContext *ctx); int ff_mpeg4_get_video_packet_prefix_length(MpegEncContext *s); -int ff_mpeg4_decode_video_packet_header(MpegEncContext *s); +int ff_mpeg4_decode_video_packet_header(Mpeg4DecContext *ctx); void ff_mpeg4_init_direct_mv(MpegEncContext *s); void ff_mpeg4videodec_static_init(void); +int ff_mpeg4_workaround_bugs(AVCodecContext *avctx); +int ff_mpeg4_frame_end(AVCodecContext *avctx, const uint8_t *buf, int buf_size); /** * @@ -109,8 +158,7 @@ void ff_mpeg4videodec_static_init(void); */ int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my); -extern uint8_t ff_mpeg4_static_rl_table_store[3][2][2*MAX_RUN + MAX_LEVEL + 3]; - +extern uint8_t ff_mpeg4_static_rl_table_store[3][2][2 * MAX_RUN + MAX_LEVEL + 3]; #if 0 //3IV1 is quite rare and it slows things down a tiny bit #define IS_3IV1 s->codec_tag == AV_RL32("3IV1") @@ -118,7 +166,6 @@ extern uint8_t ff_mpeg4_static_rl_table_store[3][2][2*MAX_RUN + MAX_LEVEL + 3]; #define IS_3IV1 0 #endif - /** * Predict the dc. * encoding quantized level -> quantized diff @@ -126,75 +173,81 @@ extern uint8_t ff_mpeg4_static_rl_table_store[3][2][2*MAX_RUN + MAX_LEVEL + 3]; * @param n block index (0-3 are luma, 4-5 are chroma) * @param dir_ptr pointer to an integer where the prediction direction will be stored */ -static inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, int level, int *dir_ptr, int encoding) +static inline int ff_mpeg4_pred_dc(MpegEncContext *s, int n, int level, + int *dir_ptr, int encoding) { int a, b, c, wrap, pred, scale, ret; int16_t *dc_val; /* find prediction */ - if (n < 4) { + if (n < 4) scale = s->y_dc_scale; - } else { + else scale = s->c_dc_scale; - } - if(IS_3IV1) - scale= 8; + if (IS_3IV1) + scale = 8; - wrap= s->block_wrap[n]; + wrap = s->block_wrap[n]; dc_val = s->dc_val[0] + s->block_index[n]; /* B C * A X */ - a = dc_val[ - 1]; - b = dc_val[ - 1 - wrap]; - c = dc_val[ - wrap]; - - /* outside slice handling (we can't do that by memset as we need the dc for error resilience) */ - if(s->first_slice_line && n!=3){ - if(n!=2) b=c= 1024; - if(n!=1 && s->mb_x == s->resync_mb_x) b=a= 1024; + a = dc_val[-1]; + b = dc_val[-1 - wrap]; + c = dc_val[-wrap]; + + /* outside slice handling (we can't do that by memset as we need the + * dc for error resilience) */ + if (s->first_slice_line && n != 3) { + if (n != 2) + b = c = 1024; + if (n != 1 && s->mb_x == s->resync_mb_x) + b = a = 1024; } - if(s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y+1){ - if(n==0 || n==4 || n==5) - b=1024; + if (s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y + 1) { + if (n == 0 || n == 4 || n == 5) + b = 1024; } if (abs(a - b) < abs(b - c)) { - pred = c; + pred = c; *dir_ptr = 1; /* top */ } else { - pred = a; + pred = a; *dir_ptr = 0; /* left */ } /* we assume pred is positive */ pred = FASTDIV((pred + (scale >> 1)), scale); - if(encoding){ + if (encoding) { ret = level - pred; - }else{ + } else { level += pred; - ret= level; - if(s->err_recognition&(AV_EF_BITSTREAM|AV_EF_AGGRESSIVE)){ - if(level<0){ - av_log(s->avctx, AV_LOG_ERROR, "dc<0 at %dx%d\n", s->mb_x, s->mb_y); + ret = level; + if (s->err_recognition & (AV_EF_BITSTREAM | AV_EF_AGGRESSIVE)) { + if (level < 0) { + av_log(s->avctx, AV_LOG_ERROR, + "dc<0 at %dx%d\n", s->mb_x, s->mb_y); return -1; } - if(level*scale > 2048 + scale){ - av_log(s->avctx, AV_LOG_ERROR, "dc overflow at %dx%d\n", s->mb_x, s->mb_y); + if (level * scale > 2048 + scale) { + av_log(s->avctx, AV_LOG_ERROR, + "dc overflow at %dx%d\n", s->mb_x, s->mb_y); return -1; } } } - level *=scale; - if(level&(~2047)){ - if(level<0) - level=0; - else if(!(s->workaround_bugs&FF_BUG_DC_CLIP)) - level=2047; + level *= scale; + if (level & (~2047)) { + if (level < 0) + level = 0; + else if (!(s->workaround_bugs & FF_BUG_DC_CLIP)) + level = 2047; } - dc_val[0]= level; + dc_val[0] = level; return ret; } + #endif /* AVCODEC_MPEG4VIDEO_H */ diff --git a/ffmpeg/libavcodec/mpeg4video_parser.c b/ffmpeg/libavcodec/mpeg4video_parser.c index 3cbd69d..96ed519 100644 --- a/ffmpeg/libavcodec/mpeg4video_parser.c +++ b/ffmpeg/libavcodec/mpeg4video_parser.c @@ -22,6 +22,7 @@ #define UNCHECKED_BITSTREAM_READER 1 +#include "internal.h" #include "parser.h" #include "mpegvideo.h" #include "mpeg4video.h" @@ -29,44 +30,45 @@ struct Mp4vParseContext { ParseContext pc; - struct MpegEncContext enc; + Mpeg4DecContext dec_ctx; int first_picture; }; -int ff_mpeg4_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){ +int ff_mpeg4_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size) +{ int vop_found, i; uint32_t state; - vop_found= pc->frame_start_found; - state= pc->state; + vop_found = pc->frame_start_found; + state = pc->state; - i=0; - if(!vop_found){ - for(i=0; iframe_start_found=0; - pc->state=-1; - return i-3; + for (; i < buf_size; i++) { + state = (state << 8) | buf[i]; + if ((state & 0xFFFFFF00) == 0x100) { + pc->frame_start_found = 0; + pc->state = -1; + return i - 3; } } } - pc->frame_start_found= vop_found; - pc->state= state; + pc->frame_start_found = vop_found; + pc->state = state; return END_NOT_FOUND; } @@ -76,22 +78,26 @@ static int av_mpeg4_decode_header(AVCodecParserContext *s1, const uint8_t *buf, int buf_size) { struct Mp4vParseContext *pc = s1->priv_data; - MpegEncContext *s = &pc->enc; + Mpeg4DecContext *dec_ctx = &pc->dec_ctx; + MpegEncContext *s = &dec_ctx->m; GetBitContext gb1, *gb = &gb1; int ret; - s->avctx = avctx; + s->avctx = avctx; s->current_picture_ptr = &s->current_picture; - if (avctx->extradata_size && pc->first_picture){ - init_get_bits(gb, avctx->extradata, avctx->extradata_size*8); - ret = ff_mpeg4_decode_picture_header(s, gb); + if (avctx->extradata_size && pc->first_picture) { + init_get_bits(gb, avctx->extradata, avctx->extradata_size * 8); + ret = ff_mpeg4_decode_picture_header(dec_ctx, gb); } init_get_bits(gb, buf, 8 * buf_size); - ret = ff_mpeg4_decode_picture_header(s, gb); - if (s->width && (!avctx->width || !avctx->height || !avctx->coded_width || !avctx->coded_height)) { - avcodec_set_dimensions(avctx, s->width, s->height); + ret = ff_mpeg4_decode_picture_header(dec_ctx, gb); + if (s->width && (!avctx->width || !avctx->height || + !avctx->coded_width || !avctx->coded_height)) { + ret = ff_set_dimensions(avctx, s->width, s->height); + if (ret < 0) + return ret; } if((s1->flags & PARSER_FLAG_USE_CODEC_TS) && s->avctx->time_base.den>0 && ret>=0){ av_assert1(s1->pts == AV_NOPTS_VALUE); @@ -100,7 +106,7 @@ static int av_mpeg4_decode_header(AVCodecParserContext *s1, s1->pts = av_rescale_q(s->time, (AVRational){1, s->avctx->time_base.den}, (AVRational){1, 1200000}); } - s1->pict_type= s->pict_type; + s1->pict_type = s->pict_type; pc->first_picture = 0; return ret; } @@ -111,39 +117,39 @@ static av_cold int mpeg4video_parse_init(AVCodecParserContext *s) ff_mpeg4videodec_static_init(); - pc->first_picture = 1; - pc->enc.quant_precision=5; - pc->enc.slice_context_count = 1; + pc->first_picture = 1; + pc->dec_ctx.m.quant_precision = 5; + pc->dec_ctx.m.slice_context_count = 1; + pc->dec_ctx.showed_packed_warning = 1; return 0; } static int mpeg4video_parse(AVCodecParserContext *s, - AVCodecContext *avctx, - const uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) { ParseContext *pc = s->priv_data; int next; - if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ - next= buf_size; - }else{ - next= ff_mpeg4_find_frame_end(pc, buf, buf_size); + if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { + next = buf_size; + } else { + next = ff_mpeg4_find_frame_end(pc, buf, buf_size); if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { - *poutbuf = NULL; + *poutbuf = NULL; *poutbuf_size = 0; return buf_size; } } av_mpeg4_decode_header(s, avctx, buf, buf_size); - *poutbuf = buf; + *poutbuf = buf; *poutbuf_size = buf_size; return next; } - AVCodecParser ff_mpeg4video_parser = { .codec_ids = { AV_CODEC_ID_MPEG4 }, .priv_data_size = sizeof(struct Mp4vParseContext), diff --git a/ffmpeg/libavcodec/mpeg4videodec.c b/ffmpeg/libavcodec/mpeg4videodec.c index be4aa37..34ec2b3 100644 --- a/ffmpeg/libavcodec/mpeg4videodec.c +++ b/ffmpeg/libavcodec/mpeg4videodec.c @@ -30,24 +30,23 @@ #include "h263.h" #include "thread.h" -// The defines below define the number of bits that are read at once for -// reading vlc values. Changing these may improve speed and data cache needs -// be aware though that decreasing them may need the number of stages that is -// passed to get_vlc* to be increased. +/* The defines below define the number of bits that are read at once for + * reading vlc values. Changing these may improve speed and data cache needs + * be aware though that decreasing them may need the number of stages that is + * passed to get_vlc* to be increased. */ #define SPRITE_TRAJ_VLC_BITS 6 #define DC_VLC_BITS 9 #define MB_TYPE_B_VLC_BITS 4 - static VLC dc_lum, dc_chrom; static VLC sprite_trajectory; static VLC mb_type_b_vlc; -static const int mb_type_b_map[4]= { +static const int mb_type_b_map[4] = { MB_TYPE_DIRECT2 | MB_TYPE_L0L1, - MB_TYPE_L0L1 | MB_TYPE_16x16, - MB_TYPE_L1 | MB_TYPE_16x16, - MB_TYPE_L0 | MB_TYPE_16x16, + MB_TYPE_L0L1 | MB_TYPE_16x16, + MB_TYPE_L1 | MB_TYPE_16x16, + MB_TYPE_L0 | MB_TYPE_16x16, }; /** @@ -55,304 +54,334 @@ static const int mb_type_b_map[4]= { * @param n block index (0-3 are luma, 4-5 are chroma) * @param dir the ac prediction direction */ -void ff_mpeg4_pred_ac(MpegEncContext * s, int16_t *block, int n, - int dir) +void ff_mpeg4_pred_ac(MpegEncContext *s, int16_t *block, int n, int dir) { int i; int16_t *ac_val, *ac_val1; - int8_t * const qscale_table = s->current_picture.qscale_table; + int8_t *const qscale_table = s->current_picture.qscale_table; /* find prediction */ - ac_val = s->ac_val[0][0] + s->block_index[n] * 16; + ac_val = s->ac_val[0][0] + s->block_index[n] * 16; ac_val1 = ac_val; if (s->ac_pred) { if (dir == 0) { - const int xy= s->mb_x-1 + s->mb_y*s->mb_stride; + const int xy = s->mb_x - 1 + s->mb_y * s->mb_stride; /* left prediction */ ac_val -= 16; - if(s->mb_x==0 || s->qscale == qscale_table[xy] || n==1 || n==3){ + if (s->mb_x == 0 || s->qscale == qscale_table[xy] || + n == 1 || n == 3) { /* same qscale */ - for(i=1;i<8;i++) { - block[s->dsp.idct_permutation[i<<3]] += ac_val[i]; - } - }else{ + for (i = 1; i < 8; i++) + block[s->dsp.idct_permutation[i << 3]] += ac_val[i]; + } else { /* different qscale, we must rescale */ - for(i=1;i<8;i++) { - block[s->dsp.idct_permutation[i<<3]] += ROUNDED_DIV(ac_val[i]*qscale_table[xy], s->qscale); - } + for (i = 1; i < 8; i++) + block[s->dsp.idct_permutation[i << 3]] += ROUNDED_DIV(ac_val[i] * qscale_table[xy], s->qscale); } } else { - const int xy= s->mb_x + s->mb_y*s->mb_stride - s->mb_stride; + const int xy = s->mb_x + s->mb_y * s->mb_stride - s->mb_stride; /* top prediction */ ac_val -= 16 * s->block_wrap[n]; - if(s->mb_y==0 || s->qscale == qscale_table[xy] || n==2 || n==3){ + if (s->mb_y == 0 || s->qscale == qscale_table[xy] || + n == 2 || n == 3) { /* same qscale */ - for(i=1;i<8;i++) { + for (i = 1; i < 8; i++) block[s->dsp.idct_permutation[i]] += ac_val[i + 8]; - } - }else{ + } else { /* different qscale, we must rescale */ - for(i=1;i<8;i++) { - block[s->dsp.idct_permutation[i]] += ROUNDED_DIV(ac_val[i + 8]*qscale_table[xy], s->qscale); - } + for (i = 1; i < 8; i++) + block[s->dsp.idct_permutation[i]] += ROUNDED_DIV(ac_val[i + 8] * qscale_table[xy], s->qscale); } } } /* left copy */ - for(i=1;i<8;i++) - ac_val1[i ] = block[s->dsp.idct_permutation[i<<3]]; + for (i = 1; i < 8; i++) + ac_val1[i] = block[s->dsp.idct_permutation[i << 3]]; /* top copy */ - for(i=1;i<8;i++) - ac_val1[8 + i] = block[s->dsp.idct_permutation[i ]]; - + for (i = 1; i < 8; i++) + ac_val1[8 + i] = block[s->dsp.idct_permutation[i]]; } /** * check if the next stuff is a resync marker or the end. * @return 0 if not */ -static inline int mpeg4_is_resync(MpegEncContext *s){ - int bits_count= get_bits_count(&s->gb); - int v= show_bits(&s->gb, 16); +static inline int mpeg4_is_resync(Mpeg4DecContext *ctx) +{ + MpegEncContext *s = &ctx->m; + int bits_count = get_bits_count(&s->gb); + int v = show_bits(&s->gb, 16); - if(s->workaround_bugs&FF_BUG_NO_PADDING && !s->resync_marker){ + if (s->workaround_bugs & FF_BUG_NO_PADDING && !ctx->resync_marker) return 0; - } - while(v<=0xFF){ - if(s->pict_type==AV_PICTURE_TYPE_B || (v>>(8-s->pict_type)!=1) || s->partitioned_frame) + while (v <= 0xFF) { + if (s->pict_type == AV_PICTURE_TYPE_B || + (v >> (8 - s->pict_type) != 1) || s->partitioned_frame) break; - skip_bits(&s->gb, 8+s->pict_type); - bits_count+= 8+s->pict_type; - v= show_bits(&s->gb, 16); + skip_bits(&s->gb, 8 + s->pict_type); + bits_count += 8 + s->pict_type; + v = show_bits(&s->gb, 16); } - if(bits_count + 8 >= s->gb.size_in_bits){ - v>>=8; - v|= 0x7F >> (7-(bits_count&7)); + if (bits_count + 8 >= s->gb.size_in_bits) { + v >>= 8; + v |= 0x7F >> (7 - (bits_count & 7)); - if(v==0x7F) + if (v == 0x7F) return s->mb_num; - }else{ - if(v == ff_mpeg4_resync_prefix[bits_count&7]){ + } else { + if (v == ff_mpeg4_resync_prefix[bits_count & 7]) { int len, mb_num; - int mb_num_bits= av_log2(s->mb_num - 1) + 1; - GetBitContext gb= s->gb; + int mb_num_bits = av_log2(s->mb_num - 1) + 1; + GetBitContext gb = s->gb; skip_bits(&s->gb, 1); align_get_bits(&s->gb); - for(len=0; len<32; len++){ - if(get_bits1(&s->gb)) break; - } + for (len = 0; len < 32; len++) + if (get_bits1(&s->gb)) + break; - mb_num= get_bits(&s->gb, mb_num_bits); - if(!mb_num || mb_num > s->mb_num || get_bits_count(&s->gb)+6 > s->gb.size_in_bits) + mb_num = get_bits(&s->gb, mb_num_bits); + if (!mb_num || mb_num > s->mb_num || get_bits_count(&s->gb)+6 > s->gb.size_in_bits) mb_num= -1; - s->gb= gb; + s->gb = gb; - if(len>=ff_mpeg4_get_video_packet_prefix_length(s)) + if (len >= ff_mpeg4_get_video_packet_prefix_length(s)) return mb_num; } } return 0; } -static int mpeg4_decode_sprite_trajectory(MpegEncContext * s, GetBitContext *gb) +static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *gb) { - int i; - int a= 2<sprite_warping_accuracy; - int rho= 3-s->sprite_warping_accuracy; - int r=16/a; - const int vop_ref[4][2]= {{0,0}, {s->width,0}, {0, s->height}, {s->width, s->height}}; // only true for rectangle shapes - int d[4][2]={{0,0}, {0,0}, {0,0}, {0,0}}; + MpegEncContext *s = &ctx->m; + int a = 2 << s->sprite_warping_accuracy; + int rho = 3 - s->sprite_warping_accuracy; + int r = 16 / a; + int alpha = 0; + int beta = 0; + int w = s->width; + int h = s->height; + int min_ab, i, w2, h2, w3, h3; int sprite_ref[4][2]; int virtual_ref[2][2]; - int w2, h2, w3, h3; - int alpha=0, beta=0; - int w= s->width; - int h= s->height; - int min_ab; - if(w<=0 || h<=0) - return -1; + // only true for rectangle shapes + const int vop_ref[4][2] = { { 0, 0 }, { s->width, 0 }, + { 0, s->height }, { s->width, s->height } }; + int d[4][2] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }; + + if (w <= 0 || h <= 0) + return AVERROR_INVALIDDATA; - for(i=0; inum_sprite_warping_points; i++){ + for (i = 0; i < ctx->num_sprite_warping_points; i++) { int length; - int x=0, y=0; + int x = 0, y = 0; - length= get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 3); - if(length){ - x= get_xbits(gb, length); - } - if(!(s->divx_version==500 && s->divx_build==413)) skip_bits1(gb); /* marker bit */ + length = get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 3); + if (length) + x = get_xbits(gb, length); - length= get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 3); - if(length){ - y=get_xbits(gb, length); - } - skip_bits1(gb); /* marker bit */ - s->sprite_traj[i][0]= d[i][0]= x; - s->sprite_traj[i][1]= d[i][1]= y; - } - for(; i<4; i++) - s->sprite_traj[i][0]= s->sprite_traj[i][1]= 0; - - while((1<divx_version==500 && s->divx_build==413){ - sprite_ref[0][0]= a*vop_ref[0][0] + d[0][0]; - sprite_ref[0][1]= a*vop_ref[0][1] + d[0][1]; - sprite_ref[1][0]= a*vop_ref[1][0] + d[0][0] + d[1][0]; - sprite_ref[1][1]= a*vop_ref[1][1] + d[0][1] + d[1][1]; - sprite_ref[2][0]= a*vop_ref[2][0] + d[0][0] + d[2][0]; - sprite_ref[2][1]= a*vop_ref[2][1] + d[0][1] + d[2][1]; + if (!(ctx->divx_version == 500 && ctx->divx_build == 413)) + skip_bits1(gb); /* marker bit */ + + length = get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 3); + if (length) + y = get_xbits(gb, length); + + skip_bits1(gb); /* marker bit */ + ctx->sprite_traj[i][0] = d[i][0] = x; + ctx->sprite_traj[i][1] = d[i][1] = y; + } + for (; i < 4; i++) + ctx->sprite_traj[i][0] = ctx->sprite_traj[i][1] = 0; + + while ((1 << alpha) < w) + alpha++; + while ((1 << beta) < h) + beta++; /* typo in the mpeg4 std for the definition of w' and h' */ + w2 = 1 << alpha; + h2 = 1 << beta; + + // Note, the 4th point isn't used for GMC + if (ctx->divx_version == 500 && ctx->divx_build == 413) { + sprite_ref[0][0] = a * vop_ref[0][0] + d[0][0]; + sprite_ref[0][1] = a * vop_ref[0][1] + d[0][1]; + sprite_ref[1][0] = a * vop_ref[1][0] + d[0][0] + d[1][0]; + sprite_ref[1][1] = a * vop_ref[1][1] + d[0][1] + d[1][1]; + sprite_ref[2][0] = a * vop_ref[2][0] + d[0][0] + d[2][0]; + sprite_ref[2][1] = a * vop_ref[2][1] + d[0][1] + d[2][1]; } else { - sprite_ref[0][0]= (a>>1)*(2*vop_ref[0][0] + d[0][0]); - sprite_ref[0][1]= (a>>1)*(2*vop_ref[0][1] + d[0][1]); - sprite_ref[1][0]= (a>>1)*(2*vop_ref[1][0] + d[0][0] + d[1][0]); - sprite_ref[1][1]= (a>>1)*(2*vop_ref[1][1] + d[0][1] + d[1][1]); - sprite_ref[2][0]= (a>>1)*(2*vop_ref[2][0] + d[0][0] + d[2][0]); - sprite_ref[2][1]= (a>>1)*(2*vop_ref[2][1] + d[0][1] + d[2][1]); - } -/* sprite_ref[3][0]= (a>>1)*(2*vop_ref[3][0] + d[0][0] + d[1][0] + d[2][0] + d[3][0]); - sprite_ref[3][1]= (a>>1)*(2*vop_ref[3][1] + d[0][1] + d[1][1] + d[2][1] + d[3][1]); */ - -// this is mostly identical to the mpeg4 std (and is totally unreadable because of that ...) -// perhaps it should be reordered to be more readable ... -// the idea behind this virtual_ref mess is to be able to use shifts later per pixel instead of divides -// so the distance between points is converted from w&h based to w2&h2 based which are of the 2^x form - virtual_ref[0][0]= 16*(vop_ref[0][0] + w2) - + ROUNDED_DIV(((w - w2)*(r*sprite_ref[0][0] - 16*vop_ref[0][0]) + w2*(r*sprite_ref[1][0] - 16*vop_ref[1][0])),w); - virtual_ref[0][1]= 16*vop_ref[0][1] - + ROUNDED_DIV(((w - w2)*(r*sprite_ref[0][1] - 16*vop_ref[0][1]) + w2*(r*sprite_ref[1][1] - 16*vop_ref[1][1])),w); - virtual_ref[1][0]= 16*vop_ref[0][0] - + ROUNDED_DIV(((h - h2)*(r*sprite_ref[0][0] - 16*vop_ref[0][0]) + h2*(r*sprite_ref[2][0] - 16*vop_ref[2][0])),h); - virtual_ref[1][1]= 16*(vop_ref[0][1] + h2) - + ROUNDED_DIV(((h - h2)*(r*sprite_ref[0][1] - 16*vop_ref[0][1]) + h2*(r*sprite_ref[2][1] - 16*vop_ref[2][1])),h); - - switch(s->num_sprite_warping_points) - { - case 0: - s->sprite_offset[0][0]= 0; - s->sprite_offset[0][1]= 0; - s->sprite_offset[1][0]= 0; - s->sprite_offset[1][1]= 0; - s->sprite_delta[0][0]= a; - s->sprite_delta[0][1]= 0; - s->sprite_delta[1][0]= 0; - s->sprite_delta[1][1]= a; - s->sprite_shift[0]= 0; - s->sprite_shift[1]= 0; - break; - case 1: //GMC only - s->sprite_offset[0][0]= sprite_ref[0][0] - a*vop_ref[0][0]; - s->sprite_offset[0][1]= sprite_ref[0][1] - a*vop_ref[0][1]; - s->sprite_offset[1][0]= ((sprite_ref[0][0]>>1)|(sprite_ref[0][0]&1)) - a*(vop_ref[0][0]/2); - s->sprite_offset[1][1]= ((sprite_ref[0][1]>>1)|(sprite_ref[0][1]&1)) - a*(vop_ref[0][1]/2); - s->sprite_delta[0][0]= a; - s->sprite_delta[0][1]= 0; - s->sprite_delta[1][0]= 0; - s->sprite_delta[1][1]= a; - s->sprite_shift[0]= 0; - s->sprite_shift[1]= 0; - break; - case 2: - s->sprite_offset[0][0]= (sprite_ref[0][0]<<(alpha+rho)) - + (-r*sprite_ref[0][0] + virtual_ref[0][0])*(-vop_ref[0][0]) - + ( r*sprite_ref[0][1] - virtual_ref[0][1])*(-vop_ref[0][1]) - + (1<<(alpha+rho-1)); - s->sprite_offset[0][1]= (sprite_ref[0][1]<<(alpha+rho)) - + (-r*sprite_ref[0][1] + virtual_ref[0][1])*(-vop_ref[0][0]) - + (-r*sprite_ref[0][0] + virtual_ref[0][0])*(-vop_ref[0][1]) - + (1<<(alpha+rho-1)); - s->sprite_offset[1][0]= ( (-r*sprite_ref[0][0] + virtual_ref[0][0])*(-2*vop_ref[0][0] + 1) - +( r*sprite_ref[0][1] - virtual_ref[0][1])*(-2*vop_ref[0][1] + 1) - +2*w2*r*sprite_ref[0][0] - - 16*w2 - + (1<<(alpha+rho+1))); - s->sprite_offset[1][1]= ( (-r*sprite_ref[0][1] + virtual_ref[0][1])*(-2*vop_ref[0][0] + 1) - +(-r*sprite_ref[0][0] + virtual_ref[0][0])*(-2*vop_ref[0][1] + 1) - +2*w2*r*sprite_ref[0][1] - - 16*w2 - + (1<<(alpha+rho+1))); - s->sprite_delta[0][0]= (-r*sprite_ref[0][0] + virtual_ref[0][0]); - s->sprite_delta[0][1]= (+r*sprite_ref[0][1] - virtual_ref[0][1]); - s->sprite_delta[1][0]= (-r*sprite_ref[0][1] + virtual_ref[0][1]); - s->sprite_delta[1][1]= (-r*sprite_ref[0][0] + virtual_ref[0][0]); - - s->sprite_shift[0]= alpha+rho; - s->sprite_shift[1]= alpha+rho+2; - break; - case 3: - min_ab= FFMIN(alpha, beta); - w3= w2>>min_ab; - h3= h2>>min_ab; - s->sprite_offset[0][0]= (sprite_ref[0][0]<<(alpha+beta+rho-min_ab)) - + (-r*sprite_ref[0][0] + virtual_ref[0][0])*h3*(-vop_ref[0][0]) - + (-r*sprite_ref[0][0] + virtual_ref[1][0])*w3*(-vop_ref[0][1]) - + (1<<(alpha+beta+rho-min_ab-1)); - s->sprite_offset[0][1]= (sprite_ref[0][1]<<(alpha+beta+rho-min_ab)) - + (-r*sprite_ref[0][1] + virtual_ref[0][1])*h3*(-vop_ref[0][0]) - + (-r*sprite_ref[0][1] + virtual_ref[1][1])*w3*(-vop_ref[0][1]) - + (1<<(alpha+beta+rho-min_ab-1)); - s->sprite_offset[1][0]= (-r*sprite_ref[0][0] + virtual_ref[0][0])*h3*(-2*vop_ref[0][0] + 1) - + (-r*sprite_ref[0][0] + virtual_ref[1][0])*w3*(-2*vop_ref[0][1] + 1) - + 2*w2*h3*r*sprite_ref[0][0] - - 16*w2*h3 - + (1<<(alpha+beta+rho-min_ab+1)); - s->sprite_offset[1][1]= (-r*sprite_ref[0][1] + virtual_ref[0][1])*h3*(-2*vop_ref[0][0] + 1) - + (-r*sprite_ref[0][1] + virtual_ref[1][1])*w3*(-2*vop_ref[0][1] + 1) - + 2*w2*h3*r*sprite_ref[0][1] - - 16*w2*h3 - + (1<<(alpha+beta+rho-min_ab+1)); - s->sprite_delta[0][0]= (-r*sprite_ref[0][0] + virtual_ref[0][0])*h3; - s->sprite_delta[0][1]= (-r*sprite_ref[0][0] + virtual_ref[1][0])*w3; - s->sprite_delta[1][0]= (-r*sprite_ref[0][1] + virtual_ref[0][1])*h3; - s->sprite_delta[1][1]= (-r*sprite_ref[0][1] + virtual_ref[1][1])*w3; - - s->sprite_shift[0]= alpha + beta + rho - min_ab; - s->sprite_shift[1]= alpha + beta + rho - min_ab + 2; - break; + sprite_ref[0][0] = (a >> 1) * (2 * vop_ref[0][0] + d[0][0]); + sprite_ref[0][1] = (a >> 1) * (2 * vop_ref[0][1] + d[0][1]); + sprite_ref[1][0] = (a >> 1) * (2 * vop_ref[1][0] + d[0][0] + d[1][0]); + sprite_ref[1][1] = (a >> 1) * (2 * vop_ref[1][1] + d[0][1] + d[1][1]); + sprite_ref[2][0] = (a >> 1) * (2 * vop_ref[2][0] + d[0][0] + d[2][0]); + sprite_ref[2][1] = (a >> 1) * (2 * vop_ref[2][1] + d[0][1] + d[2][1]); + } + /* sprite_ref[3][0] = (a >> 1) * (2 * vop_ref[3][0] + d[0][0] + d[1][0] + d[2][0] + d[3][0]); + * sprite_ref[3][1] = (a >> 1) * (2 * vop_ref[3][1] + d[0][1] + d[1][1] + d[2][1] + d[3][1]); */ + + /* this is mostly identical to the mpeg4 std (and is totally unreadable + * because of that...). Perhaps it should be reordered to be more readable. + * The idea behind this virtual_ref mess is to be able to use shifts later + * per pixel instead of divides so the distance between points is converted + * from w&h based to w2&h2 based which are of the 2^x form. */ + virtual_ref[0][0] = 16 * (vop_ref[0][0] + w2) + + ROUNDED_DIV(((w - w2) * + (r * sprite_ref[0][0] - 16 * vop_ref[0][0]) + + w2 * (r * sprite_ref[1][0] - 16 * vop_ref[1][0])), w); + virtual_ref[0][1] = 16 * vop_ref[0][1] + + ROUNDED_DIV(((w - w2) * + (r * sprite_ref[0][1] - 16 * vop_ref[0][1]) + + w2 * (r * sprite_ref[1][1] - 16 * vop_ref[1][1])), w); + virtual_ref[1][0] = 16 * vop_ref[0][0] + + ROUNDED_DIV(((h - h2) * (r * sprite_ref[0][0] - 16 * vop_ref[0][0]) + + h2 * (r * sprite_ref[2][0] - 16 * vop_ref[2][0])), h); + virtual_ref[1][1] = 16 * (vop_ref[0][1] + h2) + + ROUNDED_DIV(((h - h2) * (r * sprite_ref[0][1] - 16 * vop_ref[0][1]) + + h2 * (r * sprite_ref[2][1] - 16 * vop_ref[2][1])), h); + + switch (ctx->num_sprite_warping_points) { + case 0: + s->sprite_offset[0][0] = + s->sprite_offset[0][1] = + s->sprite_offset[1][0] = + s->sprite_offset[1][1] = 0; + s->sprite_delta[0][0] = a; + s->sprite_delta[0][1] = + s->sprite_delta[1][0] = 0; + s->sprite_delta[1][1] = a; + ctx->sprite_shift[0] = + ctx->sprite_shift[1] = 0; + break; + case 1: // GMC only + s->sprite_offset[0][0] = sprite_ref[0][0] - a * vop_ref[0][0]; + s->sprite_offset[0][1] = sprite_ref[0][1] - a * vop_ref[0][1]; + s->sprite_offset[1][0] = ((sprite_ref[0][0] >> 1) | (sprite_ref[0][0] & 1)) - + a * (vop_ref[0][0] / 2); + s->sprite_offset[1][1] = ((sprite_ref[0][1] >> 1) | (sprite_ref[0][1] & 1)) - + a * (vop_ref[0][1] / 2); + s->sprite_delta[0][0] = a; + s->sprite_delta[0][1] = + s->sprite_delta[1][0] = 0; + s->sprite_delta[1][1] = a; + ctx->sprite_shift[0] = + ctx->sprite_shift[1] = 0; + break; + case 2: + s->sprite_offset[0][0] = (sprite_ref[0][0] << (alpha + rho)) + + (-r * sprite_ref[0][0] + virtual_ref[0][0]) * + (-vop_ref[0][0]) + + (r * sprite_ref[0][1] - virtual_ref[0][1]) * + (-vop_ref[0][1]) + (1 << (alpha + rho - 1)); + s->sprite_offset[0][1] = (sprite_ref[0][1] << (alpha + rho)) + + (-r * sprite_ref[0][1] + virtual_ref[0][1]) * + (-vop_ref[0][0]) + + (-r * sprite_ref[0][0] + virtual_ref[0][0]) * + (-vop_ref[0][1]) + (1 << (alpha + rho - 1)); + s->sprite_offset[1][0] = ((-r * sprite_ref[0][0] + virtual_ref[0][0]) * + (-2 * vop_ref[0][0] + 1) + + (r * sprite_ref[0][1] - virtual_ref[0][1]) * + (-2 * vop_ref[0][1] + 1) + 2 * w2 * r * + sprite_ref[0][0] - 16 * w2 + (1 << (alpha + rho + 1))); + s->sprite_offset[1][1] = ((-r * sprite_ref[0][1] + virtual_ref[0][1]) * + (-2 * vop_ref[0][0] + 1) + + (-r * sprite_ref[0][0] + virtual_ref[0][0]) * + (-2 * vop_ref[0][1] + 1) + 2 * w2 * r * + sprite_ref[0][1] - 16 * w2 + (1 << (alpha + rho + 1))); + s->sprite_delta[0][0] = (-r * sprite_ref[0][0] + virtual_ref[0][0]); + s->sprite_delta[0][1] = (+r * sprite_ref[0][1] - virtual_ref[0][1]); + s->sprite_delta[1][0] = (-r * sprite_ref[0][1] + virtual_ref[0][1]); + s->sprite_delta[1][1] = (-r * sprite_ref[0][0] + virtual_ref[0][0]); + + ctx->sprite_shift[0] = alpha + rho; + ctx->sprite_shift[1] = alpha + rho + 2; + break; + case 3: + min_ab = FFMIN(alpha, beta); + w3 = w2 >> min_ab; + h3 = h2 >> min_ab; + s->sprite_offset[0][0] = (sprite_ref[0][0] << (alpha + beta + rho - min_ab)) + + (-r * sprite_ref[0][0] + virtual_ref[0][0]) * + h3 * (-vop_ref[0][0]) + + (-r * sprite_ref[0][0] + virtual_ref[1][0]) * + w3 * (-vop_ref[0][1]) + + (1 << (alpha + beta + rho - min_ab - 1)); + s->sprite_offset[0][1] = (sprite_ref[0][1] << (alpha + beta + rho - min_ab)) + + (-r * sprite_ref[0][1] + virtual_ref[0][1]) * + h3 * (-vop_ref[0][0]) + + (-r * sprite_ref[0][1] + virtual_ref[1][1]) * + w3 * (-vop_ref[0][1]) + + (1 << (alpha + beta + rho - min_ab - 1)); + s->sprite_offset[1][0] = (-r * sprite_ref[0][0] + virtual_ref[0][0]) * + h3 * (-2 * vop_ref[0][0] + 1) + + (-r * sprite_ref[0][0] + virtual_ref[1][0]) * + w3 * (-2 * vop_ref[0][1] + 1) + 2 * w2 * h3 * + r * sprite_ref[0][0] - 16 * w2 * h3 + + (1 << (alpha + beta + rho - min_ab + 1)); + s->sprite_offset[1][1] = (-r * sprite_ref[0][1] + virtual_ref[0][1]) * + h3 * (-2 * vop_ref[0][0] + 1) + + (-r * sprite_ref[0][1] + virtual_ref[1][1]) * + w3 * (-2 * vop_ref[0][1] + 1) + 2 * w2 * h3 * + r * sprite_ref[0][1] - 16 * w2 * h3 + + (1 << (alpha + beta + rho - min_ab + 1)); + s->sprite_delta[0][0] = (-r * sprite_ref[0][0] + virtual_ref[0][0]) * h3; + s->sprite_delta[0][1] = (-r * sprite_ref[0][0] + virtual_ref[1][0]) * w3; + s->sprite_delta[1][0] = (-r * sprite_ref[0][1] + virtual_ref[0][1]) * h3; + s->sprite_delta[1][1] = (-r * sprite_ref[0][1] + virtual_ref[1][1]) * w3; + + ctx->sprite_shift[0] = alpha + beta + rho - min_ab; + ctx->sprite_shift[1] = alpha + beta + rho - min_ab + 2; + break; } /* try to simplify the situation */ - if( s->sprite_delta[0][0] == a<sprite_shift[0] - && s->sprite_delta[0][1] == 0 - && s->sprite_delta[1][0] == 0 - && s->sprite_delta[1][1] == a<sprite_shift[0]) - { - s->sprite_offset[0][0]>>=s->sprite_shift[0]; - s->sprite_offset[0][1]>>=s->sprite_shift[0]; - s->sprite_offset[1][0]>>=s->sprite_shift[1]; - s->sprite_offset[1][1]>>=s->sprite_shift[1]; - s->sprite_delta[0][0]= a; - s->sprite_delta[0][1]= 0; - s->sprite_delta[1][0]= 0; - s->sprite_delta[1][1]= a; - s->sprite_shift[0]= 0; - s->sprite_shift[1]= 0; - s->real_sprite_warping_points=1; - } - else{ - int shift_y= 16 - s->sprite_shift[0]; - int shift_c= 16 - s->sprite_shift[1]; - for(i=0; i<2; i++){ - s->sprite_offset[0][i]<<= shift_y; - s->sprite_offset[1][i]<<= shift_c; - s->sprite_delta[0][i]<<= shift_y; - s->sprite_delta[1][i]<<= shift_y; - s->sprite_shift[i]= 16; + if (s->sprite_delta[0][0] == a << ctx->sprite_shift[0] && + s->sprite_delta[0][1] == 0 && + s->sprite_delta[1][0] == 0 && + s->sprite_delta[1][1] == a << ctx->sprite_shift[0]) { + s->sprite_offset[0][0] >>= ctx->sprite_shift[0]; + s->sprite_offset[0][1] >>= ctx->sprite_shift[0]; + s->sprite_offset[1][0] >>= ctx->sprite_shift[1]; + s->sprite_offset[1][1] >>= ctx->sprite_shift[1]; + s->sprite_delta[0][0] = a; + s->sprite_delta[0][1] = 0; + s->sprite_delta[1][0] = 0; + s->sprite_delta[1][1] = a; + ctx->sprite_shift[0] = 0; + ctx->sprite_shift[1] = 0; + s->real_sprite_warping_points = 1; + } else { + int shift_y = 16 - ctx->sprite_shift[0]; + int shift_c = 16 - ctx->sprite_shift[1]; + for (i = 0; i < 2; i++) { + s->sprite_offset[0][i] <<= shift_y; + s->sprite_offset[1][i] <<= shift_c; + s->sprite_delta[0][i] <<= shift_y; + s->sprite_delta[1][i] <<= shift_y; + ctx->sprite_shift[i] = 16; } - s->real_sprite_warping_points= s->num_sprite_warping_points; + s->real_sprite_warping_points = ctx->num_sprite_warping_points; } + + return 0; +} + +static int decode_new_pred(Mpeg4DecContext *ctx, GetBitContext *gb) { + int len = FFMIN(ctx->time_increment_bits + 3, 15); + + get_bits(gb, len); + if (get_bits1(gb)) + get_bits(gb, len); + check_marker(gb, "after new_pred"); + return 0; } @@ -360,85 +389,91 @@ static int mpeg4_decode_sprite_trajectory(MpegEncContext * s, GetBitContext *gb) * Decode the next video packet. * @return <0 if something went wrong */ -int ff_mpeg4_decode_video_packet_header(MpegEncContext *s) +int ff_mpeg4_decode_video_packet_header(Mpeg4DecContext *ctx) { - int mb_num_bits= av_log2(s->mb_num - 1) + 1; - int header_extension=0, mb_num, len; + MpegEncContext *s = &ctx->m; + + int mb_num_bits = av_log2(s->mb_num - 1) + 1; + int header_extension = 0, mb_num, len; /* is there enough space left for a video packet + header */ - if( get_bits_count(&s->gb) > s->gb.size_in_bits-20) return -1; + if (get_bits_count(&s->gb) > s->gb.size_in_bits - 20) + return -1; - for(len=0; len<32; len++){ - if(get_bits1(&s->gb)) break; - } + for (len = 0; len < 32; len++) + if (get_bits1(&s->gb)) + break; - if(len!=ff_mpeg4_get_video_packet_prefix_length(s)){ + if (len != ff_mpeg4_get_video_packet_prefix_length(s)) { av_log(s->avctx, AV_LOG_ERROR, "marker does not match f_code\n"); return -1; } - if(s->shape != RECT_SHAPE){ - header_extension= get_bits1(&s->gb); - //FIXME more stuff here + if (ctx->shape != RECT_SHAPE) { + header_extension = get_bits1(&s->gb); + // FIXME more stuff here } - mb_num= get_bits(&s->gb, mb_num_bits); - if(mb_num>=s->mb_num){ - av_log(s->avctx, AV_LOG_ERROR, "illegal mb_num in video packet (%d %d) \n", mb_num, s->mb_num); + mb_num = get_bits(&s->gb, mb_num_bits); + if (mb_num >= s->mb_num) { + av_log(s->avctx, AV_LOG_ERROR, + "illegal mb_num in video packet (%d %d) \n", mb_num, s->mb_num); return -1; } - s->mb_x= mb_num % s->mb_width; - s->mb_y= mb_num / s->mb_width; + s->mb_x = mb_num % s->mb_width; + s->mb_y = mb_num / s->mb_width; - if(s->shape != BIN_ONLY_SHAPE){ - int qscale= get_bits(&s->gb, s->quant_precision); - if(qscale) - s->chroma_qscale=s->qscale= qscale; + if (ctx->shape != BIN_ONLY_SHAPE) { + int qscale = get_bits(&s->gb, s->quant_precision); + if (qscale) + s->chroma_qscale = s->qscale = qscale; } - if(s->shape == RECT_SHAPE){ - header_extension= get_bits1(&s->gb); - } - if(header_extension){ - int time_incr=0; + if (ctx->shape == RECT_SHAPE) + header_extension = get_bits1(&s->gb); + + if (header_extension) { + int time_incr = 0; while (get_bits1(&s->gb) != 0) time_incr++; check_marker(&s->gb, "before time_increment in video packed header"); - skip_bits(&s->gb, s->time_increment_bits); /* time_increment */ + skip_bits(&s->gb, ctx->time_increment_bits); /* time_increment */ check_marker(&s->gb, "before vop_coding_type in video packed header"); skip_bits(&s->gb, 2); /* vop coding type */ - //FIXME not rect stuff here + // FIXME not rect stuff here - if(s->shape != BIN_ONLY_SHAPE){ + if (ctx->shape != BIN_ONLY_SHAPE) { skip_bits(&s->gb, 3); /* intra dc vlc threshold */ -//FIXME don't just ignore everything - if(s->pict_type == AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE){ - if(mpeg4_decode_sprite_trajectory(s, &s->gb) < 0) - return -1; + // FIXME don't just ignore everything + if (s->pict_type == AV_PICTURE_TYPE_S && + ctx->vol_sprite_usage == GMC_SPRITE) { + if (mpeg4_decode_sprite_trajectory(ctx, &s->gb) < 0) + return AVERROR_INVALIDDATA; av_log(s->avctx, AV_LOG_ERROR, "untested\n"); } - //FIXME reduced res stuff here + // FIXME reduced res stuff here if (s->pict_type != AV_PICTURE_TYPE_I) { int f_code = get_bits(&s->gb, 3); /* fcode_for */ - if(f_code==0){ - av_log(s->avctx, AV_LOG_ERROR, "Error, video packet header damaged (f_code=0)\n"); - } + if (f_code == 0) + av_log(s->avctx, AV_LOG_ERROR, + "Error, video packet header damaged (f_code=0)\n"); } if (s->pict_type == AV_PICTURE_TYPE_B) { int b_code = get_bits(&s->gb, 3); - if(b_code==0){ - av_log(s->avctx, AV_LOG_ERROR, "Error, video packet header damaged (b_code=0)\n"); - } + if (b_code == 0) + av_log(s->avctx, AV_LOG_ERROR, + "Error, video packet header damaged (b_code=0)\n"); } } } - //FIXME new-pred stuff + if (ctx->new_pred) + decode_new_pred(ctx, &s->gb); return 0; } @@ -448,43 +483,49 @@ int ff_mpeg4_decode_video_packet_header(MpegEncContext *s) * @param n either 0 for the x component or 1 for y * @return the average MV for a GMC MB */ -static inline int get_amv(MpegEncContext *s, int n){ +static inline int get_amv(Mpeg4DecContext *ctx, int n) +{ + MpegEncContext *s = &ctx->m; int x, y, mb_v, sum, dx, dy, shift; - int len = 1 << (s->f_code + 4); - const int a= s->sprite_warping_accuracy; + int len = 1 << (s->f_code + 4); + const int a = s->sprite_warping_accuracy; - if(s->workaround_bugs & FF_BUG_AMV) + if (s->workaround_bugs & FF_BUG_AMV) len >>= s->quarter_sample; - if(s->real_sprite_warping_points==1){ - if(s->divx_version==500 && s->divx_build==413) - sum= s->sprite_offset[0][n] / (1<<(a - s->quarter_sample)); + if (s->real_sprite_warping_points == 1) { + if (ctx->divx_version == 500 && ctx->divx_build == 413) + sum = s->sprite_offset[0][n] / (1 << (a - s->quarter_sample)); + else + sum = RSHIFT(s->sprite_offset[0][n] << s->quarter_sample, a); + } else { + dx = s->sprite_delta[n][0]; + dy = s->sprite_delta[n][1]; + shift = ctx->sprite_shift[0]; + if (n) + dy -= 1 << (shift + a + 1); else - sum= RSHIFT(s->sprite_offset[0][n]<quarter_sample, a); - }else{ - dx= s->sprite_delta[n][0]; - dy= s->sprite_delta[n][1]; - shift= s->sprite_shift[0]; - if(n) dy -= 1<<(shift + a + 1); - else dx -= 1<<(shift + a + 1); - mb_v= s->sprite_offset[0][n] + dx*s->mb_x*16 + dy*s->mb_y*16; - - sum=0; - for(y=0; y<16; y++){ + dx -= 1 << (shift + a + 1); + mb_v = s->sprite_offset[0][n] + dx * s->mb_x * 16 + dy * s->mb_y * 16; + + sum = 0; + for (y = 0; y < 16; y++) { int v; - v= mb_v + dy*y; - //XXX FIXME optimize - for(x=0; x<16; x++){ - sum+= v>>shift; - v+= dx; + v = mb_v + dy * y; + // FIXME optimize + for (x = 0; x < 16; x++) { + sum += v >> shift; + v += dx; } } - sum= RSHIFT(sum, a+8-s->quarter_sample); + sum = RSHIFT(sum, a + 8 - s->quarter_sample); } - if (sum < -len) sum= -len; - else if (sum >= len) sum= len-1; + if (sum < -len) + sum = -len; + else if (sum >= len) + sum = len - 1; return sum; } @@ -495,7 +536,7 @@ static inline int get_amv(MpegEncContext *s, int n){ * @param dir_ptr the prediction direction will be stored here * @return the quantized dc */ -static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr) +static inline int mpeg4_decode_dc(MpegEncContext *s, int n, int *dir_ptr) { int level, code; @@ -503,29 +544,31 @@ static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr) code = get_vlc2(&s->gb, dc_lum.table, DC_VLC_BITS, 1); else code = get_vlc2(&s->gb, dc_chrom.table, DC_VLC_BITS, 1); - if (code < 0 || code > 9 /* && s->nbit<9 */){ + + if (code < 0 || code > 9 /* && s->nbit < 9 */) { av_log(s->avctx, AV_LOG_ERROR, "illegal dc vlc\n"); return -1; } + if (code == 0) { level = 0; } else { - if(IS_3IV1){ - if(code==1) - level= 2*get_bits1(&s->gb)-1; - else{ - if(get_bits1(&s->gb)) - level = get_bits(&s->gb, code-1) + (1<<(code-1)); + if (IS_3IV1) { + if (code == 1) + level = 2 * get_bits1(&s->gb) - 1; + else { + if (get_bits1(&s->gb)) + level = get_bits(&s->gb, code - 1) + (1 << (code - 1)); else - level = -get_bits(&s->gb, code-1) - (1<<(code-1)); + level = -get_bits(&s->gb, code - 1) - (1 << (code - 1)); } - }else{ + } else { level = get_xbits(&s->gb, code); } - if (code > 8){ - if(get_bits1(&s->gb)==0){ /* marker */ - if(s->err_recognition&(AV_EF_BITSTREAM|AV_EF_COMPLIANT)){ + if (code > 8) { + if (get_bits1(&s->gb) == 0) { /* marker */ + if (s->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT)) { av_log(s->avctx, AV_LOG_ERROR, "dc marker bit missing\n"); return -1; } @@ -540,124 +583,145 @@ static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr) * Decode first partition. * @return number of MBs decoded or <0 if an error occurred */ -static int mpeg4_decode_partition_a(MpegEncContext *s){ - int mb_num; +static int mpeg4_decode_partition_a(Mpeg4DecContext *ctx) +{ + MpegEncContext *s = &ctx->m; + int mb_num = 0; static const int8_t quant_tab[4] = { -1, -2, 1, 2 }; /* decode first partition */ - mb_num=0; - s->first_slice_line=1; - for(; s->mb_ymb_height; s->mb_y++){ + s->first_slice_line = 1; + for (; s->mb_y < s->mb_height; s->mb_y++) { ff_init_block_index(s); - for(; s->mb_xmb_width; s->mb_x++){ - const int xy= s->mb_x + s->mb_y*s->mb_stride; + for (; s->mb_x < s->mb_width; s->mb_x++) { + const int xy = s->mb_x + s->mb_y * s->mb_stride; int cbpc; - int dir=0; + int dir = 0; mb_num++; ff_update_block_index(s); - if(s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y+1) - s->first_slice_line=0; + if (s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y + 1) + s->first_slice_line = 0; - if(s->pict_type==AV_PICTURE_TYPE_I){ + if (s->pict_type == AV_PICTURE_TYPE_I) { int i; - do{ - if(show_bits_long(&s->gb, 19)==DC_MARKER){ - return mb_num-1; - } + do { + if (show_bits_long(&s->gb, 19) == DC_MARKER) + return mb_num - 1; cbpc = get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2); - if (cbpc < 0){ - av_log(s->avctx, AV_LOG_ERROR, "cbpc corrupted at %d %d\n", s->mb_x, s->mb_y); + if (cbpc < 0) { + av_log(s->avctx, AV_LOG_ERROR, + "cbpc corrupted at %d %d\n", s->mb_x, s->mb_y); return -1; } - }while(cbpc == 8); + } while (cbpc == 8); - s->cbp_table[xy]= cbpc & 3; + s->cbp_table[xy] = cbpc & 3; s->current_picture.mb_type[xy] = MB_TYPE_INTRA; - s->mb_intra = 1; + s->mb_intra = 1; - if(cbpc & 4) { + if (cbpc & 4) ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]); - } - s->current_picture.qscale_table[xy]= s->qscale; - s->mbintra_table[xy]= 1; - for(i=0; i<6; i++){ + s->current_picture.qscale_table[xy] = s->qscale; + + s->mbintra_table[xy] = 1; + for (i = 0; i < 6; i++) { int dc_pred_dir; - int dc= mpeg4_decode_dc(s, i, &dc_pred_dir); - if(dc < 0){ - av_log(s->avctx, AV_LOG_ERROR, "DC corrupted at %d %d\n", s->mb_x, s->mb_y); + int dc = mpeg4_decode_dc(s, i, &dc_pred_dir); + if (dc < 0) { + av_log(s->avctx, AV_LOG_ERROR, + "DC corrupted at %d %d\n", s->mb_x, s->mb_y); return -1; } - dir<<=1; - if(dc_pred_dir) dir|=1; + dir <<= 1; + if (dc_pred_dir) + dir |= 1; } - s->pred_dir_table[xy]= dir; - }else{ /* P/S_TYPE */ + s->pred_dir_table[xy] = dir; + } else { /* P/S_TYPE */ int mx, my, pred_x, pred_y, bits; - int16_t * const mot_val = s->current_picture.motion_val[0][s->block_index[0]]; - const int stride= s->b8_stride*2; + int16_t *const mot_val = s->current_picture.motion_val[0][s->block_index[0]]; + const int stride = s->b8_stride * 2; try_again: - bits= show_bits(&s->gb, 17); - if(bits==MOTION_MARKER){ - return mb_num-1; - } + bits = show_bits(&s->gb, 17); + if (bits == MOTION_MARKER) + return mb_num - 1; + skip_bits1(&s->gb); - if(bits&0x10000){ + if (bits & 0x10000) { /* skip mb */ - if(s->pict_type==AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE){ - s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_GMC | MB_TYPE_L0; - mx= get_amv(s, 0); - my= get_amv(s, 1); - }else{ - s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; - mx=my=0; + if (s->pict_type == AV_PICTURE_TYPE_S && + ctx->vol_sprite_usage == GMC_SPRITE) { + s->current_picture.mb_type[xy] = MB_TYPE_SKIP | + MB_TYPE_16x16 | + MB_TYPE_GMC | + MB_TYPE_L0; + mx = get_amv(ctx, 0); + my = get_amv(ctx, 1); + } else { + s->current_picture.mb_type[xy] = MB_TYPE_SKIP | + MB_TYPE_16x16 | + MB_TYPE_L0; + mx = my = 0; } - mot_val[0 ]= mot_val[2 ]= - mot_val[0+stride]= mot_val[2+stride]= mx; - mot_val[1 ]= mot_val[3 ]= - mot_val[1+stride]= mot_val[3+stride]= my; - - if(s->mbintra_table[xy]) + mot_val[0] = + mot_val[2] = + mot_val[0 + stride] = + mot_val[2 + stride] = mx; + mot_val[1] = + mot_val[3] = + mot_val[1 + stride] = + mot_val[3 + stride] = my; + + if (s->mbintra_table[xy]) ff_clean_intra_table_entries(s); continue; } cbpc = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2); - if (cbpc < 0){ - av_log(s->avctx, AV_LOG_ERROR, "cbpc corrupted at %d %d\n", s->mb_x, s->mb_y); + if (cbpc < 0) { + av_log(s->avctx, AV_LOG_ERROR, + "cbpc corrupted at %d %d\n", s->mb_x, s->mb_y); return -1; } - if(cbpc == 20) + if (cbpc == 20) goto try_again; - s->cbp_table[xy]= cbpc&(8+3); //8 is dquant + s->cbp_table[xy] = cbpc & (8 + 3); // 8 is dquant s->mb_intra = ((cbpc & 4) != 0); - if(s->mb_intra){ + if (s->mb_intra) { s->current_picture.mb_type[xy] = MB_TYPE_INTRA; - s->mbintra_table[xy]= 1; - mot_val[0 ]= mot_val[2 ]= - mot_val[0+stride]= mot_val[2+stride]= 0; - mot_val[1 ]= mot_val[3 ]= - mot_val[1+stride]= mot_val[3+stride]= 0; - }else{ - if(s->mbintra_table[xy]) + s->mbintra_table[xy] = 1; + mot_val[0] = + mot_val[2] = + mot_val[0 + stride] = + mot_val[2 + stride] = 0; + mot_val[1] = + mot_val[3] = + mot_val[1 + stride] = + mot_val[3 + stride] = 0; + } else { + if (s->mbintra_table[xy]) ff_clean_intra_table_entries(s); - if(s->pict_type==AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE && (cbpc & 16) == 0) - s->mcsel= get_bits1(&s->gb); - else s->mcsel= 0; + if (s->pict_type == AV_PICTURE_TYPE_S && + ctx->vol_sprite_usage == GMC_SPRITE && + (cbpc & 16) == 0) + s->mcsel = get_bits1(&s->gb); + else + s->mcsel = 0; if ((cbpc & 16) == 0) { /* 16x16 motion prediction */ ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); - if(!s->mcsel){ + if (!s->mcsel) { mx = ff_h263_decode_motion(s, pred_x, s->f_code); if (mx >= 0xffff) return -1; @@ -665,22 +729,30 @@ try_again: my = ff_h263_decode_motion(s, pred_y, s->f_code); if (my >= 0xffff) return -1; - s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0; + s->current_picture.mb_type[xy] = MB_TYPE_16x16 | + MB_TYPE_L0; } else { - mx = get_amv(s, 0); - my = get_amv(s, 1); - s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_GMC | MB_TYPE_L0; + mx = get_amv(ctx, 0); + my = get_amv(ctx, 1); + s->current_picture.mb_type[xy] = MB_TYPE_16x16 | + MB_TYPE_GMC | + MB_TYPE_L0; } - mot_val[0 ]= mot_val[2 ] = - mot_val[0+stride]= mot_val[2+stride]= mx; - mot_val[1 ]= mot_val[3 ]= - mot_val[1+stride]= mot_val[3+stride]= my; + mot_val[0] = + mot_val[2] = + mot_val[0 + stride] = + mot_val[2 + stride] = mx; + mot_val[1] = + mot_val[3] = + mot_val[1 + stride] = + mot_val[3 + stride] = my; } else { int i; - s->current_picture.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0; - for(i=0;i<4;i++) { - int16_t *mot_val= ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y); + s->current_picture.mb_type[xy] = MB_TYPE_8x8 | + MB_TYPE_L0; + for (i = 0; i < 4; i++) { + int16_t *mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y); mx = ff_h263_decode_motion(s, pred_x, s->f_code); if (mx >= 0xffff) return -1; @@ -695,7 +767,7 @@ try_again: } } } - s->mb_x= 0; + s->mb_x = 0; } return mb_num; @@ -705,85 +777,91 @@ try_again: * decode second partition. * @return <0 if an error occurred */ -static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){ - int mb_num=0; +static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count) +{ + int mb_num = 0; static const int8_t quant_tab[4] = { -1, -2, 1, 2 }; - s->mb_x= s->resync_mb_x; - s->first_slice_line=1; - for(s->mb_y= s->resync_mb_y; mb_num < mb_count; s->mb_y++){ + s->mb_x = s->resync_mb_x; + s->first_slice_line = 1; + for (s->mb_y = s->resync_mb_y; mb_num < mb_count; s->mb_y++) { ff_init_block_index(s); - for(; mb_num < mb_count && s->mb_xmb_width; s->mb_x++){ - const int xy= s->mb_x + s->mb_y*s->mb_stride; + for (; mb_num < mb_count && s->mb_x < s->mb_width; s->mb_x++) { + const int xy = s->mb_x + s->mb_y * s->mb_stride; mb_num++; ff_update_block_index(s); - if(s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y+1) - s->first_slice_line=0; - - if(s->pict_type==AV_PICTURE_TYPE_I){ - int ac_pred= get_bits1(&s->gb); - int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1); - if(cbpy<0){ - av_log(s->avctx, AV_LOG_ERROR, "cbpy corrupted at %d %d\n", s->mb_x, s->mb_y); + if (s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y + 1) + s->first_slice_line = 0; + + if (s->pict_type == AV_PICTURE_TYPE_I) { + int ac_pred = get_bits1(&s->gb); + int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1); + if (cbpy < 0) { + av_log(s->avctx, AV_LOG_ERROR, + "cbpy corrupted at %d %d\n", s->mb_x, s->mb_y); return -1; } - s->cbp_table[xy]|= cbpy<<2; - s->current_picture.mb_type[xy] |= ac_pred*MB_TYPE_ACPRED; - }else{ /* P || S_TYPE */ + s->cbp_table[xy] |= cbpy << 2; + s->current_picture.mb_type[xy] |= ac_pred * MB_TYPE_ACPRED; + } else { /* P || S_TYPE */ if (IS_INTRA(s->current_picture.mb_type[xy])) { - int dir=0,i; + int i; + int dir = 0; int ac_pred = get_bits1(&s->gb); - int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1); + int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1); - if(cbpy<0){ - av_log(s->avctx, AV_LOG_ERROR, "I cbpy corrupted at %d %d\n", s->mb_x, s->mb_y); + if (cbpy < 0) { + av_log(s->avctx, AV_LOG_ERROR, + "I cbpy corrupted at %d %d\n", s->mb_x, s->mb_y); return -1; } - if(s->cbp_table[xy] & 8) { + if (s->cbp_table[xy] & 8) ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]); - } s->current_picture.qscale_table[xy] = s->qscale; - for(i=0; i<6; i++){ + for (i = 0; i < 6; i++) { int dc_pred_dir; - int dc= mpeg4_decode_dc(s, i, &dc_pred_dir); - if(dc < 0){ - av_log(s->avctx, AV_LOG_ERROR, "DC corrupted at %d %d\n", s->mb_x, s->mb_y); + int dc = mpeg4_decode_dc(s, i, &dc_pred_dir); + if (dc < 0) { + av_log(s->avctx, AV_LOG_ERROR, + "DC corrupted at %d %d\n", s->mb_x, s->mb_y); return -1; } - dir<<=1; - if(dc_pred_dir) dir|=1; + dir <<= 1; + if (dc_pred_dir) + dir |= 1; } - s->cbp_table[xy]&= 3; //remove dquant - s->cbp_table[xy]|= cbpy<<2; - s->current_picture.mb_type[xy] |= ac_pred*MB_TYPE_ACPRED; - s->pred_dir_table[xy]= dir; + s->cbp_table[xy] &= 3; // remove dquant + s->cbp_table[xy] |= cbpy << 2; + s->current_picture.mb_type[xy] |= ac_pred * MB_TYPE_ACPRED; + s->pred_dir_table[xy] = dir; } else if (IS_SKIP(s->current_picture.mb_type[xy])) { s->current_picture.qscale_table[xy] = s->qscale; - s->cbp_table[xy]= 0; - }else{ + s->cbp_table[xy] = 0; + } else { int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1); - if(cbpy<0){ - av_log(s->avctx, AV_LOG_ERROR, "P cbpy corrupted at %d %d\n", s->mb_x, s->mb_y); + if (cbpy < 0) { + av_log(s->avctx, AV_LOG_ERROR, + "P cbpy corrupted at %d %d\n", s->mb_x, s->mb_y); return -1; } - if(s->cbp_table[xy] & 8) { + if (s->cbp_table[xy] & 8) ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]); - } s->current_picture.qscale_table[xy] = s->qscale; - s->cbp_table[xy]&= 3; //remove dquant - s->cbp_table[xy]|= (cbpy^0xf)<<2; + s->cbp_table[xy] &= 3; // remove dquant + s->cbp_table[xy] |= (cbpy ^ 0xf) << 2; } } } - if(mb_num >= mb_count) return 0; - s->mb_x= 0; + if (mb_num >= mb_count) + return 0; + s->mb_x = 0; } return 0; } @@ -792,50 +870,60 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){ * Decode the first and second partition. * @return <0 if error (and sets error type in the error_status_table) */ -int ff_mpeg4_decode_partitions(MpegEncContext *s) +int ff_mpeg4_decode_partitions(Mpeg4DecContext *ctx) { + MpegEncContext *s = &ctx->m; int mb_num; - const int part_a_error= s->pict_type==AV_PICTURE_TYPE_I ? (ER_DC_ERROR|ER_MV_ERROR) : ER_MV_ERROR; - const int part_a_end = s->pict_type==AV_PICTURE_TYPE_I ? (ER_DC_END |ER_MV_END) : ER_MV_END; + const int part_a_error = s->pict_type == AV_PICTURE_TYPE_I ? (ER_DC_ERROR | ER_MV_ERROR) : ER_MV_ERROR; + const int part_a_end = s->pict_type == AV_PICTURE_TYPE_I ? (ER_DC_END | ER_MV_END) : ER_MV_END; - mb_num= mpeg4_decode_partition_a(s); - if(mb_num<0){ - ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, part_a_error); + mb_num = mpeg4_decode_partition_a(ctx); + if (mb_num < 0) { + ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, + s->mb_x, s->mb_y, part_a_error); return -1; } - if(s->resync_mb_x + s->resync_mb_y*s->mb_width + mb_num > s->mb_num){ + if (s->resync_mb_x + s->resync_mb_y * s->mb_width + mb_num > s->mb_num) { av_log(s->avctx, AV_LOG_ERROR, "slice below monitor ...\n"); - ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, part_a_error); + ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, + s->mb_x, s->mb_y, part_a_error); return -1; } - s->mb_num_left= mb_num; + s->mb_num_left = mb_num; - if(s->pict_type==AV_PICTURE_TYPE_I){ - while(show_bits(&s->gb, 9) == 1) + if (s->pict_type == AV_PICTURE_TYPE_I) { + while (show_bits(&s->gb, 9) == 1) skip_bits(&s->gb, 9); - if(get_bits_long(&s->gb, 19)!=DC_MARKER){ - av_log(s->avctx, AV_LOG_ERROR, "marker missing after first I partition at %d %d\n", s->mb_x, s->mb_y); + if (get_bits_long(&s->gb, 19) != DC_MARKER) { + av_log(s->avctx, AV_LOG_ERROR, + "marker missing after first I partition at %d %d\n", + s->mb_x, s->mb_y); return -1; } - }else{ - while(show_bits(&s->gb, 10) == 1) + } else { + while (show_bits(&s->gb, 10) == 1) skip_bits(&s->gb, 10); - if(get_bits(&s->gb, 17)!=MOTION_MARKER){ - av_log(s->avctx, AV_LOG_ERROR, "marker missing after first P partition at %d %d\n", s->mb_x, s->mb_y); + if (get_bits(&s->gb, 17) != MOTION_MARKER) { + av_log(s->avctx, AV_LOG_ERROR, + "marker missing after first P partition at %d %d\n", + s->mb_x, s->mb_y); return -1; } } - ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, part_a_end); + ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, + s->mb_x - 1, s->mb_y, part_a_end); - if( mpeg4_decode_partition_b(s, mb_num) < 0){ - if(s->pict_type==AV_PICTURE_TYPE_P) - ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_DC_ERROR); + if (mpeg4_decode_partition_b(s, mb_num) < 0) { + if (s->pict_type == AV_PICTURE_TYPE_P) + ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, + s->mb_x, s->mb_y, ER_DC_ERROR); return -1; - }else{ - if(s->pict_type==AV_PICTURE_TYPE_P) - ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_DC_END); + } else { + if (s->pict_type == AV_PICTURE_TYPE_P) + ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, + s->mb_x - 1, s->mb_y, ER_DC_END); } return 0; @@ -845,243 +933,265 @@ int ff_mpeg4_decode_partitions(MpegEncContext *s) * Decode a block. * @return <0 if an error occurred */ -static inline int mpeg4_decode_block(MpegEncContext * s, int16_t * block, - int n, int coded, int intra, int rvlc) +static inline int mpeg4_decode_block(Mpeg4DecContext *ctx, int16_t *block, + int n, int coded, int intra, int rvlc) { - int level, i, last, run; + MpegEncContext *s = &ctx->m; + int level, i, last, run, qmul, qadd; int av_uninit(dc_pred_dir); - RLTable * rl; - RL_VLC_ELEM * rl_vlc; - const uint8_t * scan_table; - int qmul, qadd; - - //Note intra & rvlc should be optimized away if this is inlined - - if(intra) { - if(s->use_intra_dc_vlc){ - /* DC coef */ - if(s->partitioned_frame){ - level = s->dc_val[0][ s->block_index[n] ]; - if(n<4) level= FASTDIV((level + (s->y_dc_scale>>1)), s->y_dc_scale); - else level= FASTDIV((level + (s->c_dc_scale>>1)), s->c_dc_scale); - dc_pred_dir= (s->pred_dir_table[s->mb_x + s->mb_y*s->mb_stride]<use_intra_dc_vlc) { + /* DC coef */ + if (s->partitioned_frame) { + level = s->dc_val[0][s->block_index[n]]; + if (n < 4) + level = FASTDIV((level + (s->y_dc_scale >> 1)), s->y_dc_scale); + else + level = FASTDIV((level + (s->c_dc_scale >> 1)), s->c_dc_scale); + dc_pred_dir = (s->pred_dir_table[s->mb_x + s->mb_y * s->mb_stride] << n) & 32; + } else { + level = mpeg4_decode_dc(s, n, &dc_pred_dir); + if (level < 0) + return -1; + } + block[0] = level; + i = 0; + } else { i = -1; ff_mpeg4_pred_dc(s, n, 0, &dc_pred_dir, 0); - } - if (!coded) - goto not_coded; - - if(rvlc){ - rl = &ff_rvlc_rl_intra; - rl_vlc = ff_rvlc_rl_intra.rl_vlc[0]; - }else{ - rl = &ff_mpeg4_rl_intra; - rl_vlc = ff_mpeg4_rl_intra.rl_vlc[0]; - } - if (s->ac_pred) { - if (dc_pred_dir == 0) - scan_table = s->intra_v_scantable.permutated; /* left */ - else - scan_table = s->intra_h_scantable.permutated; /* top */ - } else { + } + if (!coded) + goto not_coded; + + if (rvlc) { + rl = &ff_rvlc_rl_intra; + rl_vlc = ff_rvlc_rl_intra.rl_vlc[0]; + } else { + rl = &ff_mpeg4_rl_intra; + rl_vlc = ff_mpeg4_rl_intra.rl_vlc[0]; + } + if (s->ac_pred) { + if (dc_pred_dir == 0) + scan_table = s->intra_v_scantable.permutated; /* left */ + else + scan_table = s->intra_h_scantable.permutated; /* top */ + } else { scan_table = s->intra_scantable.permutated; - } - qmul=1; - qadd=0; + } + qmul = 1; + qadd = 0; } else { i = -1; if (!coded) { s->block_last_index[n] = i; return 0; } - if(rvlc) rl = &ff_rvlc_rl_inter; - else rl = &ff_h263_rl_inter; + if (rvlc) + rl = &ff_rvlc_rl_inter; + else + rl = &ff_h263_rl_inter; scan_table = s->intra_scantable.permutated; - if(s->mpeg_quant){ - qmul=1; - qadd=0; - if(rvlc){ + if (s->mpeg_quant) { + qmul = 1; + qadd = 0; + if (rvlc) rl_vlc = ff_rvlc_rl_inter.rl_vlc[0]; - }else{ + else rl_vlc = ff_h263_rl_inter.rl_vlc[0]; - } - }else{ + } else { qmul = s->qscale << 1; qadd = (s->qscale - 1) | 1; - if(rvlc){ + if (rvlc) rl_vlc = ff_rvlc_rl_inter.rl_vlc[s->qscale]; - }else{ + else rl_vlc = ff_h263_rl_inter.rl_vlc[s->qscale]; - } } } - { - OPEN_READER(re, &s->gb); - for(;;) { - UPDATE_CACHE(re, &s->gb); - GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 0); - if (level==0) { - /* escape */ - if(rvlc){ - if(SHOW_UBITS(re, &s->gb, 1)==0){ - av_log(s->avctx, AV_LOG_ERROR, "1. marker bit missing in rvlc esc\n"); - return -1; - }; SKIP_CACHE(re, &s->gb, 1); + { + OPEN_READER(re, &s->gb); + for (;;) { + UPDATE_CACHE(re, &s->gb); + GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 0); + if (level == 0) { + /* escape */ + if (rvlc) { + if (SHOW_UBITS(re, &s->gb, 1) == 0) { + av_log(s->avctx, AV_LOG_ERROR, + "1. marker bit missing in rvlc esc\n"); + return -1; + } + SKIP_CACHE(re, &s->gb, 1); - last= SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1); - run= SHOW_UBITS(re, &s->gb, 6); - SKIP_COUNTER(re, &s->gb, 1+1+6); - UPDATE_CACHE(re, &s->gb); + last = SHOW_UBITS(re, &s->gb, 1); + SKIP_CACHE(re, &s->gb, 1); + run = SHOW_UBITS(re, &s->gb, 6); + SKIP_COUNTER(re, &s->gb, 1 + 1 + 6); + UPDATE_CACHE(re, &s->gb); - if(SHOW_UBITS(re, &s->gb, 1)==0){ - av_log(s->avctx, AV_LOG_ERROR, "2. marker bit missing in rvlc esc\n"); - return -1; - }; SKIP_CACHE(re, &s->gb, 1); + if (SHOW_UBITS(re, &s->gb, 1) == 0) { + av_log(s->avctx, AV_LOG_ERROR, + "2. marker bit missing in rvlc esc\n"); + return -1; + } + SKIP_CACHE(re, &s->gb, 1); - level= SHOW_UBITS(re, &s->gb, 11); SKIP_CACHE(re, &s->gb, 11); + level = SHOW_UBITS(re, &s->gb, 11); + SKIP_CACHE(re, &s->gb, 11); - if(SHOW_UBITS(re, &s->gb, 5)!=0x10){ - av_log(s->avctx, AV_LOG_ERROR, "reverse esc missing\n"); - return -1; - }; SKIP_CACHE(re, &s->gb, 5); + if (SHOW_UBITS(re, &s->gb, 5) != 0x10) { + av_log(s->avctx, AV_LOG_ERROR, "reverse esc missing\n"); + return -1; + } + SKIP_CACHE(re, &s->gb, 5); - level= level * qmul + qadd; - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - SKIP_COUNTER(re, &s->gb, 1+11+5+1); - - i+= run + 1; - if(last) i+=192; - }else{ - int cache; - cache= GET_CACHE(re, &s->gb); - - if(IS_3IV1) - cache ^= 0xC0000000; - - if (cache&0x80000000) { - if (cache&0x40000000) { - /* third escape */ - SKIP_CACHE(re, &s->gb, 2); - last= SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1); - run= SHOW_UBITS(re, &s->gb, 6); - SKIP_COUNTER(re, &s->gb, 2+1+6); - UPDATE_CACHE(re, &s->gb); + level = level * qmul + qadd; + level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); + SKIP_COUNTER(re, &s->gb, 1 + 11 + 5 + 1); - if(IS_3IV1){ - level= SHOW_SBITS(re, &s->gb, 12); LAST_SKIP_BITS(re, &s->gb, 12); - }else{ - if(SHOW_UBITS(re, &s->gb, 1)==0){ - av_log(s->avctx, AV_LOG_ERROR, "1. marker bit missing in 3. esc\n"); - return -1; - }; SKIP_CACHE(re, &s->gb, 1); + i += run + 1; + if (last) + i += 192; + } else { + int cache; + cache = GET_CACHE(re, &s->gb); + + if (IS_3IV1) + cache ^= 0xC0000000; + + if (cache & 0x80000000) { + if (cache & 0x40000000) { + /* third escape */ + SKIP_CACHE(re, &s->gb, 2); + last = SHOW_UBITS(re, &s->gb, 1); + SKIP_CACHE(re, &s->gb, 1); + run = SHOW_UBITS(re, &s->gb, 6); + SKIP_COUNTER(re, &s->gb, 2 + 1 + 6); + UPDATE_CACHE(re, &s->gb); + + if (IS_3IV1) { + level = SHOW_SBITS(re, &s->gb, 12); + LAST_SKIP_BITS(re, &s->gb, 12); + } else { + if (SHOW_UBITS(re, &s->gb, 1) == 0) { + av_log(s->avctx, AV_LOG_ERROR, + "1. marker bit missing in 3. esc\n"); + return -1; + } + SKIP_CACHE(re, &s->gb, 1); - level= SHOW_SBITS(re, &s->gb, 12); SKIP_CACHE(re, &s->gb, 12); + level = SHOW_SBITS(re, &s->gb, 12); + SKIP_CACHE(re, &s->gb, 12); - if(SHOW_UBITS(re, &s->gb, 1)==0){ - av_log(s->avctx, AV_LOG_ERROR, "2. marker bit missing in 3. esc\n"); - return -1; - } + if (SHOW_UBITS(re, &s->gb, 1) == 0) { + av_log(s->avctx, AV_LOG_ERROR, + "2. marker bit missing in 3. esc\n"); + return -1; + } - SKIP_COUNTER(re, &s->gb, 1+12+1); - } + SKIP_COUNTER(re, &s->gb, 1 + 12 + 1); + } #if 0 - if(s->error_recognition >= FF_ER_COMPLIANT){ - const int abs_level= FFABS(level); - if(abs_level<=MAX_LEVEL && run<=MAX_RUN){ - const int run1= run - rl->max_run[last][abs_level] - 1; - if(abs_level <= rl->max_level[last][run]){ - av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, vlc encoding possible\n"); - return -1; - } - if(s->error_recognition > FF_ER_COMPLIANT){ - if(abs_level <= rl->max_level[last][run]*2){ - av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 1 encoding possible\n"); - return -1; - } - if(run1 >= 0 && abs_level <= rl->max_level[last][run1]){ - av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 2 encoding possible\n"); - return -1; + if (s->error_recognition >= FF_ER_COMPLIANT) { + const int abs_level= FFABS(level); + if (abs_level<=MAX_LEVEL && run<=MAX_RUN) { + const int run1= run - rl->max_run[last][abs_level] - 1; + if (abs_level <= rl->max_level[last][run]) { + av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, vlc encoding possible\n"); + return -1; + } + if (s->error_recognition > FF_ER_COMPLIANT) { + if (abs_level <= rl->max_level[last][run]*2) { + av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 1 encoding possible\n"); + return -1; + } + if (run1 >= 0 && abs_level <= rl->max_level[last][run1]) { + av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 2 encoding possible\n"); + return -1; + } + } } } - } - } #endif - if (level>0) level= level * qmul + qadd; - else level= level * qmul - qadd; - - if((unsigned)(level + 2048) > 4095){ - if(s->err_recognition & (AV_EF_BITSTREAM|AV_EF_AGGRESSIVE)){ - if(level > 2560 || level<-2560){ - av_log(s->avctx, AV_LOG_ERROR, "|level| overflow in 3. esc, qp=%d\n", s->qscale); - return -1; + if (level > 0) + level = level * qmul + qadd; + else + level = level * qmul - qadd; + + if ((unsigned)(level + 2048) > 4095) { + if (s->err_recognition & (AV_EF_BITSTREAM|AV_EF_AGGRESSIVE)) { + if (level > 2560 || level < -2560) { + av_log(s->avctx, AV_LOG_ERROR, + "|level| overflow in 3. esc, qp=%d\n", + s->qscale); + return -1; + } + } + level = level < 0 ? -2048 : 2047; } + + i += run + 1; + if (last) + i += 192; + } else { + /* second escape */ + SKIP_BITS(re, &s->gb, 2); + GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1); + i += run + rl->max_run[run >> 7][level / qmul] + 1; // FIXME opt indexing + level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); + LAST_SKIP_BITS(re, &s->gb, 1); } - level= level<0 ? -2048 : 2047; + } else { + /* first escape */ + SKIP_BITS(re, &s->gb, 1); + GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1); + i += run; + level = level + rl->max_level[run >> 7][(run - 1) & 63] * qmul; // FIXME opt indexing + level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); + LAST_SKIP_BITS(re, &s->gb, 1); } - - i+= run + 1; - if(last) i+=192; - } else { - /* second escape */ - SKIP_BITS(re, &s->gb, 2); - GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1); - i+= run + rl->max_run[run>>7][level/qmul] +1; //FIXME opt indexing - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - LAST_SKIP_BITS(re, &s->gb, 1); } } else { - /* first escape */ - SKIP_BITS(re, &s->gb, 1); - GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1); - i+= run; - level = level + rl->max_level[run>>7][(run-1)&63] * qmul;//FIXME opt indexing + i += run; level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); LAST_SKIP_BITS(re, &s->gb, 1); } - } - } else { - i+= run; - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - LAST_SKIP_BITS(re, &s->gb, 1); - } - if (i > 62){ - i-= 192; - if(i&(~63)){ - av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); - return -1; + if (i > 62) { + i -= 192; + if (i & (~63)) { + av_log(s->avctx, AV_LOG_ERROR, + "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + + block[scan_table[i]] = level; + break; } block[scan_table[i]] = level; - break; } - - block[scan_table[i]] = level; + CLOSE_READER(re, &s->gb); } - CLOSE_READER(re, &s->gb); - } - not_coded: + +not_coded: if (intra) { - if(!s->use_intra_dc_vlc){ + if (!ctx->use_intra_dc_vlc) { block[0] = ff_mpeg4_pred_dc(s, n, block[0], &dc_pred_dir, 0); - i -= i>>31; //if(i == -1) i=0; + i -= i >> 31; // if (i == -1) i = 0; } ff_mpeg4_pred_ac(s, block, n, dc_pred_dir); - if (s->ac_pred) { - i = 63; /* XXX: not optimal */ - } + if (s->ac_pred) + i = 63; // FIXME not optimal } s->block_last_index[n] = i; return 0; @@ -1093,21 +1203,22 @@ static inline int mpeg4_decode_block(MpegEncContext * s, int16_t * block, */ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, int16_t block[6][64]) { + Mpeg4DecContext *ctx = (Mpeg4DecContext *)s; int cbp, mb_type; - const int xy= s->mb_x + s->mb_y*s->mb_stride; + const int xy = s->mb_x + s->mb_y * s->mb_stride; mb_type = s->current_picture.mb_type[xy]; - cbp = s->cbp_table[xy]; + cbp = s->cbp_table[xy]; - s->use_intra_dc_vlc= s->qscale < s->intra_dc_threshold; + ctx->use_intra_dc_vlc = s->qscale < ctx->intra_dc_threshold; - if (s->current_picture.qscale_table[xy] != s->qscale) { + if (s->current_picture.qscale_table[xy] != s->qscale) ff_set_qscale(s, s->current_picture.qscale_table[xy]); - } - if (s->pict_type == AV_PICTURE_TYPE_P || s->pict_type==AV_PICTURE_TYPE_S) { + if (s->pict_type == AV_PICTURE_TYPE_P || + s->pict_type == AV_PICTURE_TYPE_S) { int i; - for(i=0; i<4; i++){ + for (i = 0; i < 4; i++) { s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0]; s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1]; } @@ -1115,21 +1226,22 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, int16_t block[6][64]) if (IS_SKIP(mb_type)) { /* skip mb */ - for(i=0;i<6;i++) + for (i = 0; i < 6; i++) s->block_last_index[i] = -1; - s->mv_dir = MV_DIR_FORWARD; + s->mv_dir = MV_DIR_FORWARD; s->mv_type = MV_TYPE_16X16; - if(s->pict_type==AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE){ - s->mcsel=1; + if (s->pict_type == AV_PICTURE_TYPE_S + && ctx->vol_sprite_usage == GMC_SPRITE) { + s->mcsel = 1; s->mb_skipped = 0; - }else{ - s->mcsel=0; + } else { + s->mcsel = 0; s->mb_skipped = 1; } - }else if(s->mb_intra){ + } else if (s->mb_intra) { s->ac_pred = IS_ACPRED(s->current_picture.mb_type[xy]); - }else if(!s->mb_intra){ -// s->mcsel= 0; //FIXME do we need to init that + } else if (!s->mb_intra) { + // s->mcsel = 0; // FIXME do we need to init that? s->mv_dir = MV_DIR_FORWARD; if (IS_8X8(mb_type)) { @@ -1140,7 +1252,7 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, int16_t block[6][64]) } } else { /* I-Frame */ s->mb_intra = 1; - s->ac_pred = IS_ACPRED(s->current_picture.mb_type[xy]); + s->ac_pred = IS_ACPRED(s->current_picture.mb_type[xy]); } if (!IS_SKIP(mb_type)) { @@ -1148,123 +1260,138 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, int16_t block[6][64]) s->dsp.clear_blocks(s->block[0]); /* decode each block */ for (i = 0; i < 6; i++) { - if(mpeg4_decode_block(s, block[i], i, cbp&32, s->mb_intra, s->rvlc) < 0){ - av_log(s->avctx, AV_LOG_ERROR, "texture corrupted at %d %d %d\n", s->mb_x, s->mb_y, s->mb_intra); + if (mpeg4_decode_block(ctx, block[i], i, cbp & 32, s->mb_intra, ctx->rvlc) < 0) { + av_log(s->avctx, AV_LOG_ERROR, + "texture corrupted at %d %d %d\n", + s->mb_x, s->mb_y, s->mb_intra); return -1; } - cbp+=cbp; + cbp += cbp; } } /* per-MB end of slice check */ - - if(--s->mb_num_left <= 0){ - if(mpeg4_is_resync(s)) + if (--s->mb_num_left <= 0) { + if (mpeg4_is_resync(ctx)) return SLICE_END; else return SLICE_NOEND; - }else{ - if(mpeg4_is_resync(s)){ - const int delta= s->mb_x + 1 == s->mb_width ? 2 : 1; - if(s->cbp_table[xy+delta]) + } else { + if (mpeg4_is_resync(ctx)) { + const int delta = s->mb_x + 1 == s->mb_width ? 2 : 1; + if (s->cbp_table[xy + delta]) return SLICE_END; } return SLICE_OK; } } -static int mpeg4_decode_mb(MpegEncContext *s, - int16_t block[6][64]) +static int mpeg4_decode_mb(MpegEncContext *s, int16_t block[6][64]) { + Mpeg4DecContext *ctx = (Mpeg4DecContext *)s; int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant; int16_t *mot_val; static int8_t quant_tab[4] = { -1, -2, 1, 2 }; - const int xy= s->mb_x + s->mb_y * s->mb_stride; + const int xy = s->mb_x + s->mb_y * s->mb_stride; av_assert2(s->h263_pred); - if (s->pict_type == AV_PICTURE_TYPE_P || s->pict_type==AV_PICTURE_TYPE_S) { - do{ + if (s->pict_type == AV_PICTURE_TYPE_P || + s->pict_type == AV_PICTURE_TYPE_S) { + do { if (get_bits1(&s->gb)) { /* skip mb */ s->mb_intra = 0; - for(i=0;i<6;i++) + for (i = 0; i < 6; i++) s->block_last_index[i] = -1; - s->mv_dir = MV_DIR_FORWARD; + s->mv_dir = MV_DIR_FORWARD; s->mv_type = MV_TYPE_16X16; - if(s->pict_type==AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE){ - s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0; - s->mcsel=1; - s->mv[0][0][0]= get_amv(s, 0); - s->mv[0][0][1]= get_amv(s, 1); - - s->mb_skipped = 0; - }else{ - s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; - s->mcsel=0; + if (s->pict_type == AV_PICTURE_TYPE_S && + ctx->vol_sprite_usage == GMC_SPRITE) { + s->current_picture.mb_type[xy] = MB_TYPE_SKIP | + MB_TYPE_GMC | + MB_TYPE_16x16 | + MB_TYPE_L0; + s->mcsel = 1; + s->mv[0][0][0] = get_amv(ctx, 0); + s->mv[0][0][1] = get_amv(ctx, 1); + s->mb_skipped = 0; + } else { + s->current_picture.mb_type[xy] = MB_TYPE_SKIP | + MB_TYPE_16x16 | + MB_TYPE_L0; + s->mcsel = 0; s->mv[0][0][0] = 0; s->mv[0][0][1] = 0; - s->mb_skipped = 1; + s->mb_skipped = 1; } goto end; } cbpc = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2); - if (cbpc < 0){ - av_log(s->avctx, AV_LOG_ERROR, "cbpc damaged at %d %d\n", s->mb_x, s->mb_y); + if (cbpc < 0) { + av_log(s->avctx, AV_LOG_ERROR, + "cbpc damaged at %d %d\n", s->mb_x, s->mb_y); return -1; } - }while(cbpc == 20); + } while (cbpc == 20); s->dsp.clear_blocks(s->block[0]); - dquant = cbpc & 8; + dquant = cbpc & 8; s->mb_intra = ((cbpc & 4) != 0); - if (s->mb_intra) goto intra; + if (s->mb_intra) + goto intra; - if(s->pict_type==AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE && (cbpc & 16) == 0) - s->mcsel= get_bits1(&s->gb); - else s->mcsel= 0; + if (s->pict_type == AV_PICTURE_TYPE_S && + ctx->vol_sprite_usage == GMC_SPRITE && (cbpc & 16) == 0) + s->mcsel = get_bits1(&s->gb); + else + s->mcsel = 0; cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1) ^ 0x0F; cbp = (cbpc & 3) | (cbpy << 2); - if (dquant) { + if (dquant) ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]); - } - if((!s->progressive_sequence) && (cbp || (s->workaround_bugs&FF_BUG_XVID_ILACE))) - s->interlaced_dct= get_bits1(&s->gb); + if ((!s->progressive_sequence) && + (cbp || (s->workaround_bugs & FF_BUG_XVID_ILACE))) + s->interlaced_dct = get_bits1(&s->gb); s->mv_dir = MV_DIR_FORWARD; if ((cbpc & 16) == 0) { - if(s->mcsel){ - s->current_picture.mb_type[xy] = MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0; + if (s->mcsel) { + s->current_picture.mb_type[xy] = MB_TYPE_GMC | + MB_TYPE_16x16 | + MB_TYPE_L0; /* 16x16 global motion prediction */ - s->mv_type = MV_TYPE_16X16; - mx= get_amv(s, 0); - my= get_amv(s, 1); + s->mv_type = MV_TYPE_16X16; + mx = get_amv(ctx, 0); + my = get_amv(ctx, 1); s->mv[0][0][0] = mx; s->mv[0][0][1] = my; - }else if((!s->progressive_sequence) && get_bits1(&s->gb)){ - s->current_picture.mb_type[xy] = MB_TYPE_16x8 | MB_TYPE_L0 | MB_TYPE_INTERLACED; + } else if ((!s->progressive_sequence) && get_bits1(&s->gb)) { + s->current_picture.mb_type[xy] = MB_TYPE_16x8 | + MB_TYPE_L0 | + MB_TYPE_INTERLACED; /* 16x8 field motion prediction */ - s->mv_type= MV_TYPE_FIELD; + s->mv_type = MV_TYPE_FIELD; - s->field_select[0][0]= get_bits1(&s->gb); - s->field_select[0][1]= get_bits1(&s->gb); + s->field_select[0][0] = get_bits1(&s->gb); + s->field_select[0][1] = get_bits1(&s->gb); ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); - for(i=0; i<2; i++){ + for (i = 0; i < 2; i++) { mx = ff_h263_decode_motion(s, pred_x, s->f_code); if (mx >= 0xffff) return -1; - my = ff_h263_decode_motion(s, pred_y/2, s->f_code); + my = ff_h263_decode_motion(s, pred_y / 2, s->f_code); if (my >= 0xffff) return -1; s->mv[0][i][0] = mx; s->mv[0][i][1] = my; } - }else{ + } else { s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0; /* 16x16 motion prediction */ s->mv_type = MV_TYPE_16X16; @@ -1283,10 +1410,10 @@ static int mpeg4_decode_mb(MpegEncContext *s, } } else { s->current_picture.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0; - s->mv_type = MV_TYPE_8X8; - for(i=0;i<4;i++) { + s->mv_type = MV_TYPE_8X8; + for (i = 0; i < 4; i++) { mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y); - mx = ff_h263_decode_motion(s, pred_x, s->f_code); + mx = ff_h263_decode_motion(s, pred_x, s->f_code); if (mx >= 0xffff) return -1; @@ -1295,215 +1422,233 @@ static int mpeg4_decode_mb(MpegEncContext *s, return -1; s->mv[0][i][0] = mx; s->mv[0][i][1] = my; - mot_val[0] = mx; - mot_val[1] = my; + mot_val[0] = mx; + mot_val[1] = my; } } - } else if(s->pict_type==AV_PICTURE_TYPE_B) { - int modb1; // first bit of modb - int modb2; // second bit of modb + } else if (s->pict_type == AV_PICTURE_TYPE_B) { + int modb1; // first bit of modb + int modb2; // second bit of modb int mb_type; - s->mb_intra = 0; //B-frames never contain intra blocks - s->mcsel=0; // ... true gmc blocks + s->mb_intra = 0; // B-frames never contain intra blocks + s->mcsel = 0; // ... true gmc blocks - if(s->mb_x==0){ - for(i=0; i<2; i++){ - s->last_mv[i][0][0]= - s->last_mv[i][0][1]= - s->last_mv[i][1][0]= - s->last_mv[i][1][1]= 0; + if (s->mb_x == 0) { + for (i = 0; i < 2; i++) { + s->last_mv[i][0][0] = + s->last_mv[i][0][1] = + s->last_mv[i][1][0] = + s->last_mv[i][1][1] = 0; } ff_thread_await_progress(&s->next_picture_ptr->tf, s->mb_y, 0); } /* if we skipped it in the future P Frame than skip it now too */ - s->mb_skipped = s->next_picture.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]; // Note, skiptab=0 if last was GMC + s->mb_skipped = s->next_picture.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]; // Note, skiptab=0 if last was GMC - if(s->mb_skipped){ - /* skip mb */ - for(i=0;i<6;i++) + if (s->mb_skipped) { + /* skip mb */ + for (i = 0; i < 6; i++) s->block_last_index[i] = -1; - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_16X16; - s->mv[0][0][0] = 0; - s->mv[0][0][1] = 0; - s->mv[1][0][0] = 0; + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_16X16; + s->mv[0][0][0] = + s->mv[0][0][1] = + s->mv[1][0][0] = s->mv[1][0][1] = 0; - s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; + s->current_picture.mb_type[xy] = MB_TYPE_SKIP | + MB_TYPE_16x16 | + MB_TYPE_L0; goto end; } - modb1= get_bits1(&s->gb); - if(modb1){ - mb_type= MB_TYPE_DIRECT2 | MB_TYPE_SKIP | MB_TYPE_L0L1; //like MB_TYPE_B_DIRECT but no vectors coded - cbp=0; - }else{ - modb2= get_bits1(&s->gb); - mb_type= get_vlc2(&s->gb, mb_type_b_vlc.table, MB_TYPE_B_VLC_BITS, 1); - if(mb_type<0){ + modb1 = get_bits1(&s->gb); + if (modb1) { + // like MB_TYPE_B_DIRECT but no vectors coded + mb_type = MB_TYPE_DIRECT2 | MB_TYPE_SKIP | MB_TYPE_L0L1; + cbp = 0; + } else { + modb2 = get_bits1(&s->gb); + mb_type = get_vlc2(&s->gb, mb_type_b_vlc.table, MB_TYPE_B_VLC_BITS, 1); + if (mb_type < 0) { av_log(s->avctx, AV_LOG_ERROR, "illegal MB_type\n"); return -1; } - mb_type= mb_type_b_map[ mb_type ]; - if(modb2) cbp= 0; - else{ + mb_type = mb_type_b_map[mb_type]; + if (modb2) { + cbp = 0; + } else { s->dsp.clear_blocks(s->block[0]); - cbp= get_bits(&s->gb, 6); + cbp = get_bits(&s->gb, 6); } if ((!IS_DIRECT(mb_type)) && cbp) { - if(get_bits1(&s->gb)){ - ff_set_qscale(s, s->qscale + get_bits1(&s->gb)*4 - 2); - } + if (get_bits1(&s->gb)) + ff_set_qscale(s, s->qscale + get_bits1(&s->gb) * 4 - 2); } - if(!s->progressive_sequence){ - if(cbp) - s->interlaced_dct= get_bits1(&s->gb); + if (!s->progressive_sequence) { + if (cbp) + s->interlaced_dct = get_bits1(&s->gb); - if(!IS_DIRECT(mb_type) && get_bits1(&s->gb)){ + if (!IS_DIRECT(mb_type) && get_bits1(&s->gb)) { mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED; mb_type &= ~MB_TYPE_16x16; - if(USES_LIST(mb_type, 0)){ - s->field_select[0][0]= get_bits1(&s->gb); - s->field_select[0][1]= get_bits1(&s->gb); + if (USES_LIST(mb_type, 0)) { + s->field_select[0][0] = get_bits1(&s->gb); + s->field_select[0][1] = get_bits1(&s->gb); } - if(USES_LIST(mb_type, 1)){ - s->field_select[1][0]= get_bits1(&s->gb); - s->field_select[1][1]= get_bits1(&s->gb); + if (USES_LIST(mb_type, 1)) { + s->field_select[1][0] = get_bits1(&s->gb); + s->field_select[1][1] = get_bits1(&s->gb); } } } s->mv_dir = 0; - if((mb_type & (MB_TYPE_DIRECT2|MB_TYPE_INTERLACED)) == 0){ - s->mv_type= MV_TYPE_16X16; + if ((mb_type & (MB_TYPE_DIRECT2 | MB_TYPE_INTERLACED)) == 0) { + s->mv_type = MV_TYPE_16X16; - if(USES_LIST(mb_type, 0)){ + if (USES_LIST(mb_type, 0)) { s->mv_dir = MV_DIR_FORWARD; mx = ff_h263_decode_motion(s, s->last_mv[0][0][0], s->f_code); my = ff_h263_decode_motion(s, s->last_mv[0][0][1], s->f_code); - s->last_mv[0][1][0]= s->last_mv[0][0][0]= s->mv[0][0][0] = mx; - s->last_mv[0][1][1]= s->last_mv[0][0][1]= s->mv[0][0][1] = my; + s->last_mv[0][1][0] = + s->last_mv[0][0][0] = + s->mv[0][0][0] = mx; + s->last_mv[0][1][1] = + s->last_mv[0][0][1] = + s->mv[0][0][1] = my; } - if(USES_LIST(mb_type, 1)){ + if (USES_LIST(mb_type, 1)) { s->mv_dir |= MV_DIR_BACKWARD; mx = ff_h263_decode_motion(s, s->last_mv[1][0][0], s->b_code); my = ff_h263_decode_motion(s, s->last_mv[1][0][1], s->b_code); - s->last_mv[1][1][0]= s->last_mv[1][0][0]= s->mv[1][0][0] = mx; - s->last_mv[1][1][1]= s->last_mv[1][0][1]= s->mv[1][0][1] = my; + s->last_mv[1][1][0] = + s->last_mv[1][0][0] = + s->mv[1][0][0] = mx; + s->last_mv[1][1][1] = + s->last_mv[1][0][1] = + s->mv[1][0][1] = my; } - }else if(!IS_DIRECT(mb_type)){ - s->mv_type= MV_TYPE_FIELD; + } else if (!IS_DIRECT(mb_type)) { + s->mv_type = MV_TYPE_FIELD; - if(USES_LIST(mb_type, 0)){ + if (USES_LIST(mb_type, 0)) { s->mv_dir = MV_DIR_FORWARD; - for(i=0; i<2; i++){ - mx = ff_h263_decode_motion(s, s->last_mv[0][i][0] , s->f_code); - my = ff_h263_decode_motion(s, s->last_mv[0][i][1]/2, s->f_code); - s->last_mv[0][i][0]= s->mv[0][i][0] = mx; - s->last_mv[0][i][1]= (s->mv[0][i][1] = my)*2; + for (i = 0; i < 2; i++) { + mx = ff_h263_decode_motion(s, s->last_mv[0][i][0], s->f_code); + my = ff_h263_decode_motion(s, s->last_mv[0][i][1] / 2, s->f_code); + s->last_mv[0][i][0] = + s->mv[0][i][0] = mx; + s->last_mv[0][i][1] = (s->mv[0][i][1] = my) * 2; } } - if(USES_LIST(mb_type, 1)){ + if (USES_LIST(mb_type, 1)) { s->mv_dir |= MV_DIR_BACKWARD; - for(i=0; i<2; i++){ - mx = ff_h263_decode_motion(s, s->last_mv[1][i][0] , s->b_code); - my = ff_h263_decode_motion(s, s->last_mv[1][i][1]/2, s->b_code); - s->last_mv[1][i][0]= s->mv[1][i][0] = mx; - s->last_mv[1][i][1]= (s->mv[1][i][1] = my)*2; + for (i = 0; i < 2; i++) { + mx = ff_h263_decode_motion(s, s->last_mv[1][i][0], s->b_code); + my = ff_h263_decode_motion(s, s->last_mv[1][i][1] / 2, s->b_code); + s->last_mv[1][i][0] = + s->mv[1][i][0] = mx; + s->last_mv[1][i][1] = (s->mv[1][i][1] = my) * 2; } } } } - if(IS_DIRECT(mb_type)){ - if(IS_SKIP(mb_type)) - mx=my=0; - else{ + if (IS_DIRECT(mb_type)) { + if (IS_SKIP(mb_type)) { + mx = + my = 0; + } else { mx = ff_h263_decode_motion(s, 0, 1); my = ff_h263_decode_motion(s, 0, 1); } s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT; - mb_type |= ff_mpeg4_set_direct_mv(s, mx, my); + mb_type |= ff_mpeg4_set_direct_mv(s, mx, my); } s->current_picture.mb_type[xy] = mb_type; } else { /* I-Frame */ - do{ + do { cbpc = get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2); - if (cbpc < 0){ - av_log(s->avctx, AV_LOG_ERROR, "I cbpc damaged at %d %d\n", s->mb_x, s->mb_y); + if (cbpc < 0) { + av_log(s->avctx, AV_LOG_ERROR, + "I cbpc damaged at %d %d\n", s->mb_x, s->mb_y); return -1; } - }while(cbpc == 8); + } while (cbpc == 8); dquant = cbpc & 4; s->mb_intra = 1; + intra: s->ac_pred = get_bits1(&s->gb); - if(s->ac_pred) + if (s->ac_pred) s->current_picture.mb_type[xy] = MB_TYPE_INTRA | MB_TYPE_ACPRED; else s->current_picture.mb_type[xy] = MB_TYPE_INTRA; cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1); - if(cbpy<0){ - av_log(s->avctx, AV_LOG_ERROR, "I cbpy damaged at %d %d\n", s->mb_x, s->mb_y); + if (cbpy < 0) { + av_log(s->avctx, AV_LOG_ERROR, + "I cbpy damaged at %d %d\n", s->mb_x, s->mb_y); return -1; } cbp = (cbpc & 3) | (cbpy << 2); - s->use_intra_dc_vlc= s->qscale < s->intra_dc_threshold; + ctx->use_intra_dc_vlc = s->qscale < ctx->intra_dc_threshold; - if (dquant) { + if (dquant) ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]); - } - if(!s->progressive_sequence) - s->interlaced_dct= get_bits1(&s->gb); + if (!s->progressive_sequence) + s->interlaced_dct = get_bits1(&s->gb); s->dsp.clear_blocks(s->block[0]); /* decode each block */ for (i = 0; i < 6; i++) { - if (mpeg4_decode_block(s, block[i], i, cbp&32, 1, 0) < 0) + if (mpeg4_decode_block(ctx, block[i], i, cbp & 32, 1, 0) < 0) return -1; - cbp+=cbp; + cbp += cbp; } goto end; } /* decode each block */ for (i = 0; i < 6; i++) { - if (mpeg4_decode_block(s, block[i], i, cbp&32, 0, 0) < 0) + if (mpeg4_decode_block(ctx, block[i], i, cbp & 32, 0, 0) < 0) return -1; - cbp+=cbp; + cbp += cbp; } -end: - /* per-MB end of slice check */ - if(s->codec_id==AV_CODEC_ID_MPEG4){ - int next= mpeg4_is_resync(s); - if(next) { +end: + /* per-MB end of slice check */ + if (s->codec_id == AV_CODEC_ID_MPEG4) { + int next = mpeg4_is_resync(ctx); + if (next) { if (s->mb_x + s->mb_y*s->mb_width + 1 > next && (s->avctx->err_recognition & AV_EF_AGGRESSIVE)) { return -1; } else if (s->mb_x + s->mb_y*s->mb_width + 1 >= next) return SLICE_END; - if(s->pict_type==AV_PICTURE_TYPE_B){ + if (s->pict_type == AV_PICTURE_TYPE_B) { const int delta= s->mb_x + 1 == s->mb_width ? 2 : 1; ff_thread_await_progress(&s->next_picture_ptr->tf, - (s->mb_x + delta >= s->mb_width) ? FFMIN(s->mb_y+1, s->mb_height-1) : s->mb_y, 0); + (s->mb_x + delta >= s->mb_width) + ? FFMIN(s->mb_y + 1, s->mb_height - 1) + : s->mb_y, 0); if (s->next_picture.mbskip_table[xy + delta]) return SLICE_OK; } @@ -1515,21 +1660,21 @@ end: return SLICE_OK; } - -static int mpeg4_decode_gop_header(MpegEncContext * s, GetBitContext *gb){ +static int mpeg4_decode_gop_header(MpegEncContext *s, GetBitContext *gb) +{ int hours, minutes, seconds; - if(!show_bits(gb, 23)){ + if (!show_bits(gb, 23)) { av_log(s->avctx, AV_LOG_WARNING, "GOP header invalid\n"); return -1; } - hours= get_bits(gb, 5); - minutes= get_bits(gb, 6); + hours = get_bits(gb, 5); + minutes = get_bits(gb, 6); skip_bits1(gb); - seconds= get_bits(gb, 6); + seconds = get_bits(gb, 6); - s->time_base= seconds + 60*(minutes + 60*hours); + s->time_base = seconds + 60*(minutes + 60*hours); skip_bits1(gb); skip_bits1(gb); @@ -1537,7 +1682,8 @@ static int mpeg4_decode_gop_header(MpegEncContext * s, GetBitContext *gb){ return 0; } -static int mpeg4_decode_profile_level(MpegEncContext * s, GetBitContext *gb){ +static int mpeg4_decode_profile_level(MpegEncContext *s, GetBitContext *gb) +{ s->avctx->profile = get_bits(gb, 4); s->avctx->level = get_bits(gb, 4); @@ -1550,33 +1696,35 @@ static int mpeg4_decode_profile_level(MpegEncContext * s, GetBitContext *gb){ return 0; } -static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){ +static int decode_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb) +{ + MpegEncContext *s = &ctx->m; int width, height, vo_ver_id; /* vol header */ - skip_bits(gb, 1); /* random access */ - s->vo_type= get_bits(gb, 8); - if (get_bits1(gb) != 0) { /* is_ol_id */ - vo_ver_id = get_bits(gb, 4); /* vo_ver_id */ - skip_bits(gb, 3); /* vo_priority */ + skip_bits(gb, 1); /* random access */ + s->vo_type = get_bits(gb, 8); + if (get_bits1(gb) != 0) { /* is_ol_id */ + vo_ver_id = get_bits(gb, 4); /* vo_ver_id */ + skip_bits(gb, 3); /* vo_priority */ } else { vo_ver_id = 1; } - s->aspect_ratio_info= get_bits(gb, 4); - if(s->aspect_ratio_info == FF_ASPECT_EXTENDED){ - s->avctx->sample_aspect_ratio.num= get_bits(gb, 8); // par_width - s->avctx->sample_aspect_ratio.den= get_bits(gb, 8); // par_height - }else{ - s->avctx->sample_aspect_ratio= ff_h263_pixel_aspect[s->aspect_ratio_info]; + s->aspect_ratio_info = get_bits(gb, 4); + if (s->aspect_ratio_info == FF_ASPECT_EXTENDED) { + s->avctx->sample_aspect_ratio.num = get_bits(gb, 8); // par_width + s->avctx->sample_aspect_ratio.den = get_bits(gb, 8); // par_height + } else { + s->avctx->sample_aspect_ratio = ff_h263_pixel_aspect[s->aspect_ratio_info]; } - if ((s->vol_control_parameters=get_bits1(gb))) { /* vol control parameter */ - int chroma_format= get_bits(gb, 2); - if(chroma_format!=CHROMA_420){ + if ((s->vol_control_parameters = get_bits1(gb))) { /* vol control parameter */ + int chroma_format = get_bits(gb, 2); + if (chroma_format != CHROMA_420) av_log(s->avctx, AV_LOG_ERROR, "illegal chroma format\n"); - } - s->low_delay= get_bits1(gb); - if(get_bits1(gb)){ /* vbv parameters */ + + s->low_delay = get_bits1(gb); + if (get_bits1(gb)) { /* vbv parameters */ get_bits(gb, 15); /* first_half_bitrate */ skip_bits1(gb); /* marker */ get_bits(gb, 15); /* latter_half_bitrate */ @@ -1589,97 +1737,108 @@ static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){ get_bits(gb, 15); /* latter_half_vbv_occupancy */ skip_bits1(gb); /* marker */ } - }else{ - // set low delay flag only once the smartest? low delay detection won't be overridden - if(s->picture_number==0) - s->low_delay=0; + } else { + /* is setting low delay flag only once the smartest thing to do? + * low delay detection won't be overriden. */ + if (s->picture_number == 0) + s->low_delay = 0; } - s->shape = get_bits(gb, 2); /* vol shape */ - if(s->shape != RECT_SHAPE) av_log(s->avctx, AV_LOG_ERROR, "only rectangular vol supported\n"); - if(s->shape == GRAY_SHAPE && vo_ver_id != 1){ + ctx->shape = get_bits(gb, 2); /* vol shape */ + if (ctx->shape != RECT_SHAPE) + av_log(s->avctx, AV_LOG_ERROR, "only rectangular vol supported\n"); + if (ctx->shape == GRAY_SHAPE && vo_ver_id != 1) { av_log(s->avctx, AV_LOG_ERROR, "Gray shape not supported\n"); - skip_bits(gb, 4); //video_object_layer_shape_extension + skip_bits(gb, 4); /* video_object_layer_shape_extension */ } check_marker(gb, "before time_increment_resolution"); s->avctx->time_base.den = get_bits(gb, 16); - if(!s->avctx->time_base.den){ + if (!s->avctx->time_base.den) { av_log(s->avctx, AV_LOG_ERROR, "time_base.den==0\n"); s->avctx->time_base.num = 0; return -1; } - s->time_increment_bits = av_log2(s->avctx->time_base.den - 1) + 1; - if (s->time_increment_bits < 1) - s->time_increment_bits = 1; + ctx->time_increment_bits = av_log2(s->avctx->time_base.den - 1) + 1; + if (ctx->time_increment_bits < 1) + ctx->time_increment_bits = 1; check_marker(gb, "before fixed_vop_rate"); - if (get_bits1(gb) != 0) { /* fixed_vop_rate */ - s->avctx->time_base.num = get_bits(gb, s->time_increment_bits); - }else + if (get_bits1(gb) != 0) /* fixed_vop_rate */ + s->avctx->time_base.num = get_bits(gb, ctx->time_increment_bits); + else s->avctx->time_base.num = 1; - s->t_frame=0; + ctx->t_frame = 0; - if (s->shape != BIN_ONLY_SHAPE) { - if (s->shape == RECT_SHAPE) { - skip_bits1(gb); /* marker */ + if (ctx->shape != BIN_ONLY_SHAPE) { + if (ctx->shape == RECT_SHAPE) { + check_marker(gb, "before width"); width = get_bits(gb, 13); - skip_bits1(gb); /* marker */ + check_marker(gb, "before height"); height = get_bits(gb, 13); - skip_bits1(gb); /* marker */ - if(width && height && !(s->width && s->codec_tag == AV_RL32("MP4S"))){ /* they should be non zero but who knows ... */ + check_marker(gb, "after height"); + if (width && height && /* they should be non zero but who knows */ + !(s->width && s->codec_tag == AV_RL32("MP4S"))) { if (s->width && s->height && (s->width != width || s->height != height)) s->context_reinit = 1; - s->width = width; + s->width = width; s->height = height; } } - s->progressive_sequence= - s->progressive_frame= get_bits1(gb)^1; - s->interlaced_dct=0; - if(!get_bits1(gb) && (s->avctx->debug & FF_DEBUG_PICT_INFO)) - av_log(s->avctx, AV_LOG_INFO, "MPEG4 OBMC not supported (very likely buggy encoder)\n"); /* OBMC Disable */ - if (vo_ver_id == 1) { - s->vol_sprite_usage = get_bits1(gb); /* vol_sprite_usage */ - } else { - s->vol_sprite_usage = get_bits(gb, 2); /* vol_sprite_usage */ - } - if(s->vol_sprite_usage==STATIC_SPRITE) av_log(s->avctx, AV_LOG_ERROR, "Static Sprites not supported\n"); - if(s->vol_sprite_usage==STATIC_SPRITE || s->vol_sprite_usage==GMC_SPRITE){ - if(s->vol_sprite_usage==STATIC_SPRITE){ - s->sprite_width = get_bits(gb, 13); + s->progressive_sequence = + s->progressive_frame = get_bits1(gb) ^ 1; + s->interlaced_dct = 0; + if (!get_bits1(gb) && (s->avctx->debug & FF_DEBUG_PICT_INFO)) + av_log(s->avctx, AV_LOG_INFO, /* OBMC Disable */ + "MPEG4 OBMC not supported (very likely buggy encoder)\n"); + if (vo_ver_id == 1) + ctx->vol_sprite_usage = get_bits1(gb); /* vol_sprite_usage */ + else + ctx->vol_sprite_usage = get_bits(gb, 2); /* vol_sprite_usage */ + + if (ctx->vol_sprite_usage == STATIC_SPRITE) + av_log(s->avctx, AV_LOG_ERROR, "Static Sprites not supported\n"); + if (ctx->vol_sprite_usage == STATIC_SPRITE || + ctx->vol_sprite_usage == GMC_SPRITE) { + if (ctx->vol_sprite_usage == STATIC_SPRITE) { + skip_bits(gb, 13); // sprite_width skip_bits1(gb); /* marker */ - s->sprite_height= get_bits(gb, 13); + skip_bits(gb, 13); // sprite_height skip_bits1(gb); /* marker */ - s->sprite_left = get_bits(gb, 13); + skip_bits(gb, 13); // sprite_left skip_bits1(gb); /* marker */ - s->sprite_top = get_bits(gb, 13); + skip_bits(gb, 13); // sprite_top skip_bits1(gb); /* marker */ } - s->num_sprite_warping_points= get_bits(gb, 6); - if(s->num_sprite_warping_points > 3){ - av_log(s->avctx, AV_LOG_ERROR, "%d sprite_warping_points\n", s->num_sprite_warping_points); - s->num_sprite_warping_points= 0; + ctx->num_sprite_warping_points = get_bits(gb, 6); + if (ctx->num_sprite_warping_points > 3) { + av_log(s->avctx, AV_LOG_ERROR, + "%d sprite_warping_points\n", + ctx->num_sprite_warping_points); + ctx->num_sprite_warping_points = 0; return -1; } - s->sprite_warping_accuracy = get_bits(gb, 2); - s->sprite_brightness_change= get_bits1(gb); - if(s->vol_sprite_usage==STATIC_SPRITE) - s->low_latency_sprite= get_bits1(gb); + s->sprite_warping_accuracy = get_bits(gb, 2); + ctx->sprite_brightness_change = get_bits1(gb); + if (ctx->vol_sprite_usage == STATIC_SPRITE) + skip_bits1(gb); // low_latency_sprite } // FIXME sadct disable bit if verid!=1 && shape not rect - if (get_bits1(gb) == 1) { /* not_8_bit */ - s->quant_precision = get_bits(gb, 4); /* quant_precision */ - if(get_bits(gb, 4)!=8) av_log(s->avctx, AV_LOG_ERROR, "N-bit not supported\n"); /* bits_per_pixel */ - if(s->quant_precision!=5) av_log(s->avctx, AV_LOG_ERROR, "quant precision %d\n", s->quant_precision); - if(s->quant_precision<3 || s->quant_precision>9) { + if (get_bits1(gb) == 1) { /* not_8_bit */ + s->quant_precision = get_bits(gb, 4); /* quant_precision */ + if (get_bits(gb, 4) != 8) /* bits_per_pixel */ + av_log(s->avctx, AV_LOG_ERROR, "N-bit not supported\n"); + if (s->quant_precision != 5) + av_log(s->avctx, AV_LOG_ERROR, + "quant precision %d\n", s->quant_precision); + if (s->quant_precision<3 || s->quant_precision>9) { s->quant_precision = 5; } } else { @@ -1688,186 +1847,190 @@ static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){ // FIXME a bunch of grayscale shape things - if((s->mpeg_quant=get_bits1(gb))){ /* vol_quant_type */ + if ((s->mpeg_quant = get_bits1(gb))) { /* vol_quant_type */ int i, v; /* load default matrixes */ - for(i=0; i<64; i++){ - int j= s->dsp.idct_permutation[i]; - v= ff_mpeg4_default_intra_matrix[i]; - s->intra_matrix[j]= v; - s->chroma_intra_matrix[j]= v; - - v= ff_mpeg4_default_non_intra_matrix[i]; - s->inter_matrix[j]= v; - s->chroma_inter_matrix[j]= v; + for (i = 0; i < 64; i++) { + int j = s->dsp.idct_permutation[i]; + v = ff_mpeg4_default_intra_matrix[i]; + s->intra_matrix[j] = v; + s->chroma_intra_matrix[j] = v; + + v = ff_mpeg4_default_non_intra_matrix[i]; + s->inter_matrix[j] = v; + s->chroma_inter_matrix[j] = v; } /* load custom intra matrix */ - if(get_bits1(gb)){ - int last=0; - for(i=0; i<64; i++){ + if (get_bits1(gb)) { + int last = 0; + for (i = 0; i < 64; i++) { int j; - v= get_bits(gb, 8); - if(v==0) break; - - last= v; - j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ]; - s->intra_matrix[j]= v; - s->chroma_intra_matrix[j]= v; + v = get_bits(gb, 8); + if (v == 0) + break; + + last = v; + j = s->dsp.idct_permutation[ff_zigzag_direct[i]]; + s->intra_matrix[j] = last; + s->chroma_intra_matrix[j] = last; } /* replicate last value */ - for(; i<64; i++){ - int j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ]; - s->intra_matrix[j]= last; - s->chroma_intra_matrix[j]= last; + for (; i < 64; i++) { + int j = s->dsp.idct_permutation[ff_zigzag_direct[i]]; + s->intra_matrix[j] = last; + s->chroma_intra_matrix[j] = last; } } /* load custom non intra matrix */ - if(get_bits1(gb)){ - int last=0; - for(i=0; i<64; i++){ + if (get_bits1(gb)) { + int last = 0; + for (i = 0; i < 64; i++) { int j; - v= get_bits(gb, 8); - if(v==0) break; - - last= v; - j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ]; - s->inter_matrix[j]= v; - s->chroma_inter_matrix[j]= v; + v = get_bits(gb, 8); + if (v == 0) + break; + + last = v; + j = s->dsp.idct_permutation[ff_zigzag_direct[i]]; + s->inter_matrix[j] = v; + s->chroma_inter_matrix[j] = v; } /* replicate last value */ - for(; i<64; i++){ - int j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ]; - s->inter_matrix[j]= last; - s->chroma_inter_matrix[j]= last; + for (; i < 64; i++) { + int j = s->dsp.idct_permutation[ff_zigzag_direct[i]]; + s->inter_matrix[j] = last; + s->chroma_inter_matrix[j] = last; } } // FIXME a bunch of grayscale shape things } - if(vo_ver_id != 1) - s->quarter_sample= get_bits1(gb); - else s->quarter_sample=0; - - if(!get_bits1(gb)){ - int pos= get_bits_count(gb); - int estimation_method= get_bits(gb, 2); - if(estimation_method<2){ - if(!get_bits1(gb)){ - s->cplx_estimation_trash_i += 8*get_bits1(gb); //opaque - s->cplx_estimation_trash_i += 8*get_bits1(gb); //transparent - s->cplx_estimation_trash_i += 8*get_bits1(gb); //intra_cae - s->cplx_estimation_trash_i += 8*get_bits1(gb); //inter_cae - s->cplx_estimation_trash_i += 8*get_bits1(gb); //no_update - s->cplx_estimation_trash_i += 8*get_bits1(gb); //upampling + if (vo_ver_id != 1) + s->quarter_sample = get_bits1(gb); + else + s->quarter_sample = 0; + + if (!get_bits1(gb)) { + int pos = get_bits_count(gb); + int estimation_method = get_bits(gb, 2); + if (estimation_method < 2) { + if (!get_bits1(gb)) { + ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* opaque */ + ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* transparent */ + ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* intra_cae */ + ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* inter_cae */ + ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* no_update */ + ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* upampling */ } - if(!get_bits1(gb)){ - s->cplx_estimation_trash_i += 8*get_bits1(gb); //intra_blocks - s->cplx_estimation_trash_p += 8*get_bits1(gb); //inter_blocks - s->cplx_estimation_trash_p += 8*get_bits1(gb); //inter4v_blocks - s->cplx_estimation_trash_i += 8*get_bits1(gb); //not coded blocks + if (!get_bits1(gb)) { + ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* intra_blocks */ + ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* inter_blocks */ + ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* inter4v_blocks */ + ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* not coded blocks */ } - if(!check_marker(gb, "in complexity estimation part 1")){ + if (!check_marker(gb, "in complexity estimation part 1")) { skip_bits_long(gb, pos - get_bits_count(gb)); goto no_cplx_est; } - if(!get_bits1(gb)){ - s->cplx_estimation_trash_i += 8*get_bits1(gb); //dct_coeffs - s->cplx_estimation_trash_i += 8*get_bits1(gb); //dct_lines - s->cplx_estimation_trash_i += 8*get_bits1(gb); //vlc_syms - s->cplx_estimation_trash_i += 4*get_bits1(gb); //vlc_bits + if (!get_bits1(gb)) { + ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* dct_coeffs */ + ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* dct_lines */ + ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* vlc_syms */ + ctx->cplx_estimation_trash_i += 4 * get_bits1(gb); /* vlc_bits */ } - if(!get_bits1(gb)){ - s->cplx_estimation_trash_p += 8*get_bits1(gb); //apm - s->cplx_estimation_trash_p += 8*get_bits1(gb); //npm - s->cplx_estimation_trash_b += 8*get_bits1(gb); //interpolate_mc_q - s->cplx_estimation_trash_p += 8*get_bits1(gb); //forwback_mc_q - s->cplx_estimation_trash_p += 8*get_bits1(gb); //halfpel2 - s->cplx_estimation_trash_p += 8*get_bits1(gb); //halfpel4 + if (!get_bits1(gb)) { + ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* apm */ + ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* npm */ + ctx->cplx_estimation_trash_b += 8 * get_bits1(gb); /* interpolate_mc_q */ + ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* forwback_mc_q */ + ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* halfpel2 */ + ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* halfpel4 */ } - if(!check_marker(gb, "in complexity estimation part 2")){ + if (!check_marker(gb, "in complexity estimation part 2")) { skip_bits_long(gb, pos - get_bits_count(gb)); goto no_cplx_est; } - if(estimation_method==1){ - s->cplx_estimation_trash_i += 8*get_bits1(gb); //sadct - s->cplx_estimation_trash_p += 8*get_bits1(gb); //qpel + if (estimation_method == 1) { + ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* sadct */ + ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* qpel */ } - }else - av_log(s->avctx, AV_LOG_ERROR, "Invalid Complexity estimation method %d\n", estimation_method); - }else{ + } else + av_log(s->avctx, AV_LOG_ERROR, + "Invalid Complexity estimation method %d\n", + estimation_method); + } else { + no_cplx_est: - s->cplx_estimation_trash_i= - s->cplx_estimation_trash_p= - s->cplx_estimation_trash_b= 0; + ctx->cplx_estimation_trash_i = + ctx->cplx_estimation_trash_p = + ctx->cplx_estimation_trash_b = 0; } - s->resync_marker= !get_bits1(gb); /* resync_marker_disabled */ + ctx->resync_marker = !get_bits1(gb); /* resync_marker_disabled */ - s->data_partitioning= get_bits1(gb); - if(s->data_partitioning){ - s->rvlc= get_bits1(gb); - } + s->data_partitioning = get_bits1(gb); + if (s->data_partitioning) + ctx->rvlc = get_bits1(gb); - if(vo_ver_id != 1) { - s->new_pred= get_bits1(gb); - if(s->new_pred){ + if (vo_ver_id != 1) { + ctx->new_pred = get_bits1(gb); + if (ctx->new_pred) { av_log(s->avctx, AV_LOG_ERROR, "new pred not supported\n"); skip_bits(gb, 2); /* requested upstream message type */ - skip_bits1(gb); /* newpred segment type */ + skip_bits1(gb); /* newpred segment type */ } - s->reduced_res_vop= get_bits1(gb); - if(s->reduced_res_vop) av_log(s->avctx, AV_LOG_ERROR, "reduced resolution VOP not supported\n"); - } - else{ - s->new_pred=0; - s->reduced_res_vop= 0; + if (get_bits1(gb)) // reduced_res_vop + av_log(s->avctx, AV_LOG_ERROR, + "reduced resolution VOP not supported\n"); + } else { + ctx->new_pred = 0; } - s->scalability= get_bits1(gb); + ctx->scalability = get_bits1(gb); - if (s->scalability) { - GetBitContext bak= *gb; + if (ctx->scalability) { + GetBitContext bak = *gb; int h_sampling_factor_n; int h_sampling_factor_m; int v_sampling_factor_n; int v_sampling_factor_m; - s->hierachy_type= get_bits1(gb); + skip_bits1(gb); // hierarchy_type skip_bits(gb, 4); /* ref_layer_id */ skip_bits1(gb); /* ref_layer_sampling_dir */ - h_sampling_factor_n= get_bits(gb, 5); - h_sampling_factor_m= get_bits(gb, 5); - v_sampling_factor_n= get_bits(gb, 5); - v_sampling_factor_m= get_bits(gb, 5); - s->enhancement_type= get_bits1(gb); - - if( h_sampling_factor_n==0 || h_sampling_factor_m==0 - || v_sampling_factor_n==0 || v_sampling_factor_m==0){ + h_sampling_factor_n = get_bits(gb, 5); + h_sampling_factor_m = get_bits(gb, 5); + v_sampling_factor_n = get_bits(gb, 5); + v_sampling_factor_m = get_bits(gb, 5); + ctx->enhancement_type = get_bits1(gb); + + if (h_sampling_factor_n == 0 || h_sampling_factor_m == 0 || + v_sampling_factor_n == 0 || v_sampling_factor_m == 0) { /* illegal scalability header (VERY broken encoder), * trying to workaround */ - s->scalability=0; - *gb= bak; - }else + ctx->scalability = 0; + *gb = bak; + } else av_log(s->avctx, AV_LOG_ERROR, "scalability not supported\n"); // bin shape stuff FIXME } } - if(s->avctx->debug&FF_DEBUG_PICT_INFO) { + if (s->avctx->debug&FF_DEBUG_PICT_INFO) { av_log(s->avctx, AV_LOG_DEBUG, "tb %d/%d, tincrbits:%d, qp_prec:%d, ps:%d, %s%s%s%s\n", s->avctx->time_base.num, s->avctx->time_base.den, - s->time_increment_bits, + ctx->time_increment_bits, s->quant_precision, s->progressive_sequence, - s->scalability ? "scalability " :"" , s->quarter_sample ? "qpel " : "", - s->data_partitioning ? "partition " : "", s->rvlc ? "rvlc " : "" + ctx->scalability ? "scalability " :"" , s->quarter_sample ? "qpel " : "", + s->data_partitioning ? "partition " : "", ctx->rvlc ? "rvlc " : "" ); } @@ -1878,288 +2041,441 @@ no_cplx_est: * Decode the user data stuff in the header. * Also initializes divx/xvid/lavc_version/build. */ -static int decode_user_data(MpegEncContext *s, GetBitContext *gb){ +static int decode_user_data(Mpeg4DecContext *ctx, GetBitContext *gb) +{ + MpegEncContext *s = &ctx->m; char buf[256]; int i; int e; int ver = 0, build = 0, ver2 = 0, ver3 = 0; char last; - for(i=0; i<255 && get_bits_count(gb) < gb->size_in_bits; i++){ - if(show_bits(gb, 23) == 0) break; - buf[i]= get_bits(gb, 8); + for (i = 0; i < 255 && get_bits_count(gb) < gb->size_in_bits; i++) { + if (show_bits(gb, 23) == 0) + break; + buf[i] = get_bits(gb, 8); } - buf[i]=0; + buf[i] = 0; /* divx detection */ - e=sscanf(buf, "DivX%dBuild%d%c", &ver, &build, &last); - if(e<2) - e=sscanf(buf, "DivX%db%d%c", &ver, &build, &last); - if(e>=2){ - s->divx_version= ver; - s->divx_build= build; - s->divx_packed= e==3 && last=='p'; - if(s->divx_packed && !s->showed_packed_warning) { - av_log(s->avctx, AV_LOG_WARNING, "Invalid and inefficient vfw-avi packed B frames detected\n"); - s->showed_packed_warning=1; + e = sscanf(buf, "DivX%dBuild%d%c", &ver, &build, &last); + if (e < 2) + e = sscanf(buf, "DivX%db%d%c", &ver, &build, &last); + if (e >= 2) { + ctx->divx_version = ver; + ctx->divx_build = build; + s->divx_packed = e == 3 && last == 'p'; + if (s->divx_packed && !ctx->showed_packed_warning) { + av_log(s->avctx, AV_LOG_INFO, "Video uses a non-standard and " + "wasteful way to store B-frames ('packed B-frames'). " + "Consider using a tool like VirtualDub or avidemux to fix it.\n"); + ctx->showed_packed_warning = 1; } } /* libavcodec detection */ - e=sscanf(buf, "FFmpe%*[^b]b%d", &build)+3; - if(e!=4) - e=sscanf(buf, "FFmpeg v%d.%d.%d / libavcodec build: %d", &ver, &ver2, &ver3, &build); - if(e!=4){ - e=sscanf(buf, "Lavc%d.%d.%d", &ver, &ver2, &ver3)+1; - if (e>1) - build= (ver<<16) + (ver2<<8) + ver3; - } - if(e!=4){ - if(strcmp(buf, "ffmpeg")==0){ - s->lavc_build= 4600; - } + e = sscanf(buf, "FFmpe%*[^b]b%d", &build) + 3; + if (e != 4) + e = sscanf(buf, "FFmpeg v%d.%d.%d / libavcodec build: %d", &ver, &ver2, &ver3, &build); + if (e != 4) { + e = sscanf(buf, "Lavc%d.%d.%d", &ver, &ver2, &ver3) + 1; + if (e > 1) + build = (ver << 16) + (ver2 << 8) + ver3; } - if(e==4){ - s->lavc_build= build; + if (e != 4) { + if (strcmp(buf, "ffmpeg") == 0) + ctx->lavc_build = 4600; } + if (e == 4) + ctx->lavc_build = build; /* Xvid detection */ - e=sscanf(buf, "XviD%d", &build); - if(e==1){ - s->xvid_build= build; + e = sscanf(buf, "XviD%d", &build); + if (e == 1) + ctx->xvid_build = build; + + return 0; +} + +int ff_mpeg4_workaround_bugs(AVCodecContext *avctx) +{ + Mpeg4DecContext *ctx = avctx->priv_data; + MpegEncContext *s = &ctx->m; + + if (ctx->xvid_build == -1 && ctx->divx_version == -1 && ctx->lavc_build == -1) { + if (s->stream_codec_tag == AV_RL32("XVID") || + s->codec_tag == AV_RL32("XVID") || + s->codec_tag == AV_RL32("XVIX") || + s->codec_tag == AV_RL32("RMP4") || + s->codec_tag == AV_RL32("ZMP4") || + s->codec_tag == AV_RL32("SIPP")) + ctx->xvid_build = 0; + } + + if (ctx->xvid_build == -1 && ctx->divx_version == -1 && ctx->lavc_build == -1) + if (s->codec_tag == AV_RL32("DIVX") && s->vo_type == 0 && + s->vol_control_parameters == 0) + ctx->divx_version = 400; // divx 4 + + if (ctx->xvid_build >= 0 && ctx->divx_version >= 0) { + ctx->divx_version = + ctx->divx_build = -1; + } + + if (s->workaround_bugs & FF_BUG_AUTODETECT) { + if (s->codec_tag == AV_RL32("XVIX")) + s->workaround_bugs |= FF_BUG_XVID_ILACE; + + if (s->codec_tag == AV_RL32("UMP4")) + s->workaround_bugs |= FF_BUG_UMP4; + + if (ctx->divx_version >= 500 && ctx->divx_build < 1814) + s->workaround_bugs |= FF_BUG_QPEL_CHROMA; + + if (ctx->divx_version > 502 && ctx->divx_build < 1814) + s->workaround_bugs |= FF_BUG_QPEL_CHROMA2; + + if (ctx->xvid_build <= 3U) + s->padding_bug_score = 256 * 256 * 256 * 64; + + if (ctx->xvid_build <= 1U) + s->workaround_bugs |= FF_BUG_QPEL_CHROMA; + + if (ctx->xvid_build <= 12U) + s->workaround_bugs |= FF_BUG_EDGE; + + if (ctx->xvid_build <= 32U) + s->workaround_bugs |= FF_BUG_DC_CLIP; + +#define SET_QPEL_FUNC(postfix1, postfix2) \ + s->dsp.put_ ## postfix1 = ff_put_ ## postfix2; \ + s->dsp.put_no_rnd_ ## postfix1 = ff_put_no_rnd_ ## postfix2; \ + s->dsp.avg_ ## postfix1 = ff_avg_ ## postfix2; + + if (ctx->lavc_build < 4653U) + s->workaround_bugs |= FF_BUG_STD_QPEL; + + if (ctx->lavc_build < 4655U) + s->workaround_bugs |= FF_BUG_DIRECT_BLOCKSIZE; + + if (ctx->lavc_build < 4670U) + s->workaround_bugs |= FF_BUG_EDGE; + + if (ctx->lavc_build <= 4712U) + s->workaround_bugs |= FF_BUG_DC_CLIP; + + if (ctx->divx_version >= 0) + s->workaround_bugs |= FF_BUG_DIRECT_BLOCKSIZE; + if (ctx->divx_version == 501 && ctx->divx_build == 20020416) + s->padding_bug_score = 256 * 256 * 256 * 64; + + if (ctx->divx_version < 500U) + s->workaround_bugs |= FF_BUG_EDGE; + + if (ctx->divx_version >= 0) + s->workaround_bugs |= FF_BUG_HPEL_CHROMA; } + if (s->workaround_bugs & FF_BUG_STD_QPEL) { + SET_QPEL_FUNC(qpel_pixels_tab[0][5], qpel16_mc11_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[0][7], qpel16_mc31_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[0][9], qpel16_mc12_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[0][11], qpel16_mc32_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[0][13], qpel16_mc13_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[0][15], qpel16_mc33_old_c) + + SET_QPEL_FUNC(qpel_pixels_tab[1][5], qpel8_mc11_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[1][7], qpel8_mc31_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[1][9], qpel8_mc12_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[1][11], qpel8_mc32_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[1][13], qpel8_mc13_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[1][15], qpel8_mc33_old_c) + } + + if (avctx->debug & FF_DEBUG_BUGS) + av_log(s->avctx, AV_LOG_DEBUG, + "bugs: %X lavc_build:%d xvid_build:%d divx_version:%d divx_build:%d %s\n", + s->workaround_bugs, ctx->lavc_build, ctx->xvid_build, + ctx->divx_version, ctx->divx_build, s->divx_packed ? "p" : ""); + +#if HAVE_MMX + if (s->codec_id == AV_CODEC_ID_MPEG4 && ctx->xvid_build >= 0 && + avctx->idct_algo == FF_IDCT_AUTO && + (av_get_cpu_flags() & AV_CPU_FLAG_MMX)) { + avctx->idct_algo = FF_IDCT_XVIDMMX; + ff_dct_common_init(s); + return 1; + } +#endif return 0; } -static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ +static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb) +{ + MpegEncContext *s = &ctx->m; int time_incr, time_increment; + int64_t pts; s->pict_type = get_bits(gb, 2) + AV_PICTURE_TYPE_I; /* pict type: I = 0 , P = 1 */ - if(s->pict_type==AV_PICTURE_TYPE_B && s->low_delay && s->vol_control_parameters==0 && !(s->flags & CODEC_FLAG_LOW_DELAY)){ + if (s->pict_type == AV_PICTURE_TYPE_B && s->low_delay && + s->vol_control_parameters == 0 && !(s->flags & CODEC_FLAG_LOW_DELAY)) { av_log(s->avctx, AV_LOG_ERROR, "low_delay flag incorrectly, clearing it\n"); - s->low_delay=0; + s->low_delay = 0; } - s->partitioned_frame= s->data_partitioning && s->pict_type!=AV_PICTURE_TYPE_B; - if(s->partitioned_frame) - s->decode_mb= mpeg4_decode_partitioned_mb; + s->partitioned_frame = s->data_partitioning && s->pict_type != AV_PICTURE_TYPE_B; + if (s->partitioned_frame) + s->decode_mb = mpeg4_decode_partitioned_mb; else - s->decode_mb= mpeg4_decode_mb; + s->decode_mb = mpeg4_decode_mb; - time_incr=0; + time_incr = 0; while (get_bits1(gb) != 0) time_incr++; check_marker(gb, "before time_increment"); - if(s->time_increment_bits==0 || !(show_bits(gb, s->time_increment_bits+1)&1)){ - av_log(s->avctx, AV_LOG_ERROR, "hmm, seems the headers are not complete, trying to guess time_increment_bits\n"); - - for(s->time_increment_bits=1 ;s->time_increment_bits<16; s->time_increment_bits++){ - if ( s->pict_type == AV_PICTURE_TYPE_P - || (s->pict_type == AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE)) { - if((show_bits(gb, s->time_increment_bits+6)&0x37) == 0x30) break; - }else - if((show_bits(gb, s->time_increment_bits+5)&0x1F) == 0x18) break; + if (ctx->time_increment_bits == 0 || + !(show_bits(gb, ctx->time_increment_bits + 1) & 1)) { + av_log(s->avctx, AV_LOG_ERROR, + "hmm, seems the headers are not complete, trying to guess time_increment_bits\n"); + + for (ctx->time_increment_bits = 1; + ctx->time_increment_bits < 16; + ctx->time_increment_bits++) { + if (s->pict_type == AV_PICTURE_TYPE_P || + (s->pict_type == AV_PICTURE_TYPE_S && + ctx->vol_sprite_usage == GMC_SPRITE)) { + if ((show_bits(gb, ctx->time_increment_bits + 6) & 0x37) == 0x30) + break; + } else if ((show_bits(gb, ctx->time_increment_bits + 5) & 0x1F) == 0x18) + break; } - av_log(s->avctx, AV_LOG_ERROR, "my guess is %d bits ;)\n",s->time_increment_bits); - if (s->avctx->time_base.den && 4*s->avctx->time_base.den < 1<time_increment_bits) { - s->avctx->time_base.den = 1<time_increment_bits; + av_log(s->avctx, AV_LOG_ERROR, + "my guess is %d bits ;)\n", ctx->time_increment_bits); + if (s->avctx->time_base.den && 4*s->avctx->time_base.den < 1<time_increment_bits) { + s->avctx->time_base.den = 1<time_increment_bits; } } - if(IS_3IV1) time_increment= get_bits1(gb); //FIXME investigate further - else time_increment= get_bits(gb, s->time_increment_bits); - - if(s->pict_type!=AV_PICTURE_TYPE_B){ - s->last_time_base= s->time_base; - s->time_base+= time_incr; - s->time= s->time_base*s->avctx->time_base.den + time_increment; - if(s->workaround_bugs&FF_BUG_UMP4){ - if(s->time < s->last_non_b_time){ + if (IS_3IV1) + time_increment = get_bits1(gb); // FIXME investigate further + else + time_increment = get_bits(gb, ctx->time_increment_bits); + + if (s->pict_type != AV_PICTURE_TYPE_B) { + s->last_time_base = s->time_base; + s->time_base += time_incr; + s->time = s->time_base * s->avctx->time_base.den + time_increment; + if (s->workaround_bugs & FF_BUG_UMP4) { + if (s->time < s->last_non_b_time) { /* header is not mpeg-4-compatible, broken encoder, * trying to workaround */ s->time_base++; - s->time+= s->avctx->time_base.den; + s->time += s->avctx->time_base.den; } } - s->pp_time= s->time - s->last_non_b_time; - s->last_non_b_time= s->time; - }else{ - s->time= (s->last_time_base + time_incr)*s->avctx->time_base.den + time_increment; - s->pb_time= s->pp_time - (s->last_non_b_time - s->time); - if(s->pp_time <=s->pb_time || s->pp_time <= s->pp_time - s->pb_time || s->pp_time<=0){ + s->pp_time = s->time - s->last_non_b_time; + s->last_non_b_time = s->time; + } else { + s->time = (s->last_time_base + time_incr) * s->avctx->time_base.den + time_increment; + s->pb_time = s->pp_time - (s->last_non_b_time - s->time); + if (s->pp_time <= s->pb_time || + s->pp_time <= s->pp_time - s->pb_time || + s->pp_time <= 0) { /* messed up order, maybe after seeking? skipping current b-frame */ return FRAME_SKIPPED; } ff_mpeg4_init_direct_mv(s); - if(s->t_frame==0) s->t_frame= s->pb_time; - if(s->t_frame==0) s->t_frame=1; // 1/0 protection - s->pp_field_time= ( ROUNDED_DIV(s->last_non_b_time, s->t_frame) - - ROUNDED_DIV(s->last_non_b_time - s->pp_time, s->t_frame))*2; - s->pb_field_time= ( ROUNDED_DIV(s->time, s->t_frame) - - ROUNDED_DIV(s->last_non_b_time - s->pp_time, s->t_frame))*2; - if(!s->progressive_sequence){ - if(s->pp_field_time <= s->pb_field_time || s->pb_field_time <= 1) + if (ctx->t_frame == 0) + ctx->t_frame = s->pb_time; + if (ctx->t_frame == 0) + ctx->t_frame = 1; // 1/0 protection + s->pp_field_time = (ROUNDED_DIV(s->last_non_b_time, ctx->t_frame) - + ROUNDED_DIV(s->last_non_b_time - s->pp_time, ctx->t_frame)) * 2; + s->pb_field_time = (ROUNDED_DIV(s->time, ctx->t_frame) - + ROUNDED_DIV(s->last_non_b_time - s->pp_time, ctx->t_frame)) * 2; + if (!s->progressive_sequence) { + if (s->pp_field_time <= s->pb_field_time || s->pb_field_time <= 1) return FRAME_SKIPPED; } } - if(s->avctx->time_base.num) - s->current_picture_ptr->f.pts = ROUNDED_DIV(s->time, s->avctx->time_base.num); + if (s->avctx->time_base.num) + pts = ROUNDED_DIV(s->time, s->avctx->time_base.num); else - s->current_picture_ptr->f.pts = AV_NOPTS_VALUE; - if(s->avctx->debug&FF_DEBUG_PTS) + pts = AV_NOPTS_VALUE; + if (s->avctx->debug&FF_DEBUG_PTS) av_log(s->avctx, AV_LOG_DEBUG, "MPEG4 PTS: %"PRId64"\n", - s->current_picture_ptr->f.pts); + pts); check_marker(gb, "before vop_coded"); /* vop coded */ - if (get_bits1(gb) != 1){ - if(s->avctx->debug&FF_DEBUG_PICT_INFO) + if (get_bits1(gb) != 1) { + if (s->avctx->debug & FF_DEBUG_PICT_INFO) av_log(s->avctx, AV_LOG_ERROR, "vop not coded\n"); return FRAME_SKIPPED; } - if (s->shape != BIN_ONLY_SHAPE && ( s->pict_type == AV_PICTURE_TYPE_P - || (s->pict_type == AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE))) { + if (ctx->new_pred) + decode_new_pred(ctx, gb); + + if (ctx->shape != BIN_ONLY_SHAPE && + (s->pict_type == AV_PICTURE_TYPE_P || + (s->pict_type == AV_PICTURE_TYPE_S && + ctx->vol_sprite_usage == GMC_SPRITE))) { /* rounding type for motion estimation */ s->no_rounding = get_bits1(gb); } else { s->no_rounding = 0; } -//FIXME reduced res stuff - - if (s->shape != RECT_SHAPE) { - if (s->vol_sprite_usage != 1 || s->pict_type != AV_PICTURE_TYPE_I) { - skip_bits(gb, 13); /* width */ - skip_bits1(gb); /* marker */ - skip_bits(gb, 13); /* height */ - skip_bits1(gb); /* marker */ - skip_bits(gb, 13); /* hor_spat_ref */ - skip_bits1(gb); /* marker */ - skip_bits(gb, 13); /* ver_spat_ref */ - } - skip_bits1(gb); /* change_CR_disable */ - - if (get_bits1(gb) != 0) { - skip_bits(gb, 8); /* constant_alpha_value */ - } - } -//FIXME complexity estimation stuff - - if (s->shape != BIN_ONLY_SHAPE) { - skip_bits_long(gb, s->cplx_estimation_trash_i); - if(s->pict_type != AV_PICTURE_TYPE_I) - skip_bits_long(gb, s->cplx_estimation_trash_p); - if(s->pict_type == AV_PICTURE_TYPE_B) - skip_bits_long(gb, s->cplx_estimation_trash_b); - - if(get_bits_left(gb) < 3) { - av_log(s->avctx, AV_LOG_ERROR, "Header truncated\n"); - return -1; - } - s->intra_dc_threshold= ff_mpeg4_dc_threshold[ get_bits(gb, 3) ]; - if(!s->progressive_sequence){ - s->top_field_first= get_bits1(gb); - s->alternate_scan= get_bits1(gb); - }else - s->alternate_scan= 0; - } - - if(s->alternate_scan){ - ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , ff_alternate_vertical_scan); - ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , ff_alternate_vertical_scan); - ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_vertical_scan); - ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan); - } else{ - ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , ff_zigzag_direct); - ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , ff_zigzag_direct); - ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_horizontal_scan); - ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan); - } - - if(s->pict_type == AV_PICTURE_TYPE_S && (s->vol_sprite_usage==STATIC_SPRITE || s->vol_sprite_usage==GMC_SPRITE)){ - if(mpeg4_decode_sprite_trajectory(s, gb) < 0) - return -1; - if(s->sprite_brightness_change) av_log(s->avctx, AV_LOG_ERROR, "sprite_brightness_change not supported\n"); - if(s->vol_sprite_usage==STATIC_SPRITE) av_log(s->avctx, AV_LOG_ERROR, "static sprite not supported\n"); - } - - if (s->shape != BIN_ONLY_SHAPE) { - s->chroma_qscale= s->qscale = get_bits(gb, s->quant_precision); - if(s->qscale==0){ - av_log(s->avctx, AV_LOG_ERROR, "Error, header damaged or not MPEG4 header (qscale=0)\n"); - return -1; // makes no sense to continue, as there is nothing left from the image then - } - - if (s->pict_type != AV_PICTURE_TYPE_I) { - s->f_code = get_bits(gb, 3); /* fcode_for */ - if(s->f_code==0){ - av_log(s->avctx, AV_LOG_ERROR, "Error, header damaged or not MPEG4 header (f_code=0)\n"); - s->f_code=1; - return -1; // makes no sense to continue, as the MV decoding will break very quickly - } - }else - s->f_code=1; - - if (s->pict_type == AV_PICTURE_TYPE_B) { - s->b_code = get_bits(gb, 3); - if(s->b_code==0){ - av_log(s->avctx, AV_LOG_ERROR, "Error, header damaged or not MPEG4 header (b_code=0)\n"); - s->b_code=1; - return -1; // makes no sense to continue, as the MV decoding will break very quickly - } - }else - s->b_code=1; - - if(s->avctx->debug&FF_DEBUG_PICT_INFO){ - av_log(s->avctx, AV_LOG_DEBUG, "qp:%d fc:%d,%d %s size:%d pro:%d alt:%d top:%d %spel part:%d resync:%d w:%d a:%d rnd:%d vot:%d%s dc:%d ce:%d/%d/%d time:%"PRId64" tincr:%d\n", - s->qscale, s->f_code, s->b_code, - s->pict_type == AV_PICTURE_TYPE_I ? "I" : (s->pict_type == AV_PICTURE_TYPE_P ? "P" : (s->pict_type == AV_PICTURE_TYPE_B ? "B" : "S")), - gb->size_in_bits,s->progressive_sequence, s->alternate_scan, s->top_field_first, - s->quarter_sample ? "q" : "h", s->data_partitioning, s->resync_marker, s->num_sprite_warping_points, - s->sprite_warping_accuracy, 1-s->no_rounding, s->vo_type, s->vol_control_parameters ? " VOLC" : " ", s->intra_dc_threshold, - s->cplx_estimation_trash_i, s->cplx_estimation_trash_p, s->cplx_estimation_trash_b, - s->time, - time_increment - ); - } - - if(!s->scalability){ - if (s->shape!=RECT_SHAPE && s->pict_type!=AV_PICTURE_TYPE_I) { - skip_bits1(gb); // vop shape coding type - } - }else{ - if(s->enhancement_type){ - int load_backward_shape= get_bits1(gb); - if(load_backward_shape){ - av_log(s->avctx, AV_LOG_ERROR, "load backward shape isn't supported\n"); - } - } - skip_bits(gb, 2); //ref_select_code - } - } - /* detect buggy encoders which don't set the low_delay flag (divx4/xvid/opendivx)*/ - // note we cannot detect divx5 without b-frames easily (although it's buggy too) - if(s->vo_type==0 && s->vol_control_parameters==0 && s->divx_version==-1 && s->picture_number==0){ - av_log(s->avctx, AV_LOG_WARNING, "looks like this file was encoded with (divx4/(old)xvid/opendivx) -> forcing low_delay flag\n"); - s->low_delay=1; - } - - s->picture_number++; // better than pic number==0 always ;) - - s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table; //FIXME add short header support - s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table; - - if(s->workaround_bugs&FF_BUG_EDGE){ - s->h_edge_pos= s->width; - s->v_edge_pos= s->height; - } - return 0; + // FIXME reduced res stuff + + if (ctx->shape != RECT_SHAPE) { + if (ctx->vol_sprite_usage != 1 || s->pict_type != AV_PICTURE_TYPE_I) { + skip_bits(gb, 13); /* width */ + skip_bits1(gb); /* marker */ + skip_bits(gb, 13); /* height */ + skip_bits1(gb); /* marker */ + skip_bits(gb, 13); /* hor_spat_ref */ + skip_bits1(gb); /* marker */ + skip_bits(gb, 13); /* ver_spat_ref */ + } + skip_bits1(gb); /* change_CR_disable */ + + if (get_bits1(gb) != 0) + skip_bits(gb, 8); /* constant_alpha_value */ + } + + // FIXME complexity estimation stuff + + if (ctx->shape != BIN_ONLY_SHAPE) { + skip_bits_long(gb, ctx->cplx_estimation_trash_i); + if (s->pict_type != AV_PICTURE_TYPE_I) + skip_bits_long(gb, ctx->cplx_estimation_trash_p); + if (s->pict_type == AV_PICTURE_TYPE_B) + skip_bits_long(gb, ctx->cplx_estimation_trash_b); + + if (get_bits_left(gb) < 3) { + av_log(s->avctx, AV_LOG_ERROR, "Header truncated\n"); + return -1; + } + ctx->intra_dc_threshold = ff_mpeg4_dc_threshold[get_bits(gb, 3)]; + if (!s->progressive_sequence) { + s->top_field_first = get_bits1(gb); + s->alternate_scan = get_bits1(gb); + } else + s->alternate_scan = 0; + } + + if (s->alternate_scan) { + ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable, ff_alternate_vertical_scan); + ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable, ff_alternate_vertical_scan); + ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_vertical_scan); + ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan); + } else { + ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable, ff_zigzag_direct); + ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct); + ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_horizontal_scan); + ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan); + } + + if (s->pict_type == AV_PICTURE_TYPE_S && + (ctx->vol_sprite_usage == STATIC_SPRITE || + ctx->vol_sprite_usage == GMC_SPRITE)) { + if (mpeg4_decode_sprite_trajectory(ctx, gb) < 0) + return AVERROR_INVALIDDATA; + if (ctx->sprite_brightness_change) + av_log(s->avctx, AV_LOG_ERROR, + "sprite_brightness_change not supported\n"); + if (ctx->vol_sprite_usage == STATIC_SPRITE) + av_log(s->avctx, AV_LOG_ERROR, "static sprite not supported\n"); + } + + if (ctx->shape != BIN_ONLY_SHAPE) { + s->chroma_qscale = s->qscale = get_bits(gb, s->quant_precision); + if (s->qscale == 0) { + av_log(s->avctx, AV_LOG_ERROR, + "Error, header damaged or not MPEG4 header (qscale=0)\n"); + return -1; // makes no sense to continue, as there is nothing left from the image then + } + + if (s->pict_type != AV_PICTURE_TYPE_I) { + s->f_code = get_bits(gb, 3); /* fcode_for */ + if (s->f_code == 0) { + av_log(s->avctx, AV_LOG_ERROR, + "Error, header damaged or not MPEG4 header (f_code=0)\n"); + s->f_code = 1; + return -1; // makes no sense to continue, as there is nothing left from the image then + } + } else + s->f_code = 1; + + if (s->pict_type == AV_PICTURE_TYPE_B) { + s->b_code = get_bits(gb, 3); + if (s->b_code == 0) { + av_log(s->avctx, AV_LOG_ERROR, + "Error, header damaged or not MPEG4 header (b_code=0)\n"); + s->b_code=1; + return -1; // makes no sense to continue, as the MV decoding will break very quickly + } + } else + s->b_code = 1; + + if (s->avctx->debug & FF_DEBUG_PICT_INFO) { + av_log(s->avctx, AV_LOG_DEBUG, + "qp:%d fc:%d,%d %s size:%d pro:%d alt:%d top:%d %spel part:%d resync:%d w:%d a:%d rnd:%d vot:%d%s dc:%d ce:%d/%d/%d time:%"PRId64" tincr:%d\n", + s->qscale, s->f_code, s->b_code, + s->pict_type == AV_PICTURE_TYPE_I ? "I" : (s->pict_type == AV_PICTURE_TYPE_P ? "P" : (s->pict_type == AV_PICTURE_TYPE_B ? "B" : "S")), + gb->size_in_bits,s->progressive_sequence, s->alternate_scan, + s->top_field_first, s->quarter_sample ? "q" : "h", + s->data_partitioning, ctx->resync_marker, + ctx->num_sprite_warping_points, s->sprite_warping_accuracy, + 1 - s->no_rounding, s->vo_type, + s->vol_control_parameters ? " VOLC" : " ", ctx->intra_dc_threshold, + ctx->cplx_estimation_trash_i, ctx->cplx_estimation_trash_p, + ctx->cplx_estimation_trash_b, + s->time, + time_increment + ); + } + + if (!ctx->scalability) { + if (ctx->shape != RECT_SHAPE && s->pict_type != AV_PICTURE_TYPE_I) + skip_bits1(gb); // vop shape coding type + } else { + if (ctx->enhancement_type) { + int load_backward_shape = get_bits1(gb); + if (load_backward_shape) + av_log(s->avctx, AV_LOG_ERROR, + "load backward shape isn't supported\n"); + } + skip_bits(gb, 2); // ref_select_code + } + } + /* detect buggy encoders which don't set the low_delay flag + * (divx4/xvid/opendivx). Note we cannot detect divx5 without b-frames + * easily (although it's buggy too) */ + if (s->vo_type == 0 && s->vol_control_parameters == 0 && + ctx->divx_version == -1 && s->picture_number == 0) { + av_log(s->avctx, AV_LOG_WARNING, + "looks like this file was encoded with (divx4/(old)xvid/opendivx) -> forcing low_delay flag\n"); + s->low_delay = 1; + } + + s->picture_number++; // better than pic number==0 always ;) + + // FIXME add short header support + s->y_dc_scale_table = ff_mpeg4_y_dc_scale_table; + s->c_dc_scale_table = ff_mpeg4_c_dc_scale_table; + + if (s->workaround_bugs & FF_BUG_EDGE) { + s->h_edge_pos = s->width; + s->v_edge_pos = s->height; + } + return 0; } /** @@ -2168,93 +2484,120 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ * FRAME_SKIPPED if a not coded VOP is found * 0 if a VOP is found */ -int ff_mpeg4_decode_picture_header(MpegEncContext * s, GetBitContext *gb) +int ff_mpeg4_decode_picture_header(Mpeg4DecContext *ctx, GetBitContext *gb) { + MpegEncContext *s = &ctx->m; unsigned startcode, v; /* search next start code */ align_get_bits(gb); - if(s->codec_tag == AV_RL32("WV1F") && show_bits(gb, 24) == 0x575630){ + if (s->codec_tag == AV_RL32("WV1F") && show_bits(gb, 24) == 0x575630) { skip_bits(gb, 24); - if(get_bits(gb, 8) == 0xF0) + if (get_bits(gb, 8) == 0xF0) goto end; } startcode = 0xff; - for(;;) { - if(get_bits_count(gb) >= gb->size_in_bits){ - if(gb->size_in_bits==8 && (s->divx_version>=0 || s->xvid_build>=0) || s->codec_tag == AV_RL32("QMP4")){ + for (;;) { + if (get_bits_count(gb) >= gb->size_in_bits) { + if (gb->size_in_bits == 8 && + (ctx->divx_version >= 0 || ctx->xvid_build >= 0) || s->codec_tag == AV_RL32("QMP4")) { av_log(s->avctx, AV_LOG_VERBOSE, "frame skip %d\n", gb->size_in_bits); - return FRAME_SKIPPED; //divx bug - }else - return -1; //end of stream + return FRAME_SKIPPED; // divx bug + } else + return -1; // end of stream } /* use the bits after the test */ v = get_bits(gb, 8); startcode = ((startcode << 8) | v) & 0xffffffff; - if((startcode&0xFFFFFF00) != 0x100) - continue; //no startcode + if ((startcode & 0xFFFFFF00) != 0x100) + continue; // no startcode - if(s->avctx->debug&FF_DEBUG_STARTCODE){ + if (s->avctx->debug & FF_DEBUG_STARTCODE) { av_log(s->avctx, AV_LOG_DEBUG, "startcode: %3X ", startcode); - if (startcode<=0x11F) av_log(s->avctx, AV_LOG_DEBUG, "Video Object Start"); - else if(startcode<=0x12F) av_log(s->avctx, AV_LOG_DEBUG, "Video Object Layer Start"); - else if(startcode<=0x13F) av_log(s->avctx, AV_LOG_DEBUG, "Reserved"); - else if(startcode<=0x15F) av_log(s->avctx, AV_LOG_DEBUG, "FGS bp start"); - else if(startcode<=0x1AF) av_log(s->avctx, AV_LOG_DEBUG, "Reserved"); - else if(startcode==0x1B0) av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Seq Start"); - else if(startcode==0x1B1) av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Seq End"); - else if(startcode==0x1B2) av_log(s->avctx, AV_LOG_DEBUG, "User Data"); - else if(startcode==0x1B3) av_log(s->avctx, AV_LOG_DEBUG, "Group of VOP start"); - else if(startcode==0x1B4) av_log(s->avctx, AV_LOG_DEBUG, "Video Session Error"); - else if(startcode==0x1B5) av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Start"); - else if(startcode==0x1B6) av_log(s->avctx, AV_LOG_DEBUG, "Video Object Plane start"); - else if(startcode==0x1B7) av_log(s->avctx, AV_LOG_DEBUG, "slice start"); - else if(startcode==0x1B8) av_log(s->avctx, AV_LOG_DEBUG, "extension start"); - else if(startcode==0x1B9) av_log(s->avctx, AV_LOG_DEBUG, "fgs start"); - else if(startcode==0x1BA) av_log(s->avctx, AV_LOG_DEBUG, "FBA Object start"); - else if(startcode==0x1BB) av_log(s->avctx, AV_LOG_DEBUG, "FBA Object Plane start"); - else if(startcode==0x1BC) av_log(s->avctx, AV_LOG_DEBUG, "Mesh Object start"); - else if(startcode==0x1BD) av_log(s->avctx, AV_LOG_DEBUG, "Mesh Object Plane start"); - else if(startcode==0x1BE) av_log(s->avctx, AV_LOG_DEBUG, "Still Texture Object start"); - else if(startcode==0x1BF) av_log(s->avctx, AV_LOG_DEBUG, "Texture Spatial Layer start"); - else if(startcode==0x1C0) av_log(s->avctx, AV_LOG_DEBUG, "Texture SNR Layer start"); - else if(startcode==0x1C1) av_log(s->avctx, AV_LOG_DEBUG, "Texture Tile start"); - else if(startcode==0x1C2) av_log(s->avctx, AV_LOG_DEBUG, "Texture Shape Layer start"); - else if(startcode==0x1C3) av_log(s->avctx, AV_LOG_DEBUG, "stuffing start"); - else if(startcode<=0x1C5) av_log(s->avctx, AV_LOG_DEBUG, "reserved"); - else if(startcode<=0x1FF) av_log(s->avctx, AV_LOG_DEBUG, "System start"); + if (startcode <= 0x11F) + av_log(s->avctx, AV_LOG_DEBUG, "Video Object Start"); + else if (startcode <= 0x12F) + av_log(s->avctx, AV_LOG_DEBUG, "Video Object Layer Start"); + else if (startcode <= 0x13F) + av_log(s->avctx, AV_LOG_DEBUG, "Reserved"); + else if (startcode <= 0x15F) + av_log(s->avctx, AV_LOG_DEBUG, "FGS bp start"); + else if (startcode <= 0x1AF) + av_log(s->avctx, AV_LOG_DEBUG, "Reserved"); + else if (startcode == 0x1B0) + av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Seq Start"); + else if (startcode == 0x1B1) + av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Seq End"); + else if (startcode == 0x1B2) + av_log(s->avctx, AV_LOG_DEBUG, "User Data"); + else if (startcode == 0x1B3) + av_log(s->avctx, AV_LOG_DEBUG, "Group of VOP start"); + else if (startcode == 0x1B4) + av_log(s->avctx, AV_LOG_DEBUG, "Video Session Error"); + else if (startcode == 0x1B5) + av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Start"); + else if (startcode == 0x1B6) + av_log(s->avctx, AV_LOG_DEBUG, "Video Object Plane start"); + else if (startcode == 0x1B7) + av_log(s->avctx, AV_LOG_DEBUG, "slice start"); + else if (startcode == 0x1B8) + av_log(s->avctx, AV_LOG_DEBUG, "extension start"); + else if (startcode == 0x1B9) + av_log(s->avctx, AV_LOG_DEBUG, "fgs start"); + else if (startcode == 0x1BA) + av_log(s->avctx, AV_LOG_DEBUG, "FBA Object start"); + else if (startcode == 0x1BB) + av_log(s->avctx, AV_LOG_DEBUG, "FBA Object Plane start"); + else if (startcode == 0x1BC) + av_log(s->avctx, AV_LOG_DEBUG, "Mesh Object start"); + else if (startcode == 0x1BD) + av_log(s->avctx, AV_LOG_DEBUG, "Mesh Object Plane start"); + else if (startcode == 0x1BE) + av_log(s->avctx, AV_LOG_DEBUG, "Still Texture Object start"); + else if (startcode == 0x1BF) + av_log(s->avctx, AV_LOG_DEBUG, "Texture Spatial Layer start"); + else if (startcode == 0x1C0) + av_log(s->avctx, AV_LOG_DEBUG, "Texture SNR Layer start"); + else if (startcode == 0x1C1) + av_log(s->avctx, AV_LOG_DEBUG, "Texture Tile start"); + else if (startcode == 0x1C2) + av_log(s->avctx, AV_LOG_DEBUG, "Texture Shape Layer start"); + else if (startcode == 0x1C3) + av_log(s->avctx, AV_LOG_DEBUG, "stuffing start"); + else if (startcode <= 0x1C5) + av_log(s->avctx, AV_LOG_DEBUG, "reserved"); + else if (startcode <= 0x1FF) + av_log(s->avctx, AV_LOG_DEBUG, "System start"); av_log(s->avctx, AV_LOG_DEBUG, " at %d\n", get_bits_count(gb)); } - if(startcode >= 0x120 && startcode <= 0x12F){ - if(decode_vol_header(s, gb) < 0) + if (startcode >= 0x120 && startcode <= 0x12F) { + if (decode_vol_header(ctx, gb) < 0) return -1; - } - else if(startcode == USER_DATA_STARTCODE){ - decode_user_data(s, gb); - } - else if(startcode == GOP_STARTCODE){ + } else if (startcode == USER_DATA_STARTCODE) { + decode_user_data(ctx, gb); + } else if (startcode == GOP_STARTCODE) { mpeg4_decode_gop_header(s, gb); - } - else if(startcode == VOS_STARTCODE){ + } else if (startcode == VOS_STARTCODE) { mpeg4_decode_profile_level(s, gb); - } - else if(startcode == VOP_STARTCODE){ + } else if (startcode == VOP_STARTCODE) { break; } align_get_bits(gb); startcode = 0xff; } + end: - if(s->flags& CODEC_FLAG_LOW_DELAY) - s->low_delay=1; - s->avctx->has_b_frames= !s->low_delay; - return decode_vop_header(s, gb); + if (s->flags & CODEC_FLAG_LOW_DELAY) + s->low_delay = 1; + s->avctx->has_b_frames = !s->low_delay; + + return decode_vop_header(ctx, gb); } av_cold void ff_mpeg4videodec_static_init(void) { @@ -2268,42 +2611,101 @@ av_cold void ff_mpeg4videodec_static_init(void) { INIT_VLC_RL(ff_rvlc_rl_inter, 1072); INIT_VLC_RL(ff_rvlc_rl_intra, 1072); INIT_VLC_STATIC(&dc_lum, DC_VLC_BITS, 10 /* 13 */, - &ff_mpeg4_DCtab_lum[0][1], 2, 1, - &ff_mpeg4_DCtab_lum[0][0], 2, 1, 512); + &ff_mpeg4_DCtab_lum[0][1], 2, 1, + &ff_mpeg4_DCtab_lum[0][0], 2, 1, 512); INIT_VLC_STATIC(&dc_chrom, DC_VLC_BITS, 10 /* 13 */, - &ff_mpeg4_DCtab_chrom[0][1], 2, 1, - &ff_mpeg4_DCtab_chrom[0][0], 2, 1, 512); + &ff_mpeg4_DCtab_chrom[0][1], 2, 1, + &ff_mpeg4_DCtab_chrom[0][0], 2, 1, 512); INIT_VLC_STATIC(&sprite_trajectory, SPRITE_TRAJ_VLC_BITS, 15, - &ff_sprite_trajectory_tab[0][1], 4, 2, - &ff_sprite_trajectory_tab[0][0], 4, 2, 128); + &ff_sprite_trajectory_tab[0][1], 4, 2, + &ff_sprite_trajectory_tab[0][0], 4, 2, 128); INIT_VLC_STATIC(&mb_type_b_vlc, MB_TYPE_B_VLC_BITS, 4, - &ff_mb_type_b_tab[0][1], 2, 1, - &ff_mb_type_b_tab[0][0], 2, 1, 16); + &ff_mb_type_b_tab[0][1], 2, 1, + &ff_mb_type_b_tab[0][0], 2, 1, 16); done = 1; } } +int ff_mpeg4_frame_end(AVCodecContext *avctx, const uint8_t *buf, int buf_size) +{ + Mpeg4DecContext *ctx = avctx->priv_data; + MpegEncContext *s = &ctx->m; + + /* divx 5.01+ bitstream reorder stuff */ + /* Since this clobbers the input buffer and hwaccel codecs still need the + * data during hwaccel->end_frame we should not do this any earlier */ + if (s->divx_packed) { + int current_pos = s->gb.buffer == s->bitstream_buffer ? 0 : (get_bits_count(&s->gb) >> 3); + int startcode_found = 0; + + if (buf_size - current_pos > 7) { + + int i; + for (i = current_pos; i < buf_size - 4; i++) + + if (buf[i] == 0 && + buf[i + 1] == 0 && + buf[i + 2] == 1 && + buf[i + 3] == 0xB6) { + startcode_found = !(buf[i + 4] & 0x40); + break; + } + } + + if (startcode_found) { + av_fast_malloc(&s->bitstream_buffer, + &s->allocated_bitstream_buffer_size, + buf_size - current_pos + + FF_INPUT_BUFFER_PADDING_SIZE); + if (!s->bitstream_buffer) + return AVERROR(ENOMEM); + memcpy(s->bitstream_buffer, buf + current_pos, + buf_size - current_pos); + s->bitstream_buffer_size = buf_size - current_pos; + } + } + + return 0; +} + +static int mpeg4_update_thread_context(AVCodecContext *dst, + const AVCodecContext *src) +{ + Mpeg4DecContext *s = dst->priv_data; + const Mpeg4DecContext *s1 = src->priv_data; + + int ret = ff_mpeg_update_thread_context(dst, src); + + if (ret < 0) + return ret; + + memcpy(((uint8_t*)s) + sizeof(MpegEncContext), ((uint8_t*)s1) + sizeof(MpegEncContext), sizeof(Mpeg4DecContext) - sizeof(MpegEncContext)); + + return 0; +} + static av_cold int decode_init(AVCodecContext *avctx) { - MpegEncContext *s = avctx->priv_data; + Mpeg4DecContext *ctx = avctx->priv_data; + MpegEncContext *s = &ctx->m; int ret; - s->divx_version= - s->divx_build= - s->xvid_build= - s->lavc_build= -1; + ctx->divx_version = + ctx->divx_build = + ctx->xvid_build = + ctx->lavc_build = -1; - if((ret=ff_h263_decode_init(avctx)) < 0) + if ((ret = ff_h263_decode_init(avctx)) < 0) return ret; ff_mpeg4videodec_static_init(); s->h263_pred = 1; - s->low_delay = 0; //default, might be overridden in the vol header during header parsing - s->decode_mb= mpeg4_decode_mb; - s->time_increment_bits = 4; /* default value for broken headers */ - avctx->chroma_sample_location = AVCHROMA_LOC_LEFT; + s->low_delay = 0; /* default, might be overridden in the vol header during header parsing */ + s->decode_mb = mpeg4_decode_mb; + ctx->time_increment_bits = 4; /* default value for broken headers */ + avctx->chroma_sample_location = AVCHROMA_LOC_LEFT; avctx->internal->allocate_progress = 1; return 0; @@ -2351,9 +2753,10 @@ static const AVClass mpeg4_vdpau_class = { AVCodec ff_mpeg4_decoder = { .name = "mpeg4", + .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MPEG4, - .priv_data_size = sizeof(MpegEncContext), + .priv_data_size = sizeof(Mpeg4DecContext), .init = decode_init, .close = ff_h263_decode_end, .decode = ff_h263_decode_frame, @@ -2362,10 +2765,9 @@ AVCodec ff_mpeg4_decoder = { CODEC_CAP_FRAME_THREADS, .flush = ff_mpeg_flush, .max_lowres = 3, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2"), .pix_fmts = ff_h263_hwaccel_pixfmt_list_420, .profiles = NULL_IF_CONFIG_SMALL(mpeg4_video_profiles), - .update_thread_context = ONLY_IF_THREADS_ENABLED(ff_mpeg_update_thread_context), + .update_thread_context = ONLY_IF_THREADS_ENABLED(mpeg4_update_thread_context), .priv_class = &mpeg4_class, }; @@ -2373,6 +2775,7 @@ AVCodec ff_mpeg4_decoder = { #if CONFIG_MPEG4_VDPAU_DECODER AVCodec ff_mpeg4_vdpau_decoder = { .name = "mpeg4_vdpau", + .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 (VDPAU)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MPEG4, .priv_data_size = sizeof(MpegEncContext), @@ -2381,8 +2784,7 @@ AVCodec ff_mpeg4_vdpau_decoder = { .decode = ff_h263_decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 (VDPAU)"), - .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_VDPAU_MPEG4, + .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_VDPAU_MPEG4, AV_PIX_FMT_NONE }, .priv_class = &mpeg4_vdpau_class, }; diff --git a/ffmpeg/libavcodec/mpeg4videoenc.c b/ffmpeg/libavcodec/mpeg4videoenc.c index 5662735..14c6e8f 100644 --- a/ffmpeg/libavcodec/mpeg4videoenc.c +++ b/ffmpeg/libavcodec/mpeg4videoenc.c @@ -20,69 +20,73 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/attributes.h" #include "libavutil/log.h" #include "libavutil/opt.h" #include "mpegvideo.h" #include "h263.h" #include "mpeg4video.h" -//The uni_DCtab_* tables below contain unified bits+length tables to encode DC -//differences in mpeg4. Unified in the sense that the specification specifies -//this encoding in several steps. -static uint8_t uni_DCtab_lum_len[512]; -static uint8_t uni_DCtab_chrom_len[512]; +/* The uni_DCtab_* tables below contain unified bits+length tables to encode DC + * differences in mpeg4. Unified in the sense that the specification specifies + * this encoding in several steps. */ +static uint8_t uni_DCtab_lum_len[512]; +static uint8_t uni_DCtab_chrom_len[512]; static uint16_t uni_DCtab_lum_bits[512]; static uint16_t uni_DCtab_chrom_bits[512]; -//unified encoding tables for run length encoding of coefficients -//unified in the sense that the specification specifies the encoding in several steps. -static uint32_t uni_mpeg4_intra_rl_bits[64*64*2*2]; -static uint8_t uni_mpeg4_intra_rl_len [64*64*2*2]; -static uint32_t uni_mpeg4_inter_rl_bits[64*64*2*2]; -static uint8_t uni_mpeg4_inter_rl_len [64*64*2*2]; -//#define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128 + (run)*256 + (level)) -//#define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128*64 + (run) + (level)*64) -#define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128*64 + (run)*128 + (level)) +/* Unified encoding tables for run length encoding of coefficients. + * Unified in the sense that the specification specifies the encoding in several steps. */ +static uint32_t uni_mpeg4_intra_rl_bits[64 * 64 * 2 * 2]; +static uint8_t uni_mpeg4_intra_rl_len[64 * 64 * 2 * 2]; +static uint32_t uni_mpeg4_inter_rl_bits[64 * 64 * 2 * 2]; +static uint8_t uni_mpeg4_inter_rl_len[64 * 64 * 2 * 2]; -/* mpeg4 -inter -max level: 24/6 -max run: 53/63 - -intra -max level: 53/16 -max run: 29/41 -*/ +//#define UNI_MPEG4_ENC_INDEX(last, run, level) ((last) * 128 + (run) * 256 + (level)) +//#define UNI_MPEG4_ENC_INDEX(last, run, level) ((last) * 128 * 64 + (run) + (level) * 64) +#define UNI_MPEG4_ENC_INDEX(last, run, level) ((last) * 128 * 64 + (run) * 128 + (level)) +/* mpeg4 + * inter + * max level: 24/6 + * max run: 53/63 + * + * intra + * max level: 53/16 + * max run: 29/41 + */ /** * Return the number of bits that encoding the 8x8 block in block would need. * @param[in] block_last_index last index in scantable order that refers to a non zero element in block. */ -static inline int get_block_rate(MpegEncContext * s, int16_t block[64], int block_last_index, uint8_t scantable[64]){ - int last=0; +static inline int get_block_rate(MpegEncContext *s, int16_t block[64], + int block_last_index, uint8_t scantable[64]) +{ + int last = 0; int j; - int rate=0; - - for(j=1; j<=block_last_index; j++){ - const int index= scantable[j]; - int level= block[index]; - if(level){ - level+= 64; - if((level&(~127)) == 0){ - if(jintra_ac_vlc_length [UNI_AC_ENC_INDEX(j-last-1, level)]; - else rate+= s->intra_ac_vlc_last_length[UNI_AC_ENC_INDEX(j-last-1, level)]; - }else + int rate = 0; + + for (j = 1; j <= block_last_index; j++) { + const int index = scantable[j]; + int level = block[index]; + if (level) { + level += 64; + if ((level & (~127)) == 0) { + if (j < block_last_index) + rate += s->intra_ac_vlc_length[UNI_AC_ENC_INDEX(j - last - 1, level)]; + else + rate += s->intra_ac_vlc_last_length[UNI_AC_ENC_INDEX(j - last - 1, level)]; + } else rate += s->ac_esc_length; - last= j; + last = j; } } return rate; } - /** * Restore the ac coefficients in block that have been changed by decide_ac_pred(). * This function also restores s->block_last_index. @@ -91,25 +95,25 @@ static inline int get_block_rate(MpegEncContext * s, int16_t block[64], int bloc * @param[out] st scantable for each 8x8 block * @param[in] zigzag_last_index index referring to the last non zero coefficient in zigzag order */ -static inline void restore_ac_coeffs(MpegEncContext * s, int16_t block[6][64], const int dir[6], uint8_t *st[6], const int zigzag_last_index[6]) +static inline void restore_ac_coeffs(MpegEncContext *s, int16_t block[6][64], + const int dir[6], uint8_t *st[6], + const int zigzag_last_index[6]) { int i, n; - memcpy(s->block_last_index, zigzag_last_index, sizeof(int)*6); + memcpy(s->block_last_index, zigzag_last_index, sizeof(int) * 6); - for(n=0; n<6; n++){ + for (n = 0; n < 6; n++) { int16_t *ac_val = s->ac_val[0][0] + s->block_index[n] * 16; - st[n]= s->intra_scantable.permutated; - if(dir[n]){ + st[n] = s->intra_scantable.permutated; + if (dir[n]) { /* top prediction */ - for(i=1; i<8; i++){ - block[n][s->dsp.idct_permutation[i ]] = ac_val[i+8]; - } - }else{ + for (i = 1; i < 8; i++) + block[n][s->dsp.idct_permutation[i]] = ac_val[i + 8]; + } else { /* left prediction */ - for(i=1; i<8; i++){ - block[n][s->dsp.idct_permutation[i<<3]]= ac_val[i ]; - } + for (i = 1; i < 8; i++) + block[n][s->dsp.idct_permutation[i << 3]] = ac_val[i]; } } } @@ -122,77 +126,81 @@ static inline void restore_ac_coeffs(MpegEncContext * s, int16_t block[6][64], c * @param[out] st scantable for each 8x8 block * @param[out] zigzag_last_index index referring to the last non zero coefficient in zigzag order */ -static inline int decide_ac_pred(MpegEncContext * s, int16_t block[6][64], const int dir[6], uint8_t *st[6], int zigzag_last_index[6]) +static inline int decide_ac_pred(MpegEncContext *s, int16_t block[6][64], + const int dir[6], uint8_t *st[6], + int zigzag_last_index[6]) { - int score= 0; + int score = 0; int i, n; - int8_t * const qscale_table = s->current_picture.qscale_table; + int8_t *const qscale_table = s->current_picture.qscale_table; - memcpy(zigzag_last_index, s->block_last_index, sizeof(int)*6); + memcpy(zigzag_last_index, s->block_last_index, sizeof(int) * 6); - for(n=0; n<6; n++){ + for (n = 0; n < 6; n++) { int16_t *ac_val, *ac_val1; - score -= get_block_rate(s, block[n], s->block_last_index[n], s->intra_scantable.permutated); + score -= get_block_rate(s, block[n], s->block_last_index[n], + s->intra_scantable.permutated); - ac_val = s->ac_val[0][0] + s->block_index[n] * 16; - ac_val1= ac_val; - if(dir[n]){ - const int xy= s->mb_x + s->mb_y*s->mb_stride - s->mb_stride; + ac_val = s->ac_val[0][0] + s->block_index[n] * 16; + ac_val1 = ac_val; + if (dir[n]) { + const int xy = s->mb_x + s->mb_y * s->mb_stride - s->mb_stride; /* top prediction */ - ac_val-= s->block_wrap[n]*16; - if(s->mb_y==0 || s->qscale == qscale_table[xy] || n==2 || n==3){ + ac_val -= s->block_wrap[n] * 16; + if (s->mb_y == 0 || s->qscale == qscale_table[xy] || n == 2 || n == 3) { /* same qscale */ - for(i=1; i<8; i++){ - const int level= block[n][s->dsp.idct_permutation[i ]]; - block[n][s->dsp.idct_permutation[i ]] = level - ac_val[i+8]; - ac_val1[i ]= block[n][s->dsp.idct_permutation[i<<3]]; - ac_val1[i+8]= level; + for (i = 1; i < 8; i++) { + const int level = block[n][s->dsp.idct_permutation[i]]; + block[n][s->dsp.idct_permutation[i]] = level - ac_val[i + 8]; + ac_val1[i] = block[n][s->dsp.idct_permutation[i << 3]]; + ac_val1[i + 8] = level; } - }else{ + } else { /* different qscale, we must rescale */ - for(i=1; i<8; i++){ - const int level= block[n][s->dsp.idct_permutation[i ]]; - block[n][s->dsp.idct_permutation[i ]] = level - ROUNDED_DIV(ac_val[i + 8]*qscale_table[xy], s->qscale); - ac_val1[i ]= block[n][s->dsp.idct_permutation[i<<3]]; - ac_val1[i+8]= level; + for (i = 1; i < 8; i++) { + const int level = block[n][s->dsp.idct_permutation[i]]; + block[n][s->dsp.idct_permutation[i]] = level - ROUNDED_DIV(ac_val[i + 8] * qscale_table[xy], s->qscale); + ac_val1[i] = block[n][s->dsp.idct_permutation[i << 3]]; + ac_val1[i + 8] = level; } } - st[n]= s->intra_h_scantable.permutated; - }else{ - const int xy= s->mb_x-1 + s->mb_y*s->mb_stride; + st[n] = s->intra_h_scantable.permutated; + } else { + const int xy = s->mb_x - 1 + s->mb_y * s->mb_stride; /* left prediction */ - ac_val-= 16; - if(s->mb_x==0 || s->qscale == qscale_table[xy] || n==1 || n==3){ + ac_val -= 16; + if (s->mb_x == 0 || s->qscale == qscale_table[xy] || n == 1 || n == 3) { /* same qscale */ - for(i=1; i<8; i++){ - const int level= block[n][s->dsp.idct_permutation[i<<3]]; - block[n][s->dsp.idct_permutation[i<<3]]= level - ac_val[i]; - ac_val1[i ]= level; - ac_val1[i+8]= block[n][s->dsp.idct_permutation[i ]]; + for (i = 1; i < 8; i++) { + const int level = block[n][s->dsp.idct_permutation[i << 3]]; + block[n][s->dsp.idct_permutation[i << 3]] = level - ac_val[i]; + ac_val1[i] = level; + ac_val1[i + 8] = block[n][s->dsp.idct_permutation[i]]; } - }else{ + } else { /* different qscale, we must rescale */ - for(i=1; i<8; i++){ - const int level= block[n][s->dsp.idct_permutation[i<<3]]; - block[n][s->dsp.idct_permutation[i<<3]]= level - ROUNDED_DIV(ac_val[i]*qscale_table[xy], s->qscale); - ac_val1[i ]= level; - ac_val1[i+8]= block[n][s->dsp.idct_permutation[i ]]; + for (i = 1; i < 8; i++) { + const int level = block[n][s->dsp.idct_permutation[i << 3]]; + block[n][s->dsp.idct_permutation[i << 3]] = level - ROUNDED_DIV(ac_val[i] * qscale_table[xy], s->qscale); + ac_val1[i] = level; + ac_val1[i + 8] = block[n][s->dsp.idct_permutation[i]]; } } - st[n]= s->intra_v_scantable.permutated; + st[n] = s->intra_v_scantable.permutated; } - for(i=63; i>0; i--) //FIXME optimize - if(block[n][ st[n][i] ]) break; - s->block_last_index[n]= i; + for (i = 63; i > 0; i--) // FIXME optimize + if (block[n][st[n][i]]) + break; + s->block_last_index[n] = i; score += get_block_rate(s, block[n], s->block_last_index[n], st[n]); } - if(score < 0){ + if (score < 0) { return 1; - }else{ + } else { restore_ac_coeffs(s, block, dir, st, zigzag_last_index); return 0; } @@ -201,51 +209,55 @@ static inline int decide_ac_pred(MpegEncContext * s, int16_t block[6][64], const /** * modify mb_type & qscale so that encoding is actually possible in mpeg4 */ -void ff_clean_mpeg4_qscales(MpegEncContext *s){ +void ff_clean_mpeg4_qscales(MpegEncContext *s) +{ int i; - int8_t * const qscale_table = s->current_picture.qscale_table; + int8_t *const qscale_table = s->current_picture.qscale_table; ff_clean_h263_qscales(s); - if(s->pict_type== AV_PICTURE_TYPE_B){ - int odd=0; - /* ok, come on, this isn't funny anymore, there's more code for handling this mpeg4 mess than for the actual adaptive quantization */ + if (s->pict_type == AV_PICTURE_TYPE_B) { + int odd = 0; + /* ok, come on, this isn't funny anymore, there's more code for + * handling this mpeg4 mess than for the actual adaptive quantization */ - for(i=0; imb_num; i++){ - int mb_xy= s->mb_index2xy[i]; - odd += qscale_table[mb_xy]&1; + for (i = 0; i < s->mb_num; i++) { + int mb_xy = s->mb_index2xy[i]; + odd += qscale_table[mb_xy] & 1; } - if(2*odd > s->mb_num) odd=1; - else odd=0; + if (2 * odd > s->mb_num) + odd = 1; + else + odd = 0; - for(i=0; imb_num; i++){ - int mb_xy= s->mb_index2xy[i]; - if((qscale_table[mb_xy]&1) != odd) + for (i = 0; i < s->mb_num; i++) { + int mb_xy = s->mb_index2xy[i]; + if ((qscale_table[mb_xy] & 1) != odd) qscale_table[mb_xy]++; - if(qscale_table[mb_xy] > 31) - qscale_table[mb_xy]= 31; + if (qscale_table[mb_xy] > 31) + qscale_table[mb_xy] = 31; } - for(i=1; imb_num; i++){ - int mb_xy= s->mb_index2xy[i]; - if(qscale_table[mb_xy] != qscale_table[s->mb_index2xy[i-1]] && (s->mb_type[mb_xy]&CANDIDATE_MB_TYPE_DIRECT)){ - s->mb_type[mb_xy]|= CANDIDATE_MB_TYPE_BIDIR; + for (i = 1; i < s->mb_num; i++) { + int mb_xy = s->mb_index2xy[i]; + if (qscale_table[mb_xy] != qscale_table[s->mb_index2xy[i - 1]] && + (s->mb_type[mb_xy] & CANDIDATE_MB_TYPE_DIRECT)) { + s->mb_type[mb_xy] |= CANDIDATE_MB_TYPE_BIDIR; } } } } - /** * Encode the dc value. * @param n block index (0-3 are luma, 4-5 are chroma) */ -static inline void mpeg4_encode_dc(PutBitContext * s, int level, int n) +static inline void mpeg4_encode_dc(PutBitContext *s, int level, int n) { #if 1 /* DC will overflow if level is outside the [-255,255] range. */ - level+=256; + level += 256; if (n < 4) { /* luminance */ put_bits(s, uni_DCtab_lum_len[level], uni_DCtab_lum_bits[level]); @@ -257,7 +269,7 @@ static inline void mpeg4_encode_dc(PutBitContext * s, int level, int n) int size, v; /* find number of bits */ size = 0; - v = abs(level); + v = abs(level); while (v) { v >>= 1; size++; @@ -282,85 +294,98 @@ static inline void mpeg4_encode_dc(PutBitContext * s, int level, int n) #endif } -static inline int mpeg4_get_dc_length(int level, int n){ - if (n < 4) { +static inline int mpeg4_get_dc_length(int level, int n) +{ + if (n < 4) return uni_DCtab_lum_len[level + 256]; - } else { + else return uni_DCtab_chrom_len[level + 256]; - } } /** * Encode an 8x8 block. * @param n block index (0-3 are luma, 4-5 are chroma) */ -static inline void mpeg4_encode_block(MpegEncContext * s, int16_t * block, int n, int intra_dc, - uint8_t *scan_table, PutBitContext *dc_pb, PutBitContext *ac_pb) +static inline void mpeg4_encode_block(MpegEncContext *s, + int16_t *block, int n, int intra_dc, + uint8_t *scan_table, PutBitContext *dc_pb, + PutBitContext *ac_pb) { int i, last_non_zero; uint32_t *bits_tab; uint8_t *len_tab; const int last_index = s->block_last_index[n]; - if (s->mb_intra) { //Note gcc (3.2.1 at least) will optimize this away + if (s->mb_intra) { // Note gcc (3.2.1 at least) will optimize this away /* mpeg4 based DC predictor */ mpeg4_encode_dc(dc_pb, intra_dc, n); - if(last_index<1) return; + if (last_index < 1) + return; i = 1; - bits_tab= uni_mpeg4_intra_rl_bits; - len_tab = uni_mpeg4_intra_rl_len; + bits_tab = uni_mpeg4_intra_rl_bits; + len_tab = uni_mpeg4_intra_rl_len; } else { - if(last_index<0) return; + if (last_index < 0) + return; i = 0; - bits_tab= uni_mpeg4_inter_rl_bits; - len_tab = uni_mpeg4_inter_rl_len; + bits_tab = uni_mpeg4_inter_rl_bits; + len_tab = uni_mpeg4_inter_rl_len; } /* AC coefs */ last_non_zero = i - 1; for (; i < last_index; i++) { - int level = block[ scan_table[i] ]; + int level = block[scan_table[i]]; if (level) { int run = i - last_non_zero - 1; - level+=64; - if((level&(~127)) == 0){ - const int index= UNI_MPEG4_ENC_INDEX(0, run, level); + level += 64; + if ((level & (~127)) == 0) { + const int index = UNI_MPEG4_ENC_INDEX(0, run, level); put_bits(ac_pb, len_tab[index], bits_tab[index]); - }else{ //ESC3 - put_bits(ac_pb, 7+2+1+6+1+12+1, (3<<23)+(3<<21)+(0<<20)+(run<<14)+(1<<13)+(((level-64)&0xfff)<<1)+1); + } else { // ESC3 + put_bits(ac_pb, + 7 + 2 + 1 + 6 + 1 + 12 + 1, + (3 << 23) + (3 << 21) + (0 << 20) + (run << 14) + + (1 << 13) + (((level - 64) & 0xfff) << 1) + 1); } last_non_zero = i; } } - /*if(i<=last_index)*/{ - int level = block[ scan_table[i] ]; - int run = i - last_non_zero - 1; - level+=64; - if((level&(~127)) == 0){ - const int index= UNI_MPEG4_ENC_INDEX(1, run, level); + /* if (i <= last_index) */ { + int level = block[scan_table[i]]; + int run = i - last_non_zero - 1; + level += 64; + if ((level & (~127)) == 0) { + const int index = UNI_MPEG4_ENC_INDEX(1, run, level); put_bits(ac_pb, len_tab[index], bits_tab[index]); - }else{ //ESC3 - put_bits(ac_pb, 7+2+1+6+1+12+1, (3<<23)+(3<<21)+(1<<20)+(run<<14)+(1<<13)+(((level-64)&0xfff)<<1)+1); + } else { // ESC3 + put_bits(ac_pb, + 7 + 2 + 1 + 6 + 1 + 12 + 1, + (3 << 23) + (3 << 21) + (1 << 20) + (run << 14) + + (1 << 13) + (((level - 64) & 0xfff) << 1) + 1); } } } -static int mpeg4_get_block_length(MpegEncContext * s, int16_t * block, int n, int intra_dc, - uint8_t *scan_table) +static int mpeg4_get_block_length(MpegEncContext *s, + int16_t *block, int n, + int intra_dc, uint8_t *scan_table) { int i, last_non_zero; uint8_t *len_tab; const int last_index = s->block_last_index[n]; - int len=0; + int len = 0; - if (s->mb_intra) { //Note gcc (3.2.1 at least) will optimize this away + if (s->mb_intra) { // Note gcc (3.2.1 at least) will optimize this away /* mpeg4 based DC predictor */ len += mpeg4_get_dc_length(intra_dc, n); - if(last_index<1) return len; + if (last_index < 1) + return len; i = 1; len_tab = uni_mpeg4_intra_rl_len; } else { - if(last_index<0) return 0; + if (last_index < 0) + return 0; i = 0; len_tab = uni_mpeg4_inter_rl_len; } @@ -368,82 +393,88 @@ static int mpeg4_get_block_length(MpegEncContext * s, int16_t * block, int n, in /* AC coefs */ last_non_zero = i - 1; for (; i < last_index; i++) { - int level = block[ scan_table[i] ]; + int level = block[scan_table[i]]; if (level) { int run = i - last_non_zero - 1; - level+=64; - if((level&(~127)) == 0){ - const int index= UNI_MPEG4_ENC_INDEX(0, run, level); + level += 64; + if ((level & (~127)) == 0) { + const int index = UNI_MPEG4_ENC_INDEX(0, run, level); len += len_tab[index]; - }else{ //ESC3 - len += 7+2+1+6+1+12+1; + } else { // ESC3 + len += 7 + 2 + 1 + 6 + 1 + 12 + 1; } last_non_zero = i; } } - /*if(i<=last_index)*/{ - int level = block[ scan_table[i] ]; - int run = i - last_non_zero - 1; - level+=64; - if((level&(~127)) == 0){ - const int index= UNI_MPEG4_ENC_INDEX(1, run, level); + /* if (i <= last_index) */ { + int level = block[scan_table[i]]; + int run = i - last_non_zero - 1; + level += 64; + if ((level & (~127)) == 0) { + const int index = UNI_MPEG4_ENC_INDEX(1, run, level); len += len_tab[index]; - }else{ //ESC3 - len += 7+2+1+6+1+12+1; + } else { // ESC3 + len += 7 + 2 + 1 + 6 + 1 + 12 + 1; } } return len; } -static inline void mpeg4_encode_blocks(MpegEncContext * s, int16_t block[6][64], int intra_dc[6], - uint8_t **scan_table, PutBitContext *dc_pb, PutBitContext *ac_pb){ +static inline void mpeg4_encode_blocks(MpegEncContext *s, int16_t block[6][64], + int intra_dc[6], uint8_t **scan_table, + PutBitContext *dc_pb, + PutBitContext *ac_pb) +{ int i; - if(scan_table){ - if(s->flags2 & CODEC_FLAG2_NO_OUTPUT){ - for (i = 0; i < 6; i++) { - skip_put_bits(&s->pb, mpeg4_get_block_length(s, block[i], i, intra_dc[i], scan_table[i])); - } - }else{ + if (scan_table) { + if (s->flags2 & CODEC_FLAG2_NO_OUTPUT) { + for (i = 0; i < 6; i++) + skip_put_bits(&s->pb, + mpeg4_get_block_length(s, block[i], i, + intra_dc[i], scan_table[i])); + } else { /* encode each block */ - for (i = 0; i < 6; i++) { - mpeg4_encode_block(s, block[i], i, intra_dc[i], scan_table[i], dc_pb, ac_pb); - } + for (i = 0; i < 6; i++) + mpeg4_encode_block(s, block[i], i, + intra_dc[i], scan_table[i], dc_pb, ac_pb); } - }else{ - if(s->flags2 & CODEC_FLAG2_NO_OUTPUT){ - for (i = 0; i < 6; i++) { - skip_put_bits(&s->pb, mpeg4_get_block_length(s, block[i], i, 0, s->intra_scantable.permutated)); - } - }else{ + } else { + if (s->flags2 & CODEC_FLAG2_NO_OUTPUT) { + for (i = 0; i < 6; i++) + skip_put_bits(&s->pb, + mpeg4_get_block_length(s, block[i], i, 0, + s->intra_scantable.permutated)); + } else { /* encode each block */ - for (i = 0; i < 6; i++) { - mpeg4_encode_block(s, block[i], i, 0, s->intra_scantable.permutated, dc_pb, ac_pb); - } + for (i = 0; i < 6; i++) + mpeg4_encode_block(s, block[i], i, 0, + s->intra_scantable.permutated, dc_pb, ac_pb); } } } -static inline int get_b_cbp(MpegEncContext * s, int16_t block[6][64], +static inline int get_b_cbp(MpegEncContext *s, int16_t block[6][64], int motion_x, int motion_y, int mb_type) { int cbp = 0, i; if (s->mpv_flags & FF_MPV_FLAG_CBP_RD) { - int score = 0; + int score = 0; const int lambda = s->lambda2 >> (FF_LAMBDA_SHIFT - 6); - for (i = 0; i < 6; i++) + for (i = 0; i < 6; i++) { if (s->coded_score[i] < 0) { score += s->coded_score[i]; cbp |= 1 << (5 - i); } + } if (cbp) { int zero_score = -6; if ((motion_x | motion_y | s->dquant | mb_type) == 0) - zero_score -= 4; //2*MV + mb_type + cbp bit + zero_score -= 4; // 2 * MV + mb_type + cbp bit zero_score *= lambda; if (zero_score <= score) @@ -465,62 +496,61 @@ static inline int get_b_cbp(MpegEncContext * s, int16_t block[6][64], return cbp; } -//FIXME this is duplicated to h263.c -static const int dquant_code[5]= {1,0,9,2,3}; +// FIXME this is duplicated to h263.c +static const int dquant_code[5] = { 1, 0, 9, 2, 3 }; -void ff_mpeg4_encode_mb(MpegEncContext * s, - int16_t block[6][64], +void ff_mpeg4_encode_mb(MpegEncContext *s, int16_t block[6][64], int motion_x, int motion_y) { int cbpc, cbpy, pred_x, pred_y; - PutBitContext * const pb2 = s->data_partitioning ? &s->pb2 : &s->pb; - PutBitContext * const tex_pb = s->data_partitioning && s->pict_type!=AV_PICTURE_TYPE_B ? &s->tex_pb : &s->pb; - PutBitContext * const dc_pb = s->data_partitioning && s->pict_type!=AV_PICTURE_TYPE_I ? &s->pb2 : &s->pb; - const int interleaved_stats= (s->flags&CODEC_FLAG_PASS1) && !s->data_partitioning ? 1 : 0; + PutBitContext *const pb2 = s->data_partitioning ? &s->pb2 : &s->pb; + PutBitContext *const tex_pb = s->data_partitioning && s->pict_type != AV_PICTURE_TYPE_B ? &s->tex_pb : &s->pb; + PutBitContext *const dc_pb = s->data_partitioning && s->pict_type != AV_PICTURE_TYPE_I ? &s->pb2 : &s->pb; + const int interleaved_stats = (s->flags & CODEC_FLAG_PASS1) && !s->data_partitioning ? 1 : 0; if (!s->mb_intra) { int i, cbp; - if(s->pict_type==AV_PICTURE_TYPE_B){ - static const int mb_type_table[8]= {-1, 3, 2, 1,-1,-1,-1, 0}; /* convert from mv_dir to type */ - int mb_type= mb_type_table[s->mv_dir]; - - if(s->mb_x==0){ - for(i=0; i<2; i++){ - s->last_mv[i][0][0]= - s->last_mv[i][0][1]= - s->last_mv[i][1][0]= - s->last_mv[i][1][1]= 0; - } + if (s->pict_type == AV_PICTURE_TYPE_B) { + /* convert from mv_dir to type */ + static const int mb_type_table[8] = { -1, 3, 2, 1, -1, -1, -1, 0 }; + int mb_type = mb_type_table[s->mv_dir]; + + if (s->mb_x == 0) { + for (i = 0; i < 2; i++) + s->last_mv[i][0][0] = + s->last_mv[i][0][1] = + s->last_mv[i][1][0] = + s->last_mv[i][1][1] = 0; } - av_assert2(s->dquant>=-2 && s->dquant<=2); - av_assert2((s->dquant&1)==0); - av_assert2(mb_type>=0); + av_assert2(s->dquant >= -2 && s->dquant <= 2); + av_assert2((s->dquant & 1) == 0); + av_assert2(mb_type >= 0); /* nothing to do if this MB was skipped in the next P Frame */ - if (s->next_picture.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]) { //FIXME avoid DCT & ... + if (s->next_picture.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]) { // FIXME avoid DCT & ... s->skip_count++; - s->mv[0][0][0]= - s->mv[0][0][1]= - s->mv[1][0][0]= - s->mv[1][0][1]= 0; - s->mv_dir= MV_DIR_FORWARD; //doesn't matter + s->mv[0][0][0] = + s->mv[0][0][1] = + s->mv[1][0][0] = + s->mv[1][0][1] = 0; + s->mv_dir = MV_DIR_FORWARD; // doesn't matter s->qscale -= s->dquant; -// s->mb_skipped=1; +// s->mb_skipped = 1; return; } - cbp= get_b_cbp(s, block, motion_x, motion_y, mb_type); + cbp = get_b_cbp(s, block, motion_x, motion_y, mb_type); - if ((cbp | motion_x | motion_y | mb_type) ==0) { + if ((cbp | motion_x | motion_y | mb_type) == 0) { /* direct MB with MV={0,0} */ - av_assert2(s->dquant==0); + av_assert2(s->dquant == 0); put_bits(&s->pb, 1, 1); /* mb not coded modb1=1 */ - if(interleaved_stats){ + if (interleaved_stats) { s->misc_bits++; s->last_bits++; } @@ -528,149 +558,160 @@ void ff_mpeg4_encode_mb(MpegEncContext * s, return; } - put_bits(&s->pb, 1, 0); /* mb coded modb1=0 */ - put_bits(&s->pb, 1, cbp ? 0 : 1); /* modb2 */ //FIXME merge - put_bits(&s->pb, mb_type+1, 1); // this table is so simple that we don't need it :) - if(cbp) put_bits(&s->pb, 6, cbp); + put_bits(&s->pb, 1, 0); /* mb coded modb1=0 */ + put_bits(&s->pb, 1, cbp ? 0 : 1); /* modb2 */ // FIXME merge + put_bits(&s->pb, mb_type + 1, 1); // this table is so simple that we don't need it :) + if (cbp) + put_bits(&s->pb, 6, cbp); - if(cbp && mb_type){ - if(s->dquant) - put_bits(&s->pb, 2, (s->dquant>>2)+3); + if (cbp && mb_type) { + if (s->dquant) + put_bits(&s->pb, 2, (s->dquant >> 2) + 3); else put_bits(&s->pb, 1, 0); - }else + } else s->qscale -= s->dquant; - if(!s->progressive_sequence){ - if(cbp) + if (!s->progressive_sequence) { + if (cbp) put_bits(&s->pb, 1, s->interlaced_dct); - if(mb_type) // not direct mode + if (mb_type) // not direct mode put_bits(&s->pb, 1, s->mv_type == MV_TYPE_FIELD); } - if(interleaved_stats){ - s->misc_bits+= get_bits_diff(s); - } + if (interleaved_stats) + s->misc_bits += get_bits_diff(s); - if(mb_type == 0){ + if (!mb_type) { av_assert2(s->mv_dir & MV_DIRECT); ff_h263_encode_motion_vector(s, motion_x, motion_y, 1); s->b_count++; s->f_count++; - }else{ + } else { av_assert2(mb_type > 0 && mb_type < 4); - if(s->mv_type != MV_TYPE_FIELD){ - if(s->mv_dir & MV_DIR_FORWARD){ - ff_h263_encode_motion_vector(s, s->mv[0][0][0] - s->last_mv[0][0][0], - s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code); - s->last_mv[0][0][0]= s->last_mv[0][1][0]= s->mv[0][0][0]; - s->last_mv[0][0][1]= s->last_mv[0][1][1]= s->mv[0][0][1]; + if (s->mv_type != MV_TYPE_FIELD) { + if (s->mv_dir & MV_DIR_FORWARD) { + ff_h263_encode_motion_vector(s, + s->mv[0][0][0] - s->last_mv[0][0][0], + s->mv[0][0][1] - s->last_mv[0][0][1], + s->f_code); + s->last_mv[0][0][0] = + s->last_mv[0][1][0] = s->mv[0][0][0]; + s->last_mv[0][0][1] = + s->last_mv[0][1][1] = s->mv[0][0][1]; s->f_count++; } - if(s->mv_dir & MV_DIR_BACKWARD){ - ff_h263_encode_motion_vector(s, s->mv[1][0][0] - s->last_mv[1][0][0], - s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code); - s->last_mv[1][0][0]= s->last_mv[1][1][0]= s->mv[1][0][0]; - s->last_mv[1][0][1]= s->last_mv[1][1][1]= s->mv[1][0][1]; + if (s->mv_dir & MV_DIR_BACKWARD) { + ff_h263_encode_motion_vector(s, + s->mv[1][0][0] - s->last_mv[1][0][0], + s->mv[1][0][1] - s->last_mv[1][0][1], + s->b_code); + s->last_mv[1][0][0] = + s->last_mv[1][1][0] = s->mv[1][0][0]; + s->last_mv[1][0][1] = + s->last_mv[1][1][1] = s->mv[1][0][1]; s->b_count++; } - }else{ - if(s->mv_dir & MV_DIR_FORWARD){ + } else { + if (s->mv_dir & MV_DIR_FORWARD) { put_bits(&s->pb, 1, s->field_select[0][0]); put_bits(&s->pb, 1, s->field_select[0][1]); } - if(s->mv_dir & MV_DIR_BACKWARD){ + if (s->mv_dir & MV_DIR_BACKWARD) { put_bits(&s->pb, 1, s->field_select[1][0]); put_bits(&s->pb, 1, s->field_select[1][1]); } - if(s->mv_dir & MV_DIR_FORWARD){ - for(i=0; i<2; i++){ - ff_h263_encode_motion_vector(s, s->mv[0][i][0] - s->last_mv[0][i][0] , - s->mv[0][i][1] - s->last_mv[0][i][1]/2, s->f_code); - s->last_mv[0][i][0]= s->mv[0][i][0]; - s->last_mv[0][i][1]= s->mv[0][i][1]*2; + if (s->mv_dir & MV_DIR_FORWARD) { + for (i = 0; i < 2; i++) { + ff_h263_encode_motion_vector(s, + s->mv[0][i][0] - s->last_mv[0][i][0], + s->mv[0][i][1] - s->last_mv[0][i][1] / 2, + s->f_code); + s->last_mv[0][i][0] = s->mv[0][i][0]; + s->last_mv[0][i][1] = s->mv[0][i][1] * 2; } s->f_count++; } - if(s->mv_dir & MV_DIR_BACKWARD){ - for(i=0; i<2; i++){ - ff_h263_encode_motion_vector(s, s->mv[1][i][0] - s->last_mv[1][i][0] , - s->mv[1][i][1] - s->last_mv[1][i][1]/2, s->b_code); - s->last_mv[1][i][0]= s->mv[1][i][0]; - s->last_mv[1][i][1]= s->mv[1][i][1]*2; + if (s->mv_dir & MV_DIR_BACKWARD) { + for (i = 0; i < 2; i++) { + ff_h263_encode_motion_vector(s, + s->mv[1][i][0] - s->last_mv[1][i][0], + s->mv[1][i][1] - s->last_mv[1][i][1] / 2, + s->b_code); + s->last_mv[1][i][0] = s->mv[1][i][0]; + s->last_mv[1][i][1] = s->mv[1][i][1] * 2; } s->b_count++; } } } - if(interleaved_stats){ - s->mv_bits+= get_bits_diff(s); - } + if (interleaved_stats) + s->mv_bits += get_bits_diff(s); mpeg4_encode_blocks(s, block, NULL, NULL, NULL, &s->pb); - if(interleaved_stats){ - s->p_tex_bits+= get_bits_diff(s); - } - - }else{ /* s->pict_type==AV_PICTURE_TYPE_B */ - cbp= get_p_cbp(s, block, motion_x, motion_y); - - if ((cbp | motion_x | motion_y | s->dquant) == 0 && s->mv_type==MV_TYPE_16X16) { - /* check if the B frames can skip it too, as we must skip it if we skip here - why didn't they just compress the skip-mb bits instead of reusing them ?! */ - if(s->max_b_frames>0){ + if (interleaved_stats) + s->p_tex_bits += get_bits_diff(s); + } else { /* s->pict_type==AV_PICTURE_TYPE_B */ + cbp = get_p_cbp(s, block, motion_x, motion_y); + + if ((cbp | motion_x | motion_y | s->dquant) == 0 && + s->mv_type == MV_TYPE_16X16) { + /* check if the B frames can skip it too, as we must skip it + * if we skip here why didn't they just compress + * the skip-mb bits instead of reusing them ?! */ + if (s->max_b_frames > 0) { int i; - int x,y, offset; + int x, y, offset; uint8_t *p_pic; - x= s->mb_x*16; - y= s->mb_y*16; + x = s->mb_x * 16; + y = s->mb_y * 16; - offset= x + y*s->linesize; - p_pic = s->new_picture.f.data[0] + offset; + offset = x + y * s->linesize; + p_pic = s->new_picture.f.data[0] + offset; - s->mb_skipped=1; - for(i=0; imax_b_frames; i++){ + s->mb_skipped = 1; + for (i = 0; i < s->max_b_frames; i++) { uint8_t *b_pic; int diff; - Picture *pic= s->reordered_input_picture[i+1]; + Picture *pic = s->reordered_input_picture[i + 1]; - if (pic == NULL || pic->f.pict_type != AV_PICTURE_TYPE_B) + if (!pic || pic->f.pict_type != AV_PICTURE_TYPE_B) break; b_pic = pic->f.data[0] + offset; if (!pic->shared) - b_pic+= INPLACE_OFFSET; - - if(x+16 > s->width || y+16 > s->height){ - int x1,y1; - int xe= FFMIN(16, s->width - x); - int ye= FFMIN(16, s->height- y); - diff=0; - for(y1=0; y1linesize] - b_pic[x1+y1*s->linesize]); + b_pic += INPLACE_OFFSET; + + if (x + 16 > s->width || y + 16 > s->height) { + int x1, y1; + int xe = FFMIN(16, s->width - x); + int ye = FFMIN(16, s->height - y); + diff = 0; + for (y1 = 0; y1 < ye; y1++) { + for (x1 = 0; x1 < xe; x1++) { + diff += FFABS(p_pic[x1 + y1 * s->linesize] - b_pic[x1 + y1 * s->linesize]); } } - diff= diff*256/(xe*ye); - }else{ - diff= s->dsp.sad[0](NULL, p_pic, b_pic, s->linesize, 16); + diff = diff * 256 / (xe * ye); + } else { + diff = s->dsp.sad[0](NULL, p_pic, b_pic, s->linesize, 16); } - if(diff>s->qscale*70){ //FIXME check that 70 is optimal - s->mb_skipped=0; + if (diff > s->qscale * 70) { // FIXME check that 70 is optimal + s->mb_skipped = 0; break; } } - }else - s->mb_skipped=1; + } else + s->mb_skipped = 1; - if(s->mb_skipped==1){ + if (s->mb_skipped == 1) { /* skip macroblock */ put_bits(&s->pb, 1, 1); - if(interleaved_stats){ + if (interleaved_stats) { s->misc_bits++; s->last_bits++; } @@ -681,162 +722,164 @@ void ff_mpeg4_encode_mb(MpegEncContext * s, } put_bits(&s->pb, 1, 0); /* mb coded */ - cbpc = cbp & 3; - cbpy = cbp >> 2; + cbpc = cbp & 3; + cbpy = cbp >> 2; cbpy ^= 0xf; - if(s->mv_type==MV_TYPE_16X16){ - if(s->dquant) cbpc+= 8; + if (s->mv_type == MV_TYPE_16X16) { + if (s->dquant) + cbpc += 8; put_bits(&s->pb, - ff_h263_inter_MCBPC_bits[cbpc], - ff_h263_inter_MCBPC_code[cbpc]); + ff_h263_inter_MCBPC_bits[cbpc], + ff_h263_inter_MCBPC_code[cbpc]); put_bits(pb2, ff_h263_cbpy_tab[cbpy][1], ff_h263_cbpy_tab[cbpy][0]); - if(s->dquant) - put_bits(pb2, 2, dquant_code[s->dquant+2]); + if (s->dquant) + put_bits(pb2, 2, dquant_code[s->dquant + 2]); - if(!s->progressive_sequence){ - if(cbp) + if (!s->progressive_sequence) { + if (cbp) put_bits(pb2, 1, s->interlaced_dct); put_bits(pb2, 1, 0); } - if(interleaved_stats){ - s->misc_bits+= get_bits_diff(s); - } + if (interleaved_stats) + s->misc_bits += get_bits_diff(s); /* motion vectors: 16x16 mode */ ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); - ff_h263_encode_motion_vector(s, motion_x - pred_x, - motion_y - pred_y, s->f_code); - }else if(s->mv_type==MV_TYPE_FIELD){ - if(s->dquant) cbpc+= 8; + ff_h263_encode_motion_vector(s, + motion_x - pred_x, + motion_y - pred_y, + s->f_code); + } else if (s->mv_type == MV_TYPE_FIELD) { + if (s->dquant) + cbpc += 8; put_bits(&s->pb, - ff_h263_inter_MCBPC_bits[cbpc], - ff_h263_inter_MCBPC_code[cbpc]); + ff_h263_inter_MCBPC_bits[cbpc], + ff_h263_inter_MCBPC_code[cbpc]); put_bits(pb2, ff_h263_cbpy_tab[cbpy][1], ff_h263_cbpy_tab[cbpy][0]); - if(s->dquant) - put_bits(pb2, 2, dquant_code[s->dquant+2]); + if (s->dquant) + put_bits(pb2, 2, dquant_code[s->dquant + 2]); av_assert2(!s->progressive_sequence); - if(cbp) + if (cbp) put_bits(pb2, 1, s->interlaced_dct); put_bits(pb2, 1, 1); - if(interleaved_stats){ - s->misc_bits+= get_bits_diff(s); - } + if (interleaved_stats) + s->misc_bits += get_bits_diff(s); /* motion vectors: 16x8 interlaced mode */ ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); - pred_y /=2; + pred_y /= 2; put_bits(&s->pb, 1, s->field_select[0][0]); put_bits(&s->pb, 1, s->field_select[0][1]); - ff_h263_encode_motion_vector(s, s->mv[0][0][0] - pred_x, - s->mv[0][0][1] - pred_y, s->f_code); - ff_h263_encode_motion_vector(s, s->mv[0][1][0] - pred_x, - s->mv[0][1][1] - pred_y, s->f_code); - }else{ - av_assert2(s->mv_type==MV_TYPE_8X8); + ff_h263_encode_motion_vector(s, + s->mv[0][0][0] - pred_x, + s->mv[0][0][1] - pred_y, + s->f_code); + ff_h263_encode_motion_vector(s, + s->mv[0][1][0] - pred_x, + s->mv[0][1][1] - pred_y, + s->f_code); + } else { + av_assert2(s->mv_type == MV_TYPE_8X8); put_bits(&s->pb, - ff_h263_inter_MCBPC_bits[cbpc+16], - ff_h263_inter_MCBPC_code[cbpc+16]); + ff_h263_inter_MCBPC_bits[cbpc + 16], + ff_h263_inter_MCBPC_code[cbpc + 16]); put_bits(pb2, ff_h263_cbpy_tab[cbpy][1], ff_h263_cbpy_tab[cbpy][0]); - if(!s->progressive_sequence){ - if(cbp) - put_bits(pb2, 1, s->interlaced_dct); - } + if (!s->progressive_sequence && cbp) + put_bits(pb2, 1, s->interlaced_dct); - if(interleaved_stats){ - s->misc_bits+= get_bits_diff(s); - } + if (interleaved_stats) + s->misc_bits += get_bits_diff(s); - for(i=0; i<4; i++){ + for (i = 0; i < 4; i++) { /* motion vectors: 8x8 mode*/ ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y); - ff_h263_encode_motion_vector(s, s->current_picture.motion_val[0][ s->block_index[i] ][0] - pred_x, - s->current_picture.motion_val[0][ s->block_index[i] ][1] - pred_y, s->f_code); + ff_h263_encode_motion_vector(s, + s->current_picture.motion_val[0][s->block_index[i]][0] - pred_x, + s->current_picture.motion_val[0][s->block_index[i]][1] - pred_y, + s->f_code); } } - if(interleaved_stats){ - s->mv_bits+= get_bits_diff(s); - } + if (interleaved_stats) + s->mv_bits += get_bits_diff(s); mpeg4_encode_blocks(s, block, NULL, NULL, NULL, tex_pb); - if(interleaved_stats){ - s->p_tex_bits+= get_bits_diff(s); - } + if (interleaved_stats) + s->p_tex_bits += get_bits_diff(s); + s->f_count++; } } else { int cbp; - int dc_diff[6]; //dc values with the dc prediction subtracted - int dir[6]; //prediction direction + int dc_diff[6]; // dc values with the dc prediction subtracted + int dir[6]; // prediction direction int zigzag_last_index[6]; uint8_t *scan_table[6]; int i; - for(i=0; i<6; i++){ - dc_diff[i]= ff_mpeg4_pred_dc(s, i, block[i][0], &dir[i], 1); - } + for (i = 0; i < 6; i++) + dc_diff[i] = ff_mpeg4_pred_dc(s, i, block[i][0], &dir[i], 1); - if(s->flags & CODEC_FLAG_AC_PRED){ - s->ac_pred= decide_ac_pred(s, block, dir, scan_table, zigzag_last_index); - }else{ - for(i=0; i<6; i++) - scan_table[i]= s->intra_scantable.permutated; + if (s->flags & CODEC_FLAG_AC_PRED) { + s->ac_pred = decide_ac_pred(s, block, dir, scan_table, zigzag_last_index); + } else { + for (i = 0; i < 6; i++) + scan_table[i] = s->intra_scantable.permutated; } /* compute cbp */ cbp = 0; - for (i = 0; i < 6; i++) { + for (i = 0; i < 6; i++) if (s->block_last_index[i] >= 1) cbp |= 1 << (5 - i); - } cbpc = cbp & 3; if (s->pict_type == AV_PICTURE_TYPE_I) { - if(s->dquant) cbpc+=4; + if (s->dquant) + cbpc += 4; put_bits(&s->pb, - ff_h263_intra_MCBPC_bits[cbpc], - ff_h263_intra_MCBPC_code[cbpc]); + ff_h263_intra_MCBPC_bits[cbpc], + ff_h263_intra_MCBPC_code[cbpc]); } else { - if(s->dquant) cbpc+=8; + if (s->dquant) + cbpc += 8; put_bits(&s->pb, 1, 0); /* mb coded */ put_bits(&s->pb, - ff_h263_inter_MCBPC_bits[cbpc + 4], - ff_h263_inter_MCBPC_code[cbpc + 4]); + ff_h263_inter_MCBPC_bits[cbpc + 4], + ff_h263_inter_MCBPC_code[cbpc + 4]); } put_bits(pb2, 1, s->ac_pred); cbpy = cbp >> 2; put_bits(pb2, ff_h263_cbpy_tab[cbpy][1], ff_h263_cbpy_tab[cbpy][0]); - if(s->dquant) - put_bits(dc_pb, 2, dquant_code[s->dquant+2]); + if (s->dquant) + put_bits(dc_pb, 2, dquant_code[s->dquant + 2]); - if(!s->progressive_sequence){ + if (!s->progressive_sequence) put_bits(dc_pb, 1, s->interlaced_dct); - } - if(interleaved_stats){ - s->misc_bits+= get_bits_diff(s); - } + if (interleaved_stats) + s->misc_bits += get_bits_diff(s); mpeg4_encode_blocks(s, block, dc_diff, scan_table, dc_pb, tex_pb); - if(interleaved_stats){ - s->i_tex_bits+= get_bits_diff(s); - } + if (interleaved_stats) + s->i_tex_bits += get_bits_diff(s); s->i_count++; - /* restore ac coeffs & last_index stuff if we messed them up with the prediction */ - if(s->ac_pred) + /* restore ac coeffs & last_index stuff + * if we messed them up with the prediction */ + if (s->ac_pred) restore_ac_coeffs(s, block, dir, scan_table, zigzag_last_index); } } @@ -844,25 +887,28 @@ void ff_mpeg4_encode_mb(MpegEncContext * s, /** * add mpeg4 stuffing bits (01...1) */ -void ff_mpeg4_stuffing(PutBitContext * pbc) +void ff_mpeg4_stuffing(PutBitContext *pbc) { int length; put_bits(pbc, 1, 0); - length= (-put_bits_count(pbc))&7; - if(length) put_bits(pbc, length, (1<pict_type==AV_PICTURE_TYPE_B){ +void ff_set_mpeg4_time(MpegEncContext *s) +{ + if (s->pict_type == AV_PICTURE_TYPE_B) { ff_mpeg4_init_direct_mv(s); - }else{ - s->last_time_base= s->time_base; - s->time_base= FFUDIV(s->time, s->avctx->time_base.den); + } else { + s->last_time_base = s->time_base; + s->time_base = FFUDIV(s->time, s->avctx->time_base.den); } } -static void mpeg4_encode_gop_header(MpegEncContext * s){ +static void mpeg4_encode_gop_header(MpegEncContext *s) +{ int hours, minutes, seconds; int64_t time; @@ -870,52 +916,51 @@ static void mpeg4_encode_gop_header(MpegEncContext * s){ put_bits(&s->pb, 16, GOP_STARTCODE); time = s->current_picture_ptr->f.pts; - if(s->reordered_input_picture[1]) + if (s->reordered_input_picture[1]) time = FFMIN(time, s->reordered_input_picture[1]->f.pts); - time= time*s->avctx->time_base.num; - s->last_time_base= FFUDIV(time, s->avctx->time_base.den); + time = time * s->avctx->time_base.num; + s->last_time_base = FFUDIV(time, s->avctx->time_base.den); - seconds= FFUDIV(time, s->avctx->time_base.den); - minutes= FFUDIV(seconds, 60); seconds = FFUMOD(seconds, 60); - hours = FFUDIV(minutes, 60); minutes = FFUMOD(minutes, 60); - hours = FFUMOD(hours , 24); + seconds = FFUDIV(time, s->avctx->time_base.den); + minutes = FFUDIV(seconds, 60); seconds = FFUMOD(seconds, 60); + hours = FFUDIV(minutes, 60); minutes = FFUMOD(minutes, 60); + hours = FFUMOD(hours , 24); put_bits(&s->pb, 5, hours); put_bits(&s->pb, 6, minutes); put_bits(&s->pb, 1, 1); put_bits(&s->pb, 6, seconds); - put_bits(&s->pb, 1, !!(s->flags&CODEC_FLAG_CLOSED_GOP)); - put_bits(&s->pb, 1, 0); //broken link == NO + put_bits(&s->pb, 1, !!(s->flags & CODEC_FLAG_CLOSED_GOP)); + put_bits(&s->pb, 1, 0); // broken link == NO ff_mpeg4_stuffing(&s->pb); } -static void mpeg4_encode_visual_object_header(MpegEncContext * s){ +static void mpeg4_encode_visual_object_header(MpegEncContext *s) +{ int profile_and_level_indication; int vo_ver_id; - if(s->avctx->profile != FF_PROFILE_UNKNOWN){ + if (s->avctx->profile != FF_PROFILE_UNKNOWN) { profile_and_level_indication = s->avctx->profile << 4; - }else if(s->max_b_frames || s->quarter_sample){ - profile_and_level_indication= 0xF0; // adv simple - }else{ - profile_and_level_indication= 0x00; // simple + } else if (s->max_b_frames || s->quarter_sample) { + profile_and_level_indication = 0xF0; // adv simple + } else { + profile_and_level_indication = 0x00; // simple } - if(s->avctx->level != FF_LEVEL_UNKNOWN){ + if (s->avctx->level != FF_LEVEL_UNKNOWN) profile_and_level_indication |= s->avctx->level; - }else{ - profile_and_level_indication |= 1; //level 1 - } + else + profile_and_level_indication |= 1; // level 1 - if(profile_and_level_indication>>4 == 0xF){ - vo_ver_id= 5; - }else{ - vo_ver_id= 1; - } + if (profile_and_level_indication >> 4 == 0xF) + vo_ver_id = 5; + else + vo_ver_id = 1; - //FIXME levels + // FIXME levels put_bits(&s->pb, 16, 0); put_bits(&s->pb, 16, VOS_STARTCODE); @@ -926,28 +971,31 @@ static void mpeg4_encode_visual_object_header(MpegEncContext * s){ put_bits(&s->pb, 16, VISUAL_OBJ_STARTCODE); put_bits(&s->pb, 1, 1); - put_bits(&s->pb, 4, vo_ver_id); - put_bits(&s->pb, 3, 1); //priority + put_bits(&s->pb, 4, vo_ver_id); + put_bits(&s->pb, 3, 1); // priority - put_bits(&s->pb, 4, 1); //visual obj type== video obj + put_bits(&s->pb, 4, 1); // visual obj type== video obj - put_bits(&s->pb, 1, 0); //video signal type == no clue //FIXME + put_bits(&s->pb, 1, 0); // video signal type == no clue // FIXME ff_mpeg4_stuffing(&s->pb); } -static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_number) +static void mpeg4_encode_vol_header(MpegEncContext *s, + int vo_number, + int vol_number) { int vo_ver_id; - if (!CONFIG_MPEG4_ENCODER) return; + if (!CONFIG_MPEG4_ENCODER) + return; - if(s->max_b_frames || s->quarter_sample){ - vo_ver_id= 5; - s->vo_type= ADV_SIMPLE_VO_TYPE; - }else{ - vo_ver_id= 1; - s->vo_type= SIMPLE_VO_TYPE; + if (s->max_b_frames || s->quarter_sample) { + vo_ver_id = 5; + s->vo_type = ADV_SIMPLE_VO_TYPE; + } else { + vo_ver_id = 1; + s->vo_type = SIMPLE_VO_TYPE; } put_bits(&s->pb, 16, 0); @@ -957,7 +1005,7 @@ static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_n put_bits(&s->pb, 1, 0); /* random access vol */ put_bits(&s->pb, 8, s->vo_type); /* video obj type indication */ - if(s->workaround_bugs & FF_BUG_MS) { + if (s->workaround_bugs & FF_BUG_MS) { put_bits(&s->pb, 1, 0); /* is obj layer id= no */ } else { put_bits(&s->pb, 1, 1); /* is obj layer id= yes */ @@ -965,17 +1013,17 @@ static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_n put_bits(&s->pb, 3, 1); /* is obj layer priority */ } - s->aspect_ratio_info= ff_h263_aspect_to_info(s->avctx->sample_aspect_ratio); + s->aspect_ratio_info = ff_h263_aspect_to_info(s->avctx->sample_aspect_ratio); - put_bits(&s->pb, 4, s->aspect_ratio_info);/* aspect ratio info */ - if (s->aspect_ratio_info == FF_ASPECT_EXTENDED){ + put_bits(&s->pb, 4, s->aspect_ratio_info); /* aspect ratio info */ + if (s->aspect_ratio_info == FF_ASPECT_EXTENDED) { av_reduce(&s->avctx->sample_aspect_ratio.num, &s->avctx->sample_aspect_ratio.den, s->avctx->sample_aspect_ratio.num, s->avctx->sample_aspect_ratio.den, 255); put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.num); put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.den); } - if(s->workaround_bugs & FF_BUG_MS) { // + if (s->workaround_bugs & FF_BUG_MS) { put_bits(&s->pb, 1, 0); /* vol control parameters= no @@@ */ } else { put_bits(&s->pb, 1, 1); /* vol control parameters= yes */ @@ -999,16 +1047,15 @@ static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_n put_bits(&s->pb, 1, 1); /* marker bit */ put_bits(&s->pb, 1, s->progressive_sequence ? 0 : 1); put_bits(&s->pb, 1, 1); /* obmc disable */ - if (vo_ver_id == 1) { - put_bits(&s->pb, 1, s->vol_sprite_usage); /* sprite enable */ - }else{ - put_bits(&s->pb, 2, s->vol_sprite_usage); /* sprite enable */ - } + if (vo_ver_id == 1) + put_bits(&s->pb, 1, 0); /* sprite enable */ + else + put_bits(&s->pb, 2, 0); /* sprite enable */ put_bits(&s->pb, 1, 0); /* not 8 bit == false */ put_bits(&s->pb, 1, s->mpeg_quant); /* quant type= (0=h263 style)*/ - if(s->mpeg_quant){ + if (s->mpeg_quant) { ff_write_quant_matrix(&s->pb, s->avctx->intra_matrix); ff_write_quant_matrix(&s->pb, s->avctx->inter_matrix); } @@ -1016,14 +1063,12 @@ static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_n if (vo_ver_id != 1) put_bits(&s->pb, 1, s->quarter_sample); put_bits(&s->pb, 1, 1); /* complexity estimation disable */ - s->resync_marker= s->rtp_mode; - put_bits(&s->pb, 1, s->resync_marker ? 0 : 1);/* resync marker disable */ + put_bits(&s->pb, 1, s->rtp_mode ? 0 : 1); /* resync marker disable */ put_bits(&s->pb, 1, s->data_partitioning ? 1 : 0); - if(s->data_partitioning){ + if (s->data_partitioning) put_bits(&s->pb, 1, 0); /* no rvlc */ - } - if (vo_ver_id != 1){ + if (vo_ver_id != 1) { put_bits(&s->pb, 1, 0); /* newpred */ put_bits(&s->pb, 1, 0); /* reduced res vop */ } @@ -1032,7 +1077,7 @@ static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_n ff_mpeg4_stuffing(&s->pb); /* user data */ - if(!(s->flags & CODEC_FLAG_BITEXACT)){ + if (!(s->flags & CODEC_FLAG_BITEXACT)) { put_bits(&s->pb, 16, 0); put_bits(&s->pb, 16, 0x1B2); /* user_data */ avpriv_put_string(&s->pb, LIBAVCODEC_IDENT, 0); @@ -1040,33 +1085,33 @@ static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_n } /* write mpeg4 VOP header */ -void ff_mpeg4_encode_picture_header(MpegEncContext * s, int picture_number) +void ff_mpeg4_encode_picture_header(MpegEncContext *s, int picture_number) { int time_incr; int time_div, time_mod; - if(s->pict_type==AV_PICTURE_TYPE_I){ - if(!(s->flags&CODEC_FLAG_GLOBAL_HEADER)){ - if(s->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT) //HACK, the reference sw is buggy + if (s->pict_type == AV_PICTURE_TYPE_I) { + if (!(s->flags & CODEC_FLAG_GLOBAL_HEADER)) { + if (s->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT) // HACK, the reference sw is buggy mpeg4_encode_visual_object_header(s); - if(s->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT || picture_number==0) //HACK, the reference sw is buggy + if (s->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT || picture_number == 0) // HACK, the reference sw is buggy mpeg4_encode_vol_header(s, 0, 0); } - if(!(s->workaround_bugs & FF_BUG_MS)) + if (!(s->workaround_bugs & FF_BUG_MS)) mpeg4_encode_gop_header(s); } - s->partitioned_frame= s->data_partitioning && s->pict_type!=AV_PICTURE_TYPE_B; + s->partitioned_frame = s->data_partitioning && s->pict_type != AV_PICTURE_TYPE_B; put_bits(&s->pb, 16, 0); /* vop header */ put_bits(&s->pb, 16, VOP_STARTCODE); /* vop header */ put_bits(&s->pb, 2, s->pict_type - 1); /* pict type: I = 0 , P = 1 */ - time_div= FFUDIV(s->time, s->avctx->time_base.den); - time_mod= FFUMOD(s->time, s->avctx->time_base.den); - time_incr= time_div - s->last_time_base; + time_div = FFUDIV(s->time, s->avctx->time_base.den); + time_mod = FFUMOD(s->time, s->avctx->time_base.den); + time_incr = time_div - s->last_time_base; av_assert0(time_incr >= 0); - while(time_incr--) + while (time_incr--) put_bits(&s->pb, 1, 1); put_bits(&s->pb, 1, 0); @@ -1075,153 +1120,168 @@ void ff_mpeg4_encode_picture_header(MpegEncContext * s, int picture_number) put_bits(&s->pb, s->time_increment_bits, time_mod); /* time increment */ put_bits(&s->pb, 1, 1); /* marker */ put_bits(&s->pb, 1, 1); /* vop coded */ - if ( s->pict_type == AV_PICTURE_TYPE_P - || (s->pict_type == AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE)) { + if (s->pict_type == AV_PICTURE_TYPE_P) { put_bits(&s->pb, 1, s->no_rounding); /* rounding type */ } put_bits(&s->pb, 3, 0); /* intra dc VLC threshold */ - if(!s->progressive_sequence){ - put_bits(&s->pb, 1, s->current_picture_ptr->f.top_field_first); - put_bits(&s->pb, 1, s->alternate_scan); + if (!s->progressive_sequence) { + put_bits(&s->pb, 1, s->current_picture_ptr->f.top_field_first); + put_bits(&s->pb, 1, s->alternate_scan); } - //FIXME sprite stuff + // FIXME sprite stuff put_bits(&s->pb, 5, s->qscale); if (s->pict_type != AV_PICTURE_TYPE_I) - put_bits(&s->pb, 3, s->f_code); /* fcode_for */ + put_bits(&s->pb, 3, s->f_code); /* fcode_for */ if (s->pict_type == AV_PICTURE_TYPE_B) - put_bits(&s->pb, 3, s->b_code); /* fcode_back */ + put_bits(&s->pb, 3, s->b_code); /* fcode_back */ } - -static void init_uni_dc_tab(void) +static av_cold void init_uni_dc_tab(void) { int level, uni_code, uni_len; - for(level=-256; level<256; level++){ + for (level = -256; level < 256; level++) { int size, v, l; /* find number of bits */ size = 0; - v = abs(level); + v = abs(level); while (v) { v >>= 1; size++; } if (level < 0) - l= (-level) ^ ((1 << size) - 1); + l = (-level) ^ ((1 << size) - 1); else - l= level; + l = level; /* luminance */ - uni_code= ff_mpeg4_DCtab_lum[size][0]; - uni_len = ff_mpeg4_DCtab_lum[size][1]; + uni_code = ff_mpeg4_DCtab_lum[size][0]; + uni_len = ff_mpeg4_DCtab_lum[size][1]; if (size > 0) { - uni_code<<=size; uni_code|=l; - uni_len+=size; - if (size > 8){ - uni_code<<=1; uni_code|=1; + uni_code <<= size; + uni_code |= l; + uni_len += size; + if (size > 8) { + uni_code <<= 1; + uni_code |= 1; uni_len++; } } - uni_DCtab_lum_bits[level+256]= uni_code; - uni_DCtab_lum_len [level+256]= uni_len; + uni_DCtab_lum_bits[level + 256] = uni_code; + uni_DCtab_lum_len[level + 256] = uni_len; /* chrominance */ - uni_code= ff_mpeg4_DCtab_chrom[size][0]; - uni_len = ff_mpeg4_DCtab_chrom[size][1]; + uni_code = ff_mpeg4_DCtab_chrom[size][0]; + uni_len = ff_mpeg4_DCtab_chrom[size][1]; if (size > 0) { - uni_code<<=size; uni_code|=l; - uni_len+=size; - if (size > 8){ - uni_code<<=1; uni_code|=1; + uni_code <<= size; + uni_code |= l; + uni_len += size; + if (size > 8) { + uni_code <<= 1; + uni_code |= 1; uni_len++; } } - uni_DCtab_chrom_bits[level+256]= uni_code; - uni_DCtab_chrom_len [level+256]= uni_len; - + uni_DCtab_chrom_bits[level + 256] = uni_code; + uni_DCtab_chrom_len[level + 256] = uni_len; } } -static void init_uni_mpeg4_rl_tab(RLTable *rl, uint32_t *bits_tab, uint8_t *len_tab){ +static av_cold void init_uni_mpeg4_rl_tab(RLTable *rl, uint32_t *bits_tab, + uint8_t *len_tab) +{ int slevel, run, last; av_assert0(MAX_LEVEL >= 64); - av_assert0(MAX_RUN >= 63); - - for(slevel=-64; slevel<64; slevel++){ - if(slevel==0) continue; - for(run=0; run<64; run++){ - for(last=0; last<=1; last++){ - const int index= UNI_MPEG4_ENC_INDEX(last, run, slevel+64); - int level= slevel < 0 ? -slevel : slevel; - int sign= slevel < 0 ? 1 : 0; + av_assert0(MAX_RUN >= 63); + + for (slevel = -64; slevel < 64; slevel++) { + if (slevel == 0) + continue; + for (run = 0; run < 64; run++) { + for (last = 0; last <= 1; last++) { + const int index = UNI_MPEG4_ENC_INDEX(last, run, slevel + 64); + int level = slevel < 0 ? -slevel : slevel; + int sign = slevel < 0 ? 1 : 0; int bits, len, code; int level1, run1; - len_tab[index]= 100; + len_tab[index] = 100; /* ESC0 */ - code= get_rl_index(rl, last, run, level); - bits= rl->table_vlc[code][0]; - len= rl->table_vlc[code][1]; - bits=bits*2+sign; len++; - - if(code!=rl->n && len < len_tab[index]){ - bits_tab[index]= bits; - len_tab [index]= len; + code = get_rl_index(rl, last, run, level); + bits = rl->table_vlc[code][0]; + len = rl->table_vlc[code][1]; + bits = bits * 2 + sign; + len++; + + if (code != rl->n && len < len_tab[index]) { + bits_tab[index] = bits; + len_tab[index] = len; } /* ESC1 */ - bits= rl->table_vlc[rl->n][0]; - len= rl->table_vlc[rl->n][1]; - bits=bits*2; len++; //esc1 - level1= level - rl->max_level[last][run]; - if(level1>0){ - code= get_rl_index(rl, last, run, level1); - bits<<= rl->table_vlc[code][1]; - len += rl->table_vlc[code][1]; - bits += rl->table_vlc[code][0]; - bits=bits*2+sign; len++; - - if(code!=rl->n && len < len_tab[index]){ - bits_tab[index]= bits; - len_tab [index]= len; + bits = rl->table_vlc[rl->n][0]; + len = rl->table_vlc[rl->n][1]; + bits = bits * 2; + len++; // esc1 + level1 = level - rl->max_level[last][run]; + if (level1 > 0) { + code = get_rl_index(rl, last, run, level1); + bits <<= rl->table_vlc[code][1]; + len += rl->table_vlc[code][1]; + bits += rl->table_vlc[code][0]; + bits = bits * 2 + sign; + len++; + + if (code != rl->n && len < len_tab[index]) { + bits_tab[index] = bits; + len_tab[index] = len; } } /* ESC2 */ - bits= rl->table_vlc[rl->n][0]; - len= rl->table_vlc[rl->n][1]; - bits=bits*4+2; len+=2; //esc2 + bits = rl->table_vlc[rl->n][0]; + len = rl->table_vlc[rl->n][1]; + bits = bits * 4 + 2; + len += 2; // esc2 run1 = run - rl->max_run[last][level] - 1; - if(run1>=0){ - code= get_rl_index(rl, last, run1, level); - bits<<= rl->table_vlc[code][1]; - len += rl->table_vlc[code][1]; - bits += rl->table_vlc[code][0]; - bits=bits*2+sign; len++; - - if(code!=rl->n && len < len_tab[index]){ - bits_tab[index]= bits; - len_tab [index]= len; + if (run1 >= 0) { + code = get_rl_index(rl, last, run1, level); + bits <<= rl->table_vlc[code][1]; + len += rl->table_vlc[code][1]; + bits += rl->table_vlc[code][0]; + bits = bits * 2 + sign; + len++; + + if (code != rl->n && len < len_tab[index]) { + bits_tab[index] = bits; + len_tab[index] = len; } } /* ESC3 */ - bits= rl->table_vlc[rl->n][0]; - len = rl->table_vlc[rl->n][1]; - bits=bits*4+3; len+=2; //esc3 - bits=bits*2+last; len++; - bits=bits*64+run; len+=6; - bits=bits*2+1; len++; //marker - bits=bits*4096+(slevel&0xfff); len+=12; - bits=bits*2+1; len++; //marker - - if(len < len_tab[index]){ - bits_tab[index]= bits; - len_tab [index]= len; + bits = rl->table_vlc[rl->n][0]; + len = rl->table_vlc[rl->n][1]; + bits = bits * 4 + 3; + len += 2; // esc3 + bits = bits * 2 + last; + len++; + bits = bits * 64 + run; + len += 6; + bits = bits * 2 + 1; + len++; // marker + bits = bits * 4096 + (slevel & 0xfff); + len += 12; + bits = bits * 2 + 1; + len++; // marker + + if (len < len_tab[index]) { + bits_tab[index] = bits; + len_tab[index] = len; } } } @@ -1239,7 +1299,7 @@ static av_cold int encode_init(AVCodecContext *avctx) return AVERROR(EINVAL); } - if((ret=ff_MPV_encode_init(avctx)) < 0) + if ((ret = ff_MPV_encode_init(avctx)) < 0) return ret; if (!done) { @@ -1253,81 +1313,79 @@ static av_cold int encode_init(AVCodecContext *avctx) init_uni_mpeg4_rl_tab(&ff_h263_rl_inter, uni_mpeg4_inter_rl_bits, uni_mpeg4_inter_rl_len); } - s->min_qcoeff= -2048; - s->max_qcoeff= 2047; - s->intra_ac_vlc_length = uni_mpeg4_intra_rl_len; - s->intra_ac_vlc_last_length= uni_mpeg4_intra_rl_len + 128*64; - s->inter_ac_vlc_length = uni_mpeg4_inter_rl_len; - s->inter_ac_vlc_last_length= uni_mpeg4_inter_rl_len + 128*64; - s->luma_dc_vlc_length= uni_DCtab_lum_len; - s->ac_esc_length= 7+2+1+6+1+12+1; - s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table; - s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table; - - if(s->flags & CODEC_FLAG_GLOBAL_HEADER){ - - s->avctx->extradata= av_malloc(1024); + s->min_qcoeff = -2048; + s->max_qcoeff = 2047; + s->intra_ac_vlc_length = uni_mpeg4_intra_rl_len; + s->intra_ac_vlc_last_length = uni_mpeg4_intra_rl_len + 128 * 64; + s->inter_ac_vlc_length = uni_mpeg4_inter_rl_len; + s->inter_ac_vlc_last_length = uni_mpeg4_inter_rl_len + 128 * 64; + s->luma_dc_vlc_length = uni_DCtab_lum_len; + s->ac_esc_length = 7 + 2 + 1 + 6 + 1 + 12 + 1; + s->y_dc_scale_table = ff_mpeg4_y_dc_scale_table; + s->c_dc_scale_table = ff_mpeg4_c_dc_scale_table; + + if (s->flags & CODEC_FLAG_GLOBAL_HEADER) { + s->avctx->extradata = av_malloc(1024); init_put_bits(&s->pb, s->avctx->extradata, 1024); - if(!(s->workaround_bugs & FF_BUG_MS)) + if (!(s->workaround_bugs & FF_BUG_MS)) mpeg4_encode_visual_object_header(s); mpeg4_encode_vol_header(s, 0, 0); // ff_mpeg4_stuffing(&s->pb); ? flush_put_bits(&s->pb); - s->avctx->extradata_size= (put_bits_count(&s->pb)+7)>>3; + s->avctx->extradata_size = (put_bits_count(&s->pb) + 7) >> 3; } return 0; } void ff_mpeg4_init_partitions(MpegEncContext *s) { - uint8_t *start= put_bits_ptr(&s->pb); - uint8_t *end= s->pb.buf_end; - int size= end - start; - int pb_size = (((intptr_t)start + size/3)&(~3)) - (intptr_t)start; - int tex_size= (size - 2*pb_size)&(~3); + uint8_t *start = put_bits_ptr(&s->pb); + uint8_t *end = s->pb.buf_end; + int size = end - start; + int pb_size = (((intptr_t)start + size / 3) & (~3)) - (intptr_t)start; + int tex_size = (size - 2 * pb_size) & (~3); set_put_bits_buffer_size(&s->pb, pb_size); - init_put_bits(&s->tex_pb, start + pb_size , tex_size); - init_put_bits(&s->pb2 , start + pb_size + tex_size, pb_size); + init_put_bits(&s->tex_pb, start + pb_size, tex_size); + init_put_bits(&s->pb2, start + pb_size + tex_size, pb_size); } void ff_mpeg4_merge_partitions(MpegEncContext *s) { - const int pb2_len = put_bits_count(&s->pb2 ); - const int tex_pb_len= put_bits_count(&s->tex_pb); - const int bits= put_bits_count(&s->pb); + const int pb2_len = put_bits_count(&s->pb2); + const int tex_pb_len = put_bits_count(&s->tex_pb); + const int bits = put_bits_count(&s->pb); - if(s->pict_type==AV_PICTURE_TYPE_I){ + if (s->pict_type == AV_PICTURE_TYPE_I) { put_bits(&s->pb, 19, DC_MARKER); - s->misc_bits+=19 + pb2_len + bits - s->last_bits; - s->i_tex_bits+= tex_pb_len; - }else{ + s->misc_bits += 19 + pb2_len + bits - s->last_bits; + s->i_tex_bits += tex_pb_len; + } else { put_bits(&s->pb, 17, MOTION_MARKER); - s->misc_bits+=17 + pb2_len; - s->mv_bits+= bits - s->last_bits; - s->p_tex_bits+= tex_pb_len; + s->misc_bits += 17 + pb2_len; + s->mv_bits += bits - s->last_bits; + s->p_tex_bits += tex_pb_len; } flush_put_bits(&s->pb2); flush_put_bits(&s->tex_pb); set_put_bits_buffer_size(&s->pb, s->pb2.buf_end - s->pb.buf); - avpriv_copy_bits(&s->pb, s->pb2.buf , pb2_len); + avpriv_copy_bits(&s->pb, s->pb2.buf, pb2_len); avpriv_copy_bits(&s->pb, s->tex_pb.buf, tex_pb_len); - s->last_bits= put_bits_count(&s->pb); + s->last_bits = put_bits_count(&s->pb); } - void ff_mpeg4_encode_video_packet_header(MpegEncContext *s) { - int mb_num_bits= av_log2(s->mb_num - 1) + 1; + int mb_num_bits = av_log2(s->mb_num - 1) + 1; put_bits(&s->pb, ff_mpeg4_get_video_packet_prefix_length(s), 0); put_bits(&s->pb, 1, 1); - put_bits(&s->pb, mb_num_bits, s->mb_x + s->mb_y*s->mb_width); + put_bits(&s->pb, mb_num_bits, s->mb_x + s->mb_y * s->mb_width); put_bits(&s->pb, s->quant_precision, s->qscale); put_bits(&s->pb, 1, 0); /* no HEC */ } @@ -1335,8 +1393,8 @@ void ff_mpeg4_encode_video_packet_header(MpegEncContext *s) #define OFFSET(x) offsetof(MpegEncContext, x) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { - { "data_partitioning", "Use data partitioning.", OFFSET(data_partitioning), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, - { "alternate_scan", "Enable alternate scantable.", OFFSET(alternate_scan), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, + { "data_partitioning", "Use data partitioning.", OFFSET(data_partitioning), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, + { "alternate_scan", "Enable alternate scantable.", OFFSET(alternate_scan), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, FF_MPV_COMMON_OPTS { NULL }, }; @@ -1350,14 +1408,14 @@ static const AVClass mpeg4enc_class = { AVCodec ff_mpeg4_encoder = { .name = "mpeg4", + .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MPEG4, .priv_data_size = sizeof(MpegEncContext), .init = encode_init, .encode2 = ff_MPV_encode_picture, .close = ff_MPV_encode_end, - .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, + .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, .capabilities = CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2"), .priv_class = &mpeg4enc_class, }; diff --git a/ffmpeg/libavcodec/mpegaudio.h b/ffmpeg/libavcodec/mpegaudio.h index b880b7a..1591a17 100644 --- a/ffmpeg/libavcodec/mpegaudio.h +++ b/ffmpeg/libavcodec/mpegaudio.h @@ -26,8 +26,8 @@ #ifndef AVCODEC_MPEGAUDIO_H #define AVCODEC_MPEGAUDIO_H -#ifndef CONFIG_FLOAT -# define CONFIG_FLOAT 0 +#ifndef USE_FLOATS +# define USE_FLOATS 0 #endif #include @@ -58,7 +58,7 @@ #define FIX(a) ((int)((a) * FRAC_ONE)) -#if CONFIG_FLOAT +#if USE_FLOATS # define INTFLOAT float typedef float MPA_INT; typedef float OUT_INT; diff --git a/ffmpeg/libavcodec/mpegaudio_tablegen.h b/ffmpeg/libavcodec/mpegaudio_tablegen.h index 6c15d3c..f9557c9 100644 --- a/ffmpeg/libavcodec/mpegaudio_tablegen.h +++ b/ffmpeg/libavcodec/mpegaudio_tablegen.h @@ -48,7 +48,8 @@ static void mpegaudio_tableinit(void) double value = i / 4; double f, fm; int e, m; - f = value / IMDCT_SCALAR * cbrtf(value) * pow(2, (i & 3) * 0.25); + /* cbrtf() isn't available on all systems, so we use powf(). */ + f = value / IMDCT_SCALAR * pow(value, 1.0 / 3.0) * pow(2, (i & 3) * 0.25); fm = frexp(f, &e); m = (uint32_t)(fm * (1LL << 31) + 0.5); e += FRAC_BITS - 31 + 5 - 100; @@ -59,8 +60,10 @@ static void mpegaudio_tableinit(void) } for (exponent = 0; exponent < 512; exponent++) { for (value = 0; value < 16; value++) { - double f = (double)value * cbrtf(value) * pow(2, (exponent - 400) * 0.25 + FRAC_BITS + 5) / IMDCT_SCALAR; - expval_table_fixed[exponent][value] = llrint(f); + /* cbrtf() isn't available on all systems, so we use powf(). */ + double f = (double)value * pow(value, 1.0 / 3.0) * pow(2, (exponent - 400) * 0.25 + FRAC_BITS + 5) / IMDCT_SCALAR; + /* llrint() isn't always available, so round and cast manually. */ + expval_table_fixed[exponent][value] = (long long int) (f < 0xFFFFFFFF ? floor(f + 0.5) : 0xFFFFFFFF); expval_table_float[exponent][value] = f; } exp_table_fixed[exponent] = expval_table_fixed[exponent][1]; diff --git a/ffmpeg/libavcodec/mpegaudiodec.c b/ffmpeg/libavcodec/mpegaudiodec.c deleted file mode 100644 index 4fffb6c..0000000 --- a/ffmpeg/libavcodec/mpegaudiodec.c +++ /dev/null @@ -1,2076 +0,0 @@ -/* - * MPEG Audio decoder - * Copyright (c) 2001, 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MPEG Audio decoder - */ - -#include "libavutil/avassert.h" -#include "libavutil/channel_layout.h" -#include "libavutil/float_dsp.h" -#include "libavutil/libm.h" -#include "avcodec.h" -#include "get_bits.h" -#include "internal.h" -#include "mathops.h" -#include "mpegaudiodsp.h" - -/* - * TODO: - * - test lsf / mpeg25 extensively. - */ - -#include "mpegaudio.h" -#include "mpegaudiodecheader.h" - -#define BACKSTEP_SIZE 512 -#define EXTRABYTES 24 -#define LAST_BUF_SIZE 2 * BACKSTEP_SIZE + EXTRABYTES - -/* layer 3 "granule" */ -typedef struct GranuleDef { - uint8_t scfsi; - int part2_3_length; - int big_values; - int global_gain; - int scalefac_compress; - uint8_t block_type; - uint8_t switch_point; - int table_select[3]; - int subblock_gain[3]; - uint8_t scalefac_scale; - uint8_t count1table_select; - int region_size[3]; /* number of huffman codes in each region */ - int preflag; - int short_start, long_end; /* long/short band indexes */ - uint8_t scale_factors[40]; - DECLARE_ALIGNED(16, INTFLOAT, sb_hybrid)[SBLIMIT * 18]; /* 576 samples */ -} GranuleDef; - -typedef struct MPADecodeContext { - MPA_DECODE_HEADER - uint8_t last_buf[LAST_BUF_SIZE]; - int last_buf_size; - /* next header (used in free format parsing) */ - uint32_t free_format_next_header; - GetBitContext gb; - GetBitContext in_gb; - DECLARE_ALIGNED(32, MPA_INT, synth_buf)[MPA_MAX_CHANNELS][512 * 2]; - int synth_buf_offset[MPA_MAX_CHANNELS]; - DECLARE_ALIGNED(32, INTFLOAT, sb_samples)[MPA_MAX_CHANNELS][36][SBLIMIT]; - INTFLOAT mdct_buf[MPA_MAX_CHANNELS][SBLIMIT * 18]; /* previous samples, for layer 3 MDCT */ - GranuleDef granules[2][2]; /* Used in Layer 3 */ - int adu_mode; ///< 0 for standard mp3, 1 for adu formatted mp3 - int dither_state; - int err_recognition; - AVCodecContext* avctx; - MPADSPContext mpadsp; - AVFloatDSPContext fdsp; - AVFrame *frame; -} MPADecodeContext; - -#if CONFIG_FLOAT -# define SHR(a,b) ((a)*(1.0f/(1<<(b)))) -# define FIXR_OLD(a) ((int)((a) * FRAC_ONE + 0.5)) -# define FIXR(x) ((float)(x)) -# define FIXHR(x) ((float)(x)) -# define MULH3(x, y, s) ((s)*(y)*(x)) -# define MULLx(x, y, s) ((y)*(x)) -# define RENAME(a) a ## _float -# define OUT_FMT AV_SAMPLE_FMT_FLT -# define OUT_FMT_P AV_SAMPLE_FMT_FLTP -#else -# define SHR(a,b) ((a)>>(b)) -/* WARNING: only correct for positive numbers */ -# define FIXR_OLD(a) ((int)((a) * FRAC_ONE + 0.5)) -# define FIXR(a) ((int)((a) * FRAC_ONE + 0.5)) -# define FIXHR(a) ((int)((a) * (1LL<<32) + 0.5)) -# define MULH3(x, y, s) MULH((s)*(x), y) -# define MULLx(x, y, s) MULL(x,y,s) -# define RENAME(a) a ## _fixed -# define OUT_FMT AV_SAMPLE_FMT_S16 -# define OUT_FMT_P AV_SAMPLE_FMT_S16P -#endif - -/****************/ - -#define HEADER_SIZE 4 - -#include "mpegaudiodata.h" -#include "mpegaudiodectab.h" - -/* vlc structure for decoding layer 3 huffman tables */ -static VLC huff_vlc[16]; -static VLC_TYPE huff_vlc_tables[ - 0 + 128 + 128 + 128 + 130 + 128 + 154 + 166 + - 142 + 204 + 190 + 170 + 542 + 460 + 662 + 414 - ][2]; -static const int huff_vlc_tables_sizes[16] = { - 0, 128, 128, 128, 130, 128, 154, 166, - 142, 204, 190, 170, 542, 460, 662, 414 -}; -static VLC huff_quad_vlc[2]; -static VLC_TYPE huff_quad_vlc_tables[128+16][2]; -static const int huff_quad_vlc_tables_sizes[2] = { 128, 16 }; -/* computed from band_size_long */ -static uint16_t band_index_long[9][23]; -#include "mpegaudio_tablegen.h" -/* intensity stereo coef table */ -static INTFLOAT is_table[2][16]; -static INTFLOAT is_table_lsf[2][2][16]; -static INTFLOAT csa_table[8][4]; - -static int16_t division_tab3[1<<6 ]; -static int16_t division_tab5[1<<8 ]; -static int16_t division_tab9[1<<11]; - -static int16_t * const division_tabs[4] = { - division_tab3, division_tab5, NULL, division_tab9 -}; - -/* lower 2 bits: modulo 3, higher bits: shift */ -static uint16_t scale_factor_modshift[64]; -/* [i][j]: 2^(-j/3) * FRAC_ONE * 2^(i+2) / (2^(i+2) - 1) */ -static int32_t scale_factor_mult[15][3]; -/* mult table for layer 2 group quantization */ - -#define SCALE_GEN(v) \ -{ FIXR_OLD(1.0 * (v)), FIXR_OLD(0.7937005259 * (v)), FIXR_OLD(0.6299605249 * (v)) } - -static const int32_t scale_factor_mult2[3][3] = { - SCALE_GEN(4.0 / 3.0), /* 3 steps */ - SCALE_GEN(4.0 / 5.0), /* 5 steps */ - SCALE_GEN(4.0 / 9.0), /* 9 steps */ -}; - -/** - * Convert region offsets to region sizes and truncate - * size to big_values. - */ -static void ff_region_offset2size(GranuleDef *g) -{ - int i, k, j = 0; - g->region_size[2] = 576 / 2; - for (i = 0; i < 3; i++) { - k = FFMIN(g->region_size[i], g->big_values); - g->region_size[i] = k - j; - j = k; - } -} - -static void ff_init_short_region(MPADecodeContext *s, GranuleDef *g) -{ - if (g->block_type == 2) { - if (s->sample_rate_index != 8) - g->region_size[0] = (36 / 2); - else - g->region_size[0] = (72 / 2); - } else { - if (s->sample_rate_index <= 2) - g->region_size[0] = (36 / 2); - else if (s->sample_rate_index != 8) - g->region_size[0] = (54 / 2); - else - g->region_size[0] = (108 / 2); - } - g->region_size[1] = (576 / 2); -} - -static void ff_init_long_region(MPADecodeContext *s, GranuleDef *g, int ra1, int ra2) -{ - int l; - g->region_size[0] = band_index_long[s->sample_rate_index][ra1 + 1] >> 1; - /* should not overflow */ - l = FFMIN(ra1 + ra2 + 2, 22); - g->region_size[1] = band_index_long[s->sample_rate_index][ l] >> 1; -} - -static void ff_compute_band_indexes(MPADecodeContext *s, GranuleDef *g) -{ - if (g->block_type == 2) { - if (g->switch_point) { - if(s->sample_rate_index == 8) - avpriv_request_sample(s->avctx, "switch point in 8khz"); - /* if switched mode, we handle the 36 first samples as - long blocks. For 8000Hz, we handle the 72 first - exponents as long blocks */ - if (s->sample_rate_index <= 2) - g->long_end = 8; - else - g->long_end = 6; - - g->short_start = 3; - } else { - g->long_end = 0; - g->short_start = 0; - } - } else { - g->short_start = 13; - g->long_end = 22; - } -} - -/* layer 1 unscaling */ -/* n = number of bits of the mantissa minus 1 */ -static inline int l1_unscale(int n, int mant, int scale_factor) -{ - int shift, mod; - int64_t val; - - shift = scale_factor_modshift[scale_factor]; - mod = shift & 3; - shift >>= 2; - val = MUL64(mant + (-1 << n) + 1, scale_factor_mult[n-1][mod]); - shift += n; - /* NOTE: at this point, 1 <= shift >= 21 + 15 */ - return (int)((val + (1LL << (shift - 1))) >> shift); -} - -static inline int l2_unscale_group(int steps, int mant, int scale_factor) -{ - int shift, mod, val; - - shift = scale_factor_modshift[scale_factor]; - mod = shift & 3; - shift >>= 2; - - val = (mant - (steps >> 1)) * scale_factor_mult2[steps >> 2][mod]; - /* NOTE: at this point, 0 <= shift <= 21 */ - if (shift > 0) - val = (val + (1 << (shift - 1))) >> shift; - return val; -} - -/* compute value^(4/3) * 2^(exponent/4). It normalized to FRAC_BITS */ -static inline int l3_unscale(int value, int exponent) -{ - unsigned int m; - int e; - - e = table_4_3_exp [4 * value + (exponent & 3)]; - m = table_4_3_value[4 * value + (exponent & 3)]; - e -= exponent >> 2; -#ifdef DEBUG - if(e < 1) - av_log(NULL, AV_LOG_WARNING, "l3_unscale: e is %d\n", e); -#endif - if (e > 31) - return 0; - m = (m + (1 << (e - 1))) >> e; - - return m; -} - -static av_cold void decode_init_static(void) -{ - int i, j, k; - int offset; - - /* scale factors table for layer 1/2 */ - for (i = 0; i < 64; i++) { - int shift, mod; - /* 1.0 (i = 3) is normalized to 2 ^ FRAC_BITS */ - shift = i / 3; - mod = i % 3; - scale_factor_modshift[i] = mod | (shift << 2); - } - - /* scale factor multiply for layer 1 */ - for (i = 0; i < 15; i++) { - int n, norm; - n = i + 2; - norm = ((INT64_C(1) << n) * FRAC_ONE) / ((1 << n) - 1); - scale_factor_mult[i][0] = MULLx(norm, FIXR(1.0 * 2.0), FRAC_BITS); - scale_factor_mult[i][1] = MULLx(norm, FIXR(0.7937005259 * 2.0), FRAC_BITS); - scale_factor_mult[i][2] = MULLx(norm, FIXR(0.6299605249 * 2.0), FRAC_BITS); - av_dlog(NULL, "%d: norm=%x s=%x %x %x\n", i, norm, - scale_factor_mult[i][0], - scale_factor_mult[i][1], - scale_factor_mult[i][2]); - } - - RENAME(ff_mpa_synth_init)(RENAME(ff_mpa_synth_window)); - - /* huffman decode tables */ - offset = 0; - for (i = 1; i < 16; i++) { - const HuffTable *h = &mpa_huff_tables[i]; - int xsize, x, y; - uint8_t tmp_bits [512] = { 0 }; - uint16_t tmp_codes[512] = { 0 }; - - xsize = h->xsize; - - j = 0; - for (x = 0; x < xsize; x++) { - for (y = 0; y < xsize; y++) { - tmp_bits [(x << 5) | y | ((x&&y)<<4)]= h->bits [j ]; - tmp_codes[(x << 5) | y | ((x&&y)<<4)]= h->codes[j++]; - } - } - - /* XXX: fail test */ - huff_vlc[i].table = huff_vlc_tables+offset; - huff_vlc[i].table_allocated = huff_vlc_tables_sizes[i]; - init_vlc(&huff_vlc[i], 7, 512, - tmp_bits, 1, 1, tmp_codes, 2, 2, - INIT_VLC_USE_NEW_STATIC); - offset += huff_vlc_tables_sizes[i]; - } - av_assert0(offset == FF_ARRAY_ELEMS(huff_vlc_tables)); - - offset = 0; - for (i = 0; i < 2; i++) { - huff_quad_vlc[i].table = huff_quad_vlc_tables+offset; - huff_quad_vlc[i].table_allocated = huff_quad_vlc_tables_sizes[i]; - init_vlc(&huff_quad_vlc[i], i == 0 ? 7 : 4, 16, - mpa_quad_bits[i], 1, 1, mpa_quad_codes[i], 1, 1, - INIT_VLC_USE_NEW_STATIC); - offset += huff_quad_vlc_tables_sizes[i]; - } - av_assert0(offset == FF_ARRAY_ELEMS(huff_quad_vlc_tables)); - - for (i = 0; i < 9; i++) { - k = 0; - for (j = 0; j < 22; j++) { - band_index_long[i][j] = k; - k += band_size_long[i][j]; - } - band_index_long[i][22] = k; - } - - /* compute n ^ (4/3) and store it in mantissa/exp format */ - - mpegaudio_tableinit(); - - for (i = 0; i < 4; i++) { - if (ff_mpa_quant_bits[i] < 0) { - for (j = 0; j < (1 << (-ff_mpa_quant_bits[i]+1)); j++) { - int val1, val2, val3, steps; - int val = j; - steps = ff_mpa_quant_steps[i]; - val1 = val % steps; - val /= steps; - val2 = val % steps; - val3 = val / steps; - division_tabs[i][j] = val1 + (val2 << 4) + (val3 << 8); - } - } - } - - - for (i = 0; i < 7; i++) { - float f; - INTFLOAT v; - if (i != 6) { - f = tan((double)i * M_PI / 12.0); - v = FIXR(f / (1.0 + f)); - } else { - v = FIXR(1.0); - } - is_table[0][ i] = v; - is_table[1][6 - i] = v; - } - /* invalid values */ - for (i = 7; i < 16; i++) - is_table[0][i] = is_table[1][i] = 0.0; - - for (i = 0; i < 16; i++) { - double f; - int e, k; - - for (j = 0; j < 2; j++) { - e = -(j + 1) * ((i + 1) >> 1); - f = exp2(e / 4.0); - k = i & 1; - is_table_lsf[j][k ^ 1][i] = FIXR(f); - is_table_lsf[j][k ][i] = FIXR(1.0); - av_dlog(NULL, "is_table_lsf %d %d: %f %f\n", - i, j, (float) is_table_lsf[j][0][i], - (float) is_table_lsf[j][1][i]); - } - } - - for (i = 0; i < 8; i++) { - float ci, cs, ca; - ci = ci_table[i]; - cs = 1.0 / sqrt(1.0 + ci * ci); - ca = cs * ci; -#if !CONFIG_FLOAT - csa_table[i][0] = FIXHR(cs/4); - csa_table[i][1] = FIXHR(ca/4); - csa_table[i][2] = FIXHR(ca/4) + FIXHR(cs/4); - csa_table[i][3] = FIXHR(ca/4) - FIXHR(cs/4); -#else - csa_table[i][0] = cs; - csa_table[i][1] = ca; - csa_table[i][2] = ca + cs; - csa_table[i][3] = ca - cs; -#endif - } -} - -static av_cold int decode_init(AVCodecContext * avctx) -{ - static int initialized_tables = 0; - MPADecodeContext *s = avctx->priv_data; - - if (!initialized_tables) { - decode_init_static(); - initialized_tables = 1; - } - - s->avctx = avctx; - - avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT); - ff_mpadsp_init(&s->mpadsp); - - if (avctx->request_sample_fmt == OUT_FMT && - avctx->codec_id != AV_CODEC_ID_MP3ON4) - avctx->sample_fmt = OUT_FMT; - else - avctx->sample_fmt = OUT_FMT_P; - s->err_recognition = avctx->err_recognition; - - if (avctx->codec_id == AV_CODEC_ID_MP3ADU) - s->adu_mode = 1; - - return 0; -} - -#define C3 FIXHR(0.86602540378443864676/2) -#define C4 FIXHR(0.70710678118654752439/2) //0.5 / cos(pi*(9)/36) -#define C5 FIXHR(0.51763809020504152469/2) //0.5 / cos(pi*(5)/36) -#define C6 FIXHR(1.93185165257813657349/4) //0.5 / cos(pi*(15)/36) - -/* 12 points IMDCT. We compute it "by hand" by factorizing obvious - cases. */ -static void imdct12(INTFLOAT *out, INTFLOAT *in) -{ - INTFLOAT in0, in1, in2, in3, in4, in5, t1, t2; - - in0 = in[0*3]; - in1 = in[1*3] + in[0*3]; - in2 = in[2*3] + in[1*3]; - in3 = in[3*3] + in[2*3]; - in4 = in[4*3] + in[3*3]; - in5 = in[5*3] + in[4*3]; - in5 += in3; - in3 += in1; - - in2 = MULH3(in2, C3, 2); - in3 = MULH3(in3, C3, 4); - - t1 = in0 - in4; - t2 = MULH3(in1 - in5, C4, 2); - - out[ 7] = - out[10] = t1 + t2; - out[ 1] = - out[ 4] = t1 - t2; - - in0 += SHR(in4, 1); - in4 = in0 + in2; - in5 += 2*in1; - in1 = MULH3(in5 + in3, C5, 1); - out[ 8] = - out[ 9] = in4 + in1; - out[ 2] = - out[ 3] = in4 - in1; - - in0 -= in2; - in5 = MULH3(in5 - in3, C6, 2); - out[ 0] = - out[ 5] = in0 - in5; - out[ 6] = - out[11] = in0 + in5; -} - -/* return the number of decoded frames */ -static int mp_decode_layer1(MPADecodeContext *s) -{ - int bound, i, v, n, ch, j, mant; - uint8_t allocation[MPA_MAX_CHANNELS][SBLIMIT]; - uint8_t scale_factors[MPA_MAX_CHANNELS][SBLIMIT]; - - if (s->mode == MPA_JSTEREO) - bound = (s->mode_ext + 1) * 4; - else - bound = SBLIMIT; - - /* allocation bits */ - for (i = 0; i < bound; i++) { - for (ch = 0; ch < s->nb_channels; ch++) { - allocation[ch][i] = get_bits(&s->gb, 4); - } - } - for (i = bound; i < SBLIMIT; i++) - allocation[0][i] = get_bits(&s->gb, 4); - - /* scale factors */ - for (i = 0; i < bound; i++) { - for (ch = 0; ch < s->nb_channels; ch++) { - if (allocation[ch][i]) - scale_factors[ch][i] = get_bits(&s->gb, 6); - } - } - for (i = bound; i < SBLIMIT; i++) { - if (allocation[0][i]) { - scale_factors[0][i] = get_bits(&s->gb, 6); - scale_factors[1][i] = get_bits(&s->gb, 6); - } - } - - /* compute samples */ - for (j = 0; j < 12; j++) { - for (i = 0; i < bound; i++) { - for (ch = 0; ch < s->nb_channels; ch++) { - n = allocation[ch][i]; - if (n) { - mant = get_bits(&s->gb, n + 1); - v = l1_unscale(n, mant, scale_factors[ch][i]); - } else { - v = 0; - } - s->sb_samples[ch][j][i] = v; - } - } - for (i = bound; i < SBLIMIT; i++) { - n = allocation[0][i]; - if (n) { - mant = get_bits(&s->gb, n + 1); - v = l1_unscale(n, mant, scale_factors[0][i]); - s->sb_samples[0][j][i] = v; - v = l1_unscale(n, mant, scale_factors[1][i]); - s->sb_samples[1][j][i] = v; - } else { - s->sb_samples[0][j][i] = 0; - s->sb_samples[1][j][i] = 0; - } - } - } - return 12; -} - -static int mp_decode_layer2(MPADecodeContext *s) -{ - int sblimit; /* number of used subbands */ - const unsigned char *alloc_table; - int table, bit_alloc_bits, i, j, ch, bound, v; - unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT]; - unsigned char scale_code[MPA_MAX_CHANNELS][SBLIMIT]; - unsigned char scale_factors[MPA_MAX_CHANNELS][SBLIMIT][3], *sf; - int scale, qindex, bits, steps, k, l, m, b; - - /* select decoding table */ - table = ff_mpa_l2_select_table(s->bit_rate / 1000, s->nb_channels, - s->sample_rate, s->lsf); - sblimit = ff_mpa_sblimit_table[table]; - alloc_table = ff_mpa_alloc_tables[table]; - - if (s->mode == MPA_JSTEREO) - bound = (s->mode_ext + 1) * 4; - else - bound = sblimit; - - av_dlog(s->avctx, "bound=%d sblimit=%d\n", bound, sblimit); - - /* sanity check */ - if (bound > sblimit) - bound = sblimit; - - /* parse bit allocation */ - j = 0; - for (i = 0; i < bound; i++) { - bit_alloc_bits = alloc_table[j]; - for (ch = 0; ch < s->nb_channels; ch++) - bit_alloc[ch][i] = get_bits(&s->gb, bit_alloc_bits); - j += 1 << bit_alloc_bits; - } - for (i = bound; i < sblimit; i++) { - bit_alloc_bits = alloc_table[j]; - v = get_bits(&s->gb, bit_alloc_bits); - bit_alloc[0][i] = v; - bit_alloc[1][i] = v; - j += 1 << bit_alloc_bits; - } - - /* scale codes */ - for (i = 0; i < sblimit; i++) { - for (ch = 0; ch < s->nb_channels; ch++) { - if (bit_alloc[ch][i]) - scale_code[ch][i] = get_bits(&s->gb, 2); - } - } - - /* scale factors */ - for (i = 0; i < sblimit; i++) { - for (ch = 0; ch < s->nb_channels; ch++) { - if (bit_alloc[ch][i]) { - sf = scale_factors[ch][i]; - switch (scale_code[ch][i]) { - default: - case 0: - sf[0] = get_bits(&s->gb, 6); - sf[1] = get_bits(&s->gb, 6); - sf[2] = get_bits(&s->gb, 6); - break; - case 2: - sf[0] = get_bits(&s->gb, 6); - sf[1] = sf[0]; - sf[2] = sf[0]; - break; - case 1: - sf[0] = get_bits(&s->gb, 6); - sf[2] = get_bits(&s->gb, 6); - sf[1] = sf[0]; - break; - case 3: - sf[0] = get_bits(&s->gb, 6); - sf[2] = get_bits(&s->gb, 6); - sf[1] = sf[2]; - break; - } - } - } - } - - /* samples */ - for (k = 0; k < 3; k++) { - for (l = 0; l < 12; l += 3) { - j = 0; - for (i = 0; i < bound; i++) { - bit_alloc_bits = alloc_table[j]; - for (ch = 0; ch < s->nb_channels; ch++) { - b = bit_alloc[ch][i]; - if (b) { - scale = scale_factors[ch][i][k]; - qindex = alloc_table[j+b]; - bits = ff_mpa_quant_bits[qindex]; - if (bits < 0) { - int v2; - /* 3 values at the same time */ - v = get_bits(&s->gb, -bits); - v2 = division_tabs[qindex][v]; - steps = ff_mpa_quant_steps[qindex]; - - s->sb_samples[ch][k * 12 + l + 0][i] = - l2_unscale_group(steps, v2 & 15, scale); - s->sb_samples[ch][k * 12 + l + 1][i] = - l2_unscale_group(steps, (v2 >> 4) & 15, scale); - s->sb_samples[ch][k * 12 + l + 2][i] = - l2_unscale_group(steps, v2 >> 8 , scale); - } else { - for (m = 0; m < 3; m++) { - v = get_bits(&s->gb, bits); - v = l1_unscale(bits - 1, v, scale); - s->sb_samples[ch][k * 12 + l + m][i] = v; - } - } - } else { - s->sb_samples[ch][k * 12 + l + 0][i] = 0; - s->sb_samples[ch][k * 12 + l + 1][i] = 0; - s->sb_samples[ch][k * 12 + l + 2][i] = 0; - } - } - /* next subband in alloc table */ - j += 1 << bit_alloc_bits; - } - /* XXX: find a way to avoid this duplication of code */ - for (i = bound; i < sblimit; i++) { - bit_alloc_bits = alloc_table[j]; - b = bit_alloc[0][i]; - if (b) { - int mant, scale0, scale1; - scale0 = scale_factors[0][i][k]; - scale1 = scale_factors[1][i][k]; - qindex = alloc_table[j+b]; - bits = ff_mpa_quant_bits[qindex]; - if (bits < 0) { - /* 3 values at the same time */ - v = get_bits(&s->gb, -bits); - steps = ff_mpa_quant_steps[qindex]; - mant = v % steps; - v = v / steps; - s->sb_samples[0][k * 12 + l + 0][i] = - l2_unscale_group(steps, mant, scale0); - s->sb_samples[1][k * 12 + l + 0][i] = - l2_unscale_group(steps, mant, scale1); - mant = v % steps; - v = v / steps; - s->sb_samples[0][k * 12 + l + 1][i] = - l2_unscale_group(steps, mant, scale0); - s->sb_samples[1][k * 12 + l + 1][i] = - l2_unscale_group(steps, mant, scale1); - s->sb_samples[0][k * 12 + l + 2][i] = - l2_unscale_group(steps, v, scale0); - s->sb_samples[1][k * 12 + l + 2][i] = - l2_unscale_group(steps, v, scale1); - } else { - for (m = 0; m < 3; m++) { - mant = get_bits(&s->gb, bits); - s->sb_samples[0][k * 12 + l + m][i] = - l1_unscale(bits - 1, mant, scale0); - s->sb_samples[1][k * 12 + l + m][i] = - l1_unscale(bits - 1, mant, scale1); - } - } - } else { - s->sb_samples[0][k * 12 + l + 0][i] = 0; - s->sb_samples[0][k * 12 + l + 1][i] = 0; - s->sb_samples[0][k * 12 + l + 2][i] = 0; - s->sb_samples[1][k * 12 + l + 0][i] = 0; - s->sb_samples[1][k * 12 + l + 1][i] = 0; - s->sb_samples[1][k * 12 + l + 2][i] = 0; - } - /* next subband in alloc table */ - j += 1 << bit_alloc_bits; - } - /* fill remaining samples to zero */ - for (i = sblimit; i < SBLIMIT; i++) { - for (ch = 0; ch < s->nb_channels; ch++) { - s->sb_samples[ch][k * 12 + l + 0][i] = 0; - s->sb_samples[ch][k * 12 + l + 1][i] = 0; - s->sb_samples[ch][k * 12 + l + 2][i] = 0; - } - } - } - } - return 3 * 12; -} - -#define SPLIT(dst,sf,n) \ - if (n == 3) { \ - int m = (sf * 171) >> 9; \ - dst = sf - 3 * m; \ - sf = m; \ - } else if (n == 4) { \ - dst = sf & 3; \ - sf >>= 2; \ - } else if (n == 5) { \ - int m = (sf * 205) >> 10; \ - dst = sf - 5 * m; \ - sf = m; \ - } else if (n == 6) { \ - int m = (sf * 171) >> 10; \ - dst = sf - 6 * m; \ - sf = m; \ - } else { \ - dst = 0; \ - } - -static av_always_inline void lsf_sf_expand(int *slen, int sf, int n1, int n2, - int n3) -{ - SPLIT(slen[3], sf, n3) - SPLIT(slen[2], sf, n2) - SPLIT(slen[1], sf, n1) - slen[0] = sf; -} - -static void exponents_from_scale_factors(MPADecodeContext *s, GranuleDef *g, - int16_t *exponents) -{ - const uint8_t *bstab, *pretab; - int len, i, j, k, l, v0, shift, gain, gains[3]; - int16_t *exp_ptr; - - exp_ptr = exponents; - gain = g->global_gain - 210; - shift = g->scalefac_scale + 1; - - bstab = band_size_long[s->sample_rate_index]; - pretab = mpa_pretab[g->preflag]; - for (i = 0; i < g->long_end; i++) { - v0 = gain - ((g->scale_factors[i] + pretab[i]) << shift) + 400; - len = bstab[i]; - for (j = len; j > 0; j--) - *exp_ptr++ = v0; - } - - if (g->short_start < 13) { - bstab = band_size_short[s->sample_rate_index]; - gains[0] = gain - (g->subblock_gain[0] << 3); - gains[1] = gain - (g->subblock_gain[1] << 3); - gains[2] = gain - (g->subblock_gain[2] << 3); - k = g->long_end; - for (i = g->short_start; i < 13; i++) { - len = bstab[i]; - for (l = 0; l < 3; l++) { - v0 = gains[l] - (g->scale_factors[k++] << shift) + 400; - for (j = len; j > 0; j--) - *exp_ptr++ = v0; - } - } - } -} - -/* handle n = 0 too */ -static inline int get_bitsz(GetBitContext *s, int n) -{ - return n ? get_bits(s, n) : 0; -} - - -static void switch_buffer(MPADecodeContext *s, int *pos, int *end_pos, - int *end_pos2) -{ - if (s->in_gb.buffer && *pos >= s->gb.size_in_bits) { - s->gb = s->in_gb; - s->in_gb.buffer = NULL; - av_assert2((get_bits_count(&s->gb) & 7) == 0); - skip_bits_long(&s->gb, *pos - *end_pos); - *end_pos2 = - *end_pos = *end_pos2 + get_bits_count(&s->gb) - *pos; - *pos = get_bits_count(&s->gb); - } -} - -/* Following is a optimized code for - INTFLOAT v = *src - if(get_bits1(&s->gb)) - v = -v; - *dst = v; -*/ -#if CONFIG_FLOAT -#define READ_FLIP_SIGN(dst,src) \ - v = AV_RN32A(src) ^ (get_bits1(&s->gb) << 31); \ - AV_WN32A(dst, v); -#else -#define READ_FLIP_SIGN(dst,src) \ - v = -get_bits1(&s->gb); \ - *(dst) = (*(src) ^ v) - v; -#endif - -static int huffman_decode(MPADecodeContext *s, GranuleDef *g, - int16_t *exponents, int end_pos2) -{ - int s_index; - int i; - int last_pos, bits_left; - VLC *vlc; - int end_pos = FFMIN(end_pos2, s->gb.size_in_bits); - - /* low frequencies (called big values) */ - s_index = 0; - for (i = 0; i < 3; i++) { - int j, k, l, linbits; - j = g->region_size[i]; - if (j == 0) - continue; - /* select vlc table */ - k = g->table_select[i]; - l = mpa_huff_data[k][0]; - linbits = mpa_huff_data[k][1]; - vlc = &huff_vlc[l]; - - if (!l) { - memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid) * 2 * j); - s_index += 2 * j; - continue; - } - - /* read huffcode and compute each couple */ - for (; j > 0; j--) { - int exponent, x, y; - int v; - int pos = get_bits_count(&s->gb); - - if (pos >= end_pos){ - switch_buffer(s, &pos, &end_pos, &end_pos2); - if (pos >= end_pos) - break; - } - y = get_vlc2(&s->gb, vlc->table, 7, 3); - - if (!y) { - g->sb_hybrid[s_index ] = - g->sb_hybrid[s_index+1] = 0; - s_index += 2; - continue; - } - - exponent= exponents[s_index]; - - av_dlog(s->avctx, "region=%d n=%d x=%d y=%d exp=%d\n", - i, g->region_size[i] - j, x, y, exponent); - if (y & 16) { - x = y >> 5; - y = y & 0x0f; - if (x < 15) { - READ_FLIP_SIGN(g->sb_hybrid + s_index, RENAME(expval_table)[exponent] + x) - } else { - x += get_bitsz(&s->gb, linbits); - v = l3_unscale(x, exponent); - if (get_bits1(&s->gb)) - v = -v; - g->sb_hybrid[s_index] = v; - } - if (y < 15) { - READ_FLIP_SIGN(g->sb_hybrid + s_index + 1, RENAME(expval_table)[exponent] + y) - } else { - y += get_bitsz(&s->gb, linbits); - v = l3_unscale(y, exponent); - if (get_bits1(&s->gb)) - v = -v; - g->sb_hybrid[s_index+1] = v; - } - } else { - x = y >> 5; - y = y & 0x0f; - x += y; - if (x < 15) { - READ_FLIP_SIGN(g->sb_hybrid + s_index + !!y, RENAME(expval_table)[exponent] + x) - } else { - x += get_bitsz(&s->gb, linbits); - v = l3_unscale(x, exponent); - if (get_bits1(&s->gb)) - v = -v; - g->sb_hybrid[s_index+!!y] = v; - } - g->sb_hybrid[s_index + !y] = 0; - } - s_index += 2; - } - } - - /* high frequencies */ - vlc = &huff_quad_vlc[g->count1table_select]; - last_pos = 0; - while (s_index <= 572) { - int pos, code; - pos = get_bits_count(&s->gb); - if (pos >= end_pos) { - if (pos > end_pos2 && last_pos) { - /* some encoders generate an incorrect size for this - part. We must go back into the data */ - s_index -= 4; - skip_bits_long(&s->gb, last_pos - pos); - av_log(s->avctx, AV_LOG_INFO, "overread, skip %d enddists: %d %d\n", last_pos - pos, end_pos-pos, end_pos2-pos); - if(s->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT)) - s_index=0; - break; - } - switch_buffer(s, &pos, &end_pos, &end_pos2); - if (pos >= end_pos) - break; - } - last_pos = pos; - - code = get_vlc2(&s->gb, vlc->table, vlc->bits, 1); - av_dlog(s->avctx, "t=%d code=%d\n", g->count1table_select, code); - g->sb_hybrid[s_index+0] = - g->sb_hybrid[s_index+1] = - g->sb_hybrid[s_index+2] = - g->sb_hybrid[s_index+3] = 0; - while (code) { - static const int idxtab[16] = { 3,3,2,2,1,1,1,1,0,0,0,0,0,0,0,0 }; - int v; - int pos = s_index + idxtab[code]; - code ^= 8 >> idxtab[code]; - READ_FLIP_SIGN(g->sb_hybrid + pos, RENAME(exp_table)+exponents[pos]) - } - s_index += 4; - } - /* skip extension bits */ - bits_left = end_pos2 - get_bits_count(&s->gb); - if (bits_left < 0 && (s->err_recognition & (AV_EF_BUFFER|AV_EF_COMPLIANT))) { - av_log(s->avctx, AV_LOG_ERROR, "bits_left=%d\n", bits_left); - s_index=0; - } else if (bits_left > 0 && (s->err_recognition & (AV_EF_BUFFER|AV_EF_AGGRESSIVE))) { - av_log(s->avctx, AV_LOG_ERROR, "bits_left=%d\n", bits_left); - s_index = 0; - } - memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid) * (576 - s_index)); - skip_bits_long(&s->gb, bits_left); - - i = get_bits_count(&s->gb); - switch_buffer(s, &i, &end_pos, &end_pos2); - - return 0; -} - -/* Reorder short blocks from bitstream order to interleaved order. It - would be faster to do it in parsing, but the code would be far more - complicated */ -static void reorder_block(MPADecodeContext *s, GranuleDef *g) -{ - int i, j, len; - INTFLOAT *ptr, *dst, *ptr1; - INTFLOAT tmp[576]; - - if (g->block_type != 2) - return; - - if (g->switch_point) { - if (s->sample_rate_index != 8) - ptr = g->sb_hybrid + 36; - else - ptr = g->sb_hybrid + 72; - } else { - ptr = g->sb_hybrid; - } - - for (i = g->short_start; i < 13; i++) { - len = band_size_short[s->sample_rate_index][i]; - ptr1 = ptr; - dst = tmp; - for (j = len; j > 0; j--) { - *dst++ = ptr[0*len]; - *dst++ = ptr[1*len]; - *dst++ = ptr[2*len]; - ptr++; - } - ptr += 2 * len; - memcpy(ptr1, tmp, len * 3 * sizeof(*ptr1)); - } -} - -#define ISQRT2 FIXR(0.70710678118654752440) - -static void compute_stereo(MPADecodeContext *s, GranuleDef *g0, GranuleDef *g1) -{ - int i, j, k, l; - int sf_max, sf, len, non_zero_found; - INTFLOAT (*is_tab)[16], *tab0, *tab1, tmp0, tmp1, v1, v2; - int non_zero_found_short[3]; - - /* intensity stereo */ - if (s->mode_ext & MODE_EXT_I_STEREO) { - if (!s->lsf) { - is_tab = is_table; - sf_max = 7; - } else { - is_tab = is_table_lsf[g1->scalefac_compress & 1]; - sf_max = 16; - } - - tab0 = g0->sb_hybrid + 576; - tab1 = g1->sb_hybrid + 576; - - non_zero_found_short[0] = 0; - non_zero_found_short[1] = 0; - non_zero_found_short[2] = 0; - k = (13 - g1->short_start) * 3 + g1->long_end - 3; - for (i = 12; i >= g1->short_start; i--) { - /* for last band, use previous scale factor */ - if (i != 11) - k -= 3; - len = band_size_short[s->sample_rate_index][i]; - for (l = 2; l >= 0; l--) { - tab0 -= len; - tab1 -= len; - if (!non_zero_found_short[l]) { - /* test if non zero band. if so, stop doing i-stereo */ - for (j = 0; j < len; j++) { - if (tab1[j] != 0) { - non_zero_found_short[l] = 1; - goto found1; - } - } - sf = g1->scale_factors[k + l]; - if (sf >= sf_max) - goto found1; - - v1 = is_tab[0][sf]; - v2 = is_tab[1][sf]; - for (j = 0; j < len; j++) { - tmp0 = tab0[j]; - tab0[j] = MULLx(tmp0, v1, FRAC_BITS); - tab1[j] = MULLx(tmp0, v2, FRAC_BITS); - } - } else { -found1: - if (s->mode_ext & MODE_EXT_MS_STEREO) { - /* lower part of the spectrum : do ms stereo - if enabled */ - for (j = 0; j < len; j++) { - tmp0 = tab0[j]; - tmp1 = tab1[j]; - tab0[j] = MULLx(tmp0 + tmp1, ISQRT2, FRAC_BITS); - tab1[j] = MULLx(tmp0 - tmp1, ISQRT2, FRAC_BITS); - } - } - } - } - } - - non_zero_found = non_zero_found_short[0] | - non_zero_found_short[1] | - non_zero_found_short[2]; - - for (i = g1->long_end - 1;i >= 0;i--) { - len = band_size_long[s->sample_rate_index][i]; - tab0 -= len; - tab1 -= len; - /* test if non zero band. if so, stop doing i-stereo */ - if (!non_zero_found) { - for (j = 0; j < len; j++) { - if (tab1[j] != 0) { - non_zero_found = 1; - goto found2; - } - } - /* for last band, use previous scale factor */ - k = (i == 21) ? 20 : i; - sf = g1->scale_factors[k]; - if (sf >= sf_max) - goto found2; - v1 = is_tab[0][sf]; - v2 = is_tab[1][sf]; - for (j = 0; j < len; j++) { - tmp0 = tab0[j]; - tab0[j] = MULLx(tmp0, v1, FRAC_BITS); - tab1[j] = MULLx(tmp0, v2, FRAC_BITS); - } - } else { -found2: - if (s->mode_ext & MODE_EXT_MS_STEREO) { - /* lower part of the spectrum : do ms stereo - if enabled */ - for (j = 0; j < len; j++) { - tmp0 = tab0[j]; - tmp1 = tab1[j]; - tab0[j] = MULLx(tmp0 + tmp1, ISQRT2, FRAC_BITS); - tab1[j] = MULLx(tmp0 - tmp1, ISQRT2, FRAC_BITS); - } - } - } - } - } else if (s->mode_ext & MODE_EXT_MS_STEREO) { - /* ms stereo ONLY */ - /* NOTE: the 1/sqrt(2) normalization factor is included in the - global gain */ -#if CONFIG_FLOAT - s->fdsp.butterflies_float(g0->sb_hybrid, g1->sb_hybrid, 576); -#else - tab0 = g0->sb_hybrid; - tab1 = g1->sb_hybrid; - for (i = 0; i < 576; i++) { - tmp0 = tab0[i]; - tmp1 = tab1[i]; - tab0[i] = tmp0 + tmp1; - tab1[i] = tmp0 - tmp1; - } -#endif - } -} - -#if CONFIG_FLOAT -#if HAVE_MIPSFPU -# include "mips/compute_antialias_float.h" -#endif /* HAVE_MIPSFPU */ -#else -#if HAVE_MIPSDSPR1 -# include "mips/compute_antialias_fixed.h" -#endif /* HAVE_MIPSDSPR1 */ -#endif /* CONFIG_FLOAT */ - -#ifndef compute_antialias -#if CONFIG_FLOAT -#define AA(j) do { \ - float tmp0 = ptr[-1-j]; \ - float tmp1 = ptr[ j]; \ - ptr[-1-j] = tmp0 * csa_table[j][0] - tmp1 * csa_table[j][1]; \ - ptr[ j] = tmp0 * csa_table[j][1] + tmp1 * csa_table[j][0]; \ - } while (0) -#else -#define AA(j) do { \ - int tmp0 = ptr[-1-j]; \ - int tmp1 = ptr[ j]; \ - int tmp2 = MULH(tmp0 + tmp1, csa_table[j][0]); \ - ptr[-1-j] = 4 * (tmp2 - MULH(tmp1, csa_table[j][2])); \ - ptr[ j] = 4 * (tmp2 + MULH(tmp0, csa_table[j][3])); \ - } while (0) -#endif - -static void compute_antialias(MPADecodeContext *s, GranuleDef *g) -{ - INTFLOAT *ptr; - int n, i; - - /* we antialias only "long" bands */ - if (g->block_type == 2) { - if (!g->switch_point) - return; - /* XXX: check this for 8000Hz case */ - n = 1; - } else { - n = SBLIMIT - 1; - } - - ptr = g->sb_hybrid + 18; - for (i = n; i > 0; i--) { - AA(0); - AA(1); - AA(2); - AA(3); - AA(4); - AA(5); - AA(6); - AA(7); - - ptr += 18; - } -} -#endif /* compute_antialias */ - -static void compute_imdct(MPADecodeContext *s, GranuleDef *g, - INTFLOAT *sb_samples, INTFLOAT *mdct_buf) -{ - INTFLOAT *win, *out_ptr, *ptr, *buf, *ptr1; - INTFLOAT out2[12]; - int i, j, mdct_long_end, sblimit; - - /* find last non zero block */ - ptr = g->sb_hybrid + 576; - ptr1 = g->sb_hybrid + 2 * 18; - while (ptr >= ptr1) { - int32_t *p; - ptr -= 6; - p = (int32_t*)ptr; - if (p[0] | p[1] | p[2] | p[3] | p[4] | p[5]) - break; - } - sblimit = ((ptr - g->sb_hybrid) / 18) + 1; - - if (g->block_type == 2) { - /* XXX: check for 8000 Hz */ - if (g->switch_point) - mdct_long_end = 2; - else - mdct_long_end = 0; - } else { - mdct_long_end = sblimit; - } - - s->mpadsp.RENAME(imdct36_blocks)(sb_samples, mdct_buf, g->sb_hybrid, - mdct_long_end, g->switch_point, - g->block_type); - - buf = mdct_buf + 4*18*(mdct_long_end >> 2) + (mdct_long_end & 3); - ptr = g->sb_hybrid + 18 * mdct_long_end; - - for (j = mdct_long_end; j < sblimit; j++) { - /* select frequency inversion */ - win = RENAME(ff_mdct_win)[2 + (4 & -(j & 1))]; - out_ptr = sb_samples + j; - - for (i = 0; i < 6; i++) { - *out_ptr = buf[4*i]; - out_ptr += SBLIMIT; - } - imdct12(out2, ptr + 0); - for (i = 0; i < 6; i++) { - *out_ptr = MULH3(out2[i ], win[i ], 1) + buf[4*(i + 6*1)]; - buf[4*(i + 6*2)] = MULH3(out2[i + 6], win[i + 6], 1); - out_ptr += SBLIMIT; - } - imdct12(out2, ptr + 1); - for (i = 0; i < 6; i++) { - *out_ptr = MULH3(out2[i ], win[i ], 1) + buf[4*(i + 6*2)]; - buf[4*(i + 6*0)] = MULH3(out2[i + 6], win[i + 6], 1); - out_ptr += SBLIMIT; - } - imdct12(out2, ptr + 2); - for (i = 0; i < 6; i++) { - buf[4*(i + 6*0)] = MULH3(out2[i ], win[i ], 1) + buf[4*(i + 6*0)]; - buf[4*(i + 6*1)] = MULH3(out2[i + 6], win[i + 6], 1); - buf[4*(i + 6*2)] = 0; - } - ptr += 18; - buf += (j&3) != 3 ? 1 : (4*18-3); - } - /* zero bands */ - for (j = sblimit; j < SBLIMIT; j++) { - /* overlap */ - out_ptr = sb_samples + j; - for (i = 0; i < 18; i++) { - *out_ptr = buf[4*i]; - buf[4*i] = 0; - out_ptr += SBLIMIT; - } - buf += (j&3) != 3 ? 1 : (4*18-3); - } -} - -/* main layer3 decoding function */ -static int mp_decode_layer3(MPADecodeContext *s) -{ - int nb_granules, main_data_begin; - int gr, ch, blocksplit_flag, i, j, k, n, bits_pos; - GranuleDef *g; - int16_t exponents[576]; //FIXME try INTFLOAT - - /* read side info */ - if (s->lsf) { - main_data_begin = get_bits(&s->gb, 8); - skip_bits(&s->gb, s->nb_channels); - nb_granules = 1; - } else { - main_data_begin = get_bits(&s->gb, 9); - if (s->nb_channels == 2) - skip_bits(&s->gb, 3); - else - skip_bits(&s->gb, 5); - nb_granules = 2; - for (ch = 0; ch < s->nb_channels; ch++) { - s->granules[ch][0].scfsi = 0;/* all scale factors are transmitted */ - s->granules[ch][1].scfsi = get_bits(&s->gb, 4); - } - } - - for (gr = 0; gr < nb_granules; gr++) { - for (ch = 0; ch < s->nb_channels; ch++) { - av_dlog(s->avctx, "gr=%d ch=%d: side_info\n", gr, ch); - g = &s->granules[ch][gr]; - g->part2_3_length = get_bits(&s->gb, 12); - g->big_values = get_bits(&s->gb, 9); - if (g->big_values > 288) { - av_log(s->avctx, AV_LOG_ERROR, "big_values too big\n"); - return AVERROR_INVALIDDATA; - } - - g->global_gain = get_bits(&s->gb, 8); - /* if MS stereo only is selected, we precompute the - 1/sqrt(2) renormalization factor */ - if ((s->mode_ext & (MODE_EXT_MS_STEREO | MODE_EXT_I_STEREO)) == - MODE_EXT_MS_STEREO) - g->global_gain -= 2; - if (s->lsf) - g->scalefac_compress = get_bits(&s->gb, 9); - else - g->scalefac_compress = get_bits(&s->gb, 4); - blocksplit_flag = get_bits1(&s->gb); - if (blocksplit_flag) { - g->block_type = get_bits(&s->gb, 2); - if (g->block_type == 0) { - av_log(s->avctx, AV_LOG_ERROR, "invalid block type\n"); - return AVERROR_INVALIDDATA; - } - g->switch_point = get_bits1(&s->gb); - for (i = 0; i < 2; i++) - g->table_select[i] = get_bits(&s->gb, 5); - for (i = 0; i < 3; i++) - g->subblock_gain[i] = get_bits(&s->gb, 3); - ff_init_short_region(s, g); - } else { - int region_address1, region_address2; - g->block_type = 0; - g->switch_point = 0; - for (i = 0; i < 3; i++) - g->table_select[i] = get_bits(&s->gb, 5); - /* compute huffman coded region sizes */ - region_address1 = get_bits(&s->gb, 4); - region_address2 = get_bits(&s->gb, 3); - av_dlog(s->avctx, "region1=%d region2=%d\n", - region_address1, region_address2); - ff_init_long_region(s, g, region_address1, region_address2); - } - ff_region_offset2size(g); - ff_compute_band_indexes(s, g); - - g->preflag = 0; - if (!s->lsf) - g->preflag = get_bits1(&s->gb); - g->scalefac_scale = get_bits1(&s->gb); - g->count1table_select = get_bits1(&s->gb); - av_dlog(s->avctx, "block_type=%d switch_point=%d\n", - g->block_type, g->switch_point); - } - } - - if (!s->adu_mode) { - int skip; - const uint8_t *ptr = s->gb.buffer + (get_bits_count(&s->gb)>>3); - int extrasize = av_clip(get_bits_left(&s->gb) >> 3, 0, EXTRABYTES); - av_assert1((get_bits_count(&s->gb) & 7) == 0); - /* now we get bits from the main_data_begin offset */ - av_dlog(s->avctx, "seekback:%d, lastbuf:%d\n", - main_data_begin, s->last_buf_size); - - memcpy(s->last_buf + s->last_buf_size, ptr, extrasize); - s->in_gb = s->gb; - init_get_bits(&s->gb, s->last_buf, s->last_buf_size*8); -#if !UNCHECKED_BITSTREAM_READER - s->gb.size_in_bits_plus8 += FFMAX(extrasize, LAST_BUF_SIZE - s->last_buf_size) * 8; -#endif - s->last_buf_size <<= 3; - for (gr = 0; gr < nb_granules && (s->last_buf_size >> 3) < main_data_begin; gr++) { - for (ch = 0; ch < s->nb_channels; ch++) { - g = &s->granules[ch][gr]; - s->last_buf_size += g->part2_3_length; - memset(g->sb_hybrid, 0, sizeof(g->sb_hybrid)); - compute_imdct(s, g, &s->sb_samples[ch][18 * gr][0], s->mdct_buf[ch]); - } - } - skip = s->last_buf_size - 8 * main_data_begin; - if (skip >= s->gb.size_in_bits && s->in_gb.buffer) { - skip_bits_long(&s->in_gb, skip - s->gb.size_in_bits); - s->gb = s->in_gb; - s->in_gb.buffer = NULL; - } else { - skip_bits_long(&s->gb, skip); - } - } else { - gr = 0; - } - - for (; gr < nb_granules; gr++) { - for (ch = 0; ch < s->nb_channels; ch++) { - g = &s->granules[ch][gr]; - bits_pos = get_bits_count(&s->gb); - - if (!s->lsf) { - uint8_t *sc; - int slen, slen1, slen2; - - /* MPEG1 scale factors */ - slen1 = slen_table[0][g->scalefac_compress]; - slen2 = slen_table[1][g->scalefac_compress]; - av_dlog(s->avctx, "slen1=%d slen2=%d\n", slen1, slen2); - if (g->block_type == 2) { - n = g->switch_point ? 17 : 18; - j = 0; - if (slen1) { - for (i = 0; i < n; i++) - g->scale_factors[j++] = get_bits(&s->gb, slen1); - } else { - for (i = 0; i < n; i++) - g->scale_factors[j++] = 0; - } - if (slen2) { - for (i = 0; i < 18; i++) - g->scale_factors[j++] = get_bits(&s->gb, slen2); - for (i = 0; i < 3; i++) - g->scale_factors[j++] = 0; - } else { - for (i = 0; i < 21; i++) - g->scale_factors[j++] = 0; - } - } else { - sc = s->granules[ch][0].scale_factors; - j = 0; - for (k = 0; k < 4; k++) { - n = k == 0 ? 6 : 5; - if ((g->scfsi & (0x8 >> k)) == 0) { - slen = (k < 2) ? slen1 : slen2; - if (slen) { - for (i = 0; i < n; i++) - g->scale_factors[j++] = get_bits(&s->gb, slen); - } else { - for (i = 0; i < n; i++) - g->scale_factors[j++] = 0; - } - } else { - /* simply copy from last granule */ - for (i = 0; i < n; i++) { - g->scale_factors[j] = sc[j]; - j++; - } - } - } - g->scale_factors[j++] = 0; - } - } else { - int tindex, tindex2, slen[4], sl, sf; - - /* LSF scale factors */ - if (g->block_type == 2) - tindex = g->switch_point ? 2 : 1; - else - tindex = 0; - - sf = g->scalefac_compress; - if ((s->mode_ext & MODE_EXT_I_STEREO) && ch == 1) { - /* intensity stereo case */ - sf >>= 1; - if (sf < 180) { - lsf_sf_expand(slen, sf, 6, 6, 0); - tindex2 = 3; - } else if (sf < 244) { - lsf_sf_expand(slen, sf - 180, 4, 4, 0); - tindex2 = 4; - } else { - lsf_sf_expand(slen, sf - 244, 3, 0, 0); - tindex2 = 5; - } - } else { - /* normal case */ - if (sf < 400) { - lsf_sf_expand(slen, sf, 5, 4, 4); - tindex2 = 0; - } else if (sf < 500) { - lsf_sf_expand(slen, sf - 400, 5, 4, 0); - tindex2 = 1; - } else { - lsf_sf_expand(slen, sf - 500, 3, 0, 0); - tindex2 = 2; - g->preflag = 1; - } - } - - j = 0; - for (k = 0; k < 4; k++) { - n = lsf_nsf_table[tindex2][tindex][k]; - sl = slen[k]; - if (sl) { - for (i = 0; i < n; i++) - g->scale_factors[j++] = get_bits(&s->gb, sl); - } else { - for (i = 0; i < n; i++) - g->scale_factors[j++] = 0; - } - } - /* XXX: should compute exact size */ - for (; j < 40; j++) - g->scale_factors[j] = 0; - } - - exponents_from_scale_factors(s, g, exponents); - - /* read Huffman coded residue */ - huffman_decode(s, g, exponents, bits_pos + g->part2_3_length); - } /* ch */ - - if (s->mode == MPA_JSTEREO) - compute_stereo(s, &s->granules[0][gr], &s->granules[1][gr]); - - for (ch = 0; ch < s->nb_channels; ch++) { - g = &s->granules[ch][gr]; - - reorder_block(s, g); - compute_antialias(s, g); - compute_imdct(s, g, &s->sb_samples[ch][18 * gr][0], s->mdct_buf[ch]); - } - } /* gr */ - if (get_bits_count(&s->gb) < 0) - skip_bits_long(&s->gb, -get_bits_count(&s->gb)); - return nb_granules * 18; -} - -static int mp_decode_frame(MPADecodeContext *s, OUT_INT **samples, - const uint8_t *buf, int buf_size) -{ - int i, nb_frames, ch, ret; - OUT_INT *samples_ptr; - - init_get_bits(&s->gb, buf + HEADER_SIZE, (buf_size - HEADER_SIZE) * 8); - - /* skip error protection field */ - if (s->error_protection) - skip_bits(&s->gb, 16); - - switch(s->layer) { - case 1: - s->avctx->frame_size = 384; - nb_frames = mp_decode_layer1(s); - break; - case 2: - s->avctx->frame_size = 1152; - nb_frames = mp_decode_layer2(s); - break; - case 3: - s->avctx->frame_size = s->lsf ? 576 : 1152; - default: - nb_frames = mp_decode_layer3(s); - - s->last_buf_size=0; - if (s->in_gb.buffer) { - align_get_bits(&s->gb); - i = get_bits_left(&s->gb)>>3; - if (i >= 0 && i <= BACKSTEP_SIZE) { - memmove(s->last_buf, s->gb.buffer + (get_bits_count(&s->gb)>>3), i); - s->last_buf_size=i; - } else - av_log(s->avctx, AV_LOG_ERROR, "invalid old backstep %d\n", i); - s->gb = s->in_gb; - s->in_gb.buffer = NULL; - } - - align_get_bits(&s->gb); - av_assert1((get_bits_count(&s->gb) & 7) == 0); - i = get_bits_left(&s->gb) >> 3; - - if (i < 0 || i > BACKSTEP_SIZE || nb_frames < 0) { - if (i < 0) - av_log(s->avctx, AV_LOG_ERROR, "invalid new backstep %d\n", i); - i = FFMIN(BACKSTEP_SIZE, buf_size - HEADER_SIZE); - } - av_assert1(i <= buf_size - HEADER_SIZE && i >= 0); - memcpy(s->last_buf + s->last_buf_size, s->gb.buffer + buf_size - HEADER_SIZE - i, i); - s->last_buf_size += i; - } - - if(nb_frames < 0) - return nb_frames; - - /* get output buffer */ - if (!samples) { - av_assert0(s->frame != NULL); - s->frame->nb_samples = s->avctx->frame_size; - if ((ret = ff_get_buffer(s->avctx, s->frame, 0)) < 0) - return ret; - samples = (OUT_INT **)s->frame->extended_data; - } - - /* apply the synthesis filter */ - for (ch = 0; ch < s->nb_channels; ch++) { - int sample_stride; - if (s->avctx->sample_fmt == OUT_FMT_P) { - samples_ptr = samples[ch]; - sample_stride = 1; - } else { - samples_ptr = samples[0] + ch; - sample_stride = s->nb_channels; - } - for (i = 0; i < nb_frames; i++) { - RENAME(ff_mpa_synth_filter)(&s->mpadsp, s->synth_buf[ch], - &(s->synth_buf_offset[ch]), - RENAME(ff_mpa_synth_window), - &s->dither_state, samples_ptr, - sample_stride, s->sb_samples[ch][i]); - samples_ptr += 32 * sample_stride; - } - } - - return nb_frames * 32 * sizeof(OUT_INT) * s->nb_channels; -} - -static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame_ptr, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - MPADecodeContext *s = avctx->priv_data; - uint32_t header; - int ret; - - while(buf_size && !*buf){ - buf++; - buf_size--; - } - - if (buf_size < HEADER_SIZE) - return AVERROR_INVALIDDATA; - - header = AV_RB32(buf); - if (header>>8 == AV_RB32("TAG")>>8) { - av_log(avctx, AV_LOG_DEBUG, "discarding ID3 tag\n"); - return buf_size; - } - if (ff_mpa_check_header(header) < 0) { - av_log(avctx, AV_LOG_ERROR, "Header missing\n"); - return AVERROR_INVALIDDATA; - } - - if (avpriv_mpegaudio_decode_header((MPADecodeHeader *)s, header) == 1) { - /* free format: prepare to compute frame size */ - s->frame_size = -1; - return AVERROR_INVALIDDATA; - } - /* update codec info */ - avctx->channels = s->nb_channels; - avctx->channel_layout = s->nb_channels == 1 ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO; - if (!avctx->bit_rate) - avctx->bit_rate = s->bit_rate; - - if (s->frame_size <= 0 || s->frame_size > buf_size) { - av_log(avctx, AV_LOG_ERROR, "incomplete frame\n"); - return AVERROR_INVALIDDATA; - } else if (s->frame_size < buf_size) { - av_log(avctx, AV_LOG_DEBUG, "incorrect frame size - multiple frames in buffer?\n"); - buf_size= s->frame_size; - } - - s->frame = data; - - ret = mp_decode_frame(s, NULL, buf, buf_size); - if (ret >= 0) { - s->frame->nb_samples = avctx->frame_size; - *got_frame_ptr = 1; - avctx->sample_rate = s->sample_rate; - //FIXME maybe move the other codec info stuff from above here too - } else { - av_log(avctx, AV_LOG_ERROR, "Error while decoding MPEG audio frame.\n"); - /* Only return an error if the bad frame makes up the whole packet or - * the error is related to buffer management. - * If there is more data in the packet, just consume the bad frame - * instead of returning an error, which would discard the whole - * packet. */ - *got_frame_ptr = 0; - if (buf_size == avpkt->size || ret != AVERROR_INVALIDDATA) - return ret; - } - s->frame_size = 0; - return buf_size; -} - -static void mp_flush(MPADecodeContext *ctx) -{ - memset(ctx->synth_buf, 0, sizeof(ctx->synth_buf)); - ctx->last_buf_size = 0; -} - -static void flush(AVCodecContext *avctx) -{ - mp_flush(avctx->priv_data); -} - -#if CONFIG_MP3ADU_DECODER || CONFIG_MP3ADUFLOAT_DECODER -static int decode_frame_adu(AVCodecContext *avctx, void *data, - int *got_frame_ptr, AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - MPADecodeContext *s = avctx->priv_data; - uint32_t header; - int len, ret; - int av_unused out_size; - - len = buf_size; - - // Discard too short frames - if (buf_size < HEADER_SIZE) { - av_log(avctx, AV_LOG_ERROR, "Packet is too small\n"); - return AVERROR_INVALIDDATA; - } - - - if (len > MPA_MAX_CODED_FRAME_SIZE) - len = MPA_MAX_CODED_FRAME_SIZE; - - // Get header and restore sync word - header = AV_RB32(buf) | 0xffe00000; - - if (ff_mpa_check_header(header) < 0) { // Bad header, discard frame - av_log(avctx, AV_LOG_ERROR, "Invalid frame header\n"); - return AVERROR_INVALIDDATA; - } - - avpriv_mpegaudio_decode_header((MPADecodeHeader *)s, header); - /* update codec info */ - avctx->sample_rate = s->sample_rate; - avctx->channels = s->nb_channels; - if (!avctx->bit_rate) - avctx->bit_rate = s->bit_rate; - - s->frame_size = len; - - s->frame = data; - - ret = mp_decode_frame(s, NULL, buf, buf_size); - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "Error while decoding MPEG audio frame.\n"); - return ret; - } - - *got_frame_ptr = 1; - - return buf_size; -} -#endif /* CONFIG_MP3ADU_DECODER || CONFIG_MP3ADUFLOAT_DECODER */ - -#if CONFIG_MP3ON4_DECODER || CONFIG_MP3ON4FLOAT_DECODER - -/** - * Context for MP3On4 decoder - */ -typedef struct MP3On4DecodeContext { - int frames; ///< number of mp3 frames per block (number of mp3 decoder instances) - int syncword; ///< syncword patch - const uint8_t *coff; ///< channel offsets in output buffer - MPADecodeContext *mp3decctx[5]; ///< MPADecodeContext for every decoder instance -} MP3On4DecodeContext; - -#include "mpeg4audio.h" - -/* Next 3 arrays are indexed by channel config number (passed via codecdata) */ - -/* number of mp3 decoder instances */ -static const uint8_t mp3Frames[8] = { 0, 1, 1, 2, 3, 3, 4, 5 }; - -/* offsets into output buffer, assume output order is FL FR C LFE BL BR SL SR */ -static const uint8_t chan_offset[8][5] = { - { 0 }, - { 0 }, // C - { 0 }, // FLR - { 2, 0 }, // C FLR - { 2, 0, 3 }, // C FLR BS - { 2, 0, 3 }, // C FLR BLRS - { 2, 0, 4, 3 }, // C FLR BLRS LFE - { 2, 0, 6, 4, 3 }, // C FLR BLRS BLR LFE -}; - -/* mp3on4 channel layouts */ -static const int16_t chan_layout[8] = { - 0, - AV_CH_LAYOUT_MONO, - AV_CH_LAYOUT_STEREO, - AV_CH_LAYOUT_SURROUND, - AV_CH_LAYOUT_4POINT0, - AV_CH_LAYOUT_5POINT0, - AV_CH_LAYOUT_5POINT1, - AV_CH_LAYOUT_7POINT1 -}; - -static av_cold int decode_close_mp3on4(AVCodecContext * avctx) -{ - MP3On4DecodeContext *s = avctx->priv_data; - int i; - - for (i = 0; i < s->frames; i++) - av_free(s->mp3decctx[i]); - - return 0; -} - - -static int decode_init_mp3on4(AVCodecContext * avctx) -{ - MP3On4DecodeContext *s = avctx->priv_data; - MPEG4AudioConfig cfg; - int i; - - if ((avctx->extradata_size < 2) || (avctx->extradata == NULL)) { - av_log(avctx, AV_LOG_ERROR, "Codec extradata missing or too short.\n"); - return AVERROR_INVALIDDATA; - } - - avpriv_mpeg4audio_get_config(&cfg, avctx->extradata, - avctx->extradata_size * 8, 1); - if (!cfg.chan_config || cfg.chan_config > 7) { - av_log(avctx, AV_LOG_ERROR, "Invalid channel config number.\n"); - return AVERROR_INVALIDDATA; - } - s->frames = mp3Frames[cfg.chan_config]; - s->coff = chan_offset[cfg.chan_config]; - avctx->channels = ff_mpeg4audio_channels[cfg.chan_config]; - avctx->channel_layout = chan_layout[cfg.chan_config]; - - if (cfg.sample_rate < 16000) - s->syncword = 0xffe00000; - else - s->syncword = 0xfff00000; - - /* Init the first mp3 decoder in standard way, so that all tables get builded - * We replace avctx->priv_data with the context of the first decoder so that - * decode_init() does not have to be changed. - * Other decoders will be initialized here copying data from the first context - */ - // Allocate zeroed memory for the first decoder context - s->mp3decctx[0] = av_mallocz(sizeof(MPADecodeContext)); - if (!s->mp3decctx[0]) - goto alloc_fail; - // Put decoder context in place to make init_decode() happy - avctx->priv_data = s->mp3decctx[0]; - decode_init(avctx); - // Restore mp3on4 context pointer - avctx->priv_data = s; - s->mp3decctx[0]->adu_mode = 1; // Set adu mode - - /* Create a separate codec/context for each frame (first is already ok). - * Each frame is 1 or 2 channels - up to 5 frames allowed - */ - for (i = 1; i < s->frames; i++) { - s->mp3decctx[i] = av_mallocz(sizeof(MPADecodeContext)); - if (!s->mp3decctx[i]) - goto alloc_fail; - s->mp3decctx[i]->adu_mode = 1; - s->mp3decctx[i]->avctx = avctx; - s->mp3decctx[i]->mpadsp = s->mp3decctx[0]->mpadsp; - } - - return 0; -alloc_fail: - decode_close_mp3on4(avctx); - return AVERROR(ENOMEM); -} - - -static void flush_mp3on4(AVCodecContext *avctx) -{ - int i; - MP3On4DecodeContext *s = avctx->priv_data; - - for (i = 0; i < s->frames; i++) - mp_flush(s->mp3decctx[i]); -} - - -static int decode_frame_mp3on4(AVCodecContext *avctx, void *data, - int *got_frame_ptr, AVPacket *avpkt) -{ - AVFrame *frame = data; - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - MP3On4DecodeContext *s = avctx->priv_data; - MPADecodeContext *m; - int fsize, len = buf_size, out_size = 0; - uint32_t header; - OUT_INT **out_samples; - OUT_INT *outptr[2]; - int fr, ch, ret; - - /* get output buffer */ - frame->nb_samples = MPA_FRAME_SIZE; - if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) - return ret; - out_samples = (OUT_INT **)frame->extended_data; - - // Discard too short frames - if (buf_size < HEADER_SIZE) - return AVERROR_INVALIDDATA; - - avctx->bit_rate = 0; - - ch = 0; - for (fr = 0; fr < s->frames; fr++) { - fsize = AV_RB16(buf) >> 4; - fsize = FFMIN3(fsize, len, MPA_MAX_CODED_FRAME_SIZE); - m = s->mp3decctx[fr]; - av_assert1(m); - - if (fsize < HEADER_SIZE) { - av_log(avctx, AV_LOG_ERROR, "Frame size smaller than header size\n"); - return AVERROR_INVALIDDATA; - } - header = (AV_RB32(buf) & 0x000fffff) | s->syncword; // patch header - - if (ff_mpa_check_header(header) < 0) // Bad header, discard block - break; - - avpriv_mpegaudio_decode_header((MPADecodeHeader *)m, header); - - if (ch + m->nb_channels > avctx->channels || s->coff[fr] + m->nb_channels > avctx->channels) { - av_log(avctx, AV_LOG_ERROR, "frame channel count exceeds codec " - "channel count\n"); - return AVERROR_INVALIDDATA; - } - ch += m->nb_channels; - - outptr[0] = out_samples[s->coff[fr]]; - if (m->nb_channels > 1) - outptr[1] = out_samples[s->coff[fr] + 1]; - - if ((ret = mp_decode_frame(m, outptr, buf, fsize)) < 0) - return ret; - - out_size += ret; - buf += fsize; - len -= fsize; - - avctx->bit_rate += m->bit_rate; - } - - /* update codec info */ - avctx->sample_rate = s->mp3decctx[0]->sample_rate; - - frame->nb_samples = out_size / (avctx->channels * sizeof(OUT_INT)); - *got_frame_ptr = 1; - - return buf_size; -} -#endif /* CONFIG_MP3ON4_DECODER || CONFIG_MP3ON4FLOAT_DECODER */ - -#if !CONFIG_FLOAT -#if CONFIG_MP1_DECODER -AVCodec ff_mp1_decoder = { - .name = "mp1", - .type = AVMEDIA_TYPE_AUDIO, - .id = AV_CODEC_ID_MP1, - .priv_data_size = sizeof(MPADecodeContext), - .init = decode_init, - .decode = decode_frame, - .capabilities = CODEC_CAP_DR1, - .flush = flush, - .long_name = NULL_IF_CONFIG_SMALL("MP1 (MPEG audio layer 1)"), - .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, - AV_SAMPLE_FMT_S16, - AV_SAMPLE_FMT_NONE }, -}; -#endif -#if CONFIG_MP2_DECODER -AVCodec ff_mp2_decoder = { - .name = "mp2", - .type = AVMEDIA_TYPE_AUDIO, - .id = AV_CODEC_ID_MP2, - .priv_data_size = sizeof(MPADecodeContext), - .init = decode_init, - .decode = decode_frame, - .capabilities = CODEC_CAP_DR1, - .flush = flush, - .long_name = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"), - .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, - AV_SAMPLE_FMT_S16, - AV_SAMPLE_FMT_NONE }, -}; -#endif -#if CONFIG_MP3_DECODER -AVCodec ff_mp3_decoder = { - .name = "mp3", - .type = AVMEDIA_TYPE_AUDIO, - .id = AV_CODEC_ID_MP3, - .priv_data_size = sizeof(MPADecodeContext), - .init = decode_init, - .decode = decode_frame, - .capabilities = CODEC_CAP_DR1, - .flush = flush, - .long_name = NULL_IF_CONFIG_SMALL("MP3 (MPEG audio layer 3)"), - .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, - AV_SAMPLE_FMT_S16, - AV_SAMPLE_FMT_NONE }, -}; -#endif -#if CONFIG_MP3ADU_DECODER -AVCodec ff_mp3adu_decoder = { - .name = "mp3adu", - .type = AVMEDIA_TYPE_AUDIO, - .id = AV_CODEC_ID_MP3ADU, - .priv_data_size = sizeof(MPADecodeContext), - .init = decode_init, - .decode = decode_frame_adu, - .capabilities = CODEC_CAP_DR1, - .flush = flush, - .long_name = NULL_IF_CONFIG_SMALL("ADU (Application Data Unit) MP3 (MPEG audio layer 3)"), - .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, - AV_SAMPLE_FMT_S16, - AV_SAMPLE_FMT_NONE }, -}; -#endif -#if CONFIG_MP3ON4_DECODER -AVCodec ff_mp3on4_decoder = { - .name = "mp3on4", - .type = AVMEDIA_TYPE_AUDIO, - .id = AV_CODEC_ID_MP3ON4, - .priv_data_size = sizeof(MP3On4DecodeContext), - .init = decode_init_mp3on4, - .close = decode_close_mp3on4, - .decode = decode_frame_mp3on4, - .capabilities = CODEC_CAP_DR1, - .flush = flush_mp3on4, - .long_name = NULL_IF_CONFIG_SMALL("MP3onMP4"), - .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, - AV_SAMPLE_FMT_NONE }, -}; -#endif -#endif diff --git a/ffmpeg/libavcodec/mpegaudiodec_float.c b/ffmpeg/libavcodec/mpegaudiodec_float.c index 17a7757..35f07fa 100644 --- a/ffmpeg/libavcodec/mpegaudiodec_float.c +++ b/ffmpeg/libavcodec/mpegaudiodec_float.c @@ -19,12 +19,29 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#define CONFIG_FLOAT 1 -#include "mpegaudiodec.c" +#include "config.h" +#include "libavutil/samplefmt.h" + +#define USE_FLOATS 1 + +#include "mpegaudio.h" + +#define SHR(a,b) ((a)*(1.0f/(1<<(b)))) +#define FIXR_OLD(a) ((int)((a) * FRAC_ONE + 0.5)) +#define FIXR(x) ((float)(x)) +#define FIXHR(x) ((float)(x)) +#define MULH3(x, y, s) ((s)*(y)*(x)) +#define MULLx(x, y, s) ((y)*(x)) +#define RENAME(a) a ## _float +#define OUT_FMT AV_SAMPLE_FMT_FLT +#define OUT_FMT_P AV_SAMPLE_FMT_FLTP + +#include "mpegaudiodec_template.c" #if CONFIG_MP1FLOAT_DECODER AVCodec ff_mp1float_decoder = { .name = "mp1float", + .long_name = NULL_IF_CONFIG_SMALL("MP1 (MPEG audio layer 1)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_MP1, .priv_data_size = sizeof(MPADecodeContext), @@ -32,7 +49,6 @@ AVCodec ff_mp1float_decoder = { .decode = decode_frame, .capabilities = CODEC_CAP_DR1, .flush = flush, - .long_name = NULL_IF_CONFIG_SMALL("MP1 (MPEG audio layer 1)"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE }, @@ -41,6 +57,7 @@ AVCodec ff_mp1float_decoder = { #if CONFIG_MP2FLOAT_DECODER AVCodec ff_mp2float_decoder = { .name = "mp2float", + .long_name = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_MP2, .priv_data_size = sizeof(MPADecodeContext), @@ -48,7 +65,6 @@ AVCodec ff_mp2float_decoder = { .decode = decode_frame, .capabilities = CODEC_CAP_DR1, .flush = flush, - .long_name = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE }, @@ -57,6 +73,7 @@ AVCodec ff_mp2float_decoder = { #if CONFIG_MP3FLOAT_DECODER AVCodec ff_mp3float_decoder = { .name = "mp3float", + .long_name = NULL_IF_CONFIG_SMALL("MP3 (MPEG audio layer 3)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_MP3, .priv_data_size = sizeof(MPADecodeContext), @@ -64,7 +81,6 @@ AVCodec ff_mp3float_decoder = { .decode = decode_frame, .capabilities = CODEC_CAP_DR1, .flush = flush, - .long_name = NULL_IF_CONFIG_SMALL("MP3 (MPEG audio layer 3)"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE }, @@ -73,6 +89,7 @@ AVCodec ff_mp3float_decoder = { #if CONFIG_MP3ADUFLOAT_DECODER AVCodec ff_mp3adufloat_decoder = { .name = "mp3adufloat", + .long_name = NULL_IF_CONFIG_SMALL("ADU (Application Data Unit) MP3 (MPEG audio layer 3)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_MP3ADU, .priv_data_size = sizeof(MPADecodeContext), @@ -80,7 +97,6 @@ AVCodec ff_mp3adufloat_decoder = { .decode = decode_frame_adu, .capabilities = CODEC_CAP_DR1, .flush = flush, - .long_name = NULL_IF_CONFIG_SMALL("ADU (Application Data Unit) MP3 (MPEG audio layer 3)"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE }, @@ -89,6 +105,7 @@ AVCodec ff_mp3adufloat_decoder = { #if CONFIG_MP3ON4FLOAT_DECODER AVCodec ff_mp3on4float_decoder = { .name = "mp3on4float", + .long_name = NULL_IF_CONFIG_SMALL("MP3onMP4"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_MP3ON4, .priv_data_size = sizeof(MP3On4DecodeContext), @@ -97,7 +114,6 @@ AVCodec ff_mp3on4float_decoder = { .decode = decode_frame_mp3on4, .capabilities = CODEC_CAP_DR1, .flush = flush_mp3on4, - .long_name = NULL_IF_CONFIG_SMALL("MP3onMP4"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, }; diff --git a/ffmpeg/libavcodec/mpegaudiodecheader.c b/ffmpeg/libavcodec/mpegaudiodecheader.c index 7841b30..1772c2a 100644 --- a/ffmpeg/libavcodec/mpegaudiodecheader.c +++ b/ffmpeg/libavcodec/mpegaudiodecheader.c @@ -24,7 +24,6 @@ * MPEG Audio header decoder. */ -//#define DEBUG #include "avcodec.h" #include "mpegaudio.h" #include "mpegaudiodata.h" diff --git a/ffmpeg/libavcodec/mpegaudiodsp.c b/ffmpeg/libavcodec/mpegaudiodsp.c index aadc747..ddb7428 100644 --- a/ffmpeg/libavcodec/mpegaudiodsp.c +++ b/ffmpeg/libavcodec/mpegaudiodsp.c @@ -19,11 +19,12 @@ */ #include "config.h" +#include "libavutil/attributes.h" #include "mpegaudiodsp.h" #include "dct.h" #include "dct32.h" -void ff_mpadsp_init(MPADSPContext *s) +av_cold void ff_mpadsp_init(MPADSPContext *s) { DCTContext dct; @@ -41,8 +42,8 @@ void ff_mpadsp_init(MPADSPContext *s) s->imdct36_blocks_fixed = ff_imdct36_blocks_fixed; if (ARCH_ARM) ff_mpadsp_init_arm(s); + if (ARCH_PPC) ff_mpadsp_init_ppc(s); if (ARCH_X86) ff_mpadsp_init_x86(s); - if (HAVE_ALTIVEC) ff_mpadsp_init_altivec(s); if (HAVE_MIPSFPU) ff_mpadsp_init_mipsfpu(s); if (HAVE_MIPSDSPR1) ff_mpadsp_init_mipsdspr1(s); } diff --git a/ffmpeg/libavcodec/mpegaudiodsp.h b/ffmpeg/libavcodec/mpegaudiodsp.h index 623d2df..38c75c7 100644 --- a/ffmpeg/libavcodec/mpegaudiodsp.h +++ b/ffmpeg/libavcodec/mpegaudiodsp.h @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -56,8 +56,8 @@ void ff_mpa_synth_filter_float(MPADSPContext *s, float *sb_samples); void ff_mpadsp_init_arm(MPADSPContext *s); +void ff_mpadsp_init_ppc(MPADSPContext *s); void ff_mpadsp_init_x86(MPADSPContext *s); -void ff_mpadsp_init_altivec(MPADSPContext *s); void ff_mpadsp_init_mipsfpu(MPADSPContext *s); void ff_mpadsp_init_mipsdspr1(MPADSPContext *s); diff --git a/ffmpeg/libavcodec/mpegaudiodsp_fixed.c b/ffmpeg/libavcodec/mpegaudiodsp_fixed.c index 3c49a56..83c9d66 100644 --- a/ffmpeg/libavcodec/mpegaudiodsp_fixed.c +++ b/ffmpeg/libavcodec/mpegaudiodsp_fixed.c @@ -1,20 +1,20 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#define CONFIG_FLOAT 0 +#define USE_FLOATS 0 #include "mpegaudiodsp_template.c" diff --git a/ffmpeg/libavcodec/mpegaudiodsp_float.c b/ffmpeg/libavcodec/mpegaudiodsp_float.c index 2d8d53e..c45b136 100644 --- a/ffmpeg/libavcodec/mpegaudiodsp_float.c +++ b/ffmpeg/libavcodec/mpegaudiodsp_float.c @@ -1,20 +1,20 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#define CONFIG_FLOAT 1 +#define USE_FLOATS 1 #include "mpegaudiodsp_template.c" diff --git a/ffmpeg/libavcodec/mpegaudiodsp_template.c b/ffmpeg/libavcodec/mpegaudiodsp_template.c index 03a740a..62454ca 100644 --- a/ffmpeg/libavcodec/mpegaudiodsp_template.c +++ b/ffmpeg/libavcodec/mpegaudiodsp_template.c @@ -20,13 +20,14 @@ #include +#include "libavutil/attributes.h" #include "libavutil/mem.h" #include "dct32.h" #include "mathops.h" #include "mpegaudiodsp.h" #include "mpegaudio.h" -#if CONFIG_FLOAT +#if USE_FLOATS #define RENAME(n) n##_float static inline float round_sample(float *sum) @@ -124,7 +125,7 @@ void RENAME(ff_mpadsp_apply_window)(MPA_INT *synth_buf, MPA_INT *window, register const MPA_INT *w, *w2, *p; int j; OUT_INT *samples2; -#if CONFIG_FLOAT +#if USE_FLOATS float sum, sum2; #else int64_t sum, sum2; @@ -199,7 +200,7 @@ av_cold void RENAME(ff_mpa_synth_init)(MPA_INT *window) for(i=0;i<257;i++) { INTFLOAT v; v = ff_mpa_enwindow[i]; -#if CONFIG_FLOAT +#if USE_FLOATS v *= 1.0 / (1LL<<(16 + FRAC_BITS)); #endif window[i] = v; @@ -220,7 +221,7 @@ av_cold void RENAME(ff_mpa_synth_init)(MPA_INT *window) window[512+128+16*i+j] = window[64*i+48-j]; } -void RENAME(ff_init_mpadsp_tabs)(void) +av_cold void RENAME(ff_init_mpadsp_tabs)(void) { int i, j; /* compute mdct windows */ diff --git a/ffmpeg/libavcodec/mpegaudioenc.c b/ffmpeg/libavcodec/mpegaudioenc.c deleted file mode 100644 index 3a109f0..0000000 --- a/ffmpeg/libavcodec/mpegaudioenc.c +++ /dev/null @@ -1,788 +0,0 @@ -/* - * The simplest mpeg audio layer 2 encoder - * Copyright (c) 2000, 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * The simplest mpeg audio layer 2 encoder. - */ - -#include "libavutil/channel_layout.h" - -#include "avcodec.h" -#include "internal.h" -#include "put_bits.h" - -#define FRAC_BITS 15 /* fractional bits for sb_samples and dct */ -#define WFRAC_BITS 14 /* fractional bits for window */ - -#include "mpegaudio.h" -#include "mpegaudiodsp.h" - -/* currently, cannot change these constants (need to modify - quantization stage) */ -#define MUL(a,b) (((int64_t)(a) * (int64_t)(b)) >> FRAC_BITS) - -#define SAMPLES_BUF_SIZE 4096 - -typedef struct MpegAudioContext { - PutBitContext pb; - int nb_channels; - int lsf; /* 1 if mpeg2 low bitrate selected */ - int bitrate_index; /* bit rate */ - int freq_index; - int frame_size; /* frame size, in bits, without padding */ - /* padding computation */ - int frame_frac, frame_frac_incr, do_padding; - short samples_buf[MPA_MAX_CHANNELS][SAMPLES_BUF_SIZE]; /* buffer for filter */ - int samples_offset[MPA_MAX_CHANNELS]; /* offset in samples_buf */ - int sb_samples[MPA_MAX_CHANNELS][3][12][SBLIMIT]; - unsigned char scale_factors[MPA_MAX_CHANNELS][SBLIMIT][3]; /* scale factors */ - /* code to group 3 scale factors */ - unsigned char scale_code[MPA_MAX_CHANNELS][SBLIMIT]; - int sblimit; /* number of used subbands */ - const unsigned char *alloc_table; -} MpegAudioContext; - -/* define it to use floats in quantization (I don't like floats !) */ -#define USE_FLOATS - -#include "mpegaudiodata.h" -#include "mpegaudiotab.h" - -static av_cold int MPA_encode_init(AVCodecContext *avctx) -{ - MpegAudioContext *s = avctx->priv_data; - int freq = avctx->sample_rate; - int bitrate = avctx->bit_rate; - int channels = avctx->channels; - int i, v, table; - float a; - - if (channels <= 0 || channels > 2){ - av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed in mp2\n", channels); - return AVERROR(EINVAL); - } - bitrate = bitrate / 1000; - s->nb_channels = channels; - avctx->frame_size = MPA_FRAME_SIZE; - avctx->delay = 512 - 32 + 1; - - /* encoding freq */ - s->lsf = 0; - for(i=0;i<3;i++) { - if (avpriv_mpa_freq_tab[i] == freq) - break; - if ((avpriv_mpa_freq_tab[i] / 2) == freq) { - s->lsf = 1; - break; - } - } - if (i == 3){ - av_log(avctx, AV_LOG_ERROR, "Sampling rate %d is not allowed in mp2\n", freq); - return AVERROR(EINVAL); - } - s->freq_index = i; - - /* encoding bitrate & frequency */ - for(i=0;i<15;i++) { - if (avpriv_mpa_bitrate_tab[s->lsf][1][i] == bitrate) - break; - } - if (i == 15){ - av_log(avctx, AV_LOG_ERROR, "bitrate %d is not allowed in mp2\n", bitrate); - return AVERROR(EINVAL); - } - s->bitrate_index = i; - - /* compute total header size & pad bit */ - - a = (float)(bitrate * 1000 * MPA_FRAME_SIZE) / (freq * 8.0); - s->frame_size = ((int)a) * 8; - - /* frame fractional size to compute padding */ - s->frame_frac = 0; - s->frame_frac_incr = (int)((a - floor(a)) * 65536.0); - - /* select the right allocation table */ - table = ff_mpa_l2_select_table(bitrate, s->nb_channels, freq, s->lsf); - - /* number of used subbands */ - s->sblimit = ff_mpa_sblimit_table[table]; - s->alloc_table = ff_mpa_alloc_tables[table]; - - av_dlog(avctx, "%d kb/s, %d Hz, frame_size=%d bits, table=%d, padincr=%x\n", - bitrate, freq, s->frame_size, table, s->frame_frac_incr); - - for(i=0;inb_channels;i++) - s->samples_offset[i] = 0; - - for(i=0;i<257;i++) { - int v; - v = ff_mpa_enwindow[i]; -#if WFRAC_BITS != 16 - v = (v + (1 << (16 - WFRAC_BITS - 1))) >> (16 - WFRAC_BITS); -#endif - filter_bank[i] = v; - if ((i & 63) != 0) - v = -v; - if (i != 0) - filter_bank[512 - i] = v; - } - - for(i=0;i<64;i++) { - v = (int)(exp2((3 - i) / 3.0) * (1 << 20)); - if (v <= 0) - v = 1; - scale_factor_table[i] = v; -#ifdef USE_FLOATS - scale_factor_inv_table[i] = exp2(-(3 - i) / 3.0) / (float)(1 << 20); -#else -#define P 15 - scale_factor_shift[i] = 21 - P - (i / 3); - scale_factor_mult[i] = (1 << P) * exp2((i % 3) / 3.0); -#endif - } - for(i=0;i<128;i++) { - v = i - 64; - if (v <= -3) - v = 0; - else if (v < 0) - v = 1; - else if (v == 0) - v = 2; - else if (v < 3) - v = 3; - else - v = 4; - scale_diff_table[i] = v; - } - - for(i=0;i<17;i++) { - v = ff_mpa_quant_bits[i]; - if (v < 0) - v = -v; - else - v = v * 3; - total_quant_bits[i] = 12 * v; - } - - return 0; -} - -/* 32 point floating point IDCT without 1/sqrt(2) coef zero scaling */ -static void idct32(int *out, int *tab) -{ - int i, j; - int *t, *t1, xr; - const int *xp = costab32; - - for(j=31;j>=3;j-=2) tab[j] += tab[j - 2]; - - t = tab + 30; - t1 = tab + 2; - do { - t[0] += t[-4]; - t[1] += t[1 - 4]; - t -= 4; - } while (t != t1); - - t = tab + 28; - t1 = tab + 4; - do { - t[0] += t[-8]; - t[1] += t[1-8]; - t[2] += t[2-8]; - t[3] += t[3-8]; - t -= 8; - } while (t != t1); - - t = tab; - t1 = tab + 32; - do { - t[ 3] = -t[ 3]; - t[ 6] = -t[ 6]; - - t[11] = -t[11]; - t[12] = -t[12]; - t[13] = -t[13]; - t[15] = -t[15]; - t += 16; - } while (t != t1); - - - t = tab; - t1 = tab + 8; - do { - int x1, x2, x3, x4; - - x3 = MUL(t[16], FIX(SQRT2*0.5)); - x4 = t[0] - x3; - x3 = t[0] + x3; - - x2 = MUL(-(t[24] + t[8]), FIX(SQRT2*0.5)); - x1 = MUL((t[8] - x2), xp[0]); - x2 = MUL((t[8] + x2), xp[1]); - - t[ 0] = x3 + x1; - t[ 8] = x4 - x2; - t[16] = x4 + x2; - t[24] = x3 - x1; - t++; - } while (t != t1); - - xp += 2; - t = tab; - t1 = tab + 4; - do { - xr = MUL(t[28],xp[0]); - t[28] = (t[0] - xr); - t[0] = (t[0] + xr); - - xr = MUL(t[4],xp[1]); - t[ 4] = (t[24] - xr); - t[24] = (t[24] + xr); - - xr = MUL(t[20],xp[2]); - t[20] = (t[8] - xr); - t[ 8] = (t[8] + xr); - - xr = MUL(t[12],xp[3]); - t[12] = (t[16] - xr); - t[16] = (t[16] + xr); - t++; - } while (t != t1); - xp += 4; - - for (i = 0; i < 4; i++) { - xr = MUL(tab[30-i*4],xp[0]); - tab[30-i*4] = (tab[i*4] - xr); - tab[ i*4] = (tab[i*4] + xr); - - xr = MUL(tab[ 2+i*4],xp[1]); - tab[ 2+i*4] = (tab[28-i*4] - xr); - tab[28-i*4] = (tab[28-i*4] + xr); - - xr = MUL(tab[31-i*4],xp[0]); - tab[31-i*4] = (tab[1+i*4] - xr); - tab[ 1+i*4] = (tab[1+i*4] + xr); - - xr = MUL(tab[ 3+i*4],xp[1]); - tab[ 3+i*4] = (tab[29-i*4] - xr); - tab[29-i*4] = (tab[29-i*4] + xr); - - xp += 2; - } - - t = tab + 30; - t1 = tab + 1; - do { - xr = MUL(t1[0], *xp); - t1[0] = (t[0] - xr); - t[0] = (t[0] + xr); - t -= 2; - t1 += 2; - xp++; - } while (t >= tab); - - for(i=0;i<32;i++) { - out[i] = tab[bitinv32[i]]; - } -} - -#define WSHIFT (WFRAC_BITS + 15 - FRAC_BITS) - -static void filter(MpegAudioContext *s, int ch, const short *samples, int incr) -{ - short *p, *q; - int sum, offset, i, j; - int tmp[64]; - int tmp1[32]; - int *out; - - offset = s->samples_offset[ch]; - out = &s->sb_samples[ch][0][0][0]; - for(j=0;j<36;j++) { - /* 32 samples at once */ - for(i=0;i<32;i++) { - s->samples_buf[ch][offset + (31 - i)] = samples[0]; - samples += incr; - } - - /* filter */ - p = s->samples_buf[ch] + offset; - q = filter_bank; - /* maxsum = 23169 */ - for(i=0;i<64;i++) { - sum = p[0*64] * q[0*64]; - sum += p[1*64] * q[1*64]; - sum += p[2*64] * q[2*64]; - sum += p[3*64] * q[3*64]; - sum += p[4*64] * q[4*64]; - sum += p[5*64] * q[5*64]; - sum += p[6*64] * q[6*64]; - sum += p[7*64] * q[7*64]; - tmp[i] = sum; - p++; - q++; - } - tmp1[0] = tmp[16] >> WSHIFT; - for( i=1; i<=16; i++ ) tmp1[i] = (tmp[i+16]+tmp[16-i]) >> WSHIFT; - for( i=17; i<=31; i++ ) tmp1[i] = (tmp[i+16]-tmp[80-i]) >> WSHIFT; - - idct32(out, tmp1); - - /* advance of 32 samples */ - offset -= 32; - out += 32; - /* handle the wrap around */ - if (offset < 0) { - memmove(s->samples_buf[ch] + SAMPLES_BUF_SIZE - (512 - 32), - s->samples_buf[ch], (512 - 32) * 2); - offset = SAMPLES_BUF_SIZE - 512; - } - } - s->samples_offset[ch] = offset; -} - -static void compute_scale_factors(unsigned char scale_code[SBLIMIT], - unsigned char scale_factors[SBLIMIT][3], - int sb_samples[3][12][SBLIMIT], - int sblimit) -{ - int *p, vmax, v, n, i, j, k, code; - int index, d1, d2; - unsigned char *sf = &scale_factors[0][0]; - - for(j=0;j vmax) - vmax = v; - } - /* compute the scale factor index using log 2 computations */ - if (vmax > 1) { - n = av_log2(vmax); - /* n is the position of the MSB of vmax. now - use at most 2 compares to find the index */ - index = (21 - n) * 3 - 3; - if (index >= 0) { - while (vmax <= scale_factor_table[index+1]) - index++; - } else { - index = 0; /* very unlikely case of overflow */ - } - } else { - index = 62; /* value 63 is not allowed */ - } - - av_dlog(NULL, "%2d:%d in=%x %x %d\n", - j, i, vmax, scale_factor_table[index], index); - /* store the scale factor */ - av_assert2(index >=0 && index <= 63); - sf[i] = index; - } - - /* compute the transmission factor : look if the scale factors - are close enough to each other */ - d1 = scale_diff_table[sf[0] - sf[1] + 64]; - d2 = scale_diff_table[sf[1] - sf[2] + 64]; - - /* handle the 25 cases */ - switch(d1 * 5 + d2) { - case 0*5+0: - case 0*5+4: - case 3*5+4: - case 4*5+0: - case 4*5+4: - code = 0; - break; - case 0*5+1: - case 0*5+2: - case 4*5+1: - case 4*5+2: - code = 3; - sf[2] = sf[1]; - break; - case 0*5+3: - case 4*5+3: - code = 3; - sf[1] = sf[2]; - break; - case 1*5+0: - case 1*5+4: - case 2*5+4: - code = 1; - sf[1] = sf[0]; - break; - case 1*5+1: - case 1*5+2: - case 2*5+0: - case 2*5+1: - case 2*5+2: - code = 2; - sf[1] = sf[2] = sf[0]; - break; - case 2*5+3: - case 3*5+3: - code = 2; - sf[0] = sf[1] = sf[2]; - break; - case 3*5+0: - case 3*5+1: - case 3*5+2: - code = 2; - sf[0] = sf[2] = sf[1]; - break; - case 1*5+3: - code = 2; - if (sf[0] > sf[2]) - sf[0] = sf[2]; - sf[1] = sf[2] = sf[0]; - break; - default: - av_assert2(0); //cannot happen - code = 0; /* kill warning */ - } - - av_dlog(NULL, "%d: %2d %2d %2d %d %d -> %d\n", j, - sf[0], sf[1], sf[2], d1, d2, code); - scale_code[j] = code; - sf += 3; - } -} - -/* The most important function : psycho acoustic module. In this - encoder there is basically none, so this is the worst you can do, - but also this is the simpler. */ -static void psycho_acoustic_model(MpegAudioContext *s, short smr[SBLIMIT]) -{ - int i; - - for(i=0;isblimit;i++) { - smr[i] = (int)(fixed_smr[i] * 10); - } -} - - -#define SB_NOTALLOCATED 0 -#define SB_ALLOCATED 1 -#define SB_NOMORE 2 - -/* Try to maximize the smr while using a number of bits inferior to - the frame size. I tried to make the code simpler, faster and - smaller than other encoders :-) */ -static void compute_bit_allocation(MpegAudioContext *s, - short smr1[MPA_MAX_CHANNELS][SBLIMIT], - unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT], - int *padding) -{ - int i, ch, b, max_smr, max_ch, max_sb, current_frame_size, max_frame_size; - int incr; - short smr[MPA_MAX_CHANNELS][SBLIMIT]; - unsigned char subband_status[MPA_MAX_CHANNELS][SBLIMIT]; - const unsigned char *alloc; - - memcpy(smr, smr1, s->nb_channels * sizeof(short) * SBLIMIT); - memset(subband_status, SB_NOTALLOCATED, s->nb_channels * SBLIMIT); - memset(bit_alloc, 0, s->nb_channels * SBLIMIT); - - /* compute frame size and padding */ - max_frame_size = s->frame_size; - s->frame_frac += s->frame_frac_incr; - if (s->frame_frac >= 65536) { - s->frame_frac -= 65536; - s->do_padding = 1; - max_frame_size += 8; - } else { - s->do_padding = 0; - } - - /* compute the header + bit alloc size */ - current_frame_size = 32; - alloc = s->alloc_table; - for(i=0;isblimit;i++) { - incr = alloc[0]; - current_frame_size += incr * s->nb_channels; - alloc += 1 << incr; - } - for(;;) { - /* look for the subband with the largest signal to mask ratio */ - max_sb = -1; - max_ch = -1; - max_smr = INT_MIN; - for(ch=0;chnb_channels;ch++) { - for(i=0;isblimit;i++) { - if (smr[ch][i] > max_smr && subband_status[ch][i] != SB_NOMORE) { - max_smr = smr[ch][i]; - max_sb = i; - max_ch = ch; - } - } - } - if (max_sb < 0) - break; - av_dlog(NULL, "current=%d max=%d max_sb=%d max_ch=%d alloc=%d\n", - current_frame_size, max_frame_size, max_sb, max_ch, - bit_alloc[max_ch][max_sb]); - - /* find alloc table entry (XXX: not optimal, should use - pointer table) */ - alloc = s->alloc_table; - for(i=0;iscale_code[max_ch][max_sb]] * 6; - incr += total_quant_bits[alloc[1]]; - } else { - /* increments bit allocation */ - b = bit_alloc[max_ch][max_sb]; - incr = total_quant_bits[alloc[b + 1]] - - total_quant_bits[alloc[b]]; - } - - if (current_frame_size + incr <= max_frame_size) { - /* can increase size */ - b = ++bit_alloc[max_ch][max_sb]; - current_frame_size += incr; - /* decrease smr by the resolution we added */ - smr[max_ch][max_sb] = smr1[max_ch][max_sb] - quant_snr[alloc[b]]; - /* max allocation size reached ? */ - if (b == ((1 << alloc[0]) - 1)) - subband_status[max_ch][max_sb] = SB_NOMORE; - else - subband_status[max_ch][max_sb] = SB_ALLOCATED; - } else { - /* cannot increase the size of this subband */ - subband_status[max_ch][max_sb] = SB_NOMORE; - } - } - *padding = max_frame_size - current_frame_size; - av_assert0(*padding >= 0); -} - -/* - * Output the mpeg audio layer 2 frame. Note how the code is small - * compared to other encoders :-) - */ -static void encode_frame(MpegAudioContext *s, - unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT], - int padding) -{ - int i, j, k, l, bit_alloc_bits, b, ch; - unsigned char *sf; - int q[3]; - PutBitContext *p = &s->pb; - - /* header */ - - put_bits(p, 12, 0xfff); - put_bits(p, 1, 1 - s->lsf); /* 1 = mpeg1 ID, 0 = mpeg2 lsf ID */ - put_bits(p, 2, 4-2); /* layer 2 */ - put_bits(p, 1, 1); /* no error protection */ - put_bits(p, 4, s->bitrate_index); - put_bits(p, 2, s->freq_index); - put_bits(p, 1, s->do_padding); /* use padding */ - put_bits(p, 1, 0); /* private_bit */ - put_bits(p, 2, s->nb_channels == 2 ? MPA_STEREO : MPA_MONO); - put_bits(p, 2, 0); /* mode_ext */ - put_bits(p, 1, 0); /* no copyright */ - put_bits(p, 1, 1); /* original */ - put_bits(p, 2, 0); /* no emphasis */ - - /* bit allocation */ - j = 0; - for(i=0;isblimit;i++) { - bit_alloc_bits = s->alloc_table[j]; - for(ch=0;chnb_channels;ch++) { - put_bits(p, bit_alloc_bits, bit_alloc[ch][i]); - } - j += 1 << bit_alloc_bits; - } - - /* scale codes */ - for(i=0;isblimit;i++) { - for(ch=0;chnb_channels;ch++) { - if (bit_alloc[ch][i]) - put_bits(p, 2, s->scale_code[ch][i]); - } - } - - /* scale factors */ - for(i=0;isblimit;i++) { - for(ch=0;chnb_channels;ch++) { - if (bit_alloc[ch][i]) { - sf = &s->scale_factors[ch][i][0]; - switch(s->scale_code[ch][i]) { - case 0: - put_bits(p, 6, sf[0]); - put_bits(p, 6, sf[1]); - put_bits(p, 6, sf[2]); - break; - case 3: - case 1: - put_bits(p, 6, sf[0]); - put_bits(p, 6, sf[2]); - break; - case 2: - put_bits(p, 6, sf[0]); - break; - } - } - } - } - - /* quantization & write sub band samples */ - - for(k=0;k<3;k++) { - for(l=0;l<12;l+=3) { - j = 0; - for(i=0;isblimit;i++) { - bit_alloc_bits = s->alloc_table[j]; - for(ch=0;chnb_channels;ch++) { - b = bit_alloc[ch][i]; - if (b) { - int qindex, steps, m, sample, bits; - /* we encode 3 sub band samples of the same sub band at a time */ - qindex = s->alloc_table[j+b]; - steps = ff_mpa_quant_steps[qindex]; - for(m=0;m<3;m++) { - sample = s->sb_samples[ch][k][l + m][i]; - /* divide by scale factor */ -#ifdef USE_FLOATS - { - float a; - a = (float)sample * scale_factor_inv_table[s->scale_factors[ch][i][k]]; - q[m] = (int)((a + 1.0) * steps * 0.5); - } -#else - { - int q1, e, shift, mult; - e = s->scale_factors[ch][i][k]; - shift = scale_factor_shift[e]; - mult = scale_factor_mult[e]; - - /* normalize to P bits */ - if (shift < 0) - q1 = sample << (-shift); - else - q1 = sample >> shift; - q1 = (q1 * mult) >> P; - q[m] = ((q1 + (1 << P)) * steps) >> (P + 1); - } -#endif - if (q[m] >= steps) - q[m] = steps - 1; - av_assert2(q[m] >= 0 && q[m] < steps); - } - bits = ff_mpa_quant_bits[qindex]; - if (bits < 0) { - /* group the 3 values to save bits */ - put_bits(p, -bits, - q[0] + steps * (q[1] + steps * q[2])); - } else { - put_bits(p, bits, q[0]); - put_bits(p, bits, q[1]); - put_bits(p, bits, q[2]); - } - } - } - /* next subband in alloc table */ - j += 1 << bit_alloc_bits; - } - } - } - - /* padding */ - for(i=0;ipriv_data; - const int16_t *samples = (const int16_t *)frame->data[0]; - short smr[MPA_MAX_CHANNELS][SBLIMIT]; - unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT]; - int padding, i, ret; - - for(i=0;inb_channels;i++) { - filter(s, i, samples + i, s->nb_channels); - } - - for(i=0;inb_channels;i++) { - compute_scale_factors(s->scale_code[i], s->scale_factors[i], - s->sb_samples[i], s->sblimit); - } - for(i=0;inb_channels;i++) { - psycho_acoustic_model(s, smr[i]); - } - compute_bit_allocation(s, smr, bit_alloc, &padding); - - if ((ret = ff_alloc_packet2(avctx, avpkt, MPA_MAX_CODED_FRAME_SIZE)) < 0) - return ret; - - init_put_bits(&s->pb, avpkt->data, avpkt->size); - - encode_frame(s, bit_alloc, padding); - - if (frame->pts != AV_NOPTS_VALUE) - avpkt->pts = frame->pts - ff_samples_to_time_base(avctx, avctx->delay); - - avpkt->size = put_bits_count(&s->pb) / 8; - *got_packet_ptr = 1; - return 0; -} - -static const AVCodecDefault mp2_defaults[] = { - { "b", "128k" }, - { NULL }, -}; - -AVCodec ff_mp2_encoder = { - .name = "mp2", - .type = AVMEDIA_TYPE_AUDIO, - .id = AV_CODEC_ID_MP2, - .priv_data_size = sizeof(MpegAudioContext), - .init = MPA_encode_init, - .encode2 = MPA_encode_frame, - .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, - AV_SAMPLE_FMT_NONE }, - .supported_samplerates = (const int[]){ - 44100, 48000, 32000, 22050, 24000, 16000, 0 - }, - .channel_layouts = (const uint64_t[]){ AV_CH_LAYOUT_MONO, - AV_CH_LAYOUT_STEREO, - 0 }, - .long_name = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"), - .defaults = mp2_defaults, -}; diff --git a/ffmpeg/libavcodec/mpegaudiotab.h b/ffmpeg/libavcodec/mpegaudiotab.h index 35129e6..42d42d8 100644 --- a/ffmpeg/libavcodec/mpegaudiotab.h +++ b/ffmpeg/libavcodec/mpegaudiotab.h @@ -79,20 +79,6 @@ static const int bitinv32[32] = { }; -static int16_t filter_bank[512]; - -static int scale_factor_table[64]; -#ifdef USE_FLOATS -static float scale_factor_inv_table[64]; -#else -static int8_t scale_factor_shift[64]; -static unsigned short scale_factor_mult[64]; -#endif -static unsigned char scale_diff_table[128]; - -/* total number of bits per allocation group */ -static unsigned short total_quant_bits[17]; - /* signal to noise ratio of each quantification step (could be computed from quant_steps[]). The values are dB multiplied by 10 */ diff --git a/ffmpeg/libavcodec/mpegvideo.c b/ffmpeg/libavcodec/mpegvideo.c index 46f829c..cf71784 100644 --- a/ffmpeg/libavcodec/mpegvideo.c +++ b/ffmpeg/libavcodec/mpegvideo.c @@ -27,8 +27,10 @@ * The simplest mpeg encoder (well, it was the simplest!). */ +#include "libavutil/attributes.h" #include "libavutil/avassert.h" #include "libavutil/imgutils.h" +#include "libavutil/internal.h" #include "avcodec.h" #include "dsputil.h" #include "h264chroma.h" @@ -37,13 +39,9 @@ #include "mpegvideo.h" #include "mjpegenc.h" #include "msmpeg4.h" -#include "xvmc_internal.h" #include "thread.h" #include -//#undef NDEBUG -//#include - static void dct_unquantize_mpeg1_intra_c(MpegEncContext *s, int16_t *block, int n, int qscale); static void dct_unquantize_mpeg1_inter_c(MpegEncContext *s, @@ -59,10 +57,6 @@ static void dct_unquantize_h263_intra_c(MpegEncContext *s, static void dct_unquantize_h263_inter_c(MpegEncContext *s, int16_t *block, int n, int qscale); - -//#define DEBUG - - static const uint8_t ff_default_chroma_qscale_table[32] = { // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -152,43 +146,11 @@ static void mpeg_er_decode_mb(void *opaque, int ref, int mv_dir, int mv_type, s->dest[1] = s->current_picture.f.data[1] + (s->mb_y * (16 >> s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16 >> s->chroma_x_shift); s->dest[2] = s->current_picture.f.data[2] + (s->mb_y * (16 >> s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16 >> s->chroma_x_shift); - assert(ref == 0); + if (ref) + av_log(s->avctx, AV_LOG_DEBUG, "Interlaced error concealment is not fully implemented\n"); ff_MPV_decode_mb(s, s->block); } -const uint8_t *avpriv_mpv_find_start_code(const uint8_t *av_restrict p, - const uint8_t *end, - uint32_t *av_restrict state) -{ - int i; - - assert(p <= end); - if (p >= end) - return end; - - for (i = 0; i < 3; i++) { - uint32_t tmp = *state << 8; - *state = tmp + *(p++); - if (tmp == 0x100 || p == end) - return p; - } - - while (p < end) { - if (p[-1] > 1 ) p += 3; - else if (p[-2] ) p += 2; - else if (p[-3]|(p[-1]-1)) p++; - else { - p++; - break; - } - } - - p = FFMIN(p, end) - 4; - *state = AV_RB32(p); - - return p + 4; -} - /* init common dct for both encoder and decoder */ av_cold int ff_dct_common_init(MpegEncContext *s) { @@ -206,17 +168,16 @@ av_cold int ff_dct_common_init(MpegEncContext *s) s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_bitexact; s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_c; -#if ARCH_X86 - ff_MPV_common_init_x86(s); -#elif ARCH_ALPHA - ff_MPV_common_init_axp(s); -#elif ARCH_ARM - ff_MPV_common_init_arm(s); -#elif HAVE_ALTIVEC - ff_MPV_common_init_altivec(s); -#elif ARCH_BFIN - ff_MPV_common_init_bfin(s); -#endif + if (ARCH_ALPHA) + ff_MPV_common_init_axp(s); + if (ARCH_ARM) + ff_MPV_common_init_arm(s); + if (ARCH_BFIN) + ff_MPV_common_init_bfin(s); + if (ARCH_PPC) + ff_MPV_common_init_ppc(s); + if (ARCH_X86) + ff_MPV_common_init_x86(s); /* load & permutate scantables * note: only wmv uses different ones @@ -234,7 +195,7 @@ av_cold int ff_dct_common_init(MpegEncContext *s) return 0; } -int ff_mpv_frame_size_alloc(MpegEncContext *s, int linesize) +static int frame_size_alloc(MpegEncContext *s, int linesize) { int alloc_size = FFALIGN(FFABS(linesize) + 64, 32); @@ -279,7 +240,7 @@ static int alloc_frame_buffer(MpegEncContext *s, Picture *pic) r = avcodec_default_get_buffer2(s->avctx, &pic->f, 0); } - if (r < 0 || !pic->f.data[0]) { + if (r < 0 || !pic->f.buf[0]) { av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (%d %p)\n", r, pic->f.data[0]); return -1; @@ -313,7 +274,7 @@ static int alloc_frame_buffer(MpegEncContext *s, Picture *pic) } if (!s->edge_emu_buffer && - (ret = ff_mpv_frame_size_alloc(s, pic->f.linesize[0])) < 0) { + (ret = frame_size_alloc(s, pic->f.linesize[0])) < 0) { av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed to allocate context scratch buffers.\n"); ff_mpeg_unref_picture(s, pic); @@ -323,10 +284,13 @@ static int alloc_frame_buffer(MpegEncContext *s, Picture *pic) return 0; } -static void free_picture_tables(Picture *pic) +void ff_free_picture_tables(Picture *pic) { int i; + pic->alloc_mb_width = + pic->alloc_mb_height = 0; + av_buffer_unref(&pic->mb_var_buf); av_buffer_unref(&pic->mc_mb_var_buf); av_buffer_unref(&pic->mb_mean_buf); @@ -363,8 +327,7 @@ static int alloc_picture_tables(MpegEncContext *s, Picture *pic) return AVERROR(ENOMEM); } - if (s->out_format == FMT_H263 || s->encoding || - (s->avctx->debug & FF_DEBUG_MV) || s->avctx->debug_mv) { + if (s->out_format == FMT_H263 || s->encoding || s->avctx->debug_mv) { int mv_size = 2 * (b8_array_size + 4) * sizeof(int16_t); int ref_index_size = 4 * mb_array_size; @@ -376,6 +339,9 @@ static int alloc_picture_tables(MpegEncContext *s, Picture *pic) } } + pic->alloc_mb_width = s->mb_width; + pic->alloc_mb_height = s->mb_height; + return 0; } @@ -413,15 +379,15 @@ int ff_alloc_picture(MpegEncContext *s, Picture *pic, int shared) int i, ret; if (pic->qscale_table_buf) - if (pic->mbskip_table_buf->size < s->mb_stride * s->mb_height + 2 || - pic->qscale_table_buf->size < s->mb_stride * (s->mb_height + 1) + 1 + s->mb_stride) - free_picture_tables(pic); + if ( pic->alloc_mb_width != s->mb_width + || pic->alloc_mb_height != s->mb_height) + ff_free_picture_tables(pic); if (shared) { - assert(pic->f.data[0]); + av_assert0(pic->f.data[0]); pic->shared = 1; } else { - assert(!pic->f.data[0]); + av_assert0(!pic->f.buf[0]); if (alloc_frame_buffer(s, pic) < 0) return -1; @@ -458,7 +424,7 @@ int ff_alloc_picture(MpegEncContext *s, Picture *pic, int shared) fail: av_log(s->avctx, AV_LOG_ERROR, "Error allocating a picture.\n"); ff_mpeg_unref_picture(s, pic); - free_picture_tables(pic); + ff_free_picture_tables(pic); return AVERROR(ENOMEM); } @@ -468,7 +434,6 @@ fail: void ff_mpeg_unref_picture(MpegEncContext *s, Picture *pic) { int off = offsetof(Picture, mb_mean) + sizeof(pic->mb_mean); - pic->period_since_free = 0; pic->tf.f = &pic->f; /* WM Image / Screen codecs allocate internal buffers with different @@ -482,6 +447,9 @@ void ff_mpeg_unref_picture(MpegEncContext *s, Picture *pic) av_buffer_unref(&pic->hwaccel_priv_buf); + if (pic->needs_realloc) + ff_free_picture_tables(pic); + memset((uint8_t*)pic + off, 0, sizeof(*pic) - off); } @@ -496,7 +464,7 @@ do {\ av_buffer_unref(&dst->table);\ dst->table = av_buffer_ref(src->table);\ if (!dst->table) {\ - free_picture_tables(dst);\ + ff_free_picture_tables(dst);\ return AVERROR(ENOMEM);\ }\ }\ @@ -524,6 +492,9 @@ do {\ dst->ref_index[i] = src->ref_index[i]; } + dst->alloc_mb_width = src->alloc_mb_width; + dst->alloc_mb_height = src->alloc_mb_height; + return 0; } @@ -565,6 +536,15 @@ fail: return ret; } +static void exchange_uv(MpegEncContext *s) +{ + int16_t (*tmp)[64]; + + tmp = s->pblocks[4]; + s->pblocks[4] = s->pblocks[5]; + s->pblocks[5] = tmp; +} + static int init_duplicate_context(MpegEncContext *s) { int y_size = s->b8_stride * (2 * s->mb_height + 1); @@ -595,6 +575,8 @@ static int init_duplicate_context(MpegEncContext *s) for (i = 0; i < 12; i++) { s->pblocks[i] = &s->block[i]; } + if (s->avctx->codec_tag == AV_RL32("VCR2")) + exchange_uv(s); if (s->out_format == FMT_H263) { /* ac values */ @@ -669,8 +651,10 @@ int ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src) for (i = 0; i < 12; i++) { dst->pblocks[i] = &dst->block[i]; } + if (dst->avctx->codec_tag == AV_RL32("VCR2")) + exchange_uv(dst); if (!dst->edge_emu_buffer && - (ret = ff_mpv_frame_size_alloc(dst, dst->linesize)) < 0) { + (ret = frame_size_alloc(dst, dst->linesize)) < 0) { av_log(dst->avctx, AV_LOG_ERROR, "failed to allocate context " "scratch buffers.\n"); return ret; @@ -726,21 +710,20 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst, s->coded_picture_number = s1->coded_picture_number; s->picture_number = s1->picture_number; - s->input_picture_number = s1->input_picture_number; av_assert0(!s->picture || s->picture != s1->picture); + if(s->picture) for (i = 0; i < MAX_PICTURE_COUNT; i++) { ff_mpeg_unref_picture(s, &s->picture[i]); - if (s1->picture[i].f.data[0] && + if (s1->picture[i].f.buf[0] && (ret = ff_mpeg_ref_picture(s, &s->picture[i], &s1->picture[i])) < 0) return ret; - s->picture[i].period_since_free ++; } #define UPDATE_PICTURE(pic)\ do {\ ff_mpeg_unref_picture(s, &s->pic);\ - if (s1->pic.f.data[0])\ + if (s1->pic.f.buf[0])\ ret = ff_mpeg_ref_picture(s, &s->pic, &s1->pic);\ else\ ret = update_picture_tables(&s->pic, &s1->pic);\ @@ -762,8 +745,9 @@ do {\ s->padding_bug_score = s1->padding_bug_score; // MPEG4 timing info - memcpy(&s->time_increment_bits, &s1->time_increment_bits, - (char *) &s1->shape - (char *) &s1->time_increment_bits); + memcpy(&s->last_time_base, &s1->last_time_base, + (char *) &s1->pb_field_time + sizeof(s1->pb_field_time) - + (char *) &s1->last_time_base); // B-frame info s->max_b_frames = s1->max_b_frames; @@ -789,7 +773,7 @@ do {\ // linesize dependend scratch buffer allocation if (!s->edge_emu_buffer) if (s1->linesize) { - if (ff_mpv_frame_size_alloc(s, s1->linesize) < 0) { + if (frame_size_alloc(s, s1->linesize) < 0) { av_log(s->avctx, AV_LOG_ERROR, "Failed to allocate context " "scratch buffers.\n"); return AVERROR(ENOMEM); @@ -807,10 +791,6 @@ do {\ s->last_pict_type = s1->pict_type; if (s1->current_picture_ptr) s->last_lambda_for[s1->pict_type] = s1->current_picture_ptr->f.quality; - - if (s1->pict_type != AV_PICTURE_TYPE_B) { - s->last_non_b_pict_type = s1->pict_type; - } } return 0; @@ -833,9 +813,6 @@ void ff_MPV_common_defaults(MpegEncContext *s) s->coded_picture_number = 0; s->picture_number = 0; - s->input_picture_number = 0; - - s->picture_in_gop_number = 0; s->f_code = 1; s->b_code = 1; @@ -1057,47 +1034,26 @@ av_cold int ff_MPV_common_init(MpegEncContext *s) s->flags2 = s->avctx->flags2; /* set chroma shifts */ - avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &s->chroma_x_shift, &s->chroma_y_shift); + avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, + &s->chroma_x_shift, + &s->chroma_y_shift); /* convert fourcc to upper case */ - s->codec_tag = avpriv_toupper4(s->avctx->codec_tag); - s->stream_codec_tag = avpriv_toupper4(s->avctx->stream_codec_tag); - - s->avctx->coded_frame = &s->current_picture.f; - - if (s->encoding) { - if (s->msmpeg4_version) { - FF_ALLOCZ_OR_GOTO(s->avctx, s->ac_stats, - 2 * 2 * (MAX_LEVEL + 1) * - (MAX_RUN + 1) * 2 * sizeof(int), fail); - } - FF_ALLOCZ_OR_GOTO(s->avctx, s->avctx->stats_out, 256, fail); + s->codec_tag = avpriv_toupper4(s->avctx->codec_tag); - FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix, 64 * 32 * sizeof(int), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->q_chroma_intra_matrix, 64 * 32 * sizeof(int), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix, 64 * 32 * sizeof(int), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix16, 64 * 32 * 2 * sizeof(uint16_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->q_chroma_intra_matrix16, 64 * 32 * 2 * sizeof(uint16_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix16, 64 * 32 * 2 * sizeof(uint16_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->input_picture, MAX_PICTURE_COUNT * sizeof(Picture *), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->reordered_input_picture, MAX_PICTURE_COUNT * sizeof(Picture *), fail) - - if (s->avctx->noise_reduction) { - FF_ALLOCZ_OR_GOTO(s->avctx, s->dct_offset, 2 * 64 * sizeof(uint16_t), fail); - } - } + s->stream_codec_tag = avpriv_toupper4(s->avctx->stream_codec_tag); FF_ALLOCZ_OR_GOTO(s->avctx, s->picture, MAX_PICTURE_COUNT * sizeof(Picture), fail); for (i = 0; i < MAX_PICTURE_COUNT; i++) { - avcodec_get_frame_defaults(&s->picture[i].f); + av_frame_unref(&s->picture[i].f); } memset(&s->next_picture, 0, sizeof(s->next_picture)); memset(&s->last_picture, 0, sizeof(s->last_picture)); memset(&s->current_picture, 0, sizeof(s->current_picture)); - avcodec_get_frame_defaults(&s->next_picture.f); - avcodec_get_frame_defaults(&s->last_picture.f); - avcodec_get_frame_defaults(&s->current_picture.f); + av_frame_unref(&s->next_picture.f); + av_frame_unref(&s->last_picture.f); + av_frame_unref(&s->current_picture.f); if (init_context_frame(s)) goto fail; @@ -1251,7 +1207,8 @@ int ff_MPV_common_frame_size_change(MpegEncContext *s) (s->mb_height * (i + 1) + nb_slices / 2) / nb_slices; } } else { - if (init_duplicate_context(s) < 0) + err = init_duplicate_context(s); + if (err < 0) goto fail; s->start_mb_y = 0; s->end_mb_y = s->mb_height; @@ -1286,36 +1243,19 @@ void ff_MPV_common_end(MpegEncContext *s) av_freep(&s->bitstream_buffer); s->allocated_bitstream_buffer_size = 0; - av_freep(&s->avctx->stats_out); - av_freep(&s->ac_stats); - - if(s->q_chroma_intra_matrix != s->q_intra_matrix ) av_freep(&s->q_chroma_intra_matrix); - if(s->q_chroma_intra_matrix16 != s->q_intra_matrix16) av_freep(&s->q_chroma_intra_matrix16); - s->q_chroma_intra_matrix= NULL; - s->q_chroma_intra_matrix16= NULL; - av_freep(&s->q_intra_matrix); - av_freep(&s->q_inter_matrix); - av_freep(&s->q_intra_matrix16); - av_freep(&s->q_inter_matrix16); - av_freep(&s->input_picture); - av_freep(&s->reordered_input_picture); - av_freep(&s->dct_offset); - if (s->picture) { for (i = 0; i < MAX_PICTURE_COUNT; i++) { - free_picture_tables(&s->picture[i]); + ff_free_picture_tables(&s->picture[i]); ff_mpeg_unref_picture(s, &s->picture[i]); } } av_freep(&s->picture); - free_picture_tables(&s->last_picture); + ff_free_picture_tables(&s->last_picture); ff_mpeg_unref_picture(s, &s->last_picture); - free_picture_tables(&s->current_picture); + ff_free_picture_tables(&s->current_picture); ff_mpeg_unref_picture(s, &s->current_picture); - free_picture_tables(&s->next_picture); + ff_free_picture_tables(&s->next_picture); ff_mpeg_unref_picture(s, &s->next_picture); - free_picture_tables(&s->new_picture); - ff_mpeg_unref_picture(s, &s->new_picture); free_context_frame(s); @@ -1326,8 +1266,8 @@ void ff_MPV_common_end(MpegEncContext *s) s->linesize = s->uvlinesize = 0; } -void ff_init_rl(RLTable *rl, - uint8_t static_store[2][2 * MAX_RUN + MAX_LEVEL + 3]) +av_cold void ff_init_rl(RLTable *rl, + uint8_t static_store[2][2 * MAX_RUN + MAX_LEVEL + 3]) { int8_t max_level[MAX_RUN + 1], max_run[MAX_LEVEL + 1]; uint8_t index_run[MAX_RUN + 1]; @@ -1378,7 +1318,7 @@ void ff_init_rl(RLTable *rl, } } -void ff_init_vlc_rl(RLTable *rl) +av_cold void ff_init_vlc_rl(RLTable *rl) { int i, q; @@ -1418,28 +1358,22 @@ void ff_init_vlc_rl(RLTable *rl) } } -void ff_release_unused_pictures(MpegEncContext*s, int remove_current) +static void release_unused_pictures(MpegEncContext *s) { int i; /* release non reference frames */ for (i = 0; i < MAX_PICTURE_COUNT; i++) { - if (!s->picture[i].reference && - (remove_current || &s->picture[i] != s->current_picture_ptr)) { + if (!s->picture[i].reference) ff_mpeg_unref_picture(s, &s->picture[i]); - } } } static inline int pic_is_unused(MpegEncContext *s, Picture *pic) { - if ( (s->avctx->active_thread_type & FF_THREAD_FRAME) - && pic->f.qscale_table //check if the frame has anything allocated - && pic->period_since_free < s->avctx->thread_count) - return 0; if (pic == s->last_picture_ptr) return 0; - if (pic->f.data[0] == NULL) + if (pic->f.buf[0] == NULL) return 1; if (pic->needs_realloc && !(pic->reference & DELAYED_PIC_REF)) return 1; @@ -1452,7 +1386,7 @@ static int find_unused_picture(MpegEncContext *s, int shared) if (shared) { for (i = 0; i < MAX_PICTURE_COUNT; i++) { - if (s->picture[i].f.data[0] == NULL && &s->picture[i] != s->last_picture_ptr) + if (s->picture[i].f.buf[0] == NULL && &s->picture[i] != s->last_picture_ptr) return i; } } else { @@ -1486,9 +1420,8 @@ int ff_find_unused_picture(MpegEncContext *s, int shared) if (ret >= 0 && ret < MAX_PICTURE_COUNT) { if (s->picture[ret].needs_realloc) { s->picture[ret].needs_realloc = 0; - free_picture_tables(&s->picture[ret]); + ff_free_picture_tables(&s->picture[ret]); ff_mpeg_unref_picture(s, &s->picture[ret]); - avcodec_get_frame_defaults(&s->picture[ret].f); } } return ret; @@ -1533,7 +1466,7 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) /* mark & release old frames */ if (s->pict_type != AV_PICTURE_TYPE_B && s->last_picture_ptr && s->last_picture_ptr != s->next_picture_ptr && - s->last_picture_ptr->f.data[0]) { + s->last_picture_ptr->f.buf[0]) { ff_mpeg_unref_picture(s, s->last_picture_ptr); } @@ -1552,11 +1485,13 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) } } + ff_mpeg_unref_picture(s, &s->current_picture); + if (!s->encoding) { - ff_release_unused_pictures(s, 1); + release_unused_pictures(s); if (s->current_picture_ptr && - s->current_picture_ptr->f.data[0] == NULL) { + s->current_picture_ptr->f.buf[0] == NULL) { // we already have a unused image // (maybe it was set before reading the header) pic = s->current_picture_ptr; @@ -1599,7 +1534,6 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) // s->current_picture_ptr->quality = s->new_picture_ptr->quality; s->current_picture_ptr->f.key_frame = s->pict_type == AV_PICTURE_TYPE_I; - ff_mpeg_unref_picture(s, &s->current_picture); if ((ret = ff_mpeg_ref_picture(s, &s->current_picture, s->current_picture_ptr)) < 0) return ret; @@ -1617,17 +1551,20 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) s->pict_type, s->droppable); if ((s->last_picture_ptr == NULL || - s->last_picture_ptr->f.data[0] == NULL) && + s->last_picture_ptr->f.buf[0] == NULL) && (s->pict_type != AV_PICTURE_TYPE_I || s->picture_structure != PICT_FRAME)) { int h_chroma_shift, v_chroma_shift; av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt, &h_chroma_shift, &v_chroma_shift); - if (s->pict_type != AV_PICTURE_TYPE_I) + if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture_ptr && s->next_picture_ptr->f.buf[0]) + av_log(avctx, AV_LOG_DEBUG, + "allocating dummy last picture for B frame\n"); + else if (s->pict_type != AV_PICTURE_TYPE_I) av_log(avctx, AV_LOG_ERROR, "warning: first frame is no keyframe\n"); else if (s->picture_structure != PICT_FRAME) - av_log(avctx, AV_LOG_INFO, + av_log(avctx, AV_LOG_DEBUG, "allocate dummy last picture for field based first keyframe\n"); /* Allocate a dummy frame */ @@ -1661,7 +1598,7 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) ff_thread_report_progress(&s->last_picture_ptr->tf, INT_MAX, 1); } if ((s->next_picture_ptr == NULL || - s->next_picture_ptr->f.data[0] == NULL) && + s->next_picture_ptr->f.buf[0] == NULL) && s->pict_type == AV_PICTURE_TYPE_B) { /* Allocate a dummy frame */ i = ff_find_unused_picture(s, 0); @@ -1685,21 +1622,21 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) #endif if (s->last_picture_ptr) { ff_mpeg_unref_picture(s, &s->last_picture); - if (s->last_picture_ptr->f.data[0] && + if (s->last_picture_ptr->f.buf[0] && (ret = ff_mpeg_ref_picture(s, &s->last_picture, s->last_picture_ptr)) < 0) return ret; } if (s->next_picture_ptr) { ff_mpeg_unref_picture(s, &s->next_picture); - if (s->next_picture_ptr->f.data[0] && + if (s->next_picture_ptr->f.buf[0] && (ret = ff_mpeg_ref_picture(s, &s->next_picture, s->next_picture_ptr)) < 0) return ret; } - assert(s->pict_type == AV_PICTURE_TYPE_I || (s->last_picture_ptr && - s->last_picture_ptr->f.data[0])); + av_assert0(s->pict_type == AV_PICTURE_TYPE_I || (s->last_picture_ptr && + s->last_picture_ptr->f.buf[0])); if (s->picture_structure!= PICT_FRAME) { int i; @@ -1731,34 +1668,25 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) } if (s->dct_error_sum) { - assert(s->avctx->noise_reduction && s->encoding); + av_assert2(s->avctx->noise_reduction && s->encoding); update_noise_reduction(s); } - if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration) - return ff_xvmc_field_start(s, avctx); - return 0; } -/* generic function for encode/decode called after a - * frame has been coded/decoded. */ +/* called after a frame has been decoded. */ void ff_MPV_frame_end(MpegEncContext *s) { - int i; - /* redraw edges for the frame if decoding didn't complete */ - // just to make sure that all data is rendered. - if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration) { - ff_xvmc_field_end(s); - } else if ((s->er.error_count || s->encoding || !(s->avctx->codec->capabilities&CODEC_CAP_DRAW_HORIZ_BAND)) && - !s->avctx->hwaccel && - !(s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) && - s->unrestricted_mv && - s->current_picture.reference && - !s->intra_only && - !(s->flags & CODEC_FLAG_EMU_EDGE) && - !s->avctx->lowres - ) { + if ((s->er.error_count || !(s->avctx->codec->capabilities&CODEC_CAP_DRAW_HORIZ_BAND)) && + !s->avctx->hwaccel && + !(s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) && + s->unrestricted_mv && + s->current_picture.reference && + !s->intra_only && + !(s->flags & CODEC_FLAG_EMU_EDGE) && + !s->avctx->lowres + ) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->avctx->pix_fmt); int hshift = desc->log2_chroma_w; int vshift = desc->log2_chroma_h; @@ -1778,37 +1706,6 @@ void ff_MPV_frame_end(MpegEncContext *s) emms_c(); - s->last_pict_type = s->pict_type; - s->last_lambda_for [s->pict_type] = s->current_picture_ptr->f.quality; - if (s->pict_type!= AV_PICTURE_TYPE_B) { - s->last_non_b_pict_type = s->pict_type; - } -#if 0 - /* copy back current_picture variables */ - for (i = 0; i < MAX_PICTURE_COUNT; i++) { - if (s->picture[i].f.data[0] == s->current_picture.f.data[0]) { - s->picture[i] = s->current_picture; - break; - } - } - assert(i < MAX_PICTURE_COUNT); -#endif - - if (s->encoding) { - /* release non-reference frames */ - for (i = 0; i < MAX_PICTURE_COUNT; i++) { - if (!s->picture[i].reference) - ff_mpeg_unref_picture(s, &s->picture[i]); - } - } - // clear copies, to avoid confusion -#if 0 - memset(&s->last_picture, 0, sizeof(Picture)); - memset(&s->next_picture, 0, sizeof(Picture)); - memset(&s->current_picture, 0, sizeof(Picture)); -#endif - s->avctx->coded_frame = &s->current_picture_ptr->f; - if (s->current_picture.reference) ff_thread_report_progress(&s->current_picture_ptr->tf, INT_MAX, 0); } @@ -2212,13 +2109,13 @@ static inline int hpel_motion_lowres(MpegEncContext *s, uint8_t *dest, uint8_t *src, int field_based, int field_select, int src_x, int src_y, - int width, int height, int stride, + int width, int height, ptrdiff_t stride, int h_edge_pos, int v_edge_pos, int w, int h, h264_chroma_mc_func *pix_op, int motion_x, int motion_y) { const int lowres = s->avctx->lowres; - const int op_index = FFMIN(lowres, 2); + const int op_index = FFMIN(lowres, 3); const int s_mask = (2 << lowres) - 1; int emu = 0; int sx, sy; @@ -2237,11 +2134,11 @@ static inline int hpel_motion_lowres(MpegEncContext *s, if ((unsigned)src_x > FFMAX( h_edge_pos - (!!sx) - w, 0) || (unsigned)src_y > FFMAX((v_edge_pos >> field_based) - (!!sy) - h, 0)) { - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, w + 1, - (h + 1) << field_based, src_x, - src_y << field_based, - h_edge_pos, - v_edge_pos); + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, src, + s->linesize, s->linesize, + w + 1, (h + 1) << field_based, + src_x, src_y << field_based, + h_edge_pos, v_edge_pos); src = s->edge_emu_buffer; emu = 1; } @@ -2268,10 +2165,10 @@ static av_always_inline void mpeg_motion_lowres(MpegEncContext *s, int h, int mb_y) { uint8_t *ptr_y, *ptr_cb, *ptr_cr; - int mx, my, src_x, src_y, uvsrc_x, uvsrc_y, uvlinesize, linesize, sx, sy, - uvsx, uvsy; + int mx, my, src_x, src_y, uvsrc_x, uvsrc_y, sx, sy, uvsx, uvsy; + ptrdiff_t uvlinesize, linesize; const int lowres = s->avctx->lowres; - const int op_index = FFMIN(lowres-1+s->chroma_x_shift, 2); + const int op_index = FFMIN(lowres-1+s->chroma_x_shift, 3); const int block_s = 8>>lowres; const int s_mask = (2 << lowres) - 1; const int h_edge_pos = s->h_edge_pos >> lowres; @@ -2337,21 +2234,24 @@ static av_always_inline void mpeg_motion_lowres(MpegEncContext *s, ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x; ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x; - if ((unsigned) src_x > FFMAX( h_edge_pos - (!!sx) - 2 * block_s, 0) || + if ((unsigned) src_x > FFMAX( h_edge_pos - (!!sx) - 2 * block_s, 0) || uvsrc_y<0 || (unsigned) src_y > FFMAX((v_edge_pos >> field_based) - (!!sy) - h, 0)) { s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y, - linesize >> field_based, 17, 17 + field_based, + linesize >> field_based, linesize >> field_based, + 17, 17 + field_based, src_x, src_y << field_based, h_edge_pos, v_edge_pos); ptr_y = s->edge_emu_buffer; if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) { uint8_t *uvbuf = s->edge_emu_buffer + 18 * s->linesize; - s->vdsp.emulated_edge_mc(uvbuf , ptr_cb, uvlinesize >> field_based, 9, - 9 + field_based, + s->vdsp.emulated_edge_mc(uvbuf, ptr_cb, + uvlinesize >> field_based, uvlinesize >> field_based, + 9, 9 + field_based, uvsrc_x, uvsrc_y << field_based, h_edge_pos >> 1, v_edge_pos >> 1); - s->vdsp.emulated_edge_mc(uvbuf + 16, ptr_cr, uvlinesize >> field_based, 9, - 9 + field_based, + s->vdsp.emulated_edge_mc(uvbuf + 16, ptr_cr, + uvlinesize >> field_based,uvlinesize >> field_based, + 9, 9 + field_based, uvsrc_x, uvsrc_y << field_based, h_edge_pos >> 1, v_edge_pos >> 1); ptr_cb = uvbuf; @@ -2377,11 +2277,12 @@ static av_always_inline void mpeg_motion_lowres(MpegEncContext *s, pix_op[lowres - 1](dest_y, ptr_y, linesize, h, sx, sy); if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) { + int hc = s->chroma_y_shift ? (h+1-bottom_field)>>1 : h; uvsx = (uvsx << 2) >> lowres; uvsy = (uvsy << 2) >> lowres; - if (h >> s->chroma_y_shift) { - pix_op[op_index](dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift, uvsx, uvsy); - pix_op[op_index](dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift, uvsx, uvsy); + if (hc) { + pix_op[op_index](dest_cb, ptr_cb, uvlinesize, hc, uvsx, uvsy); + pix_op[op_index](dest_cr, ptr_cr, uvlinesize, hc, uvsx, uvsy); } } // FIXME h261 lowres loop filter @@ -2394,12 +2295,13 @@ static inline void chroma_4mv_motion_lowres(MpegEncContext *s, int mx, int my) { const int lowres = s->avctx->lowres; - const int op_index = FFMIN(lowres, 2); + const int op_index = FFMIN(lowres, 3); const int block_s = 8 >> lowres; const int s_mask = (2 << lowres) - 1; const int h_edge_pos = s->h_edge_pos >> lowres + 1; const int v_edge_pos = s->v_edge_pos >> lowres + 1; - int emu = 0, src_x, src_y, offset, sx, sy; + int emu = 0, src_x, src_y, sx, sy; + ptrdiff_t offset; uint8_t *ptr; if (s->quarter_sample) { @@ -2419,14 +2321,14 @@ static inline void chroma_4mv_motion_lowres(MpegEncContext *s, offset = src_y * s->uvlinesize + src_x; ptr = ref_picture[1] + offset; - if (s->flags & CODEC_FLAG_EMU_EDGE) { - if ((unsigned) src_x > FFMAX(h_edge_pos - (!!sx) - block_s, 0) || - (unsigned) src_y > FFMAX(v_edge_pos - (!!sy) - block_s, 0)) { - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, - 9, 9, src_x, src_y, h_edge_pos, v_edge_pos); - ptr = s->edge_emu_buffer; - emu = 1; - } + if ((unsigned) src_x > FFMAX(h_edge_pos - (!!sx) - block_s, 0) || + (unsigned) src_y > FFMAX(v_edge_pos - (!!sy) - block_s, 0)) { + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, + s->uvlinesize, s->uvlinesize, + 9, 9, + src_x, src_y, h_edge_pos, v_edge_pos); + ptr = s->edge_emu_buffer; + emu = 1; } sx = (sx << 2) >> lowres; sy = (sy << 2) >> lowres; @@ -2434,8 +2336,10 @@ static inline void chroma_4mv_motion_lowres(MpegEncContext *s, ptr = ref_picture[2] + offset; if (emu) { - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9, - src_x, src_y, h_edge_pos, v_edge_pos); + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, + s->uvlinesize, s->uvlinesize, + 9, 9, + src_x, src_y, h_edge_pos, v_edge_pos); ptr = s->edge_emu_buffer; } pix_op[op_index](dest_cr, ptr, s->uvlinesize, block_s, sx, sy); @@ -2696,8 +2600,10 @@ void MPV_decode_mb_internal(MpegEncContext *s, int16_t block[12][64], int lowres_flag, int is_mpeg12) { const int mb_xy = s->mb_y * s->mb_stride + s->mb_x; - if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration){ - ff_xvmc_decode_mb(s);//xvmc uses pblocks + + if (CONFIG_XVMC && + s->avctx->hwaccel && s->avctx->hwaccel->decode_mb) { + s->avctx->hwaccel->decode_mb(s);//xvmc uses pblocks return; } @@ -2729,7 +2635,9 @@ void MPV_decode_mb_internal(MpegEncContext *s, int16_t block[12][64], else if (!is_mpeg12 && (s->h263_pred || s->h263_aic)) s->mbintra_table[mb_xy]=1; - if ((s->flags&CODEC_FLAG_PSNR) || !(s->encoding && (s->intra_only || s->pict_type==AV_PICTURE_TYPE_B) && s->avctx->mb_decision != FF_MB_DECISION_RD)) { //FIXME precalc + if ( (s->flags&CODEC_FLAG_PSNR) + || s->avctx->frame_skip_threshold || s->avctx->frame_skip_factor + || !(s->encoding && (s->intra_only || s->pict_type==AV_PICTURE_TYPE_B) && s->avctx->mb_decision != FF_MB_DECISION_RD)) { //FIXME precalc uint8_t *dest_y, *dest_cb, *dest_cr; int dct_linesize, dct_offset; op_pixels_func (*op_pix)[4]; @@ -2797,7 +2705,7 @@ void MPV_decode_mb_internal(MpegEncContext *s, int16_t block[12][64], MPV_motion_lowres(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.f.data, op_pix); } }else{ - op_qpix= s->me.qpel_put; + op_qpix = s->me.qpel_put; if ((!s->no_rounding) || s->pict_type==AV_PICTURE_TYPE_B){ op_pix = s->hdsp.put_pixels_tab; }else{ @@ -2908,7 +2816,7 @@ void MPV_decode_mb_internal(MpegEncContext *s, int16_t block[12][64], }else{ dct_linesize = uvlinesize << s->interlaced_dct; - dct_offset = s->interlaced_dct? uvlinesize : uvlinesize*block_size; + dct_offset = s->interlaced_dct ? uvlinesize : uvlinesize*block_size; s->dsp.idct_put(dest_cb, dct_linesize, block[4]); s->dsp.idct_put(dest_cr, dct_linesize, block[5]); @@ -3025,8 +2933,8 @@ void ff_draw_horiz_band(AVCodecContext *avctx, DSPContext *dsp, Picture *cur, void ff_mpeg_draw_horiz_band(MpegEncContext *s, int y, int h) { int draw_edges = s->unrestricted_mv && !s->intra_only; - ff_draw_horiz_band(s->avctx, &s->dsp, &s->current_picture, - &s->last_picture, y, h, s->picture_structure, + ff_draw_horiz_band(s->avctx, &s->dsp, s->current_picture_ptr, + s->last_picture_ptr, y, h, s->picture_structure, s->first_field, draw_edges, s->low_delay, s->v_edge_pos, s->h_edge_pos); } @@ -3103,6 +3011,10 @@ void ff_mpeg_flush(AVCodecContext *avctx){ ff_mpeg_unref_picture(s, &s->picture[i]); s->current_picture_ptr = s->last_picture_ptr = s->next_picture_ptr = NULL; + ff_mpeg_unref_picture(s, &s->current_picture); + ff_mpeg_unref_picture(s, &s->last_picture); + ff_mpeg_unref_picture(s, &s->next_picture); + s->mb_x= s->mb_y= 0; s->closed_gop= 0; @@ -3269,7 +3181,7 @@ static void dct_unquantize_h263_intra_c(MpegEncContext *s, int i, level, qmul, qadd; int nCoeffs; - assert(s->block_last_index[n]>=0); + av_assert2(s->block_last_index[n]>=0 || s->h263_aic); qmul = qscale << 1; @@ -3303,7 +3215,7 @@ static void dct_unquantize_h263_inter_c(MpegEncContext *s, int i, level, qmul, qadd; int nCoeffs; - assert(s->block_last_index[n]>=0); + av_assert2(s->block_last_index[n]>=0); qadd = (qscale - 1) | 1; qmul = qscale << 1; diff --git a/ffmpeg/libavcodec/mpegvideo.h b/ffmpeg/libavcodec/mpegvideo.h index 40fd295..6786ec1 100644 --- a/ffmpeg/libavcodec/mpegvideo.h +++ b/ffmpeg/libavcodec/mpegvideo.h @@ -33,6 +33,7 @@ #include "error_resilience.h" #include "get_bits.h" #include "h264chroma.h" +#include "h263dsp.h" #include "hpeldsp.h" #include "put_bits.h" #include "ratecontrol.h" @@ -65,6 +66,8 @@ enum OutputFormat { #define MAX_THREADS 32 #define MAX_PICTURE_COUNT 36 +#define MAX_B_FRAMES 16 + #define ME_MAP_SIZE 64 #define ME_MAP_SHIFT 3 #define ME_MAP_MV_BITS 11 @@ -107,6 +110,30 @@ typedef struct Picture{ AVBufferRef *mb_type_buf; uint32_t *mb_type; +#if !FF_API_MB_TYPE +#define MB_TYPE_INTRA4x4 0x0001 +#define MB_TYPE_INTRA16x16 0x0002 //FIXME H.264-specific +#define MB_TYPE_INTRA_PCM 0x0004 //FIXME H.264-specific +#define MB_TYPE_16x16 0x0008 +#define MB_TYPE_16x8 0x0010 +#define MB_TYPE_8x16 0x0020 +#define MB_TYPE_8x8 0x0040 +#define MB_TYPE_INTERLACED 0x0080 +#define MB_TYPE_DIRECT2 0x0100 //FIXME +#define MB_TYPE_ACPRED 0x0200 +#define MB_TYPE_GMC 0x0400 +#define MB_TYPE_SKIP 0x0800 +#define MB_TYPE_P0L0 0x1000 +#define MB_TYPE_P1L0 0x2000 +#define MB_TYPE_P0L1 0x4000 +#define MB_TYPE_P1L1 0x8000 +#define MB_TYPE_L0 (MB_TYPE_P0L0 | MB_TYPE_P1L0) +#define MB_TYPE_L1 (MB_TYPE_P0L1 | MB_TYPE_P1L1) +#define MB_TYPE_L0L1 (MB_TYPE_L0 | MB_TYPE_L1) +#define MB_TYPE_QUANT 0x00010000 +#define MB_TYPE_CBP 0x00020000 +#endif + AVBufferRef *mbskip_table_buf; uint8_t *mbskip_table; @@ -119,6 +146,9 @@ typedef struct Picture{ AVBufferRef *mc_mb_var_buf; uint16_t *mc_mb_var; ///< Table for motion compensated MB variances + int alloc_mb_width; ///< mb_width used to allocate tables + int alloc_mb_height; ///< mb_height used to allocate tables + AVBufferRef *mb_mean_buf; uint8_t *mb_mean; ///< Table for MB luminance @@ -164,17 +194,20 @@ typedef struct Picture{ int ref_count[2][2]; ///< number of entries in ref_poc (FIXME need per slice) int mbaff; ///< h264 1 -> MBAFF frame 0-> not MBAFF int field_picture; ///< whether or not the picture was encoded in separate fields - int sync; ///< has been decoded after a keyframe int mb_var_sum; ///< sum of MB variance for current frame int mc_mb_var_sum; ///< motion compensated MB variance for current frame - int b_frame_score; /* */ + int b_frame_score; int needs_realloc; ///< Picture needs to be reallocated (eg due to a frame size change) - int period_since_free; ///< "cycles" since this Picture has been freed int reference; int shared; + int recovered; ///< Picture at IDR or recovery point + recovery count + + int crop; + int crop_left; + int crop_top; } Picture; /** @@ -278,8 +311,8 @@ typedef struct MpegEncContext { int b4_stride; ///< 4*mb_width+1 used for some 4x4 block arrays to allow simple addressing int h_edge_pos, v_edge_pos;///< horizontal / vertical position of the right/bottom edge (pixel replication) int mb_num; ///< number of MBs of a picture - int linesize; ///< line size, in bytes, may be different from width - int uvlinesize; ///< line size, for chroma in bytes, may be different from width + ptrdiff_t linesize; ///< line size, in bytes, may be different from width + ptrdiff_t uvlinesize; ///< line size, for chroma in bytes, may be different from width Picture *picture; ///< main picture buffer Picture **input_picture; ///< next pictures on display order for encoding Picture **reordered_input_picture; ///< pointer to the next pictures in codedorder for encoding @@ -298,7 +331,7 @@ typedef struct MpegEncContext { /* WARNING: changes above this line require updates to hardcoded * offsets used in asm. */ - int64_t user_specified_pts;///< last non zero pts from AVFrame which was passed into avcodec_encode_video() + int64_t user_specified_pts; ///< last non-zero pts from AVFrame which was passed into avcodec_encode_video2() /** * pts difference between the first and second input frame, used for * calculating dts of the first frame when there's a delay */ @@ -352,7 +385,7 @@ typedef struct MpegEncContext { uint8_t *coded_block_base; uint8_t *coded_block; ///< used for coded block pattern prediction (msmpeg4v3, wmv1) int16_t (*ac_val_base)[16]; - int16_t (*ac_val[3])[16]; ///< used for for mpeg4 AC prediction, all 3 arrays must be continuous + int16_t (*ac_val[3])[16]; ///< used for mpeg4 AC prediction, all 3 arrays must be continuous int mb_skipped; ///< MUST BE SET only during DECODING uint8_t *mbskip_table; /**< used to avoid copy if macroblock skipped (for black regions for example) and used for b-frame encoding & decoding (contains skip table of next P Frame) */ @@ -390,6 +423,7 @@ typedef struct MpegEncContext { H264ChromaContext h264chroma; HpelDSPContext hdsp; VideoDSPContext vdsp; + H263DSPContext h263dsp; int f_code; ///< forward MV resolution int b_code; ///< backward MV resolution for B Frames (mpeg4) int16_t (*p_mv_table_base)[2]; @@ -534,11 +568,11 @@ typedef struct MpegEncContext { /* H.263 specific */ int gob_index; int obmc; ///< overlapped block motion compensation - int showed_packed_warning; ///< flag for having shown the warning about divxs invalid b frames int mb_info; ///< interval for outputting info about mb offsets as side data int prev_mb_info, last_mb_info; uint8_t *mb_info_ptr; int mb_info_size; + int ehc_mode; /* H.263+ specific */ int umvplus; ///< == H263+ && unrestricted_mv @@ -550,7 +584,8 @@ typedef struct MpegEncContext { int custom_pcf; /* mpeg4 specific */ - int time_increment_bits; ///< number of bits to represent the fractional part of time + ///< number of bits to represent the fractional part of time (encoder only) + int time_increment_bits; int last_time_base; int time_base; ///< time in seconds of last I,P,S Frame int64_t time; ///< time of current frame @@ -559,61 +594,30 @@ typedef struct MpegEncContext { uint16_t pb_time; ///< time distance between the last b and p,s,i frame uint16_t pp_field_time; uint16_t pb_field_time; ///< like above, just for interlaced - int shape; - int vol_sprite_usage; - int sprite_width; - int sprite_height; - int sprite_left; - int sprite_top; - int sprite_brightness_change; - int num_sprite_warping_points; int real_sprite_warping_points; - uint16_t sprite_traj[4][2]; ///< sprite trajectory points int sprite_offset[2][2]; ///< sprite offset[isChroma][isMVY] int sprite_delta[2][2]; ///< sprite_delta [isY][isMVY] - int sprite_shift[2]; ///< sprite shift [isChroma] int mcsel; int quant_precision; int quarter_sample; ///< 1->qpel, 0->half pel ME/MC - int scalability; - int hierachy_type; - int enhancement_type; - int new_pred; - int reduced_res_vop; int aspect_ratio_info; //FIXME remove int sprite_warping_accuracy; - int low_latency_sprite; int data_partitioning; ///< data partitioning flag from header int partitioned_frame; ///< is current frame partitioned - int rvlc; ///< reversible vlc - int resync_marker; ///< could this stream contain resync markers int low_delay; ///< no reordering needed / has no b-frames int vo_type; int vol_control_parameters; ///< does the stream contain the low_delay flag, used to workaround buggy encoders - int intra_dc_threshold; ///< QP above whch the ac VLC should be used for intra dc - int use_intra_dc_vlc; PutBitContext tex_pb; ///< used for data partitioned VOPs PutBitContext pb2; ///< used for data partitioned VOPs int mpeg_quant; - int t_frame; ///< time distance of first I -> B, used for interlaced b frames int padding_bug_score; ///< used to detect the VERY common padding bug in MPEG4 - int cplx_estimation_trash_i; - int cplx_estimation_trash_p; - int cplx_estimation_trash_b; /* divx specific, used to workaround (many) bugs in divx5 */ - int divx_version; - int divx_build; int divx_packed; uint8_t *bitstream_buffer; //Divx 5.01 puts several frames in a single one, this is used to reorder them int bitstream_buffer_size; unsigned int allocated_bitstream_buffer_size; - int xvid_build; - - /* lavc specific stuff, used to workaround bugs in libavcodec */ - int lavc_build; - /* RV10 specific */ int rv10_version; ///< RV10 version: 0 or 3 int rv10_first_dc_coded[3]; @@ -621,8 +625,6 @@ typedef struct MpegEncContext { /* MJPEG specific */ struct MJpegContext *mjpeg_ctx; - int mjpeg_vsample[3]; ///< vertical sampling factors, default = {2, 1, 1} - int mjpeg_hsample[3]; ///< horizontal sampling factors, default = {2, 1, 1} int esc_pos; /* MSMPEG4 specific */ @@ -649,7 +651,6 @@ typedef struct MpegEncContext { /* Mpeg1 specific */ int gop_picture_number; ///< index of the first picture of a GOP based on fake_pic_num & mpeg1 specific int last_mv_dir; ///< last mv_dir, used for b frame encoding - int broken_link; ///< no_output_of_prior_pics_flag uint8_t *vbv_delay_ptr; ///< pointer to vbv_delay in the bitstream /* MPEG-2-specific - I wished not to have to support this mess. */ @@ -680,7 +681,6 @@ typedef struct MpegEncContext { int progressive_frame; int full_pel[2]; int interlaced_dct; - int first_slice; int first_field; ///< is 1 for the first field of a field picture 0 otherwise int drop_frame_timecode; ///< timecode is in drop frame format. int scan_offset; ///< reserve space for SVCD scan offset user data. @@ -693,6 +693,7 @@ typedef struct MpegEncContext { uint8_t *ptr_lastgob; int swap_uv; //vcr2 codec is an MPEG-2 variant with U and V swapped + int pack_pblocks; //xvmc needs to keep blocks without gaps. int16_t (*pblocks[12])[64]; int16_t (*block)[64]; ///< points to one of the following blocks @@ -738,6 +739,11 @@ typedef struct MpegEncContext { int context_reinit; ERContext er; + + int error_rate; + + /* temporary frames used by b_frame_strategy = 2 */ + AVFrame *tmp_frames[MAX_B_FRAMES + 2]; } MpegEncContext; #define REBASE_PICTURE(pic, new_ctx, old_ctx) \ @@ -763,7 +769,9 @@ typedef struct MpegEncContext { FF_MPV_OFFSET(luma_elim_threshold), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS },\ { "chroma_elim_threshold", "single coefficient elimination threshold for chrominance (negative values also consider dc coefficient)",\ FF_MPV_OFFSET(chroma_elim_threshold), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS },\ -{ "quantizer_noise_shaping", NULL, FF_MPV_OFFSET(quantizer_noise_shaping), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FF_MPV_OPT_FLAGS }, +{ "quantizer_noise_shaping", NULL, FF_MPV_OFFSET(quantizer_noise_shaping), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FF_MPV_OPT_FLAGS },\ +{ "error_rate", "Simulate errors in the bitstream to test error concealment.", \ + FF_MPV_OFFSET(error_rate), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FF_MPV_OPT_FLAGS }, extern const AVOption ff_mpv_generic_options[]; @@ -784,7 +792,6 @@ void ff_MPV_common_defaults(MpegEncContext *s); void ff_MPV_decode_defaults(MpegEncContext *s); int ff_MPV_common_init(MpegEncContext *s); -int ff_mpv_frame_size_alloc(MpegEncContext *s, int linesize); int ff_MPV_common_frame_size_change(MpegEncContext *s); void ff_MPV_common_end(MpegEncContext *s); void ff_MPV_decode_mb(MpegEncContext *s, int16_t block[12][64]); @@ -798,8 +805,8 @@ void ff_dct_encode_init_x86(MpegEncContext *s); void ff_MPV_common_init_x86(MpegEncContext *s); void ff_MPV_common_init_axp(MpegEncContext *s); void ff_MPV_common_init_arm(MpegEncContext *s); -void ff_MPV_common_init_altivec(MpegEncContext *s); void ff_MPV_common_init_bfin(MpegEncContext *s); +void ff_MPV_common_init_ppc(MpegEncContext *s); void ff_clean_intra_table_entries(MpegEncContext *s); void ff_draw_horiz_band(AVCodecContext *avctx, DSPContext *dsp, Picture *cur, Picture *last, int y, int h, int picture_structure, @@ -816,14 +823,12 @@ void ff_print_debug_info2(AVCodecContext *avctx, Picture *p, AVFrame *pict, uint int ff_mpv_export_qp_table(MpegEncContext *s, AVFrame *f, Picture *p, int qp_type); void ff_write_quant_matrix(PutBitContext *pb, uint16_t *matrix); -void ff_release_unused_pictures(MpegEncContext *s, int remove_current); int ff_find_unused_picture(MpegEncContext *s, int shared); void ff_denoise_dct(MpegEncContext *s, int16_t *block); int ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src); int ff_MPV_lowest_referenced_row(MpegEncContext *s, int dir); void ff_MPV_report_decode_progress(MpegEncContext *s); int ff_mpeg_update_thread_context(AVCodecContext *dst, const AVCodecContext *src); -const uint8_t *avpriv_mpv_find_start_code(const uint8_t *p, const uint8_t *end, uint32_t *state); void ff_set_qscale(MpegEncContext * s, int qscale); void ff_mpeg_er_frame_start(MpegEncContext *s); @@ -915,23 +920,9 @@ void ff_mpeg1_encode_mb(MpegEncContext *s, int motion_x, int motion_y); void ff_mpeg1_encode_init(MpegEncContext *s); void ff_mpeg1_encode_slice_header(MpegEncContext *s); -void ff_mpeg1_clean_buffers(MpegEncContext *s); -int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, AVCodecParserContext *s); extern const uint8_t ff_aic_dc_scale_table[32]; extern const uint8_t ff_h263_chroma_qscale_table[32]; -extern const uint8_t ff_h263_loop_filter_strength[32]; - -/* h261.c */ -void ff_h261_loop_filter(MpegEncContext *s); -void ff_h261_reorder_mb_index(MpegEncContext* s); -void ff_h261_encode_mb(MpegEncContext *s, - int16_t block[6][64], - int motion_x, int motion_y); -void ff_h261_encode_picture_header(MpegEncContext * s, int picture_number); -void ff_h261_encode_init(MpegEncContext *s); -int ff_h261_get_picture_format(int width, int height); - /* rv10.c */ void ff_rv10_encode_picture_header(MpegEncContext *s, int picture_number); @@ -963,6 +954,7 @@ void ff_wmv2_encode_mb(MpegEncContext * s, int ff_mpeg_ref_picture(MpegEncContext *s, Picture *dst, Picture *src); void ff_mpeg_unref_picture(MpegEncContext *s, Picture *picture); +void ff_free_picture_tables(Picture *pic); #endif /* AVCODEC_MPEGVIDEO_H */ diff --git a/ffmpeg/libavcodec/mpegvideo_enc.c b/ffmpeg/libavcodec/mpegvideo_enc.c index dd66943..6bf3e38 100644 --- a/ffmpeg/libavcodec/mpegvideo_enc.c +++ b/ffmpeg/libavcodec/mpegvideo_enc.c @@ -27,6 +27,8 @@ * The simplest mpeg encoder (well, it was the simplest!). */ +#include + #include "libavutil/internal.h" #include "libavutil/intmath.h" #include "libavutil/mathematics.h" @@ -35,7 +37,9 @@ #include "avcodec.h" #include "dct.h" #include "dsputil.h" +#include "mpeg12.h" #include "mpegvideo.h" +#include "h261.h" #include "h263.h" #include "mathops.h" #include "mjpegenc.h" @@ -50,17 +54,12 @@ #include #include "sp5x.h" -//#undef NDEBUG -//#include - static int encode_picture(MpegEncContext *s, int picture_number); static int dct_quantize_refine(MpegEncContext *s, int16_t *block, int16_t *weight, int16_t *orig, int n, int qscale); static int sse_mb(MpegEncContext *s); static void denoise_dct_c(MpegEncContext *s, int16_t *block); static int dct_quantize_trellis_c(MpegEncContext *s, int16_t *block, int n, int qscale, int *overflow); -//#define DEBUG - static uint8_t default_mv_penalty[MAX_FCODE + 1][MAX_MV * 2 + 1]; static uint8_t default_fcode_tab[MAX_MV * 2 + 1]; @@ -185,19 +184,6 @@ void ff_init_qscale_tab(MpegEncContext *s) } } -static void copy_picture_attributes(MpegEncContext *s, AVFrame *dst, - const AVFrame *src) -{ - dst->pict_type = src->pict_type; - dst->quality = src->quality; - dst->coded_picture_number = src->coded_picture_number; - dst->display_picture_number = src->display_picture_number; - //dst->reference = src->reference; - dst->pts = src->pts; - dst->interlaced_frame = src->interlaced_frame; - dst->top_field_first = src->top_field_first; -} - static void update_duplicate_context_after_me(MpegEncContext *dst, MpegEncContext *src) { @@ -231,12 +217,16 @@ static void MPV_encode_defaults(MpegEncContext *s) } s->me.mv_penalty = default_mv_penalty; s->fcode_tab = default_fcode_tab; + + s->input_picture_number = 0; + s->picture_in_gop_number = 0; } av_cold int ff_dct_encode_init(MpegEncContext *s) { if (ARCH_X86) ff_dct_encode_init_x86(s); + ff_h263dsp_init(&s->h263dsp); if (!s->dct_quantize) s->dct_quantize = ff_dct_quantize_c; if (!s->denoise_dct) @@ -252,8 +242,7 @@ av_cold int ff_dct_encode_init(MpegEncContext *s) { av_cold int ff_MPV_encode_init(AVCodecContext *avctx) { MpegEncContext *s = avctx->priv_data; - int i; - int chroma_h_shift, chroma_v_shift; + int i, ret; MPV_encode_defaults(s); @@ -266,21 +255,6 @@ av_cold int ff_MPV_encode_init(AVCodecContext *avctx) return -1; } break; - case AV_CODEC_ID_LJPEG: - if (avctx->pix_fmt != AV_PIX_FMT_YUVJ420P && - avctx->pix_fmt != AV_PIX_FMT_YUVJ422P && - avctx->pix_fmt != AV_PIX_FMT_YUVJ444P && - avctx->pix_fmt != AV_PIX_FMT_BGR0 && - avctx->pix_fmt != AV_PIX_FMT_BGRA && - avctx->pix_fmt != AV_PIX_FMT_BGR24 && - ((avctx->pix_fmt != AV_PIX_FMT_YUV420P && - avctx->pix_fmt != AV_PIX_FMT_YUV422P && - avctx->pix_fmt != AV_PIX_FMT_YUV444P) || - avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL)) { - av_log(avctx, AV_LOG_ERROR, "colorspace not supported in LJPEG\n"); - return -1; - } - break; case AV_CODEC_ID_MJPEG: case AV_CODEC_ID_AMV: if (avctx->pix_fmt != AV_PIX_FMT_YUVJ420P && @@ -331,6 +305,11 @@ av_cold int ff_MPV_encode_init(AVCodecContext *avctx) s->avctx = avctx; s->flags = avctx->flags; s->flags2 = avctx->flags2; + if (avctx->max_b_frames > MAX_B_FRAMES) { + av_log(avctx, AV_LOG_ERROR, "Too many B-frames requested, maximum " + "is %d.\n", MAX_B_FRAMES); + avctx->max_b_frames = MAX_B_FRAMES; + } s->max_b_frames = avctx->max_b_frames; s->codec_id = avctx->codec->id; s->strict_std_compliance = avctx->strict_std_compliance; @@ -468,6 +447,11 @@ av_cold int ff_MPV_encode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "b frames not supported by codec\n"); return -1; } + if (s->max_b_frames < 0) { + av_log(avctx, AV_LOG_ERROR, + "max b frames must be 0 or positive for mpegvideo based encoders\n"); + return -1; + } if ((s->codec_id == AV_CODEC_ID_MPEG4 || s->codec_id == AV_CODEC_ID_H263 || @@ -538,7 +522,8 @@ av_cold int ff_MPV_encode_init(AVCodecContext *avctx) } // FIXME mpeg2 uses that too - if (s->mpeg_quant && s->codec_id != AV_CODEC_ID_MPEG4) { + if (s->mpeg_quant && ( s->codec_id != AV_CODEC_ID_MPEG4 + && s->codec_id != AV_CODEC_ID_MPEG2VIDEO)) { av_log(avctx, AV_LOG_ERROR, "mpeg2 style quantization not supported by codec\n"); return -1; @@ -644,6 +629,11 @@ av_cold int ff_MPV_encode_init(AVCodecContext *avctx) s->inter_quant_bias = -(1 << (QUANT_BIAS_SHIFT - 2)); } + if (avctx->qmin > avctx->qmax || avctx->qmin <= 0) { + av_log(avctx, AV_LOG_ERROR, "qmin and or qmax are invalid, they must be 0 < min <= max\n"); + return AVERROR(EINVAL); + } + if (avctx->intra_quant_bias != FF_DEFAULT_QUANT_BIAS) s->intra_quant_bias = avctx->intra_quant_bias; if (avctx->inter_quant_bias != FF_DEFAULT_QUANT_BIAS) @@ -651,8 +641,6 @@ av_cold int ff_MPV_encode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_DEBUG, "intra_quant_bias = %d inter_quant_bias = %d\n",s->intra_quant_bias,s->inter_quant_bias); - avcodec_get_chroma_sub_sample(avctx->pix_fmt, &chroma_h_shift, &chroma_v_shift); - if (avctx->codec_id == AV_CODEC_ID_MPEG4 && s->avctx->time_base.den > (1 << 16) - 1) { av_log(avctx, AV_LOG_ERROR, @@ -676,30 +664,11 @@ av_cold int ff_MPV_encode_init(AVCodecContext *avctx) avctx->delay = s->low_delay ? 0 : (s->max_b_frames + 1); s->rtp_mode = 1; break; - case AV_CODEC_ID_LJPEG: case AV_CODEC_ID_MJPEG: case AV_CODEC_ID_AMV: s->out_format = FMT_MJPEG; s->intra_only = 1; /* force intra only for jpeg */ - if (avctx->codec->id == AV_CODEC_ID_LJPEG && - (avctx->pix_fmt == AV_PIX_FMT_BGR0 - || s->avctx->pix_fmt == AV_PIX_FMT_BGRA - || s->avctx->pix_fmt == AV_PIX_FMT_BGR24)) { - s->mjpeg_vsample[0] = s->mjpeg_hsample[0] = - s->mjpeg_vsample[1] = s->mjpeg_hsample[1] = - s->mjpeg_vsample[2] = s->mjpeg_hsample[2] = 1; - } else if (avctx->pix_fmt == AV_PIX_FMT_YUV444P || avctx->pix_fmt == AV_PIX_FMT_YUVJ444P) { - s->mjpeg_vsample[0] = s->mjpeg_vsample[1] = s->mjpeg_vsample[2] = 2; - s->mjpeg_hsample[0] = s->mjpeg_hsample[1] = s->mjpeg_hsample[2] = 1; - } else { - s->mjpeg_vsample[0] = 2; - s->mjpeg_vsample[1] = 2 >> chroma_v_shift; - s->mjpeg_vsample[2] = 2 >> chroma_v_shift; - s->mjpeg_hsample[0] = 2; - s->mjpeg_hsample[1] = 2 >> chroma_h_shift; - s->mjpeg_hsample[2] = 2 >> chroma_h_shift; - } - if (!(CONFIG_MJPEG_ENCODER || CONFIG_LJPEG_ENCODER) || + if (!CONFIG_MJPEG_ENCODER || ff_mjpeg_encode_init(s) < 0) return -1; avctx->delay = 0; @@ -831,6 +800,31 @@ av_cold int ff_MPV_encode_init(AVCodecContext *avctx) if (ff_MPV_common_init(s) < 0) return -1; + s->avctx->coded_frame = &s->current_picture.f; + + if (s->msmpeg4_version) { + FF_ALLOCZ_OR_GOTO(s->avctx, s->ac_stats, + 2 * 2 * (MAX_LEVEL + 1) * + (MAX_RUN + 1) * 2 * sizeof(int), fail); + } + FF_ALLOCZ_OR_GOTO(s->avctx, s->avctx->stats_out, 256, fail); + + FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix, 64 * 32 * sizeof(int), fail); + FF_ALLOCZ_OR_GOTO(s->avctx, s->q_chroma_intra_matrix, 64 * 32 * sizeof(int), fail); + FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix, 64 * 32 * sizeof(int), fail); + FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix16, 64 * 32 * 2 * sizeof(uint16_t), fail); + FF_ALLOCZ_OR_GOTO(s->avctx, s->q_chroma_intra_matrix16, 64 * 32 * 2 * sizeof(uint16_t), fail); + FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix16, 64 * 32 * 2 * sizeof(uint16_t), fail); + FF_ALLOCZ_OR_GOTO(s->avctx, s->input_picture, + MAX_PICTURE_COUNT * sizeof(Picture *), fail); + FF_ALLOCZ_OR_GOTO(s->avctx, s->reordered_input_picture, + MAX_PICTURE_COUNT * sizeof(Picture *), fail); + + if (s->avctx->noise_reduction) { + FF_ALLOCZ_OR_GOTO(s->avctx, s->dct_offset, + 2 * 64 * sizeof(uint16_t), fail); + } + ff_dct_encode_init(s); if ((CONFIG_H263P_ENCODER || CONFIG_RV20_ENCODER) && s->modified_quant) @@ -886,22 +880,70 @@ av_cold int ff_MPV_encode_init(AVCodecContext *avctx) if (ff_rate_control_init(s) < 0) return -1; +#if FF_API_ERROR_RATE + FF_DISABLE_DEPRECATION_WARNINGS + if (avctx->error_rate) + s->error_rate = avctx->error_rate; + FF_ENABLE_DEPRECATION_WARNINGS; +#endif + + if (avctx->b_frame_strategy == 2) { + for (i = 0; i < s->max_b_frames + 2; i++) { + s->tmp_frames[i] = av_frame_alloc(); + if (!s->tmp_frames[i]) + return AVERROR(ENOMEM); + + s->tmp_frames[i]->format = AV_PIX_FMT_YUV420P; + s->tmp_frames[i]->width = s->width >> avctx->brd_scale; + s->tmp_frames[i]->height = s->height >> avctx->brd_scale; + + ret = av_frame_get_buffer(s->tmp_frames[i], 32); + if (ret < 0) + return ret; + } + } + return 0; +fail: + ff_MPV_encode_end(avctx); + return AVERROR_UNKNOWN; } av_cold int ff_MPV_encode_end(AVCodecContext *avctx) { MpegEncContext *s = avctx->priv_data; + int i; ff_rate_control_uninit(s); ff_MPV_common_end(s); - if ((CONFIG_MJPEG_ENCODER || CONFIG_LJPEG_ENCODER) && + if (CONFIG_MJPEG_ENCODER && s->out_format == FMT_MJPEG) ff_mjpeg_encode_close(s); av_freep(&avctx->extradata); + for (i = 0; i < FF_ARRAY_ELEMS(s->tmp_frames); i++) + av_frame_free(&s->tmp_frames[i]); + + ff_free_picture_tables(&s->new_picture); + ff_mpeg_unref_picture(s, &s->new_picture); + + av_freep(&s->avctx->stats_out); + av_freep(&s->ac_stats); + + if(s->q_chroma_intra_matrix != s->q_intra_matrix ) av_freep(&s->q_chroma_intra_matrix); + if(s->q_chroma_intra_matrix16 != s->q_intra_matrix16) av_freep(&s->q_chroma_intra_matrix16); + s->q_chroma_intra_matrix= NULL; + s->q_chroma_intra_matrix16= NULL; + av_freep(&s->q_intra_matrix); + av_freep(&s->q_inter_matrix); + av_freep(&s->q_intra_matrix16); + av_freep(&s->q_inter_matrix16); + av_freep(&s->input_picture); + av_freep(&s->reordered_input_picture); + av_freep(&s->dct_offset); + return 0; } @@ -958,18 +1000,17 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg) if (pts != AV_NOPTS_VALUE) { if (s->user_specified_pts != AV_NOPTS_VALUE) { - int64_t time = pts; int64_t last = s->user_specified_pts; - if (time <= last) { + if (pts <= last) { av_log(s->avctx, AV_LOG_ERROR, - "Error, Invalid timestamp=%"PRId64", " - "last=%"PRId64"\n", pts, s->user_specified_pts); - return -1; + "Invalid pts (%"PRId64") <= last (%"PRId64")\n", + pts, last); + return AVERROR(EINVAL); } if (!s->low_delay && display_picture_number == 1) - s->dts_delta = time - last; + s->dts_delta = pts - last; } s->user_specified_pts = pts; } else { @@ -995,7 +1036,7 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg) if (pic_arg->linesize[2] != s->uvlinesize) direct = 0; - av_dlog(s->avctx, "%d %d %d %d\n", pic_arg->linesize[0], + av_dlog(s->avctx, "%d %d %td %td\n", pic_arg->linesize[0], pic_arg->linesize[1], s->linesize, s->uvlinesize); if (direct) { @@ -1071,7 +1112,10 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg) } } } - copy_picture_attributes(s, &pic->f, pic_arg); + ret = av_frame_copy_props(&pic->f, pic_arg); + if (ret < 0) + return ret; + pic->f.display_picture_number = display_picture_number; pic->f.pts = pts; // we set this here to avoid modifiying pic_arg } @@ -1104,9 +1148,9 @@ static int skip_check(MpegEncContext *s, Picture *p, Picture *ref) switch (s->avctx->frame_skip_exp) { case 0: score = FFMAX(score, v); break; case 1: score += FFABS(v); break; - case 2: score += v * v; break; - case 3: score64 += FFABS(v * v * (int64_t)v); break; - case 4: score64 += v * v * (int64_t)(v * v); break; + case 2: score64 += v * (int64_t)v; break; + case 3: score64 += FFABS(v * (int64_t)v * v); break; + case 4: score64 += (v * (int64_t)v) * (v * (int64_t)v); break; } } } @@ -1141,7 +1185,6 @@ static int estimate_best_b_count(MpegEncContext *s) { AVCodec *codec = avcodec_find_encoder(s->avctx->codec_id); AVCodecContext *c = avcodec_alloc_context3(NULL); - AVFrame input[FF_MAX_B_FRAMES + 2]; const int scale = s->avctx->brd_scale; int i, j, out_size, p_lambda, b_lambda, lambda2; int64_t best_rd = INT64_MAX; @@ -1176,19 +1219,9 @@ static int estimate_best_b_count(MpegEncContext *s) return -1; for (i = 0; i < s->max_b_frames + 2; i++) { - int ysize = c->width * c->height; - int csize = (c->width / 2) * (c->height / 2); Picture pre_input, *pre_input_ptr = i ? s->input_picture[i - 1] : s->next_picture_ptr; - avcodec_get_frame_defaults(&input[i]); - input[i].data[0] = av_malloc(ysize + 2 * csize); - input[i].data[1] = input[i].data[0] + ysize; - input[i].data[2] = input[i].data[1] + csize; - input[i].linesize[0] = c->width; - input[i].linesize[1] = - input[i].linesize[2] = c->width / 2; - if (pre_input_ptr && (!i || s->input_picture[i - 1])) { pre_input = *pre_input_ptr; @@ -1198,13 +1231,13 @@ static int estimate_best_b_count(MpegEncContext *s) pre_input.f.data[2] += INPLACE_OFFSET; } - s->dsp.shrink[scale](input[i].data[0], input[i].linesize[0], + s->dsp.shrink[scale](s->tmp_frames[i]->data[0], s->tmp_frames[i]->linesize[0], pre_input.f.data[0], pre_input.f.linesize[0], c->width, c->height); - s->dsp.shrink[scale](input[i].data[1], input[i].linesize[1], + s->dsp.shrink[scale](s->tmp_frames[i]->data[1], s->tmp_frames[i]->linesize[1], pre_input.f.data[1], pre_input.f.linesize[1], c->width >> 1, c->height >> 1); - s->dsp.shrink[scale](input[i].data[2], input[i].linesize[2], + s->dsp.shrink[scale](s->tmp_frames[i]->data[2], s->tmp_frames[i]->linesize[2], pre_input.f.data[2], pre_input.f.linesize[2], c->width >> 1, c->height >> 1); } @@ -1218,21 +1251,21 @@ static int estimate_best_b_count(MpegEncContext *s) c->error[0] = c->error[1] = c->error[2] = 0; - input[0].pict_type = AV_PICTURE_TYPE_I; - input[0].quality = 1 * FF_QP2LAMBDA; + s->tmp_frames[0]->pict_type = AV_PICTURE_TYPE_I; + s->tmp_frames[0]->quality = 1 * FF_QP2LAMBDA; - out_size = encode_frame(c, &input[0]); + out_size = encode_frame(c, s->tmp_frames[0]); //rd += (out_size * lambda2) >> FF_LAMBDA_SHIFT; for (i = 0; i < s->max_b_frames + 1; i++) { int is_p = i % (j + 1) == j || i == s->max_b_frames; - input[i + 1].pict_type = is_p ? + s->tmp_frames[i + 1]->pict_type = is_p ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_B; - input[i + 1].quality = is_p ? p_lambda : b_lambda; + s->tmp_frames[i + 1]->quality = is_p ? p_lambda : b_lambda; - out_size = encode_frame(c, &input[i + 1]); + out_size = encode_frame(c, s->tmp_frames[i + 1]); rd += (out_size * lambda2) >> (FF_LAMBDA_SHIFT - 3); } @@ -1254,10 +1287,6 @@ static int estimate_best_b_count(MpegEncContext *s) avcodec_close(c); av_freep(&c); - for (i = 0; i < s->max_b_frames + 2; i++) { - av_freep(&input[i].data[0]); - } - return best_b_count; } @@ -1271,6 +1300,20 @@ static int select_input_picture(MpegEncContext *s) /* set next picture type & ordering */ if (s->reordered_input_picture[0] == NULL && s->input_picture[0]) { + if (s->avctx->frame_skip_threshold || s->avctx->frame_skip_factor) { + if (s->picture_in_gop_number < s->gop_size && + s->next_picture_ptr && + skip_check(s, s->input_picture[0], s->next_picture_ptr)) { + // FIXME check that te gop check above is +-1 correct + av_frame_unref(&s->input_picture[0]->f); + + emms_c(); + ff_vbv_update(s, 0); + + goto no_output_pic; + } + } + if (/*s->picture_in_gop_number >= s->gop_size ||*/ s->next_picture_ptr == NULL || s->intra_only) { s->reordered_input_picture[0] = s->input_picture[0]; @@ -1280,19 +1323,6 @@ static int select_input_picture(MpegEncContext *s) } else { int b_frames; - if (s->avctx->frame_skip_threshold || s->avctx->frame_skip_factor) { - if (s->picture_in_gop_number < s->gop_size && - skip_check(s, s->input_picture[0], s->next_picture_ptr)) { - // FIXME check that te gop check above is +-1 correct - av_frame_unref(&s->input_picture[0]->f); - - emms_c(); - ff_vbv_update(s, 0); - - goto no_output_pic; - } - } - if (s->flags & CODEC_FLAG_PASS2) { for (i = 0; i < s->max_b_frames + 1; i++) { int pict_num = s->input_picture[0]->f.display_picture_number + i; @@ -1411,8 +1441,9 @@ no_output_pic: return -1; } - copy_picture_attributes(s, &pic->f, - &s->reordered_input_picture[0]->f); + ret = av_frame_copy_props(&pic->f, &s->reordered_input_picture[0]->f); + if (ret < 0) + return ret; /* mark us unused / free shared pic */ av_frame_unref(&s->reordered_input_picture[0]->f); @@ -1438,6 +1469,39 @@ no_output_pic: return 0; } +static void frame_end(MpegEncContext *s) +{ + if (s->unrestricted_mv && + s->current_picture.reference && + !s->intra_only) { + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->avctx->pix_fmt); + int hshift = desc->log2_chroma_w; + int vshift = desc->log2_chroma_h; + s->dsp.draw_edges(s->current_picture.f.data[0], s->current_picture.f.linesize[0], + s->h_edge_pos, s->v_edge_pos, + EDGE_WIDTH, EDGE_WIDTH, + EDGE_TOP | EDGE_BOTTOM); + s->dsp.draw_edges(s->current_picture.f.data[1], s->current_picture.f.linesize[1], + s->h_edge_pos >> hshift, s->v_edge_pos >> vshift, + EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift, + EDGE_TOP | EDGE_BOTTOM); + s->dsp.draw_edges(s->current_picture.f.data[2], s->current_picture.f.linesize[2], + s->h_edge_pos >> hshift, s->v_edge_pos >> vshift, + EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift, + EDGE_TOP | EDGE_BOTTOM); + } + + emms_c(); + + s->last_pict_type = s->pict_type; + s->last_lambda_for [s->pict_type] = s->current_picture_ptr->f.quality; + if (s->pict_type!= AV_PICTURE_TYPE_B) + s->last_non_b_pict_type = s->pict_type; + + s->avctx->coded_frame = &s->current_picture_ptr->f; + +} + int ff_MPV_encode_picture(AVCodecContext *avctx, AVPacket *pkt, AVFrame *pic_arg, int *got_packet) { @@ -1493,10 +1557,10 @@ vbv_retry: avctx->p_count = s->mb_num - s->i_count - s->skip_count; avctx->skip_count = s->skip_count; - ff_MPV_frame_end(s); + frame_end(s); if (CONFIG_MJPEG_ENCODER && s->out_format == FMT_MJPEG) - ff_mjpeg_encode_picture_trailer(s); + ff_mjpeg_encode_picture_trailer(&s->pb, s->header_bits); if (avctx->rc_buffer_size) { RateControlContext *rcc = &s->rc_context; @@ -1635,6 +1699,13 @@ vbv_retry: } else { s->frame_bits = 0; } + + /* release non-reference frames */ + for (i = 0; i < MAX_PICTURE_COUNT; i++) { + if (!s->picture[i].reference) + ff_mpeg_unref_picture(s, &s->picture[i]); + } + assert((s->frame_bits & 7) == 0); pkt->size = s->frame_bits / 8; @@ -1771,7 +1842,7 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s, int dct_offset = s->linesize * 8; // default for progressive frames int uv_dct_offset = s->uvlinesize * 8; uint8_t *ptr_y, *ptr_cb, *ptr_cr; - int wrap_y, wrap_c; + ptrdiff_t wrap_y, wrap_c; for (i = 0; i < mb_block_count; i++) skip_dct[i] = s->skipdct; @@ -1815,19 +1886,25 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s, ptr_cr = s->new_picture.f.data[2] + (mb_y * mb_block_height * wrap_c) + mb_x * mb_block_width; - if((mb_x*16+16 > s->width || mb_y*16+16 > s->height) && s->codec_id != AV_CODEC_ID_AMV){ + if((mb_x * 16 + 16 > s->width || mb_y * 16 + 16 > s->height) && s->codec_id != AV_CODEC_ID_AMV){ uint8_t *ebuf = s->edge_emu_buffer + 32; int cw = (s->width + s->chroma_x_shift) >> s->chroma_x_shift; int ch = (s->height + s->chroma_y_shift) >> s->chroma_y_shift; - s->vdsp.emulated_edge_mc(ebuf, ptr_y, wrap_y, 16, 16, mb_x * 16, - mb_y * 16, s->width, s->height); + s->vdsp.emulated_edge_mc(ebuf, ptr_y, + wrap_y, wrap_y, + 16, 16, mb_x * 16, mb_y * 16, + s->width, s->height); ptr_y = ebuf; - s->vdsp.emulated_edge_mc(ebuf + 18 * wrap_y, ptr_cb, wrap_c, mb_block_width, - mb_block_height, mb_x * mb_block_width, mb_y * mb_block_height, + s->vdsp.emulated_edge_mc(ebuf + 18 * wrap_y, ptr_cb, + wrap_c, wrap_c, + mb_block_width, mb_block_height, + mb_x * mb_block_width, mb_y * mb_block_height, cw, ch); ptr_cb = ebuf + 18 * wrap_y; - s->vdsp.emulated_edge_mc(ebuf + 18 * wrap_y + 16, ptr_cr, wrap_c, mb_block_width, - mb_block_height, mb_x * mb_block_width, mb_y * mb_block_height, + s->vdsp.emulated_edge_mc(ebuf + 18 * wrap_y + 16, ptr_cr, + wrap_c, wrap_c, + mb_block_width, mb_block_height, + mb_x * mb_block_width, mb_y * mb_block_height, cw, ch); ptr_cr = ebuf + 18 * wrap_y + 16; } @@ -2567,6 +2644,7 @@ static int encode_thread(AVCodecContext *c, void *arg){ if(is_gob_start){ if(s->start_mb_y != mb_y || mb_x!=0){ write_slice_end(s); + if(CONFIG_MPEG4_ENCODER && s->codec_id==AV_CODEC_ID_MPEG4 && s->partitioned_frame){ ff_mpeg4_init_partitions(s); } @@ -2575,9 +2653,9 @@ static int encode_thread(AVCodecContext *c, void *arg){ av_assert2((put_bits_count(&s->pb)&7) == 0); current_packet_size= put_bits_ptr(&s->pb) - s->ptr_lastgob; - if(s->avctx->error_rate && s->resync_mb_x + s->resync_mb_y > 0){ + if (s->error_rate && s->resync_mb_x + s->resync_mb_y > 0) { int r= put_bits_count(&s->pb)/8 + s->picture_number + 16 + s->mb_x + s->mb_y; - int d= 100 / s->avctx->error_rate; + int d = 100 / s->error_rate; if(r % d == 0){ current_packet_size=0; s->pb.buf_ptr= s->ptr_lastgob; @@ -3372,7 +3450,8 @@ static int encode_picture(MpegEncContext *s, int picture_number) switch(s->out_format) { case FMT_MJPEG: if (CONFIG_MJPEG_ENCODER) - ff_mjpeg_encode_picture_header(s); + ff_mjpeg_encode_picture_header(s->avctx, &s->pb, &s->intra_scantable, + s->intra_matrix); break; case FMT_H261: if (CONFIG_H261_ENCODER) @@ -3572,7 +3651,7 @@ static int dct_quantize_trellis_c(MpegEncContext *s, av_assert2(level); - if(s->out_format == FMT_H263){ + if(s->out_format == FMT_H263 || s->out_format == FMT_H261){ unquant_coeff= alevel*qmul + qadd; }else{ //MPEG1 j= s->dsp.idct_permutation[ scantable[i] ]; //FIXME optimize @@ -3601,7 +3680,7 @@ static int dct_quantize_trellis_c(MpegEncContext *s, } } - if(s->out_format == FMT_H263){ + if(s->out_format == FMT_H263 || s->out_format == FMT_H261){ for(j=survivor_count-1; j>=0; j--){ int run= i - survivor[j]; int score= distortion + last_length[UNI_AC_ENC_INDEX(run, level)]*lambda; @@ -3627,7 +3706,7 @@ static int dct_quantize_trellis_c(MpegEncContext *s, } } - if(s->out_format == FMT_H263){ + if(s->out_format == FMT_H263 || s->out_format == FMT_H261){ for(j=survivor_count-1; j>=0; j--){ int run= i - survivor[j]; int score= distortion + score_tab[i-run]; @@ -3660,7 +3739,7 @@ static int dct_quantize_trellis_c(MpegEncContext *s, survivor[ survivor_count++ ]= i+1; } - if(s->out_format != FMT_H263){ + if(s->out_format != FMT_H263 && s->out_format != FMT_H261){ last_score= 256*256*256*120; for(i= survivor[0]; i<=last_non_zero + 1; i++){ int score= score_tab[i]; @@ -3693,7 +3772,7 @@ static int dct_quantize_trellis_c(MpegEncContext *s, int alevel= FFABS(level); int unquant_coeff, score, distortion; - if(s->out_format == FMT_H263){ + if(s->out_format == FMT_H263 || s->out_format == FMT_H261){ unquant_coeff= (alevel*qmul + qadd)>>3; }else{ //MPEG1 unquant_coeff = ((( alevel << 1) + 1) * qscale * ((int) s->inter_matrix[0])) >> 4; @@ -4225,6 +4304,7 @@ static const AVClass h263_class = { AVCodec ff_h263_encoder = { .name = "h263", + .long_name = NULL_IF_CONFIG_SMALL("H.263 / H.263-1996"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H263, .priv_data_size = sizeof(MpegEncContext), @@ -4232,7 +4312,6 @@ AVCodec ff_h263_encoder = { .encode2 = ff_MPV_encode_picture, .close = ff_MPV_encode_end, .pix_fmts= (const enum AVPixelFormat[]){AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("H.263 / H.263-1996"), .priv_class = &h263_class, }; @@ -4253,6 +4332,7 @@ static const AVClass h263p_class = { AVCodec ff_h263p_encoder = { .name = "h263p", + .long_name = NULL_IF_CONFIG_SMALL("H.263+ / H.263-1998 / H.263 version 2"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H263P, .priv_data_size = sizeof(MpegEncContext), @@ -4261,7 +4341,6 @@ AVCodec ff_h263p_encoder = { .close = ff_MPV_encode_end, .capabilities = CODEC_CAP_SLICE_THREADS, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("H.263+ / H.263-1998 / H.263 version 2"), .priv_class = &h263p_class, }; @@ -4269,6 +4348,7 @@ FF_MPV_GENERIC_CLASS(msmpeg4v2) AVCodec ff_msmpeg4v2_encoder = { .name = "msmpeg4v2", + .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 2"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MSMPEG4V2, .priv_data_size = sizeof(MpegEncContext), @@ -4276,7 +4356,6 @@ AVCodec ff_msmpeg4v2_encoder = { .encode2 = ff_MPV_encode_picture, .close = ff_MPV_encode_end, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 2"), .priv_class = &msmpeg4v2_class, }; @@ -4284,6 +4363,7 @@ FF_MPV_GENERIC_CLASS(msmpeg4v3) AVCodec ff_msmpeg4v3_encoder = { .name = "msmpeg4", + .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 3"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MSMPEG4V3, .priv_data_size = sizeof(MpegEncContext), @@ -4291,7 +4371,6 @@ AVCodec ff_msmpeg4v3_encoder = { .encode2 = ff_MPV_encode_picture, .close = ff_MPV_encode_end, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 3"), .priv_class = &msmpeg4v3_class, }; @@ -4299,6 +4378,7 @@ FF_MPV_GENERIC_CLASS(wmv1) AVCodec ff_wmv1_encoder = { .name = "wmv1", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 7"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_WMV1, .priv_data_size = sizeof(MpegEncContext), @@ -4306,6 +4386,5 @@ AVCodec ff_wmv1_encoder = { .encode2 = ff_MPV_encode_picture, .close = ff_MPV_encode_end, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 7"), .priv_class = &wmv1_class, }; diff --git a/ffmpeg/libavcodec/mpegvideo_motion.c b/ffmpeg/libavcodec/mpegvideo_motion.c index beb4d6c..9ec3789 100644 --- a/ffmpeg/libavcodec/mpegvideo_motion.c +++ b/ffmpeg/libavcodec/mpegvideo_motion.c @@ -27,6 +27,7 @@ #include "libavutil/internal.h" #include "avcodec.h" #include "dsputil.h" +#include "h261.h" #include "mpegvideo.h" #include "mjpegenc.h" #include "msmpeg4.h" @@ -37,85 +38,96 @@ static void gmc1_motion(MpegEncContext *s, uint8_t **ref_picture) { uint8_t *ptr; - int offset, src_x, src_y, linesize, uvlinesize; - int motion_x, motion_y; - int emu=0; - - motion_x= s->sprite_offset[0][0]; - motion_y= s->sprite_offset[0][1]; - src_x = s->mb_x * 16 + (motion_x >> (s->sprite_warping_accuracy+1)); - src_y = s->mb_y * 16 + (motion_y >> (s->sprite_warping_accuracy+1)); - motion_x<<=(3-s->sprite_warping_accuracy); - motion_y<<=(3-s->sprite_warping_accuracy); - src_x = av_clip(src_x, -16, s->width); + int src_x, src_y, motion_x, motion_y; + ptrdiff_t offset, linesize, uvlinesize; + int emu = 0; + + motion_x = s->sprite_offset[0][0]; + motion_y = s->sprite_offset[0][1]; + src_x = s->mb_x * 16 + (motion_x >> (s->sprite_warping_accuracy + 1)); + src_y = s->mb_y * 16 + (motion_y >> (s->sprite_warping_accuracy + 1)); + motion_x <<= (3 - s->sprite_warping_accuracy); + motion_y <<= (3 - s->sprite_warping_accuracy); + src_x = av_clip(src_x, -16, s->width); if (src_x == s->width) - motion_x =0; + motion_x = 0; src_y = av_clip(src_y, -16, s->height); if (src_y == s->height) - motion_y =0; + motion_y = 0; - linesize = s->linesize; + linesize = s->linesize; uvlinesize = s->uvlinesize; - ptr = ref_picture[0] + (src_y * linesize) + src_x; + ptr = ref_picture[0] + src_y * linesize + src_x; - if(s->flags&CODEC_FLAG_EMU_EDGE){ - if( (unsigned)src_x >= FFMAX(s->h_edge_pos - 17, 0) - || (unsigned)src_y >= FFMAX(s->v_edge_pos - 17, 0)){ - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, linesize, 17, 17, src_x, src_y, s->h_edge_pos, s->v_edge_pos); - ptr= s->edge_emu_buffer; + if ((unsigned)src_x >= FFMAX(s->h_edge_pos - 17, 0) || + (unsigned)src_y >= FFMAX(s->v_edge_pos - 17, 0)) { + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, + linesize, linesize, + 17, 17, + src_x, src_y, + s->h_edge_pos, s->v_edge_pos); + ptr = s->edge_emu_buffer; } - } - if((motion_x|motion_y)&7){ - s->dsp.gmc1(dest_y , ptr , linesize, 16, motion_x&15, motion_y&15, 128 - s->no_rounding); - s->dsp.gmc1(dest_y+8, ptr+8, linesize, 16, motion_x&15, motion_y&15, 128 - s->no_rounding); - }else{ + if ((motion_x | motion_y) & 7) { + s->dsp.gmc1(dest_y, ptr, linesize, 16, + motion_x & 15, motion_y & 15, 128 - s->no_rounding); + s->dsp.gmc1(dest_y + 8, ptr + 8, linesize, 16, + motion_x & 15, motion_y & 15, 128 - s->no_rounding); + } else { int dxy; - dxy= ((motion_x>>3)&1) | ((motion_y>>2)&2); - if (s->no_rounding){ + dxy = ((motion_x >> 3) & 1) | ((motion_y >> 2) & 2); + if (s->no_rounding) { s->hdsp.put_no_rnd_pixels_tab[0][dxy](dest_y, ptr, linesize, 16); - }else{ - s->hdsp.put_pixels_tab [0][dxy](dest_y, ptr, linesize, 16); + } else { + s->hdsp.put_pixels_tab[0][dxy](dest_y, ptr, linesize, 16); } } - if(CONFIG_GRAY && s->flags&CODEC_FLAG_GRAY) return; - - motion_x= s->sprite_offset[1][0]; - motion_y= s->sprite_offset[1][1]; - src_x = s->mb_x * 8 + (motion_x >> (s->sprite_warping_accuracy+1)); - src_y = s->mb_y * 8 + (motion_y >> (s->sprite_warping_accuracy+1)); - motion_x<<=(3-s->sprite_warping_accuracy); - motion_y<<=(3-s->sprite_warping_accuracy); - src_x = av_clip(src_x, -8, s->width>>1); - if (src_x == s->width>>1) - motion_x =0; - src_y = av_clip(src_y, -8, s->height>>1); - if (src_y == s->height>>1) - motion_y =0; + if (CONFIG_GRAY && s->flags & CODEC_FLAG_GRAY) + return; + + motion_x = s->sprite_offset[1][0]; + motion_y = s->sprite_offset[1][1]; + src_x = s->mb_x * 8 + (motion_x >> (s->sprite_warping_accuracy + 1)); + src_y = s->mb_y * 8 + (motion_y >> (s->sprite_warping_accuracy + 1)); + motion_x <<= (3 - s->sprite_warping_accuracy); + motion_y <<= (3 - s->sprite_warping_accuracy); + src_x = av_clip(src_x, -8, s->width >> 1); + if (src_x == s->width >> 1) + motion_x = 0; + src_y = av_clip(src_y, -8, s->height >> 1); + if (src_y == s->height >> 1) + motion_y = 0; offset = (src_y * uvlinesize) + src_x; - ptr = ref_picture[1] + offset; - if(s->flags&CODEC_FLAG_EMU_EDGE){ - if( (unsigned)src_x >= FFMAX((s->h_edge_pos>>1) - 9, 0) - || (unsigned)src_y >= FFMAX((s->v_edge_pos>>1) - 9, 0)){ - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1); - ptr= s->edge_emu_buffer; - emu=1; + ptr = ref_picture[1] + offset; + if ((unsigned)src_x >= FFMAX((s->h_edge_pos >> 1) - 9, 0) || + (unsigned)src_y >= FFMAX((s->v_edge_pos >> 1) - 9, 0)) { + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, + uvlinesize, uvlinesize, + 9, 9, + src_x, src_y, + s->h_edge_pos >> 1, s->v_edge_pos >> 1); + ptr = s->edge_emu_buffer; + emu = 1; } - } - s->dsp.gmc1(dest_cb, ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding); + s->dsp.gmc1(dest_cb, ptr, uvlinesize, 8, + motion_x & 15, motion_y & 15, 128 - s->no_rounding); ptr = ref_picture[2] + offset; - if(emu){ - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1); - ptr= s->edge_emu_buffer; + if (emu) { + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, + uvlinesize, uvlinesize, + 9, 9, + src_x, src_y, + s->h_edge_pos >> 1, s->v_edge_pos >> 1); + ptr = s->edge_emu_buffer; } - s->dsp.gmc1(dest_cr, ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding); - - return; + s->dsp.gmc1(dest_cr, ptr, uvlinesize, 8, + motion_x & 15, motion_y & 15, 128 - s->no_rounding); } static void gmc_motion(MpegEncContext *s, @@ -124,70 +136,72 @@ static void gmc_motion(MpegEncContext *s, { uint8_t *ptr; int linesize, uvlinesize; - const int a= s->sprite_warping_accuracy; + const int a = s->sprite_warping_accuracy; int ox, oy; - linesize = s->linesize; + linesize = s->linesize; uvlinesize = s->uvlinesize; ptr = ref_picture[0]; - ox= s->sprite_offset[0][0] + s->sprite_delta[0][0]*s->mb_x*16 + s->sprite_delta[0][1]*s->mb_y*16; - oy= s->sprite_offset[0][1] + s->sprite_delta[1][0]*s->mb_x*16 + s->sprite_delta[1][1]*s->mb_y*16; + ox = s->sprite_offset[0][0] + s->sprite_delta[0][0] * s->mb_x * 16 + + s->sprite_delta[0][1] * s->mb_y * 16; + oy = s->sprite_offset[0][1] + s->sprite_delta[1][0] * s->mb_x * 16 + + s->sprite_delta[1][1] * s->mb_y * 16; s->dsp.gmc(dest_y, ptr, linesize, 16, - ox, - oy, - s->sprite_delta[0][0], s->sprite_delta[0][1], - s->sprite_delta[1][0], s->sprite_delta[1][1], - a+1, (1<<(2*a+1)) - s->no_rounding, - s->h_edge_pos, s->v_edge_pos); - s->dsp.gmc(dest_y+8, ptr, linesize, 16, - ox + s->sprite_delta[0][0]*8, - oy + s->sprite_delta[1][0]*8, - s->sprite_delta[0][0], s->sprite_delta[0][1], - s->sprite_delta[1][0], s->sprite_delta[1][1], - a+1, (1<<(2*a+1)) - s->no_rounding, - s->h_edge_pos, s->v_edge_pos); - - if(CONFIG_GRAY && s->flags&CODEC_FLAG_GRAY) return; - - ox= s->sprite_offset[1][0] + s->sprite_delta[0][0]*s->mb_x*8 + s->sprite_delta[0][1]*s->mb_y*8; - oy= s->sprite_offset[1][1] + s->sprite_delta[1][0]*s->mb_x*8 + s->sprite_delta[1][1]*s->mb_y*8; + ox, oy, + s->sprite_delta[0][0], s->sprite_delta[0][1], + s->sprite_delta[1][0], s->sprite_delta[1][1], + a + 1, (1 << (2 * a + 1)) - s->no_rounding, + s->h_edge_pos, s->v_edge_pos); + s->dsp.gmc(dest_y + 8, ptr, linesize, 16, + ox + s->sprite_delta[0][0] * 8, + oy + s->sprite_delta[1][0] * 8, + s->sprite_delta[0][0], s->sprite_delta[0][1], + s->sprite_delta[1][0], s->sprite_delta[1][1], + a + 1, (1 << (2 * a + 1)) - s->no_rounding, + s->h_edge_pos, s->v_edge_pos); + + if (CONFIG_GRAY && s->flags & CODEC_FLAG_GRAY) + return; + + ox = s->sprite_offset[1][0] + s->sprite_delta[0][0] * s->mb_x * 8 + + s->sprite_delta[0][1] * s->mb_y * 8; + oy = s->sprite_offset[1][1] + s->sprite_delta[1][0] * s->mb_x * 8 + + s->sprite_delta[1][1] * s->mb_y * 8; ptr = ref_picture[1]; s->dsp.gmc(dest_cb, ptr, uvlinesize, 8, - ox, - oy, - s->sprite_delta[0][0], s->sprite_delta[0][1], - s->sprite_delta[1][0], s->sprite_delta[1][1], - a+1, (1<<(2*a+1)) - s->no_rounding, - s->h_edge_pos>>1, s->v_edge_pos>>1); + ox, oy, + s->sprite_delta[0][0], s->sprite_delta[0][1], + s->sprite_delta[1][0], s->sprite_delta[1][1], + a + 1, (1 << (2 * a + 1)) - s->no_rounding, + s->h_edge_pos >> 1, s->v_edge_pos >> 1); ptr = ref_picture[2]; s->dsp.gmc(dest_cr, ptr, uvlinesize, 8, - ox, - oy, - s->sprite_delta[0][0], s->sprite_delta[0][1], - s->sprite_delta[1][0], s->sprite_delta[1][1], - a+1, (1<<(2*a+1)) - s->no_rounding, - s->h_edge_pos>>1, s->v_edge_pos>>1); + ox, oy, + s->sprite_delta[0][0], s->sprite_delta[0][1], + s->sprite_delta[1][0], s->sprite_delta[1][1], + a + 1, (1 << (2 * a + 1)) - s->no_rounding, + s->h_edge_pos >> 1, s->v_edge_pos >> 1); } static inline int hpel_motion(MpegEncContext *s, - uint8_t *dest, uint8_t *src, - int src_x, int src_y, - op_pixels_func *pix_op, - int motion_x, int motion_y) + uint8_t *dest, uint8_t *src, + int src_x, int src_y, + op_pixels_func *pix_op, + int motion_x, int motion_y) { int dxy = 0; - int emu=0; + int emu = 0; src_x += motion_x >> 1; src_y += motion_y >> 1; /* WARNING: do no forget half pels */ - src_x = av_clip(src_x, -16, s->width); //FIXME unneeded for emu? + src_x = av_clip(src_x, -16, s->width); // FIXME unneeded for emu? if (src_x != s->width) dxy |= motion_x & 1; src_y = av_clip(src_y, -16, s->height); @@ -195,13 +209,16 @@ static inline int hpel_motion(MpegEncContext *s, dxy |= (motion_y & 1) << 1; src += src_y * s->linesize + src_x; - if(s->unrestricted_mv && (s->flags&CODEC_FLAG_EMU_EDGE)){ - if( (unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x&1) - 8, 0) - || (unsigned)src_y > FFMAX(s->v_edge_pos - (motion_y&1) - 8, 0)){ - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, 9, 9, - src_x, src_y, s->h_edge_pos, s->v_edge_pos); - src= s->edge_emu_buffer; - emu=1; + if (s->flags & CODEC_FLAG_EMU_EDGE) { + if ((unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x & 1) - 8, 0) || + (unsigned)src_y > FFMAX(s->v_edge_pos - (motion_y & 1) - 8, 0)) { + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, src, + s->linesize, s->linesize, + 9, 9, + src_x, src_y, + s->h_edge_pos, s->v_edge_pos); + src = s->edge_emu_buffer; + emu = 1; } } pix_op[dxy](dest, src, s->linesize, 8); @@ -210,66 +227,76 @@ static inline int hpel_motion(MpegEncContext *s, static av_always_inline void mpeg_motion_internal(MpegEncContext *s, - uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, - int field_based, int bottom_field, int field_select, - uint8_t **ref_picture, op_pixels_func (*pix_op)[4], - int motion_x, int motion_y, int h, int is_mpeg12, int mb_y) + uint8_t *dest_y, + uint8_t *dest_cb, + uint8_t *dest_cr, + int field_based, + int bottom_field, + int field_select, + uint8_t **ref_picture, + op_pixels_func (*pix_op)[4], + int motion_x, + int motion_y, + int h, + int is_mpeg12, + int mb_y) { uint8_t *ptr_y, *ptr_cb, *ptr_cr; int dxy, uvdxy, mx, my, src_x, src_y, - uvsrc_x, uvsrc_y, v_edge_pos, uvlinesize, linesize; + uvsrc_x, uvsrc_y, v_edge_pos; + ptrdiff_t uvlinesize, linesize; #if 0 -if(s->quarter_sample) -{ - motion_x>>=1; - motion_y>>=1; -} + if (s->quarter_sample) { + motion_x >>= 1; + motion_y >>= 1; + } #endif v_edge_pos = s->v_edge_pos >> field_based; linesize = s->current_picture.f.linesize[0] << field_based; uvlinesize = s->current_picture.f.linesize[1] << field_based; - dxy = ((motion_y & 1) << 1) | (motion_x & 1); - src_x = s->mb_x* 16 + (motion_x >> 1); - src_y =( mb_y<<(4-field_based)) + (motion_y >> 1); + dxy = ((motion_y & 1) << 1) | (motion_x & 1); + src_x = s->mb_x * 16 + (motion_x >> 1); + src_y = (mb_y << (4 - field_based)) + (motion_y >> 1); if (!is_mpeg12 && s->out_format == FMT_H263) { - if((s->workaround_bugs & FF_BUG_HPEL_CHROMA) && field_based){ - mx = (motion_x>>1)|(motion_x&1); - my = motion_y >>1; - uvdxy = ((my & 1) << 1) | (mx & 1); - uvsrc_x = s->mb_x* 8 + (mx >> 1); - uvsrc_y =( mb_y<<(3-field_based))+ (my >> 1); - }else{ - uvdxy = dxy | (motion_y & 2) | ((motion_x & 2) >> 1); - uvsrc_x = src_x>>1; - uvsrc_y = src_y>>1; + if ((s->workaround_bugs & FF_BUG_HPEL_CHROMA) && field_based) { + mx = (motion_x >> 1) | (motion_x & 1); + my = motion_y >> 1; + uvdxy = ((my & 1) << 1) | (mx & 1); + uvsrc_x = s->mb_x * 8 + (mx >> 1); + uvsrc_y = (mb_y << (3 - field_based)) + (my >> 1); + } else { + uvdxy = dxy | (motion_y & 2) | ((motion_x & 2) >> 1); + uvsrc_x = src_x >> 1; + uvsrc_y = src_y >> 1; } - }else if(!is_mpeg12 && s->out_format == FMT_H261){//even chroma mv's are full pel in H261 - mx = motion_x / 4; - my = motion_y / 4; - uvdxy = 0; - uvsrc_x = s->mb_x*8 + mx; - uvsrc_y = mb_y*8 + my; + // Even chroma mv's are full pel in H261 + } else if (!is_mpeg12 && s->out_format == FMT_H261) { + mx = motion_x / 4; + my = motion_y / 4; + uvdxy = 0; + uvsrc_x = s->mb_x * 8 + mx; + uvsrc_y = mb_y * 8 + my; } else { - if(s->chroma_y_shift){ - mx = motion_x / 2; - my = motion_y / 2; - uvdxy = ((my & 1) << 1) | (mx & 1); - uvsrc_x = s->mb_x* 8 + (mx >> 1); - uvsrc_y =( mb_y<<(3-field_based))+ (my >> 1); + if (s->chroma_y_shift) { + mx = motion_x / 2; + my = motion_y / 2; + uvdxy = ((my & 1) << 1) | (mx & 1); + uvsrc_x = s->mb_x * 8 + (mx >> 1); + uvsrc_y = (mb_y << (3 - field_based)) + (my >> 1); } else { - if(s->chroma_x_shift){ - //Chroma422 - mx = motion_x / 2; - uvdxy = ((motion_y & 1) << 1) | (mx & 1); - uvsrc_x = s->mb_x* 8 + (mx >> 1); + if (s->chroma_x_shift) { + // Chroma422 + mx = motion_x / 2; + uvdxy = ((motion_y & 1) << 1) | (mx & 1); + uvsrc_x = s->mb_x * 8 + (mx >> 1); uvsrc_y = src_y; } else { - //Chroma444 - uvdxy = dxy; + // Chroma444 + uvdxy = dxy; uvsrc_x = src_x; uvsrc_y = src_y; } @@ -280,58 +307,63 @@ if(s->quarter_sample) ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x; ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x; - if( (unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x&1) - 16, 0) - || (unsigned)src_y > FFMAX( v_edge_pos - (motion_y&1) - h , 0)){ - if(is_mpeg12 || s->codec_id == AV_CODEC_ID_MPEG2VIDEO || - s->codec_id == AV_CODEC_ID_MPEG1VIDEO){ - av_log(s->avctx,AV_LOG_DEBUG, - "MPEG motion vector out of boundary (%d %d)\n", src_x, src_y); - return; - } - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize, - 17, 17+field_based, - src_x, src_y<h_edge_pos, s->v_edge_pos); - ptr_y = s->edge_emu_buffer; - if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ - uint8_t *uvbuf= s->edge_emu_buffer+18*s->linesize; - s->vdsp.emulated_edge_mc(uvbuf , - ptr_cb, s->uvlinesize, - 9, 9+field_based, - uvsrc_x, uvsrc_y<h_edge_pos>>1, s->v_edge_pos>>1); - s->vdsp.emulated_edge_mc(uvbuf+16, - ptr_cr, s->uvlinesize, - 9, 9+field_based, - uvsrc_x, uvsrc_y<h_edge_pos>>1, s->v_edge_pos>>1); - ptr_cb= uvbuf; - ptr_cr= uvbuf+16; - } + if ((unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x & 1) - 16, 0) || + (unsigned)src_y > FFMAX( v_edge_pos - (motion_y & 1) - h , 0)) { + if (is_mpeg12 || + s->codec_id == AV_CODEC_ID_MPEG2VIDEO || + s->codec_id == AV_CODEC_ID_MPEG1VIDEO) { + av_log(s->avctx, AV_LOG_DEBUG, + "MPEG motion vector out of boundary (%d %d)\n", src_x, + src_y); + return; + } + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y, + s->linesize, s->linesize, + 17, 17 + field_based, + src_x, src_y << field_based, + s->h_edge_pos, s->v_edge_pos); + ptr_y = s->edge_emu_buffer; + if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) { + uint8_t *uvbuf = s->edge_emu_buffer + 18 * s->linesize; + s->vdsp.emulated_edge_mc(uvbuf, ptr_cb, + s->uvlinesize, s->uvlinesize, + 9, 9 + field_based, + uvsrc_x, uvsrc_y << field_based, + s->h_edge_pos >> 1, s->v_edge_pos >> 1); + s->vdsp.emulated_edge_mc(uvbuf + 16, ptr_cr, + s->uvlinesize, s->uvlinesize, + 9, 9 + field_based, + uvsrc_x, uvsrc_y << field_based, + s->h_edge_pos >> 1, s->v_edge_pos >> 1); + ptr_cb = uvbuf; + ptr_cr = uvbuf + 16; + } } - if(bottom_field){ //FIXME use this for field pix too instead of the obnoxious hack which changes picture.data - dest_y += s->linesize; - dest_cb+= s->uvlinesize; - dest_cr+= s->uvlinesize; + /* FIXME use this for field pix too instead of the obnoxious hack which + * changes picture.data */ + if (bottom_field) { + dest_y += s->linesize; + dest_cb += s->uvlinesize; + dest_cr += s->uvlinesize; } - if(field_select){ - ptr_y += s->linesize; - ptr_cb+= s->uvlinesize; - ptr_cr+= s->uvlinesize; + if (field_select) { + ptr_y += s->linesize; + ptr_cb += s->uvlinesize; + ptr_cr += s->uvlinesize; } pix_op[0][dxy](dest_y, ptr_y, linesize, h); - if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ + if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) { pix_op[s->chroma_x_shift][uvdxy] - (dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift); + (dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift); pix_op[s->chroma_x_shift][uvdxy] - (dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift); + (dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift); } - if(!is_mpeg12 && (CONFIG_H261_ENCODER || CONFIG_H261_DECODER) && - s->out_format == FMT_H261){ + if (!is_mpeg12 && (CONFIG_H261_ENCODER || CONFIG_H261_DECODER) && + s->out_format == FMT_H261) { ff_h261_loop_filter(s); } } @@ -343,15 +375,15 @@ static void mpeg_motion(MpegEncContext *s, int motion_x, int motion_y, int h, int mb_y) { #if !CONFIG_SMALL - if(s->out_format == FMT_MPEG1) + if (s->out_format == FMT_MPEG1) mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 0, 0, - field_select, ref_picture, pix_op, - motion_x, motion_y, h, 1, mb_y); + field_select, ref_picture, pix_op, + motion_x, motion_y, h, 1, mb_y); else #endif mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 0, 0, - field_select, ref_picture, pix_op, - motion_x, motion_y, h, 0, mb_y); + field_select, ref_picture, pix_op, + motion_x, motion_y, h, 0, mb_y); } static void mpeg_motion_field(MpegEncContext *s, uint8_t *dest_y, @@ -362,25 +394,26 @@ static void mpeg_motion_field(MpegEncContext *s, uint8_t *dest_y, int motion_x, int motion_y, int h, int mb_y) { #if !CONFIG_SMALL - if(s->out_format == FMT_MPEG1) + if (s->out_format == FMT_MPEG1) mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 1, - bottom_field, field_select, ref_picture, pix_op, - motion_x, motion_y, h, 1, mb_y); + bottom_field, field_select, ref_picture, pix_op, + motion_x, motion_y, h, 1, mb_y); else #endif mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 1, - bottom_field, field_select, ref_picture, pix_op, - motion_x, motion_y, h, 0, mb_y); + bottom_field, field_select, ref_picture, pix_op, + motion_x, motion_y, h, 0, mb_y); } -//FIXME move to dsputil, avg variant, 16x16 version -static inline void put_obmc(uint8_t *dst, uint8_t *src[5], int stride){ +// FIXME move to dsputil, avg variant, 16x16 version +static inline void put_obmc(uint8_t *dst, uint8_t *src[5], int stride) +{ int x; - uint8_t * const top = src[1]; - uint8_t * const left = src[2]; - uint8_t * const mid = src[0]; - uint8_t * const right = src[3]; - uint8_t * const bottom= src[4]; + uint8_t *const top = src[1]; + uint8_t *const left = src[2]; + uint8_t *const mid = src[0]; + uint8_t *const right = src[3]; + uint8_t *const bottom = src[4]; #define OBMC_FILTER(x, t, l, m, r, b)\ dst[x]= (t*top[x] + l*left[x] + m*mid[x] + r*right[x] + b*bottom[x] + 4)>>3 #define OBMC_FILTER4(x, t, l, m, r, b)\ @@ -389,40 +422,40 @@ static inline void put_obmc(uint8_t *dst, uint8_t *src[5], int stride){ OBMC_FILTER(x +stride, t, l, m, r, b);\ OBMC_FILTER(x+1+stride, t, l, m, r, b); - x=0; - OBMC_FILTER (x , 2, 2, 4, 0, 0); - OBMC_FILTER (x+1, 2, 1, 5, 0, 0); - OBMC_FILTER4(x+2, 2, 1, 5, 0, 0); - OBMC_FILTER4(x+4, 2, 0, 5, 1, 0); - OBMC_FILTER (x+6, 2, 0, 5, 1, 0); - OBMC_FILTER (x+7, 2, 0, 4, 2, 0); - x+= stride; - OBMC_FILTER (x , 1, 2, 5, 0, 0); - OBMC_FILTER (x+1, 1, 2, 5, 0, 0); - OBMC_FILTER (x+6, 1, 0, 5, 2, 0); - OBMC_FILTER (x+7, 1, 0, 5, 2, 0); - x+= stride; - OBMC_FILTER4(x , 1, 2, 5, 0, 0); - OBMC_FILTER4(x+2, 1, 1, 6, 0, 0); - OBMC_FILTER4(x+4, 1, 0, 6, 1, 0); - OBMC_FILTER4(x+6, 1, 0, 5, 2, 0); - x+= 2*stride; - OBMC_FILTER4(x , 0, 2, 5, 0, 1); - OBMC_FILTER4(x+2, 0, 1, 6, 0, 1); - OBMC_FILTER4(x+4, 0, 0, 6, 1, 1); - OBMC_FILTER4(x+6, 0, 0, 5, 2, 1); - x+= 2*stride; - OBMC_FILTER (x , 0, 2, 5, 0, 1); - OBMC_FILTER (x+1, 0, 2, 5, 0, 1); - OBMC_FILTER4(x+2, 0, 1, 5, 0, 2); - OBMC_FILTER4(x+4, 0, 0, 5, 1, 2); - OBMC_FILTER (x+6, 0, 0, 5, 2, 1); - OBMC_FILTER (x+7, 0, 0, 5, 2, 1); - x+= stride; - OBMC_FILTER (x , 0, 2, 4, 0, 2); - OBMC_FILTER (x+1, 0, 1, 5, 0, 2); - OBMC_FILTER (x+6, 0, 0, 5, 1, 2); - OBMC_FILTER (x+7, 0, 0, 4, 2, 2); + x = 0; + OBMC_FILTER (x , 2, 2, 4, 0, 0); + OBMC_FILTER (x + 1, 2, 1, 5, 0, 0); + OBMC_FILTER4(x + 2, 2, 1, 5, 0, 0); + OBMC_FILTER4(x + 4, 2, 0, 5, 1, 0); + OBMC_FILTER (x + 6, 2, 0, 5, 1, 0); + OBMC_FILTER (x + 7, 2, 0, 4, 2, 0); + x += stride; + OBMC_FILTER (x , 1, 2, 5, 0, 0); + OBMC_FILTER (x + 1, 1, 2, 5, 0, 0); + OBMC_FILTER (x + 6, 1, 0, 5, 2, 0); + OBMC_FILTER (x + 7, 1, 0, 5, 2, 0); + x += stride; + OBMC_FILTER4(x , 1, 2, 5, 0, 0); + OBMC_FILTER4(x + 2, 1, 1, 6, 0, 0); + OBMC_FILTER4(x + 4, 1, 0, 6, 1, 0); + OBMC_FILTER4(x + 6, 1, 0, 5, 2, 0); + x += 2 * stride; + OBMC_FILTER4(x , 0, 2, 5, 0, 1); + OBMC_FILTER4(x + 2, 0, 1, 6, 0, 1); + OBMC_FILTER4(x + 4, 0, 0, 6, 1, 1); + OBMC_FILTER4(x + 6, 0, 0, 5, 2, 1); + x += 2*stride; + OBMC_FILTER (x , 0, 2, 5, 0, 1); + OBMC_FILTER (x + 1, 0, 2, 5, 0, 1); + OBMC_FILTER4(x + 2, 0, 1, 5, 0, 2); + OBMC_FILTER4(x + 4, 0, 0, 5, 1, 2); + OBMC_FILTER (x + 6, 0, 0, 5, 2, 1); + OBMC_FILTER (x + 7, 0, 0, 5, 2, 1); + x += stride; + OBMC_FILTER (x , 0, 2, 4, 0, 2); + OBMC_FILTER (x + 1, 0, 1, 5, 0, 2); + OBMC_FILTER (x + 6, 0, 0, 5, 1, 2); + OBMC_FILTER (x + 7, 0, 0, 4, 2, 2); } /* obmc for 1 8x8 luma block */ @@ -430,22 +463,21 @@ static inline void obmc_motion(MpegEncContext *s, uint8_t *dest, uint8_t *src, int src_x, int src_y, op_pixels_func *pix_op, - int16_t mv[5][2]/* mid top left right bottom*/) + int16_t mv[5][2] /* mid top left right bottom */) #define MID 0 { int i; uint8_t *ptr[5]; - av_assert2(s->quarter_sample==0); + av_assert2(s->quarter_sample == 0); - for(i=0; i<5; i++){ - if(i && mv[i][0]==mv[MID][0] && mv[i][1]==mv[MID][1]){ - ptr[i]= ptr[MID]; - }else{ - ptr[i]= s->obmc_scratchpad + 8*(i&1) + s->linesize*8*(i>>1); - hpel_motion(s, ptr[i], src, - src_x, src_y, - pix_op, + for (i = 0; i < 5; i++) { + if (i && mv[i][0] == mv[MID][0] && mv[i][1] == mv[MID][1]) { + ptr[i] = ptr[MID]; + } else { + ptr[i] = s->obmc_scratchpad + 8 * (i & 1) + + s->linesize * 8 * (i >> 1); + hpel_motion(s, ptr[i], src, src_x, src_y, pix_op, mv[i][0], mv[i][1]); } } @@ -454,92 +486,101 @@ static inline void obmc_motion(MpegEncContext *s, } static inline void qpel_motion(MpegEncContext *s, - uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, - int field_based, int bottom_field, int field_select, - uint8_t **ref_picture, op_pixels_func (*pix_op)[4], + uint8_t *dest_y, + uint8_t *dest_cb, + uint8_t *dest_cr, + int field_based, int bottom_field, + int field_select, uint8_t **ref_picture, + op_pixels_func (*pix_op)[4], qpel_mc_func (*qpix_op)[16], int motion_x, int motion_y, int h) { uint8_t *ptr_y, *ptr_cb, *ptr_cr; - int dxy, uvdxy, mx, my, src_x, src_y, uvsrc_x, uvsrc_y, v_edge_pos, linesize, uvlinesize; + int dxy, uvdxy, mx, my, src_x, src_y, uvsrc_x, uvsrc_y, v_edge_pos; + ptrdiff_t linesize, uvlinesize; + + dxy = ((motion_y & 3) << 2) | (motion_x & 3); - dxy = ((motion_y & 3) << 2) | (motion_x & 3); src_x = s->mb_x * 16 + (motion_x >> 2); src_y = s->mb_y * (16 >> field_based) + (motion_y >> 2); v_edge_pos = s->v_edge_pos >> field_based; - linesize = s->linesize << field_based; + linesize = s->linesize << field_based; uvlinesize = s->uvlinesize << field_based; - if(field_based){ - mx= motion_x/2; - my= motion_y>>1; - }else if(s->workaround_bugs&FF_BUG_QPEL_CHROMA2){ - static const int rtab[8]= {0,0,1,1,0,0,0,1}; - mx= (motion_x>>1) + rtab[motion_x&7]; - my= (motion_y>>1) + rtab[motion_y&7]; - }else if(s->workaround_bugs&FF_BUG_QPEL_CHROMA){ - mx= (motion_x>>1)|(motion_x&1); - my= (motion_y>>1)|(motion_y&1); - }else{ - mx= motion_x/2; - my= motion_y/2; + if (field_based) { + mx = motion_x / 2; + my = motion_y >> 1; + } else if (s->workaround_bugs & FF_BUG_QPEL_CHROMA2) { + static const int rtab[8] = { 0, 0, 1, 1, 0, 0, 0, 1 }; + mx = (motion_x >> 1) + rtab[motion_x & 7]; + my = (motion_y >> 1) + rtab[motion_y & 7]; + } else if (s->workaround_bugs & FF_BUG_QPEL_CHROMA) { + mx = (motion_x >> 1) | (motion_x & 1); + my = (motion_y >> 1) | (motion_y & 1); + } else { + mx = motion_x / 2; + my = motion_y / 2; } - mx= (mx>>1)|(mx&1); - my= (my>>1)|(my&1); + mx = (mx >> 1) | (mx & 1); + my = (my >> 1) | (my & 1); - uvdxy= (mx&1) | ((my&1)<<1); - mx>>=1; - my>>=1; + uvdxy = (mx & 1) | ((my & 1) << 1); + mx >>= 1; + my >>= 1; uvsrc_x = s->mb_x * 8 + mx; uvsrc_y = s->mb_y * (8 >> field_based) + my; - ptr_y = ref_picture[0] + src_y * linesize + src_x; + ptr_y = ref_picture[0] + src_y * linesize + src_x; ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x; ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x; - if( (unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x&3) - 16, 0) - || (unsigned)src_y > FFMAX( v_edge_pos - (motion_y&3) - h , 0)){ - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize, - 17, 17+field_based, src_x, src_y<h_edge_pos, s->v_edge_pos); - ptr_y= s->edge_emu_buffer; - if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ - uint8_t *uvbuf= s->edge_emu_buffer + 18*s->linesize; - s->vdsp.emulated_edge_mc(uvbuf, ptr_cb, s->uvlinesize, - 9, 9 + field_based, - uvsrc_x, uvsrc_y<h_edge_pos>>1, s->v_edge_pos>>1); - s->vdsp.emulated_edge_mc(uvbuf + 16, ptr_cr, s->uvlinesize, - 9, 9 + field_based, - uvsrc_x, uvsrc_y<h_edge_pos>>1, s->v_edge_pos>>1); - ptr_cb= uvbuf; - ptr_cr= uvbuf + 16; + if ((unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x & 3) - 16, 0) || + (unsigned)src_y > FFMAX( v_edge_pos - (motion_y & 3) - h, 0)) { + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y, + s->linesize, s->linesize, + 17, 17 + field_based, + src_x, src_y << field_based, + s->h_edge_pos, s->v_edge_pos); + ptr_y = s->edge_emu_buffer; + if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) { + uint8_t *uvbuf = s->edge_emu_buffer + 18 * s->linesize; + s->vdsp.emulated_edge_mc(uvbuf, ptr_cb, + s->uvlinesize, s->uvlinesize, + 9, 9 + field_based, + uvsrc_x, uvsrc_y << field_based, + s->h_edge_pos >> 1, s->v_edge_pos >> 1); + s->vdsp.emulated_edge_mc(uvbuf + 16, ptr_cr, + s->uvlinesize, s->uvlinesize, + 9, 9 + field_based, + uvsrc_x, uvsrc_y << field_based, + s->h_edge_pos >> 1, s->v_edge_pos >> 1); + ptr_cb = uvbuf; + ptr_cr = uvbuf + 16; } } - if(!field_based) + if (!field_based) qpix_op[0][dxy](dest_y, ptr_y, linesize); - else{ - if(bottom_field){ - dest_y += s->linesize; - dest_cb+= s->uvlinesize; - dest_cr+= s->uvlinesize; + else { + if (bottom_field) { + dest_y += s->linesize; + dest_cb += s->uvlinesize; + dest_cr += s->uvlinesize; } - if(field_select){ + if (field_select) { ptr_y += s->linesize; ptr_cb += s->uvlinesize; ptr_cr += s->uvlinesize; } - //damn interlaced mode - //FIXME boundary mirroring is not exactly correct here - qpix_op[1][dxy](dest_y , ptr_y , linesize); - qpix_op[1][dxy](dest_y+8, ptr_y+8, linesize); + // damn interlaced mode + // FIXME boundary mirroring is not exactly correct here + qpix_op[1][dxy](dest_y, ptr_y, linesize); + qpix_op[1][dxy](dest_y + 8, ptr_y + 8, linesize); } - if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ + if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) { pix_op[1][uvdxy](dest_cr, ptr_cr, uvlinesize, h >> 1); pix_op[1][uvdxy](dest_cb, ptr_cb, uvlinesize, h >> 1); } @@ -554,15 +595,16 @@ static void chroma_4mv_motion(MpegEncContext *s, op_pixels_func *pix_op, int mx, int my) { - int dxy, emu=0, src_x, src_y, offset; uint8_t *ptr; + int src_x, src_y, dxy, emu = 0; + ptrdiff_t offset; /* In case of 8X8, we construct a single chroma motion vector - with a special rounding */ - mx= ff_h263_round_chroma(mx); - my= ff_h263_round_chroma(my); + * with a special rounding */ + mx = ff_h263_round_chroma(mx); + my = ff_h263_round_chroma(my); - dxy = ((my & 1) << 1) | (mx & 1); + dxy = ((my & 1) << 1) | (mx & 1); mx >>= 1; my >>= 1; @@ -576,39 +618,204 @@ static void chroma_4mv_motion(MpegEncContext *s, dxy &= ~2; offset = src_y * s->uvlinesize + src_x; - ptr = ref_picture[1] + offset; - if(s->flags&CODEC_FLAG_EMU_EDGE){ - if( (unsigned)src_x > FFMAX((s->h_edge_pos>>1) - (dxy &1) - 8, 0) - || (unsigned)src_y > FFMAX((s->v_edge_pos>>1) - (dxy>>1) - 8, 0)){ - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, - 9, 9, src_x, src_y, - s->h_edge_pos>>1, s->v_edge_pos>>1); - ptr= s->edge_emu_buffer; - emu=1; + ptr = ref_picture[1] + offset; + if (s->flags & CODEC_FLAG_EMU_EDGE) { + if ((unsigned)src_x > FFMAX((s->h_edge_pos >> 1) - (dxy & 1) - 8, 0) || + (unsigned)src_y > FFMAX((s->v_edge_pos >> 1) - (dxy >> 1) - 8, 0)) { + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, + s->uvlinesize, s->uvlinesize, + 9, 9, src_x, src_y, + s->h_edge_pos >> 1, s->v_edge_pos >> 1); + ptr = s->edge_emu_buffer; + emu = 1; } } pix_op[dxy](dest_cb, ptr, s->uvlinesize, 8); ptr = ref_picture[2] + offset; - if(emu){ - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, - 9, 9, src_x, src_y, - s->h_edge_pos>>1, s->v_edge_pos>>1); - ptr= s->edge_emu_buffer; + if (emu) { + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, + s->uvlinesize, s->uvlinesize, + 9, 9, src_x, src_y, + s->h_edge_pos >> 1, s->v_edge_pos >> 1); + ptr = s->edge_emu_buffer; } pix_op[dxy](dest_cr, ptr, s->uvlinesize, 8); } -static inline void prefetch_motion(MpegEncContext *s, uint8_t **pix, int dir){ +static inline void prefetch_motion(MpegEncContext *s, uint8_t **pix, int dir) +{ /* fetch pixels for estimated mv 4 macroblocks ahead * optimized for 64byte cache lines */ const int shift = s->quarter_sample ? 2 : 1; - const int mx= (s->mv[dir][0][0]>>shift) + 16*s->mb_x + 8; - const int my= (s->mv[dir][0][1]>>shift) + 16*s->mb_y; - int off= mx + (my + (s->mb_x&3)*4)*s->linesize + 64; - s->vdsp.prefetch(pix[0]+off, s->linesize, 4); - off= (mx>>1) + ((my>>1) + (s->mb_x&7))*s->uvlinesize + 64; - s->vdsp.prefetch(pix[1]+off, pix[2]-pix[1], 2); + const int mx = (s->mv[dir][0][0] >> shift) + 16 * s->mb_x + 8; + const int my = (s->mv[dir][0][1] >> shift) + 16 * s->mb_y; + int off = mx + (my + (s->mb_x & 3) * 4) * s->linesize + 64; + + s->vdsp.prefetch(pix[0] + off, s->linesize, 4); + off = (mx >> 1) + ((my >> 1) + (s->mb_x & 7)) * s->uvlinesize + 64; + s->vdsp.prefetch(pix[1] + off, pix[2] - pix[1], 2); +} + +static inline void apply_obmc(MpegEncContext *s, + uint8_t *dest_y, + uint8_t *dest_cb, + uint8_t *dest_cr, + uint8_t **ref_picture, + op_pixels_func (*pix_op)[4]) +{ + LOCAL_ALIGNED_8(int16_t, mv_cache, [4], [4][2]); + Picture *cur_frame = &s->current_picture; + int mb_x = s->mb_x; + int mb_y = s->mb_y; + const int xy = mb_x + mb_y * s->mb_stride; + const int mot_stride = s->b8_stride; + const int mot_xy = mb_x * 2 + mb_y * 2 * mot_stride; + int mx, my, i; + + av_assert2(!s->mb_skipped); + + AV_COPY32(mv_cache[1][1], cur_frame->motion_val[0][mot_xy]); + AV_COPY32(mv_cache[1][2], cur_frame->motion_val[0][mot_xy + 1]); + + AV_COPY32(mv_cache[2][1], + cur_frame->motion_val[0][mot_xy + mot_stride]); + AV_COPY32(mv_cache[2][2], + cur_frame->motion_val[0][mot_xy + mot_stride + 1]); + + AV_COPY32(mv_cache[3][1], + cur_frame->motion_val[0][mot_xy + mot_stride]); + AV_COPY32(mv_cache[3][2], + cur_frame->motion_val[0][mot_xy + mot_stride + 1]); + + if (mb_y == 0 || IS_INTRA(cur_frame->mb_type[xy - s->mb_stride])) { + AV_COPY32(mv_cache[0][1], mv_cache[1][1]); + AV_COPY32(mv_cache[0][2], mv_cache[1][2]); + } else { + AV_COPY32(mv_cache[0][1], + cur_frame->motion_val[0][mot_xy - mot_stride]); + AV_COPY32(mv_cache[0][2], + cur_frame->motion_val[0][mot_xy - mot_stride + 1]); + } + + if (mb_x == 0 || IS_INTRA(cur_frame->mb_type[xy - 1])) { + AV_COPY32(mv_cache[1][0], mv_cache[1][1]); + AV_COPY32(mv_cache[2][0], mv_cache[2][1]); + } else { + AV_COPY32(mv_cache[1][0], cur_frame->motion_val[0][mot_xy - 1]); + AV_COPY32(mv_cache[2][0], + cur_frame->motion_val[0][mot_xy - 1 + mot_stride]); + } + + if (mb_x + 1 >= s->mb_width || IS_INTRA(cur_frame->mb_type[xy + 1])) { + AV_COPY32(mv_cache[1][3], mv_cache[1][2]); + AV_COPY32(mv_cache[2][3], mv_cache[2][2]); + } else { + AV_COPY32(mv_cache[1][3], cur_frame->motion_val[0][mot_xy + 2]); + AV_COPY32(mv_cache[2][3], + cur_frame->motion_val[0][mot_xy + 2 + mot_stride]); + } + + mx = 0; + my = 0; + for (i = 0; i < 4; i++) { + const int x = (i & 1) + 1; + const int y = (i >> 1) + 1; + int16_t mv[5][2] = { + { mv_cache[y][x][0], mv_cache[y][x][1] }, + { mv_cache[y - 1][x][0], mv_cache[y - 1][x][1] }, + { mv_cache[y][x - 1][0], mv_cache[y][x - 1][1] }, + { mv_cache[y][x + 1][0], mv_cache[y][x + 1][1] }, + { mv_cache[y + 1][x][0], mv_cache[y + 1][x][1] } + }; + // FIXME cleanup + obmc_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize, + ref_picture[0], + mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >> 1) * 8, + pix_op[1], + mv); + + mx += mv[0][0]; + my += mv[0][1]; + } + if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) + chroma_4mv_motion(s, dest_cb, dest_cr, + ref_picture, pix_op[1], + mx, my); +} + +static inline void apply_8x8(MpegEncContext *s, + uint8_t *dest_y, + uint8_t *dest_cb, + uint8_t *dest_cr, + int dir, + uint8_t **ref_picture, + qpel_mc_func (*qpix_op)[16], + op_pixels_func (*pix_op)[4]) +{ + int dxy, mx, my, src_x, src_y; + int i; + int mb_x = s->mb_x; + int mb_y = s->mb_y; + uint8_t *ptr, *dest; + + mx = 0; + my = 0; + if (s->quarter_sample) { + for (i = 0; i < 4; i++) { + int motion_x = s->mv[dir][i][0]; + int motion_y = s->mv[dir][i][1]; + + dxy = ((motion_y & 3) << 2) | (motion_x & 3); + src_x = mb_x * 16 + (motion_x >> 2) + (i & 1) * 8; + src_y = mb_y * 16 + (motion_y >> 2) + (i >> 1) * 8; + + /* WARNING: do no forget half pels */ + src_x = av_clip(src_x, -16, s->width); + if (src_x == s->width) + dxy &= ~3; + src_y = av_clip(src_y, -16, s->height); + if (src_y == s->height) + dxy &= ~12; + + ptr = ref_picture[0] + (src_y * s->linesize) + (src_x); + if (s->flags & CODEC_FLAG_EMU_EDGE) { + if ((unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x & 3) - 8, 0) || + (unsigned)src_y > FFMAX(s->v_edge_pos - (motion_y & 3) - 8, 0)) { + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, + s->linesize, s->linesize, + 9, 9, + src_x, src_y, + s->h_edge_pos, + s->v_edge_pos); + ptr = s->edge_emu_buffer; + } + } + dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize; + qpix_op[1][dxy](dest, ptr, s->linesize); + + mx += s->mv[dir][i][0] / 2; + my += s->mv[dir][i][1] / 2; + } + } else { + for (i = 0; i < 4; i++) { + hpel_motion(s, + dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize, + ref_picture[0], + mb_x * 16 + (i & 1) * 8, + mb_y * 16 + (i >> 1) * 8, + pix_op[1], + s->mv[dir][i][0], + s->mv[dir][i][1]); + + mx += s->mv[dir][i][0]; + my += s->mv[dir][i][1]; + } + } + + if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) + chroma_4mv_motion(s, dest_cb, dest_cr, + ref_picture, pix_op[1], mx, my); } /** @@ -624,101 +831,36 @@ static inline void prefetch_motion(MpegEncContext *s, uint8_t **pix, int dir){ * the motion vectors are taken from s->mv and the MV type from s->mv_type */ static av_always_inline void MPV_motion_internal(MpegEncContext *s, - uint8_t *dest_y, uint8_t *dest_cb, - uint8_t *dest_cr, int dir, - uint8_t **ref_picture, - op_pixels_func (*pix_op)[4], - qpel_mc_func (*qpix_op)[16], int is_mpeg12) + uint8_t *dest_y, + uint8_t *dest_cb, + uint8_t *dest_cr, + int dir, + uint8_t **ref_picture, + op_pixels_func (*pix_op)[4], + qpel_mc_func (*qpix_op)[16], + int is_mpeg12) { - int dxy, mx, my, src_x, src_y, motion_x, motion_y; - int mb_x, mb_y, i; - uint8_t *ptr, *dest; - - mb_x = s->mb_x; - mb_y = s->mb_y; + int i; + int mb_y = s->mb_y; prefetch_motion(s, ref_picture, dir); - if(!is_mpeg12 && s->obmc && s->pict_type != AV_PICTURE_TYPE_B){ - LOCAL_ALIGNED_8(int16_t, mv_cache, [4], [4][2]); - Picture *cur_frame = &s->current_picture; - const int xy= s->mb_x + s->mb_y*s->mb_stride; - const int mot_stride= s->b8_stride; - const int mot_xy= mb_x*2 + mb_y*2*mot_stride; - - av_assert2(!s->mb_skipped); - - AV_COPY32(mv_cache[1][1], cur_frame->motion_val[0][mot_xy ]); - AV_COPY32(mv_cache[1][2], cur_frame->motion_val[0][mot_xy + 1]); - - AV_COPY32(mv_cache[2][1], cur_frame->motion_val[0][mot_xy + mot_stride ]); - AV_COPY32(mv_cache[2][2], cur_frame->motion_val[0][mot_xy + mot_stride + 1]); - - AV_COPY32(mv_cache[3][1], cur_frame->motion_val[0][mot_xy + mot_stride ]); - AV_COPY32(mv_cache[3][2], cur_frame->motion_val[0][mot_xy + mot_stride + 1]); - - if (mb_y == 0 || IS_INTRA(cur_frame->mb_type[xy - s->mb_stride])) { - AV_COPY32(mv_cache[0][1], mv_cache[1][1]); - AV_COPY32(mv_cache[0][2], mv_cache[1][2]); - }else{ - AV_COPY32(mv_cache[0][1], cur_frame->motion_val[0][mot_xy - mot_stride ]); - AV_COPY32(mv_cache[0][2], cur_frame->motion_val[0][mot_xy - mot_stride + 1]); - } - - if (mb_x == 0 || IS_INTRA(cur_frame->mb_type[xy - 1])) { - AV_COPY32(mv_cache[1][0], mv_cache[1][1]); - AV_COPY32(mv_cache[2][0], mv_cache[2][1]); - }else{ - AV_COPY32(mv_cache[1][0], cur_frame->motion_val[0][mot_xy - 1]); - AV_COPY32(mv_cache[2][0], cur_frame->motion_val[0][mot_xy - 1 + mot_stride]); - } - - if (mb_x + 1 >= s->mb_width || IS_INTRA(cur_frame->mb_type[xy + 1])) { - AV_COPY32(mv_cache[1][3], mv_cache[1][2]); - AV_COPY32(mv_cache[2][3], mv_cache[2][2]); - }else{ - AV_COPY32(mv_cache[1][3], cur_frame->motion_val[0][mot_xy + 2]); - AV_COPY32(mv_cache[2][3], cur_frame->motion_val[0][mot_xy + 2 + mot_stride]); - } - - mx = 0; - my = 0; - for(i=0;i<4;i++) { - const int x= (i&1)+1; - const int y= (i>>1)+1; - int16_t mv[5][2]= { - {mv_cache[y][x ][0], mv_cache[y][x ][1]}, - {mv_cache[y-1][x][0], mv_cache[y-1][x][1]}, - {mv_cache[y][x-1][0], mv_cache[y][x-1][1]}, - {mv_cache[y][x+1][0], mv_cache[y][x+1][1]}, - {mv_cache[y+1][x][0], mv_cache[y+1][x][1]}}; - //FIXME cleanup - obmc_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize, - ref_picture[0], - mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8, - pix_op[1], - mv); - - mx += mv[0][0]; - my += mv[0][1]; - } - if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)) - chroma_4mv_motion(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my); - + if (!is_mpeg12 && s->obmc && s->pict_type != AV_PICTURE_TYPE_B) { + apply_obmc(s, dest_y, dest_cb, dest_cr, ref_picture, pix_op); return; } - switch(s->mv_type) { + switch (s->mv_type) { case MV_TYPE_16X16: - if(s->mcsel){ - if(s->real_sprite_warping_points==1){ + if (s->mcsel) { + if (s->real_sprite_warping_points == 1) { gmc1_motion(s, dest_y, dest_cb, dest_cr, ref_picture); - }else{ + } else { gmc_motion(s, dest_y, dest_cb, dest_cr, - ref_picture); + ref_picture); } - }else if(!is_mpeg12 && s->quarter_sample){ + } else if (!is_mpeg12 && s->quarter_sample) { qpel_motion(s, dest_y, dest_cb, dest_cr, 0, 0, 0, ref_picture, pix_op, qpix_op, @@ -726,80 +868,28 @@ static av_always_inline void MPV_motion_internal(MpegEncContext *s, } else if (!is_mpeg12 && (CONFIG_WMV2_DECODER || CONFIG_WMV2_ENCODER) && s->mspel && s->codec_id == AV_CODEC_ID_WMV2) { ff_mspel_motion(s, dest_y, dest_cb, dest_cr, - ref_picture, pix_op, - s->mv[dir][0][0], s->mv[dir][0][1], 16); - }else - { + ref_picture, pix_op, + s->mv[dir][0][0], s->mv[dir][0][1], 16); + } else { mpeg_motion(s, dest_y, dest_cb, dest_cr, 0, ref_picture, pix_op, s->mv[dir][0][0], s->mv[dir][0][1], 16, mb_y); } break; case MV_TYPE_8X8: - if (!is_mpeg12) { - mx = 0; - my = 0; - if(s->quarter_sample){ - for(i=0;i<4;i++) { - motion_x = s->mv[dir][i][0]; - motion_y = s->mv[dir][i][1]; - - dxy = ((motion_y & 3) << 2) | (motion_x & 3); - src_x = mb_x * 16 + (motion_x >> 2) + (i & 1) * 8; - src_y = mb_y * 16 + (motion_y >> 2) + (i >>1) * 8; - - /* WARNING: do no forget half pels */ - src_x = av_clip(src_x, -16, s->width); - if (src_x == s->width) - dxy &= ~3; - src_y = av_clip(src_y, -16, s->height); - if (src_y == s->height) - dxy &= ~12; - - ptr = ref_picture[0] + (src_y * s->linesize) + (src_x); - if(s->flags&CODEC_FLAG_EMU_EDGE){ - if( (unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x&3) - 8, 0) - || (unsigned)src_y > FFMAX(s->v_edge_pos - (motion_y&3) - 8, 0)){ - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, - s->linesize, 9, 9, - src_x, src_y, - s->h_edge_pos, s->v_edge_pos); - ptr= s->edge_emu_buffer; - } - } - dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize; - qpix_op[1][dxy](dest, ptr, s->linesize); - - mx += s->mv[dir][i][0]/2; - my += s->mv[dir][i][1]/2; - } - }else{ - for(i=0;i<4;i++) { - hpel_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize, - ref_picture[0], - mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8, - pix_op[1], - s->mv[dir][i][0], s->mv[dir][i][1]); - - mx += s->mv[dir][i][0]; - my += s->mv[dir][i][1]; - } - } - - if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)) - chroma_4mv_motion(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my); - } + if (!is_mpeg12) + apply_8x8(s, dest_y, dest_cb, dest_cr, + dir, ref_picture, qpix_op, pix_op); break; case MV_TYPE_FIELD: if (s->picture_structure == PICT_FRAME) { - if(!is_mpeg12 && s->quarter_sample){ - for(i=0; i<2; i++){ + if (!is_mpeg12 && s->quarter_sample) { + for (i = 0; i < 2; i++) qpel_motion(s, dest_y, dest_cb, dest_cr, 1, i, s->field_select[dir][i], ref_picture, pix_op, qpix_op, s->mv[dir][i][0], s->mv[dir][i][1], 8); - } - }else{ + } else { /* top field */ mpeg_motion_field(s, dest_y, dest_cb, dest_cr, 0, s->field_select[dir][0], @@ -812,66 +902,72 @@ static av_always_inline void MPV_motion_internal(MpegEncContext *s, s->mv[dir][1][0], s->mv[dir][1][1], 8, mb_y); } } else { - if(s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != AV_PICTURE_TYPE_B && !s->first_field){ + if ( s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != AV_PICTURE_TYPE_B && !s->first_field + || !ref_picture[0]) { ref_picture = s->current_picture_ptr->f.data; } mpeg_motion(s, dest_y, dest_cb, dest_cr, s->field_select[dir][0], ref_picture, pix_op, - s->mv[dir][0][0], s->mv[dir][0][1], 16, mb_y>>1); + s->mv[dir][0][0], s->mv[dir][0][1], 16, mb_y >> 1); } break; case MV_TYPE_16X8: - for(i=0; i<2; i++){ - uint8_t ** ref2picture; + for (i = 0; i < 2; i++) { + uint8_t **ref2picture; - if(s->picture_structure == s->field_select[dir][i] + 1 - || s->pict_type == AV_PICTURE_TYPE_B || s->first_field){ - ref2picture= ref_picture; - }else{ + if ((s->picture_structure == s->field_select[dir][i] + 1 + || s->pict_type == AV_PICTURE_TYPE_B || s->first_field) && ref_picture[0]) { + ref2picture = ref_picture; + } else { ref2picture = s->current_picture_ptr->f.data; } mpeg_motion(s, dest_y, dest_cb, dest_cr, s->field_select[dir][i], ref2picture, pix_op, - s->mv[dir][i][0], s->mv[dir][i][1] + 16*i, 8, mb_y>>1); + s->mv[dir][i][0], s->mv[dir][i][1] + 16 * i, + 8, mb_y >> 1); - dest_y += 16*s->linesize; - dest_cb+= (16>>s->chroma_y_shift)*s->uvlinesize; - dest_cr+= (16>>s->chroma_y_shift)*s->uvlinesize; + dest_y += 16 * s->linesize; + dest_cb += (16 >> s->chroma_y_shift) * s->uvlinesize; + dest_cr += (16 >> s->chroma_y_shift) * s->uvlinesize; } break; case MV_TYPE_DMV: - if(s->picture_structure == PICT_FRAME){ - for(i=0; i<2; i++){ + if (s->picture_structure == PICT_FRAME) { + for (i = 0; i < 2; i++) { int j; - for(j=0; j<2; j++){ + for (j = 0; j < 2; j++) mpeg_motion_field(s, dest_y, dest_cb, dest_cr, - j, j^i, ref_picture, pix_op, - s->mv[dir][2*i + j][0], - s->mv[dir][2*i + j][1], 8, mb_y); - } + j, j ^ i, ref_picture, pix_op, + s->mv[dir][2 * i + j][0], + s->mv[dir][2 * i + j][1], 8, mb_y); pix_op = s->hdsp.avg_pixels_tab; } - }else{ - for(i=0; i<2; i++){ + } else { + if (!ref_picture[0]) { + ref_picture = s->current_picture_ptr->f.data; + } + for (i = 0; i < 2; i++) { mpeg_motion(s, dest_y, dest_cb, dest_cr, - s->picture_structure != i+1, + s->picture_structure != i + 1, ref_picture, pix_op, - s->mv[dir][2*i][0],s->mv[dir][2*i][1],16, mb_y>>1); + s->mv[dir][2 * i][0], s->mv[dir][2 * i][1], + 16, mb_y >> 1); // after put we make avg of the same block - pix_op=s->hdsp.avg_pixels_tab; + pix_op = s->hdsp.avg_pixels_tab; - //opposite parity is always in the same frame if this is second field - if(!s->first_field){ + /* opposite parity is always in the same frame if this is + * second field */ + if (!s->first_field) { ref_picture = s->current_picture_ptr->f.data; } } } - break; + break; default: av_assert2(0); } } @@ -884,7 +980,7 @@ void ff_MPV_motion(MpegEncContext *s, qpel_mc_func (*qpix_op)[16]) { #if !CONFIG_SMALL - if(s->out_format == FMT_MPEG1) + if (s->out_format == FMT_MPEG1) MPV_motion_internal(s, dest_y, dest_cb, dest_cr, dir, ref_picture, pix_op, qpix_op, 1); else diff --git a/ffmpeg/libavcodec/mpegvideo_parser.c b/ffmpeg/libavcodec/mpegvideo_parser.c index 35a9160..7aa3660 100644 --- a/ffmpeg/libavcodec/mpegvideo_parser.c +++ b/ffmpeg/libavcodec/mpegvideo_parser.c @@ -21,7 +21,8 @@ */ #include "parser.h" -#include "mpegvideo.h" +#include "mpeg12.h" +#include "internal.h" struct MpvParseContext { ParseContext pc; @@ -50,7 +51,7 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s, while (buf < buf_end) { start_code= -1; - buf= avpriv_mpv_find_start_code(buf, buf_end, &start_code); + buf= avpriv_find_start_code(buf, buf_end, &start_code); bytes_left = buf_end - buf; switch(start_code) { case PICTURE_START_CODE: @@ -65,7 +66,7 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s, pc->width = (buf[0] << 4) | (buf[1] >> 4); pc->height = ((buf[1] & 0x0f) << 8) | buf[2]; if(!avctx->width || !avctx->height || !avctx->coded_width || !avctx->coded_height){ - avcodec_set_dimensions(avctx, pc->width, pc->height); + ff_set_dimensions(avctx, pc->width, pc->height); did_set_size=1; } frame_rate_index = buf[3] & 0xf; @@ -93,7 +94,7 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s, pc->height |=( vert_size_ext << 12); bit_rate = (bit_rate&0x3FFFF) | (bit_rate_ext << 18); if(did_set_size) - avcodec_set_dimensions(avctx, pc->width, pc->height); + ff_set_dimensions(avctx, pc->width, pc->height); avctx->time_base.den = pc->frame_rate.den * (frame_rate_ext_n + 1) * 2; avctx->time_base.num = pc->frame_rate.num * (frame_rate_ext_d + 1); avctx->codec_id = AV_CODEC_ID_MPEG2VIDEO; @@ -117,6 +118,14 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s, s->repeat_pict = 2; } } + + if (!pc->progressive_sequence) { + if (top_field_first) + s->field_order = AV_FIELD_TT; + else + s->field_order = AV_FIELD_BB; + } else + s->field_order = AV_FIELD_PROGRESSIVE; } break; } diff --git a/ffmpeg/libavcodec/mpegvideo_xvmc.c b/ffmpeg/libavcodec/mpegvideo_xvmc.c index 6b0c6ac..9fc97cb 100644 --- a/ffmpeg/libavcodec/mpegvideo_xvmc.c +++ b/ffmpeg/libavcodec/mpegvideo_xvmc.c @@ -30,6 +30,7 @@ #include "xvmc.h" #include "xvmc_internal.h" +#include "version.h" /** * Initialize the block field of the MpegEncContext pointer passed as @@ -46,6 +47,15 @@ void ff_xvmc_init_block(MpegEncContext *s) s->block = (int16_t (*)[64])(render->data_blocks + render->next_free_data_block_num * 64); } +static void exchange_uv(MpegEncContext *s) +{ + int16_t (*tmp)[64]; + + tmp = s->pblocks[4]; + s->pblocks[4] = s->pblocks[5]; + s->pblocks[5] = tmp; +} + /** * Fill individual block pointers, so there are no gaps in the data_block array * in case not all blocks in the macroblock are coded. @@ -63,6 +73,9 @@ void ff_xvmc_pack_pblocks(MpegEncContext *s, int cbp) s->pblocks[i] = NULL; cbp += cbp; } + if (s->swap_uv) { + exchange_uv(s); + } } /** @@ -70,8 +83,9 @@ void ff_xvmc_pack_pblocks(MpegEncContext *s, int cbp) * This function should be called for every new field and/or frame. * It should be safe to call the function a few times for the same field. */ -int ff_xvmc_field_start(MpegEncContext *s, AVCodecContext *avctx) +static int ff_xvmc_field_start(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size) { + struct MpegEncContext *s = avctx->priv_data; struct xvmc_pix_fmt *last, *next, *render = (struct xvmc_pix_fmt*)s->current_picture.f.data[2]; const int mb_block_count = 4 + (1 << s->chroma_format); @@ -138,20 +152,22 @@ return -1; * some leftover blocks, for example from error_resilience(), may remain. * It should be safe to call the function a few times for the same field. */ -void ff_xvmc_field_end(MpegEncContext *s) +static int ff_xvmc_field_end(AVCodecContext *avctx) { + struct MpegEncContext *s = avctx->priv_data; struct xvmc_pix_fmt *render = (struct xvmc_pix_fmt*)s->current_picture.f.data[2]; assert(render); if (render->filled_mv_blocks_num > 0) ff_mpeg_draw_horiz_band(s, 0, 0); + return 0; } /** * Synthesize the data needed by XvMC to render one macroblock of data. * Fill all relevant fields, if necessary do IDCT. */ -void ff_xvmc_decode_mb(MpegEncContext *s) +static void ff_xvmc_decode_mb(struct MpegEncContext *s) { XvMCMacroBlock *mv_block; struct xvmc_pix_fmt *render; @@ -310,7 +326,7 @@ void ff_xvmc_decode_mb(MpegEncContext *s) * slowdown. */ } // copy blocks only if the codec doesn't support pblocks reordering - if (s->avctx->xvmc_acceleration == 1) { + if (!s->pack_pblocks) { memcpy(&render->data_blocks[render->next_free_data_block_num*64], s->pblocks[i], sizeof(*s->pblocks[i])); } @@ -329,3 +345,31 @@ void ff_xvmc_decode_mb(MpegEncContext *s) if (render->filled_mv_blocks_num == render->allocated_mv_blocks) ff_mpeg_draw_horiz_band(s, 0, 0); } + +#if CONFIG_MPEG1_XVMC_HWACCEL +AVHWAccel ff_mpeg1_xvmc_hwaccel = { + .name = "mpeg1_xvmc", + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_MPEG1VIDEO, + .pix_fmt = AV_PIX_FMT_XVMC, + .start_frame = ff_xvmc_field_start, + .end_frame = ff_xvmc_field_end, + .decode_slice = NULL, + .decode_mb = ff_xvmc_decode_mb, + .priv_data_size = 0, +}; +#endif + +#if CONFIG_MPEG2_XVMC_HWACCEL +AVHWAccel ff_mpeg2_xvmc_hwaccel = { + .name = "mpeg2_xvmc", + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_MPEG2VIDEO, + .pix_fmt = AV_PIX_FMT_XVMC, + .start_frame = ff_xvmc_field_start, + .end_frame = ff_xvmc_field_end, + .decode_slice = NULL, + .decode_mb = ff_xvmc_decode_mb, + .priv_data_size = 0, +}; +#endif diff --git a/ffmpeg/libavcodec/mqc.c b/ffmpeg/libavcodec/mqc.c index 700b957..f8294cd 100644 --- a/ffmpeg/libavcodec/mqc.c +++ b/ffmpeg/libavcodec/mqc.c @@ -20,89 +20,96 @@ */ /** - * MQ-coder ecoder and decoder common functions + * MQ-coder common (decoder/encoder) functions * @file * @author Kamil Nowosad */ +#include +#include + #include "mqc.h" -typedef struct { - uint16_t qe; - uint8_t nmps; - uint8_t nlps; - uint8_t sw; +/* MQ coder context state structure */ +typedef struct MqcCxState { + uint16_t qe; + uint8_t nmps; + uint8_t nlps; + uint8_t sw; } MqcCxState; -const static MqcCxState cx_states[47] = { - {0x5601, 1, 1, 1}, - {0x3401, 2, 6, 0}, - {0x1801, 3, 9, 0}, - {0x0AC1, 4, 12, 0}, - {0x0521, 5, 29, 0}, - {0x0221, 38, 33, 0}, - {0x5601, 7, 6, 1}, - {0x5401, 8, 14, 0}, - {0x4801, 9, 14, 0}, - {0x3801, 10, 14, 0}, - {0x3001, 11, 17, 0}, - {0x2401, 12, 18, 0}, - {0x1C01, 13, 20, 0}, - {0x1601, 29, 21, 0}, - {0x5601, 15, 14, 1}, - {0x5401, 16, 14, 0}, - {0x5101, 17, 15, 0}, - {0x4801, 18, 16, 0}, - {0x3801, 19, 17, 0}, - {0x3401, 20, 18, 0}, - {0x3001, 21, 19, 0}, - {0x2801, 22, 19, 0}, - {0x2401, 23, 20, 0}, - {0x2201, 24, 21, 0}, - {0x1C01, 25, 22, 0}, - {0x1801, 26, 23, 0}, - {0x1601, 27, 24, 0}, - {0x1401, 28, 25, 0}, - {0x1201, 29, 26, 0}, - {0x1101, 30, 27, 0}, - {0x0AC1, 31, 28, 0}, - {0x09C1, 32, 29, 0}, - {0x08A1, 33, 30, 0}, - {0x0521, 34, 31, 0}, - {0x0441, 35, 32, 0}, - {0x02A1, 36, 33, 0}, - {0x0221, 37, 34, 0}, - {0x0141, 38, 35, 0}, - {0x0111, 39, 36, 0}, - {0x0085, 40, 37, 0}, - {0x0049, 41, 38, 0}, - {0x0025, 42, 39, 0}, - {0x0015, 43, 40, 0}, - {0x0009, 44, 41, 0}, - {0x0005, 45, 42, 0}, - {0x0001, 45, 43, 0}, - {0x5601, 46, 46, 0} +static const MqcCxState cx_states[47] = { + { 0x5601, 1, 1, 1 }, + { 0x3401, 2, 6, 0 }, + { 0x1801, 3, 9, 0 }, + { 0x0AC1, 4, 12, 0 }, + { 0x0521, 5, 29, 0 }, + { 0x0221, 38, 33, 0 }, + { 0x5601, 7, 6, 1 }, + { 0x5401, 8, 14, 0 }, + { 0x4801, 9, 14, 0 }, + { 0x3801, 10, 14, 0 }, + { 0x3001, 11, 17, 0 }, + { 0x2401, 12, 18, 0 }, + { 0x1C01, 13, 20, 0 }, + { 0x1601, 29, 21, 0 }, + { 0x5601, 15, 14, 1 }, + { 0x5401, 16, 14, 0 }, + { 0x5101, 17, 15, 0 }, + { 0x4801, 18, 16, 0 }, + { 0x3801, 19, 17, 0 }, + { 0x3401, 20, 18, 0 }, + { 0x3001, 21, 19, 0 }, + { 0x2801, 22, 19, 0 }, + { 0x2401, 23, 20, 0 }, + { 0x2201, 24, 21, 0 }, + { 0x1C01, 25, 22, 0 }, + { 0x1801, 26, 23, 0 }, + { 0x1601, 27, 24, 0 }, + { 0x1401, 28, 25, 0 }, + { 0x1201, 29, 26, 0 }, + { 0x1101, 30, 27, 0 }, + { 0x0AC1, 31, 28, 0 }, + { 0x09C1, 32, 29, 0 }, + { 0x08A1, 33, 30, 0 }, + { 0x0521, 34, 31, 0 }, + { 0x0441, 35, 32, 0 }, + { 0x02A1, 36, 33, 0 }, + { 0x0221, 37, 34, 0 }, + { 0x0141, 38, 35, 0 }, + { 0x0111, 39, 36, 0 }, + { 0x0085, 40, 37, 0 }, + { 0x0049, 41, 38, 0 }, + { 0x0025, 42, 39, 0 }, + { 0x0015, 43, 40, 0 }, + { 0x0009, 44, 41, 0 }, + { 0x0005, 45, 42, 0 }, + { 0x0001, 45, 43, 0 }, + { 0x5601, 46, 46, 0 } }; -uint16_t ff_mqc_qe [2*47]; -uint8_t ff_mqc_nlps[2*47]; -uint8_t ff_mqc_nmps[2*47]; +uint16_t ff_mqc_qe [2 * 47]; +uint8_t ff_mqc_nlps[2 * 47]; +uint8_t ff_mqc_nmps[2 * 47]; -void ff_mqc_init_contexts(MqcState *mqc) +void ff_mqc_init_context_tables(void) { int i; - memset(mqc->cx_states, 0, sizeof(mqc->cx_states)); - mqc->cx_states[MQC_CX_UNI] = 2 * 46; - mqc->cx_states[MQC_CX_RL] = 2 * 3; - mqc->cx_states[0] = 2 * 4; - - for (i = 0; i < 47; i++){ - ff_mqc_qe[2*i ] = - ff_mqc_qe[2*i+1] = cx_states[i].qe; + for (i = 0; i < 47; i++) { + ff_mqc_qe[2 * i] = + ff_mqc_qe[2 * i + 1] = cx_states[i].qe; - ff_mqc_nlps[2*i ] = 2*cx_states[i].nlps + cx_states[i].sw; - ff_mqc_nlps[2*i+1] = 2*cx_states[i].nlps + 1 - cx_states[i].sw; - ff_mqc_nmps[2*i ] = 2*cx_states[i].nmps; - ff_mqc_nmps[2*i+1] = 2*cx_states[i].nmps + 1; + ff_mqc_nlps[2 * i] = 2 * cx_states[i].nlps + cx_states[i].sw; + ff_mqc_nlps[2 * i + 1] = 2 * cx_states[i].nlps + 1 - cx_states[i].sw; + ff_mqc_nmps[2 * i] = 2 * cx_states[i].nmps; + ff_mqc_nmps[2 * i + 1] = 2 * cx_states[i].nmps + 1; } } + +void ff_mqc_init_contexts(MqcState *mqc) +{ + memset(mqc->cx_states, 0, sizeof(mqc->cx_states)); + mqc->cx_states[MQC_CX_UNI] = 2 * 46; + mqc->cx_states[MQC_CX_RL] = 2 * 3; + mqc->cx_states[0] = 2 * 4; +} diff --git a/ffmpeg/libavcodec/mqc.h b/ffmpeg/libavcodec/mqc.h index b28c13e..c0827bd 100644 --- a/ffmpeg/libavcodec/mqc.h +++ b/ffmpeg/libavcodec/mqc.h @@ -1,5 +1,5 @@ /* - * MQ-coder + * MQ-coder: structures, common and decoder functions * Copyright (c) 2007 Kamil Nowosad * * This file is part of FFmpeg. @@ -28,16 +28,16 @@ * @author Kamil Nowosad */ -#include "avcodec.h" +#include #define MQC_CX_UNI 17 #define MQC_CX_RL 18 -extern uint16_t ff_mqc_qe[2*47]; -extern uint8_t ff_mqc_nlps[2*47]; -extern uint8_t ff_mqc_nmps[2*47]; +extern uint16_t ff_mqc_qe[2 * 47]; +extern uint8_t ff_mqc_nlps[2 * 47]; +extern uint8_t ff_mqc_nmps[2 * 47]; -typedef struct { +typedef struct MqcState { uint8_t *bp, *bpstart; unsigned int a; unsigned int c; @@ -61,15 +61,32 @@ int ff_mqc_flush(MqcState *mqc); /* decoder */ -/** initialize the decoder */ +/** + * Initialize MQ-decoder. + * @param mqc MQ decoder state + * @param bp byte poiter + */ void ff_mqc_initdec(MqcState *mqc, uint8_t *bp); -/** returns decoded bit with context cx */ +/** + * MQ decoder. + * @param mqc MQ decoder state + * @param cxstate Context + * @return Decision (0 ot 1) + */ int ff_mqc_decode(MqcState *mqc, uint8_t *cxstate); /* common */ -/** initialize the contexts */ +/** + * MQ-coder Initialize context tables (QE, NLPS, NMPS) + */ +void ff_mqc_init_context_tables(void); + +/** + * MQ-coder context initialisations. + * @param mqc MQ-coder context + */ void ff_mqc_init_contexts(MqcState *mqc); #endif /* AVCODEC_MQC_H */ diff --git a/ffmpeg/libavcodec/mqcdec.c b/ffmpeg/libavcodec/mqcdec.c index 56e22f8..3625069 100644 --- a/ffmpeg/libavcodec/mqcdec.c +++ b/ffmpeg/libavcodec/mqcdec.c @@ -29,14 +29,14 @@ static void bytein(MqcState *mqc) { - if (*mqc->bp == 0xff){ - if (*(mqc->bp+1) > 0x8f) + if (*mqc->bp == 0xff) { + if (*(mqc->bp + 1) > 0x8f) mqc->c++; - else{ + else { mqc->bp++; mqc->c += 2 + 0xfe00 - (*mqc->bp << 9); } - } else{ + } else { mqc->bp++; mqc->c += 1 + 0xff00 - (*mqc->bp << 8); } @@ -45,20 +45,20 @@ static void bytein(MqcState *mqc) static int exchange(MqcState *mqc, uint8_t *cxstate, int lps) { int d; - if ((mqc->a < ff_mqc_qe[*cxstate]) ^ (!lps)){ + if ((mqc->a < ff_mqc_qe[*cxstate]) ^ (!lps)) { if (lps) mqc->a = ff_mqc_qe[*cxstate]; d = *cxstate & 1; *cxstate = ff_mqc_nmps[*cxstate]; - } else{ + } else { if (lps) mqc->a = ff_mqc_qe[*cxstate]; d = 1 - (*cxstate & 1); *cxstate = ff_mqc_nlps[*cxstate]; } - // renormd: - do{ - if (!(mqc->c & 0xff)){ + // do RENORMD: see ISO/IEC 15444-1:2002 §C.3.3 + do { + if (!(mqc->c & 0xff)) { mqc->c -= 0x100; bytein(mqc); } @@ -72,7 +72,7 @@ void ff_mqc_initdec(MqcState *mqc, uint8_t *bp) { ff_mqc_init_contexts(mqc); mqc->bp = bp; - mqc->c = (*mqc->bp ^ 0xff) << 16; + mqc->c = (*mqc->bp ^ 0xff) << 16; bytein(mqc); mqc->c = mqc->c << 7; mqc->a = 0x8000; @@ -81,7 +81,7 @@ void ff_mqc_initdec(MqcState *mqc, uint8_t *bp) int ff_mqc_decode(MqcState *mqc, uint8_t *cxstate) { mqc->a -= ff_mqc_qe[*cxstate]; - if ((mqc->c >> 16) < mqc->a){ + if ((mqc->c >> 16) < mqc->a) { if (mqc->a & 0x8000) return *cxstate & 1; else diff --git a/ffmpeg/libavcodec/msgsmdec.c b/ffmpeg/libavcodec/msgsmdec.c index 90e83ae..4c4ddb4 100644 --- a/ffmpeg/libavcodec/msgsmdec.c +++ b/ffmpeg/libavcodec/msgsmdec.c @@ -26,13 +26,13 @@ #include "gsmdec_template.c" int ff_msgsm_decode_block(AVCodecContext *avctx, int16_t *samples, - const uint8_t *buf) + const uint8_t *buf, int mode) { int res; GetBitContext gb; init_get_bits(&gb, buf, GSM_MS_BLOCK_SIZE * 8); - res = gsm_decode_block(avctx, samples, &gb); + res = gsm_decode_block(avctx, samples, &gb, mode); if (res < 0) return res; - return gsm_decode_block(avctx, samples + GSM_FRAME_SIZE, &gb); + return gsm_decode_block(avctx, samples + GSM_FRAME_SIZE, &gb, mode); } diff --git a/ffmpeg/libavcodec/msgsmdec.h b/ffmpeg/libavcodec/msgsmdec.h index 3bfd1fd..b2a1a62 100644 --- a/ffmpeg/libavcodec/msgsmdec.h +++ b/ffmpeg/libavcodec/msgsmdec.h @@ -25,6 +25,6 @@ #include "avcodec.h" int ff_msgsm_decode_block(AVCodecContext *avctx, int16_t *samples, - const uint8_t *buf); + const uint8_t *buf, int mode); #endif /* AVCODEC_MSGSMDEC_H */ diff --git a/ffmpeg/libavcodec/msmpeg4.c b/ffmpeg/libavcodec/msmpeg4.c index 395dffc..b071d74 100644 --- a/ffmpeg/libavcodec/msmpeg4.c +++ b/ffmpeg/libavcodec/msmpeg4.c @@ -45,16 +45,6 @@ * - (encoding) select best mv table (two choices) * - (encoding) select best vlc/dc table */ -//#define DEBUG - -#define DC_VLC_BITS 9 -#define V2_INTRA_CBPC_VLC_BITS 3 -#define V2_MB_TYPE_VLC_BITS 7 -#define MV_VLC_BITS 9 -#define V2_MV_VLC_BITS 9 -#define TEX_VLC_BITS 9 - -#define DEFAULT_INTER_INDEX 3 /* This table is practically identical to the one from h263 * except that it is inverted. */ @@ -185,28 +175,13 @@ int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block return pred; } -static inline int msmpeg4v1_pred_dc(MpegEncContext * s, int n, - int32_t **dc_val_ptr) -{ - int i; - - if (n < 4) { - i= 0; - } else { - i= n-3; - } - - *dc_val_ptr= &s->last_dc[i]; - return s->last_dc[i]; -} - -static int get_dc(uint8_t *src, int stride, int scale) +static int get_dc(uint8_t *src, int stride, int scale, int block_size) { int y; int sum=0; - for(y=0; y<8; y++){ + for(y=0; y> 1)) / 8; b = (b + (8 >> 1)) / 8; @@ -301,17 +273,18 @@ int ff_msmpeg4_pred_dc(MpegEncContext *s, int n, *dir_ptr = 0; } }else{ + int bs = 8 >> s->avctx->lowres; if(n<4){ wrap= s->linesize; - dest= s->current_picture.f.data[0] + (((n >> 1) + 2*s->mb_y) * 8* wrap ) + ((n & 1) + 2*s->mb_x) * 8; + dest= s->current_picture.f.data[0] + (((n >> 1) + 2*s->mb_y) * bs* wrap ) + ((n & 1) + 2*s->mb_x) * bs; }else{ wrap= s->uvlinesize; - dest= s->current_picture.f.data[n - 3] + (s->mb_y * 8 * wrap) + s->mb_x * 8; + dest= s->current_picture.f.data[n - 3] + (s->mb_y * bs * wrap) + s->mb_x * bs; } if(s->mb_x==0) a= (1024 + (scale>>1))/scale; - else a= get_dc(dest-8, wrap, scale*8); + else a= get_dc(dest-bs, wrap, scale*8>>(2*s->avctx->lowres), bs); if(s->mb_y==0) c= (1024 + (scale>>1))/scale; - else c= get_dc(dest-8*wrap, wrap, scale*8); + else c= get_dc(dest-bs*wrap, wrap, scale*8>>(2*s->avctx->lowres), bs); if (s->h263_aic_dir==0) { pred= a; @@ -361,909 +334,3 @@ int ff_msmpeg4_pred_dc(MpegEncContext *s, int n, return pred; } -/****************************************/ -/* decoding stuff */ - -VLC ff_mb_non_intra_vlc[4]; -static VLC v2_dc_lum_vlc; -static VLC v2_dc_chroma_vlc; -static VLC v2_intra_cbpc_vlc; -static VLC v2_mb_type_vlc; -static VLC v2_mv_vlc; -VLC ff_inter_intra_vlc; - -/* This is identical to h263 except that its range is multiplied by 2. */ -static int msmpeg4v2_decode_motion(MpegEncContext * s, int pred, int f_code) -{ - int code, val, sign, shift; - - code = get_vlc2(&s->gb, v2_mv_vlc.table, V2_MV_VLC_BITS, 2); - av_dlog(s, "MV code %d at %d %d pred: %d\n", code, s->mb_x,s->mb_y, pred); - if (code < 0) - return 0xffff; - - if (code == 0) - return pred; - sign = get_bits1(&s->gb); - shift = f_code - 1; - val = code; - if (shift) { - val = (val - 1) << shift; - val |= get_bits(&s->gb, shift); - val++; - } - if (sign) - val = -val; - - val += pred; - if (val <= -64) - val += 64; - else if (val >= 64) - val -= 64; - - return val; -} - -static int msmpeg4v12_decode_mb(MpegEncContext *s, int16_t block[6][64]) -{ - int cbp, code, i; - uint32_t * const mb_type_ptr = &s->current_picture.mb_type[s->mb_x + s->mb_y*s->mb_stride]; - - if (s->pict_type == AV_PICTURE_TYPE_P) { - if (s->use_skip_mb_code) { - if (get_bits1(&s->gb)) { - /* skip mb */ - s->mb_intra = 0; - for(i=0;i<6;i++) - s->block_last_index[i] = -1; - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_16X16; - s->mv[0][0][0] = 0; - s->mv[0][0][1] = 0; - s->mb_skipped = 1; - *mb_type_ptr = MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16; - return 0; - } - } - - if(s->msmpeg4_version==2) - code = get_vlc2(&s->gb, v2_mb_type_vlc.table, V2_MB_TYPE_VLC_BITS, 1); - else - code = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2); - if(code<0 || code>7){ - av_log(s->avctx, AV_LOG_ERROR, "cbpc %d invalid at %d %d\n", code, s->mb_x, s->mb_y); - return -1; - } - - s->mb_intra = code >>2; - - cbp = code & 0x3; - } else { - s->mb_intra = 1; - if(s->msmpeg4_version==2) - cbp= get_vlc2(&s->gb, v2_intra_cbpc_vlc.table, V2_INTRA_CBPC_VLC_BITS, 1); - else - cbp= get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 1); - if(cbp<0 || cbp>3){ - av_log(s->avctx, AV_LOG_ERROR, "cbpc %d invalid at %d %d\n", cbp, s->mb_x, s->mb_y); - return -1; - } - } - - if (!s->mb_intra) { - int mx, my, cbpy; - - cbpy= get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1); - if(cbpy<0){ - av_log(s->avctx, AV_LOG_ERROR, "cbpy %d invalid at %d %d\n", cbp, s->mb_x, s->mb_y); - return -1; - } - - cbp|= cbpy<<2; - if(s->msmpeg4_version==1 || (cbp&3) != 3) cbp^= 0x3C; - - ff_h263_pred_motion(s, 0, 0, &mx, &my); - mx= msmpeg4v2_decode_motion(s, mx, 1); - my= msmpeg4v2_decode_motion(s, my, 1); - - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_16X16; - s->mv[0][0][0] = mx; - s->mv[0][0][1] = my; - *mb_type_ptr = MB_TYPE_L0 | MB_TYPE_16x16; - } else { - if(s->msmpeg4_version==2){ - s->ac_pred = get_bits1(&s->gb); - cbp|= get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1)<<2; //FIXME check errors - } else{ - s->ac_pred = 0; - cbp|= get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1)<<2; //FIXME check errors - if(s->pict_type==AV_PICTURE_TYPE_P) cbp^=0x3C; - } - *mb_type_ptr = MB_TYPE_INTRA; - } - - s->dsp.clear_blocks(s->block[0]); - for (i = 0; i < 6; i++) { - if (ff_msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0) - { - av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i); - return -1; - } - } - return 0; -} - -static int msmpeg4v34_decode_mb(MpegEncContext *s, int16_t block[6][64]) -{ - int cbp, code, i; - uint8_t *coded_val; - uint32_t * const mb_type_ptr = &s->current_picture.mb_type[s->mb_x + s->mb_y*s->mb_stride]; - - if (s->pict_type == AV_PICTURE_TYPE_P) { - if (s->use_skip_mb_code) { - if (get_bits1(&s->gb)) { - /* skip mb */ - s->mb_intra = 0; - for(i=0;i<6;i++) - s->block_last_index[i] = -1; - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_16X16; - s->mv[0][0][0] = 0; - s->mv[0][0][1] = 0; - s->mb_skipped = 1; - *mb_type_ptr = MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16; - - return 0; - } - } - - code = get_vlc2(&s->gb, ff_mb_non_intra_vlc[DEFAULT_INTER_INDEX].table, MB_NON_INTRA_VLC_BITS, 3); - if (code < 0) - return -1; - //s->mb_intra = (code & 0x40) ? 0 : 1; - s->mb_intra = (~code & 0x40) >> 6; - - cbp = code & 0x3f; - } else { - s->mb_intra = 1; - code = get_vlc2(&s->gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); - if (code < 0) - return -1; - /* predict coded block pattern */ - cbp = 0; - for(i=0;i<6;i++) { - int val = ((code >> (5 - i)) & 1); - if (i < 4) { - int pred = ff_msmpeg4_coded_block_pred(s, i, &coded_val); - val = val ^ pred; - *coded_val = val; - } - cbp |= val << (5 - i); - } - } - - if (!s->mb_intra) { - int mx, my; - if(s->per_mb_rl_table && cbp){ - s->rl_table_index = decode012(&s->gb); - s->rl_chroma_table_index = s->rl_table_index; - } - ff_h263_pred_motion(s, 0, 0, &mx, &my); - if (ff_msmpeg4_decode_motion(s, &mx, &my) < 0) - return -1; - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_16X16; - s->mv[0][0][0] = mx; - s->mv[0][0][1] = my; - *mb_type_ptr = MB_TYPE_L0 | MB_TYPE_16x16; - } else { - av_dlog(s, "I at %d %d %d %06X\n", s->mb_x, s->mb_y, - ((cbp & 3) ? 1 : 0) +((cbp & 0x3C)? 2 : 0), - show_bits(&s->gb, 24)); - s->ac_pred = get_bits1(&s->gb); - *mb_type_ptr = MB_TYPE_INTRA; - if(s->inter_intra_pred){ - s->h263_aic_dir= get_vlc2(&s->gb, ff_inter_intra_vlc.table, INTER_INTRA_VLC_BITS, 1); - av_dlog(s, "%d%d %d %d/", - s->ac_pred, s->h263_aic_dir, s->mb_x, s->mb_y); - } - if(s->per_mb_rl_table && cbp){ - s->rl_table_index = decode012(&s->gb); - s->rl_chroma_table_index = s->rl_table_index; - } - } - - s->dsp.clear_blocks(s->block[0]); - for (i = 0; i < 6; i++) { - if (ff_msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0) - { - av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i); - return -1; - } - } - - return 0; -} - -/* init all vlc decoding tables */ -av_cold int ff_msmpeg4_decode_init(AVCodecContext *avctx) -{ - MpegEncContext *s = avctx->priv_data; - static volatile int done = 0; - int i, ret; - MVTable *mv; - - if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0) - return ret; - - if (ff_h263_decode_init(avctx) < 0) - return -1; - - ff_msmpeg4_common_init(s); - - if (!done) { - for(i=0;ivlc, MV_VLC_BITS, mv->n + 1, - mv->table_mv_bits, 1, 1, - mv->table_mv_code, 2, 2, 3714); - mv = &ff_mv_tables[1]; - INIT_VLC_STATIC(&mv->vlc, MV_VLC_BITS, mv->n + 1, - mv->table_mv_bits, 1, 1, - mv->table_mv_code, 2, 2, 2694); - - INIT_VLC_STATIC(&ff_msmp4_dc_luma_vlc[0], DC_VLC_BITS, 120, - &ff_table0_dc_lum[0][1], 8, 4, - &ff_table0_dc_lum[0][0], 8, 4, 1158); - INIT_VLC_STATIC(&ff_msmp4_dc_chroma_vlc[0], DC_VLC_BITS, 120, - &ff_table0_dc_chroma[0][1], 8, 4, - &ff_table0_dc_chroma[0][0], 8, 4, 1118); - INIT_VLC_STATIC(&ff_msmp4_dc_luma_vlc[1], DC_VLC_BITS, 120, - &ff_table1_dc_lum[0][1], 8, 4, - &ff_table1_dc_lum[0][0], 8, 4, 1476); - INIT_VLC_STATIC(&ff_msmp4_dc_chroma_vlc[1], DC_VLC_BITS, 120, - &ff_table1_dc_chroma[0][1], 8, 4, - &ff_table1_dc_chroma[0][0], 8, 4, 1216); - - INIT_VLC_STATIC(&v2_dc_lum_vlc, DC_VLC_BITS, 512, - &ff_v2_dc_lum_table[0][1], 8, 4, - &ff_v2_dc_lum_table[0][0], 8, 4, 1472); - INIT_VLC_STATIC(&v2_dc_chroma_vlc, DC_VLC_BITS, 512, - &ff_v2_dc_chroma_table[0][1], 8, 4, - &ff_v2_dc_chroma_table[0][0], 8, 4, 1506); - - INIT_VLC_STATIC(&v2_intra_cbpc_vlc, V2_INTRA_CBPC_VLC_BITS, 4, - &ff_v2_intra_cbpc[0][1], 2, 1, - &ff_v2_intra_cbpc[0][0], 2, 1, 8); - INIT_VLC_STATIC(&v2_mb_type_vlc, V2_MB_TYPE_VLC_BITS, 8, - &ff_v2_mb_type[0][1], 2, 1, - &ff_v2_mb_type[0][0], 2, 1, 128); - INIT_VLC_STATIC(&v2_mv_vlc, V2_MV_VLC_BITS, 33, - &ff_mvtab[0][1], 2, 1, - &ff_mvtab[0][0], 2, 1, 538); - - INIT_VLC_STATIC(&ff_mb_non_intra_vlc[0], MB_NON_INTRA_VLC_BITS, 128, - &ff_wmv2_inter_table[0][0][1], 8, 4, - &ff_wmv2_inter_table[0][0][0], 8, 4, 1636); - INIT_VLC_STATIC(&ff_mb_non_intra_vlc[1], MB_NON_INTRA_VLC_BITS, 128, - &ff_wmv2_inter_table[1][0][1], 8, 4, - &ff_wmv2_inter_table[1][0][0], 8, 4, 2648); - INIT_VLC_STATIC(&ff_mb_non_intra_vlc[2], MB_NON_INTRA_VLC_BITS, 128, - &ff_wmv2_inter_table[2][0][1], 8, 4, - &ff_wmv2_inter_table[2][0][0], 8, 4, 1532); - INIT_VLC_STATIC(&ff_mb_non_intra_vlc[3], MB_NON_INTRA_VLC_BITS, 128, - &ff_wmv2_inter_table[3][0][1], 8, 4, - &ff_wmv2_inter_table[3][0][0], 8, 4, 2488); - - INIT_VLC_STATIC(&ff_msmp4_mb_i_vlc, MB_INTRA_VLC_BITS, 64, - &ff_msmp4_mb_i_table[0][1], 4, 2, - &ff_msmp4_mb_i_table[0][0], 4, 2, 536); - - INIT_VLC_STATIC(&ff_inter_intra_vlc, INTER_INTRA_VLC_BITS, 4, - &ff_table_inter_intra[0][1], 2, 1, - &ff_table_inter_intra[0][0], 2, 1, 8); - done = 1; - } - - switch(s->msmpeg4_version){ - case 1: - case 2: - s->decode_mb= msmpeg4v12_decode_mb; - break; - case 3: - case 4: - s->decode_mb= msmpeg4v34_decode_mb; - break; - case 5: - if (CONFIG_WMV2_DECODER) - s->decode_mb= ff_wmv2_decode_mb; - case 6: - //FIXME + TODO VC1 decode mb - break; - } - - s->slice_height= s->mb_height; //to avoid 1/0 if the first frame is not a keyframe - - return 0; -} - -int ff_msmpeg4_decode_picture_header(MpegEncContext * s) -{ - int code; - - if(s->msmpeg4_version==1){ - int start_code = get_bits_long(&s->gb, 32); - if(start_code!=0x00000100){ - av_log(s->avctx, AV_LOG_ERROR, "invalid startcode\n"); - return -1; - } - - skip_bits(&s->gb, 5); // frame number */ - } - - s->pict_type = get_bits(&s->gb, 2) + 1; - if (s->pict_type != AV_PICTURE_TYPE_I && - s->pict_type != AV_PICTURE_TYPE_P){ - av_log(s->avctx, AV_LOG_ERROR, "invalid picture type\n"); - return -1; - } -#if 0 -{ - static int had_i=0; - if(s->pict_type == AV_PICTURE_TYPE_I) had_i=1; - if(!had_i) return -1; -} -#endif - s->chroma_qscale= s->qscale = get_bits(&s->gb, 5); - if(s->qscale==0){ - av_log(s->avctx, AV_LOG_ERROR, "invalid qscale\n"); - return -1; - } - - if (s->pict_type == AV_PICTURE_TYPE_I) { - code = get_bits(&s->gb, 5); - if(s->msmpeg4_version==1){ - if(code==0 || code>s->mb_height){ - av_log(s->avctx, AV_LOG_ERROR, "invalid slice height %d\n", code); - return -1; - } - - s->slice_height = code; - }else{ - /* 0x17: one slice, 0x18: two slices, ... */ - if (code < 0x17){ - av_log(s->avctx, AV_LOG_ERROR, "error, slice code was %X\n", code); - return -1; - } - - s->slice_height = s->mb_height / (code - 0x16); - } - - switch(s->msmpeg4_version){ - case 1: - case 2: - s->rl_chroma_table_index = 2; - s->rl_table_index = 2; - - s->dc_table_index = 0; //not used - break; - case 3: - s->rl_chroma_table_index = decode012(&s->gb); - s->rl_table_index = decode012(&s->gb); - - s->dc_table_index = get_bits1(&s->gb); - break; - case 4: - ff_msmpeg4_decode_ext_header(s, (2+5+5+17+7)/8); - - if(s->bit_rate > MBAC_BITRATE) s->per_mb_rl_table= get_bits1(&s->gb); - else s->per_mb_rl_table= 0; - - if(!s->per_mb_rl_table){ - s->rl_chroma_table_index = decode012(&s->gb); - s->rl_table_index = decode012(&s->gb); - } - - s->dc_table_index = get_bits1(&s->gb); - s->inter_intra_pred= 0; - break; - } - s->no_rounding = 1; - if(s->avctx->debug&FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_DEBUG, "qscale:%d rlc:%d rl:%d dc:%d mbrl:%d slice:%d \n", - s->qscale, - s->rl_chroma_table_index, - s->rl_table_index, - s->dc_table_index, - s->per_mb_rl_table, - s->slice_height); - } else { - switch(s->msmpeg4_version){ - case 1: - case 2: - if(s->msmpeg4_version==1) - s->use_skip_mb_code = 1; - else - s->use_skip_mb_code = get_bits1(&s->gb); - s->rl_table_index = 2; - s->rl_chroma_table_index = s->rl_table_index; - s->dc_table_index = 0; //not used - s->mv_table_index = 0; - break; - case 3: - s->use_skip_mb_code = get_bits1(&s->gb); - s->rl_table_index = decode012(&s->gb); - s->rl_chroma_table_index = s->rl_table_index; - - s->dc_table_index = get_bits1(&s->gb); - - s->mv_table_index = get_bits1(&s->gb); - break; - case 4: - s->use_skip_mb_code = get_bits1(&s->gb); - - if(s->bit_rate > MBAC_BITRATE) s->per_mb_rl_table= get_bits1(&s->gb); - else s->per_mb_rl_table= 0; - - if(!s->per_mb_rl_table){ - s->rl_table_index = decode012(&s->gb); - s->rl_chroma_table_index = s->rl_table_index; - } - - s->dc_table_index = get_bits1(&s->gb); - - s->mv_table_index = get_bits1(&s->gb); - s->inter_intra_pred= (s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE); - break; - } - - if(s->avctx->debug&FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_DEBUG, "skip:%d rl:%d rlc:%d dc:%d mv:%d mbrl:%d qp:%d \n", - s->use_skip_mb_code, - s->rl_table_index, - s->rl_chroma_table_index, - s->dc_table_index, - s->mv_table_index, - s->per_mb_rl_table, - s->qscale); - - if(s->flipflop_rounding){ - s->no_rounding ^= 1; - }else{ - s->no_rounding = 0; - } - } - av_dlog(s->avctx, "%d %d %d %d %d\n", s->pict_type, s->bit_rate, - s->inter_intra_pred, s->width, s->height); - - s->esc3_level_length= 0; - s->esc3_run_length= 0; - - return 0; -} - -int ff_msmpeg4_decode_ext_header(MpegEncContext * s, int buf_size) -{ - int left= buf_size*8 - get_bits_count(&s->gb); - int length= s->msmpeg4_version>=3 ? 17 : 16; - /* the alt_bitstream reader could read over the end so we need to check it */ - if(left>=length && leftgb, 5); /* fps */ - s->bit_rate= get_bits(&s->gb, 11)*1024; - if(s->msmpeg4_version>=3) - s->flipflop_rounding= get_bits1(&s->gb); - else - s->flipflop_rounding= 0; - } - else if(leftflipflop_rounding= 0; - if(s->msmpeg4_version != 2) - av_log(s->avctx, AV_LOG_ERROR, "ext header missing, %d left\n", left); - } - else - { - av_log(s->avctx, AV_LOG_ERROR, "I frame too long, ignoring ext header\n"); - } - - return 0; -} - -static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr) -{ - int level, pred; - - if(s->msmpeg4_version<=2){ - if (n < 4) { - level = get_vlc2(&s->gb, v2_dc_lum_vlc.table, DC_VLC_BITS, 3); - } else { - level = get_vlc2(&s->gb, v2_dc_chroma_vlc.table, DC_VLC_BITS, 3); - } - if (level < 0) - return -1; - level-=256; - }else{ //FIXME optimize use unified tables & index - if (n < 4) { - level = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3); - } else { - level = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3); - } - if (level < 0){ - av_log(s->avctx, AV_LOG_ERROR, "illegal dc vlc\n"); - return -1; - } - - if (level == DC_MAX) { - level = get_bits(&s->gb, 8); - if (get_bits1(&s->gb)) - level = -level; - } else if (level != 0) { - if (get_bits1(&s->gb)) - level = -level; - } - } - - if(s->msmpeg4_version==1){ - int32_t *dc_val; - pred = msmpeg4v1_pred_dc(s, n, &dc_val); - level += pred; - - /* update predictor */ - *dc_val= level; - }else{ - int16_t *dc_val; - pred = ff_msmpeg4_pred_dc(s, n, &dc_val, dir_ptr); - level += pred; - - /* update predictor */ - if (n < 4) { - *dc_val = level * s->y_dc_scale; - } else { - *dc_val = level * s->c_dc_scale; - } - } - - return level; -} - -//#define ERROR_DETAILS -int ff_msmpeg4_decode_block(MpegEncContext * s, int16_t * block, - int n, int coded, const uint8_t *scan_table) -{ - int level, i, last, run, run_diff; - int av_uninit(dc_pred_dir); - RLTable *rl; - RL_VLC_ELEM *rl_vlc; - int qmul, qadd; - - if (s->mb_intra) { - qmul=1; - qadd=0; - - /* DC coef */ - level = msmpeg4_decode_dc(s, n, &dc_pred_dir); - - if (level < 0){ - av_log(s->avctx, AV_LOG_ERROR, "dc overflow- block: %d qscale: %d//\n", n, s->qscale); - if(s->inter_intra_pred) level=0; - else return -1; - } - if (n < 4) { - rl = &ff_rl_table[s->rl_table_index]; - if(level > 256*s->y_dc_scale){ - av_log(s->avctx, AV_LOG_ERROR, "dc overflow+ L qscale: %d//\n", s->qscale); - if(!s->inter_intra_pred) return -1; - } - } else { - rl = &ff_rl_table[3 + s->rl_chroma_table_index]; - if(level > 256*s->c_dc_scale){ - av_log(s->avctx, AV_LOG_ERROR, "dc overflow+ C qscale: %d//\n", s->qscale); - if(!s->inter_intra_pred) return -1; - } - } - block[0] = level; - - run_diff = s->msmpeg4_version >= 4; - i = 0; - if (!coded) { - goto not_coded; - } - if (s->ac_pred) { - if (dc_pred_dir == 0) - scan_table = s->intra_v_scantable.permutated; /* left */ - else - scan_table = s->intra_h_scantable.permutated; /* top */ - } else { - scan_table = s->intra_scantable.permutated; - } - rl_vlc= rl->rl_vlc[0]; - } else { - qmul = s->qscale << 1; - qadd = (s->qscale - 1) | 1; - i = -1; - rl = &ff_rl_table[3 + s->rl_table_index]; - - if(s->msmpeg4_version==2) - run_diff = 0; - else - run_diff = 1; - - if (!coded) { - s->block_last_index[n] = i; - return 0; - } - if(!scan_table) - scan_table = s->inter_scantable.permutated; - rl_vlc= rl->rl_vlc[s->qscale]; - } - { - OPEN_READER(re, &s->gb); - for(;;) { - UPDATE_CACHE(re, &s->gb); - GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 0); - if (level==0) { - int cache; - cache= GET_CACHE(re, &s->gb); - /* escape */ - if (s->msmpeg4_version==1 || (cache&0x80000000)==0) { - if (s->msmpeg4_version==1 || (cache&0x40000000)==0) { - /* third escape */ - if(s->msmpeg4_version!=1) LAST_SKIP_BITS(re, &s->gb, 2); - UPDATE_CACHE(re, &s->gb); - if(s->msmpeg4_version<=3){ - last= SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1); - run= SHOW_UBITS(re, &s->gb, 6); SKIP_CACHE(re, &s->gb, 6); - level= SHOW_SBITS(re, &s->gb, 8); - SKIP_COUNTER(re, &s->gb, 1+6+8); - }else{ - int sign; - last= SHOW_UBITS(re, &s->gb, 1); SKIP_BITS(re, &s->gb, 1); - if(!s->esc3_level_length){ - int ll; - av_dlog(s->avctx, "ESC-3 %X at %d %d\n", - show_bits(&s->gb, 24), s->mb_x, s->mb_y); - if(s->qscale<8){ - ll= SHOW_UBITS(re, &s->gb, 3); SKIP_BITS(re, &s->gb, 3); - if(ll==0){ - ll= 8+SHOW_UBITS(re, &s->gb, 1); SKIP_BITS(re, &s->gb, 1); - } - }else{ - ll=2; - while(ll<8 && SHOW_UBITS(re, &s->gb, 1)==0){ - ll++; - SKIP_BITS(re, &s->gb, 1); - } - if(ll<8) SKIP_BITS(re, &s->gb, 1); - } - - s->esc3_level_length= ll; - s->esc3_run_length= SHOW_UBITS(re, &s->gb, 2) + 3; SKIP_BITS(re, &s->gb, 2); - UPDATE_CACHE(re, &s->gb); - } - run= SHOW_UBITS(re, &s->gb, s->esc3_run_length); - SKIP_BITS(re, &s->gb, s->esc3_run_length); - - sign= SHOW_UBITS(re, &s->gb, 1); - SKIP_BITS(re, &s->gb, 1); - - level= SHOW_UBITS(re, &s->gb, s->esc3_level_length); - SKIP_BITS(re, &s->gb, s->esc3_level_length); - if(sign) level= -level; - } - -#if 0 // waste of time / this will detect very few errors - { - const int abs_level= FFABS(level); - const int run1= run - rl->max_run[last][abs_level] - run_diff; - if(abs_level<=MAX_LEVEL && run<=MAX_RUN){ - if(abs_level <= rl->max_level[last][run]){ - av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, vlc encoding possible\n"); - return DECODING_AC_LOST; - } - if(abs_level <= rl->max_level[last][run]*2){ - av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 1 encoding possible\n"); - return DECODING_AC_LOST; - } - if(run1>=0 && abs_level <= rl->max_level[last][run1]){ - av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 2 encoding possible\n"); - return DECODING_AC_LOST; - } - } - } -#endif - //level = level * qmul + (level>0) * qadd - (level<=0) * qadd ; - if (level>0) level= level * qmul + qadd; - else level= level * qmul - qadd; -#if 0 // waste of time too :( - if(level>2048 || level<-2048){ - av_log(s->avctx, AV_LOG_ERROR, "|level| overflow in 3. esc\n"); - return DECODING_AC_LOST; - } -#endif - i+= run + 1; - if(last) i+=192; -#ifdef ERROR_DETAILS - if(run==66) - av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code in ESC3 level=%d\n", level); - else if((i>62 && i<192) || i>192+63) - av_log(s->avctx, AV_LOG_ERROR, "run overflow in ESC3 i=%d run=%d level=%d\n", i, run, level); -#endif - } else { - /* second escape */ - SKIP_BITS(re, &s->gb, 2); - GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1); - i+= run + rl->max_run[run>>7][level/qmul] + run_diff; //FIXME opt indexing - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - LAST_SKIP_BITS(re, &s->gb, 1); -#ifdef ERROR_DETAILS - if(run==66) - av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code in ESC2 level=%d\n", level); - else if((i>62 && i<192) || i>192+63) - av_log(s->avctx, AV_LOG_ERROR, "run overflow in ESC2 i=%d run=%d level=%d\n", i, run, level); -#endif - } - } else { - /* first escape */ - SKIP_BITS(re, &s->gb, 1); - GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1); - i+= run; - level = level + rl->max_level[run>>7][(run-1)&63] * qmul;//FIXME opt indexing - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - LAST_SKIP_BITS(re, &s->gb, 1); -#ifdef ERROR_DETAILS - if(run==66) - av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code in ESC1 level=%d\n", level); - else if((i>62 && i<192) || i>192+63) - av_log(s->avctx, AV_LOG_ERROR, "run overflow in ESC1 i=%d run=%d level=%d\n", i, run, level); -#endif - } - } else { - i+= run; - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - LAST_SKIP_BITS(re, &s->gb, 1); -#ifdef ERROR_DETAILS - if(run==66) - av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code level=%d\n", level); - else if((i>62 && i<192) || i>192+63) - av_log(s->avctx, AV_LOG_ERROR, "run overflow i=%d run=%d level=%d\n", i, run, level); -#endif - } - if (i > 62){ - i-= 192; - if(i&(~63)){ - const int left= get_bits_left(&s->gb); - if(((i+192 == 64 && level/qmul==-1) || !(s->err_recognition&(AV_EF_BITSTREAM|AV_EF_COMPLIANT))) && left>=0){ - av_log(s->avctx, AV_LOG_ERROR, "ignoring overflow at %d %d\n", s->mb_x, s->mb_y); - i = 63; - break; - }else{ - av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - } - - block[scan_table[i]] = level; - break; - } - - block[scan_table[i]] = level; - } - CLOSE_READER(re, &s->gb); - } - not_coded: - if (s->mb_intra) { - ff_mpeg4_pred_ac(s, block, n, dc_pred_dir); - if (s->ac_pred) { - i = 63; /* XXX: not optimal */ - } - } - if(s->msmpeg4_version>=4 && i>0) i=63; //FIXME/XXX optimize - s->block_last_index[n] = i; - - return 0; -} - -int ff_msmpeg4_decode_motion(MpegEncContext * s, - int *mx_ptr, int *my_ptr) -{ - MVTable *mv; - int code, mx, my; - - mv = &ff_mv_tables[s->mv_table_index]; - - code = get_vlc2(&s->gb, mv->vlc.table, MV_VLC_BITS, 2); - if (code < 0){ - av_log(s->avctx, AV_LOG_ERROR, "illegal MV code at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - if (code == mv->n) { - mx = get_bits(&s->gb, 6); - my = get_bits(&s->gb, 6); - } else { - mx = mv->table_mvx[code]; - my = mv->table_mvy[code]; - } - - mx += *mx_ptr - 32; - my += *my_ptr - 32; - /* WARNING : they do not do exactly modulo encoding */ - if (mx <= -64) - mx += 64; - else if (mx >= 64) - mx -= 64; - - if (my <= -64) - my += 64; - else if (my >= 64) - my -= 64; - *mx_ptr = mx; - *my_ptr = my; - return 0; -} - -AVCodec ff_msmpeg4v1_decoder = { - .name = "msmpeg4v1", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_MSMPEG4V1, - .priv_data_size = sizeof(MpegEncContext), - .init = ff_msmpeg4_decode_init, - .close = ff_h263_decode_end, - .decode = ff_h263_decode_frame, - .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, - .max_lowres = 3, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 1"), - .pix_fmts = ff_pixfmt_list_420, -}; - -AVCodec ff_msmpeg4v2_decoder = { - .name = "msmpeg4v2", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_MSMPEG4V2, - .priv_data_size = sizeof(MpegEncContext), - .init = ff_msmpeg4_decode_init, - .close = ff_h263_decode_end, - .decode = ff_h263_decode_frame, - .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, - .max_lowres = 3, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 2"), - .pix_fmts = ff_pixfmt_list_420, -}; - -AVCodec ff_msmpeg4v3_decoder = { - .name = "msmpeg4", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_MSMPEG4V3, - .priv_data_size = sizeof(MpegEncContext), - .init = ff_msmpeg4_decode_init, - .close = ff_h263_decode_end, - .decode = ff_h263_decode_frame, - .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, - .max_lowres = 3, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 3"), - .pix_fmts = ff_pixfmt_list_420, -}; - -AVCodec ff_wmv1_decoder = { - .name = "wmv1", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_WMV1, - .priv_data_size = sizeof(MpegEncContext), - .init = ff_msmpeg4_decode_init, - .close = ff_h263_decode_end, - .decode = ff_h263_decode_frame, - .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, - .max_lowres = 3, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 7"), - .pix_fmts = ff_pixfmt_list_420, -}; diff --git a/ffmpeg/libavcodec/msmpeg4data.c b/ffmpeg/libavcodec/msmpeg4data.c index 50ba18c..8eb07e9 100644 --- a/ffmpeg/libavcodec/msmpeg4data.c +++ b/ffmpeg/libavcodec/msmpeg4data.c @@ -27,6 +27,8 @@ * MSMPEG4 data tables. */ +#include "h263.h" +#include "mpeg4video.h" #include "msmpeg4data.h" uint32_t ff_v2_dc_lum_table[512][2]; @@ -596,14 +598,6 @@ static const int8_t table4_run[168] = { 29, 30, 31, 32, 33, 34, 35, 36, }; -extern const uint16_t ff_inter_vlc[103][2]; -extern const int8_t ff_inter_level[102]; -extern const int8_t ff_inter_run[102]; - -extern const uint16_t ff_mpeg4_intra_vlc[103][2]; -extern const int8_t ff_mpeg4_intra_level[102]; -extern const int8_t ff_mpeg4_intra_run[102]; - RLTable ff_rl_table[NB_RL_TABLES] = { /* intra luminance tables */ /* low motion */ diff --git a/ffmpeg/libavcodec/msmpeg4enc.c b/ffmpeg/libavcodec/msmpeg4enc.c index 82e6646..e7f51db 100644 --- a/ffmpeg/libavcodec/msmpeg4enc.c +++ b/ffmpeg/libavcodec/msmpeg4enc.c @@ -30,10 +30,10 @@ #include #include +#include "libavutil/attributes.h" #include "libavutil/avutil.h" #include "libavutil/mem.h" #include "mpegvideo.h" -#include "msmpeg4.h" #include "h263.h" #include "mpeg4video.h" #include "msmpeg4.h" @@ -45,7 +45,7 @@ static uint8_t rl_length[NB_RL_TABLES][MAX_LEVEL+1][MAX_RUN+1][2]; /* build the table which associate a (x,y) motion vector to a vlc */ -static void init_mv_table(MVTable *tab) +static av_cold void init_mv_table(MVTable *tab) { int i, x, y; diff --git a/ffmpeg/libavcodec/msrle.c b/ffmpeg/libavcodec/msrle.c index 674e586..7ae4b08 100644 --- a/ffmpeg/libavcodec/msrle.c +++ b/ffmpeg/libavcodec/msrle.c @@ -38,7 +38,7 @@ typedef struct MsrleContext { AVCodecContext *avctx; - AVFrame frame; + AVFrame *frame; GetByteContext gb; const unsigned char *buf; @@ -54,7 +54,7 @@ static av_cold int msrle_decode_init(AVCodecContext *avctx) s->avctx = avctx; - switch (avctx->bits_per_coded_sample) { + switch (avctx->bits_per_coded_sample & 0x1f) { case 1: avctx->pix_fmt = AV_PIX_FMT_MONOWHITE; break; @@ -70,7 +70,9 @@ static av_cold int msrle_decode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } - avcodec_get_frame_defaults(&s->frame); + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); if (avctx->extradata_size >= 4) for (i = 0; i < FFMIN(avctx->extradata_size, AVPALETTE_SIZE)/4; i++) @@ -92,24 +94,24 @@ static int msrle_decode_frame(AVCodecContext *avctx, s->buf = buf; s->size = buf_size; - if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) + if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) return ret; if (avctx->bits_per_coded_sample > 1 && avctx->bits_per_coded_sample <= 8) { const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); if (pal) { - s->frame.palette_has_changed = 1; + s->frame->palette_has_changed = 1; memcpy(s->pal, pal, AVPALETTE_SIZE); } /* make the palette available */ - memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE); + memcpy(s->frame->data[1], s->pal, AVPALETTE_SIZE); } /* FIXME how to correctly detect RLE ??? */ if (avctx->height * istride == avpkt->size) { /* assume uncompressed */ int linesize = (avctx->width * avctx->bits_per_coded_sample + 7) / 8; - uint8_t *ptr = s->frame.data[0]; + uint8_t *ptr = s->frame->data[0]; uint8_t *buf = avpkt->data + (avctx->height-1)*istride; int i, j; @@ -125,14 +127,14 @@ static int msrle_decode_frame(AVCodecContext *avctx, memcpy(ptr, buf, linesize); } buf -= istride; - ptr += s->frame.linesize[0]; + ptr += s->frame->linesize[0]; } } else { bytestream2_init(&s->gb, buf, buf_size); - ff_msrle_decode(avctx, (AVPicture*)&s->frame, avctx->bits_per_coded_sample, &s->gb); + ff_msrle_decode(avctx, (AVPicture*)s->frame, avctx->bits_per_coded_sample, &s->gb); } - if ((ret = av_frame_ref(data, &s->frame)) < 0) + if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; *got_frame = 1; @@ -146,13 +148,14 @@ static av_cold int msrle_decode_end(AVCodecContext *avctx) MsrleContext *s = avctx->priv_data; /* release the last frame */ - av_frame_unref(&s->frame); + av_frame_free(&s->frame); return 0; } AVCodec ff_msrle_decoder = { .name = "msrle", + .long_name = NULL_IF_CONFIG_SMALL("Microsoft RLE"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MSRLE, .priv_data_size = sizeof(MsrleContext), @@ -160,5 +163,4 @@ AVCodec ff_msrle_decoder = { .close = msrle_decode_end, .decode = msrle_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Microsoft RLE"), }; diff --git a/ffmpeg/libavcodec/msrledec.c b/ffmpeg/libavcodec/msrledec.c index 83d7d13..4d3da5b 100644 --- a/ffmpeg/libavcodec/msrledec.c +++ b/ffmpeg/libavcodec/msrledec.c @@ -184,9 +184,9 @@ static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, } if ((depth == 8) || (depth == 24)) { - for(i = 0; i < p2 * (depth >> 3); i++) { - *output++ = bytestream2_get_byteu(gb); - } + bytestream2_get_bufferu(gb, output, p2 * (depth >> 3)); + output += p2 * (depth >> 3); + // RLE8 copy is actually padded - and runs are not! if(depth == 8 && (p2 & 1)) { bytestream2_skip(gb, 1); @@ -211,8 +211,8 @@ static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, switch(depth){ case 8: pix[0] = bytestream2_get_byte(gb); - for(i = 0; i < p1; i++) - *output++ = pix[0]; + memset(output, pix[0], p1); + output += p1; break; case 16: pix16 = bytestream2_get_le16(gb); diff --git a/ffmpeg/libavcodec/mss1.c b/ffmpeg/libavcodec/mss1.c index bb1858d..fc88eb0 100644 --- a/ffmpeg/libavcodec/mss1.c +++ b/ffmpeg/libavcodec/mss1.c @@ -30,7 +30,7 @@ typedef struct MSS1Context { MSS12Context ctx; - AVFrame pic; + AVFrame *pic; SliceContext sc; } MSS1Context; @@ -139,8 +139,6 @@ static int decode_pal(MSS12Context *ctx, ArithCoder *acoder) static int mss1_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; MSS1Context *ctx = avctx->priv_data; MSS12Context *c = &ctx->ctx; GetBitContext gb; @@ -148,41 +146,43 @@ static int mss1_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, int pal_changed = 0; int ret; - init_get_bits(&gb, buf, buf_size * 8); + if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0) + return ret; + arith_init(&acoder, &gb); - if ((ret = ff_reget_buffer(avctx, &ctx->pic)) < 0) + if ((ret = ff_reget_buffer(avctx, ctx->pic)) < 0) return ret; - c->pal_pic = ctx->pic.data[0] + ctx->pic.linesize[0] * (avctx->height - 1); - c->pal_stride = -ctx->pic.linesize[0]; + c->pal_pic = ctx->pic->data[0] + ctx->pic->linesize[0] * (avctx->height - 1); + c->pal_stride = -ctx->pic->linesize[0]; c->keyframe = !arith_get_bit(&acoder); if (c->keyframe) { c->corrupted = 0; ff_mss12_slicecontext_reset(&ctx->sc); pal_changed = decode_pal(c, &acoder); - ctx->pic.key_frame = 1; - ctx->pic.pict_type = AV_PICTURE_TYPE_I; + ctx->pic->key_frame = 1; + ctx->pic->pict_type = AV_PICTURE_TYPE_I; } else { if (c->corrupted) return AVERROR_INVALIDDATA; - ctx->pic.key_frame = 0; - ctx->pic.pict_type = AV_PICTURE_TYPE_P; + ctx->pic->key_frame = 0; + ctx->pic->pict_type = AV_PICTURE_TYPE_P; } c->corrupted = ff_mss12_decode_rect(&ctx->sc, &acoder, 0, 0, avctx->width, avctx->height); if (c->corrupted) return AVERROR_INVALIDDATA; - memcpy(ctx->pic.data[1], c->pal, AVPALETTE_SIZE); - ctx->pic.palette_has_changed = pal_changed; + memcpy(ctx->pic->data[1], c->pal, AVPALETTE_SIZE); + ctx->pic->palette_has_changed = pal_changed; - if ((ret = av_frame_ref(data, &ctx->pic)) < 0) + if ((ret = av_frame_ref(data, ctx->pic)) < 0) return ret; *got_frame = 1; /* always report that the buffer was completely consumed */ - return buf_size; + return avpkt->size; } static av_cold int mss1_decode_init(AVCodecContext *avctx) @@ -192,7 +192,9 @@ static av_cold int mss1_decode_init(AVCodecContext *avctx) c->ctx.avctx = avctx; - avcodec_get_frame_defaults(&c->pic); + c->pic = av_frame_alloc(); + if (!c->pic) + return AVERROR(ENOMEM); ret = ff_mss12_decode_init(&c->ctx, 0, &c->sc, NULL); @@ -205,7 +207,7 @@ static av_cold int mss1_decode_end(AVCodecContext *avctx) { MSS1Context * const ctx = avctx->priv_data; - av_frame_unref(&ctx->pic); + av_frame_free(&ctx->pic); ff_mss12_decode_end(&ctx->ctx); return 0; @@ -213,6 +215,7 @@ static av_cold int mss1_decode_end(AVCodecContext *avctx) AVCodec ff_mss1_decoder = { .name = "mss1", + .long_name = NULL_IF_CONFIG_SMALL("MS Screen 1"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MSS1, .priv_data_size = sizeof(MSS1Context), @@ -220,5 +223,4 @@ AVCodec ff_mss1_decoder = { .close = mss1_decode_end, .decode = mss1_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("MS Screen 1"), }; diff --git a/ffmpeg/libavcodec/mss2.c b/ffmpeg/libavcodec/mss2.c index fcdbbd2..99db046 100644 --- a/ffmpeg/libavcodec/mss2.c +++ b/ffmpeg/libavcodec/mss2.c @@ -34,7 +34,7 @@ typedef struct MSS2Context { VC1Context v; int split_position; - AVFrame last_pic; + AVFrame *last_pic; MSS12Context c; MSS2DSPContext dsp; SliceContext sc[2]; @@ -377,18 +377,12 @@ static int decode_wmv9(AVCodecContext *avctx, const uint8_t *buf, int buf_size, ff_mpeg_flush(avctx); - if (s->current_picture_ptr == NULL || s->current_picture_ptr->f.data[0]) { - int i = ff_find_unused_picture(s, 0); - if (i < 0) - return i; - s->current_picture_ptr = &s->picture[i]; - } - - init_get_bits(&s->gb, buf, buf_size * 8); + if ((ret = init_get_bits8(&s->gb, buf, buf_size)) < 0) + return ret; s->loop_filter = avctx->skip_loop_filter < AVDISCARD_ALL; - if (ff_vc1_parse_frame_header(v, &s->gb) == -1) { + if (ff_vc1_parse_frame_header(v, &s->gb) < 0) { av_log(v->s.avctx, AV_LOG_ERROR, "header error\n"); return AVERROR_INVALIDDATA; } @@ -482,7 +476,8 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, av_assert0(FF_INPUT_BUFFER_PADDING_SIZE >= ARITH2_PADDING + (MIN_CACHE_BITS + 7) / 8); - init_get_bits(&gb, buf, buf_size * 8); + if ((ret = init_get_bits8(&gb, buf, buf_size)) < 0) + return ret; if (keyframe = get_bits1(&gb)) skip_bits(&gb, 7); @@ -523,8 +518,8 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return AVERROR_INVALIDDATA; avctx->pix_fmt = is_555 ? AV_PIX_FMT_RGB555 : AV_PIX_FMT_RGB24; - if (ctx->last_pic.format != avctx->pix_fmt) - av_frame_unref(&ctx->last_pic); + if (ctx->last_pic->format != avctx->pix_fmt) + av_frame_unref(ctx->last_pic); if (has_wmv9) { bytestream2_init(&gB, buf, buf_size + ARITH2_PADDING); @@ -601,18 +596,18 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; - if (ctx->last_pic.data[0]) { - av_assert0(frame->linesize[0] == ctx->last_pic.linesize[0]); - c->last_rgb_pic = ctx->last_pic.data[0] + - ctx->last_pic.linesize[0] * (avctx->height - 1); + if (ctx->last_pic->data[0]) { + av_assert0(frame->linesize[0] == ctx->last_pic->linesize[0]); + c->last_rgb_pic = ctx->last_pic->data[0] + + ctx->last_pic->linesize[0] * (avctx->height - 1); } else { av_log(avctx, AV_LOG_ERROR, "Missing keyframe\n"); return AVERROR_INVALIDDATA; } } else { - if ((ret = ff_reget_buffer(avctx, &ctx->last_pic)) < 0) + if ((ret = ff_reget_buffer(avctx, ctx->last_pic)) < 0) return ret; - if ((ret = av_frame_ref(frame, &ctx->last_pic)) < 0) + if ((ret = av_frame_ref(frame, ctx->last_pic)) < 0) return ret; c->last_rgb_pic = NULL; @@ -640,7 +635,8 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, ff_mss12_slicecontext_reset(&ctx->sc[1]); } if (is_rle) { - init_get_bits(&gb, buf, buf_size * 8); + if ((ret = init_get_bits8(&gb, buf, buf_size)) < 0) + return ret; if (ret = decode_rle(&gb, c->pal_pic, c->pal_stride, c->rgb_pic, c->rgb_stride, c->pal, keyframe, ctx->split_position, 0, @@ -726,8 +722,8 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, av_log(avctx, AV_LOG_WARNING, "buffer not fully consumed\n"); if (c->mvX < 0 || c->mvY < 0) { - av_frame_unref(&ctx->last_pic); - ret = av_frame_ref(&ctx->last_pic, frame); + av_frame_unref(ctx->last_pic); + ret = av_frame_ref(ctx->last_pic, frame); if (ret < 0) return ret; } @@ -775,7 +771,7 @@ static av_cold int wmv9_init(AVCodecContext *avctx) v->overlap = 0; - v->s.resync_marker = 0; + v->resync_marker = 0; v->rangered = 0; v->s.max_b_frames = avctx->max_b_frames = 0; @@ -802,7 +798,7 @@ static av_cold int mss2_decode_end(AVCodecContext *avctx) { MSS2Context *const ctx = avctx->priv_data; - av_frame_unref(&ctx->last_pic); + av_frame_free(&ctx->last_pic); ff_mss12_decode_end(&ctx->c); av_freep(&ctx->c.pal_pic); @@ -820,10 +816,11 @@ static av_cold int mss2_decode_init(AVCodecContext *avctx) c->avctx = avctx; if (ret = ff_mss12_decode_init(c, 1, &ctx->sc[0], &ctx->sc[1])) return ret; + ctx->last_pic = av_frame_alloc(); c->pal_stride = c->mask_stride; c->pal_pic = av_mallocz(c->pal_stride * avctx->height); c->last_pal_pic = av_mallocz(c->pal_stride * avctx->height); - if (!c->pal_pic || !c->last_pal_pic) { + if (!c->pal_pic || !c->last_pal_pic || !ctx->last_pic) { mss2_decode_end(avctx); return AVERROR(ENOMEM); } @@ -836,11 +833,13 @@ static av_cold int mss2_decode_init(AVCodecContext *avctx) avctx->pix_fmt = c->free_colours == 127 ? AV_PIX_FMT_RGB555 : AV_PIX_FMT_RGB24; + return 0; } AVCodec ff_mss2_decoder = { .name = "mss2", + .long_name = NULL_IF_CONFIG_SMALL("MS Windows Media Video V9 Screen"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MSS2, .priv_data_size = sizeof(MSS2Context), @@ -848,5 +847,4 @@ AVCodec ff_mss2_decoder = { .close = mss2_decode_end, .decode = mss2_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("MS Windows Media Video V9 Screen"), }; diff --git a/ffmpeg/libavcodec/mss3.c b/ffmpeg/libavcodec/mss3.c index 3cc484f..c6bb838 100644 --- a/ffmpeg/libavcodec/mss3.c +++ b/ffmpeg/libavcodec/mss3.c @@ -108,7 +108,7 @@ typedef struct HaarBlockCoder { typedef struct MSS3Context { AVCodecContext *avctx; - AVFrame pic; + AVFrame *pic; int got_error; RangeCoder coder; @@ -731,12 +731,12 @@ static int mss3_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return buf_size; c->got_error = 0; - if ((ret = ff_reget_buffer(avctx, &c->pic)) < 0) + if ((ret = ff_reget_buffer(avctx, c->pic)) < 0) return ret; - c->pic.key_frame = keyframe; - c->pic.pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; + c->pic->key_frame = keyframe; + c->pic->pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; if (!bytestream2_get_bytes_left(&gb)) { - if ((ret = av_frame_ref(data, &c->pic)) < 0) + if ((ret = av_frame_ref(data, c->pic)) < 0) return ret; *got_frame = 1; @@ -749,9 +749,9 @@ static int mss3_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, mb_width = dec_width >> 4; mb_height = dec_height >> 4; - dst[0] = c->pic.data[0] + dec_x + dec_y * c->pic.linesize[0]; - dst[1] = c->pic.data[1] + dec_x / 2 + (dec_y / 2) * c->pic.linesize[1]; - dst[2] = c->pic.data[2] + dec_x / 2 + (dec_y / 2) * c->pic.linesize[2]; + dst[0] = c->pic->data[0] + dec_x + dec_y * c->pic->linesize[0]; + dst[1] = c->pic->data[1] + dec_x / 2 + (dec_y / 2) * c->pic->linesize[1]; + dst[2] = c->pic->data[2] + dec_x / 2 + (dec_y / 2) * c->pic->linesize[2]; for (y = 0; y < mb_height; y++) { for (x = 0; x < mb_width; x++) { for (i = 0; i < 3; i++) { @@ -762,23 +762,23 @@ static int mss3_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, case FILL_BLOCK: decode_fill_block(acoder, c->fill_coder + i, dst[i] + x * blk_size, - c->pic.linesize[i], blk_size); + c->pic->linesize[i], blk_size); break; case IMAGE_BLOCK: decode_image_block(acoder, c->image_coder + i, dst[i] + x * blk_size, - c->pic.linesize[i], blk_size); + c->pic->linesize[i], blk_size); break; case DCT_BLOCK: decode_dct_block(acoder, c->dct_coder + i, dst[i] + x * blk_size, - c->pic.linesize[i], blk_size, + c->pic->linesize[i], blk_size, c->dctblock, x, y); break; case HAAR_BLOCK: decode_haar_block(acoder, c->haar_coder + i, dst[i] + x * blk_size, - c->pic.linesize[i], blk_size, + c->pic->linesize[i], blk_size, c->hblock); break; } @@ -790,12 +790,12 @@ static int mss3_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } } } - dst[0] += c->pic.linesize[0] * 16; - dst[1] += c->pic.linesize[1] * 8; - dst[2] += c->pic.linesize[2] * 8; + dst[0] += c->pic->linesize[0] * 16; + dst[1] += c->pic->linesize[1] * 8; + dst[2] += c->pic->linesize[2] * 8; } - if ((ret = av_frame_ref(data, &c->pic)) < 0) + if ((ret = av_frame_ref(data, c->pic)) < 0) return ret; *got_frame = 1; @@ -803,6 +803,18 @@ static int mss3_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return buf_size; } +static av_cold int mss3_decode_end(AVCodecContext *avctx) +{ + MSS3Context * const c = avctx->priv_data; + int i; + + av_frame_free(&c->pic); + for (i = 0; i < 3; i++) + av_freep(&c->dct_coder[i].prev_dc); + + return 0; +} + static av_cold int mss3_decode_init(AVCodecContext *avctx) { MSS3Context * const c = avctx->priv_data; @@ -826,6 +838,7 @@ static av_cold int mss3_decode_init(AVCodecContext *avctx) b_width * b_height); if (!c->dct_coder[i].prev_dc) { av_log(avctx, AV_LOG_ERROR, "Cannot allocate buffer\n"); + av_frame_free(&c->pic); while (i >= 0) { av_freep(&c->dct_coder[i].prev_dc); i--; @@ -834,6 +847,12 @@ static av_cold int mss3_decode_init(AVCodecContext *avctx) } } + c->pic = av_frame_alloc(); + if (!c->pic) { + mss3_decode_end(avctx); + return AVERROR(ENOMEM); + } + avctx->pix_fmt = AV_PIX_FMT_YUV420P; init_coders(c); @@ -841,20 +860,9 @@ static av_cold int mss3_decode_init(AVCodecContext *avctx) return 0; } -static av_cold int mss3_decode_end(AVCodecContext *avctx) -{ - MSS3Context * const c = avctx->priv_data; - int i; - - av_frame_unref(&c->pic); - for (i = 0; i < 3; i++) - av_freep(&c->dct_coder[i].prev_dc); - - return 0; -} - AVCodec ff_msa1_decoder = { .name = "msa1", + .long_name = NULL_IF_CONFIG_SMALL("MS ATC Screen"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MSA1, .priv_data_size = sizeof(MSS3Context), @@ -862,5 +870,4 @@ AVCodec ff_msa1_decoder = { .close = mss3_decode_end, .decode = mss3_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("MS ATC Screen"), }; diff --git a/ffmpeg/libavcodec/mss4.c b/ffmpeg/libavcodec/mss4.c index 391805f..662cf24 100644 --- a/ffmpeg/libavcodec/mss4.c +++ b/ffmpeg/libavcodec/mss4.c @@ -126,7 +126,7 @@ static const uint8_t mss4_vec_entry_vlc_syms[2][9] = { #define MAX_ENTRIES 162 typedef struct MSS4Context { - AVFrame pic; + AVFrame *pic; VLC dc_vlc[2], ac_vlc[2]; VLC vec_entry_vlc[2]; @@ -297,10 +297,10 @@ static int mss4_decode_dct_block(MSS4Context *c, GetBitContext *gb, return ret; c->prev_dc[0][mb_x * 2 + i] = c->dc_cache[j][LEFT]; - ff_mss34_dct_put(out + xpos * 8, c->pic.linesize[0], + ff_mss34_dct_put(out + xpos * 8, c->pic->linesize[0], c->block); } - out += 8 * c->pic.linesize[0]; + out += 8 * c->pic->linesize[0]; } for (i = 1; i < 3; i++) { @@ -320,7 +320,7 @@ static int mss4_decode_dct_block(MSS4Context *c, GetBitContext *gb, for (j = 0; j < 16; j++) { for (k = 0; k < 8; k++) AV_WN16A(out + k * 2, c->imgbuf[i][k + (j & ~1) * 4] * 0x101); - out += c->pic.linesize[i]; + out += c->pic->linesize[i]; } } @@ -481,7 +481,7 @@ static int mss4_decode_image_block(MSS4Context *ctx, GetBitContext *gb, for (i = 0; i < 3; i++) for (j = 0; j < 16; j++) - memcpy(picdst[i] + mb_x * 16 + j * ctx->pic.linesize[i], + memcpy(picdst[i] + mb_x * 16 + j * ctx->pic->linesize[i], ctx->imgbuf[i] + j * 16, 16); return 0; @@ -554,14 +554,14 @@ static int mss4_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return AVERROR_INVALIDDATA; } - if ((ret = ff_reget_buffer(avctx, &c->pic)) < 0) + if ((ret = ff_reget_buffer(avctx, c->pic)) < 0) return ret; - c->pic.key_frame = (frame_type == INTRA_FRAME); - c->pic.pict_type = (frame_type == INTRA_FRAME) ? AV_PICTURE_TYPE_I + c->pic->key_frame = (frame_type == INTRA_FRAME); + c->pic->pict_type = (frame_type == INTRA_FRAME) ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; if (frame_type == SKIP_FRAME) { *got_frame = 1; - if ((ret = av_frame_ref(data, &c->pic)) < 0) + if ((ret = av_frame_ref(data, c->pic)) < 0) return ret; return buf_size; @@ -573,13 +573,13 @@ static int mss4_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, ff_mss34_gen_quant_mat(c->quant_mat[i], quality, !i); } - init_get_bits(&gb, buf + HEADER_SIZE, (buf_size - HEADER_SIZE) * 8); + init_get_bits8(&gb, buf + HEADER_SIZE, (buf_size - HEADER_SIZE)); mb_width = FFALIGN(width, 16) >> 4; mb_height = FFALIGN(height, 16) >> 4; - dst[0] = c->pic.data[0]; - dst[1] = c->pic.data[1]; - dst[2] = c->pic.data[2]; + dst[0] = c->pic->data[0]; + dst[1] = c->pic->data[1]; + dst[2] = c->pic->data[2]; memset(c->prev_vec, 0, sizeof(c->prev_vec)); for (y = 0; y < mb_height; y++) { @@ -613,12 +613,12 @@ static int mss4_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (blk_type != DCT_BLOCK) mss4_update_dc_cache(c, x); } - dst[0] += c->pic.linesize[0] * 16; - dst[1] += c->pic.linesize[1] * 16; - dst[2] += c->pic.linesize[2] * 16; + dst[0] += c->pic->linesize[0] * 16; + dst[1] += c->pic->linesize[1] * 16; + dst[2] += c->pic->linesize[2] * 16; } - if ((ret = av_frame_ref(data, &c->pic)) < 0) + if ((ret = av_frame_ref(data, c->pic)) < 0) return ret; *got_frame = 1; @@ -626,6 +626,19 @@ static int mss4_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return buf_size; } +static av_cold int mss4_decode_end(AVCodecContext *avctx) +{ + MSS4Context * const c = avctx->priv_data; + int i; + + av_frame_free(&c->pic); + for (i = 0; i < 3; i++) + av_freep(&c->prev_dc[i]); + mss4_free_vlcs(c); + + return 0; +} + static av_cold int mss4_decode_init(AVCodecContext *avctx) { MSS4Context * const c = avctx->priv_data; @@ -646,26 +659,20 @@ static av_cold int mss4_decode_init(AVCodecContext *avctx) } } - avctx->pix_fmt = AV_PIX_FMT_YUV444P; - - return 0; -} - -static av_cold int mss4_decode_end(AVCodecContext *avctx) -{ - MSS4Context * const c = avctx->priv_data; - int i; + c->pic = av_frame_alloc(); + if (!c->pic) { + mss4_decode_end(avctx); + return AVERROR(ENOMEM); + } - av_frame_unref(&c->pic); - for (i = 0; i < 3; i++) - av_freep(&c->prev_dc[i]); - mss4_free_vlcs(c); + avctx->pix_fmt = AV_PIX_FMT_YUV444P; return 0; } AVCodec ff_mts2_decoder = { .name = "mts2", + .long_name = NULL_IF_CONFIG_SMALL("MS Expression Encoder Screen"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MTS2, .priv_data_size = sizeof(MSS4Context), @@ -673,5 +680,4 @@ AVCodec ff_mts2_decoder = { .close = mss4_decode_end, .decode = mss4_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("MS Expression Encoder Screen"), }; diff --git a/ffmpeg/libavcodec/msvideo1.c b/ffmpeg/libavcodec/msvideo1.c index c5a1daa..970c67c 100644 --- a/ffmpeg/libavcodec/msvideo1.c +++ b/ffmpeg/libavcodec/msvideo1.c @@ -47,7 +47,7 @@ typedef struct Msvideo1Context { AVCodecContext *avctx; - AVFrame frame; + AVFrame *frame; const unsigned char *buf; int size; @@ -72,7 +72,9 @@ static av_cold int msvideo1_decode_init(AVCodecContext *avctx) avctx->pix_fmt = AV_PIX_FMT_RGB555; } - avcodec_get_frame_defaults(&s->frame); + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); return 0; } @@ -93,8 +95,8 @@ static void msvideo1_decode_8bit(Msvideo1Context *s) unsigned short flags; int skip_blocks; unsigned char colors[8]; - unsigned char *pixels = s->frame.data[0]; - int stride = s->frame.linesize[0]; + unsigned char *pixels = s->frame->data[0]; + int stride = s->frame->linesize[0]; stream_ptr = 0; skip_blocks = 0; @@ -174,7 +176,7 @@ static void msvideo1_decode_8bit(Msvideo1Context *s) /* make the palette available on the way out */ if (s->avctx->pix_fmt == AV_PIX_FMT_PAL8) - memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE); + memcpy(s->frame->data[1], s->pal, AVPALETTE_SIZE); } static void msvideo1_decode_16bit(Msvideo1Context *s) @@ -193,8 +195,8 @@ static void msvideo1_decode_16bit(Msvideo1Context *s) unsigned short flags; int skip_blocks; unsigned short colors[8]; - unsigned short *pixels = (unsigned short *)s->frame.data[0]; - int stride = s->frame.linesize[0] / 2; + unsigned short *pixels = (unsigned short *)s->frame->data[0]; + int stride = s->frame->linesize[0] / 2; stream_ptr = 0; skip_blocks = 0; @@ -298,7 +300,7 @@ static int msvideo1_decode_frame(AVCodecContext *avctx, s->buf = buf; s->size = buf_size; - if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) + if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) return ret; if (s->mode_8bit) { @@ -306,7 +308,7 @@ static int msvideo1_decode_frame(AVCodecContext *avctx, if (pal) { memcpy(s->pal, pal, AVPALETTE_SIZE); - s->frame.palette_has_changed = 1; + s->frame->palette_has_changed = 1; } } @@ -315,7 +317,7 @@ static int msvideo1_decode_frame(AVCodecContext *avctx, else msvideo1_decode_16bit(s); - if ((ret = av_frame_ref(data, &s->frame)) < 0) + if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; *got_frame = 1; @@ -328,13 +330,14 @@ static av_cold int msvideo1_decode_end(AVCodecContext *avctx) { Msvideo1Context *s = avctx->priv_data; - av_frame_unref(&s->frame); + av_frame_free(&s->frame); return 0; } AVCodec ff_msvideo1_decoder = { .name = "msvideo1", + .long_name = NULL_IF_CONFIG_SMALL("Microsoft Video 1"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MSVIDEO1, .priv_data_size = sizeof(Msvideo1Context), @@ -342,5 +345,4 @@ AVCodec ff_msvideo1_decoder = { .close = msvideo1_decode_end, .decode = msvideo1_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Microsoft Video 1"), }; diff --git a/ffmpeg/libavcodec/msvideo1enc.c b/ffmpeg/libavcodec/msvideo1enc.c index e0efb48..9928250 100644 --- a/ffmpeg/libavcodec/msvideo1enc.c +++ b/ffmpeg/libavcodec/msvideo1enc.c @@ -35,7 +35,6 @@ */ typedef struct Msvideo1EncContext { AVCodecContext *avctx; - AVFrame pic; AVLFG rnd; uint8_t *prev; @@ -67,7 +66,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { Msvideo1EncContext * const c = avctx->priv_data; - AVFrame * const p = &c->pic; + const AVFrame *p = pict; uint16_t *src; uint8_t *prevptr; uint8_t *dst, *buf; @@ -75,12 +74,12 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, int no_skips = 1; int i, j, k, x, y, ret; int skips = 0; + int quality = 24; if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width*avctx->height*9 + FF_MIN_BUFFER_SIZE)) < 0) return ret; dst= buf= pkt->data; - *p = *pict; if(!c->prev) c->prev = av_malloc(avctx->width * 3 * (avctx->height + 3)); prevptr = c->prev + avctx->width * 3 * (FFALIGN(avctx->height, 4) - 1); @@ -88,7 +87,6 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, if(c->keyint >= avctx->keyint_min) keyframe = 1; - p->quality = 24; for(y = 0; y < avctx->height; y += 4){ for(x = 0; x < avctx->width; x += 4){ @@ -114,12 +112,12 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, bestscore += t*t; } } - bestscore /= p->quality; + bestscore /= quality; } // try to find optimal value to fill whole 4x4 block score = 0; - ff_init_elbg(c->block, 3, 16, c->avg, 1, 1, c->output, &c->rnd); - ff_do_elbg (c->block, 3, 16, c->avg, 1, 1, c->output, &c->rnd); + avpriv_init_elbg(c->block, 3, 16, c->avg, 1, 1, c->output, &c->rnd); + avpriv_do_elbg (c->block, 3, 16, c->avg, 1, 1, c->output, &c->rnd); if(c->avg[0] == 1) // red component = 1 will be written as skip code c->avg[0] = 0; for(j = 0; j < 4; j++){ @@ -130,7 +128,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, } } } - score /= p->quality; + score /= quality; score += 2; if(score < bestscore){ bestscore = score; @@ -138,8 +136,8 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, } // search for optimal filling of 2-color block score = 0; - ff_init_elbg(c->block, 3, 16, c->codebook, 2, 1, c->output, &c->rnd); - ff_do_elbg (c->block, 3, 16, c->codebook, 2, 1, c->output, &c->rnd); + avpriv_init_elbg(c->block, 3, 16, c->codebook, 2, 1, c->output, &c->rnd); + avpriv_do_elbg (c->block, 3, 16, c->codebook, 2, 1, c->output, &c->rnd); // last output value should be always 1, swap codebooks if needed if(!c->output[15]){ for(i = 0; i < 3; i++) @@ -155,7 +153,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, } } } - score /= p->quality; + score /= quality; score += 6; if(score < bestscore){ bestscore = score; @@ -164,8 +162,8 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, // search for optimal filling of 2-color 2x2 subblocks score = 0; for(i = 0; i < 4; i++){ - ff_init_elbg(c->block2 + i*4*3, 3, 4, c->codebook2 + i*2*3, 2, 1, c->output2 + i*4, &c->rnd); - ff_do_elbg (c->block2 + i*4*3, 3, 4, c->codebook2 + i*2*3, 2, 1, c->output2 + i*4, &c->rnd); + avpriv_init_elbg(c->block2 + i*4*3, 3, 4, c->codebook2 + i*2*3, 2, 1, c->output2 + i*4, &c->rnd); + avpriv_do_elbg (c->block2 + i*4*3, 3, 4, c->codebook2 + i*2*3, 2, 1, c->output2 + i*4, &c->rnd); } // last value should be always 1, swap codebooks if needed if(!c->output2[15]){ @@ -182,7 +180,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, } } } - score /= p->quality; + score /= quality; score += 18; if(score < bestscore){ bestscore = score; @@ -248,8 +246,6 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, c->keyint = 0; else c->keyint++; - p->pict_type= keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; - p->key_frame= keyframe; if (keyframe) pkt->flags |= AV_PKT_FLAG_KEY; pkt->size = dst - buf; *got_packet = 1; @@ -274,8 +270,6 @@ static av_cold int encode_init(AVCodecContext *avctx) return -1; } - avcodec_get_frame_defaults(&c->pic); - avctx->coded_frame = (AVFrame*)&c->pic; avctx->bits_per_coded_sample = 16; c->keyint = avctx->keyint_min; @@ -300,6 +294,7 @@ static av_cold int encode_end(AVCodecContext *avctx) AVCodec ff_msvideo1_encoder = { .name = "msvideo1", + .long_name = NULL_IF_CONFIG_SMALL("Microsoft Video-1"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MSVIDEO1, .priv_data_size = sizeof(Msvideo1EncContext), @@ -307,5 +302,4 @@ AVCodec ff_msvideo1_encoder = { .encode2 = encode_frame, .close = encode_end, .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_RGB555, AV_PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("Microsoft Video-1"), }; diff --git a/ffmpeg/libavcodec/mvcdec.c b/ffmpeg/libavcodec/mvcdec.c index c4385fe..2cc7735 100644 --- a/ffmpeg/libavcodec/mvcdec.c +++ b/ffmpeg/libavcodec/mvcdec.c @@ -39,6 +39,7 @@ static av_cold int mvc_decode_init(AVCodecContext *avctx) MvcContext *s = avctx->priv_data; int width = avctx->width; int height = avctx->height; + int ret; if (avctx->codec_id == AV_CODEC_ID_MVC1) { width += 3; @@ -46,8 +47,8 @@ static av_cold int mvc_decode_init(AVCodecContext *avctx) } width &= ~3; height &= ~3; - if (width != avctx->width || height != avctx->height) - avcodec_set_dimensions(avctx, width, height); + if ((ret = ff_set_dimensions(avctx, width, height)) < 0) + return ret; avctx->pix_fmt = (avctx->codec_id == AV_CODEC_ID_MVC1) ? AV_PIX_FMT_RGB555 : AV_PIX_FMT_BGRA; s->frame = av_frame_alloc(); @@ -260,6 +261,7 @@ static av_cold int mvc_decode_end(AVCodecContext *avctx) #if CONFIG_MVC1_DECODER AVCodec ff_mvc1_decoder = { .name = "mvc1", + .long_name = NULL_IF_CONFIG_SMALL("Silicon Graphics Motion Video Compressor 1"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MVC1, .priv_data_size = sizeof(MvcContext), @@ -267,13 +269,13 @@ AVCodec ff_mvc1_decoder = { .close = mvc_decode_end, .decode = mvc_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Silicon Graphics Motion Video Compressor 1"), }; #endif #if CONFIG_MVC2_DECODER AVCodec ff_mvc2_decoder = { .name = "mvc2", + .long_name = NULL_IF_CONFIG_SMALL("Silicon Graphics Motion Video Compressor 2"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MVC2, .priv_data_size = sizeof(MvcContext), @@ -281,6 +283,5 @@ AVCodec ff_mvc2_decoder = { .close = mvc_decode_end, .decode = mvc_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Silicon Graphics Motion Video Compressor 2"), }; #endif diff --git a/ffmpeg/libavcodec/mxpegdec.c b/ffmpeg/libavcodec/mxpegdec.c index 0069ca5..8eee3b8 100644 --- a/ffmpeg/libavcodec/mxpegdec.c +++ b/ffmpeg/libavcodec/mxpegdec.c @@ -31,7 +31,7 @@ typedef struct MXpegDecodeContext { MJpegDecodeContext jpg; - AVFrame picture[2]; /* pictures array */ + AVFrame *picture[2]; /* pictures array */ int picture_index; /* index of current picture */ int got_sof_data; /* true if SOF data successfully parsed */ int got_mxm_bitmask; /* true if MXM bitmask available */ @@ -42,11 +42,36 @@ typedef struct MXpegDecodeContext { unsigned mb_width, mb_height; /* size of picture in MB's from MXM header */ } MXpegDecodeContext; +static av_cold int mxpeg_decode_end(AVCodecContext *avctx) +{ + MXpegDecodeContext *s = avctx->priv_data; + MJpegDecodeContext *jpg = &s->jpg; + int i; + + jpg->picture_ptr = NULL; + ff_mjpeg_decode_end(avctx); + + for (i = 0; i < 2; ++i) + av_frame_free(&s->picture[i]); + + av_freep(&s->mxm_bitmask); + av_freep(&s->completion_bitmask); + + return 0; +} + static av_cold int mxpeg_decode_init(AVCodecContext *avctx) { MXpegDecodeContext *s = avctx->priv_data; - s->jpg.picture_ptr = &s->picture[0]; + s->picture[0] = av_frame_alloc(); + s->picture[1] = av_frame_alloc(); + if (!s->picture[0] || !s->picture[1]) { + mxpeg_decode_end(avctx); + return AVERROR(ENOMEM); + } + + s->jpg.picture_ptr = s->picture[0]; return ff_mjpeg_decode_init(avctx); } @@ -260,7 +285,7 @@ static int mxpeg_decode_frame(AVCodecContext *avctx, } if (s->got_mxm_bitmask) { - AVFrame *reference_ptr = &s->picture[s->picture_index ^ 1]; + AVFrame *reference_ptr = s->picture[s->picture_index ^ 1]; if (mxpeg_check_dimensions(s, jpg, reference_ptr) < 0) break; @@ -295,7 +320,7 @@ the_end: *got_frame = 1; s->picture_index ^= 1; - jpg->picture_ptr = &s->picture[s->picture_index]; + jpg->picture_ptr = s->picture[s->picture_index]; if (!s->has_complete_frame) { if (!s->got_mxm_bitmask) @@ -308,24 +333,6 @@ the_end: return buf_ptr - buf; } -static av_cold int mxpeg_decode_end(AVCodecContext *avctx) -{ - MXpegDecodeContext *s = avctx->priv_data; - MJpegDecodeContext *jpg = &s->jpg; - int i; - - jpg->picture_ptr = NULL; - ff_mjpeg_decode_end(avctx); - - for (i = 0; i < 2; ++i) - av_frame_unref(&s->picture[i]); - - av_freep(&s->mxm_bitmask); - av_freep(&s->completion_bitmask); - - return 0; -} - AVCodec ff_mxpeg_decoder = { .name = "mxpeg", .long_name = NULL_IF_CONFIG_SMALL("Mobotix MxPEG video"), diff --git a/ffmpeg/libavcodec/nellymoserdec.c b/ffmpeg/libavcodec/nellymoserdec.c index 42110a2..ef16fd6 100644 --- a/ffmpeg/libavcodec/nellymoserdec.c +++ b/ffmpeg/libavcodec/nellymoserdec.c @@ -196,6 +196,7 @@ static av_cold int decode_end(AVCodecContext * avctx) { AVCodec ff_nellymoser_decoder = { .name = "nellymoser", + .long_name = NULL_IF_CONFIG_SMALL("Nellymoser Asao"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_NELLYMOSER, .priv_data_size = sizeof(NellyMoserDecodeContext), @@ -203,7 +204,6 @@ AVCodec ff_nellymoser_decoder = { .close = decode_end, .decode = decode_tag, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_PARAM_CHANGE, - .long_name = NULL_IF_CONFIG_SMALL("Nellymoser Asao"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE }, }; diff --git a/ffmpeg/libavcodec/nellymoserenc.c b/ffmpeg/libavcodec/nellymoserenc.c index b35820a..f9d1389 100644 --- a/ffmpeg/libavcodec/nellymoserenc.c +++ b/ffmpeg/libavcodec/nellymoserenc.c @@ -404,6 +404,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *avpkt, AVCodec ff_nellymoser_encoder = { .name = "nellymoser", + .long_name = NULL_IF_CONFIG_SMALL("Nellymoser Asao"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_NELLYMOSER, .priv_data_size = sizeof(NellyMoserEncodeContext), @@ -411,7 +412,6 @@ AVCodec ff_nellymoser_encoder = { .encode2 = encode_frame, .close = encode_end, .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY, - .long_name = NULL_IF_CONFIG_SMALL("Nellymoser Asao"), .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE }, }; diff --git a/ffmpeg/libavcodec/noise_bsf.c b/ffmpeg/libavcodec/noise_bsf.c index 763af79..4f609de 100644 --- a/ffmpeg/libavcodec/noise_bsf.c +++ b/ffmpeg/libavcodec/noise_bsf.c @@ -36,6 +36,8 @@ static int noise(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const ch return AVERROR(EINVAL); *poutbuf= av_malloc(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!*poutbuf) + return AVERROR(ENOMEM); memcpy(*poutbuf, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); for(i=0; iwidth || height != c->height) { // also reserve space for a possible additional header - int buf_size = 24 + height * width * 3 / 2 + AV_LZO_OUTPUT_PADDING; + int buf_size = height * width * 3 / 2 + + FFMAX(AV_LZO_OUTPUT_PADDING, FF_INPUT_BUFFER_PADDING_SIZE) + + RTJPEG_HEADER_SIZE; if (buf_size > INT_MAX/8) return -1; if ((ret = av_image_check_size(height, width, 0, avctx)) < 0) @@ -138,6 +140,7 @@ static int codec_reinit(AVCodecContext *avctx, int width, int height, } ff_rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height, c->lq, c->cq); + av_frame_unref(c->pic); return 1; } else if (quality != c->quality) ff_rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height, @@ -154,7 +157,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, NuvContext *c = avctx->priv_data; AVFrame *picture = data; int orig_size = buf_size; - int keyframe; + int keyframe, ret; int size_change = 0; int result, init_frame = !avctx->frame_number; enum { @@ -207,11 +210,15 @@ retry: buf = &buf[12]; buf_size -= 12; if (comptype == NUV_RTJPEG_IN_LZO || comptype == NUV_LZO) { - int outlen = c->decomp_size - AV_LZO_OUTPUT_PADDING, inlen = buf_size; - if (av_lzo1x_decode(c->decomp_buf, &outlen, buf, &inlen)) + int outlen = c->decomp_size - FFMAX(FF_INPUT_BUFFER_PADDING_SIZE, AV_LZO_OUTPUT_PADDING); + int inlen = buf_size; + if (av_lzo1x_decode(c->decomp_buf, &outlen, buf, &inlen)) { av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n"); + return AVERROR_INVALIDDATA; + } buf = c->decomp_buf; - buf_size = c->decomp_size - AV_LZO_OUTPUT_PADDING - outlen; + buf_size = c->decomp_size - FFMAX(FF_INPUT_BUFFER_PADDING_SIZE, AV_LZO_OUTPUT_PADDING) - outlen; + memset(c->decomp_buf + buf_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); } if (c->codec_frameheader) { int w, h, q; @@ -242,20 +249,20 @@ retry: } if (size_change || keyframe) { - av_frame_unref(&c->pic); + av_frame_unref(c->pic); init_frame = 1; } - if ((result = ff_reget_buffer(avctx, &c->pic)) < 0) + if ((result = ff_reget_buffer(avctx, c->pic)) < 0) return result; if (init_frame) { - memset(c->pic.data[0], 0, avctx->height * c->pic.linesize[0]); - memset(c->pic.data[1], 0x80, avctx->height * c->pic.linesize[1] / 2); - memset(c->pic.data[2], 0x80, avctx->height * c->pic.linesize[2] / 2); + memset(c->pic->data[0], 0, avctx->height * c->pic->linesize[0]); + memset(c->pic->data[1], 0x80, avctx->height * c->pic->linesize[1] / 2); + memset(c->pic->data[2], 0x80, avctx->height * c->pic->linesize[2] / 2); } - c->pic.pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; - c->pic.key_frame = keyframe; + c->pic->pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; + c->pic->key_frame = keyframe; // decompress/copy/whatever data switch (comptype) { case NUV_LZO: @@ -266,17 +273,19 @@ retry: height = buf_size / c->width / 3 * 2; } if(height > 0) - copy_frame(&c->pic, buf, c->width, height); + copy_frame(c->pic, buf, c->width, height); break; } case NUV_RTJPEG_IN_LZO: case NUV_RTJPEG: - ff_rtjpeg_decode_frame_yuv420(&c->rtj, &c->pic, buf, buf_size); + ret = ff_rtjpeg_decode_frame_yuv420(&c->rtj, c->pic, buf, buf_size); + if (ret < 0) + return ret; break; case NUV_BLACK: - memset(c->pic.data[0], 0, c->width * c->height); - memset(c->pic.data[1], 128, c->width * c->height / 4); - memset(c->pic.data[2], 128, c->width * c->height / 4); + memset(c->pic->data[0], 0, c->width * c->height); + memset(c->pic->data[1], 128, c->width * c->height / 4); + memset(c->pic->data[2], 128, c->width * c->height / 4); break; case NUV_COPY_LAST: /* nothing more to do here */ @@ -286,7 +295,7 @@ retry: return AVERROR_INVALIDDATA; } - if ((result = av_frame_ref(picture, &c->pic)) < 0) + if ((result = av_frame_ref(picture, c->pic)) < 0) return result; *got_frame = 1; @@ -298,8 +307,11 @@ static av_cold int decode_init(AVCodecContext *avctx) NuvContext *c = avctx->priv_data; int ret; + c->pic = av_frame_alloc(); + if (!c->pic) + return AVERROR(ENOMEM); + avctx->pix_fmt = AV_PIX_FMT_YUV420P; - c->pic.data[0] = NULL; c->decomp_buf = NULL; c->quality = -1; c->width = 0; @@ -323,13 +335,14 @@ static av_cold int decode_end(AVCodecContext *avctx) NuvContext *c = avctx->priv_data; av_freep(&c->decomp_buf); - av_frame_unref(&c->pic); + av_frame_free(&c->pic); return 0; } AVCodec ff_nuv_decoder = { .name = "nuv", + .long_name = NULL_IF_CONFIG_SMALL("NuppelVideo/RTJPEG"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_NUV, .priv_data_size = sizeof(NuvContext), @@ -337,5 +350,4 @@ AVCodec ff_nuv_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("NuppelVideo/RTJPEG"), }; diff --git a/ffmpeg/libavcodec/old_codec_ids.h b/ffmpeg/libavcodec/old_codec_ids.h index d8a8f74..b956264 100644 --- a/ffmpeg/libavcodec/old_codec_ids.h +++ b/ffmpeg/libavcodec/old_codec_ids.h @@ -34,7 +34,9 @@ /* video codecs */ CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding +#if FF_API_XVMC CODEC_ID_MPEG2VIDEO_XVMC, +#endif CODEC_ID_H261, CODEC_ID_H263, CODEC_ID_RV10, diff --git a/ffmpeg/libavcodec/options.c b/ffmpeg/libavcodec/options.c index 1d10128..5ee9d6b 100644 --- a/ffmpeg/libavcodec/options.c +++ b/ffmpeg/libavcodec/options.c @@ -77,7 +77,7 @@ static AVClassCategory get_category(void *ptr) static const AVClass av_codec_context_class = { .class_name = "AVCodecContext", .item_name = context_to_name, - .option = options, + .option = avcodec_options, .version = LIBAVUTIL_VERSION_INT, .log_level_offset_offset = offsetof(AVCodecContext, log_level_offset), .child_next = codec_child_next, @@ -86,14 +86,6 @@ static const AVClass av_codec_context_class = { .get_category = get_category, }; -#if FF_API_ALLOC_CONTEXT -void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType codec_type){ - AVCodec c= {0}; - c.type= codec_type; - avcodec_get_context_defaults3(s, &c); -} -#endif - int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec) { int flags=0; @@ -102,6 +94,9 @@ int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec) s->av_class = &av_codec_context_class; s->codec_type = codec ? codec->type : AVMEDIA_TYPE_UNKNOWN; + if (codec) + s->codec_id = codec->id; + if(s->codec_type == AVMEDIA_TYPE_AUDIO) flags= AV_OPT_FLAG_AUDIO_PARAM; else if(s->codec_type == AVMEDIA_TYPE_VIDEO) @@ -159,26 +154,6 @@ AVCodecContext *avcodec_alloc_context3(const AVCodec *codec) return avctx; } -#if FF_API_ALLOC_CONTEXT -AVCodecContext *avcodec_alloc_context2(enum AVMediaType codec_type){ - AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext)); - - if(avctx==NULL) return NULL; - - avcodec_get_context_defaults2(avctx, codec_type); - - return avctx; -} - -void avcodec_get_context_defaults(AVCodecContext *s){ - avcodec_get_context_defaults2(s, AVMEDIA_TYPE_UNKNOWN); -} - -AVCodecContext *avcodec_alloc_context(void){ - return avcodec_alloc_context2(AVMEDIA_TYPE_UNKNOWN); -} -#endif - int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src) { if (avcodec_is_open(dest)) { // check that the dest context is uninitialized @@ -187,6 +162,10 @@ int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src) src, dest); return AVERROR(EINVAL); } + + av_opt_free(dest); + av_free(dest->priv_data); + memcpy(dest, src, sizeof(*dest)); /* set values specific to opened codecs back to their default state */ @@ -194,7 +173,6 @@ int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src) dest->codec = NULL; dest->slice_offset = NULL; dest->hwaccel = NULL; - dest->thread_opaque = NULL; dest->internal = NULL; /* reallocate values that should be allocated separately */ @@ -223,6 +201,7 @@ int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src) alloc_and_copy_or_fail(intra_matrix, 64 * sizeof(int16_t), 0); alloc_and_copy_or_fail(inter_matrix, 64 * sizeof(int16_t), 0); alloc_and_copy_or_fail(rc_override, src->rc_override_count * sizeof(*src->rc_override), 0); + alloc_and_copy_or_fail(subtitle_header, src->subtitle_header_size, 1); #undef alloc_and_copy_or_fail return 0; diff --git a/ffmpeg/libavcodec/options_table.h b/ffmpeg/libavcodec/options_table.h index d7e2683..c82c104 100644 --- a/ffmpeg/libavcodec/options_table.h +++ b/ffmpeg/libavcodec/options_table.h @@ -24,11 +24,11 @@ #include #include +#include #include "libavutil/opt.h" #include "avcodec.h" #include "version.h" -#include "config.h" #define OFFSET(x) offsetof(AVCodecContext,x) #define DEFAULT 0 //should be NAN but it does not work as it is not a constant in glibc as required by ANSI/ISO C @@ -41,7 +41,7 @@ #define AV_CODEC_DEFAULT_BITRATE 200*1000 -static const AVOption options[]={ +static const AVOption avcodec_options[] = { {"b", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT, {.i64 = AV_CODEC_DEFAULT_BITRATE }, 0, INT_MAX, A|V|E}, {"ab", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT, {.i64 = 128*1000 }, 0, INT_MAX, A|E}, {"bt", "Set video bitrate tolerance (in bits/s). In 1-pass mode, bitrate tolerance specifies how far " @@ -49,6 +49,7 @@ static const AVOption options[]={ "to minimum/maximum bitrate. Lowering tolerance too much has an adverse effect on quality.", OFFSET(bit_rate_tolerance), AV_OPT_TYPE_INT, {.i64 = AV_CODEC_DEFAULT_BITRATE*20 }, 1, INT_MAX, V|E}, {"flags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, UINT_MAX, V|A|S|E|D, "flags"}, +{"unaligned", "allow decoders to produce unaligned output", 0, AV_OPT_TYPE_CONST, { .i64 = CODEC_FLAG_UNALIGNED }, INT_MIN, INT_MAX, V | D, "flags" }, {"mv4", "use four motion vectors per macroblock (MPEG-4)", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_4MV }, INT_MIN, INT_MAX, V|E, "flags"}, {"qpel", "use 1/4-pel motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_QPEL }, INT_MIN, INT_MAX, V|E, "flags"}, {"loop", "use loop filter", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_LOOP_FILTER }, INT_MIN, INT_MAX, V|E, "flags"}, @@ -70,9 +71,10 @@ static const AVOption options[]={ {"aic", "H.263 advanced intra coding / MPEG-4 AC prediction", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_AC_PRED }, INT_MIN, INT_MAX, V|E, "flags"}, {"ilme", "interlaced motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_INTERLACED_ME }, INT_MIN, INT_MAX, V|E, "flags"}, {"cgop", "closed GOP", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_CLOSED_GOP }, INT_MIN, INT_MAX, V|E, "flags"}, +{"output_corrupt", "Output even potentially corrupted frames", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_OUTPUT_CORRUPT }, INT_MIN, INT_MAX, V|D, "flags"}, {"fast", "allow non-spec-compliant speedup tricks", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_FAST }, INT_MIN, INT_MAX, V|E, "flags2"}, {"noout", "skip bitstream encoding", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_NO_OUTPUT }, INT_MIN, INT_MAX, V|E, "flags2"}, -{"ignorecrop", "ignore cropping information from sps", 1, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_IGNORE_CROP }, INT_MIN, INT_MAX, V|D, "flags2"}, +{"ignorecrop", "ignore cropping information from sps", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_IGNORE_CROP }, INT_MIN, INT_MAX, V|D, "flags2"}, {"local_header", "place global headers at every keyframe instead of in extradata", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_LOCAL_HEADER }, INT_MIN, INT_MAX, V|E, "flags2"}, {"chunks", "Frame data might be split into multiple chunks", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_CHUNKS }, INT_MIN, INT_MAX, V|D, "flags2"}, {"showall", "Show all frames before the first keyframe", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_SHOW_ALL }, INT_MIN, INT_MAX, V|D, "flags2"}, @@ -105,7 +107,7 @@ static const AVOption options[]={ {"qmin", "minimum video quantizer scale (VBR)", OFFSET(qmin), AV_OPT_TYPE_INT, {.i64 = 2 }, -1, 69, V|E}, {"qmax", "maximum video quantizer scale (VBR)", OFFSET(qmax), AV_OPT_TYPE_INT, {.i64 = 31 }, -1, 1024, V|E}, {"qdiff", "maximum difference between the quantizer scales (VBR)", OFFSET(max_qdiff), AV_OPT_TYPE_INT, {.i64 = 3 }, INT_MIN, INT_MAX, V|E}, -{"bf", "use 'frames' B frames", OFFSET(max_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, -1, FF_MAX_B_FRAMES, V|E}, +{"bf", "set maximum number of B frames between non-B-frames", OFFSET(max_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, -1, INT_MAX, V|E}, {"b_qfactor", "QP factor between P- and B-frames", OFFSET(b_quant_factor), AV_OPT_TYPE_FLOAT, {.dbl = 1.25 }, -FLT_MAX, FLT_MAX, V|E}, {"rc_strategy", "ratecontrol method", OFFSET(rc_strategy), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, {"b_strategy", "strategy to choose between I/P/B-frames", OFFSET(b_frame_strategy), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, V|E}, @@ -122,12 +124,16 @@ static const AVOption options[]={ {"codec_tag", NULL, OFFSET(codec_tag), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, {"bug", "work around not autodetected encoder bugs", OFFSET(workaround_bugs), AV_OPT_TYPE_FLAGS, {.i64 = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, "bug"}, {"autodetect", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, "bug"}, +#if FF_API_OLD_MSMPEG4 {"old_msmpeg4", "some old lavc-generated MSMPEG4v3 files (no autodetection)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_OLD_MSMPEG4 }, INT_MIN, INT_MAX, V|D, "bug"}, +#endif {"xvid_ilace", "Xvid interlacing bug (autodetected if FOURCC == XVIX)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_XVID_ILACE }, INT_MIN, INT_MAX, V|D, "bug"}, {"ump4", "(autodetected if FOURCC == UMP4)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_UMP4 }, INT_MIN, INT_MAX, V|D, "bug"}, {"no_padding", "padding bug (autodetected)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_NO_PADDING }, INT_MIN, INT_MAX, V|D, "bug"}, {"amv", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AMV }, INT_MIN, INT_MAX, V|D, "bug"}, +#if FF_API_AC_VLC {"ac_vlc", "illegal VLC bug (autodetected per FOURCC)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AC_VLC }, INT_MIN, INT_MAX, V|D, "bug"}, +#endif {"qpel_chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_QPEL_CHROMA }, INT_MIN, INT_MAX, V|D, "bug"}, {"std_qpel", "old standard qpel (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_STD_QPEL }, INT_MIN, INT_MAX, V|D, "bug"}, {"qpel_chroma2", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_QPEL_CHROMA2 }, INT_MIN, INT_MAX, V|D, "bug"}, @@ -144,12 +150,12 @@ static const AVOption options[]={ {"unofficial", "allow unofficial extensions", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_UNOFFICIAL }, INT_MIN, INT_MAX, V|D|E, "strict"}, {"experimental", "allow non-standardized experimental things", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_EXPERIMENTAL }, INT_MIN, INT_MAX, V|D|E, "strict"}, {"b_qoffset", "QP offset between P- and B-frames", OFFSET(b_quant_offset), AV_OPT_TYPE_FLOAT, {.dbl = 1.25 }, -FLT_MAX, FLT_MAX, V|E}, -{"err_detect", "set error detection flags", OFFSET(err_recognition), AV_OPT_TYPE_FLAGS, {.i64 = AV_EF_CRCCHECK }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"err_detect", "set error detection flags", OFFSET(err_recognition), AV_OPT_TYPE_FLAGS, {.i64 = 0 }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, {"crccheck", "verify embedded CRCs", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CRCCHECK }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, {"bitstream", "detect bitstream specification deviations", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BITSTREAM }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, {"buffer", "detect improper bitstream length", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BUFFER }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, {"explode", "abort decoding on minor error detection", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_EXPLODE }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, -{"careful", "consider things that violate the spec and have not been seen in the wild as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CAREFUL }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"careful", "consider things that violate the spec, are fast to check and have not been seen in the wild as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CAREFUL }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, {"compliant", "consider all spec non compliancies as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_COMPLIANT }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, {"aggressive", "consider things that a sane encoder should not do as an error", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_AGGRESSIVE }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, {"has_b_frames", NULL, OFFSET(has_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, @@ -196,7 +202,9 @@ static const AVOption options[]={ {"simplearmv5te", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV5TE }, INT_MIN, INT_MAX, V|E|D, "idct"}, {"simplearmv6", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV6 }, INT_MIN, INT_MAX, V|E|D, "idct"}, {"simpleneon", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLENEON }, INT_MIN, INT_MAX, V|E|D, "idct"}, +#if FF_API_ARCH_ALPHA {"simplealpha", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEALPHA }, INT_MIN, INT_MAX, V|E|D, "idct"}, +#endif {"ipp", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_IPP }, INT_MIN, INT_MAX, V|E|D, "idct"}, {"xvidmmx", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVIDMMX }, INT_MIN, INT_MAX, V|E|D, "idct"}, {"faani", "floating point AAN IDCT", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_FAAN }, INT_MIN, INT_MAX, V|D|E, "idct"}, @@ -216,7 +224,9 @@ static const AVOption options[]={ {"bitstream", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BITSTREAM }, INT_MIN, INT_MAX, V|D, "debug"}, {"mb_type", "macroblock (MB) type", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MB_TYPE }, INT_MIN, INT_MAX, V|D, "debug"}, {"qp", "per-block quantization parameter (QP)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_QP }, INT_MIN, INT_MAX, V|D, "debug"}, +#if FF_API_DEBUG_MV {"mv", "motion vector", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MV }, INT_MIN, INT_MAX, V|D, "debug"}, +#endif {"dct_coeff", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_DCT_COEFF }, INT_MIN, INT_MAX, V|D, "debug"}, {"skip", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_SKIP }, INT_MIN, INT_MAX, V|D, "debug"}, {"startcode", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_STARTCODE }, INT_MIN, INT_MAX, V|D, "debug"}, @@ -227,7 +237,7 @@ static const AVOption options[]={ {"vis_qp", "visualize quantization parameter (QP), lower QP are tinted greener", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_QP }, INT_MIN, INT_MAX, V|D, "debug"}, {"vis_mb_type", "visualize block types", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MB_TYPE }, INT_MIN, INT_MAX, V|D, "debug"}, {"buffers", "picture buffer allocations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUFFERS }, INT_MIN, INT_MAX, V|D, "debug"}, -{"thread_ops", "threading operations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_THREADS }, INT_MIN, INT_MAX, V|D, "debug"}, +{"thread_ops", "threading operations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_THREADS }, INT_MIN, INT_MAX, V|A|D, "debug"}, {"vismv", "visualize motion vectors (MVs)", OFFSET(debug_mv), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|D, "debug_mv"}, {"pf", "forward predicted MVs of P-frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MV_P_FOR }, INT_MIN, INT_MAX, V|D, "debug_mv"}, {"bf", "forward predicted MVs of B-frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MV_B_FOR }, INT_MIN, INT_MAX, V|D, "debug_mv"}, @@ -272,7 +282,9 @@ static const AVOption options[]={ {"deflate", "deflate-based coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_DEFLATE }, INT_MIN, INT_MAX, V|E, "coder"}, {"context", "context model", OFFSET(context_model), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, {"slice_flags", NULL, OFFSET(slice_flags), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +#if FF_API_XVMC {"xvmc_acceleration", NULL, OFFSET(xvmc_acceleration), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +#endif /* FF_API_XVMC */ {"mbd", "macroblock decision algorithm (high quality mode)", OFFSET(mb_decision), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, 2, V|E, "mbd"}, {"simple", "use mbcmp (default)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_SIMPLE }, INT_MIN, INT_MAX, V|E, "mbd"}, {"bits", "use fewest bits", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_BITS }, INT_MIN, INT_MAX, V|E, "mbd"}, @@ -284,8 +296,10 @@ static const AVOption options[]={ {"nr", "noise reduction", OFFSET(noise_reduction), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, {"rc_init_occupancy", "number of bits which should be loaded into the rc buffer before decoding starts", OFFSET(rc_initial_buffer_occupancy), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, {"flags2", NULL, OFFSET(flags2), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT}, 0, UINT_MAX, V|A|E|D, "flags2"}, +#if FF_API_ERROR_RATE {"error", NULL, OFFSET(error_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, -{"threads", NULL, OFFSET(thread_count), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, INT_MAX, V|E|D, "threads"}, +#endif +{"threads", NULL, OFFSET(thread_count), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, INT_MAX, V|A|E|D, "threads"}, {"auto", "autodetect a suitable number of threads to use", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, INT_MIN, INT_MAX, V|E|D, "threads"}, {"me_threshold", "motion estimation threshold", OFFSET(me_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, {"mb_threshold", "macroblock threshold", OFFSET(mb_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, @@ -303,6 +317,8 @@ static const AVOption options[]={ {"aac_he_v2", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_HE_V2 }, INT_MIN, INT_MAX, A|E, "profile"}, {"aac_ld", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_LD }, INT_MIN, INT_MAX, A|E, "profile"}, {"aac_eld", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_ELD }, INT_MIN, INT_MAX, A|E, "profile"}, +{"mpeg2_aac_low", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG2_AAC_LOW }, INT_MIN, INT_MAX, A|E, "profile"}, +{"mpeg2_aac_he", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG2_AAC_HE }, INT_MIN, INT_MAX, A|E, "profile"}, {"dts", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS }, INT_MIN, INT_MAX, A|E, "profile"}, {"dts_es", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_ES }, INT_MIN, INT_MAX, A|E, "profile"}, {"dts_96_24", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_96_24 }, INT_MIN, INT_MAX, A|E, "profile"}, @@ -357,7 +373,7 @@ static const AVOption options[]={ {"chroma_sample_location", NULL, OFFSET(chroma_sample_location), AV_OPT_TYPE_INT, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, 0, AVCHROMA_LOC_NB-1, V|E|D}, {"log_level_offset", "set the log level offset", OFFSET(log_level_offset), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX }, {"slices", "number of slices, used in parallelized encoding", OFFSET(slices), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|E}, -{"thread_type", "select multithreading type", OFFSET(thread_type), AV_OPT_TYPE_FLAGS, {.i64 = FF_THREAD_SLICE|FF_THREAD_FRAME }, 0, INT_MAX, V|E|D, "thread_type"}, +{"thread_type", "select multithreading type", OFFSET(thread_type), AV_OPT_TYPE_FLAGS, {.i64 = FF_THREAD_SLICE|FF_THREAD_FRAME }, 0, INT_MAX, V|A|E|D, "thread_type"}, {"slice", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_THREAD_SLICE }, INT_MIN, INT_MAX, V|E|D, "thread_type"}, {"frame", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_THREAD_FRAME }, INT_MIN, INT_MAX, V|E|D, "thread_type"}, {"audio_service_type", "audio service type", OFFSET(audio_service_type), AV_OPT_TYPE_INT, {.i64 = AV_AUDIO_SERVICE_TYPE_MAIN }, 0, AV_AUDIO_SERVICE_TYPE_NB-1, A|E, "audio_service_type"}, @@ -370,7 +386,7 @@ static const AVOption options[]={ {"em", "Emergency", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_EMERGENCY }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, {"vo", "Voice Over", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_VOICE_OVER }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, {"ka", "Karaoke", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_KARAOKE }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, -{"request_sample_fmt", "sample format audio decoders should prefer", OFFSET(request_sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, {.i64=AV_SAMPLE_FMT_NONE}, -1, AV_SAMPLE_FMT_NB-1, A|D, "request_sample_fmt"}, +{"request_sample_fmt", "sample format audio decoders should prefer", OFFSET(request_sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, {.i64=AV_SAMPLE_FMT_NONE}, -1, INT_MAX, A|D, "request_sample_fmt"}, {"pkt_timebase", NULL, OFFSET(pkt_timebase), AV_OPT_TYPE_RATIONAL, {.dbl = 0 }, 0, INT_MAX, 0}, {"sub_charenc", "set input text subtitles character encoding", OFFSET(sub_charenc), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, S|D}, {"sub_charenc_mode", "set input text subtitles character encoding mode", OFFSET(sub_charenc_mode), AV_OPT_TYPE_FLAGS, {.i64 = FF_SUB_CHARENC_MODE_AUTOMATIC}, -1, INT_MAX, S|D, "sub_charenc_mode"}, @@ -378,6 +394,13 @@ static const AVOption options[]={ {"auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_AUTOMATIC}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"}, {"pre_decoder", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_PRE_DECODER}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"}, {"refcounted_frames", NULL, OFFSET(refcounted_frames), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, A|V|D }, +{"skip_alpha", "Skip processing alpha", OFFSET(skip_alpha), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, V|D }, +{"field_order", "Field order", OFFSET(field_order), AV_OPT_TYPE_INT, {.i64 = AV_FIELD_UNKNOWN }, 0, 5, V|D|E, "field_order" }, +{"progressive", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_PROGRESSIVE }, 0, 0, V|D|E, "field_order" }, +{"tt", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_TT }, 0, 0, V|D|E, "field_order" }, +{"bb", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_BB }, 0, 0, V|D|E, "field_order" }, +{"tb", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_TB }, 0, 0, V|D|E, "field_order" }, +{"bt", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_BT }, 0, 0, V|D|E, "field_order" }, {NULL}, }; diff --git a/ffmpeg/libavcodec/os2threads.h b/ffmpeg/libavcodec/os2threads.h deleted file mode 100644 index b816bff..0000000 --- a/ffmpeg/libavcodec/os2threads.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2011 KO Myung-Hun - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * os2threads to pthreads wrapper - */ - -#ifndef AVCODEC_OS2PTHREADS_H -#define AVCODEC_OS2PTHREADS_H - -#define INCL_DOS -#include - -#undef __STRICT_ANSI__ /* for _beginthread() */ -#include - -typedef TID pthread_t; -typedef void pthread_attr_t; - -typedef HMTX pthread_mutex_t; -typedef void pthread_mutexattr_t; - -typedef struct { - HEV event_sem; - int wait_count; -} pthread_cond_t; - -typedef void pthread_condattr_t; - -struct thread_arg { - void *(*start_routine)(void *); - void *arg; -}; - -static void thread_entry(void *arg) -{ - struct thread_arg *thread_arg = arg; - - thread_arg->start_routine(thread_arg->arg); - - av_free(thread_arg); -} - -static av_always_inline int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg) -{ - struct thread_arg *thread_arg; - - thread_arg = av_mallocz(sizeof(struct thread_arg)); - - thread_arg->start_routine = start_routine; - thread_arg->arg = arg; - - *thread = _beginthread(thread_entry, NULL, 256 * 1024, thread_arg); - - return 0; -} - -static av_always_inline int pthread_join(pthread_t thread, void **value_ptr) -{ - DosWaitThread((PTID)&thread, DCWW_WAIT); - - return 0; -} - -static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) -{ - DosCreateMutexSem(NULL, (PHMTX)mutex, 0, FALSE); - - return 0; -} - -static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex) -{ - DosCloseMutexSem(*(PHMTX)mutex); - - return 0; -} - -static av_always_inline int pthread_mutex_lock(pthread_mutex_t *mutex) -{ - DosRequestMutexSem(*(PHMTX)mutex, SEM_INDEFINITE_WAIT); - - return 0; -} - -static av_always_inline int pthread_mutex_unlock(pthread_mutex_t *mutex) -{ - DosReleaseMutexSem(*(PHMTX)mutex); - - return 0; -} - -static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) -{ - DosCreateEventSem(NULL, &cond->event_sem, DCE_POSTONE, FALSE); - - cond->wait_count = 0; - - return 0; -} - -static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond) -{ - DosCloseEventSem(cond->event_sem); - - return 0; -} - -static av_always_inline int pthread_cond_signal(pthread_cond_t *cond) -{ - if (cond->wait_count > 0) { - DosPostEventSem(cond->event_sem); - - cond->wait_count--; - } - - return 0; -} - -static av_always_inline int pthread_cond_broadcast(pthread_cond_t *cond) -{ - while (cond->wait_count > 0) { - DosPostEventSem(cond->event_sem); - - cond->wait_count--; - } - - return 0; -} - -static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) -{ - cond->wait_count++; - - pthread_mutex_unlock(mutex); - - DosWaitEventSem(cond->event_sem, SEM_INDEFINITE_WAIT); - - pthread_mutex_lock(mutex); - - return 0; -} - -#endif /* AVCODEC_OS2PTHREADS_H */ diff --git a/ffmpeg/libavcodec/paf.c b/ffmpeg/libavcodec/paf.c index 7892314..76c90c9 100644 --- a/ffmpeg/libavcodec/paf.c +++ b/ffmpeg/libavcodec/paf.c @@ -48,7 +48,7 @@ static const uint8_t block_sequences[16][8] = }; typedef struct PAFVideoDecContext { - AVFrame pic; + AVFrame *pic; GetByteContext gb; int current_frame; @@ -59,6 +59,19 @@ typedef struct PAFVideoDecContext { uint8_t *opcodes; } PAFVideoDecContext; +static av_cold int paf_vid_close(AVCodecContext *avctx) +{ + PAFVideoDecContext *c = avctx->priv_data; + int i; + + av_frame_free(&c->pic); + + for (i = 0; i < 4; i++) + av_freep(&c->frame[i]); + + return 0; +} + static av_cold int paf_vid_init(AVCodecContext *avctx) { PAFVideoDecContext *c = avctx->priv_data; @@ -71,13 +84,18 @@ static av_cold int paf_vid_init(AVCodecContext *avctx) avctx->pix_fmt = AV_PIX_FMT_PAL8; - avcodec_get_frame_defaults(&c->pic); + c->pic = av_frame_alloc(); + if (!c->pic) + return AVERROR(ENOMEM); + c->frame_size = FFALIGN(avctx->height, 256) * avctx->width; c->video_size = avctx->height * avctx->width; for (i = 0; i < 4; i++) { c->frame[i] = av_mallocz(c->frame_size); - if (!c->frame[i]) + if (!c->frame[i]) { + paf_vid_close(avctx); return AVERROR(ENOMEM); + } } return 0; @@ -251,7 +269,7 @@ static int paf_vid_decode(AVCodecContext *avctx, void *data, uint8_t code, *dst, *src, *end; int i, frame, ret; - if ((ret =ff_reget_buffer(avctx, &c->pic)) < 0) + if ((ret = ff_reget_buffer(avctx, c->pic)) < 0) return ret; bytestream2_init(&c->gb, pkt->data, pkt->size); @@ -261,17 +279,17 @@ static int paf_vid_decode(AVCodecContext *avctx, void *data, for (i = 0; i < 4; i++) memset(c->frame[i], 0, c->frame_size); - memset(c->pic.data[1], 0, AVPALETTE_SIZE); + memset(c->pic->data[1], 0, AVPALETTE_SIZE); c->current_frame = 0; - c->pic.key_frame = 1; - c->pic.pict_type = AV_PICTURE_TYPE_I; + c->pic->key_frame = 1; + c->pic->pict_type = AV_PICTURE_TYPE_I; } else { - c->pic.key_frame = 0; - c->pic.pict_type = AV_PICTURE_TYPE_P; + c->pic->key_frame = 0; + c->pic->pict_type = AV_PICTURE_TYPE_P; } if (code & 0x40) { - uint32_t *out = (uint32_t *)c->pic.data[1]; + uint32_t *out = (uint32_t *)c->pic->data[1]; int index, count; index = bytestream2_get_byte(&c->gb); @@ -294,7 +312,7 @@ static int paf_vid_decode(AVCodecContext *avctx, void *data, b = b << 2 | b >> 4; *out++ = 0xFFU << 24 | r << 16 | g << 8 | b; } - c->pic.palette_has_changed = 1; + c->pic->palette_has_changed = 1; } switch (code & 0x0F) { @@ -346,16 +364,16 @@ static int paf_vid_decode(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } - dst = c->pic.data[0]; + dst = c->pic->data[0]; src = c->frame[c->current_frame]; for (i = 0; i < avctx->height; i++) { memcpy(dst, src, avctx->width); - dst += c->pic.linesize[0]; + dst += c->pic->linesize[0]; src += avctx->width; } c->current_frame = (c->current_frame + 1) & 3; - if ((ret = av_frame_ref(data, &c->pic)) < 0) + if ((ret = av_frame_ref(data, c->pic)) < 0) return ret; *got_frame = 1; @@ -363,19 +381,6 @@ static int paf_vid_decode(AVCodecContext *avctx, void *data, return pkt->size; } -static av_cold int paf_vid_close(AVCodecContext *avctx) -{ - PAFVideoDecContext *c = avctx->priv_data; - int i; - - av_frame_unref(&c->pic); - - for (i = 0; i < 4; i++) - av_freep(&c->frame[i]); - - return 0; -} - static av_cold int paf_aud_init(AVCodecContext *avctx) { if (avctx->channels != 2) { @@ -425,6 +430,7 @@ static int paf_aud_decode(AVCodecContext *avctx, void *data, AVCodec ff_paf_video_decoder = { .name = "paf_video", + .long_name = NULL_IF_CONFIG_SMALL("Amazing Studio Packed Animation File Video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PAF_VIDEO, .priv_data_size = sizeof(PAFVideoDecContext), @@ -432,15 +438,14 @@ AVCodec ff_paf_video_decoder = { .close = paf_vid_close, .decode = paf_vid_decode, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Amazing Studio Packed Animation File Video"), }; AVCodec ff_paf_audio_decoder = { .name = "paf_audio", + .long_name = NULL_IF_CONFIG_SMALL("Amazing Studio Packed Animation File Audio"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_PAF_AUDIO, .init = paf_aud_init, .decode = paf_aud_decode, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Amazing Studio Packed Animation File Audio"), }; diff --git a/ffmpeg/libavcodec/pamenc.c b/ffmpeg/libavcodec/pamenc.c index 3e47278..64ab2b5 100644 --- a/ffmpeg/libavcodec/pamenc.c +++ b/ffmpeg/libavcodec/pamenc.c @@ -21,14 +21,11 @@ #include "avcodec.h" #include "internal.h" -#include "pnm.h" - static int pam_encode_frame(AVCodecContext *avctx, AVPacket *pkt, - const AVFrame *pict, int *got_packet) + const AVFrame *p, int *got_packet) { - PNMContext *s = avctx->priv_data; - AVFrame * const p = &s->picture; + uint8_t *bytestream_start, *bytestream, *bytestream_end; int i, h, w, n, linesize, depth, maxval, ret; const char *tuple_type; uint8_t *ptr; @@ -91,18 +88,14 @@ static int pam_encode_frame(AVCodecContext *avctx, AVPacket *pkt, if ((ret = ff_alloc_packet2(avctx, pkt, n*h + 200)) < 0) return ret; - *p = *pict; - p->pict_type = AV_PICTURE_TYPE_I; - p->key_frame = 1; - - s->bytestream_start = - s->bytestream = pkt->data; - s->bytestream_end = pkt->data + pkt->size; + bytestream_start = + bytestream = pkt->data; + bytestream_end = pkt->data + pkt->size; - snprintf(s->bytestream, s->bytestream_end - s->bytestream, + snprintf(bytestream, bytestream_end - bytestream, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n", w, h, depth, maxval, tuple_type); - s->bytestream += strlen(s->bytestream); + bytestream += strlen(bytestream); ptr = p->data[0]; linesize = p->linesize[0]; @@ -111,33 +104,50 @@ static int pam_encode_frame(AVCodecContext *avctx, AVPacket *pkt, int j; for (i = 0; i < h; i++) { for (j = 0; j < w; j++) - *s->bytestream++ = ptr[j >> 3] >> (7 - j & 7) & 1; + *bytestream++ = ptr[j >> 3] >> (7 - j & 7) & 1; ptr += linesize; } } else { for (i = 0; i < h; i++) { - memcpy(s->bytestream, ptr, n); - s->bytestream += n; - ptr += linesize; + memcpy(bytestream, ptr, n); + bytestream += n; + ptr += linesize; } } - pkt->size = s->bytestream - s->bytestream_start; + pkt->size = bytestream - bytestream_start; pkt->flags |= AV_PKT_FLAG_KEY; *got_packet = 1; return 0; } +static av_cold int pam_encode_init(AVCodecContext *avctx) +{ + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->key_frame = 1; + + return 0; +} + +static av_cold int pam_encode_close(AVCodecContext *avctx) +{ + av_frame_free(&avctx->coded_frame); + return 0; +} AVCodec ff_pam_encoder = { .name = "pam", + .long_name = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PAM, - .priv_data_size = sizeof(PNMContext), - .init = ff_pnm_init, + .init = pam_encode_init, + .close = pam_encode_close, .encode2 = pam_encode_frame, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB48BE, AV_PIX_FMT_RGBA64BE, AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY8A, AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_MONOBLACK, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"), }; diff --git a/ffmpeg/libavcodec/parser.c b/ffmpeg/libavcodec/parser.c index f7cb5cf..083ce02 100644 --- a/ffmpeg/libavcodec/parser.c +++ b/ffmpeg/libavcodec/parser.c @@ -20,9 +20,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include #include "parser.h" +#include "libavutil/atomic.h" #include "libavutil/mem.h" static AVCodecParser *av_first_parser = NULL; @@ -34,8 +36,9 @@ AVCodecParser* av_parser_next(AVCodecParser *p){ void av_register_codec_parser(AVCodecParser *parser) { - parser->next = av_first_parser; - av_first_parser = parser; + do { + parser->next = av_first_parser; + } while (parser->next != avpriv_atomic_ptr_cas((void * volatile *)&av_first_parser, parser->next, parser)); } AVCodecParserContext *av_parser_init(int codec_id) @@ -235,8 +238,10 @@ int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_s if(next == END_NOT_FOUND){ void* new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size, (*buf_size) + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); - if(!new_buffer) + if(!new_buffer) { + pc->index = 0; return AVERROR(ENOMEM); + } pc->buffer = new_buffer; memcpy(&pc->buffer[pc->index], *buf, *buf_size); pc->index += *buf_size; @@ -249,9 +254,11 @@ int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_s /* append to buffer */ if(pc->index){ void* new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size, next + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); - - if(!new_buffer) + if(!new_buffer) { + pc->overread_index = + pc->index = 0; return AVERROR(ENOMEM); + } pc->buffer = new_buffer; if (next > -FF_INPUT_BUFFER_PADDING_SIZE) memcpy(&pc->buffer[pc->index], *buf, diff --git a/ffmpeg/libavcodec/pcm-mpeg.c b/ffmpeg/libavcodec/pcm-mpeg.c deleted file mode 100644 index aec056a..0000000 --- a/ffmpeg/libavcodec/pcm-mpeg.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - * LPCM codecs for PCM formats found in MPEG streams - * Copyright (c) 2009 Christian Schmidt - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * PCM codecs for encodings found in MPEG streams (DVD/Blu-ray) - */ - -#include "libavutil/channel_layout.h" -#include "avcodec.h" -#include "bytestream.h" -#include "internal.h" - -/* - * Channel Mapping according to - * Blu-ray Disc Read-Only Format Version 1 - * Part 3: Audio Visual Basic Specifications - * mono M1 X - * stereo L R - * 3/0 L R C X - * 2/1 L R S X - * 3/1 L R C S - * 2/2 L R LS RS - * 3/2 L R C LS RS X - * 3/2+lfe L R C LS RS lfe - * 3/4 L R C LS Rls Rrs RS X - * 3/4+lfe L R C LS Rls Rrs RS lfe - */ - -/** - * Parse the header of a LPCM frame read from a MPEG-TS stream - * @param avctx the codec context - * @param header pointer to the first four bytes of the data packet - */ -static int pcm_bluray_parse_header(AVCodecContext *avctx, - const uint8_t *header) -{ - static const uint8_t bits_per_samples[4] = { 0, 16, 20, 24 }; - static const uint32_t channel_layouts[16] = { - 0, AV_CH_LAYOUT_MONO, 0, AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_SURROUND, - AV_CH_LAYOUT_2_1, AV_CH_LAYOUT_4POINT0, AV_CH_LAYOUT_2_2, AV_CH_LAYOUT_5POINT0, - AV_CH_LAYOUT_5POINT1, AV_CH_LAYOUT_7POINT0, AV_CH_LAYOUT_7POINT1, 0, 0, 0, 0 - }; - static const uint8_t channels[16] = { - 0, 1, 0, 2, 3, 3, 4, 4, 5, 6, 7, 8, 0, 0, 0, 0 - }; - uint8_t channel_layout = header[2] >> 4; - - if (avctx->debug & FF_DEBUG_PICT_INFO) - av_dlog(avctx, "pcm_bluray_parse_header: header = %02x%02x%02x%02x\n", - header[0], header[1], header[2], header[3]); - - /* get the sample depth and derive the sample format from it */ - avctx->bits_per_coded_sample = bits_per_samples[header[3] >> 6]; - if (!(avctx->bits_per_coded_sample == 16 || avctx->bits_per_coded_sample == 24)) { - av_log(avctx, AV_LOG_ERROR, "unsupported sample depth (%d)\n", avctx->bits_per_coded_sample); - return -1; - } - avctx->sample_fmt = avctx->bits_per_coded_sample == 16 ? AV_SAMPLE_FMT_S16 : - AV_SAMPLE_FMT_S32; - if (avctx->sample_fmt == AV_SAMPLE_FMT_S32) - avctx->bits_per_raw_sample = avctx->bits_per_coded_sample; - - /* get the sample rate. Not all values are used. */ - switch (header[2] & 0x0f) { - case 1: - avctx->sample_rate = 48000; - break; - case 4: - avctx->sample_rate = 96000; - break; - case 5: - avctx->sample_rate = 192000; - break; - default: - avctx->sample_rate = 0; - av_log(avctx, AV_LOG_ERROR, "reserved sample rate (%d)\n", - header[2] & 0x0f); - return -1; - } - - /* - * get the channel number (and mapping). Not all values are used. - * It must be noted that the number of channels in the MPEG stream can - * differ from the actual meaningful number, e.g. mono audio still has two - * channels, one being empty. - */ - avctx->channel_layout = channel_layouts[channel_layout]; - avctx->channels = channels[channel_layout]; - if (!avctx->channels) { - av_log(avctx, AV_LOG_ERROR, "reserved channel configuration (%d)\n", - channel_layout); - return -1; - } - - avctx->bit_rate = FFALIGN(avctx->channels, 2) * avctx->sample_rate * - avctx->bits_per_coded_sample; - - if (avctx->debug & FF_DEBUG_PICT_INFO) - av_dlog(avctx, - "pcm_bluray_parse_header: %d channels, %d bits per sample, %d Hz, %d bit/s\n", - avctx->channels, avctx->bits_per_coded_sample, - avctx->sample_rate, avctx->bit_rate); - return 0; -} - -static int pcm_bluray_decode_frame(AVCodecContext *avctx, void *data, - int *got_frame_ptr, AVPacket *avpkt) -{ - AVFrame *frame = data; - const uint8_t *src = avpkt->data; - int buf_size = avpkt->size; - GetByteContext gb; - int num_source_channels, channel, retval; - int sample_size, samples; - int16_t *dst16; - int32_t *dst32; - - if (buf_size < 4) { - av_log(avctx, AV_LOG_ERROR, "PCM packet too small\n"); - return -1; - } - - if (pcm_bluray_parse_header(avctx, src)) - return -1; - src += 4; - buf_size -= 4; - - bytestream2_init(&gb, src, buf_size); - - /* There's always an even number of channels in the source */ - num_source_channels = FFALIGN(avctx->channels, 2); - sample_size = (num_source_channels * (avctx->sample_fmt == AV_SAMPLE_FMT_S16 ? 16 : 24)) >> 3; - samples = buf_size / sample_size; - - /* get output buffer */ - frame->nb_samples = samples; - if ((retval = ff_get_buffer(avctx, frame, 0)) < 0) - return retval; - dst16 = (int16_t *)frame->data[0]; - dst32 = (int32_t *)frame->data[0]; - - if (samples) { - switch (avctx->channel_layout) { - /* cases with same number of source and coded channels */ - case AV_CH_LAYOUT_STEREO: - case AV_CH_LAYOUT_4POINT0: - case AV_CH_LAYOUT_2_2: - samples *= num_source_channels; - if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { -#if HAVE_BIGENDIAN - bytestream2_get_buffer(&gb, dst16, buf_size); -#else - do { - *dst16++ = bytestream2_get_be16u(&gb); - } while (--samples); -#endif - } else { - do { - *dst32++ = bytestream2_get_be24u(&gb) << 8; - } while (--samples); - } - break; - /* cases where number of source channels = coded channels + 1 */ - case AV_CH_LAYOUT_MONO: - case AV_CH_LAYOUT_SURROUND: - case AV_CH_LAYOUT_2_1: - case AV_CH_LAYOUT_5POINT0: - if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { - do { -#if HAVE_BIGENDIAN - bytestream2_get_buffer(&gb, dst16, avctx->channels * 2); - dst16 += avctx->channels; -#else - channel = avctx->channels; - do { - *dst16++ = bytestream2_get_be16u(&gb); - } while (--channel); -#endif - bytestream2_skip(&gb, 2); - } while (--samples); - } else { - do { - channel = avctx->channels; - do { - *dst32++ = bytestream2_get_be24u(&gb) << 8; - } while (--channel); - bytestream2_skip(&gb, 3); - } while (--samples); - } - break; - /* remapping: L, R, C, LBack, RBack, LF */ - case AV_CH_LAYOUT_5POINT1: - if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { - do { - dst16[0] = bytestream2_get_be16u(&gb); - dst16[1] = bytestream2_get_be16u(&gb); - dst16[2] = bytestream2_get_be16u(&gb); - dst16[4] = bytestream2_get_be16u(&gb); - dst16[5] = bytestream2_get_be16u(&gb); - dst16[3] = bytestream2_get_be16u(&gb); - dst16 += 6; - } while (--samples); - } else { - do { - dst32[0] = bytestream2_get_be24u(&gb) << 8; - dst32[1] = bytestream2_get_be24u(&gb) << 8; - dst32[2] = bytestream2_get_be24u(&gb) << 8; - dst32[4] = bytestream2_get_be24u(&gb) << 8; - dst32[5] = bytestream2_get_be24u(&gb) << 8; - dst32[3] = bytestream2_get_be24u(&gb) << 8; - dst32 += 6; - } while (--samples); - } - break; - /* remapping: L, R, C, LSide, LBack, RBack, RSide, */ - case AV_CH_LAYOUT_7POINT0: - if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { - do { - dst16[0] = bytestream2_get_be16u(&gb); - dst16[1] = bytestream2_get_be16u(&gb); - dst16[2] = bytestream2_get_be16u(&gb); - dst16[5] = bytestream2_get_be16u(&gb); - dst16[3] = bytestream2_get_be16u(&gb); - dst16[4] = bytestream2_get_be16u(&gb); - dst16[6] = bytestream2_get_be16u(&gb); - dst16 += 7; - bytestream2_skip(&gb, 2); - } while (--samples); - } else { - do { - dst32[0] = bytestream2_get_be24u(&gb) << 8; - dst32[1] = bytestream2_get_be24u(&gb) << 8; - dst32[2] = bytestream2_get_be24u(&gb) << 8; - dst32[5] = bytestream2_get_be24u(&gb) << 8; - dst32[3] = bytestream2_get_be24u(&gb) << 8; - dst32[4] = bytestream2_get_be24u(&gb) << 8; - dst32[6] = bytestream2_get_be24u(&gb) << 8; - dst32 += 7; - bytestream2_skip(&gb, 3); - } while (--samples); - } - break; - /* remapping: L, R, C, LSide, LBack, RBack, RSide, LF */ - case AV_CH_LAYOUT_7POINT1: - if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { - do { - dst16[0] = bytestream2_get_be16u(&gb); - dst16[1] = bytestream2_get_be16u(&gb); - dst16[2] = bytestream2_get_be16u(&gb); - dst16[6] = bytestream2_get_be16u(&gb); - dst16[4] = bytestream2_get_be16u(&gb); - dst16[5] = bytestream2_get_be16u(&gb); - dst16[7] = bytestream2_get_be16u(&gb); - dst16[3] = bytestream2_get_be16u(&gb); - dst16 += 8; - } while (--samples); - } else { - do { - dst32[0] = bytestream2_get_be24u(&gb) << 8; - dst32[1] = bytestream2_get_be24u(&gb) << 8; - dst32[2] = bytestream2_get_be24u(&gb) << 8; - dst32[6] = bytestream2_get_be24u(&gb) << 8; - dst32[4] = bytestream2_get_be24u(&gb) << 8; - dst32[5] = bytestream2_get_be24u(&gb) << 8; - dst32[7] = bytestream2_get_be24u(&gb) << 8; - dst32[3] = bytestream2_get_be24u(&gb) << 8; - dst32 += 8; - } while (--samples); - } - break; - } - } - - *got_frame_ptr = 1; - - retval = bytestream2_tell(&gb); - if (avctx->debug & FF_DEBUG_BITSTREAM) - av_dlog(avctx, "pcm_bluray_decode_frame: decoded %d -> %d bytes\n", - retval, buf_size); - return retval + 4; -} - -AVCodec ff_pcm_bluray_decoder = { - .name = "pcm_bluray", - .type = AVMEDIA_TYPE_AUDIO, - .id = AV_CODEC_ID_PCM_BLURAY, - .decode = pcm_bluray_decode_frame, - .capabilities = CODEC_CAP_DR1, - .sample_fmts = (const enum AVSampleFormat[]){ - AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE - }, - .long_name = NULL_IF_CONFIG_SMALL("PCM signed 16|20|24-bit big-endian for Blu-ray media"), -}; diff --git a/ffmpeg/libavcodec/pcm.c b/ffmpeg/libavcodec/pcm.c index 83482dd..0a4ad0b 100644 --- a/ffmpeg/libavcodec/pcm.c +++ b/ffmpeg/libavcodec/pcm.c @@ -48,16 +48,6 @@ static av_cold int pcm_encode_init(AVCodecContext *avctx) avctx->bits_per_coded_sample = av_get_bits_per_sample(avctx->codec->id); avctx->block_align = avctx->channels * avctx->bits_per_coded_sample / 8; avctx->bit_rate = avctx->block_align * avctx->sample_rate * 8; - avctx->coded_frame = avcodec_alloc_frame(); - if (!avctx->coded_frame) - return AVERROR(ENOMEM); - - return 0; -} - -static av_cold int pcm_encode_close(AVCodecContext *avctx) -{ - av_freep(&avctx->coded_frame); return 0; } @@ -308,18 +298,7 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data, /* av_get_bits_per_sample returns 0 for AV_CODEC_ID_PCM_DVD */ samples_per_block = 1; - if (AV_CODEC_ID_PCM_DVD == avctx->codec_id) { - if (avctx->bits_per_coded_sample != 20 && - avctx->bits_per_coded_sample != 24) { - av_log(avctx, AV_LOG_ERROR, - "PCM DVD unsupported sample depth %i\n", - avctx->bits_per_coded_sample); - return AVERROR(EINVAL); - } - /* 2 samples are interleaved per block in PCM_DVD */ - samples_per_block = 2; - sample_size = avctx->bits_per_coded_sample * 2 / 8; - } else if (avctx->codec_id == AV_CODEC_ID_PCM_LXF) { + if (avctx->codec_id == AV_CODEC_ID_PCM_LXF) { /* we process 40-bit blocks per channel for LXF */ samples_per_block = 2; sample_size = 5; @@ -480,37 +459,6 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data, samples += 2; } break; - case AV_CODEC_ID_PCM_DVD: - { - const uint8_t *src8; - dst_int32_t = (int32_t *)frame->data[0]; - n /= avctx->channels; - switch (avctx->bits_per_coded_sample) { - case 20: - while (n--) { - c = avctx->channels; - src8 = src + 4 * c; - while (c--) { - *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8 & 0xf0) << 8); - *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8++ & 0x0f) << 12); - } - src = src8; - } - break; - case 24: - while (n--) { - c = avctx->channels; - src8 = src + 4 * c; - while (c--) { - *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8++) << 8); - *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8++) << 8); - } - src = src8; - } - break; - } - break; - } case AV_CODEC_ID_PCM_LXF: { int i; @@ -548,15 +496,14 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data, #define PCM_ENCODER_1(id_, sample_fmt_, name_, long_name_) \ AVCodec ff_ ## name_ ## _encoder = { \ .name = #name_, \ + .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ .type = AVMEDIA_TYPE_AUDIO, \ .id = AV_CODEC_ID_ ## id_, \ .init = pcm_encode_init, \ .encode2 = pcm_encode_frame, \ - .close = pcm_encode_close, \ .capabilities = CODEC_CAP_VARIABLE_FRAME_SIZE, \ .sample_fmts = (const enum AVSampleFormat[]){ sample_fmt_, \ AV_SAMPLE_FMT_NONE }, \ - .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ } #define PCM_ENCODER_2(cf, id, sample_fmt, name, long_name) \ @@ -570,6 +517,7 @@ AVCodec ff_ ## name_ ## _encoder = { \ #define PCM_DECODER_1(id_, sample_fmt_, name_, long_name_) \ AVCodec ff_ ## name_ ## _decoder = { \ .name = #name_, \ + .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ .type = AVMEDIA_TYPE_AUDIO, \ .id = AV_CODEC_ID_ ## id_, \ .priv_data_size = sizeof(PCMDecode), \ @@ -578,7 +526,6 @@ AVCodec ff_ ## name_ ## _decoder = { \ .capabilities = CODEC_CAP_DR1, \ .sample_fmts = (const enum AVSampleFormat[]){ sample_fmt_, \ AV_SAMPLE_FMT_NONE }, \ - .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ } #define PCM_DECODER_2(cf, id, sample_fmt, name, long_name) \ @@ -594,7 +541,6 @@ AVCodec ff_ ## name_ ## _decoder = { \ /* Note: Do not forget to add new entries to the Makefile as well. */ PCM_CODEC (PCM_ALAW, AV_SAMPLE_FMT_S16, pcm_alaw, "PCM A-law / G.711 A-law"); -PCM_DECODER(PCM_DVD, AV_SAMPLE_FMT_S32, pcm_dvd, "PCM signed 20|24-bit big-endian"); PCM_CODEC (PCM_F32BE, AV_SAMPLE_FMT_FLT, pcm_f32be, "PCM 32-bit floating point big-endian"); PCM_CODEC (PCM_F32LE, AV_SAMPLE_FMT_FLT, pcm_f32le, "PCM 32-bit floating point little-endian"); PCM_CODEC (PCM_F64BE, AV_SAMPLE_FMT_DBL, pcm_f64be, "PCM 64-bit floating point big-endian"); diff --git a/ffmpeg/libavcodec/pcx.c b/ffmpeg/libavcodec/pcx.c index ba92332..6487aa5 100644 --- a/ffmpeg/libavcodec/pcx.c +++ b/ffmpeg/libavcodec/pcx.c @@ -28,21 +28,23 @@ #include "get_bits.h" #include "internal.h" -static void pcx_rle_decode(GetByteContext *gb, uint8_t *dst, - unsigned int bytes_per_scanline, int compressed) +static void pcx_rle_decode(GetByteContext *gb, + uint8_t *dst, + unsigned int bytes_per_scanline, + int compressed) { unsigned int i = 0; unsigned char run, value; if (compressed) { - while (i0) { + run = 1; value = bytestream2_get_byte(gb); - if (value >= 0xc0) { - run = value & 0x3f; + if (value >= 0xc0 && bytestream2_get_bytes_left(gb)>0) { + run = value & 0x3f; value = bytestream2_get_byte(gb); } - while (isample_aspect_ratio.num = bytestream2_get_le16u(&gb); avctx->sample_aspect_ratio.den = bytestream2_get_le16u(&gb); @@ -102,35 +106,35 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, bytes_per_line = bytestream2_get_le16u(&gb); bytes_per_scanline = nplanes * bytes_per_line; - if (bytes_per_scanline < (w * bits_per_pixel * nplanes + 7) / 8) { + if (bytes_per_scanline < (w * bits_per_pixel * nplanes + 7) / 8 || + (!compressed && bytes_per_scanline > bytestream2_get_bytes_left(&gb) / h)) { av_log(avctx, AV_LOG_ERROR, "PCX data is corrupted\n"); return AVERROR_INVALIDDATA; } - switch ((nplanes<<8) + bits_per_pixel) { - case 0x0308: - avctx->pix_fmt = AV_PIX_FMT_RGB24; - break; - case 0x0108: - case 0x0104: - case 0x0102: - case 0x0101: - case 0x0401: - case 0x0301: - case 0x0201: - avctx->pix_fmt = AV_PIX_FMT_PAL8; - break; - default: - av_log(avctx, AV_LOG_ERROR, "invalid PCX file\n"); - return AVERROR_INVALIDDATA; + switch ((nplanes << 8) + bits_per_pixel) { + case 0x0308: + avctx->pix_fmt = AV_PIX_FMT_RGB24; + break; + case 0x0108: + case 0x0104: + case 0x0102: + case 0x0101: + case 0x0401: + case 0x0301: + case 0x0201: + avctx->pix_fmt = AV_PIX_FMT_PAL8; + break; + default: + av_log(avctx, AV_LOG_ERROR, "invalid PCX file\n"); + return AVERROR_INVALIDDATA; } bytestream2_skipu(&gb, 60); - if ((ret = av_image_check_size(w, h, 0, avctx)) < 0) + if ((ret = ff_set_dimensions(avctx, w, h)) < 0) return ret; - if (w != avctx->width || h != avctx->height) - avcodec_set_dimensions(avctx, w, h); + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) return ret; @@ -144,22 +148,28 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return AVERROR(ENOMEM); if (nplanes == 3 && bits_per_pixel == 8) { - for (y=0; ysize - 769; - for (y=0; ysize < 769) { + av_log(avctx, AV_LOG_ERROR, "File is too short\n"); + ret = avctx->err_recognition & AV_EF_EXPLODE ? + AVERROR_INVALIDDATA : avpkt->size; + goto end; + } + + for (y = 0; y < h; y++, ptr += stride) { pcx_rle_decode(&gb, scanline, bytes_per_scanline, compressed); memcpy(ptr, scanline, w); } @@ -170,34 +180,33 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } if (bytestream2_get_byte(&gb) != 12) { av_log(avctx, AV_LOG_ERROR, "expected palette after image data\n"); - ret = AVERROR_INVALIDDATA; + ret = avctx->err_recognition & AV_EF_EXPLODE ? + AVERROR_INVALIDDATA : avpkt->size; goto end; } - } else if (nplanes == 1) { /* all packed formats, max. 16 colors */ GetBitContext s; - for (y=0; y> (x&7), v = 0; - for (i=nplanes - 1; i>=0; i--) { + for (x = 0; x < w; x++) { + int m = 0x80 >> (x & 7), v = 0; + for (i = nplanes - 1; i >= 0; i--) { v <<= 1; - v += !!(scanline[i*bytes_per_line + (x>>3)] & m); + v += !!(scanline[i * bytes_per_line + (x >> 3)] & m); } ptr[x] = v; } @@ -207,14 +216,14 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, ret = bytestream2_tell(&gb); if (nplanes == 1 && bits_per_pixel == 8) { - pcx_palette(&gb, (uint32_t *) p->data[1], 256); + pcx_palette(&gb, (uint32_t *)p->data[1], 256); ret += 256 * 3; } else if (bits_per_pixel * nplanes == 1) { AV_WN32A(p->data[1] , 0xFF000000); AV_WN32A(p->data[1]+4, 0xFFFFFFFF); } else if (bits_per_pixel < 8) { bytestream2_seek(&gb, 16, SEEK_SET); - pcx_palette(&gb, (uint32_t *) p->data[1], 16); + pcx_palette(&gb, (uint32_t *)p->data[1], 16); } *got_frame = 1; @@ -225,10 +234,10 @@ end: } AVCodec ff_pcx_decoder = { - .name = "pcx", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_PCX, - .decode = pcx_decode_frame, - .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("PC Paintbrush PCX image"), + .name = "pcx", + .long_name = NULL_IF_CONFIG_SMALL("PC Paintbrush PCX image"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_PCX, + .decode = pcx_decode_frame, + .capabilities = CODEC_CAP_DR1, }; diff --git a/ffmpeg/libavcodec/pcxenc.c b/ffmpeg/libavcodec/pcxenc.c index 7cb3af3..f48063b 100644 --- a/ffmpeg/libavcodec/pcxenc.c +++ b/ffmpeg/libavcodec/pcxenc.c @@ -31,19 +31,23 @@ #include "libavutil/imgutils.h" #include "internal.h" -typedef struct PCXContext { - AVFrame picture; -} PCXContext; - static const uint32_t monoblack_pal[16] = { 0x000000, 0xFFFFFF }; static av_cold int pcx_encode_init(AVCodecContext *avctx) { - PCXContext *s = avctx->priv_data; + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->key_frame = 1; - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame = &s->picture; + return 0; +} +static av_cold int pcx_encode_close(AVCodecContext *avctx) +{ + av_frame_free(&avctx->coded_frame); return 0; } @@ -100,8 +104,6 @@ static int pcx_rle_encode( uint8_t *dst, int dst_size, static int pcx_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet) { - PCXContext *s = avctx->priv_data; - AVFrame *const pict = &s->picture; const uint8_t *buf_end; uint8_t *buf; @@ -110,10 +112,6 @@ static int pcx_encode_frame(AVCodecContext *avctx, AVPacket *pkt, uint32_t palette256[256]; const uint8_t *src; - *pict = *frame; - pict->pict_type = AV_PICTURE_TYPE_I; - pict->key_frame = 1; - if (avctx->width > 65535 || avctx->height > 65535) { av_log(avctx, AV_LOG_ERROR, "image dimensions do not fit in 16 bits\n"); return -1; @@ -137,7 +135,7 @@ static int pcx_encode_frame(AVCodecContext *avctx, AVPacket *pkt, case AV_PIX_FMT_PAL8: bpp = 8; nplanes = 1; - pal = (uint32_t *)pict->data[1]; + pal = (uint32_t *)frame->data[1]; break; case AV_PIX_FMT_MONOBLACK: bpp = 1; @@ -182,7 +180,7 @@ static int pcx_encode_frame(AVCodecContext *avctx, AVPacket *pkt, while (buf - pkt->data < 128) *buf++= 0; - src = pict->data[0]; + src = frame->data[0]; for (y = 0; y < avctx->height; y++) { if ((written = pcx_rle_encode(buf, buf_end - buf, @@ -191,7 +189,7 @@ static int pcx_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return -1; } buf += written; - src += pict->linesize[0]; + src += frame->linesize[0]; } if (nplanes == 1 && bpp == 8) { @@ -214,10 +212,11 @@ static int pcx_encode_frame(AVCodecContext *avctx, AVPacket *pkt, AVCodec ff_pcx_encoder = { .name = "pcx", + .long_name = NULL_IF_CONFIG_SMALL("PC Paintbrush PCX image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PCX, - .priv_data_size = sizeof(PCXContext), .init = pcx_encode_init, + .close = pcx_encode_close, .encode2 = pcx_encode_frame, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_RGB24, @@ -226,5 +225,4 @@ AVCodec ff_pcx_encoder = { AV_PIX_FMT_MONOBLACK, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("PC Paintbrush PCX image"), }; diff --git a/ffmpeg/libavcodec/pgssubdec.c b/ffmpeg/libavcodec/pgssubdec.c index d0cff7b..f45f0bf 100644 --- a/ffmpeg/libavcodec/pgssubdec.c +++ b/ffmpeg/libavcodec/pgssubdec.c @@ -27,6 +27,8 @@ #include "avcodec.h" #include "dsputil.h" #include "bytestream.h" +#include "internal.h" + #include "libavutil/colorspace.h" #include "libavutil/imgutils.h" #include "libavutil/opt.h" @@ -98,7 +100,7 @@ static av_cold int close_decoder(AVCodecContext *avctx) /** * Decode the RLE data. * - * The subtitle is stored as an Run Length Encoded image. + * The subtitle is stored as a Run Length Encoded image. * * @param avctx contains the current codec context * @param sub pointer to the processed subtitle data @@ -294,11 +296,12 @@ static void parse_palette_segment(AVCodecContext *avctx, * @param buf_size size of packet to process * @todo TODO: Implement cropping */ -static void parse_presentation_segment(AVCodecContext *avctx, - const uint8_t *buf, int buf_size, - int64_t pts) +static int parse_presentation_segment(AVCodecContext *avctx, + const uint8_t *buf, int buf_size, + int64_t pts) { PGSSubContext *ctx = avctx->priv_data; + int ret; int w = bytestream_get_be16(&buf); int h = bytestream_get_be16(&buf); @@ -309,8 +312,9 @@ static void parse_presentation_segment(AVCodecContext *avctx, av_dlog(avctx, "Video Dimensions %dx%d\n", w, h); - if (av_image_check_size(w, h, 0, avctx) >= 0) - avcodec_set_dimensions(avctx, w, h); + ret = ff_set_dimensions(avctx, w, h); + if (ret < 0) + return ret; /* Skip 1 bytes of unknown, frame rate? */ buf++; @@ -327,20 +331,20 @@ static void parse_presentation_segment(AVCodecContext *avctx, ctx->presentation.object_count = bytestream_get_byte(&buf); if (!ctx->presentation.object_count) - return; + return 0; /* Verify that enough bytes are remaining for all of the objects. */ buf_size -= 11; if (buf_size < ctx->presentation.object_count * 8) { ctx->presentation.object_count = 0; - return; + return AVERROR_INVALIDDATA; } av_freep(&ctx->presentation.objects); ctx->presentation.objects = av_malloc(sizeof(PGSSubPictureReference) * ctx->presentation.object_count); if (!ctx->presentation.objects) { ctx->presentation.object_count = 0; - return; + return AVERROR(ENOMEM); } for (object_index = 0; object_index < ctx->presentation.object_count; ++object_index) { @@ -365,6 +369,8 @@ static void parse_presentation_segment(AVCodecContext *avctx, reference->y = 0; } } + + return 0; } /** @@ -456,7 +462,7 @@ static int decode(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf_end; uint8_t segment_type; int segment_length; - int i; + int i, ret; av_dlog(avctx, "PGS sub packet:\n"); @@ -495,7 +501,9 @@ static int decode(AVCodecContext *avctx, void *data, int *data_size, parse_picture_segment(avctx, buf, segment_length); break; case PRESENTATION_SEGMENT: - parse_presentation_segment(avctx, buf, segment_length, sub->pts); + ret = parse_presentation_segment(avctx, buf, segment_length, sub->pts); + if (ret < 0) + return ret; break; case WINDOW_SEGMENT: /* @@ -538,12 +546,12 @@ static const AVClass pgsdec_class = { AVCodec ff_pgssub_decoder = { .name = "pgssub", + .long_name = NULL_IF_CONFIG_SMALL("HDMV Presentation Graphic Stream subtitles"), .type = AVMEDIA_TYPE_SUBTITLE, .id = AV_CODEC_ID_HDMV_PGS_SUBTITLE, .priv_data_size = sizeof(PGSSubContext), .init = init_decoder, .close = close_decoder, .decode = decode, - .long_name = NULL_IF_CONFIG_SMALL("HDMV Presentation Graphic Stream subtitles"), .priv_class = &pgsdec_class, }; diff --git a/ffmpeg/libavcodec/pictordec.c b/ffmpeg/libavcodec/pictordec.c index bf138b2..1bc51bc 100644 --- a/ffmpeg/libavcodec/pictordec.c +++ b/ffmpeg/libavcodec/pictordec.c @@ -140,10 +140,12 @@ static int decode_frame(AVCodecContext *avctx, avctx->pix_fmt = AV_PIX_FMT_PAL8; + if (av_image_check_size(s->width, s->height, 0, avctx) < 0) + return -1; if (s->width != avctx->width && s->height != avctx->height) { - if (av_image_check_size(s->width, s->height, 0, avctx) < 0) - return -1; - avcodec_set_dimensions(avctx, s->width, s->height); + ret = ff_set_dimensions(avctx, s->width, s->height); + if (ret < 0) + return ret; } if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) @@ -201,7 +203,7 @@ static int decode_frame(AVCodecContext *avctx, if (bytestream2_get_le16(&s->g)) { x = 0; plane = 0; - while (y >= 0 && bytestream2_get_bytes_left(&s->g) >= 6) { + while (bytestream2_get_bytes_left(&s->g) >= 6) { int stop_size, marker, t1, t2; t1 = bytestream2_get_bytes_left(&s->g); @@ -211,7 +213,7 @@ static int decode_frame(AVCodecContext *avctx, bytestream2_skip(&s->g, 2); marker = bytestream2_get_byte(&s->g); - while (plane < s->nb_planes && y >= 0 && + while (plane < s->nb_planes && bytestream2_get_bytes_left(&s->g) > stop_size) { int run = 1; val = bytestream2_get_byte(&s->g); @@ -226,13 +228,15 @@ static int decode_frame(AVCodecContext *avctx, if (bits_per_plane == 8) { picmemset_8bpp(s, frame, val, run, &x, &y); + if (y < 0) + goto finish; } else { picmemset(s, frame, val, run, &x, &y, &plane, bits_per_plane); } } } - if (x < avctx->width && y >= 0) { + if (x < avctx->width) { int run = (y + 1) * avctx->width - x; if (bits_per_plane == 8) picmemset_8bpp(s, frame, val, run, &x, &y); @@ -246,6 +250,7 @@ static int decode_frame(AVCodecContext *avctx, y--; } } +finish: *got_frame = 1; return avpkt->size; @@ -253,10 +258,10 @@ static int decode_frame(AVCodecContext *avctx, AVCodec ff_pictor_decoder = { .name = "pictor", + .long_name = NULL_IF_CONFIG_SMALL("Pictor/PC Paint"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PICTOR, .priv_data_size = sizeof(PicContext), .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Pictor/PC Paint"), }; diff --git a/ffmpeg/libavcodec/png_parser.c b/ffmpeg/libavcodec/png_parser.c index 6f153d9..530d5a0 100644 --- a/ffmpeg/libavcodec/png_parser.c +++ b/ffmpeg/libavcodec/png_parser.c @@ -27,12 +27,11 @@ #include "parser.h" #include "png.h" -typedef struct PNGParseContext -{ +typedef struct PNGParseContext { ParseContext pc; - uint32_t index; - uint32_t chunk_length; - uint32_t remaining_size; + uint32_t chunk_pos; ///< position inside current chunk + uint32_t chunk_length; ///< length of the current chunk + uint32_t remaining_size; ///< remaining size of the current chunk } PNGParseContext; static int png_parse(AVCodecParserContext *s, AVCodecContext *avctx, @@ -60,38 +59,37 @@ static int png_parse(AVCodecParserContext *s, AVCodecContext *avctx, } } ppc->pc.state64 = state64; - } else - if (ppc->remaining_size) { - i = FFMIN(ppc->remaining_size, buf_size); - ppc->remaining_size -= i; - if (ppc->remaining_size) - goto flush; - if (ppc->index == -1) { - next = i; - goto flush; - } + } else if (ppc->remaining_size) { + i = FFMIN(ppc->remaining_size, buf_size); + ppc->remaining_size -= i; + if (ppc->remaining_size) + goto flush; + if (ppc->chunk_pos == -1) { + next = i; + goto flush; } + } - for (;ppc->pc.frame_start_found && i < buf_size; i++) { - ppc->pc.state = (ppc->pc.state<<8) | buf[i]; - if (ppc->index == 3) { + for (; ppc->pc.frame_start_found && i < buf_size; i++) { + ppc->pc.state = (ppc->pc.state << 8) | buf[i]; + if (ppc->chunk_pos == 3) { ppc->chunk_length = ppc->pc.state; if (ppc->chunk_length > 0x7fffffff) { - ppc->index = ppc->pc.frame_start_found = 0; + ppc->chunk_pos = ppc->pc.frame_start_found = 0; goto flush; } ppc->chunk_length += 4; - } else if (ppc->index == 7) { + } else if (ppc->chunk_pos == 7) { if (ppc->chunk_length >= buf_size - i) - ppc->remaining_size = ppc->chunk_length - buf_size + i + 1; + ppc->remaining_size = ppc->chunk_length - buf_size + i + 1; if (ppc->pc.state == MKBETAG('I', 'E', 'N', 'D')) { if (ppc->remaining_size) - ppc->index = -1; + ppc->chunk_pos = -1; else next = ppc->chunk_length + i + 1; break; } else { - ppc->index = 0; + ppc->chunk_pos = 0; if (ppc->remaining_size) break; else @@ -99,13 +97,14 @@ static int png_parse(AVCodecParserContext *s, AVCodecContext *avctx, continue; } } - ppc->index++; + ppc->chunk_pos++; } + flush: if (ff_combine_frame(&ppc->pc, next, &buf, &buf_size) < 0) return buf_size; - ppc->index = ppc->pc.frame_start_found = 0; + ppc->chunk_pos = ppc->pc.frame_start_found = 0; *poutbuf = buf; *poutbuf_size = buf_size; diff --git a/ffmpeg/libavcodec/pngdec.c b/ffmpeg/libavcodec/pngdec.c index 086f3b4..516dd41 100644 --- a/ffmpeg/libavcodec/pngdec.c +++ b/ffmpeg/libavcodec/pngdec.c @@ -28,21 +28,17 @@ #include "internal.h" #include "png.h" #include "pngdsp.h" - -/* TODO: - * - add 16 bit depth support - */ +#include "thread.h" #include -//#define DEBUG - typedef struct PNGDecContext { PNGDSPContext dsp; AVCodecContext *avctx; GetByteContext gb; - AVFrame *prev; + ThreadFrame last_picture; + ThreadFrame picture; int state; int width, height; @@ -60,7 +56,11 @@ typedef struct PNGDecContext { uint32_t palette[256]; uint8_t *crow_buf; uint8_t *last_row; + unsigned int last_row_size; uint8_t *tmp_row; + unsigned int tmp_row_size; + uint8_t *buffer; + int buffer_size; int pass; int crow_size; /* compressed row size (include filter type) */ int row_size; /* decompressed row size */ @@ -226,7 +226,7 @@ static void png_filter_row(PNGDSPContext *dsp, uint8_t *dst, int filter_type, if (bpp == 4) { p = *(int*)dst; for (; i < size; i += bpp) { - int s = *(int*)(src + i); + unsigned s = *(int*)(src + i); p = ((s & 0x7f7f7f7f) + (p & 0x7f7f7f7f)) ^ ((s ^ p) & 0x80808080); *(int*)(dst + i) = p; } @@ -328,6 +328,7 @@ static void png_handle_row(PNGDecContext *s) png_filter_row(&s->dsp, s->tmp_row, s->crow_buf[0], s->crow_buf + 1, s->last_row, s->pass_row_size, s->bpp); FFSWAP(uint8_t*, s->last_row, s->tmp_row); + FFSWAP(unsigned int, s->last_row_size, s->tmp_row_size); got_line = 1; } if ((png_pass_dsp_ymask[s->pass] << (s->y & 7)) & 0x80) { @@ -370,8 +371,8 @@ static int png_decode_idat(PNGDecContext *s, int length) while (s->zstream.avail_in > 0) { ret = inflate(&s->zstream, Z_PARTIAL_FLUSH); if (ret != Z_OK && ret != Z_STREAM_END) { - av_log(s->avctx, AV_LOG_ERROR, "inflate returned %d\n", ret); - return -1; + av_log(s->avctx, AV_LOG_ERROR, "inflate returned error %d\n", ret); + return AVERROR_EXTERNAL; } if (s->zstream.avail_out == 0) { if (!(s->state & PNG_ALLIMAGE)) { @@ -380,6 +381,10 @@ static int png_decode_idat(PNGDecContext *s, int length) s->zstream.avail_out = s->crow_size; s->zstream.next_out = s->crow_buf; } + if (ret == Z_STREAM_END && s->zstream.avail_in > 0) { + av_log(NULL, AV_LOG_WARNING, "%d undecompressed bytes left in buffer\n", s->zstream.avail_in); + return 0; + } } return 0; } @@ -507,13 +512,16 @@ static int decode_frame(AVCodecContext *avctx, PNGDecContext * const s = avctx->priv_data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - AVFrame *p = data; + AVFrame *p; AVDictionary *metadata = NULL; - uint8_t *crow_buf_base = NULL; uint32_t tag, length; int64_t sig; int ret; + ff_thread_release_buffer(avctx, &s->last_picture); + FFSWAP(ThreadFrame, s->picture, s->last_picture); + p = s->picture.f; + bytestream2_init(&s->gb, buf, buf_size); /* check signature */ @@ -521,7 +529,7 @@ static int decode_frame(AVCodecContext *avctx, if (sig != PNGSIG && sig != MNGSIG) { av_log(avctx, AV_LOG_ERROR, "Missing png signature\n"); - return -1; + return AVERROR_INVALIDDATA; } s->y = s->state = 0; @@ -532,8 +540,8 @@ static int decode_frame(AVCodecContext *avctx, s->zstream.opaque = NULL; ret = inflateInit(&s->zstream); if (ret != Z_OK) { - av_log(avctx, AV_LOG_ERROR, "inflateInit returned %d\n", ret); - return -1; + av_log(avctx, AV_LOG_ERROR, "inflateInit returned error %d\n", ret); + return AVERROR_EXTERNAL; } for (;;) { if (bytestream2_get_bytes_left(&s->gb) <= 0) { @@ -637,8 +645,10 @@ static int decode_frame(AVCodecContext *avctx, goto fail; } - if (ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF) < 0) + if (ff_thread_get_buffer(avctx, &s->picture, AV_GET_BUFFER_FLAG_REF) < 0) goto fail; + ff_thread_finish_setup(avctx); + p->pict_type = AV_PICTURE_TYPE_I; p->key_frame = 1; p->interlaced_frame = !!s->interlace_type; @@ -661,22 +671,22 @@ static int decode_frame(AVCodecContext *avctx, if (avctx->pix_fmt == AV_PIX_FMT_PAL8) memcpy(p->data[1], s->palette, 256 * sizeof(uint32_t)); /* empty row is used if differencing to the first row */ - s->last_row = av_mallocz(s->row_size); + av_fast_padded_mallocz(&s->last_row, &s->last_row_size, s->row_size); if (!s->last_row) goto fail; if (s->interlace_type || s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { - s->tmp_row = av_malloc(s->row_size); + av_fast_padded_malloc(&s->tmp_row, &s->tmp_row_size, s->row_size); if (!s->tmp_row) goto fail; } /* compressed row */ - crow_buf_base = av_malloc(s->row_size + 16); - if (!crow_buf_base) + av_fast_padded_malloc(&s->buffer, &s->buffer_size, s->row_size + 16); + if (!s->buffer) goto fail; /* we want crow_buf+1 to be 16-byte aligned */ - s->crow_buf = crow_buf_base + 15; + s->crow_buf = s->buffer + 15; s->zstream.avail_out = s->crow_size; s->zstream.next_out = s->crow_buf; } @@ -822,16 +832,17 @@ static int decode_frame(AVCodecContext *avctx, } /* handle p-frames only if a predecessor frame is available */ - if (s->prev->data[0]) { - if ( !(avpkt->flags & AV_PKT_FLAG_KEY) - && s->prev->width == p->width - && s->prev->height== p->height - && s->prev->format== p->format + if (s->last_picture.f->data[0]) { + if ( !(avpkt->flags & AV_PKT_FLAG_KEY) && avctx->codec_tag != AV_RL32("MPNG") + && s->last_picture.f->width == p->width + && s->last_picture.f->height== p->height + && s->last_picture.f->format== p->format ) { int i, j; uint8_t *pd = p->data[0]; - uint8_t *pd_last = s->prev->data[0]; + uint8_t *pd_last = s->last_picture.f->data[0]; + ff_thread_await_progress(&s->last_picture, INT_MAX, 0); for (j = 0; j < s->height; j++) { for (i = 0; i < s->width * s->bpp; i++) { pd[i] += pd_last[i]; @@ -841,41 +852,57 @@ static int decode_frame(AVCodecContext *avctx, } } } + ff_thread_report_progress(&s->picture, INT_MAX, 0); av_frame_set_metadata(p, metadata); metadata = NULL; - av_frame_unref(s->prev); - if ((ret = av_frame_ref(s->prev, p)) < 0) - goto fail; + if ((ret = av_frame_ref(data, s->picture.f)) < 0) + return ret; *got_frame = 1; ret = bytestream2_tell(&s->gb); the_end: inflateEnd(&s->zstream); - av_free(crow_buf_base); s->crow_buf = NULL; - av_freep(&s->last_row); - av_freep(&s->tmp_row); return ret; fail: av_dict_free(&metadata); - ret = -1; + ff_thread_report_progress(&s->picture, INT_MAX, 0); + ret = AVERROR_INVALIDDATA; goto the_end; } +static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) +{ + PNGDecContext *psrc = src->priv_data; + PNGDecContext *pdst = dst->priv_data; + + if (dst == src) + return 0; + + ff_thread_release_buffer(dst, &pdst->picture); + if (psrc->picture.f->data[0]) + return ff_thread_ref_frame(&pdst->picture, &psrc->picture); + + return 0; +} + static av_cold int png_dec_init(AVCodecContext *avctx) { PNGDecContext *s = avctx->priv_data; - s->prev = av_frame_alloc(); - if (!s->prev) + s->avctx = avctx; + s->last_picture.f = av_frame_alloc(); + s->picture.f = av_frame_alloc(); + if (!s->last_picture.f || !s->picture.f) return AVERROR(ENOMEM); - ff_pngdsp_init(&s->dsp); - - s->avctx = avctx; + if (!avctx->internal->is_copy) { + avctx->internal->allocate_progress = 1; + ff_pngdsp_init(&s->dsp); + } return 0; } @@ -884,19 +911,30 @@ static av_cold int png_dec_end(AVCodecContext *avctx) { PNGDecContext *s = avctx->priv_data; - av_frame_free(&s->prev); + ff_thread_release_buffer(avctx, &s->last_picture); + av_frame_free(&s->last_picture.f); + ff_thread_release_buffer(avctx, &s->picture); + av_frame_free(&s->picture.f); + av_freep(&s->buffer); + s->buffer_size = 0; + av_freep(&s->last_row); + s->last_row_size = 0; + av_freep(&s->tmp_row); + s->tmp_row_size = 0; return 0; } AVCodec ff_png_decoder = { .name = "png", + .long_name = NULL_IF_CONFIG_SMALL("PNG (Portable Network Graphics) image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PNG, .priv_data_size = sizeof(PNGDecContext), .init = png_dec_init, .close = png_dec_end, .decode = decode_frame, - .capabilities = CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/, - .long_name = NULL_IF_CONFIG_SMALL("PNG (Portable Network Graphics) image"), + .init_thread_copy = ONLY_IF_THREADS_ENABLED(png_dec_init), + .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context), + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS /*| CODEC_CAP_DRAW_HORIZ_BAND*/, }; diff --git a/ffmpeg/libavcodec/pngdsp.c b/ffmpeg/libavcodec/pngdsp.c index 1ee8b57..5ab1c35 100644 --- a/ffmpeg/libavcodec/pngdsp.c +++ b/ffmpeg/libavcodec/pngdsp.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/attributes.h" #include "libavutil/common.h" #include "png.h" #include "pngdsp.h" @@ -30,7 +31,7 @@ static void add_bytes_l2_c(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w) { long i; - for (i = 0; i <= w - sizeof(long); i += sizeof(long)) { + for (i = 0; i <= w - (int)sizeof(long); i += sizeof(long)) { long a = *(long *)(src1 + i); long b = *(long *)(src2 + i); *(long *)(dst + i) = ((a & pb_7f) + (b & pb_7f)) ^ ((a ^ b) & pb_80); @@ -39,7 +40,7 @@ static void add_bytes_l2_c(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w) dst[i] = src1[i] + src2[i]; } -void ff_pngdsp_init(PNGDSPContext *dsp) +av_cold void ff_pngdsp_init(PNGDSPContext *dsp) { dsp->add_bytes_l2 = add_bytes_l2_c; dsp->add_paeth_prediction = ff_add_png_paeth_prediction; diff --git a/ffmpeg/libavcodec/pngenc.c b/ffmpeg/libavcodec/pngenc.c index a401c78..bf61be1 100644 --- a/ffmpeg/libavcodec/pngenc.c +++ b/ffmpeg/libavcodec/pngenc.c @@ -25,29 +25,26 @@ #include "png.h" #include "libavutil/avassert.h" - -/* TODO: - * - add 2, 4 and 16 bit depth support - */ +#include "libavutil/opt.h" #include -//#define DEBUG - #define IOBUF_SIZE 4096 typedef struct PNGEncContext { + AVClass *class; DSPContext dsp; uint8_t *bytestream; uint8_t *bytestream_start; uint8_t *bytestream_end; - AVFrame picture; int filter_type; z_stream zstream; uint8_t buf[IOBUF_SIZE]; + int dpi; ///< Physical pixel density, in dots per inch, if set + int dpm; ///< Physical pixel density, in dots per meter, if set } PNGEncContext; static void png_get_interlaced_row(uint8_t *dst, int row_size, @@ -57,8 +54,9 @@ static void png_get_interlaced_row(uint8_t *dst, int row_size, int x, mask, dst_x, j, b, bpp; uint8_t *d; const uint8_t *s; + static const int masks[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff}; - mask = (int[]){0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff}[pass]; + mask = masks[pass]; switch(bits_per_pixel) { case 1: memset(dst, 0, row_size); @@ -219,7 +217,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { PNGEncContext *s = avctx->priv_data; - AVFrame * const p= &s->picture; + const AVFrame * const p = pict; int bit_depth, color_type, y, len, row_size, ret, is_progressive; int bits_per_pixel, pass_row_size, enc_row_size; int64_t max_packet_size; @@ -229,10 +227,6 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, uint8_t *progressive_buf = NULL; uint8_t *top_buf = NULL; - *p = *pict; - p->pict_type= AV_PICTURE_TYPE_I; - p->key_frame= 1; - is_progressive = !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT); switch(avctx->pix_fmt) { case AV_PIX_FMT_RGBA64BE: @@ -330,9 +324,15 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, png_write_chunk(&s->bytestream, MKTAG('I', 'H', 'D', 'R'), s->buf, 13); - AV_WB32(s->buf, avctx->sample_aspect_ratio.num); - AV_WB32(s->buf + 4, avctx->sample_aspect_ratio.den); - s->buf[8] = 0; /* unit specifier is unknown */ + if (s->dpm) { + AV_WB32(s->buf, s->dpm); + AV_WB32(s->buf + 4, s->dpm); + s->buf[8] = 1; /* unit specifier is meter */ + } else { + AV_WB32(s->buf, avctx->sample_aspect_ratio.num); + AV_WB32(s->buf + 4, avctx->sample_aspect_ratio.den); + s->buf[8] = 0; /* unit specifier is unknown */ + } png_write_chunk(&s->bytestream, MKTAG('p', 'H', 'Y', 's'), s->buf, 9); /* put the palette if needed */ @@ -449,23 +449,58 @@ static av_cold int png_enc_init(AVCodecContext *avctx){ avctx->bits_per_coded_sample = 8; } - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame= &s->picture; + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->key_frame = 1; + ff_dsputil_init(&s->dsp, avctx); s->filter_type = av_clip(avctx->prediction_method, PNG_FILTER_VALUE_NONE, PNG_FILTER_VALUE_MIXED); if(avctx->pix_fmt == AV_PIX_FMT_MONOBLACK) s->filter_type = PNG_FILTER_VALUE_NONE; + if (s->dpi && s->dpm) { + av_log(avctx, AV_LOG_ERROR, "Only one of 'dpi' or 'dpm' options should be set\n"); + return AVERROR(EINVAL); + } else if (s->dpi) { + s->dpm = s->dpi * 10000 / 254; + } + return 0; } +static av_cold int png_enc_close(AVCodecContext *avctx) +{ + av_frame_free(&avctx->coded_frame); + return 0; +} + +#define OFFSET(x) offsetof(PNGEncContext, x) +#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM +static const AVOption options[] = { + {"dpi", "Set image resolution (in dots per inch)", OFFSET(dpi), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 0x10000, VE}, + {"dpm", "Set image resolution (in dots per meter)", OFFSET(dpm), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 0x10000, VE}, + { NULL } +}; + +static const AVClass pngenc_class = { + .class_name = "PNG encoder", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + AVCodec ff_png_encoder = { .name = "png", + .long_name = NULL_IF_CONFIG_SMALL("PNG (Portable Network Graphics) image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PNG, .priv_data_size = sizeof(PNGEncContext), .init = png_enc_init, + .close = png_enc_close, .encode2 = encode_frame, .capabilities = CODEC_CAP_FRAME_THREADS | CODEC_CAP_INTRA_ONLY, .pix_fmts = (const enum AVPixelFormat[]){ @@ -476,5 +511,5 @@ AVCodec ff_png_encoder = { AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_MONOBLACK, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("PNG (Portable Network Graphics) image"), + .priv_class = &pngenc_class, }; diff --git a/ffmpeg/libavcodec/pnm.c b/ffmpeg/libavcodec/pnm.c index 33b8896..63b77cd 100644 --- a/ffmpeg/libavcodec/pnm.c +++ b/ffmpeg/libavcodec/pnm.c @@ -116,10 +116,10 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s) if (depth == 1) { if (maxval == 1) { avctx->pix_fmt = AV_PIX_FMT_MONOBLACK; - } else if (maxval == 255) { + } else if (maxval < 256) { avctx->pix_fmt = AV_PIX_FMT_GRAY8; } else { - avctx->pix_fmt = AV_PIX_FMT_GRAY16BE; + avctx->pix_fmt = AV_PIX_FMT_GRAY16; } } else if (depth == 2) { if (maxval == 255) @@ -128,13 +128,13 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s) if (maxval < 256) { avctx->pix_fmt = AV_PIX_FMT_RGB24; } else { - avctx->pix_fmt = AV_PIX_FMT_RGB48BE; + avctx->pix_fmt = AV_PIX_FMT_RGB48; } } else if (depth == 4) { if (maxval < 256) { avctx->pix_fmt = AV_PIX_FMT_RGBA; } else { - avctx->pix_fmt = AV_PIX_FMT_RGBA64BE; + avctx->pix_fmt = AV_PIX_FMT_RGBA64; } } else { return AVERROR_INVALIDDATA; @@ -162,14 +162,14 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s) } if (s->maxval >= 256) { if (avctx->pix_fmt == AV_PIX_FMT_GRAY8) { - avctx->pix_fmt = AV_PIX_FMT_GRAY16BE; + avctx->pix_fmt = AV_PIX_FMT_GRAY16; } else if (avctx->pix_fmt == AV_PIX_FMT_RGB24) { - avctx->pix_fmt = AV_PIX_FMT_RGB48BE; + avctx->pix_fmt = AV_PIX_FMT_RGB48; } else if (avctx->pix_fmt == AV_PIX_FMT_YUV420P && s->maxval < 65536) { if (s->maxval < 512) - avctx->pix_fmt = AV_PIX_FMT_YUV420P9BE; + avctx->pix_fmt = AV_PIX_FMT_YUV420P9; else if (s->maxval < 1024) - avctx->pix_fmt = AV_PIX_FMT_YUV420P10BE; + avctx->pix_fmt = AV_PIX_FMT_YUV420P10; else avctx->pix_fmt = AV_PIX_FMT_YUV420P16; } else { @@ -181,7 +181,7 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s) }else s->maxval=1; /* more check if YUV420 */ - if (av_pix_fmt_desc_get(avctx->pix_fmt)->flags & PIX_FMT_PLANAR) { + if (av_pix_fmt_desc_get(avctx->pix_fmt)->flags & AV_PIX_FMT_FLAG_PLANAR) { if ((avctx->width & 1) != 0) return AVERROR_INVALIDDATA; h = (avctx->height * 2); @@ -192,13 +192,3 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s) } return 0; } - -av_cold int ff_pnm_init(AVCodecContext *avctx) -{ - PNMContext *s = avctx->priv_data; - - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame = &s->picture; - - return 0; -} diff --git a/ffmpeg/libavcodec/pnm.h b/ffmpeg/libavcodec/pnm.h index 92edf8d..5bc0aad 100644 --- a/ffmpeg/libavcodec/pnm.h +++ b/ffmpeg/libavcodec/pnm.h @@ -28,12 +28,10 @@ typedef struct PNMContext { uint8_t *bytestream; uint8_t *bytestream_start; uint8_t *bytestream_end; - AVFrame picture; int maxval; ///< maximum value of a pixel int type; } PNMContext; int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s); -int ff_pnm_init(AVCodecContext *avctx); #endif /* AVCODEC_PNM_H */ diff --git a/ffmpeg/libavcodec/pnmdec.c b/ffmpeg/libavcodec/pnmdec.c index d0c7295..c84b6eb 100644 --- a/ffmpeg/libavcodec/pnmdec.c +++ b/ffmpeg/libavcodec/pnmdec.c @@ -24,6 +24,17 @@ #include "put_bits.h" #include "pnm.h" +static void samplecpy(uint8_t *dst, const uint8_t *src, int n, int maxval) +{ + if (maxval <= 255) { + memcpy(dst, src, n); + } else { + int i; + for (i=0; ipict_type = AV_PICTURE_TYPE_I; p->key_frame = 1; + avctx->bits_per_raw_sample = av_log2(s->maxval) + 1; switch (avctx->pix_fmt) { default: return AVERROR(EINVAL); - case AV_PIX_FMT_RGBA64BE: + case AV_PIX_FMT_RGBA64: n = avctx->width * 8; components=4; sample_len=16; + if (s->maxval < 65535) + upgrade = 2; goto do_read; - case AV_PIX_FMT_RGB48BE: + case AV_PIX_FMT_RGB48: n = avctx->width * 6; components=3; sample_len=16; + if (s->maxval < 65535) + upgrade = 2; goto do_read; case AV_PIX_FMT_RGBA: n = avctx->width * 4; @@ -70,6 +86,8 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data, n = avctx->width * 3; components=3; sample_len=8; + if (s->maxval < 255) + upgrade = 1; goto do_read; case AV_PIX_FMT_GRAY8: n = avctx->width; @@ -83,8 +101,7 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data, components=2; sample_len=8; goto do_read; - case AV_PIX_FMT_GRAY16BE: - case AV_PIX_FMT_GRAY16LE: + case AV_PIX_FMT_GRAY16: n = avctx->width * 2; components=1; sample_len=16; @@ -124,15 +141,19 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data, c = (*s->bytestream++) - '0'; } while (c <= 9); } - put_bits(&pb, sample_len, (((1<maxval>>1))/s->maxval); + if (sample_len == 16) { + ((uint16_t*)ptr)[j] = (((1<maxval>>1))/s->maxval; + } else + put_bits(&pb, sample_len, (((1<maxval>>1))/s->maxval); } - flush_put_bits(&pb); + if (sample_len != 16) + flush_put_bits(&pb); ptr+= linesize; } }else{ for (i = 0; i < avctx->height; i++) { if (!upgrade) - memcpy(ptr, s->bytestream, n); + samplecpy(ptr, s->bytestream, n, s->maxval); else if (upgrade == 1) { unsigned int j, f = (255 * 128 + s->maxval / 2) / s->maxval; for (j = 0; j < n; j++) @@ -150,8 +171,8 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data, } break; case AV_PIX_FMT_YUV420P: - case AV_PIX_FMT_YUV420P9BE: - case AV_PIX_FMT_YUV420P10BE: + case AV_PIX_FMT_YUV420P9: + case AV_PIX_FMT_YUV420P10: { unsigned char *ptr1, *ptr2; @@ -163,7 +184,7 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data, if (s->bytestream + n * avctx->height * 3 / 2 > s->bytestream_end) return AVERROR_INVALIDDATA; for (i = 0; i < avctx->height; i++) { - memcpy(ptr, s->bytestream, n); + samplecpy(ptr, s->bytestream, n, s->maxval); s->bytestream += n; ptr += linesize; } @@ -172,9 +193,9 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data, n >>= 1; h = avctx->height >> 1; for (i = 0; i < h; i++) { - memcpy(ptr1, s->bytestream, n); + samplecpy(ptr1, s->bytestream, n, s->maxval); s->bytestream += n; - memcpy(ptr2, s->bytestream, n); + samplecpy(ptr2, s->bytestream, n, s->maxval); s->bytestream += n; ptr1 += p->linesize[1]; ptr2 += p->linesize[2]; @@ -232,59 +253,59 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data, #if CONFIG_PGM_DECODER AVCodec ff_pgm_decoder = { .name = "pgm", + .long_name = NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PGM, .priv_data_size = sizeof(PNMContext), .decode = pnm_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"), }; #endif #if CONFIG_PGMYUV_DECODER AVCodec ff_pgmyuv_decoder = { .name = "pgmyuv", + .long_name = NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PGMYUV, .priv_data_size = sizeof(PNMContext), .decode = pnm_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"), }; #endif #if CONFIG_PPM_DECODER AVCodec ff_ppm_decoder = { .name = "ppm", + .long_name = NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PPM, .priv_data_size = sizeof(PNMContext), .decode = pnm_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"), }; #endif #if CONFIG_PBM_DECODER AVCodec ff_pbm_decoder = { .name = "pbm", + .long_name = NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PBM, .priv_data_size = sizeof(PNMContext), .decode = pnm_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"), }; #endif #if CONFIG_PAM_DECODER AVCodec ff_pam_decoder = { .name = "pam", + .long_name = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PAM, .priv_data_size = sizeof(PNMContext), .decode = pnm_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"), }; #endif diff --git a/ffmpeg/libavcodec/pnmenc.c b/ffmpeg/libavcodec/pnmenc.c index 8cd96be..e6c3635 100644 --- a/ffmpeg/libavcodec/pnmenc.c +++ b/ffmpeg/libavcodec/pnmenc.c @@ -22,14 +22,11 @@ #include "libavutil/pixdesc.h" #include "avcodec.h" #include "internal.h" -#include "pnm.h" - static int pnm_encode_frame(AVCodecContext *avctx, AVPacket *pkt, - const AVFrame *pict, int *got_packet) + const AVFrame *p, int *got_packet) { - PNMContext *s = avctx->priv_data; - AVFrame * const p = &s->picture; + uint8_t *bytestream, *bytestream_start, *bytestream_end; int i, h, h1, c, n, linesize, ret; uint8_t *ptr, *ptr1, *ptr2; @@ -38,13 +35,9 @@ static int pnm_encode_frame(AVCodecContext *avctx, AVPacket *pkt, avctx->height) + 200)) < 0) return ret; - *p = *pict; - p->pict_type = AV_PICTURE_TYPE_I; - p->key_frame = 1; - - s->bytestream_start = - s->bytestream = pkt->data; - s->bytestream_end = pkt->data + pkt->size; + bytestream_start = + bytestream = pkt->data; + bytestream_end = pkt->data + pkt->size; h = avctx->height; h1 = h; @@ -86,22 +79,22 @@ static int pnm_encode_frame(AVCodecContext *avctx, AVPacket *pkt, default: return -1; } - snprintf(s->bytestream, s->bytestream_end - s->bytestream, + snprintf(bytestream, bytestream_end - bytestream, "P%c\n%d %d\n", c, avctx->width, h1); - s->bytestream += strlen(s->bytestream); + bytestream += strlen(bytestream); if (avctx->pix_fmt != AV_PIX_FMT_MONOWHITE) { int maxdepth = (1 << (av_pix_fmt_desc_get(avctx->pix_fmt)->comp[0].depth_minus1 + 1)) - 1; - snprintf(s->bytestream, s->bytestream_end - s->bytestream, + snprintf(bytestream, bytestream_end - bytestream, "%d\n", maxdepth); - s->bytestream += strlen(s->bytestream); + bytestream += strlen(bytestream); } ptr = p->data[0]; linesize = p->linesize[0]; for (i = 0; i < h; i++) { - memcpy(s->bytestream, ptr, n); - s->bytestream += n; - ptr += linesize; + memcpy(bytestream, ptr, n); + bytestream += n; + ptr += linesize; } if (avctx->pix_fmt == AV_PIX_FMT_YUV420P || avctx->pix_fmt == AV_PIX_FMT_YUV420P16BE) { @@ -110,77 +103,94 @@ static int pnm_encode_frame(AVCodecContext *avctx, AVPacket *pkt, ptr1 = p->data[1]; ptr2 = p->data[2]; for (i = 0; i < h; i++) { - memcpy(s->bytestream, ptr1, n); - s->bytestream += n; - memcpy(s->bytestream, ptr2, n); - s->bytestream += n; + memcpy(bytestream, ptr1, n); + bytestream += n; + memcpy(bytestream, ptr2, n); + bytestream += n; ptr1 += p->linesize[1]; ptr2 += p->linesize[2]; } } - pkt->size = s->bytestream - s->bytestream_start; + pkt->size = bytestream - bytestream_start; pkt->flags |= AV_PKT_FLAG_KEY; *got_packet = 1; return 0; } +static av_cold int pnm_encode_init(AVCodecContext *avctx) +{ + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->key_frame = 1; + + return 0; +} + +static av_cold int pnm_encode_close(AVCodecContext *avctx) +{ + av_frame_free(&avctx->coded_frame); + return 0; +} #if CONFIG_PGM_ENCODER AVCodec ff_pgm_encoder = { .name = "pgm", + .long_name = NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PGM, - .priv_data_size = sizeof(PNMContext), - .init = ff_pnm_init, + .init = pnm_encode_init, + .close = pnm_encode_close, .encode2 = pnm_encode_frame, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"), }; #endif #if CONFIG_PGMYUV_ENCODER AVCodec ff_pgmyuv_encoder = { .name = "pgmyuv", + .long_name = NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PGMYUV, - .priv_data_size = sizeof(PNMContext), - .init = ff_pnm_init, + .init = pnm_encode_init, + .close = pnm_encode_close, .encode2 = pnm_encode_frame, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P16BE, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"), }; #endif #if CONFIG_PPM_ENCODER AVCodec ff_ppm_encoder = { .name = "ppm", + .long_name = NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PPM, - .priv_data_size = sizeof(PNMContext), - .init = ff_pnm_init, + .init = pnm_encode_init, + .close = pnm_encode_close, .encode2 = pnm_encode_frame, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB48BE, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"), }; #endif #if CONFIG_PBM_ENCODER AVCodec ff_pbm_encoder = { .name = "pbm", + .long_name = NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PBM, - .priv_data_size = sizeof(PNMContext), - .init = ff_pnm_init, + .init = pnm_encode_init, + .close = pnm_encode_close, .encode2 = pnm_encode_frame, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_MONOWHITE, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"), }; #endif diff --git a/ffmpeg/libavcodec/ppc/Makefile b/ffmpeg/libavcodec/ppc/Makefile index febbb0a..71b23da 100644 --- a/ffmpeg/libavcodec/ppc/Makefile +++ b/ffmpeg/libavcodec/ppc/Makefile @@ -1,24 +1,24 @@ OBJS += ppc/dsputil_ppc.o \ + ppc/fmtconvert_altivec.o \ ppc/videodsp_ppc.o \ +OBJS-$(CONFIG_FFT) += ppc/fft_altivec.o OBJS-$(CONFIG_H264CHROMA) += ppc/h264chroma_init.o -OBJS-$(CONFIG_H264QPEL) += ppc/h264_qpel.o +OBJS-$(CONFIG_H264DSP) += ppc/h264dsp.o +OBJS-$(CONFIG_H264QPEL) += ppc/h264qpel.o OBJS-$(CONFIG_HPELDSP) += ppc/hpeldsp_altivec.o +OBJS-$(CONFIG_MPEGAUDIODSP) += ppc/mpegaudiodsp_altivec.o +OBJS-$(CONFIG_MPEGVIDEO) += ppc/mpegvideo_altivec.o +OBJS-$(CONFIG_VC1_DECODER) += ppc/vc1dsp_altivec.o OBJS-$(CONFIG_VORBIS_DECODER) += ppc/vorbisdsp_altivec.o OBJS-$(CONFIG_VP3DSP) += ppc/vp3dsp_altivec.o - -FFT-OBJS-$(HAVE_GNU_AS) += ppc/fft_altivec_s.o -ALTIVEC-OBJS-$(CONFIG_FFT) += ppc/fft_altivec.o \ - $(FFT-OBJS-yes) -ALTIVEC-OBJS-$(CONFIG_H264DSP) += ppc/h264_altivec.o -ALTIVEC-OBJS-$(CONFIG_MPEGAUDIODSP) += ppc/mpegaudiodec_altivec.o -ALTIVEC-OBJS-$(CONFIG_MPEGVIDEO) += ppc/mpegvideo_altivec.o -ALTIVEC-OBJS-$(CONFIG_VC1_DECODER) += ppc/vc1dsp_altivec.o -ALTIVEC-OBJS-$(CONFIG_VP8_DECODER) += ppc/vp8dsp_altivec.o +OBJS-$(CONFIG_VP8_DECODER) += ppc/vp8dsp_altivec.o ALTIVEC-OBJS += ppc/dsputil_altivec.o \ ppc/fdct_altivec.o \ - ppc/fmtconvert_altivec.o \ ppc/gmc_altivec.o \ ppc/idct_altivec.o \ ppc/int_altivec.o \ + +FFT-OBJS-$(HAVE_GNU_AS) += ppc/fft_altivec_s.o +ALTIVEC-OBJS-$(CONFIG_FFT) += $(FFT-OBJS-yes) diff --git a/ffmpeg/libavcodec/ppc/dsputil_ppc.c b/ffmpeg/libavcodec/ppc/dsputil_ppc.c index 6112b0c..7454ea0 100644 --- a/ffmpeg/libavcodec/ppc/dsputil_ppc.c +++ b/ffmpeg/libavcodec/ppc/dsputil_ppc.c @@ -25,6 +25,7 @@ #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/mem.h" +#include "libavutil/ppc/cpu.h" #include "dsputil_altivec.h" /* ***** WARNING ***** WARNING ***** WARNING ***** */ @@ -156,8 +157,7 @@ av_cold void ff_dsputil_init_ppc(DSPContext *c, AVCodecContext *avctx) } } -#if HAVE_ALTIVEC - if (mm_flags & AV_CPU_FLAG_ALTIVEC) { + if (PPC_ALTIVEC(mm_flags)) { ff_dsputil_init_altivec(c, avctx); ff_int_init_altivec(c, avctx); c->gmc1 = ff_gmc1_altivec; @@ -180,5 +180,4 @@ av_cold void ff_dsputil_init_ppc(DSPContext *c, AVCodecContext *avctx) } } -#endif /* HAVE_ALTIVEC */ } diff --git a/ffmpeg/libavcodec/ppc/fdct_altivec.c b/ffmpeg/libavcodec/ppc/fdct_altivec.c index acab127..ff816e2 100644 --- a/ffmpeg/libavcodec/ppc/fdct_altivec.c +++ b/ffmpeg/libavcodec/ppc/fdct_altivec.c @@ -458,5 +458,3 @@ void ff_fdct_altivec(int16_t *block) #undef CTS /* }}} */ } - -/* vim:set foldmethod=marker foldlevel=0: */ diff --git a/ffmpeg/libavcodec/ppc/fft_altivec.c b/ffmpeg/libavcodec/ppc/fft_altivec.c index 651ee26..2357198 100644 --- a/ffmpeg/libavcodec/ppc/fft_altivec.c +++ b/ffmpeg/libavcodec/ppc/fft_altivec.c @@ -20,6 +20,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "config.h" +#include "libavutil/cpu.h" #include "libavutil/ppc/types_altivec.h" #include "libavutil/ppc/util_altivec.h" #include "libavcodec/fft.h" @@ -36,8 +38,8 @@ void ff_fft_calc_altivec(FFTContext *s, FFTComplex *z); void ff_fft_calc_interleave_altivec(FFTContext *s, FFTComplex *z); -#if HAVE_GNU_AS -static void ff_imdct_half_altivec(FFTContext *s, FFTSample *output, const FFTSample *input) +#if HAVE_GNU_AS && HAVE_ALTIVEC +static void imdct_half_altivec(FFTContext *s, FFTSample *output, const FFTSample *input) { int j, k; int n = 1 << s->mdct_bits; @@ -117,7 +119,7 @@ static void ff_imdct_half_altivec(FFTContext *s, FFTSample *output, const FFTSam } while(k >= 0); } -static void ff_imdct_calc_altivec(FFTContext *s, FFTSample *output, const FFTSample *input) +static void imdct_calc_altivec(FFTContext *s, FFTSample *output, const FFTSample *input) { int k; int n = 1 << s->mdct_bits; @@ -127,7 +129,7 @@ static void ff_imdct_calc_altivec(FFTContext *s, FFTSample *output, const FFTSam vec_u32 *p0 = (vec_u32*)(output+n4); vec_u32 *p1 = (vec_u32*)(output+n4*3); - ff_imdct_half_altivec(s, output+n4, input); + imdct_half_altivec(s, output + n4, input); for (k = 0; k < n16; k++) { vec_u32 a = p0[k] ^ sign; @@ -136,15 +138,18 @@ static void ff_imdct_calc_altivec(FFTContext *s, FFTSample *output, const FFTSam p1[k] = vec_perm(b, b, vcprm(3,2,1,0)); } } -#endif /* HAVE_GNU_AS */ +#endif /* HAVE_GNU_AS && HAVE_ALTIVEC */ -av_cold void ff_fft_init_altivec(FFTContext *s) +av_cold void ff_fft_init_ppc(FFTContext *s) { -#if HAVE_GNU_AS +#if HAVE_GNU_AS && HAVE_ALTIVEC + if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC)) + return; + s->fft_calc = ff_fft_calc_interleave_altivec; if (s->mdct_bits >= 5) { - s->imdct_calc = ff_imdct_calc_altivec; - s->imdct_half = ff_imdct_half_altivec; + s->imdct_calc = imdct_calc_altivec; + s->imdct_half = imdct_half_altivec; } -#endif +#endif /* HAVE_GNU_AS && HAVE_ALTIVEC */ } diff --git a/ffmpeg/libavcodec/ppc/fmtconvert_altivec.c b/ffmpeg/libavcodec/ppc/fmtconvert_altivec.c index b29c7d4..cd32e39 100644 --- a/ffmpeg/libavcodec/ppc/fmtconvert_altivec.c +++ b/ffmpeg/libavcodec/ppc/fmtconvert_altivec.c @@ -18,14 +18,17 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "libavcodec/fmtconvert.h" - -#include "libavutil/ppc/util_altivec.h" +#include "config.h" #include "libavutil/attributes.h" +#include "libavutil/cpu.h" #include "libavutil/mem.h" +#include "libavutil/ppc/util_altivec.h" +#include "libavcodec/fmtconvert.h" #include "dsputil_altivec.h" -static void int32_to_float_fmul_scalar_altivec(float *dst, const int *src, +#if HAVE_ALTIVEC + +static void int32_to_float_fmul_scalar_altivec(float *dst, const int32_t *src, float mul, int len) { union { @@ -156,11 +159,19 @@ static void float_to_int16_interleave_altivec(int16_t *dst, const float **src, } } -av_cold void ff_fmt_convert_init_altivec(FmtConvertContext *c, AVCodecContext *avctx) +#endif /* HAVE_ALTIVEC */ + +av_cold void ff_fmt_convert_init_ppc(FmtConvertContext *c, + AVCodecContext *avctx) { +#if HAVE_ALTIVEC + if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC)) + return; + c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_altivec; if (!(avctx->flags & CODEC_FLAG_BITEXACT)) { c->float_to_int16 = float_to_int16_altivec; c->float_to_int16_interleave = float_to_int16_interleave_altivec; } +#endif /* HAVE_ALTIVEC */ } diff --git a/ffmpeg/libavcodec/ppc/gmc_altivec.c b/ffmpeg/libavcodec/ppc/gmc_altivec.c index 4db761d..45d850a 100644 --- a/ffmpeg/libavcodec/ppc/gmc_altivec.c +++ b/ffmpeg/libavcodec/ppc/gmc_altivec.c @@ -66,7 +66,7 @@ void ff_gmc1_altivec(uint8_t *dst /* align 8 */, uint8_t *src /* align1 */, int srcvA = vec_perm(src_0, src_1, vec_lvsl(0, src)); if (src_really_odd != 0x0000000F) { - // if src & 0xF == 0xF, then (src+1) is properly aligned + // if (src & 0xF) == 0xF, then (src+1) is properly aligned // on the second vector. srcvB = vec_perm(src_0, src_1, vec_lvsl(1, src)); } else { @@ -90,7 +90,7 @@ void ff_gmc1_altivec(uint8_t *dst /* align 8 */, uint8_t *src /* align1 */, int srcvC = vec_perm(src_0, src_1, vec_lvsl(stride + 0, src)); if (src_really_odd != 0x0000000F) { - // if src & 0xF == 0xF, then (src+1) is properly aligned + // if (src & 0xF) == 0xF, then (src+1) is properly aligned // on the second vector. srcvD = vec_perm(src_0, src_1, vec_lvsl(stride + 1, src)); } else { diff --git a/ffmpeg/libavcodec/ppc/h264_altivec.c b/ffmpeg/libavcodec/ppc/h264_altivec.c deleted file mode 100644 index 3c2bb4d..0000000 --- a/ffmpeg/libavcodec/ppc/h264_altivec.c +++ /dev/null @@ -1,748 +0,0 @@ -/* - * Copyright (c) 2004 Romain Dolbeau - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/attributes.h" -#include "libavutil/cpu.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/ppc/types_altivec.h" -#include "libavutil/ppc/util_altivec.h" -#include "libavcodec/h264data.h" -#include "libavcodec/h264dsp.h" - -/**************************************************************************** - * IDCT transform: - ****************************************************************************/ - -#define VEC_1D_DCT(vb0,vb1,vb2,vb3,va0,va1,va2,va3) \ - /* 1st stage */ \ - vz0 = vec_add(vb0,vb2); /* temp[0] = Y[0] + Y[2] */ \ - vz1 = vec_sub(vb0,vb2); /* temp[1] = Y[0] - Y[2] */ \ - vz2 = vec_sra(vb1,vec_splat_u16(1)); \ - vz2 = vec_sub(vz2,vb3); /* temp[2] = Y[1].1/2 - Y[3] */ \ - vz3 = vec_sra(vb3,vec_splat_u16(1)); \ - vz3 = vec_add(vb1,vz3); /* temp[3] = Y[1] + Y[3].1/2 */ \ - /* 2nd stage: output */ \ - va0 = vec_add(vz0,vz3); /* x[0] = temp[0] + temp[3] */ \ - va1 = vec_add(vz1,vz2); /* x[1] = temp[1] + temp[2] */ \ - va2 = vec_sub(vz1,vz2); /* x[2] = temp[1] - temp[2] */ \ - va3 = vec_sub(vz0,vz3) /* x[3] = temp[0] - temp[3] */ - -#define VEC_TRANSPOSE_4(a0,a1,a2,a3,b0,b1,b2,b3) \ - b0 = vec_mergeh( a0, a0 ); \ - b1 = vec_mergeh( a1, a0 ); \ - b2 = vec_mergeh( a2, a0 ); \ - b3 = vec_mergeh( a3, a0 ); \ - a0 = vec_mergeh( b0, b2 ); \ - a1 = vec_mergel( b0, b2 ); \ - a2 = vec_mergeh( b1, b3 ); \ - a3 = vec_mergel( b1, b3 ); \ - b0 = vec_mergeh( a0, a2 ); \ - b1 = vec_mergel( a0, a2 ); \ - b2 = vec_mergeh( a1, a3 ); \ - b3 = vec_mergel( a1, a3 ) - -#define VEC_LOAD_U8_ADD_S16_STORE_U8(va) \ - vdst_orig = vec_ld(0, dst); \ - vdst = vec_perm(vdst_orig, zero_u8v, vdst_mask); \ - vdst_ss = (vec_s16) vec_mergeh(zero_u8v, vdst); \ - va = vec_add(va, vdst_ss); \ - va_u8 = vec_packsu(va, zero_s16v); \ - va_u32 = vec_splat((vec_u32)va_u8, 0); \ - vec_ste(va_u32, element, (uint32_t*)dst); - -static void ff_h264_idct_add_altivec(uint8_t *dst, int16_t *block, int stride) -{ - vec_s16 va0, va1, va2, va3; - vec_s16 vz0, vz1, vz2, vz3; - vec_s16 vtmp0, vtmp1, vtmp2, vtmp3; - vec_u8 va_u8; - vec_u32 va_u32; - vec_s16 vdst_ss; - const vec_u16 v6us = vec_splat_u16(6); - vec_u8 vdst, vdst_orig; - vec_u8 vdst_mask = vec_lvsl(0, dst); - int element = ((unsigned long)dst & 0xf) >> 2; - LOAD_ZERO; - - block[0] += 32; /* add 32 as a DC-level for rounding */ - - vtmp0 = vec_ld(0,block); - vtmp1 = vec_sld(vtmp0, vtmp0, 8); - vtmp2 = vec_ld(16,block); - vtmp3 = vec_sld(vtmp2, vtmp2, 8); - memset(block, 0, 16 * sizeof(int16_t)); - - VEC_1D_DCT(vtmp0,vtmp1,vtmp2,vtmp3,va0,va1,va2,va3); - VEC_TRANSPOSE_4(va0,va1,va2,va3,vtmp0,vtmp1,vtmp2,vtmp3); - VEC_1D_DCT(vtmp0,vtmp1,vtmp2,vtmp3,va0,va1,va2,va3); - - va0 = vec_sra(va0,v6us); - va1 = vec_sra(va1,v6us); - va2 = vec_sra(va2,v6us); - va3 = vec_sra(va3,v6us); - - VEC_LOAD_U8_ADD_S16_STORE_U8(va0); - dst += stride; - VEC_LOAD_U8_ADD_S16_STORE_U8(va1); - dst += stride; - VEC_LOAD_U8_ADD_S16_STORE_U8(va2); - dst += stride; - VEC_LOAD_U8_ADD_S16_STORE_U8(va3); -} - -#define IDCT8_1D_ALTIVEC(s0, s1, s2, s3, s4, s5, s6, s7, d0, d1, d2, d3, d4, d5, d6, d7) {\ - /* a0 = SRC(0) + SRC(4); */ \ - vec_s16 a0v = vec_add(s0, s4); \ - /* a2 = SRC(0) - SRC(4); */ \ - vec_s16 a2v = vec_sub(s0, s4); \ - /* a4 = (SRC(2)>>1) - SRC(6); */ \ - vec_s16 a4v = vec_sub(vec_sra(s2, onev), s6); \ - /* a6 = (SRC(6)>>1) + SRC(2); */ \ - vec_s16 a6v = vec_add(vec_sra(s6, onev), s2); \ - /* b0 = a0 + a6; */ \ - vec_s16 b0v = vec_add(a0v, a6v); \ - /* b2 = a2 + a4; */ \ - vec_s16 b2v = vec_add(a2v, a4v); \ - /* b4 = a2 - a4; */ \ - vec_s16 b4v = vec_sub(a2v, a4v); \ - /* b6 = a0 - a6; */ \ - vec_s16 b6v = vec_sub(a0v, a6v); \ - /* a1 = SRC(5) - SRC(3) - SRC(7) - (SRC(7)>>1); */ \ - /* a1 = (SRC(5)-SRC(3)) - (SRC(7) + (SRC(7)>>1)); */ \ - vec_s16 a1v = vec_sub( vec_sub(s5, s3), vec_add(s7, vec_sra(s7, onev)) ); \ - /* a3 = SRC(7) + SRC(1) - SRC(3) - (SRC(3)>>1); */ \ - /* a3 = (SRC(7)+SRC(1)) - (SRC(3) + (SRC(3)>>1)); */ \ - vec_s16 a3v = vec_sub( vec_add(s7, s1), vec_add(s3, vec_sra(s3, onev)) );\ - /* a5 = SRC(7) - SRC(1) + SRC(5) + (SRC(5)>>1); */ \ - /* a5 = (SRC(7)-SRC(1)) + SRC(5) + (SRC(5)>>1); */ \ - vec_s16 a5v = vec_add( vec_sub(s7, s1), vec_add(s5, vec_sra(s5, onev)) );\ - /* a7 = SRC(5)+SRC(3) + SRC(1) + (SRC(1)>>1); */ \ - vec_s16 a7v = vec_add( vec_add(s5, s3), vec_add(s1, vec_sra(s1, onev)) );\ - /* b1 = (a7>>2) + a1; */ \ - vec_s16 b1v = vec_add( vec_sra(a7v, twov), a1v); \ - /* b3 = a3 + (a5>>2); */ \ - vec_s16 b3v = vec_add(a3v, vec_sra(a5v, twov)); \ - /* b5 = (a3>>2) - a5; */ \ - vec_s16 b5v = vec_sub( vec_sra(a3v, twov), a5v); \ - /* b7 = a7 - (a1>>2); */ \ - vec_s16 b7v = vec_sub( a7v, vec_sra(a1v, twov)); \ - /* DST(0, b0 + b7); */ \ - d0 = vec_add(b0v, b7v); \ - /* DST(1, b2 + b5); */ \ - d1 = vec_add(b2v, b5v); \ - /* DST(2, b4 + b3); */ \ - d2 = vec_add(b4v, b3v); \ - /* DST(3, b6 + b1); */ \ - d3 = vec_add(b6v, b1v); \ - /* DST(4, b6 - b1); */ \ - d4 = vec_sub(b6v, b1v); \ - /* DST(5, b4 - b3); */ \ - d5 = vec_sub(b4v, b3v); \ - /* DST(6, b2 - b5); */ \ - d6 = vec_sub(b2v, b5v); \ - /* DST(7, b0 - b7); */ \ - d7 = vec_sub(b0v, b7v); \ -} - -#define ALTIVEC_STORE_SUM_CLIP(dest, idctv, perm_ldv, perm_stv, sel) { \ - /* unaligned load */ \ - vec_u8 hv = vec_ld( 0, dest ); \ - vec_u8 lv = vec_ld( 7, dest ); \ - vec_u8 dstv = vec_perm( hv, lv, (vec_u8)perm_ldv ); \ - vec_s16 idct_sh6 = vec_sra(idctv, sixv); \ - vec_u16 dst16 = (vec_u16)vec_mergeh(zero_u8v, dstv); \ - vec_s16 idstsum = vec_adds(idct_sh6, (vec_s16)dst16); \ - vec_u8 idstsum8 = vec_packsu(zero_s16v, idstsum); \ - vec_u8 edgehv; \ - /* unaligned store */ \ - vec_u8 bodyv = vec_perm( idstsum8, idstsum8, perm_stv );\ - vec_u8 edgelv = vec_perm( sel, zero_u8v, perm_stv ); \ - lv = vec_sel( lv, bodyv, edgelv ); \ - vec_st( lv, 7, dest ); \ - hv = vec_ld( 0, dest ); \ - edgehv = vec_perm( zero_u8v, sel, perm_stv ); \ - hv = vec_sel( hv, bodyv, edgehv ); \ - vec_st( hv, 0, dest ); \ - } - -static void ff_h264_idct8_add_altivec( uint8_t *dst, int16_t *dct, int stride ) { - vec_s16 s0, s1, s2, s3, s4, s5, s6, s7; - vec_s16 d0, d1, d2, d3, d4, d5, d6, d7; - vec_s16 idct0, idct1, idct2, idct3, idct4, idct5, idct6, idct7; - - vec_u8 perm_ldv = vec_lvsl(0, dst); - vec_u8 perm_stv = vec_lvsr(8, dst); - - const vec_u16 onev = vec_splat_u16(1); - const vec_u16 twov = vec_splat_u16(2); - const vec_u16 sixv = vec_splat_u16(6); - - const vec_u8 sel = (vec_u8) {0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1}; - LOAD_ZERO; - - dct[0] += 32; // rounding for the >>6 at the end - - s0 = vec_ld(0x00, (int16_t*)dct); - s1 = vec_ld(0x10, (int16_t*)dct); - s2 = vec_ld(0x20, (int16_t*)dct); - s3 = vec_ld(0x30, (int16_t*)dct); - s4 = vec_ld(0x40, (int16_t*)dct); - s5 = vec_ld(0x50, (int16_t*)dct); - s6 = vec_ld(0x60, (int16_t*)dct); - s7 = vec_ld(0x70, (int16_t*)dct); - memset(dct, 0, 64 * sizeof(int16_t)); - - IDCT8_1D_ALTIVEC(s0, s1, s2, s3, s4, s5, s6, s7, - d0, d1, d2, d3, d4, d5, d6, d7); - - TRANSPOSE8( d0, d1, d2, d3, d4, d5, d6, d7 ); - - IDCT8_1D_ALTIVEC(d0, d1, d2, d3, d4, d5, d6, d7, - idct0, idct1, idct2, idct3, idct4, idct5, idct6, idct7); - - ALTIVEC_STORE_SUM_CLIP(&dst[0*stride], idct0, perm_ldv, perm_stv, sel); - ALTIVEC_STORE_SUM_CLIP(&dst[1*stride], idct1, perm_ldv, perm_stv, sel); - ALTIVEC_STORE_SUM_CLIP(&dst[2*stride], idct2, perm_ldv, perm_stv, sel); - ALTIVEC_STORE_SUM_CLIP(&dst[3*stride], idct3, perm_ldv, perm_stv, sel); - ALTIVEC_STORE_SUM_CLIP(&dst[4*stride], idct4, perm_ldv, perm_stv, sel); - ALTIVEC_STORE_SUM_CLIP(&dst[5*stride], idct5, perm_ldv, perm_stv, sel); - ALTIVEC_STORE_SUM_CLIP(&dst[6*stride], idct6, perm_ldv, perm_stv, sel); - ALTIVEC_STORE_SUM_CLIP(&dst[7*stride], idct7, perm_ldv, perm_stv, sel); -} - -static av_always_inline void h264_idct_dc_add_internal(uint8_t *dst, int16_t *block, int stride, int size) -{ - vec_s16 dc16; - vec_u8 dcplus, dcminus, v0, v1, v2, v3, aligner; - LOAD_ZERO; - DECLARE_ALIGNED(16, int, dc); - int i; - - dc = (block[0] + 32) >> 6; - block[0] = 0; - dc16 = vec_splat((vec_s16) vec_lde(0, &dc), 1); - - if (size == 4) - dc16 = vec_sld(dc16, zero_s16v, 8); - dcplus = vec_packsu(dc16, zero_s16v); - dcminus = vec_packsu(vec_sub(zero_s16v, dc16), zero_s16v); - - aligner = vec_lvsr(0, dst); - dcplus = vec_perm(dcplus, dcplus, aligner); - dcminus = vec_perm(dcminus, dcminus, aligner); - - for (i = 0; i < size; i += 4) { - v0 = vec_ld(0, dst+0*stride); - v1 = vec_ld(0, dst+1*stride); - v2 = vec_ld(0, dst+2*stride); - v3 = vec_ld(0, dst+3*stride); - - v0 = vec_adds(v0, dcplus); - v1 = vec_adds(v1, dcplus); - v2 = vec_adds(v2, dcplus); - v3 = vec_adds(v3, dcplus); - - v0 = vec_subs(v0, dcminus); - v1 = vec_subs(v1, dcminus); - v2 = vec_subs(v2, dcminus); - v3 = vec_subs(v3, dcminus); - - vec_st(v0, 0, dst+0*stride); - vec_st(v1, 0, dst+1*stride); - vec_st(v2, 0, dst+2*stride); - vec_st(v3, 0, dst+3*stride); - - dst += 4*stride; - } -} - -static void h264_idct_dc_add_altivec(uint8_t *dst, int16_t *block, int stride) -{ - h264_idct_dc_add_internal(dst, block, stride, 4); -} - -static void ff_h264_idct8_dc_add_altivec(uint8_t *dst, int16_t *block, int stride) -{ - h264_idct_dc_add_internal(dst, block, stride, 8); -} - -static void ff_h264_idct_add16_altivec(uint8_t *dst, const int *block_offset, int16_t *block, int stride, const uint8_t nnzc[15*8]){ - int i; - for(i=0; i<16; i++){ - int nnz = nnzc[ scan8[i] ]; - if(nnz){ - if(nnz==1 && block[i*16]) h264_idct_dc_add_altivec(dst + block_offset[i], block + i*16, stride); - else ff_h264_idct_add_altivec(dst + block_offset[i], block + i*16, stride); - } - } -} - -static void ff_h264_idct_add16intra_altivec(uint8_t *dst, const int *block_offset, int16_t *block, int stride, const uint8_t nnzc[15*8]){ - int i; - for(i=0; i<16; i++){ - if(nnzc[ scan8[i] ]) ff_h264_idct_add_altivec(dst + block_offset[i], block + i*16, stride); - else if(block[i*16]) h264_idct_dc_add_altivec(dst + block_offset[i], block + i*16, stride); - } -} - -static void ff_h264_idct8_add4_altivec(uint8_t *dst, const int *block_offset, int16_t *block, int stride, const uint8_t nnzc[15*8]){ - int i; - for(i=0; i<16; i+=4){ - int nnz = nnzc[ scan8[i] ]; - if(nnz){ - if(nnz==1 && block[i*16]) ff_h264_idct8_dc_add_altivec(dst + block_offset[i], block + i*16, stride); - else ff_h264_idct8_add_altivec (dst + block_offset[i], block + i*16, stride); - } - } -} - -static void ff_h264_idct_add8_altivec(uint8_t **dest, const int *block_offset, int16_t *block, int stride, const uint8_t nnzc[15*8]){ - int i, j; - for (j = 1; j < 3; j++) { - for(i = j * 16; i < j * 16 + 4; i++){ - if(nnzc[ scan8[i] ]) - ff_h264_idct_add_altivec(dest[j-1] + block_offset[i], block + i*16, stride); - else if(block[i*16]) - h264_idct_dc_add_altivec(dest[j-1] + block_offset[i], block + i*16, stride); - } - } -} - -#define transpose4x16(r0, r1, r2, r3) { \ - register vec_u8 r4; \ - register vec_u8 r5; \ - register vec_u8 r6; \ - register vec_u8 r7; \ - \ - r4 = vec_mergeh(r0, r2); /*0, 2 set 0*/ \ - r5 = vec_mergel(r0, r2); /*0, 2 set 1*/ \ - r6 = vec_mergeh(r1, r3); /*1, 3 set 0*/ \ - r7 = vec_mergel(r1, r3); /*1, 3 set 1*/ \ - \ - r0 = vec_mergeh(r4, r6); /*all set 0*/ \ - r1 = vec_mergel(r4, r6); /*all set 1*/ \ - r2 = vec_mergeh(r5, r7); /*all set 2*/ \ - r3 = vec_mergel(r5, r7); /*all set 3*/ \ -} - -static inline void write16x4(uint8_t *dst, int dst_stride, - register vec_u8 r0, register vec_u8 r1, - register vec_u8 r2, register vec_u8 r3) { - DECLARE_ALIGNED(16, unsigned char, result)[64]; - uint32_t *src_int = (uint32_t *)result, *dst_int = (uint32_t *)dst; - int int_dst_stride = dst_stride/4; - - vec_st(r0, 0, result); - vec_st(r1, 16, result); - vec_st(r2, 32, result); - vec_st(r3, 48, result); - /* FIXME: there has to be a better way!!!! */ - *dst_int = *src_int; - *(dst_int+ int_dst_stride) = *(src_int + 1); - *(dst_int+ 2*int_dst_stride) = *(src_int + 2); - *(dst_int+ 3*int_dst_stride) = *(src_int + 3); - *(dst_int+ 4*int_dst_stride) = *(src_int + 4); - *(dst_int+ 5*int_dst_stride) = *(src_int + 5); - *(dst_int+ 6*int_dst_stride) = *(src_int + 6); - *(dst_int+ 7*int_dst_stride) = *(src_int + 7); - *(dst_int+ 8*int_dst_stride) = *(src_int + 8); - *(dst_int+ 9*int_dst_stride) = *(src_int + 9); - *(dst_int+10*int_dst_stride) = *(src_int + 10); - *(dst_int+11*int_dst_stride) = *(src_int + 11); - *(dst_int+12*int_dst_stride) = *(src_int + 12); - *(dst_int+13*int_dst_stride) = *(src_int + 13); - *(dst_int+14*int_dst_stride) = *(src_int + 14); - *(dst_int+15*int_dst_stride) = *(src_int + 15); -} - -/** @brief performs a 6x16 transpose of data in src, and stores it to dst - @todo FIXME: see if we can't spare some vec_lvsl() by them factorizing - out of unaligned_load() */ -#define readAndTranspose16x6(src, src_stride, r8, r9, r10, r11, r12, r13) {\ - register vec_u8 r0 = unaligned_load(0, src); \ - register vec_u8 r1 = unaligned_load( src_stride, src); \ - register vec_u8 r2 = unaligned_load(2* src_stride, src); \ - register vec_u8 r3 = unaligned_load(3* src_stride, src); \ - register vec_u8 r4 = unaligned_load(4* src_stride, src); \ - register vec_u8 r5 = unaligned_load(5* src_stride, src); \ - register vec_u8 r6 = unaligned_load(6* src_stride, src); \ - register vec_u8 r7 = unaligned_load(7* src_stride, src); \ - register vec_u8 r14 = unaligned_load(14*src_stride, src); \ - register vec_u8 r15 = unaligned_load(15*src_stride, src); \ - \ - r8 = unaligned_load( 8*src_stride, src); \ - r9 = unaligned_load( 9*src_stride, src); \ - r10 = unaligned_load(10*src_stride, src); \ - r11 = unaligned_load(11*src_stride, src); \ - r12 = unaligned_load(12*src_stride, src); \ - r13 = unaligned_load(13*src_stride, src); \ - \ - /*Merge first pairs*/ \ - r0 = vec_mergeh(r0, r8); /*0, 8*/ \ - r1 = vec_mergeh(r1, r9); /*1, 9*/ \ - r2 = vec_mergeh(r2, r10); /*2,10*/ \ - r3 = vec_mergeh(r3, r11); /*3,11*/ \ - r4 = vec_mergeh(r4, r12); /*4,12*/ \ - r5 = vec_mergeh(r5, r13); /*5,13*/ \ - r6 = vec_mergeh(r6, r14); /*6,14*/ \ - r7 = vec_mergeh(r7, r15); /*7,15*/ \ - \ - /*Merge second pairs*/ \ - r8 = vec_mergeh(r0, r4); /*0,4, 8,12 set 0*/ \ - r9 = vec_mergel(r0, r4); /*0,4, 8,12 set 1*/ \ - r10 = vec_mergeh(r1, r5); /*1,5, 9,13 set 0*/ \ - r11 = vec_mergel(r1, r5); /*1,5, 9,13 set 1*/ \ - r12 = vec_mergeh(r2, r6); /*2,6,10,14 set 0*/ \ - r13 = vec_mergel(r2, r6); /*2,6,10,14 set 1*/ \ - r14 = vec_mergeh(r3, r7); /*3,7,11,15 set 0*/ \ - r15 = vec_mergel(r3, r7); /*3,7,11,15 set 1*/ \ - \ - /*Third merge*/ \ - r0 = vec_mergeh(r8, r12); /*0,2,4,6,8,10,12,14 set 0*/ \ - r1 = vec_mergel(r8, r12); /*0,2,4,6,8,10,12,14 set 1*/ \ - r2 = vec_mergeh(r9, r13); /*0,2,4,6,8,10,12,14 set 2*/ \ - r4 = vec_mergeh(r10, r14); /*1,3,5,7,9,11,13,15 set 0*/ \ - r5 = vec_mergel(r10, r14); /*1,3,5,7,9,11,13,15 set 1*/ \ - r6 = vec_mergeh(r11, r15); /*1,3,5,7,9,11,13,15 set 2*/ \ - /* Don't need to compute 3 and 7*/ \ - \ - /*Final merge*/ \ - r8 = vec_mergeh(r0, r4); /*all set 0*/ \ - r9 = vec_mergel(r0, r4); /*all set 1*/ \ - r10 = vec_mergeh(r1, r5); /*all set 2*/ \ - r11 = vec_mergel(r1, r5); /*all set 3*/ \ - r12 = vec_mergeh(r2, r6); /*all set 4*/ \ - r13 = vec_mergel(r2, r6); /*all set 5*/ \ - /* Don't need to compute 14 and 15*/ \ - \ -} - -// out: o = |x-y| < a -static inline vec_u8 diff_lt_altivec ( register vec_u8 x, - register vec_u8 y, - register vec_u8 a) { - - register vec_u8 diff = vec_subs(x, y); - register vec_u8 diffneg = vec_subs(y, x); - register vec_u8 o = vec_or(diff, diffneg); /* |x-y| */ - o = (vec_u8)vec_cmplt(o, a); - return o; -} - -static inline vec_u8 h264_deblock_mask ( register vec_u8 p0, - register vec_u8 p1, - register vec_u8 q0, - register vec_u8 q1, - register vec_u8 alpha, - register vec_u8 beta) { - - register vec_u8 mask; - register vec_u8 tempmask; - - mask = diff_lt_altivec(p0, q0, alpha); - tempmask = diff_lt_altivec(p1, p0, beta); - mask = vec_and(mask, tempmask); - tempmask = diff_lt_altivec(q1, q0, beta); - mask = vec_and(mask, tempmask); - - return mask; -} - -// out: newp1 = clip((p2 + ((p0 + q0 + 1) >> 1)) >> 1, p1-tc0, p1+tc0) -static inline vec_u8 h264_deblock_q1(register vec_u8 p0, - register vec_u8 p1, - register vec_u8 p2, - register vec_u8 q0, - register vec_u8 tc0) { - - register vec_u8 average = vec_avg(p0, q0); - register vec_u8 temp; - register vec_u8 uncliped; - register vec_u8 ones; - register vec_u8 max; - register vec_u8 min; - register vec_u8 newp1; - - temp = vec_xor(average, p2); - average = vec_avg(average, p2); /*avg(p2, avg(p0, q0)) */ - ones = vec_splat_u8(1); - temp = vec_and(temp, ones); /*(p2^avg(p0, q0)) & 1 */ - uncliped = vec_subs(average, temp); /*(p2+((p0+q0+1)>>1))>>1 */ - max = vec_adds(p1, tc0); - min = vec_subs(p1, tc0); - newp1 = vec_max(min, uncliped); - newp1 = vec_min(max, newp1); - return newp1; -} - -#define h264_deblock_p0_q0(p0, p1, q0, q1, tc0masked) { \ - \ - const vec_u8 A0v = vec_sl(vec_splat_u8(10), vec_splat_u8(4)); \ - \ - register vec_u8 pq0bit = vec_xor(p0,q0); \ - register vec_u8 q1minus; \ - register vec_u8 p0minus; \ - register vec_u8 stage1; \ - register vec_u8 stage2; \ - register vec_u8 vec160; \ - register vec_u8 delta; \ - register vec_u8 deltaneg; \ - \ - q1minus = vec_nor(q1, q1); /* 255 - q1 */ \ - stage1 = vec_avg(p1, q1minus); /* (p1 - q1 + 256)>>1 */ \ - stage2 = vec_sr(stage1, vec_splat_u8(1)); /* (p1 - q1 + 256)>>2 = 64 + (p1 - q1) >> 2 */ \ - p0minus = vec_nor(p0, p0); /* 255 - p0 */ \ - stage1 = vec_avg(q0, p0minus); /* (q0 - p0 + 256)>>1 */ \ - pq0bit = vec_and(pq0bit, vec_splat_u8(1)); \ - stage2 = vec_avg(stage2, pq0bit); /* 32 + ((q0 - p0)&1 + (p1 - q1) >> 2 + 1) >> 1 */ \ - stage2 = vec_adds(stage2, stage1); /* 160 + ((p0 - q0) + (p1 - q1) >> 2 + 1) >> 1 */ \ - vec160 = vec_ld(0, &A0v); \ - deltaneg = vec_subs(vec160, stage2); /* -d */ \ - delta = vec_subs(stage2, vec160); /* d */ \ - deltaneg = vec_min(tc0masked, deltaneg); \ - delta = vec_min(tc0masked, delta); \ - p0 = vec_subs(p0, deltaneg); \ - q0 = vec_subs(q0, delta); \ - p0 = vec_adds(p0, delta); \ - q0 = vec_adds(q0, deltaneg); \ -} - -#define h264_loop_filter_luma_altivec(p2, p1, p0, q0, q1, q2, alpha, beta, tc0) { \ - DECLARE_ALIGNED(16, unsigned char, temp)[16]; \ - register vec_u8 alphavec; \ - register vec_u8 betavec; \ - register vec_u8 mask; \ - register vec_u8 p1mask; \ - register vec_u8 q1mask; \ - register vector signed char tc0vec; \ - register vec_u8 finaltc0; \ - register vec_u8 tc0masked; \ - register vec_u8 newp1; \ - register vec_u8 newq1; \ - \ - temp[0] = alpha; \ - temp[1] = beta; \ - alphavec = vec_ld(0, temp); \ - betavec = vec_splat(alphavec, 0x1); \ - alphavec = vec_splat(alphavec, 0x0); \ - mask = h264_deblock_mask(p0, p1, q0, q1, alphavec, betavec); /*if in block */ \ - \ - AV_COPY32(temp, tc0); \ - tc0vec = vec_ld(0, (signed char*)temp); \ - tc0vec = vec_mergeh(tc0vec, tc0vec); \ - tc0vec = vec_mergeh(tc0vec, tc0vec); \ - mask = vec_and(mask, vec_cmpgt(tc0vec, vec_splat_s8(-1))); /* if tc0[i] >= 0 */ \ - finaltc0 = vec_and((vec_u8)tc0vec, mask); /* tc = tc0 */ \ - \ - p1mask = diff_lt_altivec(p2, p0, betavec); \ - p1mask = vec_and(p1mask, mask); /* if ( |p2 - p0| < beta) */ \ - tc0masked = vec_and(p1mask, (vec_u8)tc0vec); \ - finaltc0 = vec_sub(finaltc0, p1mask); /* tc++ */ \ - newp1 = h264_deblock_q1(p0, p1, p2, q0, tc0masked); \ - /*end if*/ \ - \ - q1mask = diff_lt_altivec(q2, q0, betavec); \ - q1mask = vec_and(q1mask, mask); /* if ( |q2 - q0| < beta ) */\ - tc0masked = vec_and(q1mask, (vec_u8)tc0vec); \ - finaltc0 = vec_sub(finaltc0, q1mask); /* tc++ */ \ - newq1 = h264_deblock_q1(p0, q1, q2, q0, tc0masked); \ - /*end if*/ \ - \ - h264_deblock_p0_q0(p0, p1, q0, q1, finaltc0); \ - p1 = newp1; \ - q1 = newq1; \ -} - -static void h264_v_loop_filter_luma_altivec(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) { - - if ((tc0[0] & tc0[1] & tc0[2] & tc0[3]) >= 0) { - register vec_u8 p2 = vec_ld(-3*stride, pix); - register vec_u8 p1 = vec_ld(-2*stride, pix); - register vec_u8 p0 = vec_ld(-1*stride, pix); - register vec_u8 q0 = vec_ld(0, pix); - register vec_u8 q1 = vec_ld(stride, pix); - register vec_u8 q2 = vec_ld(2*stride, pix); - h264_loop_filter_luma_altivec(p2, p1, p0, q0, q1, q2, alpha, beta, tc0); - vec_st(p1, -2*stride, pix); - vec_st(p0, -1*stride, pix); - vec_st(q0, 0, pix); - vec_st(q1, stride, pix); - } -} - -static void h264_h_loop_filter_luma_altivec(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) { - - register vec_u8 line0, line1, line2, line3, line4, line5; - if ((tc0[0] & tc0[1] & tc0[2] & tc0[3]) < 0) - return; - readAndTranspose16x6(pix-3, stride, line0, line1, line2, line3, line4, line5); - h264_loop_filter_luma_altivec(line0, line1, line2, line3, line4, line5, alpha, beta, tc0); - transpose4x16(line1, line2, line3, line4); - write16x4(pix-2, stride, line1, line2, line3, line4); -} - -static av_always_inline -void weight_h264_W_altivec(uint8_t *block, int stride, int height, - int log2_denom, int weight, int offset, int w) -{ - int y, aligned; - vec_u8 vblock; - vec_s16 vtemp, vweight, voffset, v0, v1; - vec_u16 vlog2_denom; - DECLARE_ALIGNED(16, int32_t, temp)[4]; - LOAD_ZERO; - - offset <<= log2_denom; - if(log2_denom) offset += 1<<(log2_denom-1); - temp[0] = log2_denom; - temp[1] = weight; - temp[2] = offset; - - vtemp = (vec_s16)vec_ld(0, temp); - vlog2_denom = (vec_u16)vec_splat(vtemp, 1); - vweight = vec_splat(vtemp, 3); - voffset = vec_splat(vtemp, 5); - aligned = !((unsigned long)block & 0xf); - - for (y = 0; y < height; y++) { - vblock = vec_ld(0, block); - - v0 = (vec_s16)vec_mergeh(zero_u8v, vblock); - v1 = (vec_s16)vec_mergel(zero_u8v, vblock); - - if (w == 16 || aligned) { - v0 = vec_mladd(v0, vweight, zero_s16v); - v0 = vec_adds(v0, voffset); - v0 = vec_sra(v0, vlog2_denom); - } - if (w == 16 || !aligned) { - v1 = vec_mladd(v1, vweight, zero_s16v); - v1 = vec_adds(v1, voffset); - v1 = vec_sra(v1, vlog2_denom); - } - vblock = vec_packsu(v0, v1); - vec_st(vblock, 0, block); - - block += stride; - } -} - -static av_always_inline -void biweight_h264_W_altivec(uint8_t *dst, uint8_t *src, int stride, int height, - int log2_denom, int weightd, int weights, int offset, int w) -{ - int y, dst_aligned, src_aligned; - vec_u8 vsrc, vdst; - vec_s16 vtemp, vweights, vweightd, voffset, v0, v1, v2, v3; - vec_u16 vlog2_denom; - DECLARE_ALIGNED(16, int32_t, temp)[4]; - LOAD_ZERO; - - offset = ((offset + 1) | 1) << log2_denom; - temp[0] = log2_denom+1; - temp[1] = weights; - temp[2] = weightd; - temp[3] = offset; - - vtemp = (vec_s16)vec_ld(0, temp); - vlog2_denom = (vec_u16)vec_splat(vtemp, 1); - vweights = vec_splat(vtemp, 3); - vweightd = vec_splat(vtemp, 5); - voffset = vec_splat(vtemp, 7); - dst_aligned = !((unsigned long)dst & 0xf); - src_aligned = !((unsigned long)src & 0xf); - - for (y = 0; y < height; y++) { - vdst = vec_ld(0, dst); - vsrc = vec_ld(0, src); - - v0 = (vec_s16)vec_mergeh(zero_u8v, vdst); - v1 = (vec_s16)vec_mergel(zero_u8v, vdst); - v2 = (vec_s16)vec_mergeh(zero_u8v, vsrc); - v3 = (vec_s16)vec_mergel(zero_u8v, vsrc); - - if (w == 8) { - if (src_aligned) - v3 = v2; - else - v2 = v3; - } - - if (w == 16 || dst_aligned) { - v0 = vec_mladd(v0, vweightd, zero_s16v); - v2 = vec_mladd(v2, vweights, zero_s16v); - - v0 = vec_adds(v0, voffset); - v0 = vec_adds(v0, v2); - v0 = vec_sra(v0, vlog2_denom); - } - if (w == 16 || !dst_aligned) { - v1 = vec_mladd(v1, vweightd, zero_s16v); - v3 = vec_mladd(v3, vweights, zero_s16v); - - v1 = vec_adds(v1, voffset); - v1 = vec_adds(v1, v3); - v1 = vec_sra(v1, vlog2_denom); - } - vdst = vec_packsu(v0, v1); - vec_st(vdst, 0, dst); - - dst += stride; - src += stride; - } -} - -#define H264_WEIGHT(W) \ -static void ff_weight_h264_pixels ## W ## _altivec(uint8_t *block, int stride, int height, \ - int log2_denom, int weight, int offset){ \ - weight_h264_W_altivec(block, stride, height, log2_denom, weight, offset, W); \ -}\ -static void ff_biweight_h264_pixels ## W ## _altivec(uint8_t *dst, uint8_t *src, int stride, int height, \ - int log2_denom, int weightd, int weights, int offset){ \ - biweight_h264_W_altivec(dst, src, stride, height, log2_denom, weightd, weights, offset, W); \ -} - -H264_WEIGHT(16) -H264_WEIGHT( 8) - -av_cold void ff_h264dsp_init_ppc(H264DSPContext *c, const int bit_depth, - const int chroma_format_idc) -{ - if (av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) { - if (bit_depth == 8) { - c->h264_idct_add = ff_h264_idct_add_altivec; - if (chroma_format_idc == 1) - c->h264_idct_add8 = ff_h264_idct_add8_altivec; - c->h264_idct_add16 = ff_h264_idct_add16_altivec; - c->h264_idct_add16intra = ff_h264_idct_add16intra_altivec; - c->h264_idct_dc_add= h264_idct_dc_add_altivec; - c->h264_idct8_dc_add = ff_h264_idct8_dc_add_altivec; - c->h264_idct8_add = ff_h264_idct8_add_altivec; - c->h264_idct8_add4 = ff_h264_idct8_add4_altivec; - c->h264_v_loop_filter_luma= h264_v_loop_filter_luma_altivec; - c->h264_h_loop_filter_luma= h264_h_loop_filter_luma_altivec; - - c->weight_h264_pixels_tab[0] = ff_weight_h264_pixels16_altivec; - c->weight_h264_pixels_tab[1] = ff_weight_h264_pixels8_altivec; - c->biweight_h264_pixels_tab[0] = ff_biweight_h264_pixels16_altivec; - c->biweight_h264_pixels_tab[1] = ff_biweight_h264_pixels8_altivec; - } - } -} diff --git a/ffmpeg/libavcodec/ppc/h264_qpel.c b/ffmpeg/libavcodec/ppc/h264_qpel.c deleted file mode 100644 index 429ae42..0000000 --- a/ffmpeg/libavcodec/ppc/h264_qpel.c +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Copyright (c) 2004 Romain Dolbeau - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" -#include "libavutil/attributes.h" -#include "libavcodec/h264qpel.h" - -#if HAVE_ALTIVEC -#include "libavutil/cpu.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/ppc/types_altivec.h" -#include "libavutil/ppc/util_altivec.h" -#include "dsputil_altivec.h" - -#define PUT_OP_U8_ALTIVEC(d, s, dst) d = s -#define AVG_OP_U8_ALTIVEC(d, s, dst) d = vec_avg(dst, s) - -#define OP_U8_ALTIVEC PUT_OP_U8_ALTIVEC -#define PREFIX_h264_qpel16_h_lowpass_altivec put_h264_qpel16_h_lowpass_altivec -#define PREFIX_h264_qpel16_h_lowpass_num altivec_put_h264_qpel16_h_lowpass_num -#define PREFIX_h264_qpel16_v_lowpass_altivec put_h264_qpel16_v_lowpass_altivec -#define PREFIX_h264_qpel16_v_lowpass_num altivec_put_h264_qpel16_v_lowpass_num -#define PREFIX_h264_qpel16_hv_lowpass_altivec put_h264_qpel16_hv_lowpass_altivec -#define PREFIX_h264_qpel16_hv_lowpass_num altivec_put_h264_qpel16_hv_lowpass_num -#include "h264_qpel_template.c" -#undef OP_U8_ALTIVEC -#undef PREFIX_h264_qpel16_h_lowpass_altivec -#undef PREFIX_h264_qpel16_h_lowpass_num -#undef PREFIX_h264_qpel16_v_lowpass_altivec -#undef PREFIX_h264_qpel16_v_lowpass_num -#undef PREFIX_h264_qpel16_hv_lowpass_altivec -#undef PREFIX_h264_qpel16_hv_lowpass_num - -#define OP_U8_ALTIVEC AVG_OP_U8_ALTIVEC -#define PREFIX_h264_qpel16_h_lowpass_altivec avg_h264_qpel16_h_lowpass_altivec -#define PREFIX_h264_qpel16_h_lowpass_num altivec_avg_h264_qpel16_h_lowpass_num -#define PREFIX_h264_qpel16_v_lowpass_altivec avg_h264_qpel16_v_lowpass_altivec -#define PREFIX_h264_qpel16_v_lowpass_num altivec_avg_h264_qpel16_v_lowpass_num -#define PREFIX_h264_qpel16_hv_lowpass_altivec avg_h264_qpel16_hv_lowpass_altivec -#define PREFIX_h264_qpel16_hv_lowpass_num altivec_avg_h264_qpel16_hv_lowpass_num -#include "h264_qpel_template.c" -#undef OP_U8_ALTIVEC -#undef PREFIX_h264_qpel16_h_lowpass_altivec -#undef PREFIX_h264_qpel16_h_lowpass_num -#undef PREFIX_h264_qpel16_v_lowpass_altivec -#undef PREFIX_h264_qpel16_v_lowpass_num -#undef PREFIX_h264_qpel16_hv_lowpass_altivec -#undef PREFIX_h264_qpel16_hv_lowpass_num - -#define H264_MC(OPNAME, SIZE, CODETYPE) \ -static void OPNAME ## h264_qpel ## SIZE ## _mc00_ ## CODETYPE (uint8_t *dst, uint8_t *src, ptrdiff_t stride)\ -{\ - ff_ ## OPNAME ## pixels ## SIZE ## _ ## CODETYPE(dst, src, stride, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc10_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\ -{ \ - DECLARE_ALIGNED(16, uint8_t, half)[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(half, src, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src, half, stride, stride, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc20_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\ -{\ - OPNAME ## h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(dst, src, stride, stride);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc30_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\ -{\ - DECLARE_ALIGNED(16, uint8_t, half)[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(half, src, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src+1, half, stride, stride, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc01_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\ -{\ - DECLARE_ALIGNED(16, uint8_t, half)[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(half, src, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src, half, stride, stride, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc02_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\ -{\ - OPNAME ## h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(dst, src, stride, stride);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc03_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\ -{\ - DECLARE_ALIGNED(16, uint8_t, half)[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(half, src, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src+stride, half, stride, stride, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc11_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\ -{\ - DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\ - DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src, SIZE, stride);\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc31_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\ -{\ - DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\ - DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src, SIZE, stride);\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src+1, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc13_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\ -{\ - DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\ - DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src + stride, SIZE, stride);\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc33_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\ -{\ - DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\ - DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src + stride, SIZE, stride);\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src+1, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc22_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\ -{\ - DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\ - OPNAME ## h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(dst, tmp, src, stride, SIZE, stride);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc21_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\ -{\ - DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\ - DECLARE_ALIGNED(16, uint8_t, halfHV)[SIZE*SIZE];\ - DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\ - put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src, SIZE, stride);\ - put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfHV, stride, SIZE, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc23_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\ -{\ - DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\ - DECLARE_ALIGNED(16, uint8_t, halfHV)[SIZE*SIZE];\ - DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\ - put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src + stride, SIZE, stride);\ - put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfHV, stride, SIZE, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc12_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\ -{\ - DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\ - DECLARE_ALIGNED(16, uint8_t, halfHV)[SIZE*SIZE];\ - DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src, SIZE, stride);\ - put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfV, halfHV, stride, SIZE, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc32_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\ -{\ - DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\ - DECLARE_ALIGNED(16, uint8_t, halfHV)[SIZE*SIZE];\ - DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src+1, SIZE, stride);\ - put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfV, halfHV, stride, SIZE, SIZE);\ -}\ - -static inline void put_pixels16_l2_altivec( uint8_t * dst, const uint8_t * src1, - const uint8_t * src2, int dst_stride, - int src_stride1, int h) -{ - int i; - vec_u8 a, b, d, tmp1, tmp2, mask, mask_, edges, align; - - mask_ = vec_lvsl(0, src2); - - for (i = 0; i < h; i++) { - - tmp1 = vec_ld(i * src_stride1, src1); - mask = vec_lvsl(i * src_stride1, src1); - tmp2 = vec_ld(i * src_stride1 + 15, src1); - - a = vec_perm(tmp1, tmp2, mask); - - tmp1 = vec_ld(i * 16, src2); - tmp2 = vec_ld(i * 16 + 15, src2); - - b = vec_perm(tmp1, tmp2, mask_); - - tmp1 = vec_ld(0, dst); - mask = vec_lvsl(0, dst); - tmp2 = vec_ld(15, dst); - - d = vec_avg(a, b); - - edges = vec_perm(tmp2, tmp1, mask); - - align = vec_lvsr(0, dst); - - tmp2 = vec_perm(d, edges, align); - tmp1 = vec_perm(edges, d, align); - - vec_st(tmp2, 15, dst); - vec_st(tmp1, 0 , dst); - - dst += dst_stride; - } -} - -static inline void avg_pixels16_l2_altivec( uint8_t * dst, const uint8_t * src1, - const uint8_t * src2, int dst_stride, - int src_stride1, int h) -{ - int i; - vec_u8 a, b, d, tmp1, tmp2, mask, mask_, edges, align; - - mask_ = vec_lvsl(0, src2); - - for (i = 0; i < h; i++) { - - tmp1 = vec_ld(i * src_stride1, src1); - mask = vec_lvsl(i * src_stride1, src1); - tmp2 = vec_ld(i * src_stride1 + 15, src1); - - a = vec_perm(tmp1, tmp2, mask); - - tmp1 = vec_ld(i * 16, src2); - tmp2 = vec_ld(i * 16 + 15, src2); - - b = vec_perm(tmp1, tmp2, mask_); - - tmp1 = vec_ld(0, dst); - mask = vec_lvsl(0, dst); - tmp2 = vec_ld(15, dst); - - d = vec_avg(vec_perm(tmp1, tmp2, mask), vec_avg(a, b)); - - edges = vec_perm(tmp2, tmp1, mask); - - align = vec_lvsr(0, dst); - - tmp2 = vec_perm(d, edges, align); - tmp1 = vec_perm(edges, d, align); - - vec_st(tmp2, 15, dst); - vec_st(tmp1, 0 , dst); - - dst += dst_stride; - } -} - -/* Implemented but could be faster -#define put_pixels16_l2_altivec(d,s1,s2,ds,s1s,h) put_pixels16_l2(d,s1,s2,ds,s1s,16,h) -#define avg_pixels16_l2_altivec(d,s1,s2,ds,s1s,h) avg_pixels16_l2(d,s1,s2,ds,s1s,16,h) - */ - -H264_MC(put_, 16, altivec) -H264_MC(avg_, 16, altivec) -#endif /* HAVE_ALTIVEC */ - -av_cold void ff_h264qpel_init_ppc(H264QpelContext *c, int bit_depth) -{ -#if HAVE_ALTIVEC - const int high_bit_depth = bit_depth > 8; - - if (av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) { - if (!high_bit_depth) { -#define dspfunc(PFX, IDX, NUM) \ - c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_altivec; \ - c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_altivec; \ - c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_altivec; \ - c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_altivec; \ - c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_altivec; \ - c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_altivec; \ - c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_altivec; \ - c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_altivec; \ - c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_altivec; \ - c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_altivec; \ - c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_altivec; \ - c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_altivec; \ - c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_altivec; \ - c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_altivec; \ - c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_altivec; \ - c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_altivec - - dspfunc(put_h264_qpel, 0, 16); - dspfunc(avg_h264_qpel, 0, 16); -#undef dspfunc - } - } -#endif /* HAVE_ALTIVEC */ -} diff --git a/ffmpeg/libavcodec/ppc/h264_qpel_template.c b/ffmpeg/libavcodec/ppc/h264_qpel_template.c deleted file mode 100644 index cfc4560..0000000 --- a/ffmpeg/libavcodec/ppc/h264_qpel_template.c +++ /dev/null @@ -1,507 +0,0 @@ -/* - * Copyright (c) 2004 Romain Dolbeau - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/mem.h" - -#ifdef DEBUG -#define ASSERT_ALIGNED(ptr) assert(((unsigned long)ptr&0x0000000F)); -#else -#define ASSERT_ALIGNED(ptr) ; -#endif - -/* this code assume stride % 16 == 0 */ -#ifdef PREFIX_h264_qpel16_h_lowpass_altivec -static void PREFIX_h264_qpel16_h_lowpass_altivec(uint8_t * dst, uint8_t * src, int dstStride, int srcStride) { - register int i; - - LOAD_ZERO; - const vec_u8 permM2 = vec_lvsl(-2, src); - const vec_u8 permM1 = vec_lvsl(-1, src); - const vec_u8 permP0 = vec_lvsl(+0, src); - const vec_u8 permP1 = vec_lvsl(+1, src); - const vec_u8 permP2 = vec_lvsl(+2, src); - const vec_u8 permP3 = vec_lvsl(+3, src); - const vec_s16 v5ss = vec_splat_s16(5); - const vec_u16 v5us = vec_splat_u16(5); - const vec_s16 v20ss = vec_sl(vec_splat_s16(5),vec_splat_u16(2)); - const vec_s16 v16ss = vec_sl(vec_splat_s16(1),vec_splat_u16(4)); - - vec_u8 srcM2, srcM1, srcP0, srcP1, srcP2, srcP3; - - register int align = ((((unsigned long)src) - 2) % 16); - - vec_s16 srcP0A, srcP0B, srcP1A, srcP1B, - srcP2A, srcP2B, srcP3A, srcP3B, - srcM1A, srcM1B, srcM2A, srcM2B, - sum1A, sum1B, sum2A, sum2B, sum3A, sum3B, - pp1A, pp1B, pp2A, pp2B, pp3A, pp3B, - psumA, psumB, sumA, sumB; - - vec_u8 sum, fsum; - - for (i = 0 ; i < 16 ; i ++) { - vec_u8 srcR1 = vec_ld(-2, src); - vec_u8 srcR2 = vec_ld(14, src); - - switch (align) { - default: { - srcM2 = vec_perm(srcR1, srcR2, permM2); - srcM1 = vec_perm(srcR1, srcR2, permM1); - srcP0 = vec_perm(srcR1, srcR2, permP0); - srcP1 = vec_perm(srcR1, srcR2, permP1); - srcP2 = vec_perm(srcR1, srcR2, permP2); - srcP3 = vec_perm(srcR1, srcR2, permP3); - } break; - case 11: { - srcM2 = vec_perm(srcR1, srcR2, permM2); - srcM1 = vec_perm(srcR1, srcR2, permM1); - srcP0 = vec_perm(srcR1, srcR2, permP0); - srcP1 = vec_perm(srcR1, srcR2, permP1); - srcP2 = vec_perm(srcR1, srcR2, permP2); - srcP3 = srcR2; - } break; - case 12: { - vec_u8 srcR3 = vec_ld(30, src); - srcM2 = vec_perm(srcR1, srcR2, permM2); - srcM1 = vec_perm(srcR1, srcR2, permM1); - srcP0 = vec_perm(srcR1, srcR2, permP0); - srcP1 = vec_perm(srcR1, srcR2, permP1); - srcP2 = srcR2; - srcP3 = vec_perm(srcR2, srcR3, permP3); - } break; - case 13: { - vec_u8 srcR3 = vec_ld(30, src); - srcM2 = vec_perm(srcR1, srcR2, permM2); - srcM1 = vec_perm(srcR1, srcR2, permM1); - srcP0 = vec_perm(srcR1, srcR2, permP0); - srcP1 = srcR2; - srcP2 = vec_perm(srcR2, srcR3, permP2); - srcP3 = vec_perm(srcR2, srcR3, permP3); - } break; - case 14: { - vec_u8 srcR3 = vec_ld(30, src); - srcM2 = vec_perm(srcR1, srcR2, permM2); - srcM1 = vec_perm(srcR1, srcR2, permM1); - srcP0 = srcR2; - srcP1 = vec_perm(srcR2, srcR3, permP1); - srcP2 = vec_perm(srcR2, srcR3, permP2); - srcP3 = vec_perm(srcR2, srcR3, permP3); - } break; - case 15: { - vec_u8 srcR3 = vec_ld(30, src); - srcM2 = vec_perm(srcR1, srcR2, permM2); - srcM1 = srcR2; - srcP0 = vec_perm(srcR2, srcR3, permP0); - srcP1 = vec_perm(srcR2, srcR3, permP1); - srcP2 = vec_perm(srcR2, srcR3, permP2); - srcP3 = vec_perm(srcR2, srcR3, permP3); - } break; - } - - srcP0A = (vec_s16) vec_mergeh(zero_u8v, srcP0); - srcP0B = (vec_s16) vec_mergel(zero_u8v, srcP0); - srcP1A = (vec_s16) vec_mergeh(zero_u8v, srcP1); - srcP1B = (vec_s16) vec_mergel(zero_u8v, srcP1); - - srcP2A = (vec_s16) vec_mergeh(zero_u8v, srcP2); - srcP2B = (vec_s16) vec_mergel(zero_u8v, srcP2); - srcP3A = (vec_s16) vec_mergeh(zero_u8v, srcP3); - srcP3B = (vec_s16) vec_mergel(zero_u8v, srcP3); - - srcM1A = (vec_s16) vec_mergeh(zero_u8v, srcM1); - srcM1B = (vec_s16) vec_mergel(zero_u8v, srcM1); - srcM2A = (vec_s16) vec_mergeh(zero_u8v, srcM2); - srcM2B = (vec_s16) vec_mergel(zero_u8v, srcM2); - - sum1A = vec_adds(srcP0A, srcP1A); - sum1B = vec_adds(srcP0B, srcP1B); - sum2A = vec_adds(srcM1A, srcP2A); - sum2B = vec_adds(srcM1B, srcP2B); - sum3A = vec_adds(srcM2A, srcP3A); - sum3B = vec_adds(srcM2B, srcP3B); - - pp1A = vec_mladd(sum1A, v20ss, v16ss); - pp1B = vec_mladd(sum1B, v20ss, v16ss); - - pp2A = vec_mladd(sum2A, v5ss, zero_s16v); - pp2B = vec_mladd(sum2B, v5ss, zero_s16v); - - pp3A = vec_add(sum3A, pp1A); - pp3B = vec_add(sum3B, pp1B); - - psumA = vec_sub(pp3A, pp2A); - psumB = vec_sub(pp3B, pp2B); - - sumA = vec_sra(psumA, v5us); - sumB = vec_sra(psumB, v5us); - - sum = vec_packsu(sumA, sumB); - - ASSERT_ALIGNED(dst); - - OP_U8_ALTIVEC(fsum, sum, vec_ld(0, dst)); - - vec_st(fsum, 0, dst); - - src += srcStride; - dst += dstStride; - } -} -#endif - -/* this code assume stride % 16 == 0 */ -#ifdef PREFIX_h264_qpel16_v_lowpass_altivec -static void PREFIX_h264_qpel16_v_lowpass_altivec(uint8_t * dst, uint8_t * src, int dstStride, int srcStride) { - register int i; - - LOAD_ZERO; - const vec_u8 perm = vec_lvsl(0, src); - const vec_s16 v20ss = vec_sl(vec_splat_s16(5),vec_splat_u16(2)); - const vec_u16 v5us = vec_splat_u16(5); - const vec_s16 v5ss = vec_splat_s16(5); - const vec_s16 v16ss = vec_sl(vec_splat_s16(1),vec_splat_u16(4)); - - uint8_t *srcbis = src - (srcStride * 2); - - const vec_u8 srcM2a = vec_ld(0, srcbis); - const vec_u8 srcM2b = vec_ld(16, srcbis); - const vec_u8 srcM2 = vec_perm(srcM2a, srcM2b, perm); - //srcbis += srcStride; - const vec_u8 srcM1a = vec_ld(0, srcbis += srcStride); - const vec_u8 srcM1b = vec_ld(16, srcbis); - const vec_u8 srcM1 = vec_perm(srcM1a, srcM1b, perm); - //srcbis += srcStride; - const vec_u8 srcP0a = vec_ld(0, srcbis += srcStride); - const vec_u8 srcP0b = vec_ld(16, srcbis); - const vec_u8 srcP0 = vec_perm(srcP0a, srcP0b, perm); - //srcbis += srcStride; - const vec_u8 srcP1a = vec_ld(0, srcbis += srcStride); - const vec_u8 srcP1b = vec_ld(16, srcbis); - const vec_u8 srcP1 = vec_perm(srcP1a, srcP1b, perm); - //srcbis += srcStride; - const vec_u8 srcP2a = vec_ld(0, srcbis += srcStride); - const vec_u8 srcP2b = vec_ld(16, srcbis); - const vec_u8 srcP2 = vec_perm(srcP2a, srcP2b, perm); - //srcbis += srcStride; - - vec_s16 srcM2ssA = (vec_s16) vec_mergeh(zero_u8v, srcM2); - vec_s16 srcM2ssB = (vec_s16) vec_mergel(zero_u8v, srcM2); - vec_s16 srcM1ssA = (vec_s16) vec_mergeh(zero_u8v, srcM1); - vec_s16 srcM1ssB = (vec_s16) vec_mergel(zero_u8v, srcM1); - vec_s16 srcP0ssA = (vec_s16) vec_mergeh(zero_u8v, srcP0); - vec_s16 srcP0ssB = (vec_s16) vec_mergel(zero_u8v, srcP0); - vec_s16 srcP1ssA = (vec_s16) vec_mergeh(zero_u8v, srcP1); - vec_s16 srcP1ssB = (vec_s16) vec_mergel(zero_u8v, srcP1); - vec_s16 srcP2ssA = (vec_s16) vec_mergeh(zero_u8v, srcP2); - vec_s16 srcP2ssB = (vec_s16) vec_mergel(zero_u8v, srcP2); - - vec_s16 pp1A, pp1B, pp2A, pp2B, pp3A, pp3B, - psumA, psumB, sumA, sumB, - srcP3ssA, srcP3ssB, - sum1A, sum1B, sum2A, sum2B, sum3A, sum3B; - - vec_u8 sum, fsum, srcP3a, srcP3b, srcP3; - - for (i = 0 ; i < 16 ; i++) { - srcP3a = vec_ld(0, srcbis += srcStride); - srcP3b = vec_ld(16, srcbis); - srcP3 = vec_perm(srcP3a, srcP3b, perm); - srcP3ssA = (vec_s16) vec_mergeh(zero_u8v, srcP3); - srcP3ssB = (vec_s16) vec_mergel(zero_u8v, srcP3); - //srcbis += srcStride; - - sum1A = vec_adds(srcP0ssA, srcP1ssA); - sum1B = vec_adds(srcP0ssB, srcP1ssB); - sum2A = vec_adds(srcM1ssA, srcP2ssA); - sum2B = vec_adds(srcM1ssB, srcP2ssB); - sum3A = vec_adds(srcM2ssA, srcP3ssA); - sum3B = vec_adds(srcM2ssB, srcP3ssB); - - srcM2ssA = srcM1ssA; - srcM2ssB = srcM1ssB; - srcM1ssA = srcP0ssA; - srcM1ssB = srcP0ssB; - srcP0ssA = srcP1ssA; - srcP0ssB = srcP1ssB; - srcP1ssA = srcP2ssA; - srcP1ssB = srcP2ssB; - srcP2ssA = srcP3ssA; - srcP2ssB = srcP3ssB; - - pp1A = vec_mladd(sum1A, v20ss, v16ss); - pp1B = vec_mladd(sum1B, v20ss, v16ss); - - pp2A = vec_mladd(sum2A, v5ss, zero_s16v); - pp2B = vec_mladd(sum2B, v5ss, zero_s16v); - - pp3A = vec_add(sum3A, pp1A); - pp3B = vec_add(sum3B, pp1B); - - psumA = vec_sub(pp3A, pp2A); - psumB = vec_sub(pp3B, pp2B); - - sumA = vec_sra(psumA, v5us); - sumB = vec_sra(psumB, v5us); - - sum = vec_packsu(sumA, sumB); - - ASSERT_ALIGNED(dst); - - OP_U8_ALTIVEC(fsum, sum, vec_ld(0, dst)); - - vec_st(fsum, 0, dst); - - dst += dstStride; - } -} -#endif - -/* this code assume stride % 16 == 0 *and* tmp is properly aligned */ -#ifdef PREFIX_h264_qpel16_hv_lowpass_altivec -static void PREFIX_h264_qpel16_hv_lowpass_altivec(uint8_t * dst, int16_t * tmp, uint8_t * src, int dstStride, int tmpStride, int srcStride) { - register int i; - LOAD_ZERO; - const vec_u8 permM2 = vec_lvsl(-2, src); - const vec_u8 permM1 = vec_lvsl(-1, src); - const vec_u8 permP0 = vec_lvsl(+0, src); - const vec_u8 permP1 = vec_lvsl(+1, src); - const vec_u8 permP2 = vec_lvsl(+2, src); - const vec_u8 permP3 = vec_lvsl(+3, src); - const vec_s16 v20ss = vec_sl(vec_splat_s16(5),vec_splat_u16(2)); - const vec_u32 v10ui = vec_splat_u32(10); - const vec_s16 v5ss = vec_splat_s16(5); - const vec_s16 v1ss = vec_splat_s16(1); - const vec_s32 v512si = vec_sl(vec_splat_s32(1),vec_splat_u32(9)); - const vec_u32 v16ui = vec_sl(vec_splat_u32(1),vec_splat_u32(4)); - - register int align = ((((unsigned long)src) - 2) % 16); - - vec_s16 srcP0A, srcP0B, srcP1A, srcP1B, - srcP2A, srcP2B, srcP3A, srcP3B, - srcM1A, srcM1B, srcM2A, srcM2B, - sum1A, sum1B, sum2A, sum2B, sum3A, sum3B, - pp1A, pp1B, pp2A, pp2B, psumA, psumB; - - const vec_u8 mperm = (const vec_u8) - {0x00, 0x08, 0x01, 0x09, 0x02, 0x0A, 0x03, 0x0B, - 0x04, 0x0C, 0x05, 0x0D, 0x06, 0x0E, 0x07, 0x0F}; - int16_t *tmpbis = tmp; - - vec_s16 tmpM1ssA, tmpM1ssB, tmpM2ssA, tmpM2ssB, - tmpP0ssA, tmpP0ssB, tmpP1ssA, tmpP1ssB, - tmpP2ssA, tmpP2ssB; - - vec_s32 pp1Ae, pp1Ao, pp1Be, pp1Bo, pp2Ae, pp2Ao, pp2Be, pp2Bo, - pp3Ae, pp3Ao, pp3Be, pp3Bo, pp1cAe, pp1cAo, pp1cBe, pp1cBo, - pp32Ae, pp32Ao, pp32Be, pp32Bo, sumAe, sumAo, sumBe, sumBo, - ssumAe, ssumAo, ssumBe, ssumBo; - vec_u8 fsum, sumv, sum; - vec_s16 ssume, ssumo; - - src -= (2 * srcStride); - for (i = 0 ; i < 21 ; i ++) { - vec_u8 srcM2, srcM1, srcP0, srcP1, srcP2, srcP3; - vec_u8 srcR1 = vec_ld(-2, src); - vec_u8 srcR2 = vec_ld(14, src); - - switch (align) { - default: { - srcM2 = vec_perm(srcR1, srcR2, permM2); - srcM1 = vec_perm(srcR1, srcR2, permM1); - srcP0 = vec_perm(srcR1, srcR2, permP0); - srcP1 = vec_perm(srcR1, srcR2, permP1); - srcP2 = vec_perm(srcR1, srcR2, permP2); - srcP3 = vec_perm(srcR1, srcR2, permP3); - } break; - case 11: { - srcM2 = vec_perm(srcR1, srcR2, permM2); - srcM1 = vec_perm(srcR1, srcR2, permM1); - srcP0 = vec_perm(srcR1, srcR2, permP0); - srcP1 = vec_perm(srcR1, srcR2, permP1); - srcP2 = vec_perm(srcR1, srcR2, permP2); - srcP3 = srcR2; - } break; - case 12: { - vec_u8 srcR3 = vec_ld(30, src); - srcM2 = vec_perm(srcR1, srcR2, permM2); - srcM1 = vec_perm(srcR1, srcR2, permM1); - srcP0 = vec_perm(srcR1, srcR2, permP0); - srcP1 = vec_perm(srcR1, srcR2, permP1); - srcP2 = srcR2; - srcP3 = vec_perm(srcR2, srcR3, permP3); - } break; - case 13: { - vec_u8 srcR3 = vec_ld(30, src); - srcM2 = vec_perm(srcR1, srcR2, permM2); - srcM1 = vec_perm(srcR1, srcR2, permM1); - srcP0 = vec_perm(srcR1, srcR2, permP0); - srcP1 = srcR2; - srcP2 = vec_perm(srcR2, srcR3, permP2); - srcP3 = vec_perm(srcR2, srcR3, permP3); - } break; - case 14: { - vec_u8 srcR3 = vec_ld(30, src); - srcM2 = vec_perm(srcR1, srcR2, permM2); - srcM1 = vec_perm(srcR1, srcR2, permM1); - srcP0 = srcR2; - srcP1 = vec_perm(srcR2, srcR3, permP1); - srcP2 = vec_perm(srcR2, srcR3, permP2); - srcP3 = vec_perm(srcR2, srcR3, permP3); - } break; - case 15: { - vec_u8 srcR3 = vec_ld(30, src); - srcM2 = vec_perm(srcR1, srcR2, permM2); - srcM1 = srcR2; - srcP0 = vec_perm(srcR2, srcR3, permP0); - srcP1 = vec_perm(srcR2, srcR3, permP1); - srcP2 = vec_perm(srcR2, srcR3, permP2); - srcP3 = vec_perm(srcR2, srcR3, permP3); - } break; - } - - srcP0A = (vec_s16) vec_mergeh(zero_u8v, srcP0); - srcP0B = (vec_s16) vec_mergel(zero_u8v, srcP0); - srcP1A = (vec_s16) vec_mergeh(zero_u8v, srcP1); - srcP1B = (vec_s16) vec_mergel(zero_u8v, srcP1); - - srcP2A = (vec_s16) vec_mergeh(zero_u8v, srcP2); - srcP2B = (vec_s16) vec_mergel(zero_u8v, srcP2); - srcP3A = (vec_s16) vec_mergeh(zero_u8v, srcP3); - srcP3B = (vec_s16) vec_mergel(zero_u8v, srcP3); - - srcM1A = (vec_s16) vec_mergeh(zero_u8v, srcM1); - srcM1B = (vec_s16) vec_mergel(zero_u8v, srcM1); - srcM2A = (vec_s16) vec_mergeh(zero_u8v, srcM2); - srcM2B = (vec_s16) vec_mergel(zero_u8v, srcM2); - - sum1A = vec_adds(srcP0A, srcP1A); - sum1B = vec_adds(srcP0B, srcP1B); - sum2A = vec_adds(srcM1A, srcP2A); - sum2B = vec_adds(srcM1B, srcP2B); - sum3A = vec_adds(srcM2A, srcP3A); - sum3B = vec_adds(srcM2B, srcP3B); - - pp1A = vec_mladd(sum1A, v20ss, sum3A); - pp1B = vec_mladd(sum1B, v20ss, sum3B); - - pp2A = vec_mladd(sum2A, v5ss, zero_s16v); - pp2B = vec_mladd(sum2B, v5ss, zero_s16v); - - psumA = vec_sub(pp1A, pp2A); - psumB = vec_sub(pp1B, pp2B); - - vec_st(psumA, 0, tmp); - vec_st(psumB, 16, tmp); - - src += srcStride; - tmp += tmpStride; /* int16_t*, and stride is 16, so it's OK here */ - } - - tmpM2ssA = vec_ld(0, tmpbis); - tmpM2ssB = vec_ld(16, tmpbis); - tmpbis += tmpStride; - tmpM1ssA = vec_ld(0, tmpbis); - tmpM1ssB = vec_ld(16, tmpbis); - tmpbis += tmpStride; - tmpP0ssA = vec_ld(0, tmpbis); - tmpP0ssB = vec_ld(16, tmpbis); - tmpbis += tmpStride; - tmpP1ssA = vec_ld(0, tmpbis); - tmpP1ssB = vec_ld(16, tmpbis); - tmpbis += tmpStride; - tmpP2ssA = vec_ld(0, tmpbis); - tmpP2ssB = vec_ld(16, tmpbis); - tmpbis += tmpStride; - - for (i = 0 ; i < 16 ; i++) { - const vec_s16 tmpP3ssA = vec_ld(0, tmpbis); - const vec_s16 tmpP3ssB = vec_ld(16, tmpbis); - - const vec_s16 sum1A = vec_adds(tmpP0ssA, tmpP1ssA); - const vec_s16 sum1B = vec_adds(tmpP0ssB, tmpP1ssB); - const vec_s16 sum2A = vec_adds(tmpM1ssA, tmpP2ssA); - const vec_s16 sum2B = vec_adds(tmpM1ssB, tmpP2ssB); - const vec_s16 sum3A = vec_adds(tmpM2ssA, tmpP3ssA); - const vec_s16 sum3B = vec_adds(tmpM2ssB, tmpP3ssB); - - tmpbis += tmpStride; - - tmpM2ssA = tmpM1ssA; - tmpM2ssB = tmpM1ssB; - tmpM1ssA = tmpP0ssA; - tmpM1ssB = tmpP0ssB; - tmpP0ssA = tmpP1ssA; - tmpP0ssB = tmpP1ssB; - tmpP1ssA = tmpP2ssA; - tmpP1ssB = tmpP2ssB; - tmpP2ssA = tmpP3ssA; - tmpP2ssB = tmpP3ssB; - - pp1Ae = vec_mule(sum1A, v20ss); - pp1Ao = vec_mulo(sum1A, v20ss); - pp1Be = vec_mule(sum1B, v20ss); - pp1Bo = vec_mulo(sum1B, v20ss); - - pp2Ae = vec_mule(sum2A, v5ss); - pp2Ao = vec_mulo(sum2A, v5ss); - pp2Be = vec_mule(sum2B, v5ss); - pp2Bo = vec_mulo(sum2B, v5ss); - - pp3Ae = vec_sra((vec_s32)sum3A, v16ui); - pp3Ao = vec_mulo(sum3A, v1ss); - pp3Be = vec_sra((vec_s32)sum3B, v16ui); - pp3Bo = vec_mulo(sum3B, v1ss); - - pp1cAe = vec_add(pp1Ae, v512si); - pp1cAo = vec_add(pp1Ao, v512si); - pp1cBe = vec_add(pp1Be, v512si); - pp1cBo = vec_add(pp1Bo, v512si); - - pp32Ae = vec_sub(pp3Ae, pp2Ae); - pp32Ao = vec_sub(pp3Ao, pp2Ao); - pp32Be = vec_sub(pp3Be, pp2Be); - pp32Bo = vec_sub(pp3Bo, pp2Bo); - - sumAe = vec_add(pp1cAe, pp32Ae); - sumAo = vec_add(pp1cAo, pp32Ao); - sumBe = vec_add(pp1cBe, pp32Be); - sumBo = vec_add(pp1cBo, pp32Bo); - - ssumAe = vec_sra(sumAe, v10ui); - ssumAo = vec_sra(sumAo, v10ui); - ssumBe = vec_sra(sumBe, v10ui); - ssumBo = vec_sra(sumBo, v10ui); - - ssume = vec_packs(ssumAe, ssumBe); - ssumo = vec_packs(ssumAo, ssumBo); - - sumv = vec_packsu(ssume, ssumo); - sum = vec_perm(sumv, sumv, mperm); - - ASSERT_ALIGNED(dst); - - OP_U8_ALTIVEC(fsum, sum, vec_ld(0, dst)); - - vec_st(fsum, 0, dst); - - dst += dstStride; - } -} -#endif diff --git a/ffmpeg/libavcodec/ppc/h264chroma_init.c b/ffmpeg/libavcodec/ppc/h264chroma_init.c index f9e2a76..921f2de 100644 --- a/ffmpeg/libavcodec/ppc/h264chroma_init.c +++ b/ffmpeg/libavcodec/ppc/h264chroma_init.c @@ -20,15 +20,14 @@ #include "config.h" #include "libavutil/attributes.h" -#include "libavcodec/h264chroma.h" - -#if HAVE_ALTIVEC #include "libavutil/cpu.h" #include "libavutil/intreadwrite.h" #include "libavutil/ppc/types_altivec.h" #include "libavutil/ppc/util_altivec.h" +#include "libavcodec/h264chroma.h" #include "dsputil_altivec.h" +#if HAVE_ALTIVEC #define PUT_OP_U8_ALTIVEC(d, s, dst) d = s #define AVG_OP_U8_ALTIVEC(d, s, dst) d = vec_avg(dst, s) @@ -54,11 +53,12 @@ av_cold void ff_h264chroma_init_ppc(H264ChromaContext *c, int bit_depth) #if HAVE_ALTIVEC const int high_bit_depth = bit_depth > 8; - if (av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) { + if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC)) + return; + if (!high_bit_depth) { c->put_h264_chroma_pixels_tab[0] = put_h264_chroma_mc8_altivec; c->avg_h264_chroma_pixels_tab[0] = avg_h264_chroma_mc8_altivec; } - } #endif /* HAVE_ALTIVEC */ } diff --git a/ffmpeg/libavcodec/ppc/hpeldsp_altivec.c b/ffmpeg/libavcodec/ppc/hpeldsp_altivec.c index 4309d39..345ec39 100644 --- a/ffmpeg/libavcodec/ppc/hpeldsp_altivec.c +++ b/ffmpeg/libavcodec/ppc/hpeldsp_altivec.c @@ -21,17 +21,19 @@ */ #include "config.h" -#include "libavutil/cpu.h" -#include "libavcodec/hpeldsp.h" -#if HAVE_ALTIVEC #if HAVE_ALTIVEC_H #include #endif + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" #include "libavutil/ppc/types_altivec.h" #include "libavutil/ppc/util_altivec.h" +#include "libavcodec/hpeldsp.h" #include "dsputil_altivec.h" +#if HAVE_ALTIVEC /* next one assumes that ((line_size % 16) == 0) */ void ff_put_pixels16_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) { @@ -444,21 +446,22 @@ static void avg_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, ptrdi } #endif /* HAVE_ALTIVEC */ -void ff_hpeldsp_init_ppc(HpelDSPContext* c, int flags) +av_cold void ff_hpeldsp_init_ppc(HpelDSPContext *c, int flags) { #if HAVE_ALTIVEC - int mm_flags = av_get_cpu_flags(); - - if (mm_flags & AV_CPU_FLAG_ALTIVEC) { - c->put_pixels_tab[0][0] = ff_put_pixels16_altivec; - c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_altivec; - c->avg_pixels_tab[0][0] = ff_avg_pixels16_altivec; - c->avg_pixels_tab[1][0] = avg_pixels8_altivec; - c->avg_pixels_tab[1][3] = avg_pixels8_xy2_altivec; - c->put_pixels_tab[1][3] = put_pixels8_xy2_altivec; - c->put_no_rnd_pixels_tab[1][3] = put_no_rnd_pixels8_xy2_altivec; - c->put_pixels_tab[0][3] = put_pixels16_xy2_altivec; - c->put_no_rnd_pixels_tab[0][3] = put_no_rnd_pixels16_xy2_altivec; - } + if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC)) + return; + + c->avg_pixels_tab[0][0] = ff_avg_pixels16_altivec; + c->avg_pixels_tab[1][0] = avg_pixels8_altivec; + c->avg_pixels_tab[1][3] = avg_pixels8_xy2_altivec; + + c->put_pixels_tab[0][0] = ff_put_pixels16_altivec; + c->put_pixels_tab[1][3] = put_pixels8_xy2_altivec; + c->put_pixels_tab[0][3] = put_pixels16_xy2_altivec; + + c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_altivec; + c->put_no_rnd_pixels_tab[1][3] = put_no_rnd_pixels8_xy2_altivec; + c->put_no_rnd_pixels_tab[0][3] = put_no_rnd_pixels16_xy2_altivec; #endif /* HAVE_ALTIVEC */ } diff --git a/ffmpeg/libavcodec/ppc/int_altivec.c b/ffmpeg/libavcodec/ppc/int_altivec.c index 4386b13..d4e0c85 100644 --- a/ffmpeg/libavcodec/ppc/int_altivec.c +++ b/ffmpeg/libavcodec/ppc/int_altivec.c @@ -84,14 +84,12 @@ static int32_t scalarproduct_int16_altivec(const int16_t *v1, const int16_t *v2, { int i; LOAD_ZERO; - const vec_s16 *pv; register vec_s16 vec1; register vec_s32 res = vec_splat_s32(0), t; int32_t ires; for(i = 0; i < order; i += 8){ - pv = (const vec_s16*)v1; - vec1 = vec_perm(pv[0], pv[1], vec_lvsl(0, v1)); + vec1 = vec_unaligned_load(v1); t = vec_msum(vec1, vec_ld(0, v2), zero_s32v); res = vec_sums(t, res); v1 += 8; @@ -129,8 +127,8 @@ static int32_t scalarproduct_and_madd_int16_altivec(int16_t *v1, const int16_t * pv1[0] = vec_mladd(t0, muls, i0); pv1[1] = vec_mladd(t1, muls, i1); pv1 += 2; - v2 += 8; - v3 += 8; + v2 += 16; + v3 += 16; } while(--order); res = vec_splat(vec_sums(res, zero_s32v), 3); vec_ste(res, 0, &ires); diff --git a/ffmpeg/libavcodec/ppc/mpegaudiodec_altivec.c b/ffmpeg/libavcodec/ppc/mpegaudiodec_altivec.c deleted file mode 100644 index 1152fd7..0000000 --- a/ffmpeg/libavcodec/ppc/mpegaudiodec_altivec.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Altivec optimized MP3 decoding functions - * Copyright (c) 2010 Vitor Sessak - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "dsputil_altivec.h" -#include "libavutil/attributes.h" -#include "libavutil/internal.h" -#include "libavutil/ppc/util_altivec.h" -#include "libavcodec/mpegaudiodsp.h" - -#define MACS(rt, ra, rb) rt+=(ra)*(rb) -#define MLSS(rt, ra, rb) rt-=(ra)*(rb) - -#define SUM8(op, sum, w, p) \ -{ \ - op(sum, (w)[0 * 64], (p)[0 * 64]); \ - op(sum, (w)[1 * 64], (p)[1 * 64]); \ - op(sum, (w)[2 * 64], (p)[2 * 64]); \ - op(sum, (w)[3 * 64], (p)[3 * 64]); \ - op(sum, (w)[4 * 64], (p)[4 * 64]); \ - op(sum, (w)[5 * 64], (p)[5 * 64]); \ - op(sum, (w)[6 * 64], (p)[6 * 64]); \ - op(sum, (w)[7 * 64], (p)[7 * 64]); \ -} - -static void apply_window(const float *buf, const float *win1, - const float *win2, float *sum1, float *sum2, int len) -{ - const vector float *win1a = (const vector float *) win1; - const vector float *win2a = (const vector float *) win2; - const vector float *bufa = (const vector float *) buf; - vector float *sum1a = (vector float *) sum1; - vector float *sum2a = (vector float *) sum2; - vector float av_uninit(v0), av_uninit(v4); - vector float v1, v2, v3; - - len = len >> 2; - -#define MULT(a, b) \ - { \ - v1 = vec_ld(a, win1a); \ - v2 = vec_ld(b, win2a); \ - v3 = vec_ld(a, bufa); \ - v0 = vec_madd(v3, v1, v0); \ - v4 = vec_madd(v2, v3, v4); \ - } - - while (len--) { - v0 = vec_xor(v0, v0); - v4 = vec_xor(v4, v4); - - MULT( 0, 0); - MULT( 256, 64); - MULT( 512, 128); - MULT( 768, 192); - MULT(1024, 256); - MULT(1280, 320); - MULT(1536, 384); - MULT(1792, 448); - - vec_st(v0, 0, sum1a); - vec_st(v4, 0, sum2a); - sum1a++; - sum2a++; - win1a++; - win2a++; - bufa++; - } -} - -static void apply_window_mp3(float *in, float *win, int *unused, float *out, - int incr) -{ - LOCAL_ALIGNED_16(float, suma, [17]); - LOCAL_ALIGNED_16(float, sumb, [17]); - LOCAL_ALIGNED_16(float, sumc, [17]); - LOCAL_ALIGNED_16(float, sumd, [17]); - - float sum; - int j; - float *out2 = out + 32 * incr; - - /* copy to avoid wrap */ - memcpy(in + 512, in, 32 * sizeof(*in)); - - apply_window(in + 16, win , win + 512, suma, sumc, 16); - apply_window(in + 32, win + 48, win + 640, sumb, sumd, 16); - - SUM8(MLSS, suma[0], win + 32, in + 48); - - sumc[ 0] = 0; - sumb[16] = 0; - sumd[16] = 0; - - out[0 ] = suma[ 0]; - out += incr; - out2 -= incr; - for(j=1;j<16;j++) { - *out = suma[ j] - sumd[16-j]; - *out2 = -sumb[16-j] - sumc[ j]; - out += incr; - out2 -= incr; - } - - sum = 0; - SUM8(MLSS, sum, win + 16 + 32, in + 32); - *out = sum; -} - -av_cold void ff_mpadsp_init_altivec(MPADSPContext *s) -{ - s->apply_window_float = apply_window_mp3; -} diff --git a/ffmpeg/libavcodec/ppc/mpegvideo_altivec.c b/ffmpeg/libavcodec/ppc/mpegvideo_altivec.c index bf490b0..cedc1c8 100644 --- a/ffmpeg/libavcodec/ppc/mpegvideo_altivec.c +++ b/ffmpeg/libavcodec/ppc/mpegvideo_altivec.c @@ -24,14 +24,16 @@ #include #include +#include "config.h" #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/ppc/types_altivec.h" #include "libavutil/ppc/util_altivec.h" #include "libavcodec/mpegvideo.h" - #include "dsputil_altivec.h" +#if HAVE_ALTIVEC + /* AltiVec version of dct_unquantize_h263 this code assumes `block' is 16 bytes-aligned */ static void dct_unquantize_h263_altivec(MpegEncContext *s, @@ -111,14 +113,18 @@ static void dct_unquantize_h263_altivec(MpegEncContext *s, } } +#endif /* HAVE_ALTIVEC */ -av_cold void ff_MPV_common_init_altivec(MpegEncContext *s) +av_cold void ff_MPV_common_init_ppc(MpegEncContext *s) { - if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC)) return; +#if HAVE_ALTIVEC + if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC)) + return; if ((s->avctx->dct_algo == FF_DCT_AUTO) || - (s->avctx->dct_algo == FF_DCT_ALTIVEC)) { + (s->avctx->dct_algo == FF_DCT_ALTIVEC)) { s->dct_unquantize_h263_intra = dct_unquantize_h263_altivec; s->dct_unquantize_h263_inter = dct_unquantize_h263_altivec; } +#endif /* HAVE_ALTIVEC */ } diff --git a/ffmpeg/libavcodec/ppc/vc1dsp_altivec.c b/ffmpeg/libavcodec/ppc/vc1dsp_altivec.c index 9c2ad70..1b73dd0 100644 --- a/ffmpeg/libavcodec/ppc/vc1dsp_altivec.c +++ b/ffmpeg/libavcodec/ppc/vc1dsp_altivec.c @@ -19,11 +19,14 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "config.h" #include "libavutil/attributes.h" #include "libavutil/ppc/types_altivec.h" #include "libavutil/ppc/util_altivec.h" #include "libavcodec/vc1dsp.h" +#if HAVE_ALTIVEC + // main steps of 8x8 transform #define STEP8(s0, s1, s2, s3, s4, s5, s6, s7, vec_rnd) \ do { \ @@ -335,8 +338,11 @@ static void vc1_inv_trans_8x4_altivec(uint8_t *dest, int stride, int16_t *block) #undef OP_U8_ALTIVEC #undef PREFIX_no_rnd_vc1_chroma_mc8_altivec -av_cold void ff_vc1dsp_init_altivec(VC1DSPContext *dsp) +#endif /* HAVE_ALTIVEC */ + +av_cold void ff_vc1dsp_init_ppc(VC1DSPContext *dsp) { +#if HAVE_ALTIVEC if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC)) return; @@ -344,4 +350,5 @@ av_cold void ff_vc1dsp_init_altivec(VC1DSPContext *dsp) dsp->vc1_inv_trans_8x4 = vc1_inv_trans_8x4_altivec; dsp->put_no_rnd_vc1_chroma_pixels_tab[0] = put_no_rnd_vc1_chroma_mc8_altivec; dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = avg_no_rnd_vc1_chroma_mc8_altivec; +#endif /* HAVE_ALTIVEC */ } diff --git a/ffmpeg/libavcodec/ppc/vorbisdsp_altivec.c b/ffmpeg/libavcodec/ppc/vorbisdsp_altivec.c index 08a2b26..d243bf6 100644 --- a/ffmpeg/libavcodec/ppc/vorbisdsp_altivec.c +++ b/ffmpeg/libavcodec/ppc/vorbisdsp_altivec.c @@ -54,8 +54,9 @@ static void vorbis_inverse_coupling_altivec(float *mag, float *ang, av_cold void ff_vorbisdsp_init_ppc(VorbisDSPContext *c) { #if HAVE_ALTIVEC - if (av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) { - c->vorbis_inverse_coupling = vorbis_inverse_coupling_altivec; - } + if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC)) + return; + + c->vorbis_inverse_coupling = vorbis_inverse_coupling_altivec; #endif /* HAVE_ALTIVEC */ } diff --git a/ffmpeg/libavcodec/ppc/vp3dsp_altivec.c b/ffmpeg/libavcodec/ppc/vp3dsp_altivec.c index cc587b0..56c2d0b 100644 --- a/ffmpeg/libavcodec/ppc/vp3dsp_altivec.c +++ b/ffmpeg/libavcodec/ppc/vp3dsp_altivec.c @@ -23,14 +23,13 @@ #include "config.h" #include "libavutil/attributes.h" #include "libavutil/cpu.h" -#include "libavcodec/vp3dsp.h" - -#if HAVE_ALTIVEC - #include "libavutil/ppc/types_altivec.h" #include "libavutil/ppc/util_altivec.h" +#include "libavcodec/vp3dsp.h" #include "dsputil_altivec.h" +#if HAVE_ALTIVEC + static const vec_s16 constants = {0, 64277, 60547, 54491, 46341, 36410, 25080, 12785}; static const vec_u8 interleave_high = @@ -181,9 +180,10 @@ static void vp3_idct_add_altivec(uint8_t *dst, int stride, int16_t block[64]) av_cold void ff_vp3dsp_init_ppc(VP3DSPContext *c, int flags) { #if HAVE_ALTIVEC - if (av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) { - c->idct_put = vp3_idct_put_altivec; - c->idct_add = vp3_idct_add_altivec; - } + if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC)) + return; + + c->idct_put = vp3_idct_put_altivec; + c->idct_add = vp3_idct_add_altivec; #endif } diff --git a/ffmpeg/libavcodec/ppc/vp8dsp_altivec.c b/ffmpeg/libavcodec/ppc/vp8dsp_altivec.c index 14d8784..c858d8a 100644 --- a/ffmpeg/libavcodec/ppc/vp8dsp_altivec.c +++ b/ffmpeg/libavcodec/ppc/vp8dsp_altivec.c @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "config.h" #include "libavutil/cpu.h" #include "libavutil/mem.h" #include "libavutil/ppc/types_altivec.h" @@ -27,6 +28,7 @@ #include "libavcodec/vp8dsp.h" #include "dsputil_altivec.h" +#if HAVE_ALTIVEC #define REPT4(...) { __VA_ARGS__, __VA_ARGS__, __VA_ARGS__, __VA_ARGS__ } // h subpel filter uses msum to multiply+add 4 pixel taps at once @@ -239,15 +241,15 @@ void put_vp8_epel ## WIDTH ## _v ## TAPS ## _altivec(uint8_t *dst, ptrdiff_t dst } #define EPEL_HV(WIDTH, HTAPS, VTAPS) \ -static void put_vp8_epel ## WIDTH ## _h ## HTAPS ## v ## VTAPS ## _altivec(uint8_t *dst, ptrdiff_t stride, uint8_t *src, ptrdiff_t s, int h, int mx, int my) \ +static void put_vp8_epel ## WIDTH ## _h ## HTAPS ## v ## VTAPS ## _altivec(uint8_t *dst, ptrdiff_t dstride, uint8_t *src, ptrdiff_t sstride, int h, int mx, int my) \ { \ DECLARE_ALIGNED(16, uint8_t, tmp)[(2*WIDTH+5)*16]; \ if (VTAPS == 6) { \ - put_vp8_epel ## WIDTH ## _h ## HTAPS ## _altivec(tmp, 16, src-2*stride, stride, h+5, mx, my); \ - put_vp8_epel ## WIDTH ## _v ## VTAPS ## _altivec(dst, stride, tmp+2*16, 16, h, mx, my); \ + put_vp8_epel ## WIDTH ## _h ## HTAPS ## _altivec(tmp, 16, src-2*sstride, sstride, h+5, mx, my); \ + put_vp8_epel ## WIDTH ## _v ## VTAPS ## _altivec(dst, dstride, tmp+2*16, 16, h, mx, my); \ } else { \ - put_vp8_epel ## WIDTH ## _h ## HTAPS ## _altivec(tmp, 16, src-stride, stride, h+4, mx, my); \ - put_vp8_epel ## WIDTH ## _v ## VTAPS ## _altivec(dst, stride, tmp+16, 16, h, mx, my); \ + put_vp8_epel ## WIDTH ## _h ## HTAPS ## _altivec(tmp, 16, src-sstride, sstride, h+4, mx, my); \ + put_vp8_epel ## WIDTH ## _v ## VTAPS ## _altivec(dst, dstride, tmp+16, 16, h, mx, my); \ } \ } @@ -267,13 +269,51 @@ EPEL_HV(4, 4,6) EPEL_HV(4, 6,4) EPEL_HV(4, 4,4) -static void put_vp8_pixels16_altivec(uint8_t *dst, ptrdiff_t stride, uint8_t *src, ptrdiff_t s, int h, int mx, int my) +static void put_vp8_pixels16_altivec(uint8_t *dst, ptrdiff_t dstride, uint8_t *src, ptrdiff_t sstride, int h, int mx, int my) { - ff_put_pixels16_altivec(dst, src, stride, h); + register vector unsigned char pixelsv1, pixelsv2; + register vector unsigned char pixelsv1B, pixelsv2B; + register vector unsigned char pixelsv1C, pixelsv2C; + register vector unsigned char pixelsv1D, pixelsv2D; + + register vector unsigned char perm = vec_lvsl(0, src); + int i; + register ptrdiff_t dstride2 = dstride << 1, sstride2 = sstride << 1; + register ptrdiff_t dstride3 = dstride2 + dstride, sstride3 = sstride + sstride2; + register ptrdiff_t dstride4 = dstride << 2, sstride4 = sstride << 2; + +// hand-unrolling the loop by 4 gains about 15% +// mininum execution time goes from 74 to 60 cycles +// it's faster than -funroll-loops, but using +// -funroll-loops w/ this is bad - 74 cycles again. +// all this is on a 7450, tuning for the 7450 + for (i = 0; i < h; i += 4) { + pixelsv1 = vec_ld( 0, src); + pixelsv2 = vec_ld(15, src); + pixelsv1B = vec_ld(sstride, src); + pixelsv2B = vec_ld(15 + sstride, src); + pixelsv1C = vec_ld(sstride2, src); + pixelsv2C = vec_ld(15 + sstride2, src); + pixelsv1D = vec_ld(sstride3, src); + pixelsv2D = vec_ld(15 + sstride3, src); + vec_st(vec_perm(pixelsv1, pixelsv2, perm), + 0, (unsigned char*)dst); + vec_st(vec_perm(pixelsv1B, pixelsv2B, perm), + dstride, (unsigned char*)dst); + vec_st(vec_perm(pixelsv1C, pixelsv2C, perm), + dstride2, (unsigned char*)dst); + vec_st(vec_perm(pixelsv1D, pixelsv2D, perm), + dstride3, (unsigned char*)dst); + src += sstride4; + dst += dstride4; + } } -av_cold void ff_vp8dsp_init_altivec(VP8DSPContext *c) +#endif /* HAVE_ALTIVEC */ + +av_cold void ff_vp8dsp_init_ppc(VP8DSPContext *c) { +#if HAVE_ALTIVEC if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC)) return; @@ -301,4 +341,5 @@ av_cold void ff_vp8dsp_init_altivec(VP8DSPContext *c) c->put_vp8_epel_pixels_tab[2][1][1] = put_vp8_epel4_h4v4_altivec; c->put_vp8_epel_pixels_tab[2][1][2] = put_vp8_epel4_h6v4_altivec; c->put_vp8_epel_pixels_tab[2][2][1] = put_vp8_epel4_h4v6_altivec; +#endif /* HAVE_ALTIVEC */ } diff --git a/ffmpeg/libavcodec/proresdata.c b/ffmpeg/libavcodec/proresdata.c index fcaf32a..9849b5c 100644 --- a/ffmpeg/libavcodec/proresdata.c +++ b/ffmpeg/libavcodec/proresdata.c @@ -3,20 +3,20 @@ * * Copyright (c) 2010-2011 Maxim Poliakovski * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/proresdec.h b/ffmpeg/libavcodec/proresdec.h index f42c448..de50dae 100644 --- a/ffmpeg/libavcodec/proresdec.h +++ b/ffmpeg/libavcodec/proresdec.h @@ -49,6 +49,7 @@ typedef struct { uint8_t interlaced_scan[64]; const uint8_t *scan; int first_field; + int alpha_info; } ProresContext; #endif /* AVCODEC_PRORESDEC_H */ diff --git a/ffmpeg/libavcodec/proresdec2.c b/ffmpeg/libavcodec/proresdec2.c index b7aef36..b1affad 100644 --- a/ffmpeg/libavcodec/proresdec2.c +++ b/ffmpeg/libavcodec/proresdec2.c @@ -33,6 +33,7 @@ #include "internal.h" #include "simple_idct.h" #include "proresdec.h" +#include "proresdata.h" static void permute(uint8_t *dst, const uint8_t *src, const uint8_t permutation[64]) { @@ -41,28 +42,6 @@ static void permute(uint8_t *dst, const uint8_t *src, const uint8_t permutation[ dst[i] = permutation[src[i]]; } -static const uint8_t progressive_scan[64] = { - 0, 1, 8, 9, 2, 3, 10, 11, - 16, 17, 24, 25, 18, 19, 26, 27, - 4, 5, 12, 20, 13, 6, 7, 14, - 21, 28, 29, 22, 15, 23, 30, 31, - 32, 33, 40, 48, 41, 34, 35, 42, - 49, 56, 57, 50, 43, 36, 37, 44, - 51, 58, 59, 52, 45, 38, 39, 46, - 53, 60, 61, 54, 47, 55, 62, 63 -}; - -static const uint8_t interlaced_scan[64] = { - 0, 8, 1, 9, 16, 24, 17, 25, - 2, 10, 3, 11, 18, 26, 19, 27, - 32, 40, 33, 34, 41, 48, 56, 49, - 42, 35, 43, 50, 57, 58, 51, 59, - 4, 12, 5, 6, 13, 20, 28, 21, - 14, 7, 15, 22, 29, 36, 44, 37, - 30, 23, 31, 38, 45, 52, 60, 53, - 46, 39, 47, 54, 61, 62, 55, 63, -}; - static av_cold int decode_init(AVCodecContext *avctx) { ProresContext *ctx = avctx->priv_data; @@ -76,8 +55,8 @@ static av_cold int decode_init(AVCodecContext *avctx) ff_init_scantable_permutation(idct_permutation, ctx->prodsp.idct_permutation_type); - permute(ctx->progressive_scan, progressive_scan, idct_permutation); - permute(ctx->interlaced_scan, interlaced_scan, idct_permutation); + permute(ctx->progressive_scan, ff_prores_progressive_scan, idct_permutation); + permute(ctx->interlaced_scan, ff_prores_interlaced_scan, idct_permutation); return 0; } @@ -93,14 +72,14 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf, av_dlog(avctx, "header size %d\n", hdr_size); if (hdr_size > data_size) { av_log(avctx, AV_LOG_ERROR, "error, wrong header size\n"); - return -1; + return AVERROR_INVALIDDATA; } version = AV_RB16(buf + 2); av_dlog(avctx, "%.4s version %d\n", buf+4, version); if (version > 1) { av_log(avctx, AV_LOG_ERROR, "unsupported version: %d\n", version); - return -1; + return AVERROR_PATCHWELCOME; } width = AV_RB16(buf + 8); @@ -108,10 +87,17 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf, if (width != avctx->width || height != avctx->height) { av_log(avctx, AV_LOG_ERROR, "picture resolution change: %dx%d -> %dx%d\n", avctx->width, avctx->height, width, height); - return -1; + return AVERROR_PATCHWELCOME; } ctx->frame_type = (buf[12] >> 2) & 3; + ctx->alpha_info = buf[17] & 0xf; + + if (ctx->alpha_info > 2) { + av_log(avctx, AV_LOG_ERROR, "Invalid alpha mode %d\n", ctx->alpha_info); + return AVERROR_INVALIDDATA; + } + if (avctx->skip_alpha) ctx->alpha_info = 0; av_dlog(avctx, "frame type %d\n", ctx->frame_type); @@ -123,7 +109,11 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf, ctx->frame->top_field_first = ctx->frame_type == 1; } - avctx->pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUV444P10 : AV_PIX_FMT_YUV422P10; + if (ctx->alpha_info) { + avctx->pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUVA444P10 : AV_PIX_FMT_YUVA422P10; + } else { + avctx->pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUV444P10 : AV_PIX_FMT_YUV422P10; + } ptr = buf + 20; flags = buf[19]; @@ -132,7 +122,7 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf, if (flags & 2) { if(buf + data_size - ptr < 64) { av_log(avctx, AV_LOG_ERROR, "Header truncated\n"); - return -1; + return AVERROR_INVALIDDATA; } permute(ctx->qmat_luma, ctx->prodsp.idct_permutation, ptr); ptr += 64; @@ -143,7 +133,7 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf, if (flags & 1) { if(buf + data_size - ptr < 64) { av_log(avctx, AV_LOG_ERROR, "Header truncated\n"); - return -1; + return AVERROR_INVALIDDATA; } permute(ctx->qmat_chroma, ctx->prodsp.idct_permutation, ptr); } else { @@ -165,13 +155,13 @@ static int decode_picture_header(AVCodecContext *avctx, const uint8_t *buf, cons hdr_size = buf[0] >> 3; if (hdr_size < 8 || hdr_size > buf_size) { av_log(avctx, AV_LOG_ERROR, "error, wrong picture header size\n"); - return -1; + return AVERROR_INVALIDDATA; } pic_data_size = AV_RB32(buf + 1); if (pic_data_size > buf_size) { av_log(avctx, AV_LOG_ERROR, "error, wrong picture data size\n"); - return -1; + return AVERROR_INVALIDDATA; } log2_slice_mb_width = buf[7] >> 4; @@ -179,7 +169,7 @@ static int decode_picture_header(AVCodecContext *avctx, const uint8_t *buf, cons if (log2_slice_mb_width > 3 || log2_slice_mb_height) { av_log(avctx, AV_LOG_ERROR, "unsupported slice resolution: %dx%d\n", 1 << log2_slice_mb_width, 1 << log2_slice_mb_height); - return -1; + return AVERROR_INVALIDDATA; } ctx->mb_width = (avctx->width + 15) >> 4; @@ -203,7 +193,7 @@ static int decode_picture_header(AVCodecContext *avctx, const uint8_t *buf, cons if (hdr_size + slice_count*2 > buf_size) { av_log(avctx, AV_LOG_ERROR, "error, wrong slice count\n"); - return -1; + return AVERROR_INVALIDDATA; } // parse slice information @@ -230,7 +220,7 @@ static int decode_picture_header(AVCodecContext *avctx, const uint8_t *buf, cons if (slice->data_size < 6) { av_log(avctx, AV_LOG_ERROR, "error, wrong slice data size\n"); - return -1; + return AVERROR_INVALIDDATA; } mb_x += slice_mb_count; @@ -241,14 +231,14 @@ static int decode_picture_header(AVCodecContext *avctx, const uint8_t *buf, cons } if (data_ptr > buf + buf_size) { av_log(avctx, AV_LOG_ERROR, "error, slice out of bounds\n"); - return -1; + return AVERROR_INVALIDDATA; } } if (mb_x || mb_y != ctx->mb_height) { av_log(avctx, AV_LOG_ERROR, "error wrong mb count y %d h %d\n", mb_y, ctx->mb_height); - return -1; + return AVERROR_INVALIDDATA; } return pic_data_size; @@ -320,8 +310,8 @@ static av_always_inline void decode_dc_coeffs(GetBitContext *gb, int16_t *out, static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29, 0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C }; static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28, 0x28, 0x28, 0x28, 0x4C }; -static av_always_inline void decode_ac_coeffs(AVCodecContext *avctx, GetBitContext *gb, - int16_t *out, int blocks_per_slice) +static av_always_inline int decode_ac_coeffs(AVCodecContext *avctx, GetBitContext *gb, + int16_t *out, int blocks_per_slice) { ProresContext *ctx = avctx->priv_data; int block_mask, sign; @@ -346,7 +336,7 @@ static av_always_inline void decode_ac_coeffs(AVCodecContext *avctx, GetBitConte pos += run + 1; if (pos >= max_coeffs) { av_log(avctx, AV_LOG_ERROR, "ac tex damaged %d, %d\n", pos, max_coeffs); - return; + return AVERROR_INVALIDDATA; } DECODE_CODEWORD(level, lev_to_cb[FFMIN(level, 9)]); @@ -360,18 +350,20 @@ static av_always_inline void decode_ac_coeffs(AVCodecContext *avctx, GetBitConte } CLOSE_READER(re, gb); + return 0; } -static void decode_slice_luma(AVCodecContext *avctx, SliceContext *slice, - uint16_t *dst, int dst_stride, - const uint8_t *buf, unsigned buf_size, - const int16_t *qmat) +static int decode_slice_luma(AVCodecContext *avctx, SliceContext *slice, + uint16_t *dst, int dst_stride, + const uint8_t *buf, unsigned buf_size, + const int16_t *qmat) { ProresContext *ctx = avctx->priv_data; LOCAL_ALIGNED_16(int16_t, blocks, [8*4*64]); int16_t *block; GetBitContext gb; int i, blocks_per_slice = slice->mb_count<<2; + int ret; for (i = 0; i < blocks_per_slice; i++) ctx->dsp.clear_block(blocks+(i<<6)); @@ -379,7 +371,8 @@ static void decode_slice_luma(AVCodecContext *avctx, SliceContext *slice, init_get_bits(&gb, buf, buf_size << 3); decode_dc_coeffs(&gb, blocks, blocks_per_slice); - decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice); + if ((ret = decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice)) < 0) + return ret; block = blocks; for (i = 0; i < slice->mb_count; i++) { @@ -390,18 +383,20 @@ static void decode_slice_luma(AVCodecContext *avctx, SliceContext *slice, block += 4*64; dst += 16; } + return 0; } -static void decode_slice_chroma(AVCodecContext *avctx, SliceContext *slice, - uint16_t *dst, int dst_stride, - const uint8_t *buf, unsigned buf_size, - const int16_t *qmat, int log2_blocks_per_mb) +static int decode_slice_chroma(AVCodecContext *avctx, SliceContext *slice, + uint16_t *dst, int dst_stride, + const uint8_t *buf, unsigned buf_size, + const int16_t *qmat, int log2_blocks_per_mb) { ProresContext *ctx = avctx->priv_data; LOCAL_ALIGNED_16(int16_t, blocks, [8*4*64]); int16_t *block; GetBitContext gb; int i, j, blocks_per_slice = slice->mb_count << log2_blocks_per_mb; + int ret; for (i = 0; i < blocks_per_slice; i++) ctx->dsp.clear_block(blocks+(i<<6)); @@ -409,7 +404,8 @@ static void decode_slice_chroma(AVCodecContext *avctx, SliceContext *slice, init_get_bits(&gb, buf, buf_size << 3); decode_dc_coeffs(&gb, blocks, blocks_per_slice); - decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice); + if ((ret = decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice)) < 0) + return ret; block = blocks; for (i = 0; i < slice->mb_count; i++) { @@ -420,6 +416,84 @@ static void decode_slice_chroma(AVCodecContext *avctx, SliceContext *slice, dst += 8; } } + return 0; +} + +static void unpack_alpha(GetBitContext *gb, uint16_t *dst, int num_coeffs, + const int num_bits) +{ + const int mask = (1 << num_bits) - 1; + int i, idx, val, alpha_val; + + idx = 0; + alpha_val = mask; + do { + do { + if (get_bits1(gb)) { + val = get_bits(gb, num_bits); + } else { + int sign; + val = get_bits(gb, num_bits == 16 ? 7 : 4); + sign = val & 1; + val = (val + 2) >> 1; + if (sign) + val = -val; + } + alpha_val = (alpha_val + val) & mask; + if (num_bits == 16) { + dst[idx++] = alpha_val >> 6; + } else { + dst[idx++] = (alpha_val << 2) | (alpha_val >> 6); + } + if (idx >= num_coeffs) + break; + } while (get_bits_left(gb)>0 && get_bits1(gb)); + val = get_bits(gb, 4); + if (!val) + val = get_bits(gb, 11); + if (idx + val > num_coeffs) + val = num_coeffs - idx; + if (num_bits == 16) { + for (i = 0; i < val; i++) + dst[idx++] = alpha_val >> 6; + } else { + for (i = 0; i < val; i++) + dst[idx++] = (alpha_val << 2) | (alpha_val >> 6); + + } + } while (idx < num_coeffs); +} + +/** + * Decode alpha slice plane. + */ +static void decode_slice_alpha(ProresContext *ctx, + uint16_t *dst, int dst_stride, + const uint8_t *buf, int buf_size, + int blocks_per_slice) +{ + GetBitContext gb; + int i; + LOCAL_ALIGNED_16(int16_t, blocks, [8*4*64]); + int16_t *block; + + for (i = 0; i < blocks_per_slice<<2; i++) + ctx->dsp.clear_block(blocks+(i<<6)); + + init_get_bits(&gb, buf, buf_size << 3); + + if (ctx->alpha_info == 2) { + unpack_alpha(&gb, blocks, blocks_per_slice * 4 * 64, 16); + } else { + unpack_alpha(&gb, blocks, blocks_per_slice * 4 * 64, 8); + } + + block = blocks; + for (i = 0; i < 16; i++) { + memcpy(dst, block, 16 * blocks_per_slice * sizeof(*dst)); + dst += dst_stride >> 1; + block += 16 * blocks_per_slice; + } } static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int threadnr) @@ -430,11 +504,12 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int AVFrame *pic = ctx->frame; int i, hdr_size, qscale, log2_chroma_blocks_per_mb; int luma_stride, chroma_stride; - int y_data_size, u_data_size, v_data_size; - uint8_t *dest_y, *dest_u, *dest_v; + int y_data_size, u_data_size, v_data_size, a_data_size; + uint8_t *dest_y, *dest_u, *dest_v, *dest_a; int16_t qmat_luma_scaled[64]; int16_t qmat_chroma_scaled[64]; int mb_x_shift; + int ret; slice->ret = -1; //av_log(avctx, AV_LOG_INFO, "slice %d mb width %d mb x %d y %d\n", @@ -448,11 +523,13 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int u_data_size = AV_RB16(buf + 4); v_data_size = slice->data_size - y_data_size - u_data_size - hdr_size; if (hdr_size > 7) v_data_size = AV_RB16(buf + 6); + a_data_size = slice->data_size - y_data_size - u_data_size - + v_data_size - hdr_size; if (y_data_size < 0 || u_data_size < 0 || v_data_size < 0 || hdr_size+y_data_size+u_data_size+v_data_size > slice->data_size){ av_log(avctx, AV_LOG_ERROR, "invalid plane data size\n"); - return -1; + return AVERROR_INVALIDDATA; } buf += hdr_size; @@ -470,7 +547,7 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int chroma_stride = pic->linesize[1] << 1; } - if (avctx->pix_fmt == AV_PIX_FMT_YUV444P10) { + if (avctx->pix_fmt == AV_PIX_FMT_YUV444P10 || avctx->pix_fmt == AV_PIX_FMT_YUVA444P10) { mb_x_shift = 5; log2_chroma_blocks_per_mb = 2; } else { @@ -481,24 +558,38 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int dest_y = pic->data[0] + (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5); dest_u = pic->data[1] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift); dest_v = pic->data[2] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift); + dest_a = pic->data[3] + (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5); if (ctx->frame_type && ctx->first_field ^ ctx->frame->top_field_first) { dest_y += pic->linesize[0]; dest_u += pic->linesize[1]; dest_v += pic->linesize[2]; + dest_a += pic->linesize[3]; } - decode_slice_luma(avctx, slice, (uint16_t*)dest_y, luma_stride, - buf, y_data_size, qmat_luma_scaled); + ret = decode_slice_luma(avctx, slice, (uint16_t*)dest_y, luma_stride, + buf, y_data_size, qmat_luma_scaled); + if (ret < 0) + return ret; if (!(avctx->flags & CODEC_FLAG_GRAY)) { - decode_slice_chroma(avctx, slice, (uint16_t*)dest_u, chroma_stride, - buf + y_data_size, u_data_size, - qmat_chroma_scaled, log2_chroma_blocks_per_mb); - decode_slice_chroma(avctx, slice, (uint16_t*)dest_v, chroma_stride, - buf + y_data_size + u_data_size, v_data_size, - qmat_chroma_scaled, log2_chroma_blocks_per_mb); + ret = decode_slice_chroma(avctx, slice, (uint16_t*)dest_u, chroma_stride, + buf + y_data_size, u_data_size, + qmat_chroma_scaled, log2_chroma_blocks_per_mb); + if (ret < 0) + return ret; + + ret = decode_slice_chroma(avctx, slice, (uint16_t*)dest_v, chroma_stride, + buf + y_data_size + u_data_size, v_data_size, + qmat_chroma_scaled, log2_chroma_blocks_per_mb); + if (ret < 0) + return ret; } + /* decode alpha plane if available */ + if (ctx->alpha_info && pic->data[3] && a_data_size) + decode_slice_alpha(ctx, (uint16_t*)dest_a, luma_stride, + buf + y_data_size + u_data_size + v_data_size, + a_data_size, slice->mb_count); slice->ret = 0; return 0; @@ -525,14 +616,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVFrame *frame = data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - int frame_hdr_size, pic_size; + int frame_hdr_size, pic_size, ret; if (buf_size < 28 || AV_RL32(buf + 4) != AV_RL32("icpf")) { av_log(avctx, AV_LOG_ERROR, "invalid frame header\n"); - return -1; + return AVERROR_INVALIDDATA; } ctx->frame = frame; + ctx->frame->pict_type = AV_PICTURE_TYPE_I; + ctx->frame->key_frame = 1; ctx->first_field = 1; buf += 8; @@ -540,24 +633,24 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, frame_hdr_size = decode_frame_header(ctx, buf, buf_size, avctx); if (frame_hdr_size < 0) - return -1; + return frame_hdr_size; buf += frame_hdr_size; buf_size -= frame_hdr_size; - if (ff_get_buffer(avctx, frame, 0) < 0) - return -1; + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + return ret; decode_picture: pic_size = decode_picture_header(avctx, buf, buf_size); if (pic_size < 0) { av_log(avctx, AV_LOG_ERROR, "error decoding picture header\n"); - return -1; + return pic_size; } - if (decode_picture(avctx)) { + if ((ret = decode_picture(avctx)) < 0) { av_log(avctx, AV_LOG_ERROR, "error decoding picture\n"); - return -1; + return ret; } buf += pic_size; @@ -584,12 +677,12 @@ static av_cold int decode_close(AVCodecContext *avctx) AVCodec ff_prores_decoder = { .name = "prores", + .long_name = NULL_IF_CONFIG_SMALL("ProRes"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PRORES, .priv_data_size = sizeof(ProresContext), .init = decode_init, .close = decode_close, .decode = decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("ProRes"), .capabilities = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS, }; diff --git a/ffmpeg/libavcodec/proresdec_lgpl.c b/ffmpeg/libavcodec/proresdec_lgpl.c index 59c9843..a57429d 100644 --- a/ffmpeg/libavcodec/proresdec_lgpl.c +++ b/ffmpeg/libavcodec/proresdec_lgpl.c @@ -3,20 +3,20 @@ * * Copyright (c) 2010-2011 Maxim Poliakovski * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -134,12 +134,22 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf, ctx->chroma_factor = (buf[12] >> 6) & 3; ctx->mb_chroma_factor = ctx->chroma_factor + 2; ctx->num_chroma_blocks = (1 << ctx->chroma_factor) >> 1; + ctx->alpha_info = buf[17] & 0xf; + + if (ctx->alpha_info > 2) { + av_log(avctx, AV_LOG_ERROR, "Invalid alpha mode %d\n", ctx->alpha_info); + return AVERROR_INVALIDDATA; + } + if (avctx->skip_alpha) ctx->alpha_info = 0; + switch (ctx->chroma_factor) { case 2: - avctx->pix_fmt = AV_PIX_FMT_YUV422P10; + avctx->pix_fmt = ctx->alpha_info ? AV_PIX_FMT_YUVA422P10 + : AV_PIX_FMT_YUV422P10; break; case 3: - avctx->pix_fmt = AV_PIX_FMT_YUV444P10; + avctx->pix_fmt = ctx->alpha_info ? AV_PIX_FMT_YUVA444P10 + : AV_PIX_FMT_YUV444P10; break; default: av_log(avctx, AV_LOG_ERROR, @@ -168,10 +178,6 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf, avctx->color_trc = buf[15]; avctx->colorspace = buf[16]; - ctx->alpha_info = buf[17] & 0xf; - if (ctx->alpha_info) - avpriv_report_missing_feature(avctx, "Alpha channel"); - ctx->qmat_changed = 0; ptr = buf + 20; flags = buf[19]; @@ -364,10 +370,10 @@ static inline void decode_dc_coeffs(GetBitContext *gb, int16_t *out, /** * Decode AC coefficients for all blocks in a slice. */ -static inline void decode_ac_coeffs(GetBitContext *gb, int16_t *out, - int blocks_per_slice, - int plane_size_factor, - const uint8_t *scan) +static inline int decode_ac_coeffs(GetBitContext *gb, int16_t *out, + int blocks_per_slice, + int plane_size_factor, + const uint8_t *scan) { int pos, block_mask, run, level, sign, run_cb_index, lev_cb_index; int max_coeffs, bits_left; @@ -385,15 +391,19 @@ static inline void decode_ac_coeffs(GetBitContext *gb, int16_t *out, bits_left = get_bits_left(gb); if (bits_left <= 0 || (bits_left <= 8 && !show_bits(gb, bits_left))) - return; + return 0; run = decode_vlc_codeword(gb, ff_prores_ac_codebook[run_cb_index]); + if (run < 0) + return AVERROR_INVALIDDATA; bits_left = get_bits_left(gb); if (bits_left <= 0 || (bits_left <= 8 && !show_bits(gb, bits_left))) - return; + return AVERROR_INVALIDDATA; level = decode_vlc_codeword(gb, ff_prores_ac_codebook[lev_cb_index]) + 1; + if (level < 0) + return AVERROR_INVALIDDATA; pos += run + 1; if (pos >= max_coeffs) @@ -403,22 +413,24 @@ static inline void decode_ac_coeffs(GetBitContext *gb, int16_t *out, out[((pos & block_mask) << 6) + scan[pos >> plane_size_factor]] = (level ^ sign) - sign; } + + return 0; } /** * Decode a slice plane (luma or chroma). */ -static void decode_slice_plane(ProresContext *ctx, ProresThreadData *td, - const uint8_t *buf, - int data_size, uint16_t *out_ptr, - int linesize, int mbs_per_slice, - int blocks_per_mb, int plane_size_factor, - const int16_t *qmat, int is_chroma) +static int decode_slice_plane(ProresContext *ctx, ProresThreadData *td, + const uint8_t *buf, + int data_size, uint16_t *out_ptr, + int linesize, int mbs_per_slice, + int blocks_per_mb, int plane_size_factor, + const int16_t *qmat, int is_chroma) { GetBitContext gb; int16_t *block_ptr; - int mb_num, blocks_per_slice; + int mb_num, blocks_per_slice, ret; blocks_per_slice = mbs_per_slice * blocks_per_mb; @@ -428,8 +440,10 @@ static void decode_slice_plane(ProresContext *ctx, ProresThreadData *td, decode_dc_coeffs(&gb, td->blocks, blocks_per_slice); - decode_ac_coeffs(&gb, td->blocks, blocks_per_slice, - plane_size_factor, ctx->scantable.permutated); + ret = decode_ac_coeffs(&gb, td->blocks, blocks_per_slice, + plane_size_factor, ctx->scantable.permutated); + if (ret < 0) + return ret; /* inverse quantization, inverse transform and output */ block_ptr = td->blocks; @@ -463,8 +477,82 @@ static void decode_slice_plane(ProresContext *ctx, ProresThreadData *td, } } } + return 0; +} + + +static void unpack_alpha(GetBitContext *gb, uint16_t *dst, int num_coeffs, + const int num_bits) +{ + const int mask = (1 << num_bits) - 1; + int i, idx, val, alpha_val; + + idx = 0; + alpha_val = mask; + do { + do { + if (get_bits1(gb)) + val = get_bits(gb, num_bits); + else { + int sign; + val = get_bits(gb, num_bits == 16 ? 7 : 4); + sign = val & 1; + val = (val + 2) >> 1; + if (sign) + val = -val; + } + alpha_val = (alpha_val + val) & mask; + if (num_bits == 16) + dst[idx++] = alpha_val >> 6; + else + dst[idx++] = (alpha_val << 2) | (alpha_val >> 6); + if (idx >= num_coeffs) { + break; + } + } while (get_bits1(gb)); + val = get_bits(gb, 4); + if (!val) + val = get_bits(gb, 11); + if (idx + val > num_coeffs) + val = num_coeffs - idx; + if (num_bits == 16) + for (i = 0; i < val; i++) + dst[idx++] = alpha_val >> 6; + else + for (i = 0; i < val; i++) + dst[idx++] = (alpha_val << 2) | (alpha_val >> 6); + } while (idx < num_coeffs); } +/** + * Decode alpha slice plane. + */ +static void decode_alpha_plane(ProresContext *ctx, ProresThreadData *td, + const uint8_t *buf, int data_size, + uint16_t *out_ptr, int linesize, + int mbs_per_slice) +{ + GetBitContext gb; + int i; + uint16_t *block_ptr; + + memset(td->blocks, 0, 8 * 4 * 64 * sizeof(*td->blocks)); + + init_get_bits(&gb, buf, data_size << 3); + + if (ctx->alpha_info == 2) + unpack_alpha(&gb, td->blocks, mbs_per_slice * 4 * 64, 16); + else + unpack_alpha(&gb, td->blocks, mbs_per_slice * 4 * 64, 8); + + block_ptr = td->blocks; + + for (i = 0; i < 16; i++) { + memcpy(out_ptr, block_ptr, 16 * mbs_per_slice * sizeof(*out_ptr)); + out_ptr += linesize >> 1; + block_ptr += 16 * mbs_per_slice; + } +} static int decode_slice(AVCodecContext *avctx, void *tdata) { @@ -476,11 +564,14 @@ static int decode_slice(AVCodecContext *avctx, void *tdata) int slice_num = td->slice_num; int mbs_per_slice = td->slice_width; const uint8_t *buf; - uint8_t *y_data, *u_data, *v_data; + uint8_t *y_data, *u_data, *v_data, *a_data; AVFrame *pic = ctx->frame; int i, sf, slice_width_factor; - int slice_data_size, hdr_size, y_data_size, u_data_size, v_data_size; - int y_linesize, u_linesize, v_linesize; + int slice_data_size, hdr_size; + int y_data_size, u_data_size, v_data_size, a_data_size; + int y_linesize, u_linesize, v_linesize, a_linesize; + int coff[4]; + int ret; buf = ctx->slice_data[slice_num].index; slice_data_size = ctx->slice_data[slice_num + 1].index - buf; @@ -490,20 +581,30 @@ static int decode_slice(AVCodecContext *avctx, void *tdata) y_data = pic->data[0]; u_data = pic->data[1]; v_data = pic->data[2]; + a_data = pic->data[3]; y_linesize = pic->linesize[0]; u_linesize = pic->linesize[1]; v_linesize = pic->linesize[2]; + a_linesize = pic->linesize[3]; if (pic->interlaced_frame) { if (!(pic_num ^ pic->top_field_first)) { y_data += y_linesize; u_data += u_linesize; v_data += v_linesize; + if (a_data) + a_data += a_linesize; } y_linesize <<= 1; u_linesize <<= 1; v_linesize <<= 1; + a_linesize <<= 1; } + y_data += (mb_y_pos << 4) * y_linesize + (mb_x_pos << 5); + u_data += (mb_y_pos << 4) * u_linesize + (mb_x_pos << ctx->mb_chroma_factor); + v_data += (mb_y_pos << 4) * v_linesize + (mb_x_pos << ctx->mb_chroma_factor); + if (a_data) + a_data += (mb_y_pos << 4) * a_linesize + (mb_x_pos << 5); if (slice_data_size < 6) { av_log(avctx, AV_LOG_ERROR, "slice data too small\n"); @@ -512,13 +613,18 @@ static int decode_slice(AVCodecContext *avctx, void *tdata) /* parse slice header */ hdr_size = buf[0] >> 3; + coff[0] = hdr_size; y_data_size = AV_RB16(buf + 2); + coff[1] = coff[0] + y_data_size; u_data_size = AV_RB16(buf + 4); - v_data_size = hdr_size > 7 ? AV_RB16(buf + 6) : - slice_data_size - y_data_size - u_data_size - hdr_size; - - if (hdr_size + y_data_size + u_data_size + v_data_size > slice_data_size || - v_data_size < 0 || hdr_size < 6) { + coff[2] = coff[1] + u_data_size; + v_data_size = hdr_size > 7 ? AV_RB16(buf + 6) : slice_data_size - coff[2]; + coff[3] = coff[2] + v_data_size; + a_data_size = ctx->alpha_info ? slice_data_size - coff[3] : 0; + + /* if V or alpha component size is negative that means that previous + component sizes are too large */ + if (v_data_size < 0 || a_data_size < 0 || hdr_size < 6) { av_log(avctx, AV_LOG_ERROR, "invalid data size\n"); return AVERROR_INVALIDDATA; } @@ -537,28 +643,37 @@ static int decode_slice(AVCodecContext *avctx, void *tdata) } /* decode luma plane */ - decode_slice_plane(ctx, td, buf + hdr_size, y_data_size, - (uint16_t*) (y_data + (mb_y_pos << 4) * y_linesize + - (mb_x_pos << 5)), y_linesize, - mbs_per_slice, 4, slice_width_factor + 2, - td->qmat_luma_scaled, 0); + ret = decode_slice_plane(ctx, td, buf + coff[0], y_data_size, + (uint16_t*) y_data, y_linesize, + mbs_per_slice, 4, slice_width_factor + 2, + td->qmat_luma_scaled, 0); + + if (ret < 0) + return ret; /* decode U chroma plane */ - decode_slice_plane(ctx, td, buf + hdr_size + y_data_size, u_data_size, - (uint16_t*) (u_data + (mb_y_pos << 4) * u_linesize + - (mb_x_pos << ctx->mb_chroma_factor)), - u_linesize, mbs_per_slice, ctx->num_chroma_blocks, - slice_width_factor + ctx->chroma_factor - 1, - td->qmat_chroma_scaled, 1); + ret = decode_slice_plane(ctx, td, buf + coff[1], u_data_size, + (uint16_t*) u_data, u_linesize, + mbs_per_slice, ctx->num_chroma_blocks, + slice_width_factor + ctx->chroma_factor - 1, + td->qmat_chroma_scaled, 1); + if (ret < 0) + return ret; /* decode V chroma plane */ - decode_slice_plane(ctx, td, buf + hdr_size + y_data_size + u_data_size, - v_data_size, - (uint16_t*) (v_data + (mb_y_pos << 4) * v_linesize + - (mb_x_pos << ctx->mb_chroma_factor)), - v_linesize, mbs_per_slice, ctx->num_chroma_blocks, - slice_width_factor + ctx->chroma_factor - 1, - td->qmat_chroma_scaled, 1); + ret = decode_slice_plane(ctx, td, buf + coff[2], v_data_size, + (uint16_t*) v_data, v_linesize, + mbs_per_slice, ctx->num_chroma_blocks, + slice_width_factor + ctx->chroma_factor - 1, + td->qmat_chroma_scaled, 1); + if (ret < 0) + return ret; + + /* decode alpha plane if available */ + if (a_data && a_data_size) + decode_alpha_plane(ctx, td, buf + coff[3], a_data_size, + (uint16_t*) a_data, a_linesize, + mbs_per_slice); return 0; } @@ -657,6 +772,7 @@ static av_cold int decode_close(AVCodecContext *avctx) AVCodec ff_prores_lgpl_decoder = { .name = "prores_lgpl", + .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PRORES, .priv_data_size = sizeof(ProresContext), @@ -664,5 +780,4 @@ AVCodec ff_prores_lgpl_decoder = { .close = decode_close, .decode = decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS, - .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)") }; diff --git a/ffmpeg/libavcodec/proresdsp.c b/ffmpeg/libavcodec/proresdsp.c index d73de46..4ff219e 100644 --- a/ffmpeg/libavcodec/proresdsp.c +++ b/ffmpeg/libavcodec/proresdsp.c @@ -3,28 +3,29 @@ * * Copyright (c) 2010-2011 Maxim Poliakovski * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/attributes.h" +#include "libavutil/common.h" #include "dct.h" #include "dsputil.h" #include "proresdsp.h" #include "simple_idct.h" -#include "libavutil/common.h" #define BIAS (1 << (PRORES_BITS_PER_SAMPLE - 1)) ///< bias value for converting signed pixels into unsigned ones #define CLIP_MIN (1 << (PRORES_BITS_PER_SAMPLE - 8)) ///< minimum value for clipping resulting pixels @@ -56,7 +57,7 @@ static void prores_idct_put_c(uint16_t *out, int linesize, int16_t *block, const } #endif -#if CONFIG_PRORES_KOSTYA_ENCODER +#if CONFIG_PRORES_KS_ENCODER static void prores_fdct_c(const uint16_t *src, int linesize, int16_t *block) { int x, y; @@ -71,7 +72,7 @@ static void prores_fdct_c(const uint16_t *src, int linesize, int16_t *block) } #endif -void ff_proresdsp_init(ProresDSPContext *dsp, AVCodecContext *avctx) +av_cold void ff_proresdsp_init(ProresDSPContext *dsp, AVCodecContext *avctx) { #if CONFIG_PRORES_DECODER | CONFIG_PRORES_LGPL_DECODER dsp->idct_put = prores_idct_put_c; @@ -82,7 +83,7 @@ void ff_proresdsp_init(ProresDSPContext *dsp, AVCodecContext *avctx) ff_init_scantable_permutation(dsp->idct_permutation, dsp->idct_permutation_type); #endif -#if CONFIG_PRORES_KOSTYA_ENCODER +#if CONFIG_PRORES_KS_ENCODER dsp->fdct = prores_fdct_c; dsp->dct_permutation_type = FF_NO_IDCT_PERM; ff_init_scantable_permutation(dsp->dct_permutation, diff --git a/ffmpeg/libavcodec/proresenc_anatoliy.c b/ffmpeg/libavcodec/proresenc_anatoliy.c index 7bf71a3..80ce135 100644 --- a/ffmpeg/libavcodec/proresenc_anatoliy.c +++ b/ffmpeg/libavcodec/proresenc_anatoliy.c @@ -581,7 +581,7 @@ static av_cold int prores_encode_init(AVCodecContext *avctx) scale_mat(QMAT_CHROMA[avctx->profile], ctx->qmat_chroma[i - 1], i); } - avctx->coded_frame = avcodec_alloc_frame(); + avctx->coded_frame = av_frame_alloc(); avctx->coded_frame->key_frame = 1; avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; @@ -597,8 +597,9 @@ static av_cold int prores_encode_close(AVCodecContext *avctx) return 0; } -AVCodec ff_prores_anatoliy_encoder = { - .name = "prores_anatoliy", +AVCodec ff_prores_aw_encoder = { + .name = "prores_aw", + .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PRORES, .priv_data_size = sizeof(ProresContext), @@ -606,13 +607,13 @@ AVCodec ff_prores_anatoliy_encoder = { .close = prores_encode_close, .encode2 = prores_encode_frame, .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes"), .capabilities = CODEC_CAP_FRAME_THREADS | CODEC_CAP_INTRA_ONLY, .profiles = profiles }; AVCodec ff_prores_encoder = { .name = "prores", + .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PRORES, .priv_data_size = sizeof(ProresContext), @@ -620,7 +621,6 @@ AVCodec ff_prores_encoder = { .close = prores_encode_close, .encode2 = prores_encode_frame, .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes"), .capabilities = CODEC_CAP_FRAME_THREADS | CODEC_CAP_INTRA_ONLY, .profiles = profiles }; diff --git a/ffmpeg/libavcodec/proresenc_kostya.c b/ffmpeg/libavcodec/proresenc_kostya.c index 8da13ac..71c2cb4 100644 --- a/ffmpeg/libavcodec/proresenc_kostya.c +++ b/ffmpeg/libavcodec/proresenc_kostya.c @@ -6,24 +6,25 @@ * This encoder appears to be based on Anatoliy Wassermans considering * similarities in the bugs. * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "libavutil/opt.h" +#include "libavutil/pixdesc.h" #include "avcodec.h" #include "dsputil.h" #include "put_bits.h" @@ -37,13 +38,14 @@ #define MAX_MBS_PER_SLICE 8 -#define MAX_PLANES 3 // should be increased to 4 when there's AV_PIX_FMT_YUV444AP10 +#define MAX_PLANES 4 enum { PRORES_PROFILE_PROXY = 0, PRORES_PROFILE_LT, PRORES_PROFILE_STANDARD, PRORES_PROFILE_HQ, + PRORES_PROFILE_4444, }; enum { @@ -122,7 +124,7 @@ static const struct prores_profile { int max_quant; int br_tab[NUM_MB_LIMITS]; int quant; -} prores_profile_info[4] = { +} prores_profile_info[5] = { { .full_name = "proxy", .tag = MKTAG('a', 'p', 'c', 'o'), @@ -154,8 +156,15 @@ static const struct prores_profile { .max_quant = 6, .br_tab = { 1566, 1216, 1070, 950 }, .quant = QUANT_MAT_HQ, + }, + { + .full_name = "4444", + .tag = MKTAG('a', 'p', '4', 'h'), + .min_quant = 1, + .max_quant = 6, + .br_tab = { 2350, 1828, 1600, 1425 }, + .quant = QUANT_MAT_HQ, } -// for 4444 profile bitrate numbers are { 2350, 1828, 1600, 1425 } }; #define TRELLIS_WIDTH 16 @@ -198,6 +207,7 @@ typedef struct ProresContext { int num_planes; int bits_per_mb; int force_quant; + int alpha_bits; char *vendor; int quant_sel; @@ -283,6 +293,34 @@ static void get_slice_data(ProresContext *ctx, const uint16_t *src, } } +static void get_alpha_data(ProresContext *ctx, const uint16_t *src, + int linesize, int x, int y, int w, int h, + int16_t *blocks, int mbs_per_slice, int abits) +{ + const int slice_width = 16 * mbs_per_slice; + int i, j, copy_w, copy_h; + + copy_w = FFMIN(w - x, slice_width); + copy_h = FFMIN(h - y, 16); + for (i = 0; i < copy_h; i++) { + memcpy(blocks, src, copy_w * sizeof(*src)); + if (abits == 8) + for (j = 0; j < copy_w; j++) + blocks[j] >>= 2; + else + for (j = 0; j < copy_w; j++) + blocks[j] = (blocks[j] << 6) | (blocks[j] >> 4); + for (j = copy_w; j < slice_width; j++) + blocks[j] = blocks[copy_w - 1]; + blocks += slice_width; + src += linesize >> 1; + } + for (; i < 16; i++) { + memcpy(blocks, blocks - slice_width, slice_width * sizeof(*blocks)); + blocks += slice_width; + } +} + /** * Write an unsigned rice/exp golomb codeword. */ @@ -397,6 +435,73 @@ static int encode_slice_plane(ProresContext *ctx, PutBitContext *pb, return (put_bits_count(pb) - saved_pos) >> 3; } +static void put_alpha_diff(PutBitContext *pb, int cur, int prev, int abits) +{ + const int mask = (1 << abits) - 1; + const int dbits = (abits == 8) ? 4 : 7; + const int dsize = 1 << dbits - 1; + int diff = cur - prev; + + diff &= mask; + if (diff >= (1 << abits) - dsize) + diff -= 1 << abits; + if (diff < -dsize || diff > dsize || !diff) { + put_bits(pb, 1, 1); + put_bits(pb, abits, diff); + } else { + put_bits(pb, 1, 0); + put_bits(pb, dbits - 1, FFABS(diff) - 1); + put_bits(pb, 1, diff < 0); + } +} + +static void put_alpha_run(PutBitContext *pb, int run) +{ + if (run) { + put_bits(pb, 1, 0); + if (run < 0x10) + put_bits(pb, 4, run); + else + put_bits(pb, 15, run); + } else { + put_bits(pb, 1, 1); + } +} + +// todo alpha quantisation for high quants +static int encode_alpha_plane(ProresContext *ctx, PutBitContext *pb, + const uint16_t *src, int linesize, + int mbs_per_slice, uint16_t *blocks, + int quant) +{ + const int abits = ctx->alpha_bits; + const int mask = (1 << abits) - 1; + const int num_coeffs = mbs_per_slice * 256; + int saved_pos = put_bits_count(pb); + int prev = mask, cur; + int idx = 0; + int run = 0; + + cur = blocks[idx++]; + put_alpha_diff(pb, cur, prev, abits); + prev = cur; + do { + cur = blocks[idx++]; + if (cur != prev) { + put_alpha_run (pb, run); + put_alpha_diff(pb, cur, prev, abits); + prev = cur; + run = 0; + } else { + run++; + } + } while (idx < num_coeffs); + if (run) + put_alpha_run(pb, run); + flush_put_bits(pb); + return (put_bits_count(pb) - saved_pos) >> 3; +} + static int encode_slice(AVCodecContext *avctx, const AVFrame *pic, PutBitContext *pb, int sizes[4], int x, int y, int quant, @@ -447,14 +552,23 @@ static int encode_slice(AVCodecContext *avctx, const AVFrame *pic, src = (const uint16_t*)(pic->data[i] + yp * linesize + line_add * pic->linesize[i]) + xp; - get_slice_data(ctx, src, linesize, xp, yp, - pwidth, avctx->height / ctx->pictures_per_frame, - ctx->blocks[0], ctx->emu_buf, - mbs_per_slice, num_cblocks, is_chroma); - sizes[i] = encode_slice_plane(ctx, pb, src, linesize, - mbs_per_slice, ctx->blocks[0], - num_cblocks, plane_factor, - qmat); + if (i < 3) { + get_slice_data(ctx, src, linesize, xp, yp, + pwidth, avctx->height / ctx->pictures_per_frame, + ctx->blocks[0], ctx->emu_buf, + mbs_per_slice, num_cblocks, is_chroma); + sizes[i] = encode_slice_plane(ctx, pb, src, linesize, + mbs_per_slice, ctx->blocks[0], + num_cblocks, plane_factor, + qmat); + } else { + get_alpha_data(ctx, src, linesize, xp, yp, + pwidth, avctx->height / ctx->pictures_per_frame, + ctx->blocks[0], mbs_per_slice, ctx->alpha_bits); + sizes[i] = encode_alpha_plane(ctx, pb, src, linesize, + mbs_per_slice, ctx->blocks[0], + quant); + } total_size += sizes[i]; } return total_size; @@ -567,6 +681,66 @@ static int estimate_slice_plane(ProresContext *ctx, int *error, int plane, return FFALIGN(bits, 8); } +static int est_alpha_diff(int cur, int prev, int abits) +{ + const int mask = (1 << abits) - 1; + const int dbits = (abits == 8) ? 4 : 7; + const int dsize = 1 << dbits - 1; + int diff = cur - prev; + + diff &= mask; + if (diff >= (1 << abits) - dsize) + diff -= 1 << abits; + if (diff < -dsize || diff > dsize || !diff) + return abits + 1; + else + return dbits + 1; +} + +static int estimate_alpha_plane(ProresContext *ctx, int *error, + const uint16_t *src, int linesize, + int mbs_per_slice, int quant, + int16_t *blocks) +{ + const int abits = ctx->alpha_bits; + const int mask = (1 << abits) - 1; + const int num_coeffs = mbs_per_slice * 256; + int prev = mask, cur; + int idx = 0; + int run = 0; + int bits; + + *error = 0; + cur = blocks[idx++]; + bits = est_alpha_diff(cur, prev, abits); + prev = cur; + do { + cur = blocks[idx++]; + if (cur != prev) { + if (!run) + bits++; + else if (run < 0x10) + bits += 4; + else + bits += 15; + bits += est_alpha_diff(cur, prev, abits); + prev = cur; + run = 0; + } else { + run++; + } + } while (idx < num_coeffs); + + if (run) { + if (run < 0x10) + bits += 4; + else + bits += 15; + } + + return bits; +} + static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic, int trellis_node, int x, int y, int mbs_per_slice, ProresThreadData *td) @@ -613,10 +787,16 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic, src = (const uint16_t*)(pic->data[i] + yp * linesize[i] + line_add * pic->linesize[i]) + xp; - get_slice_data(ctx, src, linesize[i], xp, yp, - pwidth, avctx->height / ctx->pictures_per_frame, - td->blocks[i], td->emu_buf, - mbs_per_slice, num_cblocks[i], is_chroma[i]); + if (i < 3) { + get_slice_data(ctx, src, linesize[i], xp, yp, + pwidth, avctx->height / ctx->pictures_per_frame, + td->blocks[i], td->emu_buf, + mbs_per_slice, num_cblocks[i], is_chroma[i]); + } else { + get_alpha_data(ctx, src, linesize[i], xp, yp, + pwidth, avctx->height / ctx->pictures_per_frame, + td->blocks[i], mbs_per_slice, ctx->alpha_bits); + } } for (q = min_quant; q < max_quant + 2; q++) { @@ -628,13 +808,16 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic, for (q = min_quant; q <= max_quant; q++) { bits = 0; error = 0; - for (i = 0; i < ctx->num_planes; i++) { + for (i = 0; i < ctx->num_planes - !!ctx->alpha_bits; i++) { bits += estimate_slice_plane(ctx, &error, i, src, linesize[i], mbs_per_slice, num_cblocks[i], plane_factor[i], ctx->quants[q], td); } + if (ctx->alpha_bits) + bits += estimate_alpha_plane(ctx, &error, src, linesize[3], + mbs_per_slice, q, td->blocks[3]); if (bits > 65000 * 8) { error = SCORE_LIMIT; break; @@ -657,13 +840,16 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic, for (i = 0; i < 64; i++) qmat[i] = ctx->quant_mat[i] * q; } - for (i = 0; i < ctx->num_planes; i++) { + for (i = 0; i < ctx->num_planes - !!ctx->alpha_bits; i++) { bits += estimate_slice_plane(ctx, &error, i, src, linesize[i], mbs_per_slice, num_cblocks[i], plane_factor[i], qmat, td); } + if (ctx->alpha_bits) + bits += estimate_alpha_plane(ctx, &error, src, linesize[3], + mbs_per_slice, q, td->blocks[3]); if (bits <= ctx->bits_per_mb * mbs_per_slice) break; } @@ -783,7 +969,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, bytestream_put_byte (&buf, avctx->color_primaries); bytestream_put_byte (&buf, avctx->color_trc); bytestream_put_byte (&buf, avctx->colorspace); - bytestream_put_byte (&buf, 0x40); // source format and alpha information + bytestream_put_byte (&buf, 0x40 | (ctx->alpha_bits >> 3)); bytestream_put_byte (&buf, 0); // reserved if (ctx->quant_sel != QUANT_MAT_DEFAULT) { bytestream_put_byte (&buf, 0x03); // matrix flags - both matrices are present @@ -887,7 +1073,7 @@ static av_cold int encode_init(AVCodecContext *avctx) int interlaced = !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT); avctx->bits_per_raw_sample = 10; - avctx->coded_frame = avcodec_alloc_frame(); + avctx->coded_frame = av_frame_alloc(); if (!avctx->coded_frame) return AVERROR(ENOMEM); @@ -902,12 +1088,20 @@ static av_cold int encode_init(AVCodecContext *avctx) "there should be an integer power of two MBs per slice\n"); return AVERROR(EINVAL); } + if (av_pix_fmt_desc_get(avctx->pix_fmt)->flags & AV_PIX_FMT_FLAG_ALPHA) { + if (ctx->alpha_bits & 7) { + av_log(avctx, AV_LOG_ERROR, "alpha bits should be 0, 8 or 16\n"); + return AVERROR(EINVAL); + } + } else { + ctx->alpha_bits = 0; + } ctx->chroma_factor = avctx->pix_fmt == AV_PIX_FMT_YUV422P10 ? CFACTOR_Y422 : CFACTOR_Y444; ctx->profile_info = prores_profile_info + ctx->profile; - ctx->num_planes = 3; + ctx->num_planes = 3 + !!ctx->alpha_bits; ctx->mb_width = FFALIGN(avctx->width, 16) >> 4; @@ -1023,7 +1217,7 @@ static const AVOption options[] = { AV_OPT_TYPE_INT, { .i64 = 8 }, 1, MAX_MBS_PER_SLICE, VE }, { "profile", NULL, OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = PRORES_PROFILE_STANDARD }, - PRORES_PROFILE_PROXY, PRORES_PROFILE_HQ, VE, "profile" }, + PRORES_PROFILE_PROXY, PRORES_PROFILE_4444, VE, "profile" }, { "proxy", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_PROXY }, 0, 0, VE, "profile" }, { "lt", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_LT }, @@ -1032,6 +1226,8 @@ static const AVOption options[] = { 0, 0, VE, "profile" }, { "hq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_HQ }, 0, 0, VE, "profile" }, + { "4444", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_4444 }, + 0, 0, VE, "profile" }, { "vendor", "vendor ID", OFFSET(vendor), AV_OPT_TYPE_STRING, { .str = "Lavc" }, CHAR_MIN, CHAR_MAX, VE }, { "bits_per_mb", "desired bits per macroblock", OFFSET(bits_per_mb), @@ -1050,6 +1246,8 @@ static const AVOption options[] = { 0, 0, VE, "quant_mat" }, { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_DEFAULT }, 0, 0, VE, "quant_mat" }, + { "alpha_bits", "bits for alpha plane", OFFSET(alpha_bits), AV_OPT_TYPE_INT, + { .i64 = 16 }, 0, 16, VE }, { NULL } }; @@ -1060,8 +1258,9 @@ static const AVClass proresenc_class = { .version = LIBAVUTIL_VERSION_INT, }; -AVCodec ff_prores_kostya_encoder = { - .name = "prores_kostya", +AVCodec ff_prores_ks_encoder = { + .name = "prores_ks", + .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PRORES, .priv_data_size = sizeof(ProresContext), @@ -1069,9 +1268,9 @@ AVCodec ff_prores_kostya_encoder = { .close = encode_close, .encode2 = encode_frame, .capabilities = CODEC_CAP_SLICE_THREADS, - .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)"), .pix_fmts = (const enum AVPixelFormat[]) { - AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_NONE + AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE }, .priv_class = &proresenc_class, }; diff --git a/ffmpeg/libavcodec/psymodel.c b/ffmpeg/libavcodec/psymodel.c index ea11636..bfc85b3 100644 --- a/ffmpeg/libavcodec/psymodel.c +++ b/ffmpeg/libavcodec/psymodel.c @@ -75,7 +75,7 @@ FFPsyChannelGroup *ff_psy_find_group(FFPsyContext *ctx, int channel) av_cold void ff_psy_end(FFPsyContext *ctx) { - if (ctx->model->end) + if (ctx->model && ctx->model->end) ctx->model->end(ctx); av_freep(&ctx->bands); av_freep(&ctx->num_bands); diff --git a/ffmpeg/libavcodec/pthread.c b/ffmpeg/libavcodec/pthread.c index 9dbaec3..407ca2e 100644 --- a/ffmpeg/libavcodec/pthread.c +++ b/ffmpeg/libavcodec/pthread.c @@ -29,1047 +29,10 @@ * @see doc/multithreading.txt */ -#include "config.h" - -#if HAVE_SCHED_GETAFFINITY -#ifndef _GNU_SOURCE -# define _GNU_SOURCE -#endif -#include -#endif -#if HAVE_GETPROCESSAFFINITYMASK -#include -#endif -#if HAVE_SYSCTL -#if HAVE_SYS_PARAM_H -#include -#endif -#include -#include -#include -#endif -#if HAVE_SYSCONF -#include -#endif - #include "avcodec.h" #include "internal.h" +#include "pthread_internal.h" #include "thread.h" -#include "libavutil/avassert.h" -#include "libavutil/common.h" - -#if HAVE_PTHREADS -#include -#elif HAVE_W32THREADS -#include "w32pthreads.h" -#elif HAVE_OS2THREADS -#include "os2threads.h" -#endif - -typedef int (action_func)(AVCodecContext *c, void *arg); -typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr); - -typedef struct ThreadContext { - pthread_t *workers; - action_func *func; - action_func2 *func2; - void *args; - int *rets; - int rets_count; - int job_count; - int job_size; - - pthread_cond_t last_job_cond; - pthread_cond_t current_job_cond; - pthread_mutex_t current_job_lock; - int current_job; - unsigned int current_execute; - int done; -} ThreadContext; - -/** - * Context used by codec threads and stored in their AVCodecContext thread_opaque. - */ -typedef struct PerThreadContext { - struct FrameThreadContext *parent; - - pthread_t thread; - int thread_init; - pthread_cond_t input_cond; ///< Used to wait for a new packet from the main thread. - pthread_cond_t progress_cond; ///< Used by child threads to wait for progress to change. - pthread_cond_t output_cond; ///< Used by the main thread to wait for frames to finish. - - pthread_mutex_t mutex; ///< Mutex used to protect the contents of the PerThreadContext. - pthread_mutex_t progress_mutex; ///< Mutex used to protect frame progress values and progress_cond. - - AVCodecContext *avctx; ///< Context used to decode packets passed to this thread. - - AVPacket avpkt; ///< Input packet (for decoding) or output (for encoding). - uint8_t *buf; ///< backup storage for packet data when the input packet is not refcounted - int allocated_buf_size; ///< Size allocated for buf - - AVFrame frame; ///< Output frame (for decoding) or input (for encoding). - int got_frame; ///< The output of got_picture_ptr from the last avcodec_decode_video() call. - int result; ///< The result of the last codec decode/encode() call. - - enum { - STATE_INPUT_READY, ///< Set when the thread is awaiting a packet. - STATE_SETTING_UP, ///< Set before the codec has called ff_thread_finish_setup(). - STATE_GET_BUFFER, /**< - * Set when the codec calls get_buffer(). - * State is returned to STATE_SETTING_UP afterwards. - */ - STATE_SETUP_FINISHED ///< Set after the codec has called ff_thread_finish_setup(). - } state; - - /** - * Array of frames passed to ff_thread_release_buffer(). - * Frames are released after all threads referencing them are finished. - */ - AVFrame *released_buffers; - int num_released_buffers; - int released_buffers_allocated; - - AVFrame *requested_frame; ///< AVFrame the codec passed to get_buffer() - int requested_flags; ///< flags passed to get_buffer() for requested_frame -} PerThreadContext; - -/** - * Context stored in the client AVCodecContext thread_opaque. - */ -typedef struct FrameThreadContext { - PerThreadContext *threads; ///< The contexts for each thread. - PerThreadContext *prev_thread; ///< The last thread submit_packet() was called on. - - pthread_mutex_t buffer_mutex; ///< Mutex used to protect get/release_buffer(). - - int next_decoding; ///< The next context to submit a packet to. - int next_finished; ///< The next context to return output from. - - int delaying; /**< - * Set for the first N packets, where N is the number of threads. - * While it is set, ff_thread_en/decode_frame won't return any results. - */ - - int die; ///< Set when threads should exit. -} FrameThreadContext; - - -/* H264 slice threading seems to be buggy with more than 16 threads, - * limit the number of threads to 16 for automatic detection */ -#define MAX_AUTO_THREADS 16 - -int ff_get_logical_cpus(AVCodecContext *avctx) -{ - int ret, nb_cpus = 1; -#if HAVE_SCHED_GETAFFINITY && defined(CPU_COUNT) - cpu_set_t cpuset; - - CPU_ZERO(&cpuset); - - ret = sched_getaffinity(0, sizeof(cpuset), &cpuset); - if (!ret) { - nb_cpus = CPU_COUNT(&cpuset); - } -#elif HAVE_GETPROCESSAFFINITYMASK - DWORD_PTR proc_aff, sys_aff; - ret = GetProcessAffinityMask(GetCurrentProcess(), &proc_aff, &sys_aff); - if (ret) - nb_cpus = av_popcount64(proc_aff); -#elif HAVE_SYSCTL && defined(HW_NCPU) - int mib[2] = { CTL_HW, HW_NCPU }; - size_t len = sizeof(nb_cpus); - - ret = sysctl(mib, 2, &nb_cpus, &len, NULL, 0); - if (ret == -1) - nb_cpus = 0; -#elif HAVE_SYSCONF && defined(_SC_NPROC_ONLN) - nb_cpus = sysconf(_SC_NPROC_ONLN); -#elif HAVE_SYSCONF && defined(_SC_NPROCESSORS_ONLN) - nb_cpus = sysconf(_SC_NPROCESSORS_ONLN); -#endif - av_log(avctx, AV_LOG_DEBUG, "detected %d logical cores\n", nb_cpus); - - if (avctx->height) - nb_cpus = FFMIN(nb_cpus, (avctx->height+15)/16); - - return nb_cpus; -} - - -static void* attribute_align_arg worker(void *v) -{ - AVCodecContext *avctx = v; - ThreadContext *c = avctx->thread_opaque; - int our_job = c->job_count; - int last_execute = 0; - int thread_count = avctx->thread_count; - int self_id; - - pthread_mutex_lock(&c->current_job_lock); - self_id = c->current_job++; - for (;;){ - while (our_job >= c->job_count) { - if (c->current_job == thread_count + c->job_count) - pthread_cond_signal(&c->last_job_cond); - - while (last_execute == c->current_execute && !c->done) - pthread_cond_wait(&c->current_job_cond, &c->current_job_lock); - last_execute = c->current_execute; - our_job = self_id; - - if (c->done) { - pthread_mutex_unlock(&c->current_job_lock); - return NULL; - } - } - pthread_mutex_unlock(&c->current_job_lock); - - c->rets[our_job%c->rets_count] = c->func ? c->func(avctx, (char*)c->args + our_job*c->job_size): - c->func2(avctx, c->args, our_job, self_id); - - pthread_mutex_lock(&c->current_job_lock); - our_job = c->current_job++; - } -} - -static av_always_inline void avcodec_thread_park_workers(ThreadContext *c, int thread_count) -{ - while (c->current_job != thread_count + c->job_count) - pthread_cond_wait(&c->last_job_cond, &c->current_job_lock); - pthread_mutex_unlock(&c->current_job_lock); -} - -static void thread_free(AVCodecContext *avctx) -{ - ThreadContext *c = avctx->thread_opaque; - int i; - - pthread_mutex_lock(&c->current_job_lock); - c->done = 1; - pthread_cond_broadcast(&c->current_job_cond); - pthread_mutex_unlock(&c->current_job_lock); - - for (i=0; ithread_count; i++) - pthread_join(c->workers[i], NULL); - - pthread_mutex_destroy(&c->current_job_lock); - pthread_cond_destroy(&c->current_job_cond); - pthread_cond_destroy(&c->last_job_cond); - av_free(c->workers); - av_freep(&avctx->thread_opaque); -} - -static int avcodec_thread_execute(AVCodecContext *avctx, action_func* func, void *arg, int *ret, int job_count, int job_size) -{ - ThreadContext *c= avctx->thread_opaque; - int dummy_ret; - - if (!(avctx->active_thread_type&FF_THREAD_SLICE) || avctx->thread_count <= 1) - return avcodec_default_execute(avctx, func, arg, ret, job_count, job_size); - - if (job_count <= 0) - return 0; - - pthread_mutex_lock(&c->current_job_lock); - - c->current_job = avctx->thread_count; - c->job_count = job_count; - c->job_size = job_size; - c->args = arg; - c->func = func; - if (ret) { - c->rets = ret; - c->rets_count = job_count; - } else { - c->rets = &dummy_ret; - c->rets_count = 1; - } - c->current_execute++; - pthread_cond_broadcast(&c->current_job_cond); - - avcodec_thread_park_workers(c, avctx->thread_count); - - return 0; -} - -static int avcodec_thread_execute2(AVCodecContext *avctx, action_func2* func2, void *arg, int *ret, int job_count) -{ - ThreadContext *c= avctx->thread_opaque; - c->func2 = func2; - return avcodec_thread_execute(avctx, NULL, arg, ret, job_count, 0); -} - -static int thread_init(AVCodecContext *avctx) -{ - int i; - ThreadContext *c; - int thread_count = avctx->thread_count; - - if (!thread_count) { - int nb_cpus = ff_get_logical_cpus(avctx); - // use number of cores + 1 as thread count if there is more than one - if (nb_cpus > 1) - thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS); - else - thread_count = avctx->thread_count = 1; - } - - if (thread_count <= 1) { - avctx->active_thread_type = 0; - return 0; - } - - c = av_mallocz(sizeof(ThreadContext)); - if (!c) - return -1; - - c->workers = av_mallocz(sizeof(pthread_t)*thread_count); - if (!c->workers) { - av_free(c); - return -1; - } - - avctx->thread_opaque = c; - c->current_job = 0; - c->job_count = 0; - c->job_size = 0; - c->done = 0; - pthread_cond_init(&c->current_job_cond, NULL); - pthread_cond_init(&c->last_job_cond, NULL); - pthread_mutex_init(&c->current_job_lock, NULL); - pthread_mutex_lock(&c->current_job_lock); - for (i=0; iworkers[i], NULL, worker, avctx)) { - avctx->thread_count = i; - pthread_mutex_unlock(&c->current_job_lock); - ff_thread_free(avctx); - return -1; - } - } - - avcodec_thread_park_workers(c, thread_count); - - avctx->execute = avcodec_thread_execute; - avctx->execute2 = avcodec_thread_execute2; - return 0; -} - -/** - * Codec worker thread. - * - * Automatically calls ff_thread_finish_setup() if the codec does - * not provide an update_thread_context method, or if the codec returns - * before calling it. - */ -static attribute_align_arg void *frame_worker_thread(void *arg) -{ - PerThreadContext *p = arg; - FrameThreadContext *fctx = p->parent; - AVCodecContext *avctx = p->avctx; - const AVCodec *codec = avctx->codec; - - pthread_mutex_lock(&p->mutex); - while (1) { - while (p->state == STATE_INPUT_READY && !fctx->die) - pthread_cond_wait(&p->input_cond, &p->mutex); - - if (fctx->die) break; - - if (!codec->update_thread_context && (avctx->thread_safe_callbacks || ( -#if FF_API_GET_BUFFER - !avctx->get_buffer && -#endif - avctx->get_buffer2 == avcodec_default_get_buffer2))) - ff_thread_finish_setup(avctx); - - avcodec_get_frame_defaults(&p->frame); - p->got_frame = 0; - p->result = codec->decode(avctx, &p->frame, &p->got_frame, &p->avpkt); - - /* many decoders assign whole AVFrames, thus overwriting extended_data; - * make sure it's set correctly */ - p->frame.extended_data = p->frame.data; - - if (p->state == STATE_SETTING_UP) ff_thread_finish_setup(avctx); - - pthread_mutex_lock(&p->progress_mutex); -#if 0 //BUFREF-FIXME - for (i = 0; i < MAX_BUFFERS; i++) - if (p->progress_used[i] && (p->got_frame || p->result<0 || avctx->codec_id != AV_CODEC_ID_H264)) { - p->progress[i][0] = INT_MAX; - p->progress[i][1] = INT_MAX; - } -#endif - p->state = STATE_INPUT_READY; - - pthread_cond_broadcast(&p->progress_cond); - pthread_cond_signal(&p->output_cond); - pthread_mutex_unlock(&p->progress_mutex); - } - pthread_mutex_unlock(&p->mutex); - - return NULL; -} - -/** - * Update the next thread's AVCodecContext with values from the reference thread's context. - * - * @param dst The destination context. - * @param src The source context. - * @param for_user 0 if the destination is a codec thread, 1 if the destination is the user's thread - */ -static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, int for_user) -{ - int err = 0; - - if (dst != src) { - dst->time_base = src->time_base; - dst->width = src->width; - dst->height = src->height; - dst->pix_fmt = src->pix_fmt; - - dst->coded_width = src->coded_width; - dst->coded_height = src->coded_height; - - dst->has_b_frames = src->has_b_frames; - dst->idct_algo = src->idct_algo; - - dst->bits_per_coded_sample = src->bits_per_coded_sample; - dst->sample_aspect_ratio = src->sample_aspect_ratio; - dst->dtg_active_format = src->dtg_active_format; - - dst->profile = src->profile; - dst->level = src->level; - - dst->bits_per_raw_sample = src->bits_per_raw_sample; - dst->ticks_per_frame = src->ticks_per_frame; - dst->color_primaries = src->color_primaries; - - dst->color_trc = src->color_trc; - dst->colorspace = src->colorspace; - dst->color_range = src->color_range; - dst->chroma_sample_location = src->chroma_sample_location; - } - - if (for_user) { - dst->delay = src->thread_count - 1; - dst->coded_frame = src->coded_frame; - } else { - if (dst->codec->update_thread_context) - err = dst->codec->update_thread_context(dst, src); - } - - return err; -} - -/** - * Update the next thread's AVCodecContext with values set by the user. - * - * @param dst The destination context. - * @param src The source context. - * @return 0 on success, negative error code on failure - */ -static int update_context_from_user(AVCodecContext *dst, AVCodecContext *src) -{ -#define copy_fields(s, e) memcpy(&dst->s, &src->s, (char*)&dst->e - (char*)&dst->s); - dst->flags = src->flags; - - dst->draw_horiz_band= src->draw_horiz_band; - dst->get_buffer2 = src->get_buffer2; -#if FF_API_GET_BUFFER - dst->get_buffer = src->get_buffer; - dst->release_buffer = src->release_buffer; -#endif - - dst->opaque = src->opaque; - dst->debug = src->debug; - dst->debug_mv = src->debug_mv; - - dst->slice_flags = src->slice_flags; - dst->flags2 = src->flags2; - - copy_fields(skip_loop_filter, subtitle_header); - - dst->frame_number = src->frame_number; - dst->reordered_opaque = src->reordered_opaque; - dst->thread_safe_callbacks = src->thread_safe_callbacks; - - if (src->slice_count && src->slice_offset) { - if (dst->slice_count < src->slice_count) { - int *tmp = av_realloc(dst->slice_offset, src->slice_count * - sizeof(*dst->slice_offset)); - if (!tmp) { - av_free(dst->slice_offset); - return AVERROR(ENOMEM); - } - dst->slice_offset = tmp; - } - memcpy(dst->slice_offset, src->slice_offset, - src->slice_count * sizeof(*dst->slice_offset)); - } - dst->slice_count = src->slice_count; - return 0; -#undef copy_fields -} - -/// Releases the buffers that this decoding thread was the last user of. -static void release_delayed_buffers(PerThreadContext *p) -{ - FrameThreadContext *fctx = p->parent; - - while (p->num_released_buffers > 0) { - AVFrame *f; - - pthread_mutex_lock(&fctx->buffer_mutex); - - // fix extended data in case the caller screwed it up - av_assert0(p->avctx->codec_type == AVMEDIA_TYPE_VIDEO); - f = &p->released_buffers[--p->num_released_buffers]; - f->extended_data = f->data; - av_frame_unref(f); - - pthread_mutex_unlock(&fctx->buffer_mutex); - } -} - -static int submit_packet(PerThreadContext *p, AVPacket *avpkt) -{ - FrameThreadContext *fctx = p->parent; - PerThreadContext *prev_thread = fctx->prev_thread; - const AVCodec *codec = p->avctx->codec; - - if (!avpkt->size && !(codec->capabilities & CODEC_CAP_DELAY)) return 0; - - pthread_mutex_lock(&p->mutex); - - release_delayed_buffers(p); - - if (prev_thread) { - int err; - if (prev_thread->state == STATE_SETTING_UP) { - pthread_mutex_lock(&prev_thread->progress_mutex); - while (prev_thread->state == STATE_SETTING_UP) - pthread_cond_wait(&prev_thread->progress_cond, &prev_thread->progress_mutex); - pthread_mutex_unlock(&prev_thread->progress_mutex); - } - - err = update_context_from_thread(p->avctx, prev_thread->avctx, 0); - if (err) { - pthread_mutex_unlock(&p->mutex); - return err; - } - } - - av_buffer_unref(&p->avpkt.buf); - p->avpkt = *avpkt; - if (avpkt->buf) - p->avpkt.buf = av_buffer_ref(avpkt->buf); - else { - av_fast_malloc(&p->buf, &p->allocated_buf_size, avpkt->size + FF_INPUT_BUFFER_PADDING_SIZE); - p->avpkt.data = p->buf; - memcpy(p->buf, avpkt->data, avpkt->size); - memset(p->buf + avpkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE); - } - - p->state = STATE_SETTING_UP; - pthread_cond_signal(&p->input_cond); - pthread_mutex_unlock(&p->mutex); - - /* - * If the client doesn't have a thread-safe get_buffer(), - * then decoding threads call back to the main thread, - * and it calls back to the client here. - */ - - if (!p->avctx->thread_safe_callbacks && ( -#if FF_API_GET_BUFFER - p->avctx->get_buffer || -#endif - p->avctx->get_buffer2 != avcodec_default_get_buffer2)) { - while (p->state != STATE_SETUP_FINISHED && p->state != STATE_INPUT_READY) { - pthread_mutex_lock(&p->progress_mutex); - while (p->state == STATE_SETTING_UP) - pthread_cond_wait(&p->progress_cond, &p->progress_mutex); - - if (p->state == STATE_GET_BUFFER) { - p->result = ff_get_buffer(p->avctx, p->requested_frame, p->requested_flags); - p->state = STATE_SETTING_UP; - pthread_cond_signal(&p->progress_cond); - } - pthread_mutex_unlock(&p->progress_mutex); - } - } - - fctx->prev_thread = p; - fctx->next_decoding++; - - return 0; -} - -int ff_thread_decode_frame(AVCodecContext *avctx, - AVFrame *picture, int *got_picture_ptr, - AVPacket *avpkt) -{ - FrameThreadContext *fctx = avctx->thread_opaque; - int finished = fctx->next_finished; - PerThreadContext *p; - int err; - - /* - * Submit a packet to the next decoding thread. - */ - - p = &fctx->threads[fctx->next_decoding]; - err = update_context_from_user(p->avctx, avctx); - if (err) return err; - err = submit_packet(p, avpkt); - if (err) return err; - - /* - * If we're still receiving the initial packets, don't return a frame. - */ - - if (fctx->delaying) { - if (fctx->next_decoding >= (avctx->thread_count-1)) fctx->delaying = 0; - - *got_picture_ptr=0; - if (avpkt->size) - return avpkt->size; - } - - /* - * Return the next available frame from the oldest thread. - * If we're at the end of the stream, then we have to skip threads that - * didn't output a frame, because we don't want to accidentally signal - * EOF (avpkt->size == 0 && *got_picture_ptr == 0). - */ - - do { - p = &fctx->threads[finished++]; - - if (p->state != STATE_INPUT_READY) { - pthread_mutex_lock(&p->progress_mutex); - while (p->state != STATE_INPUT_READY) - pthread_cond_wait(&p->output_cond, &p->progress_mutex); - pthread_mutex_unlock(&p->progress_mutex); - } - - av_frame_move_ref(picture, &p->frame); - *got_picture_ptr = p->got_frame; - picture->pkt_dts = p->avpkt.dts; - - /* - * A later call with avkpt->size == 0 may loop over all threads, - * including this one, searching for a frame to return before being - * stopped by the "finished != fctx->next_finished" condition. - * Make sure we don't mistakenly return the same frame again. - */ - p->got_frame = 0; - - if (finished >= avctx->thread_count) finished = 0; - } while (!avpkt->size && !*got_picture_ptr && finished != fctx->next_finished); - - update_context_from_thread(avctx, p->avctx, 1); - - if (fctx->next_decoding >= avctx->thread_count) fctx->next_decoding = 0; - - fctx->next_finished = finished; - - /* return the size of the consumed packet if no error occurred */ - return (p->result >= 0) ? avpkt->size : p->result; -} - -void ff_thread_report_progress(ThreadFrame *f, int n, int field) -{ - PerThreadContext *p; - volatile int *progress = f->progress ? (int*)f->progress->data : NULL; - - if (!progress || progress[field] >= n) return; - - p = f->owner->thread_opaque; - - if (f->owner->debug&FF_DEBUG_THREADS) - av_log(f->owner, AV_LOG_DEBUG, "%p finished %d field %d\n", progress, n, field); - - pthread_mutex_lock(&p->progress_mutex); - progress[field] = n; - pthread_cond_broadcast(&p->progress_cond); - pthread_mutex_unlock(&p->progress_mutex); -} - -void ff_thread_await_progress(ThreadFrame *f, int n, int field) -{ - PerThreadContext *p; - volatile int *progress = f->progress ? (int*)f->progress->data : NULL; - - if (!progress || progress[field] >= n) return; - - p = f->owner->thread_opaque; - - if (f->owner->debug&FF_DEBUG_THREADS) - av_log(f->owner, AV_LOG_DEBUG, "thread awaiting %d field %d from %p\n", n, field, progress); - - pthread_mutex_lock(&p->progress_mutex); - while (progress[field] < n) - pthread_cond_wait(&p->progress_cond, &p->progress_mutex); - pthread_mutex_unlock(&p->progress_mutex); -} - -void ff_thread_finish_setup(AVCodecContext *avctx) { - PerThreadContext *p = avctx->thread_opaque; - - if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return; - - if(p->state == STATE_SETUP_FINISHED){ - av_log(avctx, AV_LOG_WARNING, "Multiple ff_thread_finish_setup() calls\n"); - } - - pthread_mutex_lock(&p->progress_mutex); - p->state = STATE_SETUP_FINISHED; - pthread_cond_broadcast(&p->progress_cond); - pthread_mutex_unlock(&p->progress_mutex); -} - -/// Waits for all threads to finish. -static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count) -{ - int i; - - for (i = 0; i < thread_count; i++) { - PerThreadContext *p = &fctx->threads[i]; - - if (p->state != STATE_INPUT_READY) { - pthread_mutex_lock(&p->progress_mutex); - while (p->state != STATE_INPUT_READY) - pthread_cond_wait(&p->output_cond, &p->progress_mutex); - pthread_mutex_unlock(&p->progress_mutex); - } - p->got_frame = 0; - } -} - -static void frame_thread_free(AVCodecContext *avctx, int thread_count) -{ - FrameThreadContext *fctx = avctx->thread_opaque; - const AVCodec *codec = avctx->codec; - int i; - - park_frame_worker_threads(fctx, thread_count); - - if (fctx->prev_thread && fctx->prev_thread != fctx->threads) - if (update_context_from_thread(fctx->threads->avctx, fctx->prev_thread->avctx, 0) < 0) { - av_log(avctx, AV_LOG_ERROR, "Final thread update failed\n"); - fctx->prev_thread->avctx->internal->is_copy = fctx->threads->avctx->internal->is_copy; - fctx->threads->avctx->internal->is_copy = 1; - } - - fctx->die = 1; - - for (i = 0; i < thread_count; i++) { - PerThreadContext *p = &fctx->threads[i]; - - pthread_mutex_lock(&p->mutex); - pthread_cond_signal(&p->input_cond); - pthread_mutex_unlock(&p->mutex); - - if (p->thread_init) - pthread_join(p->thread, NULL); - p->thread_init=0; - - if (codec->close) - codec->close(p->avctx); - - avctx->codec = NULL; - - release_delayed_buffers(p); - av_frame_unref(&p->frame); - } - - for (i = 0; i < thread_count; i++) { - PerThreadContext *p = &fctx->threads[i]; - - pthread_mutex_destroy(&p->mutex); - pthread_mutex_destroy(&p->progress_mutex); - pthread_cond_destroy(&p->input_cond); - pthread_cond_destroy(&p->progress_cond); - pthread_cond_destroy(&p->output_cond); - av_buffer_unref(&p->avpkt.buf); - av_freep(&p->buf); - av_freep(&p->released_buffers); - - if (i) { - av_freep(&p->avctx->priv_data); - av_freep(&p->avctx->internal); - av_freep(&p->avctx->slice_offset); - } - - av_freep(&p->avctx); - } - - av_freep(&fctx->threads); - pthread_mutex_destroy(&fctx->buffer_mutex); - av_freep(&avctx->thread_opaque); -} - -static int frame_thread_init(AVCodecContext *avctx) -{ - int thread_count = avctx->thread_count; - const AVCodec *codec = avctx->codec; - AVCodecContext *src = avctx; - FrameThreadContext *fctx; - int i, err = 0; - - if (!thread_count) { - int nb_cpus = ff_get_logical_cpus(avctx); - if ((avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) || avctx->debug_mv) - nb_cpus = 1; - // use number of cores + 1 as thread count if there is more than one - if (nb_cpus > 1) - thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS); - else - thread_count = avctx->thread_count = 1; - } - - if (thread_count <= 1) { - avctx->active_thread_type = 0; - return 0; - } - - avctx->thread_opaque = fctx = av_mallocz(sizeof(FrameThreadContext)); - - fctx->threads = av_mallocz(sizeof(PerThreadContext) * thread_count); - pthread_mutex_init(&fctx->buffer_mutex, NULL); - fctx->delaying = 1; - - for (i = 0; i < thread_count; i++) { - AVCodecContext *copy = av_malloc(sizeof(AVCodecContext)); - PerThreadContext *p = &fctx->threads[i]; - - pthread_mutex_init(&p->mutex, NULL); - pthread_mutex_init(&p->progress_mutex, NULL); - pthread_cond_init(&p->input_cond, NULL); - pthread_cond_init(&p->progress_cond, NULL); - pthread_cond_init(&p->output_cond, NULL); - - p->parent = fctx; - p->avctx = copy; - - if (!copy) { - err = AVERROR(ENOMEM); - goto error; - } - - *copy = *src; - copy->thread_opaque = p; - copy->pkt = &p->avpkt; - - if (!i) { - src = copy; - - if (codec->init) - err = codec->init(copy); - - update_context_from_thread(avctx, copy, 1); - } else { - copy->priv_data = av_malloc(codec->priv_data_size); - if (!copy->priv_data) { - err = AVERROR(ENOMEM); - goto error; - } - memcpy(copy->priv_data, src->priv_data, codec->priv_data_size); - copy->internal = av_malloc(sizeof(AVCodecInternal)); - if (!copy->internal) { - err = AVERROR(ENOMEM); - goto error; - } - *copy->internal = *src->internal; - copy->internal->is_copy = 1; - - if (codec->init_thread_copy) - err = codec->init_thread_copy(copy); - } - - if (err) goto error; - - err = AVERROR(pthread_create(&p->thread, NULL, frame_worker_thread, p)); - p->thread_init= !err; - if(!p->thread_init) - goto error; - } - - return 0; - -error: - frame_thread_free(avctx, i+1); - - return err; -} - -void ff_thread_flush(AVCodecContext *avctx) -{ - int i; - FrameThreadContext *fctx = avctx->thread_opaque; - - if (!avctx->thread_opaque) return; - - park_frame_worker_threads(fctx, avctx->thread_count); - if (fctx->prev_thread) { - if (fctx->prev_thread != &fctx->threads[0]) - update_context_from_thread(fctx->threads[0].avctx, fctx->prev_thread->avctx, 0); - if (avctx->codec->flush) - avctx->codec->flush(fctx->threads[0].avctx); - } - - fctx->next_decoding = fctx->next_finished = 0; - fctx->delaying = 1; - fctx->prev_thread = NULL; - for (i = 0; i < avctx->thread_count; i++) { - PerThreadContext *p = &fctx->threads[i]; - // Make sure decode flush calls with size=0 won't return old frames - p->got_frame = 0; - av_frame_unref(&p->frame); - - release_delayed_buffers(p); - } -} - -int ff_thread_can_start_frame(AVCodecContext *avctx) -{ - PerThreadContext *p = avctx->thread_opaque; - if ((avctx->active_thread_type&FF_THREAD_FRAME) && p->state != STATE_SETTING_UP && - (avctx->codec->update_thread_context || (!avctx->thread_safe_callbacks && ( -#if FF_API_GET_BUFFER - avctx->get_buffer || -#endif - avctx->get_buffer2 != avcodec_default_get_buffer2)))) { - return 0; - } - return 1; -} - -static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int flags) -{ - PerThreadContext *p = avctx->thread_opaque; - int err; - - f->owner = avctx; - - ff_init_buffer_info(avctx, f->f); - - if (!(avctx->active_thread_type & FF_THREAD_FRAME)) - return ff_get_buffer(avctx, f->f, flags); - - if (p->state != STATE_SETTING_UP && - (avctx->codec->update_thread_context || (!avctx->thread_safe_callbacks && ( -#if FF_API_GET_BUFFER - avctx->get_buffer || -#endif - avctx->get_buffer2 != avcodec_default_get_buffer2)))) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n"); - return -1; - } - - if (avctx->internal->allocate_progress) { - int *progress; - f->progress = av_buffer_alloc(2 * sizeof(int)); - if (!f->progress) { - return AVERROR(ENOMEM); - } - progress = (int*)f->progress->data; - - progress[0] = progress[1] = -1; - } - - pthread_mutex_lock(&p->parent->buffer_mutex); - - if (avctx->thread_safe_callbacks || ( -#if FF_API_GET_BUFFER - !avctx->get_buffer && -#endif - avctx->get_buffer2 == avcodec_default_get_buffer2)) { - err = ff_get_buffer(avctx, f->f, flags); - } else { - pthread_mutex_lock(&p->progress_mutex); - p->requested_frame = f->f; - p->requested_flags = flags; - p->state = STATE_GET_BUFFER; - pthread_cond_broadcast(&p->progress_cond); - - while (p->state != STATE_SETTING_UP) - pthread_cond_wait(&p->progress_cond, &p->progress_mutex); - - err = p->result; - - pthread_mutex_unlock(&p->progress_mutex); - - if (!avctx->codec->update_thread_context) - ff_thread_finish_setup(avctx); - } - - if (err) - av_buffer_unref(&f->progress); - - pthread_mutex_unlock(&p->parent->buffer_mutex); - - return err; -} - -int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags) -{ - int ret = thread_get_buffer_internal(avctx, f, flags); - if (ret < 0) - av_log(avctx, AV_LOG_ERROR, "thread_get_buffer() failed\n"); - return ret; -} - -void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f) -{ - PerThreadContext *p = avctx->thread_opaque; - FrameThreadContext *fctx; - AVFrame *dst, *tmp; - int can_direct_free = !(avctx->active_thread_type & FF_THREAD_FRAME) || - avctx->thread_safe_callbacks || - ( -#if FF_API_GET_BUFFER - !avctx->get_buffer && -#endif - avctx->get_buffer2 == avcodec_default_get_buffer2); - - if (!f->f->data[0]) - return; - - if (avctx->debug & FF_DEBUG_BUFFERS) - av_log(avctx, AV_LOG_DEBUG, "thread_release_buffer called on pic %p\n", f); - - av_buffer_unref(&f->progress); - f->owner = NULL; - - if (can_direct_free) { - av_frame_unref(f->f); - return; - } - - fctx = p->parent; - pthread_mutex_lock(&fctx->buffer_mutex); - - if (p->num_released_buffers + 1 >= INT_MAX / sizeof(*p->released_buffers)) - goto fail; - tmp = av_fast_realloc(p->released_buffers, &p->released_buffers_allocated, - (p->num_released_buffers + 1) * - sizeof(*p->released_buffers)); - if (!tmp) - goto fail; - p->released_buffers = tmp; - - dst = &p->released_buffers[p->num_released_buffers]; - av_frame_move_ref(dst, f->f); - - p->num_released_buffers++; - -fail: - pthread_mutex_unlock(&fctx->buffer_mutex); -} /** * Set the threading algorithms used. @@ -1106,23 +69,12 @@ static void validate_thread_parameters(AVCodecContext *avctx) int ff_thread_init(AVCodecContext *avctx) { - if (avctx->thread_opaque) { - av_log(avctx, AV_LOG_ERROR, "avcodec_thread_init is ignored after avcodec_open\n"); - return -1; - } - -#if HAVE_W32THREADS - w32thread_init(); -#endif + validate_thread_parameters(avctx); - if (avctx->codec) { - validate_thread_parameters(avctx); - - if (avctx->active_thread_type&FF_THREAD_SLICE) - return thread_init(avctx); - else if (avctx->active_thread_type&FF_THREAD_FRAME) - return frame_thread_init(avctx); - } + if (avctx->active_thread_type&FF_THREAD_SLICE) + return ff_slice_thread_init(avctx); + else if (avctx->active_thread_type&FF_THREAD_FRAME) + return ff_frame_thread_init(avctx); return 0; } @@ -1130,7 +82,7 @@ int ff_thread_init(AVCodecContext *avctx) void ff_thread_free(AVCodecContext *avctx) { if (avctx->active_thread_type&FF_THREAD_FRAME) - frame_thread_free(avctx, avctx->thread_count); + ff_frame_thread_free(avctx, avctx->thread_count); else - thread_free(avctx); + ff_slice_thread_free(avctx); } diff --git a/ffmpeg/libavcodec/ptx.c b/ffmpeg/libavcodec/ptx.c index 37135c5..8c3abd7 100644 --- a/ffmpeg/libavcodec/ptx.c +++ b/ffmpeg/libavcodec/ptx.c @@ -55,10 +55,9 @@ static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, buf += offset; - if ((ret = av_image_check_size(w, h, 0, avctx)) < 0) + if ((ret = ff_set_dimensions(avctx, w, h)) < 0) return ret; - if (w != avctx->width || h != avctx->height) - avcodec_set_dimensions(avctx, w, h); + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) return ret; @@ -85,9 +84,9 @@ static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVCodec ff_ptx_decoder = { .name = "ptx", + .long_name = NULL_IF_CONFIG_SMALL("V.Flash PTX image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PTX, .decode = ptx_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("V.Flash PTX image"), }; diff --git a/ffmpeg/libavcodec/put_bits.h b/ffmpeg/libavcodec/put_bits.h index 7320443..e2c4a61 100644 --- a/ffmpeg/libavcodec/put_bits.h +++ b/ffmpeg/libavcodec/put_bits.h @@ -75,6 +75,14 @@ static inline int put_bits_count(PutBitContext *s) return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left; } +/** + * @return the number of bits available in the bitstream. + */ +static inline int put_bits_left(PutBitContext* s) +{ + return (s->buf_end - s->buf_ptr) * 8 - 32 + s->bit_left; +} + /** * Pad the end of the output stream with zeros. */ diff --git a/ffmpeg/libavcodec/qcelpdec.c b/ffmpeg/libavcodec/qcelpdec.c index f8fe85d..9650711 100644 --- a/ffmpeg/libavcodec/qcelpdec.c +++ b/ffmpeg/libavcodec/qcelpdec.c @@ -29,6 +29,7 @@ #include +#include "libavutil/avassert.h" #include "libavutil/channel_layout.h" #include "libavutil/float_dsp.h" #include "avcodec.h" @@ -40,9 +41,6 @@ #include "acelp_vectors.h" #include "lsp.h" -#undef NDEBUG -#include - typedef enum { I_F_Q = -1, /**< insufficient frame quality */ SILENCE, @@ -94,7 +92,7 @@ static av_cold int qcelp_decode_init(AVCodecContext *avctx) avctx->sample_fmt = AV_SAMPLE_FMT_FLT; for (i = 0; i < 10; i++) - q->prev_lspf[i] = (i + 1) / 11.; + q->prev_lspf[i] = (i + 1) / 11.0; return 0; } @@ -135,7 +133,7 @@ static int decode_lspf(QCELPContext *q, float *lspf) } else { erasure_coeff = QCELP_LSP_OCTAVE_PREDICTOR; - assert(q->bitrate == I_F_Q); + av_assert2(q->bitrate == I_F_Q); if (q->erasure_count > 1) erasure_coeff *= q->erasure_count < 4 ? 0.9 : 0.7; @@ -162,7 +160,7 @@ static int decode_lspf(QCELPContext *q, float *lspf) } else { q->octave_count = 0; - tmp_lspf = 0.; + tmp_lspf = 0.0; for (i = 0; i < 5; i++) { lspf[2 * i + 0] = tmp_lspf += qcelp_lspvq[i][q->frame.lspv[i]][0] * 0.0001; lspf[2 * i + 1] = tmp_lspf += qcelp_lspvq[i][q->frame.lspv[i]][1] * 0.0001; @@ -239,7 +237,7 @@ static void decode_gain_and_index(QCELPContext *q, float *gain) av_clip((q->prev_g1[0] + q->prev_g1[1]) / 2 - 5, 0, 54); subframes_count = 8; } else { - assert(q->bitrate == I_F_Q); + av_assert2(q->bitrate == I_F_Q); g1[0] = q->prev_g1[1]; switch (q->erasure_count) { @@ -434,7 +432,7 @@ static const float *do_pitchfilter(float memory[303], const float v_in[160], v_lag = memory + 143 + 40 * i - lag[i]; for (v_len = v_in + 40; v_in < v_len; v_in++) { if (pfrac[i]) { // If it is a fractional lag... - for (j = 0, *v_out = 0.; j < 4; j++) + for (j = 0, *v_out = 0.0; j < 4; j++) *v_out += qcelp_hammsinc_table[j] * (v_lag[j - 4] + v_lag[3 - j]); } else *v_out = *v_lag; @@ -486,7 +484,7 @@ static void apply_pitch_filters(QCELPContext *q, float *cdn_vector) else max_pitch_gain = 0.0; } else { - assert(q->bitrate == SILENCE); + av_assert2(q->bitrate == SILENCE); max_pitch_gain = 1.0; } for (i = 0; i < 4; i++) @@ -787,11 +785,11 @@ erasure: AVCodec ff_qcelp_decoder = { .name = "qcelp", + .long_name = NULL_IF_CONFIG_SMALL("QCELP / PureVoice"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_QCELP, .init = qcelp_decode_init, .decode = qcelp_decode_frame, .capabilities = CODEC_CAP_DR1, .priv_data_size = sizeof(QCELPContext), - .long_name = NULL_IF_CONFIG_SMALL("QCELP / PureVoice"), }; diff --git a/ffmpeg/libavcodec/qdm2.c b/ffmpeg/libavcodec/qdm2.c index 108c327..bf830db 100644 --- a/ffmpeg/libavcodec/qdm2.c +++ b/ffmpeg/libavcodec/qdm2.c @@ -216,121 +216,154 @@ static const uint16_t qdm2_vlc_offs[] = { 0,260,566,598,894,1166,1230,1294,1678,1950,2214,2278,2310,2570,2834,3124,3448,3838, }; +static const int switchtable[23] = { + 0, 5, 1, 5, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 3, 5, 5, 5, 5, 5, 4 +}; + static av_cold void qdm2_init_vlc(void) { - static int vlcs_initialized = 0; static VLC_TYPE qdm2_table[3838][2]; - if (!vlcs_initialized) { - - vlc_tab_level.table = &qdm2_table[qdm2_vlc_offs[0]]; - vlc_tab_level.table_allocated = qdm2_vlc_offs[1] - qdm2_vlc_offs[0]; - init_vlc (&vlc_tab_level, 8, 24, - vlc_tab_level_huffbits, 1, 1, - vlc_tab_level_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlc_tab_diff.table = &qdm2_table[qdm2_vlc_offs[1]]; - vlc_tab_diff.table_allocated = qdm2_vlc_offs[2] - qdm2_vlc_offs[1]; - init_vlc (&vlc_tab_diff, 8, 37, - vlc_tab_diff_huffbits, 1, 1, - vlc_tab_diff_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlc_tab_run.table = &qdm2_table[qdm2_vlc_offs[2]]; - vlc_tab_run.table_allocated = qdm2_vlc_offs[3] - qdm2_vlc_offs[2]; - init_vlc (&vlc_tab_run, 5, 6, - vlc_tab_run_huffbits, 1, 1, - vlc_tab_run_huffcodes, 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - fft_level_exp_alt_vlc.table = &qdm2_table[qdm2_vlc_offs[3]]; - fft_level_exp_alt_vlc.table_allocated = qdm2_vlc_offs[4] - qdm2_vlc_offs[3]; - init_vlc (&fft_level_exp_alt_vlc, 8, 28, - fft_level_exp_alt_huffbits, 1, 1, - fft_level_exp_alt_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - - fft_level_exp_vlc.table = &qdm2_table[qdm2_vlc_offs[4]]; - fft_level_exp_vlc.table_allocated = qdm2_vlc_offs[5] - qdm2_vlc_offs[4]; - init_vlc (&fft_level_exp_vlc, 8, 20, - fft_level_exp_huffbits, 1, 1, - fft_level_exp_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - fft_stereo_exp_vlc.table = &qdm2_table[qdm2_vlc_offs[5]]; - fft_stereo_exp_vlc.table_allocated = qdm2_vlc_offs[6] - qdm2_vlc_offs[5]; - init_vlc (&fft_stereo_exp_vlc, 6, 7, - fft_stereo_exp_huffbits, 1, 1, - fft_stereo_exp_huffcodes, 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - fft_stereo_phase_vlc.table = &qdm2_table[qdm2_vlc_offs[6]]; - fft_stereo_phase_vlc.table_allocated = qdm2_vlc_offs[7] - qdm2_vlc_offs[6]; - init_vlc (&fft_stereo_phase_vlc, 6, 9, - fft_stereo_phase_huffbits, 1, 1, - fft_stereo_phase_huffcodes, 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlc_tab_tone_level_idx_hi1.table = &qdm2_table[qdm2_vlc_offs[7]]; - vlc_tab_tone_level_idx_hi1.table_allocated = qdm2_vlc_offs[8] - qdm2_vlc_offs[7]; - init_vlc (&vlc_tab_tone_level_idx_hi1, 8, 20, - vlc_tab_tone_level_idx_hi1_huffbits, 1, 1, - vlc_tab_tone_level_idx_hi1_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlc_tab_tone_level_idx_mid.table = &qdm2_table[qdm2_vlc_offs[8]]; - vlc_tab_tone_level_idx_mid.table_allocated = qdm2_vlc_offs[9] - qdm2_vlc_offs[8]; - init_vlc (&vlc_tab_tone_level_idx_mid, 8, 24, - vlc_tab_tone_level_idx_mid_huffbits, 1, 1, - vlc_tab_tone_level_idx_mid_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlc_tab_tone_level_idx_hi2.table = &qdm2_table[qdm2_vlc_offs[9]]; - vlc_tab_tone_level_idx_hi2.table_allocated = qdm2_vlc_offs[10] - qdm2_vlc_offs[9]; - init_vlc (&vlc_tab_tone_level_idx_hi2, 8, 24, - vlc_tab_tone_level_idx_hi2_huffbits, 1, 1, - vlc_tab_tone_level_idx_hi2_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlc_tab_type30.table = &qdm2_table[qdm2_vlc_offs[10]]; - vlc_tab_type30.table_allocated = qdm2_vlc_offs[11] - qdm2_vlc_offs[10]; - init_vlc (&vlc_tab_type30, 6, 9, - vlc_tab_type30_huffbits, 1, 1, - vlc_tab_type30_huffcodes, 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlc_tab_type34.table = &qdm2_table[qdm2_vlc_offs[11]]; - vlc_tab_type34.table_allocated = qdm2_vlc_offs[12] - qdm2_vlc_offs[11]; - init_vlc (&vlc_tab_type34, 5, 10, - vlc_tab_type34_huffbits, 1, 1, - vlc_tab_type34_huffcodes, 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlc_tab_fft_tone_offset[0].table = &qdm2_table[qdm2_vlc_offs[12]]; - vlc_tab_fft_tone_offset[0].table_allocated = qdm2_vlc_offs[13] - qdm2_vlc_offs[12]; - init_vlc (&vlc_tab_fft_tone_offset[0], 8, 23, - vlc_tab_fft_tone_offset_0_huffbits, 1, 1, - vlc_tab_fft_tone_offset_0_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlc_tab_fft_tone_offset[1].table = &qdm2_table[qdm2_vlc_offs[13]]; - vlc_tab_fft_tone_offset[1].table_allocated = qdm2_vlc_offs[14] - qdm2_vlc_offs[13]; - init_vlc (&vlc_tab_fft_tone_offset[1], 8, 28, - vlc_tab_fft_tone_offset_1_huffbits, 1, 1, - vlc_tab_fft_tone_offset_1_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlc_tab_fft_tone_offset[2].table = &qdm2_table[qdm2_vlc_offs[14]]; - vlc_tab_fft_tone_offset[2].table_allocated = qdm2_vlc_offs[15] - qdm2_vlc_offs[14]; - init_vlc (&vlc_tab_fft_tone_offset[2], 8, 32, - vlc_tab_fft_tone_offset_2_huffbits, 1, 1, - vlc_tab_fft_tone_offset_2_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlc_tab_fft_tone_offset[3].table = &qdm2_table[qdm2_vlc_offs[15]]; - vlc_tab_fft_tone_offset[3].table_allocated = qdm2_vlc_offs[16] - qdm2_vlc_offs[15]; - init_vlc (&vlc_tab_fft_tone_offset[3], 8, 35, - vlc_tab_fft_tone_offset_3_huffbits, 1, 1, - vlc_tab_fft_tone_offset_3_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlc_tab_fft_tone_offset[4].table = &qdm2_table[qdm2_vlc_offs[16]]; - vlc_tab_fft_tone_offset[4].table_allocated = qdm2_vlc_offs[17] - qdm2_vlc_offs[16]; - init_vlc (&vlc_tab_fft_tone_offset[4], 8, 38, - vlc_tab_fft_tone_offset_4_huffbits, 1, 1, - vlc_tab_fft_tone_offset_4_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlcs_initialized=1; - } + vlc_tab_level.table = &qdm2_table[qdm2_vlc_offs[0]]; + vlc_tab_level.table_allocated = qdm2_vlc_offs[1] - qdm2_vlc_offs[0]; + init_vlc(&vlc_tab_level, 8, 24, + vlc_tab_level_huffbits, 1, 1, + vlc_tab_level_huffcodes, 2, 2, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + + vlc_tab_diff.table = &qdm2_table[qdm2_vlc_offs[1]]; + vlc_tab_diff.table_allocated = qdm2_vlc_offs[2] - qdm2_vlc_offs[1]; + init_vlc(&vlc_tab_diff, 8, 37, + vlc_tab_diff_huffbits, 1, 1, + vlc_tab_diff_huffcodes, 2, 2, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + + vlc_tab_run.table = &qdm2_table[qdm2_vlc_offs[2]]; + vlc_tab_run.table_allocated = qdm2_vlc_offs[3] - qdm2_vlc_offs[2]; + init_vlc(&vlc_tab_run, 5, 6, + vlc_tab_run_huffbits, 1, 1, + vlc_tab_run_huffcodes, 1, 1, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + + fft_level_exp_alt_vlc.table = &qdm2_table[qdm2_vlc_offs[3]]; + fft_level_exp_alt_vlc.table_allocated = qdm2_vlc_offs[4] - + qdm2_vlc_offs[3]; + init_vlc(&fft_level_exp_alt_vlc, 8, 28, + fft_level_exp_alt_huffbits, 1, 1, + fft_level_exp_alt_huffcodes, 2, 2, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + + fft_level_exp_vlc.table = &qdm2_table[qdm2_vlc_offs[4]]; + fft_level_exp_vlc.table_allocated = qdm2_vlc_offs[5] - qdm2_vlc_offs[4]; + init_vlc(&fft_level_exp_vlc, 8, 20, + fft_level_exp_huffbits, 1, 1, + fft_level_exp_huffcodes, 2, 2, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + + fft_stereo_exp_vlc.table = &qdm2_table[qdm2_vlc_offs[5]]; + fft_stereo_exp_vlc.table_allocated = qdm2_vlc_offs[6] - + qdm2_vlc_offs[5]; + init_vlc(&fft_stereo_exp_vlc, 6, 7, + fft_stereo_exp_huffbits, 1, 1, + fft_stereo_exp_huffcodes, 1, 1, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + + fft_stereo_phase_vlc.table = &qdm2_table[qdm2_vlc_offs[6]]; + fft_stereo_phase_vlc.table_allocated = qdm2_vlc_offs[7] - + qdm2_vlc_offs[6]; + init_vlc(&fft_stereo_phase_vlc, 6, 9, + fft_stereo_phase_huffbits, 1, 1, + fft_stereo_phase_huffcodes, 1, 1, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + + vlc_tab_tone_level_idx_hi1.table = + &qdm2_table[qdm2_vlc_offs[7]]; + vlc_tab_tone_level_idx_hi1.table_allocated = qdm2_vlc_offs[8] - + qdm2_vlc_offs[7]; + init_vlc(&vlc_tab_tone_level_idx_hi1, 8, 20, + vlc_tab_tone_level_idx_hi1_huffbits, 1, 1, + vlc_tab_tone_level_idx_hi1_huffcodes, 2, 2, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + + vlc_tab_tone_level_idx_mid.table = + &qdm2_table[qdm2_vlc_offs[8]]; + vlc_tab_tone_level_idx_mid.table_allocated = qdm2_vlc_offs[9] - + qdm2_vlc_offs[8]; + init_vlc(&vlc_tab_tone_level_idx_mid, 8, 24, + vlc_tab_tone_level_idx_mid_huffbits, 1, 1, + vlc_tab_tone_level_idx_mid_huffcodes, 2, 2, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + + vlc_tab_tone_level_idx_hi2.table = + &qdm2_table[qdm2_vlc_offs[9]]; + vlc_tab_tone_level_idx_hi2.table_allocated = qdm2_vlc_offs[10] - + qdm2_vlc_offs[9]; + init_vlc(&vlc_tab_tone_level_idx_hi2, 8, 24, + vlc_tab_tone_level_idx_hi2_huffbits, 1, 1, + vlc_tab_tone_level_idx_hi2_huffcodes, 2, 2, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + + vlc_tab_type30.table = &qdm2_table[qdm2_vlc_offs[10]]; + vlc_tab_type30.table_allocated = qdm2_vlc_offs[11] - qdm2_vlc_offs[10]; + init_vlc(&vlc_tab_type30, 6, 9, + vlc_tab_type30_huffbits, 1, 1, + vlc_tab_type30_huffcodes, 1, 1, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + + vlc_tab_type34.table = &qdm2_table[qdm2_vlc_offs[11]]; + vlc_tab_type34.table_allocated = qdm2_vlc_offs[12] - qdm2_vlc_offs[11]; + init_vlc(&vlc_tab_type34, 5, 10, + vlc_tab_type34_huffbits, 1, 1, + vlc_tab_type34_huffcodes, 1, 1, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + + vlc_tab_fft_tone_offset[0].table = + &qdm2_table[qdm2_vlc_offs[12]]; + vlc_tab_fft_tone_offset[0].table_allocated = qdm2_vlc_offs[13] - + qdm2_vlc_offs[12]; + init_vlc(&vlc_tab_fft_tone_offset[0], 8, 23, + vlc_tab_fft_tone_offset_0_huffbits, 1, 1, + vlc_tab_fft_tone_offset_0_huffcodes, 2, 2, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + + vlc_tab_fft_tone_offset[1].table = + &qdm2_table[qdm2_vlc_offs[13]]; + vlc_tab_fft_tone_offset[1].table_allocated = qdm2_vlc_offs[14] - + qdm2_vlc_offs[13]; + init_vlc(&vlc_tab_fft_tone_offset[1], 8, 28, + vlc_tab_fft_tone_offset_1_huffbits, 1, 1, + vlc_tab_fft_tone_offset_1_huffcodes, 2, 2, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + + vlc_tab_fft_tone_offset[2].table = + &qdm2_table[qdm2_vlc_offs[14]]; + vlc_tab_fft_tone_offset[2].table_allocated = qdm2_vlc_offs[15] - + qdm2_vlc_offs[14]; + init_vlc(&vlc_tab_fft_tone_offset[2], 8, 32, + vlc_tab_fft_tone_offset_2_huffbits, 1, 1, + vlc_tab_fft_tone_offset_2_huffcodes, 2, 2, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + + vlc_tab_fft_tone_offset[3].table = + &qdm2_table[qdm2_vlc_offs[15]]; + vlc_tab_fft_tone_offset[3].table_allocated = qdm2_vlc_offs[16] - + qdm2_vlc_offs[15]; + init_vlc(&vlc_tab_fft_tone_offset[3], 8, 35, + vlc_tab_fft_tone_offset_3_huffbits, 1, 1, + vlc_tab_fft_tone_offset_3_huffcodes, 2, 2, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + + vlc_tab_fft_tone_offset[4].table = + &qdm2_table[qdm2_vlc_offs[16]]; + vlc_tab_fft_tone_offset[4].table_allocated = qdm2_vlc_offs[17] - + qdm2_vlc_offs[16]; + init_vlc(&vlc_tab_fft_tone_offset[4], 8, 38, + vlc_tab_fft_tone_offset_4_huffbits, 1, 1, + vlc_tab_fft_tone_offset_4_huffcodes, 2, 2, + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); } -static int qdm2_get_vlc (GetBitContext *gb, VLC *vlc, int flag, int depth) +static int qdm2_get_vlc(GetBitContext *gb, VLC *vlc, int flag, int depth) { int value; @@ -338,7 +371,7 @@ static int qdm2_get_vlc (GetBitContext *gb, VLC *vlc, int flag, int depth) /* stage-2, 3 bits exponent escape sequence */ if (value-- == 0) - value = get_bits (gb, get_bits (gb, 3) + 1); + value = get_bits(gb, get_bits(gb, 3) + 1); /* stage-3, optional */ if (flag) { @@ -352,22 +385,20 @@ static int qdm2_get_vlc (GetBitContext *gb, VLC *vlc, int flag, int depth) tmp= vlc_stage3_values[value]; if ((value & ~3) > 0) - tmp += get_bits (gb, (value >> 2)); + tmp += get_bits(gb, (value >> 2)); value = tmp; } return value; } - -static int qdm2_get_se_vlc (VLC *vlc, GetBitContext *gb, int depth) +static int qdm2_get_se_vlc(VLC *vlc, GetBitContext *gb, int depth) { - int value = qdm2_get_vlc (gb, vlc, 0, depth); + int value = qdm2_get_vlc(gb, vlc, 0, depth); return (value & 1) ? ((value + 1) >> 1) : -(value >> 1); } - /** * QDM2 checksum * @@ -377,49 +408,50 @@ static int qdm2_get_se_vlc (VLC *vlc, GetBitContext *gb, int depth) * * @return 0 if checksum is OK */ -static uint16_t qdm2_packet_checksum (const uint8_t *data, int length, int value) { +static uint16_t qdm2_packet_checksum(const uint8_t *data, int length, int value) +{ int i; - for (i=0; i < length; i++) + for (i = 0; i < length; i++) value -= data[i]; return (uint16_t)(value & 0xffff); } - /** * Fill a QDM2SubPacket structure with packet type, size, and data pointer. * * @param gb bitreader context * @param sub_packet packet under analysis */ -static void qdm2_decode_sub_packet_header (GetBitContext *gb, QDM2SubPacket *sub_packet) +static void qdm2_decode_sub_packet_header(GetBitContext *gb, + QDM2SubPacket *sub_packet) { - sub_packet->type = get_bits (gb, 8); + sub_packet->type = get_bits(gb, 8); if (sub_packet->type == 0) { sub_packet->size = 0; sub_packet->data = NULL; } else { - sub_packet->size = get_bits (gb, 8); + sub_packet->size = get_bits(gb, 8); - if (sub_packet->type & 0x80) { - sub_packet->size <<= 8; - sub_packet->size |= get_bits (gb, 8); - sub_packet->type &= 0x7f; - } + if (sub_packet->type & 0x80) { + sub_packet->size <<= 8; + sub_packet->size |= get_bits(gb, 8); + sub_packet->type &= 0x7f; + } - if (sub_packet->type == 0x7f) - sub_packet->type |= (get_bits (gb, 8) << 8); + if (sub_packet->type == 0x7f) + sub_packet->type |= (get_bits(gb, 8) << 8); - sub_packet->data = &gb->buffer[get_bits_count(gb) / 8]; // FIXME: this depends on bitreader internal data + // FIXME: this depends on bitreader-internal data + sub_packet->data = &gb->buffer[get_bits_count(gb) / 8]; } - av_log(NULL,AV_LOG_DEBUG,"Subpacket: type=%d size=%d start_offs=%x\n", - sub_packet->type, sub_packet->size, get_bits_count(gb) / 8); + av_log(NULL, AV_LOG_DEBUG, "Subpacket: type=%d size=%d start_offs=%x\n", + sub_packet->type, sub_packet->size, get_bits_count(gb) / 8); } - /** * Return node pointer to first packet of requested type in list. * @@ -427,7 +459,8 @@ static void qdm2_decode_sub_packet_header (GetBitContext *gb, QDM2SubPacket *sub * @param type type of searched subpacket * @return node pointer for subpacket if found, else NULL */ -static QDM2SubPNode* qdm2_search_subpacket_type_in_list (QDM2SubPNode *list, int type) +static QDM2SubPNode *qdm2_search_subpacket_type_in_list(QDM2SubPNode *list, + int type) { while (list != NULL && list->packet != NULL) { if (list->packet->type == type) @@ -437,14 +470,13 @@ static QDM2SubPNode* qdm2_search_subpacket_type_in_list (QDM2SubPNode *list, int return NULL; } - /** * Replace 8 elements with their average value. * Called by qdm2_decode_superblock before starting subblock decoding. * * @param q context */ -static void average_quantized_coeffs (QDM2Context *q) +static void average_quantized_coeffs(QDM2Context *q) { int i, j, n, ch, sum; @@ -461,12 +493,11 @@ static void average_quantized_coeffs (QDM2Context *q) if (sum > 0) sum--; - for (j=0; j < 8; j++) + for (j = 0; j < 8; j++) q->quantized_coeffs[ch][i][j] = sum; } } - /** * Build subband samples with noise weighted by q->tone_level. * Called by synthfilt_build_sb_samples. @@ -474,7 +505,7 @@ static void average_quantized_coeffs (QDM2Context *q) * @param q context * @param sb subband index */ -static void build_sb_samples_from_noise (QDM2Context *q, int sb) +static void build_sb_samples_from_noise(QDM2Context *q, int sb) { int ch, j; @@ -483,14 +514,16 @@ static void build_sb_samples_from_noise (QDM2Context *q, int sb) if (!q->nb_channels) return; - for (ch = 0; ch < q->nb_channels; ch++) + for (ch = 0; ch < q->nb_channels; ch++) { for (j = 0; j < 64; j++) { - q->sb_samples[ch][j * 2][sb] = SB_DITHERING_NOISE(sb,q->noise_idx) * q->tone_level[ch][sb][j]; - q->sb_samples[ch][j * 2 + 1][sb] = SB_DITHERING_NOISE(sb,q->noise_idx) * q->tone_level[ch][sb][j]; + q->sb_samples[ch][j * 2][sb] = + SB_DITHERING_NOISE(sb, q->noise_idx) * q->tone_level[ch][sb][j]; + q->sb_samples[ch][j * 2 + 1][sb] = + SB_DITHERING_NOISE(sb, q->noise_idx) * q->tone_level[ch][sb][j]; } + } } - /** * Called while processing data from subpackets 11 and 12. * Used after making changes to coding_method array. @@ -499,44 +532,65 @@ static void build_sb_samples_from_noise (QDM2Context *q, int sb) * @param channels number of channels * @param coding_method q->coding_method[0][0][0] */ -static void fix_coding_method_array (int sb, int channels, sb_int8_array coding_method) +static int fix_coding_method_array(int sb, int channels, + sb_int8_array coding_method) { - int j,k; + int j, k; int ch; int run, case_val; - static const int switchtable[23] = {0,5,1,5,5,5,5,5,2,5,5,5,5,5,5,5,3,5,5,5,5,5,4}; for (ch = 0; ch < channels; ch++) { for (j = 0; j < 64; ) { - if((coding_method[ch][sb][j] - 8) > 22) { - run = 1; + if (coding_method[ch][sb][j] < 8) + return -1; + if ((coding_method[ch][sb][j] - 8) > 22) { + run = 1; case_val = 8; } else { - switch (switchtable[coding_method[ch][sb][j]-8]) { - case 0: run = 10; case_val = 10; break; - case 1: run = 1; case_val = 16; break; - case 2: run = 5; case_val = 24; break; - case 3: run = 3; case_val = 30; break; - case 4: run = 1; case_val = 30; break; - case 5: run = 1; case_val = 8; break; - default: run = 1; case_val = 8; break; + switch (switchtable[coding_method[ch][sb][j] - 8]) { + case 0: run = 10; + case_val = 10; + break; + case 1: run = 1; + case_val = 16; + break; + case 2: run = 5; + case_val = 24; + break; + case 3: run = 3; + case_val = 30; + break; + case 4: run = 1; + case_val = 30; + break; + case 5: run = 1; + case_val = 8; + break; + default: run = 1; + case_val = 8; + break; } } - for (k = 0; k < run; k++) - if (j + k < 128) - if (coding_method[ch][sb + (j + k) / 64][(j + k) % 64] > coding_method[ch][sb][j]) + for (k = 0; k < run; k++) { + if (j + k < 128) { + if (coding_method[ch][sb + (j + k) / 64][(j + k) % 64] > coding_method[ch][sb][j]) { if (k > 0) { - SAMPLES_NEEDED + SAMPLES_NEEDED //not debugged, almost never used - memset(&coding_method[ch][sb][j + k], case_val, k * sizeof(int8_t)); - memset(&coding_method[ch][sb][j + k], case_val, 3 * sizeof(int8_t)); + memset(&coding_method[ch][sb][j + k], case_val, + k *sizeof(int8_t)); + memset(&coding_method[ch][sb][j + k], case_val, + 3 * sizeof(int8_t)); } + } + } + } j += run; } } + return 0; } - /** * Related to synthesis filter * Called by process_subpacket_10 @@ -544,7 +598,7 @@ static void fix_coding_method_array (int sb, int channels, sb_int8_array coding_ * @param q context * @param flag 1 if called after getting data from subpacket 10, 0 if no subpacket 10 */ -static void fill_tone_level_array (QDM2Context *q, int flag) +static void fill_tone_level_array(QDM2Context *q, int flag) { int i, sb, ch, sb_used; int tmp, tab; @@ -616,16 +670,14 @@ static void fill_tone_level_array (QDM2Context *q, int flag) } } } - - return; } - /** * Related to synthesis filter * Called by process_subpacket_11 * c is built with data from subpacket 11 - * Most of this function is used only if superblock_type_2_3 == 0, never seen it in samples + * Most of this function is used only if superblock_type_2_3 == 0, + * never seen it in samples. * * @param tone_level_idx * @param tone_level_idx_temp @@ -635,9 +687,12 @@ static void fill_tone_level_array (QDM2Context *q, int flag) * @param superblocktype_2_3 flag based on superblock packet type * @param cm_table_select q->cm_table_select */ -static void fill_coding_method_array (sb_int8_array tone_level_idx, sb_int8_array tone_level_idx_temp, - sb_int8_array coding_method, int nb_channels, - int c, int superblocktype_2_3, int cm_table_select) +static void fill_coding_method_array(sb_int8_array tone_level_idx, + sb_int8_array tone_level_idx_temp, + sb_int8_array coding_method, + int nb_channels, + int c, int superblocktype_2_3, + int cm_table_select) { int ch, sb, j; int tmp, acc, esp_40, comp; @@ -744,15 +799,14 @@ static void fill_coding_method_array (sb_int8_array tone_level_idx, sb_int8_arra for (j = 0; j < 64; j++) coding_method[ch][sb][j] = coding_method_table[cm_table_select][sb]; } - - return; } - /** * - * Called by process_subpacket_11 to process more data from subpacket 11 with sb 0-8 - * Called by process_subpacket_12 to process data from subpacket 12 with sb 8-sb_used + * Called by process_subpacket_11 to process more data from subpacket 11 + * with sb 0-8. + * Called by process_subpacket_12 to process data from subpacket 12 with + * sb 8-sb_used. * * @param q context * @param gb bitreader context @@ -760,26 +814,26 @@ static void fill_coding_method_array (sb_int8_array tone_level_idx, sb_int8_arra * @param sb_min lower subband processed (sb_min included) * @param sb_max higher subband processed (sb_max excluded) */ -static int synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int length, int sb_min, int sb_max) +static int synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb, + int length, int sb_min, int sb_max) { int sb, j, k, n, ch, run, channels; - int joined_stereo, zero_encoding, chs; + int joined_stereo, zero_encoding; int type34_first; float type34_div = 0; float type34_predictor; - float samples[10], sign_bits[16]; + float samples[10]; + int sign_bits[16] = {0}; if (length == 0) { // If no data use noise for (sb=sb_min; sb < sb_max; sb++) - build_sb_samples_from_noise (q, sb); + build_sb_samples_from_noise(q, sb); return 0; } for (sb = sb_min; sb < sb_max; sb++) { - FIX_NOISE_IDX(q->noise_idx); - channels = q->nb_channels; if (q->nb_channels <= 1 || sb < 12) @@ -787,27 +841,28 @@ static int synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int le else if (sb >= 24) joined_stereo = 1; else - joined_stereo = (get_bits_left(gb) >= 1) ? get_bits1 (gb) : 0; + joined_stereo = (get_bits_left(gb) >= 1) ? get_bits1(gb) : 0; if (joined_stereo) { if (get_bits_left(gb) >= 16) for (j = 0; j < 16; j++) - sign_bits[j] = get_bits1 (gb); - - if (q->coding_method[0][sb][0] <= 0) { - av_log(NULL, AV_LOG_ERROR, "coding method invalid\n"); - return AVERROR_INVALIDDATA; - } + sign_bits[j] = get_bits1(gb); for (j = 0; j < 64; j++) if (q->coding_method[1][sb][j] > q->coding_method[0][sb][j]) q->coding_method[0][sb][j] = q->coding_method[1][sb][j]; - fix_coding_method_array(sb, q->nb_channels, q->coding_method); + if (fix_coding_method_array(sb, q->nb_channels, + q->coding_method)) { + av_log(NULL, AV_LOG_ERROR, "coding method invalid\n"); + build_sb_samples_from_noise(q, sb); + continue; + } channels = 1; } for (ch = 0; ch < channels; ch++) { + FIX_NOISE_IDX(q->noise_idx); zero_encoding = (get_bits_left(gb) >= 1) ? get_bits1(gb) : 0; type34_predictor = 0.0; type34_first = 1; @@ -940,16 +995,18 @@ static int synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int le } if (joined_stereo) { - float tmp[10][MPA_MAX_CHANNELS]; - for (k = 0; k < run; k++) { - tmp[k][0] = samples[k]; - if ((j + k) < 128) - tmp[k][1] = (sign_bits[(j + k) / 8]) ? -samples[k] : samples[k]; + for (k = 0; k < run && j + k < 128; k++) { + q->sb_samples[0][j + k][sb] = + q->tone_level[0][sb][(j + k) / 2] * samples[k]; + if (q->nb_channels == 2) { + if (sign_bits[(j + k) / 8]) + q->sb_samples[1][j + k][sb] = + q->tone_level[1][sb][(j + k) / 2] * -samples[k]; + else + q->sb_samples[1][j + k][sb] = + q->tone_level[1][sb][(j + k) / 2] * samples[k]; + } } - for (chs = 0; chs < q->nb_channels; chs++) - for (k = 0; k < run; k++) - if ((j + k) < 128) - q->sb_samples[chs][j + k][sb] = q->tone_level[chs][sb][((j + k)/2)] * tmp[k][chs]; } else { for (k = 0; k < run; k++) if ((j + k) < 128) @@ -963,16 +1020,18 @@ static int synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int le return 0; } - /** - * Init the first element of a channel in quantized_coeffs with data from packet 10 (quantized_coeffs[ch][0]). - * This is similar to process_subpacket_9, but for a single channel and for element [0] + * Init the first element of a channel in quantized_coeffs with data + * from packet 10 (quantized_coeffs[ch][0]). + * This is similar to process_subpacket_9, but for a single channel + * and for element [0] * same VLC tables as process_subpacket_9 are used. * * @param quantized_coeffs pointer to quantized_coeffs[ch][0] * @param gb bitreader context */ -static int init_quantized_coeffs_elem0 (int8_t *quantized_coeffs, GetBitContext *gb) +static int init_quantized_coeffs_elem0(int8_t *quantized_coeffs, + GetBitContext *gb) { int i, k, run, level, diff; @@ -1003,16 +1062,16 @@ static int init_quantized_coeffs_elem0 (int8_t *quantized_coeffs, GetBitContext return 0; } - /** * Related to synthesis filter, process data from packet 10 * Init part of quantized_coeffs via function init_quantized_coeffs_elem0 - * Init tone_level_idx_hi1, tone_level_idx_hi2, tone_level_idx_mid with data from packet 10 + * Init tone_level_idx_hi1, tone_level_idx_hi2, tone_level_idx_mid with + * data from packet 10 * * @param q context * @param gb bitreader context */ -static void init_tone_level_dequantization (QDM2Context *q, GetBitContext *gb) +static void init_tone_level_dequantization(QDM2Context *q, GetBitContext *gb) { int sb, j, k, n, ch; @@ -1075,32 +1134,32 @@ static void init_tone_level_dequantization (QDM2Context *q, GetBitContext *gb) * @param q context * @param node pointer to node with packet */ -static int process_subpacket_9 (QDM2Context *q, QDM2SubPNode *node) +static int process_subpacket_9(QDM2Context *q, QDM2SubPNode *node) { GetBitContext gb; int i, j, k, n, ch, run, level, diff; - init_get_bits(&gb, node->packet->data, node->packet->size*8); + init_get_bits(&gb, node->packet->data, node->packet->size * 8); - n = coeff_per_sb_for_avg[q->coeff_per_sb_select][QDM2_SB_USED(q->sub_sampling) - 1] + 1; // same as averagesomething function + n = coeff_per_sb_for_avg[q->coeff_per_sb_select][QDM2_SB_USED(q->sub_sampling) - 1] + 1; for (i = 1; i < n; i++) - for (ch=0; ch < q->nb_channels; ch++) { + for (ch = 0; ch < q->nb_channels; ch++) { level = qdm2_get_vlc(&gb, &vlc_tab_level, 0, 2); q->quantized_coeffs[ch][i][0] = level; for (j = 0; j < (8 - 1); ) { - run = qdm2_get_vlc(&gb, &vlc_tab_run, 0, 1) + 1; + run = qdm2_get_vlc(&gb, &vlc_tab_run, 0, 1) + 1; diff = qdm2_get_se_vlc(&vlc_tab_diff, &gb, 2); if (j + run >= 8) return -1; for (k = 1; k <= run; k++) - q->quantized_coeffs[ch][i][j + k] = (level + ((k*diff) / run)); + q->quantized_coeffs[ch][i][j + k] = (level + ((k * diff) / run)); level += diff; - j += run; + j += run; } } @@ -1111,14 +1170,13 @@ static int process_subpacket_9 (QDM2Context *q, QDM2SubPNode *node) return 0; } - /** * Process subpacket 10 if not null, else * * @param q context * @param node pointer to node with packet */ -static void process_subpacket_10 (QDM2Context *q, QDM2SubPNode *node) +static void process_subpacket_10(QDM2Context *q, QDM2SubPNode *node) { GetBitContext gb; @@ -1131,14 +1189,13 @@ static void process_subpacket_10 (QDM2Context *q, QDM2SubPNode *node) } } - /** * Process subpacket 11 * * @param q context * @param node pointer to node with packet */ -static void process_subpacket_11 (QDM2Context *q, QDM2SubPNode *node) +static void process_subpacket_11(QDM2Context *q, QDM2SubPNode *node) { GetBitContext gb; int length = 0; @@ -1149,24 +1206,25 @@ static void process_subpacket_11 (QDM2Context *q, QDM2SubPNode *node) } if (length >= 32) { - int c = get_bits (&gb, 13); + int c = get_bits(&gb, 13); if (c > 3) - fill_coding_method_array (q->tone_level_idx, q->tone_level_idx_temp, q->coding_method, - q->nb_channels, 8*c, q->superblocktype_2_3, q->cm_table_select); + fill_coding_method_array(q->tone_level_idx, + q->tone_level_idx_temp, q->coding_method, + q->nb_channels, 8 * c, + q->superblocktype_2_3, q->cm_table_select); } synthfilt_build_sb_samples(q, &gb, length, 0, 8); } - /** * Process subpacket 12 * * @param q context * @param node pointer to node with packet */ -static void process_subpacket_12 (QDM2Context *q, QDM2SubPNode *node) +static void process_subpacket_12(QDM2Context *q, QDM2SubPNode *node) { GetBitContext gb; int length = 0; @@ -1185,7 +1243,7 @@ static void process_subpacket_12 (QDM2Context *q, QDM2SubPNode *node) * @param q context * @param list list with synthesis filter packets (list D) */ -static void process_synthesis_subpackets (QDM2Context *q, QDM2SubPNode *list) +static void process_synthesis_subpackets(QDM2Context *q, QDM2SubPNode *list) { QDM2SubPNode *nodes[4]; @@ -1212,13 +1270,12 @@ static void process_synthesis_subpackets (QDM2Context *q, QDM2SubPNode *list) process_subpacket_12(q, NULL); } - /** * Decode superblock, fill packet lists. * * @param q context */ -static void qdm2_decode_super_block (QDM2Context *q) +static void qdm2_decode_super_block(QDM2Context *q) { GetBitContext gb; QDM2SubPacket header, *packet; @@ -1230,33 +1287,33 @@ static void qdm2_decode_super_block (QDM2Context *q) memset(q->tone_level_idx_hi2, 0, sizeof(q->tone_level_idx_hi2)); q->sub_packets_B = 0; - sub_packets_D = 0; + sub_packets_D = 0; average_quantized_coeffs(q); // average elements in quantized_coeffs[max_ch][10][8] - init_get_bits(&gb, q->compressed_data, q->compressed_size*8); + init_get_bits(&gb, q->compressed_data, q->compressed_size * 8); qdm2_decode_sub_packet_header(&gb, &header); if (header.type < 2 || header.type >= 8) { q->has_errors = 1; - av_log(NULL,AV_LOG_ERROR,"bad superblock type\n"); + av_log(NULL, AV_LOG_ERROR, "bad superblock type\n"); return; } q->superblocktype_2_3 = (header.type == 2 || header.type == 3); - packet_bytes = (q->compressed_size - get_bits_count(&gb) / 8); + packet_bytes = (q->compressed_size - get_bits_count(&gb) / 8); - init_get_bits(&gb, header.data, header.size*8); + init_get_bits(&gb, header.data, header.size * 8); if (header.type == 2 || header.type == 4 || header.type == 5) { - int csum = 257 * get_bits(&gb, 8); - csum += 2 * get_bits(&gb, 8); + int csum = 257 * get_bits(&gb, 8); + csum += 2 * get_bits(&gb, 8); csum = qdm2_packet_checksum(q->compressed_data, q->checksum_size, csum); if (csum != 0) { q->has_errors = 1; - av_log(NULL,AV_LOG_ERROR,"bad packet checksum\n"); + av_log(NULL, AV_LOG_ERROR, "bad packet checksum\n"); return; } } @@ -1282,8 +1339,8 @@ static void qdm2_decode_super_block (QDM2Context *q) q->sub_packet_list_A[i - 1].next = &q->sub_packet_list_A[i]; /* seek to next block */ - init_get_bits(&gb, header.data, header.size*8); - skip_bits(&gb, next_index*8); + init_get_bits(&gb, header.data, header.size * 8); + skip_bits(&gb, next_index * 8); if (next_index >= header.size) break; @@ -1292,7 +1349,7 @@ static void qdm2_decode_super_block (QDM2Context *q) /* decode subpacket */ packet = &q->sub_packets[i]; qdm2_decode_sub_packet_header(&gb, packet); - next_index = packet->size + get_bits_count(&gb) / 8; + next_index = packet->size + get_bits_count(&gb) / 8; sub_packet_size = ((packet->size > 0xff) ? 1 : 0) + packet->size + 2; if (packet->type == 0) @@ -1325,13 +1382,13 @@ static void qdm2_decode_super_block (QDM2Context *q) } else if (packet->type == 15) { SAMPLES_NEEDED_2("packet type 15") return; - } else if (packet->type >= 16 && packet->type < 48 && !fft_subpackets[packet->type - 16]) { + } else if (packet->type >= 16 && packet->type < 48 && + !fft_subpackets[packet->type - 16]) { /* packets for FFT */ QDM2_LIST_ADD(q->sub_packet_list_B, q->sub_packets_B, packet); } } // Packet bytes loop -/* **************************************************************** */ if (q->sub_packet_list_D[0].packet != NULL) { process_synthesis_subpackets(q, q->sub_packet_list_D); q->do_synth_filter = 1; @@ -1340,39 +1397,38 @@ static void qdm2_decode_super_block (QDM2Context *q) process_subpacket_11(q, NULL); process_subpacket_12(q, NULL); } -/* **************************************************************** */ } - -static void qdm2_fft_init_coefficient (QDM2Context *q, int sub_packet, - int offset, int duration, int channel, - int exp, int phase) +static void qdm2_fft_init_coefficient(QDM2Context *q, int sub_packet, + int offset, int duration, int channel, + int exp, int phase) { if (q->fft_coefs_min_index[duration] < 0) q->fft_coefs_min_index[duration] = q->fft_coefs_index; - q->fft_coefs[q->fft_coefs_index].sub_packet = ((sub_packet >= 16) ? (sub_packet - 16) : sub_packet); + q->fft_coefs[q->fft_coefs_index].sub_packet = + ((sub_packet >= 16) ? (sub_packet - 16) : sub_packet); q->fft_coefs[q->fft_coefs_index].channel = channel; - q->fft_coefs[q->fft_coefs_index].offset = offset; - q->fft_coefs[q->fft_coefs_index].exp = exp; - q->fft_coefs[q->fft_coefs_index].phase = phase; + q->fft_coefs[q->fft_coefs_index].offset = offset; + q->fft_coefs[q->fft_coefs_index].exp = exp; + q->fft_coefs[q->fft_coefs_index].phase = phase; q->fft_coefs_index++; } - -static void qdm2_fft_decode_tones (QDM2Context *q, int duration, GetBitContext *gb, int b) +static void qdm2_fft_decode_tones(QDM2Context *q, int duration, + GetBitContext *gb, int b) { int channel, stereo, phase, exp; - int local_int_4, local_int_8, stereo_phase, local_int_10; + int local_int_4, local_int_8, stereo_phase, local_int_10; int local_int_14, stereo_exp, local_int_20, local_int_28; int n, offset; - local_int_4 = 0; + local_int_4 = 0; local_int_28 = 0; local_int_20 = 2; - local_int_8 = (4 - duration); + local_int_8 = (4 - duration); local_int_10 = 1 << (q->group_order - duration - 1); - offset = 1; + offset = 1; while (get_bits_left(gb)>0) { if (q->superblocktype_2_3) { @@ -1384,10 +1440,10 @@ static void qdm2_fft_decode_tones (QDM2Context *q, int duration, GetBitContext * } offset = 1; if (n == 0) { - local_int_4 += local_int_10; + local_int_4 += local_int_10; local_int_28 += (1 << local_int_8); } else { - local_int_4 += 8*local_int_10; + local_int_4 += 8 * local_int_10; local_int_28 += (8 << local_int_8); } } @@ -1395,7 +1451,7 @@ static void qdm2_fft_decode_tones (QDM2Context *q, int duration, GetBitContext * } else { offset += qdm2_get_vlc(gb, &vlc_tab_fft_tone_offset[local_int_8], 1, 2); while (offset >= (local_int_10 - 1)) { - offset += (1 - (local_int_10 - 1)); + offset += (1 - (local_int_10 - 1)); local_int_4 += local_int_10; local_int_28 += (1 << local_int_8); } @@ -1410,22 +1466,22 @@ static void qdm2_fft_decode_tones (QDM2Context *q, int duration, GetBitContext * if (q->nb_channels > 1) { channel = get_bits1(gb); - stereo = get_bits1(gb); + stereo = get_bits1(gb); } else { channel = 0; - stereo = 0; + stereo = 0; } - exp = qdm2_get_vlc(gb, (b ? &fft_level_exp_vlc : &fft_level_exp_alt_vlc), 0, 2); + exp = qdm2_get_vlc(gb, (b ? &fft_level_exp_vlc : &fft_level_exp_alt_vlc), 0, 2); exp += q->fft_level_exp[fft_level_index_table[local_int_14]]; - exp = (exp < 0) ? 0 : exp; + exp = (exp < 0) ? 0 : exp; - phase = get_bits(gb, 3); - stereo_exp = 0; + phase = get_bits(gb, 3); + stereo_exp = 0; stereo_phase = 0; if (stereo) { - stereo_exp = (exp - qdm2_get_vlc(gb, &fft_stereo_exp_vlc, 0, 1)); + stereo_exp = (exp - qdm2_get_vlc(gb, &fft_stereo_exp_vlc, 0, 1)); stereo_phase = (phase - qdm2_get_vlc(gb, &fft_stereo_phase_vlc, 0, 1)); if (stereo_phase < 0) stereo_phase += 8; @@ -1434,17 +1490,18 @@ static void qdm2_fft_decode_tones (QDM2Context *q, int duration, GetBitContext * if (q->frequency_range > (local_int_14 + 1)) { int sub_packet = (local_int_20 + local_int_28); - qdm2_fft_init_coefficient(q, sub_packet, offset, duration, channel, exp, phase); + qdm2_fft_init_coefficient(q, sub_packet, offset, duration, + channel, exp, phase); if (stereo) - qdm2_fft_init_coefficient(q, sub_packet, offset, duration, (1 - channel), stereo_exp, stereo_phase); + qdm2_fft_init_coefficient(q, sub_packet, offset, duration, + 1 - channel, + stereo_exp, stereo_phase); } - offset++; } } - -static void qdm2_decode_fft_packets (QDM2Context *q) +static void qdm2_decode_fft_packets(QDM2Context *q) { int i, j, min, max, value, type, unknown_flag; GetBitContext gb; @@ -1454,18 +1511,18 @@ static void qdm2_decode_fft_packets (QDM2Context *q) /* reset minimum indexes for FFT coefficients */ q->fft_coefs_index = 0; - for (i=0; i < 5; i++) + for (i = 0; i < 5; i++) q->fft_coefs_min_index[i] = -1; /* process subpackets ordered by type, largest type first */ for (i = 0, max = 256; i < q->sub_packets_B; i++) { - QDM2SubPacket *packet= NULL; + QDM2SubPacket *packet = NULL; /* find subpacket with largest type less than max */ for (j = 0, min = 0; j < q->sub_packets_B; j++) { value = q->sub_packet_list_B[j].packet->type; if (value > min && value < max) { - min = value; + min = value; packet = q->sub_packet_list_B[j].packet; } } @@ -1476,11 +1533,13 @@ static void qdm2_decode_fft_packets (QDM2Context *q) if (!packet) return; - if (i == 0 && (packet->type < 16 || packet->type >= 48 || fft_subpackets[packet->type - 16])) + if (i == 0 && + (packet->type < 16 || packet->type >= 48 || + fft_subpackets[packet->type - 16])) return; /* decode FFT tones */ - init_get_bits (&gb, packet->data, packet->size*8); + init_get_bits(&gb, packet->data, packet->size * 8); if (packet->type >= 32 && packet->type < 48 && !fft_subpackets[packet->type - 16]) unknown_flag = 1; @@ -1495,13 +1554,13 @@ static void qdm2_decode_fft_packets (QDM2Context *q) if (duration >= 0 && duration < 4) qdm2_fft_decode_tones(q, duration, &gb, unknown_flag); } else if (type == 31) { - for (j=0; j < 4; j++) + for (j = 0; j < 4; j++) qdm2_fft_decode_tones(q, j, &gb, unknown_flag); } else if (type == 46) { - for (j=0; j < 6; j++) + for (j = 0; j < 6; j++) q->fft_level_exp[j] = get_bits(&gb, 6); - for (j=0; j < 4; j++) - qdm2_fft_decode_tones(q, j, &gb, unknown_flag); + for (j = 0; j < 4; j++) + qdm2_fft_decode_tones(q, j, &gb, unknown_flag); } } // Loop on B packets @@ -1516,20 +1575,19 @@ static void qdm2_decode_fft_packets (QDM2Context *q) q->fft_coefs_max_index[j] = q->fft_coefs_index; } - -static void qdm2_fft_generate_tone (QDM2Context *q, FFTTone *tone) +static void qdm2_fft_generate_tone(QDM2Context *q, FFTTone *tone) { - float level, f[6]; - int i; - QDM2Complex c; - const double iscale = 2.0*M_PI / 512.0; + float level, f[6]; + int i; + QDM2Complex c; + const double iscale = 2.0 * M_PI / 512.0; tone->phase += tone->phase_shift; /* calculate current level (maximum amplitude) of tone */ level = fft_tone_envelope_table[tone->duration][tone->time_index] * tone->level; - c.im = level * sin(tone->phase*iscale); - c.re = level * cos(tone->phase*iscale); + c.im = level * sin(tone->phase * iscale); + c.re = level * cos(tone->phase * iscale); /* generate FFT coefficients for tone */ if (tone->duration >= 3 || tone->cutoff >= 3) { @@ -1539,30 +1597,31 @@ static void qdm2_fft_generate_tone (QDM2Context *q, FFTTone *tone) tone->complex[1].re -= c.re; } else { f[1] = -tone->table[4]; - f[0] = tone->table[3] - tone->table[0]; - f[2] = 1.0 - tone->table[2] - tone->table[3]; - f[3] = tone->table[1] + tone->table[4] - 1.0; - f[4] = tone->table[0] - tone->table[1]; - f[5] = tone->table[2]; + f[0] = tone->table[3] - tone->table[0]; + f[2] = 1.0 - tone->table[2] - tone->table[3]; + f[3] = tone->table[1] + tone->table[4] - 1.0; + f[4] = tone->table[0] - tone->table[1]; + f[5] = tone->table[2]; for (i = 0; i < 2; i++) { - tone->complex[fft_cutoff_index_table[tone->cutoff][i]].re += c.re * f[i]; - tone->complex[fft_cutoff_index_table[tone->cutoff][i]].im += c.im *((tone->cutoff <= i) ? -f[i] : f[i]); + tone->complex[fft_cutoff_index_table[tone->cutoff][i]].re += + c.re * f[i]; + tone->complex[fft_cutoff_index_table[tone->cutoff][i]].im += + c.im * ((tone->cutoff <= i) ? -f[i] : f[i]); } for (i = 0; i < 4; i++) { - tone->complex[i].re += c.re * f[i+2]; - tone->complex[i].im += c.im * f[i+2]; + tone->complex[i].re += c.re * f[i + 2]; + tone->complex[i].im += c.im * f[i + 2]; } } /* copy the tone if it has not yet died out */ if (++tone->time_index < ((1 << (5 - tone->duration)) - 1)) { - memcpy(&q->fft_tones[q->fft_tone_end], tone, sizeof(FFTTone)); - q->fft_tone_end = (q->fft_tone_end + 1) % 1000; + memcpy(&q->fft_tones[q->fft_tone_end], tone, sizeof(FFTTone)); + q->fft_tone_end = (q->fft_tone_end + 1) % 1000; } } - -static void qdm2_fft_tone_synthesizer (QDM2Context *q, int sub_packet) +static void qdm2_fft_tone_synthesizer(QDM2Context *q, int sub_packet) { int i, j, ch; const double iscale = 0.25 * M_PI; @@ -1633,29 +1692,27 @@ static void qdm2_fft_tone_synthesizer (QDM2Context *q, int sub_packet) } } - -static void qdm2_calculate_fft (QDM2Context *q, int channel, int sub_packet) +static void qdm2_calculate_fft(QDM2Context *q, int channel, int sub_packet) { const float gain = (q->channels == 1 && q->nb_channels == 2) ? 0.5f : 1.0f; - float *out = q->output_buffer + channel; + float *out = q->output_buffer + channel; int i; q->fft.complex[channel][0].re *= 2.0f; - q->fft.complex[channel][0].im = 0.0f; + q->fft.complex[channel][0].im = 0.0f; q->rdft_ctx.rdft_calc(&q->rdft_ctx, (FFTSample *)q->fft.complex[channel]); /* add samples to output buffer */ for (i = 0; i < FFALIGN(q->fft_size, 8); i++) { out[0] += q->fft.complex[channel][i].re * gain; out[q->channels] += q->fft.complex[channel][i].im * gain; - out += 2 * q->channels; + out += 2 * q->channels; } } - /** * @param q context * @param index subpacket number */ -static void qdm2_synthesis_filter (QDM2Context *q, int index) +static void qdm2_synthesis_filter(QDM2Context *q, int index) { int i, k, ch, sb_used, sub_sampling, dither_state = 0; @@ -1664,7 +1721,7 @@ static void qdm2_synthesis_filter (QDM2Context *q, int index) for (ch = 0; ch < q->channels; ch++) for (i = 0; i < 8; i++) - for (k=sb_used; k < SBLIMIT; k++) + for (k = sb_used; k < SBLIMIT; k++) q->sb_samples[ch][(8 * index) + i][k] = 0; for (ch = 0; ch < q->nb_channels; ch++) { @@ -1672,10 +1729,10 @@ static void qdm2_synthesis_filter (QDM2Context *q, int index) for (i = 0; i < 8; i++) { ff_mpa_synth_filter_float(&q->mpadsp, - q->synth_buf[ch], &(q->synth_buf_offset[ch]), - ff_mpa_synth_window_float, &dither_state, - samples_ptr, q->nb_channels, - q->sb_samples[ch][(8 * index) + i]); + q->synth_buf[ch], &(q->synth_buf_offset[ch]), + ff_mpa_synth_window_float, &dither_state, + samples_ptr, q->nb_channels, + q->sb_samples[ch][(8 * index) + i]); samples_ptr += 32 * q->nb_channels; } } @@ -1688,18 +1745,16 @@ static void qdm2_synthesis_filter (QDM2Context *q, int index) q->output_buffer[q->channels * i + ch] += (1 << 23) * q->samples[q->nb_channels * sub_sampling * i + ch]; } - /** * Init static data (does not depend on specific file) * * @param q context */ -static av_cold void qdm2_init(QDM2Context *q) { - static int initialized = 0; +static av_cold void qdm2_init_static_data(void) { + static int done; - if (initialized != 0) + if(done) return; - initialized = 1; qdm2_init_vlc(); ff_mpa_synth_init_float(ff_mpa_synth_window_float); @@ -1707,10 +1762,9 @@ static av_cold void qdm2_init(QDM2Context *q) { rnd_table_init(); init_noise_samples(); - av_log(NULL, AV_LOG_DEBUG, "init done\n"); + done = 1; } - /** * Init parameters from codec extradata */ @@ -1721,6 +1775,8 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) int extradata_size; int tmp_val, tmp, size; + qdm2_init_static_data(); + /* extradata parsing Structure: @@ -1760,7 +1816,7 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) return -1; } - extradata = avctx->extradata; + extradata = avctx->extradata; extradata_size = avctx->extradata_size; while (extradata_size > 7) { @@ -1862,18 +1918,9 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) if ((tmp * 2240) < avctx->bit_rate) tmp_val = 4; s->cm_table_select = tmp_val; - if (s->sub_sampling == 0) - tmp = 7999; - else - tmp = ((-(s->sub_sampling -1)) & 8000) + 20000; - /* - 0: 7999 -> 0 - 1: 20000 -> 2 - 2: 28000 -> 2 - */ - if (tmp < 8000) + if (avctx->bit_rate <= 8000) s->coeff_per_sb_select = 0; - else if (tmp <= 16000) + else if (avctx->bit_rate < 16000) s->coeff_per_sb_select = 1; else s->coeff_per_sb_select = 2; @@ -1883,18 +1930,19 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "Unknown FFT order (%d), contact the developers!\n", s->fft_order); return -1; } + if (s->fft_size != (1 << (s->fft_order - 1))) { + av_log(avctx, AV_LOG_ERROR, "FFT size %d not power of 2.\n", s->fft_size); + return AVERROR_INVALIDDATA; + } ff_rdft_init(&s->rdft_ctx, s->fft_order, IDFT_C2R); ff_mpadsp_init(&s->mpadsp); - qdm2_init(s); - avctx->sample_fmt = AV_SAMPLE_FMT_S16; return 0; } - static av_cold int qdm2_decode_close(AVCodecContext *avctx) { QDM2Context *s = avctx->priv_data; @@ -1904,8 +1952,7 @@ static av_cold int qdm2_decode_close(AVCodecContext *avctx) return 0; } - -static int qdm2_decode (QDM2Context *q, const uint8_t *in, int16_t *out) +static int qdm2_decode(QDM2Context *q, const uint8_t *in, int16_t *out) { int ch, i; const int frame_size = (q->frame_size * q->channels); @@ -1967,7 +2014,6 @@ static int qdm2_decode (QDM2Context *q, const uint8_t *in, int16_t *out) return 0; } - static int qdm2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { @@ -2000,15 +2046,14 @@ static int qdm2_decode_frame(AVCodecContext *avctx, void *data, return s->checksum_size; } -AVCodec ff_qdm2_decoder = -{ - .name = "qdm2", - .type = AVMEDIA_TYPE_AUDIO, - .id = AV_CODEC_ID_QDM2, - .priv_data_size = sizeof(QDM2Context), - .init = qdm2_decode_init, - .close = qdm2_decode_close, - .decode = qdm2_decode_frame, - .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("QDesign Music Codec 2"), +AVCodec ff_qdm2_decoder = { + .name = "qdm2", + .long_name = NULL_IF_CONFIG_SMALL("QDesign Music Codec 2"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_QDM2, + .priv_data_size = sizeof(QDM2Context), + .init = qdm2_decode_init, + .close = qdm2_decode_close, + .decode = qdm2_decode_frame, + .capabilities = CODEC_CAP_DR1, }; diff --git a/ffmpeg/libavcodec/qdrw.c b/ffmpeg/libavcodec/qdrw.c index 6970099..3f82e5b 100644 --- a/ffmpeg/libavcodec/qdrw.c +++ b/ffmpeg/libavcodec/qdrw.c @@ -142,10 +142,10 @@ static av_cold int decode_init(AVCodecContext *avctx) AVCodec ff_qdraw_decoder = { .name = "qdraw", + .long_name = NULL_IF_CONFIG_SMALL("Apple QuickDraw"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_QDRAW, .init = decode_init, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Apple QuickDraw"), }; diff --git a/ffmpeg/libavcodec/qpeg.c b/ffmpeg/libavcodec/qpeg.c index 6015b7f..94cb5bd 100644 --- a/ffmpeg/libavcodec/qpeg.c +++ b/ffmpeg/libavcodec/qpeg.c @@ -30,7 +30,7 @@ typedef struct QpegContext{ AVCodecContext *avctx; - AVFrame pic, ref; + AVFrame *pic, *ref; uint32_t pal[256]; GetByteContext buffer; } QpegContext; @@ -110,7 +110,7 @@ static const int qpeg_table_w[16] = { 0x00, 0x20, 0x18, 0x08, 0x18, 0x10, 0x20, 0x10, 0x08, 0x10, 0x20, 0x20, 0x08, 0x10, 0x18, 0x04}; /* Decodes delta frames */ -static void qpeg_decode_inter(QpegContext *qctx, uint8_t *dst, +static void av_noinline qpeg_decode_inter(QpegContext *qctx, uint8_t *dst, int stride, int width, int height, int delta, const uint8_t *ctable, uint8_t *refdata) @@ -193,7 +193,7 @@ static void qpeg_decode_inter(QpegContext *qctx, uint8_t *dst, filled = 0; dst -= stride; height--; - if(height < 0) + if (height < 0) break; } } @@ -209,7 +209,7 @@ static void qpeg_decode_inter(QpegContext *qctx, uint8_t *dst, filled = 0; dst -= stride; height--; - if(height < 0) + if (height < 0) break; } } @@ -255,8 +255,8 @@ static int decode_frame(AVCodecContext *avctx, { uint8_t ctable[128]; QpegContext * const a = avctx->priv_data; - AVFrame * p = &a->pic; - AVFrame * ref= &a->ref; + AVFrame * const p = a->pic; + AVFrame * const ref = a->ref; uint8_t* outdata; int delta, ret; const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); @@ -273,26 +273,26 @@ static int decode_frame(AVCodecContext *avctx, if ((ret = ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; - outdata = a->pic.data[0]; + outdata = p->data[0]; bytestream2_skip(&a->buffer, 4); bytestream2_get_buffer(&a->buffer, ctable, 128); bytestream2_skip(&a->buffer, 1); delta = bytestream2_get_byte(&a->buffer); if(delta == 0x10) { - qpeg_decode_intra(a, outdata, a->pic.linesize[0], avctx->width, avctx->height); + qpeg_decode_intra(a, outdata, p->linesize[0], avctx->width, avctx->height); } else { - qpeg_decode_inter(a, outdata, a->pic.linesize[0], avctx->width, avctx->height, delta, ctable, a->ref.data[0]); + qpeg_decode_inter(a, outdata, p->linesize[0], avctx->width, avctx->height, delta, ctable, ref->data[0]); } /* make the palette available on the way out */ if (pal) { - a->pic.palette_has_changed = 1; + p->palette_has_changed = 1; memcpy(a->pal, pal, AVPALETTE_SIZE); } - memcpy(a->pic.data[1], a->pal, AVPALETTE_SIZE); + memcpy(p->data[1], a->pal, AVPALETTE_SIZE); - if ((ret = av_frame_ref(data, &a->pic)) < 0) + if ((ret = av_frame_ref(data, p)) < 0) return ret; *got_frame = 1; @@ -312,34 +312,37 @@ static void decode_flush(AVCodecContext *avctx){ a->pal[i] = 0xFFU<<24 | AV_RL32(pal_src+4*i); } -static av_cold int decode_init(AVCodecContext *avctx){ +static av_cold int decode_end(AVCodecContext *avctx) +{ QpegContext * const a = avctx->priv_data; - avcodec_get_frame_defaults(&a->pic); - avcodec_get_frame_defaults(&a->ref); - a->avctx = avctx; - avctx->pix_fmt= AV_PIX_FMT_PAL8; - - decode_flush(avctx); - - avcodec_get_frame_defaults(&a->pic); + av_frame_free(&a->pic); + av_frame_free(&a->ref); return 0; } -static av_cold int decode_end(AVCodecContext *avctx){ +static av_cold int decode_init(AVCodecContext *avctx){ QpegContext * const a = avctx->priv_data; - AVFrame * const p = &a->pic; - AVFrame * const ref= &a->ref; - av_frame_unref(p); - av_frame_unref(ref); + a->avctx = avctx; + avctx->pix_fmt= AV_PIX_FMT_PAL8; + + decode_flush(avctx); + + a->pic = av_frame_alloc(); + a->ref = av_frame_alloc(); + if (!a->pic || !a->ref) { + decode_end(avctx); + return AVERROR(ENOMEM); + } return 0; } AVCodec ff_qpeg_decoder = { .name = "qpeg", + .long_name = NULL_IF_CONFIG_SMALL("Q-team QPEG"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_QPEG, .priv_data_size = sizeof(QpegContext), @@ -348,5 +351,4 @@ AVCodec ff_qpeg_decoder = { .decode = decode_frame, .flush = decode_flush, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Q-team QPEG"), }; diff --git a/ffmpeg/libavcodec/qtrle.c b/ffmpeg/libavcodec/qtrle.c index c043249..4eeeea4 100644 --- a/ffmpeg/libavcodec/qtrle.c +++ b/ffmpeg/libavcodec/qtrle.c @@ -41,7 +41,7 @@ typedef struct QtrleContext { AVCodecContext *avctx; - AVFrame frame; + AVFrame *frame; GetByteContext g; uint32_t pal[256]; @@ -58,17 +58,17 @@ static void qtrle_decode_1bpp(QtrleContext *s, int row_ptr, int lines_to_change) { int rle_code; int pixel_ptr; - int row_inc = s->frame.linesize[0]; - unsigned char pi0, pi1; /* 2 8-pixel values */ - unsigned char *rgb = s->frame.data[0]; - int pixel_limit = s->frame.linesize[0] * s->avctx->height; + int row_inc = s->frame->linesize[0]; + uint8_t pi0, pi1; /* 2 8-pixel values */ + uint8_t *rgb = s->frame->data[0]; + int pixel_limit = s->frame->linesize[0] * s->avctx->height; int skip; /* skip & 0x80 appears to mean 'start a new line', which can be interpreted * as 'go to next line' during the decoding of a frame but is 'go to first * line' at the beginning. Since we always interpret it as 'go to next line' * in the decoding loop (which makes code simpler/faster), the first line * would not be counted, so we count one more. - * See: https://ffmpeg.org/trac/ffmpeg/ticket/226 + * See: https://trac.ffmpeg.org/ticket/226 * In the following decoding loop, row_ptr will be the position of the * current row. */ @@ -77,7 +77,7 @@ static void qtrle_decode_1bpp(QtrleContext *s, int row_ptr, int lines_to_change) lines_to_change++; while (lines_to_change) { skip = bytestream2_get_byte(&s->g); - rle_code = (signed char)bytestream2_get_byte(&s->g); + rle_code = (int8_t)bytestream2_get_byte(&s->g); if (rle_code == 0) break; if(skip & 0x80) { @@ -110,8 +110,8 @@ static void qtrle_decode_1bpp(QtrleContext *s, int row_ptr, int lines_to_change) rle_code *= 2; CHECK_PIXEL_PTR(rle_code); - while (rle_code--) - rgb[pixel_ptr++] = bytestream2_get_byte(&s->g); + bytestream2_get_buffer(&s->g, &rgb[pixel_ptr], rle_code); + pixel_ptr += rle_code; } } } @@ -121,17 +121,17 @@ static inline void qtrle_decode_2n4bpp(QtrleContext *s, int row_ptr, { int rle_code, i; int pixel_ptr; - int row_inc = s->frame.linesize[0]; - unsigned char pi[16]; /* 16 palette indices */ - unsigned char *rgb = s->frame.data[0]; - int pixel_limit = s->frame.linesize[0] * s->avctx->height; + int row_inc = s->frame->linesize[0]; + uint8_t pi[16]; /* 16 palette indices */ + uint8_t *rgb = s->frame->data[0]; + int pixel_limit = s->frame->linesize[0] * s->avctx->height; int num_pixels = (bpp == 4) ? 8 : 16; while (lines_to_change--) { pixel_ptr = row_ptr + (num_pixels * (bytestream2_get_byte(&s->g) - 1)); CHECK_PIXEL_PTR(0); - while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) { + while ((rle_code = (int8_t)bytestream2_get_byte(&s->g)) != -1) { if (rle_code == 0) { /* there's another skip code in the stream */ pixel_ptr += (num_pixels * (bytestream2_get_byte(&s->g) - 1)); @@ -147,8 +147,8 @@ static inline void qtrle_decode_2n4bpp(QtrleContext *s, int row_ptr, } CHECK_PIXEL_PTR(rle_code * num_pixels); while (rle_code--) { - for (i = 0; i < num_pixels; i++) - rgb[pixel_ptr++] = pi[i]; + memcpy(&rgb[pixel_ptr], &pi, num_pixels); + pixel_ptr += num_pixels; } } else { /* copy the same pixel directly to output 4 times */ @@ -177,16 +177,16 @@ static void qtrle_decode_8bpp(QtrleContext *s, int row_ptr, int lines_to_change) { int rle_code; int pixel_ptr; - int row_inc = s->frame.linesize[0]; - unsigned char pi1, pi2, pi3, pi4; /* 4 palette indexes */ - unsigned char *rgb = s->frame.data[0]; - int pixel_limit = s->frame.linesize[0] * s->avctx->height; + int row_inc = s->frame->linesize[0]; + uint8_t pi1, pi2, pi3, pi4; /* 4 palette indexes */ + uint8_t *rgb = s->frame->data[0]; + int pixel_limit = s->frame->linesize[0] * s->avctx->height; while (lines_to_change--) { pixel_ptr = row_ptr + (4 * (bytestream2_get_byte(&s->g) - 1)); CHECK_PIXEL_PTR(0); - while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) { + while ((rle_code = (int8_t)bytestream2_get_byte(&s->g)) != -1) { if (rle_code == 0) { /* there's another skip code in the stream */ pixel_ptr += (4 * (bytestream2_get_byte(&s->g) - 1)); @@ -214,9 +214,8 @@ static void qtrle_decode_8bpp(QtrleContext *s, int row_ptr, int lines_to_change) rle_code *= 4; CHECK_PIXEL_PTR(rle_code); - while (rle_code--) { - rgb[pixel_ptr++] = bytestream2_get_byte(&s->g); - } + bytestream2_get_buffer(&s->g, &rgb[pixel_ptr], rle_code); + pixel_ptr += rle_code; } } row_ptr += row_inc; @@ -227,16 +226,16 @@ static void qtrle_decode_16bpp(QtrleContext *s, int row_ptr, int lines_to_change { int rle_code; int pixel_ptr; - int row_inc = s->frame.linesize[0]; - unsigned short rgb16; - unsigned char *rgb = s->frame.data[0]; - int pixel_limit = s->frame.linesize[0] * s->avctx->height; + int row_inc = s->frame->linesize[0]; + uint16_t rgb16; + uint8_t *rgb = s->frame->data[0]; + int pixel_limit = s->frame->linesize[0] * s->avctx->height; while (lines_to_change--) { pixel_ptr = row_ptr + (bytestream2_get_byte(&s->g) - 1) * 2; CHECK_PIXEL_PTR(0); - while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) { + while ((rle_code = (int8_t)bytestream2_get_byte(&s->g)) != -1) { if (rle_code == 0) { /* there's another skip code in the stream */ pixel_ptr += (bytestream2_get_byte(&s->g) - 1) * 2; @@ -249,7 +248,7 @@ static void qtrle_decode_16bpp(QtrleContext *s, int row_ptr, int lines_to_change CHECK_PIXEL_PTR(rle_code * 2); while (rle_code--) { - *(unsigned short *)(&rgb[pixel_ptr]) = rgb16; + *(uint16_t *)(&rgb[pixel_ptr]) = rgb16; pixel_ptr += 2; } } else { @@ -258,7 +257,7 @@ static void qtrle_decode_16bpp(QtrleContext *s, int row_ptr, int lines_to_change /* copy pixels directly to output */ while (rle_code--) { rgb16 = bytestream2_get_be16(&s->g); - *(unsigned short *)(&rgb[pixel_ptr]) = rgb16; + *(uint16_t *)(&rgb[pixel_ptr]) = rgb16; pixel_ptr += 2; } } @@ -271,16 +270,16 @@ static void qtrle_decode_24bpp(QtrleContext *s, int row_ptr, int lines_to_change { int rle_code; int pixel_ptr; - int row_inc = s->frame.linesize[0]; - unsigned char r, g, b; - unsigned char *rgb = s->frame.data[0]; - int pixel_limit = s->frame.linesize[0] * s->avctx->height; + int row_inc = s->frame->linesize[0]; + uint8_t r, g, b; + uint8_t *rgb = s->frame->data[0]; + int pixel_limit = s->frame->linesize[0] * s->avctx->height; while (lines_to_change--) { pixel_ptr = row_ptr + (bytestream2_get_byte(&s->g) - 1) * 3; CHECK_PIXEL_PTR(0); - while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) { + while ((rle_code = (int8_t)bytestream2_get_byte(&s->g)) != -1) { if (rle_code == 0) { /* there's another skip code in the stream */ pixel_ptr += (bytestream2_get_byte(&s->g) - 1) * 3; @@ -318,16 +317,16 @@ static void qtrle_decode_32bpp(QtrleContext *s, int row_ptr, int lines_to_change { int rle_code; int pixel_ptr; - int row_inc = s->frame.linesize[0]; + int row_inc = s->frame->linesize[0]; unsigned int argb; - unsigned char *rgb = s->frame.data[0]; - int pixel_limit = s->frame.linesize[0] * s->avctx->height; + uint8_t *rgb = s->frame->data[0]; + int pixel_limit = s->frame->linesize[0] * s->avctx->height; while (lines_to_change--) { pixel_ptr = row_ptr + (bytestream2_get_byte(&s->g) - 1) * 4; CHECK_PIXEL_PTR(0); - while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) { + while ((rle_code = (int8_t)bytestream2_get_byte(&s->g)) != -1) { if (rle_code == 0) { /* there's another skip code in the stream */ pixel_ptr += (bytestream2_get_byte(&s->g) - 1) * 4; @@ -396,7 +395,9 @@ static av_cold int qtrle_decode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } - avcodec_get_frame_defaults(&s->frame); + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); return 0; } @@ -412,7 +413,7 @@ static int qtrle_decode_frame(AVCodecContext *avctx, int ret; bytestream2_init(&s->g, avpkt->data, avpkt->size); - if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) + if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) return ret; /* check if this frame is even supposed to change */ @@ -439,7 +440,7 @@ static int qtrle_decode_frame(AVCodecContext *avctx, start_line = 0; height = s->avctx->height; } - row_ptr = s->frame.linesize[0] * start_line; + row_ptr = s->frame->linesize[0] * start_line; switch (avctx->bits_per_coded_sample) { case 1: @@ -487,16 +488,16 @@ static int qtrle_decode_frame(AVCodecContext *avctx, const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); if (pal) { - s->frame.palette_has_changed = 1; + s->frame->palette_has_changed = 1; memcpy(s->pal, pal, AVPALETTE_SIZE); } /* make the palette available on the way out */ - memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE); + memcpy(s->frame->data[1], s->pal, AVPALETTE_SIZE); } done: - if ((ret = av_frame_ref(data, &s->frame)) < 0) + if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; *got_frame = 1; @@ -508,13 +509,14 @@ static av_cold int qtrle_decode_end(AVCodecContext *avctx) { QtrleContext *s = avctx->priv_data; - av_frame_unref(&s->frame); + av_frame_free(&s->frame); return 0; } AVCodec ff_qtrle_decoder = { .name = "qtrle", + .long_name = NULL_IF_CONFIG_SMALL("QuickTime Animation (RLE) video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_QTRLE, .priv_data_size = sizeof(QtrleContext), @@ -522,5 +524,4 @@ AVCodec ff_qtrle_decoder = { .close = qtrle_decode_end, .decode = qtrle_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("QuickTime Animation (RLE) video"), }; diff --git a/ffmpeg/libavcodec/qtrleenc.c b/ffmpeg/libavcodec/qtrleenc.c index a25c45d..7f9525a 100644 --- a/ffmpeg/libavcodec/qtrleenc.c +++ b/ffmpeg/libavcodec/qtrleenc.c @@ -36,7 +36,6 @@ typedef struct QtrleEncContext { AVCodecContext *avctx; - AVFrame frame; int pixel_size; AVPicture previous_frame; unsigned int max_buf_size; @@ -61,6 +60,19 @@ typedef struct QtrleEncContext { uint8_t* skip_table; } QtrleEncContext; +static av_cold int qtrle_encode_end(AVCodecContext *avctx) +{ + QtrleEncContext *s = avctx->priv_data; + + av_frame_free(&avctx->coded_frame); + + avpicture_free(&s->previous_frame); + av_free(s->rlecode_table); + av_free(s->length_table); + av_free(s->skip_table); + return 0; +} + static av_cold int qtrle_encode_init(AVCodecContext *avctx) { QtrleEncContext *s = avctx->priv_data; @@ -108,7 +120,13 @@ static av_cold int qtrle_encode_init(AVCodecContext *avctx) + 15 /* header + footer */ + s->avctx->height*2 /* skip code+rle end */ + s->logical_width/MAX_RLE_BULK + 1 /* rle codes */; - avctx->coded_frame = &s->frame; + + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) { + qtrle_encode_end(avctx); + return AVERROR(ENOMEM); + } + return 0; } @@ -197,7 +215,7 @@ static void qtrle_encode_line(QtrleEncContext *s, const AVFrame *p, int line, ui } } - if (!s->frame.key_frame && !memcmp(this_line, prev_line, s->pixel_size)) + if (!s->avctx->coded_frame->key_frame && !memcmp(this_line, prev_line, s->pixel_size)) skipcount = FFMIN(skipcount + 1, MAX_RLE_SKIP); else skipcount = 0; @@ -308,7 +326,7 @@ static int encode_frame(QtrleEncContext *s, const AVFrame *p, uint8_t *buf) int end_line = s->avctx->height; uint8_t *orig_buf = buf; - if (!s->frame.key_frame) { + if (!s->avctx->coded_frame->key_frame) { unsigned line_size = s->logical_width * s->pixel_size; for (start_line = 0; start_line < s->avctx->height; start_line++) if (memcmp(p->data[0] + start_line*p->linesize[0], @@ -346,11 +364,9 @@ static int qtrle_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { QtrleEncContext * const s = avctx->priv_data; - AVFrame * const p = &s->frame; + AVFrame * const p = avctx->coded_frame; int ret; - *p = *pict; - if ((ret = ff_alloc_packet2(avctx, pkt, s->max_buf_size)) < 0) return ret; @@ -367,7 +383,8 @@ static int qtrle_encode_frame(AVCodecContext *avctx, AVPacket *pkt, pkt->size = encode_frame(s, pict, pkt->data); /* save the current frame */ - av_picture_copy(&s->previous_frame, (AVPicture *)p, avctx->pix_fmt, avctx->width, avctx->height); + av_picture_copy(&s->previous_frame, (const AVPicture *)pict, + avctx->pix_fmt, avctx->width, avctx->height); if (p->key_frame) pkt->flags |= AV_PKT_FLAG_KEY; @@ -376,19 +393,9 @@ static int qtrle_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return 0; } -static av_cold int qtrle_encode_end(AVCodecContext *avctx) -{ - QtrleEncContext *s = avctx->priv_data; - - avpicture_free(&s->previous_frame); - av_free(s->rlecode_table); - av_free(s->length_table); - av_free(s->skip_table); - return 0; -} - AVCodec ff_qtrle_encoder = { .name = "qtrle", + .long_name = NULL_IF_CONFIG_SMALL("QuickTime Animation (RLE) video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_QTRLE, .priv_data_size = sizeof(QtrleEncContext), @@ -398,5 +405,4 @@ AVCodec ff_qtrle_encoder = { .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB555BE, AV_PIX_FMT_ARGB, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("QuickTime Animation (RLE) video"), }; diff --git a/ffmpeg/libavcodec/r210dec.c b/ffmpeg/libavcodec/r210dec.c index 198914c..cbebf7c 100644 --- a/ffmpeg/libavcodec/r210dec.c +++ b/ffmpeg/libavcodec/r210dec.c @@ -90,33 +90,33 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, #if CONFIG_R210_DECODER AVCodec ff_r210_decoder = { .name = "r210", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed RGB 10-bit"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_R210, .init = decode_init, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Uncompressed RGB 10-bit"), }; #endif #if CONFIG_R10K_DECODER AVCodec ff_r10k_decoder = { .name = "r10k", + .long_name = NULL_IF_CONFIG_SMALL("AJA Kona 10-bit RGB Codec"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_R10K, .init = decode_init, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("AJA Kona 10-bit RGB Codec"), }; #endif #if CONFIG_AVRP_DECODER AVCodec ff_avrp_decoder = { .name = "avrp", + .long_name = NULL_IF_CONFIG_SMALL("Avid 1:1 10-bit RGB Packer"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_AVRP, .init = decode_init, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Avid 1:1 10-bit RGB Packer"), }; #endif diff --git a/ffmpeg/libavcodec/r210enc.c b/ffmpeg/libavcodec/r210enc.c index e19a27e..d61cd75 100644 --- a/ffmpeg/libavcodec/r210enc.c +++ b/ffmpeg/libavcodec/r210enc.c @@ -26,7 +26,7 @@ static av_cold int encode_init(AVCodecContext *avctx) { - avctx->coded_frame = avcodec_alloc_frame(); + avctx->coded_frame = av_frame_alloc(); if (!avctx->coded_frame) return AVERROR(ENOMEM); @@ -88,36 +88,36 @@ static av_cold int encode_close(AVCodecContext *avctx) #if CONFIG_R210_ENCODER AVCodec ff_r210_encoder = { .name = "r210", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed RGB 10-bit"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_R210, .init = encode_init, .encode2 = encode_frame, .close = encode_close, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB48, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Uncompressed RGB 10-bit"), }; #endif #if CONFIG_R10K_ENCODER AVCodec ff_r10k_encoder = { .name = "r10k", + .long_name = NULL_IF_CONFIG_SMALL("AJA Kona 10-bit RGB Codec"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_R10K, .init = encode_init, .encode2 = encode_frame, .close = encode_close, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB48, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("AJA Kona 10-bit RGB Codec"), }; #endif #if CONFIG_AVRP_ENCODER AVCodec ff_avrp_encoder = { .name = "avrp", + .long_name = NULL_IF_CONFIG_SMALL("Avid 1:1 10-bit RGB Packer"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_AVRP, .init = encode_init, .encode2 = encode_frame, .close = encode_close, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB48, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Avid 1:1 10-bit RGB Packer"), }; #endif diff --git a/ffmpeg/libavcodec/ra144.c b/ffmpeg/libavcodec/ra144.c index 1ec1e10..fe9a5bc 100644 --- a/ffmpeg/libavcodec/ra144.c +++ b/ffmpeg/libavcodec/ra144.c @@ -1504,8 +1504,8 @@ const int16_t * const ff_lpc_refl_cb[10]={ lpc_refl_cb6, lpc_refl_cb7, lpc_refl_cb8, lpc_refl_cb9, lpc_refl_cb10 }; -static void ff_add_wav(int16_t *dest, int n, int skip_first, int *m, const int16_t *s1, - const int8_t *s2, const int8_t *s3) +static void add_wav(int16_t *dest, int n, int skip_first, int *m, + const int16_t *s1, const int8_t *s2, const int8_t *s3) { int i; int v[3]; @@ -1694,12 +1694,12 @@ int ff_irms(const int16_t *data) return 0x20000000 / (ff_t_sqrt(sum) >> 8); } -void ff_subblock_synthesis(RA144Context *ractx, const uint16_t *lpc_coefs, +void ff_subblock_synthesis(RA144Context *ractx, const int16_t *lpc_coefs, int cba_idx, int cb1_idx, int cb2_idx, int gval, int gain) { - uint16_t buffer_a[BLOCKSIZE]; - uint16_t *block; + int16_t buffer_a[BLOCKSIZE]; + int16_t *block; int m[3]; if (cba_idx) { @@ -1716,8 +1716,8 @@ void ff_subblock_synthesis(RA144Context *ractx, const uint16_t *lpc_coefs, block = ractx->adapt_cb + BUFFERSIZE - BLOCKSIZE; - ff_add_wav(block, gain, cba_idx, m, cba_idx? buffer_a: NULL, - ff_cb1_vects[cb1_idx], ff_cb2_vects[cb2_idx]); + add_wav(block, gain, cba_idx, m, cba_idx? buffer_a: NULL, + ff_cb1_vects[cb1_idx], ff_cb2_vects[cb2_idx]); memcpy(ractx->curr_sblock, ractx->curr_sblock + BLOCKSIZE, LPC_ORDER*sizeof(*ractx->curr_sblock)); diff --git a/ffmpeg/libavcodec/ra144.h b/ffmpeg/libavcodec/ra144.h index eb89398..763495d 100644 --- a/ffmpeg/libavcodec/ra144.h +++ b/ffmpeg/libavcodec/ra144.h @@ -30,7 +30,7 @@ #define BLOCKSIZE 40 ///< subblock size in 16-bit words #define BUFFERSIZE 146 ///< the size of the adaptive codebook #define FIXED_CB_SIZE 128 ///< size of fixed codebooks -#define FRAMESIZE 20 ///< size of encoded frame +#define FRAME_SIZE 20 ///< size of encoded frame #define LPC_ORDER 10 ///< order of LPC filter typedef struct RA144Context { @@ -56,7 +56,7 @@ typedef struct RA144Context { /** Adaptive codebook, its size is two units bigger to avoid a * buffer overflow. */ - uint16_t adapt_cb[146+2]; + int16_t adapt_cb[146+2]; } RA144Context; void ff_copy_and_dup(int16_t *target, const int16_t *source, int offset); @@ -69,7 +69,7 @@ int ff_interp(RA144Context *ractx, int16_t *out, int a, int copyold, int energy); unsigned int ff_rescale_rms(unsigned int rms, unsigned int energy); int ff_irms(const int16_t *data); -void ff_subblock_synthesis(RA144Context *ractx, const uint16_t *lpc_coefs, +void ff_subblock_synthesis(RA144Context *ractx, const int16_t *lpc_coefs, int cba_idx, int cb1_idx, int cb2_idx, int gval, int gain); diff --git a/ffmpeg/libavcodec/ra144dec.c b/ffmpeg/libavcodec/ra144dec.c index 5531fd2..b7add7f 100644 --- a/ffmpeg/libavcodec/ra144dec.c +++ b/ffmpeg/libavcodec/ra144dec.c @@ -45,7 +45,7 @@ static av_cold int ra144_decode_init(AVCodecContext * avctx) return 0; } -static void do_output_subblock(RA144Context *ractx, const uint16_t *lpc_coefs, +static void do_output_subblock(RA144Context *ractx, const int16_t *lpc_coefs, int gval, GetBitContext *gb) { int cba_idx = get_bits(gb, 7); // index of the adaptive CB, 0 if none @@ -66,7 +66,7 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *data, int buf_size = avpkt->size; static const uint8_t sizes[LPC_ORDER] = {6, 5, 5, 4, 4, 3, 3, 3, 3, 2}; unsigned int refl_rms[NBLOCKS]; // RMS of the reflection coefficients - uint16_t block_coefs[NBLOCKS][LPC_ORDER]; // LPC coefficients of each sub-block + int16_t block_coefs[NBLOCKS][LPC_ORDER]; // LPC coefficients of each sub-block unsigned int lpc_refl[LPC_ORDER]; // LPC reflection coefficients of the frame int i, j; int ret; @@ -76,7 +76,7 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *data, RA144Context *ractx = avctx->priv_data; GetBitContext gb; - if (buf_size < FRAMESIZE) { + if (buf_size < FRAME_SIZE) { av_log(avctx, AV_LOG_ERROR, "Frame too small (%d bytes). Truncated file?\n", buf_size); *got_frame_ptr = 0; @@ -89,7 +89,7 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *data, return ret; samples = (int16_t *)frame->data[0]; - init_get_bits(&gb, buf, FRAMESIZE * 8); + init_get_bits8(&gb, buf, FRAME_SIZE); for (i = 0; i < LPC_ORDER; i++) lpc_refl[i] = ff_lpc_refl_cb[i][get_bits(&gb, sizes[i])]; @@ -122,16 +122,16 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *data, *got_frame_ptr = 1; - return FRAMESIZE; + return FRAME_SIZE; } AVCodec ff_ra_144_decoder = { .name = "real_144", + .long_name = NULL_IF_CONFIG_SMALL("RealAudio 1.0 (14.4K)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_RA_144, .priv_data_size = sizeof(RA144Context), .init = ra144_decode_init, .decode = ra144_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("RealAudio 1.0 (14.4K)"), }; diff --git a/ffmpeg/libavcodec/ra144enc.c b/ffmpeg/libavcodec/ra144enc.c index 2eac343..3558254 100644 --- a/ffmpeg/libavcodec/ra144enc.c +++ b/ffmpeg/libavcodec/ra144enc.c @@ -447,7 +447,7 @@ static int ra144_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, if (ractx->last_frame) return 0; - if ((ret = ff_alloc_packet2(avctx, avpkt, FRAMESIZE)) < 0) + if ((ret = ff_alloc_packet2(avctx, avpkt, FRAME_SIZE)) < 0) return ret; /** @@ -536,7 +536,7 @@ static int ra144_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, ff_af_queue_remove(&ractx->afq, avctx->frame_size, &avpkt->pts, &avpkt->duration); - avpkt->size = FRAMESIZE; + avpkt->size = FRAME_SIZE; *got_packet_ptr = 1; return 0; } @@ -544,6 +544,7 @@ static int ra144_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, AVCodec ff_ra_144_encoder = { .name = "real_144", + .long_name = NULL_IF_CONFIG_SMALL("RealAudio 1.0 (14.4K)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_RA_144, .priv_data_size = sizeof(RA144Context), @@ -554,5 +555,5 @@ AVCodec ff_ra_144_encoder = { .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, .supported_samplerates = (const int[]){ 8000, 0 }, - .long_name = NULL_IF_CONFIG_SMALL("RealAudio 1.0 (14.4K)"), + .channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO, 0 }, }; diff --git a/ffmpeg/libavcodec/ra288.c b/ffmpeg/libavcodec/ra288.c index 393ea0b..c1b9b6b 100644 --- a/ffmpeg/libavcodec/ra288.c +++ b/ffmpeg/libavcodec/ra288.c @@ -95,7 +95,7 @@ static void decode(RA288Context *ractx, float gain, int cb_coef) memmove(ractx->sp_hist + 70, ractx->sp_hist + 75, 36*sizeof(*block)); /* block 46 of G.728 spec */ - sum = 32.; + sum = 32.0; for (i=0; i < 10; i++) sum -= gain_block[9-i] * ractx->gain_lpc[i]; @@ -111,7 +111,7 @@ static void decode(RA288Context *ractx, float gain, int cb_coef) sum = avpriv_scalarproduct_float_c(buffer, buffer, 5); - sum = FFMAX(sum, 5. / (1<<24)); + sum = FFMAX(sum, 5.0 / (1<<24)); /* shift and store */ memmove(gain_block, gain_block + 1, 9 * sizeof(*gain_block)); @@ -157,7 +157,7 @@ static void do_hybrid_window(RA288Context *ractx, } /* Multiply by the white noise correcting factor (WNCF). */ - *out *= 257./256.; + *out *= 257.0 / 256.0; } /** @@ -202,7 +202,7 @@ static int ra288_decode_frame(AVCodecContext * avctx, void *data, return ret; out = (float *)frame->data[0]; - init_get_bits(&gb, buf, avctx->block_align * 8); + init_get_bits8(&gb, buf, avctx->block_align); for (i=0; i < RA288_BLOCKS_PER_FRAME; i++) { float gain = amptable[get_bits(&gb, 3)]; @@ -229,11 +229,11 @@ static int ra288_decode_frame(AVCodecContext * avctx, void *data, AVCodec ff_ra_288_decoder = { .name = "real_288", + .long_name = NULL_IF_CONFIG_SMALL("RealAudio 2.0 (28.8K)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_RA_288, .priv_data_size = sizeof(RA288Context), .init = ra288_decode_init, .decode = ra288_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("RealAudio 2.0 (28.8K)"), }; diff --git a/ffmpeg/libavcodec/ralf.c b/ffmpeg/libavcodec/ralf.c index d3f82d6..8a319ac 100644 --- a/ffmpeg/libavcodec/ralf.c +++ b/ffmpeg/libavcodec/ralf.c @@ -3,20 +3,20 @@ * * Copyright (c) 2012 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -26,6 +26,7 @@ * Dedicated to the mastermind behind it, Ralph Wiggum. */ +#include "libavutil/attributes.h" #include "libavutil/channel_layout.h" #include "avcodec.h" #include "get_bits.h" @@ -72,7 +73,7 @@ typedef struct RALFContext { #define MAX_ELEMS 644 // no RALF table uses more than that -static int init_ralf_vlc(VLC *vlc, const uint8_t *data, int elems) +static av_cold int init_ralf_vlc(VLC *vlc, const uint8_t *data, int elems) { uint8_t lens[MAX_ELEMS]; uint16_t codes[MAX_ELEMS]; @@ -521,6 +522,7 @@ static void decode_flush(AVCodecContext *avctx) AVCodec ff_ralf_decoder = { .name = "ralf", + .long_name = NULL_IF_CONFIG_SMALL("RealAudio Lossless"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_RALF, .priv_data_size = sizeof(RALFContext), @@ -529,7 +531,6 @@ AVCodec ff_ralf_decoder = { .decode = decode_frame, .flush = decode_flush, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("RealAudio Lossless"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_NONE }, }; diff --git a/ffmpeg/libavcodec/ralfdata.h b/ffmpeg/libavcodec/ralfdata.h index 83eb970..9a84e45 100644 --- a/ffmpeg/libavcodec/ralfdata.h +++ b/ffmpeg/libavcodec/ralfdata.h @@ -3,20 +3,20 @@ * * Copyright (c) 2012 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/rangecoder.c b/ffmpeg/libavcodec/rangecoder.c index 7d2d14d..69150a5 100644 --- a/ffmpeg/libavcodec/rangecoder.c +++ b/ffmpeg/libavcodec/rangecoder.c @@ -33,12 +33,13 @@ #include +#include "libavutil/attributes.h" #include "libavutil/avassert.h" #include "avcodec.h" #include "rangecoder.h" #include "bytestream.h" -void ff_init_range_encoder(RangeCoder *c, uint8_t *buf, int buf_size) +av_cold void ff_init_range_encoder(RangeCoder *c, uint8_t *buf, int buf_size) { c->bytestream_start = c->bytestream = buf; @@ -49,7 +50,8 @@ void ff_init_range_encoder(RangeCoder *c, uint8_t *buf, int buf_size) c->outstanding_byte = -1; } -void ff_init_range_decoder(RangeCoder *c, const uint8_t *buf, int buf_size) +av_cold void ff_init_range_decoder(RangeCoder *c, const uint8_t *buf, + int buf_size) { /* cast to avoid compiler warning */ ff_init_range_encoder(c, (uint8_t *)buf, buf_size); diff --git a/ffmpeg/libavcodec/ratecontrol.c b/ffmpeg/libavcodec/ratecontrol.c index 5860423..7db248e 100644 --- a/ffmpeg/libavcodec/ratecontrol.c +++ b/ffmpeg/libavcodec/ratecontrol.c @@ -25,6 +25,7 @@ * Rate control for video encoders. */ +#include "libavutil/attributes.h" #include "avcodec.h" #include "ratecontrol.h" #include "mpegvideo.h" @@ -83,7 +84,7 @@ static inline double bits2qp(RateControlEntry *rce, double bits) return rce->qscale * (double)(rce->i_tex_bits + rce->p_tex_bits + 1) / bits; } -int ff_rate_control_init(MpegEncContext *s) +av_cold int ff_rate_control_init(MpegEncContext *s) { RateControlContext *rcc = &s->rc_context; int i, res; @@ -296,7 +297,7 @@ int ff_rate_control_init(MpegEncContext *s) return 0; } -void ff_rate_control_uninit(MpegEncContext *s) +av_cold void ff_rate_control_uninit(MpegEncContext *s) { RateControlContext *rcc = &s->rc_context; emms_c(); @@ -327,6 +328,9 @@ int ff_vbv_update(MpegEncContext *s, int frame_size) rcc->buffer_index -= frame_size; if (rcc->buffer_index < 0) { av_log(s->avctx, AV_LOG_ERROR, "rc buffer underflow\n"); + if (frame_size > max_rate && s->qscale == s->avctx->qmax) { + av_log(s->avctx, AV_LOG_ERROR, "max bitrate possibly too small or try trellis with large lmax or increase qmax\n"); + } rcc->buffer_index = 0; } @@ -919,7 +923,7 @@ static int init_pass2(MpegEncContext *s) double rate_factor = 0; double step; const int filter_size = (int)(a->qblur * 4) | 1; - double expected_bits; + double expected_bits = 0; // init to silence gcc warning double *qscale, *blurred_qscale, qscale_sum; /* find complexity & const_bits & decide the pict_types */ diff --git a/ffmpeg/libavcodec/raw.c b/ffmpeg/libavcodec/raw.c index e23dbea..c3f3de1 100644 --- a/ffmpeg/libavcodec/raw.c +++ b/ffmpeg/libavcodec/raw.c @@ -166,6 +166,18 @@ const PixelFormatTag ff_raw_pix_fmt_tags[] = { { AV_PIX_FMT_YUVA444P16LE, MKTAG('Y', '4', 0 , 16 ) }, { AV_PIX_FMT_YUVA444P16BE, MKTAG(16 , 0 , '4', 'Y') }, + { AV_PIX_FMT_GBRP, MKTAG('G', '3', 00 , 8 ) }, + { AV_PIX_FMT_GBRP9LE, MKTAG('G', '3', 00 , 9 ) }, + { AV_PIX_FMT_GBRP9BE, MKTAG( 9 , 00 , '3', 'G') }, + { AV_PIX_FMT_GBRP10LE, MKTAG('G', '3', 00 , 10 ) }, + { AV_PIX_FMT_GBRP10BE, MKTAG(10 , 00 , '3', 'G') }, + { AV_PIX_FMT_GBRP12LE, MKTAG('G', '3', 00 , 12 ) }, + { AV_PIX_FMT_GBRP12BE, MKTAG(12 , 00 , '3', 'G') }, + { AV_PIX_FMT_GBRP14LE, MKTAG('G', '3', 00 , 14 ) }, + { AV_PIX_FMT_GBRP14BE, MKTAG(14 , 00 , '3', 'G') }, + { AV_PIX_FMT_GBRP16LE, MKTAG('G', '3', 00 , 16 ) }, + { AV_PIX_FMT_GBRP16BE, MKTAG(16 , 00 , '3', 'G') }, + /* quicktime */ { AV_PIX_FMT_YUV420P, MKTAG('R', '4', '2', '0') }, /* Radius DV YUV PAL */ { AV_PIX_FMT_YUV411P, MKTAG('R', '4', '1', '1') }, /* Radius DV YUV NTSC */ diff --git a/ffmpeg/libavcodec/rawdec.c b/ffmpeg/libavcodec/rawdec.c index 00730dc..e1682e3 100644 --- a/ffmpeg/libavcodec/rawdec.c +++ b/ffmpeg/libavcodec/rawdec.c @@ -25,6 +25,7 @@ */ #include "avcodec.h" +#include "internal.h" #include "raw.h" #include "libavutil/avassert.h" #include "libavutil/buffer.h" @@ -48,7 +49,7 @@ static const AVOption options[]={ {NULL} }; -static const AVClass class = { +static const AVClass rawdec_class = { .class_name = "rawdec", .option = options, .version = LIBAVUTIL_VERSION_INT, @@ -107,7 +108,7 @@ static av_cold int raw_init_decoder(AVCodecContext *avctx) if ( avctx->codec_tag == MKTAG('r','a','w',' ') || avctx->codec_tag == MKTAG('N','O','1','6')) avctx->pix_fmt = avpriv_find_pix_fmt(pix_fmt_bps_mov, - avctx->bits_per_coded_sample); + avctx->bits_per_coded_sample & 0x1f); else if (avctx->codec_tag == MKTAG('W', 'R', 'A', 'W')) avctx->pix_fmt = avpriv_find_pix_fmt(pix_fmt_bps_avi, avctx->bits_per_coded_sample); @@ -123,22 +124,27 @@ static av_cold int raw_init_decoder(AVCodecContext *avctx) return AVERROR(EINVAL); } - if (desc->flags & (PIX_FMT_PAL | PIX_FMT_PSEUDOPAL)) { + if (desc->flags & (AV_PIX_FMT_FLAG_PAL | AV_PIX_FMT_FLAG_PSEUDOPAL)) { context->palette = av_buffer_alloc(AVPALETTE_SIZE); if (!context->palette) return AVERROR(ENOMEM); - if (desc->flags & PIX_FMT_PSEUDOPAL) + if (desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) avpriv_set_systematic_pal2((uint32_t*)context->palette->data, avctx->pix_fmt); else memset(context->palette->data, 0, AVPALETTE_SIZE); } - context->frame_size = avpicture_get_size(avctx->pix_fmt, avctx->width, - avctx->height); - if ((avctx->bits_per_coded_sample == 4 || avctx->bits_per_coded_sample == 2) && + if (((avctx->bits_per_coded_sample & 0x1f) == 4 || (avctx->bits_per_coded_sample & 0x1f) == 2) && avctx->pix_fmt == AV_PIX_FMT_PAL8 && - (!avctx->codec_tag || avctx->codec_tag == MKTAG('r','a','w',' '))) + (!avctx->codec_tag || avctx->codec_tag == MKTAG('r','a','w',' '))) { context->is_2_4_bpp = 1; + context->frame_size = avpicture_get_size(avctx->pix_fmt, + FFALIGN(avctx->width, 16), + avctx->height); + } else { + context->frame_size = avpicture_get_size(avctx->pix_fmt, avctx->width, + avctx->height); + } if ((avctx->extradata_size >= 9 && !memcmp(avctx->extradata + avctx->extradata_size - 9, "BottomUp", 9)) || @@ -177,9 +183,9 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame, frame->pict_type = AV_PICTURE_TYPE_I; frame->key_frame = 1; frame->reordered_opaque = avctx->reordered_opaque; - frame->pkt_pts = avctx->pkt->pts; - av_frame_set_pkt_pos (frame, avctx->pkt->pos); - av_frame_set_pkt_duration(frame, avctx->pkt->duration); + frame->pkt_pts = avctx->internal->pkt->pts; + av_frame_set_pkt_pos (frame, avctx->internal->pkt->pos); + av_frame_set_pkt_duration(frame, avctx->internal->pkt->duration); if (context->tff >= 0) { frame->interlaced_frame = 1; @@ -190,7 +196,7 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame, return res; if (need_copy) - frame->buf[0] = av_buffer_alloc(context->frame_size); + frame->buf[0] = av_buffer_alloc(FFMAX(context->frame_size, buf_size)); else frame->buf[0] = av_buffer_ref(avpkt->buf); if (!frame->buf[0]) @@ -201,14 +207,14 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame, int i; uint8_t *dst = frame->buf[0]->data; buf_size = context->frame_size - AVPALETTE_SIZE; - if (avctx->bits_per_coded_sample == 4) { + if ((avctx->bits_per_coded_sample & 0x1f) == 4) { for (i = 0; 2 * i + 1 < buf_size && isize; i++) { dst[2 * i + 0] = buf[i] >> 4; dst[2 * i + 1] = buf[i] & 15; } linesize_align = 8; } else { - av_assert0(avctx->bits_per_coded_sample == 2); + av_assert0((avctx->bits_per_coded_sample & 0x1f) == 2); for (i = 0; 4 * i + 3 < buf_size && isize; i++) { dst[4 * i + 0] = buf[i] >> 6; dst[4 * i + 1] = buf[i] >> 4 & 3; @@ -219,7 +225,7 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame, } buf = dst; } else if (need_copy) { - memcpy(frame->buf[0]->data, buf, FFMIN(buf_size, context->frame_size)); + memcpy(frame->buf[0]->data, buf, buf_size); buf = frame->buf[0]->data; } @@ -230,12 +236,15 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame, len = context->frame_size - (avctx->pix_fmt==AV_PIX_FMT_PAL8 ? AVPALETTE_SIZE : 0); if (buf_size < len) { av_log(avctx, AV_LOG_ERROR, "Invalid buffer size, packet size %d < expected frame_size %d\n", buf_size, len); + av_buffer_unref(&frame->buf[0]); return AVERROR(EINVAL); } if ((res = avpicture_fill(picture, buf, avctx->pix_fmt, - avctx->width, avctx->height)) < 0) + avctx->width, avctx->height)) < 0) { + av_buffer_unref(&frame->buf[0]); return res; + } if (avctx->pix_fmt == AV_PIX_FMT_PAL8) { const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, @@ -244,8 +253,10 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame, if (pal) { av_buffer_unref(&context->palette); context->palette = av_buffer_alloc(AVPALETTE_SIZE); - if (!context->palette) + if (!context->palette) { + av_buffer_unref(&frame->buf[0]); return AVERROR(ENOMEM); + } memcpy(context->palette->data, pal, AVPALETTE_SIZE); frame->palette_has_changed = 1; } @@ -271,10 +282,12 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame, } if ((avctx->pix_fmt == AV_PIX_FMT_PAL8 && buf_size < context->frame_size) || - (desc->flags & PIX_FMT_PSEUDOPAL)) { + (desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)) { frame->buf[1] = av_buffer_ref(context->palette); - if (!frame->buf[1]) + if (!frame->buf[1]) { + av_buffer_unref(&frame->buf[0]); return AVERROR(ENOMEM); + } frame->data[1] = frame->buf[1]->data; } @@ -337,12 +350,12 @@ static av_cold int raw_close_decoder(AVCodecContext *avctx) AVCodec ff_rawvideo_decoder = { .name = "rawvideo", + .long_name = NULL_IF_CONFIG_SMALL("raw video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_RAWVIDEO, .priv_data_size = sizeof(RawVideoContext), .init = raw_init_decoder, .close = raw_close_decoder, .decode = raw_decode, - .long_name = NULL_IF_CONFIG_SMALL("raw video"), - .priv_class = &class, + .priv_class = &rawdec_class, }; diff --git a/ffmpeg/libavcodec/rawenc.c b/ffmpeg/libavcodec/rawenc.c index c6da6b8..036261d 100644 --- a/ffmpeg/libavcodec/rawenc.c +++ b/ffmpeg/libavcodec/rawenc.c @@ -71,10 +71,10 @@ static int raw_encode(AVCodecContext *avctx, AVPacket *pkt, AVCodec ff_rawvideo_encoder = { .name = "rawvideo", + .long_name = NULL_IF_CONFIG_SMALL("raw video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_RAWVIDEO, .priv_data_size = sizeof(AVFrame), .init = raw_init_encoder, .encode2 = raw_encode, - .long_name = NULL_IF_CONFIG_SMALL("raw video"), }; diff --git a/ffmpeg/libavcodec/rdft.c b/ffmpeg/libavcodec/rdft.c index ebddd8b..218dd4c 100644 --- a/ffmpeg/libavcodec/rdft.c +++ b/ffmpeg/libavcodec/rdft.c @@ -54,7 +54,7 @@ static SINTABLE_CONST FFTSample * const ff_sin_tabs[] = { * the two real FFTs into one complex FFT. Unmangle the results. * ref: http://www.engineeringproductivitytools.com/stuff/T0001/PT10.HTM */ -static void ff_rdft_calc_c(RDFTContext* s, FFTSample* data) +static void rdft_calc_c(RDFTContext *s, FFTSample *data) { int i, i1, i2; FFTComplex ev, od; @@ -120,7 +120,7 @@ av_cold int ff_rdft_init(RDFTContext *s, int nbits, enum RDFTransformType trans) s->tsin[i] = sin(i*theta); } #endif - s->rdft_calc = ff_rdft_calc_c; + s->rdft_calc = rdft_calc_c; if (ARCH_ARM) ff_rdft_init_arm(s); diff --git a/ffmpeg/libavcodec/remove_extradata_bsf.c b/ffmpeg/libavcodec/remove_extradata_bsf.c index f0d9b45..e880b95 100644 --- a/ffmpeg/libavcodec/remove_extradata_bsf.c +++ b/ffmpeg/libavcodec/remove_extradata_bsf.c @@ -49,7 +49,6 @@ static int remove_extradata(AVBitStreamFilterContext *bsfc, AVCodecContext *avct } AVBitStreamFilter ff_remove_extradata_bsf={ - "remove_extra", - 0, - remove_extradata, + .name = "remove_extra", + .filter = remove_extradata, }; diff --git a/ffmpeg/libavcodec/rl2.c b/ffmpeg/libavcodec/rl2.c index c8853de..6e63ed1 100644 --- a/ffmpeg/libavcodec/rl2.c +++ b/ffmpeg/libavcodec/rl2.c @@ -215,6 +215,7 @@ static av_cold int rl2_decode_end(AVCodecContext *avctx) AVCodec ff_rl2_decoder = { .name = "rl2", + .long_name = NULL_IF_CONFIG_SMALL("RL2 video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_RL2, .priv_data_size = sizeof(Rl2Context), @@ -222,5 +223,4 @@ AVCodec ff_rl2_decoder = { .close = rl2_decode_end, .decode = rl2_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("RL2 video"), }; diff --git a/ffmpeg/libavcodec/roqaudioenc.c b/ffmpeg/libavcodec/roqaudioenc.c index b68e3f8..b0b76d0 100644 --- a/ffmpeg/libavcodec/roqaudioenc.c +++ b/ffmpeg/libavcodec/roqaudioenc.c @@ -193,6 +193,7 @@ static int roq_dpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, AVCodec ff_roq_dpcm_encoder = { .name = "roq_dpcm", + .long_name = NULL_IF_CONFIG_SMALL("id RoQ DPCM"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_ROQ_DPCM, .priv_data_size = sizeof(ROQDPCMContext), @@ -202,5 +203,4 @@ AVCodec ff_roq_dpcm_encoder = { .capabilities = CODEC_CAP_DELAY, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("id RoQ DPCM"), }; diff --git a/ffmpeg/libavcodec/roqvideo.h b/ffmpeg/libavcodec/roqvideo.h index 3834897..39dda0c 100644 --- a/ffmpeg/libavcodec/roqvideo.h +++ b/ffmpeg/libavcodec/roqvideo.h @@ -44,7 +44,6 @@ struct RoqTempData; typedef struct RoqContext { AVCodecContext *avctx; - AVFrame frames[2]; AVFrame *last_frame; AVFrame *current_frame; int first_frame; diff --git a/ffmpeg/libavcodec/roqvideodec.c b/ffmpeg/libavcodec/roqvideodec.c index 85fdab7..8e7dffe 100644 --- a/ffmpeg/libavcodec/roqvideodec.c +++ b/ffmpeg/libavcodec/roqvideodec.c @@ -236,6 +236,7 @@ static av_cold int roq_decode_end(AVCodecContext *avctx) AVCodec ff_roq_decoder = { .name = "roqvideo", + .long_name = NULL_IF_CONFIG_SMALL("id RoQ video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_ROQ, .priv_data_size = sizeof(RoqContext), @@ -243,5 +244,4 @@ AVCodec ff_roq_decoder = { .close = roq_decode_end, .decode = roq_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("id RoQ video"), }; diff --git a/ffmpeg/libavcodec/roqvideoenc.c b/ffmpeg/libavcodec/roqvideoenc.c index a652c47..37bd8d5 100644 --- a/ffmpeg/libavcodec/roqvideoenc.c +++ b/ffmpeg/libavcodec/roqvideoenc.c @@ -56,6 +56,7 @@ #include +#include "libavutil/attributes.h" #include "roqvideo.h" #include "bytestream.h" #include "elbg.h" @@ -805,8 +806,8 @@ static void generate_codebook(RoqContext *enc, RoqTempdata *tempdata, else closest_cb = tempdata->closest_cb2; - ff_init_elbg(points, 6*c_size, inputCount, codebook, cbsize, 1, closest_cb, &enc->randctx); - ff_do_elbg(points, 6*c_size, inputCount, codebook, cbsize, 1, closest_cb, &enc->randctx); + avpriv_init_elbg(points, 6*c_size, inputCount, codebook, cbsize, 1, closest_cb, &enc->randctx); + avpriv_do_elbg(points, 6*c_size, inputCount, codebook, cbsize, 1, closest_cb, &enc->randctx); if (size == 4) av_free(closest_cb); @@ -936,7 +937,7 @@ static void roq_encode_video(RoqContext *enc) enc->framesSinceKeyframe++; } -static int roq_encode_end(AVCodecContext *avctx) +static av_cold int roq_encode_end(AVCodecContext *avctx) { RoqContext *enc = avctx->priv_data; @@ -952,7 +953,7 @@ static int roq_encode_end(AVCodecContext *avctx) return 0; } -static int roq_encode_init(AVCodecContext *avctx) +static av_cold int roq_encode_init(AVCodecContext *avctx) { RoqContext *enc = avctx->priv_data; @@ -1074,6 +1075,7 @@ static int roq_encode_frame(AVCodecContext *avctx, AVPacket *pkt, AVCodec ff_roq_encoder = { .name = "roqvideo", + .long_name = NULL_IF_CONFIG_SMALL("id RoQ video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_ROQ, .priv_data_size = sizeof(RoqContext), @@ -1083,5 +1085,4 @@ AVCodec ff_roq_encoder = { .supported_framerates = (const AVRational[]){ {30,1}, {0,0} }, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV444P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("id RoQ video"), }; diff --git a/ffmpeg/libavcodec/rpza.c b/ffmpeg/libavcodec/rpza.c index 2aa0091..d4e2b17 100644 --- a/ffmpeg/libavcodec/rpza.c +++ b/ffmpeg/libavcodec/rpza.c @@ -46,7 +46,7 @@ typedef struct RpzaContext { AVCodecContext *avctx; - AVFrame frame; + AVFrame *frame; const unsigned char *buf; int size; @@ -72,7 +72,7 @@ typedef struct RpzaContext { static void rpza_decode_stream(RpzaContext *s) { int width = s->avctx->width; - int stride = s->frame.linesize[0] / 2; + int stride = s->frame->linesize[0] / 2; int row_inc = stride - 4; int stream_ptr = 0; int chunk_size; @@ -82,10 +82,10 @@ static void rpza_decode_stream(RpzaContext *s) unsigned short color4[4]; unsigned char index, idx; unsigned short ta, tb; - unsigned short *pixels = (unsigned short *)s->frame.data[0]; + unsigned short *pixels = (unsigned short *)s->frame->data[0]; int row_ptr = 0; - int pixel_ptr = 0; + int pixel_ptr = -4; int block_ptr; int pixel_x, pixel_y; int total_blocks; @@ -141,6 +141,7 @@ static void rpza_decode_stream(RpzaContext *s) colorA = AV_RB16 (&s->buf[stream_ptr]); stream_ptr += 2; while (n_blocks--) { + ADVANCE_BLOCK() block_ptr = row_ptr + pixel_ptr; for (pixel_y = 0; pixel_y < 4; pixel_y++) { for (pixel_x = 0; pixel_x < 4; pixel_x++){ @@ -149,7 +150,6 @@ static void rpza_decode_stream(RpzaContext *s) } block_ptr += row_inc; } - ADVANCE_BLOCK(); } break; @@ -188,6 +188,7 @@ static void rpza_decode_stream(RpzaContext *s) if (s->size - stream_ptr < n_blocks * 4) return; while (n_blocks--) { + ADVANCE_BLOCK(); block_ptr = row_ptr + pixel_ptr; for (pixel_y = 0; pixel_y < 4; pixel_y++) { index = s->buf[stream_ptr++]; @@ -198,14 +199,14 @@ static void rpza_decode_stream(RpzaContext *s) } block_ptr += row_inc; } - ADVANCE_BLOCK(); } break; /* Fill block with 16 colors */ case 0x00: - if (s->size - stream_ptr < 16) + if (s->size - stream_ptr < 30) return; + ADVANCE_BLOCK(); block_ptr = row_ptr + pixel_ptr; for (pixel_y = 0; pixel_y < 4; pixel_y++) { for (pixel_x = 0; pixel_x < 4; pixel_x++){ @@ -219,7 +220,6 @@ static void rpza_decode_stream(RpzaContext *s) } block_ptr += row_inc; } - ADVANCE_BLOCK(); break; /* Unknown opcode */ @@ -239,7 +239,9 @@ static av_cold int rpza_decode_init(AVCodecContext *avctx) s->avctx = avctx; avctx->pix_fmt = AV_PIX_FMT_RGB555; - avcodec_get_frame_defaults(&s->frame); + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); return 0; } @@ -256,12 +258,12 @@ static int rpza_decode_frame(AVCodecContext *avctx, s->buf = buf; s->size = buf_size; - if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) + if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) return ret; rpza_decode_stream(s); - if ((ret = av_frame_ref(data, &s->frame)) < 0) + if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; *got_frame = 1; @@ -274,13 +276,14 @@ static av_cold int rpza_decode_end(AVCodecContext *avctx) { RpzaContext *s = avctx->priv_data; - av_frame_unref(&s->frame); + av_frame_free(&s->frame); return 0; } AVCodec ff_rpza_decoder = { .name = "rpza", + .long_name = NULL_IF_CONFIG_SMALL("QuickTime video (RPZA)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_RPZA, .priv_data_size = sizeof(RpzaContext), @@ -288,5 +291,4 @@ AVCodec ff_rpza_decoder = { .close = rpza_decode_end, .decode = rpza_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("QuickTime video (RPZA)"), }; diff --git a/ffmpeg/libavcodec/rtjpeg.c b/ffmpeg/libavcodec/rtjpeg.c index fe781ce..860d958 100644 --- a/ffmpeg/libavcodec/rtjpeg.c +++ b/ffmpeg/libavcodec/rtjpeg.c @@ -56,7 +56,7 @@ static inline int get_block(GetBitContext *gb, int16_t *block, const uint8_t *sc // number of non-zero coefficients coeff = get_bits(gb, 6); if (get_bits_left(gb) < (coeff << 1)) - return -1; + return AVERROR_INVALIDDATA; // normally we would only need to clear the (63 - coeff) last values, // but since we do not know where they are we just clear the whole block @@ -73,7 +73,7 @@ static inline int get_block(GetBitContext *gb, int16_t *block, const uint8_t *sc // 4 bits per coefficient ALIGN(4); if (get_bits_left(gb) < (coeff << 2)) - return -1; + return AVERROR_INVALIDDATA; while (coeff) { ac = get_sbits(gb, 4); if (ac == -8) @@ -84,7 +84,7 @@ static inline int get_block(GetBitContext *gb, int16_t *block, const uint8_t *sc // 8 bits per coefficient ALIGN(8); if (get_bits_left(gb) < (coeff << 3)) - return -1; + return AVERROR_INVALIDDATA; while (coeff) { ac = get_sbits(gb, 8); PUT_COEFF(ac); @@ -107,10 +107,13 @@ int ff_rtjpeg_decode_frame_yuv420(RTJpegContext *c, AVFrame *f, const uint8_t *buf, int buf_size) { GetBitContext gb; int w = c->w / 16, h = c->h / 16; - int x, y; + int x, y, ret; uint8_t *y1 = f->data[0], *y2 = f->data[0] + 8 * f->linesize[0]; uint8_t *u = f->data[1], *v = f->data[2]; - init_get_bits(&gb, buf, buf_size * 8); + + if ((ret = init_get_bits8(&gb, buf, buf_size)) < 0) + return ret; + for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { #define BLOCK(quant, dst, stride) do { \ diff --git a/ffmpeg/libavcodec/rv10.c b/ffmpeg/libavcodec/rv10.c index b5772b2..4d48a49 100644 --- a/ffmpeg/libavcodec/rv10.c +++ b/ffmpeg/libavcodec/rv10.c @@ -28,12 +28,11 @@ #include "libavutil/imgutils.h" #include "avcodec.h" #include "error_resilience.h" +#include "internal.h" #include "mpegvideo.h" #include "mpeg4video.h" #include "h263.h" -//#define DEBUG - #define RV_GET_MAJOR_VER(x) ((x) >> 28) #define RV_GET_MINOR_VER(x) (((x) >> 20) & 0xFF) #define RV_GET_MICRO_VER(x) (((x) >> 12) & 0xFF) @@ -45,148 +44,144 @@ typedef struct RVDecContext { int sub_id; } RVDecContext; -static const uint16_t rv_lum_code[256] = -{ - 0x3e7f, 0x0f00, 0x0f01, 0x0f02, 0x0f03, 0x0f04, 0x0f05, 0x0f06, - 0x0f07, 0x0f08, 0x0f09, 0x0f0a, 0x0f0b, 0x0f0c, 0x0f0d, 0x0f0e, - 0x0f0f, 0x0f10, 0x0f11, 0x0f12, 0x0f13, 0x0f14, 0x0f15, 0x0f16, - 0x0f17, 0x0f18, 0x0f19, 0x0f1a, 0x0f1b, 0x0f1c, 0x0f1d, 0x0f1e, - 0x0f1f, 0x0f20, 0x0f21, 0x0f22, 0x0f23, 0x0f24, 0x0f25, 0x0f26, - 0x0f27, 0x0f28, 0x0f29, 0x0f2a, 0x0f2b, 0x0f2c, 0x0f2d, 0x0f2e, - 0x0f2f, 0x0f30, 0x0f31, 0x0f32, 0x0f33, 0x0f34, 0x0f35, 0x0f36, - 0x0f37, 0x0f38, 0x0f39, 0x0f3a, 0x0f3b, 0x0f3c, 0x0f3d, 0x0f3e, - 0x0f3f, 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0386, - 0x0387, 0x0388, 0x0389, 0x038a, 0x038b, 0x038c, 0x038d, 0x038e, - 0x038f, 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, - 0x0397, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, - 0x039f, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, - 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, - 0x00cf, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, - 0x0057, 0x0020, 0x0021, 0x0022, 0x0023, 0x000c, 0x000d, 0x0004, - 0x0000, 0x0005, 0x000e, 0x000f, 0x0024, 0x0025, 0x0026, 0x0027, - 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, - 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, - 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, - 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, - 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af, - 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, - 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, - 0x0f40, 0x0f41, 0x0f42, 0x0f43, 0x0f44, 0x0f45, 0x0f46, 0x0f47, - 0x0f48, 0x0f49, 0x0f4a, 0x0f4b, 0x0f4c, 0x0f4d, 0x0f4e, 0x0f4f, - 0x0f50, 0x0f51, 0x0f52, 0x0f53, 0x0f54, 0x0f55, 0x0f56, 0x0f57, - 0x0f58, 0x0f59, 0x0f5a, 0x0f5b, 0x0f5c, 0x0f5d, 0x0f5e, 0x0f5f, - 0x0f60, 0x0f61, 0x0f62, 0x0f63, 0x0f64, 0x0f65, 0x0f66, 0x0f67, - 0x0f68, 0x0f69, 0x0f6a, 0x0f6b, 0x0f6c, 0x0f6d, 0x0f6e, 0x0f6f, - 0x0f70, 0x0f71, 0x0f72, 0x0f73, 0x0f74, 0x0f75, 0x0f76, 0x0f77, - 0x0f78, 0x0f79, 0x0f7a, 0x0f7b, 0x0f7c, 0x0f7d, 0x0f7e, 0x0f7f, +static const uint16_t rv_lum_code[256] = { + 0x3e7f, 0x0f00, 0x0f01, 0x0f02, 0x0f03, 0x0f04, 0x0f05, 0x0f06, + 0x0f07, 0x0f08, 0x0f09, 0x0f0a, 0x0f0b, 0x0f0c, 0x0f0d, 0x0f0e, + 0x0f0f, 0x0f10, 0x0f11, 0x0f12, 0x0f13, 0x0f14, 0x0f15, 0x0f16, + 0x0f17, 0x0f18, 0x0f19, 0x0f1a, 0x0f1b, 0x0f1c, 0x0f1d, 0x0f1e, + 0x0f1f, 0x0f20, 0x0f21, 0x0f22, 0x0f23, 0x0f24, 0x0f25, 0x0f26, + 0x0f27, 0x0f28, 0x0f29, 0x0f2a, 0x0f2b, 0x0f2c, 0x0f2d, 0x0f2e, + 0x0f2f, 0x0f30, 0x0f31, 0x0f32, 0x0f33, 0x0f34, 0x0f35, 0x0f36, + 0x0f37, 0x0f38, 0x0f39, 0x0f3a, 0x0f3b, 0x0f3c, 0x0f3d, 0x0f3e, + 0x0f3f, 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0386, + 0x0387, 0x0388, 0x0389, 0x038a, 0x038b, 0x038c, 0x038d, 0x038e, + 0x038f, 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, + 0x0397, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, + 0x039f, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, + 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, + 0x00cf, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, + 0x0057, 0x0020, 0x0021, 0x0022, 0x0023, 0x000c, 0x000d, 0x0004, + 0x0000, 0x0005, 0x000e, 0x000f, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, + 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af, + 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, + 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, + 0x0f40, 0x0f41, 0x0f42, 0x0f43, 0x0f44, 0x0f45, 0x0f46, 0x0f47, + 0x0f48, 0x0f49, 0x0f4a, 0x0f4b, 0x0f4c, 0x0f4d, 0x0f4e, 0x0f4f, + 0x0f50, 0x0f51, 0x0f52, 0x0f53, 0x0f54, 0x0f55, 0x0f56, 0x0f57, + 0x0f58, 0x0f59, 0x0f5a, 0x0f5b, 0x0f5c, 0x0f5d, 0x0f5e, 0x0f5f, + 0x0f60, 0x0f61, 0x0f62, 0x0f63, 0x0f64, 0x0f65, 0x0f66, 0x0f67, + 0x0f68, 0x0f69, 0x0f6a, 0x0f6b, 0x0f6c, 0x0f6d, 0x0f6e, 0x0f6f, + 0x0f70, 0x0f71, 0x0f72, 0x0f73, 0x0f74, 0x0f75, 0x0f76, 0x0f77, + 0x0f78, 0x0f79, 0x0f7a, 0x0f7b, 0x0f7c, 0x0f7d, 0x0f7e, 0x0f7f, }; -static const uint8_t rv_lum_bits[256] = -{ - 14, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 7, 7, 7, 7, 7, 7, 7, - 7, 6, 6, 6, 6, 5, 5, 4, - 2, 4, 5, 5, 6, 6, 6, 6, - 7, 7, 7, 7, 7, 7, 7, 7, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, +static const uint8_t rv_lum_bits[256] = { + 14, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 7, 7, 7, 7, 7, 7, 7, + 7, 6, 6, 6, 6, 5, 5, 4, + 2, 4, 5, 5, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, }; -static const uint16_t rv_chrom_code[256] = -{ - 0xfe7f, 0x3f00, 0x3f01, 0x3f02, 0x3f03, 0x3f04, 0x3f05, 0x3f06, - 0x3f07, 0x3f08, 0x3f09, 0x3f0a, 0x3f0b, 0x3f0c, 0x3f0d, 0x3f0e, - 0x3f0f, 0x3f10, 0x3f11, 0x3f12, 0x3f13, 0x3f14, 0x3f15, 0x3f16, - 0x3f17, 0x3f18, 0x3f19, 0x3f1a, 0x3f1b, 0x3f1c, 0x3f1d, 0x3f1e, - 0x3f1f, 0x3f20, 0x3f21, 0x3f22, 0x3f23, 0x3f24, 0x3f25, 0x3f26, - 0x3f27, 0x3f28, 0x3f29, 0x3f2a, 0x3f2b, 0x3f2c, 0x3f2d, 0x3f2e, - 0x3f2f, 0x3f30, 0x3f31, 0x3f32, 0x3f33, 0x3f34, 0x3f35, 0x3f36, - 0x3f37, 0x3f38, 0x3f39, 0x3f3a, 0x3f3b, 0x3f3c, 0x3f3d, 0x3f3e, - 0x3f3f, 0x0f80, 0x0f81, 0x0f82, 0x0f83, 0x0f84, 0x0f85, 0x0f86, - 0x0f87, 0x0f88, 0x0f89, 0x0f8a, 0x0f8b, 0x0f8c, 0x0f8d, 0x0f8e, - 0x0f8f, 0x0f90, 0x0f91, 0x0f92, 0x0f93, 0x0f94, 0x0f95, 0x0f96, - 0x0f97, 0x0f98, 0x0f99, 0x0f9a, 0x0f9b, 0x0f9c, 0x0f9d, 0x0f9e, - 0x0f9f, 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, - 0x03c7, 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, - 0x03cf, 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, - 0x00e7, 0x0030, 0x0031, 0x0032, 0x0033, 0x0008, 0x0009, 0x0002, - 0x0000, 0x0003, 0x000a, 0x000b, 0x0034, 0x0035, 0x0036, 0x0037, - 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, - 0x03d0, 0x03d1, 0x03d2, 0x03d3, 0x03d4, 0x03d5, 0x03d6, 0x03d7, - 0x03d8, 0x03d9, 0x03da, 0x03db, 0x03dc, 0x03dd, 0x03de, 0x03df, - 0x0fa0, 0x0fa1, 0x0fa2, 0x0fa3, 0x0fa4, 0x0fa5, 0x0fa6, 0x0fa7, - 0x0fa8, 0x0fa9, 0x0faa, 0x0fab, 0x0fac, 0x0fad, 0x0fae, 0x0faf, - 0x0fb0, 0x0fb1, 0x0fb2, 0x0fb3, 0x0fb4, 0x0fb5, 0x0fb6, 0x0fb7, - 0x0fb8, 0x0fb9, 0x0fba, 0x0fbb, 0x0fbc, 0x0fbd, 0x0fbe, 0x0fbf, - 0x3f40, 0x3f41, 0x3f42, 0x3f43, 0x3f44, 0x3f45, 0x3f46, 0x3f47, - 0x3f48, 0x3f49, 0x3f4a, 0x3f4b, 0x3f4c, 0x3f4d, 0x3f4e, 0x3f4f, - 0x3f50, 0x3f51, 0x3f52, 0x3f53, 0x3f54, 0x3f55, 0x3f56, 0x3f57, - 0x3f58, 0x3f59, 0x3f5a, 0x3f5b, 0x3f5c, 0x3f5d, 0x3f5e, 0x3f5f, - 0x3f60, 0x3f61, 0x3f62, 0x3f63, 0x3f64, 0x3f65, 0x3f66, 0x3f67, - 0x3f68, 0x3f69, 0x3f6a, 0x3f6b, 0x3f6c, 0x3f6d, 0x3f6e, 0x3f6f, - 0x3f70, 0x3f71, 0x3f72, 0x3f73, 0x3f74, 0x3f75, 0x3f76, 0x3f77, - 0x3f78, 0x3f79, 0x3f7a, 0x3f7b, 0x3f7c, 0x3f7d, 0x3f7e, 0x3f7f, +static const uint16_t rv_chrom_code[256] = { + 0xfe7f, 0x3f00, 0x3f01, 0x3f02, 0x3f03, 0x3f04, 0x3f05, 0x3f06, + 0x3f07, 0x3f08, 0x3f09, 0x3f0a, 0x3f0b, 0x3f0c, 0x3f0d, 0x3f0e, + 0x3f0f, 0x3f10, 0x3f11, 0x3f12, 0x3f13, 0x3f14, 0x3f15, 0x3f16, + 0x3f17, 0x3f18, 0x3f19, 0x3f1a, 0x3f1b, 0x3f1c, 0x3f1d, 0x3f1e, + 0x3f1f, 0x3f20, 0x3f21, 0x3f22, 0x3f23, 0x3f24, 0x3f25, 0x3f26, + 0x3f27, 0x3f28, 0x3f29, 0x3f2a, 0x3f2b, 0x3f2c, 0x3f2d, 0x3f2e, + 0x3f2f, 0x3f30, 0x3f31, 0x3f32, 0x3f33, 0x3f34, 0x3f35, 0x3f36, + 0x3f37, 0x3f38, 0x3f39, 0x3f3a, 0x3f3b, 0x3f3c, 0x3f3d, 0x3f3e, + 0x3f3f, 0x0f80, 0x0f81, 0x0f82, 0x0f83, 0x0f84, 0x0f85, 0x0f86, + 0x0f87, 0x0f88, 0x0f89, 0x0f8a, 0x0f8b, 0x0f8c, 0x0f8d, 0x0f8e, + 0x0f8f, 0x0f90, 0x0f91, 0x0f92, 0x0f93, 0x0f94, 0x0f95, 0x0f96, + 0x0f97, 0x0f98, 0x0f99, 0x0f9a, 0x0f9b, 0x0f9c, 0x0f9d, 0x0f9e, + 0x0f9f, 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, + 0x03c7, 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, + 0x03cf, 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, + 0x00e7, 0x0030, 0x0031, 0x0032, 0x0033, 0x0008, 0x0009, 0x0002, + 0x0000, 0x0003, 0x000a, 0x000b, 0x0034, 0x0035, 0x0036, 0x0037, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x03d0, 0x03d1, 0x03d2, 0x03d3, 0x03d4, 0x03d5, 0x03d6, 0x03d7, + 0x03d8, 0x03d9, 0x03da, 0x03db, 0x03dc, 0x03dd, 0x03de, 0x03df, + 0x0fa0, 0x0fa1, 0x0fa2, 0x0fa3, 0x0fa4, 0x0fa5, 0x0fa6, 0x0fa7, + 0x0fa8, 0x0fa9, 0x0faa, 0x0fab, 0x0fac, 0x0fad, 0x0fae, 0x0faf, + 0x0fb0, 0x0fb1, 0x0fb2, 0x0fb3, 0x0fb4, 0x0fb5, 0x0fb6, 0x0fb7, + 0x0fb8, 0x0fb9, 0x0fba, 0x0fbb, 0x0fbc, 0x0fbd, 0x0fbe, 0x0fbf, + 0x3f40, 0x3f41, 0x3f42, 0x3f43, 0x3f44, 0x3f45, 0x3f46, 0x3f47, + 0x3f48, 0x3f49, 0x3f4a, 0x3f4b, 0x3f4c, 0x3f4d, 0x3f4e, 0x3f4f, + 0x3f50, 0x3f51, 0x3f52, 0x3f53, 0x3f54, 0x3f55, 0x3f56, 0x3f57, + 0x3f58, 0x3f59, 0x3f5a, 0x3f5b, 0x3f5c, 0x3f5d, 0x3f5e, 0x3f5f, + 0x3f60, 0x3f61, 0x3f62, 0x3f63, 0x3f64, 0x3f65, 0x3f66, 0x3f67, + 0x3f68, 0x3f69, 0x3f6a, 0x3f6b, 0x3f6c, 0x3f6d, 0x3f6e, 0x3f6f, + 0x3f70, 0x3f71, 0x3f72, 0x3f73, 0x3f74, 0x3f75, 0x3f76, 0x3f77, + 0x3f78, 0x3f79, 0x3f7a, 0x3f7b, 0x3f7c, 0x3f7d, 0x3f7e, 0x3f7f, }; -static const uint8_t rv_chrom_bits[256] = -{ - 16, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 8, 8, 8, 8, 8, 8, 8, - 8, 6, 6, 6, 6, 4, 4, 3, - 2, 3, 4, 4, 6, 6, 6, 6, - 8, 8, 8, 8, 8, 8, 8, 8, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, +static const uint8_t rv_chrom_bits[256] = { + 16, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 8, 8, 8, 8, 8, 8, 8, + 8, 6, 6, 6, 6, 4, 4, 3, + 2, 3, 4, 4, 6, 6, 6, 6, + 8, 8, 8, 8, 8, 8, 8, 8, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, }; static VLC rv_dc_lum, rv_dc_chrom; @@ -252,20 +247,23 @@ static int rv10_decode_picture_header(MpegEncContext *s) s->pict_type = AV_PICTURE_TYPE_P; else s->pict_type = AV_PICTURE_TYPE_I; - if(!marker) av_log(s->avctx, AV_LOG_ERROR, "marker missing\n"); + + if (!marker) + av_log(s->avctx, AV_LOG_ERROR, "marker missing\n"); + pb_frame = get_bits1(&s->gb); av_dlog(s->avctx, "pict_type=%d pb_frame=%d\n", s->pict_type, pb_frame); - if (pb_frame){ - av_log(s->avctx, AV_LOG_ERROR, "pb frame not supported\n"); - return -1; + if (pb_frame) { + avpriv_request_sample(s->avctx, "pb frame"); + return AVERROR_PATCHWELCOME; } s->qscale = get_bits(&s->gb, 5); - if(s->qscale==0){ - av_log(s->avctx, AV_LOG_ERROR, "error, qscale:0\n"); - return -1; + if (s->qscale == 0) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid qscale value: 0\n"); + return AVERROR_INVALIDDATA; } if (s->pict_type == AV_PICTURE_TYPE_I) { @@ -281,14 +279,14 @@ static int rv10_decode_picture_header(MpegEncContext *s) /* if multiple packets per frame are sent, the position at which to display the macroblocks is coded here */ - mb_xy= s->mb_x + s->mb_y*s->mb_width; - if(show_bits(&s->gb, 12)==0 || (mb_xy && mb_xy < s->mb_num)){ - s->mb_x = get_bits(&s->gb, 6); /* mb_x */ - s->mb_y = get_bits(&s->gb, 6); /* mb_y */ + mb_xy = s->mb_x + s->mb_y * s->mb_width; + if (show_bits(&s->gb, 12) == 0 || (mb_xy && mb_xy < s->mb_num)) { + s->mb_x = get_bits(&s->gb, 6); /* mb_x */ + s->mb_y = get_bits(&s->gb, 6); /* mb_y */ mb_count = get_bits(&s->gb, 12); } else { - s->mb_x = 0; - s->mb_y = 0; + s->mb_x = 0; + s->mb_y = 0; mb_count = s->mb_width * s->mb_height; } skip_bits(&s->gb, 3); /* ignored */ @@ -301,84 +299,73 @@ static int rv10_decode_picture_header(MpegEncContext *s) static int rv20_decode_picture_header(RVDecContext *rv) { MpegEncContext *s = &rv->m; - int seq, mb_pos, i; + int seq, mb_pos, i, ret; int rpr_bits; -#if 0 - GetBitContext gb= s->gb; - for(i=0; i<64; i++){ - av_log(s->avctx, AV_LOG_DEBUG, "%d", get_bits1(&gb)); - if(i%4==3) av_log(s->avctx, AV_LOG_DEBUG, " "); - } - av_log(s->avctx, AV_LOG_DEBUG, "\n"); -#endif -#if 0 - av_log(s->avctx, AV_LOG_DEBUG, "%3dx%03d/%02Xx%02X ", s->width, s->height, s->width/4, s->height/4); - for(i=0; iavctx->extradata_size; i++){ - av_log(s->avctx, AV_LOG_DEBUG, "%02X ", ((uint8_t*)s->avctx->extradata)[i]); - if(i%4==3) av_log(s->avctx, AV_LOG_DEBUG, " "); - } - av_log(s->avctx, AV_LOG_DEBUG, "\n"); -#endif - - i= get_bits(&s->gb, 2); - switch(i){ - case 0: s->pict_type= AV_PICTURE_TYPE_I; break; - case 1: s->pict_type= AV_PICTURE_TYPE_I; break; //hmm ... - case 2: s->pict_type= AV_PICTURE_TYPE_P; break; - case 3: s->pict_type= AV_PICTURE_TYPE_B; break; + i = get_bits(&s->gb, 2); + switch(i) { + case 0: s->pict_type = AV_PICTURE_TYPE_I; break; + case 1: s->pict_type = AV_PICTURE_TYPE_I; break; //hmm ... + case 2: s->pict_type = AV_PICTURE_TYPE_P; break; + case 3: s->pict_type = AV_PICTURE_TYPE_B; break; default: av_log(s->avctx, AV_LOG_ERROR, "unknown frame type\n"); - return -1; + return AVERROR_INVALIDDATA; } - if(s->low_delay && s->pict_type==AV_PICTURE_TYPE_B){ + if (s->low_delay && s->pict_type == AV_PICTURE_TYPE_B) { av_log(s->avctx, AV_LOG_ERROR, "low delay B\n"); return -1; } - if(s->last_picture_ptr==NULL && s->pict_type==AV_PICTURE_TYPE_B){ - av_log(s->avctx, AV_LOG_ERROR, "early B pix\n"); - return -1; + if (s->last_picture_ptr == NULL && s->pict_type == AV_PICTURE_TYPE_B) { + av_log(s->avctx, AV_LOG_ERROR, "early B-frame\n"); + return AVERROR_INVALIDDATA; } - if (get_bits1(&s->gb)){ + if (get_bits1(&s->gb)) { av_log(s->avctx, AV_LOG_ERROR, "reserved bit set\n"); - return -1; + return AVERROR_INVALIDDATA; } s->qscale = get_bits(&s->gb, 5); - if(s->qscale==0){ - av_log(s->avctx, AV_LOG_ERROR, "error, qscale:0\n"); - return -1; + if (s->qscale == 0) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid qscale value: 0\n"); + return AVERROR_INVALIDDATA; } - if(RV_GET_MINOR_VER(rv->sub_id) >= 2) + if (RV_GET_MINOR_VER(rv->sub_id) >= 2) s->loop_filter = get_bits1(&s->gb) && !s->avctx->lowres; - if(RV_GET_MINOR_VER(rv->sub_id) <= 1) + if (RV_GET_MINOR_VER(rv->sub_id) <= 1) seq = get_bits(&s->gb, 8) << 7; else seq = get_bits(&s->gb, 13) << 2; rpr_bits = s->avctx->extradata[1] & 7; - if(rpr_bits){ + if (rpr_bits) { int f, new_w, new_h; rpr_bits = FFMIN((rpr_bits >> 1) + 1, 3); f = get_bits(&s->gb, rpr_bits); - if(f){ - new_w= 4*((uint8_t*)s->avctx->extradata)[6+2*f]; - new_h= 4*((uint8_t*)s->avctx->extradata)[7+2*f]; - }else{ - new_w= s->orig_width ; - new_h= s->orig_height; + if (f) { + if (s->avctx->extradata_size < 8 + 2 * f) { + av_log(s->avctx, AV_LOG_ERROR, "Extradata too small.\n"); + return AVERROR_INVALIDDATA; + } + + new_w = 4 * ((uint8_t*)s->avctx->extradata)[6 + 2 * f]; + new_h = 4 * ((uint8_t*)s->avctx->extradata)[7 + 2 * f]; + } else { + new_w = s->orig_width ; + new_h = s->orig_height; } - if(new_w != s->width || new_h != s->height){ + if (new_w != s->width || new_h != s->height) { AVRational old_aspect = s->avctx->sample_aspect_ratio; - av_log(s->avctx, AV_LOG_DEBUG, "attempting to change resolution to %dx%d\n", new_w, new_h); + av_log(s->avctx, AV_LOG_DEBUG, + "attempting to change resolution to %dx%d\n", new_w, new_h); if (av_image_check_size(new_w, new_h, 0, s->avctx) < 0) - return -1; + return AVERROR_INVALIDDATA; ff_MPV_common_end(s); // attempt to keep aspect during typical resolution switches @@ -388,14 +375,18 @@ static int rv20_decode_picture_header(RVDecContext *rv) s->avctx->sample_aspect_ratio = av_mul_q(old_aspect, (AVRational){2, 1}); if (new_w * s->height == 2 * new_h * s->width) s->avctx->sample_aspect_ratio = av_mul_q(old_aspect, (AVRational){1, 2}); - avcodec_set_dimensions(s->avctx, new_w, new_h); + + ret = ff_set_dimensions(s->avctx, new_w, new_h); + if (ret < 0) + return ret; + s->width = new_w; s->height = new_h; - if (ff_MPV_common_init(s) < 0) - return -1; + if ((ret = ff_MPV_common_init(s)) < 0) + return ret; } - if(s->avctx->debug & FF_DEBUG_PICT_INFO){ + if (s->avctx->debug & FF_DEBUG_PICT_INFO) { av_log(s->avctx, AV_LOG_DEBUG, "F %d/%d\n", f, rpr_bits); } } @@ -404,46 +395,47 @@ static int rv20_decode_picture_header(RVDecContext *rv) mb_pos = ff_h263_decode_mba(s); - seq |= s->time &~0x7FFF; - if(seq - s->time > 0x4000) seq -= 0x8000; - if(seq - s->time < -0x4000) seq += 0x8000; - if(seq != s->time){ - if(s->pict_type!=AV_PICTURE_TYPE_B){ - s->time= seq; - s->pp_time= s->time - s->last_non_b_time; - s->last_non_b_time= s->time; - }else{ - s->time= seq; - s->pb_time= s->pp_time - (s->last_non_b_time - s->time); + seq |= s->time & ~0x7FFF; + if (seq - s->time > 0x4000) + seq -= 0x8000; + if (seq - s->time < -0x4000) + seq += 0x8000; + + if (seq != s->time) { + if (s->pict_type != AV_PICTURE_TYPE_B) { + s->time = seq; + s->pp_time = s->time - s->last_non_b_time; + s->last_non_b_time = s->time; + } else { + s->time = seq; + s->pb_time = s->pp_time - (s->last_non_b_time - s->time); } } - if (s->pict_type==AV_PICTURE_TYPE_B) { - if(s->pp_time <=s->pb_time || s->pp_time <= s->pp_time - s->pb_time || s->pp_time<=0){ - av_log(s->avctx, AV_LOG_DEBUG, "messed up order, possible from seeking? skipping current b frame\n"); + if (s->pict_type == AV_PICTURE_TYPE_B) { + if (s->pp_time <=s->pb_time || s->pp_time <= s->pp_time - s->pb_time || s->pp_time<=0) { + av_log(s->avctx, AV_LOG_DEBUG, + "messed up order, possible from seeking? skipping current b frame\n"); #define ERROR_SKIP_FRAME -123 return ERROR_SKIP_FRAME; } ff_mpeg4_init_direct_mv(s); } - s->no_rounding= get_bits1(&s->gb); + s->no_rounding = get_bits1(&s->gb); - if(RV_GET_MINOR_VER(rv->sub_id) <= 1 && s->pict_type == AV_PICTURE_TYPE_B) + if (RV_GET_MINOR_VER(rv->sub_id) <= 1 && s->pict_type == AV_PICTURE_TYPE_B) skip_bits(&s->gb, 5); // binary decoder reads 3+2 bits here but they don't seem to be used - s->f_code = 1; + s->f_code = 1; s->unrestricted_mv = 1; - s->h263_aic= s->pict_type == AV_PICTURE_TYPE_I; -// s->alt_inter_vlc=1; -// s->obmc=1; -// s->umvplus=1; - s->modified_quant=1; - if(!s->avctx->lowres) - s->loop_filter=1; - - if(s->avctx->debug & FF_DEBUG_PICT_INFO){ - av_log(s->avctx, AV_LOG_INFO, "num:%5d x:%2d y:%2d type:%d qscale:%2d rnd:%d\n", - seq, s->mb_x, s->mb_y, s->pict_type, s->qscale, s->no_rounding); + s->h263_aic = s->pict_type == AV_PICTURE_TYPE_I; + s->modified_quant = 1; + if (!s->avctx->lowres) + s->loop_filter = 1; + + if (s->avctx->debug & FF_DEBUG_PICT_INFO) { + av_log(s->avctx, AV_LOG_INFO, "num:%5d x:%2d y:%2d type:%d qscale:%2d rnd:%d\n", + seq, s->mb_x, s->mb_y, s->pict_type, s->qscale, s->no_rounding); } av_assert0(s->pict_type != AV_PICTURE_TYPE_B || !s->low_delay); @@ -455,25 +447,28 @@ static av_cold int rv10_decode_init(AVCodecContext *avctx) { RVDecContext *rv = avctx->priv_data; MpegEncContext *s = &rv->m; - static int done=0; - int major_ver, minor_ver, micro_ver; + static int done = 0; + int major_ver, minor_ver, micro_ver, ret; if (avctx->extradata_size < 8) { av_log(avctx, AV_LOG_ERROR, "Extradata is too small.\n"); - return -1; + return AVERROR_INVALIDDATA; } + if ((ret = av_image_check_size(avctx->coded_width, + avctx->coded_height, 0, avctx)) < 0) + return ret; ff_MPV_decode_defaults(s); - s->avctx= avctx; + s->avctx = avctx; s->out_format = FMT_H263; - s->codec_id= avctx->codec_id; + s->codec_id = avctx->codec_id; - s->orig_width = s->width = avctx->coded_width; - s->orig_height= s->height = avctx->coded_height; + s->orig_width = s->width = avctx->coded_width; + s->orig_height = s->height = avctx->coded_height; - s->h263_long_vectors= ((uint8_t*)avctx->extradata)[3] & 1; - rv->sub_id = AV_RB32((uint8_t*)avctx->extradata + 4); + s->h263_long_vectors = ((uint8_t*)avctx->extradata)[3] & 1; + rv->sub_id = AV_RB32((uint8_t*)avctx->extradata + 4); major_ver = RV_GET_MAJOR_VER(rv->sub_id); minor_ver = RV_GET_MINOR_VER(rv->sub_id); @@ -483,11 +478,11 @@ static av_cold int rv10_decode_init(AVCodecContext *avctx) switch (major_ver) { case 1: s->rv10_version = micro_ver ? 3 : 1; - s->obmc = micro_ver == 2; + s->obmc = micro_ver == 2; break; case 2: if (minor_ver >= 2) { - s->low_delay = 0; + s->low_delay = 0; s->avctx->has_b_frames = 1; } break; @@ -497,25 +492,27 @@ static av_cold int rv10_decode_init(AVCodecContext *avctx) return AVERROR_PATCHWELCOME; } - if(avctx->debug & FF_DEBUG_PICT_INFO){ - av_log(avctx, AV_LOG_DEBUG, "ver:%X ver0:%X\n", rv->sub_id, ((uint32_t*)avctx->extradata)[0]); + if (avctx->debug & FF_DEBUG_PICT_INFO) { + av_log(avctx, AV_LOG_DEBUG, "ver:%X ver0:%X\n", rv->sub_id, + ((uint32_t*)avctx->extradata)[0]); } avctx->pix_fmt = AV_PIX_FMT_YUV420P; - if (ff_MPV_common_init(s) < 0) - return -1; + if ((ret = ff_MPV_common_init(s)) < 0) + return ret; + ff_h263dsp_init(&s->h263dsp); ff_h263_decode_init_vlc(); /* init rv vlc */ if (!done) { INIT_VLC_STATIC(&rv_dc_lum, DC_VLC_BITS, 256, - rv_lum_bits, 1, 1, - rv_lum_code, 2, 2, 16384); + rv_lum_bits, 1, 1, + rv_lum_code, 2, 2, 16384); INIT_VLC_STATIC(&rv_dc_chrom, DC_VLC_BITS, 256, - rv_chrom_bits, 1, 1, - rv_chrom_code, 2, 2, 16388); + rv_chrom_bits, 1, 1, + rv_chrom_code, 2, 2, 16388); done = 1; } @@ -531,49 +528,49 @@ static av_cold int rv10_decode_end(AVCodecContext *avctx) } static int rv10_decode_packet(AVCodecContext *avctx, - const uint8_t *buf, int buf_size, int buf_size2) + const uint8_t *buf, int buf_size, int buf_size2) { RVDecContext *rv = avctx->priv_data; MpegEncContext *s = &rv->m; - int mb_count, mb_pos, left, start_mb_x, active_bits_size; + int mb_count, mb_pos, left, start_mb_x, active_bits_size, ret; active_bits_size = buf_size * 8; init_get_bits(&s->gb, buf, FFMAX(buf_size, buf_size2) * 8); - if(s->codec_id ==AV_CODEC_ID_RV10) + if (s->codec_id == AV_CODEC_ID_RV10) mb_count = rv10_decode_picture_header(s); else mb_count = rv20_decode_picture_header(rv); if (mb_count < 0) { if (mb_count != ERROR_SKIP_FRAME) av_log(s->avctx, AV_LOG_ERROR, "HEADER ERROR\n"); - return -1; + return AVERROR_INVALIDDATA; } if (s->mb_x >= s->mb_width || s->mb_y >= s->mb_height) { av_log(s->avctx, AV_LOG_ERROR, "POS ERROR %d %d\n", s->mb_x, s->mb_y); - return -1; + return AVERROR_INVALIDDATA; } mb_pos = s->mb_y * s->mb_width + s->mb_x; left = s->mb_width * s->mb_height - mb_pos; if (mb_count > left) { av_log(s->avctx, AV_LOG_ERROR, "COUNT ERROR\n"); - return -1; + return AVERROR_INVALIDDATA; } - if ((s->mb_x == 0 && s->mb_y == 0) || s->current_picture_ptr==NULL) { - if(s->current_picture_ptr){ //FIXME write parser so we always have complete frames? + if ((s->mb_x == 0 && s->mb_y == 0) || s->current_picture_ptr == NULL) { + if (s->current_picture_ptr) { // FIXME write parser so we always have complete frames? ff_er_frame_end(&s->er); ff_MPV_frame_end(s); - s->mb_x= s->mb_y = s->resync_mb_x = s->resync_mb_y= 0; + s->mb_x = s->mb_y = s->resync_mb_x = s->resync_mb_y = 0; } - if(ff_MPV_frame_start(s, avctx) < 0) - return -1; + if ((ret = ff_MPV_frame_start(s, avctx)) < 0) + return ret; ff_mpeg_er_frame_start(s); } else { if (s->current_picture_ptr->f.pict_type != s->pict_type) { av_log(s->avctx, AV_LOG_ERROR, "Slice type mismatch\n"); - return -1; + return AVERROR_INVALIDDATA; } } @@ -581,47 +578,46 @@ static int rv10_decode_packet(AVCodecContext *avctx, av_dlog(avctx, "qscale=%d\n", s->qscale); /* default quantization values */ - if(s->codec_id== AV_CODEC_ID_RV10){ - if(s->mb_y==0) s->first_slice_line=1; - }else{ - s->first_slice_line=1; - s->resync_mb_x= s->mb_x; + if (s->codec_id == AV_CODEC_ID_RV10) { + if (s->mb_y == 0) + s->first_slice_line = 1; + } else { + s->first_slice_line = 1; + s->resync_mb_x = s->mb_x; } - start_mb_x= s->mb_x; - s->resync_mb_y= s->mb_y; - if(s->h263_aic){ - s->y_dc_scale_table= - s->c_dc_scale_table= ff_aic_dc_scale_table; - }else{ - s->y_dc_scale_table= - s->c_dc_scale_table= ff_mpeg1_dc_scale_table; + start_mb_x = s->mb_x; + s->resync_mb_y = s->mb_y; + if (s->h263_aic) { + s->y_dc_scale_table = s->c_dc_scale_table = ff_aic_dc_scale_table; + } else { + s->y_dc_scale_table = s->c_dc_scale_table = ff_mpeg1_dc_scale_table; } - if(s->modified_quant) - s->chroma_qscale_table= ff_h263_chroma_qscale_table; + if (s->modified_quant) + s->chroma_qscale_table = ff_h263_chroma_qscale_table; ff_set_qscale(s, s->qscale); s->rv10_first_dc_coded[0] = 0; s->rv10_first_dc_coded[1] = 0; s->rv10_first_dc_coded[2] = 0; - s->block_wrap[0]= - s->block_wrap[1]= - s->block_wrap[2]= - s->block_wrap[3]= s->b8_stride; - s->block_wrap[4]= - s->block_wrap[5]= s->mb_stride; + s->block_wrap[0] = + s->block_wrap[1] = + s->block_wrap[2] = + s->block_wrap[3] = s->b8_stride; + s->block_wrap[4] = + s->block_wrap[5] = s->mb_stride; ff_init_block_index(s); - /* decode each macroblock */ - for(s->mb_num_left= mb_count; s->mb_num_left>0; s->mb_num_left--) { + /* decode each macroblock */ + for (s->mb_num_left = mb_count; s->mb_num_left > 0; s->mb_num_left--) { int ret; ff_update_block_index(s); av_dlog(avctx, "**mb x=%d y=%d\n", s->mb_x, s->mb_y); - s->mv_dir = MV_DIR_FORWARD; + s->mv_dir = MV_DIR_FORWARD; s->mv_type = MV_TYPE_16X16; - ret=ff_h263_decode_mb(s, s->block); + ret = ff_h263_decode_mb(s, s->block); // Repeat the slice end check from ff_h263_decode_mb with our active // bitstream size @@ -639,17 +635,17 @@ static int rv10_decode_packet(AVCodecContext *avctx, active_bits_size = buf_size2 * 8; av_log(avctx, AV_LOG_DEBUG, "update size from %d to %d\n", 8 * buf_size, active_bits_size); - ret= SLICE_OK; + ret = SLICE_OK; } if (ret == SLICE_ERROR || active_bits_size < get_bits_count(&s->gb)) { av_log(s->avctx, AV_LOG_ERROR, "ERROR at MB %d %d\n", s->mb_x, s->mb_y); - return -1; + return AVERROR_INVALIDDATA; } - if(s->pict_type != AV_PICTURE_TYPE_B) + if (s->pict_type != AV_PICTURE_TYPE_B) ff_h263_update_motion_val(s); ff_MPV_decode_mb(s, s->block); - if(s->loop_filter) + if (s->loop_filter) ff_h263_loop_filter(s); if (++s->mb_x == s->mb_width) { @@ -657,20 +653,24 @@ static int rv10_decode_packet(AVCodecContext *avctx, s->mb_y++; ff_init_block_index(s); } - if(s->mb_x == s->resync_mb_x) - s->first_slice_line=0; - if(ret == SLICE_END) break; + if (s->mb_x == s->resync_mb_x) + s->first_slice_line = 0; + if (ret == SLICE_END) + break; } - ff_er_add_slice(&s->er, start_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END); + ff_er_add_slice(&s->er, start_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, + ER_MB_END); return active_bits_size; } static int get_slice_offset(AVCodecContext *avctx, const uint8_t *buf, int n) { - if(avctx->slice_count) return avctx->slice_offset[n]; - else return AV_RL32(buf + n*8); + if (avctx->slice_count) + return avctx->slice_offset[n]; + else + return AV_RL32(buf + n * 8); } static int rv10_decode_frame(AVCodecContext *avctx, @@ -678,10 +678,10 @@ static int rv10_decode_frame(AVCodecContext *avctx, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - MpegEncContext *s = avctx->priv_data; + int buf_size = avpkt->size; + MpegEncContext *s = avctx->priv_data; + AVFrame *pict = data; int i, ret; - AVFrame *pict = data; int slice_count; const uint8_t *slices_hdr = NULL; @@ -694,7 +694,7 @@ static int rv10_decode_frame(AVCodecContext *avctx, return 0; } - if(!avctx->slice_count){ + if (!avctx->slice_count) { slice_count = (*buf++) + 1; buf_size--; @@ -704,37 +704,37 @@ static int rv10_decode_frame(AVCodecContext *avctx, } slices_hdr = buf + 4; - buf += 8 * slice_count; - buf_size -= 8 * slice_count; - }else + buf += 8 * slice_count; + buf_size -= 8 * slice_count; + } else slice_count = avctx->slice_count; - for(i=0; i= buf_size) return AVERROR_INVALIDDATA; - if(i+1 == slice_count) - size= buf_size - offset; + if (i + 1 == slice_count) + size = buf_size - offset; else - size= get_slice_offset(avctx, slices_hdr, i+1) - offset; + size = get_slice_offset(avctx, slices_hdr, i + 1) - offset; - if(i+2 >= slice_count) - size2= buf_size - offset; + if (i + 2 >= slice_count) + size2 = buf_size - offset; else - size2= get_slice_offset(avctx, slices_hdr, i+2) - offset; + size2 = get_slice_offset(avctx, slices_hdr, i + 2) - offset; if (size <= 0 || size2 <= 0 || offset + FFMAX(size, size2) > buf_size) return AVERROR_INVALIDDATA; - if(rv10_decode_packet(avctx, buf+offset, size, size2) > 8*size) + if (rv10_decode_packet(avctx, buf + offset, size, size2) > 8 * size) i++; } - if(s->current_picture_ptr != NULL && s->mb_y>=s->mb_height){ + if (s->current_picture_ptr != NULL && s->mb_y >= s->mb_height) { ff_er_frame_end(&s->er); ff_MPV_frame_end(s); @@ -750,10 +750,12 @@ static int rv10_decode_frame(AVCodecContext *avctx, ff_mpv_export_qp_table(s, pict,s->last_picture_ptr, FF_QSCALE_TYPE_MPEG1); } - if(s->last_picture_ptr || s->low_delay){ + if (s->last_picture_ptr || s->low_delay) { *got_frame = 1; } - s->current_picture_ptr= NULL; // so we can detect if frame_end was not called (find some nicer solution...) + + // so we can detect if frame_end was not called (find some nicer solution...) + s->current_picture_ptr = NULL; } return avpkt->size; @@ -761,6 +763,7 @@ static int rv10_decode_frame(AVCodecContext *avctx, AVCodec ff_rv10_decoder = { .name = "rv10", + .long_name = NULL_IF_CONFIG_SMALL("RealVideo 1.0"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_RV10, .priv_data_size = sizeof(RVDecContext), @@ -769,12 +772,12 @@ AVCodec ff_rv10_decoder = { .decode = rv10_decode_frame, .capabilities = CODEC_CAP_DR1, .max_lowres = 3, - .long_name = NULL_IF_CONFIG_SMALL("RealVideo 1.0"), .pix_fmts = ff_pixfmt_list_420, }; AVCodec ff_rv20_decoder = { .name = "rv20", + .long_name = NULL_IF_CONFIG_SMALL("RealVideo 2.0"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_RV20, .priv_data_size = sizeof(RVDecContext), @@ -784,6 +787,5 @@ AVCodec ff_rv20_decoder = { .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY, .flush = ff_mpeg_flush, .max_lowres = 3, - .long_name = NULL_IF_CONFIG_SMALL("RealVideo 2.0"), .pix_fmts = ff_pixfmt_list_420, }; diff --git a/ffmpeg/libavcodec/rv10enc.c b/ffmpeg/libavcodec/rv10enc.c index c4c5c53..1f85743 100644 --- a/ffmpeg/libavcodec/rv10enc.c +++ b/ffmpeg/libavcodec/rv10enc.c @@ -60,6 +60,7 @@ FF_MPV_GENERIC_CLASS(rv10) AVCodec ff_rv10_encoder = { .name = "rv10", + .long_name = NULL_IF_CONFIG_SMALL("RealVideo 1.0"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_RV10, .priv_data_size = sizeof(MpegEncContext), @@ -67,6 +68,5 @@ AVCodec ff_rv10_encoder = { .encode2 = ff_MPV_encode_picture, .close = ff_MPV_encode_end, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("RealVideo 1.0"), .priv_class = &rv10_class, }; diff --git a/ffmpeg/libavcodec/rv20enc.c b/ffmpeg/libavcodec/rv20enc.c index 295699a..b943116 100644 --- a/ffmpeg/libavcodec/rv20enc.c +++ b/ffmpeg/libavcodec/rv20enc.c @@ -61,6 +61,7 @@ FF_MPV_GENERIC_CLASS(rv20) AVCodec ff_rv20_encoder = { .name = "rv20", + .long_name = NULL_IF_CONFIG_SMALL("RealVideo 2.0"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_RV20, .priv_data_size = sizeof(MpegEncContext), @@ -68,6 +69,5 @@ AVCodec ff_rv20_encoder = { .encode2 = ff_MPV_encode_picture, .close = ff_MPV_encode_end, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("RealVideo 2.0"), .priv_class = &rv20_class, }; diff --git a/ffmpeg/libavcodec/rv30.c b/ffmpeg/libavcodec/rv30.c index a99980e..7690da7 100644 --- a/ffmpeg/libavcodec/rv30.c +++ b/ffmpeg/libavcodec/rv30.c @@ -124,7 +124,7 @@ static int rv30_decode_mb_info(RV34DecContext *r) static inline void rv30_weak_loop_filter(uint8_t *src, const int step, const int stride, const int lim) { - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; int i, diff; for(i = 0; i < 4; i++){ @@ -248,9 +248,11 @@ static void rv30_loop_filter(RV34DecContext *r, int row) static av_cold int rv30_decode_init(AVCodecContext *avctx) { RV34DecContext *r = avctx->priv_data; + int ret; r->rv30 = 1; - ff_rv34_decode_init(avctx); + if ((ret = ff_rv34_decode_init(avctx)) < 0) + return ret; if(avctx->extradata_size < 2){ av_log(avctx, AV_LOG_ERROR, "Extradata is too small.\n"); return -1; @@ -272,6 +274,7 @@ static av_cold int rv30_decode_init(AVCodecContext *avctx) AVCodec ff_rv30_decoder = { .name = "rv30", + .long_name = NULL_IF_CONFIG_SMALL("RealVideo 3.0"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_RV30, .priv_data_size = sizeof(RV34DecContext), @@ -281,7 +284,6 @@ AVCodec ff_rv30_decoder = { .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_FRAME_THREADS, .flush = ff_mpeg_flush, - .long_name = NULL_IF_CONFIG_SMALL("RealVideo 3.0"), .pix_fmts = ff_pixfmt_list_420, .init_thread_copy = ONLY_IF_THREADS_ENABLED(ff_rv34_decode_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(ff_rv34_decode_update_thread_context), diff --git a/ffmpeg/libavcodec/rv30dsp.c b/ffmpeg/libavcodec/rv30dsp.c index 362b2a5..5e47b64 100644 --- a/ffmpeg/libavcodec/rv30dsp.c +++ b/ffmpeg/libavcodec/rv30dsp.c @@ -32,7 +32,7 @@ #define RV30_LOWPASS(OPNAME, OP) \ static av_unused void OPNAME ## rv30_tpel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, const int C1, const int C2){\ const int h = 8;\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ int i;\ for(i = 0; i < h; i++)\ {\ @@ -51,7 +51,7 @@ static av_unused void OPNAME ## rv30_tpel8_h_lowpass(uint8_t *dst, uint8_t *src, \ static void OPNAME ## rv30_tpel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, const int C1, const int C2){\ const int w = 8;\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ int i;\ for(i = 0; i < w; i++)\ {\ @@ -82,7 +82,7 @@ static void OPNAME ## rv30_tpel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstSt static void OPNAME ## rv30_tpel8_hv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ const int w = 8;\ const int h = 8;\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ int i, j;\ for(j = 0; j < h; j++){\ for(i = 0; i < w; i++){\ @@ -101,7 +101,7 @@ static void OPNAME ## rv30_tpel8_hv_lowpass(uint8_t *dst, uint8_t *src, int dstS static void OPNAME ## rv30_tpel8_hhv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ const int w = 8;\ const int h = 8;\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ int i, j;\ for(j = 0; j < h; j++){\ for(i = 0; i < w; i++){\ @@ -120,7 +120,7 @@ static void OPNAME ## rv30_tpel8_hhv_lowpass(uint8_t *dst, uint8_t *src, int dst static void OPNAME ## rv30_tpel8_hvv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ const int w = 8;\ const int h = 8;\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ int i, j;\ for(j = 0; j < h; j++){\ for(i = 0; i < w; i++){\ @@ -139,7 +139,7 @@ static void OPNAME ## rv30_tpel8_hvv_lowpass(uint8_t *dst, uint8_t *src, int dst static void OPNAME ## rv30_tpel8_hhvv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ const int w = 8;\ const int h = 8;\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ int i, j;\ for(j = 0; j < h; j++){\ for(i = 0; i < w; i++){\ diff --git a/ffmpeg/libavcodec/rv34.c b/ffmpeg/libavcodec/rv34.c index 35f9dea..da2d530 100644 --- a/ffmpeg/libavcodec/rv34.c +++ b/ffmpeg/libavcodec/rv34.c @@ -40,8 +40,6 @@ #include "rv34data.h" #include "rv34.h" -//#define DEBUG - static inline void ZERO8x2(void* dst, int stride) { fill_rectangle(dst, 1, 2, stride, 0, 4); @@ -726,13 +724,22 @@ static inline void rv34_mc(RV34DecContext *r, const int block_type, uint8_t *uvbuf = s->edge_emu_buffer + 22 * s->linesize; srcY -= 2 + 2*s->linesize; - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, (width<<3)+6, (height<<3)+6, - src_x - 2, src_y - 2, s->h_edge_pos, s->v_edge_pos); + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY, + s->linesize, s->linesize, + (width << 3) + 6, (height << 3) + 6, + src_x - 2, src_y - 2, + s->h_edge_pos, s->v_edge_pos); srcY = s->edge_emu_buffer + 2 + 2*s->linesize; - s->vdsp.emulated_edge_mc(uvbuf , srcU, s->uvlinesize, (width<<2)+1, (height<<2)+1, - uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1); - s->vdsp.emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, (width<<2)+1, (height<<2)+1, - uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1); + s->vdsp.emulated_edge_mc(uvbuf, srcU, + s->uvlinesize, s->uvlinesize, + (width << 2) + 1, (height << 2) + 1, + uvsrc_x, uvsrc_y, + s->h_edge_pos >> 1, s->v_edge_pos >> 1); + s->vdsp.emulated_edge_mc(uvbuf + 16, srcV, + s->uvlinesize, s->uvlinesize, + (width << 2) + 1, (height << 2) + 1, + uvsrc_x, uvsrc_y, + s->h_edge_pos >> 1, s->v_edge_pos >> 1); srcU = uvbuf; srcV = uvbuf + 16; } @@ -1355,11 +1362,11 @@ static int rv34_decoder_alloc(RV34DecContext *r) { r->intra_types_stride = r->s.mb_width * 4 + 4; - r->cbp_chroma = av_malloc(r->s.mb_stride * r->s.mb_height * + r->cbp_chroma = av_mallocz(r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_chroma)); - r->cbp_luma = av_malloc(r->s.mb_stride * r->s.mb_height * + r->cbp_luma = av_mallocz(r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_luma)); - r->deblock_coefs = av_malloc(r->s.mb_stride * r->s.mb_height * + r->deblock_coefs = av_mallocz(r->s.mb_stride * r->s.mb_height * sizeof(*r->deblock_coefs)); r->intra_types_hist = av_malloc(r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist)); @@ -1502,8 +1509,10 @@ av_cold int ff_rv34_decode_init(AVCodecContext *avctx) ff_rv40dsp_init(&r->rdsp); #endif - if ((ret = rv34_decoder_alloc(r)) < 0) + if ((ret = rv34_decoder_alloc(r)) < 0) { + ff_MPV_common_end(&r->s); return ret; + } if(!intra_vlcs[0].cbppattern[0].bits) rv34_init_tables(); @@ -1524,8 +1533,10 @@ int ff_rv34_decode_init_thread_copy(AVCodecContext *avctx) r->tmp_b_block_base = NULL; if ((err = ff_MPV_common_init(&r->s)) < 0) return err; - if ((err = rv34_decoder_alloc(r)) < 0) + if ((err = rv34_decoder_alloc(r)) < 0) { + ff_MPV_common_end(&r->s); return err; + } } return 0; @@ -1688,7 +1699,11 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, si.width, si.height); s->width = si.width; s->height = si.height; - avcodec_set_dimensions(s->avctx, s->width, s->height); + + err = ff_set_dimensions(s->avctx, s->width, s->height); + if (err < 0) + return err; + if ((err = ff_MPV_common_frame_size_change(s)) < 0) return err; if ((err = rv34_decoder_realloc(r)) < 0) diff --git a/ffmpeg/libavcodec/rv34_parser.c b/ffmpeg/libavcodec/rv34_parser.c index 8af7443..6a07a5f 100644 --- a/ffmpeg/libavcodec/rv34_parser.c +++ b/ffmpeg/libavcodec/rv34_parser.c @@ -2,20 +2,20 @@ * RV30/40 parser * Copyright (c) 2011 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/rv34dsp.c b/ffmpeg/libavcodec/rv34dsp.c index 7234ee8..c3f245e 100644 --- a/ffmpeg/libavcodec/rv34dsp.c +++ b/ffmpeg/libavcodec/rv34dsp.c @@ -3,20 +3,20 @@ * Copyright (c) 2007 Mike Melanson, Konstantin Shishkov * Copyright (c) 2011 Janne Grunau * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/rv34dsp.h b/ffmpeg/libavcodec/rv34dsp.h index c5d4e39..7e28b26 100644 --- a/ffmpeg/libavcodec/rv34dsp.h +++ b/ffmpeg/libavcodec/rv34dsp.h @@ -2,20 +2,20 @@ * RV30/40 decoder motion compensation functions * Copyright (c) 2008 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/rv40.c b/ffmpeg/libavcodec/rv40.c index d6dfc5e..17a2f91 100644 --- a/ffmpeg/libavcodec/rv40.c +++ b/ffmpeg/libavcodec/rv40.c @@ -359,7 +359,7 @@ static void rv40_loop_filter(RV34DecContext *r, int row) int uvcbp[4][2]; /** * This mask represents the pattern of luma subblocks that should be filtered - * in addition to the coded ones because because they lie at the edge of + * in addition to the coded ones because they lie at the edge of * 8x8 block with different enough motion vectors */ unsigned mvmasks[4]; @@ -547,9 +547,11 @@ static void rv40_loop_filter(RV34DecContext *r, int row) static av_cold int rv40_decode_init(AVCodecContext *avctx) { RV34DecContext *r = avctx->priv_data; + int ret; r->rv30 = 0; - ff_rv34_decode_init(avctx); + if ((ret = ff_rv34_decode_init(avctx)) < 0) + return ret; if(!aic_top_vlc.bits) rv40_init_tables(); r->parse_slice_header = rv40_parse_slice_header; @@ -563,6 +565,7 @@ static av_cold int rv40_decode_init(AVCodecContext *avctx) AVCodec ff_rv40_decoder = { .name = "rv40", + .long_name = NULL_IF_CONFIG_SMALL("RealVideo 4.0"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_RV40, .priv_data_size = sizeof(RV34DecContext), @@ -572,7 +575,6 @@ AVCodec ff_rv40_decoder = { .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_FRAME_THREADS, .flush = ff_mpeg_flush, - .long_name = NULL_IF_CONFIG_SMALL("RealVideo 4.0"), .pix_fmts = ff_pixfmt_list_420, .init_thread_copy = ONLY_IF_THREADS_ENABLED(ff_rv34_decode_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(ff_rv34_decode_update_thread_context), diff --git a/ffmpeg/libavcodec/rv40dsp.c b/ffmpeg/libavcodec/rv40dsp.c index fda8947..bdd9a3e 100644 --- a/ffmpeg/libavcodec/rv40dsp.c +++ b/ffmpeg/libavcodec/rv40dsp.c @@ -33,7 +33,7 @@ #define RV40_LOWPASS(OPNAME, OP) \ static av_unused void OPNAME ## rv40_qpel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride,\ const int h, const int C1, const int C2, const int SHIFT){\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ int i;\ for(i = 0; i < h; i++)\ {\ @@ -52,7 +52,7 @@ static av_unused void OPNAME ## rv40_qpel8_h_lowpass(uint8_t *dst, uint8_t *src, \ static void OPNAME ## rv40_qpel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride,\ const int w, const int C1, const int C2, const int SHIFT){\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ int i;\ for(i = 0; i < w; i++)\ {\ @@ -351,7 +351,7 @@ static av_always_inline void rv40_weak_loop_filter(uint8_t *src, const int lim_q1, const int lim_p1) { - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; int i, t, u, diff; for (i = 0; i < 4; i++, src += stride) { @@ -619,8 +619,8 @@ av_cold void ff_rv40dsp_init(RV34DSPContext *c) c->rv40_loop_filter_strength[0] = rv40_h_loop_filter_strength; c->rv40_loop_filter_strength[1] = rv40_v_loop_filter_strength; - if (ARCH_X86) - ff_rv40dsp_init_x86(c); if (ARCH_ARM) ff_rv40dsp_init_arm(c); + if (ARCH_X86) + ff_rv40dsp_init_x86(c); } diff --git a/ffmpeg/libavcodec/s302m.c b/ffmpeg/libavcodec/s302m.c index 5f73148..7639a0f 100644 --- a/ffmpeg/libavcodec/s302m.c +++ b/ffmpeg/libavcodec/s302m.c @@ -59,7 +59,7 @@ static int s302m_parse_frame_header(AVCodecContext *avctx, const uint8_t *buf, } /* Set output properties */ - avctx->bits_per_coded_sample = bits; + avctx->bits_per_raw_sample = bits; if (bits > 16) avctx->sample_fmt = AV_SAMPLE_FMT_S32; else @@ -80,10 +80,10 @@ static int s302m_parse_frame_header(AVCodecContext *avctx, const uint8_t *buf, avctx->channel_layout = AV_CH_LAYOUT_5POINT1_BACK | AV_CH_LAYOUT_STEREO_DOWNMIX; } avctx->sample_rate = 48000; - avctx->bit_rate = 48000 * avctx->channels * (avctx->bits_per_coded_sample + 4) + + avctx->bit_rate = 48000 * avctx->channels * (avctx->bits_per_raw_sample + 4) + 32 * (48000 / (buf_size * 8 / (avctx->channels * - (avctx->bits_per_coded_sample + 4)))); + (avctx->bits_per_raw_sample + 4)))); return frame_size; } @@ -104,14 +104,14 @@ static int s302m_decode_frame(AVCodecContext *avctx, void *data, buf += AES3_HEADER_LEN; /* get output buffer */ - block_size = (avctx->bits_per_coded_sample + 4) / 4; + block_size = (avctx->bits_per_raw_sample + 4) / 4; frame->nb_samples = 2 * (buf_size / block_size) / avctx->channels; if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; buf_size = (frame->nb_samples * avctx->channels / 2) * block_size; - if (avctx->bits_per_coded_sample == 24) { + if (avctx->bits_per_raw_sample == 24) { uint32_t *o = (uint32_t *)frame->data[0]; for (; buf_size > 6; buf_size -= 7) { *o++ = (ff_reverse[buf[2]] << 24) | @@ -123,7 +123,7 @@ static int s302m_decode_frame(AVCodecContext *avctx, void *data, (ff_reverse[buf[3] & 0x0f] << 4); buf += 7; } - } else if (avctx->bits_per_coded_sample == 20) { + } else if (avctx->bits_per_raw_sample == 20) { uint32_t *o = (uint32_t *)frame->data[0]; for (; buf_size > 5; buf_size -= 6) { *o++ = (ff_reverse[buf[2] & 0xf0] << 28) | @@ -153,9 +153,9 @@ static int s302m_decode_frame(AVCodecContext *avctx, void *data, AVCodec ff_s302m_decoder = { .name = "s302m", + .long_name = NULL_IF_CONFIG_SMALL("SMPTE 302M"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_S302M, .decode = s302m_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("SMPTE 302M"), }; diff --git a/ffmpeg/libavcodec/s3tc.c b/ffmpeg/libavcodec/s3tc.c index 4e791c8..4743d78 100644 --- a/ffmpeg/libavcodec/s3tc.c +++ b/ffmpeg/libavcodec/s3tc.c @@ -21,8 +21,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "libavcodec/bytestream.h" #include "avcodec.h" +#include "bytestream.h" #include "s3tc.h" static inline void dxt1_decode_pixels(GetByteContext *gb, uint32_t *d, diff --git a/ffmpeg/libavcodec/sanm.c b/ffmpeg/libavcodec/sanm.c index f217ef3..a6c1c01 100644 --- a/ffmpeg/libavcodec/sanm.c +++ b/ffmpeg/libavcodec/sanm.c @@ -732,12 +732,16 @@ static int process_frame_obj(SANMVideoContext *ctx) w = bytestream2_get_le16u(&ctx->gb); h = bytestream2_get_le16u(&ctx->gb); + if (!w || !h) { + av_log(ctx->avctx, AV_LOG_ERROR, "dimensions are invalid\n"); + return AVERROR_INVALIDDATA; + } + if (ctx->width < left + w || ctx->height < top + h) { - if (av_image_check_size(FFMAX(left + w, ctx->width), - FFMAX(top + h, ctx->height), 0, ctx->avctx) < 0) - return AVERROR_INVALIDDATA; - avcodec_set_dimensions(ctx->avctx, FFMAX(left + w, ctx->width), - FFMAX(top + h, ctx->height)); + int ret = ff_set_dimensions(ctx->avctx, FFMAX(left + w, ctx->width), + FFMAX(top + h, ctx->height)); + if (ret < 0) + return ret; init_sizes(ctx, FFMAX(left + w, ctx->width), FFMAX(top + h, ctx->height)); if (init_buffers(ctx)) { @@ -1039,8 +1043,10 @@ static int decode_5(SANMVideoContext *ctx) #if HAVE_BIGENDIAN npixels = ctx->npixels; frm = ctx->frm0; - while (npixels--) - *frm++ = av_bswap16(*frm); + while (npixels--) { + *frm = av_bswap16(*frm); + frm++; + } #endif return 0; @@ -1289,6 +1295,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, AVCodec ff_sanm_decoder = { .name = "sanm", + .long_name = NULL_IF_CONFIG_SMALL("LucasArts SMUSH video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_SANM, .priv_data_size = sizeof(SANMVideoContext), @@ -1296,5 +1303,4 @@ AVCodec ff_sanm_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("LucasArts SMUSH video"), }; diff --git a/ffmpeg/libavcodec/sbrdsp.c b/ffmpeg/libavcodec/sbrdsp.c index 6fede79..b4d5824 100644 --- a/ffmpeg/libavcodec/sbrdsp.c +++ b/ffmpeg/libavcodec/sbrdsp.c @@ -3,25 +3,26 @@ * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl ) * Copyright (c) 2009-2010 Alex Converse * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include "libavutil/attributes.h" +#include "libavutil/intfloat.h" #include "sbrdsp.h" static void sbr_sum64x5_c(float *z) @@ -51,37 +52,52 @@ static float sbr_sum_square_c(float (*x)[2], int n) static void sbr_neg_odd_64_c(float *x) { + union av_intfloat32 *xi = (union av_intfloat32*) x; int i; - for (i = 1; i < 64; i += 2) - x[i] = -x[i]; + for (i = 1; i < 64; i += 4) { + xi[i + 0].i ^= 1U << 31; + xi[i + 2].i ^= 1U << 31; + } } static void sbr_qmf_pre_shuffle_c(float *z) { + union av_intfloat32 *zi = (union av_intfloat32*) z; int k; - z[64] = z[0]; - z[65] = z[1]; - for (k = 1; k < 32; k++) { - z[64+2*k ] = -z[64 - k]; - z[64+2*k+1] = z[ k + 1]; + zi[64].i = zi[0].i; + zi[65].i = zi[1].i; + for (k = 1; k < 31; k += 2) { + zi[64 + 2 * k + 0].i = zi[64 - k].i ^ (1U << 31); + zi[64 + 2 * k + 1].i = zi[ k + 1].i; + zi[64 + 2 * k + 2].i = zi[63 - k].i ^ (1U << 31); + zi[64 + 2 * k + 3].i = zi[ k + 2].i; } + + zi[64 + 2 * 31 + 0].i = zi[64 - 31].i ^ (1U << 31); + zi[64 + 2 * 31 + 1].i = zi[31 + 1].i; } static void sbr_qmf_post_shuffle_c(float W[32][2], const float *z) { + const union av_intfloat32 *zi = (const union av_intfloat32*) z; + union av_intfloat32 *Wi = (union av_intfloat32*) W; int k; - for (k = 0; k < 32; k++) { - W[k][0] = -z[63-k]; - W[k][1] = z[k]; + for (k = 0; k < 32; k += 2) { + Wi[2 * k + 0].i = zi[63 - k].i ^ (1U << 31); + Wi[2 * k + 1].i = zi[ k + 0].i; + Wi[2 * k + 2].i = zi[62 - k].i ^ (1U << 31); + Wi[2 * k + 3].i = zi[ k + 1].i; } } static void sbr_qmf_deint_neg_c(float *v, const float *src) { + const union av_intfloat32 *si = (const union av_intfloat32*)src; + union av_intfloat32 *vi = (union av_intfloat32*)v; int i; for (i = 0; i < 32; i++) { - v[ i] = src[63 - 2*i ]; - v[63 - i] = -src[63 - 2*i - 1]; + vi[ i].i = si[63 - 2 * i ].i; + vi[63 - i].i = si[63 - 2 * i - 1].i ^ (1U << 31); } } @@ -122,9 +138,34 @@ static av_always_inline void autocorrelate(const float x[40][2], static void sbr_autocorrelate_c(const float x[40][2], float phi[3][2][2]) { +#if 0 + /* This code is slower because it multiplies memory accesses. + * It is left for educational purposes and because it may offer + * a better reference for writing arch-specific DSP functions. */ autocorrelate(x, phi, 0); autocorrelate(x, phi, 1); autocorrelate(x, phi, 2); +#else + float real_sum2 = x[0][0] * x[2][0] + x[0][1] * x[2][1]; + float imag_sum2 = x[0][0] * x[2][1] - x[0][1] * x[2][0]; + float real_sum1 = 0.0f, imag_sum1 = 0.0f, real_sum0 = 0.0f; + int i; + for (i = 1; i < 38; i++) { + real_sum0 += x[i][0] * x[i ][0] + x[i][1] * x[i ][1]; + real_sum1 += x[i][0] * x[i + 1][0] + x[i][1] * x[i + 1][1]; + imag_sum1 += x[i][0] * x[i + 1][1] - x[i][1] * x[i + 1][0]; + real_sum2 += x[i][0] * x[i + 2][0] + x[i][1] * x[i + 2][1]; + imag_sum2 += x[i][0] * x[i + 2][1] - x[i][1] * x[i + 2][0]; + } + phi[2 - 2][1][0] = real_sum2; + phi[2 - 2][1][1] = imag_sum2; + phi[2 ][1][0] = real_sum0 + x[ 0][0] * x[ 0][0] + x[ 0][1] * x[ 0][1]; + phi[1 ][0][0] = real_sum0 + x[38][0] * x[38][0] + x[38][1] * x[38][1]; + phi[2 - 1][1][0] = real_sum1 + x[ 0][0] * x[ 1][0] + x[ 0][1] * x[ 1][1]; + phi[2 - 1][1][1] = imag_sum1 + x[ 0][0] * x[ 1][1] - x[ 0][1] * x[ 1][0]; + phi[0 ][0][0] = real_sum1 + x[38][0] * x[39][0] + x[38][1] * x[39][1]; + phi[0 ][0][1] = imag_sum1 + x[38][0] * x[39][1] - x[38][1] * x[39][0]; +#endif } static void sbr_hf_gen_c(float (*X_high)[2], const float (*X_low)[2], diff --git a/ffmpeg/libavcodec/sbrdsp.h b/ffmpeg/libavcodec/sbrdsp.h index 3831135..1c1bcdf 100644 --- a/ffmpeg/libavcodec/sbrdsp.h +++ b/ffmpeg/libavcodec/sbrdsp.h @@ -1,20 +1,20 @@ /* * Copyright (c) 2012 Mans Rullgard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/sgidec.c b/ffmpeg/libavcodec/sgidec.c index e7f453b..35063ea 100644 --- a/ffmpeg/libavcodec/sgidec.c +++ b/ffmpeg/libavcodec/sgidec.c @@ -41,7 +41,7 @@ typedef struct SgiState { * @param out_buf Points to one line after the output buffer. * @param out_end end of line in output buffer * @param pixelstride pixel stride of input buffer - * @return size of output in bytes, -1 if buffer overflows + * @return size of output in bytes, else return error code. */ static int expand_rle_row(SgiState *s, uint8_t *out_buf, uint8_t *out_end, int pixelstride) @@ -58,7 +58,8 @@ static int expand_rle_row(SgiState *s, uint8_t *out_buf, } /* Check for buffer overflow. */ - if(out_buf + pixelstride * (count-1) >= out_end) return -1; + if (out_end - out_buf <= pixelstride * (count - 1)) + return AVERROR_INVALIDDATA; if (pixel & 0x80) { while (count--) { @@ -81,7 +82,7 @@ static int expand_rle_row(SgiState *s, uint8_t *out_buf, * Read a run length encoded SGI image. * @param out_buf output buffer * @param s the current image state - * @return 0 if no error, else return error number. + * @return 0 if no error, else return error code. */ static int read_rle_sgi(uint8_t *out_buf, SgiState *s) { @@ -115,7 +116,7 @@ static int read_rle_sgi(uint8_t *out_buf, SgiState *s) * Read an uncompressed SGI image. * @param out_buf output buffer * @param s the current image state - * @return 0 if read success, otherwise return -1. + * @return 0 if read success, else return error code. */ static int read_uncompressed_sgi(unsigned char* out_buf, SgiState *s) { @@ -181,13 +182,13 @@ static int decode_frame(AVCodecContext *avctx, if (s->bytes_per_channel != 1 && (s->bytes_per_channel != 2 || rle)) { av_log(avctx, AV_LOG_ERROR, "wrong channel number\n"); - return -1; + return AVERROR_INVALIDDATA; } /* Check for supported image dimensions. */ if (dimension != 2 && dimension != 3) { av_log(avctx, AV_LOG_ERROR, "wrong dimension number\n"); - return -1; + return AVERROR_INVALIDDATA; } if (s->depth == SGI_GRAYSCALE) { @@ -198,12 +199,12 @@ static int decode_frame(AVCodecContext *avctx, avctx->pix_fmt = s->bytes_per_channel == 2 ? AV_PIX_FMT_RGBA64BE : AV_PIX_FMT_RGBA; } else { av_log(avctx, AV_LOG_ERROR, "wrong picture format\n"); - return -1; + return AVERROR_INVALIDDATA; } - if (av_image_check_size(s->width, s->height, 0, avctx)) - return -1; - avcodec_set_dimensions(avctx, s->width, s->height); + ret = ff_set_dimensions(avctx, s->width, s->height); + if (ret < 0) + return ret; if ((ret = ff_get_buffer(avctx, p, 0)) < 0) return ret; @@ -223,21 +224,19 @@ static int decode_frame(AVCodecContext *avctx, } else { ret = read_uncompressed_sgi(out_buf, s); } - - if (ret == 0) { - *got_frame = 1; - return avpkt->size; - } else { + if (ret) return ret; - } + + *got_frame = 1; + return avpkt->size; } AVCodec ff_sgi_decoder = { .name = "sgi", + .long_name = NULL_IF_CONFIG_SMALL("SGI image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_SGI, .priv_data_size = sizeof(SgiState), .decode = decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("SGI image"), .capabilities = CODEC_CAP_DR1, }; diff --git a/ffmpeg/libavcodec/sgienc.c b/ffmpeg/libavcodec/sgienc.c index d03ef52..0e4f304 100644 --- a/ffmpeg/libavcodec/sgienc.c +++ b/ffmpeg/libavcodec/sgienc.c @@ -28,21 +28,15 @@ #define SGI_SINGLE_CHAN 2 #define SGI_MULTI_CHAN 3 -typedef struct SgiContext { - AVFrame picture; -} SgiContext; - static av_cold int encode_init(AVCodecContext *avctx) { - SgiContext *s = avctx->priv_data; - if (avctx->width > 65535 || avctx->height > 65535) { av_log(avctx, AV_LOG_ERROR, "SGI does not support resolutions above 65535x65535\n"); return -1; } - - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame = &s->picture; + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); return 0; } @@ -50,16 +44,14 @@ static av_cold int encode_init(AVCodecContext *avctx) static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet) { - SgiContext *s = avctx->priv_data; - AVFrame * const p = &s->picture; + const AVFrame * const p = frame; uint8_t *offsettab, *lengthtab, *in_buf, *encode_buf, *buf; int x, y, z, length, tablesize, ret; unsigned int width, height, depth, dimension, bytes_per_channel, pixmax, put_be; unsigned char *end_buf; - *p = *frame; - p->pict_type = AV_PICTURE_TYPE_I; - p->key_frame = 1; + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->key_frame = 1; width = avctx->width; height = avctx->height; @@ -210,13 +202,20 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, return 0; } +static av_cold int encode_close(AVCodecContext *avctx) +{ + av_frame_free(&avctx->coded_frame); + return 0; +} + AVCodec ff_sgi_encoder = { .name = "sgi", + .long_name = NULL_IF_CONFIG_SMALL("SGI image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_SGI, - .priv_data_size = sizeof(SgiContext), .init = encode_init, .encode2 = encode_frame, + .close = encode_close, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB48LE, AV_PIX_FMT_RGB48BE, @@ -224,5 +223,4 @@ AVCodec ff_sgi_encoder = { AV_PIX_FMT_GRAY16LE, AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("SGI image"), }; diff --git a/ffmpeg/libavcodec/sgirledec.c b/ffmpeg/libavcodec/sgirledec.c index 9d6cdba..fd3cc5e 100644 --- a/ffmpeg/libavcodec/sgirledec.c +++ b/ffmpeg/libavcodec/sgirledec.c @@ -24,9 +24,7 @@ * SGI RLE 8-bit decoder */ -#include "libavutil/intreadwrite.h" #include "avcodec.h" -#include "bytestream.h" #include "internal.h" typedef struct SGIRLEContext { @@ -44,7 +42,7 @@ static av_cold int sgirle_decode_init(AVCodecContext *avctx) } /** - * Convert SGI RGB332 pixel into PIX_FMT_BGR8 + * Convert SGI RGB332 pixel into AV_PIX_FMT_BGR8 * SGI RGB332 is packed RGB 3:3:2, 8bpp, (msb)3R 2B 3G(lsb) */ #define RGB332_TO_BGR8(x) (((x << 3) & 0xC0) | ((x << 3) & 0x38) | ((x >> 5) & 7)) @@ -84,6 +82,8 @@ static int decode_sgirle8(AVCodecContext *avctx, uint8_t *dst, const uint8_t *sr if (v > 0 && v < 0xC0) { do { int length = FFMIN(v, width - x); + if (length <= 0) + break; memset(dst + y*linesize + x, RGB332_TO_BGR8(*src), length); INC_XY(length); v -= length; @@ -93,7 +93,7 @@ static int decode_sgirle8(AVCodecContext *avctx, uint8_t *dst, const uint8_t *sr v -= 0xC0; do { int length = FFMIN3(v, width - x, src_end - src); - if (src_end - src < length) + if (src_end - src < length || length <= 0) break; memcpy_rgb332_to_bgr8(dst + y*linesize + x, src, length); INC_XY(length); @@ -140,6 +140,7 @@ static av_cold int sgirle_decode_end(AVCodecContext *avctx) AVCodec ff_sgirle_decoder = { .name = "sgirle", + .long_name = NULL_IF_CONFIG_SMALL("SGI RLE 8-bit"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_SGIRLE, .priv_data_size = sizeof(SGIRLEContext), @@ -147,5 +148,4 @@ AVCodec ff_sgirle_decoder = { .close = sgirle_decode_end, .decode = sgirle_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("SGI RLE 8-bit"), }; diff --git a/ffmpeg/libavcodec/sh4/Makefile b/ffmpeg/libavcodec/sh4/Makefile index a24b298..01a573b 100644 --- a/ffmpeg/libavcodec/sh4/Makefile +++ b/ffmpeg/libavcodec/sh4/Makefile @@ -1,7 +1,2 @@ -OBJS += sh4/dsputil_align.o \ - sh4/dsputil_sh4.o \ +OBJS += sh4/dsputil_sh4.o \ sh4/idct_sh4.o \ - -OBJS-$(CONFIG_H264CHROMA) += sh4/h264chroma_init.o \ - -OBJS-$(CONFIG_HPELDSP) += sh4/hpeldsp.o diff --git a/ffmpeg/libavcodec/sh4/dsputil_align.c b/ffmpeg/libavcodec/sh4/dsputil_align.c deleted file mode 100644 index d6bd479..0000000 --- a/ffmpeg/libavcodec/sh4/dsputil_align.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - * aligned/packed access motion - * - * Copyright (c) 2001-2003 BERO - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/attributes.h" -#include "libavcodec/avcodec.h" -#include "libavcodec/dsputil.h" -#include "libavcodec/rnd_avg.h" -#include "dsputil_sh4.h" - - -#define LP(p) *(uint32_t*)(p) -#define LPC(p) *(const uint32_t*)(p) - - -#define UNPACK(ph,pl,tt0,tt1) do { \ - uint32_t t0,t1; t0=tt0;t1=tt1; \ - ph = ( (t0 & ~BYTE_VEC32(0x03))>>2) + ( (t1 & ~BYTE_VEC32(0x03))>>2); \ - pl = (t0 & BYTE_VEC32(0x03)) + (t1 & BYTE_VEC32(0x03)); } while(0) - -#define rnd_PACK(ph,pl,nph,npl) ph + nph + (((pl + npl + BYTE_VEC32(0x02))>>2) & BYTE_VEC32(0x03)) -#define no_rnd_PACK(ph,pl,nph,npl) ph + nph + (((pl + npl + BYTE_VEC32(0x01))>>2) & BYTE_VEC32(0x03)) - -/* little-endian */ -#define MERGE1(a,b,ofs) (ofs==0)?a:( ((a)>>(8*ofs))|((b)<<(32-8*ofs)) ) -#define MERGE2(a,b,ofs) (ofs==3)?b:( ((a)>>(8*(ofs+1)))|((b)<<(32-8*(ofs+1))) ) -/* big -#define MERGE1(a,b,ofs) (ofs==0)?a:( ((a)<<(8*ofs))|((b)>>(32-8*ofs)) ) -#define MERGE2(a,b,ofs) (ofs==3)?b:( ((a)<<(8+8*ofs))|((b)>>(32-8-8*ofs)) ) -*/ - - -#define put(d,s) d = s -#define avg(d,s) d = rnd_avg32(s,d) - -#define OP_C4(ofs) \ - ref-=ofs; \ - do { \ - OP(LP(dest),MERGE1(LPC(ref),LPC(ref+4),ofs)); \ - ref+=stride; \ - dest+=stride; \ - } while(--height) - -#define OP_C40() \ - do { \ - OP(LP(dest),LPC(ref)); \ - ref+=stride; \ - dest+=stride; \ - } while(--height) - -#define OP_C(ofs,sz,avg2) \ -{ \ - ref-=ofs; \ - do { \ - uint32_t t0,t1; \ - t0 = LPC(ref+0); \ - t1 = LPC(ref+4); \ - OP(LP(dest+0), MERGE1(t0,t1,ofs)); \ - t0 = LPC(ref+8); \ - OP(LP(dest+4), MERGE1(t1,t0,ofs)); \ -if (sz==16) { \ - t1 = LPC(ref+12); \ - OP(LP(dest+8), MERGE1(t0,t1,ofs)); \ - t0 = LPC(ref+16); \ - OP(LP(dest+12), MERGE1(t1,t0,ofs)); \ -} \ - ref+=stride; \ - dest+= stride; \ - } while(--height); \ -} - -/* aligned */ -#define OP_C0(sz,avg2) \ -{ \ - do { \ - OP(LP(dest+0), LPC(ref+0)); \ - OP(LP(dest+4), LPC(ref+4)); \ -if (sz==16) { \ - OP(LP(dest+8), LPC(ref+8)); \ - OP(LP(dest+12), LPC(ref+12)); \ -} \ - ref+=stride; \ - dest+= stride; \ - } while(--height); \ -} - -#define OP_X(ofs,sz,avg2) \ -{ \ - ref-=ofs; \ - do { \ - uint32_t t0,t1; \ - t0 = LPC(ref+0); \ - t1 = LPC(ref+4); \ - OP(LP(dest+0), avg2(MERGE1(t0,t1,ofs),MERGE2(t0,t1,ofs))); \ - t0 = LPC(ref+8); \ - OP(LP(dest+4), avg2(MERGE1(t1,t0,ofs),MERGE2(t1,t0,ofs))); \ -if (sz==16) { \ - t1 = LPC(ref+12); \ - OP(LP(dest+8), avg2(MERGE1(t0,t1,ofs),MERGE2(t0,t1,ofs))); \ - t0 = LPC(ref+16); \ - OP(LP(dest+12), avg2(MERGE1(t1,t0,ofs),MERGE2(t1,t0,ofs))); \ -} \ - ref+=stride; \ - dest+= stride; \ - } while(--height); \ -} - -/* aligned */ -#define OP_Y0(sz,avg2) \ -{ \ - uint32_t t0,t1,t2,t3,t; \ -\ - t0 = LPC(ref+0); \ - t1 = LPC(ref+4); \ -if (sz==16) { \ - t2 = LPC(ref+8); \ - t3 = LPC(ref+12); \ -} \ - do { \ - ref += stride; \ -\ - t = LPC(ref+0); \ - OP(LP(dest+0), avg2(t0,t)); t0 = t; \ - t = LPC(ref+4); \ - OP(LP(dest+4), avg2(t1,t)); t1 = t; \ -if (sz==16) { \ - t = LPC(ref+8); \ - OP(LP(dest+8), avg2(t2,t)); t2 = t; \ - t = LPC(ref+12); \ - OP(LP(dest+12), avg2(t3,t)); t3 = t; \ -} \ - dest+= stride; \ - } while(--height); \ -} - -#define OP_Y(ofs,sz,avg2) \ -{ \ - uint32_t t0,t1,t2,t3,t,w0,w1; \ -\ - ref-=ofs; \ - w0 = LPC(ref+0); \ - w1 = LPC(ref+4); \ - t0 = MERGE1(w0,w1,ofs); \ - w0 = LPC(ref+8); \ - t1 = MERGE1(w1,w0,ofs); \ -if (sz==16) { \ - w1 = LPC(ref+12); \ - t2 = MERGE1(w0,w1,ofs); \ - w0 = LPC(ref+16); \ - t3 = MERGE1(w1,w0,ofs); \ -} \ - do { \ - ref += stride; \ -\ - w0 = LPC(ref+0); \ - w1 = LPC(ref+4); \ - t = MERGE1(w0,w1,ofs); \ - OP(LP(dest+0), avg2(t0,t)); t0 = t; \ - w0 = LPC(ref+8); \ - t = MERGE1(w1,w0,ofs); \ - OP(LP(dest+4), avg2(t1,t)); t1 = t; \ -if (sz==16) { \ - w1 = LPC(ref+12); \ - t = MERGE1(w0,w1,ofs); \ - OP(LP(dest+8), avg2(t2,t)); t2 = t; \ - w0 = LPC(ref+16); \ - t = MERGE1(w1,w0,ofs); \ - OP(LP(dest+12), avg2(t3,t)); t3 = t; \ -} \ - dest+=stride; \ - } while(--height); \ -} - -#define OP_X0(sz,avg2) OP_X(0,sz,avg2) -#define OP_XY0(sz,PACK) OP_XY(0,sz,PACK) -#define OP_XY(ofs,sz,PACK) \ -{ \ - uint32_t t2,t3,w0,w1; \ - uint32_t a0,a1,a2,a3,a4,a5,a6,a7; \ -\ - ref -= ofs; \ - w0 = LPC(ref+0); \ - w1 = LPC(ref+4); \ - UNPACK(a0,a1,MERGE1(w0,w1,ofs),MERGE2(w0,w1,ofs)); \ - w0 = LPC(ref+8); \ - UNPACK(a2,a3,MERGE1(w1,w0,ofs),MERGE2(w1,w0,ofs)); \ -if (sz==16) { \ - w1 = LPC(ref+12); \ - UNPACK(a4,a5,MERGE1(w0,w1,ofs),MERGE2(w0,w1,ofs)); \ - w0 = LPC(ref+16); \ - UNPACK(a6,a7,MERGE1(w1,w0,ofs),MERGE2(w1,w0,ofs)); \ -} \ - do { \ - ref+=stride; \ - w0 = LPC(ref+0); \ - w1 = LPC(ref+4); \ - UNPACK(t2,t3,MERGE1(w0,w1,ofs),MERGE2(w0,w1,ofs)); \ - OP(LP(dest+0),PACK(a0,a1,t2,t3)); \ - a0 = t2; a1 = t3; \ - w0 = LPC(ref+8); \ - UNPACK(t2,t3,MERGE1(w1,w0,ofs),MERGE2(w1,w0,ofs)); \ - OP(LP(dest+4),PACK(a2,a3,t2,t3)); \ - a2 = t2; a3 = t3; \ -if (sz==16) { \ - w1 = LPC(ref+12); \ - UNPACK(t2,t3,MERGE1(w0,w1,ofs),MERGE2(w0,w1,ofs)); \ - OP(LP(dest+8),PACK(a4,a5,t2,t3)); \ - a4 = t2; a5 = t3; \ - w0 = LPC(ref+16); \ - UNPACK(t2,t3,MERGE1(w1,w0,ofs),MERGE2(w1,w0,ofs)); \ - OP(LP(dest+12),PACK(a6,a7,t2,t3)); \ - a6 = t2; a7 = t3; \ -} \ - dest+=stride; \ - } while(--height); \ -} - -#define DEFFUNC(op,rnd,xy,sz,OP_N,avgfunc) \ -static void op##_##rnd##_pixels##sz##_##xy (uint8_t * dest, const uint8_t * ref, \ - const ptrdiff_t stride, int height) \ -{ \ - switch((int)ref&3) { \ - case 0:OP_N##0(sz,rnd##_##avgfunc); return; \ - case 1:OP_N(1,sz,rnd##_##avgfunc); return; \ - case 2:OP_N(2,sz,rnd##_##avgfunc); return; \ - case 3:OP_N(3,sz,rnd##_##avgfunc); return; \ - } \ -} - -#define put_pixels8_c ff_put_rnd_pixels8_o -#define put_pixels16_c ff_put_rnd_pixels16_o -#define avg_pixels8_c ff_avg_rnd_pixels8_o -#define avg_pixels16_c ff_avg_rnd_pixels16_o -#define put_no_rnd_pixels8_c ff_put_rnd_pixels8_o -#define put_no_rnd_pixels16_c ff_put_rnd_pixels16_o -#define avg_no_rnd_pixels16_c ff_avg_rnd_pixels16_o - -#if CONFIG_H264QPEL - -#include "qpel.c" - -#endif - -av_cold void ff_dsputil_init_align(DSPContext *c, AVCodecContext *avctx) -{ - const int high_bit_depth = avctx->bits_per_raw_sample > 8; - -#if CONFIG_H264QPEL - -#define dspfunc(PFX, IDX, NUM) \ - c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_sh4; \ - c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_sh4; \ - c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_sh4; \ - c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_sh4; \ - c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_sh4; \ - c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_sh4; \ - c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_sh4; \ - c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_sh4; \ - c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_sh4; \ - c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_sh4; \ - c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_sh4; \ - c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_sh4; \ - c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_sh4; \ - c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_sh4; \ - c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_sh4; \ - c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_sh4 - - dspfunc(put_qpel, 0, 16); - dspfunc(put_no_rnd_qpel, 0, 16); - - dspfunc(avg_qpel, 0, 16); - /* dspfunc(avg_no_rnd_qpel, 0, 16); */ - - dspfunc(put_qpel, 1, 8); - dspfunc(put_no_rnd_qpel, 1, 8); - - dspfunc(avg_qpel, 1, 8); - /* dspfunc(avg_no_rnd_qpel, 1, 8); */ - -#undef dspfunc - - c->put_mspel_pixels_tab[0]= put_mspel8_mc00_sh4; - c->put_mspel_pixels_tab[1]= put_mspel8_mc10_sh4; - c->put_mspel_pixels_tab[2]= put_mspel8_mc20_sh4; - c->put_mspel_pixels_tab[3]= put_mspel8_mc30_sh4; - c->put_mspel_pixels_tab[4]= put_mspel8_mc02_sh4; - c->put_mspel_pixels_tab[5]= put_mspel8_mc12_sh4; - c->put_mspel_pixels_tab[6]= put_mspel8_mc22_sh4; - c->put_mspel_pixels_tab[7]= put_mspel8_mc32_sh4; - - c->gmc1 = gmc1_c; - -#endif -} diff --git a/ffmpeg/libavcodec/sh4/dsputil_sh4.c b/ffmpeg/libavcodec/sh4/dsputil_sh4.c index 6e19fa0..82b75ae 100644 --- a/ffmpeg/libavcodec/sh4/dsputil_sh4.c +++ b/ffmpeg/libavcodec/sh4/dsputil_sh4.c @@ -56,7 +56,7 @@ static void clear_blocks_sh4(int16_t *blocks) static void idct_put(uint8_t *dest, int line_size, int16_t *block) { int i; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; ff_idct_sh4(block); for(i=0;i<8;i++) { dest[0] = cm[block[0]]; @@ -74,7 +74,7 @@ static void idct_put(uint8_t *dest, int line_size, int16_t *block) static void idct_add(uint8_t *dest, int line_size, int16_t *block) { int i; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; ff_idct_sh4(block); for(i=0;i<8;i++) { dest[0] = cm[dest[0]+block[0]]; @@ -94,7 +94,6 @@ av_cold void ff_dsputil_init_sh4(DSPContext *c, AVCodecContext *avctx) { const int idct_algo= avctx->idct_algo; const int high_bit_depth = avctx->bits_per_raw_sample > 8; - ff_dsputil_init_align(c,avctx); if (!high_bit_depth) c->clear_blocks = clear_blocks_sh4; diff --git a/ffmpeg/libavcodec/sh4/dsputil_sh4.h b/ffmpeg/libavcodec/sh4/dsputil_sh4.h index bd97a5b..2ba9354 100644 --- a/ffmpeg/libavcodec/sh4/dsputil_sh4.h +++ b/ffmpeg/libavcodec/sh4/dsputil_sh4.h @@ -24,11 +24,5 @@ #include "libavcodec/hpeldsp.h" void ff_idct_sh4(int16_t *block); -void ff_dsputil_init_align(DSPContext* c, AVCodecContext *avctx); - -void ff_put_rnd_pixels8_o (uint8_t * dest, const uint8_t * ref, const int stride, int height); -void ff_put_rnd_pixels16_o(uint8_t * dest, const uint8_t * ref, const int stride, int height); -void ff_avg_rnd_pixels8_o (uint8_t * dest, const uint8_t * ref, const int stride, int height); -void ff_avg_rnd_pixels16_o(uint8_t * dest, const uint8_t * ref, const int stride, int height); #endif /* AVCODEC_SH4_DSPUTIL_SH4_H */ diff --git a/ffmpeg/libavcodec/sh4/h264chroma_init.c b/ffmpeg/libavcodec/sh4/h264chroma_init.c deleted file mode 100644 index d15f0ae..0000000 --- a/ffmpeg/libavcodec/sh4/h264chroma_init.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * aligned/packed access motion - * - * Copyright (c) 2001-2003 BERO - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include - -#include "libavutil/attributes.h" -#include "libavcodec/h264chroma.h" - -#define H264_CHROMA_MC(OPNAME, OP)\ -static void OPNAME ## h264_chroma_mc2_sh4(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){\ - const int A=(8-x)*(8-y);\ - const int B=( x)*(8-y);\ - const int C=(8-x)*( y);\ - const int D=( x)*( y);\ - \ - assert(x<8 && y<8 && x>=0 && y>=0);\ -\ - do {\ - int t0,t1,t2,t3; \ - uint8_t *s0 = src; \ - uint8_t *s1 = src+stride; \ - t0 = *s0++; t2 = *s1++; \ - t1 = *s0++; t3 = *s1++; \ - OP(dst[0], (A*t0 + B*t1 + C*t2 + D*t3));\ - t0 = *s0++; t2 = *s1++; \ - OP(dst[1], (A*t1 + B*t0 + C*t3 + D*t2));\ - dst+= stride;\ - src+= stride;\ - }while(--h);\ -}\ -\ -static void OPNAME ## h264_chroma_mc4_sh4(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){\ - const int A=(8-x)*(8-y);\ - const int B=( x)*(8-y);\ - const int C=(8-x)*( y);\ - const int D=( x)*( y);\ - \ - assert(x<8 && y<8 && x>=0 && y>=0);\ -\ - do {\ - int t0,t1,t2,t3; \ - uint8_t *s0 = src; \ - uint8_t *s1 = src+stride; \ - t0 = *s0++; t2 = *s1++; \ - t1 = *s0++; t3 = *s1++; \ - OP(dst[0], (A*t0 + B*t1 + C*t2 + D*t3));\ - t0 = *s0++; t2 = *s1++; \ - OP(dst[1], (A*t1 + B*t0 + C*t3 + D*t2));\ - t1 = *s0++; t3 = *s1++; \ - OP(dst[2], (A*t0 + B*t1 + C*t2 + D*t3));\ - t0 = *s0++; t2 = *s1++; \ - OP(dst[3], (A*t1 + B*t0 + C*t3 + D*t2));\ - dst+= stride;\ - src+= stride;\ - }while(--h);\ -}\ -\ -static void OPNAME ## h264_chroma_mc8_sh4(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){\ - const int A=(8-x)*(8-y);\ - const int B=( x)*(8-y);\ - const int C=(8-x)*( y);\ - const int D=( x)*( y);\ - \ - assert(x<8 && y<8 && x>=0 && y>=0);\ -\ - do {\ - int t0,t1,t2,t3; \ - uint8_t *s0 = src; \ - uint8_t *s1 = src+stride; \ - t0 = *s0++; t2 = *s1++; \ - t1 = *s0++; t3 = *s1++; \ - OP(dst[0], (A*t0 + B*t1 + C*t2 + D*t3));\ - t0 = *s0++; t2 = *s1++; \ - OP(dst[1], (A*t1 + B*t0 + C*t3 + D*t2));\ - t1 = *s0++; t3 = *s1++; \ - OP(dst[2], (A*t0 + B*t1 + C*t2 + D*t3));\ - t0 = *s0++; t2 = *s1++; \ - OP(dst[3], (A*t1 + B*t0 + C*t3 + D*t2));\ - t1 = *s0++; t3 = *s1++; \ - OP(dst[4], (A*t0 + B*t1 + C*t2 + D*t3));\ - t0 = *s0++; t2 = *s1++; \ - OP(dst[5], (A*t1 + B*t0 + C*t3 + D*t2));\ - t1 = *s0++; t3 = *s1++; \ - OP(dst[6], (A*t0 + B*t1 + C*t2 + D*t3));\ - t0 = *s0++; t2 = *s1++; \ - OP(dst[7], (A*t1 + B*t0 + C*t3 + D*t2));\ - dst+= stride;\ - src+= stride;\ - }while(--h);\ -} - -#define op_avg(a, b) a = (((a)+(((b) + 32)>>6)+1)>>1) -#define op_put(a, b) a = (((b) + 32)>>6) - -H264_CHROMA_MC(put_ , op_put) -H264_CHROMA_MC(avg_ , op_avg) -#undef op_avg -#undef op_put - -av_cold void ff_h264chroma_init_sh4(H264ChromaContext *c, int bit_depth) -{ - const int high_bit_depth = bit_depth > 8; - - if (!high_bit_depth) { - c->put_h264_chroma_pixels_tab[0]= put_h264_chroma_mc8_sh4; - c->put_h264_chroma_pixels_tab[1]= put_h264_chroma_mc4_sh4; - c->put_h264_chroma_pixels_tab[2]= put_h264_chroma_mc2_sh4; - c->avg_h264_chroma_pixels_tab[0]= avg_h264_chroma_mc8_sh4; - c->avg_h264_chroma_pixels_tab[1]= avg_h264_chroma_mc4_sh4; - c->avg_h264_chroma_pixels_tab[2]= avg_h264_chroma_mc2_sh4; - } -} diff --git a/ffmpeg/libavcodec/sh4/hpeldsp.c b/ffmpeg/libavcodec/sh4/hpeldsp.c deleted file mode 100644 index b524003..0000000 --- a/ffmpeg/libavcodec/sh4/hpeldsp.c +++ /dev/null @@ -1,347 +0,0 @@ -/* - * aligned/packed access motion - * - * Copyright (c) 2001-2003 BERO - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#include "libavcodec/avcodec.h" -#include "libavcodec/dsputil.h" -#include "libavcodec/bit_depth_template.c" // for BYTE_VEC32 -#include "dsputil_sh4.h" - - -#define LP(p) *(uint32_t*)(p) -#define LPC(p) *(const uint32_t*)(p) - - -#define UNPACK(ph,pl,tt0,tt1) do { \ - uint32_t t0,t1; t0=tt0;t1=tt1; \ - ph = ( (t0 & ~BYTE_VEC32(0x03))>>2) + ( (t1 & ~BYTE_VEC32(0x03))>>2); \ - pl = (t0 & BYTE_VEC32(0x03)) + (t1 & BYTE_VEC32(0x03)); } while(0) - -#define rnd_PACK(ph,pl,nph,npl) ph + nph + (((pl + npl + BYTE_VEC32(0x02))>>2) & BYTE_VEC32(0x03)) -#define no_rnd_PACK(ph,pl,nph,npl) ph + nph + (((pl + npl + BYTE_VEC32(0x01))>>2) & BYTE_VEC32(0x03)) - -/* little-endian */ -#define MERGE1(a,b,ofs) (ofs==0)?a:( ((a)>>(8*ofs))|((b)<<(32-8*ofs)) ) -#define MERGE2(a,b,ofs) (ofs==3)?b:( ((a)>>(8*(ofs+1)))|((b)<<(32-8*(ofs+1))) ) -/* big -#define MERGE1(a,b,ofs) (ofs==0)?a:( ((a)<<(8*ofs))|((b)>>(32-8*ofs)) ) -#define MERGE2(a,b,ofs) (ofs==3)?b:( ((a)<<(8+8*ofs))|((b)>>(32-8-8*ofs)) ) -*/ - - -#define put(d,s) d = s -#define avg(d,s) d = rnd_avg32(s,d) - -#define OP_C4(ofs) \ - ref-=ofs; \ - do { \ - OP(LP(dest),MERGE1(LPC(ref),LPC(ref+4),ofs)); \ - ref+=stride; \ - dest+=stride; \ - } while(--height) - -#define OP_C40() \ - do { \ - OP(LP(dest),LPC(ref)); \ - ref+=stride; \ - dest+=stride; \ - } while(--height) - - -#define OP put - -static void put_pixels4_c(uint8_t *dest,const uint8_t *ref, const int stride,int height) -{ - switch((int)ref&3){ - case 0: OP_C40(); return; - case 1: OP_C4(1); return; - case 2: OP_C4(2); return; - case 3: OP_C4(3); return; - } -} - -#undef OP -#define OP avg - -static void avg_pixels4_c(uint8_t *dest,const uint8_t *ref, const int stride,int height) -{ - switch((int)ref&3){ - case 0: OP_C40(); return; - case 1: OP_C4(1); return; - case 2: OP_C4(2); return; - case 3: OP_C4(3); return; - } -} - -#undef OP - -#define OP_C(ofs,sz,avg2) \ -{ \ - ref-=ofs; \ - do { \ - uint32_t t0,t1; \ - t0 = LPC(ref+0); \ - t1 = LPC(ref+4); \ - OP(LP(dest+0), MERGE1(t0,t1,ofs)); \ - t0 = LPC(ref+8); \ - OP(LP(dest+4), MERGE1(t1,t0,ofs)); \ -if (sz==16) { \ - t1 = LPC(ref+12); \ - OP(LP(dest+8), MERGE1(t0,t1,ofs)); \ - t0 = LPC(ref+16); \ - OP(LP(dest+12), MERGE1(t1,t0,ofs)); \ -} \ - ref+=stride; \ - dest+= stride; \ - } while(--height); \ -} - -/* aligned */ -#define OP_C0(sz,avg2) \ -{ \ - do { \ - OP(LP(dest+0), LPC(ref+0)); \ - OP(LP(dest+4), LPC(ref+4)); \ -if (sz==16) { \ - OP(LP(dest+8), LPC(ref+8)); \ - OP(LP(dest+12), LPC(ref+12)); \ -} \ - ref+=stride; \ - dest+= stride; \ - } while(--height); \ -} - -#define OP_X(ofs,sz,avg2) \ -{ \ - ref-=ofs; \ - do { \ - uint32_t t0,t1; \ - t0 = LPC(ref+0); \ - t1 = LPC(ref+4); \ - OP(LP(dest+0), avg2(MERGE1(t0,t1,ofs),MERGE2(t0,t1,ofs))); \ - t0 = LPC(ref+8); \ - OP(LP(dest+4), avg2(MERGE1(t1,t0,ofs),MERGE2(t1,t0,ofs))); \ -if (sz==16) { \ - t1 = LPC(ref+12); \ - OP(LP(dest+8), avg2(MERGE1(t0,t1,ofs),MERGE2(t0,t1,ofs))); \ - t0 = LPC(ref+16); \ - OP(LP(dest+12), avg2(MERGE1(t1,t0,ofs),MERGE2(t1,t0,ofs))); \ -} \ - ref+=stride; \ - dest+= stride; \ - } while(--height); \ -} - -/* aligned */ -#define OP_Y0(sz,avg2) \ -{ \ - uint32_t t0,t1,t2,t3,t; \ -\ - t0 = LPC(ref+0); \ - t1 = LPC(ref+4); \ -if (sz==16) { \ - t2 = LPC(ref+8); \ - t3 = LPC(ref+12); \ -} \ - do { \ - ref += stride; \ -\ - t = LPC(ref+0); \ - OP(LP(dest+0), avg2(t0,t)); t0 = t; \ - t = LPC(ref+4); \ - OP(LP(dest+4), avg2(t1,t)); t1 = t; \ -if (sz==16) { \ - t = LPC(ref+8); \ - OP(LP(dest+8), avg2(t2,t)); t2 = t; \ - t = LPC(ref+12); \ - OP(LP(dest+12), avg2(t3,t)); t3 = t; \ -} \ - dest+= stride; \ - } while(--height); \ -} - -#define OP_Y(ofs,sz,avg2) \ -{ \ - uint32_t t0,t1,t2,t3,t,w0,w1; \ -\ - ref-=ofs; \ - w0 = LPC(ref+0); \ - w1 = LPC(ref+4); \ - t0 = MERGE1(w0,w1,ofs); \ - w0 = LPC(ref+8); \ - t1 = MERGE1(w1,w0,ofs); \ -if (sz==16) { \ - w1 = LPC(ref+12); \ - t2 = MERGE1(w0,w1,ofs); \ - w0 = LPC(ref+16); \ - t3 = MERGE1(w1,w0,ofs); \ -} \ - do { \ - ref += stride; \ -\ - w0 = LPC(ref+0); \ - w1 = LPC(ref+4); \ - t = MERGE1(w0,w1,ofs); \ - OP(LP(dest+0), avg2(t0,t)); t0 = t; \ - w0 = LPC(ref+8); \ - t = MERGE1(w1,w0,ofs); \ - OP(LP(dest+4), avg2(t1,t)); t1 = t; \ -if (sz==16) { \ - w1 = LPC(ref+12); \ - t = MERGE1(w0,w1,ofs); \ - OP(LP(dest+8), avg2(t2,t)); t2 = t; \ - w0 = LPC(ref+16); \ - t = MERGE1(w1,w0,ofs); \ - OP(LP(dest+12), avg2(t3,t)); t3 = t; \ -} \ - dest+=stride; \ - } while(--height); \ -} - -#define OP_X0(sz,avg2) OP_X(0,sz,avg2) -#define OP_XY0(sz,PACK) OP_XY(0,sz,PACK) -#define OP_XY(ofs,sz,PACK) \ -{ \ - uint32_t t2,t3,w0,w1; \ - uint32_t a0,a1,a2,a3,a4,a5,a6,a7; \ -\ - ref -= ofs; \ - w0 = LPC(ref+0); \ - w1 = LPC(ref+4); \ - UNPACK(a0,a1,MERGE1(w0,w1,ofs),MERGE2(w0,w1,ofs)); \ - w0 = LPC(ref+8); \ - UNPACK(a2,a3,MERGE1(w1,w0,ofs),MERGE2(w1,w0,ofs)); \ -if (sz==16) { \ - w1 = LPC(ref+12); \ - UNPACK(a4,a5,MERGE1(w0,w1,ofs),MERGE2(w0,w1,ofs)); \ - w0 = LPC(ref+16); \ - UNPACK(a6,a7,MERGE1(w1,w0,ofs),MERGE2(w1,w0,ofs)); \ -} \ - do { \ - ref+=stride; \ - w0 = LPC(ref+0); \ - w1 = LPC(ref+4); \ - UNPACK(t2,t3,MERGE1(w0,w1,ofs),MERGE2(w0,w1,ofs)); \ - OP(LP(dest+0),PACK(a0,a1,t2,t3)); \ - a0 = t2; a1 = t3; \ - w0 = LPC(ref+8); \ - UNPACK(t2,t3,MERGE1(w1,w0,ofs),MERGE2(w1,w0,ofs)); \ - OP(LP(dest+4),PACK(a2,a3,t2,t3)); \ - a2 = t2; a3 = t3; \ -if (sz==16) { \ - w1 = LPC(ref+12); \ - UNPACK(t2,t3,MERGE1(w0,w1,ofs),MERGE2(w0,w1,ofs)); \ - OP(LP(dest+8),PACK(a4,a5,t2,t3)); \ - a4 = t2; a5 = t3; \ - w0 = LPC(ref+16); \ - UNPACK(t2,t3,MERGE1(w1,w0,ofs),MERGE2(w1,w0,ofs)); \ - OP(LP(dest+12),PACK(a6,a7,t2,t3)); \ - a6 = t2; a7 = t3; \ -} \ - dest+=stride; \ - } while(--height); \ -} - -#define DEFFUNC(prefix, op,rnd,xy,sz,OP_N,avgfunc) \ -prefix void op##_##rnd##_pixels##sz##_##xy (uint8_t * dest, const uint8_t * ref, \ - const int stride, int height) \ -{ \ - switch((int)ref&3) { \ - case 0:OP_N##0(sz,rnd##_##avgfunc); return; \ - case 1:OP_N(1,sz,rnd##_##avgfunc); return; \ - case 2:OP_N(2,sz,rnd##_##avgfunc); return; \ - case 3:OP_N(3,sz,rnd##_##avgfunc); return; \ - } \ -} - -#define OP put - -DEFFUNC( ,ff_put,rnd,o,8,OP_C,avg32) -DEFFUNC(static,put, rnd,x,8,OP_X,avg32) -DEFFUNC(static,put,no_rnd,x,8,OP_X,avg32) -DEFFUNC(static,put, rnd,y,8,OP_Y,avg32) -DEFFUNC(static,put,no_rnd,y,8,OP_Y,avg32) -DEFFUNC(static,put, rnd,xy,8,OP_XY,PACK) -DEFFUNC(static,put,no_rnd,xy,8,OP_XY,PACK) -DEFFUNC( ,ff_put,rnd,o,16,OP_C,avg32) -DEFFUNC(static,put, rnd,x,16,OP_X,avg32) -DEFFUNC(static,put,no_rnd,x,16,OP_X,avg32) -DEFFUNC(static,put, rnd,y,16,OP_Y,avg32) -DEFFUNC(static,put,no_rnd,y,16,OP_Y,avg32) -DEFFUNC(static,put, rnd,xy,16,OP_XY,PACK) -DEFFUNC(static,put,no_rnd,xy,16,OP_XY,PACK) - -#undef OP -#define OP avg - -DEFFUNC( ,ff_avg,rnd,o,8,OP_C,avg32) -DEFFUNC(static,avg, rnd,x,8,OP_X,avg32) -DEFFUNC(static,avg, rnd,y,8,OP_Y,avg32) -DEFFUNC(static,avg, rnd,xy,8,OP_XY,PACK) -DEFFUNC( ,ff_avg,rnd,o,16,OP_C,avg32) -DEFFUNC(static,avg, rnd,x,16,OP_X,avg32) -DEFFUNC(static,avg,no_rnd,x,16,OP_X,avg32) -DEFFUNC(static,avg, rnd,y,16,OP_Y,avg32) -DEFFUNC(static,avg,no_rnd,y,16,OP_Y,avg32) -DEFFUNC(static,avg, rnd,xy,16,OP_XY,PACK) -DEFFUNC(static,avg,no_rnd,xy,16,OP_XY,PACK) - -#undef OP - -#define ff_put_no_rnd_pixels8_o ff_put_rnd_pixels8_o -#define ff_put_no_rnd_pixels16_o ff_put_rnd_pixels16_o -#define ff_avg_no_rnd_pixels16_o ff_avg_rnd_pixels16_o - -void ff_hpeldsp_init_sh4(HpelDSPContext* c, int flags) -{ - c->put_pixels_tab[0][0] = ff_put_rnd_pixels16_o; - c->put_pixels_tab[0][1] = put_rnd_pixels16_x; - c->put_pixels_tab[0][2] = put_rnd_pixels16_y; - c->put_pixels_tab[0][3] = put_rnd_pixels16_xy; - c->put_pixels_tab[1][0] = ff_put_rnd_pixels8_o; - c->put_pixels_tab[1][1] = put_rnd_pixels8_x; - c->put_pixels_tab[1][2] = put_rnd_pixels8_y; - c->put_pixels_tab[1][3] = put_rnd_pixels8_xy; - - c->put_no_rnd_pixels_tab[0][0] = ff_put_no_rnd_pixels16_o; - c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x; - c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y; - c->put_no_rnd_pixels_tab[0][3] = put_no_rnd_pixels16_xy; - c->put_no_rnd_pixels_tab[1][0] = ff_put_no_rnd_pixels8_o; - c->put_no_rnd_pixels_tab[1][1] = put_no_rnd_pixels8_x; - c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels8_y; - c->put_no_rnd_pixels_tab[1][3] = put_no_rnd_pixels8_xy; - - c->avg_pixels_tab[0][0] = ff_avg_rnd_pixels16_o; - c->avg_pixels_tab[0][1] = avg_rnd_pixels16_x; - c->avg_pixels_tab[0][2] = avg_rnd_pixels16_y; - c->avg_pixels_tab[0][3] = avg_rnd_pixels16_xy; - c->avg_pixels_tab[1][0] = ff_avg_rnd_pixels8_o; - c->avg_pixels_tab[1][1] = avg_rnd_pixels8_x; - c->avg_pixels_tab[1][2] = avg_rnd_pixels8_y; - c->avg_pixels_tab[1][3] = avg_rnd_pixels8_xy; - - c->avg_no_rnd_pixels_tab[0] = ff_avg_no_rnd_pixels16_o; - c->avg_no_rnd_pixels_tab[1] = avg_no_rnd_pixels16_x; - c->avg_no_rnd_pixels_tab[2] = avg_no_rnd_pixels16_y; - c->avg_no_rnd_pixels_tab[3] = avg_no_rnd_pixels16_xy; -} diff --git a/ffmpeg/libavcodec/sh4/qpel.c b/ffmpeg/libavcodec/sh4/qpel.c deleted file mode 100644 index 1a5a4cd..0000000 --- a/ffmpeg/libavcodec/sh4/qpel.c +++ /dev/null @@ -1,862 +0,0 @@ -/* - * This is optimized for sh, which have post increment addressing (*p++). - * Some CPU may be index (p[n]) faster than post increment (*p++). - * - * copyright (c) 2001-2003 BERO - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/common.h" -#include "libavcodec/copy_block.h" -#include "libavcodec/rnd_avg.h" - -#define PIXOP2(OPNAME, OP) \ -\ -static inline void OPNAME ## _pixels4_l2_aligned(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{\ - do {\ - OP(LP(dst ),rnd_avg32(LPC(src1 ),LPC(src2 )) ); \ - src1+=src_stride1; \ - src2+=src_stride2; \ - dst+=dst_stride; \ - } while(--h); \ -}\ -\ -static inline void OPNAME ## _pixels4_l2_aligned2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{\ - do {\ - OP(LP(dst ),rnd_avg32(AV_RN32(src1 ),LPC(src2 )) ); \ - src1+=src_stride1; \ - src2+=src_stride2; \ - dst+=dst_stride; \ - } while(--h); \ -}\ -\ -static inline void OPNAME ## _no_rnd_pixels16_l2_aligned2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{\ - do {\ - OP(LP(dst ),no_rnd_avg32(AV_RN32(src1 ),LPC(src2 )) ); \ - OP(LP(dst+4),no_rnd_avg32(AV_RN32(src1+4),LPC(src2+4)) ); \ - OP(LP(dst+8),no_rnd_avg32(AV_RN32(src1+8),LPC(src2+8)) ); \ - OP(LP(dst+12),no_rnd_avg32(AV_RN32(src1+12),LPC(src2+12)) ); \ - src1+=src_stride1; \ - src2+=src_stride2; \ - dst+=dst_stride; \ - } while(--h); \ -}\ -\ -static inline void OPNAME ## _pixels16_l2_aligned2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{\ - do {\ - OP(LP(dst ),rnd_avg32(AV_RN32(src1 ),LPC(src2 )) ); \ - OP(LP(dst+4),rnd_avg32(AV_RN32(src1+4),LPC(src2+4)) ); \ - OP(LP(dst+8),rnd_avg32(AV_RN32(src1+8),LPC(src2+8)) ); \ - OP(LP(dst+12),rnd_avg32(AV_RN32(src1+12),LPC(src2+12)) ); \ - src1+=src_stride1; \ - src2+=src_stride2; \ - dst+=dst_stride; \ - } while(--h); \ -}\ -\ -static inline void OPNAME ## _no_rnd_pixels8_l2_aligned2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{\ - do { /* onlye src2 aligned */\ - OP(LP(dst ),no_rnd_avg32(AV_RN32(src1 ),LPC(src2 )) ); \ - OP(LP(dst+4),no_rnd_avg32(AV_RN32(src1+4),LPC(src2+4)) ); \ - src1+=src_stride1; \ - src2+=src_stride2; \ - dst+=dst_stride; \ - } while(--h); \ -}\ -\ -static inline void OPNAME ## _pixels8_l2_aligned2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{\ - do {\ - OP(LP(dst ),rnd_avg32(AV_RN32(src1 ),LPC(src2 )) ); \ - OP(LP(dst+4),rnd_avg32(AV_RN32(src1+4),LPC(src2+4)) ); \ - src1+=src_stride1; \ - src2+=src_stride2; \ - dst+=dst_stride; \ - } while(--h); \ -}\ -\ -static inline void OPNAME ## _no_rnd_pixels8_l2_aligned(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{\ - do {\ - OP(LP(dst ),no_rnd_avg32(LPC(src1 ),LPC(src2 )) ); \ - OP(LP(dst+4),no_rnd_avg32(LPC(src1+4),LPC(src2+4)) ); \ - src1+=src_stride1; \ - src2+=src_stride2; \ - dst+=dst_stride; \ - } while(--h); \ -}\ -\ -static inline void OPNAME ## _pixels8_l2_aligned(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{\ - do {\ - OP(LP(dst ),rnd_avg32(LPC(src1 ),LPC(src2 )) ); \ - OP(LP(dst+4),rnd_avg32(LPC(src1+4),LPC(src2+4)) ); \ - src1+=src_stride1; \ - src2+=src_stride2; \ - dst+=dst_stride; \ - } while(--h); \ -}\ -\ -static inline void OPNAME ## _no_rnd_pixels16_l2_aligned(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{\ - do {\ - OP(LP(dst ),no_rnd_avg32(LPC(src1 ),LPC(src2 )) ); \ - OP(LP(dst+4),no_rnd_avg32(LPC(src1+4),LPC(src2+4)) ); \ - OP(LP(dst+8),no_rnd_avg32(LPC(src1+8),LPC(src2+8)) ); \ - OP(LP(dst+12),no_rnd_avg32(LPC(src1+12),LPC(src2+12)) ); \ - src1+=src_stride1; \ - src2+=src_stride2; \ - dst+=dst_stride; \ - } while(--h); \ -}\ -\ -static inline void OPNAME ## _pixels16_l2_aligned(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{\ - do {\ - OP(LP(dst ),rnd_avg32(LPC(src1 ),LPC(src2 )) ); \ - OP(LP(dst+4),rnd_avg32(LPC(src1+4),LPC(src2+4)) ); \ - OP(LP(dst+8),rnd_avg32(LPC(src1+8),LPC(src2+8)) ); \ - OP(LP(dst+12),rnd_avg32(LPC(src1+12),LPC(src2+12)) ); \ - src1+=src_stride1; \ - src2+=src_stride2; \ - dst+=dst_stride; \ - } while(--h); \ -}\ -\ -static inline void OPNAME ## _no_rnd_pixels16_l2_aligned1(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{ OPNAME ## _no_rnd_pixels16_l2_aligned2(dst,src2,src1,dst_stride,src_stride2,src_stride1,h); } \ -\ -static inline void OPNAME ## _pixels16_l2_aligned1(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{ OPNAME ## _pixels16_l2_aligned2(dst,src2,src1,dst_stride,src_stride2,src_stride1,h); } \ -\ -static inline void OPNAME ## _no_rnd_pixels8_l2_aligned1(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{ OPNAME ## _no_rnd_pixels8_l2_aligned2(dst,src2,src1,dst_stride,src_stride2,src_stride1,h); } \ -\ -static inline void OPNAME ## _pixels8_l2_aligned1(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{ OPNAME ## _pixels8_l2_aligned2(dst,src2,src1,dst_stride,src_stride2,src_stride1,h); } \ -\ -static inline void OPNAME ## _pixels8_l4_aligned(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\ - do { \ - uint32_t a0,a1,a2,a3; \ - UNPACK(a0,a1,LPC(src1),LPC(src2)); \ - UNPACK(a2,a3,LPC(src3),LPC(src4)); \ - OP(LP(dst),rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,LPC(src1+4),LPC(src2+4)); \ - UNPACK(a2,a3,LPC(src3+4),LPC(src4+4)); \ - OP(LP(dst+4),rnd_PACK(a0,a1,a2,a3)); \ - src1+=src_stride1;\ - src2+=src_stride2;\ - src3+=src_stride3;\ - src4+=src_stride4;\ - dst+=dst_stride;\ - } while(--h); \ -} \ -\ -static inline void OPNAME ## _no_rnd_pixels8_l4_aligned(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\ - do { \ - uint32_t a0,a1,a2,a3; \ - UNPACK(a0,a1,LPC(src1),LPC(src2)); \ - UNPACK(a2,a3,LPC(src3),LPC(src4)); \ - OP(LP(dst),no_rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,LPC(src1+4),LPC(src2+4)); \ - UNPACK(a2,a3,LPC(src3+4),LPC(src4+4)); \ - OP(LP(dst+4),no_rnd_PACK(a0,a1,a2,a3)); \ - src1+=src_stride1;\ - src2+=src_stride2;\ - src3+=src_stride3;\ - src4+=src_stride4;\ - dst+=dst_stride;\ - } while(--h); \ -} \ -\ -static inline void OPNAME ## _pixels8_l4_aligned0(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\ - do { \ - uint32_t a0,a1,a2,a3; /* src1 only not aligned */\ - UNPACK(a0,a1,AV_RN32(src1),LPC(src2)); \ - UNPACK(a2,a3,LPC(src3),LPC(src4)); \ - OP(LP(dst),rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,AV_RN32(src1+4),LPC(src2+4)); \ - UNPACK(a2,a3,LPC(src3+4),LPC(src4+4)); \ - OP(LP(dst+4),rnd_PACK(a0,a1,a2,a3)); \ - src1+=src_stride1;\ - src2+=src_stride2;\ - src3+=src_stride3;\ - src4+=src_stride4;\ - dst+=dst_stride;\ - } while(--h); \ -} \ -\ -static inline void OPNAME ## _no_rnd_pixels8_l4_aligned0(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\ - do { \ - uint32_t a0,a1,a2,a3; \ - UNPACK(a0,a1,AV_RN32(src1),LPC(src2)); \ - UNPACK(a2,a3,LPC(src3),LPC(src4)); \ - OP(LP(dst),no_rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,AV_RN32(src1+4),LPC(src2+4)); \ - UNPACK(a2,a3,LPC(src3+4),LPC(src4+4)); \ - OP(LP(dst+4),no_rnd_PACK(a0,a1,a2,a3)); \ - src1+=src_stride1;\ - src2+=src_stride2;\ - src3+=src_stride3;\ - src4+=src_stride4;\ - dst+=dst_stride;\ - } while(--h); \ -} \ -\ -static inline void OPNAME ## _pixels16_l4_aligned(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\ - do { \ - uint32_t a0,a1,a2,a3; \ - UNPACK(a0,a1,LPC(src1),LPC(src2)); \ - UNPACK(a2,a3,LPC(src3),LPC(src4)); \ - OP(LP(dst),rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,LPC(src1+4),LPC(src2+4)); \ - UNPACK(a2,a3,LPC(src3+4),LPC(src4+4)); \ - OP(LP(dst+8),rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,LPC(src1+8),LPC(src2+8)); \ - UNPACK(a2,a3,LPC(src3+8),LPC(src4+8)); \ - OP(LP(dst+8),rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,LPC(src1+12),LPC(src2+12)); \ - UNPACK(a2,a3,LPC(src3+12),LPC(src4+12)); \ - OP(LP(dst+12),rnd_PACK(a0,a1,a2,a3)); \ - src1+=src_stride1;\ - src2+=src_stride2;\ - src3+=src_stride3;\ - src4+=src_stride4;\ - dst+=dst_stride;\ - } while(--h); \ -} \ -\ -static inline void OPNAME ## _no_rnd_pixels16_l4_aligned(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\ - do { \ - uint32_t a0,a1,a2,a3; \ - UNPACK(a0,a1,LPC(src1),LPC(src2)); \ - UNPACK(a2,a3,LPC(src3),LPC(src4)); \ - OP(LP(dst),no_rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,LPC(src1+4),LPC(src2+4)); \ - UNPACK(a2,a3,LPC(src3+4),LPC(src4+4)); \ - OP(LP(dst+4),no_rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,LPC(src1+8),LPC(src2+8)); \ - UNPACK(a2,a3,LPC(src3+8),LPC(src4+8)); \ - OP(LP(dst+8),no_rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,LPC(src1+12),LPC(src2+12)); \ - UNPACK(a2,a3,LPC(src3+12),LPC(src4+12)); \ - OP(LP(dst+12),no_rnd_PACK(a0,a1,a2,a3)); \ - src1+=src_stride1;\ - src2+=src_stride2;\ - src3+=src_stride3;\ - src4+=src_stride4;\ - dst+=dst_stride;\ - } while(--h); \ -} \ -\ -static inline void OPNAME ## _pixels16_l4_aligned0(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\ - do { /* src1 is unaligned */\ - uint32_t a0,a1,a2,a3; \ - UNPACK(a0,a1,AV_RN32(src1),LPC(src2)); \ - UNPACK(a2,a3,LPC(src3),LPC(src4)); \ - OP(LP(dst),rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,AV_RN32(src1+4),LPC(src2+4)); \ - UNPACK(a2,a3,LPC(src3+4),LPC(src4+4)); \ - OP(LP(dst+8),rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,AV_RN32(src1+8),LPC(src2+8)); \ - UNPACK(a2,a3,LPC(src3+8),LPC(src4+8)); \ - OP(LP(dst+8),rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,AV_RN32(src1+12),LPC(src2+12)); \ - UNPACK(a2,a3,LPC(src3+12),LPC(src4+12)); \ - OP(LP(dst+12),rnd_PACK(a0,a1,a2,a3)); \ - src1+=src_stride1;\ - src2+=src_stride2;\ - src3+=src_stride3;\ - src4+=src_stride4;\ - dst+=dst_stride;\ - } while(--h); \ -} \ -\ -static inline void OPNAME ## _no_rnd_pixels16_l4_aligned0(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\ - do { \ - uint32_t a0,a1,a2,a3; \ - UNPACK(a0,a1,AV_RN32(src1),LPC(src2)); \ - UNPACK(a2,a3,LPC(src3),LPC(src4)); \ - OP(LP(dst),no_rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,AV_RN32(src1+4),LPC(src2+4)); \ - UNPACK(a2,a3,LPC(src3+4),LPC(src4+4)); \ - OP(LP(dst+4),no_rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,AV_RN32(src1+8),LPC(src2+8)); \ - UNPACK(a2,a3,LPC(src3+8),LPC(src4+8)); \ - OP(LP(dst+8),no_rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,AV_RN32(src1+12),LPC(src2+12)); \ - UNPACK(a2,a3,LPC(src3+12),LPC(src4+12)); \ - OP(LP(dst+12),no_rnd_PACK(a0,a1,a2,a3)); \ - src1+=src_stride1;\ - src2+=src_stride2;\ - src3+=src_stride3;\ - src4+=src_stride4;\ - dst+=dst_stride;\ - } while(--h); \ -} \ -\ - -#define op_avg(a, b) a = rnd_avg32(a,b) -#define op_put(a, b) a = b - -PIXOP2(avg, op_avg) -PIXOP2(put, op_put) -#undef op_avg -#undef op_put - -#define avg2(a,b) ((a+b+1)>>1) -#define avg4(a,b,c,d) ((a+b+c+d+2)>>2) - - -static void gmc1_c(uint8_t *dst, uint8_t *src, int stride, int h, int x16, int y16, int rounder) -{ - const int A=(16-x16)*(16-y16); - const int B=( x16)*(16-y16); - const int C=(16-x16)*( y16); - const int D=( x16)*( y16); - - do { - int t0,t1,t2,t3; - uint8_t *s0 = src; - uint8_t *s1 = src+stride; - t0 = *s0++; t2 = *s1++; - t1 = *s0++; t3 = *s1++; - dst[0]= (A*t0 + B*t1 + C*t2 + D*t3 + rounder)>>8; - t0 = *s0++; t2 = *s1++; - dst[1]= (A*t1 + B*t0 + C*t3 + D*t2 + rounder)>>8; - t1 = *s0++; t3 = *s1++; - dst[2]= (A*t0 + B*t1 + C*t2 + D*t3 + rounder)>>8; - t0 = *s0++; t2 = *s1++; - dst[3]= (A*t1 + B*t0 + C*t3 + D*t2 + rounder)>>8; - t1 = *s0++; t3 = *s1++; - dst[4]= (A*t0 + B*t1 + C*t2 + D*t3 + rounder)>>8; - t0 = *s0++; t2 = *s1++; - dst[5]= (A*t1 + B*t0 + C*t3 + D*t2 + rounder)>>8; - t1 = *s0++; t3 = *s1++; - dst[6]= (A*t0 + B*t1 + C*t2 + D*t3 + rounder)>>8; - t0 = *s0++; t2 = *s1++; - dst[7]= (A*t1 + B*t0 + C*t3 + D*t2 + rounder)>>8; - dst+= stride; - src+= stride; - }while(--h); -} - -#define QPEL_MC(r, OPNAME, RND, OP) \ -static void OPNAME ## mpeg4_qpel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h){\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ - do {\ - uint8_t *s = src; \ - int src0,src1,src2,src3,src4,src5,src6,src7,src8;\ - src0= *s++;\ - src1= *s++;\ - src2= *s++;\ - src3= *s++;\ - src4= *s++;\ - OP(dst[0], (src0+src1)*20 - (src0+src2)*6 + (src1+src3)*3 - (src2+src4));\ - src5= *s++;\ - OP(dst[1], (src1+src2)*20 - (src0+src3)*6 + (src0+src4)*3 - (src1+src5));\ - src6= *s++;\ - OP(dst[2], (src2+src3)*20 - (src1+src4)*6 + (src0+src5)*3 - (src0+src6));\ - src7= *s++;\ - OP(dst[3], (src3+src4)*20 - (src2+src5)*6 + (src1+src6)*3 - (src0+src7));\ - src8= *s++;\ - OP(dst[4], (src4+src5)*20 - (src3+src6)*6 + (src2+src7)*3 - (src1+src8));\ - OP(dst[5], (src5+src6)*20 - (src4+src7)*6 + (src3+src8)*3 - (src2+src8));\ - OP(dst[6], (src6+src7)*20 - (src5+src8)*6 + (src4+src8)*3 - (src3+src7));\ - OP(dst[7], (src7+src8)*20 - (src6+src8)*6 + (src5+src7)*3 - (src4+src6));\ - dst+=dstStride;\ - src+=srcStride;\ - }while(--h);\ -}\ -\ -static void OPNAME ## mpeg4_qpel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ - int w=8;\ - do{\ - uint8_t *s = src, *d=dst;\ - int src0,src1,src2,src3,src4,src5,src6,src7,src8;\ - src0 = *s; s+=srcStride; \ - src1 = *s; s+=srcStride; \ - src2 = *s; s+=srcStride; \ - src3 = *s; s+=srcStride; \ - src4 = *s; s+=srcStride; \ - OP(*d, (src0+src1)*20 - (src0+src2)*6 + (src1+src3)*3 - (src2+src4));d+=dstStride;\ - src5 = *s; s+=srcStride; \ - OP(*d, (src1+src2)*20 - (src0+src3)*6 + (src0+src4)*3 - (src1+src5));d+=dstStride;\ - src6 = *s; s+=srcStride; \ - OP(*d, (src2+src3)*20 - (src1+src4)*6 + (src0+src5)*3 - (src0+src6));d+=dstStride;\ - src7 = *s; s+=srcStride; \ - OP(*d, (src3+src4)*20 - (src2+src5)*6 + (src1+src6)*3 - (src0+src7));d+=dstStride;\ - src8 = *s; \ - OP(*d, (src4+src5)*20 - (src3+src6)*6 + (src2+src7)*3 - (src1+src8));d+=dstStride;\ - OP(*d, (src5+src6)*20 - (src4+src7)*6 + (src3+src8)*3 - (src2+src8));d+=dstStride;\ - OP(*d, (src6+src7)*20 - (src5+src8)*6 + (src4+src8)*3 - (src3+src7));d+=dstStride;\ - OP(*d, (src7+src8)*20 - (src6+src8)*6 + (src5+src7)*3 - (src4+src6));\ - dst++;\ - src++;\ - }while(--w);\ -}\ -\ -static void OPNAME ## mpeg4_qpel16_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h){\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ - do {\ - uint8_t *s = src;\ - int src0,src1,src2,src3,src4,src5,src6,src7,src8;\ - int src9,src10,src11,src12,src13,src14,src15,src16;\ - src0= *s++;\ - src1= *s++;\ - src2= *s++;\ - src3= *s++;\ - src4= *s++;\ - OP(dst[ 0], (src0 +src1 )*20 - (src0 +src2 )*6 + (src1 +src3 )*3 - (src2 +src4 ));\ - src5= *s++;\ - OP(dst[ 1], (src1 +src2 )*20 - (src0 +src3 )*6 + (src0 +src4 )*3 - (src1 +src5 ));\ - src6= *s++;\ - OP(dst[ 2], (src2 +src3 )*20 - (src1 +src4 )*6 + (src0 +src5 )*3 - (src0 +src6 ));\ - src7= *s++;\ - OP(dst[ 3], (src3 +src4 )*20 - (src2 +src5 )*6 + (src1 +src6 )*3 - (src0 +src7 ));\ - src8= *s++;\ - OP(dst[ 4], (src4 +src5 )*20 - (src3 +src6 )*6 + (src2 +src7 )*3 - (src1 +src8 ));\ - src9= *s++;\ - OP(dst[ 5], (src5 +src6 )*20 - (src4 +src7 )*6 + (src3 +src8 )*3 - (src2 +src9 ));\ - src10= *s++;\ - OP(dst[ 6], (src6 +src7 )*20 - (src5 +src8 )*6 + (src4 +src9 )*3 - (src3 +src10));\ - src11= *s++;\ - OP(dst[ 7], (src7 +src8 )*20 - (src6 +src9 )*6 + (src5 +src10)*3 - (src4 +src11));\ - src12= *s++;\ - OP(dst[ 8], (src8 +src9 )*20 - (src7 +src10)*6 + (src6 +src11)*3 - (src5 +src12));\ - src13= *s++;\ - OP(dst[ 9], (src9 +src10)*20 - (src8 +src11)*6 + (src7 +src12)*3 - (src6 +src13));\ - src14= *s++;\ - OP(dst[10], (src10+src11)*20 - (src9 +src12)*6 + (src8 +src13)*3 - (src7 +src14));\ - src15= *s++;\ - OP(dst[11], (src11+src12)*20 - (src10+src13)*6 + (src9 +src14)*3 - (src8 +src15));\ - src16= *s++;\ - OP(dst[12], (src12+src13)*20 - (src11+src14)*6 + (src10+src15)*3 - (src9 +src16));\ - OP(dst[13], (src13+src14)*20 - (src12+src15)*6 + (src11+src16)*3 - (src10+src16));\ - OP(dst[14], (src14+src15)*20 - (src13+src16)*6 + (src12+src16)*3 - (src11+src15));\ - OP(dst[15], (src15+src16)*20 - (src14+src16)*6 + (src13+src15)*3 - (src12+src14));\ - dst+=dstStride;\ - src+=srcStride;\ - }while(--h);\ -}\ -\ -static void OPNAME ## mpeg4_qpel16_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ - int w=16;\ - do {\ - uint8_t *s = src, *d=dst;\ - int src0,src1,src2,src3,src4,src5,src6,src7,src8;\ - int src9,src10,src11,src12,src13,src14,src15,src16;\ - src0 = *s; s+=srcStride; \ - src1 = *s; s+=srcStride; \ - src2 = *s; s+=srcStride; \ - src3 = *s; s+=srcStride; \ - src4 = *s; s+=srcStride; \ - OP(*d, (src0 +src1 )*20 - (src0 +src2 )*6 + (src1 +src3 )*3 - (src2 +src4 ));d+=dstStride;\ - src5 = *s; s+=srcStride; \ - OP(*d, (src1 +src2 )*20 - (src0 +src3 )*6 + (src0 +src4 )*3 - (src1 +src5 ));d+=dstStride;\ - src6 = *s; s+=srcStride; \ - OP(*d, (src2 +src3 )*20 - (src1 +src4 )*6 + (src0 +src5 )*3 - (src0 +src6 ));d+=dstStride;\ - src7 = *s; s+=srcStride; \ - OP(*d, (src3 +src4 )*20 - (src2 +src5 )*6 + (src1 +src6 )*3 - (src0 +src7 ));d+=dstStride;\ - src8 = *s; s+=srcStride; \ - OP(*d, (src4 +src5 )*20 - (src3 +src6 )*6 + (src2 +src7 )*3 - (src1 +src8 ));d+=dstStride;\ - src9 = *s; s+=srcStride; \ - OP(*d, (src5 +src6 )*20 - (src4 +src7 )*6 + (src3 +src8 )*3 - (src2 +src9 ));d+=dstStride;\ - src10 = *s; s+=srcStride; \ - OP(*d, (src6 +src7 )*20 - (src5 +src8 )*6 + (src4 +src9 )*3 - (src3 +src10));d+=dstStride;\ - src11 = *s; s+=srcStride; \ - OP(*d, (src7 +src8 )*20 - (src6 +src9 )*6 + (src5 +src10)*3 - (src4 +src11));d+=dstStride;\ - src12 = *s; s+=srcStride; \ - OP(*d, (src8 +src9 )*20 - (src7 +src10)*6 + (src6 +src11)*3 - (src5 +src12));d+=dstStride;\ - src13 = *s; s+=srcStride; \ - OP(*d, (src9 +src10)*20 - (src8 +src11)*6 + (src7 +src12)*3 - (src6 +src13));d+=dstStride;\ - src14 = *s; s+=srcStride; \ - OP(*d, (src10+src11)*20 - (src9 +src12)*6 + (src8 +src13)*3 - (src7 +src14));d+=dstStride;\ - src15 = *s; s+=srcStride; \ - OP(*d, (src11+src12)*20 - (src10+src13)*6 + (src9 +src14)*3 - (src8 +src15));d+=dstStride;\ - src16 = *s; \ - OP(*d, (src12+src13)*20 - (src11+src14)*6 + (src10+src15)*3 - (src9 +src16));d+=dstStride;\ - OP(*d, (src13+src14)*20 - (src12+src15)*6 + (src11+src16)*3 - (src10+src16));d+=dstStride;\ - OP(*d, (src14+src15)*20 - (src13+src16)*6 + (src12+src16)*3 - (src11+src15));d+=dstStride;\ - OP(*d, (src15+src16)*20 - (src14+src16)*6 + (src13+src15)*3 - (src12+src14));\ - dst++;\ - src++;\ - }while(--w);\ -}\ -\ -static void OPNAME ## qpel8_mc00_sh4 (uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## pixels8_c(dst, src, stride, 8);\ -}\ -\ -static void OPNAME ## qpel8_mc10_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t half[64];\ - put ## RND ## mpeg4_qpel8_h_lowpass(half, src, 8, stride, 8);\ - OPNAME ## pixels8_l2_aligned2(dst, src, half, stride, stride, 8, 8);\ -}\ -\ -static void OPNAME ## qpel8_mc20_sh4(uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## mpeg4_qpel8_h_lowpass(dst, src, stride, stride, 8);\ -}\ -\ -static void OPNAME ## qpel8_mc30_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t half[64];\ - put ## RND ## mpeg4_qpel8_h_lowpass(half, src, 8, stride, 8);\ - OPNAME ## pixels8_l2_aligned2(dst, src+1, half, stride, stride, 8, 8);\ -}\ -\ -static void OPNAME ## qpel8_mc01_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[16*9];\ - uint8_t half[64];\ - copy_block9(full, src, 16, stride, 9);\ - put ## RND ## mpeg4_qpel8_v_lowpass(half, full, 8, 16);\ - OPNAME ## pixels8_l2_aligned(dst, full, half, stride, 16, 8, 8);\ -}\ -\ -static void OPNAME ## qpel8_mc02_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[16*9];\ - copy_block9(full, src, 16, stride, 9);\ - OPNAME ## mpeg4_qpel8_v_lowpass(dst, full, stride, 16);\ -}\ -\ -static void OPNAME ## qpel8_mc03_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[16*9];\ - uint8_t half[64];\ - copy_block9(full, src, 16, stride, 9);\ - put ## RND ## mpeg4_qpel8_v_lowpass(half, full, 8, 16);\ - OPNAME ## pixels8_l2_aligned(dst, full+16, half, stride, 16, 8, 8);\ -}\ -static void OPNAME ## qpel8_mc11_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[16*9];\ - uint8_t halfH[72];\ - uint8_t halfHV[64];\ - copy_block9(full, src, 16, stride, 9);\ - put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9);\ - put ## RND ## pixels8_l2_aligned(halfH, halfH, full, 8, 8, 16, 9);\ - put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\ - OPNAME ## pixels8_l2_aligned(dst, halfH, halfHV, stride, 8, 8, 8);\ -}\ -static void OPNAME ## qpel8_mc31_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[16*9];\ - uint8_t halfH[72];\ - uint8_t halfHV[64];\ - copy_block9(full, src, 16, stride, 9);\ - put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9);\ - put ## RND ## pixels8_l2_aligned1(halfH, halfH, full+1, 8, 8, 16, 9);\ - put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\ - OPNAME ## pixels8_l2_aligned(dst, halfH, halfHV, stride, 8, 8, 8);\ -}\ -static void OPNAME ## qpel8_mc13_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[16*9];\ - uint8_t halfH[72];\ - uint8_t halfHV[64];\ - copy_block9(full, src, 16, stride, 9);\ - put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9);\ - put ## RND ## pixels8_l2_aligned(halfH, halfH, full, 8, 8, 16, 9);\ - put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\ - OPNAME ## pixels8_l2_aligned(dst, halfH+8, halfHV, stride, 8, 8, 8);\ -}\ -static void OPNAME ## qpel8_mc33_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[16*9];\ - uint8_t halfH[72];\ - uint8_t halfHV[64];\ - copy_block9(full, src, 16, stride, 9);\ - put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9);\ - put ## RND ## pixels8_l2_aligned1(halfH, halfH, full+1, 8, 8, 16, 9);\ - put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\ - OPNAME ## pixels8_l2_aligned(dst, halfH+8, halfHV, stride, 8, 8, 8);\ -}\ -static void OPNAME ## qpel8_mc21_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t halfH[72];\ - uint8_t halfHV[64];\ - put ## RND ## mpeg4_qpel8_h_lowpass(halfH, src, 8, stride, 9);\ - put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\ - OPNAME ## pixels8_l2_aligned(dst, halfH, halfHV, stride, 8, 8, 8);\ -}\ -static void OPNAME ## qpel8_mc23_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t halfH[72];\ - uint8_t halfHV[64];\ - put ## RND ## mpeg4_qpel8_h_lowpass(halfH, src, 8, stride, 9);\ - put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\ - OPNAME ## pixels8_l2_aligned(dst, halfH+8, halfHV, stride, 8, 8, 8);\ -}\ -static void OPNAME ## qpel8_mc12_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[16*9];\ - uint8_t halfH[72];\ - copy_block9(full, src, 16, stride, 9);\ - put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9);\ - put ## RND ## pixels8_l2_aligned(halfH, halfH, full, 8, 8, 16, 9);\ - OPNAME ## mpeg4_qpel8_v_lowpass(dst, halfH, stride, 8);\ -}\ -static void OPNAME ## qpel8_mc32_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[16*9];\ - uint8_t halfH[72];\ - copy_block9(full, src, 16, stride, 9);\ - put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9);\ - put ## RND ## pixels8_l2_aligned1(halfH, halfH, full+1, 8, 8, 16, 9);\ - OPNAME ## mpeg4_qpel8_v_lowpass(dst, halfH, stride, 8);\ -}\ -static void OPNAME ## qpel8_mc22_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t halfH[72];\ - put ## RND ## mpeg4_qpel8_h_lowpass(halfH, src, 8, stride, 9);\ - OPNAME ## mpeg4_qpel8_v_lowpass(dst, halfH, stride, 8);\ -}\ -static void OPNAME ## qpel16_mc00_sh4 (uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## pixels16_c(dst, src, stride, 16);\ -}\ -\ -static void OPNAME ## qpel16_mc10_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t half[256];\ - put ## RND ## mpeg4_qpel16_h_lowpass(half, src, 16, stride, 16);\ - OPNAME ## pixels16_l2_aligned2(dst, src, half, stride, stride, 16, 16);\ -}\ -\ -static void OPNAME ## qpel16_mc20_sh4(uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## mpeg4_qpel16_h_lowpass(dst, src, stride, stride, 16);\ -}\ -\ -static void OPNAME ## qpel16_mc30_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t half[256];\ - put ## RND ## mpeg4_qpel16_h_lowpass(half, src, 16, stride, 16);\ - OPNAME ## pixels16_l2_aligned2(dst, src+1, half, stride, stride, 16, 16);\ -}\ -\ -static void OPNAME ## qpel16_mc01_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[24*17];\ - uint8_t half[256];\ - copy_block17(full, src, 24, stride, 17);\ - put ## RND ## mpeg4_qpel16_v_lowpass(half, full, 16, 24);\ - OPNAME ## pixels16_l2_aligned(dst, full, half, stride, 24, 16, 16);\ -}\ -\ -static void OPNAME ## qpel16_mc02_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[24*17];\ - copy_block17(full, src, 24, stride, 17);\ - OPNAME ## mpeg4_qpel16_v_lowpass(dst, full, stride, 24);\ -}\ -\ -static void OPNAME ## qpel16_mc03_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[24*17];\ - uint8_t half[256];\ - copy_block17(full, src, 24, stride, 17);\ - put ## RND ## mpeg4_qpel16_v_lowpass(half, full, 16, 24);\ - OPNAME ## pixels16_l2_aligned(dst, full+24, half, stride, 24, 16, 16);\ -}\ -static void OPNAME ## qpel16_mc11_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[24*17];\ - uint8_t halfH[272];\ - uint8_t halfHV[256];\ - copy_block17(full, src, 24, stride, 17);\ - put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17);\ - put ## RND ## pixels16_l2_aligned(halfH, halfH, full, 16, 16, 24, 17);\ - put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\ - OPNAME ## pixels16_l2_aligned(dst, halfH, halfHV, stride, 16, 16, 16);\ -}\ -static void OPNAME ## qpel16_mc31_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[24*17];\ - uint8_t halfH[272];\ - uint8_t halfHV[256];\ - copy_block17(full, src, 24, stride, 17);\ - put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17);\ - put ## RND ## pixels16_l2_aligned1(halfH, halfH, full+1, 16, 16, 24, 17);\ - put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\ - OPNAME ## pixels16_l2_aligned(dst, halfH, halfHV, stride, 16, 16, 16);\ -}\ -static void OPNAME ## qpel16_mc13_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[24*17];\ - uint8_t halfH[272];\ - uint8_t halfHV[256];\ - copy_block17(full, src, 24, stride, 17);\ - put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17);\ - put ## RND ## pixels16_l2_aligned(halfH, halfH, full, 16, 16, 24, 17);\ - put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\ - OPNAME ## pixels16_l2_aligned(dst, halfH+16, halfHV, stride, 16, 16, 16);\ -}\ -static void OPNAME ## qpel16_mc33_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[24*17];\ - uint8_t halfH[272];\ - uint8_t halfHV[256];\ - copy_block17(full, src, 24, stride, 17);\ - put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17);\ - put ## RND ## pixels16_l2_aligned1(halfH, halfH, full+1, 16, 16, 24, 17);\ - put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\ - OPNAME ## pixels16_l2_aligned(dst, halfH+16, halfHV, stride, 16, 16, 16);\ -}\ -static void OPNAME ## qpel16_mc21_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t halfH[272];\ - uint8_t halfHV[256];\ - put ## RND ## mpeg4_qpel16_h_lowpass(halfH, src, 16, stride, 17);\ - put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\ - OPNAME ## pixels16_l2_aligned(dst, halfH, halfHV, stride, 16, 16, 16);\ -}\ -static void OPNAME ## qpel16_mc23_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t halfH[272];\ - uint8_t halfHV[256];\ - put ## RND ## mpeg4_qpel16_h_lowpass(halfH, src, 16, stride, 17);\ - put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\ - OPNAME ## pixels16_l2_aligned(dst, halfH+16, halfHV, stride, 16, 16, 16);\ -}\ -static void OPNAME ## qpel16_mc12_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[24*17];\ - uint8_t halfH[272];\ - copy_block17(full, src, 24, stride, 17);\ - put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17);\ - put ## RND ## pixels16_l2_aligned(halfH, halfH, full, 16, 16, 24, 17);\ - OPNAME ## mpeg4_qpel16_v_lowpass(dst, halfH, stride, 16);\ -}\ -static void OPNAME ## qpel16_mc32_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[24*17];\ - uint8_t halfH[272];\ - copy_block17(full, src, 24, stride, 17);\ - put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17);\ - put ## RND ## pixels16_l2_aligned1(halfH, halfH, full+1, 16, 16, 24, 17);\ - OPNAME ## mpeg4_qpel16_v_lowpass(dst, halfH, stride, 16);\ -}\ -static void OPNAME ## qpel16_mc22_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t halfH[272];\ - put ## RND ## mpeg4_qpel16_h_lowpass(halfH, src, 16, stride, 17);\ - OPNAME ## mpeg4_qpel16_v_lowpass(dst, halfH, stride, 16);\ -} - -#define op_avg(a, b) a = (((a)+cm[((b) + 16)>>5]+1)>>1) -#define op_avg_no_rnd(a, b) a = (((a)+cm[((b) + 15)>>5])>>1) -#define op_put(a, b) a = cm[((b) + 16)>>5] -#define op_put_no_rnd(a, b) a = cm[((b) + 15)>>5] - -QPEL_MC(0, put_ , _ , op_put) -QPEL_MC(1, put_no_rnd_, _no_rnd_, op_put_no_rnd) -QPEL_MC(0, avg_ , _ , op_avg) -//QPEL_MC(1, avg_no_rnd , _ , op_avg) -#undef op_avg -#undef op_avg_no_rnd -#undef op_put -#undef op_put_no_rnd - -static void wmv2_mspel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h){ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - - do{ - int src_1,src0,src1,src2,src3,src4,src5,src6,src7,src8,src9; - uint8_t *s = src; - src_1 = s[-1]; - src0 = *s++; - src1 = *s++; - src2 = *s++; - dst[0]= cm[(9*(src0 + src1) - (src_1 + src2) + 8)>>4]; - src3 = *s++; - dst[1]= cm[(9*(src1 + src2) - (src0 + src3) + 8)>>4]; - src4 = *s++; - dst[2]= cm[(9*(src2 + src3) - (src1 + src4) + 8)>>4]; - src5 = *s++; - dst[3]= cm[(9*(src3 + src4) - (src2 + src5) + 8)>>4]; - src6 = *s++; - dst[4]= cm[(9*(src4 + src5) - (src3 + src6) + 8)>>4]; - src7 = *s++; - dst[5]= cm[(9*(src5 + src6) - (src4 + src7) + 8)>>4]; - src8 = *s++; - dst[6]= cm[(9*(src6 + src7) - (src5 + src8) + 8)>>4]; - src9 = *s++; - dst[7]= cm[(9*(src7 + src8) - (src6 + src9) + 8)>>4]; - dst+=dstStride; - src+=srcStride; - }while(--h); -} - -static void wmv2_mspel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int w){ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - - do{ - int src_1,src0,src1,src2,src3,src4,src5,src6,src7,src8,src9; - uint8_t *s = src,*d = dst; - src_1 = *(s-srcStride); - src0 = *s; s+=srcStride; - src1 = *s; s+=srcStride; - src2 = *s; s+=srcStride; - *d= cm[(9*(src0 + src1) - (src_1 + src2) + 8)>>4]; d+=dstStride; - src3 = *s; s+=srcStride; - *d= cm[(9*(src1 + src2) - (src0 + src3) + 8)>>4]; d+=dstStride; - src4 = *s; s+=srcStride; - *d= cm[(9*(src2 + src3) - (src1 + src4) + 8)>>4]; d+=dstStride; - src5 = *s; s+=srcStride; - *d= cm[(9*(src3 + src4) - (src2 + src5) + 8)>>4]; d+=dstStride; - src6 = *s; s+=srcStride; - *d= cm[(9*(src4 + src5) - (src3 + src6) + 8)>>4]; d+=dstStride; - src7 = *s; s+=srcStride; - *d= cm[(9*(src5 + src6) - (src4 + src7) + 8)>>4]; d+=dstStride; - src8 = *s; s+=srcStride; - *d= cm[(9*(src6 + src7) - (src5 + src8) + 8)>>4]; d+=dstStride; - src9 = *s; - *d= cm[(9*(src7 + src8) - (src6 + src9) + 8)>>4]; d+=dstStride; - src++; - dst++; - }while(--w); -} - -static void put_mspel8_mc00_sh4 (uint8_t *dst, uint8_t *src, int stride){ - put_pixels8_c(dst, src, stride, 8); -} - -static void put_mspel8_mc10_sh4(uint8_t *dst, uint8_t *src, int stride){ - uint8_t half[64]; - wmv2_mspel8_h_lowpass(half, src, 8, stride, 8); - put_pixels8_l2_aligned2(dst, src, half, stride, stride, 8, 8); -} - -static void put_mspel8_mc20_sh4(uint8_t *dst, uint8_t *src, int stride){ - wmv2_mspel8_h_lowpass(dst, src, stride, stride, 8); -} - -static void put_mspel8_mc30_sh4(uint8_t *dst, uint8_t *src, int stride){ - uint8_t half[64]; - wmv2_mspel8_h_lowpass(half, src, 8, stride, 8); - put_pixels8_l2_aligned2(dst, src+1, half, stride, stride, 8, 8); -} - -static void put_mspel8_mc02_sh4(uint8_t *dst, uint8_t *src, int stride){ - wmv2_mspel8_v_lowpass(dst, src, stride, stride, 8); -} - -static void put_mspel8_mc12_sh4(uint8_t *dst, uint8_t *src, int stride){ - uint8_t halfH[88]; - uint8_t halfV[64]; - uint8_t halfHV[64]; - wmv2_mspel8_h_lowpass(halfH, src-stride, 8, stride, 11); - wmv2_mspel8_v_lowpass(halfV, src, 8, stride, 8); - wmv2_mspel8_v_lowpass(halfHV, halfH+8, 8, 8, 8); - put_pixels8_l2_aligned(dst, halfV, halfHV, stride, 8, 8, 8); -} -static void put_mspel8_mc32_sh4(uint8_t *dst, uint8_t *src, int stride){ - uint8_t halfH[88]; - uint8_t halfV[64]; - uint8_t halfHV[64]; - wmv2_mspel8_h_lowpass(halfH, src-stride, 8, stride, 11); - wmv2_mspel8_v_lowpass(halfV, src+1, 8, stride, 8); - wmv2_mspel8_v_lowpass(halfHV, halfH+8, 8, 8, 8); - put_pixels8_l2_aligned(dst, halfV, halfHV, stride, 8, 8, 8); -} -static void put_mspel8_mc22_sh4(uint8_t *dst, uint8_t *src, int stride){ - uint8_t halfH[88]; - wmv2_mspel8_h_lowpass(halfH, src-stride, 8, stride, 11); - wmv2_mspel8_v_lowpass(dst, halfH+8, stride, 8, 8); -} diff --git a/ffmpeg/libavcodec/shorten.c b/ffmpeg/libavcodec/shorten.c index 1d3b6eb..8b91ed3 100644 --- a/ffmpeg/libavcodec/shorten.c +++ b/ffmpeg/libavcodec/shorten.c @@ -122,9 +122,7 @@ static av_cold int shorten_decode_init(AVCodecContext *avctx) static int allocate_buffers(ShortenContext *s) { - int i, chan; - int *coeffs; - void *tmp_ptr; + int i, chan, err; for (chan = 0; chan < s->channels; chan++) { if (FFMAX(1, s->nmean) >= UINT_MAX / sizeof(int32_t)) { @@ -138,26 +136,21 @@ static int allocate_buffers(ShortenContext *s) return AVERROR_INVALIDDATA; } - tmp_ptr = - av_realloc(s->offset[chan], sizeof(int32_t) * FFMAX(1, s->nmean)); - if (!tmp_ptr) - return AVERROR(ENOMEM); - s->offset[chan] = tmp_ptr; + if ((err = av_reallocp(&s->offset[chan], + sizeof(int32_t) * + FFMAX(1, s->nmean))) < 0) + return err; - tmp_ptr = av_realloc(s->decoded_base[chan], (s->blocksize + s->nwrap) * - sizeof(s->decoded_base[0][0])); - if (!tmp_ptr) - return AVERROR(ENOMEM); - s->decoded_base[chan] = tmp_ptr; + if ((err = av_reallocp(&s->decoded_base[chan], (s->blocksize + s->nwrap) * + sizeof(s->decoded_base[0][0]))) < 0) + return err; for (i = 0; i < s->nwrap; i++) s->decoded_base[chan][i] = 0; s->decoded[chan] = s->decoded_base[chan] + s->nwrap; } - coeffs = av_realloc(s->coeffs, s->nwrap * sizeof(*s->coeffs)); - if (!coeffs) - return AVERROR(ENOMEM); - s->coeffs = coeffs; + if ((err = av_reallocp(&s->coeffs, s->nwrap * sizeof(*s->coeffs))) < 0) + return err; return 0; } @@ -209,34 +202,38 @@ static int decode_wave_header(AVCodecContext *avctx, const uint8_t *header, { int len, bps; short wave_format; - const uint8_t *end= header + header_size; + GetByteContext gb; - if (bytestream_get_le32(&header) != MKTAG('R', 'I', 'F', 'F')) { + bytestream2_init(&gb, header, header_size); + + if (bytestream2_get_le32(&gb) != MKTAG('R', 'I', 'F', 'F')) { av_log(avctx, AV_LOG_ERROR, "missing RIFF tag\n"); return AVERROR_INVALIDDATA; } - header += 4; /* chunk size */ + bytestream2_skip(&gb, 4); /* chunk size */ - if (bytestream_get_le32(&header) != MKTAG('W', 'A', 'V', 'E')) { + if (bytestream2_get_le32(&gb) != MKTAG('W', 'A', 'V', 'E')) { av_log(avctx, AV_LOG_ERROR, "missing WAVE tag\n"); return AVERROR_INVALIDDATA; } - while (bytestream_get_le32(&header) != MKTAG('f', 'm', 't', ' ')) { - len = bytestream_get_le32(&header); - if (len<0 || end - header - 8 < len) + while (bytestream2_get_le32(&gb) != MKTAG('f', 'm', 't', ' ')) { + len = bytestream2_get_le32(&gb); + bytestream2_skip(&gb, len); + if (len < 0 || bytestream2_get_bytes_left(&gb) < 16) { + av_log(avctx, AV_LOG_ERROR, "no fmt chunk found\n"); return AVERROR_INVALIDDATA; - header += len; + } } - len = bytestream_get_le32(&header); + len = bytestream2_get_le32(&gb); if (len < 16) { av_log(avctx, AV_LOG_ERROR, "fmt chunk was too short\n"); return AVERROR_INVALIDDATA; } - wave_format = bytestream_get_le16(&header); + wave_format = bytestream2_get_le16(&gb); switch (wave_format) { case WAVE_FORMAT_PCM: @@ -246,11 +243,11 @@ static int decode_wave_header(AVCodecContext *avctx, const uint8_t *header, return AVERROR(ENOSYS); } - header += 2; // skip channels (already got from shorten header) - avctx->sample_rate = bytestream_get_le32(&header); - header += 4; // skip bit rate (represents original uncompressed bit rate) - header += 2; // skip block align (not needed) - bps = bytestream_get_le16(&header); + bytestream2_skip(&gb, 2); // skip channels (already got from shorten header) + avctx->sample_rate = bytestream2_get_le32(&gb); + bytestream2_skip(&gb, 4); // skip bit rate (represents original uncompressed bit rate) + bytestream2_skip(&gb, 2); // skip block align (not needed) + bps = bytestream2_get_le16(&gb); avctx->bits_per_coded_sample = bps; if (bps != 16 && bps != 8) { @@ -265,7 +262,8 @@ static int decode_wave_header(AVCodecContext *avctx, const uint8_t *header, return 0; } -static const int fixed_coeffs[3][3] = { +static const int fixed_coeffs[][3] = { + { 0, 0, 0 }, { 1, 0, 0 }, { 2, -1, 0 }, { 3, -3, 1 } @@ -294,7 +292,12 @@ static int decode_subframe_lpc(ShortenContext *s, int command, int channel, } else { /* fixed LPC coeffs */ pred_order = command; - coeffs = fixed_coeffs[pred_order - 1]; + if (pred_order >= FF_ARRAY_ELEMS(fixed_coeffs)) { + av_log(s->avctx, AV_LOG_ERROR, "invalid pred_order %d\n", + pred_order); + return AVERROR_INVALIDDATA; + } + coeffs = fixed_coeffs[pred_order]; qshift = 0; } @@ -424,11 +427,12 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, void *tmp_ptr; s->max_framesize = 8192; // should hopefully be enough for the first header tmp_ptr = av_fast_realloc(s->bitstream, &s->allocated_bitstream_size, - s->max_framesize); + s->max_framesize + FF_INPUT_BUFFER_PADDING_SIZE); if (!tmp_ptr) { av_log(avctx, AV_LOG_ERROR, "error allocating bitstream buffer\n"); return AVERROR(ENOMEM); } + memset(tmp_ptr, 0, s->allocated_bitstream_size); s->bitstream = tmp_ptr; } @@ -437,7 +441,7 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, buf_size = FFMIN(buf_size, s->max_framesize - s->bitstream_size); input_buf_size = buf_size; - if (s->bitstream_index + s->bitstream_size + buf_size > + if (s->bitstream_index + s->bitstream_size + buf_size + FF_INPUT_BUFFER_PADDING_SIZE > s->allocated_bitstream_size) { memmove(s->bitstream, &s->bitstream[s->bitstream_index], s->bitstream_size); @@ -657,6 +661,7 @@ static av_cold int shorten_decode_close(AVCodecContext *avctx) AVCodec ff_shorten_decoder = { .name = "shorten", + .long_name = NULL_IF_CONFIG_SMALL("Shorten"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_SHORTEN, .priv_data_size = sizeof(ShortenContext), @@ -664,7 +669,6 @@ AVCodec ff_shorten_decoder = { .close = shorten_decode_close, .decode = shorten_decode_frame, .capabilities = CODEC_CAP_DELAY | CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Shorten"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_U8P, AV_SAMPLE_FMT_NONE }, diff --git a/ffmpeg/libavcodec/simple_idct.c b/ffmpeg/libavcodec/simple_idct.c index d204565..73f62b4 100644 --- a/ffmpeg/libavcodec/simple_idct.c +++ b/ffmpeg/libavcodec/simple_idct.c @@ -38,6 +38,10 @@ #include "simple_idct_template.c" #undef BIT_DEPTH +#define BIT_DEPTH 12 +#include "simple_idct_template.c" +#undef BIT_DEPTH + /* 2x4x8 idct */ #define CN_SHIFT 12 diff --git a/ffmpeg/libavcodec/simple_idct.h b/ffmpeg/libavcodec/simple_idct.h index 3fec5e0..7c0734b 100644 --- a/ffmpeg/libavcodec/simple_idct.h +++ b/ffmpeg/libavcodec/simple_idct.h @@ -37,6 +37,11 @@ void ff_simple_idct_8(int16_t *block); void ff_simple_idct_put_10(uint8_t *dest, int line_size, int16_t *block); void ff_simple_idct_add_10(uint8_t *dest, int line_size, int16_t *block); void ff_simple_idct_10(int16_t *block); + +void ff_simple_idct_put_12(uint8_t *dest, int line_size, int16_t *block); +void ff_simple_idct_add_12(uint8_t *dest, int line_size, int16_t *block); +void ff_simple_idct_12(int16_t *block); + /** * Special version of ff_simple_idct_10() which does dequantization * and scales by a factor of 2 more between the two IDCTs to account diff --git a/ffmpeg/libavcodec/simple_idct_template.c b/ffmpeg/libavcodec/simple_idct_template.c index dabfbda..64a7be0 100644 --- a/ffmpeg/libavcodec/simple_idct_template.c +++ b/ffmpeg/libavcodec/simple_idct_template.c @@ -62,8 +62,9 @@ #define MUL(a, b) MUL16(a, b) #define MAC(a, b, c) MAC16(a, b, c) -#elif BIT_DEPTH == 10 +#elif BIT_DEPTH == 10 || BIT_DEPTH == 12 +#if BIT_DEPTH == 10 #define W1 90901 #define W2 85627 #define W3 77062 @@ -75,6 +76,19 @@ #define ROW_SHIFT 15 #define COL_SHIFT 20 #define DC_SHIFT 1 +#else +#define W1 45451 +#define W2 42813 +#define W3 38531 +#define W4 32767 +#define W5 25746 +#define W6 17734 +#define W7 9041 + +#define ROW_SHIFT 16 +#define COL_SHIFT 17 +#define DC_SHIFT -1 +#endif #define MUL(a, b) ((a) * (b)) #define MAC(a, b, c) ((a) += (b) * (c)) diff --git a/ffmpeg/libavcodec/sipr.c b/ffmpeg/libavcodec/sipr.c index 35e8bf5..17260a0 100644 --- a/ffmpeg/libavcodec/sipr.c +++ b/ffmpeg/libavcodec/sipr.c @@ -240,7 +240,7 @@ static void eval_ir(const float *Az, int pitch_lag, float *freq, float tmp1[SUBFR_SIZE+1], tmp2[LP_FILTER_ORDER+1]; int i; - tmp1[0] = 1.; + tmp1[0] = 1.0; for (i = 0; i < LP_FILTER_ORDER; i++) { tmp1[i+1] = Az[i] * ff_pow_0_55[i]; tmp2[i ] = Az[i] * ff_pow_0_7 [i]; @@ -564,11 +564,11 @@ static int sipr_decode_frame(AVCodecContext *avctx, void *data, AVCodec ff_sipr_decoder = { .name = "sipr", + .long_name = NULL_IF_CONFIG_SMALL("RealAudio SIPR / ACELP.NET"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_SIPR, .priv_data_size = sizeof(SiprContext), .init = sipr_decoder_init, .decode = sipr_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("RealAudio SIPR / ACELP.NET"), }; diff --git a/ffmpeg/libavcodec/sipr16k.c b/ffmpeg/libavcodec/sipr16k.c index fbf7497..bfd8ade 100644 --- a/ffmpeg/libavcodec/sipr16k.c +++ b/ffmpeg/libavcodec/sipr16k.c @@ -24,11 +24,11 @@ #include #include "sipr.h" +#include "libavutil/attributes.h" #include "libavutil/common.h" #include "libavutil/float_dsp.h" #include "libavutil/mathematics.h" #include "lsp.h" -#include "celp_filters.h" #include "acelp_vectors.h" #include "acelp_pitch_delay.h" #include "acelp_filters.h" @@ -268,7 +268,7 @@ void ff_sipr_decode_frame_16k(SiprContext *ctx, SiprParameters *params, memcpy(ctx->iir_mem, Az[1], LP_FILTER_ORDER_16k * sizeof(float)); } -void ff_sipr_init_16k(SiprContext *ctx) +av_cold void ff_sipr_init_16k(SiprContext *ctx) { int i; diff --git a/ffmpeg/libavcodec/smacker.c b/ffmpeg/libavcodec/smacker.c index c070150..cd342b9 100644 --- a/ffmpeg/libavcodec/smacker.c +++ b/ffmpeg/libavcodec/smacker.c @@ -48,7 +48,7 @@ */ typedef struct SmackVContext { AVCodecContext *avctx; - AVFrame pic; + AVFrame *pic; int *mmap_tbl, *mclr_tbl, *full_tbl, *type_tbl; int mmap_last[3], mclr_last[3], full_last[3], type_last[3]; @@ -102,7 +102,7 @@ static int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, uint32_t pref return AVERROR_INVALIDDATA; } if(!get_bits1(gb)){ //Leaf - if(hc->current >= 256){ + if(hc->current >= hc->length){ av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n"); return AVERROR_INVALIDDATA; } @@ -204,11 +204,18 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int tmp2.bits = av_mallocz(256 * 4); tmp2.lengths = av_mallocz(256 * sizeof(int)); tmp2.values = av_mallocz(256 * sizeof(int)); + if (!tmp1.bits || !tmp1.lengths || !tmp1.values || + !tmp2.bits || !tmp2.lengths || !tmp2.values) { + err = AVERROR(ENOMEM); + goto error; + } if(get_bits1(gb)) { res = smacker_decode_tree(gb, &tmp1, 0, 0); - if (res < 0) - return res; + if (res < 0) { + err = res; + goto error; + } skip_bits1(gb); if(tmp1.current > 1) { res = init_vlc(&vlc[0], SMKTREE_BITS, tmp1.length, @@ -216,7 +223,8 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int tmp1.bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); if(res < 0) { av_log(smk->avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); - return AVERROR_INVALIDDATA; + err = res; + goto error; } } } @@ -225,8 +233,10 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int } if(get_bits1(gb)){ res = smacker_decode_tree(gb, &tmp2, 0, 0); - if (res < 0) - return res; + if (res < 0) { + err = res; + goto error; + } skip_bits1(gb); if(tmp2.current > 1) { res = init_vlc(&vlc[1], SMKTREE_BITS, tmp2.length, @@ -234,7 +244,8 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int tmp2.bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); if(res < 0) { av_log(smk->avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); - return AVERROR_INVALIDDATA; + err = res; + goto error; } } } @@ -257,10 +268,14 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int ctx.recode2 = tmp2.values; ctx.last = last; - huff.length = ((size + 3) >> 2) + 3; + huff.length = ((size + 3) >> 2) + 4; huff.maxlength = 0; huff.current = 0; huff.values = av_mallocz(huff.length * sizeof(int)); + if (!huff.values) { + err = AVERROR(ENOMEM); + goto error; + } if (smacker_decode_bigtree(gb, &huff, &ctx) < 0) err = -1; @@ -268,14 +283,16 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int if(ctx.last[0] == -1) ctx.last[0] = huff.current++; if(ctx.last[1] == -1) ctx.last[1] = huff.current++; if(ctx.last[2] == -1) ctx.last[2] = huff.current++; - if(huff.current > huff.length){ - ctx.last[0] = ctx.last[1] = ctx.last[2] = 1; - av_log(smk->avctx, AV_LOG_ERROR, "bigtree damaged\n"); - return AVERROR_INVALIDDATA; + if (ctx.last[0] >= huff.length || + ctx.last[1] >= huff.length || + ctx.last[2] >= huff.length) { + av_log(smk->avctx, AV_LOG_ERROR, "Huffman codes out of range\n"); + err = AVERROR_INVALIDDATA; } *recodes = huff.values; +error: if(vlc[0].table) ff_free_vlc(&vlc[0]); if(vlc[1].table) @@ -292,50 +309,62 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int static int decode_header_trees(SmackVContext *smk) { GetBitContext gb; - int mmap_size, mclr_size, full_size, type_size; + int mmap_size, mclr_size, full_size, type_size, ret; mmap_size = AV_RL32(smk->avctx->extradata); mclr_size = AV_RL32(smk->avctx->extradata + 4); full_size = AV_RL32(smk->avctx->extradata + 8); type_size = AV_RL32(smk->avctx->extradata + 12); - init_get_bits(&gb, smk->avctx->extradata + 16, (smk->avctx->extradata_size - 16) * 8); + init_get_bits8(&gb, smk->avctx->extradata + 16, smk->avctx->extradata_size - 16); if(!get_bits1(&gb)) { av_log(smk->avctx, AV_LOG_INFO, "Skipping MMAP tree\n"); smk->mmap_tbl = av_malloc(sizeof(int) * 2); + if (!smk->mmap_tbl) + return AVERROR(ENOMEM); smk->mmap_tbl[0] = 0; smk->mmap_last[0] = smk->mmap_last[1] = smk->mmap_last[2] = 1; } else { - if (smacker_decode_header_tree(smk, &gb, &smk->mmap_tbl, smk->mmap_last, mmap_size)) - return AVERROR_INVALIDDATA; + ret = smacker_decode_header_tree(smk, &gb, &smk->mmap_tbl, smk->mmap_last, mmap_size); + if (ret < 0) + return ret; } if(!get_bits1(&gb)) { av_log(smk->avctx, AV_LOG_INFO, "Skipping MCLR tree\n"); smk->mclr_tbl = av_malloc(sizeof(int) * 2); + if (!smk->mclr_tbl) + return AVERROR(ENOMEM); smk->mclr_tbl[0] = 0; smk->mclr_last[0] = smk->mclr_last[1] = smk->mclr_last[2] = 1; } else { - if (smacker_decode_header_tree(smk, &gb, &smk->mclr_tbl, smk->mclr_last, mclr_size)) - return AVERROR_INVALIDDATA; + ret = smacker_decode_header_tree(smk, &gb, &smk->mclr_tbl, smk->mclr_last, mclr_size); + if (ret < 0) + return ret; } if(!get_bits1(&gb)) { av_log(smk->avctx, AV_LOG_INFO, "Skipping FULL tree\n"); smk->full_tbl = av_malloc(sizeof(int) * 2); + if (!smk->full_tbl) + return AVERROR(ENOMEM); smk->full_tbl[0] = 0; smk->full_last[0] = smk->full_last[1] = smk->full_last[2] = 1; } else { - if (smacker_decode_header_tree(smk, &gb, &smk->full_tbl, smk->full_last, full_size)) - return AVERROR_INVALIDDATA; + ret = smacker_decode_header_tree(smk, &gb, &smk->full_tbl, smk->full_last, full_size); + if (ret < 0) + return ret; } if(!get_bits1(&gb)) { av_log(smk->avctx, AV_LOG_INFO, "Skipping TYPE tree\n"); smk->type_tbl = av_malloc(sizeof(int) * 2); + if (!smk->type_tbl) + return AVERROR(ENOMEM); smk->type_tbl[0] = 0; smk->type_last[0] = smk->type_last[1] = smk->type_last[2] = 1; } else { - if (smacker_decode_header_tree(smk, &gb, &smk->type_tbl, smk->type_last, type_size)) - return AVERROR_INVALIDDATA; + ret = smacker_decode_header_tree(smk, &gb, &smk->type_tbl, smk->type_last, type_size); + if (ret < 0) + return ret; } return 0; @@ -381,19 +410,19 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (avpkt->size <= 769) return AVERROR_INVALIDDATA; - if ((ret = ff_reget_buffer(avctx, &smk->pic)) < 0) + if ((ret = ff_reget_buffer(avctx, smk->pic)) < 0) return ret; /* make the palette available on the way out */ - pal = (uint32_t*)smk->pic.data[1]; + pal = (uint32_t*)smk->pic->data[1]; bytestream2_init(&gb2, avpkt->data, avpkt->size); flags = bytestream2_get_byteu(&gb2); - smk->pic.palette_has_changed = flags & 1; - smk->pic.key_frame = !!(flags & 2); - if(smk->pic.key_frame) - smk->pic.pict_type = AV_PICTURE_TYPE_I; + smk->pic->palette_has_changed = flags & 1; + smk->pic->key_frame = !!(flags & 2); + if (smk->pic->key_frame) + smk->pic->pict_type = AV_PICTURE_TYPE_I; else - smk->pic.pict_type = AV_PICTURE_TYPE_P; + smk->pic->pict_type = AV_PICTURE_TYPE_P; for(i = 0; i < 256; i++) *pal++ = 0xFFU << 24 | bytestream2_get_be24u(&gb2); @@ -402,14 +431,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, last_reset(smk->mclr_tbl, smk->mclr_last); last_reset(smk->full_tbl, smk->full_last); last_reset(smk->type_tbl, smk->type_last); - init_get_bits(&gb, avpkt->data + 769, (avpkt->size - 769) * 8); + if ((ret = init_get_bits8(&gb, avpkt->data + 769, avpkt->size - 769)) < 0) + return ret; blk = 0; bw = avctx->width >> 2; bh = avctx->height >> 2; blocks = bw * bh; - out = smk->pic.data[0]; - stride = smk->pic.linesize[0]; + out = smk->pic->data[0]; + stride = smk->pic->linesize[0]; while(blk < blocks) { int type, run, mode; uint16_t pix; @@ -423,7 +453,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, int hi, lo; clr = smk_get_code(&gb, smk->mclr_tbl, smk->mclr_last); map = smk_get_code(&gb, smk->mmap_tbl, smk->mmap_last); - out = smk->pic.data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4; + out = smk->pic->data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4; hi = clr >> 8; lo = clr & 0xFF; for(i = 0; i < 4; i++) { @@ -444,7 +474,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, else if(get_bits1(&gb)) mode = 2; } while(run-- && blk < blocks){ - out = smk->pic.data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4; + out = smk->pic->data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4; switch(mode){ case 0: for(i = 0; i < 4; i++) { @@ -496,7 +526,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, mode = type >> 8; while(run-- && blk < blocks){ uint32_t col; - out = smk->pic.data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4; + out = smk->pic->data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4; col = mode * 0x01010101; for(i = 0; i < 4; i++) { *((uint32_t*)out) = col; @@ -509,7 +539,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } - if ((ret = av_frame_ref(data, &smk->pic)) < 0) + if ((ret = av_frame_ref(data, smk->pic)) < 0) return ret; *got_frame = 1; @@ -522,47 +552,53 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, /* * - * Init smacker decoder + * Uninit smacker decoder * */ -static av_cold int decode_init(AVCodecContext *avctx) +static av_cold int decode_end(AVCodecContext *avctx) { - SmackVContext * const c = avctx->priv_data; - - c->avctx = avctx; - - avctx->pix_fmt = AV_PIX_FMT_PAL8; - avcodec_get_frame_defaults(&c->pic); + SmackVContext * const smk = avctx->priv_data; - /* decode huffman trees from extradata */ - if(avctx->extradata_size < 16){ - av_log(avctx, AV_LOG_ERROR, "Extradata missing!\n"); - return AVERROR(EINVAL); - } + av_freep(&smk->mmap_tbl); + av_freep(&smk->mclr_tbl); + av_freep(&smk->full_tbl); + av_freep(&smk->type_tbl); - if (decode_header_trees(c)) - return AVERROR_INVALIDDATA; + av_frame_free(&smk->pic); return 0; } - /* * - * Uninit smacker decoder + * Init smacker decoder * */ -static av_cold int decode_end(AVCodecContext *avctx) +static av_cold int decode_init(AVCodecContext *avctx) { - SmackVContext * const smk = avctx->priv_data; + SmackVContext * const c = avctx->priv_data; + int ret; - av_freep(&smk->mmap_tbl); - av_freep(&smk->mclr_tbl); - av_freep(&smk->full_tbl); - av_freep(&smk->type_tbl); + c->avctx = avctx; + + avctx->pix_fmt = AV_PIX_FMT_PAL8; - av_frame_unref(&smk->pic); + c->pic = av_frame_alloc(); + if (!c->pic) + return AVERROR(ENOMEM); + + /* decode huffman trees from extradata */ + if(avctx->extradata_size < 16){ + av_log(avctx, AV_LOG_ERROR, "Extradata missing!\n"); + return AVERROR(EINVAL); + } + + ret = decode_header_trees(c); + if (ret < 0) { + decode_end(avctx); + return ret; + } return 0; } @@ -612,7 +648,8 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } - init_get_bits(&gb, buf + 4, (buf_size - 4) * 8); + if ((ret = init_get_bits8(&gb, buf + 4, buf_size - 4)) < 0) + return ret; if(!get_bits1(&gb)){ av_log(avctx, AV_LOG_INFO, "Sound: no data\n"); @@ -625,7 +662,7 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_ERROR, "channels mismatch\n"); return AVERROR(EINVAL); } - if (bits && avctx->sample_fmt == AV_SAMPLE_FMT_U8) { + if (bits == (avctx->sample_fmt == AV_SAMPLE_FMT_U8)) { av_log(avctx, AV_LOG_ERROR, "sample format mismatch\n"); return AVERROR(EINVAL); } @@ -645,10 +682,15 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, h[i].bits = av_mallocz(256 * 4); h[i].lengths = av_mallocz(256 * sizeof(int)); h[i].values = av_mallocz(256 * sizeof(int)); + if (!h[i].bits || !h[i].lengths || !h[i].values) { + ret = AVERROR(ENOMEM); + goto error; + } skip_bits1(&gb); - res = smacker_decode_tree(&gb, &h[i], 0, 0); - if (res < 0) - return res; + if (smacker_decode_tree(&gb, &h[i], 0, 0) < 0) { + ret = AVERROR_INVALIDDATA; + goto error; + } skip_bits1(&gb); if(h[i].current > 1) { res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length, @@ -656,10 +698,12 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, h[i].bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); if(res < 0) { av_log(avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto error; } } } + /* this codec relies on wraparound instead of clipping audio */ if(bits) { //decode 16-bit data for(i = stereo; i >= 0; i--) pred[i] = sign_extend(av_bswap16(get_bits(&gb, 16)), 16); @@ -688,7 +732,7 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, } val |= h[3].values[res] << 8; pred[1] += sign_extend(val, 16); - *samples++ = av_clip_int16(pred[1]); + *samples++ = pred[1]; } else { if(vlc[0].table) res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); @@ -709,7 +753,7 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, } val |= h[1].values[res] << 8; pred[0] += sign_extend(val, 16); - *samples++ = av_clip_int16(pred[0]); + *samples++ = pred[0]; } } } else { //8-bit data @@ -730,7 +774,7 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } pred[1] += sign_extend(h[1].values[res], 8); - *samples8++ = av_clip_uint8(pred[1]); + *samples8++ = pred[1]; } else { if(vlc[0].table) res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); @@ -741,11 +785,15 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } pred[0] += sign_extend(h[0].values[res], 8); - *samples8++ = av_clip_uint8(pred[0]); + *samples8++ = pred[0]; } } } + *got_frame_ptr = 1; + ret = buf_size; + +error: for(i = 0; i < 4; i++) { if(vlc[i].table) ff_free_vlc(&vlc[i]); @@ -754,13 +802,12 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, av_free(h[i].values); } - *got_frame_ptr = 1; - - return buf_size; + return ret; } AVCodec ff_smacker_decoder = { .name = "smackvid", + .long_name = NULL_IF_CONFIG_SMALL("Smacker video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_SMACKVIDEO, .priv_data_size = sizeof(SmackVContext), @@ -768,15 +815,14 @@ AVCodec ff_smacker_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Smacker video"), }; AVCodec ff_smackaud_decoder = { .name = "smackaud", + .long_name = NULL_IF_CONFIG_SMALL("Smacker audio"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_SMACKAUDIO, .init = smka_decode_init, .decode = smka_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Smacker audio"), }; diff --git a/ffmpeg/libavcodec/smc.c b/ffmpeg/libavcodec/smc.c index 2c7ab9a..31e6c88 100644 --- a/ffmpeg/libavcodec/smc.c +++ b/ffmpeg/libavcodec/smc.c @@ -46,7 +46,7 @@ typedef struct SmcContext { AVCodecContext *avctx; - AVFrame frame; + AVFrame *frame; GetByteContext gb; @@ -81,7 +81,7 @@ static void smc_decode_stream(SmcContext *s) { int width = s->avctx->width; int height = s->avctx->height; - int stride = s->frame.linesize[0]; + int stride = s->frame->linesize[0]; int i; int chunk_size; int buf_size = bytestream2_size(&s->gb); @@ -92,9 +92,9 @@ static void smc_decode_stream(SmcContext *s) unsigned int color_flags_b; unsigned int flag_mask; - unsigned char *pixels = s->frame.data[0]; + unsigned char *pixels = s->frame->data[0]; - int image_size = height * s->frame.linesize[0]; + int image_size = height * s->frame->linesize[0]; int row_ptr = 0; int pixel_ptr = 0; int pixel_x, pixel_y; @@ -112,7 +112,7 @@ static void smc_decode_stream(SmcContext *s) int color_octet_index = 0; /* make the palette available */ - memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE); + memcpy(s->frame->data[1], s->pal, AVPALETTE_SIZE); bytestream2_skip(&s->gb, 1); chunk_size = bytestream2_get_be24(&s->gb); @@ -417,7 +417,9 @@ static av_cold int smc_decode_init(AVCodecContext *avctx) s->avctx = avctx; avctx->pix_fmt = AV_PIX_FMT_PAL8; - avcodec_get_frame_defaults(&s->frame); + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); return 0; } @@ -434,18 +436,18 @@ static int smc_decode_frame(AVCodecContext *avctx, bytestream2_init(&s->gb, buf, buf_size); - if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) + if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) return ret; if (pal) { - s->frame.palette_has_changed = 1; + s->frame->palette_has_changed = 1; memcpy(s->pal, pal, AVPALETTE_SIZE); } smc_decode_stream(s); *got_frame = 1; - if ((ret = av_frame_ref(data, &s->frame)) < 0) + if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; /* always report that the buffer was completely consumed */ @@ -456,13 +458,14 @@ static av_cold int smc_decode_end(AVCodecContext *avctx) { SmcContext *s = avctx->priv_data; - av_frame_unref(&s->frame); + av_frame_free(&s->frame); return 0; } AVCodec ff_smc_decoder = { .name = "smc", + .long_name = NULL_IF_CONFIG_SMALL("QuickTime Graphics (SMC)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_SMC, .priv_data_size = sizeof(SmcContext), @@ -470,5 +473,4 @@ AVCodec ff_smc_decoder = { .close = smc_decode_end, .decode = smc_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("QuickTime Graphics (SMC)"), }; diff --git a/ffmpeg/libavcodec/snow.c b/ffmpeg/libavcodec/snow.c index de19687..c645b12 100644 --- a/ffmpeg/libavcodec/snow.c +++ b/ffmpeg/libavcodec/snow.c @@ -81,18 +81,21 @@ void ff_snow_reset_contexts(SnowContext *s){ //FIXME better initial contexts } int ff_snow_alloc_blocks(SnowContext *s){ - int w= -((-s->avctx->width )>>LOG2_MB_SIZE); - int h= -((-s->avctx->height)>>LOG2_MB_SIZE); + int w= FF_CEIL_RSHIFT(s->avctx->width, LOG2_MB_SIZE); + int h= FF_CEIL_RSHIFT(s->avctx->height, LOG2_MB_SIZE); s->b_width = w; s->b_height= h; av_free(s->block); s->block= av_mallocz(w * h * sizeof(BlockNode) << (s->block_max_depth*2)); + if (!s->block) + return AVERROR(ENOMEM); + return 0; } -static void init_qexp(void){ +static av_cold void init_qexp(void){ int i; double v=128; @@ -294,7 +297,7 @@ static void mc_block(Plane *p, uint8_t *dst, const uint8_t *src, int stride, int } } -void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, int stride, int sx, int sy, int b_w, int b_h, BlockNode *block, int plane_index, int w, int h){ +void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, ptrdiff_t stride, int sx, int sy, int b_w, int b_h, BlockNode *block, int plane_index, int w, int h){ if(block->type & BLOCK_INTRA){ int x, y; const unsigned color = block->color[plane_index]; @@ -334,7 +337,7 @@ void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, int stride, } } }else{ - uint8_t *src= s->last_picture[block->ref].data[plane_index]; + uint8_t *src= s->last_picture[block->ref]->data[plane_index]; const int scale= plane_index ? (2*s->mv_scale)>>s->chroma_h_shift : 2*s->mv_scale; int mx= block->mx*scale; int my= block->my*scale; @@ -346,14 +349,15 @@ void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, int stride, src += sx + sy*stride; if( (unsigned)sx >= FFMAX(w - b_w - (HTAPS_MAX-2), 0) || (unsigned)sy >= FFMAX(h - b_h - (HTAPS_MAX-2), 0)){ - s->vdsp.emulated_edge_mc(tmp + MB_SIZE, src, stride, b_w+HTAPS_MAX-1, b_h+HTAPS_MAX-1, sx, sy, w, h); + s->vdsp.emulated_edge_mc(tmp + MB_SIZE, src, + stride, stride, + b_w+HTAPS_MAX-1, b_h+HTAPS_MAX-1, + sx, sy, w, h); src= tmp + MB_SIZE; } av_assert2(s->chroma_h_shift == s->chroma_v_shift); // only one mv_scale -// assert(b_w == b_h || 2*b_w == b_h || b_w == 2*b_h); -// assert(!(b_w&(b_w-1))); av_assert2(b_w>1 && b_h>1); av_assert2((tab_index>=0 && tab_index<4) || b_w==32); if((dx&3) || (dy&3) || !(b_w == b_h || 2*b_w == b_h || b_w == 2*b_h) || (b_w&(b_w-1)) || !s->plane[plane_index].fast_mc ) @@ -460,11 +464,15 @@ av_cold int ff_snow_common_init(AVCodecContext *avctx){ for(i=0; ilast_picture[i]); + s->last_picture[i] = av_frame_alloc(); + if (!s->last_picture[i]) + goto fail; } - avcodec_get_frame_defaults(&s->mconly_picture); - avcodec_get_frame_defaults(&s->current_picture); + s->mconly_picture = av_frame_alloc(); + s->current_picture = av_frame_alloc(); + if (!s->mconly_picture || !s->current_picture) + goto fail; return 0; fail: @@ -477,20 +485,20 @@ int ff_snow_common_init_after_header(AVCodecContext *avctx) { int ret, emu_buf_size; if(!s->scratchbuf) { - if ((ret = ff_get_buffer(s->avctx, &s->mconly_picture, + if ((ret = ff_get_buffer(s->avctx, s->mconly_picture, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; - FF_ALLOCZ_OR_GOTO(avctx, s->scratchbuf, FFMAX(s->mconly_picture.linesize[0], 2*avctx->width+256)*7*MB_SIZE, fail); - emu_buf_size = FFMAX(s->mconly_picture.linesize[0], 2*avctx->width+256) * (2 * MB_SIZE + HTAPS_MAX - 1); + FF_ALLOCZ_OR_GOTO(avctx, s->scratchbuf, FFMAX(s->mconly_picture->linesize[0], 2*avctx->width+256)*7*MB_SIZE, fail); + emu_buf_size = FFMAX(s->mconly_picture->linesize[0], 2*avctx->width+256) * (2 * MB_SIZE + HTAPS_MAX - 1); FF_ALLOC_OR_GOTO(avctx, s->emu_edge_buffer, emu_buf_size, fail); } - if(s->mconly_picture.format != avctx->pix_fmt) { + if(s->mconly_picture->format != avctx->pix_fmt) { av_log(avctx, AV_LOG_ERROR, "pixel format changed\n"); return AVERROR_INVALIDDATA; } - for(plane_index=0; plane_index<3; plane_index++){ + for(plane_index=0; plane_index < s->nb_planes; plane_index++){ int w= s->avctx->width; int h= s->avctx->height; @@ -530,6 +538,8 @@ int ff_snow_common_init_after_header(AVCodecContext *avctx) { //FIXME avoid this realloc av_freep(&b->x_coeff); b->x_coeff=av_mallocz(((b->width+1) * b->height+1)*sizeof(x_and_coeff)); + if (!b->x_coeff) + goto fail; } w= (w+1)>>1; h= (h+1)>>1; @@ -543,10 +553,10 @@ fail: #define USE_HALFPEL_PLANE 0 -static void halfpel_interpol(SnowContext *s, uint8_t *halfpel[4][4], AVFrame *frame){ +static int halfpel_interpol(SnowContext *s, uint8_t *halfpel[4][4], AVFrame *frame){ int p,x,y; - for(p=0; p<3; p++){ + for(p=0; p < s->nb_planes; p++){ int is_chroma= !!p; int w= is_chroma ? s->avctx->width >>s->chroma_h_shift : s->avctx->width; int h= is_chroma ? s->avctx->height>>s->chroma_v_shift : s->avctx->height; @@ -556,6 +566,8 @@ static void halfpel_interpol(SnowContext *s, uint8_t *halfpel[4][4], AVFrame *fr halfpel[1][p] = (uint8_t*) av_malloc(ls * (h + 2 * EDGE_WIDTH)) + EDGE_WIDTH * (1 + ls); halfpel[2][p] = (uint8_t*) av_malloc(ls * (h + 2 * EDGE_WIDTH)) + EDGE_WIDTH * (1 + ls); halfpel[3][p] = (uint8_t*) av_malloc(ls * (h + 2 * EDGE_WIDTH)) + EDGE_WIDTH * (1 + ls); + if (!halfpel[1][p] || !halfpel[2][p] || !halfpel[3][p]) + return AVERROR(ENOMEM); halfpel[0][p]= src; for(y=0; ypriv_data; int i; - if(s->last_picture[s->max_ref_frames-1].data[0]){ - av_frame_unref(&s->last_picture[s->max_ref_frames-1]); + if(s->last_picture[s->max_ref_frames-1]->data[0]){ + av_frame_unref(s->last_picture[s->max_ref_frames-1]); for(i=0; i<9; i++) if(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3]) - av_free(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3] - EDGE_WIDTH*(1+s->current_picture.linesize[i%3])); + av_free(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3] - EDGE_WIDTH*(1+s->current_picture->linesize[i%3])); } } int ff_snow_frame_start(SnowContext *s){ - AVFrame tmp; + AVFrame *tmp; int i, ret; int w= s->avctx->width; //FIXME round up to x16 ? int h= s->avctx->height; - if (s->current_picture.data[0] && !(s->avctx->flags&CODEC_FLAG_EMU_EDGE)) { - s->dsp.draw_edges(s->current_picture.data[0], - s->current_picture.linesize[0], w , h , + if (s->current_picture->data[0] && !(s->avctx->flags&CODEC_FLAG_EMU_EDGE)) { + s->dsp.draw_edges(s->current_picture->data[0], + s->current_picture->linesize[0], w , h , EDGE_WIDTH , EDGE_WIDTH , EDGE_TOP | EDGE_BOTTOM); - s->dsp.draw_edges(s->current_picture.data[1], - s->current_picture.linesize[1], w>>s->chroma_h_shift, h>>s->chroma_v_shift, - EDGE_WIDTH>>s->chroma_h_shift, EDGE_WIDTH>>s->chroma_v_shift, EDGE_TOP | EDGE_BOTTOM); - s->dsp.draw_edges(s->current_picture.data[2], - s->current_picture.linesize[2], w>>s->chroma_h_shift, h>>s->chroma_v_shift, - EDGE_WIDTH>>s->chroma_h_shift, EDGE_WIDTH>>s->chroma_v_shift, EDGE_TOP | EDGE_BOTTOM); + if (s->current_picture->data[2]) { + s->dsp.draw_edges(s->current_picture->data[1], + s->current_picture->linesize[1], w>>s->chroma_h_shift, h>>s->chroma_v_shift, + EDGE_WIDTH>>s->chroma_h_shift, EDGE_WIDTH>>s->chroma_v_shift, EDGE_TOP | EDGE_BOTTOM); + s->dsp.draw_edges(s->current_picture->data[2], + s->current_picture->linesize[2], w>>s->chroma_h_shift, h>>s->chroma_v_shift, + EDGE_WIDTH>>s->chroma_h_shift, EDGE_WIDTH>>s->chroma_v_shift, EDGE_TOP | EDGE_BOTTOM); + } } ff_snow_release_buffer(s->avctx); - av_frame_move_ref(&tmp, &s->last_picture[s->max_ref_frames-1]); + tmp= s->last_picture[s->max_ref_frames-1]; for(i=s->max_ref_frames-1; i>0; i--) - av_frame_move_ref(&s->last_picture[i+1], &s->last_picture[i]); + s->last_picture[i] = s->last_picture[i-1]; memmove(s->halfpel_plane+1, s->halfpel_plane, (s->max_ref_frames-1)*sizeof(void*)*4*4); - if(USE_HALFPEL_PLANE && s->current_picture.data[0]) - halfpel_interpol(s, s->halfpel_plane[0], &s->current_picture); - av_frame_move_ref(&s->last_picture[0], &s->current_picture); - av_frame_move_ref(&s->current_picture, &tmp); + if(USE_HALFPEL_PLANE && s->current_picture->data[0]) { + if((ret = halfpel_interpol(s, s->halfpel_plane[0], s->current_picture)) < 0) + return ret; + } + s->last_picture[0] = s->current_picture; + s->current_picture = tmp; if(s->keyframe){ s->ref_frames= 0; }else{ int i; - for(i=0; imax_ref_frames && s->last_picture[i].data[0]; i++) - if(i && s->last_picture[i-1].key_frame) + for(i=0; imax_ref_frames && s->last_picture[i]->data[0]; i++) + if(i && s->last_picture[i-1]->key_frame) break; s->ref_frames= i; if(s->ref_frames==0){ @@ -641,10 +658,10 @@ int ff_snow_frame_start(SnowContext *s){ } } - if ((ret = ff_get_buffer(s->avctx, &s->current_picture, AV_GET_BUFFER_FLAG_REF)) < 0) + if ((ret = ff_get_buffer(s->avctx, s->current_picture, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; - s->current_picture.key_frame= s->keyframe; + s->current_picture->key_frame= s->keyframe; return 0; } @@ -672,13 +689,13 @@ av_cold void ff_snow_common_end(SnowContext *s) for(i=0; iref_mvs[i]); av_freep(&s->ref_scores[i]); - if(s->last_picture[i].data[0]) { - av_assert0(s->last_picture[i].data[0] != s->current_picture.data[0]); - av_frame_unref(&s->last_picture[i]); + if(s->last_picture[i]->data[0]) { + av_assert0(s->last_picture[i]->data[0] != s->current_picture->data[0]); } + av_frame_free(&s->last_picture[i]); } - for(plane_index=0; plane_index<3; plane_index++){ + for(plane_index=0; plane_index < s->nb_planes; plane_index++){ for(level=s->spatial_decomposition_count-1; level>=0; level--){ for(orientation=level ? 1 : 0; orientation<4; orientation++){ SubBand *b= &s->plane[plane_index].band[level][orientation]; @@ -687,6 +704,6 @@ av_cold void ff_snow_common_end(SnowContext *s) } } } - av_frame_unref(&s->mconly_picture); - av_frame_unref(&s->current_picture); + av_frame_free(&s->mconly_picture); + av_frame_free(&s->current_picture); } diff --git a/ffmpeg/libavcodec/snow.h b/ffmpeg/libavcodec/snow.h index 922a48e..1222a77 100644 --- a/ffmpeg/libavcodec/snow.h +++ b/ffmpeg/libavcodec/snow.h @@ -114,12 +114,12 @@ typedef struct SnowContext{ VideoDSPContext vdsp; H264QpelContext h264qpel; SnowDWTContext dwt; - AVFrame new_picture; - AVFrame input_picture; ///< new_picture with the internal linesizes - AVFrame current_picture; - AVFrame last_picture[MAX_REF_FRAMES]; + AVFrame *new_picture; + AVFrame *input_picture; ///< new_picture with the internal linesizes + AVFrame *current_picture; + AVFrame *last_picture[MAX_REF_FRAMES]; uint8_t *halfpel_plane[MAX_REF_FRAMES][4][4]; - AVFrame mconly_picture; + AVFrame *mconly_picture; // uint8_t q_context[16]; uint8_t header_state[32]; uint8_t block_state[128 + 32*128]; @@ -159,6 +159,7 @@ typedef struct SnowContext{ int b_height; int block_max_depth; int last_block_max_depth; + int nb_planes; Plane plane[MAX_PLANES]; BlockNode *block; #define ME_CACHE_SIZE 1024 @@ -226,7 +227,7 @@ void ff_snow_release_buffer(AVCodecContext *avctx); void ff_snow_reset_contexts(SnowContext *s); int ff_snow_alloc_blocks(SnowContext *s); int ff_snow_frame_start(SnowContext *s); -void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, int stride, +void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, ptrdiff_t stride, int sx, int sy, int b_w, int b_h, BlockNode *block, int plane_index, int w, int h); /* common inline functions */ @@ -414,8 +415,8 @@ static av_always_inline void predict_slice(SnowContext *s, IDWTELEM *buf, int pl int block_h = plane_index ? block_size>>s->chroma_v_shift : block_size; const uint8_t *obmc = plane_index ? ff_obmc_tab[s->block_max_depth+s->chroma_h_shift] : ff_obmc_tab[s->block_max_depth]; const int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size; - int ref_stride= s->current_picture.linesize[plane_index]; - uint8_t *dst8= s->current_picture.data[plane_index]; + int ref_stride= s->current_picture->linesize[plane_index]; + uint8_t *dst8= s->current_picture->data[plane_index]; int w= p->width; int h= p->height; av_assert2(s->chroma_h_shift == s->chroma_v_shift); // obmc params assume squares diff --git a/ffmpeg/libavcodec/snowdec.c b/ffmpeg/libavcodec/snowdec.c index c8a0327..79cf5a1 100644 --- a/ffmpeg/libavcodec/snowdec.c +++ b/ffmpeg/libavcodec/snowdec.c @@ -33,9 +33,6 @@ #include "mpegvideo.h" #include "h263.h" -#undef NDEBUG -#include - static av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer * sb, IDWTELEM * old_buffer, int plane_index, int add, int mb_y){ Plane *p= &s->plane[plane_index]; const int mb_w= s->b_width << s->block_max_depth; @@ -46,8 +43,8 @@ static av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer int block_h = plane_index ? block_size>>s->chroma_v_shift : block_size; const uint8_t *obmc = plane_index ? ff_obmc_tab[s->block_max_depth+s->chroma_h_shift] : ff_obmc_tab[s->block_max_depth]; int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size; - int ref_stride= s->current_picture.linesize[plane_index]; - uint8_t *dst8= s->current_picture.data[plane_index]; + int ref_stride= s->current_picture->linesize[plane_index]; + uint8_t *dst8= s->current_picture->data[plane_index]; int w= p->width; int h= p->height; @@ -166,8 +163,10 @@ static int decode_q_branch(SnowContext *s, int level, int x, int y){ if(type){ pred_mv(s, &mx, &my, 0, left, top, tr); l += get_symbol(&s->c, &s->block_state[32], 1); - cb+= get_symbol(&s->c, &s->block_state[64], 1); - cr+= get_symbol(&s->c, &s->block_state[96], 1); + if (s->nb_planes > 2) { + cb+= get_symbol(&s->c, &s->block_state[64], 1); + cr+= get_symbol(&s->c, &s->block_state[96], 1); + } }else{ if(s->ref_frames > 1) ref= get_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], 0); @@ -246,7 +245,7 @@ static void correlate_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand static void decode_qlogs(SnowContext *s){ int plane_index, level, orientation; - for(plane_index=0; plane_index<3; plane_index++){ + for(plane_index=0; plane_index < s->nb_planes; plane_index++){ for(level=0; levelspatial_decomposition_count; level++){ for(orientation=level ? 1:0; orientation<4; orientation++){ int q; @@ -289,22 +288,34 @@ static int decode_header(SnowContext *s){ s->temporal_decomposition_count= get_symbol(&s->c, s->header_state, 0); GET_S(s->spatial_decomposition_count, 0 < tmp && tmp <= MAX_DECOMPOSITIONS) s->colorspace_type= get_symbol(&s->c, s->header_state, 0); - s->chroma_h_shift= get_symbol(&s->c, s->header_state, 0); - s->chroma_v_shift= get_symbol(&s->c, s->header_state, 0); - - if(s->chroma_h_shift == 1 && s->chroma_v_shift==1){ - s->avctx->pix_fmt= AV_PIX_FMT_YUV420P; - }else if(s->chroma_h_shift == 0 && s->chroma_v_shift==0){ - s->avctx->pix_fmt= AV_PIX_FMT_YUV444P; - }else if(s->chroma_h_shift == 2 && s->chroma_v_shift==2){ - s->avctx->pix_fmt= AV_PIX_FMT_YUV410P; + if (s->colorspace_type == 1) { + s->avctx->pix_fmt= AV_PIX_FMT_GRAY8; + s->nb_planes = 1; + } else if(s->colorspace_type == 0) { + s->chroma_h_shift= get_symbol(&s->c, s->header_state, 0); + s->chroma_v_shift= get_symbol(&s->c, s->header_state, 0); + + if(s->chroma_h_shift == 1 && s->chroma_v_shift==1){ + s->avctx->pix_fmt= AV_PIX_FMT_YUV420P; + }else if(s->chroma_h_shift == 0 && s->chroma_v_shift==0){ + s->avctx->pix_fmt= AV_PIX_FMT_YUV444P; + }else if(s->chroma_h_shift == 2 && s->chroma_v_shift==2){ + s->avctx->pix_fmt= AV_PIX_FMT_YUV410P; + } else { + av_log(s, AV_LOG_ERROR, "unsupported color subsample mode %d %d\n", s->chroma_h_shift, s->chroma_v_shift); + s->chroma_h_shift = s->chroma_v_shift = 1; + s->avctx->pix_fmt= AV_PIX_FMT_YUV420P; + return AVERROR_INVALIDDATA; + } + s->nb_planes = 3; } else { - av_log(s, AV_LOG_ERROR, "unsupported color subsample mode %d %d\n", s->chroma_h_shift, s->chroma_v_shift); + av_log(s, AV_LOG_ERROR, "unsupported color space\n"); s->chroma_h_shift = s->chroma_v_shift = 1; s->avctx->pix_fmt= AV_PIX_FMT_YUV420P; return AVERROR_INVALIDDATA; } + s->spatial_scalability= get_rac(&s->c, s->header_state); // s->rate_scalability= get_rac(&s->c, s->header_state); GET_S(s->max_ref_frames, tmp < (unsigned)MAX_REF_FRAMES) @@ -315,7 +326,7 @@ static int decode_header(SnowContext *s){ if(!s->keyframe){ if(get_rac(&s->c, s->header_state)){ - for(plane_index=0; plane_index<2; plane_index++){ + for(plane_index=0; plane_indexnb_planes, 2); plane_index++){ int htaps, i, sum=0; Plane *p= &s->plane[plane_index]; p->diag_mc= get_rac(&s->c, s->header_state); @@ -406,7 +417,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, ff_init_range_decoder(c, buf, buf_size); ff_build_rac_states(c, 0.05*(1LL<<32), 256-8); - s->current_picture.pict_type= AV_PICTURE_TYPE_I; //FIXME I vs. P + s->current_picture->pict_type= AV_PICTURE_TYPE_I; //FIXME I vs. P if(decode_header(s)<0) return -1; if ((res=ff_snow_common_init_after_header(avctx)) < 0) @@ -421,7 +432,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, s->spatial_idwt_buffer)) < 0) return res; - for(plane_index=0; plane_index<3; plane_index++){ + for(plane_index=0; plane_index < s->nb_planes; plane_index++){ Plane *p= &s->plane[plane_index]; p->fast_mc= p->diag_mc && p->htaps==6 && p->hcoeff[0]==40 && p->hcoeff[1]==-10 @@ -439,7 +450,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if ((res = decode_blocks(s)) < 0) return res; - for(plane_index=0; plane_index<3; plane_index++){ + for(plane_index=0; plane_index < s->nb_planes; plane_index++){ Plane *p= &s->plane[plane_index]; int w= p->width; int h= p->height; @@ -452,8 +463,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, for(y=0; ycurrent_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x]; - s->mconly_picture.data[plane_index][y*s->mconly_picture.linesize[plane_index] + x]= v; + int v= s->current_picture->data[plane_index][y*s->current_picture->linesize[plane_index] + x]; + s->mconly_picture->data[plane_index][y*s->mconly_picture->linesize[plane_index] + x]= v; } } } @@ -551,9 +562,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, ff_snow_release_buffer(avctx); if(!(s->avctx->debug&2048)) - av_frame_ref(picture, &s->current_picture); + res = av_frame_ref(picture, s->current_picture); else - av_frame_ref(picture, &s->mconly_picture); + res = av_frame_ref(picture, s->mconly_picture); + + if (res < 0) + return res; *got_frame = 1; @@ -576,6 +590,7 @@ static av_cold int decode_end(AVCodecContext *avctx) AVCodec ff_snow_decoder = { .name = "snow", + .long_name = NULL_IF_CONFIG_SMALL("Snow"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_SNOW, .priv_data_size = sizeof(SnowContext), @@ -583,5 +598,4 @@ AVCodec ff_snow_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/, - .long_name = NULL_IF_CONFIG_SMALL("Snow"), }; diff --git a/ffmpeg/libavcodec/snowenc.c b/ffmpeg/libavcodec/snowenc.c index 7266ee1..5177285 100644 --- a/ffmpeg/libavcodec/snowenc.c +++ b/ffmpeg/libavcodec/snowenc.c @@ -22,7 +22,6 @@ #include "libavutil/log.h" #include "libavutil/opt.h" #include "avcodec.h" -#include "internal.h" #include "dsputil.h" #include "internal.h" #include "snow_dwt.h" @@ -34,126 +33,6 @@ #include "mpegvideo.h" #include "h263.h" -#undef NDEBUG -#include - -#define QUANTIZE2 0 - -#if QUANTIZE2==1 -#define Q2_STEP 8 - -static void find_sse(SnowContext *s, Plane *p, int *score, int score_stride, IDWTELEM *r0, IDWTELEM *r1, int level, int orientation){ - SubBand *b= &p->band[level][orientation]; - int x, y; - int xo=0; - int yo=0; - int step= 1 << (s->spatial_decomposition_count - level); - - if(orientation&1) - xo= step>>1; - if(orientation&2) - yo= step>>1; - - //FIXME bias for nonzero ? - //FIXME optimize - memset(score, 0, sizeof(*score)*score_stride*((p->height + Q2_STEP-1)/Q2_STEP)); - for(y=0; yheight; y++){ - for(x=0; xwidth; x++){ - int sx= (x-xo + step/2) / step / Q2_STEP; - int sy= (y-yo + step/2) / step / Q2_STEP; - int v= r0[x + y*p->width] - r1[x + y*p->width]; - assert(sx>=0 && sy>=0 && sx < score_stride); - v= ((v+8)>>4)<<4; - score[sx + sy*score_stride] += v*v; - assert(score[sx + sy*score_stride] >= 0); - } - } -} - -static void dequantize_all(SnowContext *s, Plane *p, IDWTELEM *buffer, int width, int height){ - int level, orientation; - - for(level=0; levelspatial_decomposition_count; level++){ - for(orientation=level ? 1 : 0; orientation<4; orientation++){ - SubBand *b= &p->band[level][orientation]; - IDWTELEM *dst= buffer + (b->ibuf - s->spatial_idwt_buffer); - - dequantize(s, b, dst, b->stride); - } - } -} - -static void dwt_quantize(SnowContext *s, Plane *p, DWTELEM *buffer, int width, int height, int stride, int type){ - int level, orientation, ys, xs, x, y, pass; - IDWTELEM best_dequant[height * stride]; - IDWTELEM idwt2_buffer[height * stride]; - const int score_stride= (width + 10)/Q2_STEP; - int best_score[(width + 10)/Q2_STEP * (height + 10)/Q2_STEP]; //FIXME size - int score[(width + 10)/Q2_STEP * (height + 10)/Q2_STEP]; //FIXME size - int threshold= (s->m.lambda * s->m.lambda) >> 6; - - //FIXME pass the copy cleanly ? - -// memcpy(dwt_buffer, buffer, height * stride * sizeof(DWTELEM)); - ff_spatial_dwt(buffer, s->temp_dwt_buffer, width, height, stride, type, s->spatial_decomposition_count); - - for(level=0; levelspatial_decomposition_count; level++){ - for(orientation=level ? 1 : 0; orientation<4; orientation++){ - SubBand *b= &p->band[level][orientation]; - IDWTELEM *dst= best_dequant + (b->ibuf - s->spatial_idwt_buffer); - DWTELEM *src= buffer + (b-> buf - s->spatial_dwt_buffer); - assert(src == b->buf); // code does not depend on this but it is true currently - - quantize(s, b, dst, src, b->stride, s->qbias); - } - } - for(pass=0; pass<1; pass++){ - if(s->qbias == 0) //keyframe - continue; - for(level=0; levelspatial_decomposition_count; level++){ - for(orientation=level ? 1 : 0; orientation<4; orientation++){ - SubBand *b= &p->band[level][orientation]; - IDWTELEM *dst= idwt2_buffer + (b->ibuf - s->spatial_idwt_buffer); - IDWTELEM *best_dst= best_dequant + (b->ibuf - s->spatial_idwt_buffer); - - for(ys= 0; ystemp_idwt_buffer, width, height, stride, type, s->spatial_decomposition_count); - find_sse(s, p, best_score, score_stride, idwt2_buffer, s->spatial_idwt_buffer, level, orientation); - memcpy(idwt2_buffer, best_dequant, height * stride * sizeof(IDWTELEM)); - for(y=ys; yheight; y+= Q2_STEP){ - for(x=xs; xwidth; x+= Q2_STEP){ - if(dst[x + y*b->stride]<0) dst[x + y*b->stride]++; - if(dst[x + y*b->stride]>0) dst[x + y*b->stride]--; - //FIXME try more than just -- - } - } - dequantize_all(s, p, idwt2_buffer, width, height); - ff_spatial_idwt(idwt2_buffer, s->temp_idwt_buffer, width, height, stride, type, s->spatial_decomposition_count); - find_sse(s, p, score, score_stride, idwt2_buffer, s->spatial_idwt_buffer, level, orientation); - for(y=ys; yheight; y+= Q2_STEP){ - for(x=xs; xwidth; x+= Q2_STEP){ - int score_idx= x/Q2_STEP + (y/Q2_STEP)*score_stride; - if(score[score_idx] <= best_score[score_idx] + threshold){ - best_score[score_idx]= score[score_idx]; - if(best_dst[x + y*b->stride]<0) best_dst[x + y*b->stride]++; - if(best_dst[x + y*b->stride]>0) best_dst[x + y*b->stride]--; - //FIXME copy instead - } - } - } - } - } - } - } - } - memcpy(s->spatial_idwt_buffer, best_dequant, height * stride * sizeof(IDWTELEM)); //FIXME work with that directly instead of copy at the end -} - -#endif /* QUANTIZE2==1 */ - static av_cold int encode_init(AVCodecContext *avctx) { SnowContext *s = avctx->priv_data; @@ -203,6 +82,9 @@ static av_cold int encode_init(AVCodecContext *avctx) s->m.me.map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t)); s->m.me.score_map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t)); s->m.obmc_scratchpad= av_mallocz(MB_SIZE*MB_SIZE*12*sizeof(uint32_t)); + if (!s->m.me.scratchpad || !s->m.me.map || !s->m.me.score_map || !s->m.obmc_scratchpad) + return AVERROR(ENOMEM); + ff_h263_encode_init(&s->m); //mv_penalty s->max_ref_frames = FFMAX(FFMIN(avctx->refs, MAX_REF_FRAMES), 1); @@ -210,6 +92,9 @@ static av_cold int encode_init(AVCodecContext *avctx) if(avctx->flags&CODEC_FLAG_PASS1){ if(!avctx->stats_out) avctx->stats_out = av_mallocz(256); + + if (!avctx->stats_out) + return AVERROR(ENOMEM); } if((avctx->flags&CODEC_FLAG_PASS2) || !(avctx->flags&CODEC_FLAG_QSCALE)){ if(ff_rate_control_init(&s->m) < 0) @@ -217,16 +102,19 @@ static av_cold int encode_init(AVCodecContext *avctx) } s->pass1_rc= !(avctx->flags & (CODEC_FLAG_QSCALE|CODEC_FLAG_PASS2)); - avctx->coded_frame= &s->current_picture; switch(avctx->pix_fmt){ case AV_PIX_FMT_YUV444P: // case AV_PIX_FMT_YUV422P: case AV_PIX_FMT_YUV420P: -// case AV_PIX_FMT_GRAY8: // case AV_PIX_FMT_YUV411P: case AV_PIX_FMT_YUV410P: + s->nb_planes = 3; s->colorspace_type= 0; break; + case AV_PIX_FMT_GRAY8: + s->nb_planes = 1; + s->colorspace_type = 1; + break; /* case AV_PIX_FMT_RGB32: s->colorspace= 1; break;*/ @@ -239,7 +127,10 @@ static av_cold int encode_init(AVCodecContext *avctx) ff_set_cmp(&s->dsp, s->dsp.me_cmp, s->avctx->me_cmp); ff_set_cmp(&s->dsp, s->dsp.me_sub_cmp, s->avctx->me_sub_cmp); - if ((ret = ff_get_buffer(s->avctx, &s->input_picture, AV_GET_BUFFER_FLAG_REF)) < 0) + s->input_picture = av_frame_alloc(); + if (!s->input_picture) + return AVERROR(ENOMEM); + if ((ret = ff_get_buffer(s->avctx, s->input_picture, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; if(s->avctx->me_method == ME_ITER){ @@ -248,6 +139,8 @@ static av_cold int encode_init(AVCodecContext *avctx) for(i=0; imax_ref_frames; i++){ s->ref_mvs[i]= av_mallocz(size*sizeof(int16_t[2])); s->ref_scores[i]= av_mallocz(size*sizeof(uint32_t)); + if (!s->ref_mvs[i] || !s->ref_scores[i]) + return AVERROR(ENOMEM); } } @@ -347,11 +240,11 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ int pmx, pmy; int mx=0, my=0; int l,cr,cb; - const int stride= s->current_picture.linesize[0]; - const int uvstride= s->current_picture.linesize[1]; - uint8_t *current_data[3]= { s->input_picture.data[0] + (x + y* stride)*block_w, - s->input_picture.data[1] + ((x*block_w)>>s->chroma_h_shift) + ((y*uvstride*block_w)>>s->chroma_v_shift), - s->input_picture.data[2] + ((x*block_w)>>s->chroma_h_shift) + ((y*uvstride*block_w)>>s->chroma_v_shift)}; + const int stride= s->current_picture->linesize[0]; + const int uvstride= s->current_picture->linesize[1]; + uint8_t *current_data[3]= { s->input_picture->data[0] + (x + y* stride)*block_w, + s->input_picture->data[1] + ((x*block_w)>>s->chroma_h_shift) + ((y*uvstride*block_w)>>s->chroma_v_shift), + s->input_picture->data[2] + ((x*block_w)>>s->chroma_h_shift) + ((y*uvstride*block_w)>>s->chroma_v_shift)}; int P[10][2]; int16_t last_mv[3][2]; int qpel= !!(s->avctx->flags & CODEC_FLAG_QPEL); //unused @@ -363,7 +256,7 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ int s_context= 2*left->level + 2*top->level + tl->level + tr->level; int ref, best_ref, ref_score, ref_mx, ref_my; - assert(sizeof(s->block_state) >= 256); + av_assert0(sizeof(s->block_state) >= 256); if(s->keyframe){ set_blocks(s, level, x, y, pl, pcb, pcr, 0, 0, 0, BLOCK_INTRA); return 0; @@ -390,8 +283,8 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ s->m.mb_y= 0; c->skip= 0; - assert(c-> stride == stride); - assert(c->uvstride == uvstride); + av_assert1(c-> stride == stride); + av_assert1(c->uvstride == uvstride); c->penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp); c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp); @@ -425,15 +318,15 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ score= INT_MAX; best_ref= 0; for(ref=0; refref_frames; ref++){ - init_ref(c, current_data, s->last_picture[ref].data, NULL, block_w*x, block_w*y, 0); + init_ref(c, current_data, s->last_picture[ref]->data, NULL, block_w*x, block_w*y, 0); ref_score= ff_epzs_motion_search(&s->m, &ref_mx, &ref_my, P, 0, /*ref_index*/ 0, last_mv, (1<<16)>>shift, level-LOG2_MB_SIZE+4, block_w); - assert(ref_mx >= c->xmin); - assert(ref_mx <= c->xmax); - assert(ref_my >= c->ymin); - assert(ref_my <= c->ymax); + av_assert2(ref_mx >= c->xmin); + av_assert2(ref_mx <= c->xmax); + av_assert2(ref_my >= c->ymin); + av_assert2(ref_my <= c->ymax); ref_score= c->sub_motion_search(&s->m, &ref_mx, &ref_my, ref_score, 0, 0, level-LOG2_MB_SIZE+4, block_w); ref_score= ff_get_mb_score(&s->m, ref_mx, ref_my, 0, 0, level-LOG2_MB_SIZE+4, block_w, 0); @@ -475,13 +368,16 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ l= (sum + block_s/2)/block_s; iscore = pix_norm1(current_data[0], stride, block_w) - 2*l*sum + l*l*block_s; - block_s= block_w*block_w>>(s->chroma_h_shift + s->chroma_v_shift); - sum = pix_sum(current_data[1], uvstride, block_w>>s->chroma_h_shift, block_w>>s->chroma_v_shift); - cb= (sum + block_s/2)/block_s; -// iscore += pix_norm1(¤t_mb[1][0], uvstride, block_w>>1) - 2*cb*sum + cb*cb*block_s; - sum = pix_sum(current_data[2], uvstride, block_w>>s->chroma_h_shift, block_w>>s->chroma_v_shift); - cr= (sum + block_s/2)/block_s; -// iscore += pix_norm1(¤t_mb[2][0], uvstride, block_w>>1) - 2*cr*sum + cr*cr*block_s; + if (s->nb_planes > 2) { + block_s= block_w*block_w>>(s->chroma_h_shift + s->chroma_v_shift); + sum = pix_sum(current_data[1], uvstride, block_w>>s->chroma_h_shift, block_w>>s->chroma_v_shift); + cb= (sum + block_s/2)/block_s; + // iscore += pix_norm1(¤t_mb[1][0], uvstride, block_w>>1) - 2*cb*sum + cb*cb*block_s; + sum = pix_sum(current_data[2], uvstride, block_w>>s->chroma_h_shift, block_w>>s->chroma_v_shift); + cr= (sum + block_s/2)/block_s; + // iscore += pix_norm1(¤t_mb[2][0], uvstride, block_w>>1) - 2*cr*sum + cr*cr*block_s; + }else + cb = cr = 0; ic= s->c; ic.bytestream_start= @@ -491,16 +387,18 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ put_rac(&ic, &i_state[4 + s_context], 1); put_rac(&ic, &i_state[1 + left->type + top->type], 1); put_symbol(&ic, &i_state[32], l-pl , 1); - put_symbol(&ic, &i_state[64], cb-pcb, 1); - put_symbol(&ic, &i_state[96], cr-pcr, 1); + if (s->nb_planes > 2) { + put_symbol(&ic, &i_state[64], cb-pcb, 1); + put_symbol(&ic, &i_state[96], cr-pcr, 1); + } i_len= ic.bytestream - ic.bytestream_start; iscore += (s->lambda2*(get_rac_count(&ic)-base_bits))>>FF_LAMBDA_SHIFT; // assert(score==256*256*256*64-1); - assert(iscore < 255*255*256 + s->lambda2*10); - assert(iscore >= 0); - assert(l>=0 && l<=255); - assert(pl>=0 && pl<=255); + av_assert1(iscore < 255*255*256 + s->lambda2*10); + av_assert1(iscore >= 0); + av_assert1(l>=0 && l<=255); + av_assert1(pl>=0 && pl<=255); if(level==0){ int varc= iscore >> 8; @@ -583,8 +481,10 @@ static void encode_q_branch2(SnowContext *s, int level, int x, int y){ pred_mv(s, &pmx, &pmy, 0, left, top, tr); put_rac(&s->c, &s->block_state[1 + (left->type&1) + (top->type&1)], 1); put_symbol(&s->c, &s->block_state[32], b->color[0]-pl , 1); - put_symbol(&s->c, &s->block_state[64], b->color[1]-pcb, 1); - put_symbol(&s->c, &s->block_state[96], b->color[2]-pcr, 1); + if (s->nb_planes > 2) { + put_symbol(&s->c, &s->block_state[64], b->color[1]-pcb, 1); + put_symbol(&s->c, &s->block_state[96], b->color[2]-pcr, 1); + } set_blocks(s, level, x, y, b->color[0], b->color[1], b->color[2], pmx, pmy, 0, BLOCK_INTRA); }else{ pred_mv(s, &pmx, &pmy, b->ref, left, top, tr); @@ -605,8 +505,8 @@ static int get_dc(SnowContext *s, int mb_x, int mb_y, int plane_index){ const int block_h = plane_index ? block_size>>s->chroma_v_shift : block_size; const uint8_t *obmc = plane_index ? ff_obmc_tab[s->block_max_depth+s->chroma_h_shift] : ff_obmc_tab[s->block_max_depth]; const int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size; - const int ref_stride= s->current_picture.linesize[plane_index]; - uint8_t *src= s-> input_picture.data[plane_index]; + const int ref_stride= s->current_picture->linesize[plane_index]; + uint8_t *src= s-> input_picture->data[plane_index]; IDWTELEM *dst= (IDWTELEM*)s->m.obmc_scratchpad + plane_index*block_size*block_size*4; //FIXME change to unsigned const int b_stride = s->b_width << s->block_max_depth; const int w= p->width; @@ -699,9 +599,9 @@ static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, uin const int block_w = plane_index ? block_size>>s->chroma_h_shift : block_size; const int block_h = plane_index ? block_size>>s->chroma_v_shift : block_size; const int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size; - const int ref_stride= s->current_picture.linesize[plane_index]; - uint8_t *dst= s->current_picture.data[plane_index]; - uint8_t *src= s-> input_picture.data[plane_index]; + const int ref_stride= s->current_picture->linesize[plane_index]; + uint8_t *dst= s->current_picture->data[plane_index]; + uint8_t *src= s-> input_picture->data[plane_index]; IDWTELEM *pred= (IDWTELEM*)s->m.obmc_scratchpad + plane_index*block_size*block_size*4; uint8_t *cur = s->scratchbuf; uint8_t *tmp = s->emu_edge_buffer; @@ -776,7 +676,7 @@ static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, uin } } }else{ - assert(block_w==8); + av_assert2(block_w==8); distortion = s->dsp.me_cmp[0](&s->m, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, block_w*2); } @@ -802,9 +702,9 @@ static int get_4block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index){ const int block_h = plane_index ? block_size>>s->chroma_v_shift : block_size; const uint8_t *obmc = plane_index ? ff_obmc_tab[s->block_max_depth+s->chroma_h_shift] : ff_obmc_tab[s->block_max_depth]; const int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size; - const int ref_stride= s->current_picture.linesize[plane_index]; - uint8_t *dst= s->current_picture.data[plane_index]; - uint8_t *src= s-> input_picture.data[plane_index]; + const int ref_stride= s->current_picture->linesize[plane_index]; + uint8_t *dst= s->current_picture->data[plane_index]; + uint8_t *src= s-> input_picture->data[plane_index]; //FIXME zero_dst is const but add_yblock changes dst if add is 0 (this is never the case for dst=zero_dst // const has only been removed from zero_dst to suppress a warning static IDWTELEM zero_dst[4096]; //FIXME @@ -840,7 +740,7 @@ static int get_4block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index){ memcpy(dst + w + y2*ref_stride, src + w + y2*ref_stride, x+block_w - w); } - assert(block_w== 8 || block_w==16); + av_assert1(block_w== 8 || block_w==16); distortion += s->dsp.me_cmp[block_w==8](&s->m, src + x + y*ref_stride, dst + x + y*ref_stride, ref_stride, block_h); } @@ -963,10 +863,10 @@ static int encode_subband_c0run(SnowContext *s, SubBand *b, const IDWTELEM *src, if(run_index <= max_index) put_symbol2(&s->c, b->state[1], run, 3); - assert(v); + av_assert2(v); }else{ run--; - assert(!v); + av_assert2(!v); } } if(v){ @@ -997,8 +897,8 @@ static av_always_inline int check_block(SnowContext *s, int mb_x, int mb_y, int unsigned value; int rd, index; - assert(mb_x>=0 && mb_y>=0); - assert(mb_x=0 && mb_y>=0); + av_assert2(mb_xcolor[0] = p[0]; @@ -1051,9 +951,9 @@ static av_always_inline int check_4block_inter(SnowContext *s, int mb_x, int mb_ backup[2] = block[b_stride]; backup[3] = block[b_stride + 1]; - assert(mb_x>=0 && mb_y>=0); - assert(mb_x=0 && mb_y>=0); + av_assert2(mb_xme_cache_generation + (p0>>10) + (p1<<6) + (block->ref<<12); @@ -1158,9 +1058,9 @@ static void iterative_me(SnowContext *s){ //skip stuff outside the picture if(mb_x==0 || mb_y==0 || mb_x==b_width-1 || mb_y==b_height-1){ - uint8_t *src= s-> input_picture.data[0]; - uint8_t *dst= s->current_picture.data[0]; - const int stride= s->current_picture.linesize[0]; + uint8_t *src= s-> input_picture->data[0]; + uint8_t *dst= s->current_picture->data[0]; + const int stride= s->current_picture->linesize[0]; const int block_w= MB_SIZE >> s->block_max_depth; const int block_h= MB_SIZE >> s->block_max_depth; const int sx= block_w*mb_x - block_w/2; @@ -1184,7 +1084,7 @@ static void iterative_me(SnowContext *s){ } // intra(black) = neighbors' contribution to the current block - for(i=0; i<3; i++) + for(i=0; i < s->nb_planes; i++) color[i]= get_dc(s, mb_x, mb_y, i); // get previous score (cannot be cached due to OBMC) @@ -1462,7 +1362,7 @@ static void correlate(SnowContext *s, SubBand *b, IDWTELEM *src, int stride, int static void encode_qlogs(SnowContext *s){ int plane_index, level, orientation; - for(plane_index=0; plane_index<2; plane_index++){ + for(plane_index=0; plane_indexnb_planes, 2); plane_index++){ for(level=0; levelspatial_decomposition_count; level++){ for(orientation=level ? 1:0; orientation<4; orientation++){ if(orientation==2) continue; @@ -1500,8 +1400,10 @@ static void encode_header(SnowContext *s){ put_symbol(&s->c, s->header_state, s->temporal_decomposition_count, 0); put_symbol(&s->c, s->header_state, s->spatial_decomposition_count, 0); put_symbol(&s->c, s->header_state, s->colorspace_type, 0); - put_symbol(&s->c, s->header_state, s->chroma_h_shift, 0); - put_symbol(&s->c, s->header_state, s->chroma_v_shift, 0); + if (s->nb_planes > 2) { + put_symbol(&s->c, s->header_state, s->chroma_h_shift, 0); + put_symbol(&s->c, s->header_state, s->chroma_v_shift, 0); + } put_rac(&s->c, s->header_state, s->spatial_scalability); // put_rac(&s->c, s->header_state, s->rate_scalability); put_symbol(&s->c, s->header_state, s->max_ref_frames-1, 0); @@ -1511,7 +1413,7 @@ static void encode_header(SnowContext *s){ if(!s->keyframe){ int update_mc=0; - for(plane_index=0; plane_index<2; plane_index++){ + for(plane_index=0; plane_indexnb_planes, 2); plane_index++){ Plane *p= &s->plane[plane_index]; update_mc |= p->last_htaps != p->htaps; update_mc |= p->last_diag_mc != p->diag_mc; @@ -1519,7 +1421,7 @@ static void encode_header(SnowContext *s){ } put_rac(&s->c, s->header_state, update_mc); if(update_mc){ - for(plane_index=0; plane_index<2; plane_index++){ + for(plane_index=0; plane_indexnb_planes, 2); plane_index++){ Plane *p= &s->plane[plane_index]; put_rac(&s->c, s->header_state, p->diag_mc); put_symbol(&s->c, s->header_state, p->htaps/2-1, 0); @@ -1601,7 +1503,7 @@ static int ratecontrol_1pass(SnowContext *s, AVFrame *pict) /* ugly, ratecontrol just takes a sqrt again */ coef_sum = (uint64_t)coef_sum * coef_sum >> 16; - assert(coef_sum < INT_MAX); + av_assert0(coef_sum < INT_MAX); if(pict->pict_type == AV_PICTURE_TYPE_I){ s->m.current_picture.mb_var_sum= coef_sum; @@ -1647,11 +1549,11 @@ static void calculate_visual_weight(SnowContext *s, Plane *p){ } static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, - const AVFrame *pict, int *got_packet) + AVFrame *pict, int *got_packet) { SnowContext *s = avctx->priv_data; RangeCoder * const c= &s->c; - AVFrame *pic = &s->new_picture; + AVFrame *pic = pict; const int width= s->avctx->width; const int height= s->avctx->height; int level, orientation, plane_index, i, y, ret; @@ -1664,21 +1566,21 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, ff_init_range_encoder(c, pkt->data, pkt->size); ff_build_rac_states(c, 0.05*(1LL<<32), 256-8); - for(i=0; i<3; i++){ + for(i=0; i < s->nb_planes; i++){ int hshift= i ? s->chroma_h_shift : 0; int vshift= i ? s->chroma_v_shift : 0; for(y=0; y<(height>>vshift); y++) - memcpy(&s->input_picture.data[i][y * s->input_picture.linesize[i]], + memcpy(&s->input_picture->data[i][y * s->input_picture->linesize[i]], &pict->data[i][y * pict->linesize[i]], width>>hshift); - s->dsp.draw_edges(s->input_picture.data[i], s->input_picture.linesize[i], + s->dsp.draw_edges(s->input_picture->data[i], s->input_picture->linesize[i], width >> hshift, height >> vshift, EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift, EDGE_TOP | EDGE_BOTTOM); } emms_c(); - s->new_picture = *pict; + s->new_picture = pict; s->m.picture_number= avctx->frame_number; if(avctx->flags&CODEC_FLAG_PASS2){ @@ -1706,6 +1608,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, }//else keep previous frame's qlog until after motion estimation ff_snow_frame_start(s); + avctx->coded_frame= s->current_picture; s->m.current_picture_ptr= &s->m.current_picture; s->m.last_picture.f.pts = s->m.current_picture.f.pts; @@ -1713,21 +1616,21 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, if(pic->pict_type == AV_PICTURE_TYPE_P){ int block_width = (width +15)>>4; int block_height= (height+15)>>4; - int stride= s->current_picture.linesize[0]; + int stride= s->current_picture->linesize[0]; - assert(s->current_picture.data[0]); - assert(s->last_picture[0].data[0]); + av_assert0(s->current_picture->data[0]); + av_assert0(s->last_picture[0]->data[0]); s->m.avctx= s->avctx; - s->m.current_picture.f.data[0] = s->current_picture.data[0]; - s->m. last_picture.f.data[0] = s->last_picture[0].data[0]; - s->m. new_picture.f.data[0] = s-> input_picture.data[0]; + s->m.current_picture.f.data[0] = s->current_picture->data[0]; + s->m. last_picture.f.data[0] = s->last_picture[0]->data[0]; + s->m. new_picture.f.data[0] = s-> input_picture->data[0]; s->m. last_picture_ptr= &s->m. last_picture; s->m.linesize= s->m. last_picture.f.linesize[0] = s->m. new_picture.f.linesize[0] = s->m.current_picture.f.linesize[0] = stride; - s->m.uvlinesize= s->current_picture.linesize[1]; + s->m.uvlinesize= s->current_picture->linesize[1]; s->m.width = width; s->m.height= height; s->m.mb_width = block_width; @@ -1770,13 +1673,18 @@ redo_frame: || !(height>>(s->chroma_v_shift + s->spatial_decomposition_count))) s->spatial_decomposition_count--; + if (s->spatial_decomposition_count <= 0) { + av_log(avctx, AV_LOG_ERROR, "Resolution too low\n"); + return AVERROR(EINVAL); + } + s->m.pict_type = pic->pict_type; s->qbias = pic->pict_type == AV_PICTURE_TYPE_P ? 2 : 0; ff_snow_common_init_after_header(avctx); if(s->last_spatial_decomposition_count != s->spatial_decomposition_count){ - for(plane_index=0; plane_index<3; plane_index++){ + for(plane_index=0; plane_index < s->nb_planes; plane_index++){ calculate_visual_weight(s, &s->plane[plane_index]); } } @@ -1786,7 +1694,7 @@ redo_frame: encode_blocks(s, 1); s->m.mv_bits = 8*(s->c.bytestream - s->c.bytestream_start) - s->m.misc_bits; - for(plane_index=0; plane_index<3; plane_index++){ + for(plane_index=0; plane_index < s->nb_planes; plane_index++){ Plane *p= &s->plane[plane_index]; int w= p->width; int h= p->height; @@ -1811,7 +1719,7 @@ redo_frame: ff_build_rac_states(c, 0.05*(1LL<<32), 256-8); pic->pict_type= AV_PICTURE_TYPE_I; s->keyframe=1; - s->current_picture.key_frame=1; + s->current_picture->key_frame=1; goto redo_frame; } @@ -1829,10 +1737,7 @@ redo_frame: } } - /* if(QUANTIZE2) - dwt_quantize(s, p, s->spatial_dwt_buffer, w, h, w, s->spatial_decomposition_type); - else*/ - ff_spatial_dwt(s->spatial_dwt_buffer, s->temp_dwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count); + ff_spatial_dwt(s->spatial_dwt_buffer, s->temp_dwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count); if(s->pass1_rc && plane_index==0){ int delta_qlog = ratecontrol_1pass(s, pic); @@ -1852,13 +1757,12 @@ redo_frame: for(orientation=level ? 1 : 0; orientation<4; orientation++){ SubBand *b= &p->band[level][orientation]; - if(!QUANTIZE2) - quantize(s, b, b->ibuf, b->buf, b->stride, s->qbias); + quantize(s, b, b->ibuf, b->buf, b->stride, s->qbias); if(orientation==0) decorrelate(s, b, b->ibuf, b->stride, pic->pict_type == AV_PICTURE_TYPE_P, 0); if (!s->no_bitstream) encode_subband(s, b, b->ibuf, b->parent ? b->parent->ibuf : NULL, b->stride, orientation); - assert(b->parent==NULL || b->parent->stride == b->stride*2); + av_assert0(b->parent==NULL || b->parent->stride == b->stride*2); if(orientation==0) correlate(s, b, b->ibuf, b->stride, 1, 0); } @@ -1886,7 +1790,7 @@ redo_frame: if(pic->pict_type == AV_PICTURE_TYPE_I){ for(y=0; ycurrent_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x]= + s->current_picture->data[plane_index][y*s->current_picture->linesize[plane_index] + x]= pict->data[plane_index][y*pict->linesize[plane_index] + x]; } } @@ -1901,12 +1805,12 @@ redo_frame: if(pict->data[plane_index]) //FIXME gray hack for(y=0; ycurrent_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x] - pict->data[plane_index][y*pict->linesize[plane_index] + x]; + int d= s->current_picture->data[plane_index][y*s->current_picture->linesize[plane_index] + x] - pict->data[plane_index][y*pict->linesize[plane_index] + x]; error += d*d; } } s->avctx->error[plane_index] += error; - s->current_picture.error[plane_index] = error; + s->current_picture->error[plane_index] = error; } } @@ -1915,9 +1819,9 @@ redo_frame: ff_snow_release_buffer(avctx); - s->current_picture.coded_picture_number = avctx->frame_number; - s->current_picture.pict_type = pict->pict_type; - s->current_picture.quality = pict->quality; + s->current_picture->coded_picture_number = avctx->frame_number; + s->current_picture->pict_type = pict->pict_type; + s->current_picture->quality = pict->quality; s->m.frame_bits = 8*(s->c.bytestream - s->c.bytestream_start); s->m.p_tex_bits = s->m.frame_bits - s->m.misc_bits - s->m.mv_bits; s->m.current_picture.f.display_picture_number = @@ -1950,7 +1854,8 @@ static av_cold int encode_end(AVCodecContext *avctx) SnowContext *s = avctx->priv_data; ff_snow_common_end(s); - av_frame_unref(&s->input_picture); + ff_rate_control_uninit(&s->m); + av_frame_free(&s->input_picture); av_free(avctx->stats_out); return 0; @@ -1973,6 +1878,7 @@ static const AVClass snowenc_class = { AVCodec ff_snow_encoder = { .name = "snow", + .long_name = NULL_IF_CONFIG_SMALL("Snow"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_SNOW, .priv_data_size = sizeof(SnowContext), @@ -1981,9 +1887,9 @@ AVCodec ff_snow_encoder = { .close = encode_end, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Snow"), .priv_class = &snowenc_class, }; diff --git a/ffmpeg/libavcodec/sonic.c b/ffmpeg/libavcodec/sonic.c index fe9f01f..a5e573a 100644 --- a/ffmpeg/libavcodec/sonic.c +++ b/ffmpeg/libavcodec/sonic.c @@ -22,6 +22,8 @@ #include "get_bits.h" #include "golomb.h" #include "internal.h" +#include "rangecoder.h" + /** * @file @@ -45,7 +47,8 @@ #define RIGHT_SIDE 2 typedef struct SonicContext { - AVFrame frame; + int version; + int minor_version; int lossless, decorrelation; int num_taps, downsampling; @@ -76,14 +79,6 @@ typedef struct SonicContext { #define BASE_QUANT 0.6 #define RATE_VARIATION 3.0 -static inline int divide(int a, int b) -{ - if (a < 0) - return -( (-a + b/2)/b ); - else - return (a + b/2)/b; -} - static inline int shift(int a,int b) { return (a+(1<<(b-1))) >> b; @@ -91,10 +86,97 @@ static inline int shift(int a,int b) static inline int shift_down(int a,int b) { - return (a>>b)+((a<0)?1:0); + return (a>>b)+(a<0); +} + +static av_always_inline av_flatten void put_symbol(RangeCoder *c, uint8_t *state, int v, int is_signed, uint64_t rc_stat[256][2], uint64_t rc_stat2[32][2]){ + int i; + +#define put_rac(C,S,B) \ +do{\ + if(rc_stat){\ + rc_stat[*(S)][B]++;\ + rc_stat2[(S)-state][B]++;\ + }\ + put_rac(C,S,B);\ +}while(0) + + if(v){ + const int a= FFABS(v); + const int e= av_log2(a); + put_rac(c, state+0, 0); + if(e<=9){ + for(i=0; i=0; i--){ + put_rac(c, state+22+i, (a>>i)&1); //22..31 + } + + if(is_signed) + put_rac(c, state+11 + e, v < 0); //11..21 + }else{ + for(i=0; i=0; i--){ + put_rac(c, state+22+FFMIN(i,9), (a>>i)&1); //22..31 + } + + if(is_signed) + put_rac(c, state+11 + 10, v < 0); //11..21 + } + }else{ + put_rac(c, state+0, 1); + } +#undef put_rac +} + +static inline av_flatten int get_symbol(RangeCoder *c, uint8_t *state, int is_signed){ + if(get_rac(c, state+0)) + return 0; + else{ + int i, e, a; + e= 0; + while(get_rac(c, state+1 + FFMIN(e,9))){ //1..10 + e++; + } + + a= 1; + for(i=e-1; i>=0; i--){ + a += a + get_rac(c, state+22 + FFMIN(i,9)); //22..31 + } + + e= -(is_signed && get_rac(c, state+11 + FFMIN(e, 10))); //11..21 + return (a^e)-e; + } } #if 1 +static inline int intlist_write(RangeCoder *c, uint8_t *state, int *buf, int entries, int base_2_part) +{ + int i; + + for (i = 0; i < entries; i++) + put_symbol(c, state, buf[i], 1, NULL, NULL); + + return 1; +} + +static inline int intlist_read(RangeCoder *c, uint8_t *state, int *buf, int entries, int base_2_part) +{ + int i; + + for (i = 0; i < entries; i++) + buf[i] = get_symbol(c, state, 1); + + return 1; +} +#elif 1 static inline int intlist_write(PutBitContext *pb, int *buf, int entries, int base_2_part) { int i; @@ -173,9 +255,9 @@ static int intlist_write(PutBitContext *pb, int *buf, int entries, int base_2_pa int step = 256, pos = 0, dominant = 0, any = 0; int *copy, *bits; - copy = av_mallocz(4* entries); + copy = av_calloc(entries, sizeof(*copy)); if (!copy) - return -1; + return AVERROR(ENOMEM); if (base_2_part) { @@ -199,11 +281,11 @@ static int intlist_write(PutBitContext *pb, int *buf, int entries, int base_2_pa max = abs(copy[i]); } - bits = av_mallocz(4* entries*max); + bits = av_calloc(entries*max, sizeof(*bits)); if (!bits) { -// av_free(copy); - return -1; + av_free(copy); + return AVERROR(ENOMEM); } for (i = 0; i <= max; i++) @@ -258,8 +340,8 @@ static int intlist_write(PutBitContext *pb, int *buf, int entries, int base_2_pa if (buf[i]) put_bits(pb, 1, buf[i] < 0); -// av_free(bits); -// av_free(copy); + av_free(bits); + av_free(copy); return 0; } @@ -269,10 +351,10 @@ static int intlist_read(GetBitContext *gb, int *buf, int entries, int base_2_par int i, low_bits = 0, x = 0; int n_zeros = 0, step = 256, dominant = 0; int pos = 0, level = 0; - int *bits = av_mallocz(4* entries); + int *bits = av_calloc(entries, sizeof(*bits)); if (!bits) - return -1; + return AVERROR(ENOMEM); if (base_2_part) { @@ -350,7 +432,7 @@ static int intlist_read(GetBitContext *gb, int *buf, int entries, int base_2_par pos++; } -// av_free(bits); + av_free(bits); // read signs for (i = 0; i < entries; i++) @@ -419,7 +501,7 @@ static void modified_levinson_durbin(int *window, int window_entries, int *out, int out_entries, int channels, int *tap_quant) { int i; - int *state = av_mallocz(4* window_entries); + int *state = av_calloc(window_entries, sizeof(*state)); memcpy(state, window, 4* window_entries); @@ -428,18 +510,21 @@ static void modified_levinson_durbin(int *window, int window_entries, int step = (i+1)*channels, k, j; double xx = 0.0, xy = 0.0; #if 1 - int *x_ptr = &(window[step]), *state_ptr = &(state[0]); + int *x_ptr = &(window[step]); + int *state_ptr = &(state[0]); j = window_entries - step; - for (;j>=0;j--,x_ptr++,state_ptr++) + for (;j>0;j--,x_ptr++,state_ptr++) { - double x_value = *x_ptr, state_value = *state_ptr; + double x_value = *x_ptr; + double state_value = *state_ptr; xx += state_value*state_value; xy += x_value*state_value; } #else for (j = 0; j <= (window_entries - step); j++); { - double stepval = window[step+j], stateval = window[j]; + double stepval = window[step+j]; + double stateval = window[j]; // xx += (double)window[j]*(double)window[j]; // xy += (double)window[step+j]*(double)window[j]; xx += stateval*stateval; @@ -463,16 +548,18 @@ static void modified_levinson_durbin(int *window, int window_entries, x_ptr = &(window[step]); state_ptr = &(state[0]); j = window_entries - step; - for (;j>=0;j--,x_ptr++,state_ptr++) + for (;j>0;j--,x_ptr++,state_ptr++) { - int x_value = *x_ptr, state_value = *state_ptr; + int x_value = *x_ptr; + int state_value = *state_ptr; *x_ptr = x_value + shift_down(k*state_value,LATTICE_SHIFT); *state_ptr = state_value + shift_down(k*x_value, LATTICE_SHIFT); } #else for (j=0; j <= (window_entries - step); j++) { - int stepval = window[step+j], stateval=state[j]; + int stepval = window[step+j]; + int stateval=state[j]; window[step+j] += shift_down(k * stateval, LATTICE_SHIFT); state[j] += shift_down(k * stepval, LATTICE_SHIFT); } @@ -496,23 +583,27 @@ static inline int code_samplerate(int samplerate) case 16000: return 7; case 8000: return 8; } - return -1; + return AVERROR(EINVAL); } static av_cold int sonic_encode_init(AVCodecContext *avctx) { SonicContext *s = avctx->priv_data; PutBitContext pb; - int i, version = 0; + int i; + + s->version = 2; if (avctx->channels > MAX_CHANNELS) { av_log(avctx, AV_LOG_ERROR, "Only mono and stereo streams are supported by now\n"); - return -1; /* only stereo or mono for now */ + return AVERROR(EINVAL); /* only stereo or mono for now */ } if (avctx->channels == 2) s->decorrelation = MID_SIDE; + else + s->decorrelation = 3; if (avctx->codec->id == AV_CODEC_ID_SONIC_LS) { @@ -529,55 +620,57 @@ static av_cold int sonic_encode_init(AVCodecContext *avctx) } // max tap 2048 - if ((s->num_taps < 32) || (s->num_taps > 1024) || - ((s->num_taps>>5)<<5 != s->num_taps)) - { + if (s->num_taps < 32 || s->num_taps > 1024 || s->num_taps % 32) { av_log(avctx, AV_LOG_ERROR, "Invalid number of taps\n"); - return -1; + return AVERROR_INVALIDDATA; } // generate taps - s->tap_quant = av_mallocz(4* s->num_taps); + s->tap_quant = av_calloc(s->num_taps, sizeof(*s->tap_quant)); for (i = 0; i < s->num_taps; i++) - s->tap_quant[i] = (int)(sqrt(i+1)); + s->tap_quant[i] = ff_sqrt(i+1); s->channels = avctx->channels; s->samplerate = avctx->sample_rate; - s->block_align = (int)(2048.0*s->samplerate/44100)/s->downsampling; + s->block_align = 2048LL*s->samplerate/(44100*s->downsampling); s->frame_size = s->channels*s->block_align*s->downsampling; s->tail_size = s->num_taps*s->channels; - s->tail = av_mallocz(4 * s->tail_size); + s->tail = av_calloc(s->tail_size, sizeof(*s->tail)); if (!s->tail) - return -1; + return AVERROR(ENOMEM); - s->predictor_k = av_mallocz(4 * s->num_taps); + s->predictor_k = av_calloc(s->num_taps, sizeof(*s->predictor_k) ); if (!s->predictor_k) - return -1; + return AVERROR(ENOMEM); for (i = 0; i < s->channels; i++) { - s->coded_samples[i] = av_mallocz(4* s->block_align); + s->coded_samples[i] = av_calloc(s->block_align, sizeof(**s->coded_samples)); if (!s->coded_samples[i]) - return -1; + return AVERROR(ENOMEM); } - s->int_samples = av_mallocz(4* s->frame_size); + s->int_samples = av_calloc(s->frame_size, sizeof(*s->int_samples)); s->window_size = ((2*s->tail_size)+s->frame_size); - s->window = av_mallocz(4* s->window_size); + s->window = av_calloc(s->window_size, sizeof(*s->window)); if (!s->window) - return -1; + return AVERROR(ENOMEM); avctx->extradata = av_mallocz(16); if (!avctx->extradata) - return -1; + return AVERROR(ENOMEM); init_put_bits(&pb, avctx->extradata, 16*8); - put_bits(&pb, 2, version); // version - if (version == 1) + put_bits(&pb, 2, s->version); // version + if (s->version >= 1) { + if (s->version >= 2) { + put_bits(&pb, 8, s->version); + put_bits(&pb, 8, s->minor_version); + } put_bits(&pb, 2, s->channels); put_bits(&pb, 4, code_samplerate(s->samplerate)); } @@ -592,13 +685,9 @@ static av_cold int sonic_encode_init(AVCodecContext *avctx) flush_put_bits(&pb); avctx->extradata_size = put_bits_count(&pb)/8; - av_log(avctx, AV_LOG_INFO, "Sonic: ver: %d ls: %d dr: %d taps: %d block: %d frame: %d downsamp: %d\n", - version, s->lossless, s->decorrelation, s->num_taps, s->block_align, s->frame_size, s->downsampling); + av_log(avctx, AV_LOG_INFO, "Sonic: ver: %d.%d ls: %d dr: %d taps: %d block: %d frame: %d downsamp: %d\n", + s->version, s->minor_version, s->lossless, s->decorrelation, s->num_taps, s->block_align, s->frame_size, s->downsampling); - avctx->coded_frame = avcodec_alloc_frame(); - if (!avctx->coded_frame) - return AVERROR(ENOMEM); - avctx->coded_frame->key_frame = 1; avctx->frame_size = s->block_align*s->downsampling; return 0; @@ -609,16 +698,14 @@ static av_cold int sonic_encode_close(AVCodecContext *avctx) SonicContext *s = avctx->priv_data; int i; - av_freep(&avctx->coded_frame); - for (i = 0; i < s->channels; i++) - av_free(s->coded_samples[i]); + av_freep(&s->coded_samples[i]); - av_free(s->predictor_k); - av_free(s->tail); - av_free(s->tap_quant); - av_free(s->window); - av_free(s->int_samples); + av_freep(&s->predictor_k); + av_freep(&s->tail); + av_freep(&s->tap_quant); + av_freep(&s->window); + av_freep(&s->int_samples); return 0; } @@ -627,15 +714,18 @@ static int sonic_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr) { SonicContext *s = avctx->priv_data; - PutBitContext pb; + RangeCoder c; int i, j, ch, quant = 0, x = 0; int ret; const short *samples = (const int16_t*)frame->data[0]; + uint8_t state[32]; if ((ret = ff_alloc_packet2(avctx, avpkt, s->frame_size * 5 + 1000)) < 0) return ret; - init_put_bits(&pb, avpkt->data, avpkt->size); + ff_init_range_encoder(&c, avpkt->data, avpkt->size); + ff_build_rac_states(&c, 0.05*(1LL<<32), 256-8); + memset(state, 128, sizeof(state)); // short -> internal for (i = 0; i < s->frame_size; i++) @@ -681,8 +771,8 @@ static int sonic_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, // generate taps modified_levinson_durbin(s->window, s->window_size, s->predictor_k, s->num_taps, s->channels, s->tap_quant); - if (intlist_write(&pb, s->predictor_k, s->num_taps, 0) < 0) - return -1; + if ((ret = intlist_write(&c, state, s->predictor_k, s->num_taps, 0)) < 0) + return ret; for (ch = 0; ch < s->channels; ch++) { @@ -711,7 +801,7 @@ static int sonic_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, } energy2 = sqrt(energy2/(s->channels*s->block_align)); - energy1 = sqrt(2.0)*energy1/(s->channels*s->block_align); + energy1 = M_SQRT2*energy1/(s->channels*s->block_align); // increase bitrate when samples are like a gaussian distribution // reduce bitrate when samples are like a two-tailed exponential distribution @@ -722,12 +812,9 @@ static int sonic_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, quant = (int)(BASE_QUANT*s->quantization*energy2/SAMPLE_FACTOR); // av_log(avctx, AV_LOG_DEBUG, "quant: %d energy: %f / %f\n", quant, energy1, energy2); - if (quant < 1) - quant = 1; - if (quant > 65534) - quant = 65534; + quant = av_clip(quant, 1, 65534); - set_ue_golomb(&pb, quant); + put_symbol(&c, state, quant, 0, NULL, NULL); quant *= SAMPLE_FACTOR; } @@ -737,18 +824,18 @@ static int sonic_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, { if (!s->lossless) for (i = 0; i < s->block_align; i++) - s->coded_samples[ch][i] = divide(s->coded_samples[ch][i], quant); + s->coded_samples[ch][i] = ROUNDED_DIV(s->coded_samples[ch][i], quant); - if (intlist_write(&pb, s->coded_samples[ch], s->block_align, 1) < 0) - return -1; + if ((ret = intlist_write(&c, state, s->coded_samples[ch], s->block_align, 1)) < 0) + return ret; } // av_log(avctx, AV_LOG_DEBUG, "used bytes: %d\n", (put_bits_count(&pb)+7)/8); - flush_put_bits(&pb); - avpkt->size = (put_bits_count(&pb)+7)/8; + avpkt->size = ff_rac_terminate(&c); *got_packet_ptr = 1; return 0; + } #endif /* CONFIG_SONIC_ENCODER || CONFIG_SONIC_LS_ENCODER */ @@ -760,30 +847,31 @@ static av_cold int sonic_decode_init(AVCodecContext *avctx) { SonicContext *s = avctx->priv_data; GetBitContext gb; - int i, version; + int i; s->channels = avctx->channels; s->samplerate = avctx->sample_rate; - avcodec_get_frame_defaults(&s->frame); - avctx->coded_frame = &s->frame; - if (!avctx->extradata) { av_log(avctx, AV_LOG_ERROR, "No mandatory headers present\n"); - return -1; + return AVERROR_INVALIDDATA; } - init_get_bits(&gb, avctx->extradata, avctx->extradata_size); + init_get_bits8(&gb, avctx->extradata, avctx->extradata_size); - version = get_bits(&gb, 2); - if (version > 1) + s->version = get_bits(&gb, 2); + if (s->version >= 2) { + s->version = get_bits(&gb, 8); + s->minor_version = get_bits(&gb, 8); + } + if (s->version != 2) { av_log(avctx, AV_LOG_ERROR, "Unsupported Sonic version, please report\n"); - return -1; + return AVERROR_INVALIDDATA; } - if (version == 1) + if (s->version >= 1) { s->channels = get_bits(&gb, 2); s->samplerate = samplerate_table[get_bits(&gb, 4)]; @@ -794,13 +882,17 @@ static av_cold int sonic_decode_init(AVCodecContext *avctx) if (s->channels > MAX_CHANNELS) { av_log(avctx, AV_LOG_ERROR, "Only mono and stereo streams are supported by now\n"); - return -1; + return AVERROR_INVALIDDATA; } s->lossless = get_bits1(&gb); if (!s->lossless) skip_bits(&gb, 3); // XXX FIXME s->decorrelation = get_bits(&gb, 2); + if (s->decorrelation != 3 && s->channels != 2) { + av_log(avctx, AV_LOG_ERROR, "invalid decorrelation %d\n", s->decorrelation); + return AVERROR_INVALIDDATA; + } s->downsampling = get_bits(&gb, 2); if (!s->downsampling) { @@ -812,34 +904,34 @@ static av_cold int sonic_decode_init(AVCodecContext *avctx) if (get_bits1(&gb)) // XXX FIXME av_log(avctx, AV_LOG_INFO, "Custom quant table\n"); - s->block_align = (int)(2048.0*s->samplerate/44100)/s->downsampling; + s->block_align = 2048LL*s->samplerate/(44100*s->downsampling); s->frame_size = s->channels*s->block_align*s->downsampling; // avctx->frame_size = s->block_align; - av_log(avctx, AV_LOG_INFO, "Sonic: ver: %d ls: %d dr: %d taps: %d block: %d frame: %d downsamp: %d\n", - version, s->lossless, s->decorrelation, s->num_taps, s->block_align, s->frame_size, s->downsampling); + av_log(avctx, AV_LOG_INFO, "Sonic: ver: %d.%d ls: %d dr: %d taps: %d block: %d frame: %d downsamp: %d\n", + s->version, s->minor_version, s->lossless, s->decorrelation, s->num_taps, s->block_align, s->frame_size, s->downsampling); // generate taps - s->tap_quant = av_mallocz(4* s->num_taps); + s->tap_quant = av_calloc(s->num_taps, sizeof(*s->tap_quant)); for (i = 0; i < s->num_taps; i++) - s->tap_quant[i] = (int)(sqrt(i+1)); + s->tap_quant[i] = ff_sqrt(i+1); - s->predictor_k = av_mallocz(4* s->num_taps); + s->predictor_k = av_calloc(s->num_taps, sizeof(*s->predictor_k)); for (i = 0; i < s->channels; i++) { - s->predictor_state[i] = av_mallocz(4* s->num_taps); + s->predictor_state[i] = av_calloc(s->num_taps, sizeof(**s->predictor_state)); if (!s->predictor_state[i]) - return -1; + return AVERROR(ENOMEM); } for (i = 0; i < s->channels; i++) { - s->coded_samples[i] = av_mallocz(4* s->block_align); + s->coded_samples[i] = av_calloc(s->block_align, sizeof(**s->coded_samples)); if (!s->coded_samples[i]) - return -1; + return AVERROR(ENOMEM); } - s->int_samples = av_mallocz(4* s->frame_size); + s->int_samples = av_calloc(s->frame_size, sizeof(*s->int_samples)); avctx->sample_fmt = AV_SAMPLE_FMT_S16; return 0; @@ -850,14 +942,14 @@ static av_cold int sonic_decode_close(AVCodecContext *avctx) SonicContext *s = avctx->priv_data; int i; - av_free(s->int_samples); - av_free(s->tap_quant); - av_free(s->predictor_k); + av_freep(&s->int_samples); + av_freep(&s->tap_quant); + av_freep(&s->predictor_k); for (i = 0; i < s->channels; i++) { - av_free(s->predictor_state[i]); - av_free(s->coded_samples[i]); + av_freep(&s->predictor_state[i]); + av_freep(&s->coded_samples[i]); } return 0; @@ -870,22 +962,26 @@ static int sonic_decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; SonicContext *s = avctx->priv_data; - GetBitContext gb; + RangeCoder c; + uint8_t state[32]; int i, quant, ch, j, ret; int16_t *samples; + AVFrame *frame = data; if (buf_size == 0) return 0; - s->frame.nb_samples = s->frame_size; - if ((ret = ff_get_buffer(avctx, &s->frame, 0)) < 0) + frame->nb_samples = s->frame_size / avctx->channels; + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; - samples = (int16_t *)s->frame.data[0]; + samples = (int16_t *)frame->data[0]; // av_log(NULL, AV_LOG_INFO, "buf_size: %d\n", buf_size); - init_get_bits(&gb, buf, buf_size*8); + memset(state, 128, sizeof(state)); + ff_init_range_decoder(&c, buf, buf_size); + ff_build_rac_states(&c, 0.05*(1LL<<32), 256-8); - intlist_read(&gb, s->predictor_k, s->num_taps, 0); + intlist_read(&c, state, s->predictor_k, s->num_taps, 0); // dequantize for (i = 0; i < s->num_taps; i++) @@ -894,7 +990,7 @@ static int sonic_decode_frame(AVCodecContext *avctx, if (s->lossless) quant = 1; else - quant = get_ue_golomb(&gb) * SAMPLE_FACTOR; + quant = get_symbol(&c, state, 0) * SAMPLE_FACTOR; // av_log(NULL, AV_LOG_INFO, "quant: %d\n", quant); @@ -904,7 +1000,7 @@ static int sonic_decode_frame(AVCodecContext *avctx, predictor_init_state(s->predictor_k, s->predictor_state[ch], s->num_taps); - intlist_read(&gb, s->coded_samples[ch], s->block_align, 1); + intlist_read(&c, state, s->coded_samples[ch], s->block_align, 1); for (i = 0; i < s->block_align; i++) { @@ -949,16 +1045,14 @@ static int sonic_decode_frame(AVCodecContext *avctx, for (i = 0; i < s->frame_size; i++) samples[i] = av_clip_int16(s->int_samples[i]); - align_get_bits(&gb); - *got_frame_ptr = 1; - *(AVFrame*)data = s->frame; - return (get_bits_count(&gb)+7)/8; + return buf_size; } AVCodec ff_sonic_decoder = { .name = "sonic", + .long_name = NULL_IF_CONFIG_SMALL("Sonic"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_SONIC, .priv_data_size = sizeof(SonicContext), @@ -966,34 +1060,35 @@ AVCodec ff_sonic_decoder = { .close = sonic_decode_close, .decode = sonic_decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_EXPERIMENTAL, - .long_name = NULL_IF_CONFIG_SMALL("Sonic"), }; #endif /* CONFIG_SONIC_DECODER */ #if CONFIG_SONIC_ENCODER AVCodec ff_sonic_encoder = { .name = "sonic", + .long_name = NULL_IF_CONFIG_SMALL("Sonic"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_SONIC, .priv_data_size = sizeof(SonicContext), .init = sonic_encode_init, .encode2 = sonic_encode_frame, + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, .capabilities = CODEC_CAP_EXPERIMENTAL, .close = sonic_encode_close, - .long_name = NULL_IF_CONFIG_SMALL("Sonic"), }; #endif #if CONFIG_SONIC_LS_ENCODER AVCodec ff_sonic_ls_encoder = { .name = "sonicls", + .long_name = NULL_IF_CONFIG_SMALL("Sonic lossless"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_SONIC_LS, .priv_data_size = sizeof(SonicContext), .init = sonic_encode_init, .encode2 = sonic_encode_frame, + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, .capabilities = CODEC_CAP_EXPERIMENTAL, .close = sonic_encode_close, - .long_name = NULL_IF_CONFIG_SMALL("Sonic lossless"), }; #endif diff --git a/ffmpeg/libavcodec/sp5xdec.c b/ffmpeg/libavcodec/sp5xdec.c index b083015..81f3c24 100644 --- a/ffmpeg/libavcodec/sp5xdec.c +++ b/ffmpeg/libavcodec/sp5xdec.c @@ -96,6 +96,7 @@ static int sp5x_decode_frame(AVCodecContext *avctx, #if CONFIG_SP5X_DECODER AVCodec ff_sp5x_decoder = { .name = "sp5x", + .long_name = NULL_IF_CONFIG_SMALL("Sunplus JPEG (SP5X)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_SP5X, .priv_data_size = sizeof(MJpegDecodeContext), @@ -104,18 +105,17 @@ AVCodec ff_sp5x_decoder = { .decode = sp5x_decode_frame, .capabilities = CODEC_CAP_DR1, .max_lowres = 3, - .long_name = NULL_IF_CONFIG_SMALL("Sunplus JPEG (SP5X)"), }; #endif #if CONFIG_AMV_DECODER AVCodec ff_amv_decoder = { .name = "amv", + .long_name = NULL_IF_CONFIG_SMALL("AMV Video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_AMV, .priv_data_size = sizeof(MJpegDecodeContext), .init = ff_mjpeg_decode_init, .close = ff_mjpeg_decode_end, .decode = sp5x_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("AMV Video"), }; #endif diff --git a/ffmpeg/libavcodec/sparc/dsputil_vis.c b/ffmpeg/libavcodec/sparc/dsputil_vis.c index 9c3494b..414d6ca 100644 --- a/ffmpeg/libavcodec/sparc/dsputil_vis.c +++ b/ffmpeg/libavcodec/sparc/dsputil_vis.c @@ -18,33 +18,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -/* The *no_round* functions have been added by James A. Morrison, 2003,2004. - The vis code from libmpeg2 was adapted for libavcodec by James A. Morrison. - */ - -#include "config.h" - -#include - #include "libavutil/attributes.h" #include "libavcodec/dsputil.h" -#include "libavutil/mem.h" #include "dsputil_vis.h" - #include "vis.h" -#define ACCEL_SPARC_VIS 1 -#define ACCEL_SPARC_VIS2 2 - -static int vis_level(void) -{ - int accel = 0; - accel |= ACCEL_SPARC_VIS; - accel |= ACCEL_SPARC_VIS2; - return accel; -} - -/* libavcodec initialization code */ av_cold void ff_dsputil_init_vis(DSPContext *c, AVCodecContext *avctx) { /* VIS-specific optimizations */ diff --git a/ffmpeg/libavcodec/sparc/hpeldsp_vis.c b/ffmpeg/libavcodec/sparc/hpeldsp_vis.c index da2d47e..be2a85d 100644 --- a/ffmpeg/libavcodec/sparc/hpeldsp_vis.c +++ b/ffmpeg/libavcodec/sparc/hpeldsp_vis.c @@ -22,13 +22,12 @@ The vis code from libmpeg2 was adapted for libavcodec by James A. Morrison. */ -#include "config.h" +#include +#include -#include - -#include "libavcodec/hpeldsp.h" +#include "libavutil/attributes.h" #include "libavutil/mem.h" - +#include "libavcodec/hpeldsp.h" #include "vis.h" /* The trick used in some of this file is the formula from the MMX @@ -3481,19 +3480,7 @@ static void MC_avg_no_round_xy_16_vis (uint8_t * dest, const uint8_t * ref, /* End of no rounding code */ -#define ACCEL_SPARC_VIS 1 -#define ACCEL_SPARC_VIS2 2 - -static int vis_level(void) -{ - int accel = 0; - accel |= ACCEL_SPARC_VIS; - accel |= ACCEL_SPARC_VIS2; - return accel; -} - -/* libavcodec initialization code */ -void ff_hpeldsp_init_vis(HpelDSPContext* c, int flags) +av_cold void ff_hpeldsp_init_vis(HpelDSPContext *c, int flags) { /* VIS-specific optimizations */ int accel = vis_level (); diff --git a/ffmpeg/libavcodec/sparc/vis.h b/ffmpeg/libavcodec/sparc/vis.h index adee91b..107ff96 100644 --- a/ffmpeg/libavcodec/sparc/vis.h +++ b/ffmpeg/libavcodec/sparc/vis.h @@ -42,6 +42,17 @@ #ifndef AVCODEC_SPARC_VIS_H #define AVCODEC_SPARC_VIS_H +#define ACCEL_SPARC_VIS 1 +#define ACCEL_SPARC_VIS2 2 + +static inline int vis_level(void) +{ + int accel = 0; + accel |= ACCEL_SPARC_VIS; + accel |= ACCEL_SPARC_VIS2; + return accel; +} + #define vis_opc_base ((0x1 << 31) | (0x36 << 19)) #define vis_opf(X) ((X) << 5) #define vis_sreg(X) (X) @@ -139,12 +150,9 @@ #define vis_m2r_2(op,mem1,mem2,rd) \ __asm__ volatile (#op "\t[%0 + %1], %%f" #rd : : "r" (mem1), "r" (mem2) ) -static inline void vis_set_gsr(unsigned int _val) +static inline void vis_set_gsr(unsigned int val) { - register unsigned int val __asm__("g1"); - - val = _val; - __asm__ volatile(".word 0xa7804000" + __asm__ volatile("mov %0,%%asr19" : : "r" (val)); } @@ -162,32 +170,6 @@ static inline void vis_set_gsr(unsigned int _val) #define vis_st64(rs1,mem) vis_r2m(std, rs1, mem) #define vis_st64_2(rs1,mem1,mem2) vis_r2m_2(std, rs1, mem1, mem2) -#define vis_ldblk(mem, rd) \ -do { register void *__mem __asm__("g1"); \ - __mem = &(mem); \ - __asm__ volatile(".word 0xc1985e00 | %1" \ - : \ - : "r" (__mem), \ - "i" (vis_rd_d(rd)) \ - : "memory"); \ -} while (0) - -#define vis_stblk(rd, mem) \ -do { register void *__mem __asm__("g1"); \ - __mem = &(mem); \ - __asm__ volatile(".word 0xc1b85e00 | %1" \ - : \ - : "r" (__mem), \ - "i" (vis_rd_d(rd)) \ - : "memory"); \ -} while (0) - -#define vis_membar_storestore() \ - __asm__ volatile(".word 0x8143e008" : : : "memory") - -#define vis_membar_sync() \ - __asm__ volatile(".word 0x8143e040" : : : "memory") - /* 16 and 32 bit partitioned addition and subtraction. The normal * versions perform 4 16-bit or 2 32-bit additions or subtractions. * The 's' versions perform 2 16-bit or 1 32-bit additions or @@ -223,68 +205,19 @@ do { register void *__mem __asm__("g1"); \ /* Alignment instructions. */ -static inline const void *vis_alignaddr(const void *_ptr) +static inline const void *vis_alignaddr(const void *ptr) { - register const void *ptr __asm__("g1"); - - ptr = _ptr; - - __asm__ volatile(".word %2" + __asm__ volatile("alignaddr %0, %%g0, %0" : "=&r" (ptr) - : "0" (ptr), - "i" (vis_opc_base | vis_opf(0x18) | - vis_rs1_s(1) | - vis_rs2_s(0) | - vis_rd_s(1))); + : "0" (ptr)); return ptr; } -static inline void vis_alignaddr_g0(void *_ptr) +static inline void vis_alignaddr_g0(void *ptr) { - register void *ptr __asm__("g1"); - - ptr = _ptr; - - __asm__ volatile(".word %2" - : "=&r" (ptr) - : "0" (ptr), - "i" (vis_opc_base | vis_opf(0x18) | - vis_rs1_s(1) | - vis_rs2_s(0) | - vis_rd_s(0))); -} - -static inline void *vis_alignaddrl(void *_ptr) -{ - register void *ptr __asm__("g1"); - - ptr = _ptr; - - __asm__ volatile(".word %2" - : "=&r" (ptr) - : "0" (ptr), - "i" (vis_opc_base | vis_opf(0x19) | - vis_rs1_s(1) | - vis_rs2_s(0) | - vis_rd_s(1))); - - return ptr; -} - -static inline void vis_alignaddrl_g0(void *_ptr) -{ - register void *ptr __asm__("g1"); - - ptr = _ptr; - - __asm__ volatile(".word %2" - : "=&r" (ptr) - : "0" (ptr), - "i" (vis_opc_base | vis_opf(0x19) | - vis_rs1_s(1) | - vis_rs2_s(0) | - vis_rd_s(0))); + __asm__ volatile("alignaddr %0, %%g0, %%g0" + : : "r" (ptr)); } #define vis_faligndata(rs1,rs2,rd) vis_dd2d(0x48, rs1, rs2, rd) diff --git a/ffmpeg/libavcodec/srtdec.c b/ffmpeg/libavcodec/srtdec.c index 267561c..b16645a 100644 --- a/ffmpeg/libavcodec/srtdec.c +++ b/ffmpeg/libavcodec/srtdec.c @@ -204,7 +204,8 @@ static const char *read_ts(const char *buf, int *ts_start, int *ts_end, "%*[ ]X1:%u X2:%u Y1:%u Y2:%u", &hs, &ms, &ss, ts_start, &he, &me, &se, ts_end, x1, x2, y1, y2); - buf += strcspn(buf, "\n") + 1; + buf += strcspn(buf, "\n"); + buf += !!*buf; if (c >= 8) { *ts_start = 100*(ss + 60*(ms + 60*hs)) + *ts_start/10; *ts_end = 100*(se + 60*(me + 60*he)) + *ts_end /10; diff --git a/ffmpeg/libavcodec/srtenc.c b/ffmpeg/libavcodec/srtenc.c index 3036a7f..89c26dc 100644 --- a/ffmpeg/libavcodec/srtenc.c +++ b/ffmpeg/libavcodec/srtenc.c @@ -22,6 +22,7 @@ #include #include "avcodec.h" #include "libavutil/avstring.h" +#include "libavutil/bprint.h" #include "ass_split.h" #include "ass.h" @@ -31,10 +32,8 @@ typedef struct { AVCodecContext *avctx; ASSSplitContext *ass_ctx; - char buffer[2048]; - char *ptr; - char *end; - char *dialog_start; + AVBPrint buffer; + unsigned timestamp_end; int count; char stack[SRT_STACK_SIZE]; int stack_ptr; @@ -49,7 +48,7 @@ static void srt_print(SRTContext *s, const char *str, ...) { va_list vargs; va_start(vargs, str); - s->ptr += vsnprintf(s->ptr, s->end - s->ptr, str, vargs); + av_vbprintf(&s->buffer, str, vargs); va_end(vargs); } @@ -138,14 +137,14 @@ static av_cold int srt_encode_init(AVCodecContext *avctx) SRTContext *s = avctx->priv_data; s->avctx = avctx; s->ass_ctx = ff_ass_split(avctx->subtitle_header); + av_bprint_init(&s->buffer, 0, AV_BPRINT_SIZE_UNLIMITED); return s->ass_ctx ? 0 : AVERROR_INVALIDDATA; } static void srt_text_cb(void *priv, const char *text, int len) { SRTContext *s = priv; - av_strlcpy(s->ptr, text, FFMIN(s->end-s->ptr, len+1)); - s->ptr += len; + av_bprint_append_data(&s->buffer, text, len); } static void srt_new_line_cb(void *priv, int forced) @@ -208,11 +207,19 @@ static void srt_move_cb(void *priv, int x1, int y1, int x2, int y2, char buffer[32]; int len = snprintf(buffer, sizeof(buffer), " X1:%03u X2:%03u Y1:%03u Y2:%03u", x1, x2, y1, y2); - if (s->end - s->ptr > len) { - memmove(s->dialog_start+len, s->dialog_start, s->ptr-s->dialog_start+1); - memcpy(s->dialog_start, buffer, len); - s->ptr += len; + unsigned char *dummy; + unsigned room; + + av_bprint_get_buffer(&s->buffer, len, &dummy, &room); + if (room >= len) { + memmove(s->buffer.str + s->timestamp_end + len, + s->buffer.str + s->timestamp_end, + s->buffer.len - s->timestamp_end + 1); + memcpy(s->buffer.str + s->timestamp_end, buffer, len); } + /* Increment even if av_bprint_get_buffer() did not return enough room: + the bprint structure will be treated as truncated. */ + s->buffer.len += len; } } @@ -243,10 +250,9 @@ static int srt_encode_frame(AVCodecContext *avctx, { SRTContext *s = avctx->priv_data; ASSDialog *dialog; - int i, len, num; + int i, num; - s->ptr = s->buffer; - s->end = s->ptr + sizeof(s->buffer); + av_bprint_clear(&s->buffer); for (i=0; inum_rects; i++) { @@ -268,7 +274,7 @@ static int srt_encode_frame(AVCodecContext *avctx, es = ec/ 1000; ec -= 1000*es; srt_print(s,"%d\r\n%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\r\n", ++s->count, sh, sm, ss, sc, eh, em, es, ec); - s->dialog_start = s->ptr - 2; + s->timestamp_end = s->buffer.len - 2; } s->alignment_applied = 0; srt_style_apply(s, dialog->style); @@ -276,23 +282,25 @@ static int srt_encode_frame(AVCodecContext *avctx, } } - if (s->ptr == s->buffer) + if (!av_bprint_is_complete(&s->buffer)) + return AVERROR(ENOMEM); + if (!s->buffer.len) return 0; - len = av_strlcpy(buf, s->buffer, bufsize); - - if (len > bufsize-1) { + if (s->buffer.len > bufsize) { av_log(avctx, AV_LOG_ERROR, "Buffer too small for ASS event.\n"); return -1; } + memcpy(buf, s->buffer.str, s->buffer.len); - return len; + return s->buffer.len; } static int srt_encode_close(AVCodecContext *avctx) { SRTContext *s = avctx->priv_data; ff_ass_split_free(s->ass_ctx); + av_bprint_finalize(&s->buffer, NULL); return 0; } diff --git a/ffmpeg/libavcodec/sunrast.c b/ffmpeg/libavcodec/sunrast.c index 1e25b60..d9918f4 100644 --- a/ffmpeg/libavcodec/sunrast.c +++ b/ffmpeg/libavcodec/sunrast.c @@ -61,10 +61,6 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_ERROR, "invalid (compression) type\n"); return AVERROR_INVALIDDATA; } - if (av_image_check_size(w, h, 0, avctx)) { - av_log(avctx, AV_LOG_ERROR, "invalid image size\n"); - return AVERROR_INVALIDDATA; - } if (maptype == RMT_RAW) { avpriv_request_sample(avctx, "Unknown colormap type"); return AVERROR_PATCHWELCOME; @@ -100,8 +96,10 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } - if (w != avctx->width || h != avctx->height) - avcodec_set_dimensions(avctx, w, h); + ret = ff_set_dimensions(avctx, w, h); + if (ret < 0) + return ret; + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) return ret; @@ -209,9 +207,9 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, AVCodec ff_sunrast_decoder = { .name = "sunrast", + .long_name = NULL_IF_CONFIG_SMALL("Sun Rasterfile image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_SUNRAST, .decode = sunrast_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Sun Rasterfile image"), }; diff --git a/ffmpeg/libavcodec/sunrast.h b/ffmpeg/libavcodec/sunrast.h index d9fe307..d162e63 100644 --- a/ffmpeg/libavcodec/sunrast.h +++ b/ffmpeg/libavcodec/sunrast.h @@ -2,20 +2,20 @@ * Sun Rasterfile Image Format * Copyright (c) 2007, 2008 Ivo van Poorten * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/sunrastenc.c b/ffmpeg/libavcodec/sunrastenc.c index 2c7e72f..a55e3d4 100644 --- a/ffmpeg/libavcodec/sunrastenc.c +++ b/ffmpeg/libavcodec/sunrastenc.c @@ -2,20 +2,20 @@ * Sun Rasterfile (.sun/.ras/im{1,8,24}/.sunras) image encoder * Copyright (c) 2012 Aneesh Dogra (lionaneesh) * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -25,7 +25,6 @@ #include "sunrast.h" typedef struct SUNRASTContext { - AVFrame picture; PutByteContext p; int depth; ///< depth of pixel int length; ///< length (bytes) of image @@ -149,9 +148,6 @@ static av_cold int sunrast_encode_init(AVCodecContext *avctx) return AVERROR(EINVAL); } - avctx->coded_frame = &s->picture; - avctx->coded_frame->key_frame = 1; - avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; s->maptype = RMT_NONE; s->maplength = 0; @@ -202,6 +198,12 @@ static int sunrast_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, return 0; } +static av_cold int sunrast_encode_close(AVCodecContext *avctx) +{ + av_frame_free(&avctx->coded_frame); + return 0; +} + static const AVCodecDefault sunrast_defaults[] = { { "coder", "rle" }, { NULL }, @@ -209,10 +211,12 @@ static const AVCodecDefault sunrast_defaults[] = { AVCodec ff_sunrast_encoder = { .name = "sunrast", + .long_name = NULL_IF_CONFIG_SMALL("Sun Rasterfile image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_SUNRAST, .priv_data_size = sizeof(SUNRASTContext), .init = sunrast_encode_init, + .close = sunrast_encode_close, .encode2 = sunrast_encode_frame, .defaults = sunrast_defaults, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, @@ -220,5 +224,4 @@ AVCodec ff_sunrast_encoder = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_MONOWHITE, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Sun Rasterfile image"), }; diff --git a/ffmpeg/libavcodec/svq1dec.c b/ffmpeg/libavcodec/svq1dec.c index c71b361..1e7ab49 100644 --- a/ffmpeg/libavcodec/svq1dec.c +++ b/ffmpeg/libavcodec/svq1dec.c @@ -34,6 +34,7 @@ #include "avcodec.h" #include "get_bits.h" +#include "h263.h" #include "hpeldsp.h" #include "internal.h" #include "mathops.h" @@ -42,8 +43,6 @@ #undef NDEBUG #include -extern const uint8_t ff_mvtab[33][2]; - static VLC svq1_block_type; static VLC svq1_motion_component; static VLC svq1_intra_multistage[6]; @@ -321,7 +320,8 @@ static void svq1_skip_block(uint8_t *current, uint8_t *previous, static int svq1_motion_inter_block(HpelDSPContext *hdsp, GetBitContext *bitbuf, uint8_t *current, uint8_t *previous, - int pitch, svq1_pmv *motion, int x, int y) + int pitch, svq1_pmv *motion, int x, int y, + int width, int height) { uint8_t *src; uint8_t *dst; @@ -350,10 +350,8 @@ static int svq1_motion_inter_block(HpelDSPContext *hdsp, GetBitContext *bitbuf, motion[x / 8 + 2].y = motion[x / 8 + 3].y = mv.y; - if (y + (mv.y >> 1) < 0) - mv.y = 0; - if (x + (mv.x >> 1) < 0) - mv.x = 0; + mv.x = av_clip(mv.x, -2 * x, 2 * (width - x - 16)); + mv.y = av_clip(mv.y, -2 * y, 2 * (height - y - 16)); src = &previous[(x + (mv.x >> 1)) + (y + (mv.y >> 1)) * pitch]; dst = current; @@ -365,7 +363,8 @@ static int svq1_motion_inter_block(HpelDSPContext *hdsp, GetBitContext *bitbuf, static int svq1_motion_inter_4v_block(HpelDSPContext *hdsp, GetBitContext *bitbuf, uint8_t *current, uint8_t *previous, - int pitch, svq1_pmv *motion, int x, int y) + int pitch, svq1_pmv *motion, int x, int y, + int width, int height) { uint8_t *src; uint8_t *dst; @@ -421,10 +420,8 @@ static int svq1_motion_inter_4v_block(HpelDSPContext *hdsp, GetBitContext *bitbu int mvy = pmv[i]->y + (i >> 1) * 16; // FIXME: clipping or padding? - if (y + (mvy >> 1) < 0) - mvy = 0; - if (x + (mvx >> 1) < 0) - mvx = 0; + mvx = av_clip(mvx, -2 * x, 2 * (width - x - 8)); + mvy = av_clip(mvy, -2 * y, 2 * (height - y - 8)); src = &previous[(x + (mvx >> 1)) + (y + (mvy >> 1)) * pitch]; dst = current; @@ -444,7 +441,8 @@ static int svq1_motion_inter_4v_block(HpelDSPContext *hdsp, GetBitContext *bitbu static int svq1_decode_delta_block(AVCodecContext *avctx, HpelDSPContext *hdsp, GetBitContext *bitbuf, uint8_t *current, uint8_t *previous, - int pitch, svq1_pmv *motion, int x, int y) + int pitch, svq1_pmv *motion, int x, int y, + int width, int height) { uint32_t block_type; int result = 0; @@ -469,7 +467,7 @@ static int svq1_decode_delta_block(AVCodecContext *avctx, HpelDSPContext *hdsp, case SVQ1_BLOCK_INTER: result = svq1_motion_inter_block(hdsp, bitbuf, current, previous, - pitch, motion, x, y); + pitch, motion, x, y, width, height); if (result != 0) { av_dlog(avctx, "Error in svq1_motion_inter_block %i\n", result); @@ -480,7 +478,7 @@ static int svq1_decode_delta_block(AVCodecContext *avctx, HpelDSPContext *hdsp, case SVQ1_BLOCK_INTER_4V: result = svq1_motion_inter_4v_block(hdsp, bitbuf, current, previous, - pitch, motion, x, y); + pitch, motion, x, y, width, height); if (result != 0) { av_dlog(avctx, "Error in svq1_motion_inter_4v_block %i\n", result); @@ -556,7 +554,7 @@ static int svq1_decode_frame_header(AVCodecContext *avctx, AVFrame *frame) svq1_parse_string(bitbuf, msg); av_log(avctx, AV_LOG_INFO, - "embedded message: \"%s\"\n", (char *)msg); + "embedded message:\n%s\n", (char *)msg); } skip_bits(bitbuf, 2); @@ -595,8 +593,8 @@ static int svq1_decode_frame_header(AVCodecContext *avctx, AVFrame *frame) skip_bits1(bitbuf); skip_bits(bitbuf, 2); - while (get_bits1(bitbuf)) - skip_bits(bitbuf, 8); + if (skip_1stop_8data_bits(bitbuf) < 0) + return AVERROR_INVALIDDATA; } s->width = width; @@ -616,7 +614,7 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, svq1_pmv *pmv; /* initialize bit buffer */ - init_get_bits(&s->gb, buf, buf_size * 8); + init_get_bits8(&s->gb, buf, buf_size); /* decode frame header */ s->frame_code = get_bits(&s->gb, 22); @@ -640,7 +638,10 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, av_dlog(avctx, "Error in svq1_decode_frame_header %i\n", result); return result; } - avcodec_set_dimensions(avctx, s->width, s->height); + + result = ff_set_dimensions(avctx, s->width, s->height); + if (result < 0) + return result; if ((avctx->skip_frame >= AVDISCARD_NONREF && s->nonref) || (avctx->skip_frame >= AVDISCARD_NONKEY && @@ -689,7 +690,8 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, } else { /* delta frame */ uint8_t *previous = s->prev->data[i]; - if (!previous || s->prev->width != cur->width || s->prev->height != cur->height) { + if (!previous || + s->prev->width != s->width || s->prev->height != s->height) { av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n"); result = AVERROR_INVALIDDATA; goto err; @@ -702,8 +704,8 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, result = svq1_decode_delta_block(avctx, &s->hdsp, &s->gb, ¤t[x], previous, linesize, - pmv, x, y); - if (result) { + pmv, x, y, width, height); + if (result != 0) { av_dlog(avctx, "Error in svq1_decode_delta_block %i\n", result); @@ -740,7 +742,7 @@ static av_cold int svq1_decode_init(AVCodecContext *avctx) int i; int offset = 0; - s->prev = avcodec_alloc_frame(); + s->prev = av_frame_alloc(); if (!s->prev) return AVERROR(ENOMEM); @@ -807,6 +809,7 @@ static void svq1_flush(AVCodecContext *avctx) AVCodec ff_svq1_decoder = { .name = "svq1", + .long_name = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_SVQ1, .priv_data_size = sizeof(SVQ1Context), @@ -817,5 +820,4 @@ AVCodec ff_svq1_decoder = { .flush = svq1_flush, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV410P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1"), }; diff --git a/ffmpeg/libavcodec/svq1enc.c b/ffmpeg/libavcodec/svq1enc.c index cf9157f..2d7e848 100644 --- a/ffmpeg/libavcodec/svq1enc.c +++ b/ffmpeg/libavcodec/svq1enc.c @@ -45,9 +45,8 @@ typedef struct SVQ1Context { AVCodecContext *avctx; DSPContext dsp; HpelDSPContext hdsp; - AVFrame picture; - AVFrame current_picture; - AVFrame last_picture; + AVFrame *current_picture; + AVFrame *last_picture; PutBitContext pb; GetBitContext gb; @@ -264,13 +263,14 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, unsigned char *decoded_plane, int width, int height, int src_stride, int stride) { + const AVFrame *f = s->avctx->coded_frame; int x, y; int i; int block_width, block_height; int level; int threshold[6]; uint8_t *src = s->scratchbuf + stride * 16; - const int lambda = (s->picture.quality * s->picture.quality) >> + const int lambda = (f->quality * f->quality) >> (2 * FF_LAMBDA_SHIFT); /* figure out the acceptable level thresholds in advance */ @@ -281,7 +281,7 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, block_width = (width + 15) / 16; block_height = (height + 15) / 16; - if (s->picture.pict_type == AV_PICTURE_TYPE_P) { + if (f->pict_type == AV_PICTURE_TYPE_P) { s->m.avctx = s->avctx; s->m.current_picture_ptr = &s->m.current_picture; s->m.last_picture_ptr = &s->m.last_picture; @@ -297,13 +297,13 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, s->m.mb_stride = s->m.mb_width + 1; s->m.b8_stride = 2 * s->m.mb_width + 1; s->m.f_code = 1; - s->m.pict_type = s->picture.pict_type; + s->m.pict_type = f->pict_type; s->m.me_method = s->avctx->me_method; s->m.me.scene_change_score = 0; s->m.flags = s->avctx->flags; // s->m.out_format = FMT_H263; // s->m.unrestricted_mv = 1; - s->m.lambda = s->picture.quality; + s->m.lambda = f->quality; s->m.qscale = s->m.lambda * 139 + FF_LAMBDA_SCALE * 64 >> FF_LAMBDA_SHIFT + 7; @@ -396,13 +396,13 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, ff_init_block_index(&s->m); ff_update_block_index(&s->m); - if (s->picture.pict_type == AV_PICTURE_TYPE_I || + if (f->pict_type == AV_PICTURE_TYPE_I || (s->m.mb_type[x + y * s->m.mb_stride] & CANDIDATE_MB_TYPE_INTRA)) { for (i = 0; i < 6; i++) init_put_bits(&s->reorder_pb[i], reorder_buffer[0][i], 7 * 32); - if (s->picture.pict_type == AV_PICTURE_TYPE_P) { + if (f->pict_type == AV_PICTURE_TYPE_P) { const uint8_t *vlc = ff_svq1_block_type_vlc[SVQ1_BLOCK_INTRA]; put_bits(&s->reorder_pb[5], vlc[1], vlc[0]); score[0] = vlc[1] * lambda; @@ -418,7 +418,7 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, best = 0; - if (s->picture.pict_type == AV_PICTURE_TYPE_P) { + if (f->pict_type == AV_PICTURE_TYPE_P) { const uint8_t *vlc = ff_svq1_block_type_vlc[SVQ1_BLOCK_INTER]; int mx, my, pred_x, pred_y, dxy; int16_t *motion_ptr; @@ -447,9 +447,9 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, dxy = (mx & 1) + 2 * (my & 1); s->hdsp.put_pixels_tab[0][dxy](temp + 16, - ref + (mx >> 1) + - stride * (my >> 1), - stride, 16); + ref + (mx >> 1) + + stride * (my >> 1), + stride, 16); score[1] += encode_block(s, src + 16 * x, temp + 16, decoded, stride, 5, 64, lambda, 0); @@ -498,13 +498,48 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, return 0; } +static av_cold int svq1_encode_end(AVCodecContext *avctx) +{ + SVQ1Context *const s = avctx->priv_data; + int i; + + av_log(avctx, AV_LOG_DEBUG, "RD: %f\n", + s->rd_total / (double)(avctx->width * avctx->height * + avctx->frame_number)); + + av_freep(&s->m.me.scratchpad); + av_freep(&s->m.me.map); + av_freep(&s->m.me.score_map); + av_freep(&s->mb_type); + av_freep(&s->dummy); + av_freep(&s->scratchbuf); + + for (i = 0; i < 3; i++) { + av_freep(&s->motion_val8[i]); + av_freep(&s->motion_val16[i]); + } + + av_frame_free(&s->current_picture); + av_frame_free(&s->last_picture); + av_frame_free(&avctx->coded_frame); + + return 0; +} + static av_cold int svq1_encode_init(AVCodecContext *avctx) { SVQ1Context *const s = avctx->priv_data; ff_dsputil_init(&s->dsp, avctx); ff_hpeldsp_init(&s->hdsp, avctx->flags); - avctx->coded_frame = &s->picture; + + avctx->coded_frame = av_frame_alloc(); + s->current_picture = av_frame_alloc(); + s->last_picture = av_frame_alloc(); + if (!avctx->coded_frame || !s->current_picture || !s->last_picture) { + svq1_encode_end(avctx); + return AVERROR(ENOMEM); + } s->frame_width = avctx->width; s->frame_height = avctx->height; @@ -536,8 +571,7 @@ static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { SVQ1Context *const s = avctx->priv_data; - AVFrame *const p = &s->picture; - AVFrame temp; + AVFrame *const p = avctx->coded_frame; int i, ret; if ((ret = ff_alloc_packet2(avctx, pkt, s->y_block_width * s->y_block_height * @@ -549,35 +583,33 @@ static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return -1; } - if (!s->current_picture.data[0]) { - if ((ret = ff_get_buffer(avctx, &s->current_picture, 0))< 0 || - (ret = ff_get_buffer(avctx, &s->last_picture, 0)) < 0) { + if (!s->current_picture->data[0]) { + if ((ret = ff_get_buffer(avctx, s->current_picture, 0))< 0 || + (ret = ff_get_buffer(avctx, s->last_picture, 0)) < 0) { return ret; } - s->scratchbuf = av_malloc(s->current_picture.linesize[0] * 16 * 2); + s->scratchbuf = av_malloc(s->current_picture->linesize[0] * 16 * 2); } - temp = s->current_picture; - s->current_picture = s->last_picture; - s->last_picture = temp; + FFSWAP(AVFrame*, s->current_picture, s->last_picture); init_put_bits(&s->pb, pkt->data, pkt->size); - *p = *pict; p->pict_type = avctx->gop_size && avctx->frame_number % avctx->gop_size ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I; p->key_frame = p->pict_type == AV_PICTURE_TYPE_I; + p->quality = pict->quality; svq1_write_header(s, p->pict_type); for (i = 0; i < 3; i++) if (svq1_encode_plane(s, i, - s->picture.data[i], - s->last_picture.data[i], - s->current_picture.data[i], + pict->data[i], + s->last_picture->data[i], + s->current_picture->data[i], s->frame_width / (i ? 4 : 1), s->frame_height / (i ? 4 : 1), - s->picture.linesize[i], - s->current_picture.linesize[i]) < 0) + pict->linesize[i], + s->current_picture->linesize[i]) < 0) return -1; // avpriv_align_put_bits(&s->pb); @@ -594,35 +626,9 @@ static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return 0; } -static av_cold int svq1_encode_end(AVCodecContext *avctx) -{ - SVQ1Context *const s = avctx->priv_data; - int i; - - av_log(avctx, AV_LOG_DEBUG, "RD: %f\n", - s->rd_total / (double)(avctx->width * avctx->height * - avctx->frame_number)); - - av_freep(&s->m.me.scratchpad); - av_freep(&s->m.me.map); - av_freep(&s->m.me.score_map); - av_freep(&s->mb_type); - av_freep(&s->dummy); - av_freep(&s->scratchbuf); - - for (i = 0; i < 3; i++) { - av_freep(&s->motion_val8[i]); - av_freep(&s->motion_val16[i]); - } - - av_frame_unref(&s->current_picture); - av_frame_unref(&s->last_picture); - - return 0; -} - AVCodec ff_svq1_encoder = { .name = "svq1", + .long_name = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_SVQ1, .priv_data_size = sizeof(SVQ1Context), @@ -631,5 +637,4 @@ AVCodec ff_svq1_encoder = { .close = svq1_encode_end, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV410P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1"), }; diff --git a/ffmpeg/libavcodec/svq3.c b/ffmpeg/libavcodec/svq3.c index 53c4d32..e1d2588 100644 --- a/ffmpeg/libavcodec/svq3.c +++ b/ffmpeg/libavcodec/svq3.c @@ -39,6 +39,8 @@ * correctly decodes this file: * http://samples.mplayerhq.hu/V-codecs/SVQ3/Vertical400kbit.sorenson3.mov */ + +#include "libavutil/attributes.h" #include "internal.h" #include "avcodec.h" #include "mpegvideo.h" @@ -105,6 +107,13 @@ static const uint8_t svq3_scan[16] = { 0 + 3 * 4, 1 + 3 * 4, 2 + 3 * 4, 3 + 3 * 4, }; +static const uint8_t luma_dc_zigzag_scan[16] = { + 0 * 16 + 0 * 64, 1 * 16 + 0 * 64, 2 * 16 + 0 * 64, 0 * 16 + 2 * 64, + 3 * 16 + 0 * 64, 0 * 16 + 1 * 64, 1 * 16 + 1 * 64, 2 * 16 + 1 * 64, + 1 * 16 + 2 * 64, 2 * 16 + 2 * 64, 3 * 16 + 2 * 64, 0 * 16 + 3 * 64, + 3 * 16 + 1 * 64, 1 * 16 + 3 * 64, 2 * 16 + 3 * 64, 3 * 16 + 3 * 64, +}; + static const uint8_t svq3_pred_0[25][2] = { { 0, 0 }, { 1, 0 }, { 0, 1 }, @@ -149,6 +158,8 @@ static const uint32_t svq3_dequant_coeff[32] = { 61694, 68745, 77615, 89113, 100253, 109366, 126635, 141533 }; +static int svq3_decode_end(AVCodecContext *avctx); + void ff_svq3_luma_dc_dequant_idct_c(int16_t *output, int16_t *input, int qp) { const int qmul = svq3_dequant_coeff[qp]; @@ -308,7 +319,8 @@ static inline void svq3_mc_dir_part(SVQ3Context *s, src = pic->f.data[0] + mx + my * h->linesize; if (emu) { - h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src, h->linesize, + h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src, + h->linesize, h->linesize, width + 1, height + 1, mx, my, s->h_edge_pos, s->v_edge_pos); src = h->edge_emu_buffer; @@ -334,7 +346,8 @@ static inline void svq3_mc_dir_part(SVQ3Context *s, src = pic->f.data[i] + mx + my * h->uvlinesize; if (emu) { - h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src, h->uvlinesize, + h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src, + h->uvlinesize, h->uvlinesize, width + 1, height + 1, mx, my, (s->h_edge_pos >> 1), s->v_edge_pos >> 1); @@ -648,9 +661,9 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) dir = i_mb_type_info[mb_type - 8].pred_mode; dir = (dir >> 1) ^ 3 * (dir & 1) ^ 1; - if ((h->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, dir, 0)) == -1) { - av_log(h->avctx, AV_LOG_ERROR, "check_intra_pred_mode = -1\n"); - return -1; + if ((h->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, dir, 0)) < 0) { + av_log(h->avctx, AV_LOG_ERROR, "ff_h264_check_intra_pred_mode < 0\n"); + return h->intra16x16_pred_mode; } cbp = i_mb_type_info[mb_type - 8].cbp; @@ -792,8 +805,8 @@ static int svq3_decode_slice_header(AVCodecContext *avctx) header ^ s->watermark_key); } if (length > 0) { - memcpy((uint8_t *) &h->gb.buffer[get_bits_count(&h->gb) >> 3], - &h->gb.buffer[h->gb.size_in_bits >> 3], length - 1); + memmove((uint8_t *) &h->gb.buffer[get_bits_count(&h->gb) >> 3], + &h->gb.buffer[h->gb.size_in_bits >> 3], length - 1); } skip_bits_long(&h->gb, 0); } @@ -827,8 +840,8 @@ static int svq3_decode_slice_header(AVCodecContext *avctx) skip_bits1(&h->gb); skip_bits(&h->gb, 2); - while (get_bits1(&h->gb)) - skip_bits(&h->gb, 8); + if (skip_1stop_8data_bits(&h->gb) < 0) + return AVERROR_INVALIDDATA; /* reset intra predictors and invalidate motion vector references */ if (h->mb_x > 0) { @@ -857,19 +870,18 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) unsigned char *extradata_end; unsigned int size; int marker_found = 0; + int ret; s->cur_pic = av_mallocz(sizeof(*s->cur_pic)); s->last_pic = av_mallocz(sizeof(*s->last_pic)); s->next_pic = av_mallocz(sizeof(*s->next_pic)); if (!s->next_pic || !s->last_pic || !s->cur_pic) { - av_freep(&s->cur_pic); - av_freep(&s->last_pic); - av_freep(&s->next_pic); - return AVERROR(ENOMEM); + ret = AVERROR(ENOMEM); + goto fail; } - if (ff_h264_decode_init(avctx) < 0) - return -1; + if ((ret = ff_h264_decode_init(avctx)) < 0) + goto fail; ff_hpeldsp_init(&s->hdsp, avctx->flags); h->flags = avctx->flags; @@ -904,8 +916,10 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) int frame_size_code; size = AV_RB32(&extradata[4]); - if (size > extradata_end - extradata - 8) - return AVERROR_INVALIDDATA; + if (size > extradata_end - extradata - 8) { + ret = AVERROR_INVALIDDATA; + goto fail; + } init_get_bits(&gb, extradata + 8, size * 8); /* 'frame size code' and optional 'width, height' */ @@ -959,8 +973,10 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) /* unknown field */ skip_bits1(&gb); - while (get_bits1(&gb)) - skip_bits(&gb, 8); + if (skip_1stop_8data_bits(&gb) < 0) { + ret = AVERROR_INVALIDDATA; + goto fail; + } s->unknown_flag = get_bits1(&gb); avctx->has_b_frames = !h->low_delay; @@ -977,8 +993,11 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) int offset = get_bits_count(&gb) + 7 >> 3; uint8_t *buf; - if (watermark_height <= 0 || (uint64_t)watermark_width*4 > UINT_MAX/watermark_height) - return -1; + if (watermark_height <= 0 || + (uint64_t)watermark_width * 4 > UINT_MAX / watermark_height) { + ret = -1; + goto fail; + } buf = av_malloc(buf_len); av_log(avctx, AV_LOG_DEBUG, "watermark size: %dx%d\n", @@ -991,7 +1010,8 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "could not uncompress watermark logo\n"); av_free(buf); - return -1; + ret = -1; + goto fail; } s->watermark_key = ff_svq1_packet_checksum(buf, buf_len, 0); s->watermark_key = s->watermark_key << 16 | s->watermark_key; @@ -1001,7 +1021,8 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) #else av_log(avctx, AV_LOG_ERROR, "this svq3 file contains watermark which need zlib support compiled in\n"); - return -1; + ret = -1; + goto fail; #endif } } @@ -1016,12 +1037,15 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) s->h_edge_pos = h->mb_width * 16; s->v_edge_pos = h->mb_height * 16; - if (ff_h264_alloc_tables(h) < 0) { + if ((ret = ff_h264_alloc_tables(h)) < 0) { av_log(avctx, AV_LOG_ERROR, "svq3 memory allocation failed\n"); - return AVERROR(ENOMEM); + goto fail; } return 0; +fail: + svq3_decode_end(avctx); + return ret; } static void free_picture(AVCodecContext *avctx, Picture *pic) @@ -1113,8 +1137,7 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, h->mb_x = h->mb_y = h->mb_xy = 0; if (s->watermark_key) { - av_fast_malloc(&s->buf, &s->buf_size, - buf_size+FF_INPUT_BUFFER_PADDING_SIZE); + av_fast_padded_malloc(&s->buf, &s->buf_size, buf_size); if (!s->buf) return AVERROR(ENOMEM); memcpy(s->buf, avpkt->data, buf_size); @@ -1164,6 +1187,7 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, if (h->pict_type != AV_PICTURE_TYPE_I) { if (!s->last_pic->f.data[0]) { av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n"); + av_frame_unref(s->last_pic); ret = get_buffer(avctx, s->last_pic); if (ret < 0) return ret; @@ -1176,6 +1200,7 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, if (h->pict_type == AV_PICTURE_TYPE_B && !s->next_pic->f.data[0]) { av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n"); + av_frame_unref(s->next_pic); ret = get_buffer(avctx, s->next_pic); if (ret < 0) return ret; @@ -1310,7 +1335,7 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, return buf_size; } -static int svq3_decode_end(AVCodecContext *avctx) +static av_cold int svq3_decode_end(AVCodecContext *avctx) { SVQ3Context *s = avctx->priv_data; H264Context *h = &s->h; @@ -1335,6 +1360,7 @@ static int svq3_decode_end(AVCodecContext *avctx) AVCodec ff_svq3_decoder = { .name = "svq3", + .long_name = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 3 / Sorenson Video 3 / SVQ3"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_SVQ3, .priv_data_size = sizeof(SVQ3Context), @@ -1344,7 +1370,6 @@ AVCodec ff_svq3_decoder = { .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_DELAY, - .long_name = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 3 / Sorenson Video 3 / SVQ3"), .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_NONE}, }; diff --git a/ffmpeg/libavcodec/tableprint.h b/ffmpeg/libavcodec/tableprint.h index 1b39dc6..26d063e 100644 --- a/ffmpeg/libavcodec/tableprint.h +++ b/ffmpeg/libavcodec/tableprint.h @@ -71,10 +71,20 @@ void write_uint32_t_2d_array(const void *, int, int); void write_float_2d_array (const void *, int, int); /** @} */ // end of printfuncs group +/* + * MSVC doesn't have %zu, since it was introduced in C99, + * but has its own %Iu for printing size_t values. + */ +#if defined(_MSC_VER) +#define FMT "Iu" +#else +#define FMT "zu" +#endif + #define WRITE_ARRAY(prefix, type, name) \ do { \ const size_t array_size = FF_ARRAY_ELEMS(name); \ - printf(prefix" "#type" "#name"[%zu] = {\n", \ + printf(prefix" "#type" "#name"[%"FMT"] = {\n", \ array_size); \ write_##type##_array(name, array_size); \ printf("};\n"); \ @@ -84,7 +94,7 @@ void write_float_2d_array (const void *, int, int); do { \ const size_t array_size1 = FF_ARRAY_ELEMS(name); \ const size_t array_size2 = FF_ARRAY_ELEMS(name[0]); \ - printf(prefix" "#type" "#name"[%zu][%zu] = {\n", \ + printf(prefix" "#type" "#name"[%"FMT"][%"FMT"] = {\n", \ array_size1, array_size2 ); \ write_##type##_2d_array(name, array_size1, array_size2); \ printf("};\n"); \ diff --git a/ffmpeg/libavcodec/tak.c b/ffmpeg/libavcodec/tak.c index 92dc44c..ed41ca8 100644 --- a/ffmpeg/libavcodec/tak.c +++ b/ffmpeg/libavcodec/tak.c @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "libavutil/bswap.h" #include "libavutil/crc.h" #include "libavutil/intreadwrite.h" #include "tak.h" @@ -73,22 +72,6 @@ static int tak_get_nb_samples(int sample_rate, enum TAKFrameSizeType type) return nb_samples; } -static int crc_init = 0; -#if CONFIG_SMALL -#define CRC_TABLE_SIZE 257 -#else -#define CRC_TABLE_SIZE 1024 -#endif -static AVCRC crc_24[CRC_TABLE_SIZE]; - -av_cold void ff_tak_init_crc(void) -{ - if (!crc_init) { - av_crc_init(crc_24, 0, 24, 0x864CFBU, sizeof(crc_24)); - crc_init = 1; - } -} - int ff_tak_check_crc(const uint8_t *buf, unsigned int buf_size) { uint32_t crc, CRC; @@ -97,8 +80,8 @@ int ff_tak_check_crc(const uint8_t *buf, unsigned int buf_size) return AVERROR_INVALIDDATA; buf_size -= 3; - CRC = av_bswap32(AV_RL24(buf + buf_size)) >> 8; - crc = av_crc(crc_24, 0xCE04B7U, buf, buf_size); + CRC = AV_RB24(buf + buf_size); + crc = av_crc(av_crc_get_table(AV_CRC_24_IEEE), 0xCE04B7U, buf, buf_size); if (CRC != crc) return AVERROR_INVALIDDATA; diff --git a/ffmpeg/libavcodec/tak.h b/ffmpeg/libavcodec/tak.h index 876468d..e8e2dac 100644 --- a/ffmpeg/libavcodec/tak.h +++ b/ffmpeg/libavcodec/tak.h @@ -140,8 +140,6 @@ typedef struct TAKStreamInfo { int64_t samples; } TAKStreamInfo; -void ff_tak_init_crc(void); - int ff_tak_check_crc(const uint8_t *buf, unsigned int buf_size); /** diff --git a/ffmpeg/libavcodec/tak_parser.c b/ffmpeg/libavcodec/tak_parser.c index 0f2fbc2..5d8460c 100644 --- a/ffmpeg/libavcodec/tak_parser.c +++ b/ffmpeg/libavcodec/tak_parser.c @@ -33,12 +33,6 @@ typedef struct TAKParseContext { int index; } TAKParseContext; -static av_cold int tak_init(AVCodecParserContext *s) -{ - ff_tak_init_crc(); - return 0; -} - static int tak_parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size) @@ -90,6 +84,7 @@ static int tak_parse(AVCodecParserContext *s, AVCodecContext *avctx, s->duration = t->ti.last_frame_samples ? t->ti.last_frame_samples : t->ti.frame_samples; + s->key_frame = !!(t->ti.flags & TAK_FRAME_FLAG_HAS_INFO); } else { pc->frame_start_found = 0; next = t->index - pc->index; @@ -122,7 +117,6 @@ found: AVCodecParser ff_tak_parser = { .codec_ids = { AV_CODEC_ID_TAK }, .priv_data_size = sizeof(TAKParseContext), - .parser_init = tak_init, .parser_parse = tak_parse, .parser_close = ff_parse_close, }; diff --git a/ffmpeg/libavcodec/takdec.c b/ffmpeg/libavcodec/takdec.c index 43382f1..fcbe10a 100644 --- a/ffmpeg/libavcodec/takdec.c +++ b/ffmpeg/libavcodec/takdec.c @@ -28,6 +28,7 @@ #include "libavutil/internal.h" #include "libavutil/samplefmt.h" #include "tak.h" +#include "thread.h" #include "avcodec.h" #include "dsputil.h" #include "internal.h" @@ -170,7 +171,6 @@ static av_cold int tak_decode_init(AVCodecContext *avctx) { TAKDecContext *s = avctx->priv_data; - ff_tak_init_crc(); ff_dsputil_init(&s->dsp, avctx); s->avctx = avctx; @@ -468,27 +468,14 @@ static int decode_subframe(TAKDecContext *s, int32_t *decoded, for (i = 0; i < tmp; i++) { int v = 1 << (filter_quant - 1); - if (!(filter_order & 15)) { + if (filter_order & -16) v += s->dsp.scalarproduct_int16(&s->residues[i], s->filter, - filter_order); - } else if (filter_order & 4) { - for (j = 0; j < filter_order; j += 4) { - v += s->residues[i + j + 3] * s->filter[j + 3] + - s->residues[i + j + 2] * s->filter[j + 2] + - s->residues[i + j + 1] * s->filter[j + 1] + - s->residues[i + j ] * s->filter[j ]; - } - } else { - for (j = 0; j < filter_order; j += 8) { - v += s->residues[i + j + 7] * s->filter[j + 7] + - s->residues[i + j + 6] * s->filter[j + 6] + - s->residues[i + j + 5] * s->filter[j + 5] + - s->residues[i + j + 4] * s->filter[j + 4] + - s->residues[i + j + 3] * s->filter[j + 3] + - s->residues[i + j + 2] * s->filter[j + 2] + - s->residues[i + j + 1] * s->filter[j + 1] + - s->residues[i + j ] * s->filter[j ]; - } + filter_order & -16); + for (j = filter_order & -16; j < filter_order; j += 4) { + v += s->residues[i + j + 3] * s->filter[j + 3] + + s->residues[i + j + 2] * s->filter[j + 2] + + s->residues[i + j + 1] * s->filter[j + 1] + + s->residues[i + j ] * s->filter[j ]; } v = (av_clip(v >> filter_quant, -8192, 8191) << dshift) - *decoded; *decoded++ = v; @@ -686,6 +673,7 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, { TAKDecContext *s = avctx->priv_data; AVFrame *frame = data; + ThreadFrame tframe = { .f = data }; GetBitContext *gb = &s->gb; int chan, i, ret, hsize; @@ -698,11 +686,12 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, if ((ret = ff_tak_decode_frame_header(avctx, gb, &s->ti, 0)) < 0) return ret; - if (avctx->err_recognition & AV_EF_CRCCHECK) { + if (avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_COMPLIANT)) { hsize = get_bits_count(gb) / 8; if (ff_tak_check_crc(pkt->data, hsize)) { av_log(avctx, AV_LOG_ERROR, "CRC error\n"); - return AVERROR_INVALIDDATA; + if (avctx->err_recognition & AV_EF_EXPLODE) + return AVERROR_INVALIDDATA; } } @@ -749,8 +738,9 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, : s->ti.frame_samples; frame->nb_samples = s->nb_samples; - if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0) return ret; + ff_thread_finish_setup(avctx); if (avctx->bits_per_raw_sample <= 16) { int buf_size = av_samples_get_buffer_size(NULL, avctx->channels, @@ -872,11 +862,12 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, else if (get_bits_left(gb) > 0) av_log(avctx, AV_LOG_DEBUG, "underread\n"); - if (avctx->err_recognition & AV_EF_CRCCHECK) { + if (avctx->err_recognition & (AV_EF_CRCCHECK | AV_EF_COMPLIANT)) { if (ff_tak_check_crc(pkt->data + hsize, get_bits_count(gb) / 8 - hsize)) { av_log(avctx, AV_LOG_ERROR, "CRC error\n"); - return AVERROR_INVALIDDATA; + if (avctx->err_recognition & AV_EF_EXPLODE) + return AVERROR_INVALIDDATA; } } @@ -912,6 +903,25 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, return pkt->size; } +static int init_thread_copy(AVCodecContext *avctx) +{ + TAKDecContext *s = avctx->priv_data; + s->avctx = avctx; + return 0; +} + +static int update_thread_context(AVCodecContext *dst, + const AVCodecContext *src) +{ + TAKDecContext *tsrc = src->priv_data; + TAKDecContext *tdst = dst->priv_data; + + if (dst == src) + return 0; + memcpy(&tdst->ti, &tsrc->ti, sizeof(TAKStreamInfo)); + return 0; +} + static av_cold int tak_decode_close(AVCodecContext *avctx) { TAKDecContext *s = avctx->priv_data; @@ -923,14 +933,16 @@ static av_cold int tak_decode_close(AVCodecContext *avctx) AVCodec ff_tak_decoder = { .name = "tak", + .long_name = NULL_IF_CONFIG_SMALL("TAK (Tom's lossless Audio Kompressor)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_TAK, .priv_data_size = sizeof(TAKDecContext), .init = tak_decode_init, .close = tak_decode_close, .decode = tak_decode_frame, - .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("TAK (Tom's lossless Audio Kompressor)"), + .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy), + .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context), + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S32P, diff --git a/ffmpeg/libavcodec/targa.c b/ffmpeg/libavcodec/targa.c index ff4390f..b0c9b55 100644 --- a/ffmpeg/libavcodec/targa.c +++ b/ffmpeg/libavcodec/targa.c @@ -173,12 +173,12 @@ static int decode_frame(AVCodecContext *avctx, return AVERROR_INVALIDDATA; } - if ((ret = av_image_check_size(w, h, 0, avctx)) < 0) + if ((ret = ff_set_dimensions(avctx, w, h)) < 0) return ret; - if (w != avctx->width || h != avctx->height) - avcodec_set_dimensions(avctx, w, h); + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) return ret; + p->pict_type = AV_PICTURE_TYPE_I; if (flags & TGA_TOPTOBOTTOM) { dst = p->data[0]; @@ -298,10 +298,10 @@ static int decode_frame(AVCodecContext *avctx, AVCodec ff_targa_decoder = { .name = "targa", + .long_name = NULL_IF_CONFIG_SMALL("Truevision Targa image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_TARGA, .priv_data_size = sizeof(TargaContext), .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Truevision Targa image"), }; diff --git a/ffmpeg/libavcodec/targa_y216dec.c b/ffmpeg/libavcodec/targa_y216dec.c index 38694ce..5f4eeaa 100644 --- a/ffmpeg/libavcodec/targa_y216dec.c +++ b/ffmpeg/libavcodec/targa_y216dec.c @@ -72,19 +72,12 @@ static int y216_decode_frame(AVCodecContext *avctx, void *data, return avpkt->size; } -static av_cold int y216_decode_close(AVCodecContext *avctx) -{ - - return 0; -} - AVCodec ff_targa_y216_decoder = { .name = "targa_y216", + .long_name = NULL_IF_CONFIG_SMALL("Pinnacle TARGA CineWave YUV16"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_TARGA_Y216, .init = y216_decode_init, .decode = y216_decode_frame, - .close = y216_decode_close, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Pinnacle TARGA CineWave YUV16"), }; diff --git a/ffmpeg/libavcodec/targaenc.c b/ffmpeg/libavcodec/targaenc.c index b2c679d..d4483ec 100644 --- a/ffmpeg/libavcodec/targaenc.c +++ b/ffmpeg/libavcodec/targaenc.c @@ -29,10 +29,6 @@ #include "rle.h" #include "targa.h" -typedef struct TargaContext { - AVFrame picture; -} TargaContext; - /** * RLE compress the image, with maximum size of out_size * @param outbuf Output buffer @@ -176,26 +172,32 @@ static int targa_encode_frame(AVCodecContext *avctx, AVPacket *pkt, static av_cold int targa_encode_init(AVCodecContext *avctx) { - TargaContext *s = avctx->priv_data; + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); - avcodec_get_frame_defaults(&s->picture); - s->picture.key_frame= 1; - s->picture.pict_type = AV_PICTURE_TYPE_I; - avctx->coded_frame= &s->picture; + avctx->coded_frame->key_frame = 1; + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; return 0; } +static av_cold int targa_encode_close(AVCodecContext *avctx) +{ + av_frame_free(&avctx->coded_frame); + return 0; +} + AVCodec ff_targa_encoder = { .name = "targa", + .long_name = NULL_IF_CONFIG_SMALL("Truevision Targa image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_TARGA, - .priv_data_size = sizeof(TargaContext), .init = targa_encode_init, + .close = targa_encode_close, .encode2 = targa_encode_frame, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_BGRA, AV_PIX_FMT_RGB555LE, AV_PIX_FMT_GRAY8, AV_PIX_FMT_PAL8, AV_PIX_FMT_NONE }, - .long_name= NULL_IF_CONFIG_SMALL("Truevision Targa image"), }; diff --git a/ffmpeg/libavcodec/textdec.c b/ffmpeg/libavcodec/textdec.c index f3e6117..d904023 100644 --- a/ffmpeg/libavcodec/textdec.c +++ b/ffmpeg/libavcodec/textdec.c @@ -41,59 +41,20 @@ static const AVOption options[] = { { NULL } }; -static int text_event_to_ass(const AVCodecContext *avctx, AVBPrint *buf, - const char *p, const char *p_end) -{ - const TextContext *text = avctx->priv_data; - - for (; p < p_end && *p; p++) { - - /* forced custom line breaks, not accounted as "normal" EOL */ - if (text->linebreaks && strchr(text->linebreaks, *p)) { - av_bprintf(buf, "\\N"); - - /* standard ASS escaping so random characters don't get mis-interpreted - * as ASS */ - } else if (!text->keep_ass_markup && strchr("{}\\", *p)) { - av_bprintf(buf, "\\%c", *p); - - /* some packets might end abruptly (no \0 at the end, like for example - * in some cases of demuxing from a classic video container), some - * might be terminated with \n or \r\n which we have to remove (for - * consistency with those who haven't), and we also have to deal with - * evil cases such as \r at the end of the buffer (and no \0 terminated - * character) */ - } else if (p[0] == '\n') { - /* some stuff left so we can insert a line break */ - if (p < p_end - 1) - av_bprintf(buf, "\\N"); - } else if (p[0] == '\r' && p < p_end - 1 && p[1] == '\n') { - /* \r followed by a \n, we can skip it. We don't insert the \N yet - * because we don't know if it is followed by more text */ - continue; - - /* finally, a sane character */ - } else { - av_bprint_chars(buf, *p, 1); - } - } - av_bprintf(buf, "\r\n"); - return 0; -} - static int text_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, AVPacket *avpkt) { AVBPrint buf; AVSubtitle *sub = data; const char *ptr = avpkt->data; + const TextContext *text = avctx->priv_data; const int ts_start = av_rescale_q(avpkt->pts, avctx->time_base, (AVRational){1,100}); const int ts_duration = avpkt->duration != -1 ? av_rescale_q(avpkt->duration, avctx->time_base, (AVRational){1,100}) : -1; av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED); - if (ptr && avpkt->size > 0 && *ptr && - !text_event_to_ass(avctx, &buf, ptr, ptr + avpkt->size)) { + if (ptr && avpkt->size > 0 && *ptr) { + ff_ass_bprint_text_event(&buf, ptr, avpkt->size, text->linebreaks, text->keep_ass_markup); if (!av_bprint_is_complete(&buf)) { av_bprint_finalize(&buf, NULL); return AVERROR(ENOMEM); @@ -118,8 +79,8 @@ DECLARE_CLASS(text); AVCodec ff_text_decoder = { .name = "text", - .priv_data_size = sizeof(TextContext), .long_name = NULL_IF_CONFIG_SMALL("Raw text subtitle"), + .priv_data_size = sizeof(TextContext), .type = AVMEDIA_TYPE_SUBTITLE, .id = AV_CODEC_ID_TEXT, .decode = text_decode_frame, @@ -143,8 +104,8 @@ DECLARE_CLASS(vplayer); AVCodec ff_vplayer_decoder = { .name = "vplayer", - .priv_data_size = sizeof(TextContext), .long_name = NULL_IF_CONFIG_SMALL("VPlayer subtitle"), + .priv_data_size = sizeof(TextContext), .type = AVMEDIA_TYPE_SUBTITLE, .id = AV_CODEC_ID_VPLAYER, .decode = text_decode_frame, @@ -159,8 +120,8 @@ DECLARE_CLASS(pjs); AVCodec ff_pjs_decoder = { .name = "pjs", - .priv_data_size = sizeof(TextContext), .long_name = NULL_IF_CONFIG_SMALL("PJS subtitle"), + .priv_data_size = sizeof(TextContext), .type = AVMEDIA_TYPE_SUBTITLE, .id = AV_CODEC_ID_PJS, .decode = text_decode_frame, @@ -175,8 +136,8 @@ DECLARE_CLASS(subviewer1); AVCodec ff_subviewer1_decoder = { .name = "subviewer1", - .priv_data_size = sizeof(TextContext), .long_name = NULL_IF_CONFIG_SMALL("SubViewer1 subtitle"), + .priv_data_size = sizeof(TextContext), .type = AVMEDIA_TYPE_SUBTITLE, .id = AV_CODEC_ID_SUBVIEWER1, .decode = text_decode_frame, diff --git a/ffmpeg/libavcodec/thread.h b/ffmpeg/libavcodec/thread.h index 24e62b4..c848d7a 100644 --- a/ffmpeg/libavcodec/thread.h +++ b/ffmpeg/libavcodec/thread.h @@ -97,6 +97,16 @@ void ff_thread_report_progress(ThreadFrame *f, int progress, int field); */ void ff_thread_await_progress(ThreadFrame *f, int progress, int field); +/** + * Wrapper around get_format() for frame-multithreaded codecs. + * Call this function instead of avctx->get_format(). + * Cannot be called after the codec has called ff_thread_finish_setup(). + * + * @param avctx The current context. + * @param fmt The list of available formats. + */ +enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt); + /** * Wrapper around get_buffer() for frame-multithreaded codecs. * Call this function instead of ff_get_buffer(f). @@ -125,4 +135,9 @@ int ff_thread_ref_frame(ThreadFrame *dst, ThreadFrame *src); int ff_thread_init(AVCodecContext *s); void ff_thread_free(AVCodecContext *s); +int ff_alloc_entries(AVCodecContext *avctx, int count); +void ff_reset_entries(AVCodecContext *avctx); +void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n); +void ff_thread_await_progress2(AVCodecContext *avctx, int field, int thread, int shift); + #endif /* AVCODEC_THREAD_H */ diff --git a/ffmpeg/libavcodec/tiertexseqv.c b/ffmpeg/libavcodec/tiertexseqv.c index f892e4d..7c62208 100644 --- a/ffmpeg/libavcodec/tiertexseqv.c +++ b/ffmpeg/libavcodec/tiertexseqv.c @@ -32,7 +32,7 @@ typedef struct SeqVideoContext { AVCodecContext *avctx; - AVFrame frame; + AVFrame *frame; } SeqVideoContext; @@ -93,14 +93,14 @@ static const unsigned char *seq_decode_op1(SeqVideoContext *seq, src = seq_unpack_rle_block(src, src_end, block, sizeof(block)); for (b = 0; b < 8; b++) { memcpy(dst, &block[b * 8], 8); - dst += seq->frame.linesize[0]; + dst += seq->frame->linesize[0]; } break; case 2: src = seq_unpack_rle_block(src, src_end, block, sizeof(block)); for (i = 0; i < 8; i++) { for (b = 0; b < 8; b++) - dst[b * seq->frame.linesize[0]] = block[i * 8 + b]; + dst[b * seq->frame->linesize[0]] = block[i * 8 + b]; ++dst; } break; @@ -117,7 +117,7 @@ static const unsigned char *seq_decode_op1(SeqVideoContext *seq, for (b = 0; b < 8; b++) { for (i = 0; i < 8; i++) dst[i] = color_table[get_bits(&gb, bits)]; - dst += seq->frame.linesize[0]; + dst += seq->frame->linesize[0]; } } @@ -137,7 +137,7 @@ static const unsigned char *seq_decode_op2(SeqVideoContext *seq, for (i = 0; i < 8; i++) { memcpy(dst, src, 8); src += 8; - dst += seq->frame.linesize[0]; + dst += seq->frame->linesize[0]; } return src; @@ -154,7 +154,7 @@ static const unsigned char *seq_decode_op3(SeqVideoContext *seq, if (src_end - src < 2) return NULL; pos = *src++; - offset = ((pos >> 3) & 7) * seq->frame.linesize[0] + (pos & 7); + offset = ((pos >> 3) & 7) * seq->frame->linesize[0] + (pos & 7); dst[offset] = *src++; } while (!(pos & 0x80)); @@ -173,7 +173,7 @@ static int seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int flags = *data++; if (flags & 1) { - palette = (uint32_t *)seq->frame.data[1]; + palette = (uint32_t *)seq->frame->data[1]; if (data_end - data < 256 * 3) return AVERROR_INVALIDDATA; for (i = 0; i < 256; i++) { @@ -181,7 +181,7 @@ static int seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int c[j] = (*data << 2) | (*data >> 4); palette[i] = 0xFFU << 24 | AV_RB24(c); } - seq->frame.palette_has_changed = 1; + seq->frame->palette_has_changed = 1; } if (flags & 2) { @@ -190,7 +190,7 @@ static int seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int init_get_bits(&gb, data, 128 * 8); data += 128; for (y = 0; y < 128; y += 8) for (x = 0; x < 256; x += 8) { - dst = &seq->frame.data[0][y * seq->frame.linesize[0] + x]; + dst = &seq->frame->data[0][y * seq->frame->linesize[0] + x]; op = get_bits(&gb, 2); switch (op) { case 1: @@ -217,7 +217,9 @@ static av_cold int seqvideo_decode_init(AVCodecContext *avctx) seq->avctx = avctx; avctx->pix_fmt = AV_PIX_FMT_PAL8; - avcodec_get_frame_defaults(&seq->frame); + seq->frame = av_frame_alloc(); + if (!seq->frame) + return AVERROR(ENOMEM); return 0; } @@ -232,13 +234,13 @@ static int seqvideo_decode_frame(AVCodecContext *avctx, SeqVideoContext *seq = avctx->priv_data; - if ((ret = ff_reget_buffer(avctx, &seq->frame)) < 0) + if ((ret = ff_reget_buffer(avctx, seq->frame)) < 0) return ret; if (seqvideo_decode(seq, buf, buf_size)) return AVERROR_INVALIDDATA; - if ((ret = av_frame_ref(data, &seq->frame)) < 0) + if ((ret = av_frame_ref(data, seq->frame)) < 0) return ret; *got_frame = 1; @@ -249,13 +251,14 @@ static av_cold int seqvideo_decode_end(AVCodecContext *avctx) { SeqVideoContext *seq = avctx->priv_data; - av_frame_unref(&seq->frame); + av_frame_free(&seq->frame); return 0; } AVCodec ff_tiertexseqvideo_decoder = { .name = "tiertexseqvideo", + .long_name = NULL_IF_CONFIG_SMALL("Tiertex Limited SEQ video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_TIERTEXSEQVIDEO, .priv_data_size = sizeof(SeqVideoContext), @@ -263,5 +266,4 @@ AVCodec ff_tiertexseqvideo_decoder = { .close = seqvideo_decode_end, .decode = seqvideo_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Tiertex Limited SEQ video"), }; diff --git a/ffmpeg/libavcodec/tiff.c b/ffmpeg/libavcodec/tiff.c index 6c2dc23..cd20967 100644 --- a/ffmpeg/libavcodec/tiff.c +++ b/ffmpeg/libavcodec/tiff.c @@ -24,22 +24,24 @@ * @author Konstantin Shishkov */ -#include "avcodec.h" -#include "bytestream.h" #include "config.h" #if CONFIG_ZLIB #include #endif -#include "lzw.h" -#include "tiff.h" -#include "tiff_data.h" -#include "faxcompr.h" -#include "internal.h" -#include "mathops.h" + #include "libavutil/attributes.h" +#include "libavutil/avstring.h" #include "libavutil/intreadwrite.h" #include "libavutil/imgutils.h" -#include "libavutil/avstring.h" +#include "avcodec.h" +#include "bytestream.h" +#include "faxcompr.h" +#include "internal.h" +#include "lzw.h" +#include "mathops.h" +#include "tiff.h" +#include "tiff_data.h" +#include "thread.h" typedef struct TiffContext { AVCodecContext *avctx; @@ -52,6 +54,7 @@ typedef struct TiffContext { int le; enum TiffCompr compr; int invert; + int planar; int fax_opts; int predictor; int fill_order; @@ -68,34 +71,6 @@ typedef struct TiffContext { TiffGeoTag *geotags; } TiffContext; -static unsigned tget_short(GetByteContext *gb, int le) -{ - unsigned v = le ? bytestream2_get_le16(gb) : bytestream2_get_be16(gb); - return v; -} - -static unsigned tget_long(GetByteContext *gb, int le) -{ - unsigned v = le ? bytestream2_get_le32(gb) : bytestream2_get_be32(gb); - return v; -} - -static double tget_double(GetByteContext *gb, int le) -{ - av_alias64 i = { .u64 = le ? bytestream2_get_le64(gb) : bytestream2_get_be64(gb)}; - return i.f64; -} - -static unsigned tget(GetByteContext *gb, int type, int le) -{ - switch (type) { - case TIFF_BYTE : return bytestream2_get_byte(gb); - case TIFF_SHORT: return tget_short(gb, le); - case TIFF_LONG : return tget_long(gb, le); - default : return UINT_MAX; - } -} - static void free_geotags(TiffContext *const s) { int i; @@ -239,138 +214,17 @@ static char *doubles2str(double *dp, int count, const char *sep) return ap0; } -static char *shorts2str(int16_t *sp, int count, const char *sep) -{ - int i; - char *ap, *ap0; - uint64_t component_len; - if (!sep) sep = ", "; - component_len = 7LL + strlen(sep); - if (count >= (INT_MAX - 1)/component_len) - return NULL; - ap = av_malloc(component_len * count + 1); - if (!ap) - return NULL; - ap0 = ap; - ap[0] = '\0'; - for (i = 0; i < count; i++) { - unsigned l = snprintf(ap, component_len, "%d%s", sp[i], sep); - if (l >= component_len) { - av_free(ap0); - return NULL; - } - ap += l; - } - ap0[strlen(ap0) - strlen(sep)] = '\0'; - return ap0; -} - -static int add_doubles_metadata(int count, - const char *name, const char *sep, - TiffContext *s, AVFrame *frame) -{ - char *ap; - int i; - double *dp; - - if (count >= INT_MAX / sizeof(int64_t) || count <= 0) - return AVERROR_INVALIDDATA; - if (bytestream2_get_bytes_left(&s->gb) < count * sizeof(int64_t)) - return AVERROR_INVALIDDATA; - - dp = av_malloc(count * sizeof(double)); - if (!dp) - return AVERROR(ENOMEM); - - for (i = 0; i < count; i++) - dp[i] = tget_double(&s->gb, s->le); - ap = doubles2str(dp, count, sep); - av_freep(&dp); - if (!ap) - return AVERROR(ENOMEM); - av_dict_set(avpriv_frame_get_metadatap(frame), name, ap, AV_DICT_DONT_STRDUP_VAL); - return 0; -} - -static int add_shorts_metadata(int count, const char *name, - const char *sep, TiffContext *s, AVFrame *frame) -{ - char *ap; - int i; - int16_t *sp; - - if (count >= INT_MAX / sizeof(int16_t) || count <= 0) - return AVERROR_INVALIDDATA; - if (bytestream2_get_bytes_left(&s->gb) < count * sizeof(int16_t)) - return AVERROR_INVALIDDATA; - - sp = av_malloc(count * sizeof(int16_t)); - if (!sp) - return AVERROR(ENOMEM); - - for (i = 0; i < count; i++) - sp[i] = tget_short(&s->gb, s->le); - ap = shorts2str(sp, count, sep); - av_freep(&sp); - if (!ap) - return AVERROR(ENOMEM); - av_dict_set(avpriv_frame_get_metadatap(frame), name, ap, AV_DICT_DONT_STRDUP_VAL); - return 0; -} - -static int add_string_metadata(int count, const char *name, - TiffContext *s, AVFrame *frame) -{ - char *value; - - if (bytestream2_get_bytes_left(&s->gb) < count || count < 0) - return AVERROR_INVALIDDATA; - - value = av_malloc(count + 1); - if (!value) - return AVERROR(ENOMEM); - - bytestream2_get_bufferu(&s->gb, value, count); - value[count] = 0; - - av_dict_set(avpriv_frame_get_metadatap(frame), name, value, AV_DICT_DONT_STRDUP_VAL); - return 0; -} - static int add_metadata(int count, int type, const char *name, const char *sep, TiffContext *s, AVFrame *frame) { switch(type) { - case TIFF_DOUBLE: return add_doubles_metadata(count, name, sep, s, frame); - case TIFF_SHORT : return add_shorts_metadata(count, name, sep, s, frame); - case TIFF_STRING: return add_string_metadata(count, name, s, frame); + case TIFF_DOUBLE: return ff_tadd_doubles_metadata(count, name, sep, &s->gb, s->le, avpriv_frame_get_metadatap(frame)); + case TIFF_SHORT : return ff_tadd_shorts_metadata(count, name, sep, &s->gb, s->le, avpriv_frame_get_metadatap(frame)); + case TIFF_STRING: return ff_tadd_string_metadata(count, name, &s->gb, s->le, avpriv_frame_get_metadatap(frame)); default : return AVERROR_INVALIDDATA; }; } -#if CONFIG_ZLIB -static int tiff_uncompress(uint8_t *dst, unsigned long *len, const uint8_t *src, - int size) -{ - z_stream zstream = { 0 }; - int zret; - - zstream.next_in = (uint8_t *)src; - zstream.avail_in = size; - zstream.next_out = dst; - zstream.avail_out = *len; - zret = inflateInit(&zstream); - if (zret != Z_OK) { - av_log(NULL, AV_LOG_ERROR, "Inflate init error: %d\n", zret); - return zret; - } - zret = inflate(&zstream, Z_SYNC_FLUSH); - inflateEnd(&zstream); - *len = zstream.total_out; - return zret == Z_STREAM_END ? Z_OK : zret; -} -#endif - static void av_always_inline horizontal_fill(unsigned int bpp, uint8_t* dst, int usePtr, const uint8_t *src, uint8_t c, int width, int offset) @@ -411,71 +265,147 @@ static void av_always_inline horizontal_fill(unsigned int bpp, uint8_t* dst, } } +static int deinvert_buffer(TiffContext *s, const uint8_t *src, int size) +{ + int i; + + av_fast_padded_malloc(&s->deinvert_buf, &s->deinvert_buf_size, size); + if (!s->deinvert_buf) + return AVERROR(ENOMEM); + for (i = 0; i < size; i++) + s->deinvert_buf[i] = ff_reverse[src[i]]; + + return 0; +} + +#if CONFIG_ZLIB +static int tiff_uncompress(uint8_t *dst, unsigned long *len, const uint8_t *src, + int size) +{ + z_stream zstream = { 0 }; + int zret; + + zstream.next_in = (uint8_t *)src; + zstream.avail_in = size; + zstream.next_out = dst; + zstream.avail_out = *len; + zret = inflateInit(&zstream); + if (zret != Z_OK) { + av_log(NULL, AV_LOG_ERROR, "Inflate init error: %d\n", zret); + return zret; + } + zret = inflate(&zstream, Z_SYNC_FLUSH); + inflateEnd(&zstream); + *len = zstream.total_out; + return zret == Z_STREAM_END ? Z_OK : zret; +} + +static int tiff_unpack_zlib(TiffContext *s, uint8_t *dst, int stride, + const uint8_t *src, int size, + int width, int lines) +{ + uint8_t *zbuf; + unsigned long outlen; + int ret, line; + outlen = width * lines; + zbuf = av_malloc(outlen); + if (!zbuf) + return AVERROR(ENOMEM); + if (s->fill_order) { + if ((ret = deinvert_buffer(s, src, size)) < 0) { + av_free(zbuf); + return ret; + } + src = s->deinvert_buf; + } + ret = tiff_uncompress(zbuf, &outlen, src, size); + if (ret != Z_OK) { + av_log(s->avctx, AV_LOG_ERROR, + "Uncompressing failed (%lu of %lu) with error %d\n", outlen, + (unsigned long)width * lines, ret); + av_free(zbuf); + return AVERROR_UNKNOWN; + } + src = zbuf; + for (line = 0; line < lines; line++) { + if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8) { + horizontal_fill(s->bpp, dst, 1, src, 0, width, 0); + } else { + memcpy(dst, src, width); + } + dst += stride; + src += width; + } + av_free(zbuf); + return 0; +} +#endif + + +static int tiff_unpack_fax(TiffContext *s, uint8_t *dst, int stride, + const uint8_t *src, int size, int width, int lines) +{ + int i, ret = 0; + int line; + uint8_t *src2 = av_malloc((unsigned)size + + FF_INPUT_BUFFER_PADDING_SIZE); + + if (!src2) { + av_log(s->avctx, AV_LOG_ERROR, + "Error allocating temporary buffer\n"); + return AVERROR(ENOMEM); + } + if (s->fax_opts & 2) { + avpriv_request_sample(s->avctx, "Uncompressed fax mode"); + av_free(src2); + return AVERROR_PATCHWELCOME; + } + if (!s->fill_order) { + memcpy(src2, src, size); + } else { + for (i = 0; i < size; i++) + src2[i] = ff_reverse[src[i]]; + } + memset(src2 + size, 0, FF_INPUT_BUFFER_PADDING_SIZE); + ret = ff_ccitt_unpack(s->avctx, src2, size, dst, lines, stride, + s->compr, s->fax_opts); + if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8) + for (line = 0; line < lines; line++) { + horizontal_fill(s->bpp, dst, 1, dst, 0, width, 0); + dst += stride; + } + av_free(src2); + return ret; +} + static int tiff_unpack_strip(TiffContext *s, uint8_t *dst, int stride, const uint8_t *src, int size, int lines) { int c, line, pixels, code, ret; const uint8_t *ssrc = src; - int width = ((s->width * s->bpp) + 7) >> 3; + int width = ((s->width * s->bpp) + 7) >> 3; + + if (s->planar) + width /= s->bppcount; if (size <= 0) return AVERROR_INVALIDDATA; -#if CONFIG_ZLIB if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE) { - uint8_t *src2 = NULL, *zbuf; - unsigned long outlen; - int i, ret; - outlen = width * lines; - zbuf = av_malloc(outlen); - if (!zbuf) - return AVERROR(ENOMEM); - if (s->fill_order) { - src2 = av_malloc((unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!src2) { - av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n"); - av_free(zbuf); - return AVERROR(ENOMEM); - } - for (i = 0; i < size; i++) - src2[i] = ff_reverse[src[i]]; - memset(src2 + size, 0, FF_INPUT_BUFFER_PADDING_SIZE); - src = src2; - } - ret = tiff_uncompress(zbuf, &outlen, src, size); - if (ret != Z_OK) { - av_log(s->avctx, AV_LOG_ERROR, - "Uncompressing failed (%lu of %lu) with error %d\n", outlen, - (unsigned long)width * lines, ret); - av_free(src2); - av_free(zbuf); - return AVERROR_UNKNOWN; - } - src = zbuf; - for (line = 0; line < lines; line++) { - if(s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8){ - horizontal_fill(s->bpp, dst, 1, src, 0, width, 0); - }else{ - memcpy(dst, src, width); - } - dst += stride; - src += width; - } - av_free(src2); - av_free(zbuf); - return 0; - } +#if CONFIG_ZLIB + return tiff_unpack_zlib(s, dst, stride, src, size, width, lines); +#else + av_log(s->avctx, AV_LOG_ERROR, + "zlib support not enabled, " + "deflate compression not supported\n"); + return AVERROR(ENOSYS); #endif + } if (s->compr == TIFF_LZW) { if (s->fill_order) { - int i; - av_fast_padded_malloc(&s->deinvert_buf, &s->deinvert_buf_size, size); - if (!s->deinvert_buf) - return AVERROR(ENOMEM); - for (i = 0; i < size; i++) - s->deinvert_buf[i] = ff_reverse[src[i]]; - src = s->deinvert_buf; - ssrc = src; + if ((ret = deinvert_buffer(s, src, size)) < 0) + return ret; + ssrc = src = s->deinvert_buf; } if (size > 1 && !src[0] && (src[1]&1)) { av_log(s->avctx, AV_LOG_ERROR, "Old style LZW is unsupported\n"); @@ -485,45 +415,10 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t *dst, int stride, return ret; } } - if (s->compr == TIFF_CCITT_RLE || s->compr == TIFF_G3 - || s->compr == TIFF_G4) { - int i, ret = 0; - uint8_t *src2 = av_malloc((unsigned)size + - FF_INPUT_BUFFER_PADDING_SIZE); - - if (!src2) { - av_log(s->avctx, AV_LOG_ERROR, - "Error allocating temporary buffer\n"); - return AVERROR(ENOMEM); - } - if (s->fax_opts & 2) { - av_log(s->avctx, AV_LOG_ERROR, - "Uncompressed fax mode is not supported (yet)\n"); - av_free(src2); - return AVERROR_INVALIDDATA; - } - if (!s->fill_order) { - memcpy(src2, src, size); - } else { - for (i = 0; i < size; i++) - src2[i] = ff_reverse[src[i]]; - } - memset(src2 + size, 0, FF_INPUT_BUFFER_PADDING_SIZE); - switch (s->compr) { - case TIFF_CCITT_RLE: - case TIFF_G3: - case TIFF_G4: - ret = ff_ccitt_unpack(s->avctx, src2, size, dst, lines, stride, - s->compr, s->fax_opts); - break; - } - if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8) - for (line = 0; line < lines; line++) { - horizontal_fill(s->bpp, dst, 1, dst, 0, width, 0); - dst += stride; - } - av_free(src2); - return ret; + if (s->compr == TIFF_CCITT_RLE || + s->compr == TIFF_G3 || + s->compr == TIFF_G4) { + return tiff_unpack_fax(s, dst, stride, src, size, width, lines); } for (line = 0; line < lines; line++) { if (src - ssrc > size) { @@ -550,21 +445,18 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t *dst, int stride, av_log(s->avctx, AV_LOG_ERROR, "Read went out of bounds\n"); return AVERROR_INVALIDDATA; } - code = (int8_t) * src++; + code = s->fill_order ? (int8_t) ff_reverse[*src++]: (int8_t) *src++; if (code >= 0) { code++; - if (pixels + code > width) { + if (pixels + code > width || + ssrc + size - src < code) { av_log(s->avctx, AV_LOG_ERROR, "Copy went out of bounds\n"); return AVERROR_INVALIDDATA; } - if (ssrc + size - src < code) { - av_log(s->avctx, AV_LOG_ERROR, "Read went out of bounds\n"); - return AVERROR_INVALIDDATA; - } horizontal_fill(s->bpp * (s->avctx->pix_fmt == AV_PIX_FMT_PAL8), dst, 1, src, 0, code, pixels); - src += code; + src += code; pixels += code; } else if (code != -128) { // -127..-1 code = (-code) + 1; @@ -579,6 +471,11 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t *dst, int stride, pixels += code; } } + if (s->fill_order) { + int i; + for (i = 0; i < width; i++) + dst[i] = ff_reverse[dst[i]]; + } break; case TIFF_LZW: pixels = ff_lzw_decode(s->lzw, dst, width); @@ -596,12 +493,12 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t *dst, int stride, return 0; } -static int init_image(TiffContext *s, AVFrame *frame) +static int init_image(TiffContext *s, ThreadFrame *frame) { int i, ret; uint32_t *pal; - switch (s->bpp * 10 + s->bppcount) { + switch (s->planar * 1000 + s->bpp * 10 + s->bppcount) { case 11: if (!s->palette_is_set) { s->avctx->pix_fmt = AV_PIX_FMT_MONOBLACK; @@ -625,10 +522,22 @@ static int init_image(TiffContext *s, AVFrame *frame) s->avctx->pix_fmt = AV_PIX_FMT_RGBA; break; case 483: - s->avctx->pix_fmt = s->le ? AV_PIX_FMT_RGB48LE : AV_PIX_FMT_RGB48BE; + s->avctx->pix_fmt = s->le ? AV_PIX_FMT_RGB48LE : AV_PIX_FMT_RGB48BE; break; case 644: - s->avctx->pix_fmt = s->le ? AV_PIX_FMT_RGBA64LE : AV_PIX_FMT_RGBA64BE; + s->avctx->pix_fmt = s->le ? AV_PIX_FMT_RGBA64LE : AV_PIX_FMT_RGBA64BE; + break; + case 1243: + s->avctx->pix_fmt = AV_PIX_FMT_GBRP; + break; + case 1324: + s->avctx->pix_fmt = AV_PIX_FMT_GBRAP; + break; + case 1483: + s->avctx->pix_fmt = s->le ? AV_PIX_FMT_GBRP16LE : AV_PIX_FMT_GBRP16BE; + break; + case 1644: + s->avctx->pix_fmt = s->le ? AV_PIX_FMT_GBRAP16LE : AV_PIX_FMT_GBRAP16BE; break; default: av_log(s->avctx, AV_LOG_ERROR, @@ -637,18 +546,18 @@ static int init_image(TiffContext *s, AVFrame *frame) return AVERROR_INVALIDDATA; } if (s->width != s->avctx->width || s->height != s->avctx->height) { - if ((ret = av_image_check_size(s->width, s->height, 0, s->avctx)) < 0) + ret = ff_set_dimensions(s->avctx, s->width, s->height); + if (ret < 0) return ret; - avcodec_set_dimensions(s->avctx, s->width, s->height); } - if ((ret = ff_get_buffer(s->avctx, frame, 0)) < 0) + if ((ret = ff_thread_get_buffer(s->avctx, frame, 0)) < 0) return ret; if (s->avctx->pix_fmt == AV_PIX_FMT_PAL8) { if (s->palette_is_set) { - memcpy(frame->data[1], s->palette, sizeof(s->palette)); + memcpy(frame->f->data[1], s->palette, sizeof(s->palette)); } else { /* make default grayscale pal */ - pal = (uint32_t *) frame->data[1]; + pal = (uint32_t *) frame->f->data[1]; for (i = 0; i < 1<bpp; i++) pal[i] = 0xFFU << 24 | i * 255 / ((1<bpp) - 1) * 0x010101; } @@ -664,42 +573,25 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) uint32_t *pal; double *dp; - tag = tget_short(&s->gb, s->le); - type = tget_short(&s->gb, s->le); - count = tget_long(&s->gb, s->le); - off = tget_long(&s->gb, s->le); - start = bytestream2_tell(&s->gb); - - if (type == 0 || type >= FF_ARRAY_ELEMS(type_sizes)) { - av_log(s->avctx, AV_LOG_DEBUG, "Unknown tiff type (%u) encountered\n", - type); - return 0; + ret = ff_tread_tag(&s->gb, s->le, &tag, &type, &count, &start); + if (ret < 0) { + goto end; } + off = bytestream2_tell(&s->gb); if (count == 1) { switch (type) { case TIFF_BYTE: case TIFF_SHORT: - bytestream2_seek(&s->gb, -4, SEEK_CUR); - value = tget(&s->gb, type, s->le); - break; case TIFF_LONG: - value = off; + value = ff_tget(&s->gb, type, s->le); break; case TIFF_STRING: if (count <= 4) { - bytestream2_seek(&s->gb, -4, SEEK_CUR); break; } default: value = UINT_MAX; - bytestream2_seek(&s->gb, off, SEEK_SET); - } - } else { - if (count <= 4 && type_sizes[type] * count <= 4) { - bytestream2_seek(&s->gb, -4, SEEK_CUR); - } else { - bytestream2_seek(&s->gb, off, SEEK_SET); } } @@ -723,16 +615,13 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) else { switch (type) { case TIFF_BYTE: - s->bpp = (off & 0xFF) + ((off >> 8) & 0xFF) + - ((off >> 16) & 0xFF) + ((off >> 24) & 0xFF); - break; case TIFF_SHORT: case TIFF_LONG: s->bpp = 0; if (bytestream2_get_bytes_left(&s->gb) < type_sizes[type] * count) return AVERROR_INVALIDDATA; for (i = 0; i < count; i++) - s->bpp += tget(&s->gb, type, s->le); + s->bpp += ff_tget(&s->gb, type, s->le); break; default: s->bpp = -1; @@ -755,7 +644,7 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) s->bppcount = value; break; case TIFF_COMPR: - s->compr = value; + s->compr = value; s->predictor = 0; switch (s->compr) { case TIFF_RAW: @@ -777,8 +666,7 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) #endif case TIFF_JPEG: case TIFF_NEWJPEG: - av_log(s->avctx, AV_LOG_ERROR, - "JPEG compression is not supported\n"); + avpriv_report_missing_feature(s->avctx, "JPEG compression"); return AVERROR_PATCHWELCOME; default: av_log(s->avctx, AV_LOG_ERROR, "Unknown compression method %i\n", @@ -798,8 +686,8 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) break; case TIFF_STRIP_OFFS: if (count == 1) { - s->strippos = 0; - s->stripoff = value; + s->strippos = 0; + s->stripoff = value; } else s->strippos = off; s->strips = count; @@ -815,8 +703,8 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) case TIFF_STRIP_SIZE: if (count == 1) { s->stripsizesoff = 0; - s->stripsize = value; - s->strips = 1; + s->stripsize = value; + s->strips = 1; } else { s->stripsizesoff = off; } @@ -873,17 +761,14 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) for (i = 0; i < count / 3; i++) { if (k == 2) pal[i] = 0xFFU << 24; - j = (tget(&s->gb, type, s->le) >> off) << (k * 8); + j = (ff_tget(&s->gb, type, s->le) >> off) << (k * 8); pal[i] |= j; } } s->palette_is_set = 1; break; case TIFF_PLANAR: - if (value == 2) { - av_log(s->avctx, AV_LOG_ERROR, "Planar format is not supported\n"); - return AVERROR_PATCHWELCOME; - } + s->planar = value == 2; break; case TIFF_T4OPTIONS: if (s->compr == TIFF_G3) @@ -896,7 +781,7 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) #define ADD_METADATA(count, name, sep)\ if ((ret = add_metadata(count, type, name, sep, s, frame)) < 0) {\ av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");\ - return ret;\ + goto end;\ } case TIFF_MODEL_PIXEL_SCALE: ADD_METADATA(count, "ModelPixelScaleTag", NULL); @@ -910,7 +795,7 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) case TIFF_GEO_KEY_DIRECTORY: ADD_METADATA(1, "GeoTIFF_Version", NULL); ADD_METADATA(2, "GeoTIFF_Key_Revision", "."); - s->geotag_count = tget_short(&s->gb, s->le); + s->geotag_count = ff_tget_short(&s->gb, s->le); if (s->geotag_count > count / 4 - 1) { s->geotag_count = count / 4 - 1; av_log(s->avctx, AV_LOG_WARNING, "GeoTIFF key directory buffer shorter than specified\n"); @@ -923,17 +808,17 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) if (!s->geotags) { av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n"); s->geotag_count = 0; - return AVERROR(ENOMEM); + goto end; } for (i = 0; i < s->geotag_count; i++) { - s->geotags[i].key = tget_short(&s->gb, s->le); - s->geotags[i].type = tget_short(&s->gb, s->le); - s->geotags[i].count = tget_short(&s->gb, s->le); + s->geotags[i].key = ff_tget_short(&s->gb, s->le); + s->geotags[i].type = ff_tget_short(&s->gb, s->le); + s->geotags[i].count = ff_tget_short(&s->gb, s->le); if (!s->geotags[i].type) - s->geotags[i].val = get_geokey_val(s->geotags[i].key, tget_short(&s->gb, s->le)); + s->geotags[i].val = get_geokey_val(s->geotags[i].key, ff_tget_short(&s->gb, s->le)); else - s->geotags[i].offset = tget_short(&s->gb, s->le); + s->geotags[i].offset = ff_tget_short(&s->gb, s->le); } break; case TIFF_GEO_DOUBLE_PARAMS: @@ -944,10 +829,10 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) dp = av_malloc(count * sizeof(double)); if (!dp) { av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n"); - return AVERROR(ENOMEM); + goto end; } for (i = 0; i < count; i++) - dp[i] = tget_double(&s->gb, s->le); + dp[i] = ff_tget_double(&s->gb, s->le); for (i = 0; i < s->geotag_count; i++) { if (s->geotags[i].type == TIFF_GEO_DOUBLE_PARAMS) { if (s->geotags[i].count == 0 @@ -1025,9 +910,14 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) ADD_METADATA(count, "software", NULL); break; default: - av_log(s->avctx, AV_LOG_DEBUG, "Unknown or unsupported tag %d/0X%0X\n", - tag, tag); + if (s->avctx->err_recognition & AV_EF_EXPLODE) { + av_log(s->avctx, AV_LOG_ERROR, + "Unknown or unsupported tag %d/0X%0X\n", + tag, tag); + return AVERROR_INVALIDDATA; + } } +end: bytestream2_seek(&s->gb, start, SEEK_SET); return 0; } @@ -1037,10 +927,10 @@ static int decode_frame(AVCodecContext *avctx, { TiffContext *const s = avctx->priv_data; AVFrame *const p = data; + ThreadFrame frame = { .f = data }; unsigned off; - int id, le, ret; - int i, j, entries; - int stride; + int le, ret, plane, planes; + int i, j, entries, stride; unsigned soff, ssize; uint8_t *dst; GetByteContext stripsizes; @@ -1048,43 +938,27 @@ static int decode_frame(AVCodecContext *avctx, bytestream2_init(&s->gb, avpkt->data, avpkt->size); - //parse image header - if (avpkt->size < 8) - return AVERROR_INVALIDDATA; - id = bytestream2_get_le16u(&s->gb); - if (id == 0x4949) - le = 1; - else if (id == 0x4D4D) - le = 0; - else { - av_log(avctx, AV_LOG_ERROR, "TIFF header not found\n"); + // parse image header + if ((ret = ff_tdecode_header(&s->gb, &le, &off))) { + av_log(avctx, AV_LOG_ERROR, "Invalid TIFF header\n"); + return ret; + } else if (off >= UINT_MAX - 14 || avpkt->size < off + 14) { + av_log(avctx, AV_LOG_ERROR, "IFD offset is greater than image size\n"); return AVERROR_INVALIDDATA; } - s->le = le; + s->le = le; // TIFF_BPP is not a required tag and defaults to 1 - s->bppcount = s->bpp = 1; - s->invert = 0; - s->compr = TIFF_RAW; + s->bppcount = s->bpp = 1; + s->invert = 0; + s->compr = TIFF_RAW; s->fill_order = 0; free_geotags(s); - // As TIFF 6.0 specification puts it "An arbitrary but carefully chosen number - // that further identifies the file as a TIFF file" - if (tget_short(&s->gb, le) != 42) { - av_log(avctx, AV_LOG_ERROR, - "The answer to life, universe and everything is not correct!\n"); - return AVERROR_INVALIDDATA; - } // Reset these offsets so we can tell if they were set this frame s->stripsizesoff = s->strippos = 0; /* parse image file directory */ - off = tget_long(&s->gb, le); - if (off >= UINT_MAX - 14 || avpkt->size < off + 14) { - av_log(avctx, AV_LOG_ERROR, "IFD offset is greater than image size\n"); - return AVERROR_INVALIDDATA; - } bytestream2_seek(&s->gb, off, SEEK_SET); - entries = tget_short(&s->gb, le); + entries = ff_tget_short(&s->gb, le); if (bytestream2_get_bytes_left(&s->gb) < entries * 12) return AVERROR_INVALIDDATA; for (i = 0; i < entries; i++) { @@ -1114,15 +988,13 @@ static int decode_frame(AVCodecContext *avctx, return AVERROR_INVALIDDATA; } /* now we have the data and may start decoding */ - if ((ret = init_image(s, p)) < 0) + if ((ret = init_image(s, &frame)) < 0) return ret; if (s->strips == 1 && !s->stripsize) { av_log(avctx, AV_LOG_WARNING, "Image data size missing\n"); s->stripsize = avpkt->size - s->stripoff; } - stride = p->linesize[0]; - dst = p->data[0]; if (s->stripsizesoff) { if (s->stripsizesoff >= (unsigned)avpkt->size) @@ -1140,14 +1012,18 @@ static int decode_frame(AVCodecContext *avctx, return AVERROR_INVALIDDATA; } + planes = s->planar ? s->bppcount : 1; + for (plane = 0; plane < planes; plane++) { + stride = p->linesize[plane]; + dst = p->data[plane]; for (i = 0; i < s->height; i += s->rps) { if (s->stripsizesoff) - ssize = tget(&stripsizes, s->sstype, s->le); + ssize = ff_tget(&stripsizes, s->sstype, s->le); else ssize = s->stripsize; if (s->strippos) - soff = tget(&stripdata, s->sot, s->le); + soff = ff_tget(&stripdata, s->sot, s->le); else soff = s->stripoff; @@ -1155,24 +1031,33 @@ static int decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "Invalid strip size/offset\n"); return AVERROR_INVALIDDATA; } - if (tiff_unpack_strip(s, dst, stride, avpkt->data + soff, ssize, - FFMIN(s->rps, s->height - i)) < 0) + if ((ret = tiff_unpack_strip(s, dst, stride, avpkt->data + soff, ssize, + FFMIN(s->rps, s->height - i))) < 0) { + if (avctx->err_recognition & AV_EF_EXPLODE) + return ret; break; + } dst += s->rps * stride; } if (s->predictor == 2) { - dst = p->data[0]; - soff = s->bpp >> 3; + dst = p->data[plane]; + soff = s->bpp >> 3; + if (s->planar) + soff = FFMAX(soff / s->bppcount, 1); ssize = s->width * soff; if (s->avctx->pix_fmt == AV_PIX_FMT_RGB48LE || - s->avctx->pix_fmt == AV_PIX_FMT_RGBA64LE) { + s->avctx->pix_fmt == AV_PIX_FMT_RGBA64LE || + s->avctx->pix_fmt == AV_PIX_FMT_GBRP16LE || + s->avctx->pix_fmt == AV_PIX_FMT_GBRAP16LE) { for (i = 0; i < s->height; i++) { for (j = soff; j < ssize; j += 2) AV_WL16(dst + j, AV_RL16(dst + j) + AV_RL16(dst + j - soff)); dst += stride; } } else if (s->avctx->pix_fmt == AV_PIX_FMT_RGB48BE || - s->avctx->pix_fmt == AV_PIX_FMT_RGBA64BE) { + s->avctx->pix_fmt == AV_PIX_FMT_RGBA64BE || + s->avctx->pix_fmt == AV_PIX_FMT_GBRP16BE || + s->avctx->pix_fmt == AV_PIX_FMT_GBRAP16BE) { for (i = 0; i < s->height; i++) { for (j = soff; j < ssize; j += 2) AV_WB16(dst + j, AV_RB16(dst + j) + AV_RB16(dst + j - soff)); @@ -1188,13 +1073,22 @@ static int decode_frame(AVCodecContext *avctx, } if (s->invert) { - dst = p->data[0]; + dst = p->data[plane]; for (i = 0; i < s->height; i++) { - for (j = 0; j < p->linesize[0]; j++) + for (j = 0; j < p->linesize[plane]; j++) dst[j] = (s->avctx->pix_fmt == AV_PIX_FMT_PAL8 ? (1<bpp) - 1 : 255) - dst[j]; - dst += p->linesize[0]; + dst += p->linesize[plane]; } } + } + + if (s->planar && s->bppcount > 2) { + FFSWAP(uint8_t*, p->data[0], p->data[2]); + FFSWAP(int, p->linesize[0], p->linesize[2]); + FFSWAP(uint8_t*, p->data[0], p->data[1]); + FFSWAP(int, p->linesize[0], p->linesize[1]); + } + *got_frame = 1; return avpkt->size; @@ -1204,9 +1098,9 @@ static av_cold int tiff_init(AVCodecContext *avctx) { TiffContext *s = avctx->priv_data; - s->width = 0; + s->width = 0; s->height = 0; - s->avctx = avctx; + s->avctx = avctx; ff_lzw_decode_open(&s->lzw); ff_ccitt_unpack_init(); @@ -1226,12 +1120,13 @@ static av_cold int tiff_end(AVCodecContext *avctx) AVCodec ff_tiff_decoder = { .name = "tiff", + .long_name = NULL_IF_CONFIG_SMALL("TIFF image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_TIFF, .priv_data_size = sizeof(TiffContext), .init = tiff_init, .close = tiff_end, .decode = decode_frame, - .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("TIFF image"), + .init_thread_copy = ONLY_IF_THREADS_ENABLED(tiff_init), + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, }; diff --git a/ffmpeg/libavcodec/tiff.h b/ffmpeg/libavcodec/tiff.h index 6d760f0..ae189b6 100644 --- a/ffmpeg/libavcodec/tiff.h +++ b/ffmpeg/libavcodec/tiff.h @@ -31,60 +31,61 @@ #define AVCODEC_TIFF_H #include +#include "tiff_common.h" /** abridged list of TIFF tags */ -enum TiffTags{ - TIFF_SUBFILE = 0xfe, - TIFF_WIDTH = 0x100, +enum TiffTags { + TIFF_SUBFILE = 0xfe, + TIFF_WIDTH = 0x100, TIFF_HEIGHT, TIFF_BPP, TIFF_COMPR, - TIFF_INVERT = 0x106, - TIFF_FILL_ORDER = 0x10A, - TIFF_DOCUMENT_NAME = 0x10D, - TIFF_IMAGE_DESCRIPTION = 0x10E, - TIFF_MAKE = 0x10F, - TIFF_MODEL = 0x110, - TIFF_STRIP_OFFS = 0x111, - TIFF_SAMPLES_PER_PIXEL = 0x115, - TIFF_ROWSPERSTRIP = 0x116, + TIFF_INVERT = 0x106, + TIFF_FILL_ORDER = 0x10A, + TIFF_DOCUMENT_NAME = 0x10D, + TIFF_IMAGE_DESCRIPTION = 0x10E, + TIFF_MAKE = 0x10F, + TIFF_MODEL = 0x110, + TIFF_STRIP_OFFS = 0x111, + TIFF_SAMPLES_PER_PIXEL = 0x115, + TIFF_ROWSPERSTRIP = 0x116, TIFF_STRIP_SIZE, - TIFF_XRES = 0x11A, - TIFF_YRES = 0x11B, - TIFF_PLANAR = 0x11C, - TIFF_PAGE_NAME = 0x11D, - TIFF_XPOS = 0x11E, - TIFF_YPOS = 0x11F, - TIFF_T4OPTIONS = 0x124, + TIFF_XRES = 0x11A, + TIFF_YRES = 0x11B, + TIFF_PLANAR = 0x11C, + TIFF_PAGE_NAME = 0x11D, + TIFF_XPOS = 0x11E, + TIFF_YPOS = 0x11F, + TIFF_T4OPTIONS = 0x124, TIFF_T6OPTIONS, - TIFF_RES_UNIT = 0x128, - TIFF_PAGE_NUMBER = 0x129, - TIFF_SOFTWARE_NAME = 0x131, - TIFF_DATE = 0x132, - TIFF_ARTIST = 0x13B, - TIFF_HOST_COMPUTER = 0x13C, - TIFF_PREDICTOR = 0x13D, - TIFF_PAL = 0x140, - TIFF_TILE_WIDTH = 0x142, - TIFF_TILE_LENGTH = 0x143, - TIFF_TILE_OFFSETS = 0x144, - TIFF_TILE_BYTE_COUNTS = 0x145, - TIFF_EXTRASAMPLES = 0x152, + TIFF_RES_UNIT = 0x128, + TIFF_PAGE_NUMBER = 0x129, + TIFF_SOFTWARE_NAME = 0x131, + TIFF_DATE = 0x132, + TIFF_ARTIST = 0x13B, + TIFF_HOST_COMPUTER = 0x13C, + TIFF_PREDICTOR = 0x13D, + TIFF_PAL = 0x140, + TIFF_TILE_WIDTH = 0x142, + TIFF_TILE_LENGTH = 0x143, + TIFF_TILE_OFFSETS = 0x144, + TIFF_TILE_BYTE_COUNTS = 0x145, + TIFF_EXTRASAMPLES = 0x152, TIFF_YCBCR_COEFFICIENTS = 0x211, - TIFF_YCBCR_SUBSAMPLING = 0x212, - TIFF_YCBCR_POSITIONING = 0x213, - TIFF_REFERENCE_BW = 0x214, - TIFF_COPYRIGHT = 0x8298, - TIFF_MODEL_TIEPOINT = 0x8482, - TIFF_MODEL_PIXEL_SCALE = 0x830E, - TIFF_MODEL_TRANSFORMATION = 0x8480, - TIFF_GEO_KEY_DIRECTORY = 0x87AF, - TIFF_GEO_DOUBLE_PARAMS = 0x87B0, - TIFF_GEO_ASCII_PARAMS = 0x87B1 + TIFF_YCBCR_SUBSAMPLING = 0x212, + TIFF_YCBCR_POSITIONING = 0x213, + TIFF_REFERENCE_BW = 0x214, + TIFF_COPYRIGHT = 0x8298, + TIFF_MODEL_TIEPOINT = 0x8482, + TIFF_MODEL_PIXEL_SCALE = 0x830E, + TIFF_MODEL_TRANSFORMATION= 0x8480, + TIFF_GEO_KEY_DIRECTORY = 0x87AF, + TIFF_GEO_DOUBLE_PARAMS = 0x87B0, + TIFF_GEO_ASCII_PARAMS = 0x87B1 }; /** list of TIFF compression types */ -enum TiffCompr{ +enum TiffCompr { TIFF_RAW = 1, TIFF_CCITT_RLE, TIFF_G3, @@ -94,23 +95,7 @@ enum TiffCompr{ TIFF_NEWJPEG, TIFF_ADOBE_DEFLATE, TIFF_PACKBITS = 0x8005, - TIFF_DEFLATE = 0x80B2 -}; - -enum TiffTypes{ - TIFF_BYTE = 1, - TIFF_STRING, - TIFF_SHORT, - TIFF_LONG, - TIFF_RATIONAL, - TIFF_SBYTE, - TIFF_UNDEFINED, - TIFF_SSHORT, - TIFF_SLONG, - TIFF_SRATIONAL, - TIFF_FLOAT, - TIFF_DOUBLE, - TIFF_IFD + TIFF_DEFLATE = 0x80B2 }; enum TiffGeoTagKey { @@ -167,11 +152,6 @@ enum TiffGeoTagType { GEOTIFF_STRING = 34737 }; -/** sizes of various TIFF field types (string size = 100)*/ -static const uint8_t type_sizes[14] = { - 0, 1, 100, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 4 -}; - typedef struct TiffGeoTag { enum TiffGeoTagKey key; enum TiffTags type; diff --git a/ffmpeg/libavcodec/tiff_data.c b/ffmpeg/libavcodec/tiff_data.c index 5bfe009..88c2256 100644 --- a/ffmpeg/libavcodec/tiff_data.c +++ b/ffmpeg/libavcodec/tiff_data.c @@ -2,20 +2,20 @@ * TIFF data tables * Copyright (c) 2011 Thomas Kuehnel * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/tiff_data.h b/ffmpeg/libavcodec/tiff_data.h index 91a4e1e..57515f9 100644 --- a/ffmpeg/libavcodec/tiff_data.h +++ b/ffmpeg/libavcodec/tiff_data.h @@ -2,20 +2,20 @@ * TIFF data tables * Copyright (c) 2011 Thomas Kuehnel * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/tiffenc.c b/ffmpeg/libavcodec/tiffenc.c index 61294b9..7b1e510 100644 --- a/ffmpeg/libavcodec/tiffenc.c +++ b/ffmpeg/libavcodec/tiffenc.c @@ -25,22 +25,22 @@ * @author Bartlomiej Wolowiec */ +#include "config.h" +#if CONFIG_ZLIB +#include +#endif + #include "libavutil/imgutils.h" #include "libavutil/log.h" #include "libavutil/opt.h" #include "libavutil/pixdesc.h" - #include "avcodec.h" -#include "config.h" -#if CONFIG_ZLIB -#include -#endif #include "bytestream.h" #include "internal.h" -#include "tiff.h" -#include "rle.h" #include "lzw.h" #include "put_bits.h" +#include "rle.h" +#include "tiff.h" #define TIFF_MAX_ENTRY 32 @@ -50,35 +50,33 @@ static const uint8_t type_sizes2[14] = { }; typedef struct TiffEncoderContext { - AVClass *class; ///< for private options + AVClass *class; ///< for private options AVCodecContext *avctx; - AVFrame picture; - - int width; ///< picture width - int height; ///< picture height - unsigned int bpp; ///< bits per pixel - int compr; ///< compression level - int bpp_tab_size; ///< bpp_tab size - int photometric_interpretation; ///< photometric interpretation - int strips; ///< number of strips + + int width; ///< picture width + int height; ///< picture height + unsigned int bpp; ///< bits per pixel + int compr; ///< compression level + int bpp_tab_size; ///< bpp_tab size + int photometric_interpretation; ///< photometric interpretation + int strips; ///< number of strips uint32_t *strip_sizes; unsigned int strip_sizes_size; uint32_t *strip_offsets; unsigned int strip_offsets_size; uint8_t *yuv_line; unsigned int yuv_line_size; - int rps; ///< row per strip - uint8_t entries[TIFF_MAX_ENTRY*12]; ///< entires in header - int num_entries; ///< number of entires - uint8_t **buf; ///< actual position in buffer - uint8_t *buf_start; ///< pointer to first byte in buffer - int buf_size; ///< buffer size - uint16_t subsampling[2]; ///< YUV subsampling factors - struct LZWEncodeState *lzws; ///< LZW Encode state - uint32_t dpi; ///< image resolution in DPI + int rps; ///< row per strip + uint8_t entries[TIFF_MAX_ENTRY * 12]; ///< entries in header + int num_entries; ///< number of entries + uint8_t **buf; ///< actual position in buffer + uint8_t *buf_start; ///< pointer to first byte in buffer + int buf_size; ///< buffer size + uint16_t subsampling[2]; ///< YUV subsampling factors + struct LZWEncodeState *lzws; ///< LZW encode state + uint32_t dpi; ///< image resolution in DPI } TiffEncoderContext; - /** * Check free space in buffer. * @@ -86,7 +84,7 @@ typedef struct TiffEncoderContext { * @param need Needed bytes * @return 0 - ok, 1 - no free space */ -static inline int check_size(TiffEncoderContext * s, uint64_t need) +static inline int check_size(TiffEncoderContext *s, uint64_t need) { if (s->buf_size < *s->buf - s->buf_start + need) { *s->buf = s->buf_start + s->buf_size + 1; @@ -105,12 +103,12 @@ static inline int check_size(TiffEncoderContext * s, uint64_t need) * @param type type of values * @param flip = 0 - normal copy, >0 - flip */ -static void tnput(uint8_t ** p, int n, const uint8_t * val, enum TiffTypes type, +static void tnput(uint8_t **p, int n, const uint8_t *val, enum TiffTypes type, int flip) { int i; #if HAVE_BIGENDIAN - flip ^= ((int[]) {0, 0, 0, 1, 3, 3})[type]; + flip ^= ((int[]) { 0, 0, 0, 1, 3, 3 })[type]; #endif for (i = 0; i < n * type_sizes2[type]; i++) *(*p)++ = val[i ^ flip]; @@ -125,9 +123,8 @@ static void tnput(uint8_t ** p, int n, const uint8_t * val, enum TiffTypes type, * @param count the number of values * @param ptr_val pointer to values */ -static void add_entry(TiffEncoderContext * s, - enum TiffTags tag, enum TiffTypes type, int count, - const void *ptr_val) +static void add_entry(TiffEncoderContext *s, enum TiffTags tag, + enum TiffTypes type, int count, const void *ptr_val) { uint8_t *entries_ptr = s->entries + 12 * s->num_entries; @@ -148,10 +145,11 @@ static void add_entry(TiffEncoderContext * s, s->num_entries++; } -static void add_entry1(TiffEncoderContext * s, - enum TiffTags tag, enum TiffTypes type, int val){ - uint16_t w = val; - uint32_t dw= val; +static void add_entry1(TiffEncoderContext *s, + enum TiffTags tag, enum TiffTypes type, int val) +{ + uint16_t w = val; + uint32_t dw = val; add_entry(s, tag, type, 1, type == TIFF_SHORT ? (void *)&w : (void *)&dw); } @@ -165,22 +163,21 @@ static void add_entry1(TiffEncoderContext * s, * @param compr compression method * @return number of output bytes. If an output error is encountered, -1 is returned */ -static int encode_strip(TiffEncoderContext * s, const int8_t * src, - uint8_t * dst, int n, int compr) +static int encode_strip(TiffEncoderContext *s, const int8_t *src, + uint8_t *dst, int n, int compr) { - switch (compr) { #if CONFIG_ZLIB case TIFF_DEFLATE: case TIFF_ADOBE_DEFLATE: - { - unsigned long zlen = s->buf_size - (*s->buf - s->buf_start); - if (compress(dst, &zlen, src, n) != Z_OK) { - av_log(s->avctx, AV_LOG_ERROR, "Compressing failed\n"); - return -1; - } - return zlen; + { + unsigned long zlen = s->buf_size - (*s->buf - s->buf_start); + if (compress(dst, &zlen, src, n) != Z_OK) { + av_log(s->avctx, AV_LOG_ERROR, "Compressing failed\n"); + return -1; } + return zlen; + } #endif case TIFF_RAW: if (check_size(s, n)) @@ -188,7 +185,8 @@ static int encode_strip(TiffEncoderContext * s, const int8_t * src, memcpy(dst, src, n); return n; case TIFF_PACKBITS: - return ff_rle_encode(dst, s->buf_size - (*s->buf - s->buf_start), src, 1, n, 2, 0xff, -1, 0); + return ff_rle_encode(dst, s->buf_size - (*s->buf - s->buf_start), + src, 1, n, 2, 0xff, -1, 0); case TIFF_LZW: return ff_lzw_encode(s->lzws, src, n); default: @@ -196,15 +194,15 @@ static int encode_strip(TiffEncoderContext * s, const int8_t * src, } } -static void pack_yuv(TiffEncoderContext * s, uint8_t * dst, int lnum) +static void pack_yuv(TiffEncoderContext *s, const AVFrame *p, + uint8_t *dst, int lnum) { - AVFrame *p = &s->picture; int i, j, k; - int w = (s->width - 1) / s->subsampling[0] + 1; + int w = (s->width - 1) / s->subsampling[0] + 1; uint8_t *pu = &p->data[1][lnum / s->subsampling[1] * p->linesize[1]]; uint8_t *pv = &p->data[2][lnum / s->subsampling[1] * p->linesize[2]]; - if(s->width % s->subsampling[0] || s->height % s->subsampling[1]){ - for (i = 0; i < w; i++){ + if (s->width % s->subsampling[0] || s->height % s->subsampling[1]) { + for (i = 0; i < w; i++) { for (j = 0; j < s->subsampling[1]; j++) for (k = 0; k < s->subsampling[0]; k++) *dst++ = p->data[0][FFMIN(lnum + j, s->height-1) * p->linesize[0] + @@ -213,7 +211,7 @@ static void pack_yuv(TiffEncoderContext * s, uint8_t * dst, int lnum) *dst++ = *pv++; } }else{ - for (i = 0; i < w; i++){ + for (i = 0; i < w; i++) { for (j = 0; j < s->subsampling[1]; j++) for (k = 0; k < s->subsampling[0]; k++) *dst++ = p->data[0][(lnum + j) * p->linesize[0] + @@ -224,44 +222,30 @@ static void pack_yuv(TiffEncoderContext * s, uint8_t * dst, int lnum) } } -static av_cold int encode_init(AVCodecContext *avctx) -{ - TiffEncoderContext *s = avctx->priv_data; - - avctx->coded_frame= &s->picture; - avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; - avctx->coded_frame->key_frame = 1; - s->avctx = avctx; - - return 0; -} - -static int encode_frame(AVCodecContext * avctx, AVPacket *pkt, +static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); TiffEncoderContext *s = avctx->priv_data; - AVFrame *const p = &s->picture; + const AVFrame *const p = pict; int i; uint8_t *ptr; uint8_t *offset; uint32_t strips; int bytes_per_row; - uint32_t res[2] = { s->dpi, 1 }; // image resolution (72/1) + uint32_t res[2] = { s->dpi, 1 }; // image resolution (72/1) uint16_t bpp_tab[4]; int ret = -1; int is_yuv = 0, alpha = 0; int shift_h, shift_v; - *p = *pict; - - s->width = avctx->width; - s->height = avctx->height; + s->width = avctx->width; + s->height = avctx->height; s->subsampling[0] = 1; s->subsampling[1] = 1; avctx->bits_per_coded_sample = - s->bpp = av_get_bits_per_pixel(desc); + s->bpp = av_get_bits_per_pixel(desc); s->bpp_tab_size = desc->nb_components; switch (avctx->pix_fmt) { @@ -292,11 +276,11 @@ static int encode_frame(AVCodecContext * avctx, AVPacket *pkt, case AV_PIX_FMT_YUV444P: case AV_PIX_FMT_YUV410P: case AV_PIX_FMT_YUV411P: + av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &shift_h, &shift_v); s->photometric_interpretation = 6; - avcodec_get_chroma_sub_sample(avctx->pix_fmt, &shift_h, &shift_v); - s->subsampling[0] = 1 << shift_h; - s->subsampling[1] = 1 << shift_v; - is_yuv = 1; + s->subsampling[0] = 1 << shift_h; + s->subsampling[1] = 1 << shift_v; + is_yuv = 1; break; default: av_log(s->avctx, AV_LOG_ERROR, @@ -307,17 +291,22 @@ static int encode_frame(AVCodecContext * avctx, AVPacket *pkt, for (i = 0; i < s->bpp_tab_size; i++) bpp_tab[i] = desc->comp[i].depth_minus1 + 1; - if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE || s->compr == TIFF_LZW) - //best choose for DEFLATE + if (s->compr == TIFF_DEFLATE || + s->compr == TIFF_ADOBE_DEFLATE || + s->compr == TIFF_LZW) + // best choice for DEFLATE s->rps = s->height; else - s->rps = FFMAX(8192 / (((s->width * s->bpp) >> 3) + 1), 1); // suggest size of strip - s->rps = ((s->rps - 1) / s->subsampling[1] + 1) * s->subsampling[1]; // round rps up + // suggest size of strip + s->rps = FFMAX(8192 / (((s->width * s->bpp) >> 3) + 1), 1); + // round rps up + s->rps = ((s->rps - 1) / s->subsampling[1] + 1) * s->subsampling[1]; strips = (s->height - 1) / s->rps + 1; - if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width * avctx->height * s->bpp * 2 + - avctx->height * 4 + FF_MIN_BUFFER_SIZE)) < 0) + if ((ret = ff_alloc_packet2(avctx, pkt, + avctx->width * avctx->height * s->bpp * 2 + + avctx->height * 4 + FF_MIN_BUFFER_SIZE)) < 0) return ret; ptr = pkt->data; s->buf_start = pkt->data; @@ -334,7 +323,7 @@ static int encode_frame(AVCodecContext * avctx, AVPacket *pkt, offset = ptr; bytestream_put_le32(&ptr, 0); - av_fast_padded_mallocz(&s->strip_sizes, &s->strip_sizes_size, sizeof(s->strip_sizes[0]) * strips); + av_fast_padded_mallocz(&s->strip_sizes , &s->strip_sizes_size , sizeof(s->strip_sizes [0]) * strips); av_fast_padded_mallocz(&s->strip_offsets, &s->strip_offsets_size, sizeof(s->strip_offsets[0]) * strips); if (!s->strip_sizes || !s->strip_offsets) { @@ -342,11 +331,11 @@ static int encode_frame(AVCodecContext * avctx, AVPacket *pkt, goto fail; } - bytes_per_row = (((s->width - 1)/s->subsampling[0] + 1) * s->bpp - * s->subsampling[0] * s->subsampling[1] + 7) >> 3; - if (is_yuv){ + bytes_per_row = (((s->width - 1) / s->subsampling[0] + 1) * s->bpp * + s->subsampling[0] * s->subsampling[1] + 7) >> 3; + if (is_yuv) { av_fast_padded_malloc(&s->yuv_line, &s->yuv_line_size, bytes_per_row); - if (s->yuv_line == NULL){ + if (s->yuv_line == NULL) { av_log(s->avctx, AV_LOG_ERROR, "Not enough memory\n"); ret = AVERROR(ENOMEM); goto fail; @@ -366,14 +355,13 @@ static int encode_frame(AVCodecContext * avctx, AVPacket *pkt, goto fail; } s->strip_offsets[0] = ptr - pkt->data; - zn = 0; + zn = 0; for (j = 0; j < s->rps; j++) { - if (is_yuv){ - pack_yuv(s, s->yuv_line, j); + if (is_yuv) { + pack_yuv(s, p, s->yuv_line, j); memcpy(zbuf + zn, s->yuv_line, bytes_per_row); j += s->subsampling[1] - 1; - } - else + } else memcpy(zbuf + j * bytes_per_row, p->data[0] + j * p->linesize[0], bytes_per_row); zn += bytes_per_row; @@ -384,97 +372,99 @@ static int encode_frame(AVCodecContext * avctx, AVPacket *pkt, av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n"); goto fail; } - ptr += ret; + ptr += ret; s->strip_sizes[0] = ptr - pkt->data - s->strip_offsets[0]; } else #endif { - if (s->compr == TIFF_LZW) { - s->lzws = av_malloc(ff_lzw_encode_state_size); - if (!s->lzws) { - ret = AVERROR(ENOMEM); - goto fail; - } + if (s->compr == TIFF_LZW) { + s->lzws = av_malloc(ff_lzw_encode_state_size); + if (!s->lzws) { + ret = AVERROR(ENOMEM); + goto fail; } - for (i = 0; i < s->height; i++) { - if (s->strip_sizes[i / s->rps] == 0) { - if(s->compr == TIFF_LZW){ - ff_lzw_encode_init(s->lzws, ptr, s->buf_size - (*s->buf - s->buf_start), - 12, FF_LZW_TIFF, put_bits); - } - s->strip_offsets[i / s->rps] = ptr - pkt->data; - } - if (is_yuv){ - pack_yuv(s, s->yuv_line, i); - ret = encode_strip(s, s->yuv_line, ptr, bytes_per_row, s->compr); - i += s->subsampling[1] - 1; - } - else - ret = encode_strip(s, p->data[0] + i * p->linesize[0], - ptr, bytes_per_row, s->compr); - if (ret < 0) { - av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n"); - goto fail; - } - s->strip_sizes[i / s->rps] += ret; - ptr += ret; - if(s->compr == TIFF_LZW && (i==s->height-1 || i%s->rps == s->rps-1)){ - ret = ff_lzw_encode_flush(s->lzws, flush_put_bits); - s->strip_sizes[(i / s->rps )] += ret ; - ptr += ret; + } + for (i = 0; i < s->height; i++) { + if (s->strip_sizes[i / s->rps] == 0) { + if (s->compr == TIFF_LZW) { + ff_lzw_encode_init(s->lzws, ptr, + s->buf_size - (*s->buf - s->buf_start), + 12, FF_LZW_TIFF, put_bits); } + s->strip_offsets[i / s->rps] = ptr - pkt->data; + } + if (is_yuv) { + pack_yuv(s, p, s->yuv_line, i); + ret = encode_strip(s, s->yuv_line, ptr, bytes_per_row, s->compr); + i += s->subsampling[1] - 1; + } else + ret = encode_strip(s, p->data[0] + i * p->linesize[0], + ptr, bytes_per_row, s->compr); + if (ret < 0) { + av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n"); + goto fail; } - if(s->compr == TIFF_LZW) - av_free(s->lzws); + s->strip_sizes[i / s->rps] += ret; + ptr += ret; + if (s->compr == TIFF_LZW && + (i == s->height - 1 || i % s->rps == s->rps - 1)) { + ret = ff_lzw_encode_flush(s->lzws, flush_put_bits); + s->strip_sizes[(i / s->rps)] += ret; + ptr += ret; + } + } + if (s->compr == TIFF_LZW) + av_free(s->lzws); } s->num_entries = 0; - add_entry1(s,TIFF_SUBFILE, TIFF_LONG, 0); - add_entry1(s,TIFF_WIDTH, TIFF_LONG, s->width); - add_entry1(s,TIFF_HEIGHT, TIFF_LONG, s->height); + add_entry1(s, TIFF_SUBFILE, TIFF_LONG, 0); + add_entry1(s, TIFF_WIDTH, TIFF_LONG, s->width); + add_entry1(s, TIFF_HEIGHT, TIFF_LONG, s->height); if (s->bpp_tab_size) - add_entry(s, TIFF_BPP, TIFF_SHORT, s->bpp_tab_size, bpp_tab); + add_entry(s, TIFF_BPP, TIFF_SHORT, s->bpp_tab_size, bpp_tab); - add_entry1(s,TIFF_COMPR, TIFF_SHORT, s->compr); - add_entry1(s,TIFF_INVERT, TIFF_SHORT, s->photometric_interpretation); - add_entry(s, TIFF_STRIP_OFFS, TIFF_LONG, strips, s->strip_offsets); + add_entry1(s, TIFF_COMPR, TIFF_SHORT, s->compr); + add_entry1(s, TIFF_INVERT, TIFF_SHORT, s->photometric_interpretation); + add_entry(s, TIFF_STRIP_OFFS, TIFF_LONG, strips, s->strip_offsets); if (s->bpp_tab_size) - add_entry1(s,TIFF_SAMPLES_PER_PIXEL, TIFF_SHORT, s->bpp_tab_size); + add_entry1(s, TIFF_SAMPLES_PER_PIXEL, TIFF_SHORT, s->bpp_tab_size); - add_entry1(s,TIFF_ROWSPERSTRIP, TIFF_LONG, s->rps); - add_entry(s, TIFF_STRIP_SIZE, TIFF_LONG, strips, s->strip_sizes); - add_entry(s, TIFF_XRES, TIFF_RATIONAL, 1, res); - add_entry(s, TIFF_YRES, TIFF_RATIONAL, 1, res); - add_entry1(s,TIFF_RES_UNIT, TIFF_SHORT, 2); + add_entry1(s, TIFF_ROWSPERSTRIP, TIFF_LONG, s->rps); + add_entry(s, TIFF_STRIP_SIZE, TIFF_LONG, strips, s->strip_sizes); + add_entry(s, TIFF_XRES, TIFF_RATIONAL, 1, res); + add_entry(s, TIFF_YRES, TIFF_RATIONAL, 1, res); + add_entry1(s, TIFF_RES_UNIT, TIFF_SHORT, 2); - if(!(avctx->flags & CODEC_FLAG_BITEXACT)) - add_entry(s, TIFF_SOFTWARE_NAME, TIFF_STRING, - strlen(LIBAVCODEC_IDENT) + 1, LIBAVCODEC_IDENT); + if (!(avctx->flags & CODEC_FLAG_BITEXACT)) + add_entry(s, TIFF_SOFTWARE_NAME, TIFF_STRING, + strlen(LIBAVCODEC_IDENT) + 1, LIBAVCODEC_IDENT); if (avctx->pix_fmt == AV_PIX_FMT_PAL8) { uint16_t pal[256 * 3]; for (i = 0; i < 256; i++) { uint32_t rgb = *(uint32_t *) (p->data[1] + i * 4); pal[i] = ((rgb >> 16) & 0xff) * 257; - pal[i + 256] = ((rgb >> 8 ) & 0xff) * 257; - pal[i + 512] = ( rgb & 0xff) * 257; + pal[i + 256] = ((rgb >> 8) & 0xff) * 257; + pal[i + 512] = (rgb & 0xff) * 257; } add_entry(s, TIFF_PAL, TIFF_SHORT, 256 * 3, pal); } if (alpha) add_entry1(s,TIFF_EXTRASAMPLES, TIFF_SHORT, 2); - if (is_yuv){ + if (is_yuv) { /** according to CCIR Recommendation 601.1 */ - uint32_t refbw[12] = {15, 1, 235, 1, 128, 1, 240, 1, 128, 1, 240, 1}; + uint32_t refbw[12] = { 15, 1, 235, 1, 128, 1, 240, 1, 128, 1, 240, 1 }; add_entry(s, TIFF_YCBCR_SUBSAMPLING, TIFF_SHORT, 2, s->subsampling); if (avctx->chroma_sample_location == AVCHROMA_LOC_TOPLEFT) add_entry1(s, TIFF_YCBCR_POSITIONING, TIFF_SHORT, 2); add_entry(s, TIFF_REFERENCE_BW, TIFF_RATIONAL, 6, refbw); } - bytestream_put_le32(&offset, ptr - pkt->data); // write offset to dir + // write offset to dir + bytestream_put_le32(&offset, ptr - pkt->data); if (check_size(s, 6 + s->num_entries * 12)) { ret = AVERROR(EINVAL); @@ -492,10 +482,26 @@ fail: return ret < 0 ? ret : 0; } +static av_cold int encode_init(AVCodecContext *avctx) +{ + TiffEncoderContext *s = avctx->priv_data; + + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->key_frame = 1; + s->avctx = avctx; + + return 0; +} + static av_cold int encode_close(AVCodecContext *avctx) { TiffEncoderContext *s = avctx->priv_data; + av_frame_free(&avctx->coded_frame); av_freep(&s->strip_sizes); av_freep(&s->strip_offsets); av_freep(&s->yuv_line); @@ -507,12 +513,12 @@ static av_cold int encode_close(AVCodecContext *avctx) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { {"dpi", "set the image resolution (in dpi)", OFFSET(dpi), AV_OPT_TYPE_INT, {.i64 = 72}, 1, 0x10000, AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_ENCODING_PARAM}, - { "compression_algo", NULL, OFFSET(compr), AV_OPT_TYPE_INT, {.i64 = TIFF_PACKBITS}, TIFF_RAW, TIFF_DEFLATE, VE, "compression_algo" }, - { "packbits", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = TIFF_PACKBITS}, 0, 0, VE, "compression_algo" }, - { "raw", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = TIFF_RAW}, 0, 0, VE, "compression_algo" }, - { "lzw", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = TIFF_LZW}, 0, 0, VE, "compression_algo" }, + { "compression_algo", NULL, OFFSET(compr), AV_OPT_TYPE_INT, { .i64 = TIFF_PACKBITS }, TIFF_RAW, TIFF_DEFLATE, VE, "compression_algo" }, + { "packbits", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = TIFF_PACKBITS }, 0, 0, VE, "compression_algo" }, + { "raw", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = TIFF_RAW }, 0, 0, VE, "compression_algo" }, + { "lzw", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = TIFF_LZW }, 0, 0, VE, "compression_algo" }, #if CONFIG_ZLIB - { "deflate", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = TIFF_DEFLATE}, 0, 0, VE, "compression_algo" }, + { "deflate", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = TIFF_DEFLATE }, 0, 0, VE, "compression_algo" }, #endif { NULL }, }; @@ -526,12 +532,13 @@ static const AVClass tiffenc_class = { AVCodec ff_tiff_encoder = { .name = "tiff", + .long_name = NULL_IF_CONFIG_SMALL("TIFF image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_TIFF, .priv_data_size = sizeof(TiffEncoderContext), .init = encode_init, - .encode2 = encode_frame, .close = encode_close, + .encode2 = encode_frame, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB24, AV_PIX_FMT_PAL8, AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY8A, AV_PIX_FMT_GRAY16LE, @@ -541,6 +548,5 @@ AVCodec ff_tiff_encoder = { AV_PIX_FMT_RGBA, AV_PIX_FMT_RGBA64LE, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("TIFF image"), .priv_class = &tiffenc_class, }; diff --git a/ffmpeg/libavcodec/timecode.c b/ffmpeg/libavcodec/timecode.c deleted file mode 100644 index f9862e5..0000000 --- a/ffmpeg/libavcodec/timecode.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2006 Smartjog S.A.S, Baptiste Coudurier - * Copyright (C) 2011 Smartjog S.A.S, Clément BÅ“sch - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Timecode helpers - * This *private* API is deprecated, please use the one available in libavutil instead. - */ - -#include "version.h" - -#if FF_API_OLD_TIMECODE - -#include -#include "timecode.h" -#include "libavutil/log.h" - -int avpriv_framenum_to_drop_timecode(int frame_num) -{ - /* only works for NTSC 29.97 */ - int d = frame_num / 17982; - int m = frame_num % 17982; - //if (m < 2) m += 2; /* not needed since -2,-1 / 1798 in C returns 0 */ - return frame_num + 18 * d + 2 * ((m - 2) / 1798); -} - -uint32_t avpriv_framenum_to_smpte_timecode(unsigned frame, int fps, int drop) -{ - return (0 << 31) | // color frame flag - (drop << 30) | // drop frame flag - ( ((frame % fps) / 10) << 28) | // tens of frames - ( ((frame % fps) % 10) << 24) | // units of frames - (0 << 23) | // field phase (NTSC), b0 (PAL) - ((((frame / fps) % 60) / 10) << 20) | // tens of seconds - ((((frame / fps) % 60) % 10) << 16) | // units of seconds - (0 << 15) | // b0 (NTSC), b2 (PAL) - ((((frame / (fps * 60)) % 60) / 10) << 12) | // tens of minutes - ((((frame / (fps * 60)) % 60) % 10) << 8) | // units of minutes - (0 << 7) | // b1 - (0 << 6) | // b2 (NTSC), field phase (PAL) - ((((frame / (fps * 3600) % 24)) / 10) << 4) | // tens of hours - ( (frame / (fps * 3600) % 24)) % 10; // units of hours -} - -int avpriv_check_timecode_rate(void *avcl, AVRational rate, int drop) -{ - int fps; - - if (!rate.num || !rate.den) { - av_log(avcl, AV_LOG_ERROR, "Timecode frame rate must be specified\n"); - return -1; - } - fps = (rate.num + rate.den/2) / rate.den; - if (drop && fps != 30) { - av_log(avcl, AV_LOG_ERROR, "Drop frame is only allowed with 30000/1001 FPS\n"); - return -2; - } - switch (fps) { - case 24: - case 25: - case 30: return 0; - - default: - av_log(avcl, AV_LOG_ERROR, "Timecode frame rate not supported\n"); - return -3; - } -} - -char *avpriv_timecode_to_string(char *buf, const struct ff_timecode *tc, unsigned frame) -{ - int frame_num = tc->start + frame; - int fps = (tc->rate.num + tc->rate.den/2) / tc->rate.den; - int hh, mm, ss, ff, neg = 0; - - if (tc->drop) - frame_num = avpriv_framenum_to_drop_timecode(frame_num); - if (frame_num < 0) { - frame_num = -frame_num; - neg = 1; - } - ff = frame_num % fps; - ss = frame_num / fps % 60; - mm = frame_num / (fps*60) % 60; - hh = frame_num / (fps*3600); - snprintf(buf, 16, "%s%02d:%02d:%02d%c%02d", - neg ? "-" : "", - hh, mm, ss, tc->drop ? ';' : ':', ff); - return buf; -} - -int avpriv_init_smpte_timecode(void *avcl, struct ff_timecode *tc) -{ - int hh, mm, ss, ff, fps, ret; - char c; - - if (sscanf(tc->str, "%d:%d:%d%c%d", &hh, &mm, &ss, &c, &ff) != 5) { - av_log(avcl, AV_LOG_ERROR, "unable to parse timecode, " - "syntax: hh:mm:ss[:;.]ff\n"); - return -1; - } - - tc->drop = c != ':'; // drop if ';', '.', ... - - ret = avpriv_check_timecode_rate(avcl, tc->rate, tc->drop); - if (ret < 0) - return ret; - - fps = (tc->rate.num + tc->rate.den/2) / tc->rate.den; - tc->start = (hh*3600 + mm*60 + ss) * fps + ff; - - if (tc->drop) { /* adjust frame number */ - int tmins = 60*hh + mm; - tc->start -= 2 * (tmins - tmins/10); - } - return 0; -} - -int ff_framenum_to_drop_timecode(int frame_num) -{ - return avpriv_framenum_to_drop_timecode(frame_num); -} - -uint32_t ff_framenum_to_smtpe_timecode(unsigned frame, int fps, int drop) -{ - return avpriv_framenum_to_smpte_timecode(frame, fps, drop); -} - -int ff_init_smtpe_timecode(void *avcl, struct ff_timecode *tc) -{ - return avpriv_init_smpte_timecode(avcl, tc); -} -#endif diff --git a/ffmpeg/libavcodec/timecode.h b/ffmpeg/libavcodec/timecode.h deleted file mode 100644 index 8bc69e9..0000000 --- a/ffmpeg/libavcodec/timecode.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2006 Smartjog S.A.S, Baptiste Coudurier - * Copyright (C) 2011 Smartjog S.A.S, Clément BÅ“sch - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Timecode helpers header - * This *private* API is deprecated, please use the one available in libavutil instead. - */ - -#ifndef AVCODEC_TIMECODE_H -#define AVCODEC_TIMECODE_H - -#include "version.h" - -#if FF_API_OLD_TIMECODE - -#include -#include "avcodec.h" -#include "libavutil/rational.h" - -#define TIMECODE_OPT(ctx, flags) \ - "timecode", "set timecode value following hh:mm:ss[:;.]ff format, " \ - "use ';' or '.' before frame number for drop frame", \ - offsetof(ctx, tc.str), \ - AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, flags - -struct ff_timecode { - char *str; ///< string following the hh:mm:ss[:;.]ff format - int start; ///< timecode frame start - int drop; ///< drop flag (1 if drop, else 0) - AVRational rate; ///< Frame rate in rational form -}; - -/** - * @brief Adjust frame number for NTSC drop frame time code - * @param frame_num Actual frame number to adjust - * @return Adjusted frame number - * @warning Adjustment is only valid in NTSC 29.97 - */ -int avpriv_framenum_to_drop_timecode(int frame_num); - -/** - * @brief Convert frame id (timecode) to SMPTE 12M binary representation - * @param frame Frame number - * @param fps Frame rate - * @param drop Drop flag - * @return The actual binary representation - */ -uint32_t avpriv_framenum_to_smpte_timecode(unsigned frame, int fps, int drop); - -/** - * @brief Load timecode string in buf - * @param buf Destination buffer - * @param tc Timecode struct pointer - * @param frame Frame id (timecode frame is computed with tc->start+frame) - * @return a pointer to the buf parameter - * @note timecode representation can be a negative timecode and have - * more than 24 hours. - * @note buf must have enough space to store the timecode representation: 16 - * bytes is the minimum required size. - */ -char *avpriv_timecode_to_string(char *buf, const struct ff_timecode *tc, unsigned frame); - -/** - * Check if timecode rate is valid and consistent with the drop flag. - * - * @return 0 on success, negative value on failure - */ -int avpriv_check_timecode_rate(void *avcl, AVRational rate, int drop); - -/** - * Parse SMTPE 12M time representation (hh:mm:ss[:;.]ff). str and rate fields - * from tc struct must be set. - * - * @param avcl A pointer to an arbitrary struct of which the first field is a - * pointer to an AVClass struct (used for av_log). - * @param tc Timecode struct pointer - * @return 0 on success, negative value on failure - * @warning Adjustement is only valid in NTSC 29.97 - */ -int avpriv_init_smpte_timecode(void *avcl, struct ff_timecode *tc); - -attribute_deprecated int ff_framenum_to_drop_timecode(int frame_num); -attribute_deprecated uint32_t ff_framenum_to_smtpe_timecode(unsigned frame, int fps, int drop); -attribute_deprecated int ff_init_smtpe_timecode(void *avcl, struct ff_timecode *tc); -#endif - -#endif /* AVCODEC_TIMECODE_H */ diff --git a/ffmpeg/libavcodec/tmv.c b/ffmpeg/libavcodec/tmv.c index 279298c..e525a73 100644 --- a/ffmpeg/libavcodec/tmv.c +++ b/ffmpeg/libavcodec/tmv.c @@ -88,10 +88,10 @@ static av_cold int tmv_decode_init(AVCodecContext *avctx) AVCodec ff_tmv_decoder = { .name = "tmv", + .long_name = NULL_IF_CONFIG_SMALL("8088flex TMV"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_TMV, .init = tmv_decode_init, .decode = tmv_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("8088flex TMV"), }; diff --git a/ffmpeg/libavcodec/truemotion1.c b/ffmpeg/libavcodec/truemotion1.c index 5a387ca..6528a1f 100644 --- a/ffmpeg/libavcodec/truemotion1.c +++ b/ffmpeg/libavcodec/truemotion1.c @@ -44,7 +44,7 @@ typedef struct TrueMotion1Context { AVCodecContext *avctx; - AVFrame frame; + AVFrame *frame; const uint8_t *buf; int size; @@ -397,16 +397,19 @@ static int truemotion1_decode_header(TrueMotion1Context *s) new_pix_fmt = AV_PIX_FMT_RGB555; // RGB565 is supported as well s->w >>= width_shift; - if ((ret = av_image_check_size(s->w, s->h, 0, s->avctx)) < 0) - return ret; if (s->w != s->avctx->width || s->h != s->avctx->height || new_pix_fmt != s->avctx->pix_fmt) { - av_frame_unref(&s->frame); + av_frame_unref(s->frame); s->avctx->sample_aspect_ratio = (AVRational){ 1 << width_shift, 1 }; s->avctx->pix_fmt = new_pix_fmt; - avcodec_set_dimensions(s->avctx, s->w, s->h); + + if ((ret = ff_set_dimensions(s->avctx, s->w, s->h)) < 0) + return ret; + av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int)); + if (!s->vert_pred) + return AVERROR(ENOMEM); } /* There is 1 change bit per 4 pixels, so each change byte represents @@ -468,11 +471,15 @@ static av_cold int truemotion1_decode_init(AVCodecContext *avctx) // else // avctx->pix_fmt = AV_PIX_FMT_RGB555; - avcodec_get_frame_defaults(&s->frame); + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); /* there is a vertical predictor for each pixel in a line; each vertical * predictor is 0 to start with */ av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int)); + if (!s->vert_pred) + return AVERROR(ENOMEM); return 0; } @@ -512,11 +519,16 @@ hres,vres,i,i%vres (0 < i < 4) index = s->index_stream[index_stream_index++] * 4; \ } +#define INC_INDEX \ +do { \ + if (index >= 1023) { \ + av_log(s->avctx, AV_LOG_ERROR, "Invalid index value.\n"); \ + return; \ + } \ + index++; \ +} while (0) + #define APPLY_C_PREDICTOR() \ - if(index > 1023){\ - av_log(s->avctx, AV_LOG_ERROR, " index %d went out of bounds\n", index); \ - return; \ - }\ predictor_pair = s->c_predictor_table[index]; \ horiz_pred += (predictor_pair >> 1); \ if (predictor_pair & 1) { \ @@ -528,16 +540,12 @@ hres,vres,i,i%vres (0 < i < 4) if (predictor_pair & 1) \ GET_NEXT_INDEX() \ else \ - index++; \ + INC_INDEX; \ } \ } else \ - index++; + INC_INDEX; #define APPLY_C_PREDICTOR_24() \ - if(index > 1023){\ - av_log(s->avctx, AV_LOG_ERROR, " index %d went out of bounds\n", index); \ - return; \ - }\ predictor_pair = s->c_predictor_table[index]; \ horiz_pred += (predictor_pair >> 1); \ if (predictor_pair & 1) { \ @@ -549,17 +557,13 @@ hres,vres,i,i%vres (0 < i < 4) if (predictor_pair & 1) \ GET_NEXT_INDEX() \ else \ - index++; \ + INC_INDEX; \ } \ } else \ - index++; + INC_INDEX; #define APPLY_Y_PREDICTOR() \ - if(index > 1023){\ - av_log(s->avctx, AV_LOG_ERROR, " index %d went out of bounds\n", index); \ - return; \ - }\ predictor_pair = s->y_predictor_table[index]; \ horiz_pred += (predictor_pair >> 1); \ if (predictor_pair & 1) { \ @@ -571,16 +575,12 @@ hres,vres,i,i%vres (0 < i < 4) if (predictor_pair & 1) \ GET_NEXT_INDEX() \ else \ - index++; \ + INC_INDEX; \ } \ } else \ - index++; + INC_INDEX; #define APPLY_Y_PREDICTOR_24() \ - if(index > 1023){\ - av_log(s->avctx, AV_LOG_ERROR, " index %d went out of bounds\n", index); \ - return; \ - }\ predictor_pair = s->y_predictor_table[index]; \ horiz_pred += (predictor_pair >> 1); \ if (predictor_pair & 1) { \ @@ -592,10 +592,10 @@ hres,vres,i,i%vres (0 < i < 4) if (predictor_pair & 1) \ GET_NEXT_INDEX() \ else \ - index++; \ + INC_INDEX; \ } \ } else \ - index++; + INC_INDEX; #define OUTPUT_PIXEL_PAIR() \ *current_pixel_pair = *vert_pred + horiz_pred; \ @@ -609,7 +609,7 @@ static void truemotion1_decode_16bit(TrueMotion1Context *s) unsigned int horiz_pred; unsigned int *vert_pred; unsigned int *current_pixel_pair; - unsigned char *current_line = s->frame.data[0]; + unsigned char *current_line = s->frame->data[0]; int keyframe = s->flags & FLAG_KEYFRAME; /* these variables are for managing the stream of macroblock change bits */ @@ -723,7 +723,7 @@ static void truemotion1_decode_16bit(TrueMotion1Context *s) if (((y + 1) & 3) == 0) mb_change_bits += s->mb_change_bits_row_size; - current_line += s->frame.linesize[0]; + current_line += s->frame->linesize[0]; } } @@ -735,7 +735,7 @@ static void truemotion1_decode_24bit(TrueMotion1Context *s) unsigned int horiz_pred; unsigned int *vert_pred; unsigned int *current_pixel_pair; - unsigned char *current_line = s->frame.data[0]; + unsigned char *current_line = s->frame->data[0]; int keyframe = s->flags & FLAG_KEYFRAME; /* these variables are for managing the stream of macroblock change bits */ @@ -849,7 +849,7 @@ static void truemotion1_decode_24bit(TrueMotion1Context *s) if (((y + 1) & 3) == 0) mb_change_bits += s->mb_change_bits_row_size; - current_line += s->frame.linesize[0]; + current_line += s->frame->linesize[0]; } } @@ -868,7 +868,7 @@ static int truemotion1_decode_frame(AVCodecContext *avctx, if ((ret = truemotion1_decode_header(s)) < 0) return ret; - if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) + if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) return ret; if (compression_types[s->compression].algorithm == ALGO_RGB24H) { @@ -877,7 +877,7 @@ static int truemotion1_decode_frame(AVCodecContext *avctx, truemotion1_decode_16bit(s); } - if ((ret = av_frame_ref(data, &s->frame)) < 0) + if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; *got_frame = 1; @@ -890,14 +890,15 @@ static av_cold int truemotion1_decode_end(AVCodecContext *avctx) { TrueMotion1Context *s = avctx->priv_data; - av_frame_unref(&s->frame); - av_free(s->vert_pred); + av_frame_free(&s->frame); + av_freep(&s->vert_pred); return 0; } AVCodec ff_truemotion1_decoder = { .name = "truemotion1", + .long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 1.0"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_TRUEMOTION1, .priv_data_size = sizeof(TrueMotion1Context), @@ -905,5 +906,4 @@ AVCodec ff_truemotion1_decoder = { .close = truemotion1_decode_end, .decode = truemotion1_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 1.0"), }; diff --git a/ffmpeg/libavcodec/truemotion2.c b/ffmpeg/libavcodec/truemotion2.c index 7783386..a1683f5 100644 --- a/ffmpeg/libavcodec/truemotion2.c +++ b/ffmpeg/libavcodec/truemotion2.c @@ -58,7 +58,7 @@ enum TM2_BLOCKS { typedef struct TM2Context { AVCodecContext *avctx; - AVFrame pic; + AVFrame *pic; GetBitContext gb; DSPContext dsp; @@ -169,9 +169,14 @@ static int tm2_build_huff_table(TM2Context *ctx, TM2Codes *code) /* allocate space for codes - it is exactly ceil(nodes / 2) entries */ huff.max_num = (huff.nodes + 1) >> 1; - huff.nums = av_mallocz(huff.max_num * sizeof(int)); - huff.bits = av_mallocz(huff.max_num * sizeof(uint32_t)); - huff.lens = av_mallocz(huff.max_num * sizeof(int)); + huff.nums = av_calloc(huff.max_num, sizeof(int)); + huff.bits = av_calloc(huff.max_num, sizeof(uint32_t)); + huff.lens = av_calloc(huff.max_num, sizeof(int)); + + if (!huff.nums || !huff.bits || !huff.lens) { + res = AVERROR(ENOMEM); + goto fail; + } res = tm2_read_tree(ctx, 0, 0, &huff); @@ -193,11 +198,16 @@ static int tm2_build_huff_table(TM2Context *ctx, TM2Codes *code) else { code->bits = huff.max_bits; code->length = huff.max_num; - code->recode = av_malloc(code->length * sizeof(int)); + code->recode = av_malloc_array(code->length, sizeof(int)); + if (!code->recode) { + res = AVERROR(ENOMEM); + goto fail; + } for (i = 0; i < code->length; i++) code->recode[i] = huff.nums[i]; } } +fail: /* free allocated memory */ av_free(huff.nums); av_free(huff.bits); @@ -332,7 +342,11 @@ static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, i tm2_free_codes(&codes); return AVERROR_INVALIDDATA; } - ctx->tokens[stream_id] = av_realloc(ctx->tokens[stream_id], toks * sizeof(int)); + ret = av_reallocp_array(&ctx->tokens[stream_id], toks, sizeof(int)); + if (ret < 0) { + ctx->tok_lens[stream_id] = 0; + return ret; + } ctx->tok_lens[stream_id] = toks; len = bytestream2_get_be32(&gb); if (len > 0) { @@ -858,7 +872,7 @@ static int decode_frame(AVCodecContext *avctx, TM2Context * const l = avctx->priv_data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size & ~3; - AVFrame * const p = &l->pic; + AVFrame * const p = l->pic; int offset = TM2_HEADER_SIZE; int i, t, ret; @@ -900,7 +914,7 @@ static int decode_frame(AVCodecContext *avctx, l->cur = !l->cur; *got_frame = 1; - ret = av_frame_ref(data, &l->pic); + ret = av_frame_ref(data, l->pic); return (ret < 0) ? ret : buf_size; } @@ -916,13 +930,16 @@ static av_cold int decode_init(AVCodecContext *avctx) } l->avctx = avctx; - avcodec_get_frame_defaults(&l->pic); avctx->pix_fmt = AV_PIX_FMT_BGR24; + l->pic = av_frame_alloc(); + if (!l->pic) + return AVERROR(ENOMEM); + ff_dsputil_init(&l->dsp, avctx); - l->last = av_malloc(4 * sizeof(*l->last) * (w >> 2)); - l->clast = av_malloc(4 * sizeof(*l->clast) * (w >> 2)); + l->last = av_malloc_array(w >> 2, 4 * sizeof(*l->last) ); + l->clast = av_malloc_array(w >> 2, 4 * sizeof(*l->clast)); for (i = 0; i < TM2_NUM_STREAMS; i++) { l->tokens[i] = NULL; @@ -931,28 +948,29 @@ static av_cold int decode_init(AVCodecContext *avctx) w += 8; h += 8; - l->Y1_base = av_mallocz(sizeof(*l->Y1_base) * w * h); - l->Y2_base = av_mallocz(sizeof(*l->Y2_base) * w * h); + l->Y1_base = av_calloc(w * h, sizeof(*l->Y1_base)); + l->Y2_base = av_calloc(w * h, sizeof(*l->Y2_base)); l->y_stride = w; w = (w + 1) >> 1; h = (h + 1) >> 1; - l->U1_base = av_mallocz(sizeof(*l->U1_base) * w * h); - l->V1_base = av_mallocz(sizeof(*l->V1_base) * w * h); - l->U2_base = av_mallocz(sizeof(*l->U2_base) * w * h); - l->V2_base = av_mallocz(sizeof(*l->V1_base) * w * h); + l->U1_base = av_calloc(w * h, sizeof(*l->U1_base)); + l->V1_base = av_calloc(w * h, sizeof(*l->V1_base)); + l->U2_base = av_calloc(w * h, sizeof(*l->U2_base)); + l->V2_base = av_calloc(w * h, sizeof(*l->V1_base)); l->uv_stride = w; l->cur = 0; if (!l->Y1_base || !l->Y2_base || !l->U1_base || !l->V1_base || !l->U2_base || !l->V2_base || !l->last || !l->clast) { - av_freep(l->Y1_base); - av_freep(l->Y2_base); - av_freep(l->U1_base); - av_freep(l->U2_base); - av_freep(l->V1_base); - av_freep(l->V2_base); - av_freep(l->last); - av_freep(l->clast); + av_freep(&l->Y1_base); + av_freep(&l->Y2_base); + av_freep(&l->U1_base); + av_freep(&l->U2_base); + av_freep(&l->V1_base); + av_freep(&l->V2_base); + av_freep(&l->last); + av_freep(&l->clast); + av_frame_free(&l->pic); return AVERROR(ENOMEM); } l->Y1 = l->Y1_base + l->y_stride * 4 + 4; @@ -968,7 +986,6 @@ static av_cold int decode_init(AVCodecContext *avctx) static av_cold int decode_end(AVCodecContext *avctx) { TM2Context * const l = avctx->priv_data; - AVFrame *pic = &l->pic; int i; av_free(l->last); @@ -986,13 +1003,14 @@ static av_cold int decode_end(AVCodecContext *avctx) av_freep(&l->buffer); l->buffer_size = 0; - av_frame_unref(pic); + av_frame_free(&l->pic); return 0; } AVCodec ff_truemotion2_decoder = { .name = "truemotion2", + .long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 2.0"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_TRUEMOTION2, .priv_data_size = sizeof(TM2Context), @@ -1000,5 +1018,4 @@ AVCodec ff_truemotion2_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 2.0"), }; diff --git a/ffmpeg/libavcodec/truespeech.c b/ffmpeg/libavcodec/truespeech.c index 2eb218c..d3e3b20 100644 --- a/ffmpeg/libavcodec/truespeech.c +++ b/ffmpeg/libavcodec/truespeech.c @@ -356,11 +356,11 @@ static int truespeech_decode_frame(AVCodecContext *avctx, void *data, AVCodec ff_truespeech_decoder = { .name = "truespeech", + .long_name = NULL_IF_CONFIG_SMALL("DSP Group TrueSpeech"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_TRUESPEECH, .priv_data_size = sizeof(TSContext), .init = truespeech_decode_init, .decode = truespeech_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("DSP Group TrueSpeech"), }; diff --git a/ffmpeg/libavcodec/tscc.c b/ffmpeg/libavcodec/tscc.c index 6e1e077..b4931ec 100644 --- a/ffmpeg/libavcodec/tscc.c +++ b/ffmpeg/libavcodec/tscc.c @@ -179,6 +179,7 @@ static av_cold int decode_end(AVCodecContext *avctx) AVCodec ff_tscc_decoder = { .name = "camtasia", + .long_name = NULL_IF_CONFIG_SMALL("TechSmith Screen Capture Codec"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_TSCC, .priv_data_size = sizeof(CamtasiaContext), @@ -186,5 +187,4 @@ AVCodec ff_tscc_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("TechSmith Screen Capture Codec"), }; diff --git a/ffmpeg/libavcodec/tscc2.c b/ffmpeg/libavcodec/tscc2.c index f275ff9..bdc7525 100644 --- a/ffmpeg/libavcodec/tscc2.c +++ b/ffmpeg/libavcodec/tscc2.c @@ -33,7 +33,7 @@ typedef struct TSCC2Context { AVCodecContext *avctx; - AVFrame pic; + AVFrame *pic; int mb_width, mb_height; uint8_t *slice_quants; int quant[2]; @@ -192,7 +192,8 @@ static int tscc2_decode_slice(TSCC2Context *c, int mb_y, int i, mb_x, q, ret; int off; - init_get_bits(&c->gb, buf, buf_size * 8); + if ((ret = init_get_bits8(&c->gb, buf, buf_size)) < 0) + return ret; for (mb_x = 0; mb_x < c->mb_width; mb_x++) { q = c->slice_quants[mb_x + c->mb_width * mb_y]; @@ -200,9 +201,9 @@ static int tscc2_decode_slice(TSCC2Context *c, int mb_y, if (q == 0 || q == 3) // skip block continue; for (i = 0; i < 3; i++) { - off = mb_x * 16 + mb_y * 8 * c->pic.linesize[i]; + off = mb_x * 16 + mb_y * 8 * c->pic->linesize[i]; ret = tscc2_decode_mb(c, c->q[q - 1], c->quant[q - 1] - 2, - c->pic.data[i] + off, c->pic.linesize[i], i); + c->pic->data[i] + off, c->pic->linesize[i], i); if (ret) return ret; } @@ -230,12 +231,13 @@ static int tscc2_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } - if ((ret = ff_reget_buffer(avctx, &c->pic)) < 0) + if ((ret = ff_reget_buffer(avctx, c->pic)) < 0) { return ret; + } if (frame_type == 0) { *got_frame = 1; - if ((ret = av_frame_ref(data, &c->pic)) < 0) + if ((ret = av_frame_ref(data, c->pic)) < 0) return ret; return buf_size; @@ -320,13 +322,24 @@ static int tscc2_decode_frame(AVCodecContext *avctx, void *data, } *got_frame = 1; - if ((ret = av_frame_ref(data, &c->pic)) < 0) + if ((ret = av_frame_ref(data, c->pic)) < 0) return ret; /* always report that the buffer was completely consumed */ return buf_size; } +static av_cold int tscc2_decode_end(AVCodecContext *avctx) +{ + TSCC2Context * const c = avctx->priv_data; + + av_frame_free(&c->pic); + av_freep(&c->slice_quants); + free_vlcs(c); + + return 0; +} + static av_cold int tscc2_decode_init(AVCodecContext *avctx) { TSCC2Context * const c = avctx->priv_data; @@ -350,22 +363,18 @@ static av_cold int tscc2_decode_init(AVCodecContext *avctx) return AVERROR(ENOMEM); } - return 0; -} - -static av_cold int tscc2_decode_end(AVCodecContext *avctx) -{ - TSCC2Context * const c = avctx->priv_data; - - av_frame_unref(&c->pic); - av_freep(&c->slice_quants); - free_vlcs(c); + c->pic = av_frame_alloc(); + if (!c->pic) { + tscc2_decode_end(avctx); + return AVERROR(ENOMEM); + } return 0; } AVCodec ff_tscc2_decoder = { .name = "tscc2", + .long_name = NULL_IF_CONFIG_SMALL("TechSmith Screen Codec 2"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_TSCC2, .priv_data_size = sizeof(TSCC2Context), @@ -373,5 +382,4 @@ AVCodec ff_tscc2_decoder = { .close = tscc2_decode_end, .decode = tscc2_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("TechSmith Screen Codec 2"), }; diff --git a/ffmpeg/libavcodec/tta.c b/ffmpeg/libavcodec/tta.c index 8b4ca5a..b917881 100644 --- a/ffmpeg/libavcodec/tta.c +++ b/ffmpeg/libavcodec/tta.c @@ -28,10 +28,12 @@ */ #define BITSTREAM_READER_LE -//#define DEBUG #include +#include "ttadata.h" #include "avcodec.h" #include "get_bits.h" +#include "thread.h" +#include "unary.h" #include "internal.h" #include "libavutil/crc.h" #include "libavutil/intreadwrite.h" @@ -40,28 +42,9 @@ #define FORMAT_SIMPLE 1 #define FORMAT_ENCRYPTED 2 -#define MAX_ORDER 16 -typedef struct TTAFilter { - int32_t shift, round, error; - int32_t qm[MAX_ORDER]; - int32_t dx[MAX_ORDER]; - int32_t dl[MAX_ORDER]; -} TTAFilter; - -typedef struct TTARice { - uint32_t k0, k1, sum0, sum1; -} TTARice; - -typedef struct TTAChannel { - int32_t predictor; - TTAFilter filter; - TTARice rice; -} TTAChannel; - typedef struct TTAContext { AVClass *class; AVCodecContext *avctx; - GetBitContext gb; const AVCRC *crc_table; int format, channels, bps; @@ -75,40 +58,6 @@ typedef struct TTAContext { TTAChannel *ch_ctx; } TTAContext; -static const uint32_t shift_1[] = { - 0x00000001, 0x00000002, 0x00000004, 0x00000008, - 0x00000010, 0x00000020, 0x00000040, 0x00000080, - 0x00000100, 0x00000200, 0x00000400, 0x00000800, - 0x00001000, 0x00002000, 0x00004000, 0x00008000, - 0x00010000, 0x00020000, 0x00040000, 0x00080000, - 0x00100000, 0x00200000, 0x00400000, 0x00800000, - 0x01000000, 0x02000000, 0x04000000, 0x08000000, - 0x10000000, 0x20000000, 0x40000000, 0x80000000, - 0x80000000, 0x80000000, 0x80000000, 0x80000000, - 0x80000000, 0x80000000, 0x80000000, 0x80000000 -}; - -static const uint32_t * const shift_16 = shift_1 + 4; - -static const int32_t ttafilter_configs[4] = { - 10, - 9, - 10, - 12 -}; - -static void ttafilter_init(TTAContext *s, TTAFilter *c, int32_t shift) { - memset(c, 0, sizeof(TTAFilter)); - if (s->format == FORMAT_ENCRYPTED) { - int i; - for (i = 0; i < 8; i++) - c->qm[i] = sign_extend(s->crc_pass[i], 8); - } - c->shift = shift; - c->round = shift_1[shift-1]; -// c->round = 1 << (shift - 1); -} - static inline void ttafilter_process(TTAFilter *c, int32_t *in) { register int32_t *dl = c->dl, *qm = c->qm, *dx = c->dx, sum = c->round; @@ -140,24 +89,6 @@ static inline void ttafilter_process(TTAFilter *c, int32_t *in) dl[5] += dl[6]; dl[4] += dl[5]; } -static void rice_init(TTARice *c, uint32_t k0, uint32_t k1) -{ - c->k0 = k0; - c->k1 = k1; - c->sum0 = shift_16[k0]; - c->sum1 = shift_16[k1]; -} - -static int tta_get_unary(GetBitContext *gb) -{ - int ret = 0; - - // count ones - while (get_bits_left(gb) > 0 && get_bits1(gb)) - ret++; - return ret; -} - static const int64_t tta_channel_layouts[7] = { AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY, @@ -197,29 +128,44 @@ static uint64_t tta_check_crc64(uint8_t *pass) return crc ^ UINT64_MAX; } +static int allocate_buffers(AVCodecContext *avctx) +{ + TTAContext *s = avctx->priv_data; + + if (s->bps < 3) { + s->decode_buffer = av_mallocz(sizeof(int32_t)*s->frame_length*s->channels); + if (!s->decode_buffer) + return AVERROR(ENOMEM); + } else + s->decode_buffer = NULL; + s->ch_ctx = av_malloc(avctx->channels * sizeof(*s->ch_ctx)); + if (!s->ch_ctx) { + av_freep(&s->decode_buffer); + return AVERROR(ENOMEM); + } + + return 0; +} + static av_cold int tta_decode_init(AVCodecContext * avctx) { TTAContext *s = avctx->priv_data; + GetBitContext gb; int total_frames; s->avctx = avctx; - // 30bytes includes a seektable with one frame - if (avctx->extradata_size < 30) + // 30bytes includes TTA1 header + if (avctx->extradata_size < 22) return AVERROR_INVALIDDATA; - init_get_bits(&s->gb, avctx->extradata, avctx->extradata_size * 8); - if (show_bits_long(&s->gb, 32) == AV_RL32("TTA1")) - { - if (avctx->err_recognition & AV_EF_CRCCHECK) { - s->crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE); - tta_check_crc(s, avctx->extradata, 18); - } - + s->crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE); + init_get_bits8(&gb, avctx->extradata, avctx->extradata_size); + if (show_bits_long(&gb, 32) == AV_RL32("TTA1")) { /* signature */ - skip_bits_long(&s->gb, 32); + skip_bits_long(&gb, 32); - s->format = get_bits(&s->gb, 16); + s->format = get_bits(&gb, 16); if (s->format > 2) { av_log(avctx, AV_LOG_ERROR, "Invalid format\n"); return AVERROR_INVALIDDATA; @@ -231,14 +177,14 @@ static av_cold int tta_decode_init(AVCodecContext * avctx) } AV_WL64(s->crc_pass, tta_check_crc64(s->pass)); } - avctx->channels = s->channels = get_bits(&s->gb, 16); + avctx->channels = s->channels = get_bits(&gb, 16); if (s->channels > 1 && s->channels < 9) avctx->channel_layout = tta_channel_layouts[s->channels-2]; - avctx->bits_per_raw_sample = get_bits(&s->gb, 16); + avctx->bits_per_raw_sample = get_bits(&gb, 16); s->bps = (avctx->bits_per_raw_sample + 7) / 8; - avctx->sample_rate = get_bits_long(&s->gb, 32); - s->data_length = get_bits_long(&s->gb, 32); - skip_bits_long(&s->gb, 32); // CRC32 of header + avctx->sample_rate = get_bits_long(&gb, 32); + s->data_length = get_bits_long(&gb, 32); + skip_bits_long(&gb, 32); // CRC32 of header if (s->channels == 0) { av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n"); @@ -279,62 +225,43 @@ static av_cold int tta_decode_init(AVCodecContext * avctx) av_log(avctx, AV_LOG_DEBUG, "data_length: %d frame_length: %d last: %d total: %d\n", s->data_length, s->frame_length, s->last_frame_length, total_frames); - // FIXME: seek table - if (avctx->extradata_size <= 26 || total_frames > INT_MAX / 4 || - avctx->extradata_size - 26 < total_frames * 4) - av_log(avctx, AV_LOG_WARNING, "Seek table missing or too small\n"); - else if (avctx->err_recognition & AV_EF_CRCCHECK) { - if (tta_check_crc(s, avctx->extradata + 22, total_frames * 4)) - return AVERROR_INVALIDDATA; - } - skip_bits_long(&s->gb, 32 * total_frames); - skip_bits_long(&s->gb, 32); // CRC32 of seektable - if(s->frame_length >= UINT_MAX / (s->channels * sizeof(int32_t))){ av_log(avctx, AV_LOG_ERROR, "frame_length too large\n"); return AVERROR_INVALIDDATA; } - - if (s->bps < 3) { - s->decode_buffer = av_mallocz(sizeof(int32_t)*s->frame_length*s->channels); - if (!s->decode_buffer) - return AVERROR(ENOMEM); - } else - s->decode_buffer = NULL; - s->ch_ctx = av_malloc(avctx->channels * sizeof(*s->ch_ctx)); - if (!s->ch_ctx) { - av_freep(&s->decode_buffer); - return AVERROR(ENOMEM); - } } else { av_log(avctx, AV_LOG_ERROR, "Wrong extradata present\n"); return AVERROR_INVALIDDATA; } - return 0; + return allocate_buffers(avctx); } static int tta_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { AVFrame *frame = data; + ThreadFrame tframe = { .f = data }; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; TTAContext *s = avctx->priv_data; + GetBitContext gb; int i, ret; int cur_chan = 0, framelen = s->frame_length; int32_t *p; if (avctx->err_recognition & AV_EF_CRCCHECK) { - if (buf_size < 4 || tta_check_crc(s, buf, buf_size - 4)) + if (buf_size < 4 || + (tta_check_crc(s, buf, buf_size - 4) && avctx->err_recognition & AV_EF_EXPLODE)) return AVERROR_INVALIDDATA; } - init_get_bits(&s->gb, buf, buf_size*8); + if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0) + return ret; /* get output buffer */ frame->nb_samples = framelen; - if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0) return ret; // decode directly to output buffer for 24-bit sample format @@ -343,9 +270,15 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, // init per channel states for (i = 0; i < s->channels; i++) { + TTAFilter *filter = &s->ch_ctx[i].filter; s->ch_ctx[i].predictor = 0; - ttafilter_init(s, &s->ch_ctx[i].filter, ttafilter_configs[s->bps-1]); - rice_init(&s->ch_ctx[i].rice, 10, 10); + ff_tta_filter_init(filter, ff_tta_filter_configs[s->bps-1]); + if (s->format == FORMAT_ENCRYPTED) { + int i; + for (i = 0; i < 8; i++) + filter->qm[i] = sign_extend(s->crc_pass[i], 8); + } + ff_tta_rice_init(&s->ch_ctx[i].rice, 10, 10); } i = 0; @@ -356,7 +289,7 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, uint32_t unary, depth, k; int32_t value; - unary = tta_get_unary(&s->gb); + unary = get_unary(&gb, 0, get_bits_left(&gb)); if (unary == 0) { depth = 0; @@ -367,7 +300,7 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, unary--; } - if (get_bits_left(&s->gb) < k) { + if (get_bits_left(&gb) < k) { ret = AVERROR_INVALIDDATA; goto error; } @@ -377,7 +310,7 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, ret = AVERROR_INVALIDDATA; goto error; } - value = (unary << k) + get_bits(&s->gb, k); + value = (unary << k) + get_bits(&gb, k); } else value = unary; @@ -385,16 +318,16 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, switch (depth) { case 1: rice->sum1 += value - (rice->sum1 >> 4); - if (rice->k1 > 0 && rice->sum1 < shift_16[rice->k1]) + if (rice->k1 > 0 && rice->sum1 < ff_tta_shift_16[rice->k1]) rice->k1--; - else if(rice->sum1 > shift_16[rice->k1 + 1]) + else if(rice->sum1 > ff_tta_shift_16[rice->k1 + 1]) rice->k1++; - value += shift_1[rice->k0]; + value += ff_tta_shift_1[rice->k0]; default: rice->sum0 += value - (rice->sum0 >> 4); - if (rice->k0 > 0 && rice->sum0 < shift_16[rice->k0]) + if (rice->k0 > 0 && rice->sum0 < ff_tta_shift_16[rice->k0]) rice->k0--; - else if(rice->sum0 > shift_16[rice->k0 + 1]) + else if(rice->sum0 > ff_tta_shift_16[rice->k0 + 1]) rice->k0++; } @@ -427,19 +360,19 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, cur_chan = 0; i++; // check for last frame - if (i == s->last_frame_length && get_bits_left(&s->gb) / 8 == 4) { + if (i == s->last_frame_length && get_bits_left(&gb) / 8 == 4) { frame->nb_samples = framelen = s->last_frame_length; break; } } } - align_get_bits(&s->gb); - if (get_bits_left(&s->gb) < 32) { + align_get_bits(&gb); + if (get_bits_left(&gb) < 32) { ret = AVERROR_INVALIDDATA; goto error; } - skip_bits_long(&s->gb, 32); // frame crc + skip_bits_long(&gb, 32); // frame crc // convert to output buffer switch (s->bps) { @@ -458,7 +391,7 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, case 3: { // shift samples for 24-bit sample format int32_t *samples = (int32_t *)frame->data[0]; - for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++) + for (i = 0; i < framelen * s->channels; i++) *samples++ <<= 8; // reset decode buffer s->decode_buffer = NULL; @@ -476,6 +409,13 @@ error: return ret; } +static int init_thread_copy(AVCodecContext *avctx) +{ + TTAContext *s = avctx->priv_data; + s->avctx = avctx; + return allocate_buffers(avctx); +} + static av_cold int tta_decode_close(AVCodecContext *avctx) { TTAContext *s = avctx->priv_data; @@ -503,13 +443,14 @@ static const AVClass tta_decoder_class = { AVCodec ff_tta_decoder = { .name = "tta", + .long_name = NULL_IF_CONFIG_SMALL("TTA (True Audio)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_TTA, .priv_data_size = sizeof(TTAContext), .init = tta_decode_init, .close = tta_decode_close, .decode = tta_decode_frame, - .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("TTA (True Audio)"), + .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy), + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, .priv_class = &tta_decoder_class, }; diff --git a/ffmpeg/libavcodec/twinvq.c b/ffmpeg/libavcodec/twinvq.c index 8b9c79f..08a7a9f 100644 --- a/ffmpeg/libavcodec/twinvq.c +++ b/ffmpeg/libavcodec/twinvq.c @@ -19,219 +19,23 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include +#include + #include "libavutil/channel_layout.h" #include "libavutil/float_dsp.h" #include "avcodec.h" -#include "get_bits.h" #include "fft.h" #include "internal.h" #include "lsp.h" #include "sinewin.h" - -#include -#include - -#include "twinvq_data.h" - -enum FrameType { - FT_SHORT = 0, ///< Short frame (divided in n sub-blocks) - FT_MEDIUM, ///< Medium frame (divided in mmtab; - int size_s = mtab->size / mtab->fmode[FT_SHORT].sub; + const TwinVQModeTab *mtab = tctx->mtab; + int size_s = mtab->size / mtab->fmode[TWINVQ_FT_SHORT].sub; - for (i = 0; i < size_s/2; i++) { + for (i = 0; i < size_s / 2; i++) { float cos_i = tctx->cos_tabs[0][i]; - lpc[i] = eval_lpc_spectrum(cos_vals, cos_i, mtab->n_lsp); - lpc[size_s-i-1] = eval_lpc_spectrum(cos_vals, -cos_i, mtab->n_lsp); + lpc[i] = eval_lpc_spectrum(cos_vals, cos_i, mtab->n_lsp); + lpc[size_s - i - 1] = eval_lpc_spectrum(cos_vals, -cos_i, mtab->n_lsp); } } static void interpolate(float *out, float v1, float v2, int size) { int i; - float step = (v1 - v2)/(size + 1); + float step = (v1 - v2) / (size + 1); for (i = 0; i < size; i++) { - v2 += step; + v2 += step; out[i] = v2; } } static inline float get_cos(int idx, int part, const float *cos_tab, int size) { - return part ? -cos_tab[size - idx - 1] : - cos_tab[ idx ]; + return part ? -cos_tab[size - idx - 1] + : cos_tab[idx]; } /** @@ -303,19 +107,19 @@ static inline float get_cos(int idx, int part, const float *cos_tab, int size) * unexplained condition. * * @param step the size of a block "siiiibiiii" - * @param in the cosinus of the LSP data - * @param part is 0 for 0...PI (positive cossinus values) and 1 for PI...2PI - (negative cossinus values) + * @param in the cosine of the LSP data + * @param part is 0 for 0...PI (positive cosine values) and 1 for PI...2PI + * (negative cosine values) * @param size the size of the whole output */ -static inline void eval_lpcenv_or_interp(TwinContext *tctx, - enum FrameType ftype, +static inline void eval_lpcenv_or_interp(TwinVQContext *tctx, + enum TwinVQFrameType ftype, float *out, const float *in, int size, int step, int part) { int i; - const ModeTab *mtab = tctx->mtab; - const float *cos_tab = tctx->cos_tabs[ftype]; + const TwinVQModeTab *mtab = tctx->mtab; + const float *cos_tab = tctx->cos_tabs[ftype]; // Fill the 's' for (i = 0; i < size; i += step) @@ -325,33 +129,39 @@ static inline void eval_lpcenv_or_interp(TwinContext *tctx, mtab->n_lsp); // Fill the 'iiiibiiii' - for (i = step; i <= size - 2*step; i += step) { - if (out[i + step] + out[i - step] > 1.95*out[i] || - out[i + step] >= out[i - step]) { - interpolate(out + i - step + 1, out[i], out[i-step], step - 1); + for (i = step; i <= size - 2 * step; i += step) { + if (out[i + step] + out[i - step] > 1.95 * out[i] || + out[i + step] >= out[i - step]) { + interpolate(out + i - step + 1, out[i], out[i - step], step - 1); } else { - out[i - step/2] = + out[i - step / 2] = eval_lpc_spectrum(in, - get_cos(i-step/2, part, cos_tab, size), + get_cos(i - step / 2, part, cos_tab, size), mtab->n_lsp); - interpolate(out + i - step + 1, out[i-step/2], out[i-step ], step/2 - 1); - interpolate(out + i - step/2 + 1, out[i ], out[i-step/2], step/2 - 1); + interpolate(out + i - step + 1, out[i - step / 2], + out[i - step], step / 2 - 1); + interpolate(out + i - step / 2 + 1, out[i], + out[i - step / 2], step / 2 - 1); } } - interpolate(out + size - 2*step + 1, out[size-step], out[size - 2*step], step - 1); + interpolate(out + size - 2 * step + 1, out[size - step], + out[size - 2 * step], step - 1); } -static void eval_lpcenv_2parts(TwinContext *tctx, enum FrameType ftype, +static void eval_lpcenv_2parts(TwinVQContext *tctx, enum TwinVQFrameType ftype, const float *buf, float *lpc, int size, int step) { - eval_lpcenv_or_interp(tctx, ftype, lpc , buf, size/2, step, 0); - eval_lpcenv_or_interp(tctx, ftype, lpc + size/2, buf, size/2, 2*step, 1); + eval_lpcenv_or_interp(tctx, ftype, lpc, buf, size / 2, step, 0); + eval_lpcenv_or_interp(tctx, ftype, lpc + size / 2, buf, size / 2, + 2 * step, 1); - interpolate(lpc+size/2-step+1, lpc[size/2], lpc[size/2-step], step); + interpolate(lpc + size / 2 - step + 1, lpc[size / 2], + lpc[size / 2 - step], step); - memset_float(lpc + size - 2*step + 1, lpc[size - 2*step], 2*step - 1); + twinvq_memset_float(lpc + size - 2 * step + 1, lpc[size - 2 * step], + 2 * step - 1); } /** @@ -359,8 +169,8 @@ static void eval_lpcenv_2parts(TwinContext *tctx, enum FrameType ftype, * bitstream, sum the corresponding vectors and write the result to *out * after permutation. */ -static void dequant(TwinContext *tctx, GetBitContext *gb, float *out, - enum FrameType ftype, +static void dequant(TwinVQContext *tctx, const uint8_t *cb_bits, float *out, + enum TwinVQFrameType ftype, const int16_t *cb0, const int16_t *cb1, int cb_len) { int pos = 0; @@ -375,156 +185,58 @@ static void dequant(TwinContext *tctx, GetBitContext *gb, float *out, int bitstream_second_part = (i >= tctx->bits_main_spec_change[ftype]); int bits = tctx->bits_main_spec[0][ftype][bitstream_second_part]; + tmp0 = *cb_bits++; if (bits == 7) { - if (get_bits1(gb)) + if (tmp0 & 0x40) sign0 = -1; - bits = 6; + tmp0 &= 0x3F; } - tmp0 = get_bits(gb, bits); bits = tctx->bits_main_spec[1][ftype][bitstream_second_part]; - + tmp1 = *cb_bits++; if (bits == 7) { - if (get_bits1(gb)) + if (tmp1 & 0x40) sign1 = -1; - - bits = 6; + tmp1 &= 0x3F; } - tmp1 = get_bits(gb, bits); - tab0 = cb0 + tmp0*cb_len; - tab1 = cb1 + tmp1*cb_len; + tab0 = cb0 + tmp0 * cb_len; + tab1 = cb1 + tmp1 * cb_len; for (j = 0; j < length; j++) - out[tctx->permut[ftype][pos+j]] = sign0*tab0[j] + sign1*tab1[j]; + out[tctx->permut[ftype][pos + j]] = sign0 * tab0[j] + + sign1 * tab1[j]; pos += length; } - -} - -static inline float mulawinv(float y, float clip, float mu) -{ - y = av_clipf(y/clip, -1, 1); - return clip * FFSIGN(y) * (exp(log(1+mu) * fabs(y)) - 1) / mu; -} - -/** - * Evaluate a*b/400 rounded to the nearest integer. When, for example, - * a*b == 200 and the nearest integer is ill-defined, use a table to emulate - * the following broken float-based implementation used by the binary decoder: - * - * @code - * static int very_broken_op(int a, int b) - * { - * static float test; // Ugh, force gcc to do the division first... - * - * test = a/400.; - * return b * test + 0.5; - * } - * @endcode - * - * @note if this function is replaced by just ROUNDED_DIV(a*b,400.), the stddev - * between the original file (before encoding with Yamaha encoder) and the - * decoded output increases, which leads one to believe that the encoder expects - * exactly this broken calculation. - */ -static int very_broken_op(int a, int b) -{ - int x = a*b + 200; - int size; - const uint8_t *rtab; - - if (x%400 || b%5) - return x/400; - - x /= 400; - - size = tabs[b/5].size; - rtab = tabs[b/5].tab; - return x - rtab[size*av_log2(2*(x - 1)/size)+(x - 1)%size]; -} - -/** - * Sum to data a periodic peak of a given period, width and shape. - * - * @param period the period of the peak divised by 400.0 - */ -static void add_peak(int period, int width, const float *shape, - float ppc_gain, float *speech, int len) -{ - int i, j; - - const float *shape_end = shape + len; - int center; - - // First peak centered around zero - for (i = 0; i < width/2; i++) - speech[i] += ppc_gain * *shape++; - - for (i = 1; i < ROUNDED_DIV(len,width) ; i++) { - center = very_broken_op(period, i); - for (j = -width/2; j < (width+1)/2; j++) - speech[j+center] += ppc_gain * *shape++; - } - - // For the last block, be careful not to go beyond the end of the buffer - center = very_broken_op(period, i); - for (j = -width/2; j < (width + 1)/2 && shape < shape_end; j++) - speech[j+center] += ppc_gain * *shape++; } -static void decode_ppc(TwinContext *tctx, int period_coef, const float *shape, - float ppc_gain, float *speech) +static void dec_gain(TwinVQContext *tctx, + enum TwinVQFrameType ftype, float *out) { - const ModeTab *mtab = tctx->mtab; - int isampf = tctx->avctx->sample_rate/1000; - int ibps = tctx->avctx->bit_rate/(1000 * tctx->avctx->channels); - int min_period = ROUNDED_DIV( 40*2*mtab->size, isampf); - int max_period = ROUNDED_DIV(6*40*2*mtab->size, isampf); - int period_range = max_period - min_period; - - // This is actually the period multiplied by 400. It is just linearly coded - // between its maximum and minimum value. - int period = min_period + - ROUNDED_DIV(period_coef*period_range, (1 << mtab->ppc_period_bit) - 1); - int width; - - if (isampf == 22 && ibps == 32) { - // For some unknown reason, NTT decided to code this case differently... - width = ROUNDED_DIV((period + 800)* mtab->peak_per2wid, 400*mtab->size); - } else - width = (period )* mtab->peak_per2wid/(400*mtab->size); - - add_peak(period, width, shape, ppc_gain, speech, mtab->ppc_shape_len); -} - -static void dec_gain(TwinContext *tctx, GetBitContext *gb, enum FrameType ftype, - float *out) -{ - const ModeTab *mtab = tctx->mtab; + const TwinVQModeTab *mtab = tctx->mtab; + const TwinVQFrameData *bits = &tctx->bits[tctx->cur_frame]; int i, j; - int sub = mtab->fmode[ftype].sub; - float step = AMP_MAX / ((1 << GAIN_BITS) - 1); - float sub_step = SUB_AMP_MAX / ((1 << SUB_GAIN_BITS) - 1); + int sub = mtab->fmode[ftype].sub; + float step = TWINVQ_AMP_MAX / ((1 << TWINVQ_GAIN_BITS) - 1); + float sub_step = TWINVQ_SUB_AMP_MAX / ((1 << TWINVQ_SUB_GAIN_BITS) - 1); - if (ftype == FT_LONG) { + if (ftype == TWINVQ_FT_LONG) { for (i = 0; i < tctx->avctx->channels; i++) - out[i] = (1./(1<<13)) * - mulawinv(step * 0.5 + step * get_bits(gb, GAIN_BITS), - AMP_MAX, MULAW_MU); + out[i] = (1.0 / (1 << 13)) * + twinvq_mulawinv(step * 0.5 + step * bits->gain_bits[i], + TWINVQ_AMP_MAX, TWINVQ_MULAW_MU); } else { for (i = 0; i < tctx->avctx->channels; i++) { - float val = (1./(1<<23)) * - mulawinv(step * 0.5 + step * get_bits(gb, GAIN_BITS), - AMP_MAX, MULAW_MU); - - for (j = 0; j < sub; j++) { - out[i*sub + j] = - val*mulawinv(sub_step* 0.5 + - sub_step* get_bits(gb, SUB_GAIN_BITS), - SUB_AMP_MAX, MULAW_MU); - } + float val = (1.0 / (1 << 23)) * + twinvq_mulawinv(step * 0.5 + step * bits->gain_bits[i], + TWINVQ_AMP_MAX, TWINVQ_MULAW_MU); + + for (j = 0; j < sub; j++) + out[i * sub + j] = + val * twinvq_mulawinv(sub_step * 0.5 + + sub_step * bits->sub_gain_bits[i * sub + j], + TWINVQ_SUB_AMP_MAX, TWINVQ_MULAW_MU); } } } @@ -540,23 +252,23 @@ static void rearrange_lsp(int order, float *lsp, float min_dist) int i; float min_dist2 = min_dist * 0.5; for (i = 1; i < order; i++) - if (lsp[i] - lsp[i-1] < min_dist) { - float avg = (lsp[i] + lsp[i-1]) * 0.5; + if (lsp[i] - lsp[i - 1] < min_dist) { + float avg = (lsp[i] + lsp[i - 1]) * 0.5; - lsp[i-1] = avg - min_dist2; - lsp[i ] = avg + min_dist2; + lsp[i - 1] = avg - min_dist2; + lsp[i] = avg + min_dist2; } } -static void decode_lsp(TwinContext *tctx, int lpc_idx1, uint8_t *lpc_idx2, +static void decode_lsp(TwinVQContext *tctx, int lpc_idx1, uint8_t *lpc_idx2, int lpc_hist_idx, float *lsp, float *hist) { - const ModeTab *mtab = tctx->mtab; + const TwinVQModeTab *mtab = tctx->mtab; int i, j; - const float *cb = mtab->lspcodebook; - const float *cb2 = cb + (1 << mtab->lsp_bit1)*mtab->n_lsp; - const float *cb3 = cb2 + (1 << mtab->lsp_bit2)*mtab->n_lsp; + const float *cb = mtab->lspcodebook; + const float *cb2 = cb + (1 << mtab->lsp_bit1) * mtab->n_lsp; + const float *cb3 = cb2 + (1 << mtab->lsp_bit2) * mtab->n_lsp; const int8_t funny_rounding[4] = { -2, @@ -567,17 +279,18 @@ static void decode_lsp(TwinContext *tctx, int lpc_idx1, uint8_t *lpc_idx2, j = 0; for (i = 0; i < mtab->lsp_split; i++) { - int chunk_end = ((i + 1)*mtab->n_lsp + funny_rounding[i])/mtab->lsp_split; + int chunk_end = ((i + 1) * mtab->n_lsp + funny_rounding[i]) / + mtab->lsp_split; for (; j < chunk_end; j++) - lsp[j] = cb [lpc_idx1 * mtab->n_lsp + j] + + lsp[j] = cb[lpc_idx1 * mtab->n_lsp + j] + cb2[lpc_idx2[i] * mtab->n_lsp + j]; } rearrange_lsp(mtab->n_lsp, lsp, 0.0001); for (i = 0; i < mtab->n_lsp; i++) { - float tmp1 = 1. - cb3[lpc_hist_idx*mtab->n_lsp + i]; - float tmp2 = hist[i] * cb3[lpc_hist_idx*mtab->n_lsp + i]; + float tmp1 = 1.0 - cb3[lpc_hist_idx * mtab->n_lsp + i]; + float tmp2 = hist[i] * cb3[lpc_hist_idx * mtab->n_lsp + i]; hist[i] = lsp[i]; lsp[i] = lsp[i] * tmp1 + tmp2; } @@ -587,96 +300,94 @@ static void decode_lsp(TwinContext *tctx, int lpc_idx1, uint8_t *lpc_idx2, ff_sort_nearly_sorted_floats(lsp, mtab->n_lsp); } -static void dec_lpc_spectrum_inv(TwinContext *tctx, float *lsp, - enum FrameType ftype, float *lpc) +static void dec_lpc_spectrum_inv(TwinVQContext *tctx, float *lsp, + enum TwinVQFrameType ftype, float *lpc) { int i; int size = tctx->mtab->size / tctx->mtab->fmode[ftype].sub; for (i = 0; i < tctx->mtab->n_lsp; i++) - lsp[i] = 2*cos(lsp[i]); + lsp[i] = 2 * cos(lsp[i]); switch (ftype) { - case FT_LONG: + case TWINVQ_FT_LONG: eval_lpcenv_2parts(tctx, ftype, lsp, lpc, size, 8); break; - case FT_MEDIUM: + case TWINVQ_FT_MEDIUM: eval_lpcenv_2parts(tctx, ftype, lsp, lpc, size, 2); break; - case FT_SHORT: + case TWINVQ_FT_SHORT: eval_lpcenv(tctx, lsp, lpc); break; } } -static void imdct_and_window(TwinContext *tctx, enum FrameType ftype, int wtype, - float *in, float *prev, int ch) +static const uint8_t wtype_to_wsize[] = { 0, 0, 2, 2, 2, 1, 0, 1, 1 }; + +static void imdct_and_window(TwinVQContext *tctx, enum TwinVQFrameType ftype, + int wtype, float *in, float *prev, int ch) { FFTContext *mdct = &tctx->mdct_ctx[ftype]; - const ModeTab *mtab = tctx->mtab; + const TwinVQModeTab *mtab = tctx->mtab; int bsize = mtab->size / mtab->fmode[ftype].sub; int size = mtab->size; float *buf1 = tctx->tmp_buf; - int j; - int wsize; // Window size - float *out = tctx->curr_frame + 2*ch*mtab->size; + int j, first_wsize, wsize; // Window size + float *out = tctx->curr_frame + 2 * ch * mtab->size; float *out2 = out; float *prev_buf; - int first_wsize; - - static const uint8_t wtype_to_wsize[] = {0, 0, 2, 2, 2, 1, 0, 1, 1}; int types_sizes[] = { - mtab->size / mtab->fmode[FT_LONG ].sub, - mtab->size / mtab->fmode[FT_MEDIUM].sub, - mtab->size / (2*mtab->fmode[FT_SHORT ].sub), + mtab->size / mtab->fmode[TWINVQ_FT_LONG].sub, + mtab->size / mtab->fmode[TWINVQ_FT_MEDIUM].sub, + mtab->size / (mtab->fmode[TWINVQ_FT_SHORT].sub * 2), }; - wsize = types_sizes[wtype_to_wsize[wtype]]; + wsize = types_sizes[wtype_to_wsize[wtype]]; first_wsize = wsize; - prev_buf = prev + (size - bsize)/2; + prev_buf = prev + (size - bsize) / 2; for (j = 0; j < mtab->fmode[ftype].sub; j++) { - int sub_wtype = ftype == FT_MEDIUM ? 8 : wtype; + int sub_wtype = ftype == TWINVQ_FT_MEDIUM ? 8 : wtype; if (!j && wtype == 4) sub_wtype = 4; - else if (j == mtab->fmode[ftype].sub-1 && wtype == 7) + else if (j == mtab->fmode[ftype].sub - 1 && wtype == 7) sub_wtype = 7; wsize = types_sizes[wtype_to_wsize[sub_wtype]]; - mdct->imdct_half(mdct, buf1 + bsize*j, in + bsize*j); + mdct->imdct_half(mdct, buf1 + bsize * j, in + bsize * j); - tctx->fdsp.vector_fmul_window(out2, prev_buf + (bsize-wsize) / 2, + tctx->fdsp.vector_fmul_window(out2, prev_buf + (bsize - wsize) / 2, buf1 + bsize * j, ff_sine_windows[av_log2(wsize)], wsize / 2); out2 += wsize; - memcpy(out2, buf1 + bsize*j + wsize/2, (bsize - wsize/2)*sizeof(float)); + memcpy(out2, buf1 + bsize * j + wsize / 2, + (bsize - wsize / 2) * sizeof(float)); - out2 += ftype == FT_MEDIUM ? (bsize-wsize)/2 : bsize - wsize; + out2 += ftype == TWINVQ_FT_MEDIUM ? (bsize - wsize) / 2 : bsize - wsize; - prev_buf = buf1 + bsize*j + bsize/2; + prev_buf = buf1 + bsize * j + bsize / 2; } - tctx->last_block_pos[ch] = (size + first_wsize)/2; + tctx->last_block_pos[ch] = (size + first_wsize) / 2; } -static void imdct_output(TwinContext *tctx, enum FrameType ftype, int wtype, - float **out) +static void imdct_output(TwinVQContext *tctx, enum TwinVQFrameType ftype, + int wtype, float **out, int offset) { - const ModeTab *mtab = tctx->mtab; - int size1, size2; - float *prev_buf = tctx->prev_frame + tctx->last_block_pos[0]; - int i; + const TwinVQModeTab *mtab = tctx->mtab; + float *prev_buf = tctx->prev_frame + tctx->last_block_pos[0]; + int size1, size2, i; + float *out1, *out2; - for (i = 0; i < tctx->avctx->channels; i++) { + for (i = 0; i < tctx->avctx->channels; i++) imdct_and_window(tctx, ftype, wtype, - tctx->spectrum + i*mtab->size, - prev_buf + 2*i*mtab->size, + tctx->spectrum + i * mtab->size, + prev_buf + 2 * i * mtab->size, i); - } if (!out) return; @@ -684,118 +395,68 @@ static void imdct_output(TwinContext *tctx, enum FrameType ftype, int wtype, size2 = tctx->last_block_pos[0]; size1 = mtab->size - size2; - memcpy(&out[0][0 ], prev_buf, size1 * sizeof(out[0][0])); - memcpy(&out[0][size1], tctx->curr_frame, size2 * sizeof(out[0][0])); + out1 = &out[0][0] + offset; + memcpy(out1, prev_buf, size1 * sizeof(*out1)); + memcpy(out1 + size1, tctx->curr_frame, size2 * sizeof(*out1)); if (tctx->avctx->channels == 2) { - memcpy(&out[1][0], &prev_buf[2*mtab->size], size1 * sizeof(out[1][0])); - memcpy(&out[1][size1], &tctx->curr_frame[2*mtab->size], size2 * sizeof(out[1][0])); - tctx->fdsp.butterflies_float(out[0], out[1], mtab->size); + out2 = &out[1][0] + offset; + memcpy(out2, &prev_buf[2 * mtab->size], + size1 * sizeof(*out2)); + memcpy(out2 + size1, &tctx->curr_frame[2 * mtab->size], + size2 * sizeof(*out2)); + tctx->fdsp.butterflies_float(out1, out2, mtab->size); } } -static void dec_bark_env(TwinContext *tctx, const uint8_t *in, int use_hist, - int ch, float *out, float gain, enum FrameType ftype) -{ - const ModeTab *mtab = tctx->mtab; - int i,j; - float *hist = tctx->bark_hist[ftype][ch]; - float val = ((const float []) {0.4, 0.35, 0.28})[ftype]; - int bark_n_coef = mtab->fmode[ftype].bark_n_coef; - int fw_cb_len = mtab->fmode[ftype].bark_env_size / bark_n_coef; - int idx = 0; - - for (i = 0; i < fw_cb_len; i++) - for (j = 0; j < bark_n_coef; j++, idx++) { - float tmp2 = - mtab->fmode[ftype].bark_cb[fw_cb_len*in[j] + i] * (1./4096); - float st = use_hist ? - (1. - val) * tmp2 + val*hist[idx] + 1. : tmp2 + 1.; - - hist[idx] = tmp2; - if (st < -1.) st = 1.; - - memset_float(out, st * gain, mtab->fmode[ftype].bark_tab[idx]); - out += mtab->fmode[ftype].bark_tab[idx]; - } - -} - -static void read_and_decode_spectrum(TwinContext *tctx, GetBitContext *gb, - float *out, enum FrameType ftype) +static void read_and_decode_spectrum(TwinVQContext *tctx, float *out, + enum TwinVQFrameType ftype) { - const ModeTab *mtab = tctx->mtab; - int channels = tctx->avctx->channels; - int sub = mtab->fmode[ftype].sub; + const TwinVQModeTab *mtab = tctx->mtab; + TwinVQFrameData *bits = &tctx->bits[tctx->cur_frame]; + int channels = tctx->avctx->channels; + int sub = mtab->fmode[ftype].sub; int block_size = mtab->size / sub; - float gain[CHANNELS_MAX*SUBBLOCKS_MAX]; - float ppc_shape[PPC_SHAPE_LEN_MAX * CHANNELS_MAX * 4]; - uint8_t bark1[CHANNELS_MAX][SUBBLOCKS_MAX][BARK_N_COEF_MAX]; - uint8_t bark_use_hist[CHANNELS_MAX][SUBBLOCKS_MAX]; + float gain[TWINVQ_CHANNELS_MAX * TWINVQ_SUBBLOCKS_MAX]; + float ppc_shape[TWINVQ_PPC_SHAPE_LEN_MAX * TWINVQ_CHANNELS_MAX * 4]; - uint8_t lpc_idx1[CHANNELS_MAX]; - uint8_t lpc_idx2[CHANNELS_MAX][LSP_SPLIT_MAX]; - uint8_t lpc_hist_idx[CHANNELS_MAX]; - - int i, j, k; + int i, j; - dequant(tctx, gb, out, ftype, + dequant(tctx, bits->main_coeffs, out, ftype, mtab->fmode[ftype].cb0, mtab->fmode[ftype].cb1, mtab->fmode[ftype].cb_len_read); - for (i = 0; i < channels; i++) - for (j = 0; j < sub; j++) - for (k = 0; k < mtab->fmode[ftype].bark_n_coef; k++) - bark1[i][j][k] = - get_bits(gb, mtab->fmode[ftype].bark_n_bit); - - for (i = 0; i < channels; i++) - for (j = 0; j < sub; j++) - bark_use_hist[i][j] = get_bits1(gb); - - dec_gain(tctx, gb, ftype, gain); - - for (i = 0; i < channels; i++) { - lpc_hist_idx[i] = get_bits(gb, tctx->mtab->lsp_bit0); - lpc_idx1 [i] = get_bits(gb, tctx->mtab->lsp_bit1); - - for (j = 0; j < tctx->mtab->lsp_split; j++) - lpc_idx2[i][j] = get_bits(gb, tctx->mtab->lsp_bit2); - } + dec_gain(tctx, ftype, gain); - if (ftype == FT_LONG) { - int cb_len_p = (tctx->n_div[3] + mtab->ppc_shape_len*channels - 1)/ - tctx->n_div[3]; - dequant(tctx, gb, ppc_shape, FT_PPC, mtab->ppc_shape_cb, - mtab->ppc_shape_cb + cb_len_p*PPC_SHAPE_CB_SIZE, cb_len_p); + if (ftype == TWINVQ_FT_LONG) { + int cb_len_p = (tctx->n_div[3] + mtab->ppc_shape_len * channels - 1) / + tctx->n_div[3]; + dequant(tctx, bits->ppc_coeffs, ppc_shape, + TWINVQ_FT_PPC, mtab->ppc_shape_cb, + mtab->ppc_shape_cb + cb_len_p * TWINVQ_PPC_SHAPE_CB_SIZE, + cb_len_p); } for (i = 0; i < channels; i++) { float *chunk = out + mtab->size * i; - float lsp[LSP_COEFS_MAX]; + float lsp[TWINVQ_LSP_COEFS_MAX]; for (j = 0; j < sub; j++) { - dec_bark_env(tctx, bark1[i][j], bark_use_hist[i][j], i, - tctx->tmp_buf, gain[sub*i+j], ftype); + tctx->dec_bark_env(tctx, bits->bark1[i][j], + bits->bark_use_hist[i][j], i, + tctx->tmp_buf, gain[sub * i + j], ftype); - tctx->fdsp.vector_fmul(chunk + block_size*j, chunk + block_size*j, + tctx->fdsp.vector_fmul(chunk + block_size * j, + chunk + block_size * j, tctx->tmp_buf, block_size); - } - if (ftype == FT_LONG) { - float pgain_step = 25000. / ((1 << mtab->pgain_bit) - 1); - int p_coef = get_bits(gb, tctx->mtab->ppc_period_bit); - int g_coef = get_bits(gb, tctx->mtab->pgain_bit); - float v = 1./8192* - mulawinv(pgain_step*g_coef+ pgain_step/2, 25000., PGAIN_MU); - - decode_ppc(tctx, p_coef, ppc_shape + i*mtab->ppc_shape_len, v, - chunk); - } + if (ftype == TWINVQ_FT_LONG) + tctx->decode_ppc(tctx, bits->p_coef[i], bits->g_coef[i], + ppc_shape + i * mtab->ppc_shape_len, chunk); - decode_lsp(tctx, lpc_idx1[i], lpc_idx2[i], lpc_hist_idx[i], lsp, - tctx->lsp_hist[i]); + decode_lsp(tctx, bits->lpc_idx1[i], bits->lpc_idx2[i], + bits->lpc_hist_idx[i], lsp, tctx->lsp_hist[i]); dec_lpc_spectrum_inv(tctx, lsp, ftype, tctx->tmp_buf); @@ -806,53 +467,51 @@ static void read_and_decode_spectrum(TwinContext *tctx, GetBitContext *gb, } } -static int twin_decode_frame(AVCodecContext * avctx, void *data, - int *got_frame_ptr, AVPacket *avpkt) +const enum TwinVQFrameType ff_twinvq_wtype_to_ftype_table[] = { + TWINVQ_FT_LONG, TWINVQ_FT_LONG, TWINVQ_FT_SHORT, TWINVQ_FT_LONG, + TWINVQ_FT_MEDIUM, TWINVQ_FT_LONG, TWINVQ_FT_LONG, TWINVQ_FT_MEDIUM, + TWINVQ_FT_MEDIUM +}; + +int ff_twinvq_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame_ptr, AVPacket *avpkt) { AVFrame *frame = data; const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - TwinContext *tctx = avctx->priv_data; - GetBitContext gb; - const ModeTab *mtab = tctx->mtab; + int buf_size = avpkt->size; + TwinVQContext *tctx = avctx->priv_data; + const TwinVQModeTab *mtab = tctx->mtab; float **out = NULL; - enum FrameType ftype; - int window_type, ret; - static const enum FrameType wtype_to_ftype_table[] = { - FT_LONG, FT_LONG, FT_SHORT, FT_LONG, - FT_MEDIUM, FT_LONG, FT_LONG, FT_MEDIUM, FT_MEDIUM - }; - - if (buf_size*8 < avctx->bit_rate*mtab->size/avctx->sample_rate + 8) { - av_log(avctx, AV_LOG_ERROR, - "Frame too small (%d bytes). Truncated file?\n", buf_size); - return AVERROR(EINVAL); - } + int ret; /* get output buffer */ if (tctx->discarded_packets >= 2) { - frame->nb_samples = mtab->size; + frame->nb_samples = mtab->size * tctx->frames_per_packet; if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; out = (float **)frame->extended_data; } - init_get_bits(&gb, buf, buf_size * 8); - skip_bits(&gb, get_bits(&gb, 8)); - window_type = get_bits(&gb, WINDOW_TYPE_BITS); - - if (window_type > 8) { - av_log(avctx, AV_LOG_ERROR, "Invalid window type, broken sample?\n"); - return -1; + if (buf_size < avctx->block_align) { + av_log(avctx, AV_LOG_ERROR, + "Frame too small (%d bytes). Truncated file?\n", buf_size); + return AVERROR(EINVAL); } - ftype = wtype_to_ftype_table[window_type]; + if ((ret = tctx->read_bitstream(avctx, tctx, buf, buf_size)) < 0) + return ret; - read_and_decode_spectrum(tctx, &gb, tctx->spectrum, ftype); + for (tctx->cur_frame = 0; tctx->cur_frame < tctx->frames_per_packet; + tctx->cur_frame++) { + read_and_decode_spectrum(tctx, tctx->spectrum, + tctx->bits[tctx->cur_frame].ftype); - imdct_output(tctx, ftype, window_type, out); + imdct_output(tctx, tctx->bits[tctx->cur_frame].ftype, + tctx->bits[tctx->cur_frame].window_type, out, + tctx->cur_frame * mtab->size); - FFSWAP(float*, tctx->curr_frame, tctx->prev_frame); + FFSWAP(float *, tctx->curr_frame, tctx->prev_frame); + } if (tctx->discarded_packets < 2) { tctx->discarded_packets++; @@ -862,25 +521,28 @@ static int twin_decode_frame(AVCodecContext * avctx, void *data, *got_frame_ptr = 1; - return buf_size; + // VQF can deliver packets 1 byte greater than block align + if (buf_size == avctx->block_align + 1) + return buf_size; + return avctx->block_align; } /** * Init IMDCT and windowing tables */ -static av_cold int init_mdct_win(TwinContext *tctx) +static av_cold int init_mdct_win(TwinVQContext *tctx) { int i, j, ret; - const ModeTab *mtab = tctx->mtab; - int size_s = mtab->size / mtab->fmode[FT_SHORT].sub; - int size_m = mtab->size / mtab->fmode[FT_MEDIUM].sub; + const TwinVQModeTab *mtab = tctx->mtab; + int size_s = mtab->size / mtab->fmode[TWINVQ_FT_SHORT].sub; + int size_m = mtab->size / mtab->fmode[TWINVQ_FT_MEDIUM].sub; int channels = tctx->avctx->channels; - float norm = channels == 1 ? 2. : 1.; + float norm = channels == 1 ? 2.0 : 1.0; for (i = 0; i < 3; i++) { - int bsize = tctx->mtab->size/tctx->mtab->fmode[i].sub; + int bsize = tctx->mtab->size / tctx->mtab->fmode[i].sub; if ((ret = ff_mdct_init(&tctx->mdct_ctx[i], av_log2(bsize) + 1, 1, - -sqrt(norm/bsize) / (1<<15)))) + -sqrt(norm / bsize) / (1 << 15)))) return ret; } @@ -898,23 +560,23 @@ static av_cold int init_mdct_win(TwinContext *tctx) alloc_fail); for (i = 0; i < 3; i++) { - int m = 4*mtab->size/mtab->fmode[i].sub; - double freq = 2*M_PI/m; + int m = 4 * mtab->size / mtab->fmode[i].sub; + double freq = 2 * M_PI / m; FF_ALLOC_OR_GOTO(tctx->avctx, tctx->cos_tabs[i], (m / 4) * sizeof(*tctx->cos_tabs[i]), alloc_fail); - for (j = 0; j <= m/8; j++) - tctx->cos_tabs[i][j] = cos((2*j + 1)*freq); - for (j = 1; j < m/8; j++) - tctx->cos_tabs[i][m/4-j] = tctx->cos_tabs[i][j]; + for (j = 0; j <= m / 8; j++) + tctx->cos_tabs[i][j] = cos((2 * j + 1) * freq); + for (j = 1; j < m / 8; j++) + tctx->cos_tabs[i][m / 4 - j] = tctx->cos_tabs[i][j]; } - ff_init_ff_sine_windows(av_log2(size_m)); - ff_init_ff_sine_windows(av_log2(size_s/2)); + ff_init_ff_sine_windows(av_log2(size_s / 2)); ff_init_ff_sine_windows(av_log2(mtab->size)); return 0; + alloc_fail: return AVERROR(ENOMEM); } @@ -928,26 +590,25 @@ alloc_fail: static void permutate_in_line(int16_t *tab, int num_vect, int num_blocks, int block_size, const uint8_t line_len[2], int length_div, - enum FrameType ftype) - + enum TwinVQFrameType ftype) { - int i,j; + int i, j; for (i = 0; i < line_len[0]; i++) { int shift; - if (num_blocks == 1 || - (ftype == FT_LONG && num_vect % num_blocks) || - (ftype != FT_LONG && num_vect & 1 ) || + if (num_blocks == 1 || + (ftype == TWINVQ_FT_LONG && num_vect % num_blocks) || + (ftype != TWINVQ_FT_LONG && num_vect & 1) || i == line_len[1]) { shift = 0; - } else if (ftype == FT_LONG) { + } else if (ftype == TWINVQ_FT_LONG) { shift = i; } else - shift = i*i; + shift = i * i; - for (j = 0; j < num_vect && (j+num_vect*i < block_size*num_blocks); j++) - tab[i*num_vect+j] = i*num_vect + (j + shift) % num_vect; + for (j = 0; j < num_vect && (j + num_vect * i < block_size * num_blocks); j++) + tab[i * num_vect + j] = i * num_vect + (j + shift) % num_vect; } } @@ -969,31 +630,32 @@ static void permutate_in_line(int16_t *tab, int num_vect, int num_blocks, static void transpose_perm(int16_t *out, int16_t *in, int num_vect, const uint8_t line_len[2], int length_div) { - int i,j; - int cont= 0; + int i, j; + int cont = 0; + for (i = 0; i < num_vect; i++) for (j = 0; j < line_len[i >= length_div]; j++) - out[cont++] = in[j*num_vect + i]; + out[cont++] = in[j * num_vect + i]; } static void linear_perm(int16_t *out, int16_t *in, int n_blocks, int size) { - int block_size = size/n_blocks; + int block_size = size / n_blocks; int i; for (i = 0; i < size; i++) out[i] = block_size * (in[i] % n_blocks) + in[i] / n_blocks; } -static av_cold void construct_perm_table(TwinContext *tctx,enum FrameType ftype) +static av_cold void construct_perm_table(TwinVQContext *tctx, + enum TwinVQFrameType ftype) { - int block_size; - const ModeTab *mtab = tctx->mtab; - int size; - int16_t *tmp_perm = (int16_t *) tctx->tmp_buf; + int block_size, size; + const TwinVQModeTab *mtab = tctx->mtab; + int16_t *tmp_perm = (int16_t *)tctx->tmp_buf; - if (ftype == FT_PPC) { - size = tctx->avctx->channels; + if (ftype == TWINVQ_FT_PPC) { + size = tctx->avctx->channels; block_size = mtab->ppc_shape_len; } else { size = tctx->avctx->channels * mtab->fmode[ftype].sub; @@ -1008,81 +670,87 @@ static av_cold void construct_perm_table(TwinContext *tctx,enum FrameType ftype) tctx->length[ftype], tctx->length_change[ftype]); linear_perm(tctx->permut[ftype], tctx->permut[ftype], size, - size*block_size); + size * block_size); } -static av_cold void init_bitstream_params(TwinContext *tctx) +static av_cold void init_bitstream_params(TwinVQContext *tctx) { - const ModeTab *mtab = tctx->mtab; - int n_ch = tctx->avctx->channels; - int total_fr_bits = tctx->avctx->bit_rate*mtab->size/ - tctx->avctx->sample_rate; + const TwinVQModeTab *mtab = tctx->mtab; + int n_ch = tctx->avctx->channels; + int total_fr_bits = tctx->avctx->bit_rate * mtab->size / + tctx->avctx->sample_rate; - int lsp_bits_per_block = n_ch*(mtab->lsp_bit0 + mtab->lsp_bit1 + - mtab->lsp_split*mtab->lsp_bit2); + int lsp_bits_per_block = n_ch * (mtab->lsp_bit0 + mtab->lsp_bit1 + + mtab->lsp_split * mtab->lsp_bit2); - int ppc_bits = n_ch*(mtab->pgain_bit + mtab->ppc_shape_bit + - mtab->ppc_period_bit); + int ppc_bits = n_ch * (mtab->pgain_bit + mtab->ppc_shape_bit + + mtab->ppc_period_bit); - int bsize_no_main_cb[3]; - int bse_bits[3]; - int i; - enum FrameType frametype; + int bsize_no_main_cb[3], bse_bits[3], i; + enum TwinVQFrameType frametype; for (i = 0; i < 3; i++) // +1 for history usage switch bse_bits[i] = n_ch * - (mtab->fmode[i].bark_n_coef * mtab->fmode[i].bark_n_bit + 1); + (mtab->fmode[i].bark_n_coef * + mtab->fmode[i].bark_n_bit + 1); bsize_no_main_cb[2] = bse_bits[2] + lsp_bits_per_block + ppc_bits + - WINDOW_TYPE_BITS + n_ch*GAIN_BITS; + TWINVQ_WINDOW_TYPE_BITS + n_ch * TWINVQ_GAIN_BITS; for (i = 0; i < 2; i++) bsize_no_main_cb[i] = - lsp_bits_per_block + n_ch*GAIN_BITS + WINDOW_TYPE_BITS + - mtab->fmode[i].sub*(bse_bits[i] + n_ch*SUB_GAIN_BITS); + lsp_bits_per_block + n_ch * TWINVQ_GAIN_BITS + + TWINVQ_WINDOW_TYPE_BITS + + mtab->fmode[i].sub * (bse_bits[i] + n_ch * TWINVQ_SUB_GAIN_BITS); + + if (tctx->codec == TWINVQ_CODEC_METASOUND && !tctx->is_6kbps) { + bsize_no_main_cb[1] += 2; + bsize_no_main_cb[2] += 2; + } // The remaining bits are all used for the main spectrum coefficients for (i = 0; i < 4; i++) { - int bit_size; - int vect_size; + int bit_size, vect_size; int rounded_up, rounded_down, num_rounded_down, num_rounded_up; if (i == 3) { bit_size = n_ch * mtab->ppc_shape_bit; vect_size = n_ch * mtab->ppc_shape_len; } else { - bit_size = total_fr_bits - bsize_no_main_cb[i]; + bit_size = total_fr_bits - bsize_no_main_cb[i]; vect_size = n_ch * mtab->size; } tctx->n_div[i] = (bit_size + 13) / 14; - rounded_up = (bit_size + tctx->n_div[i] - 1)/tctx->n_div[i]; - rounded_down = (bit_size )/tctx->n_div[i]; - num_rounded_down = rounded_up * tctx->n_div[i] - bit_size; - num_rounded_up = tctx->n_div[i] - num_rounded_down; - tctx->bits_main_spec[0][i][0] = (rounded_up + 1)/2; - tctx->bits_main_spec[1][i][0] = (rounded_up )/2; - tctx->bits_main_spec[0][i][1] = (rounded_down + 1)/2; - tctx->bits_main_spec[1][i][1] = (rounded_down )/2; + rounded_up = (bit_size + tctx->n_div[i] - 1) / + tctx->n_div[i]; + rounded_down = (bit_size) / tctx->n_div[i]; + num_rounded_down = rounded_up * tctx->n_div[i] - bit_size; + num_rounded_up = tctx->n_div[i] - num_rounded_down; + tctx->bits_main_spec[0][i][0] = (rounded_up + 1) / 2; + tctx->bits_main_spec[1][i][0] = rounded_up / 2; + tctx->bits_main_spec[0][i][1] = (rounded_down + 1) / 2; + tctx->bits_main_spec[1][i][1] = rounded_down / 2; tctx->bits_main_spec_change[i] = num_rounded_up; - rounded_up = (vect_size + tctx->n_div[i] - 1)/tctx->n_div[i]; - rounded_down = (vect_size )/tctx->n_div[i]; - num_rounded_down = rounded_up * tctx->n_div[i] - vect_size; - num_rounded_up = tctx->n_div[i] - num_rounded_down; - tctx->length[i][0] = rounded_up; - tctx->length[i][1] = rounded_down; + rounded_up = (vect_size + tctx->n_div[i] - 1) / + tctx->n_div[i]; + rounded_down = (vect_size) / tctx->n_div[i]; + num_rounded_down = rounded_up * tctx->n_div[i] - vect_size; + num_rounded_up = tctx->n_div[i] - num_rounded_down; + tctx->length[i][0] = rounded_up; + tctx->length[i][1] = rounded_down; tctx->length_change[i] = num_rounded_up; } - for (frametype = FT_SHORT; frametype <= FT_PPC; frametype++) + for (frametype = TWINVQ_FT_SHORT; frametype <= TWINVQ_FT_PPC; frametype++) construct_perm_table(tctx, frametype); } -static av_cold int twin_decode_close(AVCodecContext *avctx) +av_cold int ff_twinvq_decode_close(AVCodecContext *avctx) { - TwinContext *tctx = avctx->priv_data; + TwinVQContext *tctx = avctx->priv_data; int i; for (i = 0; i < 3; i++) { @@ -1090,7 +758,6 @@ static av_cold int twin_decode_close(AVCodecContext *avctx) av_free(tctx->cos_tabs[i]); } - av_free(tctx->curr_frame); av_free(tctx->spectrum); av_free(tctx->prev_frame); @@ -1099,87 +766,38 @@ static av_cold int twin_decode_close(AVCodecContext *avctx) return 0; } -static av_cold int twin_decode_init(AVCodecContext *avctx) +av_cold int ff_twinvq_decode_init(AVCodecContext *avctx) { int ret; - TwinContext *tctx = avctx->priv_data; - int isampf, ibps; + TwinVQContext *tctx = avctx->priv_data; tctx->avctx = avctx; avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; - if (!avctx->extradata || avctx->extradata_size < 12) { - av_log(avctx, AV_LOG_ERROR, "Missing or incomplete extradata\n"); + if (!avctx->block_align) { + avctx->block_align = tctx->frame_size + 7 >> 3; + } else if (avctx->block_align * 8 < tctx->frame_size) { + av_log(avctx, AV_LOG_ERROR, "Block align is %d bits, expected %d\n", + avctx->block_align * 8, tctx->frame_size); return AVERROR_INVALIDDATA; } - avctx->channels = AV_RB32(avctx->extradata ) + 1; - avctx->bit_rate = AV_RB32(avctx->extradata + 4) * 1000; - isampf = AV_RB32(avctx->extradata + 8); - - if (isampf < 8 || isampf > 44) { - av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate\n"); - return AVERROR_INVALIDDATA; - } - switch (isampf) { - case 44: avctx->sample_rate = 44100; break; - case 22: avctx->sample_rate = 22050; break; - case 11: avctx->sample_rate = 11025; break; - default: avctx->sample_rate = isampf * 1000; break; - } - - if (avctx->channels <= 0 || avctx->channels > CHANNELS_MAX) { - av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %i\n", - avctx->channels); - return -1; - } - avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO : - AV_CH_LAYOUT_STEREO; - - ibps = avctx->bit_rate / (1000 * avctx->channels); - - if (ibps > 255U) { - av_log(avctx, AV_LOG_ERROR, "unsupported per channel bitrate %dkbps\n", ibps); + tctx->frames_per_packet = avctx->block_align * 8 / tctx->frame_size; + if (tctx->frames_per_packet > TWINVQ_MAX_FRAMES_PER_PACKET) { + av_log(avctx, AV_LOG_ERROR, "Too many frames per packet (%d)\n", + tctx->frames_per_packet); return AVERROR_INVALIDDATA; } - switch ((isampf << 8) + ibps) { - case (8 <<8) + 8: tctx->mtab = &mode_08_08; break; - case (11<<8) + 8: tctx->mtab = &mode_11_08; break; - case (11<<8) + 10: tctx->mtab = &mode_11_10; break; - case (16<<8) + 16: tctx->mtab = &mode_16_16; break; - case (22<<8) + 20: tctx->mtab = &mode_22_20; break; - case (22<<8) + 24: tctx->mtab = &mode_22_24; break; - case (22<<8) + 32: tctx->mtab = &mode_22_32; break; - case (44<<8) + 40: tctx->mtab = &mode_44_40; break; - case (44<<8) + 48: tctx->mtab = &mode_44_48; break; - default: - av_log(avctx, AV_LOG_ERROR, "This version does not support %d kHz - %d kbit/s/ch mode.\n", isampf, isampf); - return -1; - } - avpriv_float_dsp_init(&tctx->fdsp, avctx->flags & CODEC_FLAG_BITEXACT); if ((ret = init_mdct_win(tctx))) { av_log(avctx, AV_LOG_ERROR, "Error initializing MDCT\n"); - twin_decode_close(avctx); + ff_twinvq_decode_close(avctx); return ret; } init_bitstream_params(tctx); - memset_float(tctx->bark_hist[0][0], 0.1, FF_ARRAY_ELEMS(tctx->bark_hist)); + twinvq_memset_float(tctx->bark_hist[0][0], 0.1, + FF_ARRAY_ELEMS(tctx->bark_hist)); return 0; } - -AVCodec ff_twinvq_decoder = { - .name = "twinvq", - .type = AVMEDIA_TYPE_AUDIO, - .id = AV_CODEC_ID_TWINVQ, - .priv_data_size = sizeof(TwinContext), - .init = twin_decode_init, - .close = twin_decode_close, - .decode = twin_decode_frame, - .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("VQF TwinVQ"), - .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, - AV_SAMPLE_FMT_NONE }, -}; diff --git a/ffmpeg/libavcodec/twinvq_data.h b/ffmpeg/libavcodec/twinvq_data.h index 63911f8..375acc2 100644 --- a/ffmpeg/libavcodec/twinvq_data.h +++ b/ffmpeg/libavcodec/twinvq_data.h @@ -39,95 +39,94 @@ * for some slightly nonconventional bark-scale function */ static const uint16_t bark_tab_l08_512[] = { - 7, 8, 7, 8, 8, 8, 8, 8, 8, 9, - 9, 10, 10, 11, 11, 12, 12, 14, 15, 16, - 18, 19, 21, 24, 27, 30, 35, 40, 46, 53 + 7, 8, 7, 8, 8, 8, 8, 8, 8, 9, + 9, 10, 10, 11, 11, 12, 12, 14, 15, 16, + 18, 19, 21, 24, 27, 30, 35, 40, 46, 53 }; static const uint16_t bark_tab_l11_512[] = { - 6, 6, 6, 6, 6, 6, 7, 6, 7, 7, - 8, 8, 8, 9, 10, 10, 11, 13, 13, 15, - 17, 18, 21, 25, 27, 33, 38, 45, 54, 66 + 6, 6, 6, 6, 6, 6, 7, 6, 7, 7, + 8, 8, 8, 9, 10, 10, 11, 13, 13, 15, + 17, 18, 21, 25, 27, 33, 38, 45, 54, 66 }; static const uint16_t bark_tab_l16_1024[] = { - 9, 9, 8, 9, 10, 9, 10, 10, 10, 12, - 11, 13, 13, 14, 16, 17, 19, 20, 24, 26, - 30, 35, 40, 48, 56, 68, 83, 102, 128, 165 + 9, 9, 8, 9, 10, 9, 10, 10, 10, 12, + 11, 13, 13, 14, 16, 17, 19, 20, 24, 26, + 30, 35, 40, 48, 56, 68, 83, 102, 128, 165 }; static const uint16_t bark_tab_l22_1024[] = { - 6, 7, 6, 6, 7, 7, 7, 7, 7, 8, - 9, 8, 10, 10, 11, 12, 13, 15, 16, 18, - 21, 24, 27, 33, 38, 46, 55, 68, 84, 107, - 140, 191 + 6, 7, 6, 6, 7, 7, 7, 7, 7, 8, + 9, 8, 10, 10, 11, 12, 13, 15, 16, 18, + 21, 24, 27, 33, 38, 46, 55, 68, 84, 107, + 140, 191 }; static const uint16_t bark_tab_l22_512[] = { - 3, 3, 3, 4, 3, 3, 4, 3, 4, 4, - 4, 5, 4, 5, 6, 6, 7, 7, 8, 9, - 10, 12, 14, 16, 20, 22, 28, 34, 42, 53, - 71, 95 + 3, 3, 3, 4, 3, 3, 4, 3, 4, 4, + 4, 5, 4, 5, 6, 6, 7, 7, 8, 9, + 10, 12, 14, 16, 20, 22, 28, 34, 42, 53, + 71, 95 }; static const uint16_t bark_tab_l44_2048[] = { - 5, 6, 5, 6, 5, 6, 6, 6, 6, 6, - 7, 7, 7, 8, 8, 9, 9, 10, 11, 11, - 13, 14, 16, 17, 19, 22, 25, 29, 33, 39, - 46, 54, 64, 79, 98, 123, 161, 220, 320, 512 + 5, 6, 5, 6, 5, 6, 6, 6, 6, 6, + 7, 7, 7, 8, 8, 9, 9, 10, 11, 11, + 13, 14, 16, 17, 19, 22, 25, 29, 33, 39, + 46, 54, 64, 79, 98, 123, 161, 220, 320, 512 }; static const uint16_t bark_tab_m08_256[] = { - 6, 5, 6, 6, 6, 6, 7, 7, 8, 8, - 9, 10, 11, 13, 15, 18, 20, 25, 31, 39 + 6, 5, 6, 6, 6, 6, 7, 7, 8, 8, + 9, 10, 11, 13, 15, 18, 20, 25, 31, 39 }; static const uint16_t bark_tab_m11_256[] = { - 4, 5, 4, 5, 5, 5, 6, 5, 7, 7, - 8, 9, 10, 12, 15, 17, 22, 28, 35, 47 + 4, 5, 4, 5, 5, 5, 6, 5, 7, 7, + 8, 9, 10, 12, 15, 17, 22, 28, 35, 47 }; static const uint16_t bark_tab_m16_512[] = { - 7, 6, 7, 7, 7, 8, 9, 9, 10, 11, - 14, 15, 18, 22, 27, 34, 44, 59, 81, 117 + 7, 6, 7, 7, 7, 8, 9, 9, 10, 11, + 14, 15, 18, 22, 27, 34, 44, 59, 81, 117 }; static const uint16_t bark_tab_m22_256[] = { - 3, 2, 3, 2, 3, 3, 4, 3, 4, 5, - 5, 7, 8, 9, 13, 16, 22, 30, 44, 70 + 3, 2, 3, 2, 3, 3, 4, 3, 4, 5, + 5, 7, 8, 9, 13, 16, 22, 30, 44, 70 }; static const uint16_t bark_tab_m22_512[] = { - 5, 5, 5, 6, 5, 7, 6, 7, 9, 9, - 11, 13, 15, 20, 24, 33, 43, 61, 88, 140 + 5, 5, 5, 6, 5, 7, 6, 7, 9, 9, + 11, 13, 15, 20, 24, 33, 43, 61, 88, 140 }; static const uint16_t bark_tab_m44_512[] = { - 3, 2, 3, 3, 3, 4, 3, 5, 4, 6, - 7, 8, 10, 14, 18, 25, 36, 55, 95, 208 + 3, 2, 3, 3, 3, 4, 3, 5, 4, 6, + 7, 8, 10, 14, 18, 25, 36, 55, 95, 208 }; static const uint16_t bark_tab_s08_64[] = { - 3, 3, 3, 3, 4, 5, 6, 8, 12, 17 + 3, 3, 3, 3, 4, 5, 6, 8, 12, 17 }; static const uint16_t bark_tab_s11_64[] = { - 2, 3, 2, 3, 3, 4, 6, 8, 12, 21 + 2, 3, 2, 3, 3, 4, 6, 8, 12, 21 }; static const uint16_t bark_tab_s16_128[] = { - 3, 4, 4, 4, 5, 7, 10, 16, 26, 49 + 3, 4, 4, 4, 5, 7, 10, 16, 26, 49 }; static const uint16_t bark_tab_s22_128[] = { - 3, 2, 3, 4, 4, 6, 9, 14, 26, 57 + 3, 2, 3, 4, 4, 6, 9, 14, 26, 57 }; static const uint16_t bark_tab_s44_128[] = { - 1, 2, 1, 2, 3, 4, 6, 10, 23, 76 + 1, 2, 1, 2, 3, 4, 6, 10, 23, 76 }; - /** * TwinVQ codebooks. They are coded in a struct so we can use code such as * @@ -10991,147 +10990,155 @@ static const struct twinvq_data { }, }; - static const uint8_t tab7[][35] = { - {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0}, - {0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0}, - {0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, - {0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0}, - {0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0}, - {0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, - {0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0}, - {0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1}, - {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0} + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0 }, + { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0 }, + { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0 }, + { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0 }, + { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0 }, + { 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, + 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, + 1, 0, 1 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0 } }; static const uint8_t tab8[][5] = { - {0, 0, 0, 1, 1}, - {0, 1, 0, 0, 1}, - {1, 1, 0, 0, 0}, - {1, 0, 0, 1, 0}, - {0, 0, 0, 1, 1}, - {0, 1, 0, 0, 1}, - {1, 1, 0, 0, 0}, - {1, 0, 0, 1, 0}, - {0, 0, 0, 1, 1}, - {0, 1, 0, 0, 1}, - {1, 1, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 1, 0, 1, 0} + { 0, 0, 0, 1, 1 }, + { 0, 1, 0, 0, 1 }, + { 1, 1, 0, 0, 0 }, + { 1, 0, 0, 1, 0 }, + { 0, 0, 0, 1, 1 }, + { 0, 1, 0, 0, 1 }, + { 1, 1, 0, 0, 0 }, + { 1, 0, 0, 1, 0 }, + { 0, 0, 0, 1, 1 }, + { 0, 1, 0, 0, 1 }, + { 1, 1, 0, 0, 0 }, + { 0, 0, 0, 0, 0 }, + { 0, 1, 0, 1, 0 } }; static const uint8_t tab9[][45] = { - { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 - },{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 - },{ - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - },{ - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - },{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 - },{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 - },{ - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - },{ - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - },{ - 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, - 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0 - },{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - } + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, + 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; -static const uint8_t tab10[][25] = -{ - {1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0}, - {1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0}, - {1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0}, - {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, - {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}, - {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1}, - {1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0}, - {0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1} +static const uint8_t tab10[][25] = { + { 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, + 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0 }, + { 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, + 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0 }, + { 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, + 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0 }, + { 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 }, + { 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, + 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 }, + { 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 }, + { 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1 } }; static const uint8_t tab11[][55] = { - { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0 - },{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - },{ - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - },{ - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - }, { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - },{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - },{ - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - },{ - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - },{ - 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - } + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, }, + { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, + { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, }, + { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, + { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, + { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, } }; static const uint8_t tab12[][15] = { - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0}, - {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, - {0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0}, - {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, - {0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0}, - {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0 }, + { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 }, + { 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0 }, + { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 }, + { 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0 }, + { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1 }, }; static const struct { int size; const uint8_t *tab; } tabs[] = { - {0 , NULL}, - {5 , &tab8 [0][0]},{5 , &tab8 [0][0]}, {15, &tab12[0][0]}, - {5 , &tab8 [0][0]},{25, &tab10[0][0]}, {15, &tab12[0][0]}, - {35, &tab7 [0][0]},{5 , &tab8 [0][0]}, {45, &tab9 [0][0]}, - {25, &tab10[0][0]},{55, &tab11[0][0]}, {15, &tab12[0][0]} + { 0, NULL }, + { 5, &tab8[0][0] }, { 5, &tab8[0][0] }, { 15, &tab12[0][0] }, + { 5, &tab8[0][0] }, { 25, &tab10[0][0] }, { 15, &tab12[0][0] }, + { 35, &tab7[0][0] }, { 5, &tab8[0][0] }, { 45, &tab9[0][0] }, + { 25, &tab10[0][0] }, { 55, &tab11[0][0] }, { 15, &tab12[0][0] } }; #endif /* AVCODEC_TWINVQ_DATA_H */ diff --git a/ffmpeg/libavcodec/txd.c b/ffmpeg/libavcodec/txd.c index e8d483f..ad1a015 100644 --- a/ffmpeg/libavcodec/txd.c +++ b/ffmpeg/libavcodec/txd.c @@ -63,10 +63,9 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return AVERROR_PATCHWELCOME; } - if ((ret = av_image_check_size(w, h, 0, avctx)) < 0) + if ((ret = ff_set_dimensions(avctx, w, h)) < 0) return ret; - if (w != avctx->width || h != avctx->height) - avcodec_set_dimensions(avctx, w, h); + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) return ret; @@ -134,9 +133,9 @@ unsupported: AVCodec ff_txd_decoder = { .name = "txd", + .long_name = NULL_IF_CONFIG_SMALL("Renderware TXD (TeXture Dictionary) image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_TXD, .decode = txd_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Renderware TXD (TeXture Dictionary) image"), }; diff --git a/ffmpeg/libavcodec/ulti.c b/ffmpeg/libavcodec/ulti.c index 2120d97..6b76214 100644 --- a/ffmpeg/libavcodec/ulti.c +++ b/ffmpeg/libavcodec/ulti.c @@ -37,7 +37,7 @@ typedef struct UltimotionDecodeContext { AVCodecContext *avctx; int width, height, blocks; - AVFrame frame; + AVFrame *frame; const uint8_t *ulti_codebook; GetByteContext gb; } UltimotionDecodeContext; @@ -51,19 +51,19 @@ static av_cold int ulti_decode_init(AVCodecContext *avctx) s->height = avctx->height; s->blocks = (s->width / 8) * (s->height / 8); avctx->pix_fmt = AV_PIX_FMT_YUV410P; - avctx->coded_frame = &s->frame; - avctx->coded_frame = (AVFrame*) &s->frame; s->ulti_codebook = ulti_codebook; - avcodec_get_frame_defaults(&s->frame); + + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); return 0; } static av_cold int ulti_decode_end(AVCodecContext *avctx){ UltimotionDecodeContext *s = avctx->priv_data; - AVFrame *pic = &s->frame; - av_frame_unref(pic); + av_frame_free(&s->frame); return 0; } @@ -227,7 +227,7 @@ static int ulti_decode_frame(AVCodecContext *avctx, int skip; int tmp; - if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) + if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) return ret; bytestream2_init(&s->gb, buf, buf_size); @@ -368,7 +368,7 @@ static int ulti_decode_frame(AVCodecContext *avctx, Luma[14] = (tmp >> 6) & 0x3F; Luma[15] = tmp & 0x3F; - ulti_convert_yuv(&s->frame, tx, ty, Luma, chroma); + ulti_convert_yuv(s->frame, tx, ty, Luma, chroma); } else { if (bytestream2_get_bytes_left(&s->gb) < 4) goto err; @@ -380,20 +380,20 @@ static int ulti_decode_frame(AVCodecContext *avctx, Y[1] = tmp & 0x3F; Y[2] = bytestream2_get_byteu(&s->gb) & 0x3F; Y[3] = bytestream2_get_byteu(&s->gb) & 0x3F; - ulti_grad(&s->frame, tx, ty, Y, chroma, angle); //draw block + ulti_grad(s->frame, tx, ty, Y, chroma, angle); //draw block } else { // some patterns int f0, f1; f0 = bytestream2_get_byteu(&s->gb); f1 = tmp; Y[0] = bytestream2_get_byteu(&s->gb) & 0x3F; Y[1] = bytestream2_get_byteu(&s->gb) & 0x3F; - ulti_pattern(&s->frame, tx, ty, f1, f0, Y[0], Y[1], chroma); + ulti_pattern(s->frame, tx, ty, f1, f0, Y[0], Y[1], chroma); } } break; } if(code != 3) - ulti_grad(&s->frame, tx, ty, Y, chroma, angle); // draw block + ulti_grad(s->frame, tx, ty, Y, chroma, angle); // draw block } blocks++; x += 8; @@ -405,7 +405,7 @@ static int ulti_decode_frame(AVCodecContext *avctx, } *got_frame = 1; - if ((ret = av_frame_ref(data, &s->frame)) < 0) + if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; return buf_size; @@ -418,6 +418,7 @@ err: AVCodec ff_ulti_decoder = { .name = "ultimotion", + .long_name = NULL_IF_CONFIG_SMALL("IBM UltiMotion"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_ULTI, .priv_data_size = sizeof(UltimotionDecodeContext), @@ -425,5 +426,4 @@ AVCodec ff_ulti_decoder = { .close = ulti_decode_end, .decode = ulti_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("IBM UltiMotion"), }; diff --git a/ffmpeg/libavcodec/utils.c b/ffmpeg/libavcodec/utils.c index c15b772..c000d27 100644 --- a/ffmpeg/libavcodec/utils.c +++ b/ffmpeg/libavcodec/utils.c @@ -26,18 +26,20 @@ */ #include "config.h" +#include "libavutil/atomic.h" +#include "libavutil/attributes.h" #include "libavutil/avassert.h" #include "libavutil/avstring.h" #include "libavutil/bprint.h" #include "libavutil/channel_layout.h" #include "libavutil/crc.h" #include "libavutil/frame.h" +#include "libavutil/internal.h" #include "libavutil/mathematics.h" #include "libavutil/pixdesc.h" #include "libavutil/imgutils.h" #include "libavutil/samplefmt.h" #include "libavutil/dict.h" -#include "libavutil/avassert.h" #include "avcodec.h" #include "dsputil.h" #include "libavutil/opt.h" @@ -54,30 +56,84 @@ # include #endif +#if HAVE_PTHREADS +#include +#elif HAVE_W32THREADS +#include "compat/w32pthreads.h" +#elif HAVE_OS2THREADS +#include "compat/os2threads.h" +#endif + +#if HAVE_PTHREADS || HAVE_W32THREADS || HAVE_OS2THREADS +static int default_lockmgr_cb(void **arg, enum AVLockOp op) +{ + void * volatile * mutex = arg; + int err; + + switch (op) { + case AV_LOCK_CREATE: + return 0; + case AV_LOCK_OBTAIN: + if (!*mutex) { + pthread_mutex_t *tmp = av_malloc(sizeof(pthread_mutex_t)); + if (!tmp) + return AVERROR(ENOMEM); + if ((err = pthread_mutex_init(tmp, NULL))) { + av_free(tmp); + return AVERROR(err); + } + if (avpriv_atomic_ptr_cas(mutex, NULL, tmp)) { + pthread_mutex_destroy(tmp); + av_free(tmp); + } + } + + if ((err = pthread_mutex_lock(*mutex))) + return AVERROR(err); + + return 0; + case AV_LOCK_RELEASE: + if ((err = pthread_mutex_unlock(*mutex))) + return AVERROR(err); + + return 0; + case AV_LOCK_DESTROY: + if (*mutex) + pthread_mutex_destroy(*mutex); + av_free(*mutex); + avpriv_atomic_ptr_cas(mutex, *mutex, NULL); + return 0; + } + return 1; +} +static int (*lockmgr_cb)(void **mutex, enum AVLockOp op) = default_lockmgr_cb; +#else +static int (*lockmgr_cb)(void **mutex, enum AVLockOp op) = NULL; +#endif + + volatile int ff_avcodec_locked; static int volatile entangled_thread_counter = 0; -static int (*ff_lockmgr_cb)(void **mutex, enum AVLockOp op); static void *codec_mutex; static void *avformat_mutex; -void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size) -{ - if (min_size < *size) - return ptr; - - min_size = FFMAX(17 * min_size / 16 + 32, min_size); - - ptr = av_realloc(ptr, min_size); - /* we could set this to the unmodified min_size but this is safer - * if the user lost the ptr and uses NULL now - */ - if (!ptr) - min_size = 0; +#if CONFIG_RAISE_MAJOR +# define LIBNAME "LIBAVCODEC_155" +#else +# define LIBNAME "LIBAVCODEC_55" +#endif - *size = min_size; +#if FF_API_FAST_MALLOC && CONFIG_SHARED && HAVE_SYMVER +FF_SYMVER(void*, av_fast_realloc, (void *ptr, unsigned int *size, size_t min_size), LIBNAME) +{ + return av_fast_realloc(ptr, size, min_size); +} - return ptr; +FF_SYMVER(void, av_fast_malloc, (void *ptr, unsigned int *size, size_t min_size), LIBNAME) +{ + av_fast_malloc(ptr, size, min_size); } +#endif static inline int ff_fast_malloc(void *ptr, unsigned int *size, size_t min_size, int zero_realloc) { @@ -93,11 +149,6 @@ static inline int ff_fast_malloc(void *ptr, unsigned int *size, size_t min_size, return 1; } -void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size) -{ - ff_fast_malloc(ptr, size, min_size, 0); -} - void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size) { uint8_t **p = ptr; @@ -124,6 +175,7 @@ void av_fast_padded_mallocz(void *ptr, unsigned int *size, size_t min_size) /* encoder management */ static AVCodec *first_avcodec = NULL; +static AVCodec **last_avcodec = &first_avcodec; AVCodec *av_codec_next(const AVCodec *c) { @@ -133,7 +185,7 @@ AVCodec *av_codec_next(const AVCodec *c) return first_avcodec; } -static void avcodec_init(void) +static av_cold void avcodec_init(void) { static int initialized = 0; @@ -155,16 +207,17 @@ int av_codec_is_decoder(const AVCodec *codec) return codec && codec->decode; } -void avcodec_register(AVCodec *codec) +av_cold void avcodec_register(AVCodec *codec) { AVCodec **p; avcodec_init(); - p = &first_avcodec; - while (*p != NULL) - p = &(*p)->next; - *p = codec; + p = last_avcodec; codec->next = NULL; + while(*p || avpriv_atomic_ptr_cas((void * volatile *)p, NULL, codec)) + p = &(*p)->next; + last_avcodec = &codec->next; + if (codec->init_static_data) codec->init_static_data(codec); } @@ -174,15 +227,32 @@ unsigned avcodec_get_edge_width(void) return EDGE_WIDTH; } +#if FF_API_SET_DIMENSIONS void avcodec_set_dimensions(AVCodecContext *s, int width, int height) { + int ret = ff_set_dimensions(s, width, height); + if (ret < 0) { + av_log(s, AV_LOG_WARNING, "Failed to set dimensions %d %d\n", width, height); + } +} +#endif + +int ff_set_dimensions(AVCodecContext *s, int width, int height) +{ + int ret = av_image_check_size(width, height, 0, s); + + if (ret < 0) + width = height = 0; + s->coded_width = width; s->coded_height = height; - s->width = -((-width ) >> s->lowres); - s->height = -((-height) >> s->lowres); + s->width = FF_CEIL_RSHIFT(width, s->lowres); + s->height = FF_CEIL_RSHIFT(height, s->lowres); + + return ret; } -#if (ARCH_ARM && HAVE_NEON) || ARCH_PPC || HAVE_MMX +#if HAVE_NEON || ARCH_PPC || HAVE_MMX # define STRIDE_ALIGN 16 #else # define STRIDE_ALIGN 8 @@ -202,6 +272,7 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, case AV_PIX_FMT_YUV422P: case AV_PIX_FMT_YUV440P: case AV_PIX_FMT_YUV444P: + case AV_PIX_FMT_GBRAP: case AV_PIX_FMT_GBRP: case AV_PIX_FMT_GRAY8: case AV_PIX_FMT_GRAY16BE: @@ -221,6 +292,8 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, case AV_PIX_FMT_YUV420P12BE: case AV_PIX_FMT_YUV420P14LE: case AV_PIX_FMT_YUV420P14BE: + case AV_PIX_FMT_YUV420P16LE: + case AV_PIX_FMT_YUV420P16BE: case AV_PIX_FMT_YUV422P9LE: case AV_PIX_FMT_YUV422P9BE: case AV_PIX_FMT_YUV422P10LE: @@ -229,6 +302,8 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, case AV_PIX_FMT_YUV422P12BE: case AV_PIX_FMT_YUV422P14LE: case AV_PIX_FMT_YUV422P14BE: + case AV_PIX_FMT_YUV422P16LE: + case AV_PIX_FMT_YUV422P16BE: case AV_PIX_FMT_YUV444P9LE: case AV_PIX_FMT_YUV444P9BE: case AV_PIX_FMT_YUV444P10LE: @@ -237,6 +312,26 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, case AV_PIX_FMT_YUV444P12BE: case AV_PIX_FMT_YUV444P14LE: case AV_PIX_FMT_YUV444P14BE: + case AV_PIX_FMT_YUV444P16LE: + case AV_PIX_FMT_YUV444P16BE: + case AV_PIX_FMT_YUVA420P9LE: + case AV_PIX_FMT_YUVA420P9BE: + case AV_PIX_FMT_YUVA420P10LE: + case AV_PIX_FMT_YUVA420P10BE: + case AV_PIX_FMT_YUVA420P16LE: + case AV_PIX_FMT_YUVA420P16BE: + case AV_PIX_FMT_YUVA422P9LE: + case AV_PIX_FMT_YUVA422P9BE: + case AV_PIX_FMT_YUVA422P10LE: + case AV_PIX_FMT_YUVA422P10BE: + case AV_PIX_FMT_YUVA422P16LE: + case AV_PIX_FMT_YUVA422P16BE: + case AV_PIX_FMT_YUVA444P9LE: + case AV_PIX_FMT_YUVA444P9BE: + case AV_PIX_FMT_YUVA444P10LE: + case AV_PIX_FMT_YUVA444P10BE: + case AV_PIX_FMT_YUVA444P16LE: + case AV_PIX_FMT_YUVA444P16BE: case AV_PIX_FMT_GBRP9LE: case AV_PIX_FMT_GBRP9BE: case AV_PIX_FMT_GBRP10LE: @@ -249,6 +344,7 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, h_align = 16 * 2; // interlaced needs 2 macroblocks height break; case AV_PIX_FMT_YUV411P: + case AV_PIX_FMT_YUVJ411P: case AV_PIX_FMT_UYYVYY411: w_align = 32; h_align = 8; @@ -323,6 +419,29 @@ void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height) *width = FFALIGN(*width, align); } +int avcodec_enum_to_chroma_pos(int *xpos, int *ypos, enum AVChromaLocation pos) +{ + if (pos <= AVCHROMA_LOC_UNSPECIFIED || pos >= AVCHROMA_LOC_NB) + return AVERROR(EINVAL); + pos--; + + *xpos = (pos&1) * 128; + *ypos = ((pos>>1)^(pos<4)) * 128; + + return 0; +} + +enum AVChromaLocation avcodec_chroma_pos_to_enum(int xpos, int ypos) +{ + int pos, xout, yout; + + for (pos = AVCHROMA_LOC_UNSPECIFIED + 1; pos < AVCHROMA_LOC_NB; pos++) { + if (avcodec_enum_to_chroma_pos(&xout, &yout, pos) == 0 && xout == xpos && yout == ypos) + return pos; + } + return AVCHROMA_LOC_UNSPECIFIED; +} + int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels, enum AVSampleFormat sample_fmt, const uint8_t *buf, int buf_size, int align) @@ -408,7 +527,10 @@ static int update_frame_pool(AVCodecContext *avctx, AVFrame *frame) av_buffer_pool_uninit(&pool->pools[i]); pool->linesize[i] = picture.linesize[i]; if (size[i]) { - pool->pools[i] = av_buffer_pool_init(size[i] + 16, NULL); + pool->pools[i] = av_buffer_pool_init(size[i] + 16 + STRIDE_ALIGN - 1, + CONFIG_MEMORY_POISONING ? + NULL : + av_buffer_allocz); if (!pool->pools[i]) { ret = AVERROR(ENOMEM); goto fail; @@ -526,6 +648,7 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic) for (i = 0; i < 4 && pool->pools[i]; i++) { const int h_shift = i == 0 ? 0 : h_chroma_shift; const int v_shift = i == 0 ? 0 : v_chroma_shift; + int is_planar = pool->pools[2] || (i==0 && s->pix_fmt == AV_PIX_FMT_GRAY8); pic->linesize[i] = pool->linesize[i]; @@ -534,7 +657,7 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic) goto fail; // no edge if EDGE EMU or not planar YUV - if ((s->flags & CODEC_FLAG_EMU_EDGE) || !pool->pools[2]) + if ((s->flags & CODEC_FLAG_EMU_EDGE) || !is_planar) pic->data[i] = pic->buf[i]->data; else { pic->data[i] = pic->buf[i]->data + @@ -563,13 +686,14 @@ void avpriv_color_frame(AVFrame *frame, const int c[4]) const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); int p, y, x; - av_assert0(desc->flags & PIX_FMT_PLANAR); + av_assert0(desc->flags & AV_PIX_FMT_FLAG_PLANAR); for (p = 0; pnb_components; p++) { uint8_t *dst = frame->data[p]; int is_chroma = p == 1 || p == 2; - int bytes = -((-frame->width) >> (is_chroma ? desc->log2_chroma_w : 0)); - for (y = 0; y<-((-frame->height) >> (is_chroma ? desc->log2_chroma_h : 0)); y++){ + int bytes = is_chroma ? FF_CEIL_RSHIFT(frame->width, desc->log2_chroma_w) : frame->width; + int height = is_chroma ? FF_CEIL_RSHIFT(frame->height, desc->log2_chroma_h) : frame->height; + for (y = 0; y < height; y++) { if (desc->comp[0].depth_minus1 >= 8) { for (x = 0; xtype = FF_BUFFER_TYPE_INTERNAL; +FF_ENABLE_DEPRECATION_WARNINGS #endif switch (avctx->codec_type) { @@ -603,11 +729,11 @@ int avcodec_default_get_buffer2(AVCodecContext *avctx, AVFrame *frame, int flags int ff_init_buffer_info(AVCodecContext *avctx, AVFrame *frame) { - if (avctx->pkt) { - frame->pkt_pts = avctx->pkt->pts; - av_frame_set_pkt_pos (frame, avctx->pkt->pos); - av_frame_set_pkt_duration(frame, avctx->pkt->duration); - av_frame_set_pkt_size (frame, avctx->pkt->size); + if (avctx->internal->pkt) { + frame->pkt_pts = avctx->internal->pkt->pts; + av_frame_set_pkt_pos (frame, avctx->internal->pkt->pos); + av_frame_set_pkt_duration(frame, avctx->internal->pkt->duration); + av_frame_set_pkt_size (frame, avctx->internal->pkt->size); } else { frame->pkt_pts = AV_NOPTS_VALUE; av_frame_set_pkt_pos (frame, -1); @@ -618,14 +744,16 @@ int ff_init_buffer_info(AVCodecContext *avctx, AVFrame *frame) switch (avctx->codec->type) { case AVMEDIA_TYPE_VIDEO: - if (!frame->width) - frame->width = avctx->width; - if (!frame->height) - frame->height = avctx->height; + frame->width = FFMAX(avctx->width, FF_CEIL_RSHIFT(avctx->coded_width, avctx->lowres)); + frame->height = FFMAX(avctx->height, FF_CEIL_RSHIFT(avctx->coded_height, avctx->lowres)); if (frame->format < 0) frame->format = avctx->pix_fmt; if (!frame->sample_aspect_ratio.num) frame->sample_aspect_ratio = avctx->sample_aspect_ratio; + if (av_frame_get_colorspace(frame) == AVCOL_SPC_UNSPECIFIED) + av_frame_set_colorspace(frame, avctx->colorspace); + if (av_frame_get_color_range(frame) == AVCOL_RANGE_UNSPECIFIED) + av_frame_set_color_range(frame, avctx->color_range); break; case AVMEDIA_TYPE_AUDIO: if (!frame->sample_rate) @@ -648,8 +776,6 @@ int ff_init_buffer_info(AVCodecContext *avctx, AVFrame *frame) avctx->channels); return AVERROR(ENOSYS); } - - frame->channel_layout = av_get_default_channel_layout(avctx->channels); } } av_frame_set_channels(frame, avctx->channels); @@ -659,6 +785,7 @@ int ff_init_buffer_info(AVCodecContext *avctx, AVFrame *frame) } #if FF_API_GET_BUFFER +FF_DISABLE_DEPRECATION_WARNINGS int avcodec_default_get_buffer(AVCodecContext *avctx, AVFrame *frame) { return avcodec_default_get_buffer2(avctx, frame, 0); @@ -682,6 +809,7 @@ static void compat_release_buffer(void *opaque, uint8_t *data) AVBufferRef *buf = opaque; av_buffer_unref(&buf); } +FF_ENABLE_DEPRECATION_WARNINGS #endif static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags) @@ -698,8 +826,9 @@ static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags) return ret; #if FF_API_GET_BUFFER +FF_DISABLE_DEPRECATION_WARNINGS /* - * Wrap an old get_buffer()-allocated buffer in an bunch of AVBuffers. + * Wrap an old get_buffer()-allocated buffer in a bunch of AVBuffers. * We wrap each plane in its own AVBuffer. Each of those has a reference to * a dummy AVBuffer as its private data, unreffing it on free. * When all the planes are freed, the dummy buffer's free callback calls @@ -722,7 +851,7 @@ static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags) * avcodec_default_get_buffer */ if (frame->buf[0]) - return 0; + goto end; priv = av_mallocz(sizeof(*priv)); if (!priv) { @@ -758,6 +887,10 @@ do { \ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); planes = av_pix_fmt_count_planes(frame->format); + /* workaround for AVHWAccel plane count of 0, buf[0] is used as + check for allocated buffers: make libavcodec happy */ + if (desc && desc->flags & AV_PIX_FMT_FLAG_HWACCEL) + planes = 1; if (!desc || planes <= 0) { ret = AVERROR(EINVAL); goto fail; @@ -794,6 +927,10 @@ do { \ av_buffer_unref(&dummy_buf); +end: + frame->width = avctx->width; + frame->height = avctx->height; + return 0; fail: @@ -802,9 +939,17 @@ fail: av_buffer_unref(&dummy_buf); return ret; } +FF_ENABLE_DEPRECATION_WARNINGS #endif - return avctx->get_buffer2(avctx, frame, flags); + ret = avctx->get_buffer2(avctx, frame, flags); + + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { + frame->width = avctx->width; + frame->height = avctx->height; + } + + return ret; } int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) @@ -871,6 +1016,7 @@ void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic) int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic) { av_assert0(0); + return AVERROR_BUG; } #endif @@ -901,7 +1047,7 @@ int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, static int is_hwaccel_pix_fmt(enum AVPixelFormat pix_fmt) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); - return desc->flags & PIX_FMT_HWACCEL; + return desc->flags & AV_PIX_FMT_FLAG_HWACCEL; } enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum AVPixelFormat *fmt) @@ -911,6 +1057,7 @@ enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const en return fmt[0]; } +#if FF_API_AVFRAME_LAVC void avcodec_get_frame_defaults(AVFrame *frame) { #if LIBAVCODEC_VERSION_MAJOR >= 55 @@ -921,54 +1068,29 @@ void avcodec_get_frame_defaults(AVFrame *frame) #endif memset(frame, 0, sizeof(AVFrame)); - - frame->pts = - frame->pkt_dts = - frame->pkt_pts = AV_NOPTS_VALUE; - av_frame_set_best_effort_timestamp(frame, AV_NOPTS_VALUE); - av_frame_set_pkt_duration (frame, 0); - av_frame_set_pkt_pos (frame, -1); - av_frame_set_pkt_size (frame, -1); - frame->key_frame = 1; - frame->sample_aspect_ratio = (AVRational) {0, 1 }; - frame->format = -1; /* unknown */ - frame->extended_data = frame->data; + av_frame_unref(frame); } AVFrame *avcodec_alloc_frame(void) { - AVFrame *frame = av_malloc(sizeof(AVFrame)); - - if (frame == NULL) - return NULL; - - frame->extended_data = NULL; - avcodec_get_frame_defaults(frame); - - return frame; + return av_frame_alloc(); } void avcodec_free_frame(AVFrame **frame) { - AVFrame *f; - - if (!frame || !*frame) - return; - - f = *frame; - - if (f->extended_data != f->data) - av_freep(&f->extended_data); - - av_freep(frame); + av_frame_free(frame); } - -#define MAKE_ACCESSORS(str, name, type, field) \ - type av_##name##_get_##field(const str *s) { return s->field; } \ - void av_##name##_set_##field(str *s, type v) { s->field = v; } +#endif MAKE_ACCESSORS(AVCodecContext, codec, AVRational, pkt_timebase) MAKE_ACCESSORS(AVCodecContext, codec, const AVCodecDescriptor *, codec_descriptor) +MAKE_ACCESSORS(AVCodecContext, codec, int, lowres) +MAKE_ACCESSORS(AVCodecContext, codec, int, seek_preroll) + +int av_codec_get_max_lowres(const AVCodec *codec) +{ + return codec->max_lowres; +} static void avcodec_get_subtitle_defaults(AVSubtitle *sub) { @@ -999,13 +1121,6 @@ static int get_bit_rate(AVCodecContext *ctx) return bit_rate; } -#if FF_API_AVCODEC_OPEN -int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec) -{ - return avcodec_open2(avctx, codec, NULL); -} -#endif - int attribute_align_arg ff_codec_open2_recursive(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options) { int ret = 0; @@ -1060,6 +1175,12 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code goto free_and_end; } + avctx->internal->to_free = av_frame_alloc(); + if (!avctx->internal->to_free) { + ret = AVERROR(ENOMEM); + goto free_and_end; + } + if (codec->priv_data_size > 0) { if (!avctx->priv_data) { avctx->priv_data = av_mallocz(codec->priv_data_size); @@ -1080,20 +1201,22 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code if ((ret = av_opt_set_dict(avctx, &tmp)) < 0) goto free_and_end; - // only call avcodec_set_dimensions() for non H.264/VP6F codecs so as not to overwrite previously setup dimensions + // only call ff_set_dimensions() for non H.264/VP6F codecs so as not to overwrite previously setup dimensions if (!(avctx->coded_width && avctx->coded_height && avctx->width && avctx->height && (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_VP6F))) { if (avctx->coded_width && avctx->coded_height) - avcodec_set_dimensions(avctx, avctx->coded_width, avctx->coded_height); + ret = ff_set_dimensions(avctx, avctx->coded_width, avctx->coded_height); else if (avctx->width && avctx->height) - avcodec_set_dimensions(avctx, avctx->width, avctx->height); + ret = ff_set_dimensions(avctx, avctx->width, avctx->height); + if (ret < 0) + goto free_and_end; } if ((avctx->coded_width || avctx->coded_height || avctx->width || avctx->height) && ( av_image_check_size(avctx->coded_width, avctx->coded_height, 0, avctx) < 0 || av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0)) { av_log(avctx, AV_LOG_WARNING, "Ignoring invalid width/height values\n"); - avcodec_set_dimensions(avctx, 0, 0); + ff_set_dimensions(avctx, 0, 0); } /* if the decoder init function was already called previously, @@ -1125,13 +1248,13 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { const char *codec_string = av_codec_is_encoder(codec) ? "encoder" : "decoder"; AVCodec *codec2; - av_log(NULL, AV_LOG_ERROR, + av_log(avctx, AV_LOG_ERROR, "The %s '%s' is experimental but experimental codecs are not enabled, " "add '-strict %d' if you want to use it.\n", codec_string, codec->name, FF_COMPLIANCE_EXPERIMENTAL); codec2 = av_codec_is_encoder(codec) ? avcodec_find_encoder(codec->id) : avcodec_find_decoder(codec->id); if (!(codec2->capabilities & CODEC_CAP_EXPERIMENTAL)) - av_log(NULL, AV_LOG_ERROR, "Alternatively use the non experimental %s '%s'.\n", + av_log(avctx, AV_LOG_ERROR, "Alternatively use the non experimental %s '%s'.\n", codec_string, codec2->name); ret = AVERROR_EXPERIMENTAL; goto free_and_end; @@ -1154,7 +1277,7 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code goto free_and_end; } - if (HAVE_THREADS && !avctx->thread_opaque + if (HAVE_THREADS && !(avctx->internal->frame_thread_encoder && (avctx->active_thread_type&FF_THREAD_FRAME))) { ret = ff_thread_init(avctx); if (ret < 0) { @@ -1354,17 +1477,24 @@ end: free_and_end: av_dict_free(&tmp); av_freep(&avctx->priv_data); - if (avctx->internal) + if (avctx->internal) { av_freep(&avctx->internal->pool); + av_frame_free(&avctx->internal->to_free); + } av_freep(&avctx->internal); avctx->codec = NULL; goto end; } -int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int size) +int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int64_t size) { - if (size < 0 || avpkt->size < 0 || size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE) { - av_log(avctx, AV_LOG_ERROR, "Size %d invalid\n", size); + if (avpkt->size < 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid negative user packet size %d\n", avpkt->size); + return AVERROR(EINVAL); + } + if (size < 0 || size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE) { + av_log(avctx, AV_LOG_ERROR, "Invalid minimum required packet size %"PRId64" (max allowed is %d)\n", + size, INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE); return AVERROR(EINVAL); } @@ -1381,17 +1511,21 @@ int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int size) if (avpkt->data) { AVBufferRef *buf = avpkt->buf; #if FF_API_DESTRUCT_PACKET +FF_DISABLE_DEPRECATION_WARNINGS void *destruct = avpkt->destruct; +FF_ENABLE_DEPRECATION_WARNINGS #endif if (avpkt->size < size) { - av_log(avctx, AV_LOG_ERROR, "User packet is too small (%d < %d)\n", avpkt->size, size); + av_log(avctx, AV_LOG_ERROR, "User packet is too small (%d < %"PRId64")\n", avpkt->size, size); return AVERROR(EINVAL); } av_init_packet(avpkt); #if FF_API_DESTRUCT_PACKET +FF_DISABLE_DEPRECATION_WARNINGS avpkt->destruct = destruct; +FF_ENABLE_DEPRECATION_WARNINGS #endif avpkt->buf = buf; avpkt->size = size; @@ -1399,7 +1533,7 @@ int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int size) } else { int ret = av_new_packet(avpkt, size); if (ret < 0) - av_log(avctx, AV_LOG_ERROR, "Failed to allocate packet of size %d\n", size); + av_log(avctx, AV_LOG_ERROR, "Failed to allocate packet of size %"PRId64"\n", size); return ret; } } @@ -1415,26 +1549,23 @@ int ff_alloc_packet(AVPacket *avpkt, int size) static int pad_last_frame(AVCodecContext *s, AVFrame **dst, const AVFrame *src) { AVFrame *frame = NULL; - uint8_t *buf = NULL; int ret; - if (!(frame = avcodec_alloc_frame())) + if (!(frame = av_frame_alloc())) return AVERROR(ENOMEM); - *frame = *src; - if ((ret = av_samples_get_buffer_size(&frame->linesize[0], s->channels, - s->frame_size, s->sample_fmt, 0)) < 0) + frame->format = src->format; + frame->channel_layout = src->channel_layout; + av_frame_set_channels(frame, av_frame_get_channels(src)); + frame->nb_samples = s->frame_size; + ret = av_frame_get_buffer(frame, 32); + if (ret < 0) goto fail; - if (!(buf = av_malloc(ret))) { - ret = AVERROR(ENOMEM); + ret = av_frame_copy_props(frame, src); + if (ret < 0) goto fail; - } - frame->nb_samples = s->frame_size; - if ((ret = avcodec_fill_audio_frame(frame, s->channels, s->sample_fmt, - buf, ret, 0)) < 0) - goto fail; if ((ret = av_samples_copy(frame->extended_data, src->extended_data, 0, 0, src->nb_samples, s->channels, s->sample_fmt)) < 0) goto fail; @@ -1448,10 +1579,7 @@ static int pad_last_frame(AVCodecContext *s, AVFrame **dst, const AVFrame *src) return 0; fail: - if (frame->extended_data != frame->data) - av_freep(&frame->extended_data); - av_freep(&buf); - av_freep(&frame); + av_frame_free(&frame); return ret; } @@ -1573,12 +1701,7 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, avpkt->flags |= AV_PKT_FLAG_KEY; end: - if (padded_frame) { - av_freep(&padded_frame->data[0]); - if (padded_frame->extended_data != padded_frame->data) - av_freep(&padded_frame->extended_data); - av_freep(&padded_frame); - } + av_frame_free(&padded_frame); return ret; } @@ -1589,7 +1712,6 @@ int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx, const short *samples) { AVPacket pkt; - AVFrame frame0 = { { 0 } }; AVFrame *frame; int ret, samples_size, got_packet; @@ -1598,8 +1720,7 @@ int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx, pkt.size = buf_size; if (samples) { - frame = &frame0; - avcodec_get_frame_defaults(frame); + frame = av_frame_alloc(); if (avctx->frame_size) { frame->nb_samples = avctx->frame_size; @@ -1610,13 +1731,16 @@ int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx, if (!av_get_bits_per_sample(avctx->codec_id)) { av_log(avctx, AV_LOG_ERROR, "avcodec_encode_audio() does not " "support this codec\n"); + av_frame_free(&frame); return AVERROR(EINVAL); } nb_samples = (int64_t)buf_size * 8 / (av_get_bits_per_sample(avctx->codec_id) * avctx->channels); - if (nb_samples >= INT_MAX) + if (nb_samples >= INT_MAX) { + av_frame_free(&frame); return AVERROR(EINVAL); + } frame->nb_samples = nb_samples; } @@ -1628,8 +1752,10 @@ int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx, if ((ret = avcodec_fill_audio_frame(frame, avctx->channels, avctx->sample_fmt, (const uint8_t *)samples, - samples_size, 1)) < 0) + samples_size, 1)) < 0) { + av_frame_free(&frame); return ret; + } /* fabricate frame pts from sample count. * this is needed because the avcodec_encode_audio() API does not have @@ -1651,11 +1777,12 @@ int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx, avctx->coded_frame->key_frame = !!(pkt.flags & AV_PKT_FLAG_KEY); } /* free any side data since we cannot return it */ - ff_packet_free_side_data(&pkt); + av_packet_free_side_data(&pkt); if (frame && frame->extended_data != frame->data) av_freep(&frame->extended_data); + av_frame_free(&frame); return ret ? ret : pkt.size; } @@ -1767,6 +1894,8 @@ int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, if (ret < 0 || !*got_packet_ptr) av_free_packet(avpkt); + else + av_packet_merge_side_data(avpkt); emms_c(); return ret; @@ -1818,69 +1947,119 @@ static int64_t guess_correct_pts(AVCodecContext *ctx, return pts; } -static void apply_param_change(AVCodecContext *avctx, AVPacket *avpkt) +static int apply_param_change(AVCodecContext *avctx, AVPacket *avpkt) { - int size = 0; + int size = 0, ret; const uint8_t *data; uint32_t flags; - if (!(avctx->codec->capabilities & CODEC_CAP_PARAM_CHANGE)) - return; - data = av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, &size); - if (!data || size < 4) - return; + if (!data) + return 0; + + if (!(avctx->codec->capabilities & CODEC_CAP_PARAM_CHANGE)) { + av_log(avctx, AV_LOG_ERROR, "This decoder does not support parameter " + "changes, but PARAM_CHANGE side data was sent to it.\n"); + return AVERROR(EINVAL); + } + + if (size < 4) + goto fail; + flags = bytestream_get_le32(&data); size -= 4; - if (size < 4) /* Required for any of the changes */ - return; + if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT) { + if (size < 4) + goto fail; avctx->channels = bytestream_get_le32(&data); size -= 4; } if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT) { if (size < 8) - return; + goto fail; avctx->channel_layout = bytestream_get_le64(&data); size -= 8; } - if (size < 4) - return; if (flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) { + if (size < 4) + goto fail; avctx->sample_rate = bytestream_get_le32(&data); size -= 4; } if (flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) { if (size < 8) - return; + goto fail; avctx->width = bytestream_get_le32(&data); avctx->height = bytestream_get_le32(&data); - avcodec_set_dimensions(avctx, avctx->width, avctx->height); size -= 8; + ret = ff_set_dimensions(avctx, avctx->width, avctx->height); + if (ret < 0) + return ret; } + + return 0; +fail: + av_log(avctx, AV_LOG_ERROR, "PARAM_CHANGE side data too small.\n"); + return AVERROR_INVALIDDATA; } static int add_metadata_from_side_data(AVCodecContext *avctx, AVFrame *frame) { - int size, ret = 0; + int size; const uint8_t *side_metadata; - const uint8_t *end; - side_metadata = av_packet_get_side_data(avctx->pkt, + AVDictionary **frame_md = avpriv_frame_get_metadatap(frame); + + side_metadata = av_packet_get_side_data(avctx->internal->pkt, AV_PKT_DATA_STRINGS_METADATA, &size); - if (!side_metadata) - goto end; - end = side_metadata + size; - while (side_metadata < end) { - const uint8_t *key = side_metadata; - const uint8_t *val = side_metadata + strlen(key) + 1; - int ret = av_dict_set(avpriv_frame_get_metadatap(frame), key, val, 0); - if (ret < 0) - break; - side_metadata = val + strlen(val) + 1; - } -end: - return ret; + return av_packet_unpack_dictionary(side_metadata, size, frame_md); +} + +static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame) +{ + int ret; + + /* move the original frame to our backup */ + av_frame_unref(avci->to_free); + av_frame_move_ref(avci->to_free, frame); + + /* now copy everything except the AVBufferRefs back + * note that we make a COPY of the side data, so calling av_frame_free() on + * the caller's frame will work properly */ + ret = av_frame_copy_props(frame, avci->to_free); + if (ret < 0) + return ret; + + memcpy(frame->data, avci->to_free->data, sizeof(frame->data)); + memcpy(frame->linesize, avci->to_free->linesize, sizeof(frame->linesize)); + if (avci->to_free->extended_data != avci->to_free->data) { + int planes = av_frame_get_channels(avci->to_free); + int size = planes * sizeof(*frame->extended_data); + + if (!size) { + av_frame_unref(frame); + return AVERROR_BUG; + } + + frame->extended_data = av_malloc(size); + if (!frame->extended_data) { + av_frame_unref(frame); + return AVERROR(ENOMEM); + } + memcpy(frame->extended_data, avci->to_free->extended_data, + size); + } else + frame->extended_data = frame->data; + + frame->format = avci->to_free->format; + frame->width = avci->to_free->width; + frame->height = avci->to_free->height; + frame->channel_layout = avci->to_free->channel_layout; + frame->nb_samples = avci->to_free->nb_samples; + av_frame_set_channels(frame, av_frame_get_channels(avci->to_free)); + + return 0; } int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, @@ -1892,6 +2071,8 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi // copy to ensure we do not change avpkt AVPacket tmp = *avpkt; + if (!avctx->codec) + return AVERROR(EINVAL); if (avctx->codec->type != AVMEDIA_TYPE_VIDEO) { av_log(avctx, AV_LOG_ERROR, "Invalid media type for video\n"); return AVERROR(EINVAL); @@ -1901,15 +2082,18 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi if ((avctx->coded_width || avctx->coded_height) && av_image_check_size(avctx->coded_width, avctx->coded_height, 0, avctx)) return AVERROR(EINVAL); - avcodec_get_frame_defaults(picture); - - if (!avctx->refcounted_frames) - av_frame_unref(&avci->to_free); + av_frame_unref(picture); if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type & FF_THREAD_FRAME)) { int did_split = av_packet_split_side_data(&tmp); - apply_param_change(avctx, &tmp); - avctx->pkt = &tmp; + ret = apply_param_change(avctx, &tmp); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n"); + if (avctx->err_recognition & AV_EF_EXPLODE) + goto fail; + } + + avctx->internal->pkt = &tmp; if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) ret = ff_thread_decode_frame(avctx, picture, got_picture_ptr, &tmp); @@ -1932,22 +2116,21 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi } add_metadata_from_side_data(avctx, picture); +fail: emms_c(); //needed to avoid an emms_c() call before every return; - avctx->pkt = NULL; + avctx->internal->pkt = NULL; if (did_split) { - ff_packet_free_side_data(&tmp); + av_packet_free_side_data(&tmp); if(ret == tmp.size) ret = avpkt->size; } - if (ret < 0 && picture->data[0]) - av_frame_unref(picture); - if (*got_picture_ptr) { if (!avctx->refcounted_frames) { - avci->to_free = *picture; - avci->to_free.extended_data = avci->to_free.data; + int err = unrefcount_frame(avci, picture); + if (err < 0) + return err; } avctx->frame_number++; @@ -1955,13 +2138,14 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi guess_correct_pts(avctx, picture->pkt_pts, picture->pkt_dts)); - } + } else + av_frame_unref(picture); } else ret = 0; /* many decoders assign whole AVFrames, thus overwriting extended_data; * make sure it's set correctly */ - picture->extended_data = picture->data; + av_assert0(!picture->extended_data || picture->extended_data == picture->data); return ret; } @@ -1971,7 +2155,7 @@ int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *sa int *frame_size_ptr, AVPacket *avpkt) { - AVFrame frame = { { 0 } }; + AVFrame *frame = av_frame_alloc(); int ret, got_frame = 0; if (avctx->get_buffer != avcodec_default_get_buffer) { @@ -1983,26 +2167,27 @@ int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *sa avctx->release_buffer = avcodec_default_release_buffer; } - ret = avcodec_decode_audio4(avctx, &frame, &got_frame, avpkt); + ret = avcodec_decode_audio4(avctx, frame, &got_frame, avpkt); if (ret >= 0 && got_frame) { int ch, plane_size; int planar = av_sample_fmt_is_planar(avctx->sample_fmt); int data_size = av_samples_get_buffer_size(&plane_size, avctx->channels, - frame.nb_samples, + frame->nb_samples, avctx->sample_fmt, 1); if (*frame_size_ptr < data_size) { av_log(avctx, AV_LOG_ERROR, "output buffer size is too small for " "the current frame (%d < %d)\n", *frame_size_ptr, data_size); + av_frame_free(&frame); return AVERROR(EINVAL); } - memcpy(samples, frame.extended_data[0], plane_size); + memcpy(samples, frame->extended_data[0], plane_size); if (planar && avctx->channels > 1) { uint8_t *out = ((uint8_t *)samples) + plane_size; for (ch = 1; ch < avctx->channels; ch++) { - memcpy(out, frame.extended_data[ch], plane_size); + memcpy(out, frame->extended_data[ch], plane_size); out += plane_size; } } @@ -2010,6 +2195,7 @@ int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *sa } else { *frame_size_ptr = 0; } + av_frame_free(&frame); return ret; } @@ -2021,7 +2207,6 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, const AVPacket *avpkt) { AVCodecInternal *avci = avctx->internal; - int planar, channels; int ret = 0; *got_frame_ptr = 0; @@ -2030,30 +2215,39 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n"); return AVERROR(EINVAL); } + if (!avctx->codec) + return AVERROR(EINVAL); if (avctx->codec->type != AVMEDIA_TYPE_AUDIO) { av_log(avctx, AV_LOG_ERROR, "Invalid media type for audio\n"); return AVERROR(EINVAL); } - avcodec_get_frame_defaults(frame); - - if (!avctx->refcounted_frames) - av_frame_unref(&avci->to_free); + av_frame_unref(frame); - if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size) { + if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type & FF_THREAD_FRAME)) { uint8_t *side; int side_size; + uint32_t discard_padding = 0; // copy to ensure we do not change avpkt AVPacket tmp = *avpkt; int did_split = av_packet_split_side_data(&tmp); - apply_param_change(avctx, &tmp); + ret = apply_param_change(avctx, &tmp); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n"); + if (avctx->err_recognition & AV_EF_EXPLODE) + goto fail; + } - avctx->pkt = &tmp; - ret = avctx->codec->decode(avctx, frame, got_frame_ptr, &tmp); + avctx->internal->pkt = &tmp; + if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) + ret = ff_thread_decode_frame(avctx, frame, got_frame_ptr, &tmp); + else { + ret = avctx->codec->decode(avctx, frame, got_frame_ptr, &tmp); + frame->pkt_dts = avpkt->dts; + } if (ret >= 0 && *got_frame_ptr) { add_metadata_from_side_data(avctx, frame); avctx->frame_number++; - frame->pkt_dts = avpkt->dts; av_frame_set_best_effort_timestamp(frame, guess_correct_pts(avctx, frame->pkt_pts, @@ -2066,17 +2260,14 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, av_frame_set_channels(frame, avctx->channels); if (!frame->sample_rate) frame->sample_rate = avctx->sample_rate; - if (!avctx->refcounted_frames) { - avci->to_free = *frame; - avci->to_free.extended_data = avci->to_free.data; - } } - side= av_packet_get_side_data(avctx->pkt, AV_PKT_DATA_SKIP_SAMPLES, &side_size); + side= av_packet_get_side_data(avctx->internal->pkt, AV_PKT_DATA_SKIP_SAMPLES, &side_size); if(side && side_size>=10) { avctx->internal->skip_samples = AV_RL32(side); av_log(avctx, AV_LOG_DEBUG, "skip %d samples due to side data\n", avctx->internal->skip_samples); + discard_padding = AV_RL32(side + 4); } if (avctx->internal->skip_samples && *got_frame_ptr) { if(frame->nb_samples <= avctx->internal->skip_samples){ @@ -2107,29 +2298,42 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, } } - avctx->pkt = NULL; + if (discard_padding > 0 && discard_padding <= frame->nb_samples && *got_frame_ptr) { + if (discard_padding == frame->nb_samples) { + *got_frame_ptr = 0; + } else { + if(avctx->pkt_timebase.num && avctx->sample_rate) { + int64_t diff_ts = av_rescale_q(frame->nb_samples - discard_padding, + (AVRational){1, avctx->sample_rate}, + avctx->pkt_timebase); + if (av_frame_get_pkt_duration(frame) >= diff_ts) + av_frame_set_pkt_duration(frame, av_frame_get_pkt_duration(frame) - diff_ts); + } else { + av_log(avctx, AV_LOG_WARNING, "Could not update timestamps for discarded samples.\n"); + } + av_log(avctx, AV_LOG_DEBUG, "discard %d/%d samples\n", + discard_padding, frame->nb_samples); + frame->nb_samples -= discard_padding; + } + } +fail: + avctx->internal->pkt = NULL; if (did_split) { - ff_packet_free_side_data(&tmp); + av_packet_free_side_data(&tmp); if(ret == tmp.size) ret = avpkt->size; } - if (ret < 0 && frame->data[0]) + if (ret >= 0 && *got_frame_ptr) { + if (!avctx->refcounted_frames) { + int err = unrefcount_frame(avci, frame); + if (err < 0) + return err; + } + } else av_frame_unref(frame); } - /* many decoders assign whole AVFrames, thus overwriting extended_data; - * make sure it's set correctly; assume decoders that actually use - * extended_data are doing it correctly */ - if (*got_frame_ptr) { - planar = av_sample_fmt_is_planar(frame->format); - channels = av_frame_get_channels(frame); - if (!(planar && channels > AV_NUM_DATA_POINTERS)) - frame->extended_data = frame->data; - } else { - frame->extended_data = NULL; - } - return ret; } @@ -2145,7 +2349,7 @@ static int recode_subtitle(AVCodecContext *avctx, AVPacket tmp; #endif - if (avctx->sub_charenc_mode != FF_SUB_CHARENC_MODE_PRE_DECODER) + if (avctx->sub_charenc_mode != FF_SUB_CHARENC_MODE_PRE_DECODER || inpkt->size == 0) return 0; #if CONFIG_ICONV @@ -2180,7 +2384,7 @@ static int recode_subtitle(AVCodecContext *avctx, goto end; } outpkt->size -= outl; - outpkt->data[outpkt->size - 1] = '\0'; + memset(outpkt->data + outpkt->size, 0, outl); end: if (cd != (iconv_t)-1) @@ -2191,12 +2395,37 @@ end: #endif } +static int utf8_check(const uint8_t *str) +{ + const uint8_t *byte; + uint32_t codepoint, min; + + while (*str) { + byte = str; + GET_UTF8(codepoint, *(byte++), return 0;); + min = byte - str == 1 ? 0 : byte - str == 2 ? 0x80 : + 1 << (5 * (byte - str) - 4); + if (codepoint < min || codepoint >= 0x110000 || + codepoint == 0xFFFE /* BOM */ || + codepoint >= 0xD800 && codepoint <= 0xDFFF /* surrogates */) + return 0; + str = byte; + } + return 1; +} + int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, int *got_sub_ptr, AVPacket *avpkt) { - int ret = 0; + int i, ret = 0; + if (!avpkt->data && avpkt->size) { + av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n"); + return AVERROR(EINVAL); + } + if (!avctx->codec) + return AVERROR(EINVAL); if (avctx->codec->type != AVMEDIA_TYPE_SUBTITLE) { av_log(avctx, AV_LOG_ERROR, "Invalid media type for subtitles\n"); return AVERROR(EINVAL); @@ -2205,18 +2434,28 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, *got_sub_ptr = 0; avcodec_get_subtitle_defaults(sub); - if (avpkt->size) { + if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size) { AVPacket pkt_recoded; AVPacket tmp = *avpkt; int did_split = av_packet_split_side_data(&tmp); //apply_param_change(avctx, &tmp); + if (did_split) { + /* FFMIN() prevents overflow in case the packet wasn't allocated with + * proper padding. + * If the side data is smaller than the buffer padding size, the + * remaining bytes should have already been filled with zeros by the + * original packet allocation anyway. */ + memset(tmp.data + tmp.size, 0, + FFMIN(avpkt->size - tmp.size, FF_INPUT_BUFFER_PADDING_SIZE)); + } + pkt_recoded = tmp; ret = recode_subtitle(avctx, &pkt_recoded, &tmp); if (ret < 0) { *got_sub_ptr = 0; } else { - avctx->pkt = &pkt_recoded; + avctx->internal->pkt = &pkt_recoded; if (avctx->pkt_timebase.den && avpkt->pts != AV_NOPTS_VALUE) sub->pts = av_rescale_q(avpkt->pts, @@ -2224,6 +2463,24 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, ret = avctx->codec->decode(avctx, sub, got_sub_ptr, &pkt_recoded); av_assert1((ret >= 0) >= !!*got_sub_ptr && !!*got_sub_ptr >= !!sub->num_rects); + + if (sub->num_rects && !sub->end_display_time && avpkt->duration && + avctx->pkt_timebase.num) { + AVRational ms = { 1, 1000 }; + sub->end_display_time = av_rescale_q(avpkt->duration, + avctx->pkt_timebase, ms); + } + + for (i = 0; i < sub->num_rects; i++) { + if (sub->rects[i]->ass && !utf8_check(sub->rects[i]->ass)) { + av_log(avctx, AV_LOG_ERROR, + "Invalid UTF-8 in decoded subtitles text; " + "maybe missing -sub_charenc option\n"); + avsubtitle_free(sub); + return AVERROR_INVALIDDATA; + } + } + if (tmp.data != pkt_recoded.data) { // did we recode? /* prevent from destroying side data from original packet */ pkt_recoded.side_data = NULL; @@ -2231,12 +2488,15 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, av_free_packet(&pkt_recoded); } - sub->format = !(avctx->codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB); - avctx->pkt = NULL; + if (avctx->codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB) + sub->format = 0; + else if (avctx->codec_descriptor->props & AV_CODEC_PROP_TEXT_SUB) + sub->format = 1; + avctx->internal->pkt = NULL; } if (did_split) { - ff_packet_free_side_data(&tmp); + av_packet_free_side_data(&tmp); if(ret == tmp.size) ret = avpkt->size; } @@ -2281,7 +2541,12 @@ av_cold int ff_codec_close_recursive(AVCodecContext *avctx) av_cold int avcodec_close(AVCodecContext *avctx) { - int ret = ff_lock_avcodec(avctx); + int ret; + + if (!avctx) + return 0; + + ret = ff_lock_avcodec(avctx); if (ret < 0) return ret; @@ -2294,15 +2559,14 @@ av_cold int avcodec_close(AVCodecContext *avctx) ff_frame_thread_encoder_free(avctx); ff_lock_avcodec(avctx); } - if (HAVE_THREADS && avctx->thread_opaque) + if (HAVE_THREADS && avctx->internal->thread_ctx) ff_thread_free(avctx); if (avctx->codec && avctx->codec->close) avctx->codec->close(avctx); avctx->coded_frame = NULL; avctx->internal->byte_buffer_size = 0; av_freep(&avctx->internal->byte_buffer); - if (!avctx->refcounted_frames) - av_frame_unref(&avctx->internal->to_free); + av_frame_free(&avctx->internal->to_free); for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++) av_buffer_pool_uninit(&pool->pools[i]); av_freep(&avctx->internal->pool); @@ -2330,6 +2594,12 @@ static enum AVCodecID remap_deprecated_codec_id(enum AVCodecID id) // case AV_CODEC_ID_UTVIDEO_DEPRECATED: return AV_CODEC_ID_UTVIDEO; case AV_CODEC_ID_OPUS_DEPRECATED: return AV_CODEC_ID_OPUS; case AV_CODEC_ID_TAK_DEPRECATED : return AV_CODEC_ID_TAK; + case AV_CODEC_ID_PCM_S24LE_PLANAR_DEPRECATED : return AV_CODEC_ID_PCM_S24LE_PLANAR; + case AV_CODEC_ID_PCM_S32LE_PLANAR_DEPRECATED : return AV_CODEC_ID_PCM_S32LE_PLANAR; + case AV_CODEC_ID_ESCAPE130_DEPRECATED : return AV_CODEC_ID_ESCAPE130; + case AV_CODEC_ID_G2M_DEPRECATED : return AV_CODEC_ID_G2M; + case AV_CODEC_ID_WEBP_DEPRECATED: return AV_CODEC_ID_WEBP; + case AV_CODEC_ID_HEVC_DEPRECATED: return AV_CODEC_ID_HEVC; default : return id; } } @@ -2453,9 +2723,13 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) profile = av_get_profile_name(p, enc->profile); } - snprintf(buf, buf_size, "%s: %s%s", codec_type ? codec_type : "unknown", - codec_name, enc->mb_decision ? " (hq)" : ""); + snprintf(buf, buf_size, "%s: %s", codec_type ? codec_type : "unknown", + codec_name); buf[0] ^= 'a' ^ 'A'; /* first letter in uppercase */ + + if (enc->codec && strcmp(enc->codec->name, codec_name)) + snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%s)", enc->codec->name); + if (profile) snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%s)", profile); if (enc->codec_tag) { @@ -2468,13 +2742,26 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) switch (enc->codec_type) { case AVMEDIA_TYPE_VIDEO: if (enc->pix_fmt != AV_PIX_FMT_NONE) { + char detail[256] = "("; + const char *colorspace_name; snprintf(buf + strlen(buf), buf_size - strlen(buf), ", %s", av_get_pix_fmt_name(enc->pix_fmt)); if (enc->bits_per_raw_sample && enc->bits_per_raw_sample <= av_pix_fmt_desc_get(enc->pix_fmt)->comp[0].depth_minus1) - snprintf(buf + strlen(buf), buf_size - strlen(buf), - " (%d bpc)", enc->bits_per_raw_sample); + av_strlcatf(detail, sizeof(detail), "%d bpc, ", enc->bits_per_raw_sample); + if (enc->color_range != AVCOL_RANGE_UNSPECIFIED) + av_strlcatf(detail, sizeof(detail), + enc->color_range == AVCOL_RANGE_MPEG ? "tv, ": "pc, "); + + colorspace_name = av_get_colorspace_name(enc->colorspace); + if (colorspace_name) + av_strlcatf(detail, sizeof(detail), "%s, ", colorspace_name); + + if (strlen(detail) > 1) { + detail[strlen(detail) - 2] = 0; + av_strlcatf(buf, buf_size, "%s)", detail); + } } if (enc->width) { snprintf(buf + strlen(buf), buf_size - strlen(buf), @@ -2523,6 +2810,11 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) enc->time_base.num / g, enc->time_base.den / g); } break; + case AVMEDIA_TYPE_SUBTITLE: + if (enc->width) + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", %dx%d", enc->width, enc->height); + break; default: return; } @@ -2538,6 +2830,9 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) if (bitrate != 0) { snprintf(buf + strlen(buf), buf_size - strlen(buf), ", %d kb/s", bitrate / 1000); + } else if (enc->rc_max_rate > 0) { + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", max. %d kb/s", enc->rc_max_rate / 1000); } } @@ -2591,6 +2886,9 @@ void avcodec_flush_buffers(AVCodecContext *avctx) avctx->pts_correction_last_pts = avctx->pts_correction_last_dts = INT64_MIN; + + if (!avctx->refcounted_frames) + av_frame_unref(avctx->internal->to_free); } int av_get_exact_bits_per_sample(enum AVCodecID codec_id) @@ -2769,6 +3067,8 @@ int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes) switch (id) { case AV_CODEC_ID_ADPCM_AFC: return frame_bytes / (9 * ch) * 16; + case AV_CODEC_ID_ADPCM_DTK: + return frame_bytes / (16 * ch) * 28; case AV_CODEC_ID_ADPCM_4XM: case AV_CODEC_ID_ADPCM_IMA_ISS: return (frame_bytes - 4 * ch) * 2 / ch; @@ -2810,11 +3110,15 @@ int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes) int blocks = frame_bytes / ba; switch (avctx->codec_id) { case AV_CODEC_ID_ADPCM_IMA_WAV: - return blocks * (1 + (ba - 4 * ch) / (4 * ch) * 8); + if (bps < 2 || bps > 5) + return 0; + return blocks * (1 + (ba - 4 * ch) / (bps * ch) * 8); case AV_CODEC_ID_ADPCM_IMA_DK3: return blocks * (((ba - 16) * 2 / 3 * 4) / ch); case AV_CODEC_ID_ADPCM_IMA_DK4: return blocks * (1 + (ba - 4 * ch) * 2 / ch); + case AV_CODEC_ID_ADPCM_IMA_RAD: + return blocks * ((ba - 4 * ch) * 2 / ch); case AV_CODEC_ID_ADPCM_MS: return blocks * (2 + (ba - 7 * ch) * 2 / ch); } @@ -2871,6 +3175,7 @@ int ff_match_2uint16(const uint16_t(*tab)[2], int size, int a, int b) } #if FF_API_MISSING_SAMPLE +FF_DISABLE_DEPRECATION_WARNINGS void av_log_missing_feature(void *avc, const char *feature, int want_sample) { av_log(avc, AV_LOG_WARNING, "%s is not implemented. Update your FFmpeg " @@ -2895,17 +3200,19 @@ void av_log_ask_for_sample(void *avc, const char *msg, ...) va_end(argument_list); } +FF_ENABLE_DEPRECATION_WARNINGS #endif /* FF_API_MISSING_SAMPLE */ static AVHWAccel *first_hwaccel = NULL; +static AVHWAccel **last_hwaccel = &first_hwaccel; void av_register_hwaccel(AVHWAccel *hwaccel) { - AVHWAccel **p = &first_hwaccel; - while (*p) - p = &(*p)->next; - *p = hwaccel; + AVHWAccel **p = last_hwaccel; hwaccel->next = NULL; + while(*p || avpriv_atomic_ptr_cas((void * volatile *)p, NULL, hwaccel)) + p = &(*p)->next; + last_hwaccel = &hwaccel->next; } AVHWAccel *av_hwaccel_next(AVHWAccel *hwaccel) @@ -2913,8 +3220,11 @@ AVHWAccel *av_hwaccel_next(AVHWAccel *hwaccel) return hwaccel ? hwaccel->next : first_hwaccel; } -AVHWAccel *ff_find_hwaccel(enum AVCodecID codec_id, enum AVPixelFormat pix_fmt) +AVHWAccel *ff_find_hwaccel(AVCodecContext *avctx) { + enum AVCodecID codec_id = avctx->codec->id; + enum AVPixelFormat pix_fmt = avctx->pix_fmt; + AVHWAccel *hwaccel = NULL; while ((hwaccel = av_hwaccel_next(hwaccel))) @@ -2926,19 +3236,19 @@ AVHWAccel *ff_find_hwaccel(enum AVCodecID codec_id, enum AVPixelFormat pix_fmt) int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op)) { - if (ff_lockmgr_cb) { - if (ff_lockmgr_cb(&codec_mutex, AV_LOCK_DESTROY)) + if (lockmgr_cb) { + if (lockmgr_cb(&codec_mutex, AV_LOCK_DESTROY)) return -1; - if (ff_lockmgr_cb(&avformat_mutex, AV_LOCK_DESTROY)) + if (lockmgr_cb(&avformat_mutex, AV_LOCK_DESTROY)) return -1; } - ff_lockmgr_cb = cb; + lockmgr_cb = cb; - if (ff_lockmgr_cb) { - if (ff_lockmgr_cb(&codec_mutex, AV_LOCK_CREATE)) + if (lockmgr_cb) { + if (lockmgr_cb(&codec_mutex, AV_LOCK_CREATE)) return -1; - if (ff_lockmgr_cb(&avformat_mutex, AV_LOCK_CREATE)) + if (lockmgr_cb(&avformat_mutex, AV_LOCK_CREATE)) return -1; } return 0; @@ -2946,13 +3256,15 @@ int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op)) int ff_lock_avcodec(AVCodecContext *log_ctx) { - if (ff_lockmgr_cb) { - if ((*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_OBTAIN)) + if (lockmgr_cb) { + if ((*lockmgr_cb)(&codec_mutex, AV_LOCK_OBTAIN)) return -1; } entangled_thread_counter++; if (entangled_thread_counter != 1) { av_log(log_ctx, AV_LOG_ERROR, "Insufficient thread locking around avcodec_open/close()\n"); + if (!lockmgr_cb) + av_log(log_ctx, AV_LOG_ERROR, "No lock manager is set, please see av_lockmgr_register()\n"); ff_avcodec_locked = 1; ff_unlock_avcodec(); return AVERROR(EINVAL); @@ -2967,8 +3279,8 @@ int ff_unlock_avcodec(void) av_assert0(ff_avcodec_locked); ff_avcodec_locked = 0; entangled_thread_counter--; - if (ff_lockmgr_cb) { - if ((*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE)) + if (lockmgr_cb) { + if ((*lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE)) return -1; } return 0; @@ -2976,8 +3288,8 @@ int ff_unlock_avcodec(void) int avpriv_lock_avformat(void) { - if (ff_lockmgr_cb) { - if ((*ff_lockmgr_cb)(&avformat_mutex, AV_LOCK_OBTAIN)) + if (lockmgr_cb) { + if ((*lockmgr_cb)(&avformat_mutex, AV_LOCK_OBTAIN)) return -1; } return 0; @@ -2985,8 +3297,8 @@ int avpriv_lock_avformat(void) int avpriv_unlock_avformat(void) { - if (ff_lockmgr_cb) { - if ((*ff_lockmgr_cb)(&avformat_mutex, AV_LOCK_RELEASE)) + if (lockmgr_cb) { + if ((*lockmgr_cb)(&avformat_mutex, AV_LOCK_RELEASE)) return -1; } return 0; @@ -3021,6 +3333,11 @@ int ff_thread_ref_frame(ThreadFrame *dst, ThreadFrame *src) #if !HAVE_THREADS +enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt) +{ + return avctx->get_format(avctx, fmt); +} + int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags) { f->owner = avctx; @@ -3049,6 +3366,23 @@ int ff_thread_can_start_frame(AVCodecContext *avctx) return 1; } +int ff_alloc_entries(AVCodecContext *avctx, int count) +{ + return 0; +} + +void ff_reset_entries(AVCodecContext *avctx) +{ +} + +void ff_thread_await_progress2(AVCodecContext *avctx, int field, int thread, int shift) +{ +} + +void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n) +{ +} + #endif enum AVMediaType avcodec_get_type(enum AVCodecID codec_id) @@ -3093,3 +3427,36 @@ int avpriv_bprint_to_extradata(AVCodecContext *avctx, struct AVBPrint *buf) avctx->extradata_size = buf->len; return 0; } + +const uint8_t *avpriv_find_start_code(const uint8_t *av_restrict p, + const uint8_t *end, + uint32_t *av_restrict state) +{ + int i; + + av_assert0(p <= end); + if (p >= end) + return end; + + for (i = 0; i < 3; i++) { + uint32_t tmp = *state << 8; + *state = tmp + *(p++); + if (tmp == 0x100 || p == end) + return p; + } + + while (p < end) { + if (p[-1] > 1 ) p += 3; + else if (p[-2] ) p += 2; + else if (p[-3]|(p[-1]-1)) p++; + else { + p++; + break; + } + } + + p = FFMIN(p, end) - 4; + *state = AV_RB32(p); + + return p + 4; +} diff --git a/ffmpeg/libavcodec/utvideodec.c b/ffmpeg/libavcodec/utvideodec.c index 4efad1e..e3ef22d 100644 --- a/ffmpeg/libavcodec/utvideodec.c +++ b/ffmpeg/libavcodec/utvideodec.c @@ -70,7 +70,7 @@ static int build_huff(const uint8_t *src, VLC *vlc, int *fsym) code += 0x80000000u >> (he[i].len - 1); } - return ff_init_vlc_sparse(vlc, FFMIN(he[last].len, 9), last + 1, + return ff_init_vlc_sparse(vlc, FFMIN(he[last].len, 10), last + 1, bits, sizeof(*bits), sizeof(*bits), codes, sizeof(*codes), sizeof(*codes), syms, sizeof(*syms), sizeof(*syms), 0); @@ -507,10 +507,22 @@ static av_cold int decode_init(AVCodecContext *avctx) case MKTAG('U', 'L', 'Y', '0'): c->planes = 3; avctx->pix_fmt = AV_PIX_FMT_YUV420P; + avctx->colorspace = AVCOL_SPC_BT470BG; break; case MKTAG('U', 'L', 'Y', '2'): c->planes = 3; avctx->pix_fmt = AV_PIX_FMT_YUV422P; + avctx->colorspace = AVCOL_SPC_BT470BG; + break; + case MKTAG('U', 'L', 'H', '0'): + c->planes = 3; + avctx->pix_fmt = AV_PIX_FMT_YUV420P; + avctx->colorspace = AVCOL_SPC_BT709; + break; + case MKTAG('U', 'L', 'H', '2'): + c->planes = 3; + avctx->pix_fmt = AV_PIX_FMT_YUV422P; + avctx->colorspace = AVCOL_SPC_BT709; break; default: av_log(avctx, AV_LOG_ERROR, "Unknown Ut Video FOURCC provided (%08X)\n", @@ -532,6 +544,7 @@ static av_cold int decode_end(AVCodecContext *avctx) AVCodec ff_utvideo_decoder = { .name = "utvideo", + .long_name = NULL_IF_CONFIG_SMALL("Ut Video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_UTVIDEO, .priv_data_size = sizeof(UtvideoContext), @@ -539,5 +552,4 @@ AVCodec ff_utvideo_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, - .long_name = NULL_IF_CONFIG_SMALL("Ut Video"), }; diff --git a/ffmpeg/libavcodec/utvideoenc.c b/ffmpeg/libavcodec/utvideoenc.c index acb25c3..e5a858d 100644 --- a/ffmpeg/libavcodec/utvideoenc.c +++ b/ffmpeg/libavcodec/utvideoenc.c @@ -24,6 +24,7 @@ * Ut Video encoder */ +#include "libavutil/imgutils.h" #include "libavutil/intreadwrite.h" #include "avcodec.h" #include "internal.h" @@ -125,7 +126,7 @@ static av_cold int utvideo_encode_init(AVCodecContext *avctx) return AVERROR_OPTION_NOT_FOUND; } - avctx->coded_frame = avcodec_alloc_frame(); + avctx->coded_frame = av_frame_alloc(); if (!avctx->coded_frame) { av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n"); @@ -230,20 +231,6 @@ static void mangle_rgb_planes(uint8_t *dst[4], int dst_stride, uint8_t *src, } } -/* Write data to a plane, no prediction applied */ -static void write_plane(uint8_t *src, uint8_t *dst, int stride, - int width, int height) -{ - int i, j; - - for (j = 0; j < height; j++) { - for (i = 0; i < width; i++) - *dst++ = src[i]; - - src += stride; - } -} - /* Write data to a plane with left prediction */ static void left_predict(uint8_t *src, uint8_t *dst, int stride, int width, int height) @@ -383,8 +370,9 @@ static int encode_plane(AVCodecContext *avctx, uint8_t *src, for (i = 0; i < c->slices; i++) { sstart = send; send = height * (i + 1) / c->slices; - write_plane(src + sstart * stride, dst + sstart * width, - stride, width, send - sstart); + av_image_copy_plane(dst + sstart * width, width, + src + sstart * stride, stride, + width, send - sstart); } break; case PRED_LEFT: @@ -525,8 +513,7 @@ static int utvideo_encode_frame(AVCodecContext *avctx, AVPacket *pkt, bytestream2_init_writer(&pb, dst, pkt->size); - av_fast_malloc(&c->slice_bits, &c->slice_bits_size, - width * height + FF_INPUT_BUFFER_PADDING_SIZE); + av_fast_padded_malloc(&c->slice_bits, &c->slice_bits_size, width * height); if (!c->slice_bits) { av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer 2.\n"); @@ -608,6 +595,7 @@ static int utvideo_encode_frame(AVCodecContext *avctx, AVPacket *pkt, AVCodec ff_utvideo_encoder = { .name = "utvideo", + .long_name = NULL_IF_CONFIG_SMALL("Ut Video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_UTVIDEO, .priv_data_size = sizeof(UtvideoContext), @@ -618,5 +606,4 @@ AVCodec ff_utvideo_encoder = { AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Ut Video"), }; diff --git a/ffmpeg/libavcodec/v210dec.c b/ffmpeg/libavcodec/v210dec.c index 42e25cc..ae03952 100644 --- a/ffmpeg/libavcodec/v210dec.c +++ b/ffmpeg/libavcodec/v210dec.c @@ -146,6 +146,13 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, v += pic->linesize[2] / 2 - avctx->width / 2; } + if (avctx->field_order > AV_FIELD_PROGRESSIVE) { + /* we have interlaced material flagged in container */ + pic->interlaced_frame = 1; + if (avctx->field_order == AV_FIELD_TT || avctx->field_order == AV_FIELD_TB) + pic->top_field_first = 1; + } + *got_frame = 1; return avpkt->size; @@ -167,12 +174,12 @@ static const AVClass v210dec_class = { AVCodec ff_v210_decoder = { .name = "v210", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_V210, .priv_data_size = sizeof(V210DecContext), .init = decode_init, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"), .priv_class = &v210dec_class, }; diff --git a/ffmpeg/libavcodec/v210dec.h b/ffmpeg/libavcodec/v210dec.h index e1e3d32..a8db7d6 100644 --- a/ffmpeg/libavcodec/v210dec.h +++ b/ffmpeg/libavcodec/v210dec.h @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/v210enc.c b/ffmpeg/libavcodec/v210enc.c index 5527686..1e53bdb 100644 --- a/ffmpeg/libavcodec/v210enc.c +++ b/ffmpeg/libavcodec/v210enc.c @@ -36,7 +36,7 @@ static av_cold int encode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_WARNING, "bits per raw sample: %d != 10-bit\n", avctx->bits_per_raw_sample); - avctx->coded_frame = avcodec_alloc_frame(); + avctx->coded_frame = av_frame_alloc(); if (!avctx->coded_frame) return AVERROR(ENOMEM); @@ -116,11 +116,11 @@ static av_cold int encode_close(AVCodecContext *avctx) AVCodec ff_v210_encoder = { .name = "v210", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_V210, .init = encode_init, .encode2 = encode_frame, .close = encode_close, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV422P10, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"), }; diff --git a/ffmpeg/libavcodec/v210x.c b/ffmpeg/libavcodec/v210x.c index e4d5460..6330715 100644 --- a/ffmpeg/libavcodec/v210x.c +++ b/ffmpeg/libavcodec/v210x.c @@ -122,10 +122,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVCodec ff_v210x_decoder = { .name = "v210x", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_V210X, .init = decode_init, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"), }; diff --git a/ffmpeg/libavcodec/v308dec.c b/ffmpeg/libavcodec/v308dec.c index cddc779..1d31f0a 100644 --- a/ffmpeg/libavcodec/v308dec.c +++ b/ffmpeg/libavcodec/v308dec.c @@ -68,24 +68,16 @@ static int v308_decode_frame(AVCodecContext *avctx, void *data, } *got_frame = 1; - *(AVFrame *)data = *pic; return avpkt->size; } -static av_cold int v308_decode_close(AVCodecContext *avctx) -{ - - return 0; -} - AVCodec ff_v308_decoder = { .name = "v308", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed 4:4:4"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_V308, .init = v308_decode_init, .decode = v308_decode_frame, - .close = v308_decode_close, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed 4:4:4"), }; diff --git a/ffmpeg/libavcodec/v308enc.c b/ffmpeg/libavcodec/v308enc.c index 10437cc..c6c5ac5 100644 --- a/ffmpeg/libavcodec/v308enc.c +++ b/ffmpeg/libavcodec/v308enc.c @@ -31,7 +31,7 @@ static av_cold int v308_encode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } - avctx->coded_frame = avcodec_alloc_frame(); + avctx->coded_frame = av_frame_alloc(); if (!avctx->coded_frame) { av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n"); @@ -84,11 +84,11 @@ static av_cold int v308_encode_close(AVCodecContext *avctx) AVCodec ff_v308_encoder = { .name = "v308", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed 4:4:4"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_V308, .init = v308_encode_init, .encode2 = v308_encode_frame, .close = v308_encode_close, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV444P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed 4:4:4"), }; diff --git a/ffmpeg/libavcodec/v408dec.c b/ffmpeg/libavcodec/v408dec.c index 31c14dc..be442fa 100644 --- a/ffmpeg/libavcodec/v408dec.c +++ b/ffmpeg/libavcodec/v408dec.c @@ -79,33 +79,25 @@ static int v408_decode_frame(AVCodecContext *avctx, void *data, return avpkt->size; } -static av_cold int v408_decode_close(AVCodecContext *avctx) -{ - - return 0; -} - #if CONFIG_AYUV_DECODER AVCodec ff_ayuv_decoder = { .name = "ayuv", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed MS 4:4:4:4"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_AYUV, .init = v408_decode_init, .decode = v408_decode_frame, - .close = v408_decode_close, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed MS 4:4:4:4"), }; #endif #if CONFIG_V408_DECODER AVCodec ff_v408_decoder = { .name = "v408", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed QT 4:4:4:4"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_V408, .init = v408_decode_init, .decode = v408_decode_frame, - .close = v408_decode_close, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed QT 4:4:4:4"), }; #endif diff --git a/ffmpeg/libavcodec/v408enc.c b/ffmpeg/libavcodec/v408enc.c index 694bdbf..20f08c7 100644 --- a/ffmpeg/libavcodec/v408enc.c +++ b/ffmpeg/libavcodec/v408enc.c @@ -26,7 +26,7 @@ static av_cold int v408_encode_init(AVCodecContext *avctx) { - avctx->coded_frame = avcodec_alloc_frame(); + avctx->coded_frame = av_frame_alloc(); if (!avctx->coded_frame) { av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n"); @@ -90,24 +90,24 @@ static av_cold int v408_encode_close(AVCodecContext *avctx) #if CONFIG_AYUV_ENCODER AVCodec ff_ayuv_encoder = { .name = "ayuv", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed MS 4:4:4:4"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_AYUV, .init = v408_encode_init, .encode2 = v408_encode_frame, .close = v408_encode_close, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUVA444P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed MS 4:4:4:4"), }; #endif #if CONFIG_V408_ENCODER AVCodec ff_v408_encoder = { .name = "v408", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed QT 4:4:4:4"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_V408, .init = v408_encode_init, .encode2 = v408_encode_frame, .close = v408_encode_close, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUVA444P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed QT 4:4:4:4"), }; #endif diff --git a/ffmpeg/libavcodec/v410dec.c b/ffmpeg/libavcodec/v410dec.c index f8229e2..e7a9c0e 100644 --- a/ffmpeg/libavcodec/v410dec.c +++ b/ffmpeg/libavcodec/v410dec.c @@ -89,10 +89,10 @@ static int v410_decode_frame(AVCodecContext *avctx, void *data, AVCodec ff_v410_decoder = { .name = "v410", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:4:4 10-bit"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_V410, .init = v410_decode_init, .decode = v410_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:4:4 10-bit"), }; diff --git a/ffmpeg/libavcodec/v410enc.c b/ffmpeg/libavcodec/v410enc.c index 9661c7c..0e2e82a 100644 --- a/ffmpeg/libavcodec/v410enc.c +++ b/ffmpeg/libavcodec/v410enc.c @@ -32,7 +32,7 @@ static av_cold int v410_encode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } - avctx->coded_frame = avcodec_alloc_frame(); + avctx->coded_frame = av_frame_alloc(); if (!avctx->coded_frame) { av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n"); @@ -88,11 +88,11 @@ static av_cold int v410_encode_close(AVCodecContext *avctx) AVCodec ff_v410_encoder = { .name = "v410", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:4:4 10-bit"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_V410, .init = v410_encode_init, .encode2 = v410_encode_frame, .close = v410_encode_close, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV444P10, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:4:4 10-bit"), }; diff --git a/ffmpeg/libavcodec/vaapi.c b/ffmpeg/libavcodec/vaapi.c index a220a9d..db4d29d 100644 --- a/ffmpeg/libavcodec/vaapi.c +++ b/ffmpeg/libavcodec/vaapi.c @@ -46,6 +46,9 @@ int ff_vaapi_render_picture(struct vaapi_context *vactx, VASurfaceID surface) VABufferID va_buffers[3]; unsigned int n_va_buffers = 0; + if (!vactx->pic_param_buf_id) + return 0; + vaUnmapBuffer(vactx->display, vactx->pic_param_buf_id); va_buffers[n_va_buffers++] = vactx->pic_param_buf_id; @@ -194,26 +197,4 @@ void ff_vaapi_common_end_frame(AVCodecContext *avctx) vactx->slice_params_alloc = 0; } -int ff_vaapi_mpeg_end_frame(AVCodecContext *avctx) -{ - struct vaapi_context * const vactx = avctx->hwaccel_context; - MpegEncContext *s = avctx->priv_data; - int ret; - - ret = ff_vaapi_commit_slices(vactx); - if (ret < 0) - goto finish; - - ret = ff_vaapi_render_picture(vactx, - ff_vaapi_get_surface_id(s->current_picture_ptr)); - if (ret < 0) - goto finish; - - ff_mpeg_draw_horiz_band(s, 0, s->avctx->height); - -finish: - ff_vaapi_common_end_frame(avctx); - return ret; -} - /* @} */ diff --git a/ffmpeg/libavcodec/vaapi_mpeg2.c b/ffmpeg/libavcodec/vaapi_mpeg2.c index d626f24..cdc70ee 100644 --- a/ffmpeg/libavcodec/vaapi_mpeg2.c +++ b/ffmpeg/libavcodec/vaapi_mpeg2.c @@ -115,8 +115,8 @@ static int vaapi_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer intra_slice_flag = get_bits1(&gb); if (intra_slice_flag) { skip_bits(&gb, 8); - while (get_bits1(&gb) != 0) - skip_bits(&gb, 8); + if (skip_1stop_8data_bits(&gb) < 0) + return AVERROR_INVALIDDATA; } macroblock_offset = get_bits_count(&gb); diff --git a/ffmpeg/libavcodec/vaapi_mpeg4.c b/ffmpeg/libavcodec/vaapi_mpeg4.c index bcc0eba..9ed007f 100644 --- a/ffmpeg/libavcodec/vaapi_mpeg4.c +++ b/ffmpeg/libavcodec/vaapi_mpeg4.c @@ -22,9 +22,10 @@ #include "vaapi_internal.h" #include "h263.h" +#include "mpeg4video.h" /** Reconstruct bitstream intra_dc_vlc_thr */ -static int mpeg4_get_intra_dc_vlc_thr(MpegEncContext *s) +static int mpeg4_get_intra_dc_vlc_thr(Mpeg4DecContext *s) { switch (s->intra_dc_threshold) { case 99: return 0; @@ -41,7 +42,8 @@ static int mpeg4_get_intra_dc_vlc_thr(MpegEncContext *s) static int vaapi_mpeg4_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size) { - MpegEncContext * const s = avctx->priv_data; + Mpeg4DecContext *ctx = avctx->priv_data; + MpegEncContext * const s = &ctx->m; struct vaapi_context * const vactx = avctx->hwaccel_context; VAPictureParameterBufferMPEG4 *pic_param; VAIQMatrixBufferMPEG4 *iq_matrix; @@ -64,24 +66,24 @@ static int vaapi_mpeg4_start_frame(AVCodecContext *avctx, av_unused const uint8_ pic_param->vol_fields.bits.chroma_format = CHROMA_420; pic_param->vol_fields.bits.interlaced = !s->progressive_sequence; pic_param->vol_fields.bits.obmc_disable = 1; - pic_param->vol_fields.bits.sprite_enable = s->vol_sprite_usage; + pic_param->vol_fields.bits.sprite_enable = ctx->vol_sprite_usage; pic_param->vol_fields.bits.sprite_warping_accuracy = s->sprite_warping_accuracy; pic_param->vol_fields.bits.quant_type = s->mpeg_quant; pic_param->vol_fields.bits.quarter_sample = s->quarter_sample; pic_param->vol_fields.bits.data_partitioned = s->data_partitioning; - pic_param->vol_fields.bits.reversible_vlc = s->rvlc; - pic_param->vol_fields.bits.resync_marker_disable = !s->resync_marker; - pic_param->no_of_sprite_warping_points = s->num_sprite_warping_points; - for (i = 0; i < s->num_sprite_warping_points && i < 3; i++) { - pic_param->sprite_trajectory_du[i] = s->sprite_traj[i][0]; - pic_param->sprite_trajectory_dv[i] = s->sprite_traj[i][1]; + pic_param->vol_fields.bits.reversible_vlc = ctx->rvlc; + pic_param->vol_fields.bits.resync_marker_disable = !ctx->resync_marker; + pic_param->no_of_sprite_warping_points = ctx->num_sprite_warping_points; + for (i = 0; i < ctx->num_sprite_warping_points && i < 3; i++) { + pic_param->sprite_trajectory_du[i] = ctx->sprite_traj[i][0]; + pic_param->sprite_trajectory_dv[i] = ctx->sprite_traj[i][1]; } pic_param->quant_precision = s->quant_precision; pic_param->vop_fields.value = 0; /* reset all bits */ pic_param->vop_fields.bits.vop_coding_type = s->pict_type - AV_PICTURE_TYPE_I; pic_param->vop_fields.bits.backward_reference_vop_coding_type = s->pict_type == AV_PICTURE_TYPE_B ? s->next_picture.f.pict_type - AV_PICTURE_TYPE_I : 0; pic_param->vop_fields.bits.vop_rounding_type = s->no_rounding; - pic_param->vop_fields.bits.intra_dc_vlc_thr = mpeg4_get_intra_dc_vlc_thr(s); + pic_param->vop_fields.bits.intra_dc_vlc_thr = mpeg4_get_intra_dc_vlc_thr(ctx); pic_param->vop_fields.bits.top_field_first = s->top_field_first; pic_param->vop_fields.bits.alternate_vertical_scan_flag = s->alternate_scan; pic_param->vop_fcode_forward = s->f_code; @@ -122,25 +124,14 @@ static int vaapi_mpeg4_decode_slice(AVCodecContext *avctx, const uint8_t *buffer av_dlog(avctx, "vaapi_mpeg4_decode_slice(): buffer %p, size %d\n", buffer, size); - /* video_plane_with_short_video_header() contains all GOBs - * in-order, and this is what VA API (Intel backend) expects: only - * a single slice param. So fake macroblock_number for FFmpeg so - * that we don't call vaapi_mpeg4_decode_slice() again - */ - if (avctx->codec->id == AV_CODEC_ID_H263) - size = s->gb.buffer_end - buffer; - /* Fill in VASliceParameterBufferMPEG4 */ slice_param = (VASliceParameterBufferMPEG4 *)ff_vaapi_alloc_slice(avctx->hwaccel_context, buffer, size); if (!slice_param) return -1; slice_param->macroblock_offset = get_bits_count(&s->gb) % 8; - slice_param->macroblock_number = s->mb_y * s->mb_width + s->mb_x; + slice_param->macroblock_number = 0; slice_param->quant_scale = s->qscale; - if (avctx->codec->id == AV_CODEC_ID_H263) - s->mb_y = s->mb_height; - return 0; } diff --git a/ffmpeg/libavcodec/vaapi_vc1.c b/ffmpeg/libavcodec/vaapi_vc1.c index b8f0530..266fa3c 100644 --- a/ffmpeg/libavcodec/vaapi_vc1.c +++ b/ffmpeg/libavcodec/vaapi_vc1.c @@ -169,7 +169,7 @@ static int vaapi_vc1_start_frame(AVCodecContext *avctx, av_unused const uint8_t pic_param->sequence_fields.bits.psf = v->psf; pic_param->sequence_fields.bits.multires = v->multires; pic_param->sequence_fields.bits.overlap = v->overlap; - pic_param->sequence_fields.bits.syncmarker = s->resync_marker; + pic_param->sequence_fields.bits.syncmarker = v->resync_marker; pic_param->sequence_fields.bits.rangered = v->rangered; pic_param->sequence_fields.bits.max_b_frames = s->avctx->max_b_frames; #if VA_CHECK_VERSION(0,32,0) diff --git a/ffmpeg/libavcodec/vb.c b/ffmpeg/libavcodec/vb.c index 29cd104..3c89a29 100644 --- a/ffmpeg/libavcodec/vb.c +++ b/ffmpeg/libavcodec/vb.c @@ -266,12 +266,12 @@ static av_cold int decode_end(AVCodecContext *avctx) AVCodec ff_vb_decoder = { .name = "vb", + .long_name = NULL_IF_CONFIG_SMALL("Beam Software VB"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VB, .priv_data_size = sizeof(VBDecContext), .init = decode_init, .close = decode_end, .decode = decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Beam Software VB"), .capabilities = CODEC_CAP_DR1, }; diff --git a/ffmpeg/libavcodec/vble.c b/ffmpeg/libavcodec/vble.c index cbb2ffc..a8c71ed 100644 --- a/ffmpeg/libavcodec/vble.c +++ b/ffmpeg/libavcodec/vble.c @@ -202,6 +202,7 @@ static av_cold int vble_decode_init(AVCodecContext *avctx) AVCodec ff_vble_decoder = { .name = "vble", + .long_name = NULL_IF_CONFIG_SMALL("VBLE Lossless Codec"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VBLE, .priv_data_size = sizeof(VBLEContext), @@ -209,5 +210,4 @@ AVCodec ff_vble_decoder = { .close = vble_decode_close, .decode = vble_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("VBLE Lossless Codec"), }; diff --git a/ffmpeg/libavcodec/vc1.c b/ffmpeg/libavcodec/vc1.c index 0b69711..fb33e6f 100644 --- a/ffmpeg/libavcodec/vc1.c +++ b/ffmpeg/libavcodec/vc1.c @@ -27,6 +27,7 @@ * */ +#include "libavutil/attributes.h" #include "internal.h" #include "avcodec.h" #include "mpegvideo.h" @@ -46,21 +47,6 @@ * @{ */ -/** - * Imode types - * @{ - */ -enum Imode { - IMODE_RAW, - IMODE_NORM2, - IMODE_DIFF2, - IMODE_NORM6, - IMODE_DIFF6, - IMODE_ROWSKIP, - IMODE_COLSKIP -}; -/** @} */ //imode defines - /** Decode rows by checking if they are skipped * @param plane Buffer to store decoded bits * @param[in] width Width of this buffer @@ -136,12 +122,16 @@ static int bitplane_decoding(uint8_t* data, int *raw_flag, VC1Context *v) case IMODE_NORM2: if ((height * width) & 1) { *planep++ = get_bits1(gb); - offset = 1; + y = offset = 1; + if (offset == width) { + offset = 0; + planep += stride - width; + } } else - offset = 0; + y = offset = 0; // decode bitplane as one long line - for (y = offset; y < height * width; y += 2) { + for (; y < height * width; y += 2) { code = get_vlc2(gb, ff_vc1_norm2_vlc.table, VC1_NORM2_VLC_BITS, 1); *planep++ = code & 1; offset++; @@ -366,7 +356,7 @@ int ff_vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitCo v->overlap = get_bits1(gb); //common - v->s.resync_marker = get_bits1(gb); + v->resync_marker = get_bits1(gb); v->rangered = get_bits1(gb); if (v->rangered && v->profile == PROFILE_SIMPLE) { av_log(avctx, AV_LOG_INFO, @@ -408,7 +398,7 @@ int ff_vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitCo "DQuant=%i, Quantizer mode=%i, Max B frames=%i\n", v->profile, v->frmrtq_postproc, v->bitrtq_postproc, v->s.loop_filter, v->multires, v->fastuvmc, v->extended_mv, - v->rangered, v->vstransform, v->overlap, v->s.resync_marker, + v->rangered, v->vstransform, v->overlap, v->resync_marker, v->dquant, v->quantizer_mode, avctx->max_b_frames); return 0; } @@ -576,6 +566,52 @@ int ff_vc1_decode_entry_point(AVCodecContext *avctx, VC1Context *v, GetBitContex return 0; } +/* fill lookup tables for intensity compensation */ +#define INIT_LUT(lumscale, lumshift, luty, lutuv, chain) do { \ + int scale, shift, i; \ + if (!lumscale) { \ + scale = -64; \ + shift = (255 - lumshift * 2) << 6; \ + if (lumshift > 31) \ + shift += 128 << 6; \ + } else { \ + scale = lumscale + 32; \ + if (lumshift > 31) \ + shift = (lumshift - 64) << 6; \ + else \ + shift = lumshift << 6; \ + } \ + for (i = 0; i < 256; i++) { \ + int iy = chain ? luty[i] : i; \ + int iu = chain ? lutuv[i] : i; \ + luty[i] = av_clip_uint8((scale * iy + shift + 32) >> 6); \ + lutuv[i] = av_clip_uint8((scale * (iu - 128) + 128*64 + 32) >> 6);\ + } \ + } while(0) + +static void rotate_luts(VC1Context *v) +{ +#define ROTATE(DEF, L, N, C, A) do { \ + if (v->s.pict_type == AV_PICTURE_TYPE_BI || v->s.pict_type == AV_PICTURE_TYPE_B) { \ + C = A; \ + } else { \ + DEF; \ + memcpy(&tmp, L , sizeof(tmp)); \ + memcpy(L , N , sizeof(tmp)); \ + memcpy(N , &tmp, sizeof(tmp)); \ + C = N; \ + } \ + } while(0) + + ROTATE(int *tmp, &v->last_use_ic, &v->next_use_ic, v->curr_use_ic, &v->aux_use_ic); + ROTATE(uint8_t tmp[2][256], v->last_luty, v->next_luty, v->curr_luty, v->aux_luty); + ROTATE(uint8_t tmp[2][256], v->last_lutuv, v->next_lutuv, v->curr_lutuv, v->aux_lutuv); + + INIT_LUT(32, 0, v->curr_luty[0], v->curr_lutuv[0], 0); + INIT_LUT(32, 0, v->curr_luty[1], v->curr_lutuv[1], 0); + *v->curr_use_ic = 0; +} + int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) { int pqindex, lowquant, status; @@ -664,8 +700,8 @@ int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) (v->s.pict_type == AV_PICTURE_TYPE_P) ? 'P' : ((v->s.pict_type == AV_PICTURE_TYPE_I) ? 'I' : 'B'), pqindex, v->pq, v->halfpq, v->rangeredfrm); - if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_P) - v->use_ic = 0; + if (v->first_pic_header_flag) + rotate_luts(v); switch (v->s.pict_type) { case AV_PICTURE_TYPE_P: @@ -676,28 +712,13 @@ int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) lowquant = (v->pq > 12) ? 0 : 1; v->mv_mode = ff_vc1_mv_pmode_table[lowquant][get_unary(gb, 1, 4)]; if (v->mv_mode == MV_PMODE_INTENSITY_COMP) { - int scale, shift, i; v->mv_mode2 = ff_vc1_mv_pmode_table2[lowquant][get_unary(gb, 1, 3)]; v->lumscale = get_bits(gb, 6); v->lumshift = get_bits(gb, 6); - v->use_ic = 1; + v->last_use_ic = 1; /* fill lookup tables for intensity compensation */ - if (!v->lumscale) { - scale = -64; - shift = (255 - v->lumshift * 2) << 6; - if (v->lumshift > 31) - shift += 128 << 6; - } else { - scale = v->lumscale + 32; - if (v->lumshift > 31) - shift = (v->lumshift - 64) << 6; - else - shift = v->lumshift << 6; - } - for (i = 0; i < 256; i++) { - v->luty[i] = av_clip_uint8((scale * i + shift + 32) >> 6); - v->lutuv[i] = av_clip_uint8((scale * (i - 128) + 128*64 + 32) >> 6); - } + INIT_LUT(v->lumscale, v->lumshift, v->last_luty[0], v->last_lutuv[0], 1); + INIT_LUT(v->lumscale, v->lumshift, v->last_luty[1], v->last_lutuv[1], 1); } v->qs_last = v->s.quarter_sample; if (v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN) @@ -808,31 +829,11 @@ int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) return 0; } -/* fill lookup tables for intensity compensation */ -#define INIT_LUT(lumscale, lumshift, luty, lutuv) \ - if (!lumscale) { \ - scale = -64; \ - shift = (255 - lumshift * 2) << 6; \ - if (lumshift > 31) \ - shift += 128 << 6; \ - } else { \ - scale = lumscale + 32; \ - if (lumshift > 31) \ - shift = (lumshift - 64) << 6; \ - else \ - shift = lumshift << 6; \ - } \ - for (i = 0; i < 256; i++) { \ - luty[i] = av_clip_uint8((scale * i + shift + 32) >> 6); \ - lutuv[i] = av_clip_uint8((scale * (i - 128) + 128*64 + 32) >> 6); \ - } - int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) { int pqindex, lowquant; int status; int mbmodetab, imvtab, icbptab, twomvbptab, fourmvbptab; /* useful only for debugging */ - int scale, shift, i; /* for initializing LUT for intensity compensation */ int field_mode, fcm; v->numref=0; @@ -854,24 +855,26 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) if (fcm) { if (fcm == ILACE_FIELD) field_mode = 1; - if (!v->warn_interlaced++) - av_log(v->s.avctx, AV_LOG_ERROR, - "Interlaced frames/fields support is incomplete\n"); } } else { fcm = PROGRESSIVE; } if (!v->first_pic_header_flag && v->field_mode != field_mode) - return -1; + return AVERROR_INVALIDDATA; v->field_mode = field_mode; v->fcm = fcm; + av_assert0( v->s.mb_height == v->s.height + 15 >> 4 + || v->s.mb_height == FFALIGN(v->s.height + 15 >> 4, 2)); if (v->field_mode) { + v->s.mb_height = FFALIGN(v->s.height + 15 >> 4, 2); v->fptype = get_bits(gb, 3); v->s.pict_type = (v->fptype & 2) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I; if (v->fptype & 4) // B-picture v->s.pict_type = (v->fptype & 2) ? AV_PICTURE_TYPE_BI : AV_PICTURE_TYPE_B; + } else { + v->s.mb_height = v->s.height + 15 >> 4; switch (get_unary(gb, 0, 4)) { case 0: v->s.pict_type = AV_PICTURE_TYPE_P; @@ -900,6 +903,8 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) v->tff = get_bits1(gb); v->rff = get_bits1(gb); } + } else { + v->tff = 1; } if (v->panscanflag) { avpriv_report_missing_feature(v->s.avctx, "Pan-scan"); @@ -970,12 +975,12 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) if (v->postprocflag) v->postproc = get_bits(gb, 2); - if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_P) - v->use_ic = 0; - if (v->parse_only) return 0; + if (v->first_pic_header_flag) + rotate_luts(v); + switch (v->s.pict_type) { case AV_PICTURE_TYPE_I: case AV_PICTURE_TYPE_BI: @@ -1010,6 +1015,8 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) v->reffield = get_bits1(gb); v->ref_field_type[0] = v->reffield ^ !v->cur_field_type; } + } else { + v->numref = 0; } if (v->extended_mv) v->mvrange = get_unary(gb, 0, 3); @@ -1026,7 +1033,9 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) if (v->intcomp) { v->lumscale = get_bits(gb, 6); v->lumshift = get_bits(gb, 6); - INIT_LUT(v->lumscale, v->lumshift, v->luty, v->lutuv); + INIT_LUT(v->lumscale, v->lumshift, v->last_luty[0], v->last_lutuv[0], 1); + INIT_LUT(v->lumscale, v->lumshift, v->last_luty[1], v->last_lutuv[1], 1); + v->last_use_ic = 1; } status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v); av_log(v->s.avctx, AV_LOG_DEBUG, "SKIPMB plane encoding: " @@ -1069,17 +1078,38 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) int mvmode2; mvmode2 = get_unary(gb, 1, 3); v->mv_mode2 = ff_vc1_mv_pmode_table2[lowquant][mvmode2]; - if (v->field_mode) - v->intcompfield = decode210(gb); - v->lumscale = get_bits(gb, 6); - v->lumshift = get_bits(gb, 6); - INIT_LUT(v->lumscale, v->lumshift, v->luty, v->lutuv); - if ((v->field_mode) && !v->intcompfield) { + if (v->field_mode) { + v->intcompfield = decode210(gb) ^ 3; + } else + v->intcompfield = 3; + + v->lumscale2 = v->lumscale = 32; + v->lumshift2 = v->lumshift = 0; + if (v->intcompfield & 1) { + v->lumscale = get_bits(gb, 6); + v->lumshift = get_bits(gb, 6); + } + if ((v->intcompfield & 2) && v->field_mode) { v->lumscale2 = get_bits(gb, 6); v->lumshift2 = get_bits(gb, 6); - INIT_LUT(v->lumscale2, v->lumshift2, v->luty2, v->lutuv2); + } else if(!v->field_mode) { + v->lumscale2 = v->lumscale; + v->lumshift2 = v->lumshift; + } + if (v->field_mode && v->second_field) { + if (v->cur_field_type) { + INIT_LUT(v->lumscale , v->lumshift , v->curr_luty[v->cur_field_type^1], v->curr_lutuv[v->cur_field_type^1], 0); + INIT_LUT(v->lumscale2, v->lumshift2, v->last_luty[v->cur_field_type ], v->last_lutuv[v->cur_field_type ], 1); + } else { + INIT_LUT(v->lumscale2, v->lumshift2, v->curr_luty[v->cur_field_type^1], v->curr_lutuv[v->cur_field_type^1], 0); + INIT_LUT(v->lumscale , v->lumshift , v->last_luty[v->cur_field_type ], v->last_lutuv[v->cur_field_type ], 1); + } + v->next_use_ic = *v->curr_use_ic = 1; + } else { + INIT_LUT(v->lumscale , v->lumshift , v->last_luty[0], v->last_lutuv[0], 1); + INIT_LUT(v->lumscale2, v->lumshift2, v->last_luty[1], v->last_lutuv[1], 1); } - v->use_ic = 1; + v->last_use_ic = 1; } v->qs_last = v->s.quarter_sample; if (v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN) @@ -1212,7 +1242,8 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) } else if (v->fcm == ILACE_FRAME) { if (v->extended_dmv) v->dmvrange = get_unary(gb, 0, 3); - get_bits1(gb); /* intcomp - present but shall always be 0 */ + if (get_bits1(gb)) /* intcomp - present but shall always be 0 */ + av_log(v->s.avctx, AV_LOG_WARNING, "Intensity compensation set for B picture\n"); v->intcomp = 0; v->mv_mode = MV_PMODE_1MV; v->fourmvswitch = 0; @@ -1539,7 +1570,7 @@ static const uint16_t vlc_offs[] = { * @param v The VC1Context to initialize * @return Status */ -int ff_vc1_init_common(VC1Context *v) +av_cold int ff_vc1_init_common(VC1Context *v) { static int done = 0; int i = 0; diff --git a/ffmpeg/libavcodec/vc1.h b/ffmpeg/libavcodec/vc1.h index 596d4d3..662b58b 100644 --- a/ffmpeg/libavcodec/vc1.h +++ b/ffmpeg/libavcodec/vc1.h @@ -175,6 +175,21 @@ enum FrameCodingMode { ILACE_FIELD ///< in the bitstream is reported as 11b }; +/** + * Imode types + * @{ + */ +enum Imode { + IMODE_RAW, + IMODE_NORM2, + IMODE_DIFF2, + IMODE_NORM6, + IMODE_DIFF6, + IMODE_ROWSKIP, + IMODE_COLSKIP +}; +/** @} */ //imode defines + /** The VC1 Context * @todo Change size wherever another size is more efficient * Many members are only used for Advanced Profile @@ -296,8 +311,11 @@ typedef struct VC1Context{ int dmb_is_raw; ///< direct mb plane is raw int fmb_is_raw; ///< forward mb plane is raw int skip_is_raw; ///< skip mb plane is not coded - uint8_t luty[256], lutuv[256]; ///< lookup tables used for intensity compensation - int use_ic; ///< use intensity compensation in B-frames + uint8_t last_luty[2][256], last_lutuv[2][256]; ///< lookup tables used for intensity compensation + uint8_t aux_luty[2][256], aux_lutuv[2][256]; ///< lookup tables used for intensity compensation + uint8_t next_luty[2][256], next_lutuv[2][256]; ///< lookup tables used for intensity compensation + uint8_t (*curr_luty)[256] ,(*curr_lutuv)[256]; + int last_use_ic, *curr_use_ic, next_use_ic, aux_use_ic; int rnd; ///< rounding control /** Frame decoding info for S/M profiles only */ @@ -340,7 +358,6 @@ typedef struct VC1Context{ int intcomp; uint8_t lumscale2; ///< for interlaced field P picture uint8_t lumshift2; - uint8_t luty2[256], lutuv2[256]; // lookup tables used for intensity compensation VLC* mbmode_vlc; VLC* imv_vlc; VLC* twomvbp_vlc; @@ -352,7 +369,6 @@ typedef struct VC1Context{ uint8_t zzi_8x8[64]; uint8_t *blk_mv_type_base, *blk_mv_type; ///< 0: frame MV, 1: field MV (interlaced frame) uint8_t *mv_f_base, *mv_f[2]; ///< 0: MV obtained from same field, 1: opposite field - uint8_t *mv_f_last_base, *mv_f_last[2]; uint8_t *mv_f_next_base, *mv_f_next[2]; int field_mode; ///< 1 for interlaced field pictures int fptype; @@ -377,7 +393,7 @@ typedef struct VC1Context{ //@{ int new_sprite; int two_sprites; - AVFrame sprite_output_frame; + AVFrame *sprite_output_frame; int output_width, output_height, sprite_width, sprite_height; uint8_t* sr_rows[2][2]; ///< Sprite resizer line cache //@} @@ -398,8 +414,7 @@ typedef struct VC1Context{ int end_mb_x; ///< Horizontal macroblock limit (used only by mss2) int parse_only; ///< Context is used within parser - - int warn_interlaced; + int resync_marker; ///< could this stream contain resync markers } VC1Context; /** Find VC-1 marker in buffer diff --git a/ffmpeg/libavcodec/vc1_parser.c b/ffmpeg/libavcodec/vc1_parser.c index 53af61c..cc29ce1 100644 --- a/ffmpeg/libavcodec/vc1_parser.c +++ b/ffmpeg/libavcodec/vc1_parser.c @@ -25,6 +25,7 @@ * VC-1 and WMV3 parser */ +#include "libavutil/attributes.h" #include "parser.h" #include "vc1.h" #include "get_bits.h" @@ -44,11 +45,13 @@ static void vc1_extract_headers(AVCodecParserContext *s, AVCodecContext *avctx, vpc->v.s.avctx = avctx; vpc->v.parse_only = 1; + vpc->v.first_pic_header_flag = 1; next = buf; s->repeat_pict = 0; for(start = buf, end = buf + buf_size; next < end; start = next){ int buf2_size, size; + int ret; next = find_next_marker(start + 4, end); size = next - start - 4; @@ -64,9 +67,12 @@ static void vc1_extract_headers(AVCodecParserContext *s, AVCodecContext *avctx, break; case VC1_CODE_FRAME: if(vpc->v.profile < PROFILE_ADVANCED) - ff_vc1_parse_frame_header (&vpc->v, &gb); + ret = ff_vc1_parse_frame_header (&vpc->v, &gb); else - ff_vc1_parse_frame_header_adv(&vpc->v, &gb); + ret = ff_vc1_parse_frame_header_adv(&vpc->v, &gb); + + if (ret < 0) + break; /* keep AV_PICTURE_TYPE_BI internal to VC1 */ if (vpc->v.s.pict_type == AV_PICTURE_TYPE_BI) @@ -88,6 +94,11 @@ static void vc1_extract_headers(AVCodecParserContext *s, AVCodecContext *avctx, } } + if (vpc->v.broadcast && vpc->v.interlace && !vpc->v.psf) + s->field_order = vpc->v.tff ? AV_FIELD_TT : AV_FIELD_BB; + else + s->field_order = AV_FIELD_PROGRESSIVE; + break; } } @@ -184,7 +195,7 @@ static int vc1_split(AVCodecContext *avctx, return 0; } -static int vc1_parse_init(AVCodecParserContext *s) +static av_cold int vc1_parse_init(AVCodecParserContext *s) { VC1ParseContext *vpc = s->priv_data; vpc->v.s.slice_context_count = 1; diff --git a/ffmpeg/libavcodec/vc1dec.c b/ffmpeg/libavcodec/vc1dec.c index 6451f0c..efcb169 100644 --- a/ffmpeg/libavcodec/vc1dec.c +++ b/ffmpeg/libavcodec/vc1dec.c @@ -59,33 +59,18 @@ static const int offset_table2[9] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 }; * @{ */ -/** - * Imode types - * @{ - */ -enum Imode { - IMODE_RAW, - IMODE_NORM2, - IMODE_DIFF2, - IMODE_NORM6, - IMODE_DIFF6, - IMODE_ROWSKIP, - IMODE_COLSKIP -}; -/** @} */ //imode defines static void init_block_index(VC1Context *v) { MpegEncContext *s = &v->s; ff_init_block_index(s); - if (v->field_mode && v->second_field) { + if (v->field_mode && !(v->second_field ^ v->tff)) { s->dest[0] += s->current_picture_ptr->f.linesize[0]; s->dest[1] += s->current_picture_ptr->f.linesize[1]; s->dest[2] += s->current_picture_ptr->f.linesize[2]; } } - /** @} */ //Bitplane group static void vc1_put_signed_blocks_clamped(VC1Context *v) @@ -348,9 +333,10 @@ static void vc1_mc_1mv(VC1Context *v, int dir) H264ChromaContext *h264chroma = &v->h264chroma; uint8_t *srcY, *srcU, *srcV; int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y; - int off, off_uv; int v_edge_pos = s->v_edge_pos >> v->field_mode; int i; + uint8_t (*luty)[256], (*lutuv)[256]; + int use_ic; if ((!v->field_mode || (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) && @@ -384,36 +370,35 @@ static void vc1_mc_1mv(VC1Context *v, int dir) uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1)); uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1)); } - if (v->field_mode) { // interlaced field picture - if (!dir) { - if ((v->cur_field_type != v->ref_field_type[dir]) && v->second_field) { - srcY = s->current_picture.f.data[0]; - srcU = s->current_picture.f.data[1]; - srcV = s->current_picture.f.data[2]; - } else { - srcY = s->last_picture.f.data[0]; - srcU = s->last_picture.f.data[1]; - srcV = s->last_picture.f.data[2]; - } + if (!dir) { + if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) { + srcY = s->current_picture.f.data[0]; + srcU = s->current_picture.f.data[1]; + srcV = s->current_picture.f.data[2]; + luty = v->curr_luty; + lutuv = v->curr_lutuv; + use_ic = *v->curr_use_ic; } else { - srcY = s->next_picture.f.data[0]; - srcU = s->next_picture.f.data[1]; - srcV = s->next_picture.f.data[2]; - } - } else { - if (!dir) { srcY = s->last_picture.f.data[0]; srcU = s->last_picture.f.data[1]; srcV = s->last_picture.f.data[2]; - } else { - srcY = s->next_picture.f.data[0]; - srcU = s->next_picture.f.data[1]; - srcV = s->next_picture.f.data[2]; + luty = v->last_luty; + lutuv = v->last_lutuv; + use_ic = v->last_use_ic; } + } else { + srcY = s->next_picture.f.data[0]; + srcU = s->next_picture.f.data[1]; + srcV = s->next_picture.f.data[2]; + luty = v->next_luty; + lutuv = v->next_lutuv; + use_ic = v->next_use_ic; } - if(!srcY) + if (!srcY || !srcU) { + av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n"); return; + } src_x = s->mb_x * 16 + (mx >> 2); src_y = s->mb_y * 16 + (my >> 2); @@ -448,22 +433,29 @@ static void vc1_mc_1mv(VC1Context *v, int dir) srcV = s->edge_emu_buffer + 18 * s->linesize; } - if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP) + if (v->rangeredfrm || use_ic || s->h_edge_pos < 22 || v_edge_pos < 22 || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel * 3 || (unsigned)(src_y - 1) > v_edge_pos - (my&3) - 16 - 3) { uint8_t *uvbuf = s->edge_emu_buffer + 19 * s->linesize; srcY -= s->mspel * (1 + s->linesize); - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY, + s->linesize, s->linesize, 17 + s->mspel * 2, 17 + s->mspel * 2, src_x - s->mspel, src_y - s->mspel, s->h_edge_pos, v_edge_pos); srcY = s->edge_emu_buffer; - s->vdsp.emulated_edge_mc(uvbuf , srcU, s->uvlinesize, 8 + 1, 8 + 1, - uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1); - s->vdsp.emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8 + 1, 8 + 1, - uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1); + s->vdsp.emulated_edge_mc(uvbuf, srcU, + s->uvlinesize, s->uvlinesize, + 8 + 1, 8 + 1, + uvsrc_x, uvsrc_y, + s->h_edge_pos >> 1, v_edge_pos >> 1); + s->vdsp.emulated_edge_mc(uvbuf + 16, srcV, + s->uvlinesize, s->uvlinesize, + 8 + 1, 8 + 1, + uvsrc_x, uvsrc_y, + s->h_edge_pos >> 1, v_edge_pos >> 1); srcU = uvbuf; srcV = uvbuf + 16; /* if we deal with range reduction we need to scale source blocks */ @@ -489,22 +481,24 @@ static void vc1_mc_1mv(VC1Context *v, int dir) } } /* if we deal with intensity compensation we need to scale source blocks */ - if (v->mv_mode == MV_PMODE_INTENSITY_COMP) { + if (use_ic) { int i, j; uint8_t *src, *src2; src = srcY; for (j = 0; j < 17 + s->mspel * 2; j++) { + int f = v->field_mode ? v->ref_field_type[dir] : ((j + src_y - s->mspel) & 1) ; for (i = 0; i < 17 + s->mspel * 2; i++) - src[i] = v->luty[src[i]]; + src[i] = luty[f][src[i]]; src += s->linesize; } src = srcU; src2 = srcV; for (j = 0; j < 9; j++) { + int f = v->field_mode ? v->ref_field_type[dir] : ((j + uvsrc_y) & 1); for (i = 0; i < 9; i++) { - src[i] = v->lutuv[src[i]]; - src2[i] = v->lutuv[src2[i]]; + src[i] = lutuv[f][src[i]]; + src2[i] = lutuv[f][src2[i]]; } src += s->uvlinesize; src2 += s->uvlinesize; @@ -513,21 +507,19 @@ static void vc1_mc_1mv(VC1Context *v, int dir) srcY += s->mspel * (1 + s->linesize); } - off = 0; - off_uv = 0; if (s->mspel) { dxy = ((my & 3) << 2) | (mx & 3); - v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off , srcY , s->linesize, v->rnd); - v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8, srcY + 8, s->linesize, v->rnd); + v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] , srcY , s->linesize, v->rnd); + v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8, srcY + 8, s->linesize, v->rnd); srcY += s->linesize * 8; - v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8 * s->linesize , srcY , s->linesize, v->rnd); - v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8 * s->linesize + 8, srcY + 8, s->linesize, v->rnd); + v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize , srcY , s->linesize, v->rnd); + v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize + 8, srcY + 8, s->linesize, v->rnd); } else { // hpel mc - always used for luma dxy = (my & 2) | ((mx & 2) >> 1); if (!v->rnd) - s->hdsp.put_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16); + s->hdsp.put_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16); else - s->hdsp.put_no_rnd_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16); + s->hdsp.put_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16); } if (s->flags & CODEC_FLAG_GRAY) return; @@ -535,11 +527,11 @@ static void vc1_mc_1mv(VC1Context *v, int dir) uvmx = (uvmx & 3) << 1; uvmy = (uvmy & 3) << 1; if (!v->rnd) { - h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy); - h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy); + h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); + h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); } else { - v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy); - v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy); + v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); + v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); } } @@ -564,6 +556,8 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg) int off; int fieldmv = (v->fcm == ILACE_FRAME) ? v->blk_mv_type[s->block_index[n]] : 0; int v_edge_pos = s->v_edge_pos >> v->field_mode; + uint8_t (*luty)[256]; + int use_ic; if ((!v->field_mode || (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) && @@ -574,18 +568,25 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg) my = s->mv[dir][n][1]; if (!dir) { - if (v->field_mode) { - if ((v->cur_field_type != v->ref_field_type[dir]) && v->second_field) - srcY = s->current_picture.f.data[0]; - else - srcY = s->last_picture.f.data[0]; - } else + if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) { + srcY = s->current_picture.f.data[0]; + luty = v->curr_luty; + use_ic = *v->curr_use_ic; + } else { srcY = s->last_picture.f.data[0]; - } else + luty = v->last_luty; + use_ic = v->last_use_ic; + } + } else { srcY = s->next_picture.f.data[0]; + luty = v->next_luty; + use_ic = v->next_use_ic; + } - if(!srcY) + if (!srcY) { + av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n"); return; + } if (v->field_mode) { if (v->cur_field_type != v->ref_field_type[dir]) @@ -620,7 +621,7 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg) ty = (chosen_mv[f][0][1] + chosen_mv[f][1][1]) / 2; break; default: - av_assert2(0); + av_assert0(0); } s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx; s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty; @@ -683,13 +684,14 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg) v_edge_pos--; if (fieldmv && (src_y & 1) && src_y < 4) src_y--; - if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP) + if (v->rangeredfrm || use_ic || s->h_edge_pos < 13 || v_edge_pos < 23 || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 8 - s->mspel * 2 || (unsigned)(src_y - (s->mspel << fieldmv)) > v_edge_pos - (my & 3) - ((8 + s->mspel * 2) << fieldmv)) { srcY -= s->mspel * (1 + (s->linesize << fieldmv)); /* check emulate edge stride and offset */ - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY, + s->linesize, s->linesize, 9 + s->mspel * 2, (9 + s->mspel * 2) << fieldmv, src_x - s->mspel, src_y - (s->mspel << fieldmv), s->h_edge_pos, v_edge_pos); @@ -707,14 +709,15 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg) } } /* if we deal with intensity compensation we need to scale source blocks */ - if (v->mv_mode == MV_PMODE_INTENSITY_COMP) { + if (use_ic) { int i, j; uint8_t *src; src = srcY; for (j = 0; j < 9 + s->mspel * 2; j++) { + int f = v->field_mode ? v->ref_field_type[dir] : (((j<mspel << fieldmv)) & 1); for (i = 0; i < 9 + s->mspel * 2; i++) - src[i] = v->luty[src[i]]; + src[i] = luty[f][src[i]]; src += s->linesize << fieldmv; } } @@ -800,8 +803,10 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir) int k, tx = 0, ty = 0; int mvx[4], mvy[4], intra[4], mv_f[4]; int valid_count; - int chroma_ref_type = v->cur_field_type, off = 0; + int chroma_ref_type = v->cur_field_type; int v_edge_pos = s->v_edge_pos >> v->field_mode; + uint8_t (*lutuv)[256]; + int use_ic; if (!v->field_mode && !v->s.last_picture.f.data[0]) return; @@ -864,25 +869,28 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir) } if (!dir) { - if (v->field_mode) { - if ((v->cur_field_type != chroma_ref_type) && v->cur_field_type) { - srcU = s->current_picture.f.data[1]; - srcV = s->current_picture.f.data[2]; - } else { - srcU = s->last_picture.f.data[1]; - srcV = s->last_picture.f.data[2]; - } + if (v->field_mode && (v->cur_field_type != chroma_ref_type) && v->second_field) { + srcU = s->current_picture.f.data[1]; + srcV = s->current_picture.f.data[2]; + lutuv = v->curr_lutuv; + use_ic = *v->curr_use_ic; } else { srcU = s->last_picture.f.data[1]; srcV = s->last_picture.f.data[2]; + lutuv = v->last_lutuv; + use_ic = v->last_use_ic; } } else { srcU = s->next_picture.f.data[1]; srcV = s->next_picture.f.data[2]; + lutuv = v->next_lutuv; + use_ic = v->next_use_ic; } - if(!srcU) + if (!srcU) { + av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n"); return; + } srcU += uvsrc_y * s->uvlinesize + uvsrc_x; srcV += uvsrc_y * s->uvlinesize + uvsrc_x; @@ -892,17 +900,18 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir) srcU += s->current_picture_ptr->f.linesize[1]; srcV += s->current_picture_ptr->f.linesize[2]; } - off = 0; } - if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP) + if (v->rangeredfrm || use_ic || s->h_edge_pos < 18 || v_edge_pos < 18 || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9 || (unsigned)uvsrc_y > (v_edge_pos >> 1) - 9) { - s->vdsp.emulated_edge_mc(s->edge_emu_buffer , srcU, s->uvlinesize, + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcU, + s->uvlinesize, s->uvlinesize, 8 + 1, 8 + 1, uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1); - s->vdsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV, s->uvlinesize, + s->vdsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV, + s->uvlinesize, s->uvlinesize, 8 + 1, 8 + 1, uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1); srcU = s->edge_emu_buffer; @@ -925,16 +934,17 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir) } } /* if we deal with intensity compensation we need to scale source blocks */ - if (v->mv_mode == MV_PMODE_INTENSITY_COMP) { + if (use_ic) { int i, j; uint8_t *src, *src2; src = srcU; src2 = srcV; for (j = 0; j < 9; j++) { + int f = v->field_mode ? chroma_ref_type : ((j + uvsrc_y) & 1); for (i = 0; i < 9; i++) { - src[i] = v->lutuv[src[i]]; - src2[i] = v->lutuv[src2[i]]; + src[i] = lutuv[f][src[i]]; + src2[i] = lutuv[f][src2[i]]; } src += s->uvlinesize; src2 += s->uvlinesize; @@ -946,17 +956,17 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir) uvmx = (uvmx & 3) << 1; uvmy = (uvmy & 3) << 1; if (!v->rnd) { - h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1] + off, srcU, s->uvlinesize, 8, uvmx, uvmy); - h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2] + off, srcV, s->uvlinesize, 8, uvmx, uvmy); + h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); + h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); } else { - v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1] + off, srcU, s->uvlinesize, 8, uvmx, uvmy); - v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2] + off, srcV, s->uvlinesize, 8, uvmx, uvmy); + v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); + v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); } } -/** Do motion compensation for 4-MV field chroma macroblock (both U and V) +/** Do motion compensation for 4-MV interlaced frame chroma macroblock (both U and V) */ -static void vc1_mc_4mv_chroma4(VC1Context *v) +static void vc1_mc_4mv_chroma4(VC1Context *v, int dir, int dir2, int avg) { MpegEncContext *s = &v->s; H264ChromaContext *h264chroma = &v->h264chroma; @@ -968,16 +978,17 @@ static void vc1_mc_4mv_chroma4(VC1Context *v) static const int s_rndtblfield[16] = { 0, 0, 1, 2, 4, 4, 5, 6, 2, 2, 3, 8, 6, 6, 7, 12 }; int v_dist = fieldmv ? 1 : 4; // vertical offset for lower sub-blocks int v_edge_pos = s->v_edge_pos >> 1; + int use_ic; + uint8_t (*lutuv)[256]; - if (!v->s.last_picture.f.data[0]) - return; if (s->flags & CODEC_FLAG_GRAY) return; for (i = 0; i < 4; i++) { - tx = s->mv[0][i][0]; + int d = i < 2 ? dir: dir2; + tx = s->mv[d][i][0]; uvmx_field[i] = (tx + ((tx & 3) == 3)) >> 1; - ty = s->mv[0][i][1]; + ty = s->mv[d][i][1]; if (fieldmv) uvmy_field[i] = (ty >> 4) * 8 + s_rndtblfield[ty & 0xF]; else @@ -991,8 +1002,21 @@ static void vc1_mc_4mv_chroma4(VC1Context *v) // FIXME: implement proper pull-back (see vc1cropmv.c, vc1CROPMV_ChromaPullBack()) uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1); uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1); - srcU = s->last_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x; - srcV = s->last_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x; + if (i < 2 ? dir : dir2) { + srcU = s->next_picture.f.data[1]; + srcV = s->next_picture.f.data[2]; + lutuv = v->next_lutuv; + use_ic = v->next_use_ic; + } else { + srcU = s->last_picture.f.data[1]; + srcV = s->last_picture.f.data[2]; + lutuv = v->last_lutuv; + use_ic = v->last_use_ic; + } + if (!srcU) + return; + srcU += uvsrc_y * s->uvlinesize + uvsrc_x; + srcV += uvsrc_y * s->uvlinesize + uvsrc_x; uvmx_field[i] = (uvmx_field[i] & 3) << 1; uvmy_field[i] = (uvmy_field[i] & 3) << 1; @@ -1001,42 +1025,55 @@ static void vc1_mc_4mv_chroma4(VC1Context *v) if (fieldmv && (uvsrc_y & 1) && uvsrc_y < 2) uvsrc_y--; - if ((v->mv_mode == MV_PMODE_INTENSITY_COMP) + if (use_ic || s->h_edge_pos < 10 || v_edge_pos < (5 << fieldmv) || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 5 || (unsigned)uvsrc_y > v_edge_pos - (5 << fieldmv)) { - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcU, s->uvlinesize, + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcU, + s->uvlinesize, s->uvlinesize, 5, (5 << fieldmv), uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos); - s->vdsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV, s->uvlinesize, + s->vdsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV, + s->uvlinesize, s->uvlinesize, 5, (5 << fieldmv), uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos); srcU = s->edge_emu_buffer; srcV = s->edge_emu_buffer + 16; /* if we deal with intensity compensation we need to scale source blocks */ - if (v->mv_mode == MV_PMODE_INTENSITY_COMP) { + if (use_ic) { int i, j; uint8_t *src, *src2; src = srcU; src2 = srcV; for (j = 0; j < 5; j++) { + int f = (uvsrc_y + (j << fieldmv)) & 1; for (i = 0; i < 5; i++) { - src[i] = v->lutuv[src[i]]; - src2[i] = v->lutuv[src2[i]]; + src[i] = lutuv[f][src[i]]; + src2[i] = lutuv[f][src2[i]]; } - src += s->uvlinesize << 1; - src2 += s->uvlinesize << 1; + src += s->uvlinesize << fieldmv; + src2 += s->uvlinesize << fieldmv; } } } - if (!v->rnd) { - h264chroma->put_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); - h264chroma->put_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); + if (avg) { + if (!v->rnd) { + h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); + h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); + } else { + v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); + v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); + } } else { - v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); - v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); + if (!v->rnd) { + h264chroma->put_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); + h264chroma->put_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); + } else { + v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); + v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); + } } } } @@ -1637,7 +1674,7 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y, MpegEncContext *s = &v->s; int xy, wrap, off = 0; int A[2], B[2], C[2]; - int px, py; + int px = 0, py = 0; int a_valid = 0, b_valid = 0, c_valid = 0; int field_a, field_b, field_c; // 0: same, 1: opposit int total_valid, num_samefield, num_oppfield; @@ -1773,10 +1810,8 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y, } else if (total_valid) { if (a_valid) { px = A[0]; py = A[1]; } else if (b_valid) { px = B[0]; py = B[1]; } - else if (c_valid) { px = C[0]; py = C[1]; } - else av_assert2(0); - } else - px = py = 0; + else { px = C[0]; py = C[1]; } + } } } else { if (a_valid) @@ -1815,27 +1850,28 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y, } else if (!field_b && b_valid) { px = B[0]; py = B[1]; - } else if (c_valid) { + } else /*if (c_valid)*/ { + av_assert1(c_valid); px = C[0]; py = C[1]; - } else px = py = 0; + } /*else px = py = 0;*/ } else { if (field_a && a_valid) { px = A[0]; py = A[1]; - } else if (field_b && b_valid) { + } else /*if (field_b && b_valid)*/ { + av_assert1(field_b && b_valid); px = B[0]; py = B[1]; - } else if (c_valid) { + } /*else if (c_valid) { px = C[0]; py = C[1]; - } else px = py = 0; + }*/ } } else if (total_valid == 1) { px = (a_valid) ? A[0] : ((b_valid) ? B[0] : C[0]); py = (a_valid) ? A[1] : ((b_valid) ? B[1] : C[1]); - } else - px = py = 0; + } } /* store MV using signed modulus of MV range defined in 4.11 */ @@ -1866,6 +1902,7 @@ static void vc1_interp_mc(VC1Context *v) int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y; int off, off_uv; int v_edge_pos = s->v_edge_pos >> v->field_mode; + int use_ic = v->next_use_ic; if (!v->field_mode && !v->s.next_picture.f.data[0]) return; @@ -1920,21 +1957,28 @@ static void vc1_interp_mc(VC1Context *v) srcV = s->edge_emu_buffer + 18 * s->linesize; } - if (v->rangeredfrm || s->h_edge_pos < 22 || v_edge_pos < 22 + if (v->rangeredfrm || s->h_edge_pos < 22 || v_edge_pos < 22 || use_ic || (unsigned)(src_x - 1) > s->h_edge_pos - (mx & 3) - 16 - 3 || (unsigned)(src_y - 1) > v_edge_pos - (my & 3) - 16 - 3) { uint8_t *uvbuf = s->edge_emu_buffer + 19 * s->linesize; srcY -= s->mspel * (1 + s->linesize); - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY, + s->linesize, s->linesize, 17 + s->mspel * 2, 17 + s->mspel * 2, src_x - s->mspel, src_y - s->mspel, s->h_edge_pos, v_edge_pos); srcY = s->edge_emu_buffer; - s->vdsp.emulated_edge_mc(uvbuf , srcU, s->uvlinesize, 8 + 1, 8 + 1, - uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1); - s->vdsp.emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8 + 1, 8 + 1, - uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1); + s->vdsp.emulated_edge_mc(uvbuf, srcU, + s->uvlinesize, s->uvlinesize, + 8 + 1, 8 + 1, + uvsrc_x, uvsrc_y, + s->h_edge_pos >> 1, v_edge_pos >> 1); + s->vdsp.emulated_edge_mc(uvbuf + 16, srcV, + s->uvlinesize, s->uvlinesize, + 8 + 1, 8 + 1, + uvsrc_x, uvsrc_y, + s->h_edge_pos >> 1, v_edge_pos >> 1); srcU = uvbuf; srcV = uvbuf + 16; /* if we deal with range reduction we need to scale source blocks */ @@ -1959,11 +2003,37 @@ static void vc1_interp_mc(VC1Context *v) src2 += s->uvlinesize; } } + + if (use_ic) { + uint8_t (*luty )[256] = v->next_luty; + uint8_t (*lutuv)[256] = v->next_lutuv; + int i, j; + uint8_t *src, *src2; + + src = srcY; + for (j = 0; j < 17 + s->mspel * 2; j++) { + int f = v->field_mode ? v->ref_field_type[1] : ((j+src_y - s->mspel) & 1); + for (i = 0; i < 17 + s->mspel * 2; i++) + src[i] = luty[f][src[i]]; + src += s->linesize; + } + src = srcU; + src2 = srcV; + for (j = 0; j < 9; j++) { + int f = v->field_mode ? v->ref_field_type[1] : ((j+uvsrc_y) & 1); + for (i = 0; i < 9; i++) { + src[i] = lutuv[f][src[i]]; + src2[i] = lutuv[f][src2[i]]; + } + src += s->uvlinesize; + src2 += s->uvlinesize; + } + } srcY += s->mspel * (1 + s->linesize); } - off = 0; - off_uv = 0; + off = 0; + off_uv = 0; if (s->mspel) { dxy = ((my & 3) << 2) | (mx & 3); @@ -2018,30 +2088,18 @@ static av_always_inline int scale_mv(int value, int bfrac, int inv, int qs) static inline void vc1_b_mc(VC1Context *v, int dmv_x[2], int dmv_y[2], int direct, int mode) { - if (v->use_ic) { - v->mv_mode2 = v->mv_mode; - v->mv_mode = MV_PMODE_INTENSITY_COMP; - } if (direct) { vc1_mc_1mv(v, 0); vc1_interp_mc(v); - if (v->use_ic) - v->mv_mode = v->mv_mode2; return; } if (mode == BMV_TYPE_INTERPOLATED) { vc1_mc_1mv(v, 0); vc1_interp_mc(v); - if (v->use_ic) - v->mv_mode = v->mv_mode2; return; } - if (v->use_ic && (mode == BMV_TYPE_BACKWARD)) - v->mv_mode = v->mv_mode2; vc1_mc_1mv(v, (mode == BMV_TYPE_BACKWARD)); - if (v->use_ic) - v->mv_mode = v->mv_mode2; } static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], @@ -3841,7 +3899,7 @@ static int vc1_decode_p_mb_intfr(VC1Context *v) vc1_pred_mv_intfr(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0], 0); vc1_mc_4mv_luma(v, i, 0, 0); } else if (i == 4) { - vc1_mc_4mv_chroma4(v); + vc1_mc_4mv_chroma4(v, 0, 0, 0); } } } else if (twomv) { @@ -3860,7 +3918,7 @@ static int vc1_decode_p_mb_intfr(VC1Context *v) vc1_pred_mv_intfr(v, 2, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], 0); vc1_mc_4mv_luma(v, 2, 0, 0); vc1_mc_4mv_luma(v, 3, 0, 0); - vc1_mc_4mv_chroma4(v); + vc1_mc_4mv_chroma4(v, 0, 0, 0); } else { mvbp = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][2]; dmv_x = dmv_y = 0; @@ -4202,7 +4260,7 @@ static void vc1_decode_b_mb_intfi(VC1Context *v) int fwd; int dmv_x[2], dmv_y[2], pred_flag[2]; int bmvtype = BMV_TYPE_BACKWARD; - int idx_mbmode, interpmvp; + int idx_mbmode; mquant = v->pq; /* Lossy initialization */ s->mb_intra = 0; @@ -4255,6 +4313,7 @@ static void vc1_decode_b_mb_intfi(VC1Context *v) else fwd = v->forward_mb_plane[mb_pos]; if (idx_mbmode <= 5) { // 1-MV + int interpmvp = 0; dmv_x[0] = dmv_x[1] = dmv_y[0] = dmv_y[1] = 0; pred_flag[0] = pred_flag[1] = 0; if (fwd) @@ -4277,7 +4336,7 @@ static void vc1_decode_b_mb_intfi(VC1Context *v) if (bmvtype != BMV_TYPE_DIRECT && idx_mbmode & 1) { get_mvdata_interlaced(v, &dmv_x[bmvtype == BMV_TYPE_BACKWARD], &dmv_y[bmvtype == BMV_TYPE_BACKWARD], &pred_flag[bmvtype == BMV_TYPE_BACKWARD]); } - if (bmvtype == BMV_TYPE_INTERPOLATED && interpmvp) { + if (interpmvp) { get_mvdata_interlaced(v, &dmv_x[1], &dmv_y[1], &pred_flag[1]); } if (bmvtype == BMV_TYPE_DIRECT) { @@ -4370,8 +4429,7 @@ static int vc1_decode_b_mb_intfr(VC1Context *v) if (!skipped) { idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_INTFR_NON4MV_MBMODE_VLC_BITS, 2); - if (ff_vc1_mbmode_intfrp[0][idx_mbmode][0] == MV_PMODE_INTFR_2MV_FIELD) - { + if (ff_vc1_mbmode_intfrp[0][idx_mbmode][0] == MV_PMODE_INTFR_2MV_FIELD) { twomv = 1; v->blk_mv_type[s->block_index[0]] = 1; v->blk_mv_type[s->block_index[1]] = 1; @@ -4402,7 +4460,7 @@ static int vc1_decode_b_mb_intfr(VC1Context *v) s->mv[1][2][0] = s->current_picture.motion_val[1][s->block_index[2]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][0], v->bfraction, 1, s->quarter_sample); s->mv[1][2][1] = s->current_picture.motion_val[1][s->block_index[2]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][1], v->bfraction, 1, s->quarter_sample); - for (i = 1; i < 4; i+=2) { + for (i = 1; i < 4; i += 2) { s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0] = s->mv[0][i-1][0]; s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1] = s->mv[0][i-1][1]; s->mv[1][i][0] = s->current_picture.motion_val[1][s->block_index[i]][0] = s->mv[1][i-1][0]; @@ -4425,7 +4483,7 @@ static int vc1_decode_b_mb_intfr(VC1Context *v) s->mv[1][i][0] = s->current_picture.motion_val[1][s->block_index[i]][0] = 0; s->mv[1][i][1] = s->current_picture.motion_val[1][s->block_index[i]][1] = 0; } - s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA; + s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA; s->mb_intra = v->is_intra[s->mb_x] = 1; for (i = 0; i < 6; i++) v->mb_type[0][s->block_index[i]] = 1; @@ -4453,7 +4511,8 @@ static int vc1_decode_b_mb_intfr(VC1Context *v) vc1_decode_intra_block(v, s->block[i], i, val, mquant, (i & 4) ? v->codingset2 : v->codingset); - if ((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue; + if (i > 3 && (s->flags & CODEC_FLAG_GRAY)) + continue; v->vc1dsp.vc1_inv_trans_8x8(s->block[i]); if (i < 4) { stride_y = s->linesize << fieldtx; @@ -4490,10 +4549,9 @@ static int vc1_decode_b_mb_intfr(VC1Context *v) if (mb_has_coeffs) cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2); if (!direct) { - if (bmvtype == BMV_TYPE_INTERPOLATED & twomv) { + if (bmvtype == BMV_TYPE_INTERPOLATED && twomv) { v->fourmvbp = get_vlc2(gb, v->fourmvbp_vlc->table, VC1_4MV_BLOCK_PATTERN_VLC_BITS, 1); - } - else if (bmvtype == BMV_TYPE_INTERPOLATED | twomv) { + } else if (bmvtype == BMV_TYPE_INTERPOLATED || twomv) { v->twomvbp = get_vlc2(gb, v->twomvbp_vlc->table, VC1_2MV_BLOCK_PATTERN_VLC_BITS, 1); } } @@ -4509,7 +4567,8 @@ static int vc1_decode_b_mb_intfr(VC1Context *v) vc1_mc_4mv_luma(v, i, 0, 0); vc1_mc_4mv_luma(v, i, 1, 1); } - vc1_mc_4mv_chroma4(v); + vc1_mc_4mv_chroma4(v, 0, 0, 0); + vc1_mc_4mv_chroma4(v, 1, 1, 1); } else { vc1_mc_1mv(v, 0); vc1_interp_mc(v); @@ -4520,30 +4579,28 @@ static int vc1_decode_b_mb_intfr(VC1Context *v) dir = i==1 || i==3; dmv_x = dmv_y = 0; val = ((mvbp >> (3 - i)) & 1); - if (val) { + if (val) get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0); - } j = i > 1 ? 2 : 0; vc1_pred_mv_intfr(v, j, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], dir); vc1_mc_4mv_luma(v, j, dir, dir); vc1_mc_4mv_luma(v, j+1, dir, dir); } - vc1_mc_4mv_chroma4(v); + vc1_mc_4mv_chroma4(v, 0, 0, 0); + vc1_mc_4mv_chroma4(v, 1, 1, 1); } else if (bmvtype == BMV_TYPE_INTERPOLATED) { mvbp = v->twomvbp; dmv_x = dmv_y = 0; - if (mvbp & 2) { + if (mvbp & 2) get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0); - } vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 0); vc1_mc_1mv(v, 0); dmv_x = dmv_y = 0; - if (mvbp & 1) { + if (mvbp & 1) get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0); - } vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 1); vc1_interp_mc(v); @@ -4554,19 +4611,17 @@ static int vc1_decode_b_mb_intfr(VC1Context *v) dir2 = !dir; mvbp = v->twomvbp; dmv_x = dmv_y = 0; - if (mvbp & 2) { + if (mvbp & 2) get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0); - } vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], dir); dmv_x = dmv_y = 0; - if (mvbp & 1) { + if (mvbp & 1) get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0); - } vc1_pred_mv_intfr(v, 2, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], dir2); if (mvsw) { - for (i = 0; i<2; i++) { + for (i = 0; i < 2; i++) { s->mv[dir][i+2][0] = s->mv[dir][i][0] = s->current_picture.motion_val[dir][s->block_index[i+2]][0] = s->current_picture.motion_val[dir][s->block_index[i]][0]; s->mv[dir][i+2][1] = s->mv[dir][i][1] = s->current_picture.motion_val[dir][s->block_index[i+2]][1] = s->current_picture.motion_val[dir][s->block_index[i]][1]; s->mv[dir2][i+2][0] = s->mv[dir2][i][0] = s->current_picture.motion_val[dir2][s->block_index[i]][0] = s->current_picture.motion_val[dir2][s->block_index[i+2]][0]; @@ -4581,15 +4636,14 @@ static int vc1_decode_b_mb_intfr(VC1Context *v) vc1_mc_4mv_luma(v, 1, dir, 0); vc1_mc_4mv_luma(v, 2, dir2, 0); vc1_mc_4mv_luma(v, 3, dir2, 0); - vc1_mc_4mv_chroma4(v); + vc1_mc_4mv_chroma4(v, dir, dir2, 0); } else { dir = bmvtype == BMV_TYPE_BACKWARD; mvbp = ff_vc1_mbmode_intfrp[0][idx_mbmode][2]; dmv_x = dmv_y = 0; - if (mvbp) { + if (mvbp) get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0); - } vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], dir); v->blk_mv_type[s->block_index[0]] = 1; @@ -4597,7 +4651,7 @@ static int vc1_decode_b_mb_intfr(VC1Context *v) v->blk_mv_type[s->block_index[2]] = 1; v->blk_mv_type[s->block_index[3]] = 1; vc1_pred_mv_intfr(v, 0, 0, 0, 2, v->range_x, v->range_y, 0, !dir); - for (i = 0; i<2; i++) { + for (i = 0; i < 2; i++) { s->mv[!dir][i+2][0] = s->mv[!dir][i][0] = s->current_picture.motion_val[!dir][s->block_index[i+2]][0] = s->current_picture.motion_val[!dir][s->block_index[i]][0]; s->mv[!dir][i+2][1] = s->mv[!dir][i][1] = s->current_picture.motion_val[!dir][s->block_index[i+2]][1] = s->current_picture.motion_val[!dir][s->block_index[i]][1]; } @@ -4653,7 +4707,7 @@ static int vc1_decode_b_mb_intfr(VC1Context *v) int dir2 = dir; if (mvsw) dir2 = !dir; - for (i = 0; i<2; i++) { + for (i = 0; i < 2; i++) { s->mv[dir][i+2][0] = s->mv[dir][i][0] = s->current_picture.motion_val[dir][s->block_index[i+2]][0] = s->current_picture.motion_val[dir][s->block_index[i]][0]; s->mv[dir][i+2][1] = s->mv[dir][i][1] = s->current_picture.motion_val[dir][s->block_index[i+2]][1] = s->current_picture.motion_val[dir][s->block_index[i]][1]; s->mv[dir2][i+2][0] = s->mv[dir2][i][0] = s->current_picture.motion_val[dir2][s->block_index[i]][0] = s->current_picture.motion_val[dir2][s->block_index[i+2]][0]; @@ -4665,7 +4719,7 @@ static int vc1_decode_b_mb_intfr(VC1Context *v) v->blk_mv_type[s->block_index[2]] = 1; v->blk_mv_type[s->block_index[3]] = 1; vc1_pred_mv_intfr(v, 0, 0, 0, 2, v->range_x, v->range_y, 0, !dir); - for (i = 0; i<2; i++) { + for (i = 0; i < 2; i++) { s->mv[!dir][i+2][0] = s->mv[!dir][i][0] = s->current_picture.motion_val[!dir][s->block_index[i+2]][0] = s->current_picture.motion_val[!dir][s->block_index[i]][0]; s->mv[!dir][i+2][1] = s->mv[!dir][i][1] = s->current_picture.motion_val[!dir][s->block_index[i+2]][1] = s->current_picture.motion_val[!dir][s->block_index[i]][1]; } @@ -4680,7 +4734,7 @@ static int vc1_decode_b_mb_intfr(VC1Context *v) } } if (s->mb_x == s->mb_width - 1) - memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0])*s->mb_stride); + memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0]) * s->mb_stride); v->cbp[s->mb_x] = block_cbp; v->ttblk[s->mb_x] = block_tt; return 0; @@ -4992,7 +5046,8 @@ static void vc1_decode_p_blocks(VC1Context *v) break; } - apply_loop_filter = s->loop_filter && !(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY); + apply_loop_filter = s->loop_filter && !(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY) && + v->fcm == PROGRESSIVE; s->first_slice_line = 1; memset(v->cbp_base, 0, sizeof(v->cbp_base[0])*2*s->mb_stride); for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) { @@ -5006,7 +5061,7 @@ static void vc1_decode_p_blocks(VC1Context *v) else if (v->fcm == ILACE_FRAME) vc1_decode_p_mb_intfr(v); else vc1_decode_p_mb(v); - if (s->mb_y != s->start_mb_y && apply_loop_filter && v->fcm == PROGRESSIVE) + if (s->mb_y != s->start_mb_y && apply_loop_filter) vc1_apply_p_loop_filter(v); if (get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) { // TODO: may need modification to handle slice coding @@ -5023,7 +5078,7 @@ static void vc1_decode_p_blocks(VC1Context *v) if (s->mb_y != s->start_mb_y) ff_mpeg_draw_horiz_band(s, (s->mb_y - 1) * 16, 16); s->first_slice_line = 0; } - if (apply_loop_filter && v->fcm == PROGRESSIVE) { + if (apply_loop_filter) { s->mb_x = 0; init_block_index(v); for (; s->mb_x < s->mb_width; s->mb_x++) { @@ -5104,17 +5159,18 @@ static void vc1_decode_skip_blocks(VC1Context *v) { MpegEncContext *s = &v->s; + if (!v->s.last_picture.f.data[0]) + return; + ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, ER_MB_END); s->first_slice_line = 1; for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) { s->mb_x = 0; init_block_index(v); ff_update_block_index(s); - if (s->last_picture.f.data[0]) { - memcpy(s->dest[0], s->last_picture.f.data[0] + s->mb_y * 16 * s->linesize, s->linesize * 16); - memcpy(s->dest[1], s->last_picture.f.data[1] + s->mb_y * 8 * s->uvlinesize, s->uvlinesize * 8); - memcpy(s->dest[2], s->last_picture.f.data[2] + s->mb_y * 8 * s->uvlinesize, s->uvlinesize * 8); - } + memcpy(s->dest[0], s->last_picture.f.data[0] + s->mb_y * 16 * s->linesize, s->linesize * 16); + memcpy(s->dest[1], s->last_picture.f.data[1] + s->mb_y * 8 * s->uvlinesize, s->uvlinesize * 8); + memcpy(s->dest[2], s->last_picture.f.data[2] + s->mb_y * 8 * s->uvlinesize, s->uvlinesize * 8); ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16); s->first_slice_line = 0; } @@ -5218,7 +5274,7 @@ static void vc1_sprite_parse_transform(GetBitContext* gb, int c[7]) c[6] = 1 << 16; } -static void vc1_parse_sprites(VC1Context *v, GetBitContext* gb, SpriteData* sd) +static int vc1_parse_sprites(VC1Context *v, GetBitContext* gb, SpriteData* sd) { AVCodecContext *avctx = v->s.avctx; int sprite, i; @@ -5262,7 +5318,7 @@ static void vc1_parse_sprites(VC1Context *v, GetBitContext* gb, SpriteData* sd) sd->effect_pcount2 = get_bits(gb, 16); if (sd->effect_pcount2 > 10) { av_log(avctx, AV_LOG_ERROR, "Too many effect parameters\n"); - return; + return AVERROR_INVALIDDATA; } else if (sd->effect_pcount2) { i = -1; av_log(avctx, AV_LOG_DEBUG, "Effect params 2: "); @@ -5279,10 +5335,14 @@ static void vc1_parse_sprites(VC1Context *v, GetBitContext* gb, SpriteData* sd) av_log(avctx, AV_LOG_DEBUG, "Effect flag set\n"); if (get_bits_count(gb) >= gb->size_in_bits + - (avctx->codec_id == AV_CODEC_ID_WMV3IMAGE ? 64 : 0)) + (avctx->codec_id == AV_CODEC_ID_WMV3IMAGE ? 64 : 0)) { av_log(avctx, AV_LOG_ERROR, "Buffer overrun\n"); + return AVERROR_INVALIDDATA; + } if (get_bits_count(gb) < gb->size_in_bits - 8) av_log(avctx, AV_LOG_WARNING, "Buffer not fully read\n"); + + return 0; } static void vc1_draw_sprites(VC1Context *v, SpriteData* sd) @@ -5294,7 +5354,7 @@ static void vc1_draw_sprites(VC1Context *v, SpriteData* sd) int ysub[2]; MpegEncContext *s = &v->s; - for (i = 0; i < 2; i++) { + for (i = 0; i <= v->two_sprites; i++) { xoff[i] = av_clip(sd->coefs[i][2], 0, v->sprite_width-1 << 16); xadv[i] = sd->coefs[i][0]; if (xadv[i] != 1<<16 || (v->sprite_width << 16) - (v->output_width << 16) - xoff[i]) @@ -5309,8 +5369,8 @@ static void vc1_draw_sprites(VC1Context *v, SpriteData* sd) int width = v->output_width>>!!plane; for (row = 0; row < v->output_height>>!!plane; row++) { - uint8_t *dst = v->sprite_output_frame.data[plane] + - v->sprite_output_frame.linesize[plane] * row; + uint8_t *dst = v->sprite_output_frame->data[plane] + + v->sprite_output_frame->linesize[plane] * row; for (sprite = 0; sprite <= v->two_sprites; sprite++) { uint8_t *iplane = s->current_picture.f.data[plane]; @@ -5372,7 +5432,7 @@ static void vc1_draw_sprites(VC1Context *v, SpriteData* sd) } if (!plane) { - for (i = 0; i < 2; i++) { + for (i = 0; i <= v->two_sprites; i++) { xoff[i] >>= 1; yoff[i] >>= 1; } @@ -5389,7 +5449,11 @@ static int vc1_decode_sprites(VC1Context *v, GetBitContext* gb) AVCodecContext *avctx = s->avctx; SpriteData sd; - vc1_parse_sprites(v, gb, &sd); + memset(&sd, 0, sizeof(sd)); + + ret = vc1_parse_sprites(v, gb, &sd); + if (ret < 0) + return ret; if (!s->current_picture.f.data[0]) { av_log(avctx, AV_LOG_ERROR, "Got no sprites\n"); @@ -5401,8 +5465,8 @@ static int vc1_decode_sprites(VC1Context *v, GetBitContext* gb) v->two_sprites = 0; } - av_frame_unref(&v->sprite_output_frame); - if ((ret = ff_get_buffer(avctx, &v->sprite_output_frame, 0)) < 0) + av_frame_unref(v->sprite_output_frame); + if ((ret = ff_get_buffer(avctx, v->sprite_output_frame, 0)) < 0) return ret; vc1_draw_sprites(v, &sd); @@ -5434,14 +5498,15 @@ av_cold int ff_vc1_decode_init_alloc_tables(VC1Context *v) { MpegEncContext *s = &v->s; int i; + int mb_height = FFALIGN(s->mb_height, 2); /* Allocate mb bitplanes */ - v->mv_type_mb_plane = av_malloc (s->mb_stride * s->mb_height); - v->direct_mb_plane = av_malloc (s->mb_stride * s->mb_height); - v->forward_mb_plane = av_malloc (s->mb_stride * s->mb_height); - v->fieldtx_plane = av_mallocz(s->mb_stride * s->mb_height); - v->acpred_plane = av_malloc (s->mb_stride * s->mb_height); - v->over_flags_plane = av_malloc (s->mb_stride * s->mb_height); + v->mv_type_mb_plane = av_malloc (s->mb_stride * mb_height); + v->direct_mb_plane = av_malloc (s->mb_stride * mb_height); + v->forward_mb_plane = av_malloc (s->mb_stride * mb_height); + v->fieldtx_plane = av_mallocz(s->mb_stride * mb_height); + v->acpred_plane = av_malloc (s->mb_stride * mb_height); + v->over_flags_plane = av_malloc (s->mb_stride * mb_height); v->n_allocated_blks = s->mb_width + 2; v->block = av_malloc(sizeof(*v->block) * v->n_allocated_blks); @@ -5451,27 +5516,24 @@ av_cold int ff_vc1_decode_init_alloc_tables(VC1Context *v) v->ttblk = v->ttblk_base + s->mb_stride; v->is_intra_base = av_mallocz(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_base = av_mallocz(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); + v->mb_type_base = av_malloc(s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2); v->mb_type[0] = v->mb_type_base + s->b8_stride + 1; - v->mb_type[1] = v->mb_type_base + s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride + 1; - v->mb_type[2] = v->mb_type[1] + s->mb_stride * (s->mb_height + 1); + v->mb_type[1] = v->mb_type_base + s->b8_stride * (mb_height * 2 + 1) + s->mb_stride + 1; + v->mb_type[2] = v->mb_type[1] + s->mb_stride * (mb_height + 1); /* allocate memory to store block level MV info */ - v->blk_mv_type_base = av_mallocz( s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2); + v->blk_mv_type_base = av_mallocz( s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2); v->blk_mv_type = v->blk_mv_type_base + s->b8_stride + 1; - v->mv_f_base = av_mallocz(2 * (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2)); + v->mv_f_base = av_mallocz(2 * (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2)); v->mv_f[0] = v->mv_f_base + s->b8_stride + 1; - v->mv_f[1] = v->mv_f[0] + (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2); - v->mv_f_last_base = av_mallocz(2 * (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2)); - v->mv_f_last[0] = v->mv_f_last_base + s->b8_stride + 1; - v->mv_f_last[1] = v->mv_f_last[0] + (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2); - v->mv_f_next_base = av_mallocz(2 * (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2)); + v->mv_f[1] = v->mv_f[0] + (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2); + v->mv_f_next_base = av_mallocz(2 * (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2)); v->mv_f_next[0] = v->mv_f_next_base + s->b8_stride + 1; - v->mv_f_next[1] = v->mv_f_next[0] + (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2); + v->mv_f_next[1] = v->mv_f_next[0] + (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2); /* Init coded blocks info */ if (v->profile == PROFILE_ADVANCED) { @@ -5485,13 +5547,25 @@ av_cold int ff_vc1_decode_init_alloc_tables(VC1Context *v) if (s->avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || s->avctx->codec_id == AV_CODEC_ID_VC1IMAGE) { for (i = 0; i < 4; i++) - if (!(v->sr_rows[i >> 1][i & 1] = av_malloc(v->output_width))) return -1; + if (!(v->sr_rows[i >> 1][i & 1] = av_malloc(v->output_width))) + return AVERROR(ENOMEM); } if (!v->mv_type_mb_plane || !v->direct_mb_plane || !v->acpred_plane || !v->over_flags_plane || !v->block || !v->cbp_base || !v->ttblk_base || !v->is_intra_base || !v->luma_mv_base || - !v->mb_type_base) - return -1; + !v->mb_type_base) { + av_freep(&v->mv_type_mb_plane); + av_freep(&v->direct_mb_plane); + av_freep(&v->acpred_plane); + av_freep(&v->over_flags_plane); + av_freep(&v->block); + av_freep(&v->cbp_base); + av_freep(&v->ttblk_base); + av_freep(&v->is_intra_base); + av_freep(&v->luma_mv_base); + av_freep(&v->mb_type_base); + return AVERROR(ENOMEM); + } return 0; } @@ -5520,6 +5594,7 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) VC1Context *v = avctx->priv_data; MpegEncContext *s = &v->s; GetBitContext gb; + int ret; /* save the container output size for WMImage */ v->output_width = avctx->width; @@ -5531,18 +5606,18 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) avctx->pix_fmt = avctx->get_format(avctx, avctx->codec->pix_fmts); else avctx->pix_fmt = AV_PIX_FMT_GRAY8; - avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt); + avctx->hwaccel = ff_find_hwaccel(avctx); v->s.avctx = avctx; avctx->flags |= CODEC_FLAG_EMU_EDGE; v->s.flags |= CODEC_FLAG_EMU_EDGE; - if (ff_vc1_init_common(v) < 0) - return -1; + if ((ret = ff_vc1_init_common(v)) < 0) + return ret; // ensure static VLC tables are initialized - if (ff_msmpeg4_decode_init(avctx) < 0) - return -1; - if (ff_vc1_decode_init_alloc_tables(v) < 0) - return -1; + if ((ret = ff_msmpeg4_decode_init(avctx)) < 0) + return ret; + if ((ret = ff_vc1_decode_init_alloc_tables(v)) < 0) + return ret; // Hack to ensure the above functions will be called // again once we know all necessary settings. // That this is necessary might indicate a bug. @@ -5561,8 +5636,8 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) init_get_bits(&gb, avctx->extradata, avctx->extradata_size*8); - if (ff_vc1_decode_sequence_header(avctx, v, &gb) < 0) - return -1; + if ((ret = ff_vc1_decode_sequence_header(avctx, v, &gb)) < 0) + return ret; count = avctx->extradata_size*8 - get_bits_count(&gb); if (count > 0) { @@ -5596,16 +5671,16 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) init_get_bits(&gb, buf2, buf2_size * 8); switch (AV_RB32(start)) { case VC1_CODE_SEQHDR: - if (ff_vc1_decode_sequence_header(avctx, v, &gb) < 0) { + if ((ret = ff_vc1_decode_sequence_header(avctx, v, &gb)) < 0) { av_free(buf2); - return -1; + return ret; } seq_initialized = 1; break; case VC1_CODE_ENTRYPOINT: - if (ff_vc1_decode_entry_point(avctx, v, &gb) < 0) { + if ((ret = ff_vc1_decode_entry_point(avctx, v, &gb)) < 0) { av_free(buf2); - return -1; + return ret; } ep_initialized = 1; break; @@ -5619,6 +5694,10 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) v->res_sprite = (avctx->codec_id == AV_CODEC_ID_VC1IMAGE); } + v->sprite_output_frame = av_frame_alloc(); + if (!v->sprite_output_frame) + return AVERROR(ENOMEM); + avctx->profile = v->profile; if (v->profile == PROFILE_ADVANCED) avctx->level = v->level; @@ -5665,7 +5744,7 @@ av_cold int ff_vc1_decode_end(AVCodecContext *avctx) VC1Context *v = avctx->priv_data; int i; - av_frame_unref(&v->sprite_output_frame); + av_frame_free(&v->sprite_output_frame); for (i = 0; i < 4; i++) av_freep(&v->sr_rows[i >> 1][i & 1]); @@ -5681,7 +5760,6 @@ av_cold int ff_vc1_decode_end(AVCodecContext *avctx) av_freep(&v->mb_type_base); av_freep(&v->blk_mv_type_base); av_freep(&v->mv_f_base); - av_freep(&v->mv_f_last_base); av_freep(&v->mv_f_next_base); av_freep(&v->block); av_freep(&v->cbp_base); @@ -5743,6 +5821,8 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, if (avctx->codec_id == AV_CODEC_ID_VC1 || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) { int buf_size2 = 0; buf2 = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!buf2) + return AVERROR(ENOMEM); if (IS_MARKER(AV_RB32(buf))) { /* frame starts with marker and needs to be parsed */ const uint8_t *start, *end, *next; @@ -5778,7 +5858,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, buf_size3 << 3); /* assuming that the field marker is at the exact middle, hope it's correct */ - slices[n_slices].mby_start = s->mb_height >> 1; + slices[n_slices].mby_start = s->mb_height + 1 >> 1; n_slices1 = n_slices - 1; // index of the last slice of the first field n_slices++; break; @@ -5829,7 +5909,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, buf_size3 = vc1_unescape_buffer(divider + 4, buf + buf_size - divider - 4, slices[n_slices].buf); init_get_bits(&slices[n_slices].gb, slices[n_slices].buf, buf_size3 << 3); - slices[n_slices].mby_start = s->mb_height >> 1; + slices[n_slices].mby_start = s->mb_height + 1 >> 1; n_slices1 = n_slices - 1; n_slices++; } @@ -5866,8 +5946,12 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, } if (!s->context_initialized) { - if (ff_msmpeg4_decode_init(avctx) < 0 || ff_vc1_decode_init_alloc_tables(v) < 0) + if (ff_msmpeg4_decode_init(avctx) < 0) goto err; + if (ff_vc1_decode_init_alloc_tables(v) < 0) { + ff_MPV_common_end(s); + goto err; + } s->low_delay = !avctx->has_b_frames || v->res_sprite; @@ -5879,15 +5963,6 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, } } - /* We need to set current_picture_ptr before reading the header, - * otherwise we cannot store anything in there. */ - if (s->current_picture_ptr == NULL || s->current_picture_ptr->f.data[0]) { - int i = ff_find_unused_picture(s, 0); - if (i < 0) - goto err; - s->current_picture_ptr = &s->picture[i]; - } - // do parse frame header v->pic_header_flag = 0; v->first_pic_header_flag = 1; @@ -5916,18 +5991,6 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, goto err; } - // process pulldown flags - s->current_picture_ptr->f.repeat_pict = 0; - // Pulldown flags are only valid when 'broadcast' has been set. - // So ticks_per_frame will be 2 - if (v->rff) { - // repeat field - s->current_picture_ptr->f.repeat_pict = 1; - } else if (v->rptfrm) { - // repeat frames - s->current_picture_ptr->f.repeat_pict = v->rptfrm * 2; - } - // for skipping the frame s->current_picture.f.pict_type = s->pict_type; s->current_picture.f.key_frame = s->pict_type == AV_PICTURE_TYPE_I; @@ -5956,13 +6019,30 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, v->s.current_picture_ptr->f.interlaced_frame = (v->fcm != PROGRESSIVE); v->s.current_picture_ptr->f.top_field_first = v->tff; + // process pulldown flags + s->current_picture_ptr->f.repeat_pict = 0; + // Pulldown flags are only valid when 'broadcast' has been set. + // So ticks_per_frame will be 2 + if (v->rff) { + // repeat field + s->current_picture_ptr->f.repeat_pict = 1; + } else if (v->rptfrm) { + // repeat frames + s->current_picture_ptr->f.repeat_pict = v->rptfrm * 2; + } + s->me.qpel_put = s->dsp.put_qpel_pixels_tab; s->me.qpel_avg = s->dsp.avg_qpel_pixels_tab; if ((CONFIG_VC1_VDPAU_DECODER) - &&s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) - ff_vdpau_vc1_decode_picture(s, buf_start, (buf + buf_size) - buf_start); - else if (avctx->hwaccel) { + &&s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) { + if (v->field_mode && buf_start_second_field) { + ff_vdpau_vc1_decode_picture(s, buf_start, buf_start_second_field - buf_start); + ff_vdpau_vc1_decode_picture(s, buf_start_second_field, (buf + buf_size) - buf_start_second_field); + } else { + ff_vdpau_vc1_decode_picture(s, buf_start, (buf + buf_size) - buf_start); + } + } else if (avctx->hwaccel) { if (v->field_mode && buf_start_second_field) { // decode first field s->picture_structure = PICT_BOTTOM_FIELD - v->tff; @@ -6002,28 +6082,21 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, } else { int header_ret = 0; - ff_mpeg_er_frame_start(s); v->bits = buf_size * 8; v->end_mb_x = s->mb_width; if (v->field_mode) { - uint8_t *tmp[2]; s->current_picture.f.linesize[0] <<= 1; s->current_picture.f.linesize[1] <<= 1; s->current_picture.f.linesize[2] <<= 1; s->linesize <<= 1; s->uvlinesize <<= 1; - tmp[0] = v->mv_f_last[0]; - tmp[1] = v->mv_f_last[1]; - v->mv_f_last[0] = v->mv_f_next[0]; - v->mv_f_last[1] = v->mv_f_next[1]; - v->mv_f_next[0] = v->mv_f[0]; - v->mv_f_next[1] = v->mv_f[1]; - v->mv_f[0] = tmp[0]; - v->mv_f[1] = tmp[1]; } mb_height = s->mb_height >> v->field_mode; + + av_assert0 (mb_height > 0); + for (i = 0; i <= n_slices; i++) { if (i > 0 && slices[i - 1].mby_start >= mb_height) { if (v->field_mode <= 0) { @@ -6033,6 +6106,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, continue; } v->second_field = 1; + av_assert0((s->mb_height & 1) == 0); v->blocks_off = s->b8_stride * (s->mb_height&~1); v->mb_off = s->mb_stride * s->mb_height >> 1; } else { @@ -6045,12 +6119,16 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, if (v->field_mode && i == n_slices1 + 2) { if ((header_ret = ff_vc1_parse_frame_header_adv(v, &s->gb)) < 0) { av_log(v->s.avctx, AV_LOG_ERROR, "Field header damaged\n"); + if (avctx->err_recognition & AV_EF_EXPLODE) + goto err; continue; } } else if (get_bits1(&s->gb)) { v->pic_header_flag = 1; if ((header_ret = ff_vc1_parse_frame_header_adv(v, &s->gb)) < 0) { av_log(v->s.avctx, AV_LOG_ERROR, "Slice header damaged\n"); + if (avctx->err_recognition & AV_EF_EXPLODE) + goto err; continue; } } @@ -6081,15 +6159,15 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, } if (v->field_mode) { v->second_field = 0; - if (s->pict_type == AV_PICTURE_TYPE_B) { - memcpy(v->mv_f_base, v->mv_f_next_base, - 2 * (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2)); - } s->current_picture.f.linesize[0] >>= 1; s->current_picture.f.linesize[1] >>= 1; s->current_picture.f.linesize[2] >>= 1; s->linesize >>= 1; s->uvlinesize >>= 1; + if (v->s.pict_type != AV_PICTURE_TYPE_BI && v->s.pict_type != AV_PICTURE_TYPE_B) { + FFSWAP(uint8_t *, v->mv_f_next[0], v->mv_f[0]); + FFSWAP(uint8_t *, v->mv_f_next[1], v->mv_f[1]); + } } av_dlog(s->avctx, "Consumed %i/%i bits\n", get_bits_count(&s->gb), s->gb.size_in_bits); @@ -6097,7 +6175,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, // return -1; if(s->er.error_occurred && s->pict_type == AV_PICTURE_TYPE_B) goto err; - if(!v->field_mode) + if (!v->field_mode) ff_er_frame_end(&s->er); } @@ -6113,7 +6191,7 @@ image: if (vc1_decode_sprites(v, &s->gb)) goto err; #endif - if ((ret = av_frame_ref(pict, &v->sprite_output_frame)) < 0) + if ((ret = av_frame_ref(pict, v->sprite_output_frame)) < 0) goto err; *got_frame = 1; } else { @@ -6121,12 +6199,11 @@ image: if ((ret = av_frame_ref(pict, &s->current_picture_ptr->f)) < 0) goto err; ff_print_debug_info(s, s->current_picture_ptr, pict); + *got_frame = 1; } else if (s->last_picture_ptr != NULL) { if ((ret = av_frame_ref(pict, &s->last_picture_ptr->f)) < 0) goto err; ff_print_debug_info(s, s->last_picture_ptr, pict); - } - if (s->last_picture_ptr || s->low_delay) { *got_frame = 1; } } @@ -6171,6 +6248,7 @@ static const enum AVPixelFormat vc1_hwaccel_pixfmt_list_420[] = { AVCodec ff_vc1_decoder = { .name = "vc1", + .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VC1, .priv_data_size = sizeof(VC1Context), @@ -6179,7 +6257,6 @@ AVCodec ff_vc1_decoder = { .decode = vc1_decode_frame, .flush = ff_mpeg_flush, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY, - .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1"), .pix_fmts = vc1_hwaccel_pixfmt_list_420, .profiles = NULL_IF_CONFIG_SMALL(profiles) }; @@ -6187,6 +6264,7 @@ AVCodec ff_vc1_decoder = { #if CONFIG_WMV3_DECODER AVCodec ff_wmv3_decoder = { .name = "wmv3", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_WMV3, .priv_data_size = sizeof(VC1Context), @@ -6195,7 +6273,6 @@ AVCodec ff_wmv3_decoder = { .decode = vc1_decode_frame, .flush = ff_mpeg_flush, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9"), .pix_fmts = vc1_hwaccel_pixfmt_list_420, .profiles = NULL_IF_CONFIG_SMALL(profiles) }; @@ -6204,6 +6281,7 @@ AVCodec ff_wmv3_decoder = { #if CONFIG_WMV3_VDPAU_DECODER AVCodec ff_wmv3_vdpau_decoder = { .name = "wmv3_vdpau", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 VDPAU"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_WMV3, .priv_data_size = sizeof(VC1Context), @@ -6211,7 +6289,6 @@ AVCodec ff_wmv3_vdpau_decoder = { .close = ff_vc1_decode_end, .decode = vc1_decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 VDPAU"), .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_VDPAU_WMV3, AV_PIX_FMT_NONE }, .profiles = NULL_IF_CONFIG_SMALL(profiles) }; @@ -6220,6 +6297,7 @@ AVCodec ff_wmv3_vdpau_decoder = { #if CONFIG_VC1_VDPAU_DECODER AVCodec ff_vc1_vdpau_decoder = { .name = "vc1_vdpau", + .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1 VDPAU"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VC1, .priv_data_size = sizeof(VC1Context), @@ -6227,7 +6305,6 @@ AVCodec ff_vc1_vdpau_decoder = { .close = ff_vc1_decode_end, .decode = vc1_decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU, - .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1 VDPAU"), .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_VDPAU_VC1, AV_PIX_FMT_NONE }, .profiles = NULL_IF_CONFIG_SMALL(profiles) }; @@ -6236,6 +6313,7 @@ AVCodec ff_vc1_vdpau_decoder = { #if CONFIG_WMV3IMAGE_DECODER AVCodec ff_wmv3image_decoder = { .name = "wmv3image", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_WMV3IMAGE, .priv_data_size = sizeof(VC1Context), @@ -6244,7 +6322,6 @@ AVCodec ff_wmv3image_decoder = { .decode = vc1_decode_frame, .capabilities = CODEC_CAP_DR1, .flush = vc1_sprite_flush, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Image"), .pix_fmts = ff_pixfmt_list_420 }; #endif @@ -6252,6 +6329,7 @@ AVCodec ff_wmv3image_decoder = { #if CONFIG_VC1IMAGE_DECODER AVCodec ff_vc1image_decoder = { .name = "vc1image", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Image v2"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VC1IMAGE, .priv_data_size = sizeof(VC1Context), @@ -6260,7 +6338,6 @@ AVCodec ff_vc1image_decoder = { .decode = vc1_decode_frame, .capabilities = CODEC_CAP_DR1, .flush = vc1_sprite_flush, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Image v2"), .pix_fmts = ff_pixfmt_list_420 }; #endif diff --git a/ffmpeg/libavcodec/vc1dsp.c b/ffmpeg/libavcodec/vc1dsp.c index f66921a..8cca521 100644 --- a/ffmpeg/libavcodec/vc1dsp.c +++ b/ffmpeg/libavcodec/vc1dsp.c @@ -741,6 +741,26 @@ static void avg_no_rnd_vc1_chroma_mc8_c(uint8_t *dst/*align 8*/, uint8_t *src/*a } } +static void avg_no_rnd_vc1_chroma_mc4_c(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){ + const int A=(8-x)*(8-y); + const int B=( x)*(8-y); + const int C=(8-x)*( y); + const int D=( x)*( y); + int i; + + av_assert2(x<8 && y<8 && x>=0 && y>=0); + + for(i=0; i> 6)); + dst[1] = avg2(dst[1], ((A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2] + 32 - 4) >> 6)); + dst[2] = avg2(dst[2], ((A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3] + 32 - 4) >> 6)); + dst[3] = avg2(dst[3], ((A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4] + 32 - 4) >> 6)); + dst+= stride; + src+= stride; + } +} + #if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER static void sprite_h_c(uint8_t *dst, const uint8_t *src, int offset, int advance, int count) @@ -858,6 +878,7 @@ av_cold void ff_vc1dsp_init(VC1DSPContext* dsp) { dsp->put_no_rnd_vc1_chroma_pixels_tab[0]= put_no_rnd_vc1_chroma_mc8_c; dsp->avg_no_rnd_vc1_chroma_pixels_tab[0]= avg_no_rnd_vc1_chroma_mc8_c; dsp->put_no_rnd_vc1_chroma_pixels_tab[1] = put_no_rnd_vc1_chroma_mc4_c; + dsp->avg_no_rnd_vc1_chroma_pixels_tab[1] = avg_no_rnd_vc1_chroma_mc4_c; #if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER dsp->sprite_h = sprite_h_c; @@ -867,8 +888,10 @@ av_cold void ff_vc1dsp_init(VC1DSPContext* dsp) { dsp->sprite_v_double_twoscale = sprite_v_double_twoscale_c; #endif - if (HAVE_ALTIVEC) - ff_vc1dsp_init_altivec(dsp); + if (ARCH_ARM) + ff_vc1dsp_init_arm(dsp); + if (ARCH_PPC) + ff_vc1dsp_init_ppc(dsp); if (ARCH_X86) ff_vc1dsp_init_x86(dsp); } diff --git a/ffmpeg/libavcodec/vc1dsp.h b/ffmpeg/libavcodec/vc1dsp.h index 851e40c..018d298 100644 --- a/ffmpeg/libavcodec/vc1dsp.h +++ b/ffmpeg/libavcodec/vc1dsp.h @@ -29,6 +29,7 @@ #define AVCODEC_VC1DSP_H #include "dsputil.h" +#include "hpeldsp.h" #include "h264chroma.h" typedef void (*vc1op_pixels_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, ptrdiff_t line_size, int h); @@ -76,7 +77,8 @@ typedef struct VC1DSPContext { } VC1DSPContext; void ff_vc1dsp_init(VC1DSPContext* c); -void ff_vc1dsp_init_altivec(VC1DSPContext* c); +void ff_vc1dsp_init_arm(VC1DSPContext* dsp); +void ff_vc1dsp_init_ppc(VC1DSPContext *c); void ff_vc1dsp_init_x86(VC1DSPContext* dsp); #endif /* AVCODEC_VC1DSP_H */ diff --git a/ffmpeg/libavcodec/vcr1.c b/ffmpeg/libavcodec/vcr1.c index 60bfcce..f8281ea 100644 --- a/ffmpeg/libavcodec/vcr1.c +++ b/ffmpeg/libavcodec/vcr1.c @@ -26,6 +26,7 @@ #include "avcodec.h" #include "internal.h" +#include "libavutil/avassert.h" #include "libavutil/internal.h" typedef struct VCR1Context { @@ -38,24 +39,24 @@ static av_cold int vcr1_decode_init(AVCodecContext *avctx) avctx->pix_fmt = AV_PIX_FMT_YUV410P; if (avctx->width % 8 || avctx->height%4) { - avpriv_request_sample(avctx, "odd dimensions support"); - return AVERROR_PATCHWELCOME; + avpriv_request_sample(avctx, "odd dimensions (%d x %d) support", avctx->width, avctx->height); + return AVERROR_INVALIDDATA; } + return 0; } static int vcr1_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; VCR1Context *const a = avctx->priv_data; AVFrame *const p = data; - const uint8_t *bytestream = buf; + const uint8_t *bytestream = avpkt->data; + const uint8_t *bytestream_end = bytestream + avpkt->size; int i, x, y, ret; - if(buf_size < 16 + avctx->height + avctx->width*avctx->height*5/8){ - av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n"); + if(avpkt->size < 32 + avctx->height + avctx->width*avctx->height*5/8){ + av_log(avctx, AV_LOG_ERROR, "Insufficient input data. %d < %d\n", avpkt->size , 32 + avctx->height + avctx->width*avctx->height*5/8); return AVERROR(EINVAL); } @@ -77,6 +78,8 @@ static int vcr1_decode_frame(AVCodecContext *avctx, void *data, uint8_t *cb = &p->data[1][(y >> 2) * p->linesize[1]]; uint8_t *cr = &p->data[2][(y >> 2) * p->linesize[2]]; + av_assert0 (bytestream_end - bytestream >= 4 + avctx->width); + for (i = 0; i < 4; i++) a->offset[i] = *bytestream++; @@ -94,6 +97,8 @@ static int vcr1_decode_frame(AVCodecContext *avctx, void *data, bytestream += 4; } } else { + av_assert0 (bytestream_end - bytestream >= avctx->width / 2); + offset = a->offset[y & 3] - a->delta[bytestream[2] & 0xF]; for (x = 0; x < avctx->width; x += 8) { @@ -113,16 +118,16 @@ static int vcr1_decode_frame(AVCodecContext *avctx, void *data, *got_frame = 1; - return buf_size; + return bytestream - avpkt->data; } AVCodec ff_vcr1_decoder = { .name = "vcr1", + .long_name = NULL_IF_CONFIG_SMALL("ATI VCR1"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VCR1, .priv_data_size = sizeof(VCR1Context), .init = vcr1_decode_init, .decode = vcr1_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("ATI VCR1"), }; diff --git a/ffmpeg/libavcodec/vda.h b/ffmpeg/libavcodec/vda.h index 281785f..b3d6399 100644 --- a/ffmpeg/libavcodec/vda.h +++ b/ffmpeg/libavcodec/vda.h @@ -134,6 +134,17 @@ struct vda_context { * - decoding: Set/Unset by libavcodec. */ int priv_allocated_size; + + /** + * Use av_buffer to manage buffer. + * When the flag is set, the CVPixelBuffers returned by the decoder will + * be released automatically, so you have to retain them if necessary. + * Not setting this flag may cause memory leak. + * + * encoding: unused + * decoding: Set by user. + */ + int use_ref_buffer; }; /** Create the video decoder. */ diff --git a/ffmpeg/libavcodec/vda_h264.c b/ffmpeg/libavcodec/vda_h264.c index d0237c2..e0561e2 100644 --- a/ffmpeg/libavcodec/vda_h264.c +++ b/ffmpeg/libavcodec/vda_h264.c @@ -28,13 +28,16 @@ #include "libavutil/avutil.h" #include "h264.h" +struct vda_buffer { + CVPixelBufferRef cv_buffer; +}; /* Decoder callback that adds the vda frame to the queue in display order. */ -static void vda_decoder_callback (void *vda_hw_ctx, - CFDictionaryRef user_info, - OSStatus status, - uint32_t infoFlags, - CVImageBufferRef image_buffer) +static void vda_decoder_callback(void *vda_hw_ctx, + CFDictionaryRef user_info, + OSStatus status, + uint32_t infoFlags, + CVImageBufferRef image_buffer) { struct vda_context *vda_ctx = vda_hw_ctx; @@ -108,11 +111,20 @@ static int vda_h264_decode_slice(AVCodecContext *avctx, return 0; } +static void vda_h264_release_buffer(void *opaque, uint8_t *data) +{ + struct vda_buffer *context = opaque; + CVPixelBufferRelease(context->cv_buffer); + av_free(context); +} + static int vda_h264_end_frame(AVCodecContext *avctx) { H264Context *h = avctx->priv_data; struct vda_context *vda_ctx = avctx->hwaccel_context; AVFrame *frame = &h->cur_pic_ptr->f; + struct vda_buffer *context; + AVBufferRef *buffer; int status; if (!vda_ctx->decoder || !vda_ctx->priv_bitstream) @@ -124,6 +136,20 @@ static int vda_h264_end_frame(AVCodecContext *avctx) if (status) av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%d)\n", status); + if (!vda_ctx->use_ref_buffer || status) + return status; + + context = av_mallocz(sizeof(*context)); + buffer = av_buffer_create(NULL, 0, vda_h264_release_buffer, context, 0); + if (!context || !buffer) { + CVPixelBufferRelease(vda_ctx->cv_buffer); + av_free(context); + return -1; + } + + context->cv_buffer = vda_ctx->cv_buffer; + frame->buf[3] = buffer; + return status; } diff --git a/ffmpeg/libavcodec/vda_h264_dec.c b/ffmpeg/libavcodec/vda_h264_dec.c index d6c8f37..e5fa807 100644 --- a/ffmpeg/libavcodec/vda_h264_dec.c +++ b/ffmpeg/libavcodec/vda_h264_dec.c @@ -56,6 +56,15 @@ typedef struct { int h264_initialized; struct vda_context vda_ctx; enum AVPixelFormat pix_fmt; + + /* for backing-up fields set by user. + * we have to gain full control of such fields here */ + void *hwaccel_context; + enum AVPixelFormat (*get_format)(struct AVCodecContext *s, const enum AVPixelFormat * fmt); + int (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags); +#if FF_API_GET_BUFFER + int (*get_buffer)(struct AVCodecContext *c, AVFrame *pic); +#endif } VDADecoderContext; static enum AVPixelFormat get_format(struct AVCodecContext *avctx, @@ -64,23 +73,56 @@ static enum AVPixelFormat get_format(struct AVCodecContext *avctx, return AV_PIX_FMT_VDA_VLD; } -static int get_buffer(AVCodecContext *avctx, AVFrame *pic) +typedef struct { + CVPixelBufferRef cv_buffer; +} VDABufferContext; + +static void release_buffer(void *opaque, uint8_t *data) { - pic->type = FF_BUFFER_TYPE_USER; + VDABufferContext *context = opaque; + CVPixelBufferUnlockBaseAddress(context->cv_buffer, 0); + CVPixelBufferRelease(context->cv_buffer); + av_free(context); +} + +static int get_buffer2(AVCodecContext *avctx, AVFrame *pic, int flag) +{ + VDABufferContext *context = av_mallocz(sizeof(VDABufferContext)); + AVBufferRef *buffer = av_buffer_create(NULL, 0, release_buffer, context, 0); + if (!context || !buffer) { + av_free(context); + return AVERROR(ENOMEM); + } + + pic->buf[0] = buffer; pic->data[0] = (void *)1; return 0; } -static void release_buffer(AVCodecContext *avctx, AVFrame *pic) +static inline void set_context(AVCodecContext *avctx) { - int i; - - CVPixelBufferRef cv_buffer = (CVPixelBufferRef)pic->data[3]; - CVPixelBufferUnlockBaseAddress(cv_buffer, 0); - CVPixelBufferRelease(cv_buffer); + VDADecoderContext *ctx = avctx->priv_data; + ctx->hwaccel_context = avctx->hwaccel_context; + avctx->hwaccel_context = &ctx->vda_ctx; + ctx->get_format = avctx->get_format; + avctx->get_format = get_format; + ctx->get_buffer2 = avctx->get_buffer2; + avctx->get_buffer2 = get_buffer2; +#if FF_API_GET_BUFFER + ctx->get_buffer = avctx->get_buffer; + avctx->get_buffer = NULL; +#endif +} - for (i = 0; i < 4; i++) - pic->data[i] = NULL; +static inline void restore_context(AVCodecContext *avctx) +{ + VDADecoderContext *ctx = avctx->priv_data; + avctx->hwaccel_context = ctx->hwaccel_context; + avctx->get_format = ctx->get_format; + avctx->get_buffer2 = ctx->get_buffer2; +#if FF_API_GET_BUFFER + avctx->get_buffer = ctx->get_buffer; +#endif } static int vdadec_decode(AVCodecContext *avctx, @@ -90,10 +132,17 @@ static int vdadec_decode(AVCodecContext *avctx, AVFrame *pic = data; int ret; + set_context(avctx); ret = ff_h264_decoder.decode(avctx, data, got_frame, avpkt); + restore_context(avctx); if (*got_frame) { + AVBufferRef *buffer = pic->buf[0]; + VDABufferContext *context = av_buffer_get_opaque(buffer); CVPixelBufferRef cv_buffer = (CVPixelBufferRef)pic->data[3]; + + CVPixelBufferRetain(cv_buffer); CVPixelBufferLockBaseAddress(cv_buffer, 0); + context->cv_buffer = cv_buffer; pic->format = ctx->pix_fmt; if (CVPixelBufferIsPlanar(cv_buffer)) { int i, count = CVPixelBufferGetPlaneCount(cv_buffer); @@ -118,51 +167,12 @@ static av_cold int vdadec_close(AVCodecContext *avctx) /* release buffers and decoder */ ff_vda_destroy_decoder(&ctx->vda_ctx); /* close H.264 decoder */ - if (ctx->h264_initialized) + if (ctx->h264_initialized) { + set_context(avctx); ff_h264_decoder.close(avctx); - return 0; -} - -static av_cold int check_format(AVCodecContext *avctx) -{ - AVCodecParserContext *parser; - uint8_t *pout; - int psize; - int index; - H264Context *h; - int ret = -1; - - /* init parser & parse file */ - parser = av_parser_init(avctx->codec->id); - if (!parser) { - av_log(avctx, AV_LOG_ERROR, "Failed to open H.264 parser.\n"); - goto final; - } - parser->flags = PARSER_FLAG_COMPLETE_FRAMES; - index = av_parser_parse2(parser, avctx, &pout, &psize, NULL, 0, 0, 0, 0); - if (index < 0) { - av_log(avctx, AV_LOG_ERROR, "Failed to parse this file.\n"); - goto release_parser; - } - - /* check if support */ - h = parser->priv_data; - switch (h->sps.bit_depth_luma) { - case 8: - if (!CHROMA444 && !CHROMA422) { - // only this will H.264 decoder switch to hwaccel - ret = 0; - break; - } - default: - av_log(avctx, AV_LOG_ERROR, "Unsupported file.\n"); + restore_context(avctx); } - -release_parser: - av_parser_close(parser); - -final: - return ret; + return 0; } static av_cold int vdadec_init(AVCodecContext *avctx) @@ -182,16 +192,13 @@ static av_cold int vdadec_init(AVCodecContext *avctx) ff_h264_vda_decoder.pix_fmts = vda_pixfmts; } - /* check if VDA supports this file */ - if (check_format(avctx) < 0) - goto failed; - /* init vda */ memset(vda_ctx, 0, sizeof(struct vda_context)); vda_ctx->width = avctx->width; vda_ctx->height = avctx->height; vda_ctx->format = 'avc1'; vda_ctx->use_sync_decoding = 1; + vda_ctx->use_ref_buffer = 1; ctx->pix_fmt = avctx->get_format(avctx, avctx->codec->pix_fmts); switch (ctx->pix_fmt) { case AV_PIX_FMT_UYVY422: @@ -217,15 +224,11 @@ static av_cold int vdadec_init(AVCodecContext *avctx) "Failed to init VDA decoder: %d.\n", status); goto failed; } - avctx->hwaccel_context = vda_ctx; - - /* changes callback functions */ - avctx->get_format = get_format; - avctx->get_buffer = get_buffer; - avctx->release_buffer = release_buffer; /* init H.264 decoder */ + set_context(avctx); ret = ff_h264_decoder.init(avctx); + restore_context(avctx); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Failed to open H.264 decoder.\n"); goto failed; @@ -241,7 +244,9 @@ failed: static void vdadec_flush(AVCodecContext *avctx) { - return ff_h264_decoder.flush(avctx); + set_context(avctx); + ff_h264_decoder.flush(avctx); + restore_context(avctx); } AVCodec ff_h264_vda_decoder = { diff --git a/ffmpeg/libavcodec/vdpau.c b/ffmpeg/libavcodec/vdpau.c index 5606902..32a3843 100644 --- a/ffmpeg/libavcodec/vdpau.c +++ b/ffmpeg/libavcodec/vdpau.c @@ -38,44 +38,63 @@ * @{ */ -int ff_vdpau_common_start_frame(AVCodecContext *avctx, +AVVDPAUContext *av_alloc_vdpaucontext(void) +{ + return av_vdpau_alloc_context(); +} + +MAKE_ACCESSORS(AVVDPAUContext, vdpau_hwaccel, AVVDPAU_Render2, render2) + +int ff_vdpau_common_start_frame(Picture *pic, av_unused const uint8_t *buffer, av_unused uint32_t size) { - AVVDPAUContext *hwctx = avctx->hwaccel_context; + struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private; - hwctx->bitstream_buffers_used = 0; + pic_ctx->bitstream_buffers_allocated = 0; + pic_ctx->bitstream_buffers_used = 0; + pic_ctx->bitstream_buffers = NULL; return 0; } +#if CONFIG_H263_VDPAU_HWACCEL || CONFIG_MPEG1_VDPAU_HWACCEL || \ + CONFIG_MPEG2_VDPAU_HWACCEL || CONFIG_MPEG4_VDPAU_HWACCEL || \ + CONFIG_VC1_VDPAU_HWACCEL || CONFIG_WMV3_VDPAU_HWACCEL int ff_vdpau_mpeg_end_frame(AVCodecContext *avctx) { + int res = 0; AVVDPAUContext *hwctx = avctx->hwaccel_context; MpegEncContext *s = avctx->priv_data; - VdpVideoSurface surf = ff_vdpau_get_surface_id(s->current_picture_ptr); + Picture *pic = s->current_picture_ptr; + struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private; + VdpVideoSurface surf = ff_vdpau_get_surface_id(pic); - hwctx->render(hwctx->decoder, surf, (void *)&hwctx->info, - hwctx->bitstream_buffers_used, hwctx->bitstream_buffers); + if (!hwctx->render) { + res = hwctx->render2(avctx, &pic->f, (void *)&pic_ctx->info, + pic_ctx->bitstream_buffers_used, pic_ctx->bitstream_buffers); + } else + hwctx->render(hwctx->decoder, surf, (void *)&pic_ctx->info, + pic_ctx->bitstream_buffers_used, pic_ctx->bitstream_buffers); ff_mpeg_draw_horiz_band(s, 0, s->avctx->height); - hwctx->bitstream_buffers_used = 0; + av_freep(&pic_ctx->bitstream_buffers); - return 0; + return res; } +#endif -int ff_vdpau_add_buffer(AVCodecContext *avctx, - const uint8_t *buf, uint32_t size) +int ff_vdpau_add_buffer(Picture *pic, const uint8_t *buf, uint32_t size) { - AVVDPAUContext *hwctx = avctx->hwaccel_context; - VdpBitstreamBuffer *buffers = hwctx->bitstream_buffers; + struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private; + VdpBitstreamBuffer *buffers = pic_ctx->bitstream_buffers; - buffers = av_fast_realloc(buffers, &hwctx->bitstream_buffers_allocated, - (hwctx->bitstream_buffers_used + 1) * sizeof(*buffers)); + buffers = av_fast_realloc(buffers, &pic_ctx->bitstream_buffers_allocated, + (pic_ctx->bitstream_buffers_used + 1) * sizeof(*buffers)); if (!buffers) return AVERROR(ENOMEM); - hwctx->bitstream_buffers = buffers; - buffers += hwctx->bitstream_buffers_used++; + pic_ctx->bitstream_buffers = buffers; + buffers += pic_ctx->bitstream_buffers_used++; buffers->struct_version = VDP_BITSTREAM_BUFFER_VERSION; buffers->bitstream = buf; @@ -170,6 +189,7 @@ void ff_vdpau_add_data_chunk(uint8_t *data, const uint8_t *buf, int buf_size) render->bitstream_buffers_used++; } +#if CONFIG_H264_VDPAU_DECODER void ff_vdpau_h264_picture_start(H264Context *h) { struct vdpau_render_state *render; @@ -230,7 +250,9 @@ void ff_vdpau_h264_picture_complete(H264Context *h) ff_h264_draw_horiz_band(h, 0, h->avctx->height); render->bitstream_buffers_used = 0; } +#endif /* CONFIG_H264_VDPAU_DECODER */ +#if CONFIG_MPEG_VDPAU_DECODER || CONFIG_MPEG1_VDPAU_DECODER void ff_vdpau_mpeg_picture_complete(MpegEncContext *s, const uint8_t *buf, int buf_size, int slice_count) { @@ -287,7 +309,9 @@ void ff_vdpau_mpeg_picture_complete(MpegEncContext *s, const uint8_t *buf, ff_mpeg_draw_horiz_band(s, 0, s->avctx->height); render->bitstream_buffers_used = 0; } +#endif /* CONFIG_MPEG_VDPAU_DECODER || CONFIG_MPEG1_VDPAU_DECODER */ +#if CONFIG_VC1_VDPAU_DECODER void ff_vdpau_vc1_decode_picture(MpegEncContext *s, const uint8_t *buf, int buf_size) { @@ -298,7 +322,7 @@ void ff_vdpau_vc1_decode_picture(MpegEncContext *s, const uint8_t *buf, assert(render); /* fill LvPictureInfoVC1 struct */ - render->info.vc1.frame_coding_mode = v->fcm; + render->info.vc1.frame_coding_mode = v->fcm ? v->fcm + 1 : 0; render->info.vc1.postprocflag = v->postprocflag; render->info.vc1.pulldown = v->broadcast; render->info.vc1.interlace = v->interlace; @@ -321,7 +345,7 @@ void ff_vdpau_vc1_decode_picture(MpegEncContext *s, const uint8_t *buf, render->info.vc1.range_mapuv = v->range_mapuv; /* Specific to simple/main profile only */ render->info.vc1.multires = v->multires; - render->info.vc1.syncmarker = v->s.resync_marker; + render->info.vc1.syncmarker = v->resync_marker; render->info.vc1.rangered = v->rangered | (v->rangeredfrm << 1); render->info.vc1.maxbframes = v->s.max_b_frames; @@ -356,10 +380,13 @@ void ff_vdpau_vc1_decode_picture(MpegEncContext *s, const uint8_t *buf, ff_mpeg_draw_horiz_band(s, 0, s->avctx->height); render->bitstream_buffers_used = 0; } +#endif /* (CONFIG_VC1_VDPAU_DECODER */ -void ff_vdpau_mpeg4_decode_picture(MpegEncContext *s, const uint8_t *buf, +#if CONFIG_MPEG4_VDPAU_DECODER +void ff_vdpau_mpeg4_decode_picture(Mpeg4DecContext *ctx, const uint8_t *buf, int buf_size) { + MpegEncContext *s = &ctx->m; struct vdpau_render_state *render, *last, *next; int i; @@ -377,7 +404,7 @@ void ff_vdpau_mpeg4_decode_picture(MpegEncContext *s, const uint8_t *buf, render->info.mpeg4.vop_coding_type = 0; render->info.mpeg4.vop_fcode_forward = s->f_code; render->info.mpeg4.vop_fcode_backward = s->b_code; - render->info.mpeg4.resync_marker_disable = !s->resync_marker; + render->info.mpeg4.resync_marker_disable = !ctx->resync_marker; render->info.mpeg4.interlaced = !s->progressive_sequence; render->info.mpeg4.quant_type = s->mpeg_quant; render->info.mpeg4.quarter_sample = s->quarter_sample; @@ -410,5 +437,54 @@ void ff_vdpau_mpeg4_decode_picture(MpegEncContext *s, const uint8_t *buf, ff_mpeg_draw_horiz_band(s, 0, s->avctx->height); render->bitstream_buffers_used = 0; } +#endif /* CONFIG_MPEG4_VDPAU_DECODER */ + +int av_vdpau_get_profile(AVCodecContext *avctx, VdpDecoderProfile *profile) +{ +#define PROFILE(prof) \ +do { \ + *profile = prof; \ + return 0; \ +} while (0) + + switch (avctx->codec_id) { + case AV_CODEC_ID_MPEG1VIDEO: PROFILE(VDP_DECODER_PROFILE_MPEG1); + case AV_CODEC_ID_MPEG2VIDEO: + switch (avctx->profile) { + case FF_PROFILE_MPEG2_MAIN: PROFILE(VDP_DECODER_PROFILE_MPEG2_MAIN); + case FF_PROFILE_MPEG2_SIMPLE: PROFILE(VDP_DECODER_PROFILE_MPEG2_SIMPLE); + default: return AVERROR(EINVAL); + } + case AV_CODEC_ID_H263: PROFILE(VDP_DECODER_PROFILE_MPEG4_PART2_ASP); + case AV_CODEC_ID_MPEG4: + switch (avctx->profile) { + case FF_PROFILE_MPEG4_SIMPLE: PROFILE(VDP_DECODER_PROFILE_MPEG4_PART2_SP); + case FF_PROFILE_MPEG4_ADVANCED_SIMPLE: PROFILE(VDP_DECODER_PROFILE_MPEG4_PART2_ASP); + default: return AVERROR(EINVAL); + } + case AV_CODEC_ID_H264: + switch (avctx->profile) { + case FF_PROFILE_H264_CONSTRAINED_BASELINE: + case FF_PROFILE_H264_BASELINE: PROFILE(VDP_DECODER_PROFILE_H264_BASELINE); + case FF_PROFILE_H264_MAIN: PROFILE(VDP_DECODER_PROFILE_H264_MAIN); + case FF_PROFILE_H264_HIGH: PROFILE(VDP_DECODER_PROFILE_H264_HIGH); + default: return AVERROR(EINVAL); + } + case AV_CODEC_ID_WMV3: + case AV_CODEC_ID_VC1: + switch (avctx->profile) { + case FF_PROFILE_VC1_SIMPLE: PROFILE(VDP_DECODER_PROFILE_VC1_SIMPLE); + case FF_PROFILE_VC1_MAIN: PROFILE(VDP_DECODER_PROFILE_VC1_MAIN); + case FF_PROFILE_VC1_ADVANCED: PROFILE(VDP_DECODER_PROFILE_VC1_ADVANCED); + default: return AVERROR(EINVAL); + } + } + return AVERROR(EINVAL); +} + +AVVDPAUContext *av_vdpau_alloc_context(void) +{ + return av_mallocz(sizeof(AVVDPAUContext)); +} /* @}*/ diff --git a/ffmpeg/libavcodec/vdpau.h b/ffmpeg/libavcodec/vdpau.h index df2aace..e25cc42 100644 --- a/ffmpeg/libavcodec/vdpau.h +++ b/ffmpeg/libavcodec/vdpau.h @@ -51,22 +51,41 @@ #include #include +#include "libavutil/avconfig.h" +#include "libavutil/attributes.h" -union FFVdpPictureInfo { +#include "avcodec.h" +#include "version.h" + +#if FF_API_BUFS_VDPAU +union AVVDPAUPictureInfo { VdpPictureInfoH264 h264; VdpPictureInfoMPEG1Or2 mpeg; VdpPictureInfoVC1 vc1; VdpPictureInfoMPEG4Part2 mpeg4; }; +#endif + +struct AVCodecContext; +struct AVFrame; + +typedef int (*AVVDPAU_Render2)(struct AVCodecContext *, struct AVFrame *, + const VdpPictureInfo *, uint32_t, + const VdpBitstreamBuffer *); /** * This structure is used to share data between the libavcodec library and * the client video application. - * The user shall zero-allocate the structure and make it available as + * The user shall allocate the structure via the av_alloc_vdpau_hwaccel + * function and make it available as * AVCodecContext.hwaccel_context. Members can be set by the user once * during initialization or through each AVCodecContext.get_buffer() * function call. In any case, they must be valid prior to calling * decoding functions. + * + * The size of this structure is not a part of the public ABI and must not + * be used outside of libavcodec. Use av_vdpau_alloc_context() to allocate an + * AVVDPAUContext. */ typedef struct AVVDPAUContext { /** @@ -83,18 +102,21 @@ typedef struct AVVDPAUContext { */ VdpDecoderRender *render; +#if FF_API_BUFS_VDPAU /** * VDPAU picture information * * Set by libavcodec. */ - union FFVdpPictureInfo info; + attribute_deprecated + union AVVDPAUPictureInfo info; /** * Allocated size of the bitstream_buffers table. * * Set by libavcodec. */ + attribute_deprecated int bitstream_buffers_allocated; /** @@ -102,6 +124,7 @@ typedef struct AVVDPAUContext { * * Set by libavcodec. */ + attribute_deprecated int bitstream_buffers_used; /** @@ -110,10 +133,43 @@ typedef struct AVVDPAUContext { * * Set by libavcodec. */ + attribute_deprecated VdpBitstreamBuffer *bitstream_buffers; +#endif + AVVDPAU_Render2 render2; } AVVDPAUContext; +/** + * @brief allocation function for AVVDPAUContext + * + * Allows extending the struct without breaking API/ABI + */ +AVVDPAUContext *av_alloc_vdpaucontext(void); + +AVVDPAU_Render2 av_vdpau_hwaccel_get_render2(const AVVDPAUContext *); +void av_vdpau_hwaccel_set_render2(AVVDPAUContext *, AVVDPAU_Render2); +/** + * Allocate an AVVDPAUContext. + * + * @return Newly-allocated AVVDPAUContext or NULL on failure. + */ +AVVDPAUContext *av_vdpau_alloc_context(void); + +/** + * Get a decoder profile that should be used for initializing a VDPAU decoder. + * Should be called from the AVCodecContext.get_format() callback. + * + * @param avctx the codec context being used for decoding the stream + * @param profile a pointer into which the result will be written on success. + * The contents of profile are undefined if this function returns + * an error. + * + * @return 0 on success (non-negative), a negative AVERROR on failure. + */ +int av_vdpau_get_profile(AVCodecContext *avctx, VdpDecoderProfile *profile); + +#if FF_API_CAP_VDPAU /** @brief The videoSurface is used for rendering. */ #define FF_VDPAU_STATE_USED_FOR_RENDER 1 @@ -135,6 +191,11 @@ struct vdpau_render_state { int state; ///< Holds FF_VDPAU_STATE_* values. +#if AV_HAVE_INCOMPATIBLE_LIBAV_ABI + /** picture parameter information for all supported codecs */ + union AVVDPAUPictureInfo info; +#endif + /** Describe size/location of the compressed video data. Set to 0 when freeing bitstream_buffers. */ int bitstream_buffers_allocated; @@ -142,9 +203,12 @@ struct vdpau_render_state { /** The user is responsible for freeing this buffer using av_freep(). */ VdpBitstreamBuffer *bitstream_buffers; +#if !AV_HAVE_INCOMPATIBLE_LIBAV_ABI /** picture parameter information for all supported codecs */ - union FFVdpPictureInfo info; + union AVVDPAUPictureInfo info; +#endif }; +#endif /* @}*/ diff --git a/ffmpeg/libavcodec/vdpau_h264.c b/ffmpeg/libavcodec/vdpau_h264.c index ad1aff0..3f6415d 100644 --- a/ffmpeg/libavcodec/vdpau_h264.c +++ b/ffmpeg/libavcodec/vdpau_h264.c @@ -66,8 +66,8 @@ static void vdpau_h264_set_rf(VdpReferenceFrameH264 *rf, Picture *pic, static void vdpau_h264_set_reference_frames(AVCodecContext *avctx) { H264Context * const h = avctx->priv_data; - AVVDPAUContext *hwctx = avctx->hwaccel_context; - VdpPictureInfoH264 *info = &hwctx->info.h264; + struct vdpau_picture_context *pic_ctx = h->cur_pic_ptr->hwaccel_picture_private; + VdpPictureInfoH264 *info = &pic_ctx->info.h264; int list; VdpReferenceFrameH264 *rf = &info->referenceFrames[0]; @@ -118,9 +118,9 @@ static int vdpau_h264_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { H264Context * const h = avctx->priv_data; - AVVDPAUContext *hwctx = avctx->hwaccel_context; - VdpPictureInfoH264 *info = &hwctx->info.h264; Picture *pic = h->cur_pic_ptr; + struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private; + VdpPictureInfoH264 *info = &pic_ctx->info.h264; /* init VdpPictureInfoH264 */ info->slice_count = 0; @@ -161,7 +161,7 @@ static int vdpau_h264_start_frame(AVCodecContext *avctx, vdpau_h264_set_reference_frames(avctx); - return ff_vdpau_common_start_frame(avctx, buffer, size); + return ff_vdpau_common_start_frame(pic, buffer, size); } static const uint8_t start_code_prefix[3] = { 0x00, 0x00, 0x01 }; @@ -169,34 +169,43 @@ static const uint8_t start_code_prefix[3] = { 0x00, 0x00, 0x01 }; static int vdpau_h264_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { - AVVDPAUContext *hwctx = avctx->hwaccel_context; + H264Context *h = avctx->priv_data; + Picture *pic = h->cur_pic_ptr; + struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private; int val; - val = ff_vdpau_add_buffer(avctx, start_code_prefix, 3); + val = ff_vdpau_add_buffer(pic, start_code_prefix, 3); if (val) return val; - val = ff_vdpau_add_buffer(avctx, buffer, size); + val = ff_vdpau_add_buffer(pic, buffer, size); if (val) return val; - hwctx->info.h264.slice_count++; + pic_ctx->info.h264.slice_count++; return 0; } static int vdpau_h264_end_frame(AVCodecContext *avctx) { + int res = 0; AVVDPAUContext *hwctx = avctx->hwaccel_context; H264Context *h = avctx->priv_data; - VdpVideoSurface surf = ff_vdpau_get_surface_id(h->cur_pic_ptr); + Picture *pic = h->cur_pic_ptr; + struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private; + VdpVideoSurface surf = ff_vdpau_get_surface_id(pic); - hwctx->render(hwctx->decoder, surf, (void *)&hwctx->info, - hwctx->bitstream_buffers_used, hwctx->bitstream_buffers); + if (!hwctx->render) { + res = hwctx->render2(avctx, &pic->f, (void *)&pic_ctx->info, + pic_ctx->bitstream_buffers_used, pic_ctx->bitstream_buffers); + } else + hwctx->render(hwctx->decoder, surf, (void *)&pic_ctx->info, + pic_ctx->bitstream_buffers_used, pic_ctx->bitstream_buffers); ff_h264_draw_horiz_band(h, 0, h->avctx->height); - hwctx->bitstream_buffers_used = 0; + av_freep(&pic_ctx->bitstream_buffers); - return 0; + return res; } AVHWAccel ff_h264_vdpau_hwaccel = { @@ -207,4 +216,5 @@ AVHWAccel ff_h264_vdpau_hwaccel = { .start_frame = vdpau_h264_start_frame, .end_frame = vdpau_h264_end_frame, .decode_slice = vdpau_h264_decode_slice, + .priv_data_size = sizeof(struct vdpau_picture_context), }; diff --git a/ffmpeg/libavcodec/vdpau_internal.h b/ffmpeg/libavcodec/vdpau_internal.h index 790b3ef..cc63411 100644 --- a/ffmpeg/libavcodec/vdpau_internal.h +++ b/ffmpeg/libavcodec/vdpau_internal.h @@ -24,9 +24,17 @@ #ifndef AVCODEC_VDPAU_INTERNAL_H #define AVCODEC_VDPAU_INTERNAL_H +#include "config.h" #include +#if CONFIG_VDPAU +#include +#endif #include "h264.h" + +#include "avcodec.h" +#include "mpeg4video.h" #include "mpegvideo.h" +#include "version.h" /** Extract VdpVideoSurface from a Picture */ static inline uintptr_t ff_vdpau_get_surface_id(Picture *pic) @@ -34,11 +42,45 @@ static inline uintptr_t ff_vdpau_get_surface_id(Picture *pic) return (uintptr_t)pic->f.data[3]; } -int ff_vdpau_common_start_frame(AVCodecContext *avctx, +#if CONFIG_VDPAU +#if !FF_API_BUFS_VDPAU +union AVVDPAUPictureInfo { + VdpPictureInfoH264 h264; + VdpPictureInfoMPEG1Or2 mpeg; + VdpPictureInfoVC1 vc1; + VdpPictureInfoMPEG4Part2 mpeg4; +}; +#else +#include "vdpau.h" +#endif + +struct vdpau_picture_context { + /** + * VDPAU picture information. + */ + union AVVDPAUPictureInfo info; + + /** + * Allocated size of the bitstream_buffers table. + */ + int bitstream_buffers_allocated; + + /** + * Useful bitstream buffers in the bitstream buffers table. + */ + int bitstream_buffers_used; + + /** + * Table of bitstream buffers. + */ + VdpBitstreamBuffer *bitstream_buffers; +}; +#endif + +int ff_vdpau_common_start_frame(Picture *pic, const uint8_t *buffer, uint32_t size); int ff_vdpau_mpeg_end_frame(AVCodecContext *avctx); -int ff_vdpau_add_buffer(AVCodecContext *avctx, - const uint8_t *buf, uint32_t buf_size); +int ff_vdpau_add_buffer(Picture *pic, const uint8_t *buf, uint32_t buf_size); void ff_vdpau_add_data_chunk(uint8_t *data, const uint8_t *buf, @@ -54,7 +96,7 @@ void ff_vdpau_h264_picture_complete(H264Context *h); void ff_vdpau_vc1_decode_picture(MpegEncContext *s, const uint8_t *buf, int buf_size); -void ff_vdpau_mpeg4_decode_picture(MpegEncContext *s, const uint8_t *buf, +void ff_vdpau_mpeg4_decode_picture(Mpeg4DecContext *s, const uint8_t *buf, int buf_size); #endif /* AVCODEC_VDPAU_INTERNAL_H */ diff --git a/ffmpeg/libavcodec/vdpau_mpeg12.c b/ffmpeg/libavcodec/vdpau_mpeg12.c index 74e3f16..f21b341 100644 --- a/ffmpeg/libavcodec/vdpau_mpeg12.c +++ b/ffmpeg/libavcodec/vdpau_mpeg12.c @@ -31,8 +31,9 @@ static int vdpau_mpeg_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { MpegEncContext * const s = avctx->priv_data; - AVVDPAUContext *hwctx = avctx->hwaccel_context; - VdpPictureInfoMPEG1Or2 *info = &hwctx->info.mpeg; + Picture *pic = s->current_picture_ptr; + struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private; + VdpPictureInfoMPEG1Or2 *info = &pic_ctx->info.mpeg; VdpVideoSurface ref; int i; @@ -44,11 +45,11 @@ static int vdpau_mpeg_start_frame(AVCodecContext *avctx, case AV_PICTURE_TYPE_B: ref = ff_vdpau_get_surface_id(&s->next_picture); assert(ref != VDP_INVALID_HANDLE); - hwctx->info.mpeg.backward_reference = ref; + info->backward_reference = ref; /* fall through to forward prediction */ case AV_PICTURE_TYPE_P: ref = ff_vdpau_get_surface_id(&s->last_picture); - hwctx->info.mpeg.forward_reference = ref; + info->forward_reference = ref; } info->slice_count = 0; @@ -74,20 +75,22 @@ static int vdpau_mpeg_start_frame(AVCodecContext *avctx, info->non_intra_quantizer_matrix[i] = s->inter_matrix[i]; } - return ff_vdpau_common_start_frame(avctx, buffer, size); + return ff_vdpau_common_start_frame(pic, buffer, size); } static int vdpau_mpeg_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { - AVVDPAUContext *hwctx = avctx->hwaccel_context; + MpegEncContext * const s = avctx->priv_data; + Picture *pic = s->current_picture_ptr; + struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private; int val; - val = ff_vdpau_add_buffer(avctx, buffer, size); + val = ff_vdpau_add_buffer(pic, buffer, size); if (val < 0) return val; - hwctx->info.mpeg.slice_count++; + pic_ctx->info.mpeg.slice_count++; return 0; } @@ -100,6 +103,7 @@ AVHWAccel ff_mpeg1_vdpau_hwaccel = { .start_frame = vdpau_mpeg_start_frame, .end_frame = ff_vdpau_mpeg_end_frame, .decode_slice = vdpau_mpeg_decode_slice, + .priv_data_size = sizeof(struct vdpau_picture_context), }; #endif @@ -112,5 +116,6 @@ AVHWAccel ff_mpeg2_vdpau_hwaccel = { .start_frame = vdpau_mpeg_start_frame, .end_frame = ff_vdpau_mpeg_end_frame, .decode_slice = vdpau_mpeg_decode_slice, + .priv_data_size = sizeof(struct vdpau_picture_context), }; #endif diff --git a/ffmpeg/libavcodec/vdpau_mpeg4.c b/ffmpeg/libavcodec/vdpau_mpeg4.c index cb8ee0a..282796e 100644 --- a/ffmpeg/libavcodec/vdpau_mpeg4.c +++ b/ffmpeg/libavcodec/vdpau_mpeg4.c @@ -24,15 +24,18 @@ #include #include "avcodec.h" +#include "mpeg4video.h" #include "vdpau.h" #include "vdpau_internal.h" static int vdpau_mpeg4_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { - MpegEncContext * const s = avctx->priv_data; - AVVDPAUContext *hwctx = avctx->hwaccel_context; - VdpPictureInfoMPEG4Part2 *info = &hwctx->info.mpeg4; + Mpeg4DecContext *ctx = avctx->priv_data; + MpegEncContext * const s = &ctx->m; + Picture *pic = s->current_picture_ptr; + struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private; + VdpPictureInfoMPEG4Part2 *info = &pic_ctx->info.mpeg4; VdpVideoSurface ref; int i; @@ -61,7 +64,7 @@ static int vdpau_mpeg4_start_frame(AVCodecContext *avctx, info->vop_time_increment_resolution = s->avctx->time_base.den; info->vop_fcode_forward = s->f_code; info->vop_fcode_backward = s->b_code; - info->resync_marker_disable = !s->resync_marker; + info->resync_marker_disable = !ctx->resync_marker; info->interlaced = !s->progressive_sequence; info->quant_type = s->mpeg_quant; info->quarter_sample = s->quarter_sample; @@ -74,8 +77,8 @@ static int vdpau_mpeg4_start_frame(AVCodecContext *avctx, info->non_intra_quantizer_matrix[i] = s->inter_matrix[i]; } - ff_vdpau_common_start_frame(avctx, buffer, size); - return ff_vdpau_add_buffer(avctx, buffer, size); + ff_vdpau_common_start_frame(pic, buffer, size); + return ff_vdpau_add_buffer(pic, buffer, size); } static int vdpau_mpeg4_decode_slice(av_unused AVCodecContext *avctx, @@ -94,6 +97,7 @@ AVHWAccel ff_h263_vdpau_hwaccel = { .start_frame = vdpau_mpeg4_start_frame, .end_frame = ff_vdpau_mpeg_end_frame, .decode_slice = vdpau_mpeg4_decode_slice, + .priv_data_size = sizeof(struct vdpau_picture_context), }; #endif @@ -106,5 +110,6 @@ AVHWAccel ff_mpeg4_vdpau_hwaccel = { .start_frame = vdpau_mpeg4_start_frame, .end_frame = ff_vdpau_mpeg_end_frame, .decode_slice = vdpau_mpeg4_decode_slice, + .priv_data_size = sizeof(struct vdpau_picture_context), }; #endif diff --git a/ffmpeg/libavcodec/vdpau_vc1.c b/ffmpeg/libavcodec/vdpau_vc1.c index f5da9bb..c655529 100644 --- a/ffmpeg/libavcodec/vdpau_vc1.c +++ b/ffmpeg/libavcodec/vdpau_vc1.c @@ -32,9 +32,10 @@ static int vdpau_vc1_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { VC1Context * const v = avctx->priv_data; - AVVDPAUContext *hwctx = avctx->hwaccel_context; MpegEncContext * const s = &v->s; - VdpPictureInfoVC1 *info = &hwctx->info.vc1; + Picture *pic = s->current_picture_ptr; + struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private; + VdpPictureInfoVC1 *info = &pic_ctx->info.vc1; VdpVideoSurface ref; /* fill LvPictureInfoVC1 struct */ @@ -43,14 +44,18 @@ static int vdpau_vc1_start_frame(AVCodecContext *avctx, switch (s->pict_type) { case AV_PICTURE_TYPE_B: + if (s->next_picture_ptr) { ref = ff_vdpau_get_surface_id(&s->next_picture); assert(ref != VDP_INVALID_HANDLE); info->backward_reference = ref; + } /* fall-through */ case AV_PICTURE_TYPE_P: + if (s->last_picture_ptr) { ref = ff_vdpau_get_surface_id(&s->last_picture); assert(ref != VDP_INVALID_HANDLE); info->forward_reference = ref; + } } info->slice_count = 0; @@ -59,7 +64,7 @@ static int vdpau_vc1_start_frame(AVCodecContext *avctx, else info->picture_type = s->pict_type - 1 + s->pict_type / 3; - info->frame_coding_mode = v->fcm; + info->frame_coding_mode = v->fcm ? (v->fcm + 1) : 0; info->postprocflag = v->postprocflag; info->pulldown = v->broadcast; info->interlace = v->interlace; @@ -82,26 +87,29 @@ static int vdpau_vc1_start_frame(AVCodecContext *avctx, info->range_mapuv = v->range_mapuv; /* Specific to simple/main profile only */ info->multires = v->multires; - info->syncmarker = v->s.resync_marker; + info->syncmarker = v->resync_marker; info->rangered = v->rangered | (v->rangeredfrm << 1); info->maxbframes = v->s.max_b_frames; info->deblockEnable = v->postprocflag & 1; info->pquant = v->pq; - return ff_vdpau_common_start_frame(avctx, buffer, size); + return ff_vdpau_common_start_frame(pic, buffer, size); } static int vdpau_vc1_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { - AVVDPAUContext *hwctx = avctx->hwaccel_context; + VC1Context * const v = avctx->priv_data; + MpegEncContext * const s = &v->s; + Picture *pic = s->current_picture_ptr; + struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private; int val; - val = ff_vdpau_add_buffer(avctx, buffer, size); + val = ff_vdpau_add_buffer(pic, buffer, size); if (val < 0) return val; - hwctx->info.vc1.slice_count++; + pic_ctx->info.vc1.slice_count++; return 0; } @@ -114,6 +122,7 @@ AVHWAccel ff_wmv3_vdpau_hwaccel = { .start_frame = vdpau_vc1_start_frame, .end_frame = ff_vdpau_mpeg_end_frame, .decode_slice = vdpau_vc1_decode_slice, + .priv_data_size = sizeof(struct vdpau_picture_context), }; #endif @@ -125,4 +134,5 @@ AVHWAccel ff_vc1_vdpau_hwaccel = { .start_frame = vdpau_vc1_start_frame, .end_frame = ff_vdpau_mpeg_end_frame, .decode_slice = vdpau_vc1_decode_slice, + .priv_data_size = sizeof(struct vdpau_picture_context), }; diff --git a/ffmpeg/libavcodec/version.h b/ffmpeg/libavcodec/version.h index 5cf07bc..06af735 100644 --- a/ffmpeg/libavcodec/version.h +++ b/ffmpeg/libavcodec/version.h @@ -26,10 +26,10 @@ * Libavcodec version macros. */ -#include "libavutil/avutil.h" +#include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 55 -#define LIBAVCODEC_VERSION_MINOR 1 +#define LIBAVCODEC_VERSION_MINOR 46 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ @@ -51,19 +51,9 @@ #ifndef FF_API_REQUEST_CHANNELS #define FF_API_REQUEST_CHANNELS (LIBAVCODEC_VERSION_MAJOR < 56) #endif -#ifndef FF_API_ALLOC_CONTEXT -#define FF_API_ALLOC_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 55) -#endif -#ifndef FF_API_AVCODEC_OPEN -#define FF_API_AVCODEC_OPEN (LIBAVCODEC_VERSION_MAJOR < 55) -#endif #ifndef FF_API_OLD_DECODE_AUDIO #define FF_API_OLD_DECODE_AUDIO (LIBAVCODEC_VERSION_MAJOR < 56) #endif -#ifndef FF_API_OLD_TIMECODE -#define FF_API_OLD_TIMECODE (LIBAVCODEC_VERSION_MAJOR < 55) -#endif - #ifndef FF_API_OLD_ENCODE_AUDIO #define FF_API_OLD_ENCODE_AUDIO (LIBAVCODEC_VERSION_MAJOR < 56) #endif @@ -73,8 +63,11 @@ #ifndef FF_API_CODEC_ID #define FF_API_CODEC_ID (LIBAVCODEC_VERSION_MAJOR < 56) #endif +#ifndef FF_API_AUDIO_CONVERT +#define FF_API_AUDIO_CONVERT (LIBAVCODEC_VERSION_MAJOR < 56) +#endif #ifndef FF_API_AVCODEC_RESAMPLE -#define FF_API_AVCODEC_RESAMPLE (LIBAVCODEC_VERSION_MAJOR < 56) +#define FF_API_AVCODEC_RESAMPLE FF_API_AUDIO_CONVERT #endif #ifndef FF_API_DEINTERLACE #define FF_API_DEINTERLACE (LIBAVCODEC_VERSION_MAJOR < 56) @@ -88,5 +81,62 @@ #ifndef FF_API_MISSING_SAMPLE #define FF_API_MISSING_SAMPLE (LIBAVCODEC_VERSION_MAJOR < 56) #endif +#ifndef FF_API_LOWRES +#define FF_API_LOWRES (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_CAP_VDPAU +#define FF_API_CAP_VDPAU (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_BUFS_VDPAU +#define FF_API_BUFS_VDPAU (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_VOXWARE +#define FF_API_VOXWARE (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_SET_DIMENSIONS +#define FF_API_SET_DIMENSIONS (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_DEBUG_MV +#define FF_API_DEBUG_MV (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_AC_VLC +#define FF_API_AC_VLC (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_OLD_MSMPEG4 +#define FF_API_OLD_MSMPEG4 (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_ASPECT_EXTENDED +#define FF_API_ASPECT_EXTENDED (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_THREAD_OPAQUE +#define FF_API_THREAD_OPAQUE (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_CODEC_PKT +#define FF_API_CODEC_PKT (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_ARCH_ALPHA +#define FF_API_ARCH_ALPHA (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_XVMC +#define FF_API_XVMC (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_ERROR_RATE +#define FF_API_ERROR_RATE (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_QSCALE_TYPE +#define FF_API_QSCALE_TYPE (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_MB_TYPE +#define FF_API_MB_TYPE (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_MAX_BFRAMES +#define FF_API_MAX_BFRAMES (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_FAST_MALLOC +#define FF_API_FAST_MALLOC (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_NEG_LINESIZES +#define FF_API_NEG_LINESIZES (LIBAVCODEC_VERSION_MAJOR < 56) +#endif #endif /* AVCODEC_VERSION_H */ diff --git a/ffmpeg/libavcodec/videodsp.c b/ffmpeg/libavcodec/videodsp.c index f91bac3..13e4a7b 100644 --- a/ffmpeg/libavcodec/videodsp.c +++ b/ffmpeg/libavcodec/videodsp.c @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/attributes.h" #include "libavutil/avassert.h" #include "libavutil/common.h" #include "videodsp.h" @@ -34,7 +35,7 @@ static void just_return(uint8_t *buf, ptrdiff_t stride, int h) { } -void ff_videodsp_init(VideoDSPContext *ctx, int bpc) +av_cold void ff_videodsp_init(VideoDSPContext *ctx, int bpc) { ctx->prefetch = just_return; if (bpc <= 8) { diff --git a/ffmpeg/libavcodec/videodsp.h b/ffmpeg/libavcodec/videodsp.h index e397720..0bb15f2 100644 --- a/ffmpeg/libavcodec/videodsp.h +++ b/ffmpeg/libavcodec/videodsp.h @@ -30,9 +30,10 @@ #include #define EMULATED_EDGE(depth) \ -void ff_emulated_edge_mc_ ## depth (uint8_t *buf, const uint8_t *src, ptrdiff_t linesize,\ - int block_w, int block_h,\ - int src_x, int src_y, int w, int h); +void ff_emulated_edge_mc_ ## depth(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t dst_stride, ptrdiff_t src_stride, \ + int block_w, int block_h,\ + int src_x, int src_y, int w, int h); EMULATED_EDGE(8) EMULATED_EDGE(16) @@ -42,10 +43,14 @@ typedef struct VideoDSPContext { * Copy a rectangular area of samples to a temporary buffer and replicate * the border samples. * - * @param buf destination buffer + * @param dst destination buffer + * @param dst_stride number of bytes between 2 vertically adjacent samples + * in destination buffer * @param src source buffer - * @param linesize number of bytes between 2 vertically adjacent samples - * in both the source and destination buffers + * @param dst_linesize number of bytes between 2 vertically adjacent + * samples in the destination buffer + * @param src_linesize number of bytes between 2 vertically adjacent + * samples in both the source buffer * @param block_w width of block * @param block_h height of block * @param src_x x coordinate of the top left sample of the block in the @@ -55,16 +60,18 @@ typedef struct VideoDSPContext { * @param w width of the source buffer * @param h height of the source buffer */ - void (*emulated_edge_mc)(uint8_t *buf, const uint8_t *src, - ptrdiff_t linesize, int block_w, int block_h, + void (*emulated_edge_mc)(uint8_t *dst, const uint8_t *src, + ptrdiff_t dst_linesize, + ptrdiff_t src_linesize, + int block_w, int block_h, int src_x, int src_y, int w, int h); /** * Prefetch memory into cache (if supported by hardware). * - * @buf pointer to buffer to prefetch memory from - * @stride distance between two lines of buf (in bytes) - * @h number of lines to prefetch + * @param buf pointer to buffer to prefetch memory from + * @param stride distance between two lines of buf (in bytes) + * @param h number of lines to prefetch */ void (*prefetch)(uint8_t *buf, ptrdiff_t stride, int h); } VideoDSPContext; diff --git a/ffmpeg/libavcodec/videodsp_template.c b/ffmpeg/libavcodec/videodsp_template.c index 44f6a4d..c569c30 100644 --- a/ffmpeg/libavcodec/videodsp_template.c +++ b/ffmpeg/libavcodec/videodsp_template.c @@ -21,24 +21,24 @@ #include "bit_depth_template.c" void FUNC(ff_emulated_edge_mc)(uint8_t *buf, const uint8_t *src, - ptrdiff_t linesize_arg, - int block_w, int block_h, - int src_x, int src_y, int w, int h) + ptrdiff_t buf_linesize, + ptrdiff_t src_linesize, + int block_w, int block_h, + int src_x, int src_y, int w, int h) { int x, y; int start_y, start_x, end_y, end_x; - int linesize = linesize_arg; if (!w || !h) return; if (src_y >= h) { - src -= src_y * linesize; - src += (h - 1) * linesize; + src -= src_y * src_linesize; + src += (h - 1) * src_linesize; src_y = h - 1; } else if (src_y <= -block_h) { - src -= src_y * linesize; - src += (1 - block_h) * linesize; + src -= src_y * src_linesize; + src += (1 - block_h) * src_linesize; src_y = 1 - block_h; } if (src_x >= w) { @@ -57,30 +57,30 @@ void FUNC(ff_emulated_edge_mc)(uint8_t *buf, const uint8_t *src, av_assert2(start_x < end_x && block_w); w = end_x - start_x; - src += start_y * linesize + start_x * sizeof(pixel); + src += start_y * src_linesize + start_x * sizeof(pixel); buf += start_x * sizeof(pixel); // top for (y = 0; y < start_y; y++) { memcpy(buf, src, w * sizeof(pixel)); - buf += linesize; + buf += buf_linesize; } // copy existing part for (; y < end_y; y++) { memcpy(buf, src, w * sizeof(pixel)); - src += linesize; - buf += linesize; + src += src_linesize; + buf += buf_linesize; } // bottom - src -= linesize; + src -= src_linesize; for (; y < block_h; y++) { memcpy(buf, src, w * sizeof(pixel)); - buf += linesize; + buf += buf_linesize; } - buf -= block_h * linesize + start_x * sizeof(pixel); + buf -= block_h * buf_linesize + start_x * sizeof(pixel); while (block_h--) { pixel *bufp = (pixel *) buf; @@ -93,6 +93,6 @@ void FUNC(ff_emulated_edge_mc)(uint8_t *buf, const uint8_t *src, for (x = end_x; x < block_w; x++) { bufp[x] = bufp[end_x - 1]; } - buf += linesize; + buf += buf_linesize; } } diff --git a/ffmpeg/libavcodec/vima.c b/ffmpeg/libavcodec/vima.c index 705839e..f040e1b 100644 --- a/ffmpeg/libavcodec/vima.c +++ b/ffmpeg/libavcodec/vima.c @@ -19,15 +19,20 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +/** + * @file + * LucasArts VIMA audio decoder + * @author Paul B Mahol + */ + #include "libavutil/channel_layout.h" #include "avcodec.h" #include "get_bits.h" #include "internal.h" #include "adpcm_data.h" -typedef struct { - uint16_t predict_table[5786 * 2]; -} VimaContext; +static int predict_table_init = 0; +static uint16_t predict_table[5786 * 2]; static const uint8_t size_table[] = { @@ -103,8 +108,12 @@ static const int8_t* const step_index_tables[] = static av_cold int decode_init(AVCodecContext *avctx) { - VimaContext *vima = avctx->priv_data; - int start_pos; + int start_pos; + + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + + if (predict_table_init) + return 0; for (start_pos = 0; start_pos < 64; start_pos++) { unsigned int dest_pos, table_pos; @@ -120,11 +129,10 @@ static av_cold int decode_init(AVCodecContext *avctx) put += table_value; table_value >>= 1; } - vima->predict_table[dest_pos] = put; + predict_table[dest_pos] = put; } } - - avctx->sample_fmt = AV_SAMPLE_FMT_S16; + predict_table_init = 1; return 0; } @@ -133,7 +141,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *pkt) { GetBitContext gb; - VimaContext *vima = avctx->priv_data; AVFrame *frame = data; int16_t pcm_data[2]; uint32_t samples; @@ -200,7 +207,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, predict_index = (lookup << (7 - lookup_size)) | (step_index << 6); predict_index = av_clip(predict_index, 0, 5785); - diff = vima->predict_table[predict_index]; + diff = predict_table[predict_index]; if (lookup) diff += ff_adpcm_step_table[step_index] >> (lookup_size - 1); if (highbit) @@ -223,11 +230,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, AVCodec ff_vima_decoder = { .name = "vima", + .long_name = NULL_IF_CONFIG_SMALL("LucasArts VIMA audio"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_VIMA, - .priv_data_size = sizeof(VimaContext), .init = decode_init, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("LucasArts VIMA audio"), }; diff --git a/ffmpeg/libavcodec/vmdav.c b/ffmpeg/libavcodec/vmdav.c index 0e27ef6..c1fb80b 100644 --- a/ffmpeg/libavcodec/vmdav.c +++ b/ffmpeg/libavcodec/vmdav.c @@ -43,11 +43,13 @@ #include #include +#include "libavutil/avassert.h" #include "libavutil/channel_layout.h" #include "libavutil/common.h" #include "libavutil/intreadwrite.h" #include "avcodec.h" #include "internal.h" +#include "bytestream.h" #define VMD_HEADER_SIZE 0x330 #define PALETTE_COUNT 256 @@ -59,7 +61,7 @@ typedef struct VmdVideoContext { AVCodecContext *avctx; - AVFrame prev_frame; + AVFrame *prev_frame; const unsigned char *buf; int size; @@ -74,11 +76,9 @@ typedef struct VmdVideoContext { #define QUEUE_SIZE 0x1000 #define QUEUE_MASK 0x0FFF -static void lz_unpack(const unsigned char *src, int src_len, +static int lz_unpack(const unsigned char *src, int src_len, unsigned char *dest, int dest_len) { - const unsigned char *s; - const unsigned char *s_end; unsigned char *d; unsigned char *d_end; unsigned char queue[QUEUE_SIZE]; @@ -89,19 +89,17 @@ static void lz_unpack(const unsigned char *src, int src_len, unsigned int speclen; unsigned char tag; unsigned int i, j; + GetByteContext gb; - s = src; - s_end = src + src_len; + bytestream2_init(&gb, src, src_len); d = dest; d_end = d + dest_len; - - if (s_end - s < 8) - return; - dataleft = AV_RL32(s); - s += 4; + dataleft = bytestream2_get_le32(&gb); memset(queue, 0x20, QUEUE_SIZE); - if (AV_RL32(s) == 0x56781234) { - s += 4; + if (bytestream2_get_bytes_left(&gb) < 4) + return AVERROR_INVALIDDATA; + if (bytestream2_peek_le32(&gb) == 0x56781234) { + bytestream2_skipu(&gb, 4); qpos = 0x111; speclen = 0xF + 3; } else { @@ -109,13 +107,13 @@ static void lz_unpack(const unsigned char *src, int src_len, speclen = 100; /* no speclen */ } - while (s_end - s > 0 && dataleft > 0) { - tag = *s++; + while (dataleft > 0 && bytestream2_get_bytes_left(&gb) > 0) { + tag = bytestream2_get_byteu(&gb); if ((tag == 0xFF) && (dataleft > 8)) { - if (d_end - d < 8 || s_end - s < 8) - return; + if (d_end - d < 8 || bytestream2_get_bytes_left(&gb) < 8) + return AVERROR_INVALIDDATA; for (i = 0; i < 8; i++) { - queue[qpos++] = *d++ = *s++; + queue[qpos++] = *d++ = bytestream2_get_byteu(&gb); qpos &= QUEUE_MASK; } dataleft -= 8; @@ -124,24 +122,20 @@ static void lz_unpack(const unsigned char *src, int src_len, if (dataleft == 0) break; if (tag & 0x01) { - if (d_end - d < 1 || s_end - s < 1) - return; - queue[qpos++] = *d++ = *s++; + if (d_end - d < 1 || bytestream2_get_bytes_left(&gb) < 1) + return AVERROR_INVALIDDATA; + queue[qpos++] = *d++ = bytestream2_get_byteu(&gb); qpos &= QUEUE_MASK; dataleft--; } else { - if (s_end - s < 2) - return; - chainofs = *s++; - chainofs |= ((*s & 0xF0) << 4); - chainlen = (*s++ & 0x0F) + 3; + chainofs = bytestream2_get_byte(&gb); + chainofs |= ((bytestream2_peek_byte(&gb) & 0xF0) << 4); + chainlen = (bytestream2_get_byte(&gb) & 0x0F) + 3; if (chainlen == speclen) { - if (s_end - s < 1) - return; - chainlen = *s++ + 0xF + 3; + chainlen = bytestream2_get_byte(&gb) + 0xF + 3; } if (d_end - d < chainlen) - return; + return AVERROR_INVALIDDATA; for (j = 0; j < chainlen; j++) { *d = queue[chainofs++ & QUEUE_MASK]; queue[qpos++] = *d++; @@ -153,66 +147,60 @@ static void lz_unpack(const unsigned char *src, int src_len, } } } + return d - dest; } - -static int rle_unpack(const unsigned char *src, int src_len, int src_count, - unsigned char *dest, int dest_len) +static int rle_unpack(const unsigned char *src, unsigned char *dest, + int src_count, int src_size, int dest_len) { - const unsigned char *ps; - const unsigned char *ps_end; unsigned char *pd; - int i, l; + int i, l, used = 0; unsigned char *dest_end = dest + dest_len; + GetByteContext gb; + uint16_t run_val; - ps = src; - ps_end = src + src_len; + bytestream2_init(&gb, src, src_size); pd = dest; if (src_count & 1) { - if (ps_end - ps < 1) + if (bytestream2_get_bytes_left(&gb) < 1) return 0; - *pd++ = *ps++; + *pd++ = bytestream2_get_byteu(&gb); + used++; } - src_count >>= 1; - i = 0; do { - if (ps_end - ps < 1) + if (bytestream2_get_bytes_left(&gb) < 1) break; - l = *ps++; + l = bytestream2_get_byteu(&gb); if (l & 0x80) { l = (l & 0x7F) * 2; - if (dest_end - pd < l || ps_end - ps < l) - return ps - src; - memcpy(pd, ps, l); - ps += l; + if (dest_end - pd < l || bytestream2_get_bytes_left(&gb) < l) + return bytestream2_tell(&gb); + bytestream2_get_bufferu(&gb, pd, l); pd += l; } else { - if (dest_end - pd < i || ps_end - ps < 2) - return ps - src; + if (dest_end - pd < 2*l || bytestream2_get_bytes_left(&gb) < 2) + return bytestream2_tell(&gb); + run_val = bytestream2_get_ne16(&gb); for (i = 0; i < l; i++) { - *pd++ = ps[0]; - *pd++ = ps[1]; + AV_WN16(pd, run_val); + pd += 2; } - ps += 2; + l *= 2; } - i += l; - } while (i < src_count); + used += l; + } while (used < src_count); - return ps - src; + return bytestream2_tell(&gb); } -static void vmd_decode(VmdVideoContext *s, AVFrame *frame) +static int vmd_decode(VmdVideoContext *s, AVFrame *frame) { int i; unsigned int *palette32; unsigned char r, g, b; - /* point to the start of the encoded data */ - const unsigned char *p = s->buf + 16; - const unsigned char *p_end = s->buf + s->size; + GetByteContext gb; - const unsigned char *pb; - const unsigned char *pb_end; unsigned char meth; unsigned char *dp; /* pointer to current frame */ unsigned char *pp; /* pointer to previous frame */ @@ -226,16 +214,6 @@ static void vmd_decode(VmdVideoContext *s, AVFrame *frame) frame_y = AV_RL16(&s->buf[8]); frame_width = AV_RL16(&s->buf[10]) - frame_x + 1; frame_height = AV_RL16(&s->buf[12]) - frame_y + 1; - if (frame_x < 0 || frame_width < 0 || - frame_x >= s->avctx->width || - frame_width > s->avctx->width || - frame_x + frame_width > s->avctx->width) - return; - if (frame_y < 0 || frame_height < 0 || - frame_y >= s->avctx->height || - frame_height > s->avctx->height || - frame_y + frame_height > s->avctx->height) - return; if ((frame_width == s->avctx->width && frame_height == s->avctx->height) && (frame_x || frame_y)) { @@ -246,126 +224,168 @@ static void vmd_decode(VmdVideoContext *s, AVFrame *frame) frame_x -= s->x_off; frame_y -= s->y_off; + if (frame_x < 0 || frame_width < 0 || + frame_x >= s->avctx->width || + frame_width > s->avctx->width || + frame_x + frame_width > s->avctx->width) { + av_log(s->avctx, AV_LOG_ERROR, + "Invalid horizontal range %d-%d\n", + frame_x, frame_width); + return AVERROR_INVALIDDATA; + } + if (frame_y < 0 || frame_height < 0 || + frame_y >= s->avctx->height || + frame_height > s->avctx->height || + frame_y + frame_height > s->avctx->height) { + av_log(s->avctx, AV_LOG_ERROR, + "Invalid vertical range %d-%d\n", + frame_x, frame_width); + return AVERROR_INVALIDDATA; + } + /* if only a certain region will be updated, copy the entire previous * frame before the decode */ - if (s->prev_frame.data[0] && + if (s->prev_frame->data[0] && (frame_x || frame_y || (frame_width != s->avctx->width) || (frame_height != s->avctx->height))) { - memcpy(frame->data[0], s->prev_frame.data[0], + memcpy(frame->data[0], s->prev_frame->data[0], s->avctx->height * frame->linesize[0]); } /* check if there is a new palette */ + bytestream2_init(&gb, s->buf + 16, s->size - 16); if (s->buf[15] & 0x02) { - if (p_end - p < 2 + 3 * PALETTE_COUNT) - return; - p += 2; + bytestream2_skip(&gb, 2); palette32 = (unsigned int *)s->palette; - for (i = 0; i < PALETTE_COUNT; i++) { - r = *p++ * 4; - g = *p++ * 4; - b = *p++ * 4; - palette32[i] = 0xFFU << 24 | r << 16 | g << 8 | b; - palette32[i] |= palette32[i] >> 6 & 0x30303; + if (bytestream2_get_bytes_left(&gb) >= PALETTE_COUNT * 3) { + for (i = 0; i < PALETTE_COUNT; i++) { + r = bytestream2_get_byteu(&gb) * 4; + g = bytestream2_get_byteu(&gb) * 4; + b = bytestream2_get_byteu(&gb) * 4; + palette32[i] = 0xFFU << 24 | (r << 16) | (g << 8) | (b); + palette32[i] |= palette32[i] >> 6 & 0x30303; + } + } else { + av_log(s->avctx, AV_LOG_ERROR, "Incomplete palette\n"); + return AVERROR_INVALIDDATA; } } - if (p < p_end) { - /* originally UnpackFrame in VAG's code */ - pb = p; - pb_end = p_end; - meth = *pb++; - if (meth & 0x80) { - lz_unpack(pb, p_end - pb, s->unpack_buffer, s->unpack_buffer_size); - meth &= 0x7F; - pb = s->unpack_buffer; - pb_end = s->unpack_buffer + s->unpack_buffer_size; + + if (!s->size) + return 0; + + /* originally UnpackFrame in VAG's code */ + if (bytestream2_get_bytes_left(&gb) < 1) + return AVERROR_INVALIDDATA; + meth = bytestream2_get_byteu(&gb); + if (meth & 0x80) { + int size; + if (!s->unpack_buffer_size) { + av_log(s->avctx, AV_LOG_ERROR, + "Trying to unpack LZ-compressed frame with no LZ buffer\n"); + return AVERROR_INVALIDDATA; } + size = lz_unpack(gb.buffer, bytestream2_get_bytes_left(&gb), + s->unpack_buffer, s->unpack_buffer_size); + if (size < 0) + return size; + meth &= 0x7F; + bytestream2_init(&gb, s->unpack_buffer, size); + } - dp = &frame->data[0][frame_y * frame->linesize[0] + frame_x]; - pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x]; - switch (meth) { - case 1: - for (i = 0; i < frame_height; i++) { - ofs = 0; - do { - if (pb_end - pb < 1) - return; - len = *pb++; - if (len & 0x80) { - len = (len & 0x7F) + 1; - if (ofs + len > frame_width || pb_end - pb < len) - return; - memcpy(&dp[ofs], pb, len); - pb += len; - ofs += len; - } else { - /* interframe pixel copy */ - if (ofs + len + 1 > frame_width || !s->prev_frame.data[0]) - return; - memcpy(&dp[ofs], &pp[ofs], len + 1); - ofs += len + 1; - } - } while (ofs < frame_width); - if (ofs > frame_width) { - av_log(s->avctx, AV_LOG_ERROR, "offset > width (%d > %d)\n", - ofs, frame_width); - break; + dp = &frame->data[0][frame_y * frame->linesize[0] + frame_x]; + pp = &s->prev_frame->data[0][frame_y * s->prev_frame->linesize[0] + frame_x]; + switch (meth) { + case 1: + for (i = 0; i < frame_height; i++) { + ofs = 0; + do { + len = bytestream2_get_byte(&gb); + if (len & 0x80) { + len = (len & 0x7F) + 1; + if (ofs + len > frame_width || + bytestream2_get_bytes_left(&gb) < len) + return AVERROR_INVALIDDATA; + bytestream2_get_bufferu(&gb, &dp[ofs], len); + ofs += len; + } else { + /* interframe pixel copy */ + if (ofs + len + 1 > frame_width || !s->prev_frame->data[0]) + return AVERROR_INVALIDDATA; + memcpy(&dp[ofs], &pp[ofs], len + 1); + ofs += len + 1; } - dp += frame->linesize[0]; - pp += s->prev_frame.linesize[0]; - } - break; - - case 2: - for (i = 0; i < frame_height; i++) { - if (pb_end -pb < frame_width) - return; - memcpy(dp, pb, frame_width); - pb += frame_width; - dp += frame->linesize[0]; - pp += s->prev_frame.linesize[0]; + } while (ofs < frame_width); + if (ofs > frame_width) { + av_log(s->avctx, AV_LOG_ERROR, + "offset > width (%d > %d)\n", + ofs, frame_width); + return AVERROR_INVALIDDATA; } - break; + dp += frame->linesize[0]; + pp += s->prev_frame->linesize[0]; + } + break; - case 3: - for (i = 0; i < frame_height; i++) { - ofs = 0; - do { - if (pb_end - pb < 1) - return; - len = *pb++; - if (len & 0x80) { - len = (len & 0x7F) + 1; - if (pb_end - pb < 1) - return; - if (*pb++ == 0xFF) - len = rle_unpack(pb, pb_end - pb, len, &dp[ofs], frame_width - ofs); - else { - if (pb_end - pb < len) - return; - memcpy(&dp[ofs], pb, len); - } - pb += len; - ofs += len; + case 2: + for (i = 0; i < frame_height; i++) { + bytestream2_get_buffer(&gb, dp, frame_width); + dp += frame->linesize[0]; + pp += s->prev_frame->linesize[0]; + } + break; + + case 3: + for (i = 0; i < frame_height; i++) { + ofs = 0; + do { + len = bytestream2_get_byte(&gb); + if (len & 0x80) { + len = (len & 0x7F) + 1; + if (bytestream2_peek_byte(&gb) == 0xFF) { + int slen = len; + bytestream2_get_byte(&gb); + len = rle_unpack(gb.buffer, &dp[ofs], + len, bytestream2_get_bytes_left(&gb), + frame_width - ofs); + ofs += slen; + bytestream2_skip(&gb, len); } else { - /* interframe pixel copy */ - if (ofs + len + 1 > frame_width || !s->prev_frame.data[0]) - return; - memcpy(&dp[ofs], &pp[ofs], len + 1); - ofs += len + 1; + bytestream2_get_buffer(&gb, &dp[ofs], len); + ofs += len; } - } while (ofs < frame_width); - if (ofs > frame_width) { - av_log(s->avctx, AV_LOG_ERROR, "offset > width (%d > %d)\n", - ofs, frame_width); + } else { + /* interframe pixel copy */ + if (ofs + len + 1 > frame_width || !s->prev_frame->data[0]) + return AVERROR_INVALIDDATA; + memcpy(&dp[ofs], &pp[ofs], len + 1); + ofs += len + 1; } - dp += frame->linesize[0]; - pp += s->prev_frame.linesize[0]; + } while (ofs < frame_width); + if (ofs > frame_width) { + av_log(s->avctx, AV_LOG_ERROR, + "offset > width (%d > %d)\n", + ofs, frame_width); + return AVERROR_INVALIDDATA; } - break; + dp += frame->linesize[0]; + pp += s->prev_frame->linesize[0]; } + break; } + return 0; +} + +static av_cold int vmdvideo_decode_end(AVCodecContext *avctx) +{ + VmdVideoContext *s = avctx->priv_data; + + av_frame_free(&s->prev_frame); + av_freep(&s->unpack_buffer); + s->unpack_buffer_size = 0; + + return 0; } static av_cold int vmdvideo_decode_init(AVCodecContext *avctx) @@ -385,14 +405,16 @@ static av_cold int vmdvideo_decode_init(AVCodecContext *avctx) if (s->avctx->extradata_size != VMD_HEADER_SIZE) { av_log(s->avctx, AV_LOG_ERROR, "expected extradata size of %d\n", VMD_HEADER_SIZE); - return -1; + return AVERROR_INVALIDDATA; } vmd_header = (unsigned char *)avctx->extradata; s->unpack_buffer_size = AV_RL32(&vmd_header[800]); - s->unpack_buffer = av_malloc(s->unpack_buffer_size); - if (!s->unpack_buffer) - return -1; + if (s->unpack_buffer_size) { + s->unpack_buffer = av_malloc(s->unpack_buffer_size); + if (!s->unpack_buffer) + return AVERROR(ENOMEM); + } /* load up the initial palette */ raw_palette = &vmd_header[28]; @@ -401,10 +423,15 @@ static av_cold int vmdvideo_decode_init(AVCodecContext *avctx) r = raw_palette[palette_index++] * 4; g = raw_palette[palette_index++] * 4; b = raw_palette[palette_index++] * 4; - palette32[i] = (r << 16) | (g << 8) | (b); + palette32[i] = 0xFFU << 24 | (r << 16) | (g << 8) | (b); + palette32[i] |= palette32[i] >> 6 & 0x30303; } - avcodec_get_frame_defaults(&s->prev_frame); + s->prev_frame = av_frame_alloc(); + if (!s->prev_frame) { + vmdvideo_decode_end(avctx); + return AVERROR(ENOMEM); + } return 0; } @@ -423,19 +450,20 @@ static int vmdvideo_decode_frame(AVCodecContext *avctx, s->size = buf_size; if (buf_size < 16) - return buf_size; + return AVERROR_INVALIDDATA; if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; - vmd_decode(s, frame); + if ((ret = vmd_decode(s, frame)) < 0) + return ret; /* make the palette available on the way out */ memcpy(frame->data[1], s->palette, PALETTE_COUNT * 4); /* shuffle frames */ - av_frame_unref(&s->prev_frame); - if ((ret = av_frame_ref(&s->prev_frame, frame)) < 0) + av_frame_unref(s->prev_frame); + if ((ret = av_frame_ref(s->prev_frame, frame)) < 0) return ret; *got_frame = 1; @@ -444,17 +472,6 @@ static int vmdvideo_decode_frame(AVCodecContext *avctx, return buf_size; } -static av_cold int vmdvideo_decode_end(AVCodecContext *avctx) -{ - VmdVideoContext *s = avctx->priv_data; - - av_frame_unref(&s->prev_frame); - av_free(s->unpack_buffer); - - return 0; -} - - /* * Audio Decoder */ @@ -592,6 +609,9 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data, /* ensure output buffer is large enough */ audio_chunks = buf_size / s->chunk_size; + /* drop incomplete chunks */ + buf_size = audio_chunks * s->chunk_size; + /* get output buffer */ frame->nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) / avctx->channels; @@ -603,6 +623,8 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data, /* decode silent chunks */ if (silent_chunks > 0) { int silent_size = avctx->block_align * silent_chunks; + av_assert0(avctx->block_align * silent_chunks <= frame->nb_samples * avctx->channels); + if (s->out_bps == 2) { memset(output_samples_s16, 0x00, silent_size * 2); output_samples_s16 += silent_size; @@ -615,6 +637,7 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data, /* decode audio chunks */ if (audio_chunks > 0) { buf_end = buf + buf_size; + av_assert0((buf_size & (avctx->channels > 1)) == 0); while (buf_end - buf >= s->chunk_size) { if (s->out_bps == 2) { decode_audio_s16(output_samples_s16, buf, s->chunk_size, @@ -640,6 +663,7 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data, AVCodec ff_vmdvideo_decoder = { .name = "vmdvideo", + .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VMDVIDEO, .priv_data_size = sizeof(VmdVideoContext), @@ -647,16 +671,15 @@ AVCodec ff_vmdvideo_decoder = { .close = vmdvideo_decode_end, .decode = vmdvideo_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"), }; AVCodec ff_vmdaudio_decoder = { .name = "vmdaudio", + .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_VMDAUDIO, .priv_data_size = sizeof(VmdAudioContext), .init = vmdaudio_decode_init, .decode = vmdaudio_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"), }; diff --git a/ffmpeg/libavcodec/vmnc.c b/ffmpeg/libavcodec/vmnc.c index 99571a1..5f91ab1 100644 --- a/ffmpeg/libavcodec/vmnc.c +++ b/ffmpeg/libavcodec/vmnc.c @@ -32,6 +32,7 @@ #include "libavutil/intreadwrite.h" #include "avcodec.h" #include "internal.h" +#include "bytestream.h" enum EncTypes { MAGIC_WMVd = 0x574D5664, @@ -56,62 +57,73 @@ enum HexTile_Flags { */ typedef struct VmncContext { AVCodecContext *avctx; - AVFrame pic; + AVFrame *pic; int bpp; int bpp2; int bigendian; uint8_t pal[768]; int width, height; + GetByteContext gb; /* cursor data */ int cur_w, cur_h; int cur_x, cur_y; int cur_hx, cur_hy; - uint8_t* curbits, *curmask; - uint8_t* screendta; + uint8_t *curbits, *curmask; + uint8_t *screendta; } VmncContext; /* read pixel value from stream */ -static av_always_inline int vmnc_get_pixel(const uint8_t* buf, int bpp, int be) { - switch(bpp * 2 + be) { +static av_always_inline int vmnc_get_pixel(GetByteContext *gb, int bpp, int be) +{ + switch (bpp * 2 + be) { case 2: - case 3: return *buf; - case 4: return AV_RL16(buf); - case 5: return AV_RB16(buf); - case 8: return AV_RL32(buf); - case 9: return AV_RB32(buf); + case 3: + return bytestream2_get_byte(gb); + case 4: + return bytestream2_get_le16(gb); + case 5: + return bytestream2_get_be16(gb); + case 8: + return bytestream2_get_le32(gb); + case 9: + return bytestream2_get_be32(gb); default: return 0; } } -static void load_cursor(VmncContext *c, const uint8_t *src) +static void load_cursor(VmncContext *c) { int i, j, p; - const int bpp = c->bpp2; - uint8_t *dst8 = c->curbits; - uint16_t *dst16 = (uint16_t*)c->curbits; - uint32_t *dst32 = (uint32_t*)c->curbits; - - for(j = 0; j < c->cur_h; j++) { - for(i = 0; i < c->cur_w; i++) { - p = vmnc_get_pixel(src, bpp, c->bigendian); - src += bpp; - if(bpp == 1) *dst8++ = p; - if(bpp == 2) *dst16++ = p; - if(bpp == 4) *dst32++ = p; + const int bpp = c->bpp2; + uint8_t *dst8 = c->curbits; + uint16_t *dst16 = (uint16_t *)c->curbits; + uint32_t *dst32 = (uint32_t *)c->curbits; + + for (j = 0; j < c->cur_h; j++) { + for (i = 0; i < c->cur_w; i++) { + p = vmnc_get_pixel(&c->gb, bpp, c->bigendian); + if (bpp == 1) + *dst8++ = p; + if (bpp == 2) + *dst16++ = p; + if (bpp == 4) + *dst32++ = p; } } - dst8 = c->curmask; + dst8 = c->curmask; dst16 = (uint16_t*)c->curmask; dst32 = (uint32_t*)c->curmask; - for(j = 0; j < c->cur_h; j++) { - for(i = 0; i < c->cur_w; i++) { - p = vmnc_get_pixel(src, bpp, c->bigendian); - src += bpp; - if(bpp == 1) *dst8++ = p; - if(bpp == 2) *dst16++ = p; - if(bpp == 4) *dst32++ = p; + for (j = 0; j < c->cur_h; j++) { + for (i = 0; i < c->cur_w; i++) { + p = vmnc_get_pixel(&c->gb, bpp, c->bigendian); + if (bpp == 1) + *dst8++ = p; + if (bpp == 2) + *dst16++ = p; + if (bpp == 4) + *dst32++ = p; } } } @@ -121,96 +133,100 @@ static void put_cursor(uint8_t *dst, int stride, VmncContext *c, int dx, int dy) int i, j; int w, h, x, y; w = c->cur_w; - if(c->width < c->cur_x + c->cur_w) w = c->width - c->cur_x; + if (c->width < c->cur_x + c->cur_w) + w = c->width - c->cur_x; h = c->cur_h; - if(c->height < c->cur_y + c->cur_h) h = c->height - c->cur_y; + if (c->height < c->cur_y + c->cur_h) + h = c->height - c->cur_y; x = c->cur_x; y = c->cur_y; - if(x < 0) { + if (x < 0) { w += x; - x = 0; + x = 0; } - if(y < 0) { + if (y < 0) { h += y; - y = 0; + y = 0; } - if((w < 1) || (h < 1)) return; + if ((w < 1) || (h < 1)) + return; dst += x * c->bpp2 + y * stride; - if(c->bpp2 == 1) { - uint8_t* cd = c->curbits, *msk = c->curmask; - for(j = 0; j < h; j++) { - for(i = 0; i < w; i++) + if (c->bpp2 == 1) { + uint8_t *cd = c->curbits, *msk = c->curmask; + for (j = 0; j < h; j++) { + for (i = 0; i < w; i++) dst[i] = (dst[i] & cd[i]) ^ msk[i]; msk += c->cur_w; - cd += c->cur_w; + cd += c->cur_w; dst += stride; } - } else if(c->bpp2 == 2) { - uint16_t* cd = (uint16_t*)c->curbits, *msk = (uint16_t*)c->curmask; - uint16_t* dst2; - for(j = 0; j < h; j++) { + } else if (c->bpp2 == 2) { + uint16_t *cd = (uint16_t*)c->curbits, *msk = (uint16_t*)c->curmask; + uint16_t *dst2; + for (j = 0; j < h; j++) { dst2 = (uint16_t*)dst; - for(i = 0; i < w; i++) + for (i = 0; i < w; i++) dst2[i] = (dst2[i] & cd[i]) ^ msk[i]; msk += c->cur_w; - cd += c->cur_w; + cd += c->cur_w; dst += stride; } - } else if(c->bpp2 == 4) { - uint32_t* cd = (uint32_t*)c->curbits, *msk = (uint32_t*)c->curmask; - uint32_t* dst2; - for(j = 0; j < h; j++) { + } else if (c->bpp2 == 4) { + uint32_t *cd = (uint32_t*)c->curbits, *msk = (uint32_t*)c->curmask; + uint32_t *dst2; + for (j = 0; j < h; j++) { dst2 = (uint32_t*)dst; - for(i = 0; i < w; i++) + for (i = 0; i < w; i++) dst2[i] = (dst2[i] & cd[i]) ^ msk[i]; msk += c->cur_w; - cd += c->cur_w; + cd += c->cur_w; dst += stride; } } } /* fill rectangle with given color */ -static av_always_inline void paint_rect(uint8_t *dst, int dx, int dy, int w, int h, int color, int bpp, int stride) +static av_always_inline void paint_rect(uint8_t *dst, int dx, int dy, + int w, int h, int color, + int bpp, int stride) { int i, j; dst += dx * bpp + dy * stride; - if(bpp == 1){ - for(j = 0; j < h; j++) { + if (bpp == 1) { + for (j = 0; j < h; j++) { memset(dst, color, w); dst += stride; } - }else if(bpp == 2){ - uint16_t* dst2; - for(j = 0; j < h; j++) { + } else if (bpp == 2) { + uint16_t *dst2; + for (j = 0; j < h; j++) { dst2 = (uint16_t*)dst; - for(i = 0; i < w; i++) { + for (i = 0; i < w; i++) *dst2++ = color; - } dst += stride; } - }else if(bpp == 4){ - uint32_t* dst2; - for(j = 0; j < h; j++) { + } else if (bpp == 4) { + uint32_t *dst2; + for (j = 0; j < h; j++) { dst2 = (uint32_t*)dst; - for(i = 0; i < w; i++) { + for (i = 0; i < w; i++) dst2[i] = color; - } dst += stride; } } } -static av_always_inline void paint_raw(uint8_t *dst, int w, int h, const uint8_t* src, int bpp, int be, int stride) +static av_always_inline void paint_raw(uint8_t *dst, int w, int h, + GetByteContext *gb, int bpp, + int be, int stride) { int i, j, p; - for(j = 0; j < h; j++) { - for(i = 0; i < w; i++) { - p = vmnc_get_pixel(src, bpp, be); - src += bpp; - switch(bpp){ + for (j = 0; j < h; j++) { + for (i = 0; i < w; i++) { + p = vmnc_get_pixel(gb, bpp, be); + switch (bpp) { case 1: dst[i] = p; break; @@ -226,261 +242,290 @@ static av_always_inline void paint_raw(uint8_t *dst, int w, int h, const uint8_t } } -static int decode_hextile(VmncContext *c, uint8_t* dst, const uint8_t* src, int ssize, int w, int h, int stride) +static int decode_hextile(VmncContext *c, uint8_t* dst, GetByteContext *gb, + int w, int h, int stride) { int i, j, k; int bg = 0, fg = 0, rects, color, flags, xy, wh; const int bpp = c->bpp2; uint8_t *dst2; int bw = 16, bh = 16; - const uint8_t *ssrc=src; - for(j = 0; j < h; j += 16) { + for (j = 0; j < h; j += 16) { dst2 = dst; - bw = 16; - if(j + 16 > h) bh = h - j; - for(i = 0; i < w; i += 16, dst2 += 16 * bpp) { - if(src - ssrc >= ssize) { + bw = 16; + if (j + 16 > h) + bh = h - j; + for (i = 0; i < w; i += 16, dst2 += 16 * bpp) { + if (bytestream2_get_bytes_left(gb) <= 0) { av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n"); - return -1; + return AVERROR_INVALIDDATA; } - if(i + 16 > w) bw = w - i; - flags = *src++; - if(flags & HT_RAW) { - if(src - ssrc > ssize - bw * bh * bpp) { + if (i + 16 > w) + bw = w - i; + flags = bytestream2_get_byte(gb); + if (flags & HT_RAW) { + if (bytestream2_get_bytes_left(gb) < bw * bh * bpp) { av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n"); - return -1; + return AVERROR_INVALIDDATA; } - paint_raw(dst2, bw, bh, src, bpp, c->bigendian, stride); - src += bw * bh * bpp; + paint_raw(dst2, bw, bh, gb, bpp, c->bigendian, stride); } else { - if(flags & HT_BKG) { - bg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp; - } - if(flags & HT_FG) { - fg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp; - } + if (flags & HT_BKG) + bg = vmnc_get_pixel(gb, bpp, c->bigendian); + if (flags & HT_FG) + fg = vmnc_get_pixel(gb, bpp, c->bigendian); rects = 0; - if(flags & HT_SUB) - rects = *src++; + if (flags & HT_SUB) + rects = bytestream2_get_byte(gb); color = !!(flags & HT_CLR); paint_rect(dst2, 0, 0, bw, bh, bg, bpp, stride); - if(src - ssrc > ssize - rects * (color * bpp + 2)) { + if (bytestream2_get_bytes_left(gb) < rects * (color * bpp + 2)) { av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n"); - return -1; + return AVERROR_INVALIDDATA; } - for(k = 0; k < rects; k++) { - if(color) { - fg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp; - } - xy = *src++; - wh = *src++; - paint_rect(dst2, xy >> 4, xy & 0xF, (wh>>4)+1, (wh & 0xF)+1, fg, bpp, stride); + for (k = 0; k < rects; k++) { + if (color) + fg = vmnc_get_pixel(gb, bpp, c->bigendian); + xy = bytestream2_get_byte(gb); + wh = bytestream2_get_byte(gb); + paint_rect(dst2, xy >> 4, xy & 0xF, + (wh>>4)+1, (wh & 0xF)+1, fg, bpp, stride); } } } dst += stride * 16; } - return src - ssrc; + return 0; +} + +static void reset_buffers(VmncContext *c) +{ + av_freep(&c->curbits); + av_freep(&c->curmask); + av_freep(&c->screendta); + c->cur_w = c->cur_h = 0; + c->cur_hx = c->cur_hy = 0; + } static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; + int buf_size = avpkt->size; VmncContext * const c = avctx->priv_data; + GetByteContext *gb = &c->gb; uint8_t *outptr; - const uint8_t *src = buf; int dx, dy, w, h, depth, enc, chunks, res, size_left, ret; - if ((ret = ff_reget_buffer(avctx, &c->pic)) < 0) + if ((ret = ff_reget_buffer(avctx, c->pic)) < 0) return ret; - c->pic.key_frame = 0; - c->pic.pict_type = AV_PICTURE_TYPE_P; + bytestream2_init(gb, buf, buf_size); - //restore screen after cursor - if(c->screendta) { + c->pic->key_frame = 0; + c->pic->pict_type = AV_PICTURE_TYPE_P; + + // restore screen after cursor + if (c->screendta) { int i; w = c->cur_w; - if(c->width < c->cur_x + w) w = c->width - c->cur_x; + if (c->width < c->cur_x + w) + w = c->width - c->cur_x; h = c->cur_h; - if(c->height < c->cur_y + h) h = c->height - c->cur_y; + if (c->height < c->cur_y + h) + h = c->height - c->cur_y; dx = c->cur_x; - if(dx < 0) { + if (dx < 0) { w += dx; dx = 0; } dy = c->cur_y; - if(dy < 0) { + if (dy < 0) { h += dy; dy = 0; } - if((w > 0) && (h > 0)) { - outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0]; - for(i = 0; i < h; i++) { - memcpy(outptr, c->screendta + i * c->cur_w * c->bpp2, w * c->bpp2); - outptr += c->pic.linesize[0]; + if ((w > 0) && (h > 0)) { + outptr = c->pic->data[0] + dx * c->bpp2 + dy * c->pic->linesize[0]; + for (i = 0; i < h; i++) { + memcpy(outptr, c->screendta + i * c->cur_w * c->bpp2, + w * c->bpp2); + outptr += c->pic->linesize[0]; } } } - src += 2; - chunks = AV_RB16(src); src += 2; - while(chunks--) { - if(buf_size - (src - buf) < 12) { + bytestream2_skip(gb, 2); + chunks = bytestream2_get_be16(gb); + while (chunks--) { + if (bytestream2_get_bytes_left(gb) < 12) { av_log(avctx, AV_LOG_ERROR, "Premature end of data!\n"); return -1; } - dx = AV_RB16(src); src += 2; - dy = AV_RB16(src); src += 2; - w = AV_RB16(src); src += 2; - h = AV_RB16(src); src += 2; - enc = AV_RB32(src); src += 4; - outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0]; - size_left = buf_size - (src - buf); - switch(enc) { + dx = bytestream2_get_be16(gb); + dy = bytestream2_get_be16(gb); + w = bytestream2_get_be16(gb); + h = bytestream2_get_be16(gb); + enc = bytestream2_get_be32(gb); + outptr = c->pic->data[0] + dx * c->bpp2 + dy * c->pic->linesize[0]; + size_left = bytestream2_get_bytes_left(gb); + switch (enc) { case MAGIC_WMVd: // cursor if (w*(int64_t)h*c->bpp2 > INT_MAX/2 - 2) { av_log(avctx, AV_LOG_ERROR, "dimensions too large\n"); return AVERROR_INVALIDDATA; } - if(size_left < 2 + w * h * c->bpp2 * 2) { - av_log(avctx, AV_LOG_ERROR, "Premature end of data! (need %i got %i)\n", 2 + w * h * c->bpp2 * 2, size_left); - return -1; + if (size_left < 2 + w * h * c->bpp2 * 2) { + av_log(avctx, AV_LOG_ERROR, + "Premature end of data! (need %i got %i)\n", + 2 + w * h * c->bpp2 * 2, size_left); + return AVERROR_INVALIDDATA; } - src += 2; - c->cur_w = w; - c->cur_h = h; + bytestream2_skip(gb, 2); + c->cur_w = w; + c->cur_h = h; c->cur_hx = dx; c->cur_hy = dy; - if((c->cur_hx > c->cur_w) || (c->cur_hy > c->cur_h)) { - av_log(avctx, AV_LOG_ERROR, "Cursor hot spot is not in image: %ix%i of %ix%i cursor size\n", c->cur_hx, c->cur_hy, c->cur_w, c->cur_h); + if ((c->cur_hx > c->cur_w) || (c->cur_hy > c->cur_h)) { + av_log(avctx, AV_LOG_ERROR, + "Cursor hot spot is not in image: " + "%ix%i of %ix%i cursor size\n", + c->cur_hx, c->cur_hy, c->cur_w, c->cur_h); c->cur_hx = c->cur_hy = 0; } - c->curbits = av_realloc(c->curbits, c->cur_w * c->cur_h * c->bpp2); - c->curmask = av_realloc(c->curmask, c->cur_w * c->cur_h * c->bpp2); - c->screendta = av_realloc(c->screendta, c->cur_w * c->cur_h * c->bpp2); - load_cursor(c, src); - src += w * h * c->bpp2 * 2; + if (c->cur_w * c->cur_h >= INT_MAX / c->bpp2) { + reset_buffers(c); + return AVERROR(EINVAL); + } else { + int screen_size = c->cur_w * c->cur_h * c->bpp2; + if ((ret = av_reallocp(&c->curbits, screen_size)) < 0 || + (ret = av_reallocp(&c->curmask, screen_size)) < 0 || + (ret = av_reallocp(&c->screendta, screen_size)) < 0) { + reset_buffers(c); + return ret; + } + } + load_cursor(c); break; case MAGIC_WMVe: // unknown - src += 2; + bytestream2_skip(gb, 2); break; case MAGIC_WMVf: // update cursor position c->cur_x = dx - c->cur_hx; c->cur_y = dy - c->cur_hy; break; case MAGIC_WMVg: // unknown - src += 10; + bytestream2_skip(gb, 10); break; case MAGIC_WMVh: // unknown - src += 4; + bytestream2_skip(gb, 4); break; case MAGIC_WMVi: // ServerInitialization struct - c->pic.key_frame = 1; - c->pic.pict_type = AV_PICTURE_TYPE_I; - depth = *src++; - if(depth != c->bpp) { - av_log(avctx, AV_LOG_INFO, "Depth mismatch. Container %i bpp, Frame data: %i bpp\n", c->bpp, depth); + c->pic->key_frame = 1; + c->pic->pict_type = AV_PICTURE_TYPE_I; + depth = bytestream2_get_byte(gb); + if (depth != c->bpp) { + av_log(avctx, AV_LOG_INFO, + "Depth mismatch. Container %i bpp, " + "Frame data: %i bpp\n", + c->bpp, depth); } - src++; - c->bigendian = *src++; - if(c->bigendian & (~1)) { - av_log(avctx, AV_LOG_INFO, "Invalid header: bigendian flag = %i\n", c->bigendian); - return -1; + bytestream2_skip(gb, 1); + c->bigendian = bytestream2_get_byte(gb); + if (c->bigendian & (~1)) { + av_log(avctx, AV_LOG_INFO, + "Invalid header: bigendian flag = %i\n", c->bigendian); + return AVERROR_INVALIDDATA; } //skip the rest of pixel format data - src += 13; + bytestream2_skip(gb, 13); break; case MAGIC_WMVj: // unknown - src += 2; + bytestream2_skip(gb, 2); break; case 0x00000000: // raw rectangle data - if((dx + w > c->width) || (dy + h > c->height)) { - av_log(avctx, AV_LOG_ERROR, "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", w, h, dx, dy, c->width, c->height); - return -1; + if ((dx + w > c->width) || (dy + h > c->height)) { + av_log(avctx, AV_LOG_ERROR, + "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", + w, h, dx, dy, c->width, c->height); + return AVERROR_INVALIDDATA; } - if(size_left < w * h * c->bpp2) { - av_log(avctx, AV_LOG_ERROR, "Premature end of data! (need %i got %i)\n", w * h * c->bpp2, size_left); - return -1; + if (size_left < w * h * c->bpp2) { + av_log(avctx, AV_LOG_ERROR, + "Premature end of data! (need %i got %i)\n", + w * h * c->bpp2, size_left); + return AVERROR_INVALIDDATA; } - paint_raw(outptr, w, h, src, c->bpp2, c->bigendian, c->pic.linesize[0]); - src += w * h * c->bpp2; + paint_raw(outptr, w, h, gb, c->bpp2, c->bigendian, + c->pic->linesize[0]); break; case 0x00000005: // HexTile encoded rectangle - if((dx + w > c->width) || (dy + h > c->height)) { - av_log(avctx, AV_LOG_ERROR, "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", w, h, dx, dy, c->width, c->height); - return -1; + if ((dx + w > c->width) || (dy + h > c->height)) { + av_log(avctx, AV_LOG_ERROR, + "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", + w, h, dx, dy, c->width, c->height); + return AVERROR_INVALIDDATA; } - res = decode_hextile(c, outptr, src, size_left, w, h, c->pic.linesize[0]); - if(res < 0) - return -1; - src += res; + res = decode_hextile(c, outptr, gb, w, h, c->pic->linesize[0]); + if (res < 0) + return res; break; default: av_log(avctx, AV_LOG_ERROR, "Unsupported block type 0x%08X\n", enc); chunks = 0; // leave chunks decoding loop } } - if(c->screendta){ + if (c->screendta) { int i; - //save screen data before painting cursor + // save screen data before painting cursor w = c->cur_w; - if(c->width < c->cur_x + w) w = c->width - c->cur_x; + if (c->width < c->cur_x + w) + w = c->width - c->cur_x; h = c->cur_h; - if(c->height < c->cur_y + h) h = c->height - c->cur_y; + if (c->height < c->cur_y + h) + h = c->height - c->cur_y; dx = c->cur_x; - if(dx < 0) { + if (dx < 0) { w += dx; dx = 0; } dy = c->cur_y; - if(dy < 0) { + if (dy < 0) { h += dy; dy = 0; } - if((w > 0) && (h > 0)) { - outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0]; - for(i = 0; i < h; i++) { - memcpy(c->screendta + i * c->cur_w * c->bpp2, outptr, w * c->bpp2); - outptr += c->pic.linesize[0]; + if ((w > 0) && (h > 0)) { + outptr = c->pic->data[0] + dx * c->bpp2 + dy * c->pic->linesize[0]; + for (i = 0; i < h; i++) { + memcpy(c->screendta + i * c->cur_w * c->bpp2, outptr, + w * c->bpp2); + outptr += c->pic->linesize[0]; } - outptr = c->pic.data[0]; - put_cursor(outptr, c->pic.linesize[0], c, c->cur_x, c->cur_y); + outptr = c->pic->data[0]; + put_cursor(outptr, c->pic->linesize[0], c, c->cur_x, c->cur_y); } } - *got_frame = 1; - if ((ret = av_frame_ref(data, &c->pic)) < 0) + *got_frame = 1; + if ((ret = av_frame_ref(data, c->pic)) < 0) return ret; /* always report that the buffer was completely consumed */ return buf_size; } - - -/* - * - * Init VMnc decoder - * - */ static av_cold int decode_init(AVCodecContext *avctx) { VmncContext * const c = avctx->priv_data; - c->avctx = avctx; - - c->width = avctx->width; + c->avctx = avctx; + c->width = avctx->width; c->height = avctx->height; + c->bpp = avctx->bits_per_coded_sample; + c->bpp2 = c->bpp / 8; - c->bpp = avctx->bits_per_coded_sample; - c->bpp2 = c->bpp/8; - avcodec_get_frame_defaults(&c->pic); - - switch(c->bpp){ + switch (c->bpp) { case 8: avctx->pix_fmt = AV_PIX_FMT_PAL8; break; @@ -495,32 +540,28 @@ static av_cold int decode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } - avcodec_get_frame_defaults(&c->pic); + c->pic = av_frame_alloc(); + if (!c->pic) + return AVERROR(ENOMEM); return 0; } - - -/* - * - * Uninit VMnc decoder - * - */ static av_cold int decode_end(AVCodecContext *avctx) { VmncContext * const c = avctx->priv_data; - av_frame_unref(&c->pic); + av_frame_free(&c->pic); - av_free(c->curbits); - av_free(c->curmask); - av_free(c->screendta); + av_freep(&c->curbits); + av_freep(&c->curmask); + av_freep(&c->screendta); return 0; } AVCodec ff_vmnc_decoder = { .name = "vmnc", + .long_name = NULL_IF_CONFIG_SMALL("VMware Screen Codec / VMware Video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VMNC, .priv_data_size = sizeof(VmncContext), @@ -528,5 +569,4 @@ AVCodec ff_vmnc_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("VMware Screen Codec / VMware Video"), }; diff --git a/ffmpeg/libavcodec/vorbis_parser.c b/ffmpeg/libavcodec/vorbis_parser.c index 22e0461..1e2cab3 100644 --- a/ffmpeg/libavcodec/vorbis_parser.c +++ b/ffmpeg/libavcodec/vorbis_parser.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2012 Justin Ruggles * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -201,8 +201,8 @@ int avpriv_vorbis_parse_extradata(AVCodecContext *avctx, VorbisParseContext *s) return 0; } -int avpriv_vorbis_parse_frame(VorbisParseContext *s, const uint8_t *buf, - int buf_size) +int avpriv_vorbis_parse_frame_flags(VorbisParseContext *s, const uint8_t *buf, + int buf_size, int *flags) { int duration = 0; @@ -211,6 +211,22 @@ int avpriv_vorbis_parse_frame(VorbisParseContext *s, const uint8_t *buf, int previous_blocksize = s->previous_blocksize; if (buf[0] & 1) { + /* If the user doesn't care about special packets, it's a bad one. */ + if (!flags) + goto bad_packet; + + /* Set the flag for which kind of special packet it is. */ + if (buf[0] == 1) + *flags |= VORBIS_FLAG_HEADER; + else if (buf[0] == 3) + *flags |= VORBIS_FLAG_COMMENT; + else + goto bad_packet; + + /* Special packets have no duration. */ + return 0; + +bad_packet: av_log(s->avctx, AV_LOG_ERROR, "Invalid packet\n"); return AVERROR_INVALIDDATA; } @@ -234,6 +250,12 @@ int avpriv_vorbis_parse_frame(VorbisParseContext *s, const uint8_t *buf, return duration; } +int avpriv_vorbis_parse_frame(VorbisParseContext *s, const uint8_t *buf, + int buf_size) +{ + return avpriv_vorbis_parse_frame_flags(s, buf, buf_size, NULL); +} + void avpriv_vorbis_parse_reset(VorbisParseContext *s) { if (s->valid_extradata) diff --git a/ffmpeg/libavcodec/vorbis_parser.h b/ffmpeg/libavcodec/vorbis_parser.h index 480a918..590101b 100644 --- a/ffmpeg/libavcodec/vorbis_parser.h +++ b/ffmpeg/libavcodec/vorbis_parser.h @@ -1,20 +1,20 @@ /* * Copyright (c) 2012 Justin Ruggles * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -50,6 +50,24 @@ typedef struct VorbisParseContext { */ int avpriv_vorbis_parse_extradata(AVCodecContext *avctx, VorbisParseContext *s); +#define VORBIS_FLAG_HEADER 0x00000001 +#define VORBIS_FLAG_COMMENT 0x00000002 + +/** + * Get the duration for a Vorbis packet. + * + * avpriv_vorbis_parse_extradata() must have been successfully called prior to + * this in order for a correct duration to be returned. If @p flags is @c NULL, + * special frames are considered invalid. + * + * @param s Vorbis parser context + * @param buf buffer containing a Vorbis frame + * @param buf_size size of the buffer + * @param flags flags for special frames + */ +int avpriv_vorbis_parse_frame_flags(VorbisParseContext *s, const uint8_t *buf, + int buf_size, int *flags); + /** * Get the duration for a Vorbis packet. * diff --git a/ffmpeg/libavcodec/vorbisdec.c b/ffmpeg/libavcodec/vorbisdec.c index f30745d..a2f7dd2 100644 --- a/ffmpeg/libavcodec/vorbisdec.c +++ b/ffmpeg/libavcodec/vorbisdec.c @@ -1230,8 +1230,11 @@ static int vorbis_floor1_decode(vorbis_context *vc, cval = cval >> cbits; if (book > -1) { - floor1_Y[offset+j] = get_vlc2(gb, vc->codebooks[book].vlc.table, - vc->codebooks[book].nb_bits, 3); + int v = get_vlc2(gb, vc->codebooks[book].vlc.table, + vc->codebooks[book].nb_bits, 3); + if (v < 0) + return AVERROR_INVALIDDATA; + floor1_Y[offset+j] = v; } else { floor1_Y[offset+j] = 0; } @@ -1308,6 +1311,50 @@ static int vorbis_floor1_decode(vorbis_context *vc, return 0; } +static av_always_inline int setup_classifs(vorbis_context *vc, + vorbis_residue *vr, + uint8_t *do_not_decode, + unsigned ch_used, + int partition_count) +{ + int p, j, i; + unsigned c_p_c = vc->codebooks[vr->classbook].dimensions; + unsigned inverse_class = ff_inverse[vr->classifications]; + unsigned temp, temp2; + for (p = 0, j = 0; j < ch_used; ++j) { + if (!do_not_decode[j]) { + temp = get_vlc2(&vc->gb, vc->codebooks[vr->classbook].vlc.table, + vc->codebooks[vr->classbook].nb_bits, 3); + + av_dlog(NULL, "Classword: %u\n", temp); + + if ((int)temp < 0) + return temp; + + av_assert0(vr->classifications > 1); //needed for inverse[] + + if (temp <= 65536) { + for (i = partition_count + c_p_c - 1; i >= partition_count; i--) { + temp2 = (((uint64_t)temp) * inverse_class) >> 32; + + if (i < vr->ptns_to_read) + vr->classifs[p + i] = temp - temp2 * vr->classifications; + temp = temp2; + } + } else { + for (i = partition_count + c_p_c - 1; i >= partition_count; i--) { + temp2 = temp / vr->classifications; + + if (i < vr->ptns_to_read) + vr->classifs[p + i] = temp - temp2 * vr->classifications; + temp = temp2; + } + } + } + p += vr->ptns_to_read; + } + return 0; +} // Read and decode residue static av_always_inline int vorbis_residue_decode_internal(vorbis_context *vc, @@ -1321,10 +1368,10 @@ static av_always_inline int vorbis_residue_decode_internal(vorbis_context *vc, { GetBitContext *gb = &vc->gb; unsigned c_p_c = vc->codebooks[vr->classbook].dimensions; - unsigned ptns_to_read = vr->ptns_to_read; uint8_t *classifs = vr->classifs; unsigned pass, ch_used, i, j, k, l; unsigned max_output = (ch - 1) * vlen; + int ptns_to_read = vr->ptns_to_read; if (vr_type == 2) { for (j = 1; j < ch; ++j) @@ -1340,37 +1387,20 @@ static av_always_inline int vorbis_residue_decode_internal(vorbis_context *vc, if (max_output > ch_left * vlen) { av_log(vc->avctx, AV_LOG_ERROR, "Insufficient output buffer\n"); - return -1; + return AVERROR_INVALIDDATA; } av_dlog(NULL, " residue type 0/1/2 decode begin, ch: %d cpc %d \n", ch, c_p_c); for (pass = 0; pass <= vr->maxpass; ++pass) { // FIXME OPTIMIZE? - uint16_t voffset, partition_count, j_times_ptns_to_read; + int voffset, partition_count, j_times_ptns_to_read; voffset = vr->begin; for (partition_count = 0; partition_count < ptns_to_read;) { // SPEC error if (!pass) { - unsigned inverse_class = ff_inverse[vr->classifications]; - for (j_times_ptns_to_read = 0, j = 0; j < ch_used; ++j) { - if (!do_not_decode[j]) { - unsigned temp = get_vlc2(gb, vc->codebooks[vr->classbook].vlc.table, - vc->codebooks[vr->classbook].nb_bits, 3); - - av_dlog(NULL, "Classword: %u\n", temp); - - av_assert0(vr->classifications > 1 && temp <= 65536); //needed for inverse[] - for (i = 0; i < c_p_c; ++i) { - unsigned temp2; - - temp2 = (((uint64_t)temp) * inverse_class) >> 32; - if (partition_count + c_p_c - 1 - i < ptns_to_read) - classifs[j_times_ptns_to_read + partition_count + c_p_c - 1 - i] = temp - temp2 * vr->classifications; - temp = temp2; - } - } - j_times_ptns_to_read += ptns_to_read; - } + int ret; + if ((ret = setup_classifs(vc, vr, do_not_decode, ch_used, partition_count)) < 0) + return ret; } for (i = 0; (i < c_p_c) && (partition_count < ptns_to_read); ++i) { for (j_times_ptns_to_read = 0, j = 0; j < ch_used; ++j) { @@ -1610,7 +1640,7 @@ static int vorbis_parse_audio_packet(vorbis_context *vc, float **floor_ptr) residue = &vc->residues[mapping->submap_residue[i]]; if (ch_left < ch) { av_log(vc->avctx, AV_LOG_ERROR, "Too many channels in vorbis_floor_decode.\n"); - return -1; + return AVERROR_INVALIDDATA; } if (ch) { ret = vorbis_residue_decode(vc, residue, ch, do_not_decode, ch_res_ptr, vlen, ch_left); @@ -1787,6 +1817,7 @@ static av_cold void vorbis_decode_flush(AVCodecContext *avctx) AVCodec ff_vorbis_decoder = { .name = "vorbis", + .long_name = NULL_IF_CONFIG_SMALL("Vorbis"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_VORBIS, .priv_data_size = sizeof(vorbis_context), @@ -1795,7 +1826,6 @@ AVCodec ff_vorbis_decoder = { .decode = vorbis_decode_frame, .flush = vorbis_decode_flush, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Vorbis"), .channel_layouts = ff_vorbis_channel_layouts, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, diff --git a/ffmpeg/libavcodec/vorbisdsp.c b/ffmpeg/libavcodec/vorbisdsp.c index fd8dcd7..7843756 100644 --- a/ffmpeg/libavcodec/vorbisdsp.c +++ b/ffmpeg/libavcodec/vorbisdsp.c @@ -17,17 +17,18 @@ */ #include "config.h" +#include "libavutil/attributes.h" #include "vorbisdsp.h" #include "vorbis.h" -void ff_vorbisdsp_init(VorbisDSPContext *dsp) +av_cold void ff_vorbisdsp_init(VorbisDSPContext *dsp) { dsp->vorbis_inverse_coupling = ff_vorbis_inverse_coupling; - if (ARCH_X86) - ff_vorbisdsp_init_x86(dsp); - if (ARCH_PPC) - ff_vorbisdsp_init_ppc(dsp); if (ARCH_ARM) ff_vorbisdsp_init_arm(dsp); + if (ARCH_PPC) + ff_vorbisdsp_init_ppc(dsp); + if (ARCH_X86) + ff_vorbisdsp_init_x86(dsp); } diff --git a/ffmpeg/libavcodec/vorbisenc.c b/ffmpeg/libavcodec/vorbisenc.c index d685996..9ef6296 100644 --- a/ffmpeg/libavcodec/vorbisenc.c +++ b/ffmpeg/libavcodec/vorbisenc.c @@ -140,9 +140,9 @@ typedef struct { static inline int put_codeword(PutBitContext *pb, vorbis_enc_codebook *cb, int entry) { - assert(entry >= 0); - assert(entry < cb->nentries); - assert(cb->lens[entry]); + av_assert2(entry >= 0); + av_assert2(entry < cb->nentries); + av_assert2(cb->lens[entry]); if (pb->size_in_bits - put_bits_count(pb) < cb->lens[entry]) return AVERROR(EINVAL); put_bits(pb, cb->lens[entry], cb->codewords[entry]); @@ -189,7 +189,7 @@ static int ready_codebook(vorbis_enc_codebook *cb) cb->pow2[i] += cb->dimensions[i * cb->ndimensions + j] * cb->dimensions[i * cb->ndimensions + j]; div *= vals; } - cb->pow2[i] /= 2.; + cb->pow2[i] /= 2.0; } } return 0; @@ -198,7 +198,7 @@ static int ready_codebook(vorbis_enc_codebook *cb) static int ready_residue(vorbis_enc_residue *rc, vorbis_enc_context *venc) { int i; - assert(rc->type == 2); + av_assert0(rc->type == 2); rc->maxes = av_mallocz(sizeof(float[2]) * rc->classifications); if (!rc->maxes) return AVERROR(ENOMEM); @@ -728,7 +728,7 @@ static void floor_fit(vorbis_enc_context *venc, vorbis_enc_floor *fc, { int range = 255 / fc->multiplier + 1; int i; - float tot_average = 0.; + float tot_average = 0.0; float averages[MAX_FLOOR_VALUES]; for (i = 0; i < fc->values; i++) { averages[i] = get_floor_average(fc, coeffs, i); @@ -878,10 +878,10 @@ static int residue_encode(vorbis_enc_context *venc, vorbis_enc_residue *rc, int classes[MAX_CHANNELS][NUM_RESIDUE_PARTITIONS]; int classwords = venc->codebooks[rc->classbook].ndimensions; - assert(rc->type == 2); - assert(real_ch == 2); + av_assert0(rc->type == 2); + av_assert0(real_ch == 2); for (p = 0; p < partitions; p++) { - float max1 = 0., max2 = 0.; + float max1 = 0.0, max2 = 0.0; int s = rc->begin + p * psize; for (k = s; k < s + psize; k += 2) { max1 = FFMAX(max1, fabs(coeffs[ k / real_ch])); @@ -968,7 +968,7 @@ static int apply_window_and_mdct(vorbis_enc_context *venc, int i, channel; const float * win = venc->win[0]; int window_len = 1 << (venc->log2_blocksize[0] - 1); - float n = (float)(1 << venc->log2_blocksize[0]) / 4.; + float n = (float)(1 << venc->log2_blocksize[0]) / 4.0; // FIXME use dsp if (!venc->have_saved && !samples) @@ -1192,6 +1192,7 @@ error: AVCodec ff_vorbis_encoder = { .name = "vorbis", + .long_name = NULL_IF_CONFIG_SMALL("Vorbis"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_VORBIS, .priv_data_size = sizeof(vorbis_enc_context), @@ -1201,5 +1202,4 @@ AVCodec ff_vorbis_encoder = { .capabilities = CODEC_CAP_DELAY | CODEC_CAP_EXPERIMENTAL, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Vorbis"), }; diff --git a/ffmpeg/libavcodec/vp3.c b/ffmpeg/libavcodec/vp3.c index 1e76786..626642f 100644 --- a/ffmpeg/libavcodec/vp3.c +++ b/ffmpeg/libavcodec/vp3.c @@ -381,7 +381,8 @@ static void init_dequantizer(Vp3DecodeContext *s, int qpi) int qmin= 8<<(inter + !i); int qscale= i ? ac_scale_factor : dc_scale_factor; - s->qmat[qpi][inter][plane][s->idct_permutation[i]]= av_clip((qscale * coeff)/100 * 4, qmin, 4096); + s->qmat[qpi][inter][plane][s->idct_permutation[i]] = + av_clip((qscale * coeff) / 100 * 4, qmin, 4096); } // all DC coefficients use the same quant so as not to interfere with DC prediction s->qmat[qpi][inter][plane][0] = s->qmat[0][inter][plane][0]; @@ -1293,7 +1294,7 @@ static void apply_loop_filter(Vp3DecodeContext *s, int plane, int ystart, int ye int width = s->fragment_width[!!plane]; int height = s->fragment_height[!!plane]; int fragment = s->fragment_start [plane] + ystart * width; - int stride = s->current_frame.f->linesize[plane]; + ptrdiff_t stride = s->current_frame.f->linesize[plane]; uint8_t *plane_data = s->current_frame.f->data [plane]; if (!s->flipped_image) stride = -stride; plane_data += s->data_offset[plane] + 8*ystart*stride; @@ -1475,7 +1476,7 @@ static void render_slice(Vp3DecodeContext *s, int slice) uint8_t *output_plane = s->current_frame.f->data [plane] + s->data_offset[plane]; uint8_t * last_plane = s-> last_frame.f->data [plane] + s->data_offset[plane]; uint8_t *golden_plane = s-> golden_frame.f->data [plane] + s->data_offset[plane]; - int stride = s->current_frame.f->linesize[plane]; + ptrdiff_t stride = s->current_frame.f->linesize[plane]; int plane_width = s->width >> (plane && s->chroma_x_shift); int plane_height = s->height >> (plane && s->chroma_y_shift); int8_t (*motion_val)[2] = s->motion_val[!!plane]; @@ -1548,7 +1549,11 @@ static void render_slice(Vp3DecodeContext *s, int slice) uint8_t *temp= s->edge_emu_buffer; if(stride<0) temp -= 8*stride; - s->vdsp.emulated_edge_mc(temp, motion_source, stride, 9, 9, src_x, src_y, plane_width, plane_height); + s->vdsp.emulated_edge_mc(temp, motion_source, + stride, stride, + 9, 9, src_x, src_y, + plane_width, + plane_height); motion_source= temp; } } @@ -1631,16 +1636,16 @@ static av_cold int allocate_tables(AVCodecContext *avctx) y_fragment_count = s->fragment_width[0] * s->fragment_height[0]; c_fragment_count = s->fragment_width[1] * s->fragment_height[1]; - s->superblock_coding = av_malloc(s->superblock_count); - s->all_fragments = av_malloc(s->fragment_count * sizeof(Vp3Fragment)); - s->coded_fragment_list[0] = av_malloc(s->fragment_count * sizeof(int)); - s->dct_tokens_base = av_malloc(64*s->fragment_count * sizeof(*s->dct_tokens_base)); - s->motion_val[0] = av_malloc(y_fragment_count * sizeof(*s->motion_val[0])); - s->motion_val[1] = av_malloc(c_fragment_count * sizeof(*s->motion_val[1])); + s->superblock_coding = av_mallocz(s->superblock_count); + s->all_fragments = av_mallocz(s->fragment_count * sizeof(Vp3Fragment)); + s->coded_fragment_list[0] = av_mallocz(s->fragment_count * sizeof(int)); + s->dct_tokens_base = av_mallocz(64*s->fragment_count * sizeof(*s->dct_tokens_base)); + s->motion_val[0] = av_mallocz(y_fragment_count * sizeof(*s->motion_val[0])); + s->motion_val[1] = av_mallocz(c_fragment_count * sizeof(*s->motion_val[1])); /* work out the block mapping tables */ - s->superblock_fragments = av_malloc(s->superblock_count * 16 * sizeof(int)); - s->macroblock_coding = av_malloc(s->macroblock_count + 1); + s->superblock_fragments = av_mallocz(s->superblock_count * 16 * sizeof(int)); + s->macroblock_coding = av_mallocz(s->macroblock_count + 1); if (!s->superblock_coding || !s->all_fragments || !s->dct_tokens_base || !s->coded_fragment_list[0] || !s->superblock_fragments || !s->macroblock_coding || @@ -2192,6 +2197,7 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) Vp3DecodeContext *s = avctx->priv_data; int visible_width, visible_height, colorspace; int offset_x = 0, offset_y = 0; + int ret; AVRational fps, aspect; s->theora = get_bits_long(gb, 24); @@ -2208,12 +2214,6 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) visible_width = s->width = get_bits(gb, 16) << 4; visible_height = s->height = get_bits(gb, 16) << 4; - if(av_image_check_size(s->width, s->height, 0, avctx)){ - av_log(avctx, AV_LOG_ERROR, "Invalid dimensions (%dx%d)\n", s->width, s->height); - s->width= s->height= 0; - return -1; - } - if (s->theora >= 0x030200) { visible_width = get_bits_long(gb, 24); visible_height = get_bits_long(gb, 24); @@ -2225,6 +2225,10 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) fps.num = get_bits_long(gb, 32); fps.den = get_bits_long(gb, 32); if (fps.num && fps.den) { + if (fps.num < 0 || fps.den < 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid framerate\n"); + return AVERROR_INVALIDDATA; + } av_reduce(&avctx->time_base.num, &avctx->time_base.den, fps.den, fps.num, 1<<30); } @@ -2260,9 +2264,11 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) if ( visible_width <= s->width && visible_width > s->width-16 && visible_height <= s->height && visible_height > s->height-16 && !offset_x && (offset_y == s->height - visible_height)) - avcodec_set_dimensions(avctx, visible_width, visible_height); + ret = ff_set_dimensions(avctx, visible_width, visible_height); else - avcodec_set_dimensions(avctx, s->width, s->height); + ret = ff_set_dimensions(avctx, s->width, s->height); + if (ret < 0) + return ret; if (colorspace == 1) { avctx->color_primaries = AVCOL_PRI_BT470M; @@ -2454,6 +2460,7 @@ static av_cold int theora_decode_init(AVCodecContext *avctx) AVCodec ff_theora_decoder = { .name = "theora", + .long_name = NULL_IF_CONFIG_SMALL("Theora"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_THEORA, .priv_data_size = sizeof(Vp3DecodeContext), @@ -2463,7 +2470,6 @@ AVCodec ff_theora_decoder = { .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_FRAME_THREADS, .flush = vp3_decode_flush, - .long_name = NULL_IF_CONFIG_SMALL("Theora"), .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context) }; @@ -2471,6 +2477,7 @@ AVCodec ff_theora_decoder = { AVCodec ff_vp3_decoder = { .name = "vp3", + .long_name = NULL_IF_CONFIG_SMALL("On2 VP3"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VP3, .priv_data_size = sizeof(Vp3DecodeContext), @@ -2480,7 +2487,6 @@ AVCodec ff_vp3_decoder = { .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_FRAME_THREADS, .flush = vp3_decode_flush, - .long_name = NULL_IF_CONFIG_SMALL("On2 VP3"), .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context), }; diff --git a/ffmpeg/libavcodec/vp3dsp.c b/ffmpeg/libavcodec/vp3dsp.c index 9348963..5656629 100644 --- a/ffmpeg/libavcodec/vp3dsp.c +++ b/ffmpeg/libavcodec/vp3dsp.c @@ -138,7 +138,7 @@ static av_always_inline void idct(uint8_t *dst, int stride, int16_t *input, int Hd = Bd + H; /* Final sequence of operations over-write original inputs. */ - if(type==1){ + if (type == 1) { dst[0*stride] = av_clip_uint8((Gd + Cd ) >> 4); dst[7*stride] = av_clip_uint8((Gd - Cd ) >> 4); @@ -165,7 +165,7 @@ static av_always_inline void idct(uint8_t *dst, int stride, int16_t *input, int } } else { - if(type==1){ + if (type == 1) { dst[0*stride]= dst[1*stride]= dst[2*stride]= diff --git a/ffmpeg/libavcodec/vp5.c b/ffmpeg/libavcodec/vp5.c index 4eecbe3..756dc92 100644 --- a/ffmpeg/libavcodec/vp5.c +++ b/ffmpeg/libavcodec/vp5.c @@ -28,6 +28,7 @@ #include "avcodec.h" #include "get_bits.h" +#include "internal.h" #include "vp56.h" #include "vp56data.h" @@ -66,7 +67,9 @@ static int vp5_parse_header(VP56Context *s, const uint8_t *buf, int buf_size) if (!s->macroblocks || /* first frame */ 16*cols != s->avctx->coded_width || 16*rows != s->avctx->coded_height) { - avcodec_set_dimensions(s->avctx, 16*cols, 16*rows); + int ret = ff_set_dimensions(s->avctx, 16 * cols, 16 * rows); + if (ret < 0) + return ret; return VP56_SIZE_CHANGE; } } else if (!s->macroblocks) @@ -280,6 +283,7 @@ static av_cold int vp5_decode_init(AVCodecContext *avctx) AVCodec ff_vp5_decoder = { .name = "vp5", + .long_name = NULL_IF_CONFIG_SMALL("On2 VP5"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VP5, .priv_data_size = sizeof(VP56Context), @@ -287,5 +291,4 @@ AVCodec ff_vp5_decoder = { .close = ff_vp56_free, .decode = ff_vp56_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("On2 VP5"), }; diff --git a/ffmpeg/libavcodec/vp56.c b/ffmpeg/libavcodec/vp56.c index 6bf391c..a0cb060 100644 --- a/ffmpeg/libavcodec/vp56.c +++ b/ffmpeg/libavcodec/vp56.c @@ -34,8 +34,8 @@ void ff_vp56_init_dequant(VP56Context *s, int quantizer) { s->quantizer = quantizer; - s->dequant_dc = vp56_dc_dequant[quantizer] << 2; - s->dequant_ac = vp56_ac_dequant[quantizer] << 2; + s->dequant_dc = ff_vp56_dc_dequant[quantizer] << 2; + s->dequant_ac = ff_vp56_ac_dequant[quantizer] << 2; } static int vp56_get_vectors_predictors(VP56Context *s, int row, int col, @@ -47,14 +47,14 @@ static int vp56_get_vectors_predictors(VP56Context *s, int row, int col, VP56mv mvp; for (pos=0; pos<12; pos++) { - mvp.x = col + vp56_candidate_predictor_pos[pos][0]; - mvp.y = row + vp56_candidate_predictor_pos[pos][1]; + mvp.x = col + ff_vp56_candidate_predictor_pos[pos][0]; + mvp.y = row + ff_vp56_candidate_predictor_pos[pos][1]; if (mvp.x < 0 || mvp.x >= s->mb_width || mvp.y < 0 || mvp.y >= s->mb_height) continue; offset = mvp.x + s->mb_width*mvp.y; - if (vp56_reference_frame[s->macroblocks[offset].type] != ref_frame) + if (ff_vp56_reference_frame[s->macroblocks[offset].type] != ref_frame) continue; if ((s->macroblocks[offset].mv.x == vect[0].x && s->macroblocks[offset].mv.y == vect[0].y) || @@ -86,7 +86,7 @@ static void vp56_parse_mb_type_models(VP56Context *s) if (vp56_rac_get_prob(c, 174)) { int idx = vp56_rac_gets(c, 4); memcpy(model->mb_types_stats[ctx], - vp56_pre_def_mb_type_stats[idx][ctx], + ff_vp56_pre_def_mb_type_stats[idx][ctx], sizeof(model->mb_types_stats[ctx])); } if (vp56_rac_get_prob(c, 254)) { @@ -95,8 +95,8 @@ static void vp56_parse_mb_type_models(VP56Context *s) if (vp56_rac_get_prob(c, 205)) { int delta, sign = vp56_rac_get(c); - delta = vp56_rac_get_tree(c, vp56_pmbtm_tree, - vp56_mb_type_model_model); + delta = vp56_rac_get_tree(c, ff_vp56_pmbtm_tree, + ff_vp56_mb_type_model_model); if (!delta) delta = 4 * vp56_rac_gets(c, 7); model->mb_types_stats[ctx][type][i] += (delta ^ -sign) + sign; @@ -156,7 +156,7 @@ static VP56mb vp56_parse_mb_type(VP56Context *s, if (vp56_rac_get_prob(c, mb_type_model[0])) return prev_type; else - return vp56_rac_get_tree(c, vp56_pmbt_tree, mb_type_model); + return vp56_rac_get_tree(c, ff_vp56_pmbt_tree, mb_type_model); } static void vp56_decode_4mv(VP56Context *s, int row, int col) @@ -303,15 +303,15 @@ static void vp56_add_predictors_dc(VP56Context *s, VP56Frame ref_frame) } static void vp56_deblock_filter(VP56Context *s, uint8_t *yuv, - int stride, int dx, int dy) + ptrdiff_t stride, int dx, int dy) { - int t = vp56_filter_threshold[s->quantizer]; + int t = ff_vp56_filter_threshold[s->quantizer]; if (dx) s->vp56dsp.edge_filter_hor(yuv + 10-dx , stride, t); if (dy) s->vp56dsp.edge_filter_ver(yuv + stride*(10-dy), stride, t); } static void vp56_mc(VP56Context *s, int b, int plane, uint8_t *src, - int stride, int x, int y) + ptrdiff_t stride, int x, int y) { uint8_t *dst = s->frames[VP56_FRAME_CURRENT]->data[plane] + s->block_offset[b]; uint8_t *src_block; @@ -340,18 +340,19 @@ static void vp56_mc(VP56Context *s, int b, int plane, uint8_t *src, if (x<0 || x+12>=s->plane_width[plane] || y<0 || y+12>=s->plane_height[plane]) { s->vdsp.emulated_edge_mc(s->edge_emu_buffer, - src + s->block_offset[b] + (dy-2)*stride + (dx-2), - stride, 12, 12, x, y, - s->plane_width[plane], - s->plane_height[plane]); + src + s->block_offset[b] + (dy-2)*stride + (dx-2), + stride, stride, + 12, 12, x, y, + s->plane_width[plane], + s->plane_height[plane]); src_block = s->edge_emu_buffer; src_offset = 2 + 2*stride; } else if (deblock_filtering) { /* only need a 12x12 block, but there is no such dsp function, */ /* so copy a 16x12 block */ s->hdsp.put_pixels_tab[0][0](s->edge_emu_buffer, - src + s->block_offset[b] + (dy-2)*stride + (dx-2), - stride, 12); + src + s->block_offset[b] + (dy-2)*stride + (dx-2), + stride, 12); src_block = s->edge_emu_buffer; src_offset = 2 + 2*stride; } else { @@ -391,7 +392,7 @@ static void vp56_decode_mb(VP56Context *s, int row, int col, int is_alpha) mb_type = VP56_MB_INTRA; else mb_type = vp56_decode_mv(s, row, col); - ref_frame = vp56_reference_frame[mb_type]; + ref_frame = ff_vp56_reference_frame[mb_type]; s->parse_coeff(s); @@ -420,8 +421,8 @@ static void vp56_decode_mb(VP56Context *s, int row, int col, int is_alpha) plane = ff_vp56_b2p[b+ab]; off = s->block_offset[b]; s->hdsp.put_pixels_tab[1][0](frame_current->data[plane] + off, - frame_ref->data[plane] + off, - s->stride[plane], 8); + frame_ref->data[plane] + off, + s->stride[plane], 8); s->vp3dsp.idct_add(frame_current->data[plane] + off, s->stride[plane], s->block_coeff[b]); } @@ -470,18 +471,20 @@ static int vp56_size_changed(VP56Context *s) s->mb_height = (avctx->coded_height+15) / 16; if (s->mb_width > 1000 || s->mb_height > 1000) { - avcodec_set_dimensions(avctx, 0, 0); + ff_set_dimensions(avctx, 0, 0); av_log(avctx, AV_LOG_ERROR, "picture too big\n"); return -1; } - s->above_blocks = av_realloc(s->above_blocks, - (4*s->mb_width+6) * sizeof(*s->above_blocks)); - s->macroblocks = av_realloc(s->macroblocks, - s->mb_width*s->mb_height*sizeof(*s->macroblocks)); + av_reallocp_array(&s->above_blocks, 4*s->mb_width+6, + sizeof(*s->above_blocks)); + av_reallocp_array(&s->macroblocks, s->mb_width*s->mb_height, + sizeof(*s->macroblocks)); av_free(s->edge_emu_buffer_alloc); s->edge_emu_buffer_alloc = av_malloc(16*stride); s->edge_emu_buffer = s->edge_emu_buffer_alloc; + if (!s->above_blocks || !s->macroblocks || !s->edge_emu_buffer_alloc) + return AVERROR(ENOMEM); if (s->flip < 0) s->edge_emu_buffer += 15 * stride; @@ -528,7 +531,7 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF) < 0) return -1; - if (s->has_alpha) { + if (avctx->pix_fmt == AV_PIX_FMT_YUVA420P) { av_frame_unref(s->alpha_context->frames[VP56_FRAME_CURRENT]); if ((ret = av_frame_ref(s->alpha_context->frames[VP56_FRAME_CURRENT], p)) < 0) { av_frame_unref(p); @@ -543,7 +546,7 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } } - if (s->has_alpha) { + if (avctx->pix_fmt == AV_PIX_FMT_YUVA420P) { int bak_w = avctx->width; int bak_h = avctx->height; int bak_cw = avctx->coded_width; @@ -565,7 +568,7 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } } - avctx->execute2(avctx, ff_vp56_decode_mbs, 0, 0, s->has_alpha + 1); + avctx->execute2(avctx, ff_vp56_decode_mbs, 0, 0, (avctx->pix_fmt == AV_PIX_FMT_YUVA420P) + 1); if ((res = av_frame_ref(data, p)) < 0) return res; @@ -582,7 +585,8 @@ static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *data, VP56Context *s = is_alpha ? s0->alpha_context : s0; AVFrame *const p = s->frames[VP56_FRAME_CURRENT]; int mb_row, mb_col, mb_row_flip, mb_offset = 0; - int block, y, uv, stride_y, stride_uv; + int block, y, uv; + ptrdiff_t stride_y, stride_uv; int res; if (p->key_frame) { @@ -688,6 +692,7 @@ av_cold int ff_vp56_init_context(AVCodecContext *avctx, VP56Context *s, s->avctx = avctx; avctx->pix_fmt = has_alpha ? AV_PIX_FMT_YUVA420P : AV_PIX_FMT_YUV420P; + if (avctx->skip_alpha) avctx->pix_fmt = AV_PIX_FMT_YUV420P; ff_h264chroma_init(&s->h264chroma, 8); ff_hpeldsp_init(&s->hdsp, avctx->flags); diff --git a/ffmpeg/libavcodec/vp56.h b/ffmpeg/libavcodec/vp56.h index 4b0f5e1..9a95296 100644 --- a/ffmpeg/libavcodec/vp56.h +++ b/ffmpeg/libavcodec/vp56.h @@ -26,7 +26,6 @@ #ifndef AVCODEC_VP56_H #define AVCODEC_VP56_H -#include "vp56data.h" #include "dsputil.h" #include "get_bits.h" #include "hpeldsp.h" @@ -38,6 +37,32 @@ typedef struct vp56_context VP56Context; +typedef enum { + VP56_FRAME_NONE =-1, + VP56_FRAME_CURRENT = 0, + VP56_FRAME_PREVIOUS = 1, + VP56_FRAME_GOLDEN = 2, + VP56_FRAME_GOLDEN2 = 3, +} VP56Frame; + +typedef enum { + VP56_MB_INTER_NOVEC_PF = 0, /**< Inter MB, no vector, from previous frame */ + VP56_MB_INTRA = 1, /**< Intra MB */ + VP56_MB_INTER_DELTA_PF = 2, /**< Inter MB, above/left vector + delta, from previous frame */ + VP56_MB_INTER_V1_PF = 3, /**< Inter MB, first vector, from previous frame */ + VP56_MB_INTER_V2_PF = 4, /**< Inter MB, second vector, from previous frame */ + VP56_MB_INTER_NOVEC_GF = 5, /**< Inter MB, no vector, from golden frame */ + VP56_MB_INTER_DELTA_GF = 6, /**< Inter MB, above/left vector + delta, from golden frame */ + VP56_MB_INTER_4V = 7, /**< Inter MB, 4 vectors, from previous frame */ + VP56_MB_INTER_V1_GF = 8, /**< Inter MB, first vector, from golden frame */ + VP56_MB_INTER_V2_GF = 9, /**< Inter MB, second vector, from golden frame */ +} VP56mb; + +typedef struct VP56Tree { + int8_t val; + int8_t prob_idx; +} VP56Tree; + typedef struct VP56mv { DECLARE_ALIGNED(4, int16_t, x); int16_t y; diff --git a/ffmpeg/libavcodec/vp56data.c b/ffmpeg/libavcodec/vp56data.c index 5500fe0..0080370 100644 --- a/ffmpeg/libavcodec/vp56data.c +++ b/ffmpeg/libavcodec/vp56data.c @@ -66,3 +66,189 @@ const VP56Tree ff_vp56_pc_tree[] = { const uint8_t ff_vp56_coeff_bias[] = { 0, 1, 2, 3, 4, 5, 7, 11, 19, 35, 67 }; const uint8_t ff_vp56_coeff_bit_length[] = { 0, 1, 2, 3, 4, 10 }; + +const VP56Frame ff_vp56_reference_frame[] = { + VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_NOVEC_PF */ + VP56_FRAME_CURRENT, /* VP56_MB_INTRA */ + VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_DELTA_PF */ + VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_V1_PF */ + VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_V2_PF */ + VP56_FRAME_GOLDEN, /* VP56_MB_INTER_NOVEC_GF */ + VP56_FRAME_GOLDEN, /* VP56_MB_INTER_DELTA_GF */ + VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_4V */ + VP56_FRAME_GOLDEN, /* VP56_MB_INTER_V1_GF */ + VP56_FRAME_GOLDEN, /* VP56_MB_INTER_V2_GF */ +}; + +const uint8_t ff_vp56_ac_dequant[64] = { + 94, 92, 90, 88, 86, 82, 78, 74, + 70, 66, 62, 58, 54, 53, 52, 51, + 50, 49, 48, 47, 46, 45, 44, 43, + 42, 40, 39, 37, 36, 35, 34, 33, + 32, 31, 30, 29, 28, 27, 26, 25, + 24, 23, 22, 21, 20, 19, 18, 17, + 16, 15, 14, 13, 12, 11, 10, 9, + 8, 7, 6, 5, 4, 3, 2, 1, +}; + +const uint8_t ff_vp56_dc_dequant[64] = { + 47, 47, 47, 47, 45, 43, 43, 43, + 43, 43, 42, 41, 41, 40, 40, 40, + 40, 35, 35, 35, 35, 33, 33, 33, + 33, 32, 32, 32, 27, 27, 26, 26, + 25, 25, 24, 24, 23, 23, 19, 19, + 19, 19, 18, 18, 17, 16, 16, 16, + 16, 16, 15, 11, 11, 11, 10, 10, + 9, 8, 7, 5, 3, 3, 2, 2, +}; + +const uint8_t ff_vp56_pre_def_mb_type_stats[16][3][10][2] = { + { { { 9, 15 }, { 32, 25 }, { 7, 19 }, { 9, 21 }, { 1, 12 }, + { 14, 12 }, { 3, 18 }, { 14, 23 }, { 3, 10 }, { 0, 4 }, }, + { { 41, 22 }, { 1, 0 }, { 1, 31 }, { 0, 0 }, { 0, 0 }, + { 0, 1 }, { 1, 7 }, { 0, 1 }, { 98, 25 }, { 4, 10 }, }, + { { 2, 3 }, { 2, 3 }, { 0, 2 }, { 0, 2 }, { 0, 0 }, + { 11, 4 }, { 1, 4 }, { 0, 2 }, { 3, 2 }, { 0, 4 }, }, }, + { { { 48, 39 }, { 1, 2 }, { 11, 27 }, { 29, 44 }, { 7, 27 }, + { 1, 4 }, { 0, 3 }, { 1, 6 }, { 1, 2 }, { 0, 0 }, }, + { { 123, 37 }, { 6, 4 }, { 1, 27 }, { 0, 0 }, { 0, 0 }, + { 5, 8 }, { 1, 7 }, { 0, 1 }, { 12, 10 }, { 0, 2 }, }, + { { 49, 46 }, { 3, 4 }, { 7, 31 }, { 42, 41 }, { 0, 0 }, + { 2, 6 }, { 1, 7 }, { 1, 4 }, { 2, 4 }, { 0, 1 }, }, }, + { { { 21, 32 }, { 1, 2 }, { 4, 10 }, { 32, 43 }, { 6, 23 }, + { 2, 3 }, { 1, 19 }, { 1, 6 }, { 12, 21 }, { 0, 7 }, }, + { { 26, 14 }, { 14, 12 }, { 0, 24 }, { 0, 0 }, { 0, 0 }, + { 55, 17 }, { 1, 9 }, { 0, 36 }, { 5, 7 }, { 1, 3 }, }, + { { 26, 25 }, { 1, 1 }, { 2, 10 }, { 67, 39 }, { 0, 0 }, + { 1, 1 }, { 0, 14 }, { 0, 2 }, { 31, 26 }, { 1, 6 }, }, }, + { { { 69, 83 }, { 0, 0 }, { 0, 2 }, { 10, 29 }, { 3, 12 }, + { 0, 1 }, { 0, 3 }, { 0, 3 }, { 2, 2 }, { 0, 0 }, }, + { { 209, 5 }, { 0, 0 }, { 0, 27 }, { 0, 0 }, { 0, 0 }, + { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, }, + { { 103, 46 }, { 1, 2 }, { 2, 10 }, { 33, 42 }, { 0, 0 }, + { 1, 4 }, { 0, 3 }, { 0, 1 }, { 1, 3 }, { 0, 0 }, }, }, + { { { 11, 20 }, { 1, 4 }, { 18, 36 }, { 43, 48 }, { 13, 35 }, + { 0, 2 }, { 0, 5 }, { 3, 12 }, { 1, 2 }, { 0, 0 }, }, + { { 2, 5 }, { 4, 5 }, { 0, 121 }, { 0, 0 }, { 0, 0 }, + { 0, 3 }, { 2, 4 }, { 1, 4 }, { 2, 2 }, { 0, 1 }, }, + { { 14, 31 }, { 9, 13 }, { 14, 54 }, { 22, 29 }, { 0, 0 }, + { 2, 6 }, { 4, 18 }, { 6, 13 }, { 1, 5 }, { 0, 1 }, }, }, + { { { 70, 44 }, { 0, 1 }, { 2, 10 }, { 37, 46 }, { 8, 26 }, + { 0, 2 }, { 0, 2 }, { 0, 2 }, { 0, 1 }, { 0, 0 }, }, + { { 175, 5 }, { 0, 1 }, { 0, 48 }, { 0, 0 }, { 0, 0 }, + { 0, 2 }, { 0, 1 }, { 0, 2 }, { 0, 1 }, { 0, 0 }, }, + { { 85, 39 }, { 0, 0 }, { 1, 9 }, { 69, 40 }, { 0, 0 }, + { 0, 1 }, { 0, 3 }, { 0, 1 }, { 2, 3 }, { 0, 0 }, }, }, + { { { 8, 15 }, { 0, 1 }, { 8, 21 }, { 74, 53 }, { 22, 42 }, + { 0, 1 }, { 0, 2 }, { 0, 3 }, { 1, 2 }, { 0, 0 }, }, + { { 83, 5 }, { 2, 3 }, { 0, 102 }, { 0, 0 }, { 0, 0 }, + { 1, 3 }, { 0, 2 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, }, + { { 31, 28 }, { 0, 0 }, { 3, 14 }, { 130, 34 }, { 0, 0 }, + { 0, 1 }, { 0, 3 }, { 0, 1 }, { 3, 3 }, { 0, 1 }, }, }, + { { { 141, 42 }, { 0, 0 }, { 1, 4 }, { 11, 24 }, { 1, 11 }, + { 0, 1 }, { 0, 1 }, { 0, 2 }, { 0, 0 }, { 0, 0 }, }, + { { 233, 6 }, { 0, 0 }, { 0, 8 }, { 0, 0 }, { 0, 0 }, + { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 1 }, { 0, 0 }, }, + { { 171, 25 }, { 0, 0 }, { 1, 5 }, { 25, 21 }, { 0, 0 }, + { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, }, }, + { { { 8, 19 }, { 4, 10 }, { 24, 45 }, { 21, 37 }, { 9, 29 }, + { 0, 3 }, { 1, 7 }, { 11, 25 }, { 0, 2 }, { 0, 1 }, }, + { { 34, 16 }, { 112, 21 }, { 1, 28 }, { 0, 0 }, { 0, 0 }, + { 6, 8 }, { 1, 7 }, { 0, 3 }, { 2, 5 }, { 0, 2 }, }, + { { 17, 21 }, { 68, 29 }, { 6, 15 }, { 13, 22 }, { 0, 0 }, + { 6, 12 }, { 3, 14 }, { 4, 10 }, { 1, 7 }, { 0, 3 }, }, }, + { { { 46, 42 }, { 0, 1 }, { 2, 10 }, { 54, 51 }, { 10, 30 }, + { 0, 2 }, { 0, 2 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, }, + { { 159, 35 }, { 2, 2 }, { 0, 25 }, { 0, 0 }, { 0, 0 }, + { 3, 6 }, { 0, 5 }, { 0, 1 }, { 4, 4 }, { 0, 1 }, }, + { { 51, 39 }, { 0, 1 }, { 2, 12 }, { 91, 44 }, { 0, 0 }, + { 0, 2 }, { 0, 3 }, { 0, 1 }, { 2, 3 }, { 0, 1 }, }, }, + { { { 28, 32 }, { 0, 0 }, { 3, 10 }, { 75, 51 }, { 14, 33 }, + { 0, 1 }, { 0, 2 }, { 0, 1 }, { 1, 2 }, { 0, 0 }, }, + { { 75, 39 }, { 5, 7 }, { 2, 48 }, { 0, 0 }, { 0, 0 }, + { 3, 11 }, { 2, 16 }, { 1, 4 }, { 7, 10 }, { 0, 2 }, }, + { { 81, 25 }, { 0, 0 }, { 2, 9 }, { 106, 26 }, { 0, 0 }, + { 0, 1 }, { 0, 1 }, { 0, 1 }, { 1, 1 }, { 0, 0 }, }, }, + { { { 100, 46 }, { 0, 1 }, { 3, 9 }, { 21, 37 }, { 5, 20 }, + { 0, 1 }, { 0, 2 }, { 1, 2 }, { 0, 1 }, { 0, 0 }, }, + { { 212, 21 }, { 0, 1 }, { 0, 9 }, { 0, 0 }, { 0, 0 }, + { 1, 2 }, { 0, 2 }, { 0, 0 }, { 2, 2 }, { 0, 0 }, }, + { { 140, 37 }, { 0, 1 }, { 1, 8 }, { 24, 33 }, { 0, 0 }, + { 1, 2 }, { 0, 2 }, { 0, 1 }, { 1, 2 }, { 0, 0 }, }, }, + { { { 27, 29 }, { 0, 1 }, { 9, 25 }, { 53, 51 }, { 12, 34 }, + { 0, 1 }, { 0, 3 }, { 1, 5 }, { 0, 2 }, { 0, 0 }, }, + { { 4, 2 }, { 0, 0 }, { 0, 172 }, { 0, 0 }, { 0, 0 }, + { 0, 1 }, { 0, 2 }, { 0, 0 }, { 2, 0 }, { 0, 0 }, }, + { { 14, 23 }, { 1, 3 }, { 11, 53 }, { 90, 31 }, { 0, 0 }, + { 0, 3 }, { 1, 5 }, { 2, 6 }, { 1, 2 }, { 0, 0 }, }, }, + { { { 80, 38 }, { 0, 0 }, { 1, 4 }, { 69, 33 }, { 5, 16 }, + { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 1 }, { 0, 0 }, }, + { { 187, 22 }, { 1, 1 }, { 0, 17 }, { 0, 0 }, { 0, 0 }, + { 3, 6 }, { 0, 4 }, { 0, 1 }, { 4, 4 }, { 0, 1 }, }, + { { 123, 29 }, { 0, 0 }, { 1, 7 }, { 57, 30 }, { 0, 0 }, + { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, }, }, + { { { 16, 20 }, { 0, 0 }, { 2, 8 }, { 104, 49 }, { 15, 33 }, + { 0, 1 }, { 0, 1 }, { 0, 1 }, { 1, 1 }, { 0, 0 }, }, + { { 133, 6 }, { 1, 2 }, { 1, 70 }, { 0, 0 }, { 0, 0 }, + { 0, 2 }, { 0, 4 }, { 0, 3 }, { 1, 1 }, { 0, 0 }, }, + { { 13, 14 }, { 0, 0 }, { 4, 20 }, { 175, 20 }, { 0, 0 }, + { 0, 1 }, { 0, 1 }, { 0, 1 }, { 1, 1 }, { 0, 0 }, }, }, + { { { 194, 16 }, { 0, 0 }, { 1, 1 }, { 1, 9 }, { 1, 3 }, + { 0, 0 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, }, + { { 251, 1 }, { 0, 0 }, { 0, 2 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, }, + { { 202, 23 }, { 0, 0 }, { 1, 3 }, { 2, 9 }, { 0, 0 }, + { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, }, }, +}; + +const uint8_t ff_vp56_filter_threshold[] = { + 14, 14, 13, 13, 12, 12, 10, 10, + 10, 10, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 7, 7, 7, 7, + 7, 7, 6, 6, 6, 6, 6, 6, + 5, 5, 5, 5, 4, 4, 4, 4, + 4, 4, 4, 3, 3, 3, 3, 2, +}; + +const uint8_t ff_vp56_mb_type_model_model[] = { + 171, 83, 199, 140, 125, 104, +}; + +const VP56Tree ff_vp56_pmbtm_tree[] = { + { 4, 0}, + { 2, 1}, {-8}, {-4}, + { 8, 2}, + { 6, 3}, + { 4, 4}, + { 2, 5}, {-24}, {-20}, {-16}, {-12}, {-0}, +}; + +const VP56Tree ff_vp56_pmbt_tree[] = { + { 8, 1}, + { 4, 2}, + { 2, 4}, {-VP56_MB_INTER_NOVEC_PF}, {-VP56_MB_INTER_DELTA_PF}, + { 2, 5}, {-VP56_MB_INTER_V1_PF}, {-VP56_MB_INTER_V2_PF}, + { 4, 3}, + { 2, 6}, {-VP56_MB_INTRA}, {-VP56_MB_INTER_4V}, + { 4, 7}, + { 2, 8}, {-VP56_MB_INTER_NOVEC_GF}, {-VP56_MB_INTER_DELTA_GF}, + { 2, 9}, {-VP56_MB_INTER_V1_GF}, {-VP56_MB_INTER_V2_GF}, +}; + +/* relative pos of surrounding blocks, from closest to farthest */ +const int8_t ff_vp56_candidate_predictor_pos[12][2] = { + { 0, -1 }, + { -1, 0 }, + { -1, -1 }, + { 1, -1 }, + { 0, -2 }, + { -2, 0 }, + { -2, -1 }, + { -1, -2 }, + { 1, -2 }, + { 2, -1 }, + { -2, -2 }, + { 2, -2 }, +}; diff --git a/ffmpeg/libavcodec/vp56data.h b/ffmpeg/libavcodec/vp56data.h index 3cafaaf..3be268c 100644 --- a/ffmpeg/libavcodec/vp56data.h +++ b/ffmpeg/libavcodec/vp56data.h @@ -27,32 +27,7 @@ #define AVCODEC_VP56DATA_H #include "libavutil/common.h" - -typedef enum { - VP56_FRAME_NONE =-1, - VP56_FRAME_CURRENT = 0, - VP56_FRAME_PREVIOUS = 1, - VP56_FRAME_GOLDEN = 2, - VP56_FRAME_GOLDEN2 = 3, -} VP56Frame; - -typedef enum { - VP56_MB_INTER_NOVEC_PF = 0, /**< Inter MB, no vector, from previous frame */ - VP56_MB_INTRA = 1, /**< Intra MB */ - VP56_MB_INTER_DELTA_PF = 2, /**< Inter MB, above/left vector + delta, from previous frame */ - VP56_MB_INTER_V1_PF = 3, /**< Inter MB, first vector, from previous frame */ - VP56_MB_INTER_V2_PF = 4, /**< Inter MB, second vector, from previous frame */ - VP56_MB_INTER_NOVEC_GF = 5, /**< Inter MB, no vector, from golden frame */ - VP56_MB_INTER_DELTA_GF = 6, /**< Inter MB, above/left vector + delta, from golden frame */ - VP56_MB_INTER_4V = 7, /**< Inter MB, 4 vectors, from previous frame */ - VP56_MB_INTER_V1_GF = 8, /**< Inter MB, first vector, from golden frame */ - VP56_MB_INTER_V2_GF = 9, /**< Inter MB, second vector, from golden frame */ -} VP56mb; - -typedef struct VP56Tree { - int8_t val; - int8_t prob_idx; -} VP56Tree; +#include "vp56.h" extern const uint8_t ff_vp56_b2p[]; extern const uint8_t ff_vp56_b6to4[]; @@ -63,190 +38,14 @@ extern const VP56Tree ff_vp56_pc_tree[]; extern const uint8_t ff_vp56_coeff_bias[]; extern const uint8_t ff_vp56_coeff_bit_length[]; -static const VP56Frame vp56_reference_frame[] = { - VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_NOVEC_PF */ - VP56_FRAME_CURRENT, /* VP56_MB_INTRA */ - VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_DELTA_PF */ - VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_V1_PF */ - VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_V2_PF */ - VP56_FRAME_GOLDEN, /* VP56_MB_INTER_NOVEC_GF */ - VP56_FRAME_GOLDEN, /* VP56_MB_INTER_DELTA_GF */ - VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_4V */ - VP56_FRAME_GOLDEN, /* VP56_MB_INTER_V1_GF */ - VP56_FRAME_GOLDEN, /* VP56_MB_INTER_V2_GF */ -}; - -static const uint8_t vp56_ac_dequant[64] = { - 94, 92, 90, 88, 86, 82, 78, 74, - 70, 66, 62, 58, 54, 53, 52, 51, - 50, 49, 48, 47, 46, 45, 44, 43, - 42, 40, 39, 37, 36, 35, 34, 33, - 32, 31, 30, 29, 28, 27, 26, 25, - 24, 23, 22, 21, 20, 19, 18, 17, - 16, 15, 14, 13, 12, 11, 10, 9, - 8, 7, 6, 5, 4, 3, 2, 1, -}; - -static const uint8_t vp56_dc_dequant[64] = { - 47, 47, 47, 47, 45, 43, 43, 43, - 43, 43, 42, 41, 41, 40, 40, 40, - 40, 35, 35, 35, 35, 33, 33, 33, - 33, 32, 32, 32, 27, 27, 26, 26, - 25, 25, 24, 24, 23, 23, 19, 19, - 19, 19, 18, 18, 17, 16, 16, 16, - 16, 16, 15, 11, 11, 11, 10, 10, - 9, 8, 7, 5, 3, 3, 2, 2, -}; - -static const uint8_t vp56_pre_def_mb_type_stats[16][3][10][2] = { - { { { 9, 15 }, { 32, 25 }, { 7, 19 }, { 9, 21 }, { 1, 12 }, - { 14, 12 }, { 3, 18 }, { 14, 23 }, { 3, 10 }, { 0, 4 }, }, - { { 41, 22 }, { 1, 0 }, { 1, 31 }, { 0, 0 }, { 0, 0 }, - { 0, 1 }, { 1, 7 }, { 0, 1 }, { 98, 25 }, { 4, 10 }, }, - { { 2, 3 }, { 2, 3 }, { 0, 2 }, { 0, 2 }, { 0, 0 }, - { 11, 4 }, { 1, 4 }, { 0, 2 }, { 3, 2 }, { 0, 4 }, }, }, - { { { 48, 39 }, { 1, 2 }, { 11, 27 }, { 29, 44 }, { 7, 27 }, - { 1, 4 }, { 0, 3 }, { 1, 6 }, { 1, 2 }, { 0, 0 }, }, - { { 123, 37 }, { 6, 4 }, { 1, 27 }, { 0, 0 }, { 0, 0 }, - { 5, 8 }, { 1, 7 }, { 0, 1 }, { 12, 10 }, { 0, 2 }, }, - { { 49, 46 }, { 3, 4 }, { 7, 31 }, { 42, 41 }, { 0, 0 }, - { 2, 6 }, { 1, 7 }, { 1, 4 }, { 2, 4 }, { 0, 1 }, }, }, - { { { 21, 32 }, { 1, 2 }, { 4, 10 }, { 32, 43 }, { 6, 23 }, - { 2, 3 }, { 1, 19 }, { 1, 6 }, { 12, 21 }, { 0, 7 }, }, - { { 26, 14 }, { 14, 12 }, { 0, 24 }, { 0, 0 }, { 0, 0 }, - { 55, 17 }, { 1, 9 }, { 0, 36 }, { 5, 7 }, { 1, 3 }, }, - { { 26, 25 }, { 1, 1 }, { 2, 10 }, { 67, 39 }, { 0, 0 }, - { 1, 1 }, { 0, 14 }, { 0, 2 }, { 31, 26 }, { 1, 6 }, }, }, - { { { 69, 83 }, { 0, 0 }, { 0, 2 }, { 10, 29 }, { 3, 12 }, - { 0, 1 }, { 0, 3 }, { 0, 3 }, { 2, 2 }, { 0, 0 }, }, - { { 209, 5 }, { 0, 0 }, { 0, 27 }, { 0, 0 }, { 0, 0 }, - { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, }, - { { 103, 46 }, { 1, 2 }, { 2, 10 }, { 33, 42 }, { 0, 0 }, - { 1, 4 }, { 0, 3 }, { 0, 1 }, { 1, 3 }, { 0, 0 }, }, }, - { { { 11, 20 }, { 1, 4 }, { 18, 36 }, { 43, 48 }, { 13, 35 }, - { 0, 2 }, { 0, 5 }, { 3, 12 }, { 1, 2 }, { 0, 0 }, }, - { { 2, 5 }, { 4, 5 }, { 0, 121 }, { 0, 0 }, { 0, 0 }, - { 0, 3 }, { 2, 4 }, { 1, 4 }, { 2, 2 }, { 0, 1 }, }, - { { 14, 31 }, { 9, 13 }, { 14, 54 }, { 22, 29 }, { 0, 0 }, - { 2, 6 }, { 4, 18 }, { 6, 13 }, { 1, 5 }, { 0, 1 }, }, }, - { { { 70, 44 }, { 0, 1 }, { 2, 10 }, { 37, 46 }, { 8, 26 }, - { 0, 2 }, { 0, 2 }, { 0, 2 }, { 0, 1 }, { 0, 0 }, }, - { { 175, 5 }, { 0, 1 }, { 0, 48 }, { 0, 0 }, { 0, 0 }, - { 0, 2 }, { 0, 1 }, { 0, 2 }, { 0, 1 }, { 0, 0 }, }, - { { 85, 39 }, { 0, 0 }, { 1, 9 }, { 69, 40 }, { 0, 0 }, - { 0, 1 }, { 0, 3 }, { 0, 1 }, { 2, 3 }, { 0, 0 }, }, }, - { { { 8, 15 }, { 0, 1 }, { 8, 21 }, { 74, 53 }, { 22, 42 }, - { 0, 1 }, { 0, 2 }, { 0, 3 }, { 1, 2 }, { 0, 0 }, }, - { { 83, 5 }, { 2, 3 }, { 0, 102 }, { 0, 0 }, { 0, 0 }, - { 1, 3 }, { 0, 2 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, }, - { { 31, 28 }, { 0, 0 }, { 3, 14 }, { 130, 34 }, { 0, 0 }, - { 0, 1 }, { 0, 3 }, { 0, 1 }, { 3, 3 }, { 0, 1 }, }, }, - { { { 141, 42 }, { 0, 0 }, { 1, 4 }, { 11, 24 }, { 1, 11 }, - { 0, 1 }, { 0, 1 }, { 0, 2 }, { 0, 0 }, { 0, 0 }, }, - { { 233, 6 }, { 0, 0 }, { 0, 8 }, { 0, 0 }, { 0, 0 }, - { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 1 }, { 0, 0 }, }, - { { 171, 25 }, { 0, 0 }, { 1, 5 }, { 25, 21 }, { 0, 0 }, - { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, }, }, - { { { 8, 19 }, { 4, 10 }, { 24, 45 }, { 21, 37 }, { 9, 29 }, - { 0, 3 }, { 1, 7 }, { 11, 25 }, { 0, 2 }, { 0, 1 }, }, - { { 34, 16 }, { 112, 21 }, { 1, 28 }, { 0, 0 }, { 0, 0 }, - { 6, 8 }, { 1, 7 }, { 0, 3 }, { 2, 5 }, { 0, 2 }, }, - { { 17, 21 }, { 68, 29 }, { 6, 15 }, { 13, 22 }, { 0, 0 }, - { 6, 12 }, { 3, 14 }, { 4, 10 }, { 1, 7 }, { 0, 3 }, }, }, - { { { 46, 42 }, { 0, 1 }, { 2, 10 }, { 54, 51 }, { 10, 30 }, - { 0, 2 }, { 0, 2 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, }, - { { 159, 35 }, { 2, 2 }, { 0, 25 }, { 0, 0 }, { 0, 0 }, - { 3, 6 }, { 0, 5 }, { 0, 1 }, { 4, 4 }, { 0, 1 }, }, - { { 51, 39 }, { 0, 1 }, { 2, 12 }, { 91, 44 }, { 0, 0 }, - { 0, 2 }, { 0, 3 }, { 0, 1 }, { 2, 3 }, { 0, 1 }, }, }, - { { { 28, 32 }, { 0, 0 }, { 3, 10 }, { 75, 51 }, { 14, 33 }, - { 0, 1 }, { 0, 2 }, { 0, 1 }, { 1, 2 }, { 0, 0 }, }, - { { 75, 39 }, { 5, 7 }, { 2, 48 }, { 0, 0 }, { 0, 0 }, - { 3, 11 }, { 2, 16 }, { 1, 4 }, { 7, 10 }, { 0, 2 }, }, - { { 81, 25 }, { 0, 0 }, { 2, 9 }, { 106, 26 }, { 0, 0 }, - { 0, 1 }, { 0, 1 }, { 0, 1 }, { 1, 1 }, { 0, 0 }, }, }, - { { { 100, 46 }, { 0, 1 }, { 3, 9 }, { 21, 37 }, { 5, 20 }, - { 0, 1 }, { 0, 2 }, { 1, 2 }, { 0, 1 }, { 0, 0 }, }, - { { 212, 21 }, { 0, 1 }, { 0, 9 }, { 0, 0 }, { 0, 0 }, - { 1, 2 }, { 0, 2 }, { 0, 0 }, { 2, 2 }, { 0, 0 }, }, - { { 140, 37 }, { 0, 1 }, { 1, 8 }, { 24, 33 }, { 0, 0 }, - { 1, 2 }, { 0, 2 }, { 0, 1 }, { 1, 2 }, { 0, 0 }, }, }, - { { { 27, 29 }, { 0, 1 }, { 9, 25 }, { 53, 51 }, { 12, 34 }, - { 0, 1 }, { 0, 3 }, { 1, 5 }, { 0, 2 }, { 0, 0 }, }, - { { 4, 2 }, { 0, 0 }, { 0, 172 }, { 0, 0 }, { 0, 0 }, - { 0, 1 }, { 0, 2 }, { 0, 0 }, { 2, 0 }, { 0, 0 }, }, - { { 14, 23 }, { 1, 3 }, { 11, 53 }, { 90, 31 }, { 0, 0 }, - { 0, 3 }, { 1, 5 }, { 2, 6 }, { 1, 2 }, { 0, 0 }, }, }, - { { { 80, 38 }, { 0, 0 }, { 1, 4 }, { 69, 33 }, { 5, 16 }, - { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 1 }, { 0, 0 }, }, - { { 187, 22 }, { 1, 1 }, { 0, 17 }, { 0, 0 }, { 0, 0 }, - { 3, 6 }, { 0, 4 }, { 0, 1 }, { 4, 4 }, { 0, 1 }, }, - { { 123, 29 }, { 0, 0 }, { 1, 7 }, { 57, 30 }, { 0, 0 }, - { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, }, }, - { { { 16, 20 }, { 0, 0 }, { 2, 8 }, { 104, 49 }, { 15, 33 }, - { 0, 1 }, { 0, 1 }, { 0, 1 }, { 1, 1 }, { 0, 0 }, }, - { { 133, 6 }, { 1, 2 }, { 1, 70 }, { 0, 0 }, { 0, 0 }, - { 0, 2 }, { 0, 4 }, { 0, 3 }, { 1, 1 }, { 0, 0 }, }, - { { 13, 14 }, { 0, 0 }, { 4, 20 }, { 175, 20 }, { 0, 0 }, - { 0, 1 }, { 0, 1 }, { 0, 1 }, { 1, 1 }, { 0, 0 }, }, }, - { { { 194, 16 }, { 0, 0 }, { 1, 1 }, { 1, 9 }, { 1, 3 }, - { 0, 0 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, }, - { { 251, 1 }, { 0, 0 }, { 0, 2 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, }, - { { 202, 23 }, { 0, 0 }, { 1, 3 }, { 2, 9 }, { 0, 0 }, - { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, }, }, -}; - -static const uint8_t vp56_filter_threshold[] = { - 14, 14, 13, 13, 12, 12, 10, 10, - 10, 10, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 7, 7, 7, 7, - 7, 7, 6, 6, 6, 6, 6, 6, - 5, 5, 5, 5, 4, 4, 4, 4, - 4, 4, 4, 3, 3, 3, 3, 2, -}; - -static const uint8_t vp56_mb_type_model_model[] = { - 171, 83, 199, 140, 125, 104, -}; - -static const VP56Tree vp56_pmbtm_tree[] = { - { 4, 0}, - { 2, 1}, {-8}, {-4}, - { 8, 2}, - { 6, 3}, - { 4, 4}, - { 2, 5}, {-24}, {-20}, {-16}, {-12}, {-0}, -}; - -static const VP56Tree vp56_pmbt_tree[] = { - { 8, 1}, - { 4, 2}, - { 2, 4}, {-VP56_MB_INTER_NOVEC_PF}, {-VP56_MB_INTER_DELTA_PF}, - { 2, 5}, {-VP56_MB_INTER_V1_PF}, {-VP56_MB_INTER_V2_PF}, - { 4, 3}, - { 2, 6}, {-VP56_MB_INTRA}, {-VP56_MB_INTER_4V}, - { 4, 7}, - { 2, 8}, {-VP56_MB_INTER_NOVEC_GF}, {-VP56_MB_INTER_DELTA_GF}, - { 2, 9}, {-VP56_MB_INTER_V1_GF}, {-VP56_MB_INTER_V2_GF}, -}; - -/* relative pos of surrounding blocks, from closest to farthest */ -static const int8_t vp56_candidate_predictor_pos[12][2] = { - { 0, -1 }, - { -1, 0 }, - { -1, -1 }, - { 1, -1 }, - { 0, -2 }, - { -2, 0 }, - { -2, -1 }, - { -1, -2 }, - { 1, -2 }, - { 2, -1 }, - { -2, -2 }, - { 2, -2 }, -}; +extern const VP56Frame ff_vp56_reference_frame[]; +extern const uint8_t ff_vp56_ac_dequant[64]; +extern const uint8_t ff_vp56_dc_dequant[64]; +extern const uint8_t ff_vp56_pre_def_mb_type_stats[16][3][10][2]; +extern const uint8_t ff_vp56_filter_threshold[]; +extern const uint8_t ff_vp56_mb_type_model_model[]; +extern const VP56Tree ff_vp56_pmbtm_tree[]; +extern const VP56Tree ff_vp56_pmbt_tree[]; +extern const int8_t ff_vp56_candidate_predictor_pos[12][2]; #endif /* AVCODEC_VP56DATA_H */ diff --git a/ffmpeg/libavcodec/vp56dsp.c b/ffmpeg/libavcodec/vp56dsp.c index a72c48e..fa533ec 100644 --- a/ffmpeg/libavcodec/vp56dsp.c +++ b/ffmpeg/libavcodec/vp56dsp.c @@ -20,6 +20,8 @@ */ #include + +#include "libavutil/attributes.h" #include "avcodec.h" #include "vp56dsp.h" #include "libavutil/common.h" @@ -75,7 +77,7 @@ VP56_EDGE_FILTER(vp5, ver, stride, 1) VP56_EDGE_FILTER(vp6, hor, 1, stride) VP56_EDGE_FILTER(vp6, ver, stride, 1) -void ff_vp56dsp_init(VP56DSPContext *s, enum AVCodecID codec) +av_cold void ff_vp56dsp_init(VP56DSPContext *s, enum AVCodecID codec) { if (codec == AV_CODEC_ID_VP5) { s->edge_filter_hor = vp5_edge_filter_hor; @@ -86,9 +88,11 @@ void ff_vp56dsp_init(VP56DSPContext *s, enum AVCodecID codec) if (CONFIG_VP6_DECODER) { s->vp6_filter_diag4 = ff_vp6_filter_diag4_c; + + if (ARCH_ARM) + ff_vp6dsp_init_arm(s, codec); + if (ARCH_X86) + ff_vp6dsp_init_x86(s, codec); } } - - if (ARCH_ARM) ff_vp56dsp_init_arm(s, codec); - if (ARCH_X86) ff_vp56dsp_init_x86(s, codec); } diff --git a/ffmpeg/libavcodec/vp56dsp.h b/ffmpeg/libavcodec/vp56dsp.h index 51e8c16..7807baa 100644 --- a/ffmpeg/libavcodec/vp56dsp.h +++ b/ffmpeg/libavcodec/vp56dsp.h @@ -36,7 +36,7 @@ void ff_vp6_filter_diag4_c(uint8_t *dst, uint8_t *src, int stride, const int16_t *h_weights, const int16_t *v_weights); void ff_vp56dsp_init(VP56DSPContext *s, enum AVCodecID codec); -void ff_vp56dsp_init_arm(VP56DSPContext *s, enum AVCodecID codec); -void ff_vp56dsp_init_x86(VP56DSPContext* c, enum AVCodecID codec); +void ff_vp6dsp_init_arm(VP56DSPContext *s, enum AVCodecID codec); +void ff_vp6dsp_init_x86(VP56DSPContext* c, enum AVCodecID codec); #endif /* AVCODEC_VP56DSP_H */ diff --git a/ffmpeg/libavcodec/vp6.c b/ffmpeg/libavcodec/vp6.c index 6e385ce..f552524 100644 --- a/ffmpeg/libavcodec/vp6.c +++ b/ffmpeg/libavcodec/vp6.c @@ -32,6 +32,7 @@ #include "avcodec.h" #include "get_bits.h" #include "huffman.h" +#include "internal.h" #include "vp56.h" #include "vp56data.h" @@ -83,10 +84,23 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size) if (!s->macroblocks || /* first frame */ 16*cols != s->avctx->coded_width || 16*rows != s->avctx->coded_height) { - avcodec_set_dimensions(s->avctx, 16*cols, 16*rows); - if (s->avctx->extradata_size == 1) { - s->avctx->width -= s->avctx->extradata[0] >> 4; - s->avctx->height -= s->avctx->extradata[0] & 0x0F; + if (s->avctx->extradata_size == 0 && + FFALIGN(s->avctx->width, 16) == 16 * cols && + FFALIGN(s->avctx->height, 16) == 16 * rows) { + // We assume this is properly signalled container cropping, + // in an F4V file. Just set the coded_width/height, don't + // touch the cropped ones. + s->avctx->coded_width = 16 * cols; + s->avctx->coded_height = 16 * rows; + } else { + int ret = ff_set_dimensions(s->avctx, 16 * cols, 16 * rows); + if (ret < 0) + return ret; + + if (s->avctx->extradata_size == 1) { + s->avctx->width -= s->avctx->extradata[0] >> 4; + s->avctx->height -= s->avctx->extradata[0] & 0x0F; + } } res = VP56_SIZE_CHANGE; } @@ -144,7 +158,7 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size) buf_size -= coeff_offset; if (buf_size < 0) { if (s->frames[VP56_FRAME_CURRENT]->key_frame) - avcodec_set_dimensions(s->avctx, 0, 0); + ff_set_dimensions(s->avctx, 0, 0); return AVERROR_INVALIDDATA; } if (s->use_huffman) { @@ -238,7 +252,8 @@ static int vp6_build_huff_tree(VP56Context *s, uint8_t coeff_model[], ff_free_vlc(vlc); /* then build the huffman tree according to probabilities */ - return ff_huff_build_tree(s->avctx, vlc, size, nodes, vp6_huff_cmp, + return ff_huff_build_tree(s->avctx, vlc, size, FF_HUFFMAN_BITS, + nodes, vp6_huff_cmp, FF_HUFFMAN_FLAG_HNODE_FIRST); } @@ -388,11 +403,11 @@ static void vp6_parse_coeff_huffman(VP56Context *s) } else { if (get_bits_left(&s->gb) <= 0) return; - coeff = get_vlc2(&s->gb, vlc_coeff->table, 9, 3); + coeff = get_vlc2(&s->gb, vlc_coeff->table, FF_HUFFMAN_BITS, 3); if (coeff == 0) { if (coeff_idx) { int pt = (coeff_idx >= 6); - run += get_vlc2(&s->gb, s->runv_vlc[pt].table, 9, 3); + run += get_vlc2(&s->gb, s->runv_vlc[pt].table, FF_HUFFMAN_BITS, 3); if (run >= 9) run += get_bits(&s->gb, 6); } else @@ -657,6 +672,7 @@ static av_cold void vp6_decode_free_context(VP56Context *s) AVCodec ff_vp6_decoder = { .name = "vp6", + .long_name = NULL_IF_CONFIG_SMALL("On2 VP6"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VP6, .priv_data_size = sizeof(VP56Context), @@ -664,12 +680,12 @@ AVCodec ff_vp6_decoder = { .close = vp6_decode_free, .decode = ff_vp56_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("On2 VP6"), }; /* flash version, not flipped upside-down */ AVCodec ff_vp6f_decoder = { .name = "vp6f", + .long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VP6F, .priv_data_size = sizeof(VP56Context), @@ -677,12 +693,12 @@ AVCodec ff_vp6f_decoder = { .close = vp6_decode_free, .decode = ff_vp56_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version)"), }; /* flash version, not flipped upside-down, with alpha channel */ AVCodec ff_vp6a_decoder = { .name = "vp6a", + .long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version, with alpha channel)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VP6A, .priv_data_size = sizeof(VP56Context), @@ -690,5 +706,4 @@ AVCodec ff_vp6a_decoder = { .close = vp6_decode_free, .decode = ff_vp56_decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS, - .long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version, with alpha channel)"), }; diff --git a/ffmpeg/libavcodec/vp6data.h b/ffmpeg/libavcodec/vp6data.h index 3ebfd0e..539e19a 100644 --- a/ffmpeg/libavcodec/vp6data.h +++ b/ffmpeg/libavcodec/vp6data.h @@ -26,7 +26,9 @@ #ifndef AVCODEC_VP6DATA_H #define AVCODEC_VP6DATA_H -#include "vp56data.h" +#include + +#include "vp56.h" static const uint8_t vp6_def_fdv_vector_model[2][8] = { { 247, 210, 135, 68, 138, 220, 239, 246 }, diff --git a/ffmpeg/libavcodec/vp8.c b/ffmpeg/libavcodec/vp8.c index ac929d0..0e4a36d 100644 --- a/ffmpeg/libavcodec/vp8.c +++ b/ffmpeg/libavcodec/vp8.c @@ -40,8 +40,11 @@ static void free_buffers(VP8Context *s) int i; if (s->thread_data) for (i = 0; i < MAX_THREADS; i++) { +#if HAVE_THREADS + pthread_cond_destroy(&s->thread_data[i].cond); + pthread_mutex_destroy(&s->thread_data[i].lock); +#endif av_freep(&s->thread_data[i].filter_strength); - av_freep(&s->thread_data[i].edge_emu_buffer); } av_freep(&s->thread_data); av_freep(&s->macroblocks_base); @@ -110,16 +113,15 @@ static void vp8_decode_flush(AVCodecContext *avctx) static int update_dimensions(VP8Context *s, int width, int height) { AVCodecContext *avctx = s->avctx; - int i; + int i, ret; if (width != s->avctx->width || ((width+15)/16 != s->mb_width || (height+15)/16 != s->mb_height) && s->macroblocks_base || height != s->avctx->height) { - if (av_image_check_size(width, height, 0, s->avctx)) - return AVERROR_INVALIDDATA; - vp8_decode_flush_impl(s->avctx, 1); - avcodec_set_dimensions(s->avctx, width, height); + ret = ff_set_dimensions(s->avctx, width, height); + if (ret < 0) + return ret; } s->mb_width = (s->avctx->coded_width +15) / 16; @@ -1176,13 +1178,13 @@ static av_always_inline void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst, ThreadFrame *ref, const VP56mv *mv, int x_off, int y_off, int block_w, int block_h, - int width, int height, int linesize, + int width, int height, ptrdiff_t linesize, vp8_mc_func mc_func[3][3]) { uint8_t *src = ref->f->data[0]; if (AV_RN32A(mv)) { - + int src_linesize = linesize; int mx = (mv->x << 1)&7, mx_idx = subpel_idx[0][mx]; int my = (mv->y << 1)&7, my_idx = subpel_idx[0][my]; @@ -1194,12 +1196,16 @@ void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst, src += y_off * linesize + x_off; if (x_off < mx_idx || x_off >= width - block_w - subpel_idx[2][mx] || y_off < my_idx || y_off >= height - block_h - subpel_idx[2][my]) { - s->vdsp.emulated_edge_mc(td->edge_emu_buffer, src - my_idx * linesize - mx_idx, linesize, - block_w + subpel_idx[1][mx], block_h + subpel_idx[1][my], + s->vdsp.emulated_edge_mc(td->edge_emu_buffer, + src - my_idx * linesize - mx_idx, + 32, linesize, + block_w + subpel_idx[1][mx], + block_h + subpel_idx[1][my], x_off - mx_idx, y_off - my_idx, width, height); - src = td->edge_emu_buffer + mx_idx + linesize * my_idx; + src = td->edge_emu_buffer + mx_idx + 32 * my_idx; + src_linesize = 32; } - mc_func[my_idx][mx_idx](dst, linesize, src, linesize, block_h, mx, my); + mc_func[my_idx][mx_idx](dst, linesize, src, src_linesize, block_h, mx, my); } else { ff_thread_await_progress(ref, (3 + y_off + block_h) >> 4, 0); mc_func[0][0](dst, linesize, src + y_off * linesize + x_off, linesize, block_h, 0, 0); @@ -1226,7 +1232,7 @@ void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst, static av_always_inline void vp8_mc_chroma(VP8Context *s, VP8ThreadData *td, uint8_t *dst1, uint8_t *dst2, ThreadFrame *ref, const VP56mv *mv, int x_off, int y_off, - int block_w, int block_h, int width, int height, int linesize, + int block_w, int block_h, int width, int height, ptrdiff_t linesize, vp8_mc_func mc_func[3][3]) { uint8_t *src1 = ref->f->data[1], *src2 = ref->f->data[2]; @@ -1244,17 +1250,23 @@ void vp8_mc_chroma(VP8Context *s, VP8ThreadData *td, uint8_t *dst1, uint8_t *dst ff_thread_await_progress(ref, (3 + y_off + block_h + subpel_idx[2][my]) >> 3, 0); if (x_off < mx_idx || x_off >= width - block_w - subpel_idx[2][mx] || y_off < my_idx || y_off >= height - block_h - subpel_idx[2][my]) { - s->vdsp.emulated_edge_mc(td->edge_emu_buffer, src1 - my_idx * linesize - mx_idx, linesize, - block_w + subpel_idx[1][mx], block_h + subpel_idx[1][my], + s->vdsp.emulated_edge_mc(td->edge_emu_buffer, + src1 - my_idx * linesize - mx_idx, + 32, linesize, + block_w + subpel_idx[1][mx], + block_h + subpel_idx[1][my], x_off - mx_idx, y_off - my_idx, width, height); - src1 = td->edge_emu_buffer + mx_idx + linesize * my_idx; - mc_func[my_idx][mx_idx](dst1, linesize, src1, linesize, block_h, mx, my); - - s->vdsp.emulated_edge_mc(td->edge_emu_buffer, src2 - my_idx * linesize - mx_idx, linesize, - block_w + subpel_idx[1][mx], block_h + subpel_idx[1][my], + src1 = td->edge_emu_buffer + mx_idx + 32 * my_idx; + mc_func[my_idx][mx_idx](dst1, linesize, src1, 32, block_h, mx, my); + + s->vdsp.emulated_edge_mc(td->edge_emu_buffer, + src2 - my_idx * linesize - mx_idx, + 32, linesize, + block_w + subpel_idx[1][mx], + block_h + subpel_idx[1][my], x_off - mx_idx, y_off - my_idx, width, height); - src2 = td->edge_emu_buffer + mx_idx + linesize * my_idx; - mc_func[my_idx][mx_idx](dst2, linesize, src2, linesize, block_h, mx, my); + src2 = td->edge_emu_buffer + mx_idx + 32 * my_idx; + mc_func[my_idx][mx_idx](dst2, linesize, src2, 32, block_h, mx, my); } else { mc_func[my_idx][mx_idx](dst1, linesize, src1, linesize, block_h, mx, my); mc_func[my_idx][mx_idx](dst2, linesize, src2, linesize, block_h, mx, my); @@ -1676,6 +1688,11 @@ static void vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, if (s->mb_layout == 1) mb = s->macroblocks_base + ((s->mb_width+1)*(mb_y + 1) + 1); else { + // Make sure the previous frame has read its segmentation map, + // if we re-use the same map. + if (prev_frame && s->segmentation.enabled && + !s->segmentation.update_map) + ff_thread_await_progress(&prev_frame->tf, mb_y, 0); mb = s->macroblocks + (s->mb_height - mb_y - 1)*2; memset(mb - 1, 0, sizeof(*mb)); // zero left macroblock AV_WN32A(s->intra4x4_pred_mode_left, DC_PRED*0x01010101); @@ -1845,8 +1862,8 @@ static int vp8_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, return 0; } -static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, - AVPacket *avpkt) +int ff_vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, + AVPacket *avpkt) { VP8Context *s = avctx->priv_data; int ret, i, referenced, num_jobs; @@ -1935,10 +1952,6 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, s->linesize = curframe->tf.f->linesize[0]; s->uvlinesize = curframe->tf.f->linesize[1]; - if (!s->thread_data[0].edge_emu_buffer) - for (i = 0; i < MAX_THREADS; i++) - s->thread_data[i].edge_emu_buffer = av_malloc(21*s->linesize); - memset(s->top_nnz, 0, s->mb_width*sizeof(*s->top_nnz)); /* Zero macroblock structures for top/top-left prediction from outside the frame. */ if (!s->mb_layout) @@ -1955,13 +1968,14 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, memset(s->ref_count, 0, sizeof(s->ref_count)); - // Make sure the previous frame has read its segmentation map, - // if we re-use the same map. - if (prev_frame && s->segmentation.enabled && !s->segmentation.update_map) - ff_thread_await_progress(&prev_frame->tf, 1, 0); - - if (s->mb_layout == 1) + if (s->mb_layout == 1) { + // Make sure the previous frame has read its segmentation map, + // if we re-use the same map. + if (prev_frame && s->segmentation.enabled && + !s->segmentation.update_map) + ff_thread_await_progress(&prev_frame->tf, 1, 0); vp8_decode_mv_mb_modes(avctx, curframe, prev_frame); + } if (avctx->active_thread_type == FF_THREAD_FRAME) num_jobs = 1; @@ -1999,7 +2013,7 @@ err: return ret; } -static av_cold int vp8_decode_free(AVCodecContext *avctx) +av_cold int ff_vp8_decode_free(AVCodecContext *avctx) { VP8Context *s = avctx->priv_data; int i; @@ -2022,7 +2036,7 @@ static av_cold int vp8_init_frames(VP8Context *s) return 0; } -static av_cold int vp8_decode_init(AVCodecContext *avctx) +av_cold int ff_vp8_decode_init(AVCodecContext *avctx) { VP8Context *s = avctx->priv_data; int ret; @@ -2036,7 +2050,7 @@ static av_cold int vp8_decode_init(AVCodecContext *avctx) ff_vp8dsp_init(&s->vp8dsp); if ((ret = vp8_init_frames(s)) < 0) { - vp8_decode_free(avctx); + ff_vp8_decode_free(avctx); return ret; } @@ -2051,7 +2065,7 @@ static av_cold int vp8_decode_init_thread_copy(AVCodecContext *avctx) s->avctx = avctx; if ((ret = vp8_init_frames(s)) < 0) { - vp8_decode_free(avctx); + ff_vp8_decode_free(avctx); return ret; } @@ -2096,15 +2110,16 @@ static int vp8_decode_update_thread_context(AVCodecContext *dst, const AVCodecCo AVCodec ff_vp8_decoder = { .name = "vp8", + .long_name = NULL_IF_CONFIG_SMALL("On2 VP8"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VP8, .priv_data_size = sizeof(VP8Context), - .init = vp8_decode_init, - .close = vp8_decode_free, - .decode = vp8_decode_frame, + .init = ff_vp8_decode_init, + .close = ff_vp8_decode_free, + .decode = ff_vp8_decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS | CODEC_CAP_SLICE_THREADS, .flush = vp8_decode_flush, - .long_name = NULL_IF_CONFIG_SMALL("On2 VP8"), .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp8_decode_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(vp8_decode_update_thread_context), }; + diff --git a/ffmpeg/libavcodec/vp8.h b/ffmpeg/libavcodec/vp8.h index 90109ad..c9a7906 100644 --- a/ffmpeg/libavcodec/vp8.h +++ b/ffmpeg/libavcodec/vp8.h @@ -29,16 +29,15 @@ #include "libavutil/buffer.h" #include "vp56.h" -#include "vp56data.h" #include "vp8dsp.h" #include "h264pred.h" #include "thread.h" #if HAVE_PTHREADS #include -#elif HAVE_W32THREADS -#include "w32pthreads.h" #elif HAVE_OS2THREADS -#include "os2threads.h" +#include "compat/os2threads.h" +#elif HAVE_W32THREADS +#include "compat/w32pthreads.h" #endif #define VP8_MAX_QUANT 127 @@ -123,7 +122,7 @@ typedef struct VP8ThreadData { #endif int thread_mb_pos; // (mb_y << 16) | (mb_x & 0xFFFF) int wait_mb_pos; // What the current thread is waiting on. - uint8_t *edge_emu_buffer; + DECLARE_ALIGNED(16, uint8_t, edge_emu_buffer)[21*32]; VP8FilterStrength *filter_strength; } VP8ThreadData; @@ -272,4 +271,11 @@ typedef struct VP8Context { int mb_layout; } VP8Context; +int ff_vp8_decode_init(AVCodecContext *avctx); + +int ff_vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, + AVPacket *avpkt); + +int ff_vp8_decode_free(AVCodecContext *avctx); + #endif /* AVCODEC_VP8_H */ diff --git a/ffmpeg/libavcodec/vp8dsp.c b/ffmpeg/libavcodec/vp8dsp.c index 017278e..ba267fd 100644 --- a/ffmpeg/libavcodec/vp8dsp.c +++ b/ffmpeg/libavcodec/vp8dsp.c @@ -160,7 +160,7 @@ static av_always_inline void filter_common(uint8_t *p, ptrdiff_t stride, int is4 { LOAD_PIXELS int a, f1, f2; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; a = 3*(q0 - p0); @@ -215,7 +215,7 @@ static av_always_inline int hev(uint8_t *p, ptrdiff_t stride, int thresh) static av_always_inline void filter_mbedge(uint8_t *p, ptrdiff_t stride) { int a0, a1, a2, w; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; LOAD_PIXELS @@ -337,7 +337,7 @@ PUT_PIXELS(4) static void put_vp8_epel ## SIZE ## _h ## TAPS ## _c(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my) \ { \ const uint8_t *filter = subpel_filters[mx-1]; \ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; \ + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; \ int x, y; \ \ for (y = 0; y < h; y++) { \ @@ -351,7 +351,7 @@ static void put_vp8_epel ## SIZE ## _h ## TAPS ## _c(uint8_t *dst, ptrdiff_t dst static void put_vp8_epel ## SIZE ## _v ## TAPS ## _c(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my) \ { \ const uint8_t *filter = subpel_filters[my-1]; \ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; \ + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; \ int x, y; \ \ for (y = 0; y < h; y++) { \ @@ -365,7 +365,7 @@ static void put_vp8_epel ## SIZE ## _v ## TAPS ## _c(uint8_t *dst, ptrdiff_t dst static void put_vp8_epel ## SIZE ## _h ## HTAPS ## v ## VTAPS ## _c(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my) \ { \ const uint8_t *filter = subpel_filters[mx-1]; \ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; \ + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; \ int x, y; \ uint8_t tmp_array[(2*SIZE+VTAPS-1)*SIZE]; \ uint8_t *tmp = tmp_array; \ @@ -415,7 +415,7 @@ VP8_EPEL_HV(8, 6, 6) VP8_EPEL_HV(4, 6, 6) #define VP8_BILINEAR(SIZE) \ -static void put_vp8_bilinear ## SIZE ## _h_c(uint8_t *dst, ptrdiff_t stride, uint8_t *src, ptrdiff_t s2, int h, int mx, int my) \ +static void put_vp8_bilinear ## SIZE ## _h_c(uint8_t *dst, ptrdiff_t dstride, uint8_t *src, ptrdiff_t sstride, int h, int mx, int my) \ { \ int a = 8-mx, b = mx; \ int x, y; \ @@ -423,24 +423,24 @@ static void put_vp8_bilinear ## SIZE ## _h_c(uint8_t *dst, ptrdiff_t stride, uin for (y = 0; y < h; y++) { \ for (x = 0; x < SIZE; x++) \ dst[x] = (a*src[x] + b*src[x+1] + 4) >> 3; \ - dst += stride; \ - src += stride; \ + dst += dstride; \ + src += sstride; \ } \ } \ -static void put_vp8_bilinear ## SIZE ## _v_c(uint8_t *dst, ptrdiff_t stride, uint8_t *src, ptrdiff_t s2, int h, int mx, int my) \ +static void put_vp8_bilinear ## SIZE ## _v_c(uint8_t *dst, ptrdiff_t dstride, uint8_t *src, ptrdiff_t sstride, int h, int mx, int my) \ { \ int c = 8-my, d = my; \ int x, y; \ \ for (y = 0; y < h; y++) { \ for (x = 0; x < SIZE; x++) \ - dst[x] = (c*src[x] + d*src[x+stride] + 4) >> 3; \ - dst += stride; \ - src += stride; \ + dst[x] = (c*src[x] + d*src[x+sstride] + 4) >> 3; \ + dst += dstride; \ + src += sstride; \ } \ } \ \ -static void put_vp8_bilinear ## SIZE ## _hv_c(uint8_t *dst, ptrdiff_t stride, uint8_t *src, ptrdiff_t s2, int h, int mx, int my) \ +static void put_vp8_bilinear ## SIZE ## _hv_c(uint8_t *dst, ptrdiff_t dstride, uint8_t *src, ptrdiff_t sstride, int h, int mx, int my) \ { \ int a = 8-mx, b = mx; \ int c = 8-my, d = my; \ @@ -452,7 +452,7 @@ static void put_vp8_bilinear ## SIZE ## _hv_c(uint8_t *dst, ptrdiff_t stride, ui for (x = 0; x < SIZE; x++) \ tmp[x] = (a*src[x] + b*src[x+1] + 4) >> 3; \ tmp += SIZE; \ - src += stride; \ + src += sstride; \ } \ \ tmp = tmp_array; \ @@ -460,7 +460,7 @@ static void put_vp8_bilinear ## SIZE ## _hv_c(uint8_t *dst, ptrdiff_t stride, ui for (y = 0; y < h; y++) { \ for (x = 0; x < SIZE; x++) \ dst[x] = (c*tmp[x] + d*tmp[x+SIZE] + 4) >> 3; \ - dst += stride; \ + dst += dstride; \ tmp += SIZE; \ } \ } @@ -521,10 +521,10 @@ av_cold void ff_vp8dsp_init(VP8DSPContext *dsp) VP8_BILINEAR_MC_FUNC(1, 8); VP8_BILINEAR_MC_FUNC(2, 4); - if (ARCH_X86) - ff_vp8dsp_init_x86(dsp); - if (HAVE_ALTIVEC) - ff_vp8dsp_init_altivec(dsp); if (ARCH_ARM) ff_vp8dsp_init_arm(dsp); + if (ARCH_PPC) + ff_vp8dsp_init_ppc(dsp); + if (ARCH_X86) + ff_vp8dsp_init_x86(dsp); } diff --git a/ffmpeg/libavcodec/vp8dsp.h b/ffmpeg/libavcodec/vp8dsp.h index 6308ff4..58ec65a 100644 --- a/ffmpeg/libavcodec/vp8dsp.h +++ b/ffmpeg/libavcodec/vp8dsp.h @@ -90,7 +90,7 @@ void ff_put_vp8_pixels4_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride, void ff_vp8dsp_init(VP8DSPContext *c); void ff_vp8dsp_init_x86(VP8DSPContext *c); -void ff_vp8dsp_init_altivec(VP8DSPContext *c); void ff_vp8dsp_init_arm(VP8DSPContext *c); +void ff_vp8dsp_init_ppc(VP8DSPContext *c); #endif /* AVCODEC_VP8DSP_H */ diff --git a/ffmpeg/libavcodec/vqavideo.c b/ffmpeg/libavcodec/vqavideo.c index a47e2db..9133855 100644 --- a/ffmpeg/libavcodec/vqavideo.c +++ b/ffmpeg/libavcodec/vqavideo.c @@ -134,8 +134,15 @@ static av_cold int vqa_decode_init(AVCodecContext *avctx) /* load up the VQA parameters from the header */ s->vqa_version = s->avctx->extradata[0]; - if (s->vqa_version < 1 || s->vqa_version > 3) { - av_log(s->avctx, AV_LOG_ERROR, "unsupported version %d\n", s->vqa_version); + switch (s->vqa_version) { + case 1: + case 2: + break; + case 3: + avpriv_report_missing_feature(avctx, "VQA Version %d", s->vqa_version); + return AVERROR_PATCHWELCOME; + default: + avpriv_request_sample(avctx, "VQA Version %i", s->vqa_version); return AVERROR_PATCHWELCOME; } s->width = AV_RL16(&s->avctx->extradata[6]); @@ -231,7 +238,7 @@ static int decode_format80(VqaContext *s, int src_size, /* 0x80 means that frame is finished */ if (opcode == 0x80) - return 0; + break; if (dest_index >= dest_size) { av_log(s->avctx, AV_LOG_ERROR, "decode_format80 problem: dest_index (%d) exceeded dest_size (%d)\n", @@ -296,9 +303,11 @@ static int decode_format80(VqaContext *s, int src_size, * codebook entry; it is not important for compressed codebooks because * not every entry needs to be filled */ if (check_size) - if (dest_index < dest_size) + if (dest_index < dest_size) { av_log(s->avctx, AV_LOG_ERROR, "decode_format80 problem: decode finished with dest_index (%d) < dest_size (%d)\n", dest_index, dest_size); + memset(dest + dest_index, 0, dest_size - dest_index); + } return 0; // let's display what we decoded anyway } @@ -628,6 +637,7 @@ static av_cold int vqa_decode_end(AVCodecContext *avctx) AVCodec ff_vqa_decoder = { .name = "vqavideo", + .long_name = NULL_IF_CONFIG_SMALL("Westwood Studios VQA (Vector Quantized Animation) video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_WS_VQA, .priv_data_size = sizeof(VqaContext), @@ -635,5 +645,4 @@ AVCodec ff_vqa_decoder = { .close = vqa_decode_end, .decode = vqa_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Westwood Studios VQA (Vector Quantized Animation) video"), }; diff --git a/ffmpeg/libavcodec/w32pthreads.h b/ffmpeg/libavcodec/w32pthreads.h deleted file mode 100644 index 29185c7..0000000 --- a/ffmpeg/libavcodec/w32pthreads.h +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright (C) 2010-2011 x264 project - * - * Authors: Steven Walters - * Pegasys Inc. - * - * This file is part of Libav. - * - * Libav is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * Libav is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * w32threads to pthreads wrapper - */ - -#ifndef AVCODEC_W32PTHREADS_H -#define AVCODEC_W32PTHREADS_H - -/* Build up a pthread-like API using underlying Windows API. Have only static - * methods so as to not conflict with a potentially linked in pthread-win32 - * library. - * As most functions here are used without checking return values, - * only implement return values as necessary. */ - -#define WIN32_LEAN_AND_MEAN -#include -#include - -#include "libavutil/common.h" -#include "libavutil/internal.h" -#include "libavutil/mem.h" - -typedef struct pthread_t { - void *handle; - void *(*func)(void* arg); - void *arg; - void *ret; -} pthread_t; - -/* the conditional variable api for windows 6.0+ uses critical sections and - * not mutexes */ -typedef CRITICAL_SECTION pthread_mutex_t; - -/* This is the CONDITIONAL_VARIABLE typedef for using Window's native - * conditional variables on kernels 6.0+. - * MinGW does not currently have this typedef. */ -typedef struct pthread_cond_t { - void *ptr; -} pthread_cond_t; - -/* function pointers to conditional variable API on windows 6.0+ kernels */ -static void (WINAPI *cond_broadcast)(pthread_cond_t *cond); -static void (WINAPI *cond_init)(pthread_cond_t *cond); -static void (WINAPI *cond_signal)(pthread_cond_t *cond); -static BOOL (WINAPI *cond_wait)(pthread_cond_t *cond, pthread_mutex_t *mutex, - DWORD milliseconds); - -static unsigned __stdcall attribute_align_arg win32thread_worker(void *arg) -{ - pthread_t *h = arg; - h->ret = h->func(h->arg); - return 0; -} - -static int pthread_create(pthread_t *thread, const void *unused_attr, - void *(*start_routine)(void*), void *arg) -{ - thread->func = start_routine; - thread->arg = arg; - thread->handle = (void*)_beginthreadex(NULL, 0, win32thread_worker, thread, - 0, NULL); - return !thread->handle; -} - -static void pthread_join(pthread_t thread, void **value_ptr) -{ - DWORD ret = WaitForSingleObject(thread.handle, INFINITE); - if (ret != WAIT_OBJECT_0) - return; - if (value_ptr) - *value_ptr = thread.ret; - CloseHandle(thread.handle); -} - -static inline int pthread_mutex_init(pthread_mutex_t *m, void* attr) -{ - InitializeCriticalSection(m); - return 0; -} -static inline int pthread_mutex_destroy(pthread_mutex_t *m) -{ - DeleteCriticalSection(m); - return 0; -} -static inline int pthread_mutex_lock(pthread_mutex_t *m) -{ - EnterCriticalSection(m); - return 0; -} -static inline int pthread_mutex_unlock(pthread_mutex_t *m) -{ - LeaveCriticalSection(m); - return 0; -} - -/* for pre-Windows 6.0 platforms we need to define and use our own condition - * variable and api */ -typedef struct win32_cond_t { - pthread_mutex_t mtx_broadcast; - pthread_mutex_t mtx_waiter_count; - volatile int waiter_count; - HANDLE semaphore; - HANDLE waiters_done; - volatile int is_broadcast; -} win32_cond_t; - -static void pthread_cond_init(pthread_cond_t *cond, const void *unused_attr) -{ - win32_cond_t *win32_cond = NULL; - if (cond_init) { - cond_init(cond); - return; - } - - /* non native condition variables */ - win32_cond = av_mallocz(sizeof(win32_cond_t)); - if (!win32_cond) - return; - cond->ptr = win32_cond; - win32_cond->semaphore = CreateSemaphore(NULL, 0, 0x7fffffff, NULL); - if (!win32_cond->semaphore) - return; - win32_cond->waiters_done = CreateEvent(NULL, TRUE, FALSE, NULL); - if (!win32_cond->waiters_done) - return; - - pthread_mutex_init(&win32_cond->mtx_waiter_count, NULL); - pthread_mutex_init(&win32_cond->mtx_broadcast, NULL); -} - -static void pthread_cond_destroy(pthread_cond_t *cond) -{ - win32_cond_t *win32_cond = cond->ptr; - /* native condition variables do not destroy */ - if (cond_init) - return; - - /* non native condition variables */ - CloseHandle(win32_cond->semaphore); - CloseHandle(win32_cond->waiters_done); - pthread_mutex_destroy(&win32_cond->mtx_waiter_count); - pthread_mutex_destroy(&win32_cond->mtx_broadcast); - av_freep(&win32_cond); - cond->ptr = NULL; -} - -static void pthread_cond_broadcast(pthread_cond_t *cond) -{ - win32_cond_t *win32_cond = cond->ptr; - int have_waiter; - - if (cond_broadcast) { - cond_broadcast(cond); - return; - } - - /* non native condition variables */ - pthread_mutex_lock(&win32_cond->mtx_broadcast); - pthread_mutex_lock(&win32_cond->mtx_waiter_count); - have_waiter = 0; - - if (win32_cond->waiter_count) { - win32_cond->is_broadcast = 1; - have_waiter = 1; - } - - if (have_waiter) { - ReleaseSemaphore(win32_cond->semaphore, win32_cond->waiter_count, NULL); - pthread_mutex_unlock(&win32_cond->mtx_waiter_count); - WaitForSingleObject(win32_cond->waiters_done, INFINITE); - ResetEvent(win32_cond->waiters_done); - win32_cond->is_broadcast = 0; - } else - pthread_mutex_unlock(&win32_cond->mtx_waiter_count); - pthread_mutex_unlock(&win32_cond->mtx_broadcast); -} - -static int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) -{ - win32_cond_t *win32_cond = cond->ptr; - int last_waiter; - if (cond_wait) { - cond_wait(cond, mutex, INFINITE); - return 0; - } - - /* non native condition variables */ - pthread_mutex_lock(&win32_cond->mtx_broadcast); - pthread_mutex_lock(&win32_cond->mtx_waiter_count); - win32_cond->waiter_count++; - pthread_mutex_unlock(&win32_cond->mtx_waiter_count); - pthread_mutex_unlock(&win32_cond->mtx_broadcast); - - // unlock the external mutex - pthread_mutex_unlock(mutex); - WaitForSingleObject(win32_cond->semaphore, INFINITE); - - pthread_mutex_lock(&win32_cond->mtx_waiter_count); - win32_cond->waiter_count--; - last_waiter = !win32_cond->waiter_count || !win32_cond->is_broadcast; - pthread_mutex_unlock(&win32_cond->mtx_waiter_count); - - if (last_waiter) - SetEvent(win32_cond->waiters_done); - - // lock the external mutex - return pthread_mutex_lock(mutex); -} - -static void pthread_cond_signal(pthread_cond_t *cond) -{ - win32_cond_t *win32_cond = cond->ptr; - int have_waiter; - if (cond_signal) { - cond_signal(cond); - return; - } - - pthread_mutex_lock(&win32_cond->mtx_broadcast); - - /* non-native condition variables */ - pthread_mutex_lock(&win32_cond->mtx_waiter_count); - have_waiter = win32_cond->waiter_count; - pthread_mutex_unlock(&win32_cond->mtx_waiter_count); - - if (have_waiter) { - ReleaseSemaphore(win32_cond->semaphore, 1, NULL); - WaitForSingleObject(win32_cond->waiters_done, INFINITE); - ResetEvent(win32_cond->waiters_done); - } - - pthread_mutex_unlock(&win32_cond->mtx_broadcast); -} - -static void w32thread_init(void) -{ - HANDLE kernel_dll = GetModuleHandle(TEXT("kernel32.dll")); - /* if one is available, then they should all be available */ - cond_init = - (void*)GetProcAddress(kernel_dll, "InitializeConditionVariable"); - cond_broadcast = - (void*)GetProcAddress(kernel_dll, "WakeAllConditionVariable"); - cond_signal = - (void*)GetProcAddress(kernel_dll, "WakeConditionVariable"); - cond_wait = - (void*)GetProcAddress(kernel_dll, "SleepConditionVariableCS"); -} - -#endif /* AVCODEC_W32PTHREADS_H */ diff --git a/ffmpeg/libavcodec/wavpack.c b/ffmpeg/libavcodec/wavpack.c index b30b414..6f60514 100644 --- a/ffmpeg/libavcodec/wavpack.c +++ b/ffmpeg/libavcodec/wavpack.c @@ -25,54 +25,16 @@ #include "avcodec.h" #include "get_bits.h" #include "internal.h" +#include "thread.h" #include "unary.h" +#include "bytestream.h" +#include "wavpack.h" /** * @file * WavPack lossless audio decoder */ -#define WV_MONO 0x00000004 -#define WV_JOINT_STEREO 0x00000010 -#define WV_FALSE_STEREO 0x40000000 - -#define WV_HYBRID_MODE 0x00000008 -#define WV_HYBRID_SHAPE 0x00000008 -#define WV_HYBRID_BITRATE 0x00000200 -#define WV_HYBRID_BALANCE 0x00000400 - -#define WV_FLT_SHIFT_ONES 0x01 -#define WV_FLT_SHIFT_SAME 0x02 -#define WV_FLT_SHIFT_SENT 0x04 -#define WV_FLT_ZERO_SENT 0x08 -#define WV_FLT_ZERO_SIGN 0x10 - -#define WV_MAX_SAMPLES 131072 - -enum WP_ID_Flags { - WP_IDF_MASK = 0x1F, - WP_IDF_IGNORE = 0x20, - WP_IDF_ODD = 0x40, - WP_IDF_LONG = 0x80 -}; - -enum WP_ID { - WP_ID_DUMMY = 0, - WP_ID_ENCINFO, - WP_ID_DECTERMS, - WP_ID_DECWEIGHTS, - WP_ID_DECSAMPLES, - WP_ID_ENTROPY, - WP_ID_HYBRID, - WP_ID_SHAPING, - WP_ID_FLOATINFO, - WP_ID_INT32INFO, - WP_ID_DATA, - WP_ID_CORR, - WP_ID_EXTRABITS, - WP_ID_CHANINFO -}; - typedef struct SavedContext { int offset; int size; @@ -80,23 +42,6 @@ typedef struct SavedContext { uint32_t crc; } SavedContext; -#define MAX_TERMS 16 - -typedef struct Decorr { - int delta; - int value; - int weightA; - int weightB; - int samplesA[8]; - int samplesB[8]; -} Decorr; - -typedef struct WvChannel { - int median[3]; - int slow_level, error_limit; - int bitrate_acc, bitrate_delta; -} WvChannel; - typedef struct WavpackFrameContext { AVCodecContext *avctx; int frame_flags; @@ -133,113 +78,21 @@ typedef struct WavpackContext { WavpackFrameContext *fdec[WV_MAX_FRAME_DECODERS]; int fdec_num; - int multichannel; - int mkv_mode; int block; int samples; int ch_offset; } WavpackContext; -// exponent table copied from WavPack source -static const uint8_t wp_exp2_table [256] = { - 0x00, 0x01, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, 0x0b, - 0x0b, 0x0c, 0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x12, 0x13, 0x13, 0x14, 0x15, 0x16, 0x16, - 0x17, 0x18, 0x19, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1f, 0x20, 0x20, 0x21, 0x22, 0x23, - 0x24, 0x24, 0x25, 0x26, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3a, 0x3b, 0x3c, 0x3d, - 0x3e, 0x3f, 0x40, 0x41, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x48, 0x49, 0x4a, 0x4b, - 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, - 0x5b, 0x5c, 0x5d, 0x5e, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8a, - 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, - 0x9c, 0x9d, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, - 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, - 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc8, 0xc9, 0xca, 0xcb, 0xcd, 0xce, 0xcf, 0xd0, 0xd2, 0xd3, 0xd4, - 0xd6, 0xd7, 0xd8, 0xd9, 0xdb, 0xdc, 0xdd, 0xde, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe8, 0xe9, - 0xea, 0xec, 0xed, 0xee, 0xf0, 0xf1, 0xf2, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xff -}; - -static const uint8_t wp_log2_table [] = { - 0x00, 0x01, 0x03, 0x04, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x10, 0x11, 0x12, 0x14, 0x15, - 0x16, 0x18, 0x19, 0x1a, 0x1c, 0x1d, 0x1e, 0x20, 0x21, 0x22, 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a, - 0x2c, 0x2d, 0x2e, 0x2f, 0x31, 0x32, 0x33, 0x34, 0x36, 0x37, 0x38, 0x39, 0x3b, 0x3c, 0x3d, 0x3e, - 0x3f, 0x41, 0x42, 0x43, 0x44, 0x45, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4d, 0x4e, 0x4f, 0x50, 0x51, - 0x52, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, - 0x64, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x74, 0x75, - 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, - 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, - 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, - 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb2, - 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc0, - 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xce, - 0xcf, 0xd0, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd8, 0xd9, 0xda, 0xdb, - 0xdc, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe4, 0xe5, 0xe6, 0xe7, 0xe7, - 0xe8, 0xe9, 0xea, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xee, 0xef, 0xf0, 0xf1, 0xf1, 0xf2, 0xf3, 0xf4, - 0xf4, 0xf5, 0xf6, 0xf7, 0xf7, 0xf8, 0xf9, 0xf9, 0xfa, 0xfb, 0xfc, 0xfc, 0xfd, 0xfe, 0xff, 0xff -}; - -static av_always_inline int wp_exp2(int16_t val) -{ - int res, neg = 0; - - if (val < 0) { - val = -val; - neg = 1; - } - - res = wp_exp2_table[val & 0xFF] | 0x100; - val >>= 8; - res = (val > 9) ? (res << (val - 9)) : (res >> (9 - val)); - return neg ? -res : res; -} - -static av_always_inline int wp_log2(int32_t val) -{ - int bits; - - if (!val) - return 0; - if (val == 1) - return 256; - val += val >> 9; - bits = av_log2(val) + 1; - if (bits < 9) - return (bits << 8) + wp_log2_table[(val << (9 - bits)) & 0xFF]; - else - return (bits << 8) + wp_log2_table[(val >> (bits - 9)) & 0xFF]; -} - #define LEVEL_DECAY(a) ((a + 0x80) >> 8) -// macros for manipulating median values -#define GET_MED(n) ((c->median[n] >> 4) + 1) -#define DEC_MED(n) c->median[n] -= ((c->median[n] + (128 >> n) - 2) / (128 >> n)) * 2 -#define INC_MED(n) c->median[n] += ((c->median[n] + (128 >> n) ) / (128 >> n)) * 5 - -// macros for applying weight -#define UPDATE_WEIGHT_CLIP(weight, delta, samples, in) \ - if (samples && in) { \ - if ((samples ^ in) < 0) { \ - weight -= delta; \ - if (weight < -1024) \ - weight = -1024; \ - } else { \ - weight += delta; \ - if (weight > 1024) \ - weight = 1024; \ - } \ - } - - static av_always_inline int get_tail(GetBitContext *gb, int k) { int p, e, res; if (k < 1) return 0; - p = av_log2(k); - e = (1 << (p + 1)) - k - 1; + p = av_log2(k); + e = (1 << (p + 1)) - k - 1; res = p ? get_bits(gb, p) : 0; if (res >= e) res = (res << 1) - e + get_bits1(gb); @@ -252,8 +105,8 @@ static void update_error_limit(WavpackFrameContext *ctx) for (i = 0; i <= ctx->stereo_in; i++) { ctx->ch[i].bitrate_acc += ctx->ch[i].bitrate_delta; - br[i] = ctx->ch[i].bitrate_acc >> 16; - sl[i] = LEVEL_DECAY(ctx->ch[i].slow_level); + br[i] = ctx->ch[i].bitrate_acc >> 16; + sl[i] = LEVEL_DECAY(ctx->ch[i].slow_level); } if (ctx->stereo_in && ctx->hybrid_bitrate) { int balance = (sl[1] - sl[0] + br[1] + 1) >> 1; @@ -262,7 +115,7 @@ static void update_error_limit(WavpackFrameContext *ctx) br[0] = 0; } else if (-balance > br[0]) { br[0] <<= 1; - br[1] = 0; + br[1] = 0; } else { br[1] = br[0] + balance; br[0] = br[0] - balance; @@ -302,7 +155,7 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, if (t >= 2) { if (get_bits_left(gb) < t - 1) goto error; - t = get_bits(gb, t - 1) | (1 << (t-1)); + t = get_bits(gb, t - 1) | (1 << (t - 1)); } else { if (get_bits_left(gb) < 0) goto error; @@ -318,7 +171,7 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, } if (ctx->zero) { - t = 0; + t = 0; ctx->zero = 0; } else { t = get_unary_0_33(gb); @@ -339,10 +192,10 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, if (ctx->one) { ctx->one = t & 1; - t = (t >> 1) + 1; + t = (t >> 1) + 1; } else { ctx->one = t & 1; - t >>= 1; + t >>= 1; } ctx->zero = !ctx->one; } @@ -373,6 +226,10 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, INC_MED(2); } if (!c->error_limit) { + if (add >= 0x2000000U) { + av_log(ctx->avctx, AV_LOG_ERROR, "k %d is too large\n", add); + goto error; + } ret = base + get_tail(gb, add); if (get_bits_left(gb) <= 0) goto error; @@ -405,11 +262,12 @@ static inline int wv_get_value_integer(WavpackFrameContext *s, uint32_t *crc, { int bit; - if (s->extra_bits){ + if (s->extra_bits) { S <<= s->extra_bits; - if (s->got_extra_bits && get_bits_left(&s->gb_extra_bits) >= s->extra_bits) { - S |= get_bits(&s->gb_extra_bits, s->extra_bits); + if (s->got_extra_bits && + get_bits_left(&s->gb_extra_bits) >= s->extra_bits) { + S |= get_bits(&s->gb_extra_bits, s->extra_bits); *crc = *crc * 9 + (S & 0xffff) * 3 + ((unsigned)S >> 16); } } @@ -442,7 +300,7 @@ static float wv_get_value_float(WavpackFrameContext *s, uint32_t *crc, int S) } if (S) { - S <<= s->float_shift; + S <<= s->float_shift; sign = S < 0; if (sign) S = -S; @@ -462,7 +320,8 @@ static float wv_get_value_float(WavpackFrameContext *s, uint32_t *crc, int S) if (shift) { S <<= shift; if ((s->float_flag & WV_FLT_SHIFT_ONES) || - (s->got_extra_bits && (s->float_flag & WV_FLT_SHIFT_SAME) && + (s->got_extra_bits && + (s->float_flag & WV_FLT_SHIFT_SAME) && get_bits1(&s->gb_extra_bits))) { S |= (1 << shift) - 1; } else if (s->got_extra_bits && @@ -476,7 +335,7 @@ static float wv_get_value_float(WavpackFrameContext *s, uint32_t *crc, int S) S &= 0x7fffff; } else { sign = 0; - exp = 0; + exp = 0; if (s->got_extra_bits && (s->float_flag & WV_FLT_ZERO_SENT)) { if (get_bits1(&s->gb_extra_bits)) { S = get_bits(&s->gb_extra_bits, 23); @@ -498,7 +357,7 @@ static float wv_get_value_float(WavpackFrameContext *s, uint32_t *crc, int S) static void wv_reset_saved_context(WavpackFrameContext *s) { - s->pos = 0; + s->pos = 0; s->sc.crc = s->extra_sc.crc = 0xFFFFFFFF; } @@ -518,18 +377,20 @@ static inline int wv_check_crc(WavpackFrameContext *s, uint32_t crc, } static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb, - void *dst, const int type) + void *dst_l, void *dst_r, const int type) { int i, j, count = 0; int last, t; int A, B, L, L2, R, R2; - int pos = s->pos; - uint32_t crc = s->sc.crc; + int pos = s->pos; + uint32_t crc = s->sc.crc; uint32_t crc_extra_bits = s->extra_sc.crc; - int16_t *dst16 = dst; - int32_t *dst32 = dst; - float *dstfl = dst; - const int channel_pad = s->avctx->channels - 2; + int16_t *dst16_l = dst_l; + int16_t *dst16_r = dst_r; + int32_t *dst32_l = dst_l; + int32_t *dst32_r = dst_r; + float *dstfl_l = dst_l; + float *dstfl_r = dst_r; s->one = s->zero = s->zeroes = 0; do { @@ -552,39 +413,41 @@ static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb, } s->decorr[i].samplesA[1] = s->decorr[i].samplesA[0]; s->decorr[i].samplesB[1] = s->decorr[i].samplesB[0]; - j = 0; + j = 0; } else { A = s->decorr[i].samplesA[pos]; B = s->decorr[i].samplesB[pos]; j = (pos + t) & 7; } - if (type != AV_SAMPLE_FMT_S16) { + if (type != AV_SAMPLE_FMT_S16P) { L2 = L + ((s->decorr[i].weightA * (int64_t)A + 512) >> 10); R2 = R + ((s->decorr[i].weightB * (int64_t)B + 512) >> 10); } else { L2 = L + ((s->decorr[i].weightA * A + 512) >> 10); R2 = R + ((s->decorr[i].weightB * B + 512) >> 10); } - if (A && L) s->decorr[i].weightA -= ((((L ^ A) >> 30) & 2) - 1) * s->decorr[i].delta; - if (B && R) s->decorr[i].weightB -= ((((R ^ B) >> 30) & 2) - 1) * s->decorr[i].delta; + if (A && L) + s->decorr[i].weightA -= ((((L ^ A) >> 30) & 2) - 1) * s->decorr[i].delta; + if (B && R) + s->decorr[i].weightB -= ((((R ^ B) >> 30) & 2) - 1) * s->decorr[i].delta; s->decorr[i].samplesA[j] = L = L2; s->decorr[i].samplesB[j] = R = R2; } else if (t == -1) { - if (type != AV_SAMPLE_FMT_S16) + if (type != AV_SAMPLE_FMT_S16P) L2 = L + ((s->decorr[i].weightA * (int64_t)s->decorr[i].samplesA[0] + 512) >> 10); else L2 = L + ((s->decorr[i].weightA * s->decorr[i].samplesA[0] + 512) >> 10); UPDATE_WEIGHT_CLIP(s->decorr[i].weightA, s->decorr[i].delta, s->decorr[i].samplesA[0], L); L = L2; - if (type != AV_SAMPLE_FMT_S16) + if (type != AV_SAMPLE_FMT_S16P) R2 = R + ((s->decorr[i].weightB * (int64_t)L2 + 512) >> 10); else R2 = R + ((s->decorr[i].weightB * L2 + 512) >> 10); UPDATE_WEIGHT_CLIP(s->decorr[i].weightB, s->decorr[i].delta, L2, R); - R = R2; + R = R2; s->decorr[i].samplesA[0] = R; } else { - if (type != AV_SAMPLE_FMT_S16) + if (type != AV_SAMPLE_FMT_S16P) R2 = R + ((s->decorr[i].weightB * (int64_t)s->decorr[i].samplesB[0] + 512) >> 10); else R2 = R + ((s->decorr[i].weightB * s->decorr[i].samplesB[0] + 512) >> 10); @@ -592,16 +455,16 @@ static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb, R = R2; if (t == -3) { - R2 = s->decorr[i].samplesA[0]; + R2 = s->decorr[i].samplesA[0]; s->decorr[i].samplesA[0] = R; } - if (type != AV_SAMPLE_FMT_S16) + if (type != AV_SAMPLE_FMT_S16P) L2 = L + ((s->decorr[i].weightA * (int64_t)R2 + 512) >> 10); else L2 = L + ((s->decorr[i].weightA * R2 + 512) >> 10); UPDATE_WEIGHT_CLIP(s->decorr[i].weightA, s->decorr[i].delta, R2, L); - L = L2; + L = L2; s->decorr[i].samplesB[0] = L; } } @@ -610,28 +473,32 @@ static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb, L += (R -= (L >> 1)); crc = (crc * 3 + L) * 3 + R; - if (type == AV_SAMPLE_FMT_FLT) { - *dstfl++ = wv_get_value_float(s, &crc_extra_bits, L); - *dstfl++ = wv_get_value_float(s, &crc_extra_bits, R); - dstfl += channel_pad; - } else if (type == AV_SAMPLE_FMT_S32) { - *dst32++ = wv_get_value_integer(s, &crc_extra_bits, L); - *dst32++ = wv_get_value_integer(s, &crc_extra_bits, R); - dst32 += channel_pad; + if (type == AV_SAMPLE_FMT_FLTP) { + *dstfl_l++ = wv_get_value_float(s, &crc_extra_bits, L); + *dstfl_r++ = wv_get_value_float(s, &crc_extra_bits, R); + } else if (type == AV_SAMPLE_FMT_S32P) { + *dst32_l++ = wv_get_value_integer(s, &crc_extra_bits, L); + *dst32_r++ = wv_get_value_integer(s, &crc_extra_bits, R); } else { - *dst16++ = wv_get_value_integer(s, &crc_extra_bits, L); - *dst16++ = wv_get_value_integer(s, &crc_extra_bits, R); - dst16 += channel_pad; + *dst16_l++ = wv_get_value_integer(s, &crc_extra_bits, L); + *dst16_r++ = wv_get_value_integer(s, &crc_extra_bits, R); } count++; } while (!last && count < s->samples); wv_reset_saved_context(s); + + if (last && count < s->samples) { + int size = av_get_bytes_per_sample(type); + memset((uint8_t*)dst_l + count*size, 0, (s->samples-count)*size); + memset((uint8_t*)dst_r + count*size, 0, (s->samples-count)*size); + } + if ((s->avctx->err_recognition & AV_EF_CRCCHECK) && wv_check_crc(s, crc, crc_extra_bits)) return AVERROR_INVALIDDATA; - return count * 2; + return 0; } static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb, @@ -640,13 +507,12 @@ static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb, int i, j, count = 0; int last, t; int A, S, T; - int pos = s->pos; - uint32_t crc = s->sc.crc; - uint32_t crc_extra_bits = s->extra_sc.crc; - int16_t *dst16 = dst; - int32_t *dst32 = dst; - float *dstfl = dst; - const int channel_stride = s->avctx->channels; + int pos = s->pos; + uint32_t crc = s->sc.crc; + uint32_t crc_extra_bits = s->extra_sc.crc; + int16_t *dst16 = dst; + int32_t *dst32 = dst; + float *dstfl = dst; s->one = s->zero = s->zeroes = 0; do { @@ -662,12 +528,12 @@ static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb, else A = (3 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]) >> 1; s->decorr[i].samplesA[1] = s->decorr[i].samplesA[0]; - j = 0; + j = 0; } else { A = s->decorr[i].samplesA[pos]; j = (pos + t) & 7; } - if (type != AV_SAMPLE_FMT_S16) + if (type != AV_SAMPLE_FMT_S16P) S = T + ((s->decorr[i].weightA * (int64_t)A + 512) >> 10); else S = T + ((s->decorr[i].weightA * A + 512) >> 10); @@ -678,30 +544,34 @@ static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb, pos = (pos + 1) & 7; crc = crc * 3 + S; - if (type == AV_SAMPLE_FMT_FLT) { - *dstfl = wv_get_value_float(s, &crc_extra_bits, S); - dstfl += channel_stride; - } else if (type == AV_SAMPLE_FMT_S32) { - *dst32 = wv_get_value_integer(s, &crc_extra_bits, S); - dst32 += channel_stride; + if (type == AV_SAMPLE_FMT_FLTP) { + *dstfl++ = wv_get_value_float(s, &crc_extra_bits, S); + } else if (type == AV_SAMPLE_FMT_S32P) { + *dst32++ = wv_get_value_integer(s, &crc_extra_bits, S); } else { - *dst16 = wv_get_value_integer(s, &crc_extra_bits, S); - dst16 += channel_stride; + *dst16++ = wv_get_value_integer(s, &crc_extra_bits, S); } count++; } while (!last && count < s->samples); wv_reset_saved_context(s); - if ((s->avctx->err_recognition & AV_EF_CRCCHECK) && - wv_check_crc(s, crc, crc_extra_bits)) - return AVERROR_INVALIDDATA; - return count; + if (last && count < s->samples) { + int size = av_get_bytes_per_sample(type); + memset((uint8_t*)dst + count*size, 0, (s->samples-count)*size); + } + + if (s->avctx->err_recognition & AV_EF_CRCCHECK) { + int ret = wv_check_crc(s, crc, crc_extra_bits); + if (ret < 0 && s->avctx->err_recognition & AV_EF_EXPLODE) + return ret; + } + + return 0; } static av_cold int wv_alloc_frame_context(WavpackContext *c) { - if (c->fdec_num == WV_MAX_FRAME_DECODERS) return -1; @@ -715,28 +585,18 @@ static av_cold int wv_alloc_frame_context(WavpackContext *c) return 0; } +static int init_thread_copy(AVCodecContext *avctx) +{ + WavpackContext *s = avctx->priv_data; + s->avctx = avctx; + return 0; +} + static av_cold int wavpack_decode_init(AVCodecContext *avctx) { WavpackContext *s = avctx->priv_data; s->avctx = avctx; - if (avctx->bits_per_coded_sample <= 16) - avctx->sample_fmt = AV_SAMPLE_FMT_S16; - else - avctx->sample_fmt = AV_SAMPLE_FMT_S32; - if (avctx->channels <= 2 && !avctx->channel_layout) - avctx->channel_layout = (avctx->channels == 2) ? AV_CH_LAYOUT_STEREO : - AV_CH_LAYOUT_MONO; - - s->multichannel = avctx->channels > 2; - /* lavf demuxer does not provide extradata, Matroska stores 0x403 - there, use this to detect decoding mode for multichannel */ - s->mkv_mode = 0; - if (s->multichannel && avctx->extradata && avctx->extradata_size == 2) { - int ver = AV_RL16(avctx->extradata); - if (ver >= 0x402 && ver <= 0x410) - s->mkv_mode = 1; - } s->fdec_num = 0; @@ -756,64 +616,50 @@ static av_cold int wavpack_decode_end(AVCodecContext *avctx) } static int wavpack_decode_block(AVCodecContext *avctx, int block_no, - void *data, int *got_frame_ptr, - const uint8_t *buf, int buf_size) + AVFrame *frame, const uint8_t *buf, int buf_size) { WavpackContext *wc = avctx->priv_data; + ThreadFrame tframe = { .f = frame }; WavpackFrameContext *s; - void *samples = data; - int samplecount; + GetByteContext gb; + void *samples_l, *samples_r; + int ret; int got_terms = 0, got_weights = 0, got_samples = 0, got_entropy = 0, got_bs = 0, got_float = 0, got_hybrid = 0; - const uint8_t *orig_buf = buf; - const uint8_t *buf_end = buf + buf_size; int i, j, id, size, ssize, weights, t; - int bpp, chan, chmask, orig_bpp; - - if (buf_size == 0) { - *got_frame_ptr = 0; - return 0; - } + int bpp, chan = 0, chmask = 0, orig_bpp, sample_rate = 0; + int multiblock; if (block_no >= wc->fdec_num && wv_alloc_frame_context(wc) < 0) { av_log(avctx, AV_LOG_ERROR, "Error creating frame decode context\n"); - return -1; + return AVERROR_INVALIDDATA; } s = wc->fdec[block_no]; if (!s) { - av_log(avctx, AV_LOG_ERROR, "Context for block %d is not present\n", block_no); - return -1; - } - - if (wc->ch_offset >= avctx->channels) { - av_log(avctx, AV_LOG_ERROR, "too many channels\n"); - return -1; + av_log(avctx, AV_LOG_ERROR, "Context for block %d is not present\n", + block_no); + return AVERROR_INVALIDDATA; } memset(s->decorr, 0, MAX_TERMS * sizeof(Decorr)); memset(s->ch, 0, sizeof(s->ch)); - s->extra_bits = 0; - s->and = s->or = s->shift = 0; + s->extra_bits = 0; + s->and = s->or = s->shift = 0; s->got_extra_bits = 0; - if (!wc->mkv_mode) { - s->samples = AV_RL32(buf); buf += 4; - if (!s->samples) { - *got_frame_ptr = 0; - return 0; - } - if (s->samples > wc->samples) { - av_log(avctx, AV_LOG_ERROR, "too many samples in block"); - return -1; - } - } else { - s->samples = wc->samples; + bytestream2_init(&gb, buf, buf_size); + + s->samples = bytestream2_get_le32(&gb); + if (s->samples != wc->samples) { + av_log(avctx, AV_LOG_ERROR, "Mismatching number of samples in " + "a sequence: %d and %d\n", wc->samples, s->samples); + return AVERROR_INVALIDDATA; } - s->frame_flags = AV_RL32(buf); buf += 4; - bpp = av_get_bytes_per_sample(avctx->sample_fmt); - samples = (uint8_t*)samples + bpp * wc->ch_offset; - orig_bpp = ((s->frame_flags & 0x03) + 1) << 3; + s->frame_flags = bytestream2_get_le32(&gb); + bpp = av_get_bytes_per_sample(avctx->sample_fmt); + orig_bpp = ((s->frame_flags & 0x03) + 1) << 3; + multiblock = (s->frame_flags & WV_SINGLE_BLOCK) != WV_SINGLE_BLOCK; s->stereo = !(s->frame_flags & WV_MONO); s->stereo_in = (s->frame_flags & WV_FALSE_STEREO) ? 0 : s->stereo; @@ -821,51 +667,45 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, s->hybrid = s->frame_flags & WV_HYBRID_MODE; s->hybrid_bitrate = s->frame_flags & WV_HYBRID_BITRATE; s->post_shift = bpp * 8 - orig_bpp + ((s->frame_flags >> 13) & 0x1f); - s->hybrid_maxclip = (( 1LL << (orig_bpp - 1)) - 1); + s->hybrid_maxclip = ((1LL << (orig_bpp - 1)) - 1); s->hybrid_minclip = ((-1LL << (orig_bpp - 1))); - s->CRC = AV_RL32(buf); buf += 4; - if (wc->mkv_mode) - buf += 4; //skip block size; - - wc->ch_offset += 1 + s->stereo; + s->CRC = bytestream2_get_le32(&gb); // parse metadata blocks - while (buf < buf_end) { - id = *buf++; - size = *buf++; + while (bytestream2_get_bytes_left(&gb)) { + id = bytestream2_get_byte(&gb); + size = bytestream2_get_byte(&gb); if (id & WP_IDF_LONG) { - size |= (*buf++) << 8; - size |= (*buf++) << 16; + size |= (bytestream2_get_byte(&gb)) << 8; + size |= (bytestream2_get_byte(&gb)) << 16; } size <<= 1; // size is specified in words - ssize = size; + ssize = size; if (id & WP_IDF_ODD) size--; if (size < 0) { - av_log(avctx, AV_LOG_ERROR, "Got incorrect block %02X with size %i\n", id, size); + av_log(avctx, AV_LOG_ERROR, + "Got incorrect block %02X with size %i\n", id, size); break; } - if (buf + ssize > buf_end) { - av_log(avctx, AV_LOG_ERROR, "Block size %i is out of bounds\n", size); + if (bytestream2_get_bytes_left(&gb) < ssize) { + av_log(avctx, AV_LOG_ERROR, + "Block size %i is out of bounds\n", size); break; } - if (id & WP_IDF_IGNORE) { - buf += ssize; - continue; - } switch (id & WP_IDF_MASK) { case WP_ID_DECTERMS: if (size > MAX_TERMS) { av_log(avctx, AV_LOG_ERROR, "Too many decorrelation terms\n"); s->terms = 0; - buf += ssize; + bytestream2_skip(&gb, ssize); continue; } s->terms = size; for (i = 0; i < s->terms; i++) { - s->decorr[s->terms - i - 1].value = (*buf & 0x1F) - 5; - s->decorr[s->terms - i - 1].delta = *buf >> 5; - buf++; + uint8_t val = bytestream2_get_byte(&gb); + s->decorr[s->terms - i - 1].value = (val & 0x1F) - 5; + s->decorr[s->terms - i - 1].delta = val >> 5; } got_terms = 1; break; @@ -877,21 +717,21 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, weights = size >> s->stereo_in; if (weights > MAX_TERMS || weights > s->terms) { av_log(avctx, AV_LOG_ERROR, "Too many decorrelation weights\n"); - buf += ssize; + bytestream2_skip(&gb, ssize); continue; } for (i = 0; i < weights; i++) { - t = (int8_t)(*buf++); + t = (int8_t)bytestream2_get_byte(&gb); s->decorr[s->terms - i - 1].weightA = t << 3; if (s->decorr[s->terms - i - 1].weightA > 0) s->decorr[s->terms - i - 1].weightA += - (s->decorr[s->terms - i - 1].weightA + 64) >> 7; + (s->decorr[s->terms - i - 1].weightA + 64) >> 7; if (s->stereo_in) { - t = (int8_t)(*buf++); + t = (int8_t)bytestream2_get_byte(&gb); s->decorr[s->terms - i - 1].weightB = t << 3; if (s->decorr[s->terms - i - 1].weightB > 0) s->decorr[s->terms - i - 1].weightB += - (s->decorr[s->terms - i - 1].weightB + 64) >> 7; + (s->decorr[s->terms - i - 1].weightB + 64) >> 7; } } got_weights = 1; @@ -902,25 +742,34 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, continue; } t = 0; - for (i = s->terms - 1; (i >= 0) && (t < size) && buf <= buf_end; i--) { + for (i = s->terms - 1; (i >= 0) && (t < size); i--) { if (s->decorr[i].value > 8) { - s->decorr[i].samplesA[0] = wp_exp2(AV_RL16(buf)); buf += 2; - s->decorr[i].samplesA[1] = wp_exp2(AV_RL16(buf)); buf += 2; + s->decorr[i].samplesA[0] = + wp_exp2(bytestream2_get_le16(&gb)); + s->decorr[i].samplesA[1] = + wp_exp2(bytestream2_get_le16(&gb)); + if (s->stereo_in) { - s->decorr[i].samplesB[0] = wp_exp2(AV_RL16(buf)); buf += 2; - s->decorr[i].samplesB[1] = wp_exp2(AV_RL16(buf)); buf += 2; - t += 4; + s->decorr[i].samplesB[0] = + wp_exp2(bytestream2_get_le16(&gb)); + s->decorr[i].samplesB[1] = + wp_exp2(bytestream2_get_le16(&gb)); + t += 4; } t += 4; } else if (s->decorr[i].value < 0) { - s->decorr[i].samplesA[0] = wp_exp2(AV_RL16(buf)); buf += 2; - s->decorr[i].samplesB[0] = wp_exp2(AV_RL16(buf)); buf += 2; - t += 4; + s->decorr[i].samplesA[0] = + wp_exp2(bytestream2_get_le16(&gb)); + s->decorr[i].samplesB[0] = + wp_exp2(bytestream2_get_le16(&gb)); + t += 4; } else { - for (j = 0; j < s->decorr[i].value && buf+1decorr[i].samplesA[j] = wp_exp2(AV_RL16(buf)); buf += 2; + for (j = 0; j < s->decorr[i].value; j++) { + s->decorr[i].samplesA[j] = + wp_exp2(bytestream2_get_le16(&gb)); if (s->stereo_in) { - s->decorr[i].samplesB[j] = wp_exp2(AV_RL16(buf)); buf += 2; + s->decorr[i].samplesB[j] = + wp_exp2(bytestream2_get_le16(&gb)); } } t += s->decorr[i].value * 2 * (s->stereo_in + 1); @@ -930,36 +779,33 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, break; case WP_ID_ENTROPY: if (size != 6 * (s->stereo_in + 1)) { - av_log(avctx, AV_LOG_ERROR, "Entropy vars size should be %i, " - "got %i", 6 * (s->stereo_in + 1), size); - buf += ssize; + av_log(avctx, AV_LOG_ERROR, + "Entropy vars size should be %i, got %i.\n", + 6 * (s->stereo_in + 1), size); + bytestream2_skip(&gb, ssize); continue; } - for (j = 0; j <= s->stereo_in; j++) { + for (j = 0; j <= s->stereo_in; j++) for (i = 0; i < 3; i++) { - s->ch[j].median[i] = wp_exp2(AV_RL16(buf)); - buf += 2; + s->ch[j].median[i] = wp_exp2(bytestream2_get_le16(&gb)); } - } got_entropy = 1; break; case WP_ID_HYBRID: if (s->hybrid_bitrate) { for (i = 0; i <= s->stereo_in; i++) { - s->ch[i].slow_level = wp_exp2(AV_RL16(buf)); - buf += 2; - size -= 2; + s->ch[i].slow_level = wp_exp2(bytestream2_get_le16(&gb)); + size -= 2; } } for (i = 0; i < (s->stereo_in + 1); i++) { - s->ch[i].bitrate_acc = AV_RL16(buf) << 16; - buf += 2; - size -= 2; + s->ch[i].bitrate_acc = bytestream2_get_le16(&gb) << 16; + size -= 2; } if (size > 0) { for (i = 0; i < (s->stereo_in + 1); i++) { - s->ch[i].bitrate_delta = wp_exp2((int16_t)AV_RL16(buf)); - buf += 2; + s->ch[i].bitrate_delta = + wp_exp2((int16_t)bytestream2_get_le16(&gb)); } } else { for (i = 0; i < (s->stereo_in + 1); i++) @@ -967,82 +813,98 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, } got_hybrid = 1; break; - case WP_ID_INT32INFO: + case WP_ID_INT32INFO: { + uint8_t val[4]; if (size != 4) { - av_log(avctx, AV_LOG_ERROR, "Invalid INT32INFO, size = %i, sent_bits = %i\n", size, *buf); - buf += ssize; + av_log(avctx, AV_LOG_ERROR, + "Invalid INT32INFO, size = %i\n", + size); + bytestream2_skip(&gb, ssize - 4); continue; } - if (buf[0]) - s->extra_bits = buf[0]; - else if (buf[1]) - s->shift = buf[1]; - else if (buf[2]){ - s->and = s->or = 1; - s->shift = buf[2]; - } else if(buf[3]) { + bytestream2_get_buffer(&gb, val, 4); + if (val[0]) { + s->extra_bits = val[0]; + } else if (val[1]) { + s->shift = val[1]; + } else if (val[2]) { + s->and = s->or = 1; + s->shift = val[2]; + } else if (val[3]) { s->and = 1; - s->shift = buf[3]; + s->shift = val[3]; } /* original WavPack decoder forces 32-bit lossy sound to be treated - * as 24-bit one in order to have proper clipping - */ + * as 24-bit one in order to have proper clipping */ if (s->hybrid && bpp == 4 && s->post_shift < 8 && s->shift > 8) { - s->post_shift += 8; - s->shift -= 8; + s->post_shift += 8; + s->shift -= 8; s->hybrid_maxclip >>= 8; s->hybrid_minclip >>= 8; } - buf += 4; break; + } case WP_ID_FLOATINFO: if (size != 4) { - av_log(avctx, AV_LOG_ERROR, "Invalid FLOATINFO, size = %i\n", size); - buf += ssize; + av_log(avctx, AV_LOG_ERROR, + "Invalid FLOATINFO, size = %i\n", size); + bytestream2_skip(&gb, ssize); continue; } - s->float_flag = buf[0]; - s->float_shift = buf[1]; - s->float_max_exp = buf[2]; - buf += 4; - got_float = 1; + s->float_flag = bytestream2_get_byte(&gb); + s->float_shift = bytestream2_get_byte(&gb); + s->float_max_exp = bytestream2_get_byte(&gb); + got_float = 1; + bytestream2_skip(&gb, 1); break; case WP_ID_DATA: - s->sc.offset = buf - orig_buf; + s->sc.offset = bytestream2_tell(&gb); s->sc.size = size * 8; - init_get_bits(&s->gb, buf, size * 8); + if ((ret = init_get_bits8(&s->gb, gb.buffer, size)) < 0) + return ret; s->data_size = size * 8; - buf += size; - got_bs = 1; + bytestream2_skip(&gb, size); + got_bs = 1; break; case WP_ID_EXTRABITS: if (size <= 4) { av_log(avctx, AV_LOG_ERROR, "Invalid EXTRABITS, size = %i\n", size); - buf += size; + bytestream2_skip(&gb, size); continue; } - s->extra_sc.offset = buf - orig_buf; + s->extra_sc.offset = bytestream2_tell(&gb); s->extra_sc.size = size * 8; - init_get_bits(&s->gb_extra_bits, buf, size * 8); - s->crc_extra_bits = get_bits_long(&s->gb_extra_bits, 32); - buf += size; - s->got_extra_bits = 1; + if ((ret = init_get_bits8(&s->gb_extra_bits, gb.buffer, size)) < 0) + return ret; + s->crc_extra_bits = get_bits_long(&s->gb_extra_bits, 32); + bytestream2_skip(&gb, size); + s->got_extra_bits = 1; break; case WP_ID_CHANINFO: if (size <= 1) { - av_log(avctx, AV_LOG_ERROR, "Insufficient channel information\n"); - return -1; + av_log(avctx, AV_LOG_ERROR, + "Insufficient channel information\n"); + return AVERROR_INVALIDDATA; } - chan = *buf++; + chan = bytestream2_get_byte(&gb); switch (size - 2) { - case 0: chmask = *buf; break; - case 1: chmask = AV_RL16(buf); break; - case 2: chmask = AV_RL24(buf); break; - case 3: chmask = AV_RL32(buf); break; + case 0: + chmask = bytestream2_get_byte(&gb); + break; + case 1: + chmask = bytestream2_get_le16(&gb); + break; + case 2: + chmask = bytestream2_get_le24(&gb); + break; + case 3: + chmask = bytestream2_get_le32(&gb); + break; case 5: - chan |= (buf[1] & 0xF) << 8; - chmask = AV_RL24(buf + 2); + bytestream2_skip(&gb, 1); + chan |= (bytestream2_get_byte(&gb) & 0xF) << 8; + chmask = bytestream2_get_le16(&gb); break; default: av_log(avctx, AV_LOG_ERROR, "Invalid channel info size %d\n", @@ -1050,52 +912,50 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, chan = avctx->channels; chmask = avctx->channel_layout; } - if (chan != avctx->channels) { - av_log(avctx, AV_LOG_ERROR, "Block reports total %d channels, " - "decoder believes it's %d channels\n", chan, - avctx->channels); - return -1; + break; + case WP_ID_SAMPLE_RATE: + if (size != 3) { + av_log(avctx, AV_LOG_ERROR, "Invalid custom sample rate.\n"); + return AVERROR_INVALIDDATA; } - if (!avctx->channel_layout) - avctx->channel_layout = chmask; - buf += size - 1; + sample_rate = bytestream2_get_le24(&gb); break; default: - buf += size; + bytestream2_skip(&gb, size); } if (id & WP_IDF_ODD) - buf++; + bytestream2_skip(&gb, 1); } if (!got_terms) { av_log(avctx, AV_LOG_ERROR, "No block with decorrelation terms\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!got_weights) { av_log(avctx, AV_LOG_ERROR, "No block with decorrelation weights\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!got_samples) { av_log(avctx, AV_LOG_ERROR, "No block with decorrelation samples\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!got_entropy) { av_log(avctx, AV_LOG_ERROR, "No block with entropy info\n"); - return -1; + return AVERROR_INVALIDDATA; } if (s->hybrid && !got_hybrid) { av_log(avctx, AV_LOG_ERROR, "Hybrid config not found\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!got_bs) { av_log(avctx, AV_LOG_ERROR, "Packed samples not found\n"); - return -1; + return AVERROR_INVALIDDATA; } - if (!got_float && avctx->sample_fmt == AV_SAMPLE_FMT_FLT) { + if (!got_float && avctx->sample_fmt == AV_SAMPLE_FMT_FLTP) { av_log(avctx, AV_LOG_ERROR, "Float information not found\n"); - return -1; + return AVERROR_INVALIDDATA; } - if (s->got_extra_bits && avctx->sample_fmt != AV_SAMPLE_FMT_FLT) { + if (s->got_extra_bits && avctx->sample_fmt != AV_SAMPLE_FMT_FLTP) { const int size = get_bits_left(&s->gb_extra_bits); const int wanted = s->samples * s->extra_bits << s->stereo_in; if (size < wanted) { @@ -1104,64 +964,60 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, } } - if (s->stereo_in) { - if (avctx->sample_fmt == AV_SAMPLE_FMT_S16) - samplecount = wv_unpack_stereo(s, &s->gb, samples, AV_SAMPLE_FMT_S16); - else if (avctx->sample_fmt == AV_SAMPLE_FMT_S32) - samplecount = wv_unpack_stereo(s, &s->gb, samples, AV_SAMPLE_FMT_S32); - else - samplecount = wv_unpack_stereo(s, &s->gb, samples, AV_SAMPLE_FMT_FLT); - - if (samplecount < 0) - return -1; - - samplecount >>= 1; - } else { - const int channel_stride = avctx->channels; - - if (avctx->sample_fmt == AV_SAMPLE_FMT_S16) - samplecount = wv_unpack_mono(s, &s->gb, samples, AV_SAMPLE_FMT_S16); - else if (avctx->sample_fmt == AV_SAMPLE_FMT_S32) - samplecount = wv_unpack_mono(s, &s->gb, samples, AV_SAMPLE_FMT_S32); - else - samplecount = wv_unpack_mono(s, &s->gb, samples, AV_SAMPLE_FMT_FLT); - - if (samplecount < 0) - return -1; - - if (s->stereo && avctx->sample_fmt == AV_SAMPLE_FMT_S16) { - int16_t *dst = (int16_t*)samples + 1; - int16_t *src = (int16_t*)samples; - int cnt = samplecount; - while (cnt--) { - *dst = *src; - src += channel_stride; - dst += channel_stride; - } - } else if (s->stereo && avctx->sample_fmt == AV_SAMPLE_FMT_S32) { - int32_t *dst = (int32_t*)samples + 1; - int32_t *src = (int32_t*)samples; - int cnt = samplecount; - while (cnt--) { - *dst = *src; - src += channel_stride; - dst += channel_stride; - } - } else if (s->stereo) { - float *dst = (float*)samples + 1; - float *src = (float*)samples; - int cnt = samplecount; - while (cnt--) { - *dst = *src; - src += channel_stride; - dst += channel_stride; + if (!wc->ch_offset) { + int sr = (s->frame_flags >> 23) & 0xf; + if (sr == 0xf) { + if (!sample_rate) { + av_log(avctx, AV_LOG_ERROR, "Custom sample rate missing.\n"); + return AVERROR_INVALIDDATA; } + avctx->sample_rate = sample_rate; + } else + avctx->sample_rate = wv_rates[sr]; + + if (multiblock) { + if (chan) + avctx->channels = chan; + if (chmask) + avctx->channel_layout = chmask; + } else { + avctx->channels = s->stereo ? 2 : 1; + avctx->channel_layout = s->stereo ? AV_CH_LAYOUT_STEREO : + AV_CH_LAYOUT_MONO; } + + /* get output buffer */ + frame->nb_samples = s->samples + 1; + if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0) + return ret; + frame->nb_samples = s->samples; } - *got_frame_ptr = 1; + if (wc->ch_offset + s->stereo >= avctx->channels) { + av_log(avctx, AV_LOG_WARNING, "Too many channels coded in a packet.\n"); + return (avctx->err_recognition & AV_EF_EXPLODE) ? AVERROR_INVALIDDATA : 0; + } + + samples_l = frame->extended_data[wc->ch_offset]; + if (s->stereo) + samples_r = frame->extended_data[wc->ch_offset + 1]; - return samplecount * bpp; + wc->ch_offset += 1 + s->stereo; + + if (s->stereo_in) { + ret = wv_unpack_stereo(s, &s->gb, samples_l, samples_r, avctx->sample_fmt); + if (ret < 0) + return ret; + } else { + ret = wv_unpack_mono(s, &s->gb, samples_l, avctx->sample_fmt); + if (ret < 0) + return ret; + + if (s->stereo) + memcpy(samples_r, samples_l, bpp * s->samples); + } + + return 0; } static void wavpack_decode_flush(AVCodecContext *avctx) @@ -1181,78 +1037,67 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data, int buf_size = avpkt->size; AVFrame *frame = data; int frame_size, ret, frame_flags; - int samplecount = 0; + + if (avpkt->size <= WV_HEADER_SIZE) + return AVERROR_INVALIDDATA; s->block = 0; s->ch_offset = 0; /* determine number of samples */ - if (s->mkv_mode) { - s->samples = AV_RL32(buf); buf += 4; - frame_flags = AV_RL32(buf); - } else { - if (s->multichannel) { - s->samples = AV_RL32(buf + 4); - frame_flags = AV_RL32(buf + 8); - } else { - s->samples = AV_RL32(buf); - frame_flags = AV_RL32(buf + 4); - } - } + s->samples = AV_RL32(buf + 20); + frame_flags = AV_RL32(buf + 24); if (s->samples <= 0 || s->samples > WV_MAX_SAMPLES) { av_log(avctx, AV_LOG_ERROR, "Invalid number of samples: %d\n", s->samples); - return AVERROR(EINVAL); + return AVERROR_INVALIDDATA; } if (frame_flags & 0x80) { - avctx->sample_fmt = AV_SAMPLE_FMT_FLT; + avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; } else if ((frame_flags & 0x03) <= 1) { - avctx->sample_fmt = AV_SAMPLE_FMT_S16; + avctx->sample_fmt = AV_SAMPLE_FMT_S16P; } else { - avctx->sample_fmt = AV_SAMPLE_FMT_S32; + avctx->sample_fmt = AV_SAMPLE_FMT_S32P; avctx->bits_per_raw_sample = ((frame_flags & 0x03) + 1) << 3; } - /* get output buffer */ - frame->nb_samples = s->samples + 1; - if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) - return ret; - frame->nb_samples = s->samples; - while (buf_size > 0) { - if (!s->multichannel) { - frame_size = buf_size; - } else { - if (!s->mkv_mode) { - frame_size = AV_RL32(buf) - 12; buf += 4; buf_size -= 4; - } else { - if (buf_size < 12) //MKV files can have zero flags after last block - break; - frame_size = AV_RL32(buf + 8) + 12; - } - } - if (frame_size < 0 || frame_size > buf_size) { - av_log(avctx, AV_LOG_ERROR, "Block %d has invalid size (size %d " - "vs. %d bytes left)\n", s->block, frame_size, buf_size); + if (buf_size <= WV_HEADER_SIZE) + break; + frame_size = AV_RL32(buf + 4) - 12; + buf += 20; + buf_size -= 20; + if (frame_size <= 0 || frame_size > buf_size) { + av_log(avctx, AV_LOG_ERROR, + "Block %d has invalid size (size %d vs. %d bytes left)\n", + s->block, frame_size, buf_size); wavpack_decode_flush(avctx); return AVERROR_INVALIDDATA; } - if ((samplecount = wavpack_decode_block(avctx, s->block, - frame->data[0], got_frame_ptr, - buf, frame_size)) < 0) { + if ((ret = wavpack_decode_block(avctx, s->block, + frame, buf, frame_size)) < 0) { wavpack_decode_flush(avctx); - return AVERROR_INVALIDDATA; + return ret; } s->block++; - buf += frame_size; buf_size -= frame_size; + buf += frame_size; + buf_size -= frame_size; + } + + if (s->ch_offset != avctx->channels) { + av_log(avctx, AV_LOG_ERROR, "Not enough channels coded in a packet.\n"); + return AVERROR_INVALIDDATA; } + *got_frame_ptr = 1; + return avpkt->size; } AVCodec ff_wavpack_decoder = { .name = "wavpack", + .long_name = NULL_IF_CONFIG_SMALL("WavPack"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_WAVPACK, .priv_data_size = sizeof(WavpackContext), @@ -1260,6 +1105,6 @@ AVCodec ff_wavpack_decoder = { .close = wavpack_decode_end, .decode = wavpack_decode_frame, .flush = wavpack_decode_flush, - .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("WavPack"), + .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy), + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, }; diff --git a/ffmpeg/libavcodec/wma.c b/ffmpeg/libavcodec/wma.c index 1e6ca61..0122ee6 100644 --- a/ffmpeg/libavcodec/wma.c +++ b/ffmpeg/libavcodec/wma.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/attributes.h" #include "avcodec.h" #include "sinewin.h" #include "wma.h" @@ -30,9 +31,9 @@ /* XXX: use same run/length optimization as mpeg decoders */ //FIXME maybe split decode / encode or pass flag -static void init_coef_vlc(VLC *vlc, uint16_t **prun_table, - float **plevel_table, uint16_t **pint_table, - const CoefVLCTable *vlc_table) +static av_cold void init_coef_vlc(VLC *vlc, uint16_t **prun_table, + float **plevel_table, uint16_t **pint_table, + const CoefVLCTable *vlc_table) { int n = vlc_table->n; const uint8_t *table_bits = vlc_table->huffbits; @@ -68,7 +69,7 @@ static void init_coef_vlc(VLC *vlc, uint16_t **prun_table, av_free(level_table); } -int ff_wma_init(AVCodecContext *avctx, int flags2) +av_cold int ff_wma_init(AVCodecContext *avctx, int flags2) { WMACodecContext *s = avctx->priv_data; int i; @@ -307,7 +308,7 @@ int ff_wma_init(AVCodecContext *avctx, int flags2) } #endif - /* init MDCT windows : simple sinus window */ + /* init MDCT windows : simple sine window */ for (i = 0; i < s->nb_block_sizes; i++) { ff_init_ff_sine_windows(s->frame_len_bits - i); s->windows[i] = ff_sine_windows[s->frame_len_bits - i]; diff --git a/ffmpeg/libavcodec/wma_common.c b/ffmpeg/libavcodec/wma_common.c index d1d8045..51467b2 100644 --- a/ffmpeg/libavcodec/wma_common.c +++ b/ffmpeg/libavcodec/wma_common.c @@ -1,20 +1,20 @@ /* * common code shared by all WMA variants * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/ffmpeg/libavcodec/wmadec.c b/ffmpeg/libavcodec/wmadec.c index 0648c1e..e6a0b04 100644 --- a/ffmpeg/libavcodec/wmadec.c +++ b/ffmpeg/libavcodec/wmadec.c @@ -33,6 +33,7 @@ * should be 4 extra bytes for v1 data and 6 extra bytes for v2 data. */ +#include "libavutil/attributes.h" #include "avcodec.h" #include "internal.h" #include "wma.h" @@ -66,7 +67,7 @@ static void dump_floats(WMACodecContext *s, const char *name, int prec, const fl } #endif -static int wma_decode_init(AVCodecContext * avctx) +static av_cold int wma_decode_init(AVCodecContext * avctx) { WMACodecContext *s = avctx->priv_data; int i, flags2; @@ -150,7 +151,7 @@ static inline float pow_m1_4(WMACodecContext *s, float x) return s->lsp_pow_e_table[e] * (a + b * t.f); } -static void wma_lsp_to_curve_init(WMACodecContext *s, int frame_len) +static av_cold void wma_lsp_to_curve_init(WMACodecContext *s, int frame_len) { float wdel, a, b; int i, e, m; @@ -511,6 +512,10 @@ static int wma_decode_block(WMACodecContext *s) coef escape coding */ total_gain = 1; for(;;) { + if (get_bits_left(&s->gb) < 7) { + av_log(s->avctx, AV_LOG_ERROR, "total_gain overread\n"); + return AVERROR_INVALIDDATA; + } a = get_bits(&s->gb, 7); total_gain += a; if (a != 127) @@ -943,6 +948,7 @@ static av_cold void flush(AVCodecContext *avctx) #if CONFIG_WMAV1_DECODER AVCodec ff_wmav1_decoder = { .name = "wmav1", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_WMAV1, .priv_data_size = sizeof(WMACodecContext), @@ -951,7 +957,6 @@ AVCodec ff_wmav1_decoder = { .decode = wma_decode_superframe, .flush = flush, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, }; @@ -959,6 +964,7 @@ AVCodec ff_wmav1_decoder = { #if CONFIG_WMAV2_DECODER AVCodec ff_wmav2_decoder = { .name = "wmav2", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_WMAV2, .priv_data_size = sizeof(WMACodecContext), @@ -967,7 +973,6 @@ AVCodec ff_wmav2_decoder = { .decode = wma_decode_superframe, .flush = flush, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, }; diff --git a/ffmpeg/libavcodec/wmaenc.c b/ffmpeg/libavcodec/wmaenc.c index 799535e..895a180 100644 --- a/ffmpeg/libavcodec/wmaenc.c +++ b/ffmpeg/libavcodec/wmaenc.c @@ -19,13 +19,15 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/attributes.h" #include "avcodec.h" #include "internal.h" #include "wma.h" #include "libavutil/avassert.h" -static int encode_init(AVCodecContext * avctx){ +static av_cold int encode_init(AVCodecContext *avctx) +{ WMACodecContext *s = avctx->priv_data; int i, flags1, flags2, block_align; uint8_t *extradata; @@ -175,7 +177,7 @@ static int encode_block(WMACodecContext *s, float (*src_coefs)[BLOCK_MAX_SIZE], } s->block_len = 1 << s->block_len_bits; -// assert((s->block_pos + s->block_len) <= s->frame_len); +// av_assert0((s->block_pos + s->block_len) <= s->frame_len); bsize = s->frame_len_bits - s->block_len_bits; //FIXME factor @@ -374,6 +376,11 @@ static int encode_superframe(AVCodecContext *avctx, AVPacket *avpkt, while(total_gain <= 128 && error > 0) error = encode_frame(s, s->coefs, avpkt->data, avpkt->size, total_gain++); + if (error > 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid input data or requested bitrate too low, cannot encode\n"); + avpkt->size = 0; + return AVERROR(EINVAL); + } av_assert0((put_bits_count(&s->pb) & 7) == 0); i= avctx->block_align - (put_bits_count(&s->pb)+7)/8; av_assert0(i>=0); @@ -394,6 +401,7 @@ static int encode_superframe(AVCodecContext *avctx, AVPacket *avpkt, #if CONFIG_WMAV1_ENCODER AVCodec ff_wmav1_encoder = { .name = "wmav1", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_WMAV1, .priv_data_size = sizeof(WMACodecContext), @@ -402,12 +410,12 @@ AVCodec ff_wmav1_encoder = { .close = ff_wma_end, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"), }; #endif #if CONFIG_WMAV2_ENCODER AVCodec ff_wmav2_encoder = { .name = "wmav2", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_WMAV2, .priv_data_size = sizeof(WMACodecContext), @@ -416,6 +424,5 @@ AVCodec ff_wmav2_encoder = { .close = ff_wma_end, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"), }; #endif diff --git a/ffmpeg/libavcodec/wmalosslessdec.c b/ffmpeg/libavcodec/wmalosslessdec.c index 90a0109..71d8aa3 100644 --- a/ffmpeg/libavcodec/wmalosslessdec.c +++ b/ffmpeg/libavcodec/wmalosslessdec.c @@ -66,7 +66,7 @@ typedef struct { typedef struct WmallDecodeCtx { /* generic decoder variables */ AVCodecContext *avctx; - AVFrame frame; + AVFrame *frame; uint8_t frame_data[MAX_FRAMESIZE + FF_INPUT_BUFFER_PADDING_SIZE]; ///< compressed frame data PutBitContext pb; ///< context for filling the frame_data buffer @@ -178,6 +178,11 @@ static av_cold int decode_init(AVCodecContext *avctx) unsigned int channel_mask; int i, log2_max_num_subframes; + if (!avctx->block_align) { + av_log(avctx, AV_LOG_ERROR, "block_align is not set\n"); + return AVERROR(EINVAL); + } + s->avctx = avctx; init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE); @@ -261,8 +266,10 @@ static av_cold int decode_init(AVCodecContext *avctx) return AVERROR_PATCHWELCOME; } - avcodec_get_frame_defaults(&s->frame); - avctx->coded_frame = &s->frame; + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); + avctx->channel_layout = channel_mask; return 0; } @@ -341,11 +348,11 @@ static int decode_tilehdr(WmallDecodeCtx *s) if (num_samples[c] == min_channel_len) { if (fixed_channel_layout || channels_for_cur_subframe == 1 || (min_channel_len == s->samples_per_frame - s->min_samples_per_subframe)) { - contains_subframe[c] = in_use = 1; + contains_subframe[c] = 1; } else { - if (get_bits1(&s->gb)) - contains_subframe[c] = in_use = 1; + contains_subframe[c] = get_bits1(&s->gb); } + in_use |= contains_subframe[c]; } else contains_subframe[c] = 0; } @@ -908,7 +915,7 @@ static int decode_subframe(WmallDecodeCtx *s) } else if (!s->cdlms[0][0].order) { av_log(s->avctx, AV_LOG_DEBUG, "Waiting for seekable tile\n"); - s->frame.nb_samples = 0; + av_frame_unref(s->frame); return -1; } @@ -1015,15 +1022,15 @@ static int decode_frame(WmallDecodeCtx *s) GetBitContext* gb = &s->gb; int more_frames = 0, len = 0, i, ret; - s->frame.nb_samples = s->samples_per_frame; - if ((ret = ff_get_buffer(s->avctx, &s->frame, 0)) < 0) { + s->frame->nb_samples = s->samples_per_frame; + if ((ret = ff_get_buffer(s->avctx, s->frame, 0)) < 0) { /* return an error if no frame could be decoded at all */ s->packet_loss = 1; return ret; } for (i = 0; i < s->num_channels; i++) { - s->samples_16[i] = (int16_t *)s->frame.extended_data[i]; - s->samples_32[i] = (int32_t *)s->frame.extended_data[i]; + s->samples_16[i] = (int16_t *)s->frame->extended_data[i]; + s->samples_32[i] = (int32_t *)s->frame->extended_data[i]; } /* get frame length */ @@ -1170,14 +1177,18 @@ static int decode_packet(AVCodecContext *avctx, void *data, int *got_frame_ptr, int buf_size = avpkt->size; int num_bits_prev_frame, packet_sequence_number, spliced_packet; - s->frame.nb_samples = 0; + s->frame->nb_samples = 0; if (s->packet_done || s->packet_loss) { s->packet_done = 0; - /* sanity check for the buffer length */ - if (buf_size < avctx->block_align) + if (!buf_size) return 0; + /* sanity check for the buffer length */ + if (buf_size < avctx->block_align) { + av_log(avctx, AV_LOG_ERROR, "buf size %d invalid\n", buf_size); + return AVERROR_INVALIDDATA; + } s->next_packet_start = buf_size - avctx->block_align; buf_size = avctx->block_align; @@ -1263,8 +1274,8 @@ static int decode_packet(AVCodecContext *avctx, void *data, int *got_frame_ptr, save_bits(s, gb, remaining_bits(s, gb), 0); } - *got_frame_ptr = s->frame.nb_samples > 0; - av_frame_move_ref(data, &s->frame); + *got_frame_ptr = s->frame->nb_samples > 0; + av_frame_move_ref(data, s->frame); s->packet_offset = get_bits_count(gb) & 7; @@ -1280,20 +1291,30 @@ static void flush(AVCodecContext *avctx) s->frame_offset = 0; s->next_packet_start = 0; s->cdlms[0][0].order = 0; - s->frame.nb_samples = 0; + s->frame->nb_samples = 0; init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE); } +static av_cold int decode_close(AVCodecContext *avctx) +{ + WmallDecodeCtx *s = avctx->priv_data; + + av_frame_free(&s->frame); + + return 0; +} + AVCodec ff_wmalossless_decoder = { .name = "wmalossless", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio Lossless"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_WMALOSSLESS, .priv_data_size = sizeof(WmallDecodeCtx), .init = decode_init, + .close = decode_close, .decode = decode_packet, .flush = flush, .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1 | CODEC_CAP_DELAY, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio Lossless"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S32P, AV_SAMPLE_FMT_NONE }, diff --git a/ffmpeg/libavcodec/wmaprodec.c b/ffmpeg/libavcodec/wmaprodec.c index 07cc223..d57c24d 100644 --- a/ffmpeg/libavcodec/wmaprodec.c +++ b/ffmpeg/libavcodec/wmaprodec.c @@ -106,6 +106,7 @@ #define WMAPRO_BLOCK_MIN_BITS 6 ///< log2 of min block size #define WMAPRO_BLOCK_MAX_BITS 13 ///< log2 of max block size +#define WMAPRO_BLOCK_MIN_SIZE (1 << WMAPRO_BLOCK_MIN_BITS) ///< minimum block size #define WMAPRO_BLOCK_MAX_SIZE (1 << WMAPRO_BLOCK_MAX_BITS) ///< maximum block size #define WMAPRO_BLOCK_SIZES (WMAPRO_BLOCK_MAX_BITS - WMAPRO_BLOCK_MIN_BITS + 1) ///< possible block sizes @@ -124,7 +125,7 @@ static VLC vec4_vlc; ///< 4 coefficients per symbol static VLC vec2_vlc; ///< 2 coefficients per symbol static VLC vec1_vlc; ///< 1 coefficient per symbol static VLC coef_vlc[2]; ///< coefficient run length vlc codes -static float sin64[33]; ///< sinus table for decorrelation +static float sin64[33]; ///< sine table for decorrelation /** * @brief frame specific decoder context for a single channel @@ -305,6 +306,10 @@ static av_cold int decode_init(AVCodecContext *avctx) /** generic init */ s->log2_frame_size = av_log2(avctx->block_align) + 4; + if (s->log2_frame_size > 25) { + avpriv_request_sample(avctx, "Large block align"); + return AVERROR_PATCHWELCOME; + } /** frame info */ s->skip_frame = 1; /* skip first frame */ @@ -336,7 +341,7 @@ static av_cold int decode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } - if (s->min_samples_per_subframe < (1<min_samples_per_subframe < WMAPRO_BLOCK_MIN_SIZE) { av_log(avctx, AV_LOG_ERROR, "min_samples_per_subframe of %d too small\n", s->min_samples_per_subframe); return AVERROR_INVALIDDATA; @@ -438,8 +443,10 @@ static av_cold int decode_init(AVCodecContext *avctx) + s->sfb_offsets[i][b + 1] - 1) << i) >> 1; for (x = 0; x < num_possible_block_sizes; x++) { int v = 0; - while (s->sfb_offsets[x][v + 1] << x < offset) - ++v; + while (s->sfb_offsets[x][v + 1] << x < offset) { + v++; + av_assert0(v < MAX_BANDS); + } s->sf_offsets[i][x][b] = v; } } @@ -451,7 +458,7 @@ static av_cold int decode_init(AVCodecContext *avctx) 1.0 / (1 << (WMAPRO_BLOCK_MIN_BITS + i - 1)) / (1 << (s->bits_per_sample - 1))); - /** init MDCT windows: simple sinus window */ + /** init MDCT windows: simple sine window */ for (i = 0; i < WMAPRO_BLOCK_SIZES; i++) { const int win_idx = WMAPRO_BLOCK_MAX_BITS - i; ff_init_ff_sine_windows(win_idx); @@ -493,6 +500,9 @@ static int decode_subframe_length(WMAProDecodeCtx *s, int offset) if (offset == s->samples_per_frame - s->min_samples_per_subframe) return s->min_samples_per_subframe; + if (get_bits_left(&s->gb) < 1) + return AVERROR_INVALIDDATA; + /** 1 bit indicates if the subframe is of maximum length */ if (s->max_subframe_len_bit) { if (get_bits1(&s->gb)) @@ -671,7 +681,7 @@ static void decode_decorrelation_matrix(WMAProDecodeCtx *s, /** *@brief Decode channel transformation parameters *@param s codec context - *@return 0 in case of success, < 0 in case of bitstream errors + *@return >= 0 in case of success, < 0 in case of bitstream errors */ static int decode_channel_transform(WMAProDecodeCtx* s) { @@ -726,6 +736,7 @@ static int decode_channel_transform(WMAProDecodeCtx* s) if (get_bits1(&s->gb)) { avpriv_request_sample(s->avctx, "Unknown channel transform type"); + return AVERROR_PATCHWELCOME; } } else { chgroup->transform = 1; @@ -1128,11 +1139,12 @@ static int decode_subframe(WMAProDecodeCtx *s) cur_subwoofer_cutoff = s->subwoofer_cutoffs[s->table_idx]; /** configure the decoder for the current subframe */ + offset += s->samples_per_frame >> 1; + for (i = 0; i < s->channels_for_cur_subframe; i++) { int c = s->channel_indexes_for_cur_subframe[i]; - s->channel[c].coeffs = &s->channel[c].out[(s->samples_per_frame >> 1) - + offset]; + s->channel[c].coeffs = &s->channel[c].out[offset]; } s->subframe_len = subframe_len; @@ -1188,6 +1200,7 @@ static int decode_subframe(WMAProDecodeCtx *s) av_log(s->avctx, AV_LOG_ERROR, "num_vec_coeffs %d is too large\n", num_vec_coeffs); return AVERROR_INVALIDDATA; } + av_assert0(num_vec_coeffs + offset <= FF_ARRAY_ELEMS(s->channel[c].out)); s->channel[c].num_vec_coeffs = num_vec_coeffs; } } else { @@ -1469,6 +1482,8 @@ static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len, return; } + av_assert0(len <= put_bits_left(&s->pb)); + s->num_saved_bits += len; if (!append) { avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), @@ -1581,7 +1596,8 @@ static int decode_packet(AVCodecContext *avctx, void *data, (frame_size = show_bits(gb, s->log2_frame_size)) && frame_size <= remaining_bits(s, gb)) { save_bits(s, gb, frame_size, 0); - s->packet_done = !decode_frame(s, data, got_frame_ptr); + if (!s->packet_loss) + s->packet_done = !decode_frame(s, data, got_frame_ptr); } else if (!s->len_prefix && s->num_saved_bits > get_bits_count(&s->gb)) { /** when the frames do not have a length prefix, we don't know @@ -1632,6 +1648,7 @@ static void flush(AVCodecContext *avctx) */ AVCodec ff_wmapro_decoder = { .name = "wmapro", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 9 Professional"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_WMAPRO, .priv_data_size = sizeof(WMAProDecodeCtx), @@ -1640,7 +1657,6 @@ AVCodec ff_wmapro_decoder = { .decode = decode_packet, .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1, .flush = flush, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 9 Professional"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, }; diff --git a/ffmpeg/libavcodec/wmavoice.c b/ffmpeg/libavcodec/wmavoice.c index 19f8965..c2737ab 100644 --- a/ffmpeg/libavcodec/wmavoice.c +++ b/ffmpeg/libavcodec/wmavoice.c @@ -302,6 +302,20 @@ typedef struct { * @return 0 on success, <0 on error. */ static av_cold int decode_vbmtree(GetBitContext *gb, int8_t vbm_tree[25]) +{ + int cntr[8] = { 0 }, n, res; + + memset(vbm_tree, 0xff, sizeof(vbm_tree[0]) * 25); + for (n = 0; n < 17; n++) { + res = get_bits(gb, 3); + if (cntr[res] > 3) // should be >= 3 + (res == 7)) + return -1; + vbm_tree[res * 3 + cntr[res]++] = n; + } + return 0; +} + +static av_cold void wmavoice_init_static_data(AVCodec *codec) { static const uint8_t bits[] = { 2, 2, 2, 4, 4, 4, @@ -318,18 +332,9 @@ static av_cold int decode_vbmtree(GetBitContext *gb, int8_t vbm_tree[25]) 0x0ffc, 0x0ffd, 0x0ffe, // 1111111111+00/01/10 0x3ffc, 0x3ffd, 0x3ffe, 0x3fff // 111111111111+xx }; - int cntr[8] = { 0 }, n, res; - memset(vbm_tree, 0xff, sizeof(vbm_tree[0]) * 25); - for (n = 0; n < 17; n++) { - res = get_bits(gb, 3); - if (cntr[res] > 3) // should be >= 3 + (res == 7)) - return -1; - vbm_tree[res * 3 + cntr[res]++] = n; - } INIT_VLC_STATIC(&frame_type_vlc, VLC_NBITS, sizeof(bits), bits, 1, 1, codes, 2, 2, 132); - return 0; } /** @@ -352,7 +357,7 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx) av_log(ctx, AV_LOG_ERROR, "Invalid extradata size %d (should be 46)\n", ctx->extradata_size); - return -1; + return AVERROR_INVALIDDATA; } flags = AV_RL32(ctx->extradata + 18); s->spillover_bitsize = 3 + av_ceil_log2(ctx->block_align); @@ -375,7 +380,7 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx) av_log(ctx, AV_LOG_ERROR, "Invalid denoise filter strength %d (max=11)\n", s->denoise_strength); - return -1; + return AVERROR_INVALIDDATA; } s->denoise_tilt_corr = !!(flags & 0x40); s->dc_level = (flags >> 7) & 0xF; @@ -397,7 +402,7 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx) init_get_bits(&s->gb, ctx->extradata + 22, (ctx->extradata_size - 22) << 3); if (decode_vbmtree(&s->gb, s->vbm_tree) < 0) { av_log(ctx, AV_LOG_ERROR, "Invalid VBM tree; broken extradata?\n"); - return -1; + return AVERROR_INVALIDDATA; } s->min_pitch_val = ((ctx->sample_rate << 8) / 400 + 50) >> 8; @@ -405,7 +410,7 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx) pitch_range = s->max_pitch_val - s->min_pitch_val; if (pitch_range <= 0) { av_log(ctx, AV_LOG_ERROR, "Invalid pitch range; broken extradata?\n"); - return -1; + return AVERROR_INVALIDDATA; } s->pitch_nbits = av_ceil_log2(pitch_range); s->last_pitch_val = 40; @@ -420,7 +425,7 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx) "Unsupported samplerate %d (min=%d, max=%d)\n", ctx->sample_rate, min_sr, max_sr); // 322-22097 Hz - return -1; + return AVERROR(ENOSYS); } s->block_conv_table[0] = s->min_pitch_val; @@ -430,7 +435,7 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx) s->block_delta_pitch_hrange = (pitch_range >> 3) & ~0xF; if (s->block_delta_pitch_hrange <= 0) { av_log(ctx, AV_LOG_ERROR, "Invalid delta pitch hrange; broken extradata?\n"); - return -1; + return AVERROR_INVALIDDATA; } s->block_delta_pitch_nbits = 1 + av_ceil_log2(s->block_delta_pitch_hrange); s->block_pitch_range = s->block_conv_table[2] + @@ -605,7 +610,7 @@ static void calc_input_response(WMAVoiceContext *s, float *lpcs, /* 70.57 =~ 1/log10(1.0331663) */ idx = (pwr * gain_mul - 0.0295) * 70.570526123; - if (idx > 127) { // fallback if index falls outside table range + if (idx > 127) { // fall back if index falls outside table range coeffs[n] = wmavoice_energy_table[127] * powf(1.0331663, idx - 127); } else @@ -613,7 +618,7 @@ static void calc_input_response(WMAVoiceContext *s, float *lpcs, } /* calculate the Hilbert transform of the gains, which we do (since this - * is a sinus input) by doing a phase shift (in theory, H(sin())=cos()). + * is a sine input) by doing a phase shift (in theory, H(sin())=cos()). * Hilbert_Transform(RDFT(x)) = Laplace_Transform(x), which calculates the * "moment" of the LPCs in this filter. */ s->dct.dct_calc(&s->dct, lpcs); @@ -1045,9 +1050,10 @@ static void aw_parse_coords(WMAVoiceContext *s, GetBitContext *gb, * @param gb bit I/O context * @param block_idx block index in frame [0, 1] * @param fcb structure containing fixed codebook vector info + * @return -1 on error, 0 otherwise */ -static void aw_pulse_set2(WMAVoiceContext *s, GetBitContext *gb, - int block_idx, AMRFixed *fcb) +static int aw_pulse_set2(WMAVoiceContext *s, GetBitContext *gb, + int block_idx, AMRFixed *fcb) { uint16_t use_mask_mem[9]; // only 5 are used, rest is padding uint16_t *use_mask = use_mask_mem + 2; @@ -1109,7 +1115,7 @@ static void aw_pulse_set2(WMAVoiceContext *s, GetBitContext *gb, else if (use_mask[2]) idx = 0x2F; else if (use_mask[3]) idx = 0x3F; else if (use_mask[4]) idx = 0x4F; - else return; + else return -1; idx -= av_log2_16bit(use_mask[idx >> 4]); } if (use_mask[idx >> 4] & (0x8000 >> (idx & 15))) { @@ -1126,6 +1132,7 @@ static void aw_pulse_set2(WMAVoiceContext *s, GetBitContext *gb, /* set offset for next block, relative to start of that block */ n = (MAX_FRAMESIZE / 2 - start_off) % fcb->pitch_lag; s->aw_next_pulse_off_cache = n ? fcb->pitch_lag - n : 0; + return 0; } /** @@ -1288,7 +1295,18 @@ static void synth_block_fcb_acb(WMAVoiceContext *s, GetBitContext *gb, * (fixed) codebook pulses of the speech signal. */ if (frame_desc->fcb_type == FCB_TYPE_AW_PULSES) { aw_pulse_set1(s, gb, block_idx, &fcb); - aw_pulse_set2(s, gb, block_idx, &fcb); + if (aw_pulse_set2(s, gb, block_idx, &fcb)) { + /* Conceal the block with silence and return. + * Skip the correct amount of bits to read the next + * block from the correct offset. */ + int r_idx = pRNG(s->frame_cntr, block_idx, size); + + for (n = 0; n < size; n++) + excitation[n] = + wmavoice_std_codebook[r_idx + n] * s->silence_gain; + skip_bits(gb, 7 + 1); + return; + } } else /* FCB_TYPE_EXC_PULSES */ { int offset_nbits = 5 - frame_desc->log_n_blocks; @@ -1445,7 +1463,7 @@ static int synth_frame(AVCodecContext *ctx, GetBitContext *gb, int frame_idx, if (bd_idx < 0) { av_log(ctx, AV_LOG_ERROR, "Invalid frame type VLC code, skipping\n"); - return -1; + return AVERROR_INVALIDDATA; } block_nsamples = MAX_FRAMESIZE / frame_descs[bd_idx].n_blocks; @@ -1642,7 +1660,7 @@ static void stabilize_lsps(double *lsps, int num) * does not modify the state of the bitreader; it * only uses it to copy the current stream position * @param s WMA Voice decoding context private data - * @return -1 if unsupported, 1 on not enough bits or 0 if OK. + * @return < 0 on error, 1 on not enough bits or 0 if OK. */ static int check_bits_for_superframe(GetBitContext *orig_gb, WMAVoiceContext *s) @@ -1660,7 +1678,7 @@ static int check_bits_for_superframe(GetBitContext *orig_gb, if (get_bits_left(gb) < 14) return 1; if (!get_bits1(gb)) - return -1; // WMAPro-in-WMAVoice superframe + return AVERROR(ENOSYS); // WMAPro-in-WMAVoice superframe if (get_bits1(gb)) skip_bits(gb, 12); // number of samples in superframe if (s->has_residual_lsps) { // residual LSPs (for all frames) if (get_bits_left(gb) < s->sframe_lsp_bitsize) @@ -1678,7 +1696,7 @@ static int check_bits_for_superframe(GetBitContext *orig_gb, } bd_idx = s->vbm_tree[get_vlc2(gb, frame_type_vlc.table, 6, 3)]; if (bd_idx < 0) - return -1; // invalid frame type VLC code + return AVERROR_INVALIDDATA; // invalid frame type VLC code frame_desc = &frame_descs[bd_idx]; if (frame_desc->acb_type == ACB_TYPE_ASYMMETRIC) { if (get_bits_left(gb) < s->pitch_nbits) @@ -1756,7 +1774,8 @@ static int synth_superframe(AVCodecContext *ctx, AVFrame *frame, if ((res = check_bits_for_superframe(gb, s)) == 1) { *got_frame_ptr = 0; return 1; - } + } else if (res < 0) + return res; /* First bit is speech/music bit, it differentiates between WMAVoice * speech samples (the actual codec) and WMAVoice music samples, which @@ -1773,7 +1792,7 @@ static int synth_superframe(AVCodecContext *ctx, AVFrame *frame, av_log(ctx, AV_LOG_ERROR, "Superframe encodes >480 samples (%d), not allowed\n", n_samples); - return -1; + return AVERROR_INVALIDDATA; } } /* Parse LSPs, if global for the superframe (can also be per-frame). */ @@ -2042,14 +2061,15 @@ static av_cold void wmavoice_flush(AVCodecContext *ctx) } AVCodec ff_wmavoice_decoder = { - .name = "wmavoice", - .type = AVMEDIA_TYPE_AUDIO, - .id = AV_CODEC_ID_WMAVOICE, - .priv_data_size = sizeof(WMAVoiceContext), - .init = wmavoice_decode_init, - .close = wmavoice_decode_end, - .decode = wmavoice_decode_packet, - .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1, - .flush = wmavoice_flush, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio Voice"), + .name = "wmavoice", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio Voice"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_WMAVOICE, + .priv_data_size = sizeof(WMAVoiceContext), + .init = wmavoice_decode_init, + .init_static_data = wmavoice_init_static_data, + .close = wmavoice_decode_end, + .decode = wmavoice_decode_packet, + .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1, + .flush = wmavoice_flush, }; diff --git a/ffmpeg/libavcodec/wmv2.c b/ffmpeg/libavcodec/wmv2.c index 6676652..30c8bc1 100644 --- a/ffmpeg/libavcodec/wmv2.c +++ b/ffmpeg/libavcodec/wmv2.c @@ -94,7 +94,8 @@ void ff_mspel_motion(MpegEncContext *s, { Wmv2Context * const w= (Wmv2Context*)s; uint8_t *ptr; - int dxy, offset, mx, my, src_x, src_y, v_edge_pos, linesize, uvlinesize; + int dxy, mx, my, src_x, src_y, v_edge_pos; + ptrdiff_t offset, linesize, uvlinesize; int emu=0; dxy = ((motion_y & 1) << 1) | (motion_x & 1); @@ -116,15 +117,17 @@ void ff_mspel_motion(MpegEncContext *s, uvlinesize = s->uvlinesize; ptr = ref_picture[0] + (src_y * linesize) + src_x; - if(s->flags&CODEC_FLAG_EMU_EDGE){ if(src_x<1 || src_y<1 || src_x + 17 >= s->h_edge_pos || src_y + h+1 >= v_edge_pos){ - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr - 1 - s->linesize, s->linesize, 19, 19, - src_x-1, src_y-1, s->h_edge_pos, s->v_edge_pos); + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + ptr - 1 - s->linesize, + s->linesize, s->linesize, + 19, 19, + src_x - 1, src_y - 1, + s->h_edge_pos, s->v_edge_pos); ptr= s->edge_emu_buffer + 1 + s->linesize; emu=1; } - } s->dsp.put_mspel_pixels_tab[dxy](dest_y , ptr , linesize); s->dsp.put_mspel_pixels_tab[dxy](dest_y+8 , ptr+8 , linesize); @@ -160,16 +163,22 @@ void ff_mspel_motion(MpegEncContext *s, offset = (src_y * uvlinesize) + src_x; ptr = ref_picture[1] + offset; if(emu){ - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9, - src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1); + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, + s->uvlinesize, s->uvlinesize, + 9, 9, + src_x, src_y, + s->h_edge_pos >> 1, s->v_edge_pos >> 1); ptr= s->edge_emu_buffer; } pix_op[1][dxy](dest_cb, ptr, uvlinesize, h >> 1); ptr = ref_picture[2] + offset; if(emu){ - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9, - src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1); + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, + s->uvlinesize, s->uvlinesize, + 9, 9, + src_x, src_y, + s->h_edge_pos >> 1, s->v_edge_pos >> 1); ptr= s->edge_emu_buffer; } pix_op[1][dxy](dest_cr, ptr, uvlinesize, h >> 1); diff --git a/ffmpeg/libavcodec/wmv2dec.c b/ffmpeg/libavcodec/wmv2dec.c index fccb1bb..4f2a5e9 100644 --- a/ffmpeg/libavcodec/wmv2dec.c +++ b/ffmpeg/libavcodec/wmv2dec.c @@ -446,6 +446,8 @@ int ff_wmv2_decode_mb(MpegEncContext *s, int16_t block[6][64]) static av_cold int wmv2_decode_init(AVCodecContext *avctx){ Wmv2Context * const w= avctx->priv_data; + avctx->flags |= CODEC_FLAG_EMU_EDGE; + if(ff_msmpeg4_decode_init(avctx) < 0) return -1; @@ -466,6 +468,7 @@ static av_cold int wmv2_decode_end(AVCodecContext *avctx) AVCodec ff_wmv2_decoder = { .name = "wmv2", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 8"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_WMV2, .priv_data_size = sizeof(Wmv2Context), @@ -473,6 +476,5 @@ AVCodec ff_wmv2_decoder = { .close = wmv2_decode_end, .decode = ff_h263_decode_frame, .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 8"), .pix_fmts = ff_pixfmt_list_420, }; diff --git a/ffmpeg/libavcodec/wmv2enc.c b/ffmpeg/libavcodec/wmv2enc.c index 23b64a7..6aeee59 100644 --- a/ffmpeg/libavcodec/wmv2enc.c +++ b/ffmpeg/libavcodec/wmv2enc.c @@ -169,10 +169,12 @@ void ff_wmv2_encode_mb(MpegEncContext * s, ff_wmv2_inter_table[w->cbp_table_index][cbp + 64][1], ff_wmv2_inter_table[w->cbp_table_index][cbp + 64][0]); + s->misc_bits += get_bits_diff(s); /* motion vector */ ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); ff_msmpeg4_encode_motion(s, motion_x - pred_x, motion_y - pred_y); + s->mv_bits += get_bits_diff(s); } else { /* compute cbp */ cbp = 0; @@ -203,15 +205,21 @@ void ff_wmv2_encode_mb(MpegEncContext * s, s->h263_aic_dir=0; put_bits(&s->pb, ff_table_inter_intra[s->h263_aic_dir][1], ff_table_inter_intra[s->h263_aic_dir][0]); } + s->misc_bits += get_bits_diff(s); } for (i = 0; i < 6; i++) { ff_msmpeg4_encode_block(s, block[i], i); } + if (s->mb_intra) + s->i_tex_bits += get_bits_diff(s); + else + s->p_tex_bits += get_bits_diff(s); } AVCodec ff_wmv2_encoder = { .name = "wmv2", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 8"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_WMV2, .priv_data_size = sizeof(Wmv2Context), @@ -219,5 +227,4 @@ AVCodec ff_wmv2_encoder = { .encode2 = ff_MPV_encode_picture, .close = ff_MPV_encode_end, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 8"), }; diff --git a/ffmpeg/libavcodec/wnv1.c b/ffmpeg/libavcodec/wnv1.c index 162dd1f..99aee3c 100644 --- a/ffmpeg/libavcodec/wnv1.c +++ b/ffmpeg/libavcodec/wnv1.c @@ -31,8 +31,6 @@ typedef struct WNV1Context { - AVCodecContext *avctx; - int shift; GetBitContext gb; } WNV1Context; @@ -70,8 +68,8 @@ static int decode_frame(AVCodecContext *avctx, int prev_y = 0, prev_u = 0, prev_v = 0; uint8_t *rbuf; - if(buf_size<=8) { - av_log(avctx, AV_LOG_ERROR, "buf_size %d is too small\n", buf_size); + if (buf_size <= 8) { + av_log(avctx, AV_LOG_ERROR, "Packet size %d is too small\n", buf_size); return AVERROR_INVALIDDATA; } @@ -80,6 +78,7 @@ static int decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n"); return AVERROR(ENOMEM); } + memset(rbuf + buf_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); if ((ret = ff_get_buffer(avctx, p, 0)) < 0) { av_free(rbuf); @@ -133,10 +132,8 @@ static int decode_frame(AVCodecContext *avctx, static av_cold int decode_init(AVCodecContext *avctx) { - WNV1Context * const l = avctx->priv_data; static VLC_TYPE code_table[1 << CODE_VLC_BITS][2]; - l->avctx = avctx; avctx->pix_fmt = AV_PIX_FMT_YUV422P; code_vlc.table = code_table; @@ -150,11 +147,11 @@ static av_cold int decode_init(AVCodecContext *avctx) AVCodec ff_wnv1_decoder = { .name = "wnv1", + .long_name = NULL_IF_CONFIG_SMALL("Winnov WNV1"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_WNV1, .priv_data_size = sizeof(WNV1Context), .init = decode_init, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Winnov WNV1"), }; diff --git a/ffmpeg/libavcodec/ws-snd1.c b/ffmpeg/libavcodec/ws-snd1.c index d27df75..6929cbf 100644 --- a/ffmpeg/libavcodec/ws-snd1.c +++ b/ffmpeg/libavcodec/ws-snd1.c @@ -172,10 +172,10 @@ static int ws_snd_decode_frame(AVCodecContext *avctx, void *data, AVCodec ff_ws_snd1_decoder = { .name = "ws_snd1", + .long_name = NULL_IF_CONFIG_SMALL("Westwood Audio (SND1)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_WESTWOOD_SND1, .init = ws_snd_decode_init, .decode = ws_snd_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Westwood Audio (SND1)"), }; diff --git a/ffmpeg/libavcodec/x86/Makefile b/ffmpeg/libavcodec/x86/Makefile index 38ef867..2d2d5a0 100644 --- a/ffmpeg/libavcodec/x86/Makefile +++ b/ffmpeg/libavcodec/x86/Makefile @@ -1,11 +1,18 @@ -OBJS += x86/fmtconvert_init.o \ - x86/constants.o +OBJS += x86/constants.o \ + x86/fmtconvert_init.o \ OBJS-$(CONFIG_AAC_DECODER) += x86/sbrdsp_init.o OBJS-$(CONFIG_AC3DSP) += x86/ac3dsp_init.o OBJS-$(CONFIG_CAVS_DECODER) += x86/cavsdsp.o +OBJS-$(CONFIG_DCT) += x86/dct_init.o OBJS-$(CONFIG_DNXHD_ENCODER) += x86/dnxhdenc.o +OBJS-$(CONFIG_DSPUTIL) += x86/dsputil_init.o \ + x86/dsputil_x86.o +OBJS-$(CONFIG_ENCODERS) += x86/dsputilenc_mmx.o \ + x86/fdct.o \ + x86/motion_est.o OBJS-$(CONFIG_FFT) += x86/fft_init.o +OBJS-$(CONFIG_H263DSP) += x86/h263dsp_init.o OBJS-$(CONFIG_H264CHROMA) += x86/h264chroma_init.o OBJS-$(CONFIG_H264DSP) += x86/h264dsp_init.o OBJS-$(CONFIG_H264PRED) += x86/h264_intrapred_init.o @@ -13,7 +20,7 @@ OBJS-$(CONFIG_H264QPEL) += x86/h264_qpel.o OBJS-$(CONFIG_HPELDSP) += x86/hpeldsp_init.o OBJS-$(CONFIG_LPC) += x86/lpc.o OBJS-$(CONFIG_MLP_DECODER) += x86/mlpdsp.o -OBJS-$(CONFIG_MPEGAUDIODSP) += x86/mpegaudiodec.o +OBJS-$(CONFIG_MPEGAUDIODSP) += x86/mpegaudiodsp.o OBJS-$(CONFIG_MPEGVIDEO) += x86/mpegvideo.o OBJS-$(CONFIG_MPEGVIDEOENC) += x86/mpegvideoenc.o OBJS-$(CONFIG_PNG_DECODER) += x86/pngdsp_init.o @@ -28,33 +35,41 @@ OBJS-$(CONFIG_VC1_DECODER) += x86/vc1dsp_init.o OBJS-$(CONFIG_VIDEODSP) += x86/videodsp_init.o OBJS-$(CONFIG_VORBIS_DECODER) += x86/vorbisdsp_init.o OBJS-$(CONFIG_VP3DSP) += x86/vp3dsp_init.o -OBJS-$(CONFIG_VP5_DECODER) += x86/vp56dsp_init.o -OBJS-$(CONFIG_VP6_DECODER) += x86/vp56dsp_init.o +OBJS-$(CONFIG_VP6_DECODER) += x86/vp6dsp_init.o OBJS-$(CONFIG_VP8_DECODER) += x86/vp8dsp_init.o +OBJS-$(CONFIG_VP9_DECODER) += x86/vp9dsp_init.o +OBJS-$(CONFIG_WEBP_DECODER) += x86/vp8dsp_init.o OBJS-$(CONFIG_XMM_CLOBBER_TEST) += x86/w64xmmtest.o MMX-OBJS-$(CONFIG_DSPUTIL) += x86/dsputil_mmx.o \ - x86/fdct.o \ + x86/fpel_mmx.o \ x86/idct_mmx_xvid.o \ x86/idct_sse2_xvid.o \ - x86/simple_idct.o \ - -MMX-OBJS-$(CONFIG_ENCODERS) += x86/dsputilenc_mmx.o \ - x86/motion_est.o + x86/rnd_mmx.o \ + x86/simple_idct.o MMX-OBJS-$(CONFIG_DIRAC_DECODER) += x86/dirac_dwt.o +MMX-OBJS-$(CONFIG_HPELDSP) += x86/fpel_mmx.o \ + x86/hpeldsp_mmx.o \ + x86/rnd_mmx.o MMX-OBJS-$(CONFIG_SNOW_DECODER) += x86/snowdsp.o MMX-OBJS-$(CONFIG_SNOW_ENCODER) += x86/snowdsp.o MMX-OBJS-$(CONFIG_VC1_DECODER) += x86/vc1dsp_mmx.o +YASM-OBJS += x86/deinterlace.o \ + x86/fmtconvert.o \ + YASM-OBJS-$(CONFIG_AAC_DECODER) += x86/sbrdsp.o YASM-OBJS-$(CONFIG_AC3DSP) += x86/ac3dsp.o YASM-OBJS-$(CONFIG_DCT) += x86/dct32.o YASM-OBJS-$(CONFIG_DIRAC_DECODER) += x86/diracdsp_mmx.o x86/diracdsp_yasm.o\ x86/dwt_yasm.o +YASM-OBJS-$(CONFIG_DSPUTIL) += x86/dsputil.o \ + x86/fpel.o \ + x86/mpeg4qpel.o \ + x86/qpel.o YASM-OBJS-$(CONFIG_ENCODERS) += x86/dsputilenc.o YASM-OBJS-$(CONFIG_FFT) += x86/fft.o -YASM-OBJS-$(CONFIG_H263_DECODER) += x86/h263_loopfilter.o -YASM-OBJS-$(CONFIG_H263_ENCODER) += x86/h263_loopfilter.o +YASM-OBJS-$(CONFIG_H263DSP) += x86/h263_loopfilter.o YASM-OBJS-$(CONFIG_H264CHROMA) += x86/h264_chromamc.o \ x86/h264_chromamc_10bit.o YASM-OBJS-$(CONFIG_H264DSP) += x86/h264_deblock.o \ @@ -67,10 +82,10 @@ YASM-OBJS-$(CONFIG_H264PRED) += x86/h264_intrapred.o \ x86/h264_intrapred_10bit.o YASM-OBJS-$(CONFIG_H264QPEL) += x86/h264_qpel_8bit.o \ x86/h264_qpel_10bit.o \ - x86/qpelbase.o \ - x86/fpelbase.o -YASM-OBJS-$(CONFIG_HPELDSP) += x86/hpeldsp.o \ - x86/fpelbase.o + x86/fpel.o \ + x86/qpel.o +YASM-OBJS-$(CONFIG_HPELDSP) += x86/fpel.o \ + x86/hpeldsp.o YASM-OBJS-$(CONFIG_MPEGAUDIODSP) += x86/imdct36.o YASM-OBJS-$(CONFIG_PNG_DECODER) += x86/pngdsp.o YASM-OBJS-$(CONFIG_PRORES_DECODER) += x86/proresdsp.o @@ -83,13 +98,9 @@ YASM-OBJS-$(CONFIG_VC1_DECODER) += x86/vc1dsp.o YASM-OBJS-$(CONFIG_VIDEODSP) += x86/videodsp.o YASM-OBJS-$(CONFIG_VORBIS_DECODER) += x86/vorbisdsp.o YASM-OBJS-$(CONFIG_VP3DSP) += x86/vp3dsp.o -YASM-OBJS-$(CONFIG_VP6_DECODER) += x86/vp56dsp.o -YASM-OBJS-$(CONFIG_VP8_DECODER) += x86/vp8dsp.o - -YASM-OBJS-$(CONFIG_DSPUTIL) += x86/dsputil.o \ - x86/mpeg4qpel.o \ - x86/qpelbase.o \ - x86/fpelbase.o - -YASM-OBJS += x86/deinterlace.o \ - x86/fmtconvert.o +YASM-OBJS-$(CONFIG_VP6_DECODER) += x86/vp6dsp.o +YASM-OBJS-$(CONFIG_VP8_DECODER) += x86/vp8dsp.o \ + x86/vp8dsp_loopfilter.o +YASM-OBJS-$(CONFIG_VP9_DECODER) += x86/vp9itxfm.o \ + x86/vp9mc.o +YASM-OBJS-$(CONFIG_WEBP_DECODER) += x86/vp8dsp.o diff --git a/ffmpeg/libavcodec/x86/ac3dsp.asm b/ffmpeg/libavcodec/x86/ac3dsp.asm index 98fb446..89a64f5 100644 --- a/ffmpeg/libavcodec/x86/ac3dsp.asm +++ b/ffmpeg/libavcodec/x86/ac3dsp.asm @@ -379,42 +379,6 @@ cglobal ac3_compute_mantissa_size, 1, 2, 4, mant_cnt, sum %endif %endmacro -%if HAVE_AMD3DNOW_EXTERNAL -INIT_MMX 3dnow -cglobal ac3_extract_exponents, 3, 3, 0, exp, coef, len - add expq, lenq - lea coefq, [coefq+4*lenq] - neg lenq - movq m3, [pd_1] - movq m4, [pd_151] -.loop: - movq m0, [coefq+4*lenq ] - movq m1, [coefq+4*lenq+8] - PABSD m0, m2 - PABSD m1, m2 - pslld m0, 1 - por m0, m3 - pi2fd m2, m0 - psrld m2, 23 - movq m0, m4 - psubd m0, m2 - pslld m1, 1 - por m1, m3 - pi2fd m2, m1 - psrld m2, 23 - movq m1, m4 - psubd m1, m2 - packssdw m0, m0 - packuswb m0, m0 - packssdw m1, m1 - packuswb m1, m1 - punpcklwd m0, m1 - movd [expq+lenq], m0 - add lenq, 4 - jl .loop - REP_RET -%endif - %macro AC3_EXTRACT_EXPONENTS 0 cglobal ac3_extract_exponents, 3, 3, 4, exp, coef, len add expq, lenq diff --git a/ffmpeg/libavcodec/x86/ac3dsp_init.c b/ffmpeg/libavcodec/x86/ac3dsp_init.c index e2a190e..5819d00 100644 --- a/ffmpeg/libavcodec/x86/ac3dsp_init.c +++ b/ffmpeg/libavcodec/x86/ac3dsp_init.c @@ -22,34 +22,47 @@ #include "libavutil/mem.h" #include "libavutil/x86/asm.h" #include "libavutil/x86/cpu.h" -#include "dsputil_mmx.h" +#include "dsputil_x86.h" #include "libavcodec/ac3.h" #include "libavcodec/ac3dsp.h" -extern void ff_ac3_exponent_min_mmx (uint8_t *exp, int num_reuse_blocks, int nb_coefs); -extern void ff_ac3_exponent_min_mmxext(uint8_t *exp, int num_reuse_blocks, int nb_coefs); -extern void ff_ac3_exponent_min_sse2 (uint8_t *exp, int num_reuse_blocks, int nb_coefs); +void ff_ac3_exponent_min_mmx (uint8_t *exp, int num_reuse_blocks, int nb_coefs); +void ff_ac3_exponent_min_mmxext(uint8_t *exp, int num_reuse_blocks, int nb_coefs); +void ff_ac3_exponent_min_sse2 (uint8_t *exp, int num_reuse_blocks, int nb_coefs); -extern int ff_ac3_max_msb_abs_int16_mmx (const int16_t *src, int len); -extern int ff_ac3_max_msb_abs_int16_mmxext(const int16_t *src, int len); -extern int ff_ac3_max_msb_abs_int16_sse2 (const int16_t *src, int len); -extern int ff_ac3_max_msb_abs_int16_ssse3(const int16_t *src, int len); +int ff_ac3_max_msb_abs_int16_mmx (const int16_t *src, int len); +int ff_ac3_max_msb_abs_int16_mmxext(const int16_t *src, int len); +int ff_ac3_max_msb_abs_int16_sse2 (const int16_t *src, int len); +int ff_ac3_max_msb_abs_int16_ssse3(const int16_t *src, int len); -extern void ff_ac3_lshift_int16_mmx (int16_t *src, unsigned int len, unsigned int shift); -extern void ff_ac3_lshift_int16_sse2(int16_t *src, unsigned int len, unsigned int shift); +void ff_ac3_lshift_int16_mmx (int16_t *src, unsigned int len, unsigned int shift); +void ff_ac3_lshift_int16_sse2(int16_t *src, unsigned int len, unsigned int shift); -extern void ff_ac3_rshift_int32_mmx (int32_t *src, unsigned int len, unsigned int shift); -extern void ff_ac3_rshift_int32_sse2(int32_t *src, unsigned int len, unsigned int shift); +void ff_ac3_rshift_int32_mmx (int32_t *src, unsigned int len, unsigned int shift); +void ff_ac3_rshift_int32_sse2(int32_t *src, unsigned int len, unsigned int shift); -extern void ff_float_to_fixed24_3dnow(int32_t *dst, const float *src, unsigned int len); -extern void ff_float_to_fixed24_sse (int32_t *dst, const float *src, unsigned int len); -extern void ff_float_to_fixed24_sse2 (int32_t *dst, const float *src, unsigned int len); +void ff_float_to_fixed24_3dnow(int32_t *dst, const float *src, unsigned int len); +void ff_float_to_fixed24_sse (int32_t *dst, const float *src, unsigned int len); +void ff_float_to_fixed24_sse2 (int32_t *dst, const float *src, unsigned int len); -extern int ff_ac3_compute_mantissa_size_sse2(uint16_t mant_cnt[6][16]); +int ff_ac3_compute_mantissa_size_sse2(uint16_t mant_cnt[6][16]); -extern void ff_ac3_extract_exponents_3dnow(uint8_t *exp, int32_t *coef, int nb_coefs); -extern void ff_ac3_extract_exponents_sse2 (uint8_t *exp, int32_t *coef, int nb_coefs); -extern void ff_ac3_extract_exponents_ssse3(uint8_t *exp, int32_t *coef, int nb_coefs); +void ff_ac3_extract_exponents_3dnow(uint8_t *exp, int32_t *coef, int nb_coefs); +void ff_ac3_extract_exponents_sse2 (uint8_t *exp, int32_t *coef, int nb_coefs); +void ff_ac3_extract_exponents_ssse3(uint8_t *exp, int32_t *coef, int nb_coefs); + +void ff_apply_window_int16_round_mmxext(int16_t *output, const int16_t *input, + const int16_t *window, unsigned int len); +void ff_apply_window_int16_round_sse2(int16_t *output, const int16_t *input, + const int16_t *window, unsigned int len); +void ff_apply_window_int16_mmxext(int16_t *output, const int16_t *input, + const int16_t *window, unsigned int len); +void ff_apply_window_int16_sse2(int16_t *output, const int16_t *input, + const int16_t *window, unsigned int len); +void ff_apply_window_int16_ssse3(int16_t *output, const int16_t *input, + const int16_t *window, unsigned int len); +void ff_apply_window_int16_ssse3_atom(int16_t *output, const int16_t *input, + const int16_t *window, unsigned int len); #if ARCH_X86_32 && defined(__INTEL_COMPILER) # undef HAVE_7REGS @@ -185,47 +198,59 @@ static void ac3_downmix_sse(float **samples, float (*matrix)[2], av_cold void ff_ac3dsp_init_x86(AC3DSPContext *c, int bit_exact) { - int mm_flags = av_get_cpu_flags(); + int cpu_flags = av_get_cpu_flags(); - if (EXTERNAL_MMX(mm_flags)) { + if (EXTERNAL_MMX(cpu_flags)) { c->ac3_exponent_min = ff_ac3_exponent_min_mmx; c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_mmx; c->ac3_lshift_int16 = ff_ac3_lshift_int16_mmx; c->ac3_rshift_int32 = ff_ac3_rshift_int32_mmx; } - if (EXTERNAL_AMD3DNOW(mm_flags)) { - c->extract_exponents = ff_ac3_extract_exponents_3dnow; + if (EXTERNAL_AMD3DNOW(cpu_flags)) { if (!bit_exact) { c->float_to_fixed24 = ff_float_to_fixed24_3dnow; } } - if (EXTERNAL_MMXEXT(mm_flags)) { + if (EXTERNAL_MMXEXT(cpu_flags)) { c->ac3_exponent_min = ff_ac3_exponent_min_mmxext; c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_mmxext; + if (bit_exact) { + c->apply_window_int16 = ff_apply_window_int16_mmxext; + } else { + c->apply_window_int16 = ff_apply_window_int16_round_mmxext; + } } - if (EXTERNAL_SSE(mm_flags)) { + if (EXTERNAL_SSE(cpu_flags)) { c->float_to_fixed24 = ff_float_to_fixed24_sse; } - if (EXTERNAL_SSE2(mm_flags)) { + if (EXTERNAL_SSE2(cpu_flags)) { c->ac3_exponent_min = ff_ac3_exponent_min_sse2; c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_sse2; c->float_to_fixed24 = ff_float_to_fixed24_sse2; c->compute_mantissa_size = ff_ac3_compute_mantissa_size_sse2; c->extract_exponents = ff_ac3_extract_exponents_sse2; - if (!(mm_flags & AV_CPU_FLAG_SSE2SLOW)) { + if (!(cpu_flags & AV_CPU_FLAG_SSE2SLOW)) { c->ac3_lshift_int16 = ff_ac3_lshift_int16_sse2; c->ac3_rshift_int32 = ff_ac3_rshift_int32_sse2; } + if (bit_exact) { + c->apply_window_int16 = ff_apply_window_int16_sse2; + } else if (!(cpu_flags & AV_CPU_FLAG_SSE2SLOW)) { + c->apply_window_int16 = ff_apply_window_int16_round_sse2; + } } - if (EXTERNAL_SSSE3(mm_flags)) { + if (EXTERNAL_SSSE3(cpu_flags)) { c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_ssse3; - if (!(mm_flags & AV_CPU_FLAG_ATOM)) { + if (cpu_flags & AV_CPU_FLAG_ATOM) { + c->apply_window_int16 = ff_apply_window_int16_ssse3_atom; + } else { c->extract_exponents = ff_ac3_extract_exponents_ssse3; + c->apply_window_int16 = ff_apply_window_int16_ssse3; } } #if HAVE_SSE_INLINE && HAVE_7REGS - if (INLINE_SSE(mm_flags)) { + if (INLINE_SSE(cpu_flags)) { c->downmix = ac3_downmix_sse; } #endif diff --git a/ffmpeg/libavcodec/x86/cabac.h b/ffmpeg/libavcodec/x86/cabac.h index 2c9f77e..558d287 100644 --- a/ffmpeg/libavcodec/x86/cabac.h +++ b/ffmpeg/libavcodec/x86/cabac.h @@ -1,20 +1,20 @@ /* * Copyright (c) 2003 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -27,8 +27,27 @@ #include "libavutil/internal.h" #include "config.h" +#if (defined(__i386) && defined(__clang__) && (__clang_major__<2 || (__clang_major__==2 && __clang_minor__<10)))\ + || ( !defined(__clang__) && defined(__llvm__) && __GNUC__==4 && __GNUC_MINOR__==2 && __GNUC_PATCHLEVEL__<=1) +# define BROKEN_COMPILER 1 +#else +# define BROKEN_COMPILER 0 +#endif + #if HAVE_INLINE_ASM +#ifndef UNCHECKED_BITSTREAM_READER +#define UNCHECKED_BITSTREAM_READER !CONFIG_SAFE_BITSTREAM_READER +#endif + +#if UNCHECKED_BITSTREAM_READER +#define END_CHECK(end) "" +#else +#define END_CHECK(end) \ + "cmp "end" , %%"REG_c" \n\t"\ + "jge 1f \n\t" +#endif + #ifdef BROKEN_RELOCATIONS #define TABLES_ARG , "r"(tables) @@ -73,7 +92,9 @@ "test "lowword" , "lowword" \n\t"\ "jnz 2f \n\t"\ "mov "byte" , %%"REG_c" \n\t"\ + END_CHECK(end)\ "add"OPSIZE" $2 , "byte" \n\t"\ + "1: \n\t"\ "movzwl (%%"REG_c") , "tmp" \n\t"\ "lea -1("low") , %%ecx \n\t"\ "xor "low" , %%ecx \n\t"\ @@ -132,7 +153,9 @@ "test "lowword" , "lowword" \n\t"\ " jnz 2f \n\t"\ "mov "byte" , %%"REG_c" \n\t"\ + END_CHECK(end)\ "add"OPSIZE" $2 , "byte" \n\t"\ + "1: \n\t"\ "movzwl (%%"REG_c") , "tmp" \n\t"\ "lea -1("low") , %%ecx \n\t"\ "xor "low" , %%ecx \n\t"\ @@ -149,9 +172,7 @@ #endif /* BROKEN_RELOCATIONS */ - -#if HAVE_7REGS && !(defined(__i386) && defined(__clang__) && (__clang_major__<2 || (__clang_major__==2 && __clang_minor__<10)))\ - && !( !defined(__clang__) && defined(__llvm__) && __GNUC__==4 && __GNUC_MINOR__==2 && __GNUC_PATCHLEVEL__<=1) +#if HAVE_7REGS && !BROKEN_COMPILER #define get_cabac_inline get_cabac_inline_x86 static av_always_inline int get_cabac_inline_x86(CABACContext *c, uint8_t *const state) @@ -186,6 +207,7 @@ static av_always_inline int get_cabac_inline_x86(CABACContext *c, } #endif /* HAVE_7REGS */ +#if !BROKEN_COMPILER #define get_cabac_bypass_sign get_cabac_bypass_sign_x86 static av_always_inline int get_cabac_bypass_sign_x86(CABACContext *c, int val) { @@ -208,9 +230,16 @@ static av_always_inline int get_cabac_bypass_sign_x86(CABACContext *c, int val) "movzwl (%1), %%edx \n\t" "bswap %%edx \n\t" "shrl $15, %%edx \n\t" +#if UNCHECKED_BITSTREAM_READER "add $2, %1 \n\t" "addl %%edx, %%eax \n\t" "mov %1, %c4(%2) \n\t" +#else + "addl %%edx, %%eax \n\t" + "cmp %c5(%2), %1 \n\t" + "jge 1f \n\t" + "add"OPSIZE" $2, %c4(%2) \n\t" +#endif "1: \n\t" "movl %%eax, %c3(%2) \n\t" @@ -225,5 +254,46 @@ static av_always_inline int get_cabac_bypass_sign_x86(CABACContext *c, int val) return val; } +#define get_cabac_bypass get_cabac_bypass_x86 +static av_always_inline int get_cabac_bypass_x86(CABACContext *c) +{ + x86_reg tmp; + int res; + __asm__ volatile( + "movl %c6(%2), %k1 \n\t" + "movl %c3(%2), %%eax \n\t" + "shl $17, %k1 \n\t" + "add %%eax, %%eax \n\t" + "sub %k1, %%eax \n\t" + "cltd \n\t" + "and %%edx, %k1 \n\t" + "add %k1, %%eax \n\t" + "inc %%edx \n\t" + "test %%ax, %%ax \n\t" + "jnz 1f \n\t" + "mov %c4(%2), %1 \n\t" + "subl $0xFFFF, %%eax \n\t" + "movzwl (%1), %%ecx \n\t" + "bswap %%ecx \n\t" + "shrl $15, %%ecx \n\t" + "addl %%ecx, %%eax \n\t" + "cmp %c5(%2), %1 \n\t" + "jge 1f \n\t" + "add"OPSIZE" $2, %c4(%2) \n\t" + "1: \n\t" + "movl %%eax, %c3(%2) \n\t" + + : "=&d"(res), "=&r"(tmp) + : "r"(c), + "i"(offsetof(CABACContext, low)), + "i"(offsetof(CABACContext, bytestream)), + "i"(offsetof(CABACContext, bytestream_end)), + "i"(offsetof(CABACContext, range)) + : "%eax", "%ecx", "memory" + ); + return res; +} +#endif /* !BROKEN_COMPILER */ + #endif /* HAVE_INLINE_ASM */ #endif /* AVCODEC_X86_CABAC_H */ diff --git a/ffmpeg/libavcodec/x86/cavsdsp.c b/ffmpeg/libavcodec/x86/cavsdsp.c index deeb5cf..aaa09d1 100644 --- a/ffmpeg/libavcodec/x86/cavsdsp.c +++ b/ffmpeg/libavcodec/x86/cavsdsp.c @@ -28,10 +28,11 @@ #include "libavutil/x86/asm.h" #include "libavutil/x86/cpu.h" #include "libavcodec/cavsdsp.h" -#include "dsputil_mmx.h" +#include "constants.h" +#include "dsputil_x86.h" #include "config.h" -#if (HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE) +#if HAVE_MMX_INLINE /* in/out: mma=mma+mmb, mmb=mmb-mma */ #define SUMSUB_BA( a, b ) \ @@ -122,6 +123,17 @@ static inline void cavs_idct8_1d(int16_t *block, uint64_t bias) ); } +#define SBUTTERFLY(a,b,t,n,m)\ + "mov" #m " " #a ", " #t " \n\t" /* abcd */\ + "punpckl" #n " " #b ", " #a " \n\t" /* aebf */\ + "punpckh" #n " " #b ", " #t " \n\t" /* cgdh */\ + +#define TRANSPOSE4(a,b,c,d,t)\ + SBUTTERFLY(a,b,t,wd,q) /* a=aebf t=cgdh */\ + SBUTTERFLY(c,d,b,wd,q) /* c=imjn b=kolp */\ + SBUTTERFLY(a,c,d,dq,q) /* a=aeim d=bfjn */\ + SBUTTERFLY(t,b,c,dq,q) /* t=cgko c=dhlp */ + static void cavs_idct8_add_mmx(uint8_t *dst, int16_t *block, int stride) { int i; @@ -187,6 +199,10 @@ static void cavs_idct8_add_mmx(uint8_t *dst, int16_t *block, int stride) ff_add_pixels_clamped_mmx(b2, dst, stride); } +#endif /* HAVE_MMX_INLINE */ + +#if (HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE) + /***************************************************************************** * * motion compensation @@ -409,22 +425,22 @@ static void OPNAME ## cavs_qpel16_h_ ## MMX(uint8_t *dst, uint8_t *src, int dstS }\ #define CAVS_MC(OPNAME, SIZE, MMX) \ -static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc20_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\ +static void OPNAME ## cavs_qpel ## SIZE ## _mc20_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\ {\ OPNAME ## cavs_qpel ## SIZE ## _h_ ## MMX(dst, src, stride, stride);\ }\ \ -static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc01_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\ +static void OPNAME ## cavs_qpel ## SIZE ## _mc01_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\ {\ OPNAME ## cavs_qpel ## SIZE ## _v1_ ## MMX(dst, src, stride, stride);\ }\ \ -static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc02_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\ +static void OPNAME ## cavs_qpel ## SIZE ## _mc02_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\ {\ OPNAME ## cavs_qpel ## SIZE ## _v2_ ## MMX(dst, src, stride, stride);\ }\ \ -static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc03_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\ +static void OPNAME ## cavs_qpel ## SIZE ## _mc03_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\ {\ OPNAME ## cavs_qpel ## SIZE ## _v3_ ## MMX(dst, src, stride, stride);\ }\ @@ -441,6 +457,50 @@ static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc03_ ## MMX(uint8_t *dst, ui #endif /* (HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE) */ +#if HAVE_MMX_INLINE +static void put_cavs_qpel8_mc00_mmx(uint8_t *dst, uint8_t *src, + ptrdiff_t stride) +{ + ff_put_pixels8_mmx(dst, src, stride, 8); +} + +static void avg_cavs_qpel8_mc00_mmx(uint8_t *dst, uint8_t *src, + ptrdiff_t stride) +{ + ff_avg_pixels8_mmx(dst, src, stride, 8); +} + +static void put_cavs_qpel16_mc00_mmx(uint8_t *dst, uint8_t *src, + ptrdiff_t stride) +{ + ff_put_pixels16_mmx(dst, src, stride, 16); +} + +static void avg_cavs_qpel16_mc00_mmx(uint8_t *dst, uint8_t *src, + ptrdiff_t stride) +{ + ff_avg_pixels16_mmx(dst, src, stride, 16); +} + +static av_cold void cavsdsp_init_mmx(CAVSDSPContext *c, + AVCodecContext *avctx) +{ + c->put_cavs_qpel_pixels_tab[0][0] = put_cavs_qpel16_mc00_mmx; + c->put_cavs_qpel_pixels_tab[1][0] = put_cavs_qpel8_mc00_mmx; + c->avg_cavs_qpel_pixels_tab[0][0] = avg_cavs_qpel16_mc00_mmx; + c->avg_cavs_qpel_pixels_tab[1][0] = avg_cavs_qpel8_mc00_mmx; + + c->cavs_idct8_add = cavs_idct8_add_mmx; + c->idct_perm = FF_TRANSPOSE_IDCT_PERM; +} +#endif /* HAVE_MMX_INLINE */ + +#define DSPFUNC(PFX, IDX, NUM, EXT) \ + c->PFX ## _cavs_qpel_pixels_tab[IDX][ 2] = PFX ## _cavs_qpel ## NUM ## _mc20_ ## EXT; \ + c->PFX ## _cavs_qpel_pixels_tab[IDX][ 4] = PFX ## _cavs_qpel ## NUM ## _mc01_ ## EXT; \ + c->PFX ## _cavs_qpel_pixels_tab[IDX][ 8] = PFX ## _cavs_qpel ## NUM ## _mc02_ ## EXT; \ + c->PFX ## _cavs_qpel_pixels_tab[IDX][12] = PFX ## _cavs_qpel ## NUM ## _mc03_ ## EXT; \ + #if HAVE_MMXEXT_INLINE QPEL_CAVS(put_, PUT_OP, mmxext) QPEL_CAVS(avg_, AVG_MMXEXT_OP, mmxext) @@ -450,23 +510,13 @@ CAVS_MC(put_, 16, mmxext) CAVS_MC(avg_, 8, mmxext) CAVS_MC(avg_, 16, mmxext) -static av_cold void ff_cavsdsp_init_mmxext(CAVSDSPContext *c, - AVCodecContext *avctx) +static av_cold void cavsdsp_init_mmxext(CAVSDSPContext *c, + AVCodecContext *avctx) { -#define dspfunc(PFX, IDX, NUM) \ - c->PFX ## _pixels_tab[IDX][ 0] = ff_ ## PFX ## NUM ## _mc00_mmxext; \ - c->PFX ## _pixels_tab[IDX][ 2] = ff_ ## PFX ## NUM ## _mc20_mmxext; \ - c->PFX ## _pixels_tab[IDX][ 4] = ff_ ## PFX ## NUM ## _mc01_mmxext; \ - c->PFX ## _pixels_tab[IDX][ 8] = ff_ ## PFX ## NUM ## _mc02_mmxext; \ - c->PFX ## _pixels_tab[IDX][12] = ff_ ## PFX ## NUM ## _mc03_mmxext; \ - - dspfunc(put_cavs_qpel, 0, 16); - dspfunc(put_cavs_qpel, 1, 8); - dspfunc(avg_cavs_qpel, 0, 16); - dspfunc(avg_cavs_qpel, 1, 8); -#undef dspfunc - c->cavs_idct8_add = cavs_idct8_add_mmx; - c->idct_perm = FF_TRANSPOSE_IDCT_PERM; + DSPFUNC(put, 0, 16, mmxext); + DSPFUNC(put, 1, 8, mmxext); + DSPFUNC(avg, 0, 16, mmxext); + DSPFUNC(avg, 1, 8, mmxext); } #endif /* HAVE_MMXEXT_INLINE */ @@ -479,34 +529,30 @@ CAVS_MC(put_, 16,3dnow) CAVS_MC(avg_, 8, 3dnow) CAVS_MC(avg_, 16,3dnow) -static av_cold void ff_cavsdsp_init_3dnow(CAVSDSPContext *c, - AVCodecContext *avctx) +static av_cold void cavsdsp_init_3dnow(CAVSDSPContext *c, + AVCodecContext *avctx) { -#define dspfunc(PFX, IDX, NUM) \ - c->PFX ## _pixels_tab[IDX][ 0] = ff_ ## PFX ## NUM ## _mc00_mmxext; \ - c->PFX ## _pixels_tab[IDX][ 2] = ff_ ## PFX ## NUM ## _mc20_3dnow; \ - c->PFX ## _pixels_tab[IDX][ 4] = ff_ ## PFX ## NUM ## _mc01_3dnow; \ - c->PFX ## _pixels_tab[IDX][ 8] = ff_ ## PFX ## NUM ## _mc02_3dnow; \ - c->PFX ## _pixels_tab[IDX][12] = ff_ ## PFX ## NUM ## _mc03_3dnow; \ - - dspfunc(put_cavs_qpel, 0, 16); - dspfunc(put_cavs_qpel, 1, 8); - dspfunc(avg_cavs_qpel, 0, 16); - dspfunc(avg_cavs_qpel, 1, 8); -#undef dspfunc - c->cavs_idct8_add = cavs_idct8_add_mmx; - c->idct_perm = FF_TRANSPOSE_IDCT_PERM; + DSPFUNC(put, 0, 16, 3dnow); + DSPFUNC(put, 1, 8, 3dnow); + DSPFUNC(avg, 0, 16, 3dnow); + DSPFUNC(avg, 1, 8, 3dnow); } #endif /* HAVE_AMD3DNOW_INLINE */ av_cold void ff_cavsdsp_init_x86(CAVSDSPContext *c, AVCodecContext *avctx) { - int mm_flags = av_get_cpu_flags(); +#if HAVE_MMX_INLINE + int cpu_flags = av_get_cpu_flags(); -#if HAVE_MMXEXT_INLINE - if (mm_flags & AV_CPU_FLAG_MMXEXT) ff_cavsdsp_init_mmxext(c, avctx); -#endif /* HAVE_MMXEXT_INLINE */ + if (INLINE_MMX(cpu_flags)) + cavsdsp_init_mmx(c, avctx); +#endif /* HAVE_MMX_INLINE */ #if HAVE_AMD3DNOW_INLINE - if (mm_flags & AV_CPU_FLAG_3DNOW) ff_cavsdsp_init_3dnow(c, avctx); + if (INLINE_AMD3DNOW(cpu_flags)) + cavsdsp_init_3dnow(c, avctx); #endif /* HAVE_AMD3DNOW_INLINE */ +#if HAVE_MMXEXT_INLINE + if (INLINE_MMXEXT(cpu_flags)) + cavsdsp_init_mmxext(c, avctx); +#endif /* HAVE_MMXEXT_INLINE */ } diff --git a/ffmpeg/libavcodec/x86/constants.c b/ffmpeg/libavcodec/x86/constants.c index 821d73f..3bba80b 100644 --- a/ffmpeg/libavcodec/x86/constants.c +++ b/ffmpeg/libavcodec/x86/constants.c @@ -20,6 +20,9 @@ #include "libavutil/mem.h" #include "libavutil/x86/asm.h" // for xmm_reg +#include "constants.h" + +DECLARE_ALIGNED(8, const uint64_t, ff_wtwo) = 0x0002000200020002ULL; DECLARE_ALIGNED(16, const xmm_reg, ff_pw_1) = { 0x0001000100010001ULL, 0x0001000100010001ULL }; DECLARE_ALIGNED(16, const xmm_reg, ff_pw_2) = { 0x0002000200020002ULL, 0x0002000200020002ULL }; @@ -28,12 +31,23 @@ DECLARE_ALIGNED(16, const xmm_reg, ff_pw_4) = { 0x0004000400040004ULL, 0x000 DECLARE_ALIGNED(16, const xmm_reg, ff_pw_5) = { 0x0005000500050005ULL, 0x0005000500050005ULL }; DECLARE_ALIGNED(16, const xmm_reg, ff_pw_8) = { 0x0008000800080008ULL, 0x0008000800080008ULL }; DECLARE_ALIGNED(16, const xmm_reg, ff_pw_9) = { 0x0009000900090009ULL, 0x0009000900090009ULL }; +DECLARE_ALIGNED(8, const uint64_t, ff_pw_15) = 0x000F000F000F000FULL; DECLARE_ALIGNED(16, const xmm_reg, ff_pw_16) = { 0x0010001000100010ULL, 0x0010001000100010ULL }; +DECLARE_ALIGNED(16, const xmm_reg, ff_pw_17) = { 0x0011001100110011ULL, 0x0011001100110011ULL }; DECLARE_ALIGNED(16, const xmm_reg, ff_pw_18) = { 0x0012001200120012ULL, 0x0012001200120012ULL }; +DECLARE_ALIGNED(8, const uint64_t, ff_pw_20) = 0x0014001400140014ULL; DECLARE_ALIGNED(16, const xmm_reg, ff_pw_32) = { 0x0020002000200020ULL, 0x0020002000200020ULL }; +DECLARE_ALIGNED(8, const uint64_t, ff_pw_42) = 0x002A002A002A002AULL; +DECLARE_ALIGNED(8, const uint64_t, ff_pw_53) = 0x0035003500350035ULL; DECLARE_ALIGNED(16, const xmm_reg, ff_pw_64) = { 0x0040004000400040ULL, 0x0040004000400040ULL }; +DECLARE_ALIGNED(8, const uint64_t, ff_pw_96) = 0x0060006000600060ULL; +DECLARE_ALIGNED(8, const uint64_t, ff_pw_128) = 0x0080008000800080ULL; +DECLARE_ALIGNED(8, const uint64_t, ff_pw_255) = 0x00ff00ff00ff00ffULL; +DECLARE_ALIGNED(16, const xmm_reg, ff_pw_512) = { 0x0200020002000200ULL, 0x0200020002000200ULL }; +DECLARE_ALIGNED(16, const xmm_reg, ff_pw_1019) = { 0x03FB03FB03FB03FBULL, 0x03FB03FB03FB03FBULL }; DECLARE_ALIGNED(16, const xmm_reg, ff_pb_0) = { 0x0000000000000000ULL, 0x0000000000000000ULL }; DECLARE_ALIGNED(16, const xmm_reg, ff_pb_1) = { 0x0101010101010101ULL, 0x0101010101010101ULL }; DECLARE_ALIGNED(16, const xmm_reg, ff_pb_3) = { 0x0303030303030303ULL, 0x0303030303030303ULL }; DECLARE_ALIGNED(16, const xmm_reg, ff_pb_80) = { 0x8080808080808080ULL, 0x8080808080808080ULL }; +DECLARE_ALIGNED(8, const uint64_t, ff_pb_FC) = 0xFCFCFCFCFCFCFCFCULL; diff --git a/ffmpeg/libavcodec/x86/dirac_dwt.c b/ffmpeg/libavcodec/x86/dirac_dwt.c index fbb25a4..04c514f 100644 --- a/ffmpeg/libavcodec/x86/dirac_dwt.c +++ b/ffmpeg/libavcodec/x86/dirac_dwt.c @@ -21,7 +21,7 @@ */ #include "libavutil/x86/asm.h" -#include "dsputil_mmx.h" +#include "dsputil_x86.h" #include "dirac_dwt.h" #define COMPOSE_VERTICAL(ext, align) \ diff --git a/ffmpeg/libavcodec/x86/diracdsp_mmx.c b/ffmpeg/libavcodec/x86/diracdsp_mmx.c index cb6465f..a28bb82 100644 --- a/ffmpeg/libavcodec/x86/diracdsp_mmx.c +++ b/ffmpeg/libavcodec/x86/diracdsp_mmx.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "dsputil_mmx.h" +#include "dsputil_x86.h" #include "diracdsp_mmx.h" void ff_put_rect_clamped_mmx(uint8_t *dst, int dst_stride, const int16_t *src, int src_stride, int width, int height); diff --git a/ffmpeg/libavcodec/x86/dnxhdenc.c b/ffmpeg/libavcodec/x86/dnxhdenc.c index 349fbb0..c7e776a 100644 --- a/ffmpeg/libavcodec/x86/dnxhdenc.c +++ b/ffmpeg/libavcodec/x86/dnxhdenc.c @@ -23,6 +23,7 @@ #include "libavutil/attributes.h" #include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" #include "libavcodec/dnxhdenc.h" #if HAVE_SSE2_INLINE @@ -58,7 +59,7 @@ static void get_pixels_8x4_sym_sse2(int16_t *block, const uint8_t *pixels, int l av_cold void ff_dnxhdenc_init_x86(DNXHDEncContext *ctx) { #if HAVE_SSE2_INLINE - if (av_get_cpu_flags() & AV_CPU_FLAG_SSE2) { + if (INLINE_SSE2(av_get_cpu_flags())) { if (ctx->cid_table->bit_depth == 8) ctx->get_pixels_8x4_sym = get_pixels_8x4_sym_sse2; } diff --git a/ffmpeg/libavcodec/x86/dsputil.asm b/ffmpeg/libavcodec/x86/dsputil.asm index 9970c02..77069e2 100644 --- a/ffmpeg/libavcodec/x86/dsputil.asm +++ b/ffmpeg/libavcodec/x86/dsputil.asm @@ -554,8 +554,8 @@ VECTOR_CLIP_INT32 6, 1, 0, 0 %if cpuflag(ssse3) pshufb m0, m2 pshufb m1, m2 - mova [r0 + 0], m0 - mova [r0 + 16], m1 + mov%1 [r0 + 0], m0 + mov%1 [r0 + 16], m1 %else pshuflw m0, m0, 10110001b pshuflw m1, m1, 10110001b @@ -569,8 +569,8 @@ VECTOR_CLIP_INT32 6, 1, 0, 0 psrlw m3, 8 por m2, m0 por m3, m1 - mova [r0 + 0], m2 - mova [r0 + 16], m3 + mov%1 [r0 + 0], m2 + mov%1 [r0 + 16], m3 %endif add r0, 32 add r1, 32 @@ -583,7 +583,7 @@ VECTOR_CLIP_INT32 6, 1, 0, 0 mov%1 m0, [r1] %if cpuflag(ssse3) pshufb m0, m2 - mova [r0], m0 + mov%1 [r0], m0 %else pshuflw m0, m0, 10110001b pshufhw m0, m0, 10110001b @@ -591,7 +591,7 @@ VECTOR_CLIP_INT32 6, 1, 0, 0 psllw m0, 8 psrlw m2, 8 por m2, m0 - mova [r0], m2 + mov%1 [r0], m2 %endif add r1, 16 add r0, 16 @@ -607,6 +607,7 @@ cglobal bswap32_buf, 3,4,3 cglobal bswap32_buf, 3,4,5 mov r3, r1 %endif + or r3, r0 and r3, 15 jz .start_align BSWAP_LOOPS u diff --git a/ffmpeg/libavcodec/x86/dsputil_mmx.c b/ffmpeg/libavcodec/x86/dsputil_mmx.c index fe59d22..df8cfdb 100644 --- a/ffmpeg/libavcodec/x86/dsputil_mmx.c +++ b/ffmpeg/libavcodec/x86/dsputil_mmx.c @@ -22,195 +22,17 @@ * MMX optimization by Nick Kurshev */ -#include "libavutil/attributes.h" +#include "config.h" +#include "libavutil/avassert.h" #include "libavutil/cpu.h" #include "libavutil/x86/asm.h" -#include "libavcodec/dsputil.h" -#include "libavcodec/h264dsp.h" -#include "libavcodec/mpegvideo.h" -#include "libavcodec/simple_idct.h" #include "libavcodec/videodsp.h" -#include "dsputil_mmx.h" -#include "idct_xvid.h" +#include "constants.h" +#include "dsputil_x86.h" #include "diracdsp_mmx.h" -//#undef NDEBUG -//#include - -/* pixel operations */ -DECLARE_ALIGNED(8, const uint64_t, ff_bone) = 0x0101010101010101ULL; -DECLARE_ALIGNED(8, const uint64_t, ff_wtwo) = 0x0002000200020002ULL; - -DECLARE_ALIGNED(8, const uint64_t, ff_pw_15) = 0x000F000F000F000FULL; -DECLARE_ALIGNED(16, const xmm_reg, ff_pw_17) = { 0x0011001100110011ULL, 0x0011001100110011ULL }; -DECLARE_ALIGNED(8, const uint64_t, ff_pw_20) = 0x0014001400140014ULL; -DECLARE_ALIGNED(8, const uint64_t, ff_pw_42) = 0x002A002A002A002AULL; -DECLARE_ALIGNED(8, const uint64_t, ff_pw_53) = 0x0035003500350035ULL; -DECLARE_ALIGNED(8, const uint64_t, ff_pw_96) = 0x0060006000600060ULL; -DECLARE_ALIGNED(8, const uint64_t, ff_pw_128) = 0x0080008000800080ULL; -DECLARE_ALIGNED(8, const uint64_t, ff_pw_255) = 0x00ff00ff00ff00ffULL; -DECLARE_ALIGNED(16, const xmm_reg, ff_pw_512) = { 0x0200020002000200ULL, 0x0200020002000200ULL }; -DECLARE_ALIGNED(16, const xmm_reg, ff_pw_1019) = { 0x03FB03FB03FB03FBULL, 0x03FB03FB03FB03FBULL }; - -DECLARE_ALIGNED(8, const uint64_t, ff_pb_3F) = 0x3F3F3F3F3F3F3F3FULL; -DECLARE_ALIGNED(8, const uint64_t, ff_pb_FC) = 0xFCFCFCFCFCFCFCFCULL; - -DECLARE_ALIGNED(16, const double, ff_pd_1)[2] = { 1.0, 1.0 }; -DECLARE_ALIGNED(16, const double, ff_pd_2)[2] = { 2.0, 2.0 }; - - -#if HAVE_YASM -void ff_put_pixels8_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2, - int dstStride, int src1Stride, int h); -void ff_put_no_rnd_pixels8_l2_mmxext(uint8_t *dst, uint8_t *src1, - uint8_t *src2, int dstStride, - int src1Stride, int h); -void ff_avg_pixels8_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2, - int dstStride, int src1Stride, int h); -void ff_put_pixels16_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2, - int dstStride, int src1Stride, int h); -void ff_avg_pixels16_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2, - int dstStride, int src1Stride, int h); -void ff_put_no_rnd_pixels16_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2, - int dstStride, int src1Stride, int h); -void ff_avg_pixels8_mmxext(uint8_t *block, const uint8_t *pixels, - ptrdiff_t line_size, int h); - -void ff_put_pixels8_mmxext(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h); -static void ff_put_pixels16_mmxext(uint8_t *block, const uint8_t *pixels, - ptrdiff_t line_size, int h) -{ - ff_put_pixels8_mmxext(block, pixels, line_size, h); - ff_put_pixels8_mmxext(block + 8, pixels + 8, line_size, h); -} - -void ff_put_mpeg4_qpel16_h_lowpass_mmxext(uint8_t *dst, uint8_t *src, - int dstStride, int srcStride, int h); -void ff_avg_mpeg4_qpel16_h_lowpass_mmxext(uint8_t *dst, uint8_t *src, - int dstStride, int srcStride, int h); -void ff_put_no_rnd_mpeg4_qpel16_h_lowpass_mmxext(uint8_t *dst, uint8_t *src, - int dstStride, int srcStride, - int h); -void ff_put_mpeg4_qpel8_h_lowpass_mmxext(uint8_t *dst, uint8_t *src, - int dstStride, int srcStride, int h); -void ff_avg_mpeg4_qpel8_h_lowpass_mmxext(uint8_t *dst, uint8_t *src, - int dstStride, int srcStride, int h); -void ff_put_no_rnd_mpeg4_qpel8_h_lowpass_mmxext(uint8_t *dst, uint8_t *src, - int dstStride, int srcStride, - int h); -void ff_put_mpeg4_qpel16_v_lowpass_mmxext(uint8_t *dst, uint8_t *src, - int dstStride, int srcStride); -void ff_avg_mpeg4_qpel16_v_lowpass_mmxext(uint8_t *dst, uint8_t *src, - int dstStride, int srcStride); -void ff_put_no_rnd_mpeg4_qpel16_v_lowpass_mmxext(uint8_t *dst, uint8_t *src, - int dstStride, int srcStride); -void ff_put_mpeg4_qpel8_v_lowpass_mmxext(uint8_t *dst, uint8_t *src, - int dstStride, int srcStride); -void ff_avg_mpeg4_qpel8_v_lowpass_mmxext(uint8_t *dst, uint8_t *src, - int dstStride, int srcStride); -void ff_put_no_rnd_mpeg4_qpel8_v_lowpass_mmxext(uint8_t *dst, uint8_t *src, - int dstStride, int srcStride); -#define ff_put_no_rnd_pixels16_mmxext ff_put_pixels16_mmxext -#define ff_put_no_rnd_pixels8_mmxext ff_put_pixels8_mmxext -#endif /* HAVE_YASM */ - - #if HAVE_INLINE_ASM -#define JUMPALIGN() __asm__ volatile (".p2align 3"::) -#define MOVQ_ZERO(regd) __asm__ volatile ("pxor %%"#regd", %%"#regd ::) - -#define MOVQ_BFE(regd) \ - __asm__ volatile ( \ - "pcmpeqd %%"#regd", %%"#regd" \n\t" \ - "paddb %%"#regd", %%"#regd" \n\t" ::) - -#ifndef PIC -#define MOVQ_BONE(regd) __asm__ volatile ("movq %0, %%"#regd" \n\t" :: "m"(ff_bone)) -#define MOVQ_WTWO(regd) __asm__ volatile ("movq %0, %%"#regd" \n\t" :: "m"(ff_wtwo)) -#else -// for shared library it's better to use this way for accessing constants -// pcmpeqd -> -1 -#define MOVQ_BONE(regd) \ - __asm__ volatile ( \ - "pcmpeqd %%"#regd", %%"#regd" \n\t" \ - "psrlw $15, %%"#regd" \n\t" \ - "packuswb %%"#regd", %%"#regd" \n\t" ::) - -#define MOVQ_WTWO(regd) \ - __asm__ volatile ( \ - "pcmpeqd %%"#regd", %%"#regd" \n\t" \ - "psrlw $15, %%"#regd" \n\t" \ - "psllw $1, %%"#regd" \n\t"::) - -#endif - -// using regr as temporary and for the output result -// first argument is unmodifed and second is trashed -// regfe is supposed to contain 0xfefefefefefefefe -#define PAVGB_MMX(rega, regb, regr, regfe) \ - "movq "#rega", "#regr" \n\t" \ - "por "#regb", "#regr" \n\t" \ - "pxor "#rega", "#regb" \n\t" \ - "pand "#regfe", "#regb" \n\t" \ - "psrlq $1, "#regb" \n\t" \ - "psubb "#regb", "#regr" \n\t" - -// mm6 is supposed to contain 0xfefefefefefefefe -#define PAVGBP_MMX(rega, regb, regr, regc, regd, regp) \ - "movq "#rega", "#regr" \n\t" \ - "movq "#regc", "#regp" \n\t" \ - "por "#regb", "#regr" \n\t" \ - "por "#regd", "#regp" \n\t" \ - "pxor "#rega", "#regb" \n\t" \ - "pxor "#regc", "#regd" \n\t" \ - "pand %%mm6, "#regb" \n\t" \ - "pand %%mm6, "#regd" \n\t" \ - "psrlq $1, "#regd" \n\t" \ - "psrlq $1, "#regb" \n\t" \ - "psubb "#regb", "#regr" \n\t" \ - "psubb "#regd", "#regp" \n\t" - -/***********************************/ -/* MMX rounding */ - -#define DEF(x, y) x ## _ ## y ## _mmx -#define SET_RND MOVQ_WTWO -#define PAVGBP(a, b, c, d, e, f) PAVGBP_MMX(a, b, c, d, e, f) -#define PAVGB(a, b, c, e) PAVGB_MMX(a, b, c, e) -#define OP_AVG(a, b, c, e) PAVGB_MMX(a, b, c, e) - -#include "dsputil_rnd_template.c" - -#undef DEF -#undef SET_RND -#undef PAVGBP -#undef PAVGB -#undef OP_AVG - -#endif /* HAVE_INLINE_ASM */ - - -#if HAVE_YASM - -/***********************************/ -/* MMXEXT specific */ - -//FIXME the following could be optimized too ... -static void ff_avg_pixels16_mmxext(uint8_t *block, const uint8_t *pixels, - int line_size, int h) -{ - ff_avg_pixels8_mmxext(block, pixels, line_size, h); - ff_avg_pixels8_mmxext(block + 8, pixels + 8, line_size, h); -} - -#endif /* HAVE_YASM */ - - -#if HAVE_INLINE_ASM -/***********************************/ -/* standard MMX */ - void ff_put_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, int line_size) { @@ -345,70 +167,8 @@ void ff_add_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, } while (--i); } -static void put_pixels8_mmx(uint8_t *block, const uint8_t *pixels, - ptrdiff_t line_size, int h) -{ - __asm__ volatile ( - "lea (%3, %3), %%"REG_a" \n\t" - ".p2align 3 \n\t" - "1: \n\t" - "movq (%1 ), %%mm0 \n\t" - "movq (%1, %3), %%mm1 \n\t" - "movq %%mm0, (%2) \n\t" - "movq %%mm1, (%2, %3) \n\t" - "add %%"REG_a", %1 \n\t" - "add %%"REG_a", %2 \n\t" - "movq (%1 ), %%mm0 \n\t" - "movq (%1, %3), %%mm1 \n\t" - "movq %%mm0, (%2) \n\t" - "movq %%mm1, (%2, %3) \n\t" - "add %%"REG_a", %1 \n\t" - "add %%"REG_a", %2 \n\t" - "subl $4, %0 \n\t" - "jnz 1b \n\t" - : "+g"(h), "+r"(pixels), "+r"(block) - : "r"((x86_reg)line_size) - : "%"REG_a, "memory" - ); -} - -static void put_pixels16_mmx(uint8_t *block, const uint8_t *pixels, - ptrdiff_t line_size, int h) -{ - __asm__ volatile ( - "lea (%3, %3), %%"REG_a" \n\t" - ".p2align 3 \n\t" - "1: \n\t" - "movq (%1 ), %%mm0 \n\t" - "movq 8(%1 ), %%mm4 \n\t" - "movq (%1, %3), %%mm1 \n\t" - "movq 8(%1, %3), %%mm5 \n\t" - "movq %%mm0, (%2) \n\t" - "movq %%mm4, 8(%2) \n\t" - "movq %%mm1, (%2, %3) \n\t" - "movq %%mm5, 8(%2, %3) \n\t" - "add %%"REG_a", %1 \n\t" - "add %%"REG_a", %2 \n\t" - "movq (%1 ), %%mm0 \n\t" - "movq 8(%1 ), %%mm4 \n\t" - "movq (%1, %3), %%mm1 \n\t" - "movq 8(%1, %3), %%mm5 \n\t" - "movq %%mm0, (%2) \n\t" - "movq %%mm4, 8(%2) \n\t" - "movq %%mm1, (%2, %3) \n\t" - "movq %%mm5, 8(%2, %3) \n\t" - "add %%"REG_a", %1 \n\t" - "add %%"REG_a", %2 \n\t" - "subl $4, %0 \n\t" - "jnz 1b \n\t" - : "+g"(h), "+r"(pixels), "+r"(block) - : "r"((x86_reg)line_size) - : "%"REG_a, "memory" - ); -} - #define CLEAR_BLOCKS(name, n) \ -static void name(int16_t *blocks) \ +void name(int16_t *blocks) \ { \ __asm__ volatile ( \ "pxor %%mm7, %%mm7 \n\t" \ @@ -425,10 +185,10 @@ static void name(int16_t *blocks) \ : "%"REG_a \ ); \ } -CLEAR_BLOCKS(clear_blocks_mmx, 6) -CLEAR_BLOCKS(clear_block_mmx, 1) +CLEAR_BLOCKS(ff_clear_blocks_mmx, 6) +CLEAR_BLOCKS(ff_clear_block_mmx, 1) -static void clear_block_sse(int16_t *block) +void ff_clear_block_sse(int16_t *block) { __asm__ volatile ( "xorps %%xmm0, %%xmm0 \n" @@ -445,7 +205,7 @@ static void clear_block_sse(int16_t *block) ); } -static void clear_blocks_sse(int16_t *blocks) +void ff_clear_blocks_sse(int16_t *blocks) { __asm__ volatile ( "xorps %%xmm0, %%xmm0 \n" @@ -467,7 +227,7 @@ static void clear_blocks_sse(int16_t *blocks) ); } -static void add_bytes_mmx(uint8_t *dst, uint8_t *src, int w) +void ff_add_bytes_mmx(uint8_t *dst, uint8_t *src, int w) { x86_reg i = 0; __asm__ volatile ( @@ -492,53 +252,10 @@ static void add_bytes_mmx(uint8_t *dst, uint8_t *src, int w) dst[i + 0] += src[i + 0]; } -#if HAVE_7REGS -static void add_hfyu_median_prediction_cmov(uint8_t *dst, const uint8_t *top, - const uint8_t *diff, int w, - int *left, int *left_top) -{ - x86_reg w2 = -w; - x86_reg x; - int l = *left & 0xff; - int tl = *left_top & 0xff; - int t; - __asm__ volatile ( - "mov %7, %3 \n" - "1: \n" - "movzbl (%3, %4), %2 \n" - "mov %2, %k3 \n" - "sub %b1, %b3 \n" - "add %b0, %b3 \n" - "mov %2, %1 \n" - "cmp %0, %2 \n" - "cmovg %0, %2 \n" - "cmovg %1, %0 \n" - "cmp %k3, %0 \n" - "cmovg %k3, %0 \n" - "mov %7, %3 \n" - "cmp %2, %0 \n" - "cmovl %2, %0 \n" - "add (%6, %4), %b0 \n" - "mov %b0, (%5, %4) \n" - "inc %4 \n" - "jl 1b \n" - : "+&q"(l), "+&q"(tl), "=&r"(t), "=&q"(x), "+&r"(w2) - : "r"(dst + w), "r"(diff + w), "rm"(top + w) - ); - *left = l; - *left_top = tl; -} -#endif -#endif /* HAVE_INLINE_ASM */ - -void ff_h263_v_loop_filter_mmx(uint8_t *src, int stride, int qscale); -void ff_h263_h_loop_filter_mmx(uint8_t *src, int stride, int qscale); - -#if HAVE_INLINE_ASM /* Draw the edges of width 'w' of an image of size width, height * this MMX version can only handle w == 8 || w == 16. */ -static void draw_edges_mmx(uint8_t *buf, int wrap, int width, int height, - int w, int h, int sides) +void ff_draw_edges_mmx(uint8_t *buf, int wrap, int width, int height, + int w, int h, int sides) { uint8_t *ptr, *last_line; int i; @@ -649,417 +366,11 @@ static void draw_edges_mmx(uint8_t *buf, int wrap, int width, int height, } } } -#endif /* HAVE_INLINE_ASM */ - - -#if HAVE_YASM -#define QPEL_OP(OPNAME, ROUNDER, RND, MMX) \ -static void OPNAME ## qpel8_mc00_ ## MMX (uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - ff_ ## OPNAME ## pixels8_ ## MMX(dst, src, stride, 8); \ -} \ - \ -static void OPNAME ## qpel8_mc10_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - uint64_t temp[8]; \ - uint8_t * const half = (uint8_t*)temp; \ - ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(half, src, 8, \ - stride, 8); \ - ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src, half, \ - stride, stride, 8); \ -} \ - \ -static void OPNAME ## qpel8_mc20_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - ff_ ## OPNAME ## mpeg4_qpel8_h_lowpass_ ## MMX(dst, src, stride, \ - stride, 8); \ -} \ - \ -static void OPNAME ## qpel8_mc30_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - uint64_t temp[8]; \ - uint8_t * const half = (uint8_t*)temp; \ - ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(half, src, 8, \ - stride, 8); \ - ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src + 1, half, stride, \ - stride, 8); \ -} \ - \ -static void OPNAME ## qpel8_mc01_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - uint64_t temp[8]; \ - uint8_t * const half = (uint8_t*)temp; \ - ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(half, src, \ - 8, stride); \ - ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src, half, \ - stride, stride, 8); \ -} \ - \ -static void OPNAME ## qpel8_mc02_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, src, \ - stride, stride); \ -} \ - \ -static void OPNAME ## qpel8_mc03_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - uint64_t temp[8]; \ - uint8_t * const half = (uint8_t*)temp; \ - ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(half, src, \ - 8, stride); \ - ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src + stride, half, stride,\ - stride, 8); \ -} \ - \ -static void OPNAME ## qpel8_mc11_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - uint64_t half[8 + 9]; \ - uint8_t * const halfH = ((uint8_t*)half) + 64; \ - uint8_t * const halfHV = ((uint8_t*)half); \ - ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ - stride, 9); \ - ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH, 8, \ - stride, 9); \ - ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\ - ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV, \ - stride, 8, 8); \ -} \ - \ -static void OPNAME ## qpel8_mc31_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - uint64_t half[8 + 9]; \ - uint8_t * const halfH = ((uint8_t*)half) + 64; \ - uint8_t * const halfHV = ((uint8_t*)half); \ - ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ - stride, 9); \ - ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8, \ - stride, 9); \ - ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\ - ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV, \ - stride, 8, 8); \ -} \ - \ -static void OPNAME ## qpel8_mc13_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - uint64_t half[8 + 9]; \ - uint8_t * const halfH = ((uint8_t*)half) + 64; \ - uint8_t * const halfHV = ((uint8_t*)half); \ - ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ - stride, 9); \ - ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH, 8, \ - stride, 9); \ - ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\ - ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV, \ - stride, 8, 8); \ -} \ - \ -static void OPNAME ## qpel8_mc33_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - uint64_t half[8 + 9]; \ - uint8_t * const halfH = ((uint8_t*)half) + 64; \ - uint8_t * const halfHV = ((uint8_t*)half); \ - ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ - stride, 9); \ - ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8, \ - stride, 9); \ - ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\ - ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV, \ - stride, 8, 8); \ -} \ - \ -static void OPNAME ## qpel8_mc21_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - uint64_t half[8 + 9]; \ - uint8_t * const halfH = ((uint8_t*)half) + 64; \ - uint8_t * const halfHV = ((uint8_t*)half); \ - ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ - stride, 9); \ - ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\ - ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV, \ - stride, 8, 8); \ -} \ - \ -static void OPNAME ## qpel8_mc23_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - uint64_t half[8 + 9]; \ - uint8_t * const halfH = ((uint8_t*)half) + 64; \ - uint8_t * const halfHV = ((uint8_t*)half); \ - ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ - stride, 9); \ - ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\ - ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV, \ - stride, 8, 8); \ -} \ - \ -static void OPNAME ## qpel8_mc12_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - uint64_t half[8 + 9]; \ - uint8_t * const halfH = ((uint8_t*)half); \ - ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ - stride, 9); \ - ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH, \ - 8, stride, 9); \ - ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH, \ - stride, 8); \ -} \ - \ -static void OPNAME ## qpel8_mc32_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - uint64_t half[8 + 9]; \ - uint8_t * const halfH = ((uint8_t*)half); \ - ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ - stride, 9); \ - ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8, \ - stride, 9); \ - ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH, \ - stride, 8); \ -} \ - \ -static void OPNAME ## qpel8_mc22_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - uint64_t half[9]; \ - uint8_t * const halfH = ((uint8_t*)half); \ - ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ - stride, 9); \ - ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH, \ - stride, 8); \ -} \ - \ -static void OPNAME ## qpel16_mc00_ ## MMX (uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - ff_ ## OPNAME ## pixels16_ ## MMX(dst, src, stride, 16); \ -} \ - \ -static void OPNAME ## qpel16_mc10_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - uint64_t temp[32]; \ - uint8_t * const half = (uint8_t*)temp; \ - ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(half, src, 16, \ - stride, 16); \ - ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src, half, stride, \ - stride, 16); \ -} \ - \ -static void OPNAME ## qpel16_mc20_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - ff_ ## OPNAME ## mpeg4_qpel16_h_lowpass_ ## MMX(dst, src, \ - stride, stride, 16);\ -} \ - \ -static void OPNAME ## qpel16_mc30_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - uint64_t temp[32]; \ - uint8_t * const half = (uint8_t*)temp; \ - ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(half, src, 16, \ - stride, 16); \ - ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src + 1, half, \ - stride, stride, 16); \ -} \ - \ -static void OPNAME ## qpel16_mc01_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - uint64_t temp[32]; \ - uint8_t * const half = (uint8_t*)temp; \ - ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(half, src, 16, \ - stride); \ - ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src, half, stride, \ - stride, 16); \ -} \ - \ -static void OPNAME ## qpel16_mc02_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, src, \ - stride, stride); \ -} \ - \ -static void OPNAME ## qpel16_mc03_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - uint64_t temp[32]; \ - uint8_t * const half = (uint8_t*)temp; \ - ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(half, src, 16, \ - stride); \ - ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src+stride, half, \ - stride, stride, 16); \ -} \ - \ -static void OPNAME ## qpel16_mc11_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - uint64_t half[16 * 2 + 17 * 2]; \ - uint8_t * const halfH = ((uint8_t*)half) + 256; \ - uint8_t * const halfHV = ((uint8_t*)half); \ - ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ - stride, 17); \ - ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16, \ - stride, 17); \ - ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH, \ - 16, 16); \ - ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV, \ - stride, 16, 16); \ -} \ - \ -static void OPNAME ## qpel16_mc31_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - uint64_t half[16 * 2 + 17 * 2]; \ - uint8_t * const halfH = ((uint8_t*)half) + 256; \ - uint8_t * const halfHV = ((uint8_t*)half); \ - ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ - stride, 17); \ - ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16, \ - stride, 17); \ - ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH, \ - 16, 16); \ - ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV, \ - stride, 16, 16); \ -} \ - \ -static void OPNAME ## qpel16_mc13_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - uint64_t half[16 * 2 + 17 * 2]; \ - uint8_t * const halfH = ((uint8_t*)half) + 256; \ - uint8_t * const halfHV = ((uint8_t*)half); \ - ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ - stride, 17); \ - ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16, \ - stride, 17); \ - ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH, \ - 16, 16); \ - ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV, \ - stride, 16, 16); \ -} \ - \ -static void OPNAME ## qpel16_mc33_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - uint64_t half[16 * 2 + 17 * 2]; \ - uint8_t * const halfH = ((uint8_t*)half) + 256; \ - uint8_t * const halfHV = ((uint8_t*)half); \ - ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ - stride, 17); \ - ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16, \ - stride, 17); \ - ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH, \ - 16, 16); \ - ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV, \ - stride, 16, 16); \ -} \ - \ -static void OPNAME ## qpel16_mc21_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - uint64_t half[16 * 2 + 17 * 2]; \ - uint8_t * const halfH = ((uint8_t*)half) + 256; \ - uint8_t * const halfHV = ((uint8_t*)half); \ - ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ - stride, 17); \ - ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH, \ - 16, 16); \ - ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV, \ - stride, 16, 16); \ -} \ - \ -static void OPNAME ## qpel16_mc23_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - uint64_t half[16 * 2 + 17 * 2]; \ - uint8_t * const halfH = ((uint8_t*)half) + 256; \ - uint8_t * const halfHV = ((uint8_t*)half); \ - ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ - stride, 17); \ - ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH, \ - 16, 16); \ - ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV, \ - stride, 16, 16); \ -} \ - \ -static void OPNAME ## qpel16_mc12_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - uint64_t half[17 * 2]; \ - uint8_t * const halfH = ((uint8_t*)half); \ - ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ - stride, 17); \ - ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16, \ - stride, 17); \ - ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH, \ - stride, 16); \ -} \ - \ -static void OPNAME ## qpel16_mc32_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - uint64_t half[17 * 2]; \ - uint8_t * const halfH = ((uint8_t*)half); \ - ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ - stride, 17); \ - ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16, \ - stride, 17); \ - ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH, \ - stride, 16); \ -} \ - \ -static void OPNAME ## qpel16_mc22_ ## MMX(uint8_t *dst, uint8_t *src, \ - ptrdiff_t stride) \ -{ \ - uint64_t half[17 * 2]; \ - uint8_t * const halfH = ((uint8_t*)half); \ - ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ - stride, 17); \ - ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH, \ - stride, 16); \ -} - -QPEL_OP(put_, ff_pw_16, _, mmxext) -QPEL_OP(avg_, ff_pw_16, _, mmxext) -QPEL_OP(put_no_rnd_, ff_pw_15, _no_rnd_, mmxext) -#endif /* HAVE_YASM */ - - -#if HAVE_INLINE_ASM -void ff_put_rv40_qpel8_mc33_mmx(uint8_t *dst, uint8_t *src, ptrdiff_t stride) -{ - put_pixels8_xy2_mmx(dst, src, stride, 8); -} -void ff_put_rv40_qpel16_mc33_mmx(uint8_t *dst, uint8_t *src, ptrdiff_t stride) -{ - put_pixels16_xy2_mmx(dst, src, stride, 16); -} -void ff_avg_rv40_qpel8_mc33_mmx(uint8_t *dst, uint8_t *src, ptrdiff_t stride) -{ - avg_pixels8_xy2_mmx(dst, src, stride, 8); -} -void ff_avg_rv40_qpel16_mc33_mmx(uint8_t *dst, uint8_t *src, ptrdiff_t stride) -{ - avg_pixels16_xy2_mmx(dst, src, stride, 16); -} typedef void emulated_edge_mc_func(uint8_t *dst, const uint8_t *src, - ptrdiff_t linesize, int block_w, int block_h, + ptrdiff_t dst_stride, + ptrdiff_t src_linesize, + int block_w, int block_h, int src_x, int src_y, int w, int h); static av_always_inline void gmc(uint8_t *dst, uint8_t *src, @@ -1107,7 +418,7 @@ static av_always_inline void gmc(uint8_t *dst, uint8_t *src, src += ix + iy * stride; if (need_emu) { - emu_edge_fn(edge_buf, src, stride, w + 1, h + 1, ix, iy, width, height); + emu_edge_fn(edge_buf, src, stride, stride, w + 1, h + 1, ix, iy, width, height); src = edge_buf; } @@ -1191,28 +502,28 @@ static av_always_inline void gmc(uint8_t *dst, uint8_t *src, #if CONFIG_VIDEODSP #if HAVE_YASM #if ARCH_X86_32 -static void gmc_mmx(uint8_t *dst, uint8_t *src, - int stride, int h, int ox, int oy, - int dxx, int dxy, int dyx, int dyy, - int shift, int r, int width, int height) +void ff_gmc_mmx(uint8_t *dst, uint8_t *src, + int stride, int h, int ox, int oy, + int dxx, int dxy, int dyx, int dyy, + int shift, int r, int width, int height) { gmc(dst, src, stride, h, ox, oy, dxx, dxy, dyx, dyy, shift, r, width, height, &ff_emulated_edge_mc_8); } #endif -static void gmc_sse(uint8_t *dst, uint8_t *src, - int stride, int h, int ox, int oy, - int dxx, int dxy, int dyx, int dyy, - int shift, int r, int width, int height) +void ff_gmc_sse(uint8_t *dst, uint8_t *src, + int stride, int h, int ox, int oy, + int dxx, int dxy, int dyx, int dyy, + int shift, int r, int width, int height) { gmc(dst, src, stride, h, ox, oy, dxx, dxy, dyx, dyy, shift, r, width, height, &ff_emulated_edge_mc_8); } #else -static void gmc_mmx(uint8_t *dst, uint8_t *src, - int stride, int h, int ox, int oy, - int dxx, int dxy, int dyx, int dyy, - int shift, int r, int width, int height) +void ff_gmc_mmx(uint8_t *dst, uint8_t *src, + int stride, int h, int ox, int oy, + int dxx, int dxy, int dyx, int dyy, + int shift, int r, int width, int height) { gmc(dst, src, stride, h, ox, oy, dxx, dxy, dyx, dyy, shift, r, width, height, &ff_emulated_edge_mc_8); @@ -1220,43 +531,6 @@ static void gmc_mmx(uint8_t *dst, uint8_t *src, #endif #endif -#endif /* HAVE_INLINE_ASM */ - -void ff_put_pixels16_sse2(uint8_t *block, const uint8_t *pixels, - ptrdiff_t line_size, int h); -void ff_avg_pixels16_sse2(uint8_t *block, const uint8_t *pixels, - ptrdiff_t line_size, int h); - -#if HAVE_INLINE_ASM - -/* CAVS-specific */ -void ff_put_cavs_qpel8_mc00_mmxext(uint8_t *dst, uint8_t *src, ptrdiff_t stride) -{ - put_pixels8_mmx(dst, src, stride, 8); -} - -void ff_avg_cavs_qpel8_mc00_mmxext(uint8_t *dst, uint8_t *src, ptrdiff_t stride) -{ - avg_pixels8_mmx(dst, src, stride, 8); -} - -void ff_put_cavs_qpel16_mc00_mmxext(uint8_t *dst, uint8_t *src, ptrdiff_t stride) -{ - put_pixels16_mmx(dst, src, stride, 16); -} - -void ff_avg_cavs_qpel16_mc00_mmxext(uint8_t *dst, uint8_t *src, ptrdiff_t stride) -{ - avg_pixels16_mmx(dst, src, stride, 16); -} - -/* VC-1-specific */ -void ff_put_vc1_mspel_mc00_mmx(uint8_t *dst, const uint8_t *src, - ptrdiff_t stride, int rnd) -{ - put_pixels8_mmx(dst, src, stride, 8); -} - #if CONFIG_DIRAC_DECODER #define DIRAC_PIXOP(OPNAME2, OPNAME, EXT)\ void ff_ ## OPNAME2 ## _dirac_pixels8_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ @@ -1284,8 +558,9 @@ void ff_ ## OPNAME2 ## _dirac_pixels32_ ## EXT(uint8_t *dst, const uint8_t *src[ } #if HAVE_MMX_INLINE -DIRAC_PIXOP(put, put, mmx) -DIRAC_PIXOP(avg, avg, mmx) +PIXELS16(static, ff_avg, , , _mmxext) +DIRAC_PIXOP(put, ff_put, mmx) +DIRAC_PIXOP(avg, ff_avg, mmx) #endif #if HAVE_YASM @@ -1326,8 +601,8 @@ void ff_avg_dirac_pixels32_sse2(uint8_t *dst, const uint8_t *src[5], int stride, #endif #endif -static void vector_clipf_sse(float *dst, const float *src, - float min, float max, int len) +void ff_vector_clipf_sse(float *dst, const float *src, + float min, float max, int len) { x86_reg i = (len - 16) * 4; __asm__ volatile ( @@ -1361,276 +636,3 @@ static void vector_clipf_sse(float *dst, const float *src, } #endif /* HAVE_INLINE_ASM */ - -int32_t ff_scalarproduct_int16_mmxext(const int16_t *v1, const int16_t *v2, - int order); -int32_t ff_scalarproduct_int16_sse2(const int16_t *v1, const int16_t *v2, - int order); -int32_t ff_scalarproduct_and_madd_int16_mmxext(int16_t *v1, const int16_t *v2, - const int16_t *v3, - int order, int mul); -int32_t ff_scalarproduct_and_madd_int16_sse2(int16_t *v1, const int16_t *v2, - const int16_t *v3, - int order, int mul); -int32_t ff_scalarproduct_and_madd_int16_ssse3(int16_t *v1, const int16_t *v2, - const int16_t *v3, - int order, int mul); - -void ff_apply_window_int16_round_mmxext(int16_t *output, const int16_t *input, - const int16_t *window, unsigned int len); -void ff_apply_window_int16_round_sse2(int16_t *output, const int16_t *input, - const int16_t *window, unsigned int len); -void ff_apply_window_int16_mmxext(int16_t *output, const int16_t *input, - const int16_t *window, unsigned int len); -void ff_apply_window_int16_sse2(int16_t *output, const int16_t *input, - const int16_t *window, unsigned int len); -void ff_apply_window_int16_ssse3(int16_t *output, const int16_t *input, - const int16_t *window, unsigned int len); -void ff_apply_window_int16_ssse3_atom(int16_t *output, const int16_t *input, - const int16_t *window, unsigned int len); - -void ff_bswap32_buf_ssse3(uint32_t *dst, const uint32_t *src, int w); -void ff_bswap32_buf_sse2(uint32_t *dst, const uint32_t *src, int w); - -void ff_add_hfyu_median_prediction_mmxext(uint8_t *dst, const uint8_t *top, - const uint8_t *diff, int w, - int *left, int *left_top); -int ff_add_hfyu_left_prediction_ssse3(uint8_t *dst, const uint8_t *src, - int w, int left); -int ff_add_hfyu_left_prediction_sse4(uint8_t *dst, const uint8_t *src, - int w, int left); - -void ff_vector_clip_int32_mmx (int32_t *dst, const int32_t *src, - int32_t min, int32_t max, unsigned int len); -void ff_vector_clip_int32_sse2 (int32_t *dst, const int32_t *src, - int32_t min, int32_t max, unsigned int len); -void ff_vector_clip_int32_int_sse2(int32_t *dst, const int32_t *src, - int32_t min, int32_t max, unsigned int len); -void ff_vector_clip_int32_sse4 (int32_t *dst, const int32_t *src, - int32_t min, int32_t max, unsigned int len); - -#define SET_QPEL_FUNCS(PFX, IDX, SIZE, CPU, PREFIX) \ - do { \ - c->PFX ## _pixels_tab[IDX][ 0] = PREFIX ## PFX ## SIZE ## _mc00_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][ 1] = PREFIX ## PFX ## SIZE ## _mc10_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][ 2] = PREFIX ## PFX ## SIZE ## _mc20_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][ 3] = PREFIX ## PFX ## SIZE ## _mc30_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][ 4] = PREFIX ## PFX ## SIZE ## _mc01_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][ 5] = PREFIX ## PFX ## SIZE ## _mc11_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][ 6] = PREFIX ## PFX ## SIZE ## _mc21_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][ 7] = PREFIX ## PFX ## SIZE ## _mc31_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][ 8] = PREFIX ## PFX ## SIZE ## _mc02_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][ 9] = PREFIX ## PFX ## SIZE ## _mc12_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][10] = PREFIX ## PFX ## SIZE ## _mc22_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][11] = PREFIX ## PFX ## SIZE ## _mc32_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][12] = PREFIX ## PFX ## SIZE ## _mc03_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][13] = PREFIX ## PFX ## SIZE ## _mc13_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][14] = PREFIX ## PFX ## SIZE ## _mc23_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][15] = PREFIX ## PFX ## SIZE ## _mc33_ ## CPU; \ - } while (0) - -static av_cold void dsputil_init_mmx(DSPContext *c, AVCodecContext *avctx, - int mm_flags) -{ - const int high_bit_depth = avctx->bits_per_raw_sample > 8; - -#if HAVE_INLINE_ASM - c->put_pixels_clamped = ff_put_pixels_clamped_mmx; - c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_mmx; - c->add_pixels_clamped = ff_add_pixels_clamped_mmx; - - if (!high_bit_depth) { - c->clear_block = clear_block_mmx; - c->clear_blocks = clear_blocks_mmx; - c->draw_edges = draw_edges_mmx; - } - -#if CONFIG_VIDEODSP && (ARCH_X86_32 || !HAVE_YASM) - c->gmc = gmc_mmx; -#endif - - c->add_bytes = add_bytes_mmx; -#endif /* HAVE_INLINE_ASM */ - -#if HAVE_YASM - if (CONFIG_H263_DECODER || CONFIG_H263_ENCODER) { - c->h263_v_loop_filter = ff_h263_v_loop_filter_mmx; - c->h263_h_loop_filter = ff_h263_h_loop_filter_mmx; - } - - c->vector_clip_int32 = ff_vector_clip_int32_mmx; -#endif - -} - -static av_cold void dsputil_init_mmxext(DSPContext *c, AVCodecContext *avctx, - int mm_flags) -{ - -#if HAVE_YASM - SET_QPEL_FUNCS(avg_qpel, 0, 16, mmxext, ); - SET_QPEL_FUNCS(avg_qpel, 1, 8, mmxext, ); - - SET_QPEL_FUNCS(put_qpel, 0, 16, mmxext, ); - SET_QPEL_FUNCS(put_qpel, 1, 8, mmxext, ); - SET_QPEL_FUNCS(put_no_rnd_qpel, 0, 16, mmxext, ); - SET_QPEL_FUNCS(put_no_rnd_qpel, 1, 8, mmxext, ); -#endif /* HAVE_YASM */ - -#if HAVE_MMXEXT_EXTERNAL - /* slower than cmov version on AMD */ - if (!(mm_flags & AV_CPU_FLAG_3DNOW)) - c->add_hfyu_median_prediction = ff_add_hfyu_median_prediction_mmxext; - - c->scalarproduct_int16 = ff_scalarproduct_int16_mmxext; - c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_mmxext; - - if (avctx->flags & CODEC_FLAG_BITEXACT) { - c->apply_window_int16 = ff_apply_window_int16_mmxext; - } else { - c->apply_window_int16 = ff_apply_window_int16_round_mmxext; - } -#endif /* HAVE_MMXEXT_EXTERNAL */ -} - -static av_cold void dsputil_init_sse(DSPContext *c, AVCodecContext *avctx, - int mm_flags) -{ - const int high_bit_depth = avctx->bits_per_raw_sample > 8; - -#if HAVE_INLINE_ASM - if (!high_bit_depth) { - if (!(CONFIG_MPEG_XVMC_DECODER && avctx->xvmc_acceleration > 1)) { - /* XvMCCreateBlocks() may not allocate 16-byte aligned blocks */ - c->clear_block = clear_block_sse; - c->clear_blocks = clear_blocks_sse; - } - } - - c->vector_clipf = vector_clipf_sse; -#endif /* HAVE_INLINE_ASM */ - -#if HAVE_YASM -#if HAVE_INLINE_ASM && CONFIG_VIDEODSP - c->gmc = gmc_sse; -#endif -#endif /* HAVE_YASM */ -} - -static av_cold void dsputil_init_sse2(DSPContext *c, AVCodecContext *avctx, - int mm_flags) -{ - const int bit_depth = avctx->bits_per_raw_sample; - const int high_bit_depth = bit_depth > 8; - -#if HAVE_SSE2_INLINE - if (!high_bit_depth && avctx->idct_algo == FF_IDCT_XVIDMMX) { - c->idct_put = ff_idct_xvid_sse2_put; - c->idct_add = ff_idct_xvid_sse2_add; - c->idct = ff_idct_xvid_sse2; - c->idct_permutation_type = FF_SSE2_IDCT_PERM; - } -#endif /* HAVE_SSE2_INLINE */ - -#if HAVE_SSE2_EXTERNAL - c->scalarproduct_int16 = ff_scalarproduct_int16_sse2; - c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_sse2; - if (mm_flags & AV_CPU_FLAG_ATOM) { - c->vector_clip_int32 = ff_vector_clip_int32_int_sse2; - } else { - c->vector_clip_int32 = ff_vector_clip_int32_sse2; - } - if (avctx->flags & CODEC_FLAG_BITEXACT) { - c->apply_window_int16 = ff_apply_window_int16_sse2; - } else if (!(mm_flags & AV_CPU_FLAG_SSE2SLOW)) { - c->apply_window_int16 = ff_apply_window_int16_round_sse2; - } - c->bswap_buf = ff_bswap32_buf_sse2; -#endif /* HAVE_SSE2_EXTERNAL */ -} - -static av_cold void dsputil_init_ssse3(DSPContext *c, AVCodecContext *avctx, - int mm_flags) -{ -#if HAVE_SSSE3_EXTERNAL - c->add_hfyu_left_prediction = ff_add_hfyu_left_prediction_ssse3; - if (mm_flags & AV_CPU_FLAG_SSE4) // not really sse4, just slow on Conroe - c->add_hfyu_left_prediction = ff_add_hfyu_left_prediction_sse4; - - if (mm_flags & AV_CPU_FLAG_ATOM) - c->apply_window_int16 = ff_apply_window_int16_ssse3_atom; - else - c->apply_window_int16 = ff_apply_window_int16_ssse3; - if (!(mm_flags & (AV_CPU_FLAG_SSE42|AV_CPU_FLAG_3DNOW))) // cachesplit - c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_ssse3; - c->bswap_buf = ff_bswap32_buf_ssse3; -#endif /* HAVE_SSSE3_EXTERNAL */ -} - -static av_cold void dsputil_init_sse4(DSPContext *c, AVCodecContext *avctx, - int mm_flags) -{ -#if HAVE_SSE4_EXTERNAL - c->vector_clip_int32 = ff_vector_clip_int32_sse4; -#endif /* HAVE_SSE4_EXTERNAL */ -} - -av_cold void ff_dsputil_init_mmx(DSPContext *c, AVCodecContext *avctx) -{ - int mm_flags = av_get_cpu_flags(); - -#if HAVE_7REGS && HAVE_INLINE_ASM - if (mm_flags & AV_CPU_FLAG_CMOV) - c->add_hfyu_median_prediction = add_hfyu_median_prediction_cmov; -#endif - - if (mm_flags & AV_CPU_FLAG_MMX) { -#if HAVE_INLINE_ASM - const int idct_algo = avctx->idct_algo; - - if (avctx->lowres == 0 && avctx->bits_per_raw_sample <= 8) { - if (idct_algo == FF_IDCT_AUTO || idct_algo == FF_IDCT_SIMPLEMMX) { - c->idct_put = ff_simple_idct_put_mmx; - c->idct_add = ff_simple_idct_add_mmx; - c->idct = ff_simple_idct_mmx; - c->idct_permutation_type = FF_SIMPLE_IDCT_PERM; - } else if (idct_algo == FF_IDCT_XVIDMMX) { - if (mm_flags & AV_CPU_FLAG_SSE2) { - c->idct_put = ff_idct_xvid_sse2_put; - c->idct_add = ff_idct_xvid_sse2_add; - c->idct = ff_idct_xvid_sse2; - c->idct_permutation_type = FF_SSE2_IDCT_PERM; - } else if (mm_flags & AV_CPU_FLAG_MMXEXT) { - c->idct_put = ff_idct_xvid_mmxext_put; - c->idct_add = ff_idct_xvid_mmxext_add; - c->idct = ff_idct_xvid_mmxext; - } else { - c->idct_put = ff_idct_xvid_mmx_put; - c->idct_add = ff_idct_xvid_mmx_add; - c->idct = ff_idct_xvid_mmx; - } - } - } -#endif /* HAVE_INLINE_ASM */ - - dsputil_init_mmx(c, avctx, mm_flags); - } - - if (mm_flags & AV_CPU_FLAG_MMXEXT) - dsputil_init_mmxext(c, avctx, mm_flags); - - if (mm_flags & AV_CPU_FLAG_SSE) - dsputil_init_sse(c, avctx, mm_flags); - - if (mm_flags & AV_CPU_FLAG_SSE2) - dsputil_init_sse2(c, avctx, mm_flags); - - if (mm_flags & AV_CPU_FLAG_SSSE3) - dsputil_init_ssse3(c, avctx, mm_flags); - - if (mm_flags & AV_CPU_FLAG_SSE4) - dsputil_init_sse4(c, avctx, mm_flags); - - if (CONFIG_ENCODERS) - ff_dsputilenc_init_mmx(c, avctx); -} diff --git a/ffmpeg/libavcodec/x86/dsputil_mmx.h b/ffmpeg/libavcodec/x86/dsputil_mmx.h deleted file mode 100644 index 28b0078..0000000 --- a/ffmpeg/libavcodec/x86/dsputil_mmx.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * MMX optimized DSP utils - * Copyright (c) 2007 Aurelien Jacobs - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_X86_DSPUTIL_MMX_H -#define AVCODEC_X86_DSPUTIL_MMX_H - -#include -#include - -#include "libavcodec/dsputil.h" -#include "libavutil/x86/asm.h" - -extern const uint64_t ff_bone; -extern const uint64_t ff_wtwo; - -extern const xmm_reg ff_pw_3; -extern const xmm_reg ff_pw_4; -extern const xmm_reg ff_pw_5; -extern const xmm_reg ff_pw_8; -extern const uint64_t ff_pw_15; -extern const xmm_reg ff_pw_16; -extern const xmm_reg ff_pw_18; -extern const uint64_t ff_pw_20; -extern const xmm_reg ff_pw_32; -extern const uint64_t ff_pw_42; -extern const uint64_t ff_pw_53; -extern const xmm_reg ff_pw_64; -extern const uint64_t ff_pw_96; -extern const uint64_t ff_pw_128; -extern const uint64_t ff_pw_255; - -extern const xmm_reg ff_pb_1; -extern const xmm_reg ff_pb_3; -extern const uint64_t ff_pb_3F; -extern const xmm_reg ff_pb_F8; -extern const uint64_t ff_pb_FC; - -extern const double ff_pd_1[2]; -extern const double ff_pd_2[2]; - -#define SBUTTERFLY(a,b,t,n,m)\ - "mov" #m " " #a ", " #t " \n\t" /* abcd */\ - "punpckl" #n " " #b ", " #a " \n\t" /* aebf */\ - "punpckh" #n " " #b ", " #t " \n\t" /* cgdh */\ - -#define TRANSPOSE4(a,b,c,d,t)\ - SBUTTERFLY(a,b,t,wd,q) /* a=aebf t=cgdh */\ - SBUTTERFLY(c,d,b,wd,q) /* c=imjn b=kolp */\ - SBUTTERFLY(a,c,d,dq,q) /* a=aeim d=bfjn */\ - SBUTTERFLY(t,b,c,dq,q) /* t=cgko c=dhlp */ - -#define MOVQ_WONE(regd) \ - __asm__ volatile ( \ - "pcmpeqd %%" #regd ", %%" #regd " \n\t" \ - "psrlw $15, %%" #regd ::) - -void ff_dsputilenc_init_mmx(DSPContext* c, AVCodecContext *avctx); -void ff_dsputil_init_pix_mmx(DSPContext* c, AVCodecContext *avctx); - -void ff_add_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, int line_size); -void ff_put_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, int line_size); -void ff_put_signed_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, int line_size); - -void ff_avg_pixels8_mmxext(uint8_t *block, const uint8_t *pixels, - ptrdiff_t line_size, int h); - -void ff_put_cavs_qpel8_mc00_mmxext(uint8_t *dst, uint8_t *src, ptrdiff_t stride); -void ff_avg_cavs_qpel8_mc00_mmxext(uint8_t *dst, uint8_t *src, ptrdiff_t stride); -void ff_put_cavs_qpel16_mc00_mmxext(uint8_t *dst, uint8_t *src, ptrdiff_t stride); -void ff_avg_cavs_qpel16_mc00_mmxext(uint8_t *dst, uint8_t *src, ptrdiff_t stride); - -void ff_put_vc1_mspel_mc00_mmx(uint8_t *dst, const uint8_t *src, ptrdiff_t stride, int rnd); - -void ff_put_rv40_qpel8_mc33_mmx(uint8_t *block, uint8_t *pixels, ptrdiff_t stride); -void ff_put_rv40_qpel16_mc33_mmx(uint8_t *block, uint8_t *pixels, ptrdiff_t stride); -void ff_avg_rv40_qpel8_mc33_mmx(uint8_t *block, uint8_t *pixels, ptrdiff_t stride); -void ff_avg_rv40_qpel16_mc33_mmx(uint8_t *block, uint8_t *pixels, ptrdiff_t stride); - -void ff_mmx_idct(int16_t *block); -void ff_mmxext_idct(int16_t *block); - - -void ff_deinterlace_line_mmx(uint8_t *dst, - const uint8_t *lum_m4, const uint8_t *lum_m3, - const uint8_t *lum_m2, const uint8_t *lum_m1, - const uint8_t *lum, - int size); - -void ff_deinterlace_line_inplace_mmx(const uint8_t *lum_m4, - const uint8_t *lum_m3, - const uint8_t *lum_m2, - const uint8_t *lum_m1, - const uint8_t *lum, int size); - -#endif /* AVCODEC_X86_DSPUTIL_MMX_H */ diff --git a/ffmpeg/libavcodec/x86/dsputil_qns_template.c b/ffmpeg/libavcodec/x86/dsputil_qns_template.c index 77a41b9..bde6b0a 100644 --- a/ffmpeg/libavcodec/x86/dsputil_qns_template.c +++ b/ffmpeg/libavcodec/x86/dsputil_qns_template.c @@ -28,7 +28,7 @@ static int DEF(try_8x8basis)(int16_t rem[64], int16_t weight[64], int16_t basis[ { x86_reg i=0; - assert(FFABS(scale) < MAX_ABS); + av_assert2(FFABS(scale) < MAX_ABS); scale<<= 16 + SCALE_OFFSET - BASIS_SHIFT + RECON_SHIFT; SET_RND(mm6); diff --git a/ffmpeg/libavcodec/x86/dsputil_rnd_template.c b/ffmpeg/libavcodec/x86/dsputil_rnd_template.c deleted file mode 100644 index 1a89b77..0000000 --- a/ffmpeg/libavcodec/x86/dsputil_rnd_template.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * DSP utils mmx functions are compiled twice for rnd/no_rnd - * Copyright (c) 2000, 2001 Fabrice Bellard - * Copyright (c) 2003-2004 Michael Niedermayer - * - * MMX optimization by Nick Kurshev - * mostly rewritten by Michael Niedermayer - * and improved by Zdenek Kabelac - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// put_pixels -static void DEF(put, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) -{ - MOVQ_ZERO(mm7); - SET_RND(mm6); // =2 for rnd and =1 for no_rnd version - __asm__ volatile( - "movq (%1), %%mm0 \n\t" - "movq 1(%1), %%mm4 \n\t" - "movq %%mm0, %%mm1 \n\t" - "movq %%mm4, %%mm5 \n\t" - "punpcklbw %%mm7, %%mm0 \n\t" - "punpcklbw %%mm7, %%mm4 \n\t" - "punpckhbw %%mm7, %%mm1 \n\t" - "punpckhbw %%mm7, %%mm5 \n\t" - "paddusw %%mm0, %%mm4 \n\t" - "paddusw %%mm1, %%mm5 \n\t" - "xor %%"REG_a", %%"REG_a" \n\t" - "add %3, %1 \n\t" - ".p2align 3 \n\t" - "1: \n\t" - "movq (%1, %%"REG_a"), %%mm0 \n\t" - "movq 1(%1, %%"REG_a"), %%mm2 \n\t" - "movq %%mm0, %%mm1 \n\t" - "movq %%mm2, %%mm3 \n\t" - "punpcklbw %%mm7, %%mm0 \n\t" - "punpcklbw %%mm7, %%mm2 \n\t" - "punpckhbw %%mm7, %%mm1 \n\t" - "punpckhbw %%mm7, %%mm3 \n\t" - "paddusw %%mm2, %%mm0 \n\t" - "paddusw %%mm3, %%mm1 \n\t" - "paddusw %%mm6, %%mm4 \n\t" - "paddusw %%mm6, %%mm5 \n\t" - "paddusw %%mm0, %%mm4 \n\t" - "paddusw %%mm1, %%mm5 \n\t" - "psrlw $2, %%mm4 \n\t" - "psrlw $2, %%mm5 \n\t" - "packuswb %%mm5, %%mm4 \n\t" - "movq %%mm4, (%2, %%"REG_a") \n\t" - "add %3, %%"REG_a" \n\t" - - "movq (%1, %%"REG_a"), %%mm2 \n\t" // 0 <-> 2 1 <-> 3 - "movq 1(%1, %%"REG_a"), %%mm4 \n\t" - "movq %%mm2, %%mm3 \n\t" - "movq %%mm4, %%mm5 \n\t" - "punpcklbw %%mm7, %%mm2 \n\t" - "punpcklbw %%mm7, %%mm4 \n\t" - "punpckhbw %%mm7, %%mm3 \n\t" - "punpckhbw %%mm7, %%mm5 \n\t" - "paddusw %%mm2, %%mm4 \n\t" - "paddusw %%mm3, %%mm5 \n\t" - "paddusw %%mm6, %%mm0 \n\t" - "paddusw %%mm6, %%mm1 \n\t" - "paddusw %%mm4, %%mm0 \n\t" - "paddusw %%mm5, %%mm1 \n\t" - "psrlw $2, %%mm0 \n\t" - "psrlw $2, %%mm1 \n\t" - "packuswb %%mm1, %%mm0 \n\t" - "movq %%mm0, (%2, %%"REG_a") \n\t" - "add %3, %%"REG_a" \n\t" - - "subl $2, %0 \n\t" - "jnz 1b \n\t" - :"+g"(h), "+S"(pixels) - :"D"(block), "r"((x86_reg)line_size) - :REG_a, "memory"); -} - -// in case more speed is needed - unroling would certainly help -static void DEF(avg, pixels8)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) -{ - MOVQ_BFE(mm6); - JUMPALIGN(); - do { - __asm__ volatile( - "movq %0, %%mm0 \n\t" - "movq %1, %%mm1 \n\t" - OP_AVG(%%mm0, %%mm1, %%mm2, %%mm6) - "movq %%mm2, %0 \n\t" - :"+m"(*block) - :"m"(*pixels) - :"memory"); - pixels += line_size; - block += line_size; - } - while (--h); -} - -static void DEF(avg, pixels16)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) -{ - MOVQ_BFE(mm6); - JUMPALIGN(); - do { - __asm__ volatile( - "movq %0, %%mm0 \n\t" - "movq %1, %%mm1 \n\t" - OP_AVG(%%mm0, %%mm1, %%mm2, %%mm6) - "movq %%mm2, %0 \n\t" - "movq 8%0, %%mm0 \n\t" - "movq 8%1, %%mm1 \n\t" - OP_AVG(%%mm0, %%mm1, %%mm2, %%mm6) - "movq %%mm2, 8%0 \n\t" - :"+m"(*block) - :"m"(*pixels) - :"memory"); - pixels += line_size; - block += line_size; - } - while (--h); -} - -// this routine is 'slightly' suboptimal but mostly unused -static void DEF(avg, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) -{ - MOVQ_ZERO(mm7); - SET_RND(mm6); // =2 for rnd and =1 for no_rnd version - __asm__ volatile( - "movq (%1), %%mm0 \n\t" - "movq 1(%1), %%mm4 \n\t" - "movq %%mm0, %%mm1 \n\t" - "movq %%mm4, %%mm5 \n\t" - "punpcklbw %%mm7, %%mm0 \n\t" - "punpcklbw %%mm7, %%mm4 \n\t" - "punpckhbw %%mm7, %%mm1 \n\t" - "punpckhbw %%mm7, %%mm5 \n\t" - "paddusw %%mm0, %%mm4 \n\t" - "paddusw %%mm1, %%mm5 \n\t" - "xor %%"REG_a", %%"REG_a" \n\t" - "add %3, %1 \n\t" - ".p2align 3 \n\t" - "1: \n\t" - "movq (%1, %%"REG_a"), %%mm0 \n\t" - "movq 1(%1, %%"REG_a"), %%mm2 \n\t" - "movq %%mm0, %%mm1 \n\t" - "movq %%mm2, %%mm3 \n\t" - "punpcklbw %%mm7, %%mm0 \n\t" - "punpcklbw %%mm7, %%mm2 \n\t" - "punpckhbw %%mm7, %%mm1 \n\t" - "punpckhbw %%mm7, %%mm3 \n\t" - "paddusw %%mm2, %%mm0 \n\t" - "paddusw %%mm3, %%mm1 \n\t" - "paddusw %%mm6, %%mm4 \n\t" - "paddusw %%mm6, %%mm5 \n\t" - "paddusw %%mm0, %%mm4 \n\t" - "paddusw %%mm1, %%mm5 \n\t" - "psrlw $2, %%mm4 \n\t" - "psrlw $2, %%mm5 \n\t" - "movq (%2, %%"REG_a"), %%mm3 \n\t" - "packuswb %%mm5, %%mm4 \n\t" - "pcmpeqd %%mm2, %%mm2 \n\t" - "paddb %%mm2, %%mm2 \n\t" - OP_AVG(%%mm3, %%mm4, %%mm5, %%mm2) - "movq %%mm5, (%2, %%"REG_a") \n\t" - "add %3, %%"REG_a" \n\t" - - "movq (%1, %%"REG_a"), %%mm2 \n\t" // 0 <-> 2 1 <-> 3 - "movq 1(%1, %%"REG_a"), %%mm4 \n\t" - "movq %%mm2, %%mm3 \n\t" - "movq %%mm4, %%mm5 \n\t" - "punpcklbw %%mm7, %%mm2 \n\t" - "punpcklbw %%mm7, %%mm4 \n\t" - "punpckhbw %%mm7, %%mm3 \n\t" - "punpckhbw %%mm7, %%mm5 \n\t" - "paddusw %%mm2, %%mm4 \n\t" - "paddusw %%mm3, %%mm5 \n\t" - "paddusw %%mm6, %%mm0 \n\t" - "paddusw %%mm6, %%mm1 \n\t" - "paddusw %%mm4, %%mm0 \n\t" - "paddusw %%mm5, %%mm1 \n\t" - "psrlw $2, %%mm0 \n\t" - "psrlw $2, %%mm1 \n\t" - "movq (%2, %%"REG_a"), %%mm3 \n\t" - "packuswb %%mm1, %%mm0 \n\t" - "pcmpeqd %%mm2, %%mm2 \n\t" - "paddb %%mm2, %%mm2 \n\t" - OP_AVG(%%mm3, %%mm0, %%mm1, %%mm2) - "movq %%mm1, (%2, %%"REG_a") \n\t" - "add %3, %%"REG_a" \n\t" - - "subl $2, %0 \n\t" - "jnz 1b \n\t" - :"+g"(h), "+S"(pixels) - :"D"(block), "r"((x86_reg)line_size) - :REG_a, "memory"); -} - -//FIXME optimize -static void DEF(put, pixels16_xy2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){ - DEF(put, pixels8_xy2)(block , pixels , line_size, h); - DEF(put, pixels8_xy2)(block+8, pixels+8, line_size, h); -} - -static void DEF(avg, pixels16_xy2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){ - DEF(avg, pixels8_xy2)(block , pixels , line_size, h); - DEF(avg, pixels8_xy2)(block+8, pixels+8, line_size, h); -} diff --git a/ffmpeg/libavcodec/x86/dsputilenc_mmx.c b/ffmpeg/libavcodec/x86/dsputilenc_mmx.c index a3f268e..5de8ade 100644 --- a/ffmpeg/libavcodec/x86/dsputilenc_mmx.c +++ b/ffmpeg/libavcodec/x86/dsputilenc_mmx.c @@ -3,6 +3,8 @@ * Copyright (c) 2000, 2001 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer * + * MMX optimization by Nick Kurshev + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -18,8 +20,6 @@ * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * MMX optimization by Nick Kurshev */ #include "libavutil/attributes.h" @@ -30,7 +30,7 @@ #include "libavcodec/dsputil.h" #include "libavcodec/mpegvideo.h" #include "libavcodec/mathops.h" -#include "dsputil_mmx.h" +#include "dsputil_x86.h" void ff_get_pixels_mmx(int16_t *block, const uint8_t *pixels, int line_size); void ff_get_pixels_sse2(int16_t *block, const uint8_t *pixels, int line_size); @@ -946,11 +946,13 @@ hadamard_func(ssse3) av_cold void ff_dsputilenc_init_mmx(DSPContext *c, AVCodecContext *avctx) { - int mm_flags = av_get_cpu_flags(); - int bit_depth = avctx->bits_per_raw_sample; + int cpu_flags = av_get_cpu_flags(); + const int dct_algo = avctx->dct_algo; #if HAVE_YASM - if (EXTERNAL_MMX(mm_flags)) { + int bit_depth = avctx->bits_per_raw_sample; + + if (EXTERNAL_MMX(cpu_flags)) { if (bit_depth <= 8) c->get_pixels = ff_get_pixels_mmx; c->diff_pixels = ff_diff_pixels_mmx; @@ -958,25 +960,16 @@ av_cold void ff_dsputilenc_init_mmx(DSPContext *c, AVCodecContext *avctx) c->pix_norm1 = ff_pix_norm1_mmx; } - if (EXTERNAL_SSE2(mm_flags)) + if (EXTERNAL_SSE2(cpu_flags)) if (bit_depth <= 8) c->get_pixels = ff_get_pixels_sse2; #endif /* HAVE_YASM */ #if HAVE_INLINE_ASM - if (mm_flags & AV_CPU_FLAG_MMX) { - const int dct_algo = avctx->dct_algo; + if (INLINE_MMX(cpu_flags)) { if (avctx->bits_per_raw_sample <= 8 && - (dct_algo==FF_DCT_AUTO || dct_algo==FF_DCT_MMX)) { - if(mm_flags & AV_CPU_FLAG_SSE2){ - c->fdct = ff_fdct_sse2; - } else if (mm_flags & AV_CPU_FLAG_MMXEXT) { - c->fdct = ff_fdct_mmxext; - }else{ - c->fdct = ff_fdct_mmx; - } - } - + (dct_algo == FF_DCT_AUTO || dct_algo == FF_DCT_MMX)) + c->fdct = ff_fdct_mmx; c->diff_bytes= diff_bytes_mmx; c->sum_abs_dctelem= sum_abs_dctelem_mmx; @@ -997,63 +990,71 @@ av_cold void ff_dsputilenc_init_mmx(DSPContext *c, AVCodecContext *avctx) c->add_8x8basis= add_8x8basis_mmx; c->ssd_int8_vs_int16 = ssd_int8_vs_int16_mmx; + } - if (mm_flags & AV_CPU_FLAG_MMXEXT) { - c->sum_abs_dctelem = sum_abs_dctelem_mmxext; - c->vsad[4] = vsad_intra16_mmxext; + if (INLINE_AMD3DNOW(cpu_flags)) { + if (!(avctx->flags & CODEC_FLAG_BITEXACT)) { + c->try_8x8basis = try_8x8basis_3dnow; + } + c->add_8x8basis = add_8x8basis_3dnow; + } - if(!(avctx->flags & CODEC_FLAG_BITEXACT)){ - c->vsad[0] = vsad16_mmxext; - } + if (INLINE_MMXEXT(cpu_flags)) { + if (avctx->bits_per_raw_sample <= 8 && + (dct_algo == FF_DCT_AUTO || dct_algo == FF_DCT_MMX)) + c->fdct = ff_fdct_mmxext; - c->sub_hfyu_median_prediction = sub_hfyu_median_prediction_mmxext; - } + c->sum_abs_dctelem = sum_abs_dctelem_mmxext; + c->vsad[4] = vsad_intra16_mmxext; - if(mm_flags & AV_CPU_FLAG_SSE2){ - c->sum_abs_dctelem= sum_abs_dctelem_sse2; + if (!(avctx->flags & CODEC_FLAG_BITEXACT)){ + c->vsad[0] = vsad16_mmxext; } -#if HAVE_SSSE3_INLINE - if(mm_flags & AV_CPU_FLAG_SSSE3){ - if(!(avctx->flags & CODEC_FLAG_BITEXACT)){ - c->try_8x8basis= try_8x8basis_ssse3; - } - c->add_8x8basis= add_8x8basis_ssse3; - c->sum_abs_dctelem= sum_abs_dctelem_ssse3; - } -#endif + c->sub_hfyu_median_prediction = sub_hfyu_median_prediction_mmxext; + } + + if (INLINE_SSE2(cpu_flags)) { + if (avctx->bits_per_raw_sample <= 8 && + (dct_algo == FF_DCT_AUTO || dct_algo == FF_DCT_MMX)) + c->fdct = ff_fdct_sse2; + + c->sum_abs_dctelem= sum_abs_dctelem_sse2; + } - if(mm_flags & AV_CPU_FLAG_3DNOW){ - if(!(avctx->flags & CODEC_FLAG_BITEXACT)){ - c->try_8x8basis= try_8x8basis_3dnow; - } - c->add_8x8basis= add_8x8basis_3dnow; +#if HAVE_SSSE3_INLINE + if (INLINE_SSSE3(cpu_flags)) { + if (!(avctx->flags & CODEC_FLAG_BITEXACT)) { + c->try_8x8basis = try_8x8basis_ssse3; } + c->add_8x8basis = add_8x8basis_ssse3; + c->sum_abs_dctelem = sum_abs_dctelem_ssse3; } +#endif #endif /* HAVE_INLINE_ASM */ - if (EXTERNAL_MMX(mm_flags)) { + if (EXTERNAL_MMX(cpu_flags)) { c->hadamard8_diff[0] = ff_hadamard8_diff16_mmx; c->hadamard8_diff[1] = ff_hadamard8_diff_mmx; + } - if (EXTERNAL_MMXEXT(mm_flags)) { - c->hadamard8_diff[0] = ff_hadamard8_diff16_mmxext; - c->hadamard8_diff[1] = ff_hadamard8_diff_mmxext; - } + if (EXTERNAL_MMXEXT(cpu_flags)) { + c->hadamard8_diff[0] = ff_hadamard8_diff16_mmxext; + c->hadamard8_diff[1] = ff_hadamard8_diff_mmxext; + } - if (EXTERNAL_SSE2(mm_flags)) { - c->sse[0] = ff_sse16_sse2; + if (EXTERNAL_SSE2(cpu_flags)) { + c->sse[0] = ff_sse16_sse2; #if HAVE_ALIGNED_STACK - c->hadamard8_diff[0] = ff_hadamard8_diff16_sse2; - c->hadamard8_diff[1] = ff_hadamard8_diff_sse2; + c->hadamard8_diff[0] = ff_hadamard8_diff16_sse2; + c->hadamard8_diff[1] = ff_hadamard8_diff_sse2; #endif - } + } - if (EXTERNAL_SSSE3(mm_flags) && HAVE_ALIGNED_STACK) { - c->hadamard8_diff[0] = ff_hadamard8_diff16_ssse3; - c->hadamard8_diff[1] = ff_hadamard8_diff_ssse3; - } + if (EXTERNAL_SSSE3(cpu_flags) && HAVE_ALIGNED_STACK) { + c->hadamard8_diff[0] = ff_hadamard8_diff16_ssse3; + c->hadamard8_diff[1] = ff_hadamard8_diff_ssse3; } ff_dsputil_init_pix_mmx(c, avctx); diff --git a/ffmpeg/libavcodec/x86/fdct.c b/ffmpeg/libavcodec/x86/fdct.c index d35245d..11a13bb 100644 --- a/ffmpeg/libavcodec/x86/fdct.c +++ b/ffmpeg/libavcodec/x86/fdct.c @@ -34,7 +34,7 @@ #include "libavutil/x86/asm.h" #include "libavcodec/dct.h" -#if HAVE_INLINE_ASM +#if HAVE_MMX_INLINE ////////////////////////////////////////////////////////////////////// // @@ -556,6 +556,10 @@ void ff_fdct_mmx(int16_t *block) } } +#endif /* HAVE_MMX_INLINE */ + +#if HAVE_MMXEXT_INLINE + void ff_fdct_mmxext(int16_t *block) { DECLARE_ALIGNED(8, int64_t, align_tmp)[16]; @@ -574,6 +578,10 @@ void ff_fdct_mmxext(int16_t *block) } } +#endif /* HAVE_MMXEXT_INLINE */ + +#if HAVE_SSE2_INLINE + void ff_fdct_sse2(int16_t *block) { DECLARE_ALIGNED(16, int64_t, align_tmp)[16]; @@ -583,4 +591,4 @@ void ff_fdct_sse2(int16_t *block) fdct_row_sse2(block1, block); } -#endif /* HAVE_INLINE_ASM */ +#endif /* HAVE_SSE2_INLINE */ diff --git a/ffmpeg/libavcodec/x86/fft.asm b/ffmpeg/libavcodec/x86/fft.asm index 5071741..cae404c 100644 --- a/ffmpeg/libavcodec/x86/fft.asm +++ b/ffmpeg/libavcodec/x86/fft.asm @@ -36,7 +36,7 @@ %define pointer resd %endif -SECTION_RODATA +SECTION_RODATA 32 struc FFTContext .nbits: resd 1 @@ -57,7 +57,6 @@ endstruc %define M_COS_PI_1_8 0.923879532511287 %define M_COS_PI_3_8 0.38268343236509 -align 32 ps_cos16_1: dd 1.0, M_COS_PI_1_8, M_SQRT1_2, M_COS_PI_3_8, 1.0, M_COS_PI_1_8, M_SQRT1_2, M_COS_PI_3_8 ps_cos16_2: dd 0, M_COS_PI_3_8, M_SQRT1_2, M_COS_PI_1_8, 0, -M_COS_PI_3_8, -M_SQRT1_2, -M_COS_PI_1_8 @@ -672,13 +671,13 @@ cglobal imdct_calc, 3,5,3 push r1 push r0 %else - sub rsp, 8 + sub rsp, 8+32*WIN64 ; allocate win64 shadow space %endif call r4 %if ARCH_X86_32 add esp, 12 %else - add rsp, 8 + add rsp, 8+32*WIN64 %endif POP r1 POP r3 diff --git a/ffmpeg/libavcodec/x86/fft.h b/ffmpeg/libavcodec/x86/fft.h index 3f8b21d..398091e 100644 --- a/ffmpeg/libavcodec/x86/fft.h +++ b/ffmpeg/libavcodec/x86/fft.h @@ -34,8 +34,5 @@ void ff_imdct_half_3dnowext(FFTContext *s, FFTSample *output, const FFTSample *i void ff_imdct_calc_sse(FFTContext *s, FFTSample *output, const FFTSample *input); void ff_imdct_half_sse(FFTContext *s, FFTSample *output, const FFTSample *input); void ff_imdct_half_avx(FFTContext *s, FFTSample *output, const FFTSample *input); -void ff_dct32_float_sse(FFTSample *out, const FFTSample *in); -void ff_dct32_float_sse2(FFTSample *out, const FFTSample *in); -void ff_dct32_float_avx(FFTSample *out, const FFTSample *in); #endif /* AVCODEC_X86_FFT_H */ diff --git a/ffmpeg/libavcodec/x86/fft_init.c b/ffmpeg/libavcodec/x86/fft_init.c index bfa7947..5682230 100644 --- a/ffmpeg/libavcodec/x86/fft_init.c +++ b/ffmpeg/libavcodec/x86/fft_init.c @@ -16,29 +16,31 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "config.h" +#include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/x86/cpu.h" -#include "libavcodec/dct.h" #include "fft.h" av_cold void ff_fft_init_x86(FFTContext *s) { - int has_vectors = av_get_cpu_flags(); + int cpu_flags = av_get_cpu_flags(); + #if ARCH_X86_32 - if (EXTERNAL_AMD3DNOW(has_vectors)) { + if (EXTERNAL_AMD3DNOW(cpu_flags)) { /* 3DNow! for K6-2/3 */ s->imdct_calc = ff_imdct_calc_3dnow; s->imdct_half = ff_imdct_half_3dnow; s->fft_calc = ff_fft_calc_3dnow; } - if (EXTERNAL_AMD3DNOWEXT(has_vectors)) { + if (EXTERNAL_AMD3DNOWEXT(cpu_flags)) { /* 3DNowEx for K7 */ s->imdct_calc = ff_imdct_calc_3dnowext; s->imdct_half = ff_imdct_half_3dnowext; s->fft_calc = ff_fft_calc_3dnowext; } #endif - if (EXTERNAL_SSE(has_vectors)) { + if (EXTERNAL_SSE(cpu_flags)) { /* SSE for P3/P4/K8 */ s->imdct_calc = ff_imdct_calc_sse; s->imdct_half = ff_imdct_half_sse; @@ -46,23 +48,10 @@ av_cold void ff_fft_init_x86(FFTContext *s) s->fft_calc = ff_fft_calc_sse; s->fft_permutation = FF_FFT_PERM_SWAP_LSBS; } - if (EXTERNAL_AVX(has_vectors) && s->nbits >= 5) { + if (EXTERNAL_AVX(cpu_flags) && s->nbits >= 5) { /* AVX for SB */ s->imdct_half = ff_imdct_half_avx; s->fft_calc = ff_fft_calc_avx; s->fft_permutation = FF_FFT_PERM_AVX; } } - -#if CONFIG_DCT -av_cold void ff_dct_init_x86(DCTContext *s) -{ - int has_vectors = av_get_cpu_flags(); - if (EXTERNAL_SSE(has_vectors)) - s->dct32 = ff_dct32_float_sse; - if (EXTERNAL_SSE2(has_vectors)) - s->dct32 = ff_dct32_float_sse2; - if (EXTERNAL_AVX(has_vectors)) - s->dct32 = ff_dct32_float_avx; -} -#endif diff --git a/ffmpeg/libavcodec/x86/fmtconvert.asm b/ffmpeg/libavcodec/x86/fmtconvert.asm index 1bd13fc..60078e2 100644 --- a/ffmpeg/libavcodec/x86/fmtconvert.asm +++ b/ffmpeg/libavcodec/x86/fmtconvert.asm @@ -32,7 +32,7 @@ SECTION_TEXT %endmacro ;--------------------------------------------------------------------------------- -; void int32_to_float_fmul_scalar(float *dst, const int *src, float mul, int len); +; void int32_to_float_fmul_scalar(float *dst, const int32_t *src, float mul, int len); ;--------------------------------------------------------------------------------- %macro INT32_TO_FLOAT_FMUL_SCALAR 1 %if UNIX64 diff --git a/ffmpeg/libavcodec/x86/fmtconvert_init.c b/ffmpeg/libavcodec/x86/fmtconvert_init.c index 4a4c017..d300dfd 100644 --- a/ffmpeg/libavcodec/x86/fmtconvert_init.c +++ b/ffmpeg/libavcodec/x86/fmtconvert_init.c @@ -3,6 +3,8 @@ * Copyright (c) 2000, 2001 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer * + * MMX optimization by Nick Kurshev + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -18,8 +20,6 @@ * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * MMX optimization by Nick Kurshev */ #include "libavutil/attributes.h" @@ -30,8 +30,8 @@ #if HAVE_YASM -void ff_int32_to_float_fmul_scalar_sse (float *dst, const int *src, float mul, int len); -void ff_int32_to_float_fmul_scalar_sse2(float *dst, const int *src, float mul, int len); +void ff_int32_to_float_fmul_scalar_sse (float *dst, const int32_t *src, float mul, int len); +void ff_int32_to_float_fmul_scalar_sse2(float *dst, const int32_t *src, float mul, int len); void ff_float_to_int16_3dnow(int16_t *dst, const float *src, long len); void ff_float_to_int16_sse (int16_t *dst, const float *src, long len); @@ -116,33 +116,32 @@ static void float_interleave_sse(float *dst, const float **src, av_cold void ff_fmt_convert_init_x86(FmtConvertContext *c, AVCodecContext *avctx) { #if HAVE_YASM - int mm_flags = av_get_cpu_flags(); + int cpu_flags = av_get_cpu_flags(); - if (EXTERNAL_MMX(mm_flags)) { + if (EXTERNAL_MMX(cpu_flags)) { c->float_interleave = float_interleave_mmx; - - if (EXTERNAL_AMD3DNOW(mm_flags)) { - if(!(avctx->flags & CODEC_FLAG_BITEXACT)){ - c->float_to_int16 = ff_float_to_int16_3dnow; - c->float_to_int16_interleave = float_to_int16_interleave_3dnow; - } - } - if (EXTERNAL_AMD3DNOWEXT(mm_flags)) { - if(!(avctx->flags & CODEC_FLAG_BITEXACT)){ - c->float_to_int16_interleave = float_to_int16_interleave_3dnowext; - } - } - if (EXTERNAL_SSE(mm_flags)) { - c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_sse; - c->float_to_int16 = ff_float_to_int16_sse; - c->float_to_int16_interleave = float_to_int16_interleave_sse; - c->float_interleave = float_interleave_sse; + } + if (EXTERNAL_AMD3DNOW(cpu_flags)) { + if (!(avctx->flags & CODEC_FLAG_BITEXACT)) { + c->float_to_int16 = ff_float_to_int16_3dnow; + c->float_to_int16_interleave = float_to_int16_interleave_3dnow; } - if (EXTERNAL_SSE2(mm_flags)) { - c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_sse2; - c->float_to_int16 = ff_float_to_int16_sse2; - c->float_to_int16_interleave = float_to_int16_interleave_sse2; + } + if (EXTERNAL_AMD3DNOWEXT(cpu_flags)) { + if (!(avctx->flags & CODEC_FLAG_BITEXACT)) { + c->float_to_int16_interleave = float_to_int16_interleave_3dnowext; } } + if (EXTERNAL_SSE(cpu_flags)) { + c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_sse; + c->float_to_int16 = ff_float_to_int16_sse; + c->float_to_int16_interleave = float_to_int16_interleave_sse; + c->float_interleave = float_interleave_sse; + } + if (EXTERNAL_SSE2(cpu_flags)) { + c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_sse2; + c->float_to_int16 = ff_float_to_int16_sse2; + c->float_to_int16_interleave = float_to_int16_interleave_sse2; + } #endif /* HAVE_YASM */ } diff --git a/ffmpeg/libavcodec/x86/fpelbase.asm b/ffmpeg/libavcodec/x86/fpelbase.asm deleted file mode 100644 index a327206..0000000 --- a/ffmpeg/libavcodec/x86/fpelbase.asm +++ /dev/null @@ -1,106 +0,0 @@ -;****************************************************************************** -;* MMX optimized DSP utils -;* Copyright (c) 2008 Loren Merritt -;* Copyright (c) 2003-2013 Michael Niedermayer -;* Copyright (c) 2013 Daniel Kang -;* -;* This file is part of FFmpeg. -;* -;* FFmpeg is free software; you can redistribute it and/or -;* modify it under the terms of the GNU Lesser General Public -;* License as published by the Free Software Foundation; either -;* version 2.1 of the License, or (at your option) any later version. -;* -;* FFmpeg is distributed in the hope that it will be useful, -;* but WITHOUT ANY WARRANTY; without even the implied warranty of -;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;* Lesser General Public License for more details. -;* -;* You should have received a copy of the GNU Lesser General Public -;* License along with FFmpeg; if not, write to the Free Software -;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -;****************************************************************************** - -%include "libavutil/x86/x86util.asm" - -SECTION .text - -INIT_MMX mmxext -; void pixels(uint8_t *block, const uint8_t *pixels, int line_size, int h) -%macro PIXELS48 2 -%if %2 == 4 -%define OP movh -%else -%define OP mova -%endif -cglobal %1_pixels%2, 4,5 - movsxdifnidn r2, r2d - lea r4, [r2*3] -.loop: - OP m0, [r1] - OP m1, [r1+r2] - OP m2, [r1+r2*2] - OP m3, [r1+r4] - lea r1, [r1+r2*4] -%ifidn %1, avg - pavgb m0, [r0] - pavgb m1, [r0+r2] - pavgb m2, [r0+r2*2] - pavgb m3, [r0+r4] -%endif - OP [r0], m0 - OP [r0+r2], m1 - OP [r0+r2*2], m2 - OP [r0+r4], m3 - sub r3d, 4 - lea r0, [r0+r2*4] - jne .loop - RET -%endmacro - -PIXELS48 put, 4 -PIXELS48 avg, 4 -PIXELS48 put, 8 -PIXELS48 avg, 8 - - -INIT_XMM sse2 -; void put_pixels16_sse2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) -cglobal put_pixels16, 4,5,4 - lea r4, [r2*3] -.loop: - movu m0, [r1] - movu m1, [r1+r2] - movu m2, [r1+r2*2] - movu m3, [r1+r4] - lea r1, [r1+r2*4] - mova [r0], m0 - mova [r0+r2], m1 - mova [r0+r2*2], m2 - mova [r0+r4], m3 - sub r3d, 4 - lea r0, [r0+r2*4] - jnz .loop - REP_RET - -; void avg_pixels16_sse2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) -cglobal avg_pixels16, 4,5,4 - lea r4, [r2*3] -.loop: - movu m0, [r1] - movu m1, [r1+r2] - movu m2, [r1+r2*2] - movu m3, [r1+r4] - lea r1, [r1+r2*4] - pavgb m0, [r0] - pavgb m1, [r0+r2] - pavgb m2, [r0+r2*2] - pavgb m3, [r0+r4] - mova [r0], m0 - mova [r0+r2], m1 - mova [r0+r2*2], m2 - mova [r0+r4], m3 - sub r3d, 4 - lea r0, [r0+r2*4] - jnz .loop - REP_RET diff --git a/ffmpeg/libavcodec/x86/h264_chromamc_10bit.asm b/ffmpeg/libavcodec/x86/h264_chromamc_10bit.asm index b850551..beb7c0f 100644 --- a/ffmpeg/libavcodec/x86/h264_chromamc_10bit.asm +++ b/ffmpeg/libavcodec/x86/h264_chromamc_10bit.asm @@ -5,20 +5,20 @@ ;* ;* Authors: Daniel Kang ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* FFmpeg is free software; you can redistribute it and/or ;* modify it under the terms of the GNU Lesser General Public ;* License as published by the Free Software Foundation; either ;* version 2.1 of the License, or (at your option) any later version. ;* -;* Libav is distributed in the hope that it will be useful, +;* FFmpeg is distributed in the hope that it will be useful, ;* but WITHOUT ANY WARRANTY; without even the implied warranty of ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;* Lesser General Public License for more details. ;* ;* You should have received a copy of the GNU Lesser General Public -;* License along with Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** diff --git a/ffmpeg/libavcodec/x86/h264_deblock.asm b/ffmpeg/libavcodec/x86/h264_deblock.asm index d58e16c..1317783 100644 --- a/ffmpeg/libavcodec/x86/h264_deblock.asm +++ b/ffmpeg/libavcodec/x86/h264_deblock.asm @@ -331,16 +331,14 @@ cglobal deblock_v_luma_8, 5,5,10 ; void deblock_h_luma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 ) ;----------------------------------------------------------------------------- INIT_MMX cpuname -cglobal deblock_h_luma_8, 5,9 +cglobal deblock_h_luma_8, 5,9,0,0x60+16*WIN64 movsxd r7, r1d lea r8, [r7+r7*2] lea r6, [r0-4] lea r5, [r0-4+r8] %if WIN64 - sub rsp, 0x98 - %define pix_tmp rsp+0x30 + %define pix_tmp rsp+0x30 ; shadow space + r4 %else - sub rsp, 0x68 %define pix_tmp rsp %endif @@ -379,11 +377,6 @@ cglobal deblock_h_luma_8, 5,9 movq m3, [pix_tmp+0x40] TRANSPOSE8x4B_STORE PASS8ROWS(r6, r5, r7, r8) -%if WIN64 - add rsp, 0x98 -%else - add rsp, 0x68 -%endif RET %endmacro @@ -708,13 +701,16 @@ INIT_MMX cpuname ;----------------------------------------------------------------------------- ; void deblock_h_luma_intra( uint8_t *pix, int stride, int alpha, int beta ) ;----------------------------------------------------------------------------- -cglobal deblock_h_luma_intra_8, 4,9 +cglobal deblock_h_luma_intra_8, 4,9,0,0x80 movsxd r7, r1d lea r8, [r7*3] lea r6, [r0-4] lea r5, [r0-4+r8] - sub rsp, 0x88 +%if WIN64 + %define pix_tmp rsp+0x20 ; shadow space +%else %define pix_tmp rsp +%endif ; transpose 8x16 -> tmp space TRANSPOSE8x8_MEM PASS8ROWS(r6, r5, r7, r8), PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30) @@ -734,7 +730,6 @@ cglobal deblock_h_luma_intra_8, 4,9 sub r5, r7 shr r7, 3 TRANSPOSE8x8_MEM PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30), PASS8ROWS(r6, r5, r7, r8) - add rsp, 0x88 RET %else cglobal deblock_h_luma_intra_8, 2,4,8,0x80 diff --git a/ffmpeg/libavcodec/x86/h264_deblock_10bit.asm b/ffmpeg/libavcodec/x86/h264_deblock_10bit.asm index d63ca02..fdaf510 100644 --- a/ffmpeg/libavcodec/x86/h264_deblock_10bit.asm +++ b/ffmpeg/libavcodec/x86/h264_deblock_10bit.asm @@ -7,20 +7,20 @@ ;* Loren Merritt ;* Jason Garrett-Glaser ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* FFmpeg is free software; you can redistribute it and/or ;* modify it under the terms of the GNU Lesser General Public ;* License as published by the Free Software Foundation; either ;* version 2.1 of the License, or (at your option) any later version. ;* -;* Libav is distributed in the hope that it will be useful, +;* FFmpeg is distributed in the hope that it will be useful, ;* but WITHOUT ANY WARRANTY; without even the implied warranty of ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;* Lesser General Public License for more details. ;* ;* You should have received a copy of the GNU Lesser General Public -;* License along with Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** diff --git a/ffmpeg/libavcodec/x86/h264_idct.asm b/ffmpeg/libavcodec/x86/h264_idct.asm index 7bb1653..9af98a9 100644 --- a/ffmpeg/libavcodec/x86/h264_idct.asm +++ b/ffmpeg/libavcodec/x86/h264_idct.asm @@ -30,7 +30,6 @@ SECTION_RODATA -; FIXME this table is a duplicate from h264data.h, and will be removed once the tables from, h264 have been split scan8_mem: db 4+ 1*8, 5+ 1*8, 4+ 2*8, 5+ 2*8 db 6+ 1*8, 7+ 1*8, 6+ 2*8, 7+ 2*8 db 4+ 3*8, 5+ 3*8, 4+ 4*8, 5+ 4*8 @@ -81,7 +80,7 @@ SECTION .text %endmacro INIT_MMX mmx -; ff_h264_idct_add_mmx(uint8_t *dst, int16_t *block, int stride) +; ff_h264_idct_add_8_mmx(uint8_t *dst, int16_t *block, int stride) cglobal h264_idct_add_8, 3, 3, 0 IDCT4_ADD r0, r1, r2 RET @@ -203,7 +202,7 @@ cglobal h264_idct_add_8, 3, 3, 0 %endmacro INIT_MMX mmx -; ff_h264_idct8_add_mmx(uint8_t *dst, int16_t *block, int stride) +; ff_h264_idct8_add_8_mmx(uint8_t *dst, int16_t *block, int stride) cglobal h264_idct8_add_8, 3, 4, 0 %assign pad 128+4-(stack_offset&7) SUB rsp, pad @@ -271,7 +270,7 @@ cglobal h264_idct8_add_8, 3, 4, 0 %endmacro INIT_XMM sse2 -; ff_h264_idct8_add_sse2(uint8_t *dst, int16_t *block, int stride) +; ff_h264_idct8_add_8_sse2(uint8_t *dst, int16_t *block, int stride) cglobal h264_idct8_add_8, 3, 4, 10 IDCT8_ADD_SSE r0, r1, r2, r3 RET @@ -308,37 +307,38 @@ cglobal h264_idct8_add_8, 3, 4, 10 %endmacro INIT_MMX mmxext -; ff_h264_idct_dc_add_mmxext(uint8_t *dst, int16_t *block, int stride) +; ff_h264_idct_dc_add_8_mmxext(uint8_t *dst, int16_t *block, int stride) %if ARCH_X86_64 cglobal h264_idct_dc_add_8, 3, 4, 0 movsx r3, word [r1] - mov word [r1], 0 + mov dword [r1], 0 DC_ADD_MMXEXT_INIT r3, r2 DC_ADD_MMXEXT_OP movh, r0, r2, r3 RET -; ff_h264_idct8_dc_add_mmxext(uint8_t *dst, int16_t *block, int stride) +; ff_h264_idct8_dc_add_8_mmxext(uint8_t *dst, int16_t *block, int stride) cglobal h264_idct8_dc_add_8, 3, 4, 0 movsx r3, word [r1] - mov word [r1], 0 + mov dword [r1], 0 DC_ADD_MMXEXT_INIT r3, r2 DC_ADD_MMXEXT_OP mova, r0, r2, r3 lea r0, [r0+r2*4] DC_ADD_MMXEXT_OP mova, r0, r2, r3 RET %else +; ff_h264_idct_dc_add_8_mmxext(uint8_t *dst, int16_t *block, int stride) cglobal h264_idct_dc_add_8, 2, 3, 0 movsx r2, word [r1] - mov word [r1], 0 + mov dword [r1], 0 mov r1, r2m DC_ADD_MMXEXT_INIT r2, r1 DC_ADD_MMXEXT_OP movh, r0, r1, r2 RET -; ff_h264_idct8_dc_add_mmxext(uint8_t *dst, int16_t *block, int stride) +; ff_h264_idct8_dc_add_8_mmxext(uint8_t *dst, int16_t *block, int stride) cglobal h264_idct8_dc_add_8, 2, 3, 0 movsx r2, word [r1] - mov word [r1], 0 + mov dword [r1], 0 mov r1, r2m DC_ADD_MMXEXT_INIT r2, r1 DC_ADD_MMXEXT_OP mova, r0, r1, r2 @@ -348,8 +348,9 @@ cglobal h264_idct8_dc_add_8, 2, 3, 0 %endif INIT_MMX mmx -; ff_h264_idct_add16_mmx(uint8_t *dst, const int *block_offset, -; int16_t *block, int stride, const uint8_t nnzc[6*8]) +; ff_h264_idct_add16_8_mmx(uint8_t *dst, const int *block_offset, +; int16_t *block, int stride, +; const uint8_t nnzc[6 * 8]) cglobal h264_idct_add16_8, 5, 7 + npicregs, 0, dst, block_offset, block, stride, nnzc, cntr, coeff, picreg xor r5, r5 %ifdef PIC @@ -370,8 +371,9 @@ cglobal h264_idct_add16_8, 5, 7 + npicregs, 0, dst, block_offset, block, stride, jl .nextblock REP_RET -; ff_h264_idct8_add4_mmx(uint8_t *dst, const int *block_offset, -; int16_t *block, int stride, const uint8_t nnzc[6*8]) +; ff_h264_idct8_add4_8_mmx(uint8_t *dst, const int *block_offset, +; int16_t *block, int stride, +; const uint8_t nnzc[6 * 8]) cglobal h264_idct8_add4_8, 5, 7 + npicregs, 0, dst, block_offset, block, stride, nnzc, cntr, coeff, picreg %assign pad 128+4-(stack_offset&7) SUB rsp, pad @@ -403,8 +405,9 @@ cglobal h264_idct8_add4_8, 5, 7 + npicregs, 0, dst, block_offset, block, stride, RET INIT_MMX mmxext -; ff_h264_idct_add16_mmxext(uint8_t *dst, const int *block_offset, -; int16_t *block, int stride, const uint8_t nnzc[6*8]) +; ff_h264_idct_add16_8_mmxext(uint8_t *dst, const int *block_offset, +; int16_t *block, int stride, +; const uint8_t nnzc[6 * 8]) cglobal h264_idct_add16_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg xor r5, r5 %ifdef PIC @@ -449,8 +452,9 @@ cglobal h264_idct_add16_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride REP_RET INIT_MMX mmx -; ff_h264_idct_add16intra_mmx(uint8_t *dst, const int *block_offset, -; int16_t *block, int stride, const uint8_t nnzc[6*8]) +; ff_h264_idct_add16intra_8_mmx(uint8_t *dst, const int *block_offset, +; int16_t *block, int stride, +; const uint8_t nnzc[6 * 8]) cglobal h264_idct_add16intra_8, 5, 7 + npicregs, 0, dst, block_offset, block, stride, nnzc, cntr, coeff, picreg xor r5, r5 %ifdef PIC @@ -473,9 +477,9 @@ cglobal h264_idct_add16intra_8, 5, 7 + npicregs, 0, dst, block_offset, block, st REP_RET INIT_MMX mmxext -; ff_h264_idct_add16intra_mmxext(uint8_t *dst, const int *block_offset, -; int16_t *block, int stride, -; const uint8_t nnzc[6*8]) +; ff_h264_idct_add16intra_8_mmxext(uint8_t *dst, const int *block_offset, +; int16_t *block, int stride, +; const uint8_t nnzc[6 * 8]) cglobal h264_idct_add16intra_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg xor r5, r5 %ifdef PIC @@ -517,9 +521,9 @@ cglobal h264_idct_add16intra_8, 5, 8 + npicregs, 0, dst1, block_offset, block, s jl .nextblock REP_RET -; ff_h264_idct8_add4_mmxext(uint8_t *dst, const int *block_offset, -; int16_t *block, int stride, -; const uint8_t nnzc[6*8]) +; ff_h264_idct8_add4_8_mmxext(uint8_t *dst, const int *block_offset, +; int16_t *block, int stride, +; const uint8_t nnzc[6 * 8]) cglobal h264_idct8_add4_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg %assign pad 128+4-(stack_offset&7) SUB rsp, pad @@ -579,8 +583,9 @@ cglobal h264_idct8_add4_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride RET INIT_XMM sse2 -; ff_h264_idct8_add4_sse2(uint8_t *dst, const int *block_offset, -; int16_t *block, int stride, const uint8_t nnzc[6*8]) +; ff_h264_idct8_add4_8_sse2(uint8_t *dst, const int *block_offset, +; int16_t *block, int stride, +; const uint8_t nnzc[6 * 8]) cglobal h264_idct8_add4_8, 5, 8 + npicregs, 10, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg xor r5, r5 %ifdef PIC @@ -655,8 +660,8 @@ h264_idct_add8_mmx_plane: jnz .nextblock rep ret -; ff_h264_idct_add8_mmx(uint8_t **dest, const int *block_offset, -; int16_t *block, int stride, const uint8_t nnzc[6*8]) +; ff_h264_idct_add8_8_mmx(uint8_t **dest, const int *block_offset, +; int16_t *block, int stride, const uint8_t nnzc[6 * 8]) cglobal h264_idct_add8_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg mov r5, 16 add r2, 512 @@ -720,8 +725,9 @@ h264_idct_add8_mmxext_plane: rep ret INIT_MMX mmxext -; ff_h264_idct_add8_mmxext(uint8_t **dest, const int *block_offset, -; int16_t *block, int stride, const uint8_t nnzc[6*8]) +; ff_h264_idct_add8_8_mmxext(uint8_t **dest, const int *block_offset, +; int16_t *block, int stride, +; const uint8_t nnzc[6 * 8]) cglobal h264_idct_add8_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg mov r5, 16 add r2, 512 @@ -803,8 +809,9 @@ h264_add8x4_idct_sse2: %endif %endmacro -; ff_h264_idct_add16_sse2(uint8_t *dst, const int *block_offset, -; int16_t *block, int stride, const uint8_t nnzc[6*8]) +; ff_h264_idct_add16_8_sse2(uint8_t *dst, const int *block_offset, +; int16_t *block, int stride, +; const uint8_t nnzc[6 * 8]) cglobal h264_idct_add16_8, 5, 5 + ARCH_X86_64, 8 %if ARCH_X86_64 mov r5, r0 @@ -850,8 +857,9 @@ cglobal h264_idct_add16_8, 5, 5 + ARCH_X86_64, 8 %endif %endmacro -; ff_h264_idct_add16intra_sse2(uint8_t *dst, const int *block_offset, -; int16_t *block, int stride, const uint8_t nnzc[6*8]) +; ff_h264_idct_add16intra_8_sse2(uint8_t *dst, const int *block_offset, +; int16_t *block, int stride, +; const uint8_t nnzc[6 * 8]) cglobal h264_idct_add16intra_8, 5, 7 + ARCH_X86_64, 8 %if ARCH_X86_64 mov r7, r0 @@ -901,8 +909,9 @@ cglobal h264_idct_add16intra_8, 5, 7 + ARCH_X86_64, 8 %endif %endmacro -; ff_h264_idct_add8_sse2(uint8_t **dest, const int *block_offset, -; int16_t *block, int stride, const uint8_t nnzc[6*8]) +; ff_h264_idct_add8_8_sse2(uint8_t **dest, const int *block_offset, +; int16_t *block, int stride, +; const uint8_t nnzc[6 * 8]) cglobal h264_idct_add8_8, 5, 7 + ARCH_X86_64, 8 add r2, 512 %if ARCH_X86_64 diff --git a/ffmpeg/libavcodec/x86/h264_idct_10bit.asm b/ffmpeg/libavcodec/x86/h264_idct_10bit.asm index 88fdb84..df21288 100644 --- a/ffmpeg/libavcodec/x86/h264_idct_10bit.asm +++ b/ffmpeg/libavcodec/x86/h264_idct_10bit.asm @@ -5,20 +5,20 @@ ;* ;* Authors: Daniel Kang ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* FFmpeg is free software; you can redistribute it and/or ;* modify it under the terms of the GNU Lesser General Public ;* License as published by the Free Software Foundation; either ;* version 2.1 of the License, or (at your option) any later version. ;* -;* Libav is distributed in the hope that it will be useful, +;* FFmpeg is distributed in the hope that it will be useful, ;* but WITHOUT ANY WARRANTY; without even the implied warranty of ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;* Lesser General Public License for more details. ;* ;* You should have received a copy of the GNU Lesser General Public -;* License along with Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** diff --git a/ffmpeg/libavcodec/x86/h264_intrapred.asm b/ffmpeg/libavcodec/x86/h264_intrapred.asm index 5c0dff4..3064ec5 100644 --- a/ffmpeg/libavcodec/x86/h264_intrapred.asm +++ b/ffmpeg/libavcodec/x86/h264_intrapred.asm @@ -2486,10 +2486,7 @@ cglobal pred4x4_tm_vp8_8, 3,3 pshufb mm3, mm6 pshufb mm4, mm6 pshufb mm5, mm6 - psubw mm2, mm7 - psubw mm3, mm7 - psubw mm4, mm7 - psubw mm5, mm7 + psubw mm0, mm7 paddw mm2, mm0 paddw mm3, mm0 paddw mm4, mm0 diff --git a/ffmpeg/libavcodec/x86/h264_intrapred_10bit.asm b/ffmpeg/libavcodec/x86/h264_intrapred_10bit.asm index db2b25c..54eaee5 100644 --- a/ffmpeg/libavcodec/x86/h264_intrapred_10bit.asm +++ b/ffmpeg/libavcodec/x86/h264_intrapred_10bit.asm @@ -5,20 +5,20 @@ ;* ;* Authors: Daniel Kang ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* FFmpeg is free software; you can redistribute it and/or ;* modify it under the terms of the GNU Lesser General Public ;* License as published by the Free Software Foundation; either ;* version 2.1 of the License, or (at your option) any later version. ;* -;* Libav is distributed in the hope that it will be useful, +;* FFmpeg is distributed in the hope that it will be useful, ;* but WITHOUT ANY WARRANTY; without even the implied warranty of ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;* Lesser General Public License for more details. ;* ;* You should have received a copy of the GNU Lesser General Public -;* License along with Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** diff --git a/ffmpeg/libavcodec/x86/h264_intrapred_init.c b/ffmpeg/libavcodec/x86/h264_intrapred_init.c index f5b5e3e..ad2984b 100644 --- a/ffmpeg/libavcodec/x86/h264_intrapred_init.c +++ b/ffmpeg/libavcodec/x86/h264_intrapred_init.c @@ -185,10 +185,10 @@ av_cold void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth, const int chroma_format_idc) { - int mm_flags = av_get_cpu_flags(); + int cpu_flags = av_get_cpu_flags(); if (bit_depth == 8) { - if (EXTERNAL_MMX(mm_flags)) { + if (EXTERNAL_MMX(cpu_flags)) { h->pred16x16[VERT_PRED8x8 ] = ff_pred16x16_vertical_8_mmx; h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_8_mmx; if (chroma_format_idc == 1) { @@ -203,7 +203,7 @@ av_cold void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, if (chroma_format_idc == 1) h->pred8x8 [PLANE_PRED8x8] = ff_pred8x8_plane_8_mmx; if (codec_id == AV_CODEC_ID_SVQ3) { - if (mm_flags & AV_CPU_FLAG_CMOV) + if (cpu_flags & AV_CPU_FLAG_CMOV) h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_svq3_8_mmx; } else if (codec_id == AV_CODEC_ID_RV40) { h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_rv40_8_mmx; @@ -213,7 +213,7 @@ av_cold void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, } } - if (EXTERNAL_MMXEXT(mm_flags)) { + if (EXTERNAL_MMXEXT(cpu_flags)) { h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_8_mmxext; h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_8_mmxext; if (chroma_format_idc == 1) @@ -265,11 +265,11 @@ av_cold void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, } } - if (EXTERNAL_SSE(mm_flags)) { + if (EXTERNAL_SSE(cpu_flags)) { h->pred16x16[VERT_PRED8x8] = ff_pred16x16_vertical_8_sse; } - if (EXTERNAL_SSE2(mm_flags)) { + if (EXTERNAL_SSE2(cpu_flags)) { h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_8_sse2; h->pred8x8l [DIAG_DOWN_LEFT_PRED ] = ff_pred8x8l_down_left_8_sse2; h->pred8x8l [DIAG_DOWN_RIGHT_PRED ] = ff_pred8x8l_down_right_8_sse2; @@ -292,7 +292,7 @@ av_cold void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, } } - if (EXTERNAL_SSSE3(mm_flags)) { + if (EXTERNAL_SSSE3(cpu_flags)) { h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_8_ssse3; h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_8_ssse3; if (chroma_format_idc == 1) @@ -323,7 +323,7 @@ av_cold void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, } } } else if (bit_depth == 10) { - if (EXTERNAL_MMXEXT(mm_flags)) { + if (EXTERNAL_MMXEXT(cpu_flags)) { h->pred4x4[DC_PRED ] = ff_pred4x4_dc_10_mmxext; h->pred4x4[HOR_UP_PRED ] = ff_pred4x4_horizontal_up_10_mmxext; @@ -339,7 +339,7 @@ av_cold void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, h->pred16x16[VERT_PRED8x8 ] = ff_pred16x16_vertical_10_mmxext; h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_10_mmxext; } - if (EXTERNAL_SSE2(mm_flags)) { + if (EXTERNAL_SSE2(cpu_flags)) { h->pred4x4[DIAG_DOWN_LEFT_PRED ] = ff_pred4x4_down_left_10_sse2; h->pred4x4[DIAG_DOWN_RIGHT_PRED] = ff_pred4x4_down_right_10_sse2; h->pred4x4[VERT_LEFT_PRED ] = ff_pred4x4_vertical_left_10_sse2; @@ -371,7 +371,7 @@ av_cold void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, h->pred16x16[VERT_PRED8x8 ] = ff_pred16x16_vertical_10_sse2; h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_10_sse2; } - if (EXTERNAL_SSSE3(mm_flags)) { + if (EXTERNAL_SSSE3(cpu_flags)) { h->pred4x4[DIAG_DOWN_RIGHT_PRED] = ff_pred4x4_down_right_10_ssse3; h->pred4x4[VERT_RIGHT_PRED ] = ff_pred4x4_vertical_right_10_ssse3; h->pred4x4[HOR_DOWN_PRED ] = ff_pred4x4_horizontal_down_10_ssse3; @@ -382,7 +382,7 @@ av_cold void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, h->pred8x8l[VERT_RIGHT_PRED ] = ff_pred8x8l_vertical_right_10_ssse3; h->pred8x8l[HOR_UP_PRED ] = ff_pred8x8l_horizontal_up_10_ssse3; } - if (EXTERNAL_AVX(mm_flags)) { + if (EXTERNAL_AVX(cpu_flags)) { h->pred4x4[DIAG_DOWN_LEFT_PRED ] = ff_pred4x4_down_left_10_avx; h->pred4x4[DIAG_DOWN_RIGHT_PRED] = ff_pred4x4_down_right_10_avx; h->pred4x4[VERT_LEFT_PRED ] = ff_pred4x4_vertical_left_10_avx; diff --git a/ffmpeg/libavcodec/x86/h264_qpel.c b/ffmpeg/libavcodec/x86/h264_qpel.c index 96dec82..fd6068f 100644 --- a/ffmpeg/libavcodec/x86/h264_qpel.c +++ b/ffmpeg/libavcodec/x86/h264_qpel.c @@ -25,24 +25,13 @@ #include "libavutil/x86/cpu.h" #include "libavcodec/h264qpel.h" #include "libavcodec/mpegvideo.h" -#include "dsputil_mmx.h" +#include "dsputil_x86.h" #if HAVE_YASM -void ff_put_pixels4_mmxext(uint8_t *block, const uint8_t *pixels, int line_size, int h); -void ff_avg_pixels4_mmxext(uint8_t *block, const uint8_t *pixels, int line_size, int h); -void ff_put_pixels8_mmxext(uint8_t *block, const uint8_t *pixels, int line_size, int h); -static void ff_put_pixels16_mmxext(uint8_t *block, const uint8_t *pixels, - int line_size, int h) -{ - ff_put_pixels8_mmxext(block, pixels, line_size, h); - ff_put_pixels8_mmxext(block + 8, pixels + 8, line_size, h); -} -static void ff_avg_pixels16_mmxext(uint8_t *block, const uint8_t *pixels, - int line_size, int h) -{ - ff_avg_pixels8_mmxext(block, pixels, line_size, h); - ff_avg_pixels8_mmxext(block + 8, pixels + 8, line_size, h); -} +void ff_put_pixels4_mmxext(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels4_mmxext(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); void ff_put_pixels4_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h); void ff_avg_pixels4_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2, @@ -55,15 +44,14 @@ void ff_put_pixels16_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h); void ff_avg_pixels16_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h); -void ff_put_pixels16_sse2(uint8_t *block, const uint8_t *pixels, - int line_size, int h); -void ff_avg_pixels16_sse2(uint8_t *block, const uint8_t *pixels, - int line_size, int h); #define ff_put_pixels8_l2_sse2 ff_put_pixels8_l2_mmxext #define ff_avg_pixels8_l2_sse2 ff_avg_pixels8_l2_mmxext #define ff_put_pixels16_l2_sse2 ff_put_pixels16_l2_mmxext #define ff_avg_pixels16_l2_sse2 ff_avg_pixels16_l2_mmxext +PIXELS16(static, ff_avg, , , _mmxext) +PIXELS16(static, ff_put, , , _mmxext) + #define DEF_QPEL(OPNAME)\ void ff_ ## OPNAME ## _h264_qpel4_h_lowpass_mmxext(uint8_t *dst, uint8_t *src, int dstStride, int srcStride);\ void ff_ ## OPNAME ## _h264_qpel8_h_lowpass_mmxext(uint8_t *dst, uint8_t *src, int dstStride, int srcStride);\ @@ -209,7 +197,12 @@ static av_always_inline void ff_ ## OPNAME ## h264_qpel16_v_lowpass_ ## MMX(uint ff_ ## OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(dst+8, src+8, dstStride, srcStride, 16);\ } -static av_always_inline void ff_put_h264_qpel8or16_hv1_lowpass_sse2(int16_t *tmp, uint8_t *src, int tmpStride, int srcStride, int size){ +static av_always_inline void put_h264_qpel8or16_hv1_lowpass_sse2(int16_t *tmp, + uint8_t *src, + int tmpStride, + int srcStride, + int size) +{ int w = (size+8)>>3; src -= 2*srcStride+2; while(w--){ @@ -221,7 +214,7 @@ static av_always_inline void ff_put_h264_qpel8or16_hv1_lowpass_sse2(int16_t *tmp #define QPEL_H264_HV_XMM(OPNAME, OP, MMX)\ static av_always_inline void ff_ ## OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride, int size){\ - ff_put_h264_qpel8or16_hv1_lowpass_sse2(tmp, src, tmpStride, srcStride, size);\ + put_h264_qpel8or16_hv1_lowpass_sse2(tmp, src, tmpStride, srcStride, size);\ ff_ ## OPNAME ## h264_qpel8or16_hv2_lowpass_ ## MMX(dst, tmp, dstStride, tmpStride, size);\ }\ static av_always_inline void ff_ ## OPNAME ## h264_qpel8_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride){\ @@ -345,7 +338,7 @@ static void OPNAME ## h264_qpel ## SIZE ## _mc21_ ## MMX(uint8_t *dst, uint8_t * DECLARE_ALIGNED(ALIGN, uint8_t, temp)[SIZE*(SIZE<8?12:24)*2 + SIZE*SIZE];\ uint8_t * const halfHV= temp;\ int16_t * const halfV= (int16_t*)(temp + SIZE*SIZE);\ - assert(((int)temp & 7) == 0);\ + av_assert2(((int)temp & 7) == 0);\ ff_put_h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(halfHV, halfV, src, SIZE, SIZE, stride);\ ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, halfHV, stride, SIZE);\ }\ @@ -355,7 +348,7 @@ static void OPNAME ## h264_qpel ## SIZE ## _mc23_ ## MMX(uint8_t *dst, uint8_t * DECLARE_ALIGNED(ALIGN, uint8_t, temp)[SIZE*(SIZE<8?12:24)*2 + SIZE*SIZE];\ uint8_t * const halfHV= temp;\ int16_t * const halfV= (int16_t*)(temp + SIZE*SIZE);\ - assert(((int)temp & 7) == 0);\ + av_assert2(((int)temp & 7) == 0);\ ff_put_h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(halfHV, halfV, src, SIZE, SIZE, stride);\ ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src+stride, halfHV, stride, SIZE);\ }\ @@ -365,7 +358,7 @@ static void OPNAME ## h264_qpel ## SIZE ## _mc12_ ## MMX(uint8_t *dst, uint8_t * DECLARE_ALIGNED(ALIGN, uint8_t, temp)[SIZE*(SIZE<8?12:24)*2 + SIZE*SIZE];\ uint8_t * const halfHV= temp;\ int16_t * const halfV= (int16_t*)(temp + SIZE*SIZE);\ - assert(((int)temp & 7) == 0);\ + av_assert2(((int)temp & 7) == 0);\ ff_put_h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(halfHV, halfV, src, SIZE, SIZE, stride);\ ff_ ## OPNAME ## pixels ## SIZE ## _l2_shift5_mmxext(dst, halfV+2, halfHV, stride, SIZE, SIZE);\ }\ @@ -375,7 +368,7 @@ static void OPNAME ## h264_qpel ## SIZE ## _mc32_ ## MMX(uint8_t *dst, uint8_t * DECLARE_ALIGNED(ALIGN, uint8_t, temp)[SIZE*(SIZE<8?12:24)*2 + SIZE*SIZE];\ uint8_t * const halfHV= temp;\ int16_t * const halfV= (int16_t*)(temp + SIZE*SIZE);\ - assert(((int)temp & 7) == 0);\ + av_assert2(((int)temp & 7) == 0);\ ff_put_h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(halfHV, halfV, src, SIZE, SIZE, stride);\ ff_ ## OPNAME ## pixels ## SIZE ## _l2_shift5_mmxext(dst, halfV+3, halfHV, stride, SIZE, SIZE);\ }\ @@ -394,8 +387,6 @@ QPEL(put_, 16,XMM, 16)\ QPEL(avg_, 8, XMM, 16)\ QPEL(avg_, 16,XMM, 16)\ -#undef PAVGB -#define PAVGB "pavgb" QPEL_H264(put_, PUT_OP, mmxext) QPEL_H264(avg_, AVG_MMXEXT_OP, mmxext) QPEL_H264_V_XMM(put_, PUT_OP, sse2) @@ -406,7 +397,6 @@ QPEL_H264_H_XMM(put_, PUT_OP, ssse3) QPEL_H264_H_XMM(avg_,AVG_MMXEXT_OP, ssse3) QPEL_H264_HV_XMM(put_, PUT_OP, ssse3) QPEL_H264_HV_XMM(avg_,AVG_MMXEXT_OP, ssse3) -#undef PAVGB H264_MC_4816(mmxext) H264_MC_816(H264_MC_V, sse2) @@ -552,9 +542,9 @@ av_cold void ff_h264qpel_init_x86(H264QpelContext *c, int bit_depth) { #if HAVE_YASM int high_bit_depth = bit_depth > 8; - int mm_flags = av_get_cpu_flags(); + int cpu_flags = av_get_cpu_flags(); - if (EXTERNAL_MMXEXT(mm_flags)) { + if (EXTERNAL_MMXEXT(cpu_flags)) { if (!high_bit_depth) { SET_QPEL_FUNCS(put_h264_qpel, 0, 16, mmxext, ); SET_QPEL_FUNCS(put_h264_qpel, 1, 8, mmxext, ); @@ -574,8 +564,8 @@ av_cold void ff_h264qpel_init_x86(H264QpelContext *c, int bit_depth) } } - if (EXTERNAL_SSE2(mm_flags)) { - if (!(mm_flags & AV_CPU_FLAG_SSE2SLOW) && !high_bit_depth) { + if (EXTERNAL_SSE2(cpu_flags)) { + if (!(cpu_flags & AV_CPU_FLAG_SSE2SLOW) && !high_bit_depth) { // these functions are slower than mmx on AMD, but faster on Intel H264_QPEL_FUNCS(0, 0, sse2); } @@ -606,7 +596,7 @@ av_cold void ff_h264qpel_init_x86(H264QpelContext *c, int bit_depth) } } - if (EXTERNAL_SSSE3(mm_flags)) { + if (EXTERNAL_SSSE3(cpu_flags)) { if (!high_bit_depth) { H264_QPEL_FUNCS(1, 0, ssse3); H264_QPEL_FUNCS(1, 1, ssse3); @@ -629,7 +619,7 @@ av_cold void ff_h264qpel_init_x86(H264QpelContext *c, int bit_depth) } } - if (EXTERNAL_AVX(mm_flags)) { + if (EXTERNAL_AVX(cpu_flags)) { /* AVX implies 64 byte cache lines without the need to avoid unaligned * memory accesses that cross the boundary between two cache lines. * TODO: Port X264_CPU_CACHELINE_32/64 detection from x264 to avoid diff --git a/ffmpeg/libavcodec/x86/h264_qpel_10bit.asm b/ffmpeg/libavcodec/x86/h264_qpel_10bit.asm index e14df84..4561871 100644 --- a/ffmpeg/libavcodec/x86/h264_qpel_10bit.asm +++ b/ffmpeg/libavcodec/x86/h264_qpel_10bit.asm @@ -5,20 +5,20 @@ ;* ;* Authors: Daniel Kang ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* FFmpeg is free software; you can redistribute it and/or ;* modify it under the terms of the GNU Lesser General Public ;* License as published by the Free Software Foundation; either ;* version 2.1 of the License, or (at your option) any later version. ;* -;* Libav is distributed in the hope that it will be useful, +;* FFmpeg is distributed in the hope that it will be useful, ;* but WITHOUT ANY WARRANTY; without even the implied warranty of ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;* Lesser General Public License for more details. ;* ;* You should have received a copy of the GNU Lesser General Public -;* License along with Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** diff --git a/ffmpeg/libavcodec/x86/h264_weight_10bit.asm b/ffmpeg/libavcodec/x86/h264_weight_10bit.asm index 3b09e42..b7845fd 100644 --- a/ffmpeg/libavcodec/x86/h264_weight_10bit.asm +++ b/ffmpeg/libavcodec/x86/h264_weight_10bit.asm @@ -5,20 +5,20 @@ ;* ;* Authors: Daniel Kang ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* FFmpeg is free software; you can redistribute it and/or ;* modify it under the terms of the GNU Lesser General Public ;* License as published by the Free Software Foundation; either ;* version 2.1 of the License, or (at your option) any later version. ;* -;* Libav is distributed in the hope that it will be useful, +;* FFmpeg is distributed in the hope that it will be useful, ;* but WITHOUT ANY WARRANTY; without even the implied warranty of ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;* Lesser General Public License for more details. ;* ;* You should have received a copy of the GNU Lesser General Public -;* License along with Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** diff --git a/ffmpeg/libavcodec/x86/h264chroma_init.c b/ffmpeg/libavcodec/x86/h264chroma_init.c index b5c078f..3d8d5b0 100644 --- a/ffmpeg/libavcodec/x86/h264chroma_init.c +++ b/ffmpeg/libavcodec/x86/h264chroma_init.c @@ -19,6 +19,7 @@ #include #include "config.h" +#include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/x86/cpu.h" #include "libavcodec/h264chroma.h" @@ -66,49 +67,49 @@ CHROMA_MC(avg, 8, 10, sse2) CHROMA_MC(put, 8, 10, avx) CHROMA_MC(avg, 8, 10, avx) -void ff_h264chroma_init_x86(H264ChromaContext *c, int bit_depth) +av_cold void ff_h264chroma_init_x86(H264ChromaContext *c, int bit_depth) { #if HAVE_YASM int high_bit_depth = bit_depth > 8; - int mm_flags = av_get_cpu_flags(); + int cpu_flags = av_get_cpu_flags(); - if (EXTERNAL_MMX(mm_flags) && !high_bit_depth) { + if (EXTERNAL_MMX(cpu_flags) && !high_bit_depth) { c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_rnd_mmx; c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_mmx; } - if (EXTERNAL_AMD3DNOW(mm_flags) && !high_bit_depth) { + if (EXTERNAL_AMD3DNOW(cpu_flags) && !high_bit_depth) { c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_rnd_3dnow; c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_3dnow; } - if (EXTERNAL_MMXEXT(mm_flags) && !high_bit_depth) { + if (EXTERNAL_MMXEXT(cpu_flags) && !high_bit_depth) { c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_rnd_mmxext; c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_mmxext; c->avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_mmxext; c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_mmxext; } - if (EXTERNAL_MMXEXT(mm_flags) && bit_depth > 8 && bit_depth <= 10) { + if (EXTERNAL_MMXEXT(cpu_flags) && bit_depth > 8 && bit_depth <= 10) { c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_10_mmxext; c->avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_10_mmxext; c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_10_mmxext; c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_10_mmxext; } - if (EXTERNAL_SSE2(mm_flags) && bit_depth > 8 && bit_depth <= 10) { + if (EXTERNAL_SSE2(cpu_flags) && bit_depth > 8 && bit_depth <= 10) { c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_10_sse2; c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_10_sse2; } - if (EXTERNAL_SSSE3(mm_flags) && !high_bit_depth) { + if (EXTERNAL_SSSE3(cpu_flags) && !high_bit_depth) { c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_rnd_ssse3; c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_rnd_ssse3; c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_ssse3; c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_ssse3; } - if (EXTERNAL_AVX(mm_flags) && bit_depth > 8 && bit_depth <= 10) { + if (EXTERNAL_AVX(cpu_flags) && bit_depth > 8 && bit_depth <= 10) { // AVX implies !cache64. // TODO: Port cache(32|64) detection from x264. c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_10_avx; diff --git a/ffmpeg/libavcodec/x86/h264dsp_init.c b/ffmpeg/libavcodec/x86/h264dsp_init.c index 11aae77..30801c4 100644 --- a/ffmpeg/libavcodec/x86/h264dsp_init.c +++ b/ffmpeg/libavcodec/x86/h264dsp_init.c @@ -23,7 +23,7 @@ #include "libavutil/x86/asm.h" #include "libavutil/x86/cpu.h" #include "libavcodec/h264dsp.h" -#include "dsputil_mmx.h" +#include "dsputil_x86.h" /***********************************/ /* IDCT */ @@ -132,8 +132,8 @@ LF_FUNCS(uint16_t, 10) #if ARCH_X86_32 && HAVE_MMXEXT_EXTERNAL LF_FUNC(v8, luma, 8, mmxext) -static void ff_deblock_v_luma_8_mmxext(uint8_t *pix, int stride, int alpha, - int beta, int8_t *tc0) +static void deblock_v_luma_8_mmxext(uint8_t *pix, int stride, int alpha, + int beta, int8_t *tc0) { if ((tc0[0] & tc0[1]) >= 0) ff_deblock_v8_luma_8_mmxext(pix + 0, stride, alpha, beta, tc0); @@ -141,8 +141,8 @@ static void ff_deblock_v_luma_8_mmxext(uint8_t *pix, int stride, int alpha, ff_deblock_v8_luma_8_mmxext(pix + 8, stride, alpha, beta, tc0 + 2); } LF_IFUNC(v8, luma_intra, 8, mmxext) -static void ff_deblock_v_luma_intra_8_mmxext(uint8_t *pix, int stride, - int alpha, int beta) +static void deblock_v_luma_intra_8_mmxext(uint8_t *pix, int stride, + int alpha, int beta) { ff_deblock_v8_luma_intra_8_mmxext(pix + 0, stride, alpha, beta); ff_deblock_v8_luma_intra_8_mmxext(pix + 8, stride, alpha, beta); @@ -212,13 +212,13 @@ av_cold void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth, const int chroma_format_idc) { #if HAVE_YASM - int mm_flags = av_get_cpu_flags(); + int cpu_flags = av_get_cpu_flags(); - if (chroma_format_idc == 1 && EXTERNAL_MMXEXT(mm_flags)) + if (chroma_format_idc == 1 && EXTERNAL_MMXEXT(cpu_flags)) c->h264_loop_filter_strength = ff_h264_loop_filter_strength_mmxext; if (bit_depth == 8) { - if (EXTERNAL_MMX(mm_flags)) { + if (EXTERNAL_MMX(cpu_flags)) { c->h264_idct_dc_add = c->h264_idct_add = ff_h264_idct_add_8_mmx; c->h264_idct8_dc_add = @@ -229,146 +229,142 @@ av_cold void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth, if (chroma_format_idc == 1) c->h264_idct_add8 = ff_h264_idct_add8_8_mmx; c->h264_idct_add16intra = ff_h264_idct_add16intra_8_mmx; - if (mm_flags & AV_CPU_FLAG_CMOV) + if (cpu_flags & AV_CPU_FLAG_CMOV) c->h264_luma_dc_dequant_idct = ff_h264_luma_dc_dequant_idct_mmx; - - if (EXTERNAL_MMXEXT(mm_flags)) { - c->h264_idct_dc_add = ff_h264_idct_dc_add_8_mmxext; - c->h264_idct8_dc_add = ff_h264_idct8_dc_add_8_mmxext; - c->h264_idct_add16 = ff_h264_idct_add16_8_mmxext; - c->h264_idct8_add4 = ff_h264_idct8_add4_8_mmxext; - if (chroma_format_idc == 1) - c->h264_idct_add8 = ff_h264_idct_add8_8_mmxext; - c->h264_idct_add16intra = ff_h264_idct_add16intra_8_mmxext; - - c->h264_v_loop_filter_chroma = ff_deblock_v_chroma_8_mmxext; - c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_8_mmxext; - if (chroma_format_idc == 1) { - c->h264_h_loop_filter_chroma = ff_deblock_h_chroma_8_mmxext; - c->h264_h_loop_filter_chroma_intra = ff_deblock_h_chroma_intra_8_mmxext; - } + } + if (EXTERNAL_MMXEXT(cpu_flags)) { + c->h264_idct_dc_add = ff_h264_idct_dc_add_8_mmxext; + c->h264_idct8_dc_add = ff_h264_idct8_dc_add_8_mmxext; + c->h264_idct_add16 = ff_h264_idct_add16_8_mmxext; + c->h264_idct8_add4 = ff_h264_idct8_add4_8_mmxext; + if (chroma_format_idc == 1) + c->h264_idct_add8 = ff_h264_idct_add8_8_mmxext; + c->h264_idct_add16intra = ff_h264_idct_add16intra_8_mmxext; + + c->h264_v_loop_filter_chroma = ff_deblock_v_chroma_8_mmxext; + c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_8_mmxext; + if (chroma_format_idc == 1) { + c->h264_h_loop_filter_chroma = ff_deblock_h_chroma_8_mmxext; + c->h264_h_loop_filter_chroma_intra = ff_deblock_h_chroma_intra_8_mmxext; + } #if ARCH_X86_32 && HAVE_MMXEXT_EXTERNAL - c->h264_v_loop_filter_luma = ff_deblock_v_luma_8_mmxext; - c->h264_h_loop_filter_luma = ff_deblock_h_luma_8_mmxext; - c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_8_mmxext; - c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_8_mmxext; + c->h264_v_loop_filter_luma = deblock_v_luma_8_mmxext; + c->h264_h_loop_filter_luma = ff_deblock_h_luma_8_mmxext; + c->h264_v_loop_filter_luma_intra = deblock_v_luma_intra_8_mmxext; + c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_8_mmxext; #endif /* ARCH_X86_32 && HAVE_MMXEXT_EXTERNAL */ - c->weight_h264_pixels_tab[0] = ff_h264_weight_16_mmxext; - c->weight_h264_pixels_tab[1] = ff_h264_weight_8_mmxext; - c->weight_h264_pixels_tab[2] = ff_h264_weight_4_mmxext; - - c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_mmxext; - c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_mmxext; - c->biweight_h264_pixels_tab[2] = ff_h264_biweight_4_mmxext; - - if (EXTERNAL_SSE2(mm_flags)) { - c->h264_idct8_add = ff_h264_idct8_add_8_sse2; - - c->h264_idct_add16 = ff_h264_idct_add16_8_sse2; - c->h264_idct8_add4 = ff_h264_idct8_add4_8_sse2; - if (chroma_format_idc == 1) - c->h264_idct_add8 = ff_h264_idct_add8_8_sse2; - c->h264_idct_add16intra = ff_h264_idct_add16intra_8_sse2; - c->h264_luma_dc_dequant_idct = ff_h264_luma_dc_dequant_idct_sse2; - - c->weight_h264_pixels_tab[0] = ff_h264_weight_16_sse2; - c->weight_h264_pixels_tab[1] = ff_h264_weight_8_sse2; - - c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_sse2; - c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_sse2; - - c->h264_v_loop_filter_luma = ff_deblock_v_luma_8_sse2; - c->h264_h_loop_filter_luma = ff_deblock_h_luma_8_sse2; - c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_8_sse2; - c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_8_sse2; - } - if (EXTERNAL_SSSE3(mm_flags)) { - c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_ssse3; - c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_ssse3; - } - if (EXTERNAL_AVX(mm_flags)) { - c->h264_v_loop_filter_luma = ff_deblock_v_luma_8_avx; - c->h264_h_loop_filter_luma = ff_deblock_h_luma_8_avx; - c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_8_avx; - c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_8_avx; - } - } + c->weight_h264_pixels_tab[0] = ff_h264_weight_16_mmxext; + c->weight_h264_pixels_tab[1] = ff_h264_weight_8_mmxext; + c->weight_h264_pixels_tab[2] = ff_h264_weight_4_mmxext; + + c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_mmxext; + c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_mmxext; + c->biweight_h264_pixels_tab[2] = ff_h264_biweight_4_mmxext; + } + if (EXTERNAL_SSE2(cpu_flags)) { + c->h264_idct8_add = ff_h264_idct8_add_8_sse2; + + c->h264_idct_add16 = ff_h264_idct_add16_8_sse2; + c->h264_idct8_add4 = ff_h264_idct8_add4_8_sse2; + if (chroma_format_idc == 1) + c->h264_idct_add8 = ff_h264_idct_add8_8_sse2; + c->h264_idct_add16intra = ff_h264_idct_add16intra_8_sse2; + c->h264_luma_dc_dequant_idct = ff_h264_luma_dc_dequant_idct_sse2; + + c->weight_h264_pixels_tab[0] = ff_h264_weight_16_sse2; + c->weight_h264_pixels_tab[1] = ff_h264_weight_8_sse2; + + c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_sse2; + c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_sse2; + + c->h264_v_loop_filter_luma = ff_deblock_v_luma_8_sse2; + c->h264_h_loop_filter_luma = ff_deblock_h_luma_8_sse2; + c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_8_sse2; + c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_8_sse2; + } + if (EXTERNAL_SSSE3(cpu_flags)) { + c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_ssse3; + c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_ssse3; + } + if (EXTERNAL_AVX(cpu_flags)) { + c->h264_v_loop_filter_luma = ff_deblock_v_luma_8_avx; + c->h264_h_loop_filter_luma = ff_deblock_h_luma_8_avx; + c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_8_avx; + c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_8_avx; } } else if (bit_depth == 10) { - if (EXTERNAL_MMX(mm_flags)) { - if (EXTERNAL_MMXEXT(mm_flags)) { + if (EXTERNAL_MMXEXT(cpu_flags)) { #if ARCH_X86_32 - c->h264_v_loop_filter_chroma = ff_deblock_v_chroma_10_mmxext; - c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_10_mmxext; - c->h264_v_loop_filter_luma = ff_deblock_v_luma_10_mmxext; - c->h264_h_loop_filter_luma = ff_deblock_h_luma_10_mmxext; - c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_10_mmxext; - c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_10_mmxext; + c->h264_v_loop_filter_chroma = ff_deblock_v_chroma_10_mmxext; + c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_10_mmxext; + c->h264_v_loop_filter_luma = ff_deblock_v_luma_10_mmxext; + c->h264_h_loop_filter_luma = ff_deblock_h_luma_10_mmxext; + c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_10_mmxext; + c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_10_mmxext; #endif /* ARCH_X86_32 */ - c->h264_idct_dc_add = ff_h264_idct_dc_add_10_mmxext; - if (EXTERNAL_SSE2(mm_flags)) { - c->h264_idct_add = ff_h264_idct_add_10_sse2; - c->h264_idct8_dc_add = ff_h264_idct8_dc_add_10_sse2; - - c->h264_idct_add16 = ff_h264_idct_add16_10_sse2; - if (chroma_format_idc == 1) - c->h264_idct_add8 = ff_h264_idct_add8_10_sse2; - c->h264_idct_add16intra = ff_h264_idct_add16intra_10_sse2; + c->h264_idct_dc_add = ff_h264_idct_dc_add_10_mmxext; + } + if (EXTERNAL_SSE2(cpu_flags)) { + c->h264_idct_add = ff_h264_idct_add_10_sse2; + c->h264_idct8_dc_add = ff_h264_idct8_dc_add_10_sse2; + + c->h264_idct_add16 = ff_h264_idct_add16_10_sse2; + if (chroma_format_idc == 1) + c->h264_idct_add8 = ff_h264_idct_add8_10_sse2; + c->h264_idct_add16intra = ff_h264_idct_add16intra_10_sse2; #if HAVE_ALIGNED_STACK - c->h264_idct8_add = ff_h264_idct8_add_10_sse2; - c->h264_idct8_add4 = ff_h264_idct8_add4_10_sse2; + c->h264_idct8_add = ff_h264_idct8_add_10_sse2; + c->h264_idct8_add4 = ff_h264_idct8_add4_10_sse2; #endif /* HAVE_ALIGNED_STACK */ - c->weight_h264_pixels_tab[0] = ff_h264_weight_16_10_sse2; - c->weight_h264_pixels_tab[1] = ff_h264_weight_8_10_sse2; - c->weight_h264_pixels_tab[2] = ff_h264_weight_4_10_sse2; + c->weight_h264_pixels_tab[0] = ff_h264_weight_16_10_sse2; + c->weight_h264_pixels_tab[1] = ff_h264_weight_8_10_sse2; + c->weight_h264_pixels_tab[2] = ff_h264_weight_4_10_sse2; - c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_10_sse2; - c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_10_sse2; - c->biweight_h264_pixels_tab[2] = ff_h264_biweight_4_10_sse2; + c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_10_sse2; + c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_10_sse2; + c->biweight_h264_pixels_tab[2] = ff_h264_biweight_4_10_sse2; - c->h264_v_loop_filter_chroma = ff_deblock_v_chroma_10_sse2; - c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_10_sse2; + c->h264_v_loop_filter_chroma = ff_deblock_v_chroma_10_sse2; + c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_10_sse2; #if HAVE_ALIGNED_STACK - c->h264_v_loop_filter_luma = ff_deblock_v_luma_10_sse2; - c->h264_h_loop_filter_luma = ff_deblock_h_luma_10_sse2; - c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_10_sse2; - c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_10_sse2; + c->h264_v_loop_filter_luma = ff_deblock_v_luma_10_sse2; + c->h264_h_loop_filter_luma = ff_deblock_h_luma_10_sse2; + c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_10_sse2; + c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_10_sse2; #endif /* HAVE_ALIGNED_STACK */ - } - if (EXTERNAL_SSE4(mm_flags)) { - c->weight_h264_pixels_tab[0] = ff_h264_weight_16_10_sse4; - c->weight_h264_pixels_tab[1] = ff_h264_weight_8_10_sse4; - c->weight_h264_pixels_tab[2] = ff_h264_weight_4_10_sse4; - - c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_10_sse4; - c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_10_sse4; - c->biweight_h264_pixels_tab[2] = ff_h264_biweight_4_10_sse4; - } - if (EXTERNAL_AVX(mm_flags)) { - c->h264_idct_dc_add = - c->h264_idct_add = ff_h264_idct_add_10_avx; - c->h264_idct8_dc_add = ff_h264_idct8_dc_add_10_avx; - - c->h264_idct_add16 = ff_h264_idct_add16_10_avx; - if (chroma_format_idc == 1) - c->h264_idct_add8 = ff_h264_idct_add8_10_avx; - c->h264_idct_add16intra = ff_h264_idct_add16intra_10_avx; + } + if (EXTERNAL_SSE4(cpu_flags)) { + c->weight_h264_pixels_tab[0] = ff_h264_weight_16_10_sse4; + c->weight_h264_pixels_tab[1] = ff_h264_weight_8_10_sse4; + c->weight_h264_pixels_tab[2] = ff_h264_weight_4_10_sse4; + + c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_10_sse4; + c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_10_sse4; + c->biweight_h264_pixels_tab[2] = ff_h264_biweight_4_10_sse4; + } + if (EXTERNAL_AVX(cpu_flags)) { + c->h264_idct_dc_add = + c->h264_idct_add = ff_h264_idct_add_10_avx; + c->h264_idct8_dc_add = ff_h264_idct8_dc_add_10_avx; + + c->h264_idct_add16 = ff_h264_idct_add16_10_avx; + if (chroma_format_idc == 1) + c->h264_idct_add8 = ff_h264_idct_add8_10_avx; + c->h264_idct_add16intra = ff_h264_idct_add16intra_10_avx; #if HAVE_ALIGNED_STACK - c->h264_idct8_add = ff_h264_idct8_add_10_avx; - c->h264_idct8_add4 = ff_h264_idct8_add4_10_avx; + c->h264_idct8_add = ff_h264_idct8_add_10_avx; + c->h264_idct8_add4 = ff_h264_idct8_add4_10_avx; #endif /* HAVE_ALIGNED_STACK */ - c->h264_v_loop_filter_chroma = ff_deblock_v_chroma_10_avx; - c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_10_avx; + c->h264_v_loop_filter_chroma = ff_deblock_v_chroma_10_avx; + c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_10_avx; #if HAVE_ALIGNED_STACK - c->h264_v_loop_filter_luma = ff_deblock_v_luma_10_avx; - c->h264_h_loop_filter_luma = ff_deblock_h_luma_10_avx; - c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_10_avx; - c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_10_avx; + c->h264_v_loop_filter_luma = ff_deblock_v_luma_10_avx; + c->h264_h_loop_filter_luma = ff_deblock_h_luma_10_avx; + c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_10_avx; + c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_10_avx; #endif /* HAVE_ALIGNED_STACK */ - } - } } } #endif diff --git a/ffmpeg/libavcodec/x86/hpeldsp.asm b/ffmpeg/libavcodec/x86/hpeldsp.asm index 1a572a3..4eaba6e 100644 --- a/ffmpeg/libavcodec/x86/hpeldsp.asm +++ b/ffmpeg/libavcodec/x86/hpeldsp.asm @@ -423,30 +423,30 @@ cglobal avg_pixels8_xy2, 4,5 mova m6, [pb_1] lea r4, [r2*2] mova m0, [r1] - pavgb m0, [r1+1] + PAVGB m0, [r1+1] .loop: mova m2, [r1+r4] mova m1, [r1+r2] psubusb m2, m6 - pavgb m1, [r1+r2+1] - pavgb m2, [r1+r4+1] + PAVGB m1, [r1+r2+1] + PAVGB m2, [r1+r4+1] add r1, r4 - pavgb m0, m1 - pavgb m1, m2 - pavgb m0, [r0] - pavgb m1, [r0+r2] + PAVGB m0, m1 + PAVGB m1, m2 + PAVGB m0, [r0] + PAVGB m1, [r0+r2] mova [r0], m0 mova [r0+r2], m1 mova m1, [r1+r2] mova m0, [r1+r4] - pavgb m1, [r1+r2+1] - pavgb m0, [r1+r4+1] + PAVGB m1, [r1+r2+1] + PAVGB m0, [r1+r4+1] add r0, r4 add r1, r4 - pavgb m2, m1 - pavgb m1, m0 - pavgb m2, [r0] - pavgb m1, [r0+r2] + PAVGB m2, m1 + PAVGB m1, m0 + PAVGB m2, [r0] + PAVGB m1, [r0+r2] mova [r0], m2 mova [r0+r2], m1 add r0, r4 diff --git a/ffmpeg/libavcodec/x86/hpeldsp_avg_template.c b/ffmpeg/libavcodec/x86/hpeldsp_avg_template.c deleted file mode 100644 index b9a8f83..0000000 --- a/ffmpeg/libavcodec/x86/hpeldsp_avg_template.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * DSP utils : average functions are compiled twice for 3dnow/mmxext - * Copyright (c) 2000, 2001 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * MMX optimization by Nick Kurshev - * mostly rewritten by Michael Niedermayer - * and improved by Zdenek Kabelac - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -//FIXME the following could be optimized too ... -static void DEF(ff_put_no_rnd_pixels16_x2)(uint8_t *block, - const uint8_t *pixels, - ptrdiff_t line_size, int h) -{ - DEF(ff_put_no_rnd_pixels8_x2)(block, pixels, line_size, h); - DEF(ff_put_no_rnd_pixels8_x2)(block + 8, pixels + 8, line_size, h); -} - -static void DEF(ff_put_pixels16_y2)(uint8_t *block, const uint8_t *pixels, - ptrdiff_t line_size, int h) -{ - DEF(ff_put_pixels8_y2)(block, pixels, line_size, h); - DEF(ff_put_pixels8_y2)(block + 8, pixels + 8, line_size, h); -} - -static void DEF(ff_put_no_rnd_pixels16_y2)(uint8_t *block, - const uint8_t *pixels, - ptrdiff_t line_size, int h) -{ - DEF(ff_put_no_rnd_pixels8_y2)(block, pixels, line_size, h); - DEF(ff_put_no_rnd_pixels8_y2)(block + 8, pixels + 8, line_size, h); -} - -static void DEF(ff_avg_pixels16)(uint8_t *block, const uint8_t *pixels, - ptrdiff_t line_size, int h) -{ - DEF(ff_avg_pixels8)(block, pixels, line_size, h); - DEF(ff_avg_pixels8)(block + 8, pixels + 8, line_size, h); -} - -static void DEF(ff_avg_pixels16_x2)(uint8_t *block, const uint8_t *pixels, - ptrdiff_t line_size, int h) -{ - DEF(ff_avg_pixels8_x2)(block, pixels, line_size, h); - DEF(ff_avg_pixels8_x2)(block + 8, pixels + 8, line_size, h); -} - -static void DEF(ff_avg_pixels16_y2)(uint8_t *block, const uint8_t *pixels, - ptrdiff_t line_size, int h) -{ - DEF(ff_avg_pixels8_y2)(block, pixels, line_size, h); - DEF(ff_avg_pixels8_y2)(block + 8, pixels + 8, line_size, h); -} - -static void DEF(ff_avg_pixels16_xy2)(uint8_t *block, const uint8_t *pixels, - ptrdiff_t line_size, int h) -{ - DEF(ff_avg_pixels8_xy2)(block, pixels, line_size, h); - DEF(ff_avg_pixels8_xy2)(block + 8, pixels + 8, line_size, h); -} diff --git a/ffmpeg/libavcodec/x86/hpeldsp_init.c b/ffmpeg/libavcodec/x86/hpeldsp_init.c index 4b877b8..8ecf909 100644 --- a/ffmpeg/libavcodec/x86/hpeldsp_init.c +++ b/ffmpeg/libavcodec/x86/hpeldsp_init.c @@ -24,13 +24,10 @@ #include "libavutil/cpu.h" #include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" #include "libavcodec/hpeldsp.h" -#include "dsputil_mmx.h" +#include "dsputil_x86.h" -//#undef NDEBUG -//#include - -#if HAVE_YASM void ff_put_pixels8_x2_mmxext(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h); void ff_put_pixels8_x2_3dnow(uint8_t *block, const uint8_t *pixels, @@ -77,103 +74,45 @@ void ff_avg_pixels8_xy2_mmxext(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h); void ff_avg_pixels8_xy2_3dnow(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h); -#endif /* HAVE_YASM */ +#define avg_pixels8_mmx ff_avg_pixels8_mmx +#define avg_pixels8_x2_mmx ff_avg_pixels8_x2_mmx +#define avg_pixels16_mmx ff_avg_pixels16_mmx +#define avg_pixels8_xy2_mmx ff_avg_pixels8_xy2_mmx +#define avg_pixels16_xy2_mmx ff_avg_pixels16_xy2_mmx +#define put_pixels8_mmx ff_put_pixels8_mmx +#define put_pixels16_mmx ff_put_pixels16_mmx +#define put_pixels8_xy2_mmx ff_put_pixels8_xy2_mmx +#define put_pixels16_xy2_mmx ff_put_pixels16_xy2_mmx +#define avg_no_rnd_pixels16_mmx ff_avg_pixels16_mmx +#define put_no_rnd_pixels8_mmx ff_put_pixels8_mmx +#define put_no_rnd_pixels16_mmx ff_put_pixels16_mmx #if HAVE_INLINE_ASM -#define JUMPALIGN() __asm__ volatile (".p2align 3"::) -#define MOVQ_ZERO(regd) __asm__ volatile ("pxor %%"#regd", %%"#regd ::) - -#define MOVQ_BFE(regd) \ - __asm__ volatile ( \ - "pcmpeqd %%"#regd", %%"#regd" \n\t" \ - "paddb %%"#regd", %%"#regd" \n\t" ::) - -#ifndef PIC -#define MOVQ_BONE(regd) __asm__ volatile ("movq %0, %%"#regd" \n\t" :: "m"(ff_bone)) -#define MOVQ_WTWO(regd) __asm__ volatile ("movq %0, %%"#regd" \n\t" :: "m"(ff_wtwo)) -#else -// for shared library it's better to use this way for accessing constants -// pcmpeqd -> -1 -#define MOVQ_BONE(regd) \ - __asm__ volatile ( \ - "pcmpeqd %%"#regd", %%"#regd" \n\t" \ - "psrlw $15, %%"#regd" \n\t" \ - "packuswb %%"#regd", %%"#regd" \n\t" ::) - -#define MOVQ_WTWO(regd) \ - __asm__ volatile ( \ - "pcmpeqd %%"#regd", %%"#regd" \n\t" \ - "psrlw $15, %%"#regd" \n\t" \ - "psllw $1, %%"#regd" \n\t"::) - -#endif - -// using regr as temporary and for the output result -// first argument is unmodifed and second is trashed -// regfe is supposed to contain 0xfefefefefefefefe -#define PAVGB_MMX_NO_RND(rega, regb, regr, regfe) \ - "movq "#rega", "#regr" \n\t" \ - "pand "#regb", "#regr" \n\t" \ - "pxor "#rega", "#regb" \n\t" \ - "pand "#regfe", "#regb" \n\t" \ - "psrlq $1, "#regb" \n\t" \ - "paddb "#regb", "#regr" \n\t" - -#define PAVGB_MMX(rega, regb, regr, regfe) \ - "movq "#rega", "#regr" \n\t" \ - "por "#regb", "#regr" \n\t" \ - "pxor "#rega", "#regb" \n\t" \ - "pand "#regfe", "#regb" \n\t" \ - "psrlq $1, "#regb" \n\t" \ - "psubb "#regb", "#regr" \n\t" - -// mm6 is supposed to contain 0xfefefefefefefefe -#define PAVGBP_MMX_NO_RND(rega, regb, regr, regc, regd, regp) \ - "movq "#rega", "#regr" \n\t" \ - "movq "#regc", "#regp" \n\t" \ - "pand "#regb", "#regr" \n\t" \ - "pand "#regd", "#regp" \n\t" \ - "pxor "#rega", "#regb" \n\t" \ - "pxor "#regc", "#regd" \n\t" \ - "pand %%mm6, "#regb" \n\t" \ - "pand %%mm6, "#regd" \n\t" \ - "psrlq $1, "#regb" \n\t" \ - "psrlq $1, "#regd" \n\t" \ - "paddb "#regb", "#regr" \n\t" \ - "paddb "#regd", "#regp" \n\t" - -#define PAVGBP_MMX(rega, regb, regr, regc, regd, regp) \ - "movq "#rega", "#regr" \n\t" \ - "movq "#regc", "#regp" \n\t" \ - "por "#regb", "#regr" \n\t" \ - "por "#regd", "#regp" \n\t" \ - "pxor "#rega", "#regb" \n\t" \ - "pxor "#regc", "#regd" \n\t" \ - "pand %%mm6, "#regb" \n\t" \ - "pand %%mm6, "#regd" \n\t" \ - "psrlq $1, "#regd" \n\t" \ - "psrlq $1, "#regb" \n\t" \ - "psubb "#regb", "#regr" \n\t" \ - "psubb "#regd", "#regp" \n\t" - /***********************************/ /* MMX no rounding */ -#define NO_RND 1 #define DEF(x, y) x ## _no_rnd_ ## y ## _mmx #define SET_RND MOVQ_WONE #define PAVGBP(a, b, c, d, e, f) PAVGBP_MMX_NO_RND(a, b, c, d, e, f) #define PAVGB(a, b, c, e) PAVGB_MMX_NO_RND(a, b, c, e) -#define OP_AVG(a, b, c, e) PAVGB_MMX(a, b, c, e) +#define STATIC static +#include "rnd_template.c" #include "hpeldsp_rnd_template.c" #undef DEF #undef SET_RND #undef PAVGBP #undef PAVGB -#undef NO_RND +#undef STATIC + +PIXELS16(static, avg_no_rnd, , _y2, _mmx) +PIXELS16(static, put_no_rnd, , _y2, _mmx) + +PIXELS16(static, avg_no_rnd, , _xy2, _mmx) +PIXELS16(static, put_no_rnd, , _xy2, _mmx) + /***********************************/ /* MMX rounding */ @@ -188,112 +127,29 @@ void ff_avg_pixels8_xy2_3dnow(uint8_t *block, const uint8_t *pixels, #undef SET_RND #undef PAVGBP #undef PAVGB -#undef OP_AVG + +PIXELS16(static, avg, , _y2, _mmx) +PIXELS16(static, put, , _y2, _mmx) #endif /* HAVE_INLINE_ASM */ #if HAVE_YASM -#define ff_put_pixels8_mmx ff_put_pixels8_mmxext - -/***********************************/ -/* 3Dnow specific */ -#define DEF(x) x ## _3dnow +#define HPELDSP_AVG_PIXELS16(CPUEXT) \ + PIXELS16(static, put_no_rnd, ff_, _x2, CPUEXT) \ + PIXELS16(static, put, ff_, _y2, CPUEXT) \ + PIXELS16(static, put_no_rnd, ff_, _y2, CPUEXT) \ + PIXELS16(static, avg, ff_, , CPUEXT) \ + PIXELS16(static, avg, ff_, _x2, CPUEXT) \ + PIXELS16(static, avg, ff_, _y2, CPUEXT) \ + PIXELS16(static, avg, ff_, _xy2, CPUEXT) -#include "hpeldsp_avg_template.c" - -#undef DEF - -/***********************************/ -/* MMXEXT specific */ - -#define DEF(x) x ## _mmxext - -#include "hpeldsp_avg_template.c" - -#undef DEF +HPELDSP_AVG_PIXELS16(_3dnow) +HPELDSP_AVG_PIXELS16(_mmxext) #endif /* HAVE_YASM */ - -#if HAVE_INLINE_ASM -#define put_no_rnd_pixels16_mmx put_pixels16_mmx -#define put_no_rnd_pixels8_mmx put_pixels8_mmx -#define put_pixels16_mmxext put_pixels16_mmx -#define put_pixels8_mmxext put_pixels8_mmx -#define put_pixels4_mmxext put_pixels4_mmx -#define put_no_rnd_pixels16_mmxext put_no_rnd_pixels16_mmx -#define put_no_rnd_pixels8_mmxext put_no_rnd_pixels8_mmx - -static void put_pixels8_mmx(uint8_t *block, const uint8_t *pixels, - ptrdiff_t line_size, int h) -{ - __asm__ volatile ( - "lea (%3, %3), %%"REG_a" \n\t" - ".p2align 3 \n\t" - "1: \n\t" - "movq (%1 ), %%mm0 \n\t" - "movq (%1, %3), %%mm1 \n\t" - "movq %%mm0, (%2) \n\t" - "movq %%mm1, (%2, %3) \n\t" - "add %%"REG_a", %1 \n\t" - "add %%"REG_a", %2 \n\t" - "movq (%1 ), %%mm0 \n\t" - "movq (%1, %3), %%mm1 \n\t" - "movq %%mm0, (%2) \n\t" - "movq %%mm1, (%2, %3) \n\t" - "add %%"REG_a", %1 \n\t" - "add %%"REG_a", %2 \n\t" - "subl $4, %0 \n\t" - "jnz 1b \n\t" - : "+g"(h), "+r"(pixels), "+r"(block) - : "r"((x86_reg)line_size) - : "%"REG_a, "memory" - ); -} - -static void put_pixels16_mmx(uint8_t *block, const uint8_t *pixels, - ptrdiff_t line_size, int h) -{ - __asm__ volatile ( - "lea (%3, %3), %%"REG_a" \n\t" - ".p2align 3 \n\t" - "1: \n\t" - "movq (%1 ), %%mm0 \n\t" - "movq 8(%1 ), %%mm4 \n\t" - "movq (%1, %3), %%mm1 \n\t" - "movq 8(%1, %3), %%mm5 \n\t" - "movq %%mm0, (%2) \n\t" - "movq %%mm4, 8(%2) \n\t" - "movq %%mm1, (%2, %3) \n\t" - "movq %%mm5, 8(%2, %3) \n\t" - "add %%"REG_a", %1 \n\t" - "add %%"REG_a", %2 \n\t" - "movq (%1 ), %%mm0 \n\t" - "movq 8(%1 ), %%mm4 \n\t" - "movq (%1, %3), %%mm1 \n\t" - "movq 8(%1, %3), %%mm5 \n\t" - "movq %%mm0, (%2) \n\t" - "movq %%mm4, 8(%2) \n\t" - "movq %%mm1, (%2, %3) \n\t" - "movq %%mm5, 8(%2, %3) \n\t" - "add %%"REG_a", %1 \n\t" - "add %%"REG_a", %2 \n\t" - "subl $4, %0 \n\t" - "jnz 1b \n\t" - : "+g"(h), "+r"(pixels), "+r"(block) - : "r"((x86_reg)line_size) - : "%"REG_a, "memory" - ); -} -#endif /* HAVE_INLINE_ASM */ - -void ff_put_pixels16_sse2(uint8_t *block, const uint8_t *pixels, - ptrdiff_t line_size, int h); -void ff_avg_pixels16_sse2(uint8_t *block, const uint8_t *pixels, - ptrdiff_t line_size, int h); - #define SET_HPEL_FUNCS(PFX, IDX, SIZE, CPU) \ do { \ c->PFX ## _pixels_tab IDX [0] = PFX ## _pixels ## SIZE ## _ ## CPU; \ @@ -302,9 +158,9 @@ void ff_avg_pixels16_sse2(uint8_t *block, const uint8_t *pixels, c->PFX ## _pixels_tab IDX [3] = PFX ## _pixels ## SIZE ## _xy2_ ## CPU; \ } while (0) -static void hpeldsp_init_mmx(HpelDSPContext *c, int flags, int mm_flags) +static void hpeldsp_init_mmx(HpelDSPContext *c, int flags, int cpu_flags) { -#if HAVE_INLINE_ASM +#if HAVE_MMX_INLINE SET_HPEL_FUNCS(put, [0], 16, mmx); SET_HPEL_FUNCS(put_no_rnd, [0], 16, mmx); SET_HPEL_FUNCS(avg, [0], 16, mmx); @@ -312,18 +168,18 @@ static void hpeldsp_init_mmx(HpelDSPContext *c, int flags, int mm_flags) SET_HPEL_FUNCS(put, [1], 8, mmx); SET_HPEL_FUNCS(put_no_rnd, [1], 8, mmx); SET_HPEL_FUNCS(avg, [1], 8, mmx); -#endif /* HAVE_INLINE_ASM */ +#endif /* HAVE_MMX_INLINE */ } -static void hpeldsp_init_mmxext(HpelDSPContext *c, int flags, int mm_flags) +static void hpeldsp_init_mmxext(HpelDSPContext *c, int flags, int cpu_flags) { -#if HAVE_YASM +#if HAVE_MMXEXT_EXTERNAL c->put_pixels_tab[0][1] = ff_put_pixels16_x2_mmxext; - c->put_pixels_tab[0][2] = ff_put_pixels16_y2_mmxext; + c->put_pixels_tab[0][2] = put_pixels16_y2_mmxext; - c->avg_pixels_tab[0][0] = ff_avg_pixels16_mmxext; - c->avg_pixels_tab[0][1] = ff_avg_pixels16_x2_mmxext; - c->avg_pixels_tab[0][2] = ff_avg_pixels16_y2_mmxext; + c->avg_pixels_tab[0][0] = avg_pixels16_mmxext; + c->avg_pixels_tab[0][1] = avg_pixels16_x2_mmxext; + c->avg_pixels_tab[0][2] = avg_pixels16_y2_mmxext; c->put_pixels_tab[1][1] = ff_put_pixels8_x2_mmxext; c->put_pixels_tab[1][2] = ff_put_pixels8_y2_mmxext; @@ -333,17 +189,15 @@ static void hpeldsp_init_mmxext(HpelDSPContext *c, int flags, int mm_flags) c->avg_pixels_tab[1][2] = ff_avg_pixels8_y2_mmxext; if (!(flags & CODEC_FLAG_BITEXACT)) { - c->put_no_rnd_pixels_tab[0][1] = ff_put_no_rnd_pixels16_x2_mmxext; - c->put_no_rnd_pixels_tab[0][2] = ff_put_no_rnd_pixels16_y2_mmxext; + c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x2_mmxext; + c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y2_mmxext; c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_mmxext; c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_mmxext; - c->avg_pixels_tab[0][3] = ff_avg_pixels16_xy2_mmxext; + c->avg_pixels_tab[0][3] = avg_pixels16_xy2_mmxext; c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_mmxext; } -#endif /* HAVE_YASM */ -#if HAVE_MMXEXT_EXTERNAL if (flags & CODEC_FLAG_BITEXACT && CONFIG_VP3_DECODER) { c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_exact_mmxext; c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_exact_mmxext; @@ -351,15 +205,15 @@ static void hpeldsp_init_mmxext(HpelDSPContext *c, int flags, int mm_flags) #endif /* HAVE_MMXEXT_EXTERNAL */ } -static void hpeldsp_init_3dnow(HpelDSPContext *c, int flags, int mm_flags) +static void hpeldsp_init_3dnow(HpelDSPContext *c, int flags, int cpu_flags) { -#if HAVE_YASM +#if HAVE_AMD3DNOW_EXTERNAL c->put_pixels_tab[0][1] = ff_put_pixels16_x2_3dnow; - c->put_pixels_tab[0][2] = ff_put_pixels16_y2_3dnow; + c->put_pixels_tab[0][2] = put_pixels16_y2_3dnow; - c->avg_pixels_tab[0][0] = ff_avg_pixels16_3dnow; - c->avg_pixels_tab[0][1] = ff_avg_pixels16_x2_3dnow; - c->avg_pixels_tab[0][2] = ff_avg_pixels16_y2_3dnow; + c->avg_pixels_tab[0][0] = avg_pixels16_3dnow; + c->avg_pixels_tab[0][1] = avg_pixels16_x2_3dnow; + c->avg_pixels_tab[0][2] = avg_pixels16_y2_3dnow; c->put_pixels_tab[1][1] = ff_put_pixels8_x2_3dnow; c->put_pixels_tab[1][2] = ff_put_pixels8_y2_3dnow; @@ -369,12 +223,12 @@ static void hpeldsp_init_3dnow(HpelDSPContext *c, int flags, int mm_flags) c->avg_pixels_tab[1][2] = ff_avg_pixels8_y2_3dnow; if (!(flags & CODEC_FLAG_BITEXACT)){ - c->put_no_rnd_pixels_tab[0][1] = ff_put_no_rnd_pixels16_x2_3dnow; - c->put_no_rnd_pixels_tab[0][2] = ff_put_no_rnd_pixels16_y2_3dnow; + c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x2_3dnow; + c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y2_3dnow; c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_3dnow; c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_3dnow; - c->avg_pixels_tab[0][3] = ff_avg_pixels16_xy2_3dnow; + c->avg_pixels_tab[0][3] = avg_pixels16_xy2_3dnow; c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_3dnow; } @@ -382,13 +236,13 @@ static void hpeldsp_init_3dnow(HpelDSPContext *c, int flags, int mm_flags) c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_exact_3dnow; c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_exact_3dnow; } -#endif /* HAVE_YASM */ +#endif /* HAVE_AMD3DNOW_EXTERNAL */ } -static void hpeldsp_init_sse2(HpelDSPContext *c, int flags, int mm_flags) +static void hpeldsp_init_sse2(HpelDSPContext *c, int flags, int cpu_flags) { #if HAVE_SSE2_EXTERNAL - if (!(mm_flags & AV_CPU_FLAG_SSE2SLOW)) { + if (!(cpu_flags & AV_CPU_FLAG_SSE2SLOW)) { // these functions are slower than mmx on AMD, but faster on Intel c->put_pixels_tab[0][0] = ff_put_pixels16_sse2; c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_sse2; @@ -399,17 +253,17 @@ static void hpeldsp_init_sse2(HpelDSPContext *c, int flags, int mm_flags) void ff_hpeldsp_init_x86(HpelDSPContext *c, int flags) { - int mm_flags = av_get_cpu_flags(); + int cpu_flags = av_get_cpu_flags(); - if (mm_flags & AV_CPU_FLAG_MMX) - hpeldsp_init_mmx(c, flags, mm_flags); + if (INLINE_MMX(cpu_flags)) + hpeldsp_init_mmx(c, flags, cpu_flags); - if (mm_flags & AV_CPU_FLAG_MMXEXT) - hpeldsp_init_mmxext(c, flags, mm_flags); + if (EXTERNAL_AMD3DNOW(cpu_flags)) + hpeldsp_init_3dnow(c, flags, cpu_flags); - if (mm_flags & AV_CPU_FLAG_3DNOW) - hpeldsp_init_3dnow(c, flags, mm_flags); + if (EXTERNAL_MMXEXT(cpu_flags)) + hpeldsp_init_mmxext(c, flags, cpu_flags); - if (mm_flags & AV_CPU_FLAG_SSE2) - hpeldsp_init_sse2(c, flags, mm_flags); + if (EXTERNAL_SSE2(cpu_flags)) + hpeldsp_init_sse2(c, flags, cpu_flags); } diff --git a/ffmpeg/libavcodec/x86/hpeldsp_rnd_template.c b/ffmpeg/libavcodec/x86/hpeldsp_rnd_template.c index 07de675..94e06d8 100644 --- a/ffmpeg/libavcodec/x86/hpeldsp_rnd_template.c +++ b/ffmpeg/libavcodec/x86/hpeldsp_rnd_template.c @@ -132,140 +132,6 @@ static void DEF(put, pixels8_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_ :REG_a, "memory"); } -static void DEF(put, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) -{ - MOVQ_ZERO(mm7); - SET_RND(mm6); // =2 for rnd and =1 for no_rnd version - __asm__ volatile( - "movq (%1), %%mm0 \n\t" - "movq 1(%1), %%mm4 \n\t" - "movq %%mm0, %%mm1 \n\t" - "movq %%mm4, %%mm5 \n\t" - "punpcklbw %%mm7, %%mm0 \n\t" - "punpcklbw %%mm7, %%mm4 \n\t" - "punpckhbw %%mm7, %%mm1 \n\t" - "punpckhbw %%mm7, %%mm5 \n\t" - "paddusw %%mm0, %%mm4 \n\t" - "paddusw %%mm1, %%mm5 \n\t" - "xor %%"REG_a", %%"REG_a" \n\t" - "add %3, %1 \n\t" - ".p2align 3 \n\t" - "1: \n\t" - "movq (%1, %%"REG_a"), %%mm0 \n\t" - "movq 1(%1, %%"REG_a"), %%mm2 \n\t" - "movq %%mm0, %%mm1 \n\t" - "movq %%mm2, %%mm3 \n\t" - "punpcklbw %%mm7, %%mm0 \n\t" - "punpcklbw %%mm7, %%mm2 \n\t" - "punpckhbw %%mm7, %%mm1 \n\t" - "punpckhbw %%mm7, %%mm3 \n\t" - "paddusw %%mm2, %%mm0 \n\t" - "paddusw %%mm3, %%mm1 \n\t" - "paddusw %%mm6, %%mm4 \n\t" - "paddusw %%mm6, %%mm5 \n\t" - "paddusw %%mm0, %%mm4 \n\t" - "paddusw %%mm1, %%mm5 \n\t" - "psrlw $2, %%mm4 \n\t" - "psrlw $2, %%mm5 \n\t" - "packuswb %%mm5, %%mm4 \n\t" - "movq %%mm4, (%2, %%"REG_a") \n\t" - "add %3, %%"REG_a" \n\t" - - "movq (%1, %%"REG_a"), %%mm2 \n\t" // 0 <-> 2 1 <-> 3 - "movq 1(%1, %%"REG_a"), %%mm4 \n\t" - "movq %%mm2, %%mm3 \n\t" - "movq %%mm4, %%mm5 \n\t" - "punpcklbw %%mm7, %%mm2 \n\t" - "punpcklbw %%mm7, %%mm4 \n\t" - "punpckhbw %%mm7, %%mm3 \n\t" - "punpckhbw %%mm7, %%mm5 \n\t" - "paddusw %%mm2, %%mm4 \n\t" - "paddusw %%mm3, %%mm5 \n\t" - "paddusw %%mm6, %%mm0 \n\t" - "paddusw %%mm6, %%mm1 \n\t" - "paddusw %%mm4, %%mm0 \n\t" - "paddusw %%mm5, %%mm1 \n\t" - "psrlw $2, %%mm0 \n\t" - "psrlw $2, %%mm1 \n\t" - "packuswb %%mm1, %%mm0 \n\t" - "movq %%mm0, (%2, %%"REG_a") \n\t" - "add %3, %%"REG_a" \n\t" - - "subl $2, %0 \n\t" - "jnz 1b \n\t" - :"+g"(h), "+S"(pixels) - :"D"(block), "r"((x86_reg)line_size) - :REG_a, "memory"); -} - -// avg_pixels -#ifndef NO_RND -// in case more speed is needed - unroling would certainly help -static void DEF(avg, pixels8)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) -{ - MOVQ_BFE(mm6); - JUMPALIGN(); - do { - __asm__ volatile( - "movq %0, %%mm0 \n\t" - "movq %1, %%mm1 \n\t" - OP_AVG(%%mm0, %%mm1, %%mm2, %%mm6) - "movq %%mm2, %0 \n\t" - :"+m"(*block) - :"m"(*pixels) - :"memory"); - pixels += line_size; - block += line_size; - } - while (--h); -} -#endif // NO_RND - -static void DEF(avg, pixels16)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) -{ - MOVQ_BFE(mm6); - JUMPALIGN(); - do { - __asm__ volatile( - "movq %0, %%mm0 \n\t" - "movq %1, %%mm1 \n\t" - OP_AVG(%%mm0, %%mm1, %%mm2, %%mm6) - "movq %%mm2, %0 \n\t" - "movq 8%0, %%mm0 \n\t" - "movq 8%1, %%mm1 \n\t" - OP_AVG(%%mm0, %%mm1, %%mm2, %%mm6) - "movq %%mm2, 8%0 \n\t" - :"+m"(*block) - :"m"(*pixels) - :"memory"); - pixels += line_size; - block += line_size; - } - while (--h); -} - -#ifndef NO_RND -static void DEF(avg, pixels8_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) -{ - MOVQ_BFE(mm6); - JUMPALIGN(); - do { - __asm__ volatile( - "movq %1, %%mm0 \n\t" - "movq 1%1, %%mm1 \n\t" - "movq %0, %%mm3 \n\t" - PAVGB(%%mm0, %%mm1, %%mm2, %%mm6) - OP_AVG(%%mm3, %%mm2, %%mm0, %%mm6) - "movq %%mm0, %0 \n\t" - :"+m"(*block) - :"m"(*pixels) - :"memory"); - pixels += line_size; - block += line_size; - } while (--h); -} -#endif // NO_RND - static void DEF(avg, pixels16_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) { MOVQ_BFE(mm6); @@ -276,13 +142,13 @@ static void DEF(avg, pixels16_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff "movq 1%1, %%mm1 \n\t" "movq %0, %%mm3 \n\t" PAVGB(%%mm0, %%mm1, %%mm2, %%mm6) - OP_AVG(%%mm3, %%mm2, %%mm0, %%mm6) + PAVGB_MMX(%%mm3, %%mm2, %%mm0, %%mm6) "movq %%mm0, %0 \n\t" "movq 8%1, %%mm0 \n\t" "movq 9%1, %%mm1 \n\t" "movq 8%0, %%mm3 \n\t" PAVGB(%%mm0, %%mm1, %%mm2, %%mm6) - OP_AVG(%%mm3, %%mm2, %%mm0, %%mm6) + PAVGB_MMX(%%mm3, %%mm2, %%mm0, %%mm6) "movq %%mm0, 8%0 \n\t" :"+m"(*block) :"m"(*pixels) @@ -304,9 +170,9 @@ static void DEF(avg, pixels8_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_ "movq (%1, %%"REG_a"), %%mm2 \n\t" PAVGBP(%%mm1, %%mm0, %%mm4, %%mm2, %%mm1, %%mm5) "movq (%2), %%mm3 \n\t" - OP_AVG(%%mm3, %%mm4, %%mm0, %%mm6) + PAVGB_MMX(%%mm3, %%mm4, %%mm0, %%mm6) "movq (%2, %3), %%mm3 \n\t" - OP_AVG(%%mm3, %%mm5, %%mm1, %%mm6) + PAVGB_MMX(%%mm3, %%mm5, %%mm1, %%mm6) "movq %%mm0, (%2) \n\t" "movq %%mm1, (%2, %3) \n\t" "add %%"REG_a", %1 \n\t" @@ -316,9 +182,9 @@ static void DEF(avg, pixels8_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_ "movq (%1, %%"REG_a"), %%mm0 \n\t" PAVGBP(%%mm1, %%mm2, %%mm4, %%mm0, %%mm1, %%mm5) "movq (%2), %%mm3 \n\t" - OP_AVG(%%mm3, %%mm4, %%mm2, %%mm6) + PAVGB_MMX(%%mm3, %%mm4, %%mm2, %%mm6) "movq (%2, %3), %%mm3 \n\t" - OP_AVG(%%mm3, %%mm5, %%mm1, %%mm6) + PAVGB_MMX(%%mm3, %%mm5, %%mm1, %%mm6) "movq %%mm2, (%2) \n\t" "movq %%mm1, (%2, %3) \n\t" "add %%"REG_a", %1 \n\t" @@ -330,99 +196,3 @@ static void DEF(avg, pixels8_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_ :"r"((x86_reg)line_size) :REG_a, "memory"); } - -// this routine is 'slightly' suboptimal but mostly unused -static void DEF(avg, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) -{ - MOVQ_ZERO(mm7); - SET_RND(mm6); // =2 for rnd and =1 for no_rnd version - __asm__ volatile( - "movq (%1), %%mm0 \n\t" - "movq 1(%1), %%mm4 \n\t" - "movq %%mm0, %%mm1 \n\t" - "movq %%mm4, %%mm5 \n\t" - "punpcklbw %%mm7, %%mm0 \n\t" - "punpcklbw %%mm7, %%mm4 \n\t" - "punpckhbw %%mm7, %%mm1 \n\t" - "punpckhbw %%mm7, %%mm5 \n\t" - "paddusw %%mm0, %%mm4 \n\t" - "paddusw %%mm1, %%mm5 \n\t" - "xor %%"REG_a", %%"REG_a" \n\t" - "add %3, %1 \n\t" - ".p2align 3 \n\t" - "1: \n\t" - "movq (%1, %%"REG_a"), %%mm0 \n\t" - "movq 1(%1, %%"REG_a"), %%mm2 \n\t" - "movq %%mm0, %%mm1 \n\t" - "movq %%mm2, %%mm3 \n\t" - "punpcklbw %%mm7, %%mm0 \n\t" - "punpcklbw %%mm7, %%mm2 \n\t" - "punpckhbw %%mm7, %%mm1 \n\t" - "punpckhbw %%mm7, %%mm3 \n\t" - "paddusw %%mm2, %%mm0 \n\t" - "paddusw %%mm3, %%mm1 \n\t" - "paddusw %%mm6, %%mm4 \n\t" - "paddusw %%mm6, %%mm5 \n\t" - "paddusw %%mm0, %%mm4 \n\t" - "paddusw %%mm1, %%mm5 \n\t" - "psrlw $2, %%mm4 \n\t" - "psrlw $2, %%mm5 \n\t" - "movq (%2, %%"REG_a"), %%mm3 \n\t" - "packuswb %%mm5, %%mm4 \n\t" - "pcmpeqd %%mm2, %%mm2 \n\t" - "paddb %%mm2, %%mm2 \n\t" - OP_AVG(%%mm3, %%mm4, %%mm5, %%mm2) - "movq %%mm5, (%2, %%"REG_a") \n\t" - "add %3, %%"REG_a" \n\t" - - "movq (%1, %%"REG_a"), %%mm2 \n\t" // 0 <-> 2 1 <-> 3 - "movq 1(%1, %%"REG_a"), %%mm4 \n\t" - "movq %%mm2, %%mm3 \n\t" - "movq %%mm4, %%mm5 \n\t" - "punpcklbw %%mm7, %%mm2 \n\t" - "punpcklbw %%mm7, %%mm4 \n\t" - "punpckhbw %%mm7, %%mm3 \n\t" - "punpckhbw %%mm7, %%mm5 \n\t" - "paddusw %%mm2, %%mm4 \n\t" - "paddusw %%mm3, %%mm5 \n\t" - "paddusw %%mm6, %%mm0 \n\t" - "paddusw %%mm6, %%mm1 \n\t" - "paddusw %%mm4, %%mm0 \n\t" - "paddusw %%mm5, %%mm1 \n\t" - "psrlw $2, %%mm0 \n\t" - "psrlw $2, %%mm1 \n\t" - "movq (%2, %%"REG_a"), %%mm3 \n\t" - "packuswb %%mm1, %%mm0 \n\t" - "pcmpeqd %%mm2, %%mm2 \n\t" - "paddb %%mm2, %%mm2 \n\t" - OP_AVG(%%mm3, %%mm0, %%mm1, %%mm2) - "movq %%mm1, (%2, %%"REG_a") \n\t" - "add %3, %%"REG_a" \n\t" - - "subl $2, %0 \n\t" - "jnz 1b \n\t" - :"+g"(h), "+S"(pixels) - :"D"(block), "r"((x86_reg)line_size) - :REG_a, "memory"); -} - -//FIXME optimize -static void DEF(put, pixels16_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){ - DEF(put, pixels8_y2)(block , pixels , line_size, h); - DEF(put, pixels8_y2)(block+8, pixels+8, line_size, h); -} - -static void DEF(put, pixels16_xy2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){ - DEF(put, pixels8_xy2)(block , pixels , line_size, h); - DEF(put, pixels8_xy2)(block+8, pixels+8, line_size, h); -} - -static void DEF(avg, pixels16_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){ - DEF(avg, pixels8_y2)(block , pixels , line_size, h); - DEF(avg, pixels8_y2)(block+8, pixels+8, line_size, h); -} - -static void DEF(avg, pixels16_xy2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){ - DEF(avg, pixels8_xy2)(block , pixels , line_size, h); - DEF(avg, pixels8_xy2)(block+8, pixels+8, line_size, h); -} diff --git a/ffmpeg/libavcodec/x86/idct_mmx_xvid.c b/ffmpeg/libavcodec/x86/idct_mmx_xvid.c index 5e9f405..4cd6de1 100644 --- a/ffmpeg/libavcodec/x86/idct_mmx_xvid.c +++ b/ffmpeg/libavcodec/x86/idct_mmx_xvid.c @@ -44,10 +44,10 @@ #include "config.h" #include "libavcodec/avcodec.h" #include "libavutil/mem.h" -#include "dsputil_mmx.h" +#include "dsputil_x86.h" #include "idct_xvid.h" -#if HAVE_INLINE_ASM +#if HAVE_MMX_INLINE //============================================================================= // Macros and other preprocessor constants @@ -507,6 +507,22 @@ __asm__ volatile( :: "r"(block), "r"(rounder_0), "r"(tab_i_04_mmx), "r"(tg_1_16)); } +void ff_idct_xvid_mmx_put(uint8_t *dest, int line_size, int16_t *block) +{ + ff_idct_xvid_mmx(block); + ff_put_pixels_clamped_mmx(block, dest, line_size); +} + +void ff_idct_xvid_mmx_add(uint8_t *dest, int line_size, int16_t *block) +{ + ff_idct_xvid_mmx(block); + ff_add_pixels_clamped_mmx(block, dest, line_size); +} + +#endif /* HAVE_MMX_INLINE */ + +#if HAVE_MMXEXT_INLINE + //----------------------------------------------------------------------------- // void idct_xmm(uint16_t block[64]); //----------------------------------------------------------------------------- @@ -531,18 +547,6 @@ __asm__ volatile( :: "r"(block), "r"(rounder_0), "r"(tab_i_04_xmm), "r"(tg_1_16)); } -void ff_idct_xvid_mmx_put(uint8_t *dest, int line_size, int16_t *block) -{ - ff_idct_xvid_mmx(block); - ff_put_pixels_clamped_mmx(block, dest, line_size); -} - -void ff_idct_xvid_mmx_add(uint8_t *dest, int line_size, int16_t *block) -{ - ff_idct_xvid_mmx(block); - ff_add_pixels_clamped_mmx(block, dest, line_size); -} - void ff_idct_xvid_mmxext_put(uint8_t *dest, int line_size, int16_t *block) { ff_idct_xvid_mmxext(block); @@ -555,4 +559,4 @@ void ff_idct_xvid_mmxext_add(uint8_t *dest, int line_size, int16_t *block) ff_add_pixels_clamped_mmx(block, dest, line_size); } -#endif /* HAVE_INLINE_ASM */ +#endif /* HAVE_MMXEXT_INLINE */ diff --git a/ffmpeg/libavcodec/x86/idct_sse2_xvid.c b/ffmpeg/libavcodec/x86/idct_sse2_xvid.c index b51466c..af4790c 100644 --- a/ffmpeg/libavcodec/x86/idct_sse2_xvid.c +++ b/ffmpeg/libavcodec/x86/idct_sse2_xvid.c @@ -41,9 +41,9 @@ #include "libavutil/mem.h" #include "libavutil/x86/asm.h" #include "idct_xvid.h" -#include "dsputil_mmx.h" +#include "dsputil_x86.h" -#if HAVE_INLINE_ASM +#if HAVE_SSE2_INLINE /** * @file @@ -404,4 +404,4 @@ void ff_idct_xvid_sse2_add(uint8_t *dest, int line_size, short *block) ff_add_pixels_clamped_mmx(block, dest, line_size); } -#endif /* HAVE_INLINE_ASM */ +#endif /* HAVE_SSE2_INLINE */ diff --git a/ffmpeg/libavcodec/x86/lpc.c b/ffmpeg/libavcodec/x86/lpc.c index 1962212..8a74755 100644 --- a/ffmpeg/libavcodec/x86/lpc.c +++ b/ffmpeg/libavcodec/x86/lpc.c @@ -19,11 +19,16 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "libavutil/x86/asm.h" #include "libavutil/attributes.h" #include "libavutil/cpu.h" +#include "libavutil/mem.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" #include "libavcodec/lpc.h" +DECLARE_ASM_CONST(16, double, pd_1)[2] = { 1.0, 1.0 }; +DECLARE_ASM_CONST(16, double, pd_2)[2] = { 2.0, 2.0 }; + #if HAVE_SSE2_INLINE static void lpc_apply_welch_window_sse2(const int32_t *data, int len, @@ -35,8 +40,8 @@ static void lpc_apply_welch_window_sse2(const int32_t *data, int len, x86_reg j = n2*sizeof(int32_t); __asm__ volatile( "movsd %4, %%xmm7 \n\t" - "movapd "MANGLE(ff_pd_1)", %%xmm6 \n\t" - "movapd "MANGLE(ff_pd_2)", %%xmm5 \n\t" + "movapd "MANGLE(pd_1)", %%xmm6 \n\t" + "movapd "MANGLE(pd_2)", %%xmm5 \n\t" "movlhps %%xmm7, %%xmm7 \n\t" "subpd %%xmm5, %%xmm7 \n\t" "addsd %%xmm6, %%xmm7 \n\t" @@ -85,9 +90,9 @@ static void lpc_compute_autocorr_sse2(const double *data, int len, int lag, x86_reg i = -len*sizeof(double); if(j == lag-2) { __asm__ volatile( - "movsd "MANGLE(ff_pd_1)", %%xmm0 \n\t" - "movsd "MANGLE(ff_pd_1)", %%xmm1 \n\t" - "movsd "MANGLE(ff_pd_1)", %%xmm2 \n\t" + "movsd "MANGLE(pd_1)", %%xmm0 \n\t" + "movsd "MANGLE(pd_1)", %%xmm1 \n\t" + "movsd "MANGLE(pd_1)", %%xmm2 \n\t" "1: \n\t" "movapd (%2,%0), %%xmm3 \n\t" "movupd -8(%3,%0), %%xmm4 \n\t" @@ -115,8 +120,8 @@ static void lpc_compute_autocorr_sse2(const double *data, int len, int lag, ); } else { __asm__ volatile( - "movsd "MANGLE(ff_pd_1)", %%xmm0 \n\t" - "movsd "MANGLE(ff_pd_1)", %%xmm1 \n\t" + "movsd "MANGLE(pd_1)", %%xmm0 \n\t" + "movsd "MANGLE(pd_1)", %%xmm1 \n\t" "1: \n\t" "movapd (%3,%0), %%xmm3 \n\t" "movupd -8(%4,%0), %%xmm4 \n\t" @@ -144,9 +149,9 @@ static void lpc_compute_autocorr_sse2(const double *data, int len, int lag, av_cold void ff_lpc_init_x86(LPCContext *c) { #if HAVE_SSE2_INLINE - int mm_flags = av_get_cpu_flags(); + int cpu_flags = av_get_cpu_flags(); - if (mm_flags & (AV_CPU_FLAG_SSE2|AV_CPU_FLAG_SSE2SLOW)) { + if (HAVE_SSE2_INLINE && cpu_flags & (AV_CPU_FLAG_SSE2 | AV_CPU_FLAG_SSE2SLOW)) { c->lpc_apply_welch_window = lpc_apply_welch_window_sse2; c->lpc_compute_autocorr = lpc_compute_autocorr_sse2; } diff --git a/ffmpeg/libavcodec/x86/mathops.h b/ffmpeg/libavcodec/x86/mathops.h index 79e29e6..9c48afe 100644 --- a/ffmpeg/libavcodec/x86/mathops.h +++ b/ffmpeg/libavcodec/x86/mathops.h @@ -68,13 +68,13 @@ static av_always_inline av_const int64_t MUL64(int a, int b) #endif /* ARCH_X86_32 */ -#if HAVE_CMOV +#if HAVE_I686 /* median of 3 */ #define mid_pred mid_pred static inline av_const int mid_pred(int a, int b, int c) { int i=b; - __asm__ volatile( + __asm__ ( "cmp %2, %1 \n\t" "cmovg %1, %0 \n\t" "cmovg %2, %1 \n\t" @@ -87,9 +87,7 @@ static inline av_const int mid_pred(int a, int b, int c) ); return i; } -#endif -#if HAVE_CMOV #define COPY3_IF_LT(x, y, a, b, c, d)\ __asm__ volatile(\ "cmpl %0, %3 \n\t"\ @@ -99,7 +97,7 @@ __asm__ volatile(\ : "+&r" (x), "+&r" (a), "+r" (c)\ : "r" (y), "r" (b), "r" (d)\ ); -#endif +#endif /* HAVE_I686 */ #define MASK_ABS(mask, level) \ __asm__ ("cltd \n\t" \ diff --git a/ffmpeg/libavcodec/x86/mlpdsp.c b/ffmpeg/libavcodec/x86/mlpdsp.c index 81cab5a..94849b7 100644 --- a/ffmpeg/libavcodec/x86/mlpdsp.c +++ b/ffmpeg/libavcodec/x86/mlpdsp.c @@ -20,7 +20,9 @@ */ #include "libavutil/attributes.h" +#include "libavutil/cpu.h" #include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" #include "libavcodec/mlpdsp.h" #include "libavcodec/mlp.h" @@ -177,6 +179,8 @@ static void mlp_filter_channel_x86(int32_t *state, const int32_t *coeff, av_cold void ff_mlpdsp_init_x86(MLPDSPContext *c) { #if HAVE_7REGS && HAVE_INLINE_ASM - c->mlp_filter_channel = mlp_filter_channel_x86; + int cpu_flags = av_get_cpu_flags(); + if (INLINE_MMX(cpu_flags)) + c->mlp_filter_channel = mlp_filter_channel_x86; #endif } diff --git a/ffmpeg/libavcodec/x86/motion_est.c b/ffmpeg/libavcodec/x86/motion_est.c index 3ffb002..5f5d93e 100644 --- a/ffmpeg/libavcodec/x86/motion_est.c +++ b/ffmpeg/libavcodec/x86/motion_est.c @@ -26,7 +26,8 @@ #include "libavutil/avassert.h" #include "libavutil/mem.h" #include "libavutil/x86/asm.h" -#include "dsputil_mmx.h" +#include "libavutil/x86/cpu.h" +#include "dsputil_x86.h" #if HAVE_INLINE_ASM @@ -435,9 +436,9 @@ PIX_SAD(mmxext) av_cold void ff_dsputil_init_pix_mmx(DSPContext *c, AVCodecContext *avctx) { #if HAVE_INLINE_ASM - int mm_flags = av_get_cpu_flags(); + int cpu_flags = av_get_cpu_flags(); - if (mm_flags & AV_CPU_FLAG_MMX) { + if (INLINE_MMX(cpu_flags)) { c->pix_abs[0][0] = sad16_mmx; c->pix_abs[0][1] = sad16_x2_mmx; c->pix_abs[0][2] = sad16_y2_mmx; @@ -450,7 +451,7 @@ av_cold void ff_dsputil_init_pix_mmx(DSPContext *c, AVCodecContext *avctx) c->sad[0]= sad16_mmx; c->sad[1]= sad8_mmx; } - if (mm_flags & AV_CPU_FLAG_MMXEXT) { + if (INLINE_MMXEXT(cpu_flags)) { c->pix_abs[0][0] = sad16_mmxext; c->pix_abs[1][0] = sad8_mmxext; @@ -466,7 +467,7 @@ av_cold void ff_dsputil_init_pix_mmx(DSPContext *c, AVCodecContext *avctx) c->pix_abs[1][3] = sad8_xy2_mmxext; } } - if ((mm_flags & AV_CPU_FLAG_SSE2) && !(mm_flags & AV_CPU_FLAG_3DNOW) && avctx->codec_id != AV_CODEC_ID_SNOW) { + if (INLINE_SSE2(cpu_flags) && !(cpu_flags & AV_CPU_FLAG_3DNOW) && avctx->codec_id != AV_CODEC_ID_SNOW) { c->sad[0]= sad16_sse2; } #endif /* HAVE_INLINE_ASM */ diff --git a/ffmpeg/libavcodec/x86/mpegaudiodec.c b/ffmpeg/libavcodec/x86/mpegaudiodec.c deleted file mode 100644 index 287d8ff..0000000 --- a/ffmpeg/libavcodec/x86/mpegaudiodec.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * MMX optimized MP3 decoding functions - * Copyright (c) 2010 Vitor Sessak - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/attributes.h" -#include "libavutil/cpu.h" -#include "libavutil/internal.h" -#include "libavutil/x86/asm.h" -#include "libavutil/x86/cpu.h" -#include "libavcodec/mpegaudiodsp.h" - -#define DECL(CPU)\ -static void imdct36_blocks_ ## CPU(float *out, float *buf, float *in, int count, int switch_point, int block_type);\ -void ff_imdct36_float_ ## CPU(float *out, float *buf, float *in, float *win); - -DECL(sse) -DECL(sse2) -DECL(sse3) -DECL(ssse3) -DECL(avx) - -void ff_four_imdct36_float_sse(float *out, float *buf, float *in, float *win, - float *tmpbuf); -void ff_four_imdct36_float_avx(float *out, float *buf, float *in, float *win, - float *tmpbuf); - -DECLARE_ALIGNED(16, static float, mdct_win_sse)[2][4][4*40]; - -#if HAVE_SSE2_INLINE - -#define MACS(rt, ra, rb) rt+=(ra)*(rb) -#define MLSS(rt, ra, rb) rt-=(ra)*(rb) - -#define SUM8(op, sum, w, p) \ -{ \ - op(sum, (w)[0 * 64], (p)[0 * 64]); \ - op(sum, (w)[1 * 64], (p)[1 * 64]); \ - op(sum, (w)[2 * 64], (p)[2 * 64]); \ - op(sum, (w)[3 * 64], (p)[3 * 64]); \ - op(sum, (w)[4 * 64], (p)[4 * 64]); \ - op(sum, (w)[5 * 64], (p)[5 * 64]); \ - op(sum, (w)[6 * 64], (p)[6 * 64]); \ - op(sum, (w)[7 * 64], (p)[7 * 64]); \ -} - -static void apply_window(const float *buf, const float *win1, - const float *win2, float *sum1, float *sum2, int len) -{ - x86_reg count = - 4*len; - const float *win1a = win1+len; - const float *win2a = win2+len; - const float *bufa = buf+len; - float *sum1a = sum1+len; - float *sum2a = sum2+len; - - -#define MULT(a, b) \ - "movaps " #a "(%1,%0), %%xmm1 \n\t" \ - "movaps " #a "(%3,%0), %%xmm2 \n\t" \ - "mulps %%xmm2, %%xmm1 \n\t" \ - "subps %%xmm1, %%xmm0 \n\t" \ - "mulps " #b "(%2,%0), %%xmm2 \n\t" \ - "subps %%xmm2, %%xmm4 \n\t" \ - - __asm__ volatile( - "1: \n\t" - "xorps %%xmm0, %%xmm0 \n\t" - "xorps %%xmm4, %%xmm4 \n\t" - - MULT( 0, 0) - MULT( 256, 64) - MULT( 512, 128) - MULT( 768, 192) - MULT(1024, 256) - MULT(1280, 320) - MULT(1536, 384) - MULT(1792, 448) - - "movaps %%xmm0, (%4,%0) \n\t" - "movaps %%xmm4, (%5,%0) \n\t" - "add $16, %0 \n\t" - "jl 1b \n\t" - :"+&r"(count) - :"r"(win1a), "r"(win2a), "r"(bufa), "r"(sum1a), "r"(sum2a) - ); - -#undef MULT -} - -static void apply_window_mp3(float *in, float *win, int *unused, float *out, - int incr) -{ - LOCAL_ALIGNED_16(float, suma, [17]); - LOCAL_ALIGNED_16(float, sumb, [17]); - LOCAL_ALIGNED_16(float, sumc, [17]); - LOCAL_ALIGNED_16(float, sumd, [17]); - - float sum; - - /* copy to avoid wrap */ - __asm__ volatile( - "movaps 0(%0), %%xmm0 \n\t" \ - "movaps 16(%0), %%xmm1 \n\t" \ - "movaps 32(%0), %%xmm2 \n\t" \ - "movaps 48(%0), %%xmm3 \n\t" \ - "movaps %%xmm0, 0(%1) \n\t" \ - "movaps %%xmm1, 16(%1) \n\t" \ - "movaps %%xmm2, 32(%1) \n\t" \ - "movaps %%xmm3, 48(%1) \n\t" \ - "movaps 64(%0), %%xmm0 \n\t" \ - "movaps 80(%0), %%xmm1 \n\t" \ - "movaps 96(%0), %%xmm2 \n\t" \ - "movaps 112(%0), %%xmm3 \n\t" \ - "movaps %%xmm0, 64(%1) \n\t" \ - "movaps %%xmm1, 80(%1) \n\t" \ - "movaps %%xmm2, 96(%1) \n\t" \ - "movaps %%xmm3, 112(%1) \n\t" - ::"r"(in), "r"(in+512) - :"memory" - ); - - apply_window(in + 16, win , win + 512, suma, sumc, 16); - apply_window(in + 32, win + 48, win + 640, sumb, sumd, 16); - - SUM8(MACS, suma[0], win + 32, in + 48); - - sumc[ 0] = 0; - sumb[16] = 0; - sumd[16] = 0; - -#define SUMS(suma, sumb, sumc, sumd, out1, out2) \ - "movups " #sumd "(%4), %%xmm0 \n\t" \ - "shufps $0x1b, %%xmm0, %%xmm0 \n\t" \ - "subps " #suma "(%1), %%xmm0 \n\t" \ - "movaps %%xmm0," #out1 "(%0) \n\t" \ -\ - "movups " #sumc "(%3), %%xmm0 \n\t" \ - "shufps $0x1b, %%xmm0, %%xmm0 \n\t" \ - "addps " #sumb "(%2), %%xmm0 \n\t" \ - "movaps %%xmm0," #out2 "(%0) \n\t" - - if (incr == 1) { - __asm__ volatile( - SUMS( 0, 48, 4, 52, 0, 112) - SUMS(16, 32, 20, 36, 16, 96) - SUMS(32, 16, 36, 20, 32, 80) - SUMS(48, 0, 52, 4, 48, 64) - - :"+&r"(out) - :"r"(&suma[0]), "r"(&sumb[0]), "r"(&sumc[0]), "r"(&sumd[0]) - :"memory" - ); - out += 16*incr; - } else { - int j; - float *out2 = out + 32 * incr; - out[0 ] = -suma[ 0]; - out += incr; - out2 -= incr; - for(j=1;j<16;j++) { - *out = -suma[ j] + sumd[16-j]; - *out2 = sumb[16-j] + sumc[ j]; - out += incr; - out2 -= incr; - } - } - - sum = 0; - SUM8(MLSS, sum, win + 16 + 32, in + 32); - *out = sum; -} - -#endif /* HAVE_SSE2_INLINE */ - -#if HAVE_YASM -#define DECL_IMDCT_BLOCKS(CPU1, CPU2) \ -static void imdct36_blocks_ ## CPU1(float *out, float *buf, float *in, \ - int count, int switch_point, int block_type) \ -{ \ - int align_end = count - (count & 3); \ - int j; \ - for (j = 0; j < align_end; j+= 4) { \ - LOCAL_ALIGNED_16(float, tmpbuf, [1024]); \ - float *win = mdct_win_sse[switch_point && j < 4][block_type]; \ - /* apply window & overlap with previous buffer */ \ - \ - /* select window */ \ - ff_four_imdct36_float_ ## CPU2(out, buf, in, win, tmpbuf); \ - in += 4*18; \ - buf += 4*18; \ - out += 4; \ - } \ - for (; j < count; j++) { \ - /* apply window & overlap with previous buffer */ \ - \ - /* select window */ \ - int win_idx = (switch_point && j < 2) ? 0 : block_type; \ - float *win = ff_mdct_win_float[win_idx + (4 & -(j & 1))]; \ - \ - ff_imdct36_float_ ## CPU1(out, buf, in, win); \ - \ - in += 18; \ - buf++; \ - out++; \ - } \ -} - -#if HAVE_SSE -DECL_IMDCT_BLOCKS(sse,sse) -DECL_IMDCT_BLOCKS(sse2,sse) -DECL_IMDCT_BLOCKS(sse3,sse) -DECL_IMDCT_BLOCKS(ssse3,sse) -#endif -#if HAVE_AVX_EXTERNAL -DECL_IMDCT_BLOCKS(avx,avx) -#endif -#endif /* HAVE_YASM */ - -av_cold void ff_mpadsp_init_x86(MPADSPContext *s) -{ - int mm_flags = av_get_cpu_flags(); - - int i, j; - for (j = 0; j < 4; j++) { - for (i = 0; i < 40; i ++) { - mdct_win_sse[0][j][4*i ] = ff_mdct_win_float[j ][i]; - mdct_win_sse[0][j][4*i + 1] = ff_mdct_win_float[j + 4][i]; - mdct_win_sse[0][j][4*i + 2] = ff_mdct_win_float[j ][i]; - mdct_win_sse[0][j][4*i + 3] = ff_mdct_win_float[j + 4][i]; - mdct_win_sse[1][j][4*i ] = ff_mdct_win_float[0 ][i]; - mdct_win_sse[1][j][4*i + 1] = ff_mdct_win_float[4 ][i]; - mdct_win_sse[1][j][4*i + 2] = ff_mdct_win_float[j ][i]; - mdct_win_sse[1][j][4*i + 3] = ff_mdct_win_float[j + 4][i]; - } - } - -#if HAVE_SSE2_INLINE - if (mm_flags & AV_CPU_FLAG_SSE2) { - s->apply_window_float = apply_window_mp3; - } -#endif /* HAVE_SSE2_INLINE */ - -#if HAVE_YASM - if (EXTERNAL_AVX(mm_flags)) { - s->imdct36_blocks_float = imdct36_blocks_avx; - } else if (EXTERNAL_SSSE3(mm_flags)) { - s->imdct36_blocks_float = imdct36_blocks_ssse3; - } else if (EXTERNAL_SSE3(mm_flags)) { - s->imdct36_blocks_float = imdct36_blocks_sse3; - } else if (EXTERNAL_SSE2(mm_flags)) { - s->imdct36_blocks_float = imdct36_blocks_sse2; - } else if (EXTERNAL_SSE(mm_flags)) { - s->imdct36_blocks_float = imdct36_blocks_sse; - } -#endif /* HAVE_YASM */ -} diff --git a/ffmpeg/libavcodec/x86/mpegvideo.c b/ffmpeg/libavcodec/x86/mpegvideo.c index 903ad62..b2ce680 100644 --- a/ffmpeg/libavcodec/x86/mpegvideo.c +++ b/ffmpeg/libavcodec/x86/mpegvideo.c @@ -22,11 +22,12 @@ #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" #include "libavcodec/avcodec.h" #include "libavcodec/mpegvideo.h" -#include "dsputil_mmx.h" +#include "dsputil_x86.h" -#if HAVE_INLINE_ASM +#if HAVE_MMX_INLINE static void dct_unquantize_h263_intra_mmx(MpegEncContext *s, int16_t *block, int n, int qscale) @@ -111,7 +112,7 @@ static void dct_unquantize_h263_inter_mmx(MpegEncContext *s, qmul = qscale << 1; qadd = (qscale - 1) | 1; - assert(s->block_last_index[n]>=0 || s->h263_aic); + av_assert2(s->block_last_index[n]>=0 || s->h263_aic); nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ]; @@ -164,28 +165,6 @@ __asm__ volatile( ); } - -/* - We can suppose that result of two multiplications can't be greater than 0xFFFF - i.e. is 16-bit, so we use here only PMULLW instruction and can avoid - a complex multiplication. -===================================================== - Full formula for multiplication of 2 integer numbers - which are represent as high:low words: - input: value1 = high1:low1 - value2 = high2:low2 - output: value3 = value1*value2 - value3=high3:low3 (on overflow: modulus 2^32 wrap-around) - this mean that for 0x123456 * 0x123456 correct result is 0x766cb0ce4 - but this algorithm will compute only 0x66cb0ce4 - this limited by 16-bit size of operands - --------------------------------- - tlow1 = high1*low2 - tlow2 = high2*low1 - tlow1 = tlow1 + tlow2 - high3:low3 = low1*low2 - high3 += tlow1 -*/ static void dct_unquantize_mpeg1_intra_mmx(MpegEncContext *s, int16_t *block, int n, int qscale) { @@ -464,124 +443,14 @@ __asm__ volatile( ); } -static void denoise_dct_mmx(MpegEncContext *s, int16_t *block){ - const int intra= s->mb_intra; - int *sum= s->dct_error_sum[intra]; - uint16_t *offset= s->dct_offset[intra]; - - s->dct_count[intra]++; - - __asm__ volatile( - "pxor %%mm7, %%mm7 \n\t" - "1: \n\t" - "pxor %%mm0, %%mm0 \n\t" - "pxor %%mm1, %%mm1 \n\t" - "movq (%0), %%mm2 \n\t" - "movq 8(%0), %%mm3 \n\t" - "pcmpgtw %%mm2, %%mm0 \n\t" - "pcmpgtw %%mm3, %%mm1 \n\t" - "pxor %%mm0, %%mm2 \n\t" - "pxor %%mm1, %%mm3 \n\t" - "psubw %%mm0, %%mm2 \n\t" - "psubw %%mm1, %%mm3 \n\t" - "movq %%mm2, %%mm4 \n\t" - "movq %%mm3, %%mm5 \n\t" - "psubusw (%2), %%mm2 \n\t" - "psubusw 8(%2), %%mm3 \n\t" - "pxor %%mm0, %%mm2 \n\t" - "pxor %%mm1, %%mm3 \n\t" - "psubw %%mm0, %%mm2 \n\t" - "psubw %%mm1, %%mm3 \n\t" - "movq %%mm2, (%0) \n\t" - "movq %%mm3, 8(%0) \n\t" - "movq %%mm4, %%mm2 \n\t" - "movq %%mm5, %%mm3 \n\t" - "punpcklwd %%mm7, %%mm4 \n\t" - "punpckhwd %%mm7, %%mm2 \n\t" - "punpcklwd %%mm7, %%mm5 \n\t" - "punpckhwd %%mm7, %%mm3 \n\t" - "paddd (%1), %%mm4 \n\t" - "paddd 8(%1), %%mm2 \n\t" - "paddd 16(%1), %%mm5 \n\t" - "paddd 24(%1), %%mm3 \n\t" - "movq %%mm4, (%1) \n\t" - "movq %%mm2, 8(%1) \n\t" - "movq %%mm5, 16(%1) \n\t" - "movq %%mm3, 24(%1) \n\t" - "add $16, %0 \n\t" - "add $32, %1 \n\t" - "add $16, %2 \n\t" - "cmp %3, %0 \n\t" - " jb 1b \n\t" - : "+r" (block), "+r" (sum), "+r" (offset) - : "r"(block+64) - ); -} - -static void denoise_dct_sse2(MpegEncContext *s, int16_t *block){ - const int intra= s->mb_intra; - int *sum= s->dct_error_sum[intra]; - uint16_t *offset= s->dct_offset[intra]; - - s->dct_count[intra]++; - - __asm__ volatile( - "pxor %%xmm7, %%xmm7 \n\t" - "1: \n\t" - "pxor %%xmm0, %%xmm0 \n\t" - "pxor %%xmm1, %%xmm1 \n\t" - "movdqa (%0), %%xmm2 \n\t" - "movdqa 16(%0), %%xmm3 \n\t" - "pcmpgtw %%xmm2, %%xmm0 \n\t" - "pcmpgtw %%xmm3, %%xmm1 \n\t" - "pxor %%xmm0, %%xmm2 \n\t" - "pxor %%xmm1, %%xmm3 \n\t" - "psubw %%xmm0, %%xmm2 \n\t" - "psubw %%xmm1, %%xmm3 \n\t" - "movdqa %%xmm2, %%xmm4 \n\t" - "movdqa %%xmm3, %%xmm5 \n\t" - "psubusw (%2), %%xmm2 \n\t" - "psubusw 16(%2), %%xmm3 \n\t" - "pxor %%xmm0, %%xmm2 \n\t" - "pxor %%xmm1, %%xmm3 \n\t" - "psubw %%xmm0, %%xmm2 \n\t" - "psubw %%xmm1, %%xmm3 \n\t" - "movdqa %%xmm2, (%0) \n\t" - "movdqa %%xmm3, 16(%0) \n\t" - "movdqa %%xmm4, %%xmm6 \n\t" - "movdqa %%xmm5, %%xmm0 \n\t" - "punpcklwd %%xmm7, %%xmm4 \n\t" - "punpckhwd %%xmm7, %%xmm6 \n\t" - "punpcklwd %%xmm7, %%xmm5 \n\t" - "punpckhwd %%xmm7, %%xmm0 \n\t" - "paddd (%1), %%xmm4 \n\t" - "paddd 16(%1), %%xmm6 \n\t" - "paddd 32(%1), %%xmm5 \n\t" - "paddd 48(%1), %%xmm0 \n\t" - "movdqa %%xmm4, (%1) \n\t" - "movdqa %%xmm6, 16(%1) \n\t" - "movdqa %%xmm5, 32(%1) \n\t" - "movdqa %%xmm0, 48(%1) \n\t" - "add $32, %0 \n\t" - "add $64, %1 \n\t" - "add $32, %2 \n\t" - "cmp %3, %0 \n\t" - " jb 1b \n\t" - : "+r" (block), "+r" (sum), "+r" (offset) - : "r"(block+64) - XMM_CLOBBERS_ONLY("%xmm0", "%xmm1", "%xmm2", "%xmm3", - "%xmm4", "%xmm5", "%xmm6", "%xmm7") - ); -} - -#endif /* HAVE_INLINE_ASM */ +#endif /* HAVE_MMX_INLINE */ av_cold void ff_MPV_common_init_x86(MpegEncContext *s) { -#if HAVE_INLINE_ASM - int mm_flags = av_get_cpu_flags(); +#if HAVE_MMX_INLINE + int cpu_flags = av_get_cpu_flags(); - if (mm_flags & AV_CPU_FLAG_MMX) { + if (INLINE_MMX(cpu_flags)) { s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_mmx; s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_mmx; s->dct_unquantize_mpeg1_intra = dct_unquantize_mpeg1_intra_mmx; @@ -589,12 +458,6 @@ av_cold void ff_MPV_common_init_x86(MpegEncContext *s) if(!(s->flags & CODEC_FLAG_BITEXACT)) s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_mmx; s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_mmx; - - if (mm_flags & AV_CPU_FLAG_SSE2) { - s->denoise_dct= denoise_dct_sse2; - } else { - s->denoise_dct= denoise_dct_mmx; - } } -#endif /* HAVE_INLINE_ASM */ +#endif /* HAVE_MMX_INLINE */ } diff --git a/ffmpeg/libavcodec/x86/mpegvideoenc.c b/ffmpeg/libavcodec/x86/mpegvideoenc.c index 6219667..7dd9959 100644 --- a/ffmpeg/libavcodec/x86/mpegvideoenc.c +++ b/ffmpeg/libavcodec/x86/mpegvideoenc.c @@ -26,9 +26,10 @@ #include "libavcodec/avcodec.h" #include "libavcodec/dct.h" #include "libavcodec/mpegvideo.h" -#include "dsputil_mmx.h" +#include "dsputil_x86.h" -extern uint16_t ff_inv_zigzag_direct16[64]; +/* not permutated inverse zigzag_direct + 1 for MMX quantizer */ +DECLARE_ALIGNED(16, static uint16_t, inv_zigzag_direct16)[64]; #if HAVE_MMX_INLINE #define COMPILE_TEMPLATE_MMXEXT 0 @@ -81,26 +82,146 @@ extern uint16_t ff_inv_zigzag_direct16[64]; #include "mpegvideoenc_template.c" #endif /* HAVE_SSSE3_INLINE */ +#if HAVE_INLINE_ASM +static void denoise_dct_mmx(MpegEncContext *s, int16_t *block){ + const int intra= s->mb_intra; + int *sum= s->dct_error_sum[intra]; + uint16_t *offset= s->dct_offset[intra]; + + s->dct_count[intra]++; + + __asm__ volatile( + "pxor %%mm7, %%mm7 \n\t" + "1: \n\t" + "pxor %%mm0, %%mm0 \n\t" + "pxor %%mm1, %%mm1 \n\t" + "movq (%0), %%mm2 \n\t" + "movq 8(%0), %%mm3 \n\t" + "pcmpgtw %%mm2, %%mm0 \n\t" + "pcmpgtw %%mm3, %%mm1 \n\t" + "pxor %%mm0, %%mm2 \n\t" + "pxor %%mm1, %%mm3 \n\t" + "psubw %%mm0, %%mm2 \n\t" + "psubw %%mm1, %%mm3 \n\t" + "movq %%mm2, %%mm4 \n\t" + "movq %%mm3, %%mm5 \n\t" + "psubusw (%2), %%mm2 \n\t" + "psubusw 8(%2), %%mm3 \n\t" + "pxor %%mm0, %%mm2 \n\t" + "pxor %%mm1, %%mm3 \n\t" + "psubw %%mm0, %%mm2 \n\t" + "psubw %%mm1, %%mm3 \n\t" + "movq %%mm2, (%0) \n\t" + "movq %%mm3, 8(%0) \n\t" + "movq %%mm4, %%mm2 \n\t" + "movq %%mm5, %%mm3 \n\t" + "punpcklwd %%mm7, %%mm4 \n\t" + "punpckhwd %%mm7, %%mm2 \n\t" + "punpcklwd %%mm7, %%mm5 \n\t" + "punpckhwd %%mm7, %%mm3 \n\t" + "paddd (%1), %%mm4 \n\t" + "paddd 8(%1), %%mm2 \n\t" + "paddd 16(%1), %%mm5 \n\t" + "paddd 24(%1), %%mm3 \n\t" + "movq %%mm4, (%1) \n\t" + "movq %%mm2, 8(%1) \n\t" + "movq %%mm5, 16(%1) \n\t" + "movq %%mm3, 24(%1) \n\t" + "add $16, %0 \n\t" + "add $32, %1 \n\t" + "add $16, %2 \n\t" + "cmp %3, %0 \n\t" + " jb 1b \n\t" + : "+r" (block), "+r" (sum), "+r" (offset) + : "r"(block+64) + ); +} + +static void denoise_dct_sse2(MpegEncContext *s, int16_t *block){ + const int intra= s->mb_intra; + int *sum= s->dct_error_sum[intra]; + uint16_t *offset= s->dct_offset[intra]; + + s->dct_count[intra]++; + + __asm__ volatile( + "pxor %%xmm7, %%xmm7 \n\t" + "1: \n\t" + "pxor %%xmm0, %%xmm0 \n\t" + "pxor %%xmm1, %%xmm1 \n\t" + "movdqa (%0), %%xmm2 \n\t" + "movdqa 16(%0), %%xmm3 \n\t" + "pcmpgtw %%xmm2, %%xmm0 \n\t" + "pcmpgtw %%xmm3, %%xmm1 \n\t" + "pxor %%xmm0, %%xmm2 \n\t" + "pxor %%xmm1, %%xmm3 \n\t" + "psubw %%xmm0, %%xmm2 \n\t" + "psubw %%xmm1, %%xmm3 \n\t" + "movdqa %%xmm2, %%xmm4 \n\t" + "movdqa %%xmm3, %%xmm5 \n\t" + "psubusw (%2), %%xmm2 \n\t" + "psubusw 16(%2), %%xmm3 \n\t" + "pxor %%xmm0, %%xmm2 \n\t" + "pxor %%xmm1, %%xmm3 \n\t" + "psubw %%xmm0, %%xmm2 \n\t" + "psubw %%xmm1, %%xmm3 \n\t" + "movdqa %%xmm2, (%0) \n\t" + "movdqa %%xmm3, 16(%0) \n\t" + "movdqa %%xmm4, %%xmm6 \n\t" + "movdqa %%xmm5, %%xmm0 \n\t" + "punpcklwd %%xmm7, %%xmm4 \n\t" + "punpckhwd %%xmm7, %%xmm6 \n\t" + "punpcklwd %%xmm7, %%xmm5 \n\t" + "punpckhwd %%xmm7, %%xmm0 \n\t" + "paddd (%1), %%xmm4 \n\t" + "paddd 16(%1), %%xmm6 \n\t" + "paddd 32(%1), %%xmm5 \n\t" + "paddd 48(%1), %%xmm0 \n\t" + "movdqa %%xmm4, (%1) \n\t" + "movdqa %%xmm6, 16(%1) \n\t" + "movdqa %%xmm5, 32(%1) \n\t" + "movdqa %%xmm0, 48(%1) \n\t" + "add $32, %0 \n\t" + "add $64, %1 \n\t" + "add $32, %2 \n\t" + "cmp %3, %0 \n\t" + " jb 1b \n\t" + : "+r" (block), "+r" (sum), "+r" (offset) + : "r"(block+64) + XMM_CLOBBERS_ONLY("%xmm0", "%xmm1", "%xmm2", "%xmm3", + "%xmm4", "%xmm5", "%xmm6", "%xmm7") + ); +} +#endif /* HAVE_INLINE_ASM */ + av_cold void ff_dct_encode_init_x86(MpegEncContext *s) { - int mm_flags = av_get_cpu_flags(); const int dct_algo = s->avctx->dct_algo; + int i; + + for (i = 0; i < 64; i++) + inv_zigzag_direct16[ff_zigzag_direct[i]] = i + 1; if (dct_algo == FF_DCT_AUTO || dct_algo == FF_DCT_MMX) { #if HAVE_MMX_INLINE - if (INLINE_MMX(mm_flags)) + int cpu_flags = av_get_cpu_flags(); + if (INLINE_MMX(cpu_flags)) { s->dct_quantize = dct_quantize_MMX; + s->denoise_dct = denoise_dct_mmx; + } #endif #if HAVE_MMXEXT_INLINE - if (INLINE_MMXEXT(mm_flags)) + if (INLINE_MMXEXT(cpu_flags)) s->dct_quantize = dct_quantize_MMXEXT; #endif #if HAVE_SSE2_INLINE - if (INLINE_SSE2(mm_flags)) + if (INLINE_SSE2(cpu_flags)) { s->dct_quantize = dct_quantize_SSE2; + s->denoise_dct = denoise_dct_sse2; + } #endif #if HAVE_SSSE3_INLINE - if (INLINE_SSSE3(mm_flags)) + if (INLINE_SSSE3(cpu_flags)) s->dct_quantize = dct_quantize_SSSE3; #endif } diff --git a/ffmpeg/libavcodec/x86/mpegvideoenc_template.c b/ffmpeg/libavcodec/x86/mpegvideoenc_template.c index 1e0505e..0defc40 100644 --- a/ffmpeg/libavcodec/x86/mpegvideoenc_template.c +++ b/ffmpeg/libavcodec/x86/mpegvideoenc_template.c @@ -171,7 +171,7 @@ static int RENAME(dct_quantize)(MpegEncContext *s, "movzb %%al, %%"REG_a" \n\t" // last_non_zero_p1 : "+a" (last_non_zero_p1) : "r" (block+64), "r" (qmat), "r" (bias), - "r" (ff_inv_zigzag_direct16+64), "r" (temp_block+64) + "r" (inv_zigzag_direct16 + 64), "r" (temp_block + 64) XMM_CLOBBERS_ONLY("%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7") ); @@ -205,7 +205,7 @@ static int RENAME(dct_quantize)(MpegEncContext *s, "movzb %%al, %%"REG_a" \n\t" // last_non_zero_p1 : "+a" (last_non_zero_p1) : "r" (block+64), "r" (qmat+64), "r" (bias+64), - "r" (ff_inv_zigzag_direct16+64), "r" (temp_block+64) + "r" (inv_zigzag_direct16 + 64), "r" (temp_block + 64) XMM_CLOBBERS_ONLY("%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7") ); diff --git a/ffmpeg/libavcodec/x86/pngdsp.asm b/ffmpeg/libavcodec/x86/pngdsp.asm index c05f3da..8e23ccf 100644 --- a/ffmpeg/libavcodec/x86/pngdsp.asm +++ b/ffmpeg/libavcodec/x86/pngdsp.asm @@ -4,20 +4,20 @@ ;* Copyright (c) 2008 Loren Merritt ;* Copyright (c) 2012 Ronald S. Bultje ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* FFmpeg is free software; you can redistribute it and/or ;* modify it under the terms of the GNU Lesser General Public ;* License as published by the Free Software Foundation; either ;* version 2.1 of the License, or (at your option) any later version. ;* -;* Libav is distributed in the hope that it will be useful, +;* FFmpeg is distributed in the hope that it will be useful, ;* but WITHOUT ANY WARRANTY; without even the implied warranty of ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;* Lesser General Public License for more details. ;* ;* You should have received a copy of the GNU Lesser General Public -;* License along with Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** diff --git a/ffmpeg/libavcodec/x86/pngdsp_init.c b/ffmpeg/libavcodec/x86/pngdsp_init.c index 4c54ed3..7dca62c 100644 --- a/ffmpeg/libavcodec/x86/pngdsp_init.c +++ b/ffmpeg/libavcodec/x86/pngdsp_init.c @@ -35,16 +35,16 @@ void ff_add_bytes_l2_sse2(uint8_t *dst, uint8_t *src1, av_cold void ff_pngdsp_init_x86(PNGDSPContext *dsp) { - int flags = av_get_cpu_flags(); + int cpu_flags = av_get_cpu_flags(); #if ARCH_X86_32 - if (EXTERNAL_MMX(flags)) + if (EXTERNAL_MMX(cpu_flags)) dsp->add_bytes_l2 = ff_add_bytes_l2_mmx; #endif - if (EXTERNAL_MMXEXT(flags)) + if (EXTERNAL_MMXEXT(cpu_flags)) dsp->add_paeth_prediction = ff_add_png_paeth_prediction_mmxext; - if (EXTERNAL_SSE2(flags)) + if (EXTERNAL_SSE2(cpu_flags)) dsp->add_bytes_l2 = ff_add_bytes_l2_sse2; - if (EXTERNAL_SSSE3(flags)) + if (EXTERNAL_SSSE3(cpu_flags)) dsp->add_paeth_prediction = ff_add_png_paeth_prediction_ssse3; } diff --git a/ffmpeg/libavcodec/x86/proresdsp_init.c b/ffmpeg/libavcodec/x86/proresdsp_init.c index 91ff257..0273d61 100644 --- a/ffmpeg/libavcodec/x86/proresdsp_init.c +++ b/ffmpeg/libavcodec/x86/proresdsp_init.c @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/attributes.h" #include "libavutil/x86/cpu.h" #include "libavcodec/dsputil.h" #include "libavcodec/proresdsp.h" @@ -31,25 +32,25 @@ void ff_prores_idct_put_10_sse4(uint16_t *dst, int linesize, void ff_prores_idct_put_10_avx (uint16_t *dst, int linesize, int16_t *block, const int16_t *qmat); -void ff_proresdsp_x86_init(ProresDSPContext *dsp, AVCodecContext *avctx) +av_cold void ff_proresdsp_x86_init(ProresDSPContext *dsp, AVCodecContext *avctx) { #if ARCH_X86_64 - int flags = av_get_cpu_flags(); + int cpu_flags = av_get_cpu_flags(); if(avctx->flags & CODEC_FLAG_BITEXACT) return; - if (EXTERNAL_SSE2(flags)) { + if (EXTERNAL_SSE2(cpu_flags)) { dsp->idct_permutation_type = FF_TRANSPOSE_IDCT_PERM; dsp->idct_put = ff_prores_idct_put_10_sse2; } - if (EXTERNAL_SSE4(flags)) { + if (EXTERNAL_SSE4(cpu_flags)) { dsp->idct_permutation_type = FF_TRANSPOSE_IDCT_PERM; dsp->idct_put = ff_prores_idct_put_10_sse4; } - if (EXTERNAL_AVX(flags)) { + if (EXTERNAL_AVX(cpu_flags)) { dsp->idct_permutation_type = FF_TRANSPOSE_IDCT_PERM; dsp->idct_put = ff_prores_idct_put_10_avx; } diff --git a/ffmpeg/libavcodec/x86/qpelbase.asm b/ffmpeg/libavcodec/x86/qpelbase.asm deleted file mode 100644 index c2ffb86..0000000 --- a/ffmpeg/libavcodec/x86/qpelbase.asm +++ /dev/null @@ -1,176 +0,0 @@ -;****************************************************************************** -;* MMX optimized DSP utils -;* Copyright (c) 2008 Loren Merritt -;* Copyright (c) 2003-2013 Michael Niedermayer -;* Copyright (c) 2013 Daniel Kang -;* -;* This file is part of FFmpeg. -;* -;* FFmpeg is free software; you can redistribute it and/or -;* modify it under the terms of the GNU Lesser General Public -;* License as published by the Free Software Foundation; either -;* version 2.1 of the License, or (at your option) any later version. -;* -;* FFmpeg is distributed in the hope that it will be useful, -;* but WITHOUT ANY WARRANTY; without even the implied warranty of -;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;* Lesser General Public License for more details. -;* -;* You should have received a copy of the GNU Lesser General Public -;* License along with FFmpeg; if not, write to the Free Software -;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -;****************************************************************************** - -%include "libavutil/x86/x86util.asm" - -SECTION .text - -%macro op_avgh 3 - movh %3, %2 - pavgb %1, %3 - movh %2, %1 -%endmacro - -%macro op_avg 2 - pavgb %1, %2 - mova %2, %1 -%endmacro - -%macro op_puth 2-3 - movh %2, %1 -%endmacro - -%macro op_put 2 - mova %2, %1 -%endmacro - -; void pixels4_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) -%macro PIXELS4_L2 1 -%define OP op_%1h -cglobal %1_pixels4_l2, 6,6 - movsxdifnidn r3, r3d - movsxdifnidn r4, r4d - test r5d, 1 - je .loop - movd m0, [r1] - movd m1, [r2] - add r1, r4 - add r2, 4 - pavgb m0, m1 - OP m0, [r0], m3 - add r0, r3 - dec r5d -.loop: - mova m0, [r1] - mova m1, [r1+r4] - lea r1, [r1+2*r4] - pavgb m0, [r2] - pavgb m1, [r2+4] - OP m0, [r0], m3 - OP m1, [r0+r3], m3 - lea r0, [r0+2*r3] - mova m0, [r1] - mova m1, [r1+r4] - lea r1, [r1+2*r4] - pavgb m0, [r2+8] - pavgb m1, [r2+12] - OP m0, [r0], m3 - OP m1, [r0+r3], m3 - lea r0, [r0+2*r3] - add r2, 16 - sub r5d, 4 - jne .loop - REP_RET -%endmacro - -INIT_MMX mmxext -PIXELS4_L2 put -PIXELS4_L2 avg - -; void pixels8_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) -%macro PIXELS8_L2 1 -%define OP op_%1 -cglobal %1_pixels8_l2, 6,6 - movsxdifnidn r3, r3d - movsxdifnidn r4, r4d - test r5d, 1 - je .loop - mova m0, [r1] - mova m1, [r2] - add r1, r4 - add r2, 8 - pavgb m0, m1 - OP m0, [r0] - add r0, r3 - dec r5d -.loop: - mova m0, [r1] - mova m1, [r1+r4] - lea r1, [r1+2*r4] - pavgb m0, [r2] - pavgb m1, [r2+8] - OP m0, [r0] - OP m1, [r0+r3] - lea r0, [r0+2*r3] - mova m0, [r1] - mova m1, [r1+r4] - lea r1, [r1+2*r4] - pavgb m0, [r2+16] - pavgb m1, [r2+24] - OP m0, [r0] - OP m1, [r0+r3] - lea r0, [r0+2*r3] - add r2, 32 - sub r5d, 4 - jne .loop - REP_RET -%endmacro - -INIT_MMX mmxext -PIXELS8_L2 put -PIXELS8_L2 avg - -; void pixels16_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) -%macro PIXELS16_L2 1 -%define OP op_%1 -cglobal %1_pixels16_l2, 6,6 - movsxdifnidn r3, r3d - movsxdifnidn r4, r4d - test r5d, 1 - je .loop - mova m0, [r1] - mova m1, [r1+8] - pavgb m0, [r2] - pavgb m1, [r2+8] - add r1, r4 - add r2, 16 - OP m0, [r0] - OP m1, [r0+8] - add r0, r3 - dec r5d -.loop: - mova m0, [r1] - mova m1, [r1+8] - add r1, r4 - pavgb m0, [r2] - pavgb m1, [r2+8] - OP m0, [r0] - OP m1, [r0+8] - add r0, r3 - mova m0, [r1] - mova m1, [r1+8] - add r1, r4 - pavgb m0, [r2+16] - pavgb m1, [r2+24] - OP m0, [r0] - OP m1, [r0+8] - add r0, r3 - add r2, 32 - sub r5d, 2 - jne .loop - REP_RET -%endmacro - -INIT_MMX mmxext -PIXELS16_L2 put -PIXELS16_L2 avg diff --git a/ffmpeg/libavcodec/x86/rv34dsp.asm b/ffmpeg/libavcodec/x86/rv34dsp.asm index 4d9c35b..7732d65 100644 --- a/ffmpeg/libavcodec/x86/rv34dsp.asm +++ b/ffmpeg/libavcodec/x86/rv34dsp.asm @@ -2,20 +2,20 @@ ;* MMX/SSE2-optimized functions for the RV30 and RV40 decoders ;* Copyright (C) 2012 Christophe Gisquet ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* FFmpeg is free software; you can redistribute it and/or ;* modify it under the terms of the GNU Lesser General Public ;* License as published by the Free Software Foundation; either ;* version 2.1 of the License, or (at your option) any later version. ;* -;* Libav is distributed in the hope that it will be useful, +;* FFmpeg is distributed in the hope that it will be useful, ;* but WITHOUT ANY WARRANTY; without even the implied warranty of ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;* Lesser General Public License for more details. ;* ;* You should have received a copy of the GNU Lesser General Public -;* License along with Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** diff --git a/ffmpeg/libavcodec/x86/rv34dsp_init.c b/ffmpeg/libavcodec/x86/rv34dsp_init.c index a2dea74..027efe9 100644 --- a/ffmpeg/libavcodec/x86/rv34dsp_init.c +++ b/ffmpeg/libavcodec/x86/rv34dsp_init.c @@ -2,20 +2,20 @@ * RV30/40 MMX/SSE2 optimizations * Copyright (C) 2012 Christophe Gisquet * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -32,14 +32,14 @@ void ff_rv34_idct_add_mmxext(uint8_t *dst, ptrdiff_t stride, int16_t *block); av_cold void ff_rv34dsp_init_x86(RV34DSPContext* c) { - int mm_flags = av_get_cpu_flags(); + int cpu_flags = av_get_cpu_flags(); - if (EXTERNAL_MMX(mm_flags)) + if (EXTERNAL_MMX(cpu_flags)) c->rv34_idct_dc_add = ff_rv34_idct_dc_add_mmx; - if (EXTERNAL_MMXEXT(mm_flags)) { + if (EXTERNAL_MMXEXT(cpu_flags)) { c->rv34_inv_transform_dc = ff_rv34_idct_dc_noround_mmxext; c->rv34_idct_add = ff_rv34_idct_add_mmxext; } - if (EXTERNAL_SSE4(mm_flags)) + if (EXTERNAL_SSE4(cpu_flags)) c->rv34_idct_dc_add = ff_rv34_idct_dc_add_sse4; } diff --git a/ffmpeg/libavcodec/x86/rv40dsp.asm b/ffmpeg/libavcodec/x86/rv40dsp.asm index 7ec72be..792a54f 100644 --- a/ffmpeg/libavcodec/x86/rv40dsp.asm +++ b/ffmpeg/libavcodec/x86/rv40dsp.asm @@ -4,20 +4,20 @@ ;* Copyright (c) 2010 Jason Garrett-Glaser ;* Copyright (C) 2012 Christophe Gisquet ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* FFmpeg is free software; you can redistribute it and/or ;* modify it under the terms of the GNU Lesser General Public ;* License as published by the Free Software Foundation; either ;* version 2.1 of the License, or (at your option) any later version. ;* -;* Libav is distributed in the hope that it will be useful, +;* FFmpeg is distributed in the hope that it will be useful, ;* but WITHOUT ANY WARRANTY; without even the implied warranty of ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;* Lesser General Public License for more details. ;* ;* You should have received a copy of the GNU Lesser General Public -;* License along with Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** @@ -98,11 +98,7 @@ SECTION .text %endif packuswb %1, %1 %ifidn %3, avg -%if cpuflag(3dnow) - pavgusb %1, %2 -%else - pavgb %1, %2 -%endif + PAVGB %1, %2 %endif movh [dstq], %1 %endmacro diff --git a/ffmpeg/libavcodec/x86/rv40dsp_init.c b/ffmpeg/libavcodec/x86/rv40dsp_init.c index 2f97518..75ba8ba 100644 --- a/ffmpeg/libavcodec/x86/rv40dsp_init.c +++ b/ffmpeg/libavcodec/x86/rv40dsp_init.c @@ -30,7 +30,7 @@ #include "libavutil/attributes.h" #include "libavutil/mem.h" #include "libavutil/x86/cpu.h" -#include "dsputil_mmx.h" +#include "dsputil_x86.h" #if HAVE_YASM void ff_put_rv40_chroma_mc8_mmx (uint8_t *dst, uint8_t *src, @@ -188,25 +188,58 @@ QPEL_FUNCS_SET (OP, 3, 2, OPT) #endif /* HAVE_YASM */ +#if HAVE_MMX_INLINE +static void put_rv40_qpel8_mc33_mmx(uint8_t *dst, uint8_t *src, + ptrdiff_t stride) +{ + ff_put_pixels8_xy2_mmx(dst, src, stride, 8); +} +static void put_rv40_qpel16_mc33_mmx(uint8_t *dst, uint8_t *src, + ptrdiff_t stride) +{ + ff_put_pixels16_xy2_mmx(dst, src, stride, 16); +} +static void avg_rv40_qpel8_mc33_mmx(uint8_t *dst, uint8_t *src, + ptrdiff_t stride) +{ + ff_avg_pixels8_xy2_mmx(dst, src, stride, 8); +} +static void avg_rv40_qpel16_mc33_mmx(uint8_t *dst, uint8_t *src, + ptrdiff_t stride) +{ + ff_avg_pixels16_xy2_mmx(dst, src, stride, 16); +} +#endif /* HAVE_MMX_INLINE */ + av_cold void ff_rv40dsp_init_x86(RV34DSPContext *c) { -#if HAVE_YASM - int mm_flags = av_get_cpu_flags(); + int cpu_flags = av_get_cpu_flags(); - if (EXTERNAL_MMX(mm_flags)) { - c->put_chroma_pixels_tab[0] = ff_put_rv40_chroma_mc8_mmx; - c->put_chroma_pixels_tab[1] = ff_put_rv40_chroma_mc4_mmx; #if HAVE_MMX_INLINE - c->put_pixels_tab[0][15] = ff_put_rv40_qpel16_mc33_mmx; - c->put_pixels_tab[1][15] = ff_put_rv40_qpel8_mc33_mmx; - c->avg_pixels_tab[0][15] = ff_avg_rv40_qpel16_mc33_mmx; - c->avg_pixels_tab[1][15] = ff_avg_rv40_qpel8_mc33_mmx; + if (INLINE_MMX(cpu_flags)) { + c->put_pixels_tab[0][15] = put_rv40_qpel16_mc33_mmx; + c->put_pixels_tab[1][15] = put_rv40_qpel8_mc33_mmx; + c->avg_pixels_tab[0][15] = avg_rv40_qpel16_mc33_mmx; + c->avg_pixels_tab[1][15] = avg_rv40_qpel8_mc33_mmx; + } #endif /* HAVE_MMX_INLINE */ + +#if HAVE_YASM + if (EXTERNAL_MMX(cpu_flags)) { + c->put_chroma_pixels_tab[0] = ff_put_rv40_chroma_mc8_mmx; + c->put_chroma_pixels_tab[1] = ff_put_rv40_chroma_mc4_mmx; #if ARCH_X86_32 QPEL_MC_SET(put_, _mmx) #endif } - if (EXTERNAL_MMXEXT(mm_flags)) { + if (EXTERNAL_AMD3DNOW(cpu_flags)) { + c->avg_chroma_pixels_tab[0] = ff_avg_rv40_chroma_mc8_3dnow; + c->avg_chroma_pixels_tab[1] = ff_avg_rv40_chroma_mc4_3dnow; +#if ARCH_X86_32 + QPEL_MC_SET(avg_, _3dnow) +#endif + } + if (EXTERNAL_MMXEXT(cpu_flags)) { c->avg_chroma_pixels_tab[0] = ff_avg_rv40_chroma_mc8_mmxext; c->avg_chroma_pixels_tab[1] = ff_avg_rv40_chroma_mc4_mmxext; c->rv40_weight_pixels_tab[0][0] = ff_rv40_weight_func_rnd_16_mmxext; @@ -215,15 +248,9 @@ av_cold void ff_rv40dsp_init_x86(RV34DSPContext *c) c->rv40_weight_pixels_tab[1][1] = ff_rv40_weight_func_nornd_8_mmxext; #if ARCH_X86_32 QPEL_MC_SET(avg_, _mmxext) -#endif - } else if (EXTERNAL_AMD3DNOW(mm_flags)) { - c->avg_chroma_pixels_tab[0] = ff_avg_rv40_chroma_mc8_3dnow; - c->avg_chroma_pixels_tab[1] = ff_avg_rv40_chroma_mc4_3dnow; -#if ARCH_X86_32 - QPEL_MC_SET(avg_, _3dnow) #endif } - if (EXTERNAL_SSE2(mm_flags)) { + if (EXTERNAL_SSE2(cpu_flags)) { c->rv40_weight_pixels_tab[0][0] = ff_rv40_weight_func_rnd_16_sse2; c->rv40_weight_pixels_tab[0][1] = ff_rv40_weight_func_rnd_8_sse2; c->rv40_weight_pixels_tab[1][0] = ff_rv40_weight_func_nornd_16_sse2; @@ -231,7 +258,7 @@ av_cold void ff_rv40dsp_init_x86(RV34DSPContext *c) QPEL_MC_SET(put_, _sse2) QPEL_MC_SET(avg_, _sse2) } - if (EXTERNAL_SSSE3(mm_flags)) { + if (EXTERNAL_SSSE3(cpu_flags)) { c->rv40_weight_pixels_tab[0][0] = ff_rv40_weight_func_rnd_16_ssse3; c->rv40_weight_pixels_tab[0][1] = ff_rv40_weight_func_rnd_8_ssse3; c->rv40_weight_pixels_tab[1][0] = ff_rv40_weight_func_nornd_16_ssse3; diff --git a/ffmpeg/libavcodec/x86/sbrdsp.asm b/ffmpeg/libavcodec/x86/sbrdsp.asm index 1b7f3a8..adc13c4 100644 --- a/ffmpeg/libavcodec/x86/sbrdsp.asm +++ b/ffmpeg/libavcodec/x86/sbrdsp.asm @@ -2,20 +2,20 @@ ;* AAC Spectral Band Replication decoding functions ;* Copyright (C) 2012 Christophe Gisquet ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* FFmpeg is free software; you can redistribute it and/or ;* modify it under the terms of the GNU Lesser General Public ;* License as published by the Free Software Foundation; either ;* version 2.1 of the License, or (at your option) any later version. ;* -;* Libav is distributed in the hope that it will be useful, +;* FFmpeg is distributed in the hope that it will be useful, ;* but WITHOUT ANY WARRANTY; without even the implied warranty of ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;* Lesser General Public License for more details. ;* ;* You should have received a copy of the GNU Lesser General Public -;* License along with Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** @@ -24,7 +24,14 @@ SECTION_RODATA ; mask equivalent for multiply by -1.0 1.0 ps_mask times 2 dd 1<<31, 0 +ps_mask2 times 2 dd 0, 1<<31 ps_neg times 4 dd 1<<31 +ps_noise0 times 2 dd 1.0, 0.0, +ps_noise2 times 2 dd -1.0, 0.0 +ps_noise13 dd 0.0, 1.0, 0.0, -1.0 + dd 0.0, -1.0, 0.0, 1.0 + dd 0.0, 1.0, 0.0, -1.0 +cextern sbr_noise_table SECTION_TEXT @@ -220,3 +227,199 @@ cglobal sbr_qmf_post_shuffle, 2,3,4,W,z cmp zq, r2q jl .loop REP_RET + +INIT_XMM sse +cglobal sbr_neg_odd_64, 1,2,4,z + lea r1q, [zq+256] +.loop: + mova m0, [zq+ 0] + mova m1, [zq+16] + mova m2, [zq+32] + mova m3, [zq+48] + xorps m0, [ps_mask2] + xorps m1, [ps_mask2] + xorps m2, [ps_mask2] + xorps m3, [ps_mask2] + mova [zq+ 0], m0 + mova [zq+16], m1 + mova [zq+32], m2 + mova [zq+48], m3 + add zq, 64 + cmp zq, r1q + jne .loop + REP_RET + +; sbr_qmf_deint_bfly(float *v, const float *src0, const float *src1) +%macro SBR_QMF_DEINT_BFLY 0 +cglobal sbr_qmf_deint_bfly, 3,5,8, v,src0,src1,vrev,c + mov cq, 64*4-2*mmsize + lea vrevq, [vq + 64*4] +.loop: + mova m0, [src0q+cq] + mova m1, [src1q] + mova m4, [src0q+cq+mmsize] + mova m5, [src1q+mmsize] +%if cpuflag(sse2) + pshufd m2, m0, q0123 + pshufd m3, m1, q0123 + pshufd m6, m4, q0123 + pshufd m7, m5, q0123 +%else + shufps m2, m0, m0, q0123 + shufps m3, m1, m1, q0123 + shufps m6, m4, m4, q0123 + shufps m7, m5, m5, q0123 +%endif + addps m5, m2 + subps m0, m7 + addps m1, m6 + subps m4, m3 + mova [vrevq], m1 + mova [vrevq+mmsize], m5 + mova [vq+cq], m0 + mova [vq+cq+mmsize], m4 + add src1q, 2*mmsize + add vrevq, 2*mmsize + sub cq, 2*mmsize + jge .loop + REP_RET +%endmacro + +INIT_XMM sse +SBR_QMF_DEINT_BFLY + +INIT_XMM sse2 +SBR_QMF_DEINT_BFLY + +INIT_XMM sse2 +cglobal sbr_qmf_pre_shuffle, 1,4,6,z +%define OFFSET (32*4-2*mmsize) + mov r3q, OFFSET + lea r1q, [zq + (32+1)*4] + lea r2q, [zq + 64*4] + mova m5, [ps_neg] +.loop: + movu m0, [r1q] + movu m2, [r1q + mmsize] + movu m1, [zq + r3q + 4 + mmsize] + movu m3, [zq + r3q + 4] + + pxor m2, m5 + pxor m0, m5 + pshufd m2, m2, q0123 + pshufd m0, m0, q0123 + SBUTTERFLY dq, 2, 3, 4 + SBUTTERFLY dq, 0, 1, 4 + mova [r2q + 2*r3q + 0*mmsize], m2 + mova [r2q + 2*r3q + 1*mmsize], m3 + mova [r2q + 2*r3q + 2*mmsize], m0 + mova [r2q + 2*r3q + 3*mmsize], m1 + add r1q, 2*mmsize + sub r3q, 2*mmsize + jge .loop + movq m2, [zq] + movq [r2q], m2 + REP_RET + +%ifdef PIC +%define NREGS 1 +%if UNIX64 +%define NOISE_TABLE r6q ; r5q is m_max +%else +%define NOISE_TABLE r5q +%endif +%else +%define NREGS 0 +%define NOISE_TABLE sbr_noise_table +%endif + +%macro LOAD_NST 1 +%ifdef PIC + lea NOISE_TABLE, [%1] + mova m0, [kxq + NOISE_TABLE] +%else + mova m0, [kxq + %1] +%endif +%endmacro + +INIT_XMM sse2 +; sbr_hf_apply_noise_0(float (*Y)[2], const float *s_m, +; const float *q_filt, int noise, +; int kx, int m_max) +cglobal sbr_hf_apply_noise_0, 5,5+NREGS+UNIX64,8, Y,s_m,q_filt,noise,kx,m_max + mova m0, [ps_noise0] + jmp apply_noise_main + +; sbr_hf_apply_noise_1(float (*Y)[2], const float *s_m, +; const float *q_filt, int noise, +; int kx, int m_max) +cglobal sbr_hf_apply_noise_1, 5,5+NREGS+UNIX64,8, Y,s_m,q_filt,noise,kx,m_max + and kxq, 1 + shl kxq, 4 + LOAD_NST ps_noise13 + jmp apply_noise_main + +; sbr_hf_apply_noise_2(float (*Y)[2], const float *s_m, +; const float *q_filt, int noise, +; int kx, int m_max) +cglobal sbr_hf_apply_noise_2, 5,5+NREGS+UNIX64,8, Y,s_m,q_filt,noise,kx,m_max + mova m0, [ps_noise2] + jmp apply_noise_main + +; sbr_hf_apply_noise_3(float (*Y)[2], const float *s_m, +; const float *q_filt, int noise, +; int kx, int m_max) +cglobal sbr_hf_apply_noise_3, 5,5+NREGS+UNIX64,8, Y,s_m,q_filt,noise,kx,m_max + and kxq, 1 + shl kxq, 4 + LOAD_NST ps_noise13+16 + +apply_noise_main: +%if ARCH_X86_64 == 0 || WIN64 + mov kxd, m_maxm +%define count kxq +%else +%define count m_maxq +%endif + dec noiseq + shl count, 2 +%ifdef PIC + lea NOISE_TABLE, [sbr_noise_table] +%endif + lea Yq, [Yq + 2*count] + add s_mq, count + add q_filtq, count + shl noiseq, 3 + pxor m5, m5 + neg count +.loop: + mova m1, [q_filtq + count] + movu m3, [noiseq + NOISE_TABLE + 1*mmsize] + movu m4, [noiseq + NOISE_TABLE + 2*mmsize] + add noiseq, 2*mmsize + and noiseq, 0x1ff<<3 + punpckhdq m2, m1, m1 + punpckldq m1, m1 + mulps m1, m3 ; m2 = q_filt[m] * ff_sbr_noise_table[noise] + mulps m2, m4 ; m2 = q_filt[m] * ff_sbr_noise_table[noise] + mova m3, [s_mq + count] + ; TODO: replace by a vpermd in AVX2 + punpckhdq m4, m3, m3 + punpckldq m3, m3 + pcmpeqd m6, m3, m5 ; m6 == 0 + pcmpeqd m7, m4, m5 ; m7 == 0 + mulps m3, m0 ; s_m[m] * phi_sign + mulps m4, m0 ; s_m[m] * phi_sign + pand m1, m6 + pand m2, m7 + movu m6, [Yq + 2*count] + movu m7, [Yq + 2*count + mmsize] + addps m3, m1 + addps m4, m2 + addps m6, m3 + addps m7, m4 + movu [Yq + 2*count], m6 + movu [Yq + 2*count + mmsize], m7 + add count, mmsize + jl .loop + RET diff --git a/ffmpeg/libavcodec/x86/sbrdsp_init.c b/ffmpeg/libavcodec/x86/sbrdsp_init.c index 27fade1..2b912d0 100644 --- a/ffmpeg/libavcodec/x86/sbrdsp_init.c +++ b/ffmpeg/libavcodec/x86/sbrdsp_init.c @@ -2,20 +2,20 @@ * AAC Spectral Band Replication decoding functions * Copyright (c) 2012 Christophe Gisquet * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -32,17 +32,45 @@ void ff_sbr_hf_g_filt_sse(float (*Y)[2], const float (*X_high)[40][2], void ff_sbr_hf_gen_sse(float (*X_high)[2], const float (*X_low)[2], const float alpha0[2], const float alpha1[2], float bw, int start, int end); +void ff_sbr_neg_odd_64_sse(float *z); void ff_sbr_qmf_post_shuffle_sse(float W[32][2], const float *z); +void ff_sbr_qmf_deint_bfly_sse(float *v, const float *src0, const float *src1); +void ff_sbr_qmf_deint_bfly_sse2(float *v, const float *src0, const float *src1); +void ff_sbr_qmf_pre_shuffle_sse2(float *z); + +void ff_sbr_hf_apply_noise_0_sse2(float (*Y)[2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max); +void ff_sbr_hf_apply_noise_1_sse2(float (*Y)[2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max); +void ff_sbr_hf_apply_noise_2_sse2(float (*Y)[2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max); +void ff_sbr_hf_apply_noise_3_sse2(float (*Y)[2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max); av_cold void ff_sbrdsp_init_x86(SBRDSPContext *s) { - int mm_flags = av_get_cpu_flags(); + int cpu_flags = av_get_cpu_flags(); - if (EXTERNAL_SSE(mm_flags)) { + if (EXTERNAL_SSE(cpu_flags)) { + s->neg_odd_64 = ff_sbr_neg_odd_64_sse; s->sum_square = ff_sbr_sum_square_sse; s->sum64x5 = ff_sbr_sum64x5_sse; s->hf_g_filt = ff_sbr_hf_g_filt_sse; s->hf_gen = ff_sbr_hf_gen_sse; s->qmf_post_shuffle = ff_sbr_qmf_post_shuffle_sse; + s->qmf_deint_bfly = ff_sbr_qmf_deint_bfly_sse; + } + + if (EXTERNAL_SSE2(cpu_flags)) { + s->qmf_deint_bfly = ff_sbr_qmf_deint_bfly_sse2; + s->qmf_pre_shuffle = ff_sbr_qmf_pre_shuffle_sse2; + s->hf_apply_noise[0] = ff_sbr_hf_apply_noise_0_sse2; + s->hf_apply_noise[1] = ff_sbr_hf_apply_noise_1_sse2; + s->hf_apply_noise[2] = ff_sbr_hf_apply_noise_2_sse2; + s->hf_apply_noise[3] = ff_sbr_hf_apply_noise_3_sse2; } } diff --git a/ffmpeg/libavcodec/x86/simple_idct.c b/ffmpeg/libavcodec/x86/simple_idct.c index f27d2b9..c666b1a 100644 --- a/ffmpeg/libavcodec/x86/simple_idct.c +++ b/ffmpeg/libavcodec/x86/simple_idct.c @@ -21,7 +21,7 @@ */ #include "libavcodec/simple_idct.h" #include "libavutil/mem.h" -#include "dsputil_mmx.h" +#include "dsputil_x86.h" #if HAVE_INLINE_ASM @@ -80,7 +80,7 @@ DECLARE_ALIGNED(8, static const int16_t, coeffs)[]= { static inline void idct(int16_t *block) { - DECLARE_ALIGNED(8, int64_t, align_tmp)[16]; + LOCAL_ALIGNED_8(int64_t, align_tmp, [16]); int16_t * const temp= (int16_t*)align_tmp; __asm__ volatile( diff --git a/ffmpeg/libavcodec/x86/snowdsp.c b/ffmpeg/libavcodec/x86/snowdsp.c index 5505ee8..735e790 100644 --- a/ffmpeg/libavcodec/x86/snowdsp.c +++ b/ffmpeg/libavcodec/x86/snowdsp.c @@ -24,7 +24,7 @@ #include "libavcodec/avcodec.h" #include "libavcodec/snow.h" #include "libavcodec/snow_dwt.h" -#include "dsputil_mmx.h" +#include "dsputil_x86.h" #if HAVE_INLINE_ASM diff --git a/ffmpeg/libavcodec/x86/v210.asm b/ffmpeg/libavcodec/x86/v210.asm index 5473126..6554a43 100644 --- a/ffmpeg/libavcodec/x86/v210.asm +++ b/ffmpeg/libavcodec/x86/v210.asm @@ -3,20 +3,20 @@ ;* Copyright (c) 2011 Loren Merritt ;* Copyright (c) 2011 Kieran Kunhya ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* FFmpeg is free software; you can redistribute it and/or ;* modify it under the terms of the GNU Lesser General Public ;* License as published by the Free Software Foundation; either ;* version 2.1 of the License, or (at your option) any later version. ;* -;* Libav is distributed in the hope that it will be useful, +;* FFmpeg is distributed in the hope that it will be useful, ;* but WITHOUT ANY WARRANTY; without even the implied warranty of ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;* Lesser General Public License for more details. ;* ;* You should have received a copy of the GNU Lesser General Public -;* License along with Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** diff --git a/ffmpeg/libavcodec/x86/vc1dsp_init.c b/ffmpeg/libavcodec/x86/vc1dsp_init.c index 228f4dc..9f18131 100644 --- a/ffmpeg/libavcodec/x86/vc1dsp_init.c +++ b/ffmpeg/libavcodec/x86/vc1dsp_init.c @@ -27,7 +27,7 @@ #include "libavutil/cpu.h" #include "libavutil/x86/cpu.h" #include "libavcodec/vc1dsp.h" -#include "dsputil_mmx.h" +#include "dsputil_x86.h" #include "vc1dsp.h" #include "config.h" @@ -83,12 +83,12 @@ void ff_avg_vc1_chroma_mc8_nornd_ssse3(uint8_t *dst, uint8_t *src, av_cold void ff_vc1dsp_init_x86(VC1DSPContext *dsp) { - int mm_flags = av_get_cpu_flags(); + int cpu_flags = av_get_cpu_flags(); - if (INLINE_MMX(mm_flags)) + if (INLINE_MMX(cpu_flags)) ff_vc1dsp_init_mmx(dsp); - if (INLINE_MMXEXT(mm_flags)) + if (INLINE_MMXEXT(cpu_flags)) ff_vc1dsp_init_mmxext(dsp); #define ASSIGN_LF(EXT) \ @@ -100,31 +100,30 @@ av_cold void ff_vc1dsp_init_x86(VC1DSPContext *dsp) dsp->vc1_h_loop_filter16 = vc1_h_loop_filter16_ ## EXT #if HAVE_YASM - if (mm_flags & AV_CPU_FLAG_MMX) { + if (EXTERNAL_MMX(cpu_flags)) { dsp->put_no_rnd_vc1_chroma_pixels_tab[0] = ff_put_vc1_chroma_mc8_nornd_mmx; } - - if (mm_flags & AV_CPU_FLAG_MMXEXT) { + if (EXTERNAL_AMD3DNOW(cpu_flags)) { + dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_vc1_chroma_mc8_nornd_3dnow; + } + if (EXTERNAL_MMXEXT(cpu_flags)) { ASSIGN_LF(mmxext); dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_vc1_chroma_mc8_nornd_mmxext; dsp->avg_vc1_mspel_pixels_tab[0] = avg_vc1_mspel_mc00_mmxext; - } else if (mm_flags & AV_CPU_FLAG_3DNOW) { - dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_vc1_chroma_mc8_nornd_3dnow; } - - if (mm_flags & AV_CPU_FLAG_SSE2) { + if (EXTERNAL_SSE2(cpu_flags)) { dsp->vc1_v_loop_filter8 = ff_vc1_v_loop_filter8_sse2; dsp->vc1_h_loop_filter8 = ff_vc1_h_loop_filter8_sse2; dsp->vc1_v_loop_filter16 = vc1_v_loop_filter16_sse2; dsp->vc1_h_loop_filter16 = vc1_h_loop_filter16_sse2; } - if (mm_flags & AV_CPU_FLAG_SSSE3) { + if (EXTERNAL_SSSE3(cpu_flags)) { ASSIGN_LF(ssse3); dsp->put_no_rnd_vc1_chroma_pixels_tab[0] = ff_put_vc1_chroma_mc8_nornd_ssse3; dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_vc1_chroma_mc8_nornd_ssse3; } - if (mm_flags & AV_CPU_FLAG_SSE4) { + if (EXTERNAL_SSE4(cpu_flags)) { dsp->vc1_h_loop_filter8 = ff_vc1_h_loop_filter8_sse4; dsp->vc1_h_loop_filter16 = vc1_h_loop_filter16_sse4; } diff --git a/ffmpeg/libavcodec/x86/vc1dsp_mmx.c b/ffmpeg/libavcodec/x86/vc1dsp_mmx.c index df0385f..5ceacd3 100644 --- a/ffmpeg/libavcodec/x86/vc1dsp_mmx.c +++ b/ffmpeg/libavcodec/x86/vc1dsp_mmx.c @@ -28,8 +28,9 @@ #include "libavutil/mem.h" #include "libavutil/x86/asm.h" #include "libavutil/x86/cpu.h" -#include "dsputil_mmx.h" #include "libavcodec/vc1dsp.h" +#include "constants.h" +#include "dsputil_x86.h" #include "vc1dsp.h" #if HAVE_INLINE_ASM @@ -698,53 +699,59 @@ static void vc1_inv_trans_8x8_dc_mmxext(uint8_t *dest, int linesize, ); } +static void put_vc1_mspel_mc00_mmx(uint8_t *dst, const uint8_t *src, + ptrdiff_t stride, int rnd) +{ + ff_put_pixels8_mmx(dst, src, stride, 8); +} + av_cold void ff_vc1dsp_init_mmx(VC1DSPContext *dsp) { - dsp->put_vc1_mspel_pixels_tab[ 0] = ff_put_vc1_mspel_mc00_mmx; - dsp->put_vc1_mspel_pixels_tab[ 4] = put_vc1_mspel_mc01_mmx; - dsp->put_vc1_mspel_pixels_tab[ 8] = put_vc1_mspel_mc02_mmx; - dsp->put_vc1_mspel_pixels_tab[12] = put_vc1_mspel_mc03_mmx; - - dsp->put_vc1_mspel_pixels_tab[ 1] = put_vc1_mspel_mc10_mmx; - dsp->put_vc1_mspel_pixels_tab[ 5] = put_vc1_mspel_mc11_mmx; - dsp->put_vc1_mspel_pixels_tab[ 9] = put_vc1_mspel_mc12_mmx; - dsp->put_vc1_mspel_pixels_tab[13] = put_vc1_mspel_mc13_mmx; - - dsp->put_vc1_mspel_pixels_tab[ 2] = put_vc1_mspel_mc20_mmx; - dsp->put_vc1_mspel_pixels_tab[ 6] = put_vc1_mspel_mc21_mmx; - dsp->put_vc1_mspel_pixels_tab[10] = put_vc1_mspel_mc22_mmx; - dsp->put_vc1_mspel_pixels_tab[14] = put_vc1_mspel_mc23_mmx; - - dsp->put_vc1_mspel_pixels_tab[ 3] = put_vc1_mspel_mc30_mmx; - dsp->put_vc1_mspel_pixels_tab[ 7] = put_vc1_mspel_mc31_mmx; - dsp->put_vc1_mspel_pixels_tab[11] = put_vc1_mspel_mc32_mmx; - dsp->put_vc1_mspel_pixels_tab[15] = put_vc1_mspel_mc33_mmx; + dsp->put_vc1_mspel_pixels_tab[ 0] = put_vc1_mspel_mc00_mmx; + dsp->put_vc1_mspel_pixels_tab[ 4] = put_vc1_mspel_mc01_mmx; + dsp->put_vc1_mspel_pixels_tab[ 8] = put_vc1_mspel_mc02_mmx; + dsp->put_vc1_mspel_pixels_tab[12] = put_vc1_mspel_mc03_mmx; + + dsp->put_vc1_mspel_pixels_tab[ 1] = put_vc1_mspel_mc10_mmx; + dsp->put_vc1_mspel_pixels_tab[ 5] = put_vc1_mspel_mc11_mmx; + dsp->put_vc1_mspel_pixels_tab[ 9] = put_vc1_mspel_mc12_mmx; + dsp->put_vc1_mspel_pixels_tab[13] = put_vc1_mspel_mc13_mmx; + + dsp->put_vc1_mspel_pixels_tab[ 2] = put_vc1_mspel_mc20_mmx; + dsp->put_vc1_mspel_pixels_tab[ 6] = put_vc1_mspel_mc21_mmx; + dsp->put_vc1_mspel_pixels_tab[10] = put_vc1_mspel_mc22_mmx; + dsp->put_vc1_mspel_pixels_tab[14] = put_vc1_mspel_mc23_mmx; + + dsp->put_vc1_mspel_pixels_tab[ 3] = put_vc1_mspel_mc30_mmx; + dsp->put_vc1_mspel_pixels_tab[ 7] = put_vc1_mspel_mc31_mmx; + dsp->put_vc1_mspel_pixels_tab[11] = put_vc1_mspel_mc32_mmx; + dsp->put_vc1_mspel_pixels_tab[15] = put_vc1_mspel_mc33_mmx; } av_cold void ff_vc1dsp_init_mmxext(VC1DSPContext *dsp) { - dsp->avg_vc1_mspel_pixels_tab[ 4] = avg_vc1_mspel_mc01_mmxext; - dsp->avg_vc1_mspel_pixels_tab[ 8] = avg_vc1_mspel_mc02_mmxext; - dsp->avg_vc1_mspel_pixels_tab[12] = avg_vc1_mspel_mc03_mmxext; - - dsp->avg_vc1_mspel_pixels_tab[ 1] = avg_vc1_mspel_mc10_mmxext; - dsp->avg_vc1_mspel_pixels_tab[ 5] = avg_vc1_mspel_mc11_mmxext; - dsp->avg_vc1_mspel_pixels_tab[ 9] = avg_vc1_mspel_mc12_mmxext; - dsp->avg_vc1_mspel_pixels_tab[13] = avg_vc1_mspel_mc13_mmxext; - - dsp->avg_vc1_mspel_pixels_tab[ 2] = avg_vc1_mspel_mc20_mmxext; - dsp->avg_vc1_mspel_pixels_tab[ 6] = avg_vc1_mspel_mc21_mmxext; - dsp->avg_vc1_mspel_pixels_tab[10] = avg_vc1_mspel_mc22_mmxext; - dsp->avg_vc1_mspel_pixels_tab[14] = avg_vc1_mspel_mc23_mmxext; - - dsp->avg_vc1_mspel_pixels_tab[ 3] = avg_vc1_mspel_mc30_mmxext; - dsp->avg_vc1_mspel_pixels_tab[ 7] = avg_vc1_mspel_mc31_mmxext; - dsp->avg_vc1_mspel_pixels_tab[11] = avg_vc1_mspel_mc32_mmxext; - dsp->avg_vc1_mspel_pixels_tab[15] = avg_vc1_mspel_mc33_mmxext; - - dsp->vc1_inv_trans_8x8_dc = vc1_inv_trans_8x8_dc_mmxext; - dsp->vc1_inv_trans_4x8_dc = vc1_inv_trans_4x8_dc_mmxext; - dsp->vc1_inv_trans_8x4_dc = vc1_inv_trans_8x4_dc_mmxext; - dsp->vc1_inv_trans_4x4_dc = vc1_inv_trans_4x4_dc_mmxext; + dsp->avg_vc1_mspel_pixels_tab[ 4] = avg_vc1_mspel_mc01_mmxext; + dsp->avg_vc1_mspel_pixels_tab[ 8] = avg_vc1_mspel_mc02_mmxext; + dsp->avg_vc1_mspel_pixels_tab[12] = avg_vc1_mspel_mc03_mmxext; + + dsp->avg_vc1_mspel_pixels_tab[ 1] = avg_vc1_mspel_mc10_mmxext; + dsp->avg_vc1_mspel_pixels_tab[ 5] = avg_vc1_mspel_mc11_mmxext; + dsp->avg_vc1_mspel_pixels_tab[ 9] = avg_vc1_mspel_mc12_mmxext; + dsp->avg_vc1_mspel_pixels_tab[13] = avg_vc1_mspel_mc13_mmxext; + + dsp->avg_vc1_mspel_pixels_tab[ 2] = avg_vc1_mspel_mc20_mmxext; + dsp->avg_vc1_mspel_pixels_tab[ 6] = avg_vc1_mspel_mc21_mmxext; + dsp->avg_vc1_mspel_pixels_tab[10] = avg_vc1_mspel_mc22_mmxext; + dsp->avg_vc1_mspel_pixels_tab[14] = avg_vc1_mspel_mc23_mmxext; + + dsp->avg_vc1_mspel_pixels_tab[ 3] = avg_vc1_mspel_mc30_mmxext; + dsp->avg_vc1_mspel_pixels_tab[ 7] = avg_vc1_mspel_mc31_mmxext; + dsp->avg_vc1_mspel_pixels_tab[11] = avg_vc1_mspel_mc32_mmxext; + dsp->avg_vc1_mspel_pixels_tab[15] = avg_vc1_mspel_mc33_mmxext; + + dsp->vc1_inv_trans_8x8_dc = vc1_inv_trans_8x8_dc_mmxext; + dsp->vc1_inv_trans_4x8_dc = vc1_inv_trans_4x8_dc_mmxext; + dsp->vc1_inv_trans_8x4_dc = vc1_inv_trans_8x4_dc_mmxext; + dsp->vc1_inv_trans_4x4_dc = vc1_inv_trans_4x4_dc_mmxext; } #endif /* HAVE_INLINE_ASM */ diff --git a/ffmpeg/libavcodec/x86/videodsp.asm b/ffmpeg/libavcodec/x86/videodsp.asm index 0eb4721..1ac0257 100644 --- a/ffmpeg/libavcodec/x86/videodsp.asm +++ b/ffmpeg/libavcodec/x86/videodsp.asm @@ -23,577 +23,409 @@ SECTION .text -; extern void ff_emu_edge_core(uint8_t *buf, const uint8_t *src, x86_reg linesize, -; x86_reg start_y, x86_reg end_y, x86_reg block_h, -; x86_reg start_x, x86_reg end_x, x86_reg block_w); -; -; The actual function itself is below. It basically wraps a very simple -; w = end_x - start_x -; if (w) { -; if (w > 22) { -; jump to the slow loop functions -; } else { -; jump to the fast loop functions -; } -; } -; -; ... and then the same for left/right extend also. See below for loop -; function implementations. Fast are fixed-width, slow is variable-width - -%macro EMU_EDGE_FUNC 0 -%if ARCH_X86_64 -%define w_reg r7 -cglobal emu_edge_core, 6, 9, 1 - mov r8, r5 ; save block_h -%else -%define w_reg r6 -cglobal emu_edge_core, 2, 7, 0 - mov r4, r4m ; end_y - mov r5, r5m ; block_h -%endif +; slow vertical extension loop function. Works with variable-width, and +; does per-line reading/writing of source data + +%macro V_COPY_ROW 2 ; type (top/body/bottom), h +.%1_y_loop: ; do { + mov wq, r7mp ; initialize w (r7mp = wmp) +.%1_x_loop: ; do { + movu m0, [srcq+wq] ; m0 = read($mmsize) + movu [dstq+wq], m0 ; write(m0, $mmsize) + add wq, mmsize ; w -= $mmsize + cmp wq, -mmsize ; } while (w > $mmsize); + jl .%1_x_loop + movu m0, [srcq-mmsize] ; m0 = read($mmsize) + movu [dstq-mmsize], m0 ; write(m0, $mmsize) +%ifidn %1, body ; if ($type == body) { + add srcq, src_strideq ; src += src_stride +%endif ; } + add dstq, dst_strideq ; dst += dst_stride + dec %2 ; } while (--$h); + jnz .%1_y_loop +%endmacro - ; start with vertical extend (top/bottom) and body pixel copy - mov w_reg, r7m - sub w_reg, r6m ; w = start_x - end_x - sub r5, r4 +%macro vvar_fn 0 +; .----. <- zero +; | | <- top is copied from first line in body of source +; |----| <- start_y +; | | <- body is copied verbatim (line-by-line) from source +; |----| <- end_y +; | | <- bottom is copied from last line in body of source +; '----' <- bh %if ARCH_X86_64 - sub r4, r3 -%else - sub r4, dword r3m +cglobal emu_edge_vvar, 7, 8, 1, dst, dst_stride, src, src_stride, \ + start_y, end_y, bh, w +%else ; x86-32 +cglobal emu_edge_vvar, 1, 6, 1, dst, src, start_y, end_y, bh, w +%define src_strideq r3mp +%define dst_strideq r1mp + mov srcq, r2mp + mov start_yq, r4mp + mov end_yq, r5mp + mov bhq, r6mp %endif - cmp w_reg, 22 - jg .slow_v_extend_loop + sub bhq, end_yq ; bh -= end_q + sub end_yq, start_yq ; end_q -= start_q + add srcq, r7mp ; (r7mp = wmp) + add dstq, r7mp ; (r7mp = wmp) + neg r7mp ; (r7mp = wmp) + test start_yq, start_yq ; if (start_q) { + jz .body + V_COPY_ROW top, start_yq ; v_copy_row(top, start_yq) +.body: ; } + V_COPY_ROW body, end_yq ; v_copy_row(body, end_yq) + test bhq, bhq ; if (bh) { + jz .end + sub srcq, src_strideq ; src -= src_stride + V_COPY_ROW bottom, bhq ; v_copy_row(bottom, bh) +.end: ; } + RET +%endmacro + %if ARCH_X86_32 - mov r2, r2m ; linesize -%endif - sal w_reg, 7 ; w * 128 -%ifdef PIC - lea rax, [.emuedge_v_extend_1 - (.emuedge_v_extend_2 - .emuedge_v_extend_1)] - add w_reg, rax -%else - lea w_reg, [.emuedge_v_extend_1 - (.emuedge_v_extend_2 - .emuedge_v_extend_1)+w_reg] +INIT_MMX mmx +vvar_fn %endif - call w_reg ; fast top extend, body copy and bottom extend -.v_extend_end: - ; horizontal extend (left/right) - mov w_reg, r6m ; start_x - sub r0, w_reg -%if ARCH_X86_64 - mov r3, r0 ; backup of buf+block_h*linesize - mov r5, r8 -%else - mov r0m, r0 ; backup of buf+block_h*linesize - mov r5, r5m -%endif - test w_reg, w_reg - jz .right_extend - cmp w_reg, 22 - jg .slow_left_extend_loop - mov r1, w_reg - dec w_reg - ; FIXME we can do a if size == 1 here if that makes any speed difference, test me - sar w_reg, 1 - sal w_reg, 6 - ; r0=buf+block_h*linesize,r7(64)/r6(32)=start_x offset for funcs - ; r6(rax)/r3(ebx)=val,r2=linesize,r1=start_x,r5=block_h -%ifdef PIC - lea rax, [.emuedge_extend_left_2] - add w_reg, rax -%else - lea w_reg, [.emuedge_extend_left_2+w_reg] -%endif - call w_reg +INIT_XMM sse +vvar_fn + +%macro hvar_fn 0 +cglobal emu_edge_hvar, 5, 6, 1, dst, dst_stride, start_x, n_words, h, w + lea dstq, [dstq+n_wordsq*2] + neg n_wordsq + lea start_xq, [start_xq+n_wordsq*2] +.y_loop: ; do { + ; FIXME also write a ssse3 version using pshufb + movzx wd, byte [dstq+start_xq] ; w = read(1) + imul wd, 0x01010101 ; w *= 0x01010101 + movd m0, wd + mov wq, n_wordsq ; initialize w +%if cpuflag(sse2) + pshufd m0, m0, q0000 ; splat +%else ; mmx + punpckldq m0, m0 ; splat +%endif ; mmx/sse +.x_loop: ; do { + movu [dstq+wq*2], m0 ; write($reg, $mmsize) + add wq, mmsize/2 ; w -= $mmsize/2 + cmp wq, -mmsize/2 ; } while (w > $mmsize/2) + jl .x_loop + movu [dstq-mmsize], m0 ; write($reg, $mmsize) + add dstq, dst_strideq ; dst += dst_stride + dec hq ; } while (h--) + jnz .y_loop + RET +%endmacro - ; now r3(64)/r0(32)=buf,r2=linesize,r8/r5=block_h,r6/r3=val, r7/r6=end_x, r1=block_w -.right_extend: %if ARCH_X86_32 - mov r0, r0m - mov r5, r5m -%endif - mov w_reg, r7m ; end_x - mov r1, r8m ; block_w - mov r4, r1 - sub r1, w_reg - jz .h_extend_end ; if (end_x == block_w) goto h_extend_end - cmp r1, 22 - jg .slow_right_extend_loop - dec r1 - ; FIXME we can do a if size == 1 here if that makes any speed difference, test me - sar r1, 1 - sal r1, 6 -%ifdef PIC - lea rax, [.emuedge_extend_right_2] - add r1, rax -%else - lea r1, [.emuedge_extend_right_2+r1] +INIT_MMX mmx +hvar_fn %endif - call r1 -.h_extend_end: - RET -%if ARCH_X86_64 -%define vall al -%define valh ah -%define valw ax -%define valw2 r7w -%define valw3 r3w -%if WIN64 -%define valw4 r7w -%else ; unix64 -%define valw4 r3w -%endif -%define vald eax -%else -%define vall bl -%define valh bh -%define valw bx -%define valw2 r6w -%define valw3 valw2 -%define valw4 valw3 -%define vald ebx -%define stack_offset 0x14 -%endif - -%endmacro +INIT_XMM sse2 +hvar_fn ; macro to read/write a horizontal number of pixels (%2) to/from registers -; on x86-64, - fills xmm0-15 for consecutive sets of 16 pixels -; - if (%2 & 15 == 8) fills the last 8 bytes into rax -; - else if (%2 & 8) fills 8 bytes into mm0 -; - if (%2 & 7 == 4) fills the last 4 bytes into rax -; - else if (%2 & 4) fills 4 bytes into mm0-1 -; - if (%2 & 3 == 3) fills 2 bytes into r7/r3, and 1 into eax -; (note that we're using r3 for body/bottom because it's a shorter -; opcode, and then the loop fits in 128 bytes) -; - else fills remaining bytes into rax -; on x86-32, - fills mm0-7 for consecutive sets of 8 pixels -; - if (%2 & 7 == 4) fills 4 bytes into ebx -; - else if (%2 & 4) fills 4 bytes into mm0-7 -; - if (%2 & 3 == 3) fills 2 bytes into r6, and 1 into ebx -; - else fills remaining bytes into ebx +; on sse, - fills xmm0-15 for consecutive sets of 16 pixels +; - if (%2 & 8) fills 8 bytes into xmm$next +; - if (%2 & 4) fills 4 bytes into xmm$next +; - if (%2 & 3) fills 1, 2 or 4 bytes in eax +; on mmx, - fills mm0-7 for consecutive sets of 8 pixels +; - if (%2 & 4) fills 4 bytes into mm$next +; - if (%2 & 3) fills 1, 2 or 4 bytes in eax ; writing data out is in the same way %macro READ_NUM_BYTES 2 -%assign %%src_off 0 ; offset in source buffer -%assign %%smidx 0 ; mmx register idx -%assign %%sxidx 0 ; xmm register idx - -%if cpuflag(sse) -%rep %2/16 - movups xmm %+ %%sxidx, [r1+%%src_off] -%assign %%src_off %%src_off+16 -%assign %%sxidx %%sxidx+1 -%endrep ; %2/16 +%assign %%off 0 ; offset in source buffer +%assign %%mmx_idx 0 ; mmx register index +%assign %%xmm_idx 0 ; xmm register index + +%rep %2/mmsize +%if mmsize == 16 + movu xmm %+ %%xmm_idx, [srcq+%%off] +%assign %%xmm_idx %%xmm_idx+1 +%else ; mmx + movu mm %+ %%mmx_idx, [srcq+%%off] +%assign %%mmx_idx %%mmx_idx+1 +%endif +%assign %%off %%off+mmsize +%endrep ; %2/mmsize + +%if mmsize == 16 +%if (%2-%%off) >= 8 +%if %2 > 16 && (%2-%%off) > 8 + movu xmm %+ %%xmm_idx, [srcq+%2-16] +%assign %%xmm_idx %%xmm_idx+1 +%assign %%off %2 +%else + movq mm %+ %%mmx_idx, [srcq+%%off] +%assign %%mmx_idx %%mmx_idx+1 +%assign %%off %%off+8 +%endif +%endif ; (%2-%%off) >= 8 %endif -%if ARCH_X86_64 -%if (%2-%%src_off) == 8 - mov rax, [r1+%%src_off] -%assign %%src_off %%src_off+8 -%endif ; (%2-%%src_off) == 8 -%endif ; x86-64 - -%rep (%2-%%src_off)/8 - movq mm %+ %%smidx, [r1+%%src_off] -%assign %%src_off %%src_off+8 -%assign %%smidx %%smidx+1 -%endrep ; (%2-%%dst_off)/8 - -%if (%2-%%src_off) == 4 - mov vald, [r1+%%src_off] -%elif (%2-%%src_off) & 4 - movd mm %+ %%smidx, [r1+%%src_off] -%assign %%src_off %%src_off+4 -%endif ; (%2-%%src_off) ==/& 4 - -%if (%2-%%src_off) == 1 - mov vall, [r1+%%src_off] -%elif (%2-%%src_off) == 2 - mov valw, [r1+%%src_off] -%elif (%2-%%src_off) == 3 -%ifidn %1, top - mov valw2, [r1+%%src_off] +%if (%2-%%off) >= 4 +%if %2 > 8 && (%2-%%off) > 4 + movq mm %+ %%mmx_idx, [srcq+%2-8] +%assign %%off %2 +%else + movd mm %+ %%mmx_idx, [srcq+%%off] +%assign %%off %%off+4 +%endif +%assign %%mmx_idx %%mmx_idx+1 +%endif ; (%2-%%off) >= 4 + +%if (%2-%%off) >= 1 +%if %2 >= 4 + movd mm %+ %%mmx_idx, [srcq+%2-4] +%elif (%2-%%off) == 1 + mov valb, [srcq+%2-1] +%elif (%2-%%off) == 2 + mov valw, [srcq+%2-2] %elifidn %1, body - mov valw3, [r1+%%src_off] -%elifidn %1, bottom - mov valw4, [r1+%%src_off] -%endif ; %1 ==/!= top - mov vall, [r1+%%src_off+2] -%endif ; (%2-%%src_off) == 1/2/3 + mov vald, [srcq+%2-3] +%else + movd mm %+ %%mmx_idx, [srcq+%2-3] +%endif +%endif ; (%2-%%off) >= 1 %endmacro ; READ_NUM_BYTES %macro WRITE_NUM_BYTES 2 -%assign %%dst_off 0 ; offset in destination buffer -%assign %%dmidx 0 ; mmx register idx -%assign %%dxidx 0 ; xmm register idx - -%if cpuflag(sse) -%rep %2/16 - movups [r0+%%dst_off], xmm %+ %%dxidx -%assign %%dst_off %%dst_off+16 -%assign %%dxidx %%dxidx+1 -%endrep ; %2/16 +%assign %%off 0 ; offset in destination buffer +%assign %%mmx_idx 0 ; mmx register index +%assign %%xmm_idx 0 ; xmm register index + +%rep %2/mmsize +%if mmsize == 16 + movu [dstq+%%off], xmm %+ %%xmm_idx +%assign %%xmm_idx %%xmm_idx+1 +%else ; mmx + movu [dstq+%%off], mm %+ %%mmx_idx +%assign %%mmx_idx %%mmx_idx+1 +%endif +%assign %%off %%off+mmsize +%endrep ; %2/mmsize + +%if mmsize == 16 +%if (%2-%%off) >= 8 +%if %2 > 16 && (%2-%%off) > 8 + movu [dstq+%2-16], xmm %+ %%xmm_idx +%assign %%xmm_idx %%xmm_idx+1 +%assign %%off %2 +%else + movq [dstq+%%off], mm %+ %%mmx_idx +%assign %%mmx_idx %%mmx_idx+1 +%assign %%off %%off+8 +%endif +%endif ; (%2-%%off) >= 8 %endif -%if ARCH_X86_64 -%if (%2-%%dst_off) == 8 - mov [r0+%%dst_off], rax -%assign %%dst_off %%dst_off+8 -%endif ; (%2-%%dst_off) == 8 -%endif ; x86-64 - -%rep (%2-%%dst_off)/8 - movq [r0+%%dst_off], mm %+ %%dmidx -%assign %%dst_off %%dst_off+8 -%assign %%dmidx %%dmidx+1 -%endrep ; (%2-%%dst_off)/8 - -%if (%2-%%dst_off) == 4 - mov [r0+%%dst_off], vald -%elif (%2-%%dst_off) & 4 - movd [r0+%%dst_off], mm %+ %%dmidx -%assign %%dst_off %%dst_off+4 -%endif ; (%2-%%dst_off) ==/& 4 - -%if (%2-%%dst_off) == 1 - mov [r0+%%dst_off], vall -%elif (%2-%%dst_off) == 2 - mov [r0+%%dst_off], valw -%elif (%2-%%dst_off) == 3 -%ifidn %1, top - mov [r0+%%dst_off], valw2 +%if (%2-%%off) >= 4 +%if %2 > 8 && (%2-%%off) > 4 + movq [dstq+%2-8], mm %+ %%mmx_idx +%assign %%off %2 +%else + movd [dstq+%%off], mm %+ %%mmx_idx +%assign %%off %%off+4 +%endif +%assign %%mmx_idx %%mmx_idx+1 +%endif ; (%2-%%off) >= 4 + +%if (%2-%%off) >= 1 +%if %2 >= 4 + movd [dstq+%2-4], mm %+ %%mmx_idx +%elif (%2-%%off) == 1 + mov [dstq+%2-1], valb +%elif (%2-%%off) == 2 + mov [dstq+%2-2], valw %elifidn %1, body - mov [r0+%%dst_off], valw3 -%elifidn %1, bottom - mov [r0+%%dst_off], valw4 -%endif ; %1 ==/!= top - mov [r0+%%dst_off+2], vall -%endif ; (%2-%%dst_off) == 1/2/3 + mov [dstq+%2-3], valw + shr vald, 16 + mov [dstq+%2-1], valb +%else + movd vald, mm %+ %%mmx_idx + mov [dstq+%2-3], valw + shr vald, 16 + mov [dstq+%2-1], valb +%endif +%endif ; (%2-%%off) >= 1 %endmacro ; WRITE_NUM_BYTES ; vertical top/bottom extend and body copy fast loops ; these are function pointers to set-width line copy functions, i.e. ; they read a fixed number of pixels into set registers, and write ; those out into the destination buffer -; r0=buf,r1=src,r2=linesize,r3(64)/r3m(32)=start_x,r4=end_y,r5=block_h -; r6(eax/64)/r3(ebx/32)=val_reg -%macro VERTICAL_EXTEND 0 -%assign %%n 1 -%rep 22 -ALIGN 128 -.emuedge_v_extend_ %+ %%n: - ; extend pixels above body +%macro VERTICAL_EXTEND 2 +%assign %%n %1 +%rep 1+%2-%1 +%if %%n <= 3 %if ARCH_X86_64 - test r3 , r3 ; if (!start_y) - jz .emuedge_copy_body_ %+ %%n %+ _loop ; goto body -%else ; ARCH_X86_32 - cmp dword r3m, 0 - je .emuedge_copy_body_ %+ %%n %+ _loop -%endif ; ARCH_X86_64/32 - READ_NUM_BYTES top, %%n ; read bytes -.emuedge_extend_top_ %+ %%n %+ _loop: ; do { - WRITE_NUM_BYTES top, %%n ; write bytes - add r0 , r2 ; dst += linesize +cglobal emu_edge_vfix %+ %%n, 6, 8, 0, dst, dst_stride, src, src_stride, \ + start_y, end_y, val, bh + mov bhq, r6mp ; r6mp = bhmp +%else ; x86-32 +cglobal emu_edge_vfix %+ %%n, 0, 6, 0, val, dst, src, start_y, end_y, bh + mov dstq, r0mp + mov srcq, r2mp + mov start_yq, r4mp + mov end_yq, r5mp + mov bhq, r6mp +%define dst_strideq r1mp +%define src_strideq r3mp +%endif ; x86-64/32 +%else %if ARCH_X86_64 - dec r3d -%else ; ARCH_X86_32 - dec dword r3m -%endif ; ARCH_X86_64/32 - jnz .emuedge_extend_top_ %+ %%n %+ _loop ; } while (--start_y) +cglobal emu_edge_vfix %+ %%n, 7, 7, 1, dst, dst_stride, src, src_stride, \ + start_y, end_y, bh +%else ; x86-32 +cglobal emu_edge_vfix %+ %%n, 1, 5, 1, dst, src, start_y, end_y, bh + mov srcq, r2mp + mov start_yq, r4mp + mov end_yq, r5mp + mov bhq, r6mp +%define dst_strideq r1mp +%define src_strideq r3mp +%endif ; x86-64/32 +%endif + ; FIXME move this to c wrapper? + sub bhq, end_yq ; bh -= end_y + sub end_yq, start_yq ; end_y -= start_y + + ; extend pixels above body + test start_yq, start_yq ; if (start_y) { + jz .body_loop + READ_NUM_BYTES top, %%n ; $variable_regs = read($n) +.top_loop: ; do { + WRITE_NUM_BYTES top, %%n ; write($variable_regs, $n) + add dstq, dst_strideq ; dst += linesize + dec start_yq ; } while (--start_y) + jnz .top_loop ; } ; copy body pixels -.emuedge_copy_body_ %+ %%n %+ _loop: ; do { - READ_NUM_BYTES body, %%n ; read bytes - WRITE_NUM_BYTES body, %%n ; write bytes - add r0 , r2 ; dst += linesize - add r1 , r2 ; src += linesize - dec r4d - jnz .emuedge_copy_body_ %+ %%n %+ _loop ; } while (--end_y) +.body_loop: ; do { + READ_NUM_BYTES body, %%n ; $variable_regs = read($n) + WRITE_NUM_BYTES body, %%n ; write($variable_regs, $n) + add dstq, dst_strideq ; dst += dst_stride + add srcq, src_strideq ; src += src_stride + dec end_yq ; } while (--end_y) + jnz .body_loop ; copy bottom pixels - test r5 , r5 ; if (!block_h) - jz .emuedge_v_extend_end_ %+ %%n ; goto end - sub r1 , r2 ; src -= linesize - READ_NUM_BYTES bottom, %%n ; read bytes -.emuedge_extend_bottom_ %+ %%n %+ _loop: ; do { - WRITE_NUM_BYTES bottom, %%n ; write bytes - add r0 , r2 ; dst += linesize - dec r5d - jnz .emuedge_extend_bottom_ %+ %%n %+ _loop ; } while (--block_h) - -.emuedge_v_extend_end_ %+ %%n: -%if ARCH_X86_64 - ret -%else ; ARCH_X86_32 - rep ret -%endif ; ARCH_X86_64/32 + test bhq, bhq ; if (block_h) { + jz .end + sub srcq, src_strideq ; src -= linesize + READ_NUM_BYTES bottom, %%n ; $variable_regs = read($n) +.bottom_loop: ; do { + WRITE_NUM_BYTES bottom, %%n ; write($variable_regs, $n) + add dstq, dst_strideq ; dst += linesize + dec bhq ; } while (--bh) + jnz .bottom_loop ; } + +.end: + RET %assign %%n %%n+1 -%endrep -%endmacro VERTICAL_EXTEND +%endrep ; 1+%2-%1 +%endmacro ; VERTICAL_EXTEND + +INIT_MMX mmx +VERTICAL_EXTEND 1, 15 +%if ARCH_X86_32 +VERTICAL_EXTEND 16, 22 +%endif + +INIT_XMM sse +VERTICAL_EXTEND 16, 22 ; left/right (horizontal) fast extend functions ; these are essentially identical to the vertical extend ones above, ; just left/right separated because number of pixels to extend is ; obviously not the same on both sides. -; for reading, pixels are placed in eax (x86-64) or ebx (x86-64) in the -; lowest two bytes of the register (so val*0x0101), and are splatted -; into each byte of mm0 as well if n_pixels >= 8 %macro READ_V_PIXEL 2 - mov vall, %2 - mov valh, vall + movzx vald, byte %2 + imul vald, 0x01010101 %if %1 >= 8 - movd mm0, vald -%if cpuflag(mmxext) - pshufw mm0, mm0, 0 -%else ; mmx - punpcklwd mm0, mm0 - punpckldq mm0, mm0 -%endif ; sse -%endif ; %1 >= 8 -%endmacro + movd m0, vald +%if mmsize == 16 + pshufd m0, m0, q0000 +%else + punpckldq m0, m0 +%endif ; mmsize == 16 +%endif ; %1 > 16 +%endmacro ; READ_V_PIXEL %macro WRITE_V_PIXEL 2 -%assign %%dst_off 0 -%rep %1/8 - movq [%2+%%dst_off], mm0 -%assign %%dst_off %%dst_off+8 -%endrep -%if %1 & 4 -%if %1 >= 8 - movd [%2+%%dst_off], mm0 -%else ; %1 < 8 - mov [%2+%%dst_off] , valw - mov [%2+%%dst_off+2], valw -%endif ; %1 >=/< 8 -%assign %%dst_off %%dst_off+4 -%endif ; %1 & 4 -%if %1&2 - mov [%2+%%dst_off], valw -%endif ; %1 & 2 -%endmacro +%assign %%off 0 -; r0=buf+block_h*linesize, r1=start_x, r2=linesize, r5=block_h, r6/r3=val -%macro LEFT_EXTEND 0 -%assign %%n 2 -%rep 11 -ALIGN 64 -.emuedge_extend_left_ %+ %%n: ; do { - sub r0, r2 ; dst -= linesize - READ_V_PIXEL %%n, [r0+r1] ; read pixels - WRITE_V_PIXEL %%n, r0 ; write pixels - dec r5 - jnz .emuedge_extend_left_ %+ %%n ; } while (--block_h) -%if ARCH_X86_64 - ret -%else ; ARCH_X86_32 - rep ret -%endif ; ARCH_X86_64/32 -%assign %%n %%n+2 -%endrep -%endmacro ; LEFT_EXTEND - -; r3/r0=buf+block_h*linesize, r2=linesize, r8/r5=block_h, r0/r6=end_x, r6/r3=val -%macro RIGHT_EXTEND 0 -%assign %%n 2 -%rep 11 -ALIGN 64 -.emuedge_extend_right_ %+ %%n: ; do { -%if ARCH_X86_64 - sub r3, r2 ; dst -= linesize - READ_V_PIXEL %%n, [r3+w_reg-1] ; read pixels - WRITE_V_PIXEL %%n, r3+r4-%%n ; write pixels - dec r8 -%else ; ARCH_X86_32 - sub r0, r2 ; dst -= linesize - READ_V_PIXEL %%n, [r0+w_reg-1] ; read pixels - WRITE_V_PIXEL %%n, r0+r4-%%n ; write pixels - dec r5 -%endif ; ARCH_X86_64/32 - jnz .emuedge_extend_right_ %+ %%n ; } while (--block_h) -%if ARCH_X86_64 - ret -%else ; ARCH_X86_32 - rep ret -%endif ; ARCH_X86_64/32 -%assign %%n %%n+2 -%endrep - -%if ARCH_X86_32 -%define stack_offset 0x10 -%endif -%endmacro ; RIGHT_EXTEND - -; below follow the "slow" copy/extend functions, these act on a non-fixed -; width specified in a register, and run a loop to copy the full amount -; of bytes. They are optimized for copying of large amounts of pixels per -; line, so they unconditionally splat data into mm registers to copy 8 -; bytes per loop iteration. It could be considered to use xmm for x86-64 -; also, but I haven't optimized this as much (i.e. FIXME) -%macro V_COPY_NPX 4-5 -%if %0 == 4 - test w_reg, %4 - jz .%1_skip_%4_px -%else ; %0 == 5 -.%1_%4_px_loop: -%endif - %3 %2, [r1+cnt_reg] - %3 [r0+cnt_reg], %2 - add cnt_reg, %4 -%if %0 == 5 - sub w_reg, %4 - test w_reg, %5 - jnz .%1_%4_px_loop -%endif -.%1_skip_%4_px: -%endmacro +%if %1 >= 8 -%macro V_COPY_ROW 2 -%ifidn %1, bottom - sub r1, linesize -%endif -.%1_copy_loop: - xor cnt_reg, cnt_reg -%if notcpuflag(sse) -%define linesize r2m - V_COPY_NPX %1, mm0, movq, 8, 0xFFFFFFF8 -%else ; sse - V_COPY_NPX %1, xmm0, movups, 16, 0xFFFFFFF0 -%if ARCH_X86_64 -%define linesize r2 - V_COPY_NPX %1, rax , mov, 8 -%else ; ARCH_X86_32 -%define linesize r2m - V_COPY_NPX %1, mm0, movq, 8 -%endif ; ARCH_X86_64/32 -%endif ; sse - V_COPY_NPX %1, vald, mov, 4 - V_COPY_NPX %1, valw, mov, 2 - V_COPY_NPX %1, vall, mov, 1 - mov w_reg, cnt_reg -%ifidn %1, body - add r1, linesize -%endif - add r0, linesize - dec %2 - jnz .%1_copy_loop -%endmacro +%rep %1/mmsize + movu [%2+%%off], m0 +%assign %%off %%off+mmsize +%endrep ; %1/mmsize -%macro SLOW_V_EXTEND 0 -.slow_v_extend_loop: -; r0=buf,r1=src,r2(64)/r2m(32)=linesize,r3(64)/r3m(32)=start_x,r4=end_y,r5=block_h -; r8(64)/r3(later-64)/r2(32)=cnt_reg,r6(64)/r3(32)=val_reg,r7(64)/r6(32)=w=end_x-start_x -%if ARCH_X86_64 - push r8 ; save old value of block_h - test r3, r3 -%define cnt_reg r8 - jz .do_body_copy ; if (!start_y) goto do_body_copy - V_COPY_ROW top, r3 +%if mmsize == 16 +%if %1-%%off >= 8 +%if %1 > 16 && %1-%%off > 8 + movu [%2+%1-16], m0 +%assign %%off %1 %else - cmp dword r3m, 0 -%define cnt_reg r2 - je .do_body_copy ; if (!start_y) goto do_body_copy - V_COPY_ROW top, dword r3m + movq [%2+%%off], m0 +%assign %%off %%off+8 %endif +%endif ; %1-%%off >= 8 +%endif ; mmsize == 16 -.do_body_copy: - V_COPY_ROW body, r4 - -%if ARCH_X86_64 - pop r8 ; restore old value of block_h -%define cnt_reg r3 -%endif - test r5, r5 -%if ARCH_X86_64 - jz .v_extend_end +%if %1-%%off >= 4 +%if %1 > 8 && %1-%%off > 4 + movq [%2+%1-8], m0 +%assign %%off %1 %else - jz .skip_bottom_extend -%endif - V_COPY_ROW bottom, r5 -%if ARCH_X86_32 -.skip_bottom_extend: - mov r2, r2m + movd [%2+%%off], m0 +%assign %%off %%off+4 %endif - jmp .v_extend_end -%endmacro +%endif ; %1-%%off >= 4 -%macro SLOW_LEFT_EXTEND 0 -.slow_left_extend_loop: -; r0=buf+block_h*linesize,r2=linesize,r6(64)/r3(32)=val,r5=block_h,r4=cntr,r7/r6=start_x - mov r4, 8 - sub r0, linesize - READ_V_PIXEL 8, [r0+w_reg] -.left_extend_8px_loop: - movq [r0+r4-8], mm0 - add r4, 8 - cmp r4, w_reg - jle .left_extend_8px_loop - sub r4, 8 - cmp r4, w_reg - jge .left_extend_loop_end -.left_extend_2px_loop: - mov [r0+r4], valw - add r4, 2 - cmp r4, w_reg - jl .left_extend_2px_loop -.left_extend_loop_end: - dec r5 - jnz .slow_left_extend_loop -%if ARCH_X86_32 - mov r2, r2m -%endif - jmp .right_extend -%endmacro +%else ; %1 < 8 -%macro SLOW_RIGHT_EXTEND 0 -.slow_right_extend_loop: -; r3(64)/r0(32)=buf+block_h*linesize,r2=linesize,r4=block_w,r8(64)/r5(32)=block_h, -; r7(64)/r6(32)=end_x,r6/r3=val,r1=cntr -%if ARCH_X86_64 -%define buf_reg r3 -%define bh_reg r8 -%else -%define buf_reg r0 -%define bh_reg r5 -%endif - lea r1, [r4-8] - sub buf_reg, linesize - READ_V_PIXEL 8, [buf_reg+w_reg-1] -.right_extend_8px_loop: - movq [buf_reg+r1], mm0 - sub r1, 8 - cmp r1, w_reg - jge .right_extend_8px_loop - add r1, 8 - cmp r1, w_reg - je .right_extend_loop_end -.right_extend_2px_loop: - sub r1, 2 - mov [buf_reg+r1], valw - cmp r1, w_reg - jg .right_extend_2px_loop -.right_extend_loop_end: - dec bh_reg - jnz .slow_right_extend_loop - jmp .h_extend_end -%endmacro +%rep %1/4 + mov [%2+%%off], vald +%assign %%off %%off+4 +%endrep ; %1/4 -%macro emu_edge 1 -INIT_XMM %1 -EMU_EDGE_FUNC -VERTICAL_EXTEND -LEFT_EXTEND -RIGHT_EXTEND -SLOW_V_EXTEND -SLOW_LEFT_EXTEND -SLOW_RIGHT_EXTEND -%endmacro +%endif ; %1 >=/< 8 + +%if %1-%%off == 2 + mov [%2+%%off], valw +%endif ; (%1-%%off)/2 +%endmacro ; WRITE_V_PIXEL + +%macro H_EXTEND 2 +%assign %%n %1 +%rep 1+(%2-%1)/2 +cglobal emu_edge_hfix %+ %%n, 4, 5, 1, dst, dst_stride, start_x, bh, val +.loop_y: ; do { + READ_V_PIXEL %%n, [dstq+start_xq] ; $variable_regs = read($n) + WRITE_V_PIXEL %%n, dstq ; write($variable_regs, $n) + add dstq, dst_strideq ; dst += dst_stride + dec bhq ; } while (--bh) + jnz .loop_y + RET +%assign %%n %%n+2 +%endrep ; 1+(%2-%1)/2 +%endmacro ; H_EXTEND -emu_edge sse +INIT_MMX mmx +H_EXTEND 2, 14 %if ARCH_X86_32 -emu_edge mmx +H_EXTEND 16, 22 %endif +INIT_XMM sse2 +H_EXTEND 16, 22 + %macro PREFETCH_FN 1 cglobal prefetch, 3, 3, 0, buf, stride, h .loop: diff --git a/ffmpeg/libavcodec/x86/videodsp_init.c b/ffmpeg/libavcodec/x86/videodsp_init.c index 902450e..2013a93 100644 --- a/ffmpeg/libavcodec/x86/videodsp_init.c +++ b/ffmpeg/libavcodec/x86/videodsp_init.c @@ -26,36 +26,131 @@ #include "libavutil/cpu.h" #include "libavutil/mem.h" #include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" #include "libavcodec/videodsp.h" #if HAVE_YASM -typedef void emu_edge_core_func(uint8_t *buf, const uint8_t *src, - x86_reg linesize, x86_reg start_y, - x86_reg end_y, x86_reg block_h, - x86_reg start_x, x86_reg end_x, - x86_reg block_w); -extern emu_edge_core_func ff_emu_edge_core_mmx; -extern emu_edge_core_func ff_emu_edge_core_sse; - -static av_always_inline void emulated_edge_mc(uint8_t *buf, const uint8_t *src, - ptrdiff_t linesize_arg, - int block_w, int block_h, - int src_x, int src_y, - int w, int h, - emu_edge_core_func *core_fn) +typedef void emu_edge_vfix_func(uint8_t *dst, x86_reg dst_stride, + const uint8_t *src, x86_reg src_stride, + x86_reg start_y, x86_reg end_y, x86_reg bh); +typedef void emu_edge_vvar_func(uint8_t *dst, x86_reg dst_stride, + const uint8_t *src, x86_reg src_stride, + x86_reg start_y, x86_reg end_y, x86_reg bh, + x86_reg w); + +extern emu_edge_vfix_func ff_emu_edge_vfix1_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix2_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix3_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix4_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix5_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix6_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix7_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix8_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix9_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix10_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix11_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix12_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix13_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix14_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix15_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix16_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix17_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix18_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix19_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix20_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix21_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix22_mmx; +#if ARCH_X86_32 +static emu_edge_vfix_func *vfixtbl_mmx[22] = { + &ff_emu_edge_vfix1_mmx, &ff_emu_edge_vfix2_mmx, &ff_emu_edge_vfix3_mmx, + &ff_emu_edge_vfix4_mmx, &ff_emu_edge_vfix5_mmx, &ff_emu_edge_vfix6_mmx, + &ff_emu_edge_vfix7_mmx, &ff_emu_edge_vfix8_mmx, &ff_emu_edge_vfix9_mmx, + &ff_emu_edge_vfix10_mmx, &ff_emu_edge_vfix11_mmx, &ff_emu_edge_vfix12_mmx, + &ff_emu_edge_vfix13_mmx, &ff_emu_edge_vfix14_mmx, &ff_emu_edge_vfix15_mmx, + &ff_emu_edge_vfix16_mmx, &ff_emu_edge_vfix17_mmx, &ff_emu_edge_vfix18_mmx, + &ff_emu_edge_vfix19_mmx, &ff_emu_edge_vfix20_mmx, &ff_emu_edge_vfix21_mmx, + &ff_emu_edge_vfix22_mmx +}; +#endif +extern emu_edge_vvar_func ff_emu_edge_vvar_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix16_sse; +extern emu_edge_vfix_func ff_emu_edge_vfix17_sse; +extern emu_edge_vfix_func ff_emu_edge_vfix18_sse; +extern emu_edge_vfix_func ff_emu_edge_vfix19_sse; +extern emu_edge_vfix_func ff_emu_edge_vfix20_sse; +extern emu_edge_vfix_func ff_emu_edge_vfix21_sse; +extern emu_edge_vfix_func ff_emu_edge_vfix22_sse; +static emu_edge_vfix_func *vfixtbl_sse[22] = { + ff_emu_edge_vfix1_mmx, ff_emu_edge_vfix2_mmx, ff_emu_edge_vfix3_mmx, + ff_emu_edge_vfix4_mmx, ff_emu_edge_vfix5_mmx, ff_emu_edge_vfix6_mmx, + ff_emu_edge_vfix7_mmx, ff_emu_edge_vfix8_mmx, ff_emu_edge_vfix9_mmx, + ff_emu_edge_vfix10_mmx, ff_emu_edge_vfix11_mmx, ff_emu_edge_vfix12_mmx, + ff_emu_edge_vfix13_mmx, ff_emu_edge_vfix14_mmx, ff_emu_edge_vfix15_mmx, + ff_emu_edge_vfix16_sse, ff_emu_edge_vfix17_sse, ff_emu_edge_vfix18_sse, + ff_emu_edge_vfix19_sse, ff_emu_edge_vfix20_sse, ff_emu_edge_vfix21_sse, + ff_emu_edge_vfix22_sse +}; +extern emu_edge_vvar_func ff_emu_edge_vvar_sse; + +typedef void emu_edge_hfix_func(uint8_t *dst, x86_reg dst_stride, + x86_reg start_x, x86_reg bh); +typedef void emu_edge_hvar_func(uint8_t *dst, x86_reg dst_stride, + x86_reg start_x, x86_reg n_words, x86_reg bh); + +extern emu_edge_hfix_func ff_emu_edge_hfix2_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix4_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix6_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix8_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix10_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix12_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix14_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix16_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix18_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix20_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix22_mmx; +#if ARCH_X86_32 +static emu_edge_hfix_func *hfixtbl_mmx[11] = { + ff_emu_edge_hfix2_mmx, ff_emu_edge_hfix4_mmx, ff_emu_edge_hfix6_mmx, + ff_emu_edge_hfix8_mmx, ff_emu_edge_hfix10_mmx, ff_emu_edge_hfix12_mmx, + ff_emu_edge_hfix14_mmx, ff_emu_edge_hfix16_mmx, ff_emu_edge_hfix18_mmx, + ff_emu_edge_hfix20_mmx, ff_emu_edge_hfix22_mmx +}; +#endif +extern emu_edge_hvar_func ff_emu_edge_hvar_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix16_sse2; +extern emu_edge_hfix_func ff_emu_edge_hfix18_sse2; +extern emu_edge_hfix_func ff_emu_edge_hfix20_sse2; +extern emu_edge_hfix_func ff_emu_edge_hfix22_sse2; +static emu_edge_hfix_func *hfixtbl_sse2[11] = { + ff_emu_edge_hfix2_mmx, ff_emu_edge_hfix4_mmx, ff_emu_edge_hfix6_mmx, + ff_emu_edge_hfix8_mmx, ff_emu_edge_hfix10_mmx, ff_emu_edge_hfix12_mmx, + ff_emu_edge_hfix14_mmx, ff_emu_edge_hfix16_sse2, ff_emu_edge_hfix18_sse2, + ff_emu_edge_hfix20_sse2, ff_emu_edge_hfix22_sse2 +}; +extern emu_edge_hvar_func ff_emu_edge_hvar_sse2; + +static av_always_inline void emulated_edge_mc(uint8_t *dst, const uint8_t *src, + ptrdiff_t dst_stride, + ptrdiff_t src_stride, + x86_reg block_w, x86_reg block_h, + x86_reg src_x, x86_reg src_y, + x86_reg w, x86_reg h, + emu_edge_vfix_func **vfix_tbl, + emu_edge_vvar_func *v_extend_var, + emu_edge_hfix_func **hfix_tbl, + emu_edge_hvar_func *h_extend_var) { - int start_y, start_x, end_y, end_x, src_y_add = 0; - int linesize = linesize_arg; + x86_reg start_y, start_x, end_y, end_x, src_y_add = 0, p; - if(!w || !h) + if (!w || !h) return; if (src_y >= h) { - src -= src_y*linesize; + src -= src_y*src_stride; src_y_add = h - 1; src_y = h - 1; } else if (src_y <= -block_h) { - src -= src_y*linesize; + src -= src_y*src_stride; src_y_add = 1 - block_h; src_y = 1 - block_h; } @@ -75,30 +170,72 @@ static av_always_inline void emulated_edge_mc(uint8_t *buf, const uint8_t *src, av_assert2(start_y < end_y && block_h > 0); // fill in the to-be-copied part plus all above/below - src += (src_y_add + start_y) * linesize + start_x; - buf += start_x; - core_fn(buf, src, linesize, start_y, end_y, - block_h, start_x, end_x, block_w); + src += (src_y_add + start_y) * src_stride + start_x; + w = end_x - start_x; + if (w <= 22) { + vfix_tbl[w - 1](dst + start_x, dst_stride, src, src_stride, + start_y, end_y, block_h); + } else { + v_extend_var(dst + start_x, dst_stride, src, src_stride, + start_y, end_y, block_h, w); + } + + // fill left + if (start_x) { + if (start_x <= 22) { + hfix_tbl[(start_x - 1) >> 1](dst, dst_stride, start_x, block_h); + } else { + h_extend_var(dst, dst_stride, + start_x, (start_x + 1) >> 1, block_h); + } + } + + // fill right + p = block_w - end_x; + if (p) { + if (p <= 22) { + hfix_tbl[(p - 1) >> 1](dst + end_x - (p & 1), dst_stride, + -!(p & 1), block_h); + } else { + h_extend_var(dst + end_x - (p & 1), dst_stride, + -!(p & 1), (p + 1) >> 1, block_h); + } + } } #if ARCH_X86_32 static av_noinline void emulated_edge_mc_mmx(uint8_t *buf, const uint8_t *src, - ptrdiff_t linesize, + ptrdiff_t buf_stride, + ptrdiff_t src_stride, int block_w, int block_h, int src_x, int src_y, int w, int h) { - emulated_edge_mc(buf, src, linesize, block_w, block_h, src_x, src_y, - w, h, &ff_emu_edge_core_mmx); + emulated_edge_mc(buf, src, buf_stride, src_stride, block_w, block_h, + src_x, src_y, w, h, vfixtbl_mmx, &ff_emu_edge_vvar_mmx, + hfixtbl_mmx, &ff_emu_edge_hvar_mmx); } -#endif static av_noinline void emulated_edge_mc_sse(uint8_t *buf, const uint8_t *src, - ptrdiff_t linesize, + ptrdiff_t buf_stride, + ptrdiff_t src_stride, int block_w, int block_h, int src_x, int src_y, int w, int h) { - emulated_edge_mc(buf, src, linesize, block_w, block_h, src_x, src_y, - w, h, &ff_emu_edge_core_sse); + emulated_edge_mc(buf, src, buf_stride, src_stride, block_w, block_h, + src_x, src_y, w, h, vfixtbl_sse, &ff_emu_edge_vvar_sse, + hfixtbl_mmx, &ff_emu_edge_hvar_mmx); +} +#endif + +static av_noinline void emulated_edge_mc_sse2(uint8_t *buf, const uint8_t *src, + ptrdiff_t buf_stride, + ptrdiff_t src_stride, + int block_w, int block_h, + int src_x, int src_y, int w, int h) +{ + emulated_edge_mc(buf, src, buf_stride, src_stride, block_w, block_h, + src_x, src_y, w, h, vfixtbl_sse, &ff_emu_edge_vvar_sse, + hfixtbl_sse2, &ff_emu_edge_hvar_sse2); } #endif /* HAVE_YASM */ @@ -108,21 +245,26 @@ void ff_prefetch_3dnow(uint8_t *buf, ptrdiff_t stride, int h); av_cold void ff_videodsp_init_x86(VideoDSPContext *ctx, int bpc) { #if HAVE_YASM - int mm_flags = av_get_cpu_flags(); + int cpu_flags = av_get_cpu_flags(); #if ARCH_X86_32 - if (bpc <= 8 && mm_flags & AV_CPU_FLAG_MMX) { + if (EXTERNAL_MMX(cpu_flags) && bpc <= 8) { ctx->emulated_edge_mc = emulated_edge_mc_mmx; } - if (mm_flags & AV_CPU_FLAG_3DNOW) { + if (EXTERNAL_AMD3DNOW(cpu_flags)) { ctx->prefetch = ff_prefetch_3dnow; } #endif /* ARCH_X86_32 */ - if (mm_flags & AV_CPU_FLAG_MMXEXT) { + if (EXTERNAL_MMXEXT(cpu_flags)) { ctx->prefetch = ff_prefetch_mmxext; } - if (bpc <= 8 && mm_flags & AV_CPU_FLAG_SSE) { +#if ARCH_X86_32 + if (EXTERNAL_SSE(cpu_flags) && bpc <= 8) { ctx->emulated_edge_mc = emulated_edge_mc_sse; } +#endif /* ARCH_X86_32 */ + if (EXTERNAL_SSE2(cpu_flags) && bpc <= 8) { + ctx->emulated_edge_mc = emulated_edge_mc_sse2; + } #endif /* HAVE_YASM */ } diff --git a/ffmpeg/libavcodec/x86/vorbisdsp_init.c b/ffmpeg/libavcodec/x86/vorbisdsp_init.c index 08a2c09..284a528 100644 --- a/ffmpeg/libavcodec/x86/vorbisdsp_init.c +++ b/ffmpeg/libavcodec/x86/vorbisdsp_init.c @@ -21,6 +21,7 @@ #include "config.h" #include "libavutil/attributes.h" #include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" #include "libavcodec/vorbisdsp.h" void ff_vorbis_inverse_coupling_3dnow(float *mag, float *ang, @@ -31,13 +32,13 @@ void ff_vorbis_inverse_coupling_sse(float *mag, float *ang, av_cold void ff_vorbisdsp_init_x86(VorbisDSPContext *dsp) { #if HAVE_YASM - int mm_flags = av_get_cpu_flags(); + int cpu_flags = av_get_cpu_flags(); #if ARCH_X86_32 - if (mm_flags & AV_CPU_FLAG_3DNOW) + if (EXTERNAL_AMD3DNOW(cpu_flags)) dsp->vorbis_inverse_coupling = ff_vorbis_inverse_coupling_3dnow; #endif /* ARCH_X86_32 */ - if (mm_flags & AV_CPU_FLAG_SSE) + if (EXTERNAL_SSE(cpu_flags)) dsp->vorbis_inverse_coupling = ff_vorbis_inverse_coupling_sse; #endif /* HAVE_YASM */ } diff --git a/ffmpeg/libavcodec/x86/vp3dsp.asm b/ffmpeg/libavcodec/x86/vp3dsp.asm index a47b8f2..24496ae 100644 --- a/ffmpeg/libavcodec/x86/vp3dsp.asm +++ b/ffmpeg/libavcodec/x86/vp3dsp.asm @@ -33,7 +33,7 @@ vp3_idct_data: times 8 dw 64277 times 8 dw 25080 times 8 dw 12785 -pb_7: times 8 db 7 +pb_7: times 8 db 0x07 pb_1F: times 8 db 0x1f pb_81: times 8 db 0x81 diff --git a/ffmpeg/libavcodec/x86/vp3dsp_init.c b/ffmpeg/libavcodec/x86/vp3dsp_init.c index 252b40a..1f02a6f 100644 --- a/ffmpeg/libavcodec/x86/vp3dsp_init.c +++ b/ffmpeg/libavcodec/x86/vp3dsp_init.c @@ -43,7 +43,7 @@ void ff_vp3_v_loop_filter_mmxext(uint8_t *src, int stride, void ff_vp3_h_loop_filter_mmxext(uint8_t *src, int stride, int *bounding_values); -#if HAVE_INLINE_ASM +#if HAVE_MMX_INLINE #define MOVQ_BFE(regd) \ __asm__ volatile ( \ @@ -95,24 +95,24 @@ static void put_vp_no_rnd_pixels8_l2_mmx(uint8_t *dst, const uint8_t *a, const u :"memory"); // STOP_TIMER("put_vp_no_rnd_pixels8_l2_mmx") } -#endif /* HAVE_INLINE_ASM */ +#endif /* HAVE_MMX_INLINE */ av_cold void ff_vp3dsp_init_x86(VP3DSPContext *c, int flags) { - int cpuflags = av_get_cpu_flags(); + int cpu_flags = av_get_cpu_flags(); -#if HAVE_INLINE_ASM +#if HAVE_MMX_INLINE c->put_no_rnd_pixels_l2 = put_vp_no_rnd_pixels8_l2_mmx; -#endif /* HAVE_INLINE_ASM */ +#endif /* HAVE_MMX_INLINE */ #if ARCH_X86_32 - if (EXTERNAL_MMX(cpuflags)) { + if (EXTERNAL_MMX(cpu_flags)) { c->idct_put = ff_vp3_idct_put_mmx; c->idct_add = ff_vp3_idct_add_mmx; } #endif - if (EXTERNAL_MMXEXT(cpuflags)) { + if (EXTERNAL_MMXEXT(cpu_flags)) { c->idct_dc_add = ff_vp3_idct_dc_add_mmxext; if (!(flags & CODEC_FLAG_BITEXACT)) { @@ -121,7 +121,7 @@ av_cold void ff_vp3dsp_init_x86(VP3DSPContext *c, int flags) } } - if (EXTERNAL_SSE2(cpuflags)) { + if (EXTERNAL_SSE2(cpu_flags)) { c->idct_put = ff_vp3_idct_put_sse2; c->idct_add = ff_vp3_idct_add_sse2; } diff --git a/ffmpeg/libavcodec/x86/vp56dsp.asm b/ffmpeg/libavcodec/x86/vp56dsp.asm deleted file mode 100644 index 3d874ea..0000000 --- a/ffmpeg/libavcodec/x86/vp56dsp.asm +++ /dev/null @@ -1,170 +0,0 @@ -;****************************************************************************** -;* MMX/SSE2-optimized functions for the VP6 decoder -;* Copyright (C) 2009 Sebastien Lucas -;* Copyright (C) 2009 Zuxy Meng -;* -;* This file is part of FFmpeg. -;* -;* FFmpeg is free software; you can redistribute it and/or -;* modify it under the terms of the GNU Lesser General Public -;* License as published by the Free Software Foundation; either -;* version 2.1 of the License, or (at your option) any later version. -;* -;* FFmpeg is distributed in the hope that it will be useful, -;* but WITHOUT ANY WARRANTY; without even the implied warranty of -;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;* Lesser General Public License for more details. -;* -;* You should have received a copy of the GNU Lesser General Public -;* License along with FFmpeg; if not, write to the Free Software -;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -;****************************************************************************** - -%include "libavutil/x86/x86util.asm" - -cextern pw_64 - -SECTION .text - -%macro DIAG4 6 -%if mmsize == 8 - movq m0, [%1+%2] - movq m1, [%1+%3] - movq m3, m0 - movq m4, m1 - punpcklbw m0, m7 - punpcklbw m1, m7 - punpckhbw m3, m7 - punpckhbw m4, m7 - pmullw m0, [rsp+8*11] ; src[x-8 ] * biweight [0] - pmullw m1, [rsp+8*12] ; src[x ] * biweight [1] - pmullw m3, [rsp+8*11] ; src[x-8 ] * biweight [0] - pmullw m4, [rsp+8*12] ; src[x ] * biweight [1] - paddw m0, m1 - paddw m3, m4 - movq m1, [%1+%4] - movq m2, [%1+%5] - movq m4, m1 - movq m5, m2 - punpcklbw m1, m7 - punpcklbw m2, m7 - punpckhbw m4, m7 - punpckhbw m5, m7 - pmullw m1, [rsp+8*13] ; src[x+8 ] * biweight [2] - pmullw m2, [rsp+8*14] ; src[x+16] * biweight [3] - pmullw m4, [rsp+8*13] ; src[x+8 ] * biweight [2] - pmullw m5, [rsp+8*14] ; src[x+16] * biweight [3] - paddw m1, m2 - paddw m4, m5 - paddsw m0, m1 - paddsw m3, m4 - paddsw m0, m6 ; Add 64 - paddsw m3, m6 ; Add 64 - psraw m0, 7 - psraw m3, 7 - packuswb m0, m3 - movq [%6], m0 -%else ; mmsize == 16 - movq m0, [%1+%2] - movq m1, [%1+%3] - punpcklbw m0, m7 - punpcklbw m1, m7 - pmullw m0, m4 ; src[x-8 ] * biweight [0] - pmullw m1, m5 ; src[x ] * biweight [1] - paddw m0, m1 - movq m1, [%1+%4] - movq m2, [%1+%5] - punpcklbw m1, m7 - punpcklbw m2, m7 - pmullw m1, m6 ; src[x+8 ] * biweight [2] - pmullw m2, m3 ; src[x+16] * biweight [3] - paddw m1, m2 - paddsw m0, m1 - paddsw m0, [pw_64] ; Add 64 - psraw m0, 7 - packuswb m0, m0 - movq [%6], m0 -%endif ; mmsize == 8/16 -%endmacro - -%macro SPLAT4REGS 0 -%if mmsize == 8 - movq m5, m3 - punpcklwd m3, m3 - movq m4, m3 - punpckldq m3, m3 - punpckhdq m4, m4 - punpckhwd m5, m5 - movq m2, m5 - punpckhdq m2, m2 - punpckldq m5, m5 - movq [rsp+8*11], m3 - movq [rsp+8*12], m4 - movq [rsp+8*13], m5 - movq [rsp+8*14], m2 -%else ; mmsize == 16 - pshuflw m4, m3, 0x0 - pshuflw m5, m3, 0x55 - pshuflw m6, m3, 0xAA - pshuflw m3, m3, 0xFF - punpcklqdq m4, m4 - punpcklqdq m5, m5 - punpcklqdq m6, m6 - punpcklqdq m3, m3 -%endif ; mmsize == 8/16 -%endmacro - -%macro vp6_filter_diag4 0 -; void ff_vp6_filter_diag4_(uint8_t *dst, uint8_t *src, int stride, -; const int16_t h_weight[4], const int16_t v_weights[4]) -cglobal vp6_filter_diag4, 5, 7, 8 - mov r5, rsp ; backup stack pointer - and rsp, ~(mmsize-1) ; align stack -%if mmsize == 16 - sub rsp, 8*11 -%else - sub rsp, 8*15 - movq m6, [pw_64] -%endif -%if ARCH_X86_64 - movsxd r2, r2d -%endif - - sub r1, r2 - - pxor m7, m7 - movq m3, [r3] - SPLAT4REGS - - mov r3, rsp - mov r6, 11 -.nextrow: - DIAG4 r1, -1, 0, 1, 2, r3 - add r3, 8 - add r1, r2 - dec r6 - jnz .nextrow - - movq m3, [r4] - SPLAT4REGS - - lea r3, [rsp+8] - mov r6, 8 -.nextcol: - DIAG4 r3, -8, 0, 8, 16, r0 - add r3, 8 - add r0, r2 - dec r6 - jnz .nextcol - - mov rsp, r5 ; restore stack pointer - RET -%endmacro - -%if ARCH_X86_32 -INIT_MMX mmx -vp6_filter_diag4 -%endif - -INIT_XMM sse2 -vp6_filter_diag4 diff --git a/ffmpeg/libavcodec/x86/vp56dsp_init.c b/ffmpeg/libavcodec/x86/vp56dsp_init.c deleted file mode 100644 index defc63b..0000000 --- a/ffmpeg/libavcodec/x86/vp56dsp_init.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * VP6 MMX/SSE2 optimizations - * Copyright (C) 2009 Sebastien Lucas - * Copyright (C) 2009 Zuxy Meng - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/cpu.h" -#include "libavutil/x86/asm.h" -#include "libavutil/x86/cpu.h" -#include "libavcodec/vp56dsp.h" - -void ff_vp6_filter_diag4_mmx(uint8_t *dst, uint8_t *src, int stride, - const int16_t *h_weights,const int16_t *v_weights); -void ff_vp6_filter_diag4_sse2(uint8_t *dst, uint8_t *src, int stride, - const int16_t *h_weights,const int16_t *v_weights); - -av_cold void ff_vp56dsp_init_x86(VP56DSPContext* c, enum AVCodecID codec) -{ - int mm_flags = av_get_cpu_flags(); - - if (CONFIG_VP6_DECODER && codec == AV_CODEC_ID_VP6) { -#if ARCH_X86_32 - if (EXTERNAL_MMX(mm_flags)) { - c->vp6_filter_diag4 = ff_vp6_filter_diag4_mmx; - } -#endif - - if (EXTERNAL_SSE2(mm_flags)) { - c->vp6_filter_diag4 = ff_vp6_filter_diag4_sse2; - } - } -} diff --git a/ffmpeg/libavcodec/x86/vp8dsp.asm b/ffmpeg/libavcodec/x86/vp8dsp.asm index ca07333..85c7e99 100644 --- a/ffmpeg/libavcodec/x86/vp8dsp.asm +++ b/ffmpeg/libavcodec/x86/vp8dsp.asm @@ -143,27 +143,13 @@ filter_h6_shuf1: db 0, 5, 1, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12 filter_h6_shuf2: db 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9 filter_h6_shuf3: db 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11 -pw_27: times 8 dw 27 -pw_63: times 8 dw 63 pw_256: times 8 dw 256 pw_20091: times 4 dw 20091 pw_17734: times 4 dw 17734 -pb_4: times 16 db 4 -pb_F8: times 16 db 0xF8 -pb_FE: times 16 db 0xFE -pb_27_63: times 8 db 27, 63 -pb_18_63: times 8 db 18, 63 -pb_9_63: times 8 db 9, 63 - -cextern pb_1 cextern pw_3 -cextern pb_3 cextern pw_4 -cextern pw_9 -cextern pw_18 cextern pw_64 -cextern pb_80 SECTION .text @@ -1237,1544 +1223,3 @@ VP8_DC_WHT %endif INIT_MMX sse VP8_DC_WHT - -;----------------------------------------------------------------------------- -; void vp8_h/v_loop_filter_simple_(uint8_t *dst, int stride, int flim); -;----------------------------------------------------------------------------- - -; macro called with 7 mm register indexes as argument, and 4 regular registers -; -; first 4 mm registers will carry the transposed pixel data -; the other three are scratchspace (one would be sufficient, but this allows -; for more spreading/pipelining and thus faster execution on OOE CPUs) -; -; first two regular registers are buf+4*stride and buf+5*stride -; third is -stride, fourth is +stride -%macro READ_8x4_INTERLEAVED 11 - ; interleave 8 (A-H) rows of 4 pixels each - movd m%1, [%8+%10*4] ; A0-3 - movd m%5, [%9+%10*4] ; B0-3 - movd m%2, [%8+%10*2] ; C0-3 - movd m%6, [%8+%10] ; D0-3 - movd m%3, [%8] ; E0-3 - movd m%7, [%9] ; F0-3 - movd m%4, [%9+%11] ; G0-3 - punpcklbw m%1, m%5 ; A/B interleaved - movd m%5, [%9+%11*2] ; H0-3 - punpcklbw m%2, m%6 ; C/D interleaved - punpcklbw m%3, m%7 ; E/F interleaved - punpcklbw m%4, m%5 ; G/H interleaved -%endmacro - -; macro called with 7 mm register indexes as argument, and 5 regular registers -; first 11 mean the same as READ_8x4_TRANSPOSED above -; fifth regular register is scratchspace to reach the bottom 8 rows, it -; will be set to second regular register + 8*stride at the end -%macro READ_16x4_INTERLEAVED 12 - ; transpose 16 (A-P) rows of 4 pixels each - lea %12, [r0+8*r2] - - ; read (and interleave) those addressable by %8 (=r0), A/C/D/E/I/K/L/M - movd m%1, [%8+%10*4] ; A0-3 - movd m%3, [%12+%10*4] ; I0-3 - movd m%2, [%8+%10*2] ; C0-3 - movd m%4, [%12+%10*2] ; K0-3 - movd m%6, [%8+%10] ; D0-3 - movd m%5, [%12+%10] ; L0-3 - movd m%7, [%12] ; M0-3 - add %12, %11 - punpcklbw m%1, m%3 ; A/I - movd m%3, [%8] ; E0-3 - punpcklbw m%2, m%4 ; C/K - punpcklbw m%6, m%5 ; D/L - punpcklbw m%3, m%7 ; E/M - punpcklbw m%2, m%6 ; C/D/K/L interleaved - - ; read (and interleave) those addressable by %9 (=r4), B/F/G/H/J/N/O/P - movd m%5, [%9+%10*4] ; B0-3 - movd m%4, [%12+%10*4] ; J0-3 - movd m%7, [%9] ; F0-3 - movd m%6, [%12] ; N0-3 - punpcklbw m%5, m%4 ; B/J - punpcklbw m%7, m%6 ; F/N - punpcklbw m%1, m%5 ; A/B/I/J interleaved - punpcklbw m%3, m%7 ; E/F/M/N interleaved - movd m%4, [%9+%11] ; G0-3 - movd m%6, [%12+%11] ; O0-3 - movd m%5, [%9+%11*2] ; H0-3 - movd m%7, [%12+%11*2] ; P0-3 - punpcklbw m%4, m%6 ; G/O - punpcklbw m%5, m%7 ; H/P - punpcklbw m%4, m%5 ; G/H/O/P interleaved -%endmacro - -; write 4 mm registers of 2 dwords each -; first four arguments are mm register indexes containing source data -; last four are registers containing buf+4*stride, buf+5*stride, -; -stride and +stride -%macro WRITE_4x2D 8 - ; write out (2 dwords per register) - movd [%5+%7*4], m%1 - movd [%5+%7*2], m%2 - movd [%5], m%3 - movd [%6+%8], m%4 - punpckhdq m%1, m%1 - punpckhdq m%2, m%2 - punpckhdq m%3, m%3 - punpckhdq m%4, m%4 - movd [%6+%7*4], m%1 - movd [%5+%7], m%2 - movd [%6], m%3 - movd [%6+%8*2], m%4 -%endmacro - -; write 4 xmm registers of 4 dwords each -; arguments same as WRITE_2x4D, but with an extra register, so that the 5 regular -; registers contain buf+4*stride, buf+5*stride, buf+12*stride, -stride and +stride -; we add 1*stride to the third regular registry in the process -; the 10th argument is 16 if it's a Y filter (i.e. all regular registers cover the -; same memory region), or 8 if they cover two separate buffers (third one points to -; a different memory region than the first two), allowing for more optimal code for -; the 16-width case -%macro WRITE_4x4D 10 - ; write out (4 dwords per register), start with dwords zero - movd [%5+%8*4], m%1 - movd [%5], m%2 - movd [%7+%8*4], m%3 - movd [%7], m%4 - - ; store dwords 1 - psrldq m%1, 4 - psrldq m%2, 4 - psrldq m%3, 4 - psrldq m%4, 4 - movd [%6+%8*4], m%1 - movd [%6], m%2 -%if %10 == 16 - movd [%6+%9*4], m%3 -%endif - movd [%7+%9], m%4 - - ; write dwords 2 - psrldq m%1, 4 - psrldq m%2, 4 -%if %10 == 8 - movd [%5+%8*2], m%1 - movd %5d, m%3 -%endif - psrldq m%3, 4 - psrldq m%4, 4 -%if %10 == 16 - movd [%5+%8*2], m%1 -%endif - movd [%6+%9], m%2 - movd [%7+%8*2], m%3 - movd [%7+%9*2], m%4 - add %7, %9 - - ; store dwords 3 - psrldq m%1, 4 - psrldq m%2, 4 - psrldq m%3, 4 - psrldq m%4, 4 -%if %10 == 8 - mov [%7+%8*4], %5d - movd [%6+%8*2], m%1 -%else - movd [%5+%8], m%1 -%endif - movd [%6+%9*2], m%2 - movd [%7+%8*2], m%3 - movd [%7+%9*2], m%4 -%endmacro - -; write 4 or 8 words in the mmx/xmm registers as 8 lines -; 1 and 2 are the registers to write, this can be the same (for SSE2) -; for pre-SSE4: -; 3 is a general-purpose register that we will clobber -; for SSE4: -; 3 is a pointer to the destination's 5th line -; 4 is a pointer to the destination's 4th line -; 5/6 is -stride and +stride -%macro WRITE_2x4W 6 - movd %3d, %1 - punpckhdq %1, %1 - mov [%4+%5*4], %3w - shr %3, 16 - add %4, %6 - mov [%4+%5*4], %3w - - movd %3d, %1 - add %4, %5 - mov [%4+%5*2], %3w - shr %3, 16 - mov [%4+%5 ], %3w - - movd %3d, %2 - punpckhdq %2, %2 - mov [%4 ], %3w - shr %3, 16 - mov [%4+%6 ], %3w - - movd %3d, %2 - add %4, %6 - mov [%4+%6 ], %3w - shr %3, 16 - mov [%4+%6*2], %3w - add %4, %5 -%endmacro - -%macro WRITE_8W 5 -%if cpuflag(sse4) - pextrw [%3+%4*4], %1, 0 - pextrw [%2+%4*4], %1, 1 - pextrw [%3+%4*2], %1, 2 - pextrw [%3+%4 ], %1, 3 - pextrw [%3 ], %1, 4 - pextrw [%2 ], %1, 5 - pextrw [%2+%5 ], %1, 6 - pextrw [%2+%5*2], %1, 7 -%else - movd %2d, %1 - psrldq %1, 4 - mov [%3+%4*4], %2w - shr %2, 16 - add %3, %5 - mov [%3+%4*4], %2w - - movd %2d, %1 - psrldq %1, 4 - add %3, %4 - mov [%3+%4*2], %2w - shr %2, 16 - mov [%3+%4 ], %2w - - movd %2d, %1 - psrldq %1, 4 - mov [%3 ], %2w - shr %2, 16 - mov [%3+%5 ], %2w - - movd %2d, %1 - add %3, %5 - mov [%3+%5 ], %2w - shr %2, 16 - mov [%3+%5*2], %2w -%endif -%endmacro - -%macro SIMPLE_LOOPFILTER 2 -cglobal vp8_%1_loop_filter_simple, 3, %2, 8, dst, stride, flim, cntr -%if mmsize == 8 ; mmx/mmxext - mov cntrq, 2 -%endif -%if cpuflag(ssse3) - pxor m0, m0 -%endif - SPLATB_REG m7, flim, m0 ; splat "flim" into register - - ; set up indexes to address 4 rows -%if mmsize == 8 - DEFINE_ARGS dst1, mstride, stride, cntr, dst2 -%else - DEFINE_ARGS dst1, mstride, stride, dst3, dst2 -%endif - mov strideq, mstrideq - neg mstrideq -%ifidn %1, h - lea dst1q, [dst1q+4*strideq-2] -%endif - -%if mmsize == 8 ; mmx / mmxext -.next8px: -%endif -%ifidn %1, v - ; read 4 half/full rows of pixels - mova m0, [dst1q+mstrideq*2] ; p1 - mova m1, [dst1q+mstrideq] ; p0 - mova m2, [dst1q] ; q0 - mova m3, [dst1q+ strideq] ; q1 -%else ; h - lea dst2q, [dst1q+ strideq] - -%if mmsize == 8 ; mmx/mmxext - READ_8x4_INTERLEAVED 0, 1, 2, 3, 4, 5, 6, dst1q, dst2q, mstrideq, strideq -%else ; sse2 - READ_16x4_INTERLEAVED 0, 1, 2, 3, 4, 5, 6, dst1q, dst2q, mstrideq, strideq, dst3q -%endif - TRANSPOSE4x4W 0, 1, 2, 3, 4 -%endif - - ; simple_limit - mova m5, m2 ; m5=backup of q0 - mova m6, m1 ; m6=backup of p0 - psubusb m1, m2 ; p0-q0 - psubusb m2, m6 ; q0-p0 - por m1, m2 ; FFABS(p0-q0) - paddusb m1, m1 ; m1=FFABS(p0-q0)*2 - - mova m4, m3 - mova m2, m0 - psubusb m3, m0 ; q1-p1 - psubusb m0, m4 ; p1-q1 - por m3, m0 ; FFABS(p1-q1) - mova m0, [pb_80] - pxor m2, m0 - pxor m4, m0 - psubsb m2, m4 ; m2=p1-q1 (signed) backup for below - pand m3, [pb_FE] - psrlq m3, 1 ; m3=FFABS(p1-q1)/2, this can be used signed - paddusb m3, m1 - psubusb m3, m7 - pxor m1, m1 - pcmpeqb m3, m1 ; abs(p0-q0)*2+abs(p1-q1)/2<=flim mask(0xff/0x0) - - ; filter_common (use m2/p1-q1, m4=q0, m6=p0, m5/q0-p0 and m3/mask) - mova m4, m5 - pxor m5, m0 - pxor m0, m6 - psubsb m5, m0 ; q0-p0 (signed) - paddsb m2, m5 - paddsb m2, m5 - paddsb m2, m5 ; a=(p1-q1) + 3*(q0-p0) - pand m2, m3 ; apply filter mask (m3) - - mova m3, [pb_F8] - mova m1, m2 - paddsb m2, [pb_4] ; f1<<3=a+4 - paddsb m1, [pb_3] ; f2<<3=a+3 - pand m2, m3 - pand m1, m3 ; cache f2<<3 - - pxor m0, m0 - pxor m3, m3 - pcmpgtb m0, m2 ; which values are <0? - psubb m3, m2 ; -f1<<3 - psrlq m2, 3 ; +f1 - psrlq m3, 3 ; -f1 - pand m3, m0 - pandn m0, m2 - psubusb m4, m0 - paddusb m4, m3 ; q0-f1 - - pxor m0, m0 - pxor m3, m3 - pcmpgtb m0, m1 ; which values are <0? - psubb m3, m1 ; -f2<<3 - psrlq m1, 3 ; +f2 - psrlq m3, 3 ; -f2 - pand m3, m0 - pandn m0, m1 - paddusb m6, m0 - psubusb m6, m3 ; p0+f2 - - ; store -%ifidn %1, v - mova [dst1q], m4 - mova [dst1q+mstrideq], m6 -%else ; h - inc dst1q - SBUTTERFLY bw, 6, 4, 0 - -%if mmsize == 16 ; sse2 -%if cpuflag(sse4) - inc dst2q -%endif - WRITE_8W m6, dst2q, dst1q, mstrideq, strideq - lea dst2q, [dst3q+mstrideq+1] -%if cpuflag(sse4) - inc dst3q -%endif - WRITE_8W m4, dst3q, dst2q, mstrideq, strideq -%else ; mmx/mmxext - WRITE_2x4W m6, m4, dst2q, dst1q, mstrideq, strideq -%endif -%endif - -%if mmsize == 8 ; mmx/mmxext - ; next 8 pixels -%ifidn %1, v - add dst1q, 8 ; advance 8 cols = pixels -%else ; h - lea dst1q, [dst1q+strideq*8-1] ; advance 8 rows = lines -%endif - dec cntrq - jg .next8px - REP_RET -%else ; sse2 - RET -%endif -%endmacro - -%if ARCH_X86_32 -INIT_MMX mmx -SIMPLE_LOOPFILTER v, 4 -SIMPLE_LOOPFILTER h, 5 -INIT_MMX mmxext -SIMPLE_LOOPFILTER v, 4 -SIMPLE_LOOPFILTER h, 5 -%endif - -INIT_XMM sse2 -SIMPLE_LOOPFILTER v, 3 -SIMPLE_LOOPFILTER h, 5 -INIT_XMM ssse3 -SIMPLE_LOOPFILTER v, 3 -SIMPLE_LOOPFILTER h, 5 -INIT_XMM sse4 -SIMPLE_LOOPFILTER h, 5 - -;----------------------------------------------------------------------------- -; void vp8_h/v_loop_filter_inner_(uint8_t *dst, [uint8_t *v,] int stride, -; int flimE, int flimI, int hev_thr); -;----------------------------------------------------------------------------- - -%macro INNER_LOOPFILTER 2 -%define stack_size 0 -%ifndef m8 ; stack layout: [0]=E, [1]=I, [2]=hev_thr -%ifidn %1, v ; [3]=hev() result -%define stack_size mmsize * -4 -%else ; h ; extra storage space for transposes -%define stack_size mmsize * -5 -%endif -%endif - -%if %2 == 8 ; chroma -cglobal vp8_%1_loop_filter8uv_inner, 6, 6, 13, stack_size, dst, dst8, stride, flimE, flimI, hevthr -%else ; luma -cglobal vp8_%1_loop_filter16y_inner, 5, 5, 13, stack_size, dst, stride, flimE, flimI, hevthr -%endif - -%if cpuflag(ssse3) - pxor m7, m7 -%endif - -%ifndef m8 - ; splat function arguments - SPLATB_REG m0, flimEq, m7 ; E - SPLATB_REG m1, flimIq, m7 ; I - SPLATB_REG m2, hevthrq, m7 ; hev_thresh - -%define m_flimE [rsp] -%define m_flimI [rsp+mmsize] -%define m_hevthr [rsp+mmsize*2] -%define m_maskres [rsp+mmsize*3] -%define m_p0backup [rsp+mmsize*3] -%define m_q0backup [rsp+mmsize*4] - - mova m_flimE, m0 - mova m_flimI, m1 - mova m_hevthr, m2 -%else -%define m_flimE m9 -%define m_flimI m10 -%define m_hevthr m11 -%define m_maskres m12 -%define m_p0backup m12 -%define m_q0backup m8 - - ; splat function arguments - SPLATB_REG m_flimE, flimEq, m7 ; E - SPLATB_REG m_flimI, flimIq, m7 ; I - SPLATB_REG m_hevthr, hevthrq, m7 ; hev_thresh -%endif - -%if %2 == 8 ; chroma - DEFINE_ARGS dst1, dst8, mstride, stride, dst2 -%elif mmsize == 8 - DEFINE_ARGS dst1, mstride, stride, dst2, cntr - mov cntrq, 2 -%else - DEFINE_ARGS dst1, mstride, stride, dst2, dst8 -%endif - mov strideq, mstrideq - neg mstrideq -%ifidn %1, h - lea dst1q, [dst1q+strideq*4-4] -%if %2 == 8 ; chroma - lea dst8q, [dst8q+strideq*4-4] -%endif -%endif - -%if mmsize == 8 -.next8px: -%endif - ; read - lea dst2q, [dst1q+strideq] -%ifidn %1, v -%if %2 == 8 && mmsize == 16 -%define movrow movh -%else -%define movrow mova -%endif - movrow m0, [dst1q+mstrideq*4] ; p3 - movrow m1, [dst2q+mstrideq*4] ; p2 - movrow m2, [dst1q+mstrideq*2] ; p1 - movrow m5, [dst2q] ; q1 - movrow m6, [dst2q+ strideq*1] ; q2 - movrow m7, [dst2q+ strideq*2] ; q3 -%if mmsize == 16 && %2 == 8 - movhps m0, [dst8q+mstrideq*4] - movhps m2, [dst8q+mstrideq*2] - add dst8q, strideq - movhps m1, [dst8q+mstrideq*4] - movhps m5, [dst8q] - movhps m6, [dst8q+ strideq ] - movhps m7, [dst8q+ strideq*2] - add dst8q, mstrideq -%endif -%elif mmsize == 8 ; mmx/mmxext (h) - ; read 8 rows of 8px each - movu m0, [dst1q+mstrideq*4] - movu m1, [dst2q+mstrideq*4] - movu m2, [dst1q+mstrideq*2] - movu m3, [dst1q+mstrideq ] - movu m4, [dst1q] - movu m5, [dst2q] - movu m6, [dst2q+ strideq ] - - ; 8x8 transpose - TRANSPOSE4x4B 0, 1, 2, 3, 7 - mova m_q0backup, m1 - movu m7, [dst2q+ strideq*2] - TRANSPOSE4x4B 4, 5, 6, 7, 1 - SBUTTERFLY dq, 0, 4, 1 ; p3/p2 - SBUTTERFLY dq, 2, 6, 1 ; q0/q1 - SBUTTERFLY dq, 3, 7, 1 ; q2/q3 - mova m1, m_q0backup - mova m_q0backup, m2 ; store q0 - SBUTTERFLY dq, 1, 5, 2 ; p1/p0 - mova m_p0backup, m5 ; store p0 - SWAP 1, 4 - SWAP 2, 4 - SWAP 6, 3 - SWAP 5, 3 -%else ; sse2 (h) -%if %2 == 16 - lea dst8q, [dst1q+ strideq*8] -%endif - - ; read 16 rows of 8px each, interleave - movh m0, [dst1q+mstrideq*4] - movh m1, [dst8q+mstrideq*4] - movh m2, [dst1q+mstrideq*2] - movh m5, [dst8q+mstrideq*2] - movh m3, [dst1q+mstrideq ] - movh m6, [dst8q+mstrideq ] - movh m4, [dst1q] - movh m7, [dst8q] - punpcklbw m0, m1 ; A/I - punpcklbw m2, m5 ; C/K - punpcklbw m3, m6 ; D/L - punpcklbw m4, m7 ; E/M - - add dst8q, strideq - movh m1, [dst2q+mstrideq*4] - movh m6, [dst8q+mstrideq*4] - movh m5, [dst2q] - movh m7, [dst8q] - punpcklbw m1, m6 ; B/J - punpcklbw m5, m7 ; F/N - movh m6, [dst2q+ strideq ] - movh m7, [dst8q+ strideq ] - punpcklbw m6, m7 ; G/O - - ; 8x16 transpose - TRANSPOSE4x4B 0, 1, 2, 3, 7 -%ifdef m8 - SWAP 1, 8 -%else - mova m_q0backup, m1 -%endif - movh m7, [dst2q+ strideq*2] - movh m1, [dst8q+ strideq*2] - punpcklbw m7, m1 ; H/P - TRANSPOSE4x4B 4, 5, 6, 7, 1 - SBUTTERFLY dq, 0, 4, 1 ; p3/p2 - SBUTTERFLY dq, 2, 6, 1 ; q0/q1 - SBUTTERFLY dq, 3, 7, 1 ; q2/q3 -%ifdef m8 - SWAP 1, 8 - SWAP 2, 8 -%else - mova m1, m_q0backup - mova m_q0backup, m2 ; store q0 -%endif - SBUTTERFLY dq, 1, 5, 2 ; p1/p0 -%ifdef m12 - SWAP 5, 12 -%else - mova m_p0backup, m5 ; store p0 -%endif - SWAP 1, 4 - SWAP 2, 4 - SWAP 6, 3 - SWAP 5, 3 -%endif - - ; normal_limit for p3-p2, p2-p1, q3-q2 and q2-q1 - mova m4, m1 - SWAP 4, 1 - psubusb m4, m0 ; p2-p3 - psubusb m0, m1 ; p3-p2 - por m0, m4 ; abs(p3-p2) - - mova m4, m2 - SWAP 4, 2 - psubusb m4, m1 ; p1-p2 - psubusb m1, m2 ; p2-p1 - por m1, m4 ; abs(p2-p1) - - mova m4, m6 - SWAP 4, 6 - psubusb m4, m7 ; q2-q3 - psubusb m7, m6 ; q3-q2 - por m7, m4 ; abs(q3-q2) - - mova m4, m5 - SWAP 4, 5 - psubusb m4, m6 ; q1-q2 - psubusb m6, m5 ; q2-q1 - por m6, m4 ; abs(q2-q1) - -%if notcpuflag(mmxext) - mova m4, m_flimI - pxor m3, m3 - psubusb m0, m4 - psubusb m1, m4 - psubusb m7, m4 - psubusb m6, m4 - pcmpeqb m0, m3 ; abs(p3-p2) <= I - pcmpeqb m1, m3 ; abs(p2-p1) <= I - pcmpeqb m7, m3 ; abs(q3-q2) <= I - pcmpeqb m6, m3 ; abs(q2-q1) <= I - pand m0, m1 - pand m7, m6 - pand m0, m7 -%else ; mmxext/sse2 - pmaxub m0, m1 - pmaxub m6, m7 - pmaxub m0, m6 -%endif - - ; normal_limit and high_edge_variance for p1-p0, q1-q0 - SWAP 7, 3 ; now m7 is zero -%ifidn %1, v - movrow m3, [dst1q+mstrideq ] ; p0 -%if mmsize == 16 && %2 == 8 - movhps m3, [dst8q+mstrideq ] -%endif -%elifdef m12 - SWAP 3, 12 -%else - mova m3, m_p0backup -%endif - - mova m1, m2 - SWAP 1, 2 - mova m6, m3 - SWAP 3, 6 - psubusb m1, m3 ; p1-p0 - psubusb m6, m2 ; p0-p1 - por m1, m6 ; abs(p1-p0) -%if notcpuflag(mmxext) - mova m6, m1 - psubusb m1, m4 - psubusb m6, m_hevthr - pcmpeqb m1, m7 ; abs(p1-p0) <= I - pcmpeqb m6, m7 ; abs(p1-p0) <= hev_thresh - pand m0, m1 - mova m_maskres, m6 -%else ; mmxext/sse2 - pmaxub m0, m1 ; max_I - SWAP 1, 4 ; max_hev_thresh -%endif - - SWAP 6, 4 ; now m6 is I -%ifidn %1, v - movrow m4, [dst1q] ; q0 -%if mmsize == 16 && %2 == 8 - movhps m4, [dst8q] -%endif -%elifdef m8 - SWAP 4, 8 -%else - mova m4, m_q0backup -%endif - mova m1, m4 - SWAP 1, 4 - mova m7, m5 - SWAP 7, 5 - psubusb m1, m5 ; q0-q1 - psubusb m7, m4 ; q1-q0 - por m1, m7 ; abs(q1-q0) -%if notcpuflag(mmxext) - mova m7, m1 - psubusb m1, m6 - psubusb m7, m_hevthr - pxor m6, m6 - pcmpeqb m1, m6 ; abs(q1-q0) <= I - pcmpeqb m7, m6 ; abs(q1-q0) <= hev_thresh - mova m6, m_maskres - pand m0, m1 ; abs([pq][321]-[pq][210]) <= I - pand m6, m7 -%else ; mmxext/sse2 - pxor m7, m7 - pmaxub m0, m1 - pmaxub m6, m1 - psubusb m0, m_flimI - psubusb m6, m_hevthr - pcmpeqb m0, m7 ; max(abs(..)) <= I - pcmpeqb m6, m7 ; !(max(abs..) > thresh) -%endif -%ifdef m12 - SWAP 6, 12 -%else - mova m_maskres, m6 ; !(abs(p1-p0) > hev_t || abs(q1-q0) > hev_t) -%endif - - ; simple_limit - mova m1, m3 - SWAP 1, 3 - mova m6, m4 ; keep copies of p0/q0 around for later use - SWAP 6, 4 - psubusb m1, m4 ; p0-q0 - psubusb m6, m3 ; q0-p0 - por m1, m6 ; abs(q0-p0) - paddusb m1, m1 ; m1=2*abs(q0-p0) - - mova m7, m2 - SWAP 7, 2 - mova m6, m5 - SWAP 6, 5 - psubusb m7, m5 ; p1-q1 - psubusb m6, m2 ; q1-p1 - por m7, m6 ; abs(q1-p1) - pxor m6, m6 - pand m7, [pb_FE] - psrlq m7, 1 ; abs(q1-p1)/2 - paddusb m7, m1 ; abs(q0-p0)*2+abs(q1-p1)/2 - psubusb m7, m_flimE - pcmpeqb m7, m6 ; abs(q0-p0)*2+abs(q1-p1)/2 <= E - pand m0, m7 ; normal_limit result - - ; filter_common; at this point, m2-m5=p1-q1 and m0 is filter_mask -%ifdef m8 ; x86-64 && sse2 - mova m8, [pb_80] -%define m_pb_80 m8 -%else ; x86-32 or mmx/mmxext -%define m_pb_80 [pb_80] -%endif - mova m1, m4 - mova m7, m3 - pxor m1, m_pb_80 - pxor m7, m_pb_80 - psubsb m1, m7 ; (signed) q0-p0 - mova m6, m2 - mova m7, m5 - pxor m6, m_pb_80 - pxor m7, m_pb_80 - psubsb m6, m7 ; (signed) p1-q1 - mova m7, m_maskres - pandn m7, m6 - paddsb m7, m1 - paddsb m7, m1 - paddsb m7, m1 ; 3*(q0-p0)+is4tap?(p1-q1) - - pand m7, m0 - mova m1, [pb_F8] - mova m6, m7 - paddsb m7, [pb_3] - paddsb m6, [pb_4] - pand m7, m1 - pand m6, m1 - - pxor m1, m1 - pxor m0, m0 - pcmpgtb m1, m7 - psubb m0, m7 - psrlq m7, 3 ; +f2 - psrlq m0, 3 ; -f2 - pand m0, m1 - pandn m1, m7 - psubusb m3, m0 - paddusb m3, m1 ; p0+f2 - - pxor m1, m1 - pxor m0, m0 - pcmpgtb m0, m6 - psubb m1, m6 - psrlq m6, 3 ; +f1 - psrlq m1, 3 ; -f1 - pand m1, m0 - pandn m0, m6 - psubusb m4, m0 - paddusb m4, m1 ; q0-f1 - -%ifdef m12 - SWAP 6, 12 -%else - mova m6, m_maskres -%endif -%if notcpuflag(mmxext) - mova m7, [pb_1] -%else ; mmxext/sse2 - pxor m7, m7 -%endif - pand m0, m6 - pand m1, m6 -%if notcpuflag(mmxext) - paddusb m0, m7 - pand m1, [pb_FE] - pandn m7, m0 - psrlq m1, 1 - psrlq m7, 1 - SWAP 0, 7 -%else ; mmxext/sse2 - psubusb m1, [pb_1] - pavgb m0, m7 ; a - pavgb m1, m7 ; -a -%endif - psubusb m5, m0 - psubusb m2, m1 - paddusb m5, m1 ; q1-a - paddusb m2, m0 ; p1+a - - ; store -%ifidn %1, v - movrow [dst1q+mstrideq*2], m2 - movrow [dst1q+mstrideq ], m3 - movrow [dst1q], m4 - movrow [dst1q+ strideq ], m5 -%if mmsize == 16 && %2 == 8 - movhps [dst8q+mstrideq*2], m2 - movhps [dst8q+mstrideq ], m3 - movhps [dst8q], m4 - movhps [dst8q+ strideq ], m5 -%endif -%else ; h - add dst1q, 2 - add dst2q, 2 - - ; 4x8/16 transpose - TRANSPOSE4x4B 2, 3, 4, 5, 6 - -%if mmsize == 8 ; mmx/mmxext (h) - WRITE_4x2D 2, 3, 4, 5, dst1q, dst2q, mstrideq, strideq -%else ; sse2 (h) - lea dst8q, [dst8q+mstrideq +2] - WRITE_4x4D 2, 3, 4, 5, dst1q, dst2q, dst8q, mstrideq, strideq, %2 -%endif -%endif - -%if mmsize == 8 -%if %2 == 8 ; chroma -%ifidn %1, h - sub dst1q, 2 -%endif - cmp dst1q, dst8q - mov dst1q, dst8q - jnz .next8px -%else -%ifidn %1, h - lea dst1q, [dst1q+ strideq*8-2] -%else ; v - add dst1q, 8 -%endif - dec cntrq - jg .next8px -%endif - REP_RET -%else ; mmsize == 16 - RET -%endif -%endmacro - -%if ARCH_X86_32 -INIT_MMX mmx -INNER_LOOPFILTER v, 16 -INNER_LOOPFILTER h, 16 -INNER_LOOPFILTER v, 8 -INNER_LOOPFILTER h, 8 - -INIT_MMX mmxext -INNER_LOOPFILTER v, 16 -INNER_LOOPFILTER h, 16 -INNER_LOOPFILTER v, 8 -INNER_LOOPFILTER h, 8 -%endif - -INIT_XMM sse2 -INNER_LOOPFILTER v, 16 -INNER_LOOPFILTER h, 16 -INNER_LOOPFILTER v, 8 -INNER_LOOPFILTER h, 8 - -INIT_XMM ssse3 -INNER_LOOPFILTER v, 16 -INNER_LOOPFILTER h, 16 -INNER_LOOPFILTER v, 8 -INNER_LOOPFILTER h, 8 - -;----------------------------------------------------------------------------- -; void vp8_h/v_loop_filter_mbedge_(uint8_t *dst, [uint8_t *v,] int stride, -; int flimE, int flimI, int hev_thr); -;----------------------------------------------------------------------------- - -%macro MBEDGE_LOOPFILTER 2 -%define stack_size 0 -%ifndef m8 ; stack layout: [0]=E, [1]=I, [2]=hev_thr -%if mmsize == 16 ; [3]=hev() result - ; [4]=filter tmp result - ; [5]/[6] = p2/q2 backup - ; [7]=lim_res sign result -%define stack_size mmsize * -7 -%else ; 8 ; extra storage space for transposes -%define stack_size mmsize * -8 -%endif -%endif - -%if %2 == 8 ; chroma -cglobal vp8_%1_loop_filter8uv_mbedge, 6, 6, 15, stack_size, dst1, dst8, stride, flimE, flimI, hevthr -%else ; luma -cglobal vp8_%1_loop_filter16y_mbedge, 5, 5, 15, stack_size, dst1, stride, flimE, flimI, hevthr -%endif - -%if cpuflag(ssse3) - pxor m7, m7 -%endif - -%ifndef m8 - ; splat function arguments - SPLATB_REG m0, flimEq, m7 ; E - SPLATB_REG m1, flimIq, m7 ; I - SPLATB_REG m2, hevthrq, m7 ; hev_thresh - -%define m_flimE [rsp] -%define m_flimI [rsp+mmsize] -%define m_hevthr [rsp+mmsize*2] -%define m_maskres [rsp+mmsize*3] -%define m_limres [rsp+mmsize*4] -%define m_p0backup [rsp+mmsize*3] -%define m_q0backup [rsp+mmsize*4] -%define m_p2backup [rsp+mmsize*5] -%define m_q2backup [rsp+mmsize*6] -%if mmsize == 16 -%define m_limsign [rsp] -%else -%define m_limsign [rsp+mmsize*7] -%endif - - mova m_flimE, m0 - mova m_flimI, m1 - mova m_hevthr, m2 -%else ; sse2 on x86-64 -%define m_flimE m9 -%define m_flimI m10 -%define m_hevthr m11 -%define m_maskres m12 -%define m_limres m8 -%define m_p0backup m12 -%define m_q0backup m8 -%define m_p2backup m13 -%define m_q2backup m14 -%define m_limsign m9 - - ; splat function arguments - SPLATB_REG m_flimE, flimEq, m7 ; E - SPLATB_REG m_flimI, flimIq, m7 ; I - SPLATB_REG m_hevthr, hevthrq, m7 ; hev_thresh -%endif - -%if %2 == 8 ; chroma - DEFINE_ARGS dst1, dst8, mstride, stride, dst2 -%elif mmsize == 8 - DEFINE_ARGS dst1, mstride, stride, dst2, cntr - mov cntrq, 2 -%else - DEFINE_ARGS dst1, mstride, stride, dst2, dst8 -%endif - mov strideq, mstrideq - neg mstrideq -%ifidn %1, h - lea dst1q, [dst1q+strideq*4-4] -%if %2 == 8 ; chroma - lea dst8q, [dst8q+strideq*4-4] -%endif -%endif - -%if mmsize == 8 -.next8px: -%endif - ; read - lea dst2q, [dst1q+ strideq ] -%ifidn %1, v -%if %2 == 8 && mmsize == 16 -%define movrow movh -%else -%define movrow mova -%endif - movrow m0, [dst1q+mstrideq*4] ; p3 - movrow m1, [dst2q+mstrideq*4] ; p2 - movrow m2, [dst1q+mstrideq*2] ; p1 - movrow m5, [dst2q] ; q1 - movrow m6, [dst2q+ strideq ] ; q2 - movrow m7, [dst2q+ strideq*2] ; q3 -%if mmsize == 16 && %2 == 8 - movhps m0, [dst8q+mstrideq*4] - movhps m2, [dst8q+mstrideq*2] - add dst8q, strideq - movhps m1, [dst8q+mstrideq*4] - movhps m5, [dst8q] - movhps m6, [dst8q+ strideq ] - movhps m7, [dst8q+ strideq*2] - add dst8q, mstrideq -%endif -%elif mmsize == 8 ; mmx/mmxext (h) - ; read 8 rows of 8px each - movu m0, [dst1q+mstrideq*4] - movu m1, [dst2q+mstrideq*4] - movu m2, [dst1q+mstrideq*2] - movu m3, [dst1q+mstrideq ] - movu m4, [dst1q] - movu m5, [dst2q] - movu m6, [dst2q+ strideq ] - - ; 8x8 transpose - TRANSPOSE4x4B 0, 1, 2, 3, 7 - mova m_q0backup, m1 - movu m7, [dst2q+ strideq*2] - TRANSPOSE4x4B 4, 5, 6, 7, 1 - SBUTTERFLY dq, 0, 4, 1 ; p3/p2 - SBUTTERFLY dq, 2, 6, 1 ; q0/q1 - SBUTTERFLY dq, 3, 7, 1 ; q2/q3 - mova m1, m_q0backup - mova m_q0backup, m2 ; store q0 - SBUTTERFLY dq, 1, 5, 2 ; p1/p0 - mova m_p0backup, m5 ; store p0 - SWAP 1, 4 - SWAP 2, 4 - SWAP 6, 3 - SWAP 5, 3 -%else ; sse2 (h) -%if %2 == 16 - lea dst8q, [dst1q+ strideq*8 ] -%endif - - ; read 16 rows of 8px each, interleave - movh m0, [dst1q+mstrideq*4] - movh m1, [dst8q+mstrideq*4] - movh m2, [dst1q+mstrideq*2] - movh m5, [dst8q+mstrideq*2] - movh m3, [dst1q+mstrideq ] - movh m6, [dst8q+mstrideq ] - movh m4, [dst1q] - movh m7, [dst8q] - punpcklbw m0, m1 ; A/I - punpcklbw m2, m5 ; C/K - punpcklbw m3, m6 ; D/L - punpcklbw m4, m7 ; E/M - - add dst8q, strideq - movh m1, [dst2q+mstrideq*4] - movh m6, [dst8q+mstrideq*4] - movh m5, [dst2q] - movh m7, [dst8q] - punpcklbw m1, m6 ; B/J - punpcklbw m5, m7 ; F/N - movh m6, [dst2q+ strideq ] - movh m7, [dst8q+ strideq ] - punpcklbw m6, m7 ; G/O - - ; 8x16 transpose - TRANSPOSE4x4B 0, 1, 2, 3, 7 -%ifdef m8 - SWAP 1, 8 -%else - mova m_q0backup, m1 -%endif - movh m7, [dst2q+ strideq*2] - movh m1, [dst8q+ strideq*2] - punpcklbw m7, m1 ; H/P - TRANSPOSE4x4B 4, 5, 6, 7, 1 - SBUTTERFLY dq, 0, 4, 1 ; p3/p2 - SBUTTERFLY dq, 2, 6, 1 ; q0/q1 - SBUTTERFLY dq, 3, 7, 1 ; q2/q3 -%ifdef m8 - SWAP 1, 8 - SWAP 2, 8 -%else - mova m1, m_q0backup - mova m_q0backup, m2 ; store q0 -%endif - SBUTTERFLY dq, 1, 5, 2 ; p1/p0 -%ifdef m12 - SWAP 5, 12 -%else - mova m_p0backup, m5 ; store p0 -%endif - SWAP 1, 4 - SWAP 2, 4 - SWAP 6, 3 - SWAP 5, 3 -%endif - - ; normal_limit for p3-p2, p2-p1, q3-q2 and q2-q1 - mova m4, m1 - SWAP 4, 1 - psubusb m4, m0 ; p2-p3 - psubusb m0, m1 ; p3-p2 - por m0, m4 ; abs(p3-p2) - - mova m4, m2 - SWAP 4, 2 - psubusb m4, m1 ; p1-p2 - mova m_p2backup, m1 - psubusb m1, m2 ; p2-p1 - por m1, m4 ; abs(p2-p1) - - mova m4, m6 - SWAP 4, 6 - psubusb m4, m7 ; q2-q3 - psubusb m7, m6 ; q3-q2 - por m7, m4 ; abs(q3-q2) - - mova m4, m5 - SWAP 4, 5 - psubusb m4, m6 ; q1-q2 - mova m_q2backup, m6 - psubusb m6, m5 ; q2-q1 - por m6, m4 ; abs(q2-q1) - -%if notcpuflag(mmxext) - mova m4, m_flimI - pxor m3, m3 - psubusb m0, m4 - psubusb m1, m4 - psubusb m7, m4 - psubusb m6, m4 - pcmpeqb m0, m3 ; abs(p3-p2) <= I - pcmpeqb m1, m3 ; abs(p2-p1) <= I - pcmpeqb m7, m3 ; abs(q3-q2) <= I - pcmpeqb m6, m3 ; abs(q2-q1) <= I - pand m0, m1 - pand m7, m6 - pand m0, m7 -%else ; mmxext/sse2 - pmaxub m0, m1 - pmaxub m6, m7 - pmaxub m0, m6 -%endif - - ; normal_limit and high_edge_variance for p1-p0, q1-q0 - SWAP 7, 3 ; now m7 is zero -%ifidn %1, v - movrow m3, [dst1q+mstrideq ] ; p0 -%if mmsize == 16 && %2 == 8 - movhps m3, [dst8q+mstrideq ] -%endif -%elifdef m12 - SWAP 3, 12 -%else - mova m3, m_p0backup -%endif - - mova m1, m2 - SWAP 1, 2 - mova m6, m3 - SWAP 3, 6 - psubusb m1, m3 ; p1-p0 - psubusb m6, m2 ; p0-p1 - por m1, m6 ; abs(p1-p0) -%if notcpuflag(mmxext) - mova m6, m1 - psubusb m1, m4 - psubusb m6, m_hevthr - pcmpeqb m1, m7 ; abs(p1-p0) <= I - pcmpeqb m6, m7 ; abs(p1-p0) <= hev_thresh - pand m0, m1 - mova m_maskres, m6 -%else ; mmxext/sse2 - pmaxub m0, m1 ; max_I - SWAP 1, 4 ; max_hev_thresh -%endif - - SWAP 6, 4 ; now m6 is I -%ifidn %1, v - movrow m4, [dst1q] ; q0 -%if mmsize == 16 && %2 == 8 - movhps m4, [dst8q] -%endif -%elifdef m8 - SWAP 4, 8 -%else - mova m4, m_q0backup -%endif - mova m1, m4 - SWAP 1, 4 - mova m7, m5 - SWAP 7, 5 - psubusb m1, m5 ; q0-q1 - psubusb m7, m4 ; q1-q0 - por m1, m7 ; abs(q1-q0) -%if notcpuflag(mmxext) - mova m7, m1 - psubusb m1, m6 - psubusb m7, m_hevthr - pxor m6, m6 - pcmpeqb m1, m6 ; abs(q1-q0) <= I - pcmpeqb m7, m6 ; abs(q1-q0) <= hev_thresh - mova m6, m_maskres - pand m0, m1 ; abs([pq][321]-[pq][210]) <= I - pand m6, m7 -%else ; mmxext/sse2 - pxor m7, m7 - pmaxub m0, m1 - pmaxub m6, m1 - psubusb m0, m_flimI - psubusb m6, m_hevthr - pcmpeqb m0, m7 ; max(abs(..)) <= I - pcmpeqb m6, m7 ; !(max(abs..) > thresh) -%endif -%ifdef m12 - SWAP 6, 12 -%else - mova m_maskres, m6 ; !(abs(p1-p0) > hev_t || abs(q1-q0) > hev_t) -%endif - - ; simple_limit - mova m1, m3 - SWAP 1, 3 - mova m6, m4 ; keep copies of p0/q0 around for later use - SWAP 6, 4 - psubusb m1, m4 ; p0-q0 - psubusb m6, m3 ; q0-p0 - por m1, m6 ; abs(q0-p0) - paddusb m1, m1 ; m1=2*abs(q0-p0) - - mova m7, m2 - SWAP 7, 2 - mova m6, m5 - SWAP 6, 5 - psubusb m7, m5 ; p1-q1 - psubusb m6, m2 ; q1-p1 - por m7, m6 ; abs(q1-p1) - pxor m6, m6 - pand m7, [pb_FE] - psrlq m7, 1 ; abs(q1-p1)/2 - paddusb m7, m1 ; abs(q0-p0)*2+abs(q1-p1)/2 - psubusb m7, m_flimE - pcmpeqb m7, m6 ; abs(q0-p0)*2+abs(q1-p1)/2 <= E - pand m0, m7 ; normal_limit result - - ; filter_common; at this point, m2-m5=p1-q1 and m0 is filter_mask -%ifdef m8 ; x86-64 && sse2 - mova m8, [pb_80] -%define m_pb_80 m8 -%else ; x86-32 or mmx/mmxext -%define m_pb_80 [pb_80] -%endif - mova m1, m4 - mova m7, m3 - pxor m1, m_pb_80 - pxor m7, m_pb_80 - psubsb m1, m7 ; (signed) q0-p0 - mova m6, m2 - mova m7, m5 - pxor m6, m_pb_80 - pxor m7, m_pb_80 - psubsb m6, m7 ; (signed) p1-q1 - mova m7, m_maskres - paddsb m6, m1 - paddsb m6, m1 - paddsb m6, m1 - pand m6, m0 -%ifdef m8 - mova m_limres, m6 ; 3*(qp-p0)+(p1-q1) masked for filter_mbedge - pand m_limres, m7 -%else - mova m0, m6 - pand m0, m7 - mova m_limres, m0 -%endif - pandn m7, m6 ; 3*(q0-p0)+(p1-q1) masked for filter_common - - mova m1, [pb_F8] - mova m6, m7 - paddsb m7, [pb_3] - paddsb m6, [pb_4] - pand m7, m1 - pand m6, m1 - - pxor m1, m1 - pxor m0, m0 - pcmpgtb m1, m7 - psubb m0, m7 - psrlq m7, 3 ; +f2 - psrlq m0, 3 ; -f2 - pand m0, m1 - pandn m1, m7 - psubusb m3, m0 - paddusb m3, m1 ; p0+f2 - - pxor m1, m1 - pxor m0, m0 - pcmpgtb m0, m6 - psubb m1, m6 - psrlq m6, 3 ; +f1 - psrlq m1, 3 ; -f1 - pand m1, m0 - pandn m0, m6 - psubusb m4, m0 - paddusb m4, m1 ; q0-f1 - - ; filter_mbedge (m2-m5 = p1-q1; lim_res carries w) -%if cpuflag(ssse3) - mova m7, [pb_1] -%else - mova m7, [pw_63] -%endif -%ifdef m8 - SWAP 1, 8 -%else - mova m1, m_limres -%endif - pxor m0, m0 - mova m6, m1 - pcmpgtb m0, m1 ; which are negative -%if cpuflag(ssse3) - punpcklbw m6, m7 ; interleave with "1" for rounding - punpckhbw m1, m7 -%else - punpcklbw m6, m0 ; signed byte->word - punpckhbw m1, m0 -%endif - mova m_limsign, m0 -%if cpuflag(ssse3) - mova m7, [pb_27_63] -%ifndef m8 - mova m_limres, m1 -%endif -%ifdef m10 - SWAP 0, 10 ; don't lose lim_sign copy -%endif - mova m0, m7 - pmaddubsw m7, m6 - SWAP 6, 7 - pmaddubsw m0, m1 - SWAP 1, 0 -%ifdef m10 - SWAP 0, 10 -%else - mova m0, m_limsign -%endif -%else - mova m_maskres, m6 ; backup for later in filter - mova m_limres, m1 - pmullw m6, [pw_27] - pmullw m1, [pw_27] - paddw m6, m7 - paddw m1, m7 -%endif - psraw m6, 7 - psraw m1, 7 - packsswb m6, m1 ; a0 - pxor m1, m1 - psubb m1, m6 - pand m1, m0 ; -a0 - pandn m0, m6 ; +a0 -%if cpuflag(ssse3) - mova m6, [pb_18_63] ; pipelining -%endif - psubusb m3, m1 - paddusb m4, m1 - paddusb m3, m0 ; p0+a0 - psubusb m4, m0 ; q0-a0 - -%if cpuflag(ssse3) - SWAP 6, 7 -%ifdef m10 - SWAP 1, 10 -%else - mova m1, m_limres -%endif - mova m0, m7 - pmaddubsw m7, m6 - SWAP 6, 7 - pmaddubsw m0, m1 - SWAP 1, 0 -%ifdef m10 - SWAP 0, 10 -%endif - mova m0, m_limsign -%else - mova m6, m_maskres - mova m1, m_limres - pmullw m6, [pw_18] - pmullw m1, [pw_18] - paddw m6, m7 - paddw m1, m7 -%endif - mova m0, m_limsign - psraw m6, 7 - psraw m1, 7 - packsswb m6, m1 ; a1 - pxor m1, m1 - psubb m1, m6 - pand m1, m0 ; -a1 - pandn m0, m6 ; +a1 -%if cpuflag(ssse3) - mova m6, [pb_9_63] -%endif - psubusb m2, m1 - paddusb m5, m1 - paddusb m2, m0 ; p1+a1 - psubusb m5, m0 ; q1-a1 - -%if cpuflag(ssse3) - SWAP 6, 7 -%ifdef m10 - SWAP 1, 10 -%else - mova m1, m_limres -%endif - mova m0, m7 - pmaddubsw m7, m6 - SWAP 6, 7 - pmaddubsw m0, m1 - SWAP 1, 0 -%else -%ifdef m8 - SWAP 6, 12 - SWAP 1, 8 -%else - mova m6, m_maskres - mova m1, m_limres -%endif - pmullw m6, [pw_9] - pmullw m1, [pw_9] - paddw m6, m7 - paddw m1, m7 -%endif -%ifdef m9 - SWAP 7, 9 -%else - mova m7, m_limsign -%endif - psraw m6, 7 - psraw m1, 7 - packsswb m6, m1 ; a1 - pxor m0, m0 - psubb m0, m6 - pand m0, m7 ; -a1 - pandn m7, m6 ; +a1 -%ifdef m8 - SWAP 1, 13 - SWAP 6, 14 -%else - mova m1, m_p2backup - mova m6, m_q2backup -%endif - psubusb m1, m0 - paddusb m6, m0 - paddusb m1, m7 ; p1+a1 - psubusb m6, m7 ; q1-a1 - - ; store -%ifidn %1, v - movrow [dst2q+mstrideq*4], m1 - movrow [dst1q+mstrideq*2], m2 - movrow [dst1q+mstrideq ], m3 - movrow [dst1q], m4 - movrow [dst2q], m5 - movrow [dst2q+ strideq ], m6 -%if mmsize == 16 && %2 == 8 - add dst8q, mstrideq - movhps [dst8q+mstrideq*2], m1 - movhps [dst8q+mstrideq ], m2 - movhps [dst8q], m3 - add dst8q, strideq - movhps [dst8q], m4 - movhps [dst8q+ strideq ], m5 - movhps [dst8q+ strideq*2], m6 -%endif -%else ; h - inc dst1q - inc dst2q - - ; 4x8/16 transpose - TRANSPOSE4x4B 1, 2, 3, 4, 0 - SBUTTERFLY bw, 5, 6, 0 - -%if mmsize == 8 ; mmx/mmxext (h) - WRITE_4x2D 1, 2, 3, 4, dst1q, dst2q, mstrideq, strideq - add dst1q, 4 - WRITE_2x4W m5, m6, dst2q, dst1q, mstrideq, strideq -%else ; sse2 (h) - lea dst8q, [dst8q+mstrideq+1] - WRITE_4x4D 1, 2, 3, 4, dst1q, dst2q, dst8q, mstrideq, strideq, %2 - lea dst1q, [dst2q+mstrideq+4] - lea dst8q, [dst8q+mstrideq+4] -%if cpuflag(sse4) - add dst2q, 4 -%endif - WRITE_8W m5, dst2q, dst1q, mstrideq, strideq -%if cpuflag(sse4) - lea dst2q, [dst8q+ strideq ] -%endif - WRITE_8W m6, dst2q, dst8q, mstrideq, strideq -%endif -%endif - -%if mmsize == 8 -%if %2 == 8 ; chroma -%ifidn %1, h - sub dst1q, 5 -%endif - cmp dst1q, dst8q - mov dst1q, dst8q - jnz .next8px -%else -%ifidn %1, h - lea dst1q, [dst1q+ strideq*8-5] -%else ; v - add dst1q, 8 -%endif - dec cntrq - jg .next8px -%endif - REP_RET -%else ; mmsize == 16 - RET -%endif -%endmacro - -%if ARCH_X86_32 -INIT_MMX mmx -MBEDGE_LOOPFILTER v, 16 -MBEDGE_LOOPFILTER h, 16 -MBEDGE_LOOPFILTER v, 8 -MBEDGE_LOOPFILTER h, 8 - -INIT_MMX mmxext -MBEDGE_LOOPFILTER v, 16 -MBEDGE_LOOPFILTER h, 16 -MBEDGE_LOOPFILTER v, 8 -MBEDGE_LOOPFILTER h, 8 -%endif - -INIT_XMM sse2 -MBEDGE_LOOPFILTER v, 16 -MBEDGE_LOOPFILTER h, 16 -MBEDGE_LOOPFILTER v, 8 -MBEDGE_LOOPFILTER h, 8 - -INIT_XMM ssse3 -MBEDGE_LOOPFILTER v, 16 -MBEDGE_LOOPFILTER h, 16 -MBEDGE_LOOPFILTER v, 8 -MBEDGE_LOOPFILTER h, 8 - -INIT_XMM sse4 -MBEDGE_LOOPFILTER h, 16 -MBEDGE_LOOPFILTER h, 8 diff --git a/ffmpeg/libavcodec/x86/vp8dsp_init.c b/ffmpeg/libavcodec/x86/vp8dsp_init.c index 09e2d91..dca00f5 100644 --- a/ffmpeg/libavcodec/x86/vp8dsp_init.c +++ b/ffmpeg/libavcodec/x86/vp8dsp_init.c @@ -23,6 +23,7 @@ #include "libavutil/cpu.h" #include "libavutil/mem.h" #include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" #include "libavcodec/vp8dsp.h" #if HAVE_YASM @@ -30,93 +31,93 @@ /* * MC functions */ -extern void ff_put_vp8_epel4_h4_mmxext(uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); -extern void ff_put_vp8_epel4_h6_mmxext(uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); -extern void ff_put_vp8_epel4_v4_mmxext(uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); -extern void ff_put_vp8_epel4_v6_mmxext(uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); - -extern void ff_put_vp8_epel8_h4_sse2 (uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); -extern void ff_put_vp8_epel8_h6_sse2 (uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); -extern void ff_put_vp8_epel8_v4_sse2 (uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); -extern void ff_put_vp8_epel8_v6_sse2 (uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); - -extern void ff_put_vp8_epel4_h4_ssse3 (uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); -extern void ff_put_vp8_epel4_h6_ssse3 (uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); -extern void ff_put_vp8_epel4_v4_ssse3 (uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); -extern void ff_put_vp8_epel4_v6_ssse3 (uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); -extern void ff_put_vp8_epel8_h4_ssse3 (uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); -extern void ff_put_vp8_epel8_h6_ssse3 (uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); -extern void ff_put_vp8_epel8_v4_ssse3 (uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); -extern void ff_put_vp8_epel8_v6_ssse3 (uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); - -extern void ff_put_vp8_bilinear4_h_mmxext(uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); -extern void ff_put_vp8_bilinear8_h_sse2 (uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); -extern void ff_put_vp8_bilinear4_h_ssse3 (uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); -extern void ff_put_vp8_bilinear8_h_ssse3 (uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); - -extern void ff_put_vp8_bilinear4_v_mmxext(uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); -extern void ff_put_vp8_bilinear8_v_sse2 (uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); -extern void ff_put_vp8_bilinear4_v_ssse3 (uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); -extern void ff_put_vp8_bilinear8_v_ssse3 (uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); - - -extern void ff_put_vp8_pixels8_mmx (uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); -extern void ff_put_vp8_pixels16_mmx(uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); -extern void ff_put_vp8_pixels16_sse(uint8_t *dst, ptrdiff_t dststride, - uint8_t *src, ptrdiff_t srcstride, - int height, int mx, int my); +void ff_put_vp8_epel4_h4_mmxext(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel4_h6_mmxext(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel4_v4_mmxext(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel4_v6_mmxext(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); + +void ff_put_vp8_epel8_h4_sse2 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel8_h6_sse2 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel8_v4_sse2 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel8_v6_sse2 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); + +void ff_put_vp8_epel4_h4_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel4_h6_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel4_v4_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel4_v6_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel8_h4_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel8_h6_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel8_v4_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel8_v6_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); + +void ff_put_vp8_bilinear4_h_mmxext(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_bilinear8_h_sse2 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_bilinear4_h_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_bilinear8_h_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); + +void ff_put_vp8_bilinear4_v_mmxext(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_bilinear8_v_sse2 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_bilinear4_v_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_bilinear8_v_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); + + +void ff_put_vp8_pixels8_mmx (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_pixels16_mmx(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_pixels16_sse(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); #define TAP_W16(OPT, FILTERTYPE, TAPTYPE) \ static void ff_put_vp8_ ## FILTERTYPE ## 16_ ## TAPTYPE ## _ ## OPT( \ @@ -230,58 +231,56 @@ HVBILIN(ssse3, 8, 4, 8) HVBILIN(ssse3, 8, 8, 16) HVBILIN(ssse3, 8, 16, 16) -extern void ff_vp8_idct_dc_add_mmx(uint8_t *dst, int16_t block[16], - ptrdiff_t stride); -extern void ff_vp8_idct_dc_add_sse4(uint8_t *dst, int16_t block[16], - ptrdiff_t stride); -extern void ff_vp8_idct_dc_add4y_mmx(uint8_t *dst, int16_t block[4][16], - ptrdiff_t stride); -extern void ff_vp8_idct_dc_add4y_sse2(uint8_t *dst, int16_t block[4][16], - ptrdiff_t stride); -extern void ff_vp8_idct_dc_add4uv_mmx(uint8_t *dst, int16_t block[2][16], - ptrdiff_t stride); -extern void ff_vp8_luma_dc_wht_mmx(int16_t block[4][4][16], int16_t dc[16]); -extern void ff_vp8_luma_dc_wht_sse(int16_t block[4][4][16], int16_t dc[16]); -extern void ff_vp8_idct_add_mmx(uint8_t *dst, int16_t block[16], - ptrdiff_t stride); -extern void ff_vp8_idct_add_sse(uint8_t *dst, int16_t block[16], - ptrdiff_t stride); - -#define DECLARE_LOOP_FILTER(NAME)\ -extern void ff_vp8_v_loop_filter_simple_ ## NAME(uint8_t *dst, \ - ptrdiff_t stride, \ - int flim);\ -extern void ff_vp8_h_loop_filter_simple_ ## NAME(uint8_t *dst, \ - ptrdiff_t stride, \ - int flim);\ -extern void ff_vp8_v_loop_filter16y_inner_ ## NAME (uint8_t *dst, \ - ptrdiff_t stride,\ - int e, int i, int hvt);\ -extern void ff_vp8_h_loop_filter16y_inner_ ## NAME (uint8_t *dst, \ - ptrdiff_t stride,\ - int e, int i, int hvt);\ -extern void ff_vp8_v_loop_filter8uv_inner_ ## NAME (uint8_t *dstU, \ - uint8_t *dstV,\ - ptrdiff_t s, \ - int e, int i, int hvt);\ -extern void ff_vp8_h_loop_filter8uv_inner_ ## NAME (uint8_t *dstU, \ - uint8_t *dstV,\ - ptrdiff_t s, \ - int e, int i, int hvt);\ -extern void ff_vp8_v_loop_filter16y_mbedge_ ## NAME(uint8_t *dst, \ - ptrdiff_t stride,\ - int e, int i, int hvt);\ -extern void ff_vp8_h_loop_filter16y_mbedge_ ## NAME(uint8_t *dst, \ - ptrdiff_t stride,\ - int e, int i, int hvt);\ -extern void ff_vp8_v_loop_filter8uv_mbedge_ ## NAME(uint8_t *dstU, \ - uint8_t *dstV,\ - ptrdiff_t s, \ - int e, int i, int hvt);\ -extern void ff_vp8_h_loop_filter8uv_mbedge_ ## NAME(uint8_t *dstU, \ - uint8_t *dstV,\ - ptrdiff_t s, \ - int e, int i, int hvt); +void ff_vp8_idct_dc_add_mmx(uint8_t *dst, int16_t block[16], + ptrdiff_t stride); +void ff_vp8_idct_dc_add_sse4(uint8_t *dst, int16_t block[16], + ptrdiff_t stride); +void ff_vp8_idct_dc_add4y_mmx(uint8_t *dst, int16_t block[4][16], + ptrdiff_t stride); +void ff_vp8_idct_dc_add4y_sse2(uint8_t *dst, int16_t block[4][16], + ptrdiff_t stride); +void ff_vp8_idct_dc_add4uv_mmx(uint8_t *dst, int16_t block[2][16], + ptrdiff_t stride); +void ff_vp8_luma_dc_wht_mmx(int16_t block[4][4][16], int16_t dc[16]); +void ff_vp8_luma_dc_wht_sse(int16_t block[4][4][16], int16_t dc[16]); +void ff_vp8_idct_add_mmx(uint8_t *dst, int16_t block[16], ptrdiff_t stride); +void ff_vp8_idct_add_sse(uint8_t *dst, int16_t block[16], ptrdiff_t stride); + +#define DECLARE_LOOP_FILTER(NAME) \ +void ff_vp8_v_loop_filter_simple_ ## NAME(uint8_t *dst, \ + ptrdiff_t stride, \ + int flim); \ +void ff_vp8_h_loop_filter_simple_ ## NAME(uint8_t *dst, \ + ptrdiff_t stride, \ + int flim); \ +void ff_vp8_v_loop_filter16y_inner_ ## NAME (uint8_t *dst, \ + ptrdiff_t stride, \ + int e, int i, int hvt); \ +void ff_vp8_h_loop_filter16y_inner_ ## NAME (uint8_t *dst, \ + ptrdiff_t stride, \ + int e, int i, int hvt); \ +void ff_vp8_v_loop_filter8uv_inner_ ## NAME (uint8_t *dstU, \ + uint8_t *dstV, \ + ptrdiff_t s, \ + int e, int i, int hvt); \ +void ff_vp8_h_loop_filter8uv_inner_ ## NAME (uint8_t *dstU, \ + uint8_t *dstV, \ + ptrdiff_t s, \ + int e, int i, int hvt); \ +void ff_vp8_v_loop_filter16y_mbedge_ ## NAME(uint8_t *dst, \ + ptrdiff_t stride, \ + int e, int i, int hvt); \ +void ff_vp8_h_loop_filter16y_mbedge_ ## NAME(uint8_t *dst, \ + ptrdiff_t stride, \ + int e, int i, int hvt); \ +void ff_vp8_v_loop_filter8uv_mbedge_ ## NAME(uint8_t *dstU, \ + uint8_t *dstV, \ + ptrdiff_t s, \ + int e, int i, int hvt); \ +void ff_vp8_h_loop_filter8uv_mbedge_ ## NAME(uint8_t *dstU, \ + uint8_t *dstV, \ + ptrdiff_t s, \ + int e, int i, int hvt); DECLARE_LOOP_FILTER(mmx) DECLARE_LOOP_FILTER(mmxext) @@ -318,9 +317,9 @@ DECLARE_LOOP_FILTER(sse4) av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c) { #if HAVE_YASM - int mm_flags = av_get_cpu_flags(); + int cpu_flags = av_get_cpu_flags(); - if (mm_flags & AV_CPU_FLAG_MMX) { + if (EXTERNAL_MMX(cpu_flags)) { c->vp8_idct_dc_add = ff_vp8_idct_dc_add_mmx; c->vp8_idct_dc_add4uv = ff_vp8_idct_dc_add4uv_mmx; #if ARCH_X86_32 @@ -351,7 +350,7 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c) /* note that 4-tap width=16 functions are missing because w=16 * is only used for luma, and luma is always a copy or sixtap. */ - if (mm_flags & AV_CPU_FLAG_MMXEXT) { + if (EXTERNAL_MMXEXT(cpu_flags)) { VP8_MC_FUNC(2, 4, mmxext); VP8_BILINEAR_MC_FUNC(2, 4, mmxext); #if ARCH_X86_32 @@ -375,14 +374,14 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c) #endif } - if (mm_flags & AV_CPU_FLAG_SSE) { + if (EXTERNAL_SSE(cpu_flags)) { c->vp8_idct_add = ff_vp8_idct_add_sse; c->vp8_luma_dc_wht = ff_vp8_luma_dc_wht_sse; c->put_vp8_epel_pixels_tab[0][0][0] = c->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_sse; } - if (mm_flags & (AV_CPU_FLAG_SSE2|AV_CPU_FLAG_SSE2SLOW)) { + if (HAVE_SSE2_EXTERNAL && cpu_flags & (AV_CPU_FLAG_SSE2 | AV_CPU_FLAG_SSE2SLOW)) { VP8_LUMA_MC_FUNC(0, 16, sse2); VP8_MC_FUNC(1, 8, sse2); VP8_BILINEAR_MC_FUNC(0, 16, sse2); @@ -397,7 +396,7 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c) c->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_mbedge_sse2; } - if (mm_flags & AV_CPU_FLAG_SSE2) { + if (EXTERNAL_SSE2(cpu_flags)) { c->vp8_idct_dc_add4y = ff_vp8_idct_dc_add4y_sse2; c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_sse2; @@ -409,7 +408,7 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c) c->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mbedge_sse2; } - if (mm_flags & AV_CPU_FLAG_SSSE3) { + if (EXTERNAL_SSSE3(cpu_flags)) { VP8_LUMA_MC_FUNC(0, 16, ssse3); VP8_MC_FUNC(1, 8, ssse3); VP8_MC_FUNC(2, 4, ssse3); @@ -431,7 +430,7 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c) c->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mbedge_ssse3; } - if (mm_flags & AV_CPU_FLAG_SSE4) { + if (EXTERNAL_SSE4(cpu_flags)) { c->vp8_idct_dc_add = ff_vp8_idct_dc_add_sse4; c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_sse4; diff --git a/ffmpeg/libavcodec/x86/w64xmmtest.c b/ffmpeg/libavcodec/x86/w64xmmtest.c index f6e3de9..25e833f 100644 --- a/ffmpeg/libavcodec/x86/w64xmmtest.c +++ b/ffmpeg/libavcodec/x86/w64xmmtest.c @@ -2,20 +2,20 @@ * check XMM registers for clobbers on Win64 * Copyright (c) 2012 Ronald S. Bultje * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -78,3 +78,9 @@ wrap(avcodec_encode_subtitle(AVCodecContext *avctx, { testxmmclobbers(avcodec_encode_subtitle, avctx, buf, buf_size, sub); } + +wrap(avcodec_encode_video2(AVCodecContext *avctx, AVPacket *avpkt, + const AVFrame *frame, int *got_packet_ptr)) +{ + testxmmclobbers(avcodec_encode_video2, avctx, avpkt, frame, got_packet_ptr); +} diff --git a/ffmpeg/libavcodec/xan.c b/ffmpeg/libavcodec/xan.c index 2ee2291..7489113 100644 --- a/ffmpeg/libavcodec/xan.c +++ b/ffmpeg/libavcodec/xan.c @@ -52,15 +52,15 @@ typedef struct XanContext { AVCodecContext *avctx; - AVFrame last_frame; + AVFrame *last_frame; - const unsigned char *buf; + const uint8_t *buf; int size; /* scratch space */ - unsigned char *buffer1; + uint8_t *buffer1; int buffer1_size; - unsigned char *buffer2; + uint8_t *buffer2; int buffer2_size; unsigned *palettes; @@ -71,6 +71,19 @@ typedef struct XanContext { } XanContext; +static av_cold int xan_decode_end(AVCodecContext *avctx) +{ + XanContext *s = avctx->priv_data; + + av_frame_free(&s->last_frame); + + av_freep(&s->buffer1); + av_freep(&s->buffer2); + av_freep(&s->palettes); + + return 0; +} + static av_cold int xan_decode_init(AVCodecContext *avctx) { XanContext *s = avctx->priv_data; @@ -90,26 +103,31 @@ static av_cold int xan_decode_init(AVCodecContext *avctx) av_freep(&s->buffer1); return AVERROR(ENOMEM); } - avcodec_get_frame_defaults(&s->last_frame); + + s->last_frame = av_frame_alloc(); + if (!s->last_frame) { + xan_decode_end(avctx); + return AVERROR(ENOMEM); + } return 0; } -static int xan_huffman_decode(unsigned char *dest, int dest_len, - const unsigned char *src, int src_len) +static int xan_huffman_decode(uint8_t *dest, int dest_len, + const uint8_t *src, int src_len) { - unsigned char byte = *src++; - unsigned char ival = byte + 0x16; - const unsigned char * ptr = src + byte*2; + uint8_t byte = *src++; + uint8_t ival = byte + 0x16; + const uint8_t * ptr = src + byte*2; int ptr_len = src_len - 1 - byte*2; - unsigned char val = ival; - unsigned char *dest_end = dest + dest_len; + uint8_t val = ival; + uint8_t *dest_end = dest + dest_len; + uint8_t *dest_start = dest; + int ret; GetBitContext gb; - if (ptr_len < 0) - return AVERROR_INVALIDDATA; - - init_get_bits(&gb, ptr, ptr_len * 8); + if ((ret = init_get_bits8(&gb, ptr, ptr_len)) < 0) + return ret; while (val != 0x16) { unsigned idx = val - 0x17 + get_bits1(&gb) * byte; @@ -119,13 +137,13 @@ static int xan_huffman_decode(unsigned char *dest, int dest_len, if (val < 0x16) { if (dest >= dest_end) - return 0; + return dest_len; *dest++ = val; val = ival; } } - return 0; + return dest - dest_start; } /** @@ -133,13 +151,13 @@ static int xan_huffman_decode(unsigned char *dest, int dest_len, * * @param dest destination buffer of dest_len, must be padded with at least 130 bytes */ -static void xan_unpack(unsigned char *dest, int dest_len, - const unsigned char *src, int src_len) +static void xan_unpack(uint8_t *dest, int dest_len, + const uint8_t *src, int src_len) { - unsigned char opcode; + uint8_t opcode; int size; - unsigned char *dest_org = dest; - unsigned char *dest_end = dest + dest_len; + uint8_t *dest_org = dest; + uint8_t *dest_end = dest + dest_len; GetByteContext ctx; bytestream2_init(&ctx, src, src_len); @@ -188,14 +206,14 @@ static void xan_unpack(unsigned char *dest, int dest_len, } static inline void xan_wc3_output_pixel_run(XanContext *s, AVFrame *frame, - const unsigned char *pixel_buffer, int x, int y, int pixel_count) + const uint8_t *pixel_buffer, int x, int y, int pixel_count) { int stride; int line_inc; int index; int current_x; int width = s->avctx->width; - unsigned char *palette_plane; + uint8_t *palette_plane; palette_plane = frame->data[0]; stride = frame->linesize[0]; @@ -227,14 +245,14 @@ static inline void xan_wc3_copy_pixel_run(XanContext *s, AVFrame *frame, int curframe_index, prevframe_index; int curframe_x, prevframe_x; int width = s->avctx->width; - unsigned char *palette_plane, *prev_palette_plane; + uint8_t *palette_plane, *prev_palette_plane; if (y + motion_y < 0 || y + motion_y >= s->avctx->height || x + motion_x < 0 || x + motion_x >= s->avctx->width) return; palette_plane = frame->data[0]; - prev_palette_plane = s->last_frame.data[0]; + prev_palette_plane = s->last_frame->data[0]; if (!prev_palette_plane) prev_palette_plane = palette_plane; stride = frame->linesize[0]; @@ -243,6 +261,12 @@ static inline void xan_wc3_copy_pixel_run(XanContext *s, AVFrame *frame, curframe_x = x; prevframe_index = (y + motion_y) * stride + x + motion_x; prevframe_x = x + motion_x; + + if (prev_palette_plane == palette_plane && FFABS(curframe_index - prevframe_index) < pixel_count) { + avpriv_request_sample(s->avctx, "Overlapping copy\n"); + return ; + } + while (pixel_count && curframe_index < s->frame_size && prevframe_index < s->frame_size) { @@ -275,23 +299,22 @@ static int xan_wc3_decode_frame(XanContext *s, AVFrame *frame) int width = s->avctx->width; int height = s->avctx->height; int total_pixels = width * height; - unsigned char opcode; - unsigned char flag = 0; + uint8_t opcode; + uint8_t flag = 0; int size = 0; int motion_x, motion_y; - int x, y; + int x, y, ret; - unsigned char *opcode_buffer = s->buffer1; - unsigned char *opcode_buffer_end = s->buffer1 + s->buffer1_size; + uint8_t *opcode_buffer = s->buffer1; + uint8_t *opcode_buffer_end = s->buffer1 + s->buffer1_size; int opcode_buffer_size = s->buffer1_size; - const unsigned char *imagedata_buffer = s->buffer2; + const uint8_t *imagedata_buffer = s->buffer2; /* pointers to segments inside the compressed chunk */ - const unsigned char *huffman_segment; - const unsigned char *size_segment; - const unsigned char *vector_segment; - const unsigned char *imagedata_segment; - const unsigned char *buf_end = s->buf + s->size; + const uint8_t *huffman_segment; + GetByteContext size_segment; + GetByteContext vector_segment; + const uint8_t *imagedata_segment; int huffman_offset, size_offset, vector_offset, imagedata_offset, imagedata_size; @@ -310,13 +333,14 @@ static int xan_wc3_decode_frame(XanContext *s, AVFrame *frame) return AVERROR_INVALIDDATA; huffman_segment = s->buf + huffman_offset; - size_segment = s->buf + size_offset; - vector_segment = s->buf + vector_offset; + bytestream2_init(&size_segment, s->buf + size_offset, s->size - size_offset); + bytestream2_init(&vector_segment, s->buf + vector_offset, s->size - vector_offset); imagedata_segment = s->buf + imagedata_offset; - if (xan_huffman_decode(opcode_buffer, opcode_buffer_size, - huffman_segment, s->size - huffman_offset) < 0) + if ((ret = xan_huffman_decode(opcode_buffer, opcode_buffer_size, + huffman_segment, s->size - huffman_offset)) < 0) return AVERROR_INVALIDDATA; + opcode_buffer_end = opcode_buffer + ret; if (imagedata_segment[0] == 2) { xan_unpack(s->buffer2, s->buffer2_size, @@ -363,31 +387,29 @@ static int xan_wc3_decode_frame(XanContext *s, AVFrame *frame) case 9: case 19: - if (buf_end - size_segment < 1) { + if (bytestream2_get_bytes_left(&size_segment) < 1) { av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n"); return AVERROR_INVALIDDATA; } - size = *size_segment++; + size = bytestream2_get_byte(&size_segment); break; case 10: case 20: - if (buf_end - size_segment < 2) { + if (bytestream2_get_bytes_left(&size_segment) < 2) { av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n"); return AVERROR_INVALIDDATA; } - size = AV_RB16(&size_segment[0]); - size_segment += 2; + size = bytestream2_get_be16(&size_segment); break; case 11: case 21: - if (buf_end - size_segment < 3) { + if (bytestream2_get_bytes_left(&size_segment) < 3) { av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n"); return AVERROR_INVALIDDATA; } - size = AV_RB24(size_segment); - size_segment += 3; + size = bytestream2_get_be24(&size_segment); break; } @@ -408,14 +430,15 @@ static int xan_wc3_decode_frame(XanContext *s, AVFrame *frame) imagedata_size -= size; } } else { - if (vector_segment >= buf_end) { + uint8_t vector; + if (bytestream2_get_bytes_left(&vector_segment) <= 0) { av_log(s->avctx, AV_LOG_ERROR, "vector_segment overread\n"); return AVERROR_INVALIDDATA; } /* run-based motion compensation from last frame */ - motion_x = sign_extend(*vector_segment >> 4, 4); - motion_y = sign_extend(*vector_segment & 0xF, 4); - vector_segment++; + vector = bytestream2_get_byte(&vector_segment); + motion_x = sign_extend(vector >> 4, 4); + motion_y = sign_extend(vector & 0xF, 4); /* copy a run of pixels from the previous frame */ xan_wc3_copy_pixel_run(s, frame, x, y, size, motion_x, motion_y); @@ -602,8 +625,8 @@ static int xan_decode_frame(AVCodecContext *avctx, if (xan_wc3_decode_frame(s, frame) < 0) return AVERROR_INVALIDDATA; - av_frame_unref(&s->last_frame); - if ((ret = av_frame_ref(&s->last_frame, frame)) < 0) + av_frame_unref(s->last_frame); + if ((ret = av_frame_ref(s->last_frame, frame)) < 0) return ret; *got_frame = 1; @@ -612,21 +635,9 @@ static int xan_decode_frame(AVCodecContext *avctx, return buf_size; } -static av_cold int xan_decode_end(AVCodecContext *avctx) -{ - XanContext *s = avctx->priv_data; - - av_frame_unref(&s->last_frame); - - av_freep(&s->buffer1); - av_freep(&s->buffer2); - av_freep(&s->palettes); - - return 0; -} - AVCodec ff_xan_wc3_decoder = { .name = "xan_wc3", + .long_name = NULL_IF_CONFIG_SMALL("Wing Commander III / Xan"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_XAN_WC3, .priv_data_size = sizeof(XanContext), @@ -634,5 +645,4 @@ AVCodec ff_xan_wc3_decoder = { .close = xan_decode_end, .decode = xan_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Wing Commander III / Xan"), }; diff --git a/ffmpeg/libavcodec/xbmdec.c b/ffmpeg/libavcodec/xbmdec.c index 51f88a2..2976bec 100644 --- a/ffmpeg/libavcodec/xbmdec.c +++ b/ffmpeg/libavcodec/xbmdec.c @@ -27,6 +27,7 @@ static av_cold int xbm_decode_init(AVCodecContext *avctx) { + avctx->pix_fmt = AV_PIX_FMT_MONOWHITE; return 0; } @@ -56,7 +57,7 @@ static int xbm_decode_frame(AVCodecContext *avctx, void *data, int number, len; ptr += strcspn(ptr, "#"); - if (sscanf(ptr, "#define %256s %u", name, &number) != 2) { + if (sscanf(ptr, "#define %255s %u", name, &number) != 2) { av_log(avctx, AV_LOG_ERROR, "Unexpected preprocessor directive\n"); return AVERROR_INVALIDDATA; } @@ -73,8 +74,6 @@ static int xbm_decode_frame(AVCodecContext *avctx, void *data, ptr += strcspn(ptr, "\n\r") + 1; } - avctx->pix_fmt = AV_PIX_FMT_MONOWHITE; - if ((ret = ff_get_buffer(avctx, p, 0)) < 0) return ret; @@ -109,19 +108,12 @@ static int xbm_decode_frame(AVCodecContext *avctx, void *data, return avpkt->size; } -static av_cold int xbm_decode_close(AVCodecContext *avctx) -{ - - return 0; -} - AVCodec ff_xbm_decoder = { .name = "xbm", + .long_name = NULL_IF_CONFIG_SMALL("XBM (X BitMap) image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_XBM, .init = xbm_decode_init, - .close = xbm_decode_close, .decode = xbm_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("XBM (X BitMap) image"), }; diff --git a/ffmpeg/libavcodec/xbmenc.c b/ffmpeg/libavcodec/xbmenc.c index 8e39969..a752bdf 100644 --- a/ffmpeg/libavcodec/xbmenc.c +++ b/ffmpeg/libavcodec/xbmenc.c @@ -24,16 +24,6 @@ #include "internal.h" #include "mathops.h" -static av_cold int xbm_encode_init(AVCodecContext *avctx) -{ - avctx->coded_frame = avcodec_alloc_frame(); - if (!avctx->coded_frame) - return AVERROR(ENOMEM); - avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; - - return 0; -} - static int xbm_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *p, int *got_packet) { @@ -65,21 +55,12 @@ static int xbm_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return 0; } -static av_cold int xbm_encode_close(AVCodecContext *avctx) -{ - av_freep(&avctx->coded_frame); - - return 0; -} - AVCodec ff_xbm_encoder = { .name = "xbm", + .long_name = NULL_IF_CONFIG_SMALL("XBM (X BitMap) image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_XBM, - .init = xbm_encode_init, .encode2 = xbm_encode_frame, - .close = xbm_encode_close, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_MONOWHITE, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("XBM (X BitMap) image"), }; diff --git a/ffmpeg/libavcodec/xfacedec.c b/ffmpeg/libavcodec/xfacedec.c index fbaabdb..d045cb6 100644 --- a/ffmpeg/libavcodec/xfacedec.c +++ b/ffmpeg/libavcodec/xfacedec.c @@ -178,11 +178,11 @@ static int xface_decode_frame(AVCodecContext *avctx, AVCodec ff_xface_decoder = { .name = "xface", + .long_name = NULL_IF_CONFIG_SMALL("X-face image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_XFACE, .priv_data_size = sizeof(XFaceContext), .init = xface_decode_init, .decode = xface_decode_frame, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_MONOWHITE, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("X-face image"), }; diff --git a/ffmpeg/libavcodec/xfaceenc.c b/ffmpeg/libavcodec/xfaceenc.c index 5206afd..e213c9d 100644 --- a/ffmpeg/libavcodec/xfaceenc.c +++ b/ffmpeg/libavcodec/xfaceenc.c @@ -125,7 +125,7 @@ static void encode_block(char *bitmap, int w, int h, int level, ProbRangesQueue static av_cold int xface_encode_init(AVCodecContext *avctx) { - avctx->coded_frame = avcodec_alloc_frame(); + avctx->coded_frame = av_frame_alloc(); if (!avctx->coded_frame) return AVERROR(ENOMEM); avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; @@ -227,6 +227,7 @@ static av_cold int xface_encode_close(AVCodecContext *avctx) AVCodec ff_xface_encoder = { .name = "xface", + .long_name = NULL_IF_CONFIG_SMALL("X-face image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_XFACE, .priv_data_size = sizeof(XFaceContext), @@ -234,5 +235,4 @@ AVCodec ff_xface_encoder = { .close = xface_encode_close, .encode2 = xface_encode_frame, .pix_fmts = (const enum PixelFormat[]) { AV_PIX_FMT_MONOWHITE, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("X-face image"), }; diff --git a/ffmpeg/libavcodec/xl.c b/ffmpeg/libavcodec/xl.c index f50b650..2d1da1d 100644 --- a/ffmpeg/libavcodec/xl.c +++ b/ffmpeg/libavcodec/xl.c @@ -41,19 +41,18 @@ static int decode_frame(AVCodecContext *avctx, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - AVFrame * const p = data; + int buf_size = avpkt->size; + AVFrame *const p = data; uint8_t *Y, *U, *V; int i, j, ret; int stride; uint32_t val; int y0, y1, y2, y3 = 0, c0 = 0, c1 = 0; - if (avctx->width & 3) { + if (avctx->width % 4) { av_log(avctx, AV_LOG_ERROR, "width is not a multiple of 4\n"); return AVERROR_INVALIDDATA; } - if (buf_size < avctx->width * avctx->height) { av_log(avctx, AV_LOG_ERROR, "Packet is too small\n"); return AVERROR_INVALIDDATA; @@ -76,27 +75,27 @@ static int decode_frame(AVCodecContext *avctx, for (j = 0; j < avctx->width; j += 4) { /* value is stored in LE dword with word swapped */ - val = AV_RL32(buf); + val = AV_RL32(buf); buf -= 4; - val = ((val >> 16) & 0xFFFF) | ((val & 0xFFFF) << 16); + val = ((val >> 16) & 0xFFFF) | ((val & 0xFFFF) << 16); - if(!j) + if (!j) y0 = (val & 0x1F) << 2; else y0 = y3 + xl_table[val & 0x1F]; val >>= 5; - y1 = y0 + xl_table[val & 0x1F]; + y1 = y0 + xl_table[val & 0x1F]; val >>= 5; - y2 = y1 + xl_table[val & 0x1F]; + y2 = y1 + xl_table[val & 0x1F]; val >>= 6; /* align to word */ - y3 = y2 + xl_table[val & 0x1F]; + y3 = y2 + xl_table[val & 0x1F]; val >>= 5; - if(!j) + if (!j) c0 = (val & 0x1F) << 2; else c0 += xl_table[val & 0x1F]; val >>= 5; - if(!j) + if (!j) c1 = (val & 0x1F) << 2; else c1 += xl_table[val & 0x1F]; @@ -111,9 +110,9 @@ static int decode_frame(AVCodecContext *avctx, } buf += avctx->width + 4; - Y += p->linesize[0]; - U += p->linesize[1]; - V += p->linesize[2]; + Y += p->linesize[0]; + U += p->linesize[1]; + V += p->linesize[2]; } *got_frame = 1; @@ -129,11 +128,11 @@ static av_cold int decode_init(AVCodecContext *avctx) } AVCodec ff_xl_decoder = { - .name = "xl", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_VIXL, - .init = decode_init, - .decode = decode_frame, - .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Miro VideoXL"), + .name = "xl", + .long_name = NULL_IF_CONFIG_SMALL("Miro VideoXL"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_VIXL, + .init = decode_init, + .decode = decode_frame, + .capabilities = CODEC_CAP_DR1, }; diff --git a/ffmpeg/libavcodec/xsubdec.c b/ffmpeg/libavcodec/xsubdec.c index d3367b0..174d74e 100644 --- a/ffmpeg/libavcodec/xsubdec.c +++ b/ffmpeg/libavcodec/xsubdec.c @@ -137,9 +137,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVCodec ff_xsub_decoder = { .name = "xsub", + .long_name = NULL_IF_CONFIG_SMALL("XSUB"), .type = AVMEDIA_TYPE_SUBTITLE, .id = AV_CODEC_ID_XSUB, .init = decode_init, .decode = decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("XSUB"), }; diff --git a/ffmpeg/libavcodec/xsubenc.c b/ffmpeg/libavcodec/xsubenc.c index cb2a908..53f4d6c 100644 --- a/ffmpeg/libavcodec/xsubenc.c +++ b/ffmpeg/libavcodec/xsubenc.c @@ -166,8 +166,8 @@ static int xsub_encode(AVCodecContext *avctx, unsigned char *buf, bytestream_put_le16(&hdr, height); bytestream_put_le16(&hdr, h->rects[0]->x); bytestream_put_le16(&hdr, h->rects[0]->y); - bytestream_put_le16(&hdr, h->rects[0]->x + width); - bytestream_put_le16(&hdr, h->rects[0]->y + height); + bytestream_put_le16(&hdr, h->rects[0]->x + width -1); + bytestream_put_le16(&hdr, h->rects[0]->y + height -1); rlelenptr = hdr; // Will store length of first field here later. hdr+=2; @@ -190,7 +190,7 @@ static int xsub_encode(AVCodecContext *avctx, unsigned char *buf, h->rects[0]->w, h->rects[0]->h >> 1)) return -1; - // Enforce total height to be be multiple of 2 + // Enforce total height to be a multiple of 2 if (h->rects[0]->h & 1) { put_xsub_rle(&pb, h->rects[0]->w, PADDING_COLOR); avpriv_align_put_bits(&pb); @@ -206,14 +206,16 @@ static av_cold int xsub_encoder_init(AVCodecContext *avctx) if (!avctx->codec_tag) avctx->codec_tag = MKTAG('D','X','S','B'); + avctx->bits_per_coded_sample = 4; + return 0; } AVCodec ff_xsub_encoder = { .name = "xsub", + .long_name = NULL_IF_CONFIG_SMALL("DivX subtitles (XSUB)"), .type = AVMEDIA_TYPE_SUBTITLE, .id = AV_CODEC_ID_XSUB, .init = xsub_encoder_init, .encode_sub = xsub_encode, - .long_name = NULL_IF_CONFIG_SMALL("DivX subtitles (XSUB)"), }; diff --git a/ffmpeg/libavcodec/xvmc.h b/ffmpeg/libavcodec/xvmc.h index b2bf518..c2e187c 100644 --- a/ffmpeg/libavcodec/xvmc.h +++ b/ffmpeg/libavcodec/xvmc.h @@ -29,6 +29,8 @@ #include +#include "libavutil/attributes.h" +#include "version.h" #include "avcodec.h" /** @@ -41,7 +43,7 @@ #define AV_XVMC_ID 0x1DC711C0 /**< special value to ensure that regular pixel routines haven't corrupted the struct the number is 1337 speak for the letters IDCT MCo (motion compensation) */ -struct xvmc_pix_fmt { +attribute_deprecated struct xvmc_pix_fmt { /** The field contains the special constant value AV_XVMC_ID. It is used as a test that the application correctly uses the API, and that there is no corruption caused by pixel routines. diff --git a/ffmpeg/libavcodec/xvmc_internal.h b/ffmpeg/libavcodec/xvmc_internal.h index 04197ce..d365ef0 100644 --- a/ffmpeg/libavcodec/xvmc_internal.h +++ b/ffmpeg/libavcodec/xvmc_internal.h @@ -23,11 +23,9 @@ #include "avcodec.h" #include "mpegvideo.h" +#include "version.h" void ff_xvmc_init_block(MpegEncContext *s); void ff_xvmc_pack_pblocks(MpegEncContext *s, int cbp); -int ff_xvmc_field_start(MpegEncContext*s, AVCodecContext *avctx); -void ff_xvmc_field_end(MpegEncContext *s); -void ff_xvmc_decode_mb(MpegEncContext *s); #endif /* AVCODEC_XVMC_INTERNAL_H */ diff --git a/ffmpeg/libavcodec/xwddec.c b/ffmpeg/libavcodec/xwddec.c index 66a2fe9..c28e19f 100644 --- a/ffmpeg/libavcodec/xwddec.c +++ b/ffmpeg/libavcodec/xwddec.c @@ -141,7 +141,7 @@ static int xwd_decode_frame(AVCodecContext *avctx, void *data, } if (pixformat != XWD_Z_PIXMAP) { - av_log(avctx, AV_LOG_ERROR, "pixmap format %d unsupported\n", pixformat); + avpriv_report_missing_feature(avctx, "Pixmap format %d", pixformat); return AVERROR_PATCHWELCOME; } @@ -239,9 +239,9 @@ static int xwd_decode_frame(AVCodecContext *avctx, void *data, AVCodec ff_xwd_decoder = { .name = "xwd", + .long_name = NULL_IF_CONFIG_SMALL("XWD (X Window Dump) image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_XWD, .decode = xwd_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("XWD (X Window Dump) image"), }; diff --git a/ffmpeg/libavcodec/xwdenc.c b/ffmpeg/libavcodec/xwdenc.c index fac3d0b..06fa4a0 100644 --- a/ffmpeg/libavcodec/xwdenc.c +++ b/ffmpeg/libavcodec/xwdenc.c @@ -30,17 +30,8 @@ #define WINDOW_NAME "lavcxwdenc" #define WINDOW_NAME_SIZE 11 -static av_cold int xwd_encode_init(AVCodecContext *avctx) -{ - avctx->coded_frame = avcodec_alloc_frame(); - if (!avctx->coded_frame) - return AVERROR(ENOMEM); - - return 0; -} - static int xwd_encode_frame(AVCodecContext *avctx, AVPacket *pkt, - const AVFrame *p, int *got_packet) + const AVFrame *pict, int *got_packet) { enum AVPixelFormat pix_fmt = avctx->pix_fmt; const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); @@ -49,9 +40,10 @@ static int xwd_encode_frame(AVCodecContext *avctx, AVPacket *pkt, uint32_t header_size; int i, out_size, ret; uint8_t *ptr, *buf; + AVFrame * const p = (AVFrame *)pict; pixdepth = av_get_bits_per_pixel(desc); - if (desc->flags & PIX_FMT_BE) + if (desc->flags & AV_PIX_FMT_FLAG_BE) be = 1; switch (pix_fmt) { case AV_PIX_FMT_ARGB: @@ -146,7 +138,7 @@ static int xwd_encode_frame(AVCodecContext *avctx, AVPacket *pkt, vclass = XWD_STATIC_GRAY; break; default: - av_log(avctx, AV_LOG_INFO, "unsupported pixel format\n"); + av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n"); return AVERROR(EINVAL); } @@ -158,8 +150,8 @@ static int xwd_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return ret; buf = pkt->data; - avctx->coded_frame->key_frame = 1; - avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + p->key_frame = 1; + p->pict_type = AV_PICTURE_TYPE_I; bytestream_put_be32(&buf, header_size); bytestream_put_be32(&buf, XWD_VERSION); // file version @@ -216,20 +208,12 @@ static int xwd_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return 0; } -static av_cold int xwd_encode_close(AVCodecContext *avctx) -{ - av_freep(&avctx->coded_frame); - - return 0; -} - AVCodec ff_xwd_encoder = { .name = "xwd", + .long_name = NULL_IF_CONFIG_SMALL("XWD (X Window Dump) image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_XWD, - .init = xwd_encode_init, .encode2 = xwd_encode_frame, - .close = xwd_encode_close, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGRA, AV_PIX_FMT_RGBA, AV_PIX_FMT_ARGB, @@ -252,5 +236,4 @@ AVCodec ff_xwd_encoder = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_MONOWHITE, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("XWD (X Window Dump) image"), }; diff --git a/ffmpeg/libavcodec/xxan.c b/ffmpeg/libavcodec/xxan.c index e2b1b8c..b261cdf 100644 --- a/ffmpeg/libavcodec/xxan.c +++ b/ffmpeg/libavcodec/xxan.c @@ -30,7 +30,7 @@ typedef struct XanContext { AVCodecContext *avctx; - AVFrame pic; + AVFrame *pic; uint8_t *y_buffer; uint8_t *scratch_buffer; @@ -38,6 +38,18 @@ typedef struct XanContext { GetByteContext gb; } XanContext; +static av_cold int xan_decode_end(AVCodecContext *avctx) +{ + XanContext *s = avctx->priv_data; + + av_frame_free(&s->pic); + + av_freep(&s->y_buffer); + av_freep(&s->scratch_buffer); + + return 0; +} + static av_cold int xan_decode_init(AVCodecContext *avctx) { XanContext *s = avctx->priv_data; @@ -50,6 +62,10 @@ static av_cold int xan_decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "Invalid frame height: %d.\n", avctx->height); return AVERROR(EINVAL); } + if (avctx->width & 1) { + av_log(avctx, AV_LOG_ERROR, "Invalid frame width: %d.\n", avctx->width); + return AVERROR(EINVAL); + } s->buffer_size = avctx->width * avctx->height; s->y_buffer = av_malloc(s->buffer_size); @@ -57,7 +73,13 @@ static av_cold int xan_decode_init(AVCodecContext *avctx) return AVERROR(ENOMEM); s->scratch_buffer = av_malloc(s->buffer_size + 130); if (!s->scratch_buffer) { - av_freep(&s->y_buffer); + xan_decode_end(avctx); + return AVERROR(ENOMEM); + } + + s->pic = av_frame_alloc(); + if (!s->pic) { + xan_decode_end(avctx); return AVERROR(ENOMEM); } @@ -195,8 +217,8 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off) return dec_size; } - U = s->pic.data[1]; - V = s->pic.data[2]; + U = s->pic->data[1]; + V = s->pic->data[2]; src = s->scratch_buffer; src_end = src + dec_size; if (mode) { @@ -215,16 +237,16 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off) V[i] = vval | (vval >> 5); } } - U += s->pic.linesize[1]; - V += s->pic.linesize[2]; + U += s->pic->linesize[1]; + V += s->pic->linesize[2]; } if (avctx->height & 1) { - memcpy(U, U - s->pic.linesize[1], avctx->width >> 1); - memcpy(V, V - s->pic.linesize[2], avctx->width >> 1); + memcpy(U, U - s->pic->linesize[1], avctx->width >> 1); + memcpy(V, V - s->pic->linesize[2], avctx->width >> 1); } } else { - uint8_t *U2 = U + s->pic.linesize[1]; - uint8_t *V2 = V + s->pic.linesize[2]; + uint8_t *U2 = U + s->pic->linesize[1]; + uint8_t *V2 = V + s->pic->linesize[2]; for (j = 0; j < avctx->height >> 2; j++) { for (i = 0; i < avctx->width >> 1; i += 2) { @@ -241,16 +263,16 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off) V[i] = V[i+1] = V2[i] = V2[i+1] = vval | (vval >> 5); } } - U += s->pic.linesize[1] * 2; - V += s->pic.linesize[2] * 2; - U2 += s->pic.linesize[1] * 2; - V2 += s->pic.linesize[2] * 2; + U += s->pic->linesize[1] * 2; + V += s->pic->linesize[2] * 2; + U2 += s->pic->linesize[1] * 2; + V2 += s->pic->linesize[2] * 2; } if (avctx->height & 3) { int lines = ((avctx->height + 1) >> 1) - (avctx->height >> 2) * 2; - memcpy(U, U - lines * s->pic.linesize[1], lines * s->pic.linesize[1]); - memcpy(V, V - lines * s->pic.linesize[2], lines * s->pic.linesize[2]); + memcpy(U, U - lines * s->pic->linesize[1], lines * s->pic->linesize[1]); + memcpy(V, V - lines * s->pic->linesize[2], lines * s->pic->linesize[2]); } } @@ -292,8 +314,7 @@ static int xan_decode_frame_type0(AVCodecContext *avctx) ybuf[j+1] = cur << 1; last = cur; } - if(j < avctx->width) - ybuf[j] = last << 1; + ybuf[j] = last << 1; prev_buf = ybuf; ybuf += avctx->width; @@ -306,8 +327,7 @@ static int xan_decode_frame_type0(AVCodecContext *avctx) ybuf[j+1] = cur << 1; last = cur; } - if(j < avctx->width) - ybuf[j] = last << 1; + ybuf[j] = last << 1; prev_buf = ybuf; ybuf += avctx->width; } @@ -327,12 +347,12 @@ static int xan_decode_frame_type0(AVCodecContext *avctx) } src = s->y_buffer; - ybuf = s->pic.data[0]; + ybuf = s->pic->data[0]; for (j = 0; j < avctx->height; j++) { for (i = 0; i < avctx->width; i++) ybuf[i] = (src[i] << 2) | (src[i] >> 3); src += avctx->width; - ybuf += s->pic.linesize[0]; + ybuf += s->pic->linesize[0]; } return 0; @@ -367,18 +387,17 @@ static int xan_decode_frame_type1(AVCodecContext *avctx) ybuf[j+1] = cur; last = cur; } - if(j < avctx->width) - ybuf[j] = last; + ybuf[j] = last; ybuf += avctx->width; } src = s->y_buffer; - ybuf = s->pic.data[0]; + ybuf = s->pic->data[0]; for (j = 0; j < avctx->height; j++) { for (i = 0; i < avctx->width; i++) ybuf[i] = (src[i] << 2) | (src[i] >> 3); src += avctx->width; - ybuf += s->pic.linesize[0]; + ybuf += s->pic->linesize[0]; } return 0; @@ -392,7 +411,7 @@ static int xan_decode_frame(AVCodecContext *avctx, int ftype; int ret; - if ((ret = ff_reget_buffer(avctx, &s->pic)) < 0) + if ((ret = ff_reget_buffer(avctx, s->pic)) < 0) return ret; bytestream2_init(&s->gb, avpkt->data, avpkt->size); @@ -411,7 +430,7 @@ static int xan_decode_frame(AVCodecContext *avctx, if (ret) return ret; - if ((ret = av_frame_ref(data, &s->pic)) < 0) + if ((ret = av_frame_ref(data, s->pic)) < 0) return ret; *got_frame = 1; @@ -419,20 +438,9 @@ static int xan_decode_frame(AVCodecContext *avctx, return avpkt->size; } -static av_cold int xan_decode_end(AVCodecContext *avctx) -{ - XanContext *s = avctx->priv_data; - - av_frame_unref(&s->pic); - - av_freep(&s->y_buffer); - av_freep(&s->scratch_buffer); - - return 0; -} - AVCodec ff_xan_wc4_decoder = { .name = "xan_wc4", + .long_name = NULL_IF_CONFIG_SMALL("Wing Commander IV / Xxan"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_XAN_WC4, .priv_data_size = sizeof(XanContext), @@ -440,5 +448,4 @@ AVCodec ff_xan_wc4_decoder = { .close = xan_decode_end, .decode = xan_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Wing Commander IV / Xxan"), }; diff --git a/ffmpeg/libavcodec/y41pdec.c b/ffmpeg/libavcodec/y41pdec.c index 42449c6..9d1e531 100644 --- a/ffmpeg/libavcodec/y41pdec.c +++ b/ffmpeg/libavcodec/y41pdec.c @@ -81,19 +81,12 @@ static int y41p_decode_frame(AVCodecContext *avctx, void *data, return avpkt->size; } -static av_cold int y41p_decode_close(AVCodecContext *avctx) -{ - - return 0; -} - AVCodec ff_y41p_decoder = { .name = "y41p", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed YUV 4:1:1 12-bit"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_Y41P, .init = y41p_decode_init, .decode = y41p_decode_frame, - .close = y41p_decode_close, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Uncompressed YUV 4:1:1 12-bit"), }; diff --git a/ffmpeg/libavcodec/y41penc.c b/ffmpeg/libavcodec/y41penc.c index 1a8f0fb..8f67944 100644 --- a/ffmpeg/libavcodec/y41penc.c +++ b/ffmpeg/libavcodec/y41penc.c @@ -30,7 +30,7 @@ static av_cold int y41p_encode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } - avctx->coded_frame = avcodec_alloc_frame(); + avctx->coded_frame = av_frame_alloc(); avctx->bits_per_coded_sample = 12; if (!avctx->coded_frame) { @@ -91,6 +91,7 @@ static av_cold int y41p_encode_close(AVCodecContext *avctx) AVCodec ff_y41p_encoder = { .name = "y41p", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed YUV 4:1:1 12-bit"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_Y41P, .init = y41p_encode_init, @@ -98,5 +99,4 @@ AVCodec ff_y41p_encoder = { .close = y41p_encode_close, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV411P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Uncompressed YUV 4:1:1 12-bit"), }; diff --git a/ffmpeg/libavcodec/yop.c b/ffmpeg/libavcodec/yop.c index e1f5321..c6b19ec 100644 --- a/ffmpeg/libavcodec/yop.c +++ b/ffmpeg/libavcodec/yop.c @@ -31,6 +31,7 @@ typedef struct YopDecContext { AVCodecContext *avctx; + AVFrame *frame; int num_pal_colors; int first_color[2]; @@ -78,6 +79,15 @@ static const int8_t motion_vector[16][2] = { 4, -2}, {-2, 0}, }; +static av_cold int yop_decode_close(AVCodecContext *avctx) +{ + YopDecContext *s = avctx->priv_data; + + av_frame_free(&s->frame); + + return 0; +} + static av_cold int yop_decode_init(AVCodecContext *avctx) { YopDecContext *s = avctx->priv_data; @@ -107,6 +117,10 @@ static av_cold int yop_decode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); + return 0; } @@ -178,7 +192,7 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { YopDecContext *s = avctx->priv_data; - AVFrame *frame = data; + AVFrame *frame = s->frame; int tag, firstcolor, is_odd_frame; int ret, i, x, y; uint32_t *palette; @@ -188,7 +202,7 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return AVERROR_INVALIDDATA; } - if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + if ((ret = ff_reget_buffer(avctx, frame)) < 0) return ret; if (!avctx->frame_number) @@ -242,16 +256,20 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, s->dstptr += 2*frame->linesize[0] - x; } + if ((ret = av_frame_ref(data, s->frame)) < 0) + return ret; + *got_frame = 1; return avpkt->size; } AVCodec ff_yop_decoder = { .name = "yop", + .long_name = NULL_IF_CONFIG_SMALL("Psygnosis YOP Video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_YOP, .priv_data_size = sizeof(YopDecContext), .init = yop_decode_init, + .close = yop_decode_close, .decode = yop_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Psygnosis YOP Video"), }; diff --git a/ffmpeg/libavcodec/yuv4dec.c b/ffmpeg/libavcodec/yuv4dec.c index 6965f39..00ccf58 100644 --- a/ffmpeg/libavcodec/yuv4dec.c +++ b/ffmpeg/libavcodec/yuv4dec.c @@ -73,19 +73,12 @@ static int yuv4_decode_frame(AVCodecContext *avctx, void *data, return avpkt->size; } -static av_cold int yuv4_decode_close(AVCodecContext *avctx) -{ - - return 0; -} - AVCodec ff_yuv4_decoder = { .name = "yuv4", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed 4:2:0"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_YUV4, .init = yuv4_decode_init, .decode = yuv4_decode_frame, - .close = yuv4_decode_close, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed 4:2:0"), }; diff --git a/ffmpeg/libavcodec/yuv4enc.c b/ffmpeg/libavcodec/yuv4enc.c index 6e2f9bc..ed0fc77 100644 --- a/ffmpeg/libavcodec/yuv4enc.c +++ b/ffmpeg/libavcodec/yuv4enc.c @@ -25,7 +25,7 @@ static av_cold int yuv4_encode_init(AVCodecContext *avctx) { - avctx->coded_frame = avcodec_alloc_frame(); + avctx->coded_frame = av_frame_alloc(); if (!avctx->coded_frame) { av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n"); @@ -81,11 +81,11 @@ static av_cold int yuv4_encode_close(AVCodecContext *avctx) AVCodec ff_yuv4_encoder = { .name = "yuv4", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed 4:2:0"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_YUV4, .init = yuv4_encode_init, .encode2 = yuv4_encode_frame, .close = yuv4_encode_close, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed 4:2:0"), }; diff --git a/ffmpeg/libavcodec/zerocodec.c b/ffmpeg/libavcodec/zerocodec.c index 4a23b67..9f6c37c 100644 --- a/ffmpeg/libavcodec/zerocodec.c +++ b/ffmpeg/libavcodec/zerocodec.c @@ -23,7 +23,7 @@ #include "libavutil/common.h" typedef struct { - AVFrame previous_frame; + AVFrame *previous_frame; z_stream zstream; } ZeroCodecContext; @@ -32,7 +32,7 @@ static int zerocodec_decode_frame(AVCodecContext *avctx, void *data, { ZeroCodecContext *zc = avctx->priv_data; AVFrame *pic = data; - AVFrame *prev_pic = &zc->previous_frame; + AVFrame *prev_pic = zc->previous_frame; z_stream *zstream = &zc->zstream; uint8_t *prev = prev_pic->data[0]; uint8_t *dst; @@ -91,8 +91,8 @@ static int zerocodec_decode_frame(AVCodecContext *avctx, void *data, dst -= pic->linesize[0]; } - av_frame_unref(&zc->previous_frame); - if ((ret = av_frame_ref(&zc->previous_frame, pic)) < 0) + av_frame_unref(zc->previous_frame); + if ((ret = av_frame_ref(zc->previous_frame, pic)) < 0) return ret; *got_frame = 1; @@ -104,7 +104,7 @@ static av_cold int zerocodec_decode_close(AVCodecContext *avctx) { ZeroCodecContext *zc = avctx->priv_data; - av_frame_unref(&zc->previous_frame); + av_frame_free(&zc->previous_frame); inflateEnd(&zc->zstream); @@ -130,17 +130,23 @@ static av_cold int zerocodec_decode_init(AVCodecContext *avctx) return AVERROR(ENOMEM); } + zc->previous_frame = av_frame_alloc(); + if (!zc->previous_frame) { + zerocodec_decode_close(avctx); + return AVERROR(ENOMEM); + } + return 0; } AVCodec ff_zerocodec_decoder = { .type = AVMEDIA_TYPE_VIDEO, .name = "zerocodec", + .long_name = NULL_IF_CONFIG_SMALL("ZeroCodec Lossless Video"), .id = AV_CODEC_ID_ZEROCODEC, .priv_data_size = sizeof(ZeroCodecContext), .init = zerocodec_decode_init, .decode = zerocodec_decode_frame, .close = zerocodec_decode_close, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("ZeroCodec Lossless Video"), }; diff --git a/ffmpeg/libavcodec/zmbv.c b/ffmpeg/libavcodec/zmbv.c index 7f3b326..71e8287 100644 --- a/ffmpeg/libavcodec/zmbv.c +++ b/ffmpeg/libavcodec/zmbv.c @@ -28,6 +28,7 @@ #include #include "libavutil/common.h" +#include "libavutil/imgutils.h" #include "libavutil/intreadwrite.h" #include "avcodec.h" #include "internal.h" @@ -493,7 +494,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac c->bx = (c->width + c->bw - 1) / c->bw; c->by = (c->height+ c->bh - 1) / c->bh; if (!c->cur || !c->prev) - return -1; + return AVERROR(ENOMEM); memset(c->cur, 0, avctx->width * avctx->height * (c->bpp / 8)); memset(c->prev, 0, avctx->width * avctx->height * (c->bpp / 8)); c->decode_intra= decode_intra; @@ -509,7 +510,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac if (c->comp == 0) { //Uncompressed data if (c->decomp_size < len) { - av_log(avctx, AV_LOG_ERROR, "decomp buffer too small\n"); + av_log(avctx, AV_LOG_ERROR, "Buffer too small\n"); return AVERROR_INVALIDDATA; } memcpy(c->decomp_buf, buf, len); @@ -554,11 +555,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac case ZMBV_FMT_24BPP: #endif case ZMBV_FMT_32BPP: - for (j = 0; j < c->height; j++) { - memcpy(out, src, c->stride); - src += c->stride; - out += frame->linesize[0]; - } + av_image_copy_plane(out, frame->linesize[0], src, c->stride, + c->stride, c->height); break; default: av_log(avctx, AV_LOG_ERROR, "Cannot handle format %i\n", c->fmt); @@ -624,6 +622,7 @@ static av_cold int decode_end(AVCodecContext *avctx) AVCodec ff_zmbv_decoder = { .name = "zmbv", + .long_name = NULL_IF_CONFIG_SMALL("Zip Motion Blocks Video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_ZMBV, .priv_data_size = sizeof(ZmbvContext), @@ -631,5 +630,4 @@ AVCodec ff_zmbv_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Zip Motion Blocks Video"), }; diff --git a/ffmpeg/libavcodec/zmbvenc.c b/ffmpeg/libavcodec/zmbvenc.c index fb782a4..28dbe20 100644 --- a/ffmpeg/libavcodec/zmbvenc.c +++ b/ffmpeg/libavcodec/zmbvenc.c @@ -44,7 +44,6 @@ */ typedef struct ZmbvEncContext { AVCodecContext *avctx; - AVFrame pic; int range; uint8_t *comp_buf, *work_buf; @@ -121,7 +120,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { ZmbvEncContext * const c = avctx->priv_data; - AVFrame * const p = &c->pic; + const AVFrame * const p = pict; uint8_t *src, *prev, *buf; uint32_t *palptr; int keyframe, chpal; @@ -134,9 +133,8 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, c->curfrm++; if(c->curfrm == c->keyint) c->curfrm = 0; - *p = *pict; - p->pict_type= keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; - p->key_frame= keyframe; + avctx->coded_frame->pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; + avctx->coded_frame->key_frame = keyframe; chpal = !keyframe && memcmp(p->data[1], c->pal2, 1024); palptr = (uint32_t*)p->data[1]; @@ -251,6 +249,20 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, return 0; } +static av_cold int encode_end(AVCodecContext *avctx) +{ + ZmbvEncContext * const c = avctx->priv_data; + + av_freep(&c->comp_buf); + av_freep(&c->work_buf); + + deflateEnd(&c->zstream); + av_freep(&c->prev); + + av_frame_free(&avctx->coded_frame); + + return 0; +} /** * Init zmbv encoder @@ -312,31 +324,18 @@ static av_cold int encode_init(AVCodecContext *avctx) return -1; } - avctx->coded_frame = &c->pic; - - return 0; -} - - - -/** - * Uninit zmbv encoder - */ -static av_cold int encode_end(AVCodecContext *avctx) -{ - ZmbvEncContext * const c = avctx->priv_data; - - av_freep(&c->comp_buf); - av_freep(&c->work_buf); - - deflateEnd(&c->zstream); - av_freep(&c->prev); + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) { + encode_end(avctx); + return AVERROR(ENOMEM); + } return 0; } AVCodec ff_zmbv_encoder = { .name = "zmbv", + .long_name = NULL_IF_CONFIG_SMALL("Zip Motion Blocks Video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_ZMBV, .priv_data_size = sizeof(ZmbvEncContext), @@ -344,5 +343,4 @@ AVCodec ff_zmbv_encoder = { .encode2 = encode_frame, .close = encode_end, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_PAL8, AV_PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("Zip Motion Blocks Video"), }; -- cgit v1.2.3